int running_machine::run(bool firstrun) { int error = MAMERR_NONE; // use try/catch for deep error recovery try { // move to the init phase m_current_phase = MACHINE_PHASE_INIT; // if we have a logfile, set up the callback if (options_get_bool(&m_options, OPTION_LOG)) { file_error filerr = mame_fopen(SEARCHPATH_DEBUGLOG, "error.log", OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS, &m_logfile); assert_always(filerr == FILERR_NONE, "unable to open log file"); add_logerror_callback(logfile_callback); } // then finish setting up our local machine start(); // load the configuration settings and NVRAM bool settingsloaded = config_load_settings(this); nvram_load(this); sound_mute(this, FALSE); // display the startup screens ui_display_startup_screens(this, firstrun, !settingsloaded); // perform a soft reset -- this takes us to the running phase soft_reset(); // run the CPUs until a reset or exit m_hard_reset_pending = false; while ((!m_hard_reset_pending && !m_exit_pending) || m_saveload_schedule != SLS_NONE) { profiler_mark_start(PROFILER_EXTRA); // execute CPUs if not paused if (!m_paused) m_scheduler.timeslice(); // otherwise, just pump video updates through else video_frame_update(this, false); // handle save/load if (m_saveload_schedule != SLS_NONE) handle_saveload(); profiler_mark_end(); } // and out via the exit phase m_current_phase = MACHINE_PHASE_EXIT; // save the NVRAM and configuration sound_mute(this, true); nvram_save(this); config_save_settings(this); } catch (emu_fatalerror &fatal) { mame_printf_error("%s\n", fatal.string()); error = MAMERR_FATALERROR; if (fatal.exitcode() != 0) error = fatal.exitcode(); } catch (emu_exception &) { mame_printf_error("Caught unhandled emulator exception\n"); error = MAMERR_FATALERROR; } catch (std::bad_alloc &) { mame_printf_error("Out of memory!\n"); error = MAMERR_FATALERROR; } // call all exit callbacks registered call_notifiers(MACHINE_NOTIFY_EXIT); // close the logfile if (m_logfile != NULL) mame_fclose(m_logfile); return error; }
int run_game(int game) { running_machine *machine; int error = MAMERR_NONE; mame_private *mame; callback_item *cb; /* create the machine structure and driver */ machine = create_machine(game); mame = machine->mame_data; /* looooong term: remove this */ Machine = machine; /* start in the "pre-init phase" */ mame->current_phase = MAME_PHASE_PREINIT; /* perform validity checks before anything else */ if (mame_validitychecks(game) != 0) return MAMERR_FAILED_VALIDITY; /* loop across multiple hard resets */ mame->exit_pending = FALSE; while (error == 0 && !mame->exit_pending) { init_resource_tracking(); add_free_resources_callback(timer_free); add_free_resources_callback(state_save_free); /* use setjmp/longjmp for deep error recovery */ mame->fatal_error_jmpbuf_valid = TRUE; error = setjmp(mame->fatal_error_jmpbuf); if (error == 0) { int settingsloaded; /* move to the init phase */ mame->current_phase = MAME_PHASE_INIT; /* start tracking resources for real */ begin_resource_tracking(); /* if we have a logfile, set up the callback */ mame->logerror_callback_list = NULL; if (options.logfile) add_logerror_callback(machine, logfile_callback); /* then finish setting up our local machine */ init_machine(machine); /* load the configuration settings and NVRAM */ settingsloaded = config_load_settings(); nvram_load(); /* display the startup screens */ ui_display_startup_screens(!settingsloaded && !options.skip_disclaimer, !options.skip_warnings, !options.skip_gameinfo); /* ensure we don't show the opening screens on a reset */ options.skip_disclaimer = options.skip_warnings = options.skip_gameinfo = TRUE; /* start resource tracking; note that soft_reset assumes it can */ /* call end_resource_tracking followed by begin_resource_tracking */ /* to clear out resources allocated between resets */ begin_resource_tracking(); /* perform a soft reset -- this takes us to the running phase */ soft_reset(0); /* run the CPUs until a reset or exit */ mame->hard_reset_pending = FALSE; while ((!mame->hard_reset_pending && !mame->exit_pending) || mame->saveload_pending_file != NULL) { profiler_mark(PROFILER_EXTRA); /* execute CPUs if not paused */ if (!mame->paused) cpuexec_timeslice(); /* otherwise, just pump video updates through */ else video_frame_update(); /* handle save/load */ if (mame->saveload_schedule_callback) (*mame->saveload_schedule_callback)(machine); profiler_mark(PROFILER_END); } /* and out via the exit phase */ mame->current_phase = MAME_PHASE_EXIT; /* stop tracking resources at this level */ end_resource_tracking(); /* save the NVRAM and configuration */ nvram_save(); config_save_settings(); } mame->fatal_error_jmpbuf_valid = FALSE; /* call all exit callbacks registered */ for (cb = mame->exit_callback_list; cb; cb = cb->next) (*cb->func.exit)(machine); /* close all inner resource tracking */ exit_resource_tracking(); /* free our callback lists */ free_callback_list(&mame->exit_callback_list); free_callback_list(&mame->reset_callback_list); free_callback_list(&mame->pause_callback_list); } /* destroy the machine */ destroy_machine(machine); /* return an error */ return error; }
int running_machine::run(bool firstrun) { int error = MAMERR_NONE; // use try/catch for deep error recovery try { // move to the init phase m_current_phase = MACHINE_PHASE_INIT; // if we have a logfile, set up the callback if (options().log()) { m_logfile = auto_alloc(*this, emu_file(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS)); file_error filerr = m_logfile->open("error.log"); assert_always(filerr == FILERR_NONE, "unable to open log file"); add_logerror_callback(logfile_callback); } // then finish setting up our local machine start(); // load the configuration settings and NVRAM bool settingsloaded = config_load_settings(*this); nvram_load(*this); sound().ui_mute(false); // initialize ui lists ui_initialize(*this); // display the startup screens ui_display_startup_screens(*this, firstrun, !settingsloaded); // perform a soft reset -- this takes us to the running phase soft_reset(); // run the CPUs until a reset or exit m_hard_reset_pending = false; while ((!m_hard_reset_pending && !m_exit_pending) || m_saveload_schedule != SLS_NONE) { g_profiler.start(PROFILER_EXTRA); #ifdef SDLMAME_EMSCRIPTEN //break out to our async javascript loop and halt js_set_main_loop(m_scheduler); #endif // 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 != SLS_NONE) handle_saveload(); g_profiler.stop(); } // and out via the exit phase m_current_phase = MACHINE_PHASE_EXIT; // save the NVRAM and configuration sound().ui_mute(true); nvram_save(*this); config_save_settings(*this); } catch (emu_fatalerror &fatal) { mame_printf_error("%s\n", fatal.string()); error = MAMERR_FATALERROR; if (fatal.exitcode() != 0) error = fatal.exitcode(); } catch (emu_exception &) { mame_printf_error("Caught unhandled emulator exception\n"); error = MAMERR_FATALERROR; } catch (binding_type_exception &btex) { mame_printf_error("Error performing a late bind of type %s to %s\n", btex.m_actual_type.name(), btex.m_target_type.name()); error = MAMERR_FATALERROR; } catch (std::exception &ex) { mame_printf_error("Caught unhandled %s exception: %s\n", typeid(ex).name(), ex.what()); error = MAMERR_FATALERROR; } catch (...) { mame_printf_error("Caught unhandled exception\n"); error = MAMERR_FATALERROR; } // make sure our phase is set properly before cleaning up, // in case we got here via exception m_current_phase = MACHINE_PHASE_EXIT; // call all exit callbacks registered call_notifiers(MACHINE_NOTIFY_EXIT); zip_file_cache_clear(); // close the logfile auto_free(*this, m_logfile); return error; }
int running_machine::run(bool firstrun, bool benchmarking) { int error = MAMERR_NONE; // use try/catch for deep error recovery try { // move to the init phase m_current_phase = MACHINE_PHASE_INIT; // if we have a logfile, set up the callback if (options().log()) { m_logfile = auto_alloc(*this, emu_file(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS)); file_error filerr = m_logfile->open("error.log"); assert_always(filerr == FILERR_NONE, "unable to open log file"); add_logerror_callback(logfile_callback); } // then finish setting up our local machine start(); // load the configuration settings and NVRAM bool settingsloaded = config_load_settings(*this); nvram_load(*this); sound().ui_mute(false); // this point is chosen arbitrarily to be represented as 50% complete // with the "initializing state" init phase announce_init_phase(STARTUP_PHASE_INITIALIZING_STATE, 50); // display the startup screens, unless benchmarking, in which case // there is no user interaction expected and no need to show the // startup screens if (!benchmarking) { ui_display_startup_screens(*this, firstrun, !settingsloaded); } // perform a soft reset -- this takes us to the running phase soft_reset(); // now initialization is 100% complete and the next thing that will // happen is the game will start running announce_init_phase(STARTUP_PHASE_INITIALIZING_STATE, 100); // run the CPUs until a reset or exit m_hard_reset_pending = false; while ((!m_hard_reset_pending && !m_exit_pending) || m_saveload_schedule != SLS_NONE) { g_profiler.start(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 != SLS_NONE) handle_saveload(); g_profiler.stop(); } // and out via the exit phase m_current_phase = MACHINE_PHASE_EXIT; // save the NVRAM and configuration sound().ui_mute(true); nvram_save(*this); config_save_settings(*this); } catch (emu_fatalerror &fatal) { mame_printf_error("%s\n", fatal.string()); error = MAMERR_FATALERROR; if (fatal.exitcode() != 0) error = fatal.exitcode(); } catch (emu_exception &) { mame_printf_error("Caught unhandled emulator exception\n"); error = MAMERR_FATALERROR; } catch (std::bad_alloc &) { mame_printf_error("Out of memory!\n"); error = MAMERR_FATALERROR; } // make sure our phase is set properly before cleaning up, // in case we got here via exception m_current_phase = MACHINE_PHASE_EXIT; // call all exit callbacks registered call_notifiers(MACHINE_NOTIFY_EXIT); zip_file_cache_clear(); // close the logfile auto_free(*this, m_logfile); return error; }
int running_machine::run(bool firstrun) { int error = MAMERR_NONE; // move to the init phase m_current_phase = MACHINE_PHASE_INIT; // if we have a logfile, set up the callback if (options().log()) { m_logfile.reset(global_alloc(emu_file(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS))); file_error filerr = m_logfile->open("error.log"); assert_always(filerr == FILERR_NONE, "unable to open log file"); add_logerror_callback(logfile_callback); } // then finish setting up our local machine start(); // load the configuration settings and NVRAM bool settingsloaded = config_load_settings(*this); //MKCHAMP - INITIALIZING THE HISCORE ENGINE if (! options().disable_hiscore_patch()) hiscore_init(*this); // disallow save state registrations starting here. // Don't do it earlier, config load can create network // devices with timers. m_save.allow_registration(false); nvram_load(); sound().ui_mute(false); // initialize ui lists ui().initialize(*this); // display the startup screens ui().display_startup_screens(firstrun, !options().skip_nagscreen()); // perform a soft reset -- this takes us to the running phase soft_reset(); // handle initial load if (m_saveload_schedule != SLS_NONE) handle_saveload(); // run the CPUs until a reset or exit m_hard_reset_pending = false; while ((!m_hard_reset_pending && !m_exit_pending) || m_saveload_schedule != SLS_NONE) return 0; // and out via the exit phase m_current_phase = MACHINE_PHASE_EXIT; // save the NVRAM and configuration sound().ui_mute(true); nvram_save(); config_save_settings(*this); // make sure our phase is set properly before cleaning up, // in case we got here via exception m_current_phase = MACHINE_PHASE_EXIT; // call all exit callbacks registered call_notifiers(MACHINE_NOTIFY_EXIT); zip_file_cache_clear(); // close the logfile m_logfile.reset(); return error; }
int run_game(int game) { callback_item *cb; int error = 0; /* start in the "pre-init phase" */ current_phase = MAME_PHASE_PREINIT; /* AdvanceMAME: Disable validity checks */ #if 0 /* perform validity checks before anything else */ if (mame_validitychecks(game) != 0) return 1; #endif /* loop across multiple hard resets */ exit_pending = FALSE; while (error == 0 && !exit_pending) { /* use setjmp/longjmp for deep error recovery */ fatal_error_jmpbuf_valid = TRUE; error = setjmp(fatal_error_jmpbuf); if (error == 0) { int settingsloaded; /* move to the init phase */ current_phase = MAME_PHASE_INIT; /* start tracking resources for real */ begin_resource_tracking(); /* if we have a logfile, set up the callback */ logerror_callback_list = NULL; if (options.logfile) add_logerror_callback(logfile_callback); /* create the Machine structure and driver */ create_machine(game); /* then finish setting up our local machine */ init_machine(); /* load the configuration settings and NVRAM */ settingsloaded = config_load_settings(); nvram_load(); /* initialize the UI and display the startup screens */ if (ui_init(!settingsloaded && !options.skip_disclaimer, !options.skip_warnings, !options.skip_gameinfo) != 0) fatalerror("User cancelled"); /* ensure we don't show the opening screens on a reset */ options.skip_disclaimer = options.skip_warnings = options.skip_gameinfo = TRUE; /* start resource tracking; note that soft_reset assumes it can */ /* call end_resource_tracking followed by begin_resource_tracking */ /* to clear out resources allocated between resets */ begin_resource_tracking(); /* perform a soft reset -- this takes us to the running phase */ soft_reset(0); /* run the CPUs until a reset or exit */ hard_reset_pending = FALSE; while ((!hard_reset_pending && !exit_pending) || saveload_pending_file != NULL) { profiler_mark(PROFILER_EXTRA); /* execute CPUs if not paused */ if (!mame_paused) cpuexec_timeslice(); /* otherwise, just pump video updates through */ else { updatescreen(); reset_partial_updates(); } /* handle save/load */ if (saveload_schedule_callback) (*saveload_schedule_callback)(); profiler_mark(PROFILER_END); } /* and out via the exit phase */ current_phase = MAME_PHASE_EXIT; /* stop tracking resources at this level */ end_resource_tracking(); /* save the NVRAM and configuration */ nvram_save(); config_save_settings(); } fatal_error_jmpbuf_valid = FALSE; /* call all exit callbacks registered */ for (cb = exit_callback_list; cb; cb = cb->next) (*cb->func.exit)(); /* close all inner resource tracking */ while (resource_tracking_tag != 0) end_resource_tracking(); /* free our callback lists */ free_callback_list(&exit_callback_list); free_callback_list(&reset_callback_list); free_callback_list(&pause_callback_list); } /* return an error */ return error; }