summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/emu/crsshair.cpp7
-rw-r--r--src/emu/debug/debugcpu.cpp31
-rw-r--r--src/emu/debug/dvstate.cpp44
-rw-r--r--src/emu/debug/dvstate.h28
-rw-r--r--src/emu/inpttype.h3
-rw-r--r--src/emu/ioport.h3
-rw-r--r--src/emu/screen.cpp4
-rw-r--r--src/emu/screen.h2
-rw-r--r--src/emu/video.cpp551
-rw-r--r--src/emu/video.h50
-rw-r--r--src/frontend/mame/ui/cheatopt.cpp2
-rw-r--r--src/frontend/mame/ui/ui.cpp15
-rw-r--r--src/frontend/mame/ui/viewgfx.cpp6
-rw-r--r--src/osd/modules/input/input_windows.cpp9
14 files changed, 526 insertions, 229 deletions
diff --git a/src/emu/crsshair.cpp b/src/emu/crsshair.cpp
index f4e69d26d50..11bde091d15 100644
--- a/src/emu/crsshair.cpp
+++ b/src/emu/crsshair.cpp
@@ -118,7 +118,7 @@ render_crosshair::render_crosshair(running_machine &machine, int player)
, m_time(0)
{
// for now, use the main screen
- m_screen = machine.first_screen();
+ m_screen = screen_device_iterator(machine.root_device()).first();
}
@@ -314,8 +314,9 @@ crosshair_manager::crosshair_manager(running_machine &machine)
machine.configuration().config_register("crosshairs", config_load_delegate(&crosshair_manager::config_load, this), config_save_delegate(&crosshair_manager::config_save, this));
/* register the animation callback */
- if (machine.first_screen() != nullptr)
- machine.first_screen()->register_vblank_callback(vblank_state_delegate(&crosshair_manager::animate, this));
+ screen_device *first_screen = screen_device_iterator(machine.root_device()).first();
+ if (first_screen != nullptr)
+ first_screen->register_vblank_callback(vblank_state_delegate(&crosshair_manager::animate, this));
}
/*-------------------------------------------------
diff --git a/src/emu/debug/debugcpu.cpp b/src/emu/debug/debugcpu.cpp
index 52fb2f784f8..afd8884cad9 100644
--- a/src/emu/debug/debugcpu.cpp
+++ b/src/emu/debug/debugcpu.cpp
@@ -59,8 +59,6 @@ debugger_cpu::debugger_cpu(running_machine &machine)
, m_last_periodic_update_time(0)
, m_comments_loaded(false)
{
- screen_device *first_screen = m_machine.first_screen();
-
m_tempvar = make_unique_clear<u64[]>(NUM_TEMP_VARIABLES);
/* create a global symbol table */
@@ -75,9 +73,28 @@ debugger_cpu::debugger_cpu(running_machine &machine)
using namespace std::placeholders;
m_symtable->add("cpunum", std::bind(&debugger_cpu::get_cpunum, this, _1));
- m_symtable->add("beamx", std::bind(&debugger_cpu::get_beamx, this, _1, first_screen));
- m_symtable->add("beamy", std::bind(&debugger_cpu::get_beamy, this, _1, first_screen));
- m_symtable->add("frame", std::bind(&debugger_cpu::get_frame, this, _1, first_screen));
+
+ screen_device_iterator screen_iterator = screen_device_iterator(m_machine.root_device());
+ screen_device_iterator::auto_iterator iter = screen_iterator.begin();
+ const uint32_t count = (uint32_t)screen_iterator.count();
+
+ if (count == 1)
+ {
+ m_symtable->add("beamx", std::bind(&debugger_cpu::get_beamx, this, _1, iter.current()));
+ m_symtable->add("beamy", std::bind(&debugger_cpu::get_beamy, this, _1, iter.current()));
+ m_symtable->add("frame", std::bind(&debugger_cpu::get_frame, this, _1, iter.current()));
+ iter.current()->register_vblank_callback(vblank_state_delegate(&debugger_cpu::on_vblank, this));
+ }
+ else if (count > 1)
+ {
+ for (uint32_t i = 0; i < count; i++, iter++)
+ {
+ m_symtable->add(string_format("beamx%d", i).c_str(), std::bind(&debugger_cpu::get_beamx, this, _1, iter.current()));
+ m_symtable->add(string_format("beamy%d", i).c_str(), std::bind(&debugger_cpu::get_beamy, this, _1, iter.current()));
+ m_symtable->add(string_format("frame%d", i).c_str(), std::bind(&debugger_cpu::get_frame, this, _1, iter.current()));
+ iter.current()->register_vblank_callback(vblank_state_delegate(&debugger_cpu::on_vblank, this));
+ }
+ }
/* add the temporary variables to the global symbol table */
for (int regnum = 0; regnum < NUM_TEMP_VARIABLES; regnum++)
@@ -97,10 +114,6 @@ debugger_cpu::debugger_cpu(running_machine &machine)
break;
}
}
-
- /* add callback for breaking on VBLANK */
- if (m_machine.first_screen() != nullptr)
- m_machine.first_screen()->register_vblank_callback(vblank_state_delegate(&debugger_cpu::on_vblank, this));
}
void debugger_cpu::configure_memory(symbol_table &table)
diff --git a/src/emu/debug/dvstate.cpp b/src/emu/debug/dvstate.cpp
index bf6212ec3b4..092c6885ca0 100644
--- a/src/emu/debug/dvstate.cpp
+++ b/src/emu/debug/dvstate.cpp
@@ -119,14 +119,30 @@ void debug_view_state::recompute()
// add a cycles entry: cycles:99999999
m_state_list.emplace_back(REG_CYCLES, "cycles", 8);
- // add a beam entry: beamx:1234
- m_state_list.emplace_back(REG_BEAMX, "beamx", 4);
+ screen_device_iterator screen_iterator = screen_device_iterator(machine().root_device());
+ screen_device_iterator::auto_iterator iter = screen_iterator.begin();
+ const int screen_count = screen_iterator.count();
- // add a beam entry: beamy:5678
- m_state_list.emplace_back(REG_BEAMY, "beamy", 4);
+ if (screen_count == 1)
+ {
+ // add a beam entry: beamx:1234
+ m_state_list.emplace_back(REG_BEAMX, "beamx", 4);
+
+ // add a beam entry: beamy:5678
+ m_state_list.emplace_back(REG_BEAMY, "beamy", 4);
- // add a beam entry: frame:123456
- m_state_list.emplace_back(REG_FRAME, "frame", 6);
+ // add a beam entry: frame:123456
+ m_state_list.emplace_back(REG_FRAME, "frame", 6);
+ }
+ else if (screen_count > 1)
+ {
+ for (int i = 0; i < screen_count; i++, iter++)
+ {
+ m_state_list.emplace_back(REG_BEAMX_S0 - i, string_format("beamx%d", i).c_str(), 4);
+ m_state_list.emplace_back(REG_BEAMY_S0 - i, string_format("beamy%d", i).c_str(), 4);
+ m_state_list.emplace_back(REG_FRAME_S0 - i, string_format("frame%d", i).c_str(), 6);
+ }
+ }
// add a flags entry: flags:xxxxxxxx
m_state_list.emplace_back(STATE_GENFLAGS, "flags", source.m_stateintf->state_string_max_length(STATE_GENFLAGS));
@@ -196,7 +212,6 @@ void debug_view_state::view_update()
// loop over rows
auto it(m_state_list.begin());
- screen_device const *const screen(machine().first_screen());
debug_view_char *dest(&m_viewdata[0]);
for (s32 index = 0, limit = m_topleft.y + m_visible.y; (index < limit) || (it != m_state_list.end()); ++index)
{
@@ -222,18 +237,21 @@ void debug_view_state::view_update()
valstr = string_format("%-8d", curitem.value());
break;
- case REG_BEAMX:
- curitem.update(screen ? screen->hpos() : 0, cycles_changed);
+ case REG_BEAMX_S0: case REG_BEAMX_S1: case REG_BEAMX_S2: case REG_BEAMX_S3:
+ case REG_BEAMX_S4: case REG_BEAMX_S5: case REG_BEAMX_S6: case REG_BEAMX_S7:
+ curitem.update(screen_device_iterator(machine().root_device()).byindex(-(curitem.index() - REG_BEAMX_S0))->hpos(), cycles_changed);
valstr = string_format("%4d", curitem.value());
break;
- case REG_BEAMY:
- curitem.update(screen ? screen->vpos() : 0, cycles_changed);
+ case REG_BEAMY_S0: case REG_BEAMY_S1: case REG_BEAMY_S2: case REG_BEAMY_S3:
+ case REG_BEAMY_S4: case REG_BEAMY_S5: case REG_BEAMY_S6: case REG_BEAMY_S7:
+ curitem.update(screen_device_iterator(machine().root_device()).byindex(-(curitem.index() - REG_BEAMY_S0))->vpos(), cycles_changed);
valstr = string_format("%4d", curitem.value());
break;
- case REG_FRAME:
- curitem.update(screen ? screen->frame_number() : 0, cycles_changed);
+ case REG_FRAME_S0: case REG_FRAME_S1: case REG_FRAME_S2: case REG_FRAME_S3:
+ case REG_FRAME_S4: case REG_FRAME_S5: case REG_FRAME_S6: case REG_FRAME_S7:
+ curitem.update(screen_device_iterator(machine().root_device()).byindex(-(curitem.index() - REG_FRAME_S0))->frame_number(), cycles_changed);
valstr = string_format("%-6d", curitem.value());
break;
diff --git a/src/emu/debug/dvstate.h b/src/emu/debug/dvstate.h
index 22ffb8be86f..8239a53f5db 100644
--- a/src/emu/debug/dvstate.h
+++ b/src/emu/debug/dvstate.h
@@ -89,8 +89,32 @@ private:
static constexpr int REG_DIVIDER = -10;
static constexpr int REG_CYCLES = -11;
static constexpr int REG_BEAMX = -12;
- static constexpr int REG_BEAMY = -13;
- static constexpr int REG_FRAME = -14;
+ static constexpr int REG_BEAMX_S0 = -12;
+ static constexpr int REG_BEAMX_S1 = -13;
+ static constexpr int REG_BEAMX_S2 = -14;
+ static constexpr int REG_BEAMX_S3 = -15;
+ static constexpr int REG_BEAMX_S4 = -16;
+ static constexpr int REG_BEAMX_S5 = -17;
+ static constexpr int REG_BEAMX_S6 = -18;
+ static constexpr int REG_BEAMX_S7 = -19;
+ static constexpr int REG_BEAMY = -20;
+ static constexpr int REG_BEAMY_S0 = -20;
+ static constexpr int REG_BEAMY_S1 = -21;
+ static constexpr int REG_BEAMY_S2 = -22;
+ static constexpr int REG_BEAMY_S3 = -23;
+ static constexpr int REG_BEAMY_S4 = -24;
+ static constexpr int REG_BEAMY_S5 = -25;
+ static constexpr int REG_BEAMY_S6 = -26;
+ static constexpr int REG_BEAMY_S7 = -27;
+ static constexpr int REG_FRAME = -28;
+ static constexpr int REG_FRAME_S0 = -28;
+ static constexpr int REG_FRAME_S1 = -29;
+ static constexpr int REG_FRAME_S2 = -30;
+ static constexpr int REG_FRAME_S3 = -31;
+ static constexpr int REG_FRAME_S4 = -32;
+ static constexpr int REG_FRAME_S5 = -33;
+ static constexpr int REG_FRAME_S6 = -34;
+ static constexpr int REG_FRAME_S7 = -35;
};
diff --git a/src/emu/inpttype.h b/src/emu/inpttype.h
index cf7cef9150d..6cc9440c669 100644
--- a/src/emu/inpttype.h
+++ b/src/emu/inpttype.h
@@ -836,7 +836,8 @@ inline void construct_core_types_UI(simple_list<input_type_entry> &typelist)
INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_SHOW_FPS, "Show FPS", input_seq(KEYCODE_F11, input_seq::not_code, KEYCODE_LSHIFT) )
INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_SNAPSHOT, "Save Snapshot", input_seq(KEYCODE_F12, input_seq::not_code, KEYCODE_LSHIFT) )
INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_TIMECODE, "Write current timecode", input_seq(KEYCODE_F12, input_seq::not_code, KEYCODE_LSHIFT) )
- INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_RECORD_MOVIE, "Record Movie", input_seq(KEYCODE_F12, KEYCODE_LSHIFT) )
+ INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_RECORD_MNG, "Record MNG", input_seq(KEYCODE_F12, KEYCODE_LSHIFT, input_seq::not_code, KEYCODE_LCONTROL) )
+ INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_RECORD_AVI, "Record AVI", input_seq(KEYCODE_F12, KEYCODE_LSHIFT, KEYCODE_LCONTROL) )
INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_TOGGLE_CHEAT, "Toggle Cheat", input_seq(KEYCODE_F6) )
INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_TOGGLE_AUTOFIRE, "Toggle Autofire", input_seq() )
INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_UP, "UI Up", input_seq(KEYCODE_UP, input_seq::or_code, JOYCODE_Y_UP_SWITCH_INDEXED(0)) )
diff --git a/src/emu/ioport.h b/src/emu/ioport.h
index a9f25e29184..72ea16e81d5 100644
--- a/src/emu/ioport.h
+++ b/src/emu/ioport.h
@@ -333,7 +333,8 @@ enum ioport_type
IPT_UI_SHOW_FPS,
IPT_UI_SNAPSHOT,
IPT_UI_TIMECODE,
- IPT_UI_RECORD_MOVIE,
+ IPT_UI_RECORD_MNG,
+ IPT_UI_RECORD_AVI,
IPT_UI_TOGGLE_CHEAT,
IPT_UI_UP,
IPT_UI_DOWN,
diff --git a/src/emu/screen.cpp b/src/emu/screen.cpp
index 849a353ddb2..feb21251f23 100644
--- a/src/emu/screen.cpp
+++ b/src/emu/screen.cpp
@@ -1368,7 +1368,7 @@ void screen_device::vblank_begin()
m_vblank_end_time = m_vblank_start_time + attotime(0, m_vblank_period);
// if this is the primary screen and we need to update now
- if (this == machine().first_screen() && !(m_video_attributes & VIDEO_UPDATE_AFTER_VBLANK))
+ if (this == screen_device_iterator(machine().root_device()).first() && !(m_video_attributes & VIDEO_UPDATE_AFTER_VBLANK))
machine().video().frame_update();
// call the screen specific callbacks
@@ -1400,7 +1400,7 @@ void screen_device::vblank_end()
m_screen_vblank(0);
// if this is the primary screen and we need to update now
- if (this == machine().first_screen() && (m_video_attributes & VIDEO_UPDATE_AFTER_VBLANK))
+ if (this == screen_device_iterator(machine().root_device()).first() && (m_video_attributes & VIDEO_UPDATE_AFTER_VBLANK))
machine().video().frame_update();
// increment the frame number counter
diff --git a/src/emu/screen.h b/src/emu/screen.h
index a66a2f90f53..405951d9541 100644
--- a/src/emu/screen.h
+++ b/src/emu/screen.h
@@ -43,6 +43,8 @@ enum texture_format
// screen_update callback flags
constexpr u32 UPDATE_HAS_NOT_CHANGED = 0x0001; // the video has not changed
+constexpr u32 MAX_NUM_SCREENS = 9;
+
/*!
@defgroup flags for video_attributes
@{
diff --git a/src/emu/video.cpp b/src/emu/video.cpp
index dca8c938926..6cc6af39454 100644
--- a/src/emu/video.cpp
+++ b/src/emu/video.cpp
@@ -100,13 +100,6 @@ video_manager::video_manager(running_machine &machine)
m_snap_native(true),
m_snap_width(0),
m_snap_height(0),
- m_mng_frame_period(attotime::zero),
- m_mng_next_frame_time(attotime::zero),
- m_mng_frame(0),
- m_avi_file(nullptr),
- m_avi_frame_period(attotime::zero),
- m_avi_next_frame_time(attotime::zero),
- m_avi_frame(0),
m_timecode_enabled(false),
m_timecode_write(false),
m_timecode_text(""),
@@ -121,13 +114,15 @@ video_manager::video_manager(running_machine &machine)
// extract initial execution state from global configuration settings
update_refresh_speed();
+ const bool no_screens = screen_device_iterator(machine.root_device()).count() == 0;
+
// create a render target for snapshots
const char *viewname = machine.options().snap_view();
- m_snap_native = (machine.first_screen() != nullptr && (viewname[0] == 0 || strcmp(viewname, "native") == 0));
+ m_snap_native = !no_screens && (viewname[0] == 0 || strcmp(viewname, "native") == 0);
- // the native target is hard-coded to our internal layout and has all options disabled
if (m_snap_native)
{
+ // the native target is hard-coded to our internal layout and has all options disabled
m_snap_target = machine.render().target_alloc(&layout_snap, RENDER_CREATE_SINGLE_FILE | RENDER_CREATE_HIDDEN);
m_snap_target->set_backdrops_enabled(false);
m_snap_target->set_overlays_enabled(false);
@@ -137,10 +132,9 @@ video_manager::video_manager(running_machine &machine)
m_snap_target->set_screen_overlay_enabled(false);
m_snap_target->set_zoom_to_screen(false);
}
-
- // other targets select the specified view and turn off effects
else
{
+ // otherwise, non-default targets select the specified view and turn off effects
m_snap_target = machine.render().target_alloc(nullptr, RENDER_CREATE_HIDDEN);
m_snap_target->set_view(m_snap_target->configured_view(viewname, 0, 1));
m_snap_target->set_screen_overlay_enabled(false);
@@ -160,7 +154,7 @@ video_manager::video_manager(running_machine &machine)
begin_recording(filename, MF_AVI);
// if no screens, create a periodic timer to drive updates
- if (machine.first_screen() == nullptr)
+ if (no_screens)
{
m_screenless_frame_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(video_manager::screenless_update_callback), this));
m_screenless_frame_timer->adjust(screen_device::DEFAULT_FRAME_PERIOD, 0, screen_device::DEFAULT_FRAME_PERIOD);
@@ -247,7 +241,7 @@ void video_manager::frame_update(bool from_debugger)
if (phase == machine_phase::RUNNING)
{
// reset partial updates if we're paused or if the debugger is active
- screen_device *const screen = machine().first_screen();
+ screen_device *const screen = screen_device_iterator(machine().root_device()).first();
bool const debugger_enabled = machine().debug_flags & DEBUG_FLAG_ENABLED;
bool const within_instruction_hook = debugger_enabled && machine().debugger().within_instruction_hook();
if (screen && (machine().paused() || from_debugger || within_instruction_hook))
@@ -396,149 +390,223 @@ std::string &video_manager::timecode_total_text(std::string &str)
return str;
}
-
-
//-------------------------------------------------
-// begin_recording - begin recording of a movie
+// begin_recording_mng - begin recording a MNG
//-------------------------------------------------
-void video_manager::begin_recording(const char *name, movie_format format)
+void video_manager::begin_recording_mng(const char *name, uint32_t index, screen_device *screen)
{
- // create a snapshot bitmap so we know what the target size is
- create_snapshot_bitmap(nullptr);
+ // stop any existing recording
+ end_recording_mng(index);
+
+ mng_info_t &info = m_mngs[index];
+
+ // reset the state
+ info.m_mng_frame = 0;
+ info.m_mng_next_frame_time = machine().time();
- // start up an AVI recording
- if (format == MF_AVI)
+ // create a new movie file and start recording
+ info.m_mng_file = std::make_unique<emu_file>(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
+ osd_file::error filerr;
+ if (name != nullptr)
{
- // stop any existing recording
- end_recording(format);
+ std::string full_name(name);
- // reset the state
- m_avi_frame = 0;
- m_avi_next_frame_time = machine().time();
-
- // build up information about this new movie
- screen_device *screen = machine().first_screen();
- avi_file::movie_info info;
- info.video_format = 0;
- info.video_timescale = 1000 * ((screen != nullptr) ? ATTOSECONDS_TO_HZ(screen->frame_period().attoseconds()) : screen_device::DEFAULT_FRAME_RATE);
- info.video_sampletime = 1000;
- info.video_numsamples = 0;
- info.video_width = m_snap_bitmap.width();
- info.video_height = m_snap_bitmap.height();
- info.video_depth = 24;
-
- info.audio_format = 0;
- info.audio_timescale = machine().sample_rate();
- info.audio_sampletime = 1;
- info.audio_numsamples = 0;
- info.audio_channels = 2;
- info.audio_samplebits = 16;
- info.audio_samplerate = machine().sample_rate();
-
- // create a new temporary movie file
- osd_file::error filerr;
- std::string fullpath;
+ if (index > 0)
{
- emu_file tempfile(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- if (name != nullptr)
- filerr = tempfile.open(name);
- else
- filerr = open_next(tempfile, "avi");
-
- // if we succeeded, make a copy of the name and create the real file over top
- if (filerr == osd_file::error::NONE)
- fullpath = tempfile.fullpath();
+ char name_buf[256] = { 0 };
+ snprintf(name_buf, 256, "%s%d", name, index);
+ full_name = name_buf;
}
- if (filerr == osd_file::error::NONE)
- {
- // compute the frame time
- m_avi_frame_period = attotime::from_seconds(1000) / info.video_timescale;
+ filerr = info.m_mng_file->open(full_name.c_str());
+ }
+ else
+ {
+ filerr = open_next(*info.m_mng_file, "mng");
+ }
- // create the file and free the string
- avi_file::error avierr = avi_file::create(fullpath, info, m_avi_file);
- if (avierr != avi_file::error::NONE)
- {
- osd_printf_error("Error creating AVI: %s\n", avi_file::error_string(avierr));
- return end_recording(format);
- }
+ if (filerr == osd_file::error::NONE)
+ {
+ // start the capture
+ int rate = ATTOSECONDS_TO_HZ(screen->frame_period().attoseconds());
+ png_error pngerr = mng_capture_start(*info.m_mng_file, m_snap_bitmap, rate);
+ if (pngerr != PNGERR_NONE)
+ {
+ osd_printf_error("Error capturing MNG, png_error=%d\n", pngerr);
+ return end_recording_mng(index);
}
- }
- // start up a MNG recording
- else if (format == MF_MNG)
+ // compute the frame time
+ info.m_mng_frame_period = attotime::from_hz(rate);
+ }
+ else
{
- // stop any existing recording
- end_recording(format);
+ osd_printf_error("Error creating MNG, osd_file::error=%d\n", int(filerr));
+ info.m_mng_file.reset();
+ }
+}
- // reset the state
- m_mng_frame = 0;
- m_mng_next_frame_time = machine().time();
+//-------------------------------------------------
+// begin_recording_avi - begin recording an AVI
+//-------------------------------------------------
- // create a new movie file and start recording
- m_mng_file = std::make_unique<emu_file>(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- osd_file::error filerr;
+void video_manager::begin_recording_avi(const char *name, uint32_t index, screen_device *screen)
+{
+ // stop any existing recording
+ end_recording_avi(index);
+
+ avi_info_t &avi_info = m_avis[index];
+
+ // reset the state
+ avi_info.m_avi_frame = 0;
+ avi_info.m_avi_next_frame_time = machine().time();
+
+ // build up information about this new movie
+ avi_file::movie_info info;
+ info.video_format = 0;
+ info.video_timescale = 1000 * ATTOSECONDS_TO_HZ(screen->frame_period().attoseconds());
+ info.video_sampletime = 1000;
+ info.video_numsamples = 0;
+ info.video_width = m_snap_bitmap.width();
+ info.video_height = m_snap_bitmap.height();
+ info.video_depth = 24;
+
+ info.audio_format = 0;
+ info.audio_timescale = machine().sample_rate();
+ info.audio_sampletime = 1;
+ info.audio_numsamples = 0;
+ info.audio_channels = 2;
+ info.audio_samplebits = 16;
+ info.audio_samplerate = machine().sample_rate();
+
+ // create a new temporary movie file
+ osd_file::error filerr;
+ std::string fullpath;
+ {
+ emu_file tempfile(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
if (name != nullptr)
- filerr = m_mng_file->open(name);
- else
- filerr = open_next(*m_mng_file, "mng");
-
- if (filerr == osd_file::error::NONE)
{
- // start the capture
- screen_device *screen = machine().first_screen();
- int rate = (screen != nullptr) ? ATTOSECONDS_TO_HZ(screen->frame_period().attoseconds()) : screen_device::DEFAULT_FRAME_RATE;
- png_error pngerr = mng_capture_start(*m_mng_file, m_snap_bitmap, rate);
- if (pngerr != PNGERR_NONE)
+ std::string full_name(name);
+
+ if (index > 0)
{
- osd_printf_error("Error capturing MNG, png_error=%d\n", pngerr);
- return end_recording(format);
+ char name_buf[256] = { 0 };
+ snprintf(name_buf, 256, "%s%d", name, index);
+ full_name = name_buf;
}
- // compute the frame time
- m_mng_frame_period = attotime::from_hz(rate);
+ filerr = tempfile.open(full_name.c_str());
}
else
{
- osd_printf_error("Error creating MNG, osd_file::error=%d\n", int(filerr));
- m_mng_file.reset();
+ filerr = open_next(tempfile, "avi");
}
+
+ // if we succeeded, make a copy of the name and create the real file over top
+ if (filerr == osd_file::error::NONE)
+ fullpath = tempfile.fullpath();
}
-}
+ if (filerr == osd_file::error::NONE)
+ {
+ // compute the frame time
+ avi_info.m_avi_frame_period = attotime::from_seconds(1000) / info.video_timescale;
+
+ // create the file and free the string
+ avi_file::error avierr = avi_file::create(fullpath, info, avi_info.m_avi_file);
+ if (avierr != avi_file::error::NONE)
+ {
+ osd_printf_error("Error creating AVI: %s\n", avi_file::error_string(avierr));
+ return end_recording_avi(index);
+ }
+ }
+}
//-------------------------------------------------
-// end_recording - stop recording of a movie
+// begin_recording - begin recording of a movie
//-------------------------------------------------
-void video_manager::end_recording(movie_format format)
+void video_manager::begin_recording(const char *name, movie_format format)
{
- if (format == MF_AVI)
+ // create a snapshot bitmap so we know what the target size is
+ screen_device_iterator iterator = screen_device_iterator(machine().root_device());
+ screen_device_iterator::auto_iterator iter = iterator.begin();
+ const uint32_t count = (uint32_t)iterator.count();
+
+ switch (format)
{
- // close the file if it exists
- if (m_avi_file)
- {
- m_avi_file.reset();
+ case MF_AVI:
+ if (m_snap_native)
+ {
+ for (uint32_t index = 0; index < count; index++, iter++)
+ {
+ create_snapshot_bitmap(iter.current());
+ begin_recording_avi(name, index, iter.current());
+ }
+ }
+ else
+ {
+ create_snapshot_bitmap(nullptr);
+ begin_recording_avi(name, 0, iter.current());
+ }
+ break;
- // reset the state
- m_avi_frame = 0;
- }
+ case MF_MNG:
+ if (m_snap_native)
+ {
+ for (uint32_t index = 0; index < count; index++, iter++)
+ {
+ create_snapshot_bitmap(iter.current());
+ begin_recording_mng(name, index, iter.current());
+ }
+ }
+ else
+ {
+ create_snapshot_bitmap(nullptr);
+ begin_recording_avi(name, 0, iter.current());
+ }
+ break;
+
+ default:
+ osd_printf_error("Unknown movie format: %d\n", format);
+ break;
}
- else if (format == MF_MNG)
+}
+
+
+//--------------------------------------------------
+// end_recording_avi - stop recording an AVI movie
+//--------------------------------------------------
+
+void video_manager::end_recording_avi(uint32_t index)
+{
+ avi_info_t &info = m_avis[index];
+ if (info.m_avi_file)
{
- // close the file if it exists
- if (m_mng_file != nullptr)
- {
- mng_capture_stop(*m_mng_file);
- m_mng_file.reset();
+ info.m_avi_file.reset();
- // reset the state
- m_mng_frame = 0;
- }
+ // reset the state
+ info.m_avi_frame = 0;
}
}
+//--------------------------------------------------
+// end_recording_mng - stop recording a MNG movie
+//--------------------------------------------------
+
+void video_manager::end_recording_mng(uint32_t index)
+{
+ mng_info_t &info = m_mngs[index];
+ if (info.m_mng_file != nullptr)
+ {
+ mng_capture_stop(*info.m_mng_file);
+ info.m_mng_file.reset();
+
+ // reset the state
+ info.m_mng_frame = 0;
+ }
+}
//-------------------------------------------------
// add_sound_to_recording - add sound to a movie
@@ -547,24 +615,44 @@ void video_manager::end_recording(movie_format format)
void video_manager::add_sound_to_recording(const s16 *sound, int numsamples)
{
+ if (m_snap_native)
+ {
+ const uint32_t count = (uint32_t)screen_device_iterator(machine().root_device()).count();
+ for (uint32_t index = 0; index < count; index++)
+ {
+ add_sound_to_avi_recording(sound, numsamples, index);
+ }
+ }
+ else
+ {
+ add_sound_to_avi_recording(sound, numsamples, 0);
+ }
+}
+
+//-------------------------------------------------
+// add_sound_to_avi_recording - add sound to an
+// AVI recording for a given screen
+//-------------------------------------------------
+
+void video_manager::add_sound_to_avi_recording(const s16 *sound, int numsamples, uint32_t index)
+{
+ avi_info_t &info = m_avis[index];
// only record if we have a file
- if (m_avi_file != nullptr)
+ if (info.m_avi_file != nullptr)
{
g_profiler.start(PROFILER_MOVIE_REC);
// write the next frame
- avi_file::error avierr = m_avi_file->append_sound_samples(0, sound + 0, numsamples, 1);
+ avi_file::error avierr = info.m_avi_file->append_sound_samples(0, sound + 0, numsamples, 1);
if (avierr == avi_file::error::NONE)
- avierr = m_avi_file->append_sound_samples(1, sound + 1, numsamples, 1);
+ avierr = info.m_avi_file->append_sound_samples(1, sound + 1, numsamples, 1);
if (avierr != avi_file::error::NONE)
- end_recording(MF_AVI);
+ end_recording_avi(index);
g_profiler.stop();
}
}
-
-
//-------------------------------------------------
// video_exit - close down the video system
//-------------------------------------------------
@@ -572,8 +660,20 @@ void video_manager::add_sound_to_recording(const s16 *sound, int numsamples)
void video_manager::exit()
{
// stop recording any movie
- end_recording(MF_AVI);
- end_recording(MF_MNG);
+
+ screen_device_iterator device_iterator = screen_device_iterator(machine().root_device());
+ screen_device_iterator::auto_iterator iter = device_iterator.begin();
+ const uint32_t count = (uint32_t)device_iterator.count();
+
+ for (uint32_t index = 0; index < count; index++, iter++)
+ {
+ end_recording_avi(index);
+ end_recording_mng(index);
+ if (!m_snap_native)
+ {
+ break;
+ }
+ }
// free the snapshot target
machine().render().target_free(m_snap_target);
@@ -609,12 +709,49 @@ void video_manager::screenless_update_callback(void *ptr, int param)
void video_manager::postload()
{
- m_avi_next_frame_time = machine().time();
- m_mng_next_frame_time = machine().time();
+ screen_device_iterator device_iterator = screen_device_iterator(machine().root_device());
+ screen_device_iterator::auto_iterator iter = device_iterator.begin();
+ const uint32_t count = (uint32_t)device_iterator.count();
+
+ for (uint32_t index = 0; index < count; index++, iter++)
+ {
+ m_avis[index].m_avi_next_frame_time = machine().time();
+ m_mngs[index].m_mng_next_frame_time = machine().time();
+ if (!m_snap_native)
+ {
+ break;
+ }
+ }
}
//-------------------------------------------------
+// is_recording - returns whether or not any
+// screen is currently recording
+//-------------------------------------------------
+
+bool video_manager::is_recording() const
+{
+ screen_device_iterator device_iterator = screen_device_iterator(machine().root_device());
+ screen_device_iterator::auto_iterator iter = device_iterator.begin();
+ const uint32_t count = (uint32_t)device_iterator.count();
+
+ for (uint32_t index = 0; index < count; index++, iter++)
+ {
+ if (m_mngs[index].m_mng_file || m_avis[index].m_avi_file)
+ {
+ return true;
+ }
+ if (!m_snap_native)
+ {
+ break;
+ }
+ }
+
+ return false;
+}
+
+//-------------------------------------------------
// effective_autoframeskip - return the effective
// autoframeskip value, accounting for fast
// forward
@@ -1128,7 +1265,7 @@ void video_manager::create_snapshot_bitmap(screen_device *screen)
// scheme
//-------------------------------------------------
-osd_file::error video_manager::open_next(emu_file &file, const char *extension)
+osd_file::error video_manager::open_next(emu_file &file, const char *extension, uint32_t added_index)
{
u32 origflags = file.openflags();
@@ -1229,7 +1366,7 @@ osd_file::error video_manager::open_next(emu_file &file, const char *extension)
else
{
// try until we succeed
- file.set_openflags(OPEN_FLAG_READ);
+ file.set_openflags(OPEN_FLAG_WRITE);
for (int seq = 0; ; seq++)
{
// build up the filename
@@ -1238,8 +1375,10 @@ osd_file::error video_manager::open_next(emu_file &file, const char *extension)
// try to open the file; stop when we fail
osd_file::error filerr = file.open(fname.c_str());
- if (filerr != osd_file::error::NONE)
+ if (filerr == osd_file::error::NOT_FOUND)
+ {
break;
+ }
}
}
@@ -1256,68 +1395,88 @@ osd_file::error video_manager::open_next(emu_file &file, const char *extension)
void video_manager::record_frame()
{
// ignore if nothing to do
- if (m_mng_file == nullptr && m_avi_file == nullptr)
+ bool any_recording = false;
+ for (uint32_t index = 0; index < MAX_NUM_SCREENS && !any_recording; index++)
+ {
+ if (m_mngs[index].m_mng_file != nullptr || m_avis[index].m_avi_file != nullptr)
+ any_recording = true;
+ }
+ if (!any_recording)
return;
// start the profiler and get the current time
g_profiler.start(PROFILER_MOVIE_REC);
attotime curtime = machine().time();
- // create the bitmap
- create_snapshot_bitmap(nullptr);
+ screen_device_iterator device_iterator = screen_device_iterator(machine().root_device());
+ screen_device_iterator::auto_iterator iter = device_iterator.begin();
+ const uint32_t count = (uint32_t)device_iterator.count();
- // handle an AVI recording
- if (m_avi_file != nullptr)
+ for (uint32_t index = 0; index < count; index++, iter++)
{
- // loop until we hit the right time
- while (m_avi_next_frame_time <= curtime)
+ // create the bitmap
+ create_snapshot_bitmap(iter.current());
+
+ // handle an AVI recording
+ avi_info_t &avi_info = m_avis[index];
+ if (avi_info.m_avi_file != nullptr)
{
- // write the next frame
- avi_file::error avierr = m_avi_file->append_video_frame(m_snap_bitmap);
- if (avierr != avi_file::error::NONE)
+ // loop until we hit the right time
+ while (avi_info.m_avi_next_frame_time <= curtime)
{
- g_profiler.stop();
- end_recording(MF_AVI);
- break;
- }
+ // write the next frame
+ avi_file::error avierr = avi_info.m_avi_file->append_video_frame(m_snap_bitmap);
+ if (avierr != avi_file::error::NONE)
+ {
+ g_profiler.stop();
+ end_recording_avi(index);
+ break;
+ }
- // advance time
- m_avi_next_frame_time += m_avi_frame_period;
- m_avi_frame++;
+ // advance time
+ avi_info.m_avi_next_frame_time += avi_info.m_avi_frame_period;
+ avi_info.m_avi_frame++;
+ }
}
- }
- // handle a MNG recording
- if (m_mng_file != nullptr)
- {
- // loop until we hit the right time
- while (m_mng_next_frame_time <= curtime)
+ // handle a MNG recording
+ mng_info_t &mng_info = m_mngs[index];
+ if (mng_info.m_mng_file != nullptr)
{
- // set up the text fields in the movie info
- png_info pnginfo;
- if (m_mng_frame == 0)
+ // loop until we hit the right time
+ while (mng_info.m_mng_next_frame_time <= curtime)
{
- std::string text1 = std::string(emulator_info::get_appname()).append(" ").append(emulator_info::get_build_version());
- std::string text2 = std::string(machine().system().manufacturer).append(" ").append(machine().system().type.fullname());
- pnginfo.add_text("Software", text1.c_str());
- pnginfo.add_text("System", text2.c_str());
- }
+ // set up the text fields in the movie info
+ png_info pnginfo;
+ if (mng_info.m_mng_frame == 0)
+ {
+ std::string text1 = std::string(emulator_info::get_appname()).append(" ").append(emulator_info::get_build_version());
+ std::string text2 = std::string(machine().system().manufacturer).append(" ").append(machine().system().type.fullname());
+ pnginfo.add_text("Software", text1.c_str());
+ pnginfo.add_text("System", text2.c_str());
+ }
- // write the next frame
- screen_device *screen = machine().first_screen();
- const rgb_t *palette = (screen != nullptr && screen->has_palette()) ? screen->palette().palette()->entry_list_adjusted() : nullptr;
- int entries = (screen != nullptr && screen->has_palette()) ? screen->palette().entries() : 0;
- png_error error = mng_capture_frame(*m_mng_file, pnginfo, m_snap_bitmap, entries, palette);
- if (error != PNGERR_NONE)
- {
- g_profiler.stop();
- end_recording(MF_MNG);
- break;
+ // write the next frame
+ screen_device *screen = iter.current();
+ const rgb_t *palette = (screen != nullptr && screen->has_palette()) ? screen->palette().palette()->entry_list_adjusted() : nullptr;
+ int entries = (screen != nullptr && screen->has_palette()) ? screen->palette().entries() : 0;
+ png_error error = mng_capture_frame(*mng_info.m_mng_file, pnginfo, m_snap_bitmap, entries, palette);
+ if (error != PNGERR_NONE)
+ {
+ g_profiler.stop();
+ end_recording_mng(index);
+ break;
+ }
+
+ // advance time
+ mng_info.m_mng_next_frame_time += mng_info.m_mng_frame_period;
+ mng_info.m_mng_frame++;
}
+ }
- // advance time
- m_mng_next_frame_time += m_mng_frame_period;
- m_mng_frame++;
+ if (!m_snap_native)
+ {
+ break;
}
}
@@ -1338,16 +1497,52 @@ void video_manager::toggle_throttle()
// toggle_record_movie
//-------------------------------------------------
-void video_manager::toggle_record_movie()
+void video_manager::toggle_record_movie(movie_format format)
{
if (!is_recording())
{
- begin_recording(nullptr, MF_MNG);
- machine().popmessage("REC START");
+ begin_recording(nullptr, format);
+ machine().popmessage("REC START (%s)", format == MF_MNG ? "MNG" : "AVI");
}
else
{
- end_recording(MF_MNG);
- machine().popmessage("REC STOP");
+ end_recording(format);
+ machine().popmessage("REC STOP (%s)", format == MF_MNG ? "MNG" : "AVI");
+ }
+}
+
+void video_manager::end_recording(movie_format format)
+{
+ screen_device_iterator device_iterator = screen_device_iterator(machine().root_device());
+ screen_device_iterator::auto_iterator iter = device_iterator.begin();
+ const uint32_t count = (uint32_t)device_iterator.count();
+
+ switch (format)
+ {
+ case MF_AVI:
+ for (uint32_t index = 0; index < count; index++, iter++)
+ {
+ end_recording_avi(index);
+ if (!m_snap_native)
+ {
+ break;
+ }
+ }
+ break;
+
+ case MF_MNG:
+ for (uint32_t index = 0; index < count; index++, iter++)
+ {
+ end_recording_mng(index);
+ if (!m_snap_native)
+ {
+ break;
+ }
+ }
+ break;
+
+ default:
+ osd_printf_error("Unknown movie format: %d\n", format);
+ break;
}
}
diff --git a/src/emu/video.h b/src/emu/video.h
index 7e19de3c5ab..ac8de0064cd 100644
--- a/src/emu/video.h
+++ b/src/emu/video.h
@@ -59,7 +59,7 @@ public:
bool throttled() const { return m_throttled; }
float throttle_rate() const { return m_throttle_rate; }
bool fastforward() const { return m_fastforward; }
- bool is_recording() const { return (m_mng_file || m_avi_file); }
+ bool is_recording() const;
// setters
void set_frameskip(int frameskip);
@@ -70,8 +70,10 @@ public:
// misc
void toggle_throttle();
- void toggle_record_movie();
- osd_file::error open_next(emu_file &file, const char *extension);
+ void toggle_record_movie(movie_format format);
+ void toggle_record_mng() { toggle_record_movie(MF_MNG); }
+ void toggle_record_avi() { toggle_record_movie(MF_AVI); }
+ osd_file::error open_next(emu_file &file, const char *extension, uint32_t index = 0);
// render a frame
void frame_update(bool from_debugger = false);
@@ -87,8 +89,13 @@ public:
// movies
void begin_recording(const char *name, movie_format format);
+ void begin_recording_mng(const char *name, uint32_t index, screen_device *screen);
+ void begin_recording_avi(const char *name, uint32_t index, screen_device *screen);
void end_recording(movie_format format);
+ void end_recording_mng(uint32_t index);
+ void end_recording_avi(uint32_t index);
void add_sound_to_recording(const s16 *sound, int numsamples);
+ void add_sound_to_avi_recording(const s16 *sound, int numsamples, uint32_t index);
void set_timecode_enabled(bool value) { m_timecode_enabled = value; }
bool get_timecode_enabled() { return m_timecode_enabled; }
@@ -173,16 +180,37 @@ private:
s32 m_snap_height; // height of snapshots (0 == auto)
// movie recording - MNG
- std::unique_ptr<emu_file> m_mng_file; // handle to the open movie file
- attotime m_mng_frame_period; // period of a single movie frame
- attotime m_mng_next_frame_time; // time of next frame
- u32 m_mng_frame; // current movie frame number
+ class mng_info_t
+ {
+ public:
+ mng_info_t()
+ : m_mng_frame_period(attotime::zero)
+ , m_mng_next_frame_time(attotime::zero)
+ , m_mng_frame(0) { }
+
+ std::unique_ptr<emu_file> m_mng_file; // handle to the open movie file
+ attotime m_mng_frame_period; // period of a single movie frame
+ attotime m_mng_next_frame_time; // time of next frame
+ u32 m_mng_frame; // current movie frame number
+ };
+ mng_info_t m_mngs[9];
// movie recording - AVI
- avi_file::ptr m_avi_file; // handle to the open movie file
- attotime m_avi_frame_period; // period of a single movie frame
- attotime m_avi_next_frame_time; // time of next frame
- u32 m_avi_frame; // current movie frame number
+ class avi_info_t
+ {
+ public:
+ avi_info_t()
+ : m_avi_file(nullptr)
+ , m_avi_frame_period(attotime::zero)
+ , m_avi_next_frame_time(attotime::zero)
+ , m_avi_frame(0) { }
+
+ avi_file::ptr m_avi_file; // handle to the open movie file
+ attotime m_avi_frame_period; // period of a single movie frame
+ attotime m_avi_next_frame_time; // time of next frame
+ u32 m_avi_frame; // current movie frame number
+ };
+ avi_info_t m_avis[9];
static const bool s_skiptable[FRAMESKIP_LEVELS][FRAMESKIP_LEVELS];
diff --git a/src/frontend/mame/ui/cheatopt.cpp b/src/frontend/mame/ui/cheatopt.cpp
index 0e911aa0972..3982a7c7a33 100644
--- a/src/frontend/mame/ui/cheatopt.cpp
+++ b/src/frontend/mame/ui/cheatopt.cpp
@@ -176,7 +176,7 @@ menu_cheat::~menu_cheat()
menu_autofire::menu_autofire(mame_ui_manager &mui, render_container &container) : menu(mui, container), last_toggle(false)
{
- const screen_device *screen = mui.machine().first_screen();
+ const screen_device *screen = screen_device_iterator(mui.machine().root_device()).first();
if (screen == nullptr)
{
diff --git a/src/frontend/mame/ui/ui.cpp b/src/frontend/mame/ui/ui.cpp
index df5089cb1c0..9fe360d3891 100644
--- a/src/frontend/mame/ui/ui.cpp
+++ b/src/frontend/mame/ui/ui.cpp
@@ -1213,9 +1213,13 @@ uint32_t mame_ui_manager::handler_ingame(render_container &container)
if (machine().ui_input().pressed(IPT_UI_TOGGLE_CHEAT))
mame_machine_manager::instance()->cheat().set_enable(!mame_machine_manager::instance()->cheat().enabled());
- // toggle movie recording
- if (machine().ui_input().pressed(IPT_UI_RECORD_MOVIE))
- machine().video().toggle_record_movie();
+ // toggle MNG recording
+ if (machine().ui_input().pressed(IPT_UI_RECORD_MNG))
+ machine().video().toggle_record_mng();
+
+ // toggle MNG recording
+ if (machine().ui_input().pressed(IPT_UI_RECORD_AVI))
+ machine().video().toggle_record_avi();
// toggle profiler display
if (machine().ui_input().pressed(IPT_UI_SHOW_PROFILER))
@@ -1676,9 +1680,10 @@ int32_t mame_ui_manager::slider_refresh(running_machine &machine, void *arg, int
const rectangle &visarea = screen->visible_area();
screen->configure(width, height, visarea, HZ_TO_ATTOSECONDS(defrefresh + (double)newval * 0.001));
}
+
if (str)
- *str = string_format(_("%1$.3ffps"), ATTOSECONDS_TO_HZ(machine.first_screen()->frame_period().attoseconds()));
- refresh = ATTOSECONDS_TO_HZ(machine.first_screen()->frame_period().attoseconds());
+ *str = string_format(_("%1$.3ffps"), ATTOSECONDS_TO_HZ(screen->frame_period().attoseconds()));
+ refresh = ATTOSECONDS_TO_HZ(screen->frame_period().attoseconds());
return floor((refresh - defrefresh) * 1000.0 + 0.5);
}
diff --git a/src/frontend/mame/ui/viewgfx.cpp b/src/frontend/mame/ui/viewgfx.cpp
index 560dc30d0f9..0625caa1ada 100644
--- a/src/frontend/mame/ui/viewgfx.cpp
+++ b/src/frontend/mame/ui/viewgfx.cpp
@@ -1320,7 +1320,11 @@ static void tilemap_update_bitmap(running_machine &machine, ui_gfx_state &state,
{
state.bitmap->fill(0);
tilemap_t *tilemap = machine.tilemap().find(state.tilemap.which);
- tilemap->draw_debug(*machine.first_screen(), *state.bitmap, state.tilemap.xoffs, state.tilemap.yoffs, state.tilemap.flags);
+ screen_device *first_screen = screen_device_iterator(machine.root_device()).first();
+ if (first_screen)
+ {
+ tilemap->draw_debug(*first_screen, *state.bitmap, state.tilemap.xoffs, state.tilemap.yoffs, state.tilemap.flags);
+ }
// reset the texture to force an update
state.texture->set_bitmap(*state.bitmap, state.bitmap->cliprect(), TEXFORMAT_RGB32);
diff --git a/src/osd/modules/input/input_windows.cpp b/src/osd/modules/input/input_windows.cpp
index 91c546baf4a..164ee0e3c31 100644
--- a/src/osd/modules/input/input_windows.cpp
+++ b/src/osd/modules/input/input_windows.cpp
@@ -137,8 +137,13 @@ void windows_osd_interface::customize_input_type_list(simple_list<input_type_ent
break;
// add a NOT-lalt to our default shift-F12
- case IPT_UI_RECORD_MOVIE: // emu/input.c: input_seq(KEYCODE_F12, KEYCODE_LSHIFT)
- entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F12, KEYCODE_LSHIFT, input_seq::not_code, KEYCODE_LALT);
+ case IPT_UI_RECORD_MNG: // emu/input.c: input_seq(KEYCODE_F12, KEYCODE_LSHIFT, input_seq::not_code, KEYCODE_LCONTROL)
+ entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F12, KEYCODE_LSHIFT, input_seq::not_code, KEYCODE_LCONTROL, input_seq::not_code, KEYCODE_LALT);
+ break;
+
+ // add a NOT-lalt to our default shift-ctrl-F12
+ case IPT_UI_RECORD_AVI: // emu/input.c: input_seq(KEYCODE_F12, KEYCODE_LSHIFT, KEYCODE_LCONTROL)
+ entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F12, KEYCODE_LSHIFT, KEYCODE_LCONTROL, input_seq::not_code, KEYCODE_LALT);
break;
// add a NOT-lalt to write timecode file