diff options
Diffstat (limited to 'src/emu/ioport.cpp')
-rw-r--r-- | src/emu/ioport.cpp | 218 |
1 files changed, 215 insertions, 3 deletions
diff --git a/src/emu/ioport.cpp b/src/emu/ioport.cpp index 282cc5c256c..a898a10051b 100644 --- a/src/emu/ioport.cpp +++ b/src/emu/ioport.cpp @@ -1699,6 +1699,7 @@ void ioport_field::get_user_settings(user_settings &settings) else { settings.toggle = m_live->toggle; + settings.autofire = m_live->autofire; } } @@ -1737,6 +1738,7 @@ void ioport_field::set_user_settings(const user_settings &settings) else { m_live->toggle = settings.toggle; + m_live->autofire = settings.autofire; } } @@ -1904,6 +1906,19 @@ void ioport_field::frame_update(ioport_value &result, bool mouse_down) // if the state changed, look for switch down/switch up bool curstate = mouse_down || machine().input().seq_pressed(seq()) || m_digital_value; + if (m_live->autofire && !machine().ioport().get_autofire_toggle()) + { + if (curstate) + { + if (m_live->autopressed > machine().ioport().get_autofire_delay()) + m_live->autopressed = 0; + else if (m_live->autopressed > machine().ioport().get_autofire_delay() / 2) + curstate = false; + m_live->autopressed++; + } + else + m_live->autopressed = 0; + } bool changed = false; if (curstate != m_live->last) { @@ -2156,7 +2171,9 @@ ioport_field_live::ioport_field_live(ioport_field &field, analog_field *analog) impulse(0), last(0), toggle(field.toggle()), - joydir(digital_joystick::JOYDIR_COUNT) + joydir(digital_joystick::JOYDIR_COUNT), + autofire(false), + autopressed(0) { // fill in the basic values for (input_seq_type seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype) @@ -2454,10 +2471,15 @@ ioport_manager::ioport_manager(running_machine &machine) m_playback_file(machine.options().input_directory(), OPEN_FLAG_READ), m_playback_accumulated_speed(0), m_playback_accumulated_frames(0), + m_timecode_file(machine.options().input_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS), + m_timecode_count(0), + m_timecode_last_time(attotime::zero), m_has_configs(false), m_has_analog(false), m_has_dips(false), - m_has_bioses(false) + m_has_bioses(false), + m_autofire_toggle(false), + m_autofire_delay(3) // 1 seems too fast for a bunch of games { memset(m_type_to_entry, 0, sizeof(m_type_to_entry)); } @@ -2564,6 +2586,7 @@ time_t ioport_manager::initialize() // open playback and record files if specified time_t basetime = playback_init(); record_init(); + timecode_init(); return basetime; } @@ -2657,6 +2680,7 @@ void ioport_manager::exit() // close any playback or recording files playback_end(); record_end(); + timecode_end(); } @@ -3400,7 +3424,7 @@ time_t ioport_manager::playback_init() // verify the header against the current game if (memcmp(machine().system().name, header + 0x14, strlen(machine().system().name) + 1) != 0) - osd_printf_info("Input file is for %s '%s', not for current %s '%s'\n", emulator_info::get_gamenoun(), header + 0x14, emulator_info::get_gamenoun(), machine().system().name); + osd_printf_info("Input file is for machine '%s', not for current machine '%s'\n", header + 0x14, machine().system().name); // enable compression m_playback_file.compress(FCOMPRESS_MEDIUM); @@ -3428,6 +3452,12 @@ void ioport_manager::playback_end(const char *message) m_playback_accumulated_speed /= m_playback_accumulated_frames; osd_printf_info("Total playback frames: %d\n", UINT32(m_playback_accumulated_frames)); osd_printf_info("Average recorded speed: %d%%\n", UINT32((m_playback_accumulated_speed * 200 + 1) >> 21)); + + // close the program at the end of inp file playback + if (machine().options().exit_after_playback()) { + osd_printf_info("Exiting MAME now...\n"); + machine().schedule_exit(); + } } } @@ -3510,6 +3540,29 @@ void ioport_manager::record_write<bool>(bool value) record_write(byte); } +template<typename _Type> +void ioport_manager::timecode_write(_Type value) +{ + // protect against NULL handles if previous reads fail + if (!m_timecode_file.is_open()) + return; + + // read the value; if we fail, end playback + if (m_timecode_file.write(&value, sizeof(value)) != sizeof(value)) + timecode_end("Out of space"); +} + +/*template<> +void ioport_manager::timecode_write<bool>(bool value) +{ + UINT8 byte = UINT8(value); + timecode_write(byte); +}*/ +template<> +void ioport_manager::timecode_write<std::string>(std::string value) { + timecode_write(value.c_str()); +} + //------------------------------------------------- // record_init - initialize INP recording @@ -3554,6 +3607,44 @@ void ioport_manager::record_init() } +void ioport_manager::timecode_init() { + // check if option -record_timecode is enabled + if (!machine().options().record_timecode()) { + machine().video().set_timecode_enabled(false); + return; + } + // if no file, nothing to do + const char *record_filename = machine().options().record(); + if (record_filename[0] == 0) { + machine().video().set_timecode_enabled(false); + return; + } + + machine().video().set_timecode_enabled(true); + + // open the record file + std::string filename; + filename.append(record_filename).append(".timecode"); + osd_printf_info("Record input timecode file: %s\n", record_filename); + + file_error filerr = m_timecode_file.open(filename.c_str()); + assert_always(filerr == FILERR_NONE, "Failed to open file for input timecode recording"); + + m_timecode_file.puts(std::string("# ==========================================\n").c_str()); + m_timecode_file.puts(std::string("# TIMECODE FILE FOR VIDEO PREVIEW GENERATION\n").c_str()); + m_timecode_file.puts(std::string("# ==========================================\n").c_str()); + m_timecode_file.puts(std::string("#\n").c_str()); + m_timecode_file.puts(std::string("# VIDEO_PART: code of video timecode\n").c_str()); + m_timecode_file.puts(std::string("# START: start time (hh:mm:ss.mmm)\n").c_str()); + m_timecode_file.puts(std::string("# ELAPSED: elapsed time (hh:mm:ss.mmm)\n").c_str()); + m_timecode_file.puts(std::string("# MSEC_START: start time (milliseconds)\n").c_str()); + m_timecode_file.puts(std::string("# MSEC_ELAPSED: elapsed time (milliseconds)\n").c_str()); + m_timecode_file.puts(std::string("# FRAME_START: start time (frames)\n").c_str()); + m_timecode_file.puts(std::string("# FRAME_ELAPSED: elapsed time (frames)\n").c_str()); + m_timecode_file.puts(std::string("#\n").c_str()); + m_timecode_file.puts(std::string("# VIDEO_PART======= START======= ELAPSED===== MSEC_START===== MSEC_ELAPSED=== FRAME_START==== FRAME_ELAPSED==\n").c_str()); +} + //------------------------------------------------- // record_end - end INP recording //------------------------------------------------- @@ -3573,6 +3664,19 @@ void ioport_manager::record_end(const char *message) } +void ioport_manager::timecode_end(const char *message) +{ + // only applies if we have a live file + if (m_timecode_file.is_open()) { + // close the file + m_timecode_file.close(); + + // pop a message + if (message != nullptr) + machine().popmessage("Recording Timecode Ended\nReason: %s", message); + } +} + //------------------------------------------------- // record_frame - start of frame callback for // recording @@ -3590,6 +3694,114 @@ void ioport_manager::record_frame(const attotime &curtime) // then the current speed record_write(UINT32(machine().video().speed_percent() * double(1 << 20))); } + + if (m_timecode_file.is_open() && machine().video().get_timecode_write()) { + // Display the timecode + std::string current_time_str; + m_timecode_count++; + strcatprintf(current_time_str, "%02d:%02d:%02d.%03d", + (int)curtime.seconds() / (60 * 60), + (curtime.seconds() / 60) % 60, + curtime.seconds() % 60, + (int)(curtime.attoseconds()/ATTOSECONDS_PER_MILLISECOND)); + + // Elapsed from previous timecode + attotime elapsed_time = curtime - m_timecode_last_time; + m_timecode_last_time = curtime; + std::string elapsed_time_str; + strcatprintf(elapsed_time_str, "%02d:%02d:%02d.%03d", + elapsed_time.seconds() / (60 * 60), + (elapsed_time.seconds() / 60) % 60, + elapsed_time.seconds() % 60, + int(elapsed_time.attoseconds()/ATTOSECONDS_PER_MILLISECOND)); + + // Number of ms from beginning of playback + int mseconds_start = curtime.seconds()*1000 + curtime.attoseconds()/ATTOSECONDS_PER_MILLISECOND; + std::string mseconds_start_str; + strcatprintf(mseconds_start_str, "%015d", mseconds_start); + + // Number of ms from previous timecode + int mseconds_elapsed = elapsed_time.seconds()*1000 + elapsed_time.attoseconds()/ATTOSECONDS_PER_MILLISECOND; + std::string mseconds_elapsed_str; + strcatprintf(mseconds_elapsed_str, "%015d", mseconds_elapsed); + + // Number of frames from beginning of playback + int frame_start = mseconds_start * 60 / 1000; + std::string frame_start_str; + strcatprintf(frame_start_str, "%015d", frame_start); + + // Number of frames from previous timecode + int frame_elapsed = mseconds_elapsed * 60 / 1000; + std::string frame_elapsed_str; + strcatprintf(frame_elapsed_str, "%015d", frame_elapsed); + + std::string message; + std::string timecode_text; + std::string timecode_key; + bool show_timecode_counter = false; + if (m_timecode_count==1) { + message += "TIMECODE: Intro started at " + current_time_str; + timecode_key = "INTRO_START"; + timecode_text = "INTRO"; + show_timecode_counter = true; + } + else if (m_timecode_count==2) { + message += "TIMECODE: Intro duration " + elapsed_time_str; + timecode_key = "INTRO_STOP"; + machine().video().add_to_total_time(elapsed_time); + //timecode_text += "INTRO"; + } + else if (m_timecode_count==3) { + message += "TIMECODE: Gameplay started at " + current_time_str; + timecode_key = "GAMEPLAY_START"; + timecode_text += "GAMEPLAY"; + show_timecode_counter = true; + } + else if (m_timecode_count==4) { + message += "TIMECODE: Gameplay duration " + elapsed_time_str; + timecode_key = "GAMEPLAY_STOP"; + machine().video().add_to_total_time(elapsed_time); + //timecode_text += "GAMEPLAY"; + } + else if (m_timecode_count % 2 == 1) { + std::string timecode_count_str; + strcatprintf(timecode_count_str, "%03d", (m_timecode_count-3)/2); + timecode_key = "EXTRA_START_" + timecode_count_str; + timecode_count_str.clear(); + strcatprintf(timecode_count_str, "%d", (m_timecode_count-3)/2); + message += "TIMECODE: Extra " + timecode_count_str + " started at " + current_time_str; + timecode_text += "EXTRA " + timecode_count_str; + show_timecode_counter = true; + } + else { + machine().video().add_to_total_time(elapsed_time); + + std::string timecode_count_str; + strcatprintf(timecode_count_str, "%d", (m_timecode_count-4)/2); + message += "TIMECODE: Extra " + timecode_count_str + " duration " + elapsed_time_str; + + timecode_count_str.clear(); + strcatprintf(timecode_count_str, "%03d", (m_timecode_count-4)/2); + timecode_key = "EXTRA_STOP_" + timecode_count_str; + } + + osd_printf_info("%s \n", message.c_str()); + machine().popmessage("%s \n", message.c_str()); + + std::string line_to_add; + line_to_add.append(timecode_key).append(19-timecode_key.length(), ' '); + line_to_add += + " " + current_time_str + " " + elapsed_time_str + + " " + mseconds_start_str + " " + mseconds_elapsed_str + + " " + frame_start_str + " " + frame_elapsed_str + + "\n"; + m_timecode_file.puts(line_to_add.c_str()); + + machine().video().set_timecode_write(false); + machine().video().set_timecode_text(timecode_text); + machine().video().set_timecode_start(m_timecode_last_time); + machine().ui().set_show_timecode_counter(show_timecode_counter); + } } |