/*------------------------------------------------- * menu_main constructor/destructor * -------------------------------------------------*/ public menu_main(mame_ui_manager mui, render_container container) : base(mui, container) { m_phase = machine_phase.PREINIT; set_needs_prev_menu_item(false); }
string m_string_buffer; //mutable util::ovectorstream m_string_buffer; // construction/destruction //------------------------------------------------- // running_machine - constructor //------------------------------------------------- public running_machine(machine_config _config, machine_manager manager) { m_side_effects_disabled = 0; debug_flags = 0; m_config = _config; m_system = _config.gamedrv(); m_manager = manager; m_current_phase = machine_phase.PREINIT; m_paused = false; m_hard_reset_pending = false; m_exit_pending = false; m_soft_reset_timer = null; m_rand_seed = 0x9d14abd7; m_ui_active = _config.options().ui_active(); m_basename = _config.gamedrv().name; m_sample_rate = _config.options().sample_rate(); m_saveload_schedule = saveload_schedule.NONE; m_saveload_schedule_time = attotime.zero; m_saveload_searchpath = null; m_save = new save_manager(this); m_memory = new memory_manager(this); m_ioport = new ioport_manager(this); m_scheduler = new device_scheduler(this); m_scheduler.device_scheduler_after_ctor(this); for (int i = 0; i < m_notifier_list.Length; i++) { m_notifier_list[i] = new std.list <notifier_callback_item>(); } m_base_time = 0; // set the machine on all devices device_enumerator iter = new device_enumerator(root_device()); foreach (device_t device in iter) { device.set_machine(this); } // fetch core options if (options().debug()) { debug_flags = (DEBUG_FLAG_ENABLED | DEBUG_FLAG_CALL_HOOK) | (DEBUG_FLAG_OSD_ENABLED); } }
//void compute_snapshot_size(s32 &width, s32 &height); //void pixels(u32 *buffer); // render a frame //------------------------------------------------- // frame_update - handle frameskipping and UI, // plus updating the screen during normal // operations //------------------------------------------------- public void frame_update(bool from_debugger = false) { m_frame_update_counter++; // only render sound and video if we're in the running phase machine_phase phase = machine().phase(); bool skipped_it = m_skipping_this_frame; if (phase == machine_phase.RUNNING && (!machine().paused() || machine().options().update_in_pause())) { bool anything_changed = finish_screen_updates(); // if none of the screens changed and we haven't skipped too many frames in a row, // mark this frame as skipped to prevent throttling; this helps for games that // don't update their screen at the monitor refresh rate if (!anything_changed && !m_auto_frameskip && m_frameskip_level == 0 && m_empty_skip_count++ < 3) { skipped_it = true; } else { m_empty_skip_count = 0; } } // draw the user interface emulator_info.draw_user_interface(machine()); // if we're throttling, synchronize before rendering attotime current_time = machine().time(); if (!from_debugger && !skipped_it && phase > machine_phase.INIT && !m_low_latency && effective_throttle()) { update_throttle(current_time); } // ask the OSD to update g_profiler.start(profile_type.PROFILER_BLIT); machine().osd().update(!from_debugger && skipped_it); g_profiler.stop(); // we synchronize after rendering instead of before, if low latency mode is enabled if (!from_debugger && !skipped_it && phase > machine_phase.INIT && m_low_latency && effective_throttle()) { update_throttle(current_time); } // get most recent input now machine().osd().input_update(); emulator_info.periodic_check(); if (!from_debugger) { // perform tasks for this frame machine().call_notifiers(machine_notification.MACHINE_NOTIFY_FRAME); // update frameskipping if (phase > machine_phase.INIT) { update_frameskip(); } // update speed computations if (!skipped_it && phase > machine_phase.INIT) { recompute_speed(current_time); } } // call the end-of-frame callback if (phase == machine_phase.RUNNING) { // reset partial updates if we're paused or if the debugger is active screen_device screen = new screen_device_enumerator(machine().root_device()).first(); bool debugger_enabled = (machine().debug_flags & DEBUG_FLAG_ENABLED) != 0; bool within_instruction_hook = debugger_enabled && machine().debugger().within_instruction_hook(); if (screen != null && ((machine().paused() && machine().options().update_in_pause()) || from_debugger || within_instruction_hook)) { screen.reset_partial_updates(); } } }
// fetch items by name //template <class DeviceClass> [[deprecated("absolute tag lookup; use subdevice or finder instead")]] inline DeviceClass *device(const char *tag) { return downcast<DeviceClass *>(root_device().subdevice(tag)); } // immediate operations //------------------------------------------------- // run - execute the machine //------------------------------------------------- public int run(bool quiet) { int error = EMU_ERR_NONE; // use try/catch for deep error recovery try { m_manager.http().clear(); // move to the init phase m_current_phase = machine_phase.INIT; // if we have a logfile, set up the callback if (options().log() && !quiet) { m_logfile = new emu_file(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); std.error_condition filerr = m_logfile.open("error.log"); if (filerr) { throw new emu_fatalerror("running_machine::run: unable to open error.log file"); } //using namespace std::placeholders; add_logerror_callback(logfile_callback); } if (options().debug() && options().debuglog()) { m_debuglogfile = new emu_file(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); std.error_condition filerr = m_debuglogfile.open("debug.log"); if (filerr) { throw new emu_fatalerror("running_machine::run: unable to open debug.log file"); } } // then finish setting up our local machine start(); // load the configuration settings manager().before_load_settings(this); m_configuration.load_settings(); // disallow save state registrations starting here. // Don't do it earlier, config load can create network // devices with timers. m_save.allow_registration(false); // load the NVRAM nvram_load(); // set the time on RTCs (this may overwrite parts of NVRAM) set_rtc_datetime(new system_time(m_base_time)); sound().ui_mute(false); if (!quiet) { sound().start_recording(); } m_hard_reset_pending = false; // initialize ui lists // display the startup screens manager().ui_initialize(this); // perform a soft reset -- this takes us to the running phase soft_reset(); // handle initial load if (m_saveload_schedule != saveload_schedule.NONE) { handle_saveload(); } export_http_api(); #if EMSCRIPTEN // break out to our async javascript loop and halt emscripten_set_running_machine(this); #endif // run the CPUs until a reset or exit while ((!m_hard_reset_pending && !m_exit_pending) || m_saveload_schedule != saveload_schedule.NONE) { g_profiler.start(profile_type.PROFILER_EXTRA); // execute CPUs if not paused if (!m_paused) { m_scheduler.timeslice(); } // otherwise, just pump video updates through else { m_video.frame_update(); } // handle save/load if (m_saveload_schedule != saveload_schedule.NONE) { handle_saveload(); } g_profiler.stop(); } m_manager.http().clear(); // and out via the exit phase m_current_phase = machine_phase.EXIT; // save the NVRAM and configuration sound().ui_mute(true); if (options().nvram_save()) { nvram_save(); } m_configuration.save_settings(); } #if false catch (emu_fatalerror fatal) { osd_printf_error("Fatal error: %s\n", fatal.what()); error = EMU_ERR_FATALERROR; if (fatal.exitcode() != 0) { error = fatal.exitcode(); } } catch (emu_exception) { osd_printf_error("Caught unhandled emulator exception\n"); error = machine_manager.MAMERR.MAMERR_FATALERROR; } catch (binding_type_exception)// btex) { osd_printf_error("Error performing a late bind of function expecting type %s to instance of type %s\n", btex.target_type().name(), btex.actual_type().name()); error = machine_manager.MAMERR.MAMERR_FATALERROR; } catch (tag_add_exception&aex) { osd_printf_error("Tag '%s' already exists in tagged map\n", aex.tag()); error = EMU_ERR_FATALERROR; }
/*------------------------------------------------- * populate - populate main menu items * -------------------------------------------------*/ protected override void populate(ref float customtop, ref float custombottom) { m_phase = machine().phase(); item_append(__("Input (general)"), 0, INPUT_GROUPS); item_append(__("Input (this Machine)"), 0, INPUT_SPECIFIC); if (ui().machine_info().has_analog()) { item_append(__("Analog Controls"), 0, ANALOG); } if (ui().machine_info().has_dips()) { item_append(__("DIP Switches"), 0, SETTINGS_DIP_SWITCHES); } if (ui().machine_info().has_configs()) { item_append(__("Machine Configuration"), 0, SETTINGS_DRIVER_CONFIG); } item_append(__("Bookkeeping Info"), 0, BOOKKEEPING); item_append(__("Machine Information"), 0, GAME_INFO); if (ui().found_machine_warnings()) { item_append(__("Warning Information"), 0, WARN_INFO); } foreach (device_image_interface image in new image_interface_enumerator(machine().root_device())) { if (image.user_loadable()) { item_append(__("Image Information"), 0, IMAGE_MENU_IMAGE_INFO); item_append(__("File Manager"), 0, IMAGE_MENU_FILE_MANAGER); break; } } //throw new emu_unimplemented(); #if false if (cassette_device_enumerator(machine().root_device()).first() != nullptr) { item_append(_("Tape Control"), 0, (void *)TAPE_CONTROL); } if (pty_interface_enumerator(machine().root_device()).first() != nullptr) { item_append(_("Pseudo terminals"), 0, (void *)PTY_INFO); } #endif if (ui().machine_info().has_bioses()) { item_append(__("BIOS Selection"), 0, BIOS_SELECTION); } //throw new emu_unimplemented(); #if false if (slot_interface_enumerator(machine().root_device()).first() != nullptr) { item_append(_("Slot Devices"), 0, (void *)SLOT_DEVICES); } if (barcode_reader_device_enumerator(machine().root_device()).first() != nullptr) { item_append(_("Barcode Reader"), 0, (void *)BARCODE_READ); } if (network_interface_enumerator(machine().root_device()).first() != nullptr) { item_append(_("Network Devices"), 0, (void *)NETWORK_DEVICES); } if (machine().natkeyboard().keyboard_count()) { item_append(_("Keyboard Mode"), 0, (void *)KEYBOARD_MODE); } #endif item_append(__("Slider Controls"), 0, SLIDERS); item_append(__("Video Options"), 0, VIDEO_TARGETS); //throw new emu_unimplemented(); #if false if (machine().crosshair().get_usage()) { item_append(_("Crosshair Options"), 0, (void *)CROSSHAIR); } if (machine().options().cheat()) { item_append(_("Cheat"), 0, (void *)CHEAT); } if (machine_phase::RESET <= m_phase) { if (machine().options().plugins() && !mame_machine_manager::instance()->lua()->get_menu().empty()) { item_append(_("Plugin Options"), 0, (void *)PLUGINS); } if (mame_machine_manager::instance()->lua()->call_plugin_check <const char *>("data_list", "", true)) { item_append(_("External DAT View"), 0, (void *)EXTERNAL_DATS); } } item_append(menu_item_type::SEPARATOR); if (!mame_machine_manager::instance()->favorite().is_favorite(machine())) { item_append(_("Add To Favorites"), 0, (void *)ADD_FAVORITE); } else { item_append(_("Remove From Favorites"), 0, (void *)REMOVE_FAVORITE); } #endif item_append(menu_item_type.SEPARATOR); item_append(util.string_format(__("About {0}"), emulator_info.get_appname()), 0, ABOUT); item_append(menu_item_type.SEPARATOR); // item_append(_("Quit from Machine"), 0, (void *)QUIT_GAME); if (machine_phase.INIT == m_phase) { item_append(__("Start Machine"), 0, DISMISS); } else { item_append(__("Select New Machine"), 0, SELECT_GAME); item_append(__("Return to Machine"), 0, DISMISS); } }