diff options
Diffstat (limited to 'src')
91 files changed, 2380 insertions, 2553 deletions
diff --git a/src/emu/audit.c b/src/emu/audit.c index 6b4fd058089..6366ccd4dd6 100644 --- a/src/emu/audit.c +++ b/src/emu/audit.c @@ -22,8 +22,8 @@ FUNCTION PROTOTYPES ***************************************************************************/ -static void audit_one_rom(core_options *options, const rom_entry *rom, const char *regiontag, const game_driver *gamedrv, const char *validation, audit_record *record); -static void audit_one_disk(core_options *options, const rom_entry *rom, const game_driver *gamedrv, const char *validation, audit_record *record); +static void audit_one_rom(emu_options &options, const rom_entry *rom, const char *regiontag, const game_driver *gamedrv, const char *validation, audit_record *record); +static void audit_one_disk(emu_options &options, const rom_entry *rom, const game_driver *gamedrv, const char *validation, audit_record *record); static int rom_used_by_parent(const game_driver *gamedrv, const hash_collection &romhashes, const game_driver **parent); @@ -54,7 +54,7 @@ INLINE void set_status(audit_record *record, UINT8 status, UINT8 substatus) images for a game -------------------------------------------------*/ -int audit_images(core_options *options, const game_driver *gamedrv, const char *validation, audit_record **audit) +int audit_images(emu_options &options, const game_driver *gamedrv, const char *validation, audit_record **audit) { machine_config config(*gamedrv); const rom_entry *region, *rom; @@ -150,7 +150,7 @@ int audit_images(core_options *options, const game_driver *gamedrv, const char * game -------------------------------------------------*/ -int audit_samples(core_options *options, const game_driver *gamedrv, audit_record **audit) +int audit_samples(emu_options &options, const game_driver *gamedrv, audit_record **audit) { machine_config config(*gamedrv); audit_record *record; @@ -197,7 +197,7 @@ int audit_samples(core_options *options, const game_driver *gamedrv, audit_recor else { /* attempt to access the file from the game driver name */ - emu_file file(*options, SEARCHPATH_SAMPLE, OPEN_FLAG_READ | OPEN_FLAG_NO_PRELOAD); + emu_file file(options.sample_path(), OPEN_FLAG_READ | OPEN_FLAG_NO_PRELOAD); file_error filerr = file.open(gamedrv->name, PATH_SEPARATOR, intf->samplenames[sampnum]); /* attempt to access the file from the shared driver name */ @@ -320,7 +320,7 @@ int audit_summary(const game_driver *gamedrv, int count, const audit_record *rec audit_one_rom - validate a single ROM entry -------------------------------------------------*/ -static void audit_one_rom(core_options *options, const rom_entry *rom, const char *regiontag, const game_driver *gamedrv, const char *validation, audit_record *record) +static void audit_one_rom(emu_options &options, const rom_entry *rom, const char *regiontag, const game_driver *gamedrv, const char *validation, audit_record *record) { const game_driver *drv; UINT32 crc = 0; @@ -338,7 +338,7 @@ static void audit_one_rom(core_options *options, const rom_entry *rom, const cha /* find the file and checksum it, getting the file length along the way */ for (drv = gamedrv; drv != NULL; drv = driver_get_clone(drv)) { - emu_file file(*options, SEARCHPATH_ROM, OPEN_FLAG_READ | OPEN_FLAG_NO_PRELOAD); + emu_file file(options.media_path(), OPEN_FLAG_READ | OPEN_FLAG_NO_PRELOAD); /* open the file if we can */ file_error filerr; @@ -357,7 +357,7 @@ static void audit_one_rom(core_options *options, const rom_entry *rom, const cha /* if not found, check the region as a backup */ if (record->length == 0 && regiontag != NULL) { - emu_file file(*options, SEARCHPATH_ROM, OPEN_FLAG_READ | OPEN_FLAG_NO_PRELOAD); + emu_file file(options.media_path(), OPEN_FLAG_READ | OPEN_FLAG_NO_PRELOAD); /* open the file if we can */ file_error filerr; @@ -424,7 +424,7 @@ static void audit_one_rom(core_options *options, const rom_entry *rom, const cha audit_one_disk - validate a single disk entry -------------------------------------------------*/ -static void audit_one_disk(core_options *options, const rom_entry *rom, const game_driver *gamedrv, const char *validation, audit_record *record) +static void audit_one_disk(emu_options &options, const rom_entry *rom, const game_driver *gamedrv, const char *validation, audit_record *record) { emu_file *source_file; chd_file *source; @@ -436,7 +436,7 @@ static void audit_one_disk(core_options *options, const rom_entry *rom, const ga record->exphashes.from_internal_string(ROM_GETHASHDATA(rom)); /* open the disk */ - err = open_disk_image(*options, gamedrv, rom, &source_file, &source, NULL); + err = open_disk_image(options, gamedrv, rom, &source_file, &source, NULL); /* if we failed, report the error */ if (err != CHDERR_NONE) diff --git a/src/emu/audit.h b/src/emu/audit.h index 419e2e48e2a..3b6eaffd4a2 100644 --- a/src/emu/audit.h +++ b/src/emu/audit.h @@ -93,8 +93,8 @@ struct _audit_record FUNCTION PROTOTYPES ***************************************************************************/ -int audit_images(core_options *options, const game_driver *gamedrv, const char *validation, audit_record **audit); -int audit_samples(core_options *options, const game_driver *gamedrv, audit_record **audit); +int audit_images(emu_options &options, const game_driver *gamedrv, const char *validation, audit_record **audit); +int audit_samples(emu_options &options, const game_driver *gamedrv, audit_record **audit); int audit_summary(const game_driver *gamedrv, int count, const audit_record *records, int output); diff --git a/src/emu/cheat.c b/src/emu/cheat.c index 91082f1a291..4f668ab751c 100644 --- a/src/emu/cheat.c +++ b/src/emu/cheat.c @@ -1093,7 +1093,7 @@ cheat_manager::cheat_manager(running_machine &machine) m_symtable(&machine) { // if the cheat engine is disabled, we're done - if (!options_get_bool(&machine.options(), OPTION_CHEAT)) + if (!machine.options().cheat()) return; // request a callback @@ -1125,7 +1125,7 @@ cheat_manager::cheat_manager(running_machine &machine) void cheat_manager::set_enable(bool enable) { // if the cheat engine is disabled, we're done - if (!options_get_bool(&m_machine.options(), OPTION_CHEAT)) + if (!m_machine.options().cheat()) return; // if we're enabled currently and we don't want to be, turn things off @@ -1160,7 +1160,7 @@ void cheat_manager::set_enable(bool enable) void cheat_manager::reload() { // if the cheat engine is disabled, we're done - if (!options_get_bool(&m_machine.options(), OPTION_CHEAT)) + if (!m_machine.options().cheat()) return; // free everything @@ -1215,7 +1215,7 @@ void cheat_manager::reload() bool cheat_manager::save_all(const char *filename) { // open the file with the proper name - emu_file cheatfile(m_machine.options(), SEARCHPATH_CHEAT, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); + emu_file cheatfile(m_machine.options().cheat_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); file_error filerr = cheatfile.open(filename, ".xml"); // if that failed, return nothing @@ -1411,7 +1411,7 @@ void cheat_manager::frame_update() void cheat_manager::load_cheats(const char *filename) { xml_data_node *rootnode = NULL; - emu_file cheatfile(m_machine.options(), SEARCHPATH_CHEAT, OPEN_FLAG_READ); + emu_file cheatfile(m_machine.options().cheat_path(), OPEN_FLAG_READ); try { // open the file with the proper name diff --git a/src/emu/clifront.c b/src/emu/clifront.c index a3d36424896..5d6af05a45b 100644 --- a/src/emu/clifront.c +++ b/src/emu/clifront.c @@ -4,8 +4,36 @@ Command-line interface frontend for MAME. - Copyright Nicola Salmoria and the MAME Team. - Visit http://mamedev.org for licensing and usage restrictions. +**************************************************************************** + + Copyright Aaron Giles + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name 'MAME' nor the names of its contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. ***************************************************************************/ @@ -32,8 +60,7 @@ TYPE DEFINITIONS ***************************************************************************/ -typedef struct _romident_status romident_status; -struct _romident_status +struct romident_status { int total; /* total files processed */ int matches; /* number of matches found */ @@ -46,65 +73,79 @@ struct _romident_status FUNCTION PROTOTYPES ***************************************************************************/ -static int execute_simple_commands(core_options *options, const char *exename); -static int execute_commands(core_options *options, const char *exename, const game_driver *driver); +static void execute_commands(cli_options &options, const char *exename); static void display_help(void); /* informational functions */ -static int info_verifyroms(core_options *options, const char *gamename); -static int info_verifysamples(core_options *options, const char *gamename); -static int info_romident(core_options *options, const char *gamename); -static int info_listmedia(core_options *opts, const char *gamename); -static int info_listsoftware(core_options *options, const char *gamename); +static void info_verifyroms(emu_options &options, const char *gamename); +static void info_verifysamples(emu_options &options, const char *gamename); +static void info_romident(emu_options &options, const char *gamename); +static void info_listmedia(emu_options &options, const char *gamename); +static void info_listsoftware(emu_options &options, const char *gamename); /* utilities */ -static void romident(core_options *options, const char *filename, romident_status *status); -static void identify_file(core_options *options, const char *name, romident_status *status); -static void identify_data(core_options *options, const char *name, const UINT8 *data, int length, romident_status *status); -static void match_roms(core_options *options, const hash_collection &hashes, int length, int *found); +static void romident(emu_options &options, const char *filename, romident_status *status); +static void identify_file(emu_options &options, const char *name, romident_status *status); +static void identify_data(emu_options &options, const char *name, const UINT8 *data, int length, romident_status *status); +static void match_roms(emu_options &options, const hash_collection &hashes, int length, int *found); static void display_suggestions(const char *gamename); -/*************************************************************************** - COMMAND-LINE OPTIONS -***************************************************************************/ +//************************************************************************** +// COMMAND-LINE OPTIONS +//************************************************************************** -static const options_entry cli_options[] = +const options_entry cli_options::s_option_entries[] = { /* core commands */ - { NULL, NULL, OPTION_HEADER, "CORE COMMANDS" }, - { "help;h;?", "0", OPTION_COMMAND, "show help message" }, - { "validate;valid", "0", OPTION_COMMAND, "perform driver validation on all game drivers" }, + { NULL, NULL, OPTION_HEADER, "CORE COMMANDS" }, + { CLICOMMAND_HELP ";h;?", "0", OPTION_COMMAND, "show help message" }, + { CLICOMMAND_VALIDATE ";valid", "0", OPTION_COMMAND, "perform driver validation on all game drivers" }, /* configuration commands */ - { NULL, NULL, OPTION_HEADER, "CONFIGURATION COMMANDS" }, - { "createconfig;cc", "0", OPTION_COMMAND, "create the default configuration file" }, - { "showconfig;sc", "0", OPTION_COMMAND, "display running parameters" }, - { "showusage;su", "0", OPTION_COMMAND, "show this help" }, + { NULL, NULL, OPTION_HEADER, "CONFIGURATION COMMANDS" }, + { CLICOMMAND_CREATECONFIG ";cc", "0", OPTION_COMMAND, "create the default configuration file" }, + { CLICOMMAND_SHOWCONFIG ";sc", "0", OPTION_COMMAND, "display running parameters" }, + { CLICOMMAND_SHOWUSAGE ";su", "0", OPTION_COMMAND, "show this help" }, /* frontend commands */ - { NULL, NULL, OPTION_HEADER, "FRONTEND COMMANDS" }, - { "listxml;lx", "0", OPTION_COMMAND, "all available info on driver in XML format" }, - { "listfull;ll", "0", OPTION_COMMAND, "short name, full name" }, - { "listsource;ls", "0", OPTION_COMMAND, "driver sourcefile" }, - { "listclones;lc", "0", OPTION_COMMAND, "show clones" }, - { "listbrothers;lb", "0", OPTION_COMMAND, "show \"brothers\", or other drivers from same sourcefile" }, - { "listcrc", "0", OPTION_COMMAND, "CRC-32s" }, - { "listroms", "0", OPTION_COMMAND, "list required roms for a driver" }, - { "listsamples", "0", OPTION_COMMAND, "list optional samples for a driver" }, - { "verifyroms", "0", OPTION_COMMAND, "report romsets that have problems" }, - { "verifysamples", "0", OPTION_COMMAND, "report samplesets that have problems" }, - { "romident", "0", OPTION_COMMAND, "compare files with known MAME roms" }, - { "listdevices;ld", "0", OPTION_COMMAND, "list available devices" }, - { "listmedia;lm", "0", OPTION_COMMAND, "list available media for the system" }, - { "listsoftware;lsoft", "0", OPTION_COMMAND, "list known software for the system" }, + { NULL, NULL, OPTION_HEADER, "FRONTEND COMMANDS" }, + { CLICOMMAND_LISTXML ";lx", "0", OPTION_COMMAND, "all available info on driver in XML format" }, + { CLICOMMAND_LISTFULL ";ll", "0", OPTION_COMMAND, "short name, full name" }, + { CLICOMMAND_LISTSOURCE ";ls", "0", OPTION_COMMAND, "driver sourcefile" }, + { CLICOMMAND_LISTCLONES ";lc", "0", OPTION_COMMAND, "show clones" }, + { CLICOMMAND_LISTBROTHERS ";lb", "0", OPTION_COMMAND, "show \"brothers\", or other drivers from same sourcefile" }, + { CLICOMMAND_LISTCRC, "0", OPTION_COMMAND, "CRC-32s" }, + { CLICOMMAND_LISTROMS, "0", OPTION_COMMAND, "list required roms for a driver" }, + { CLICOMMAND_LISTSAMPLES, "0", OPTION_COMMAND, "list optional samples for a driver" }, + { CLICOMMAND_VERIFYROMS, "0", OPTION_COMMAND, "report romsets that have problems" }, + { CLICOMMAND_VERIFYSAMPLES, "0", OPTION_COMMAND, "report samplesets that have problems" }, + { CLICOMMAND_ROMIDENT, "0", OPTION_COMMAND, "compare files with known MAME roms" }, + { CLICOMMAND_LISTDEVICES ";ld", "0", OPTION_COMMAND, "list available devices" }, + { CLICOMMAND_LISTMEDIA ";lm", "0", OPTION_COMMAND, "list available media for the system" }, + { CLICOMMAND_LISTSOFTWARE ";lsoft", "0", OPTION_COMMAND, "list known software for the system" }, { NULL } }; +//************************************************************************** +// CLI OPTIONS +//************************************************************************** + +//------------------------------------------------- +// cli_options - constructor +//------------------------------------------------- + +cli_options::cli_options() +{ + add_entries(s_option_entries); +} + + + /*************************************************************************** CORE IMPLEMENTATION ***************************************************************************/ @@ -124,217 +165,175 @@ static void display_suggestions(const char *gamename) if (matches[drvnum] != NULL) fprintf(stderr, "%-18s%s\n", matches[drvnum]->name, matches[drvnum]->description); } -/*------------------------------------------------- - cli_execute - execute a game via the standard - command line interface --------------------------------------------------*/ -int cli_execute(int argc, char **argv, osd_interface &osd, const options_entry *osd_options) -{ - core_options *options = NULL; - const char *gamename_option; - const game_driver *driver; - int result = MAMERR_FATALERROR; - astring gamename; - astring exename; +//------------------------------------------------- +// cli_execute - execute a game via the standard +// command line interface +//------------------------------------------------- + +int cli_execute(cli_options &options, osd_interface &osd, int argc, char **argv) +{ + // wrap the core execution in a try/catch to field all fatal errors + int result = MAMERR_NONE; try { - /* initialize the options manager and add the CLI-specific options */ - options = mame_options_init(osd_options); - options_add_entries(options, cli_options); - - /* parse the command line first; if we fail here, we're screwed */ - if (options_parse_command_line(options, argc, argv, OPTION_PRIORITY_CMDLINE, FALSE)) - { - result = MAMERR_INVALID_CONFIG; - goto error; - } - - /* parse the simple commmands before we go any further */ + // parse the command line, adding any system-specific options + astring option_errors; + if (!options.parse_command_line(argc, argv, option_errors)) + throw emu_fatalerror(MAMERR_INVALID_CONFIG, "%s", option_errors.trimspace().cstr()); + if (option_errors) + printf("Error in command line:\n%s\n", option_errors.trimspace().cstr()); + + // determine the base name of the EXE + astring exename; core_filename_extract_base(&exename, argv[0], TRUE); - result = execute_simple_commands(options, exename); - if (result != -1) - goto error; - - /* find out what game we might be referring to */ - gamename_option = options_get_string(options, OPTION_GAMENAME); - core_filename_extract_base(&gamename, gamename_option, TRUE); - driver = driver_get_name(gamename); - - /* execute any commands specified */ - result = execute_commands(options, exename, driver); - if (result != -1) - goto error; - - /* if we don't have a valid driver selected, offer some suggestions */ - if (strlen(gamename_option) > 0 && driver == NULL) - { - display_suggestions(gamename_option); - /* exit with an error */ - result = MAMERR_NO_SUCH_GAME; - goto error; - } - /* parse the command line first; if we fail here, we're screwed */ - if (options_parse_command_line(options, argc, argv, OPTION_PRIORITY_CMDLINE, TRUE)) + + // if we have a command, execute that + if (strlen(options.command()) != 0) + execute_commands(options, exename); + + // otherwise, check for a valid system + else { - result = MAMERR_INVALID_CONFIG; - goto error; + // if we can't find it, give an appropriate error + const game_driver *system = options.system(); + if (system == NULL && strlen(options.system_name()) > 0) + throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "Unknown system '%s'", options.system_name()); + + // otherwise just run the game + result = mame_execute(options, osd); } - - - /* run the game */ - result = mame_execute(osd, options); } + + // handle exceptions of various types catch (emu_fatalerror &fatal) { fprintf(stderr, "%s\n", fatal.string()); - if (fatal.exitcode() != 0) - result = fatal.exitcode(); + result = (fatal.exitcode() != 0) ? fatal.exitcode() : MAMERR_FATALERROR; + + // for any unknown game, offer some suggestions + if (result == MAMERR_NO_SUCH_GAME && strlen(options.system_name()) > 0 && strchr(options.system_name(), '*') == NULL) + display_suggestions(options.system_name()); } catch (emu_exception &) { fprintf(stderr, "Caught unhandled emulator exception\n"); + result = MAMERR_FATALERROR; } catch (std::bad_alloc &) { fprintf(stderr, "Out of memory!\n"); + result = MAMERR_FATALERROR; } + + // handle any other exceptions catch (...) { fprintf(stderr, "Caught unhandled exception\n"); + result = MAMERR_FATALERROR; } -error: - /* free our options and exit */ - if (options != NULL) - options_free(options); - - /* report any unfreed memory */ - dump_unfreed_mem(); + // report any unfreed memory on clean exits + if (result == MAMERR_NONE) + dump_unfreed_mem(); return result; } -/*------------------------------------------------- - help_output - output callback for printing - requested help information --------------------------------------------------*/ - -static void help_output(const char *s) -{ - mame_printf_info("%s", s); -} - - -/*------------------------------------------------- - execute_simple_commands - execute basic - commands that don't require any context --------------------------------------------------*/ +//------------------------------------------------- +// execute_commands - execute various frontend +// commands +//------------------------------------------------- -static int execute_simple_commands(core_options *options, const char *exename) +static void execute_commands(cli_options &options, const char *exename) { - /* help? */ - if (options_get_bool(options, CLIOPTION_HELP)) + // help? + if (strcmp(options.command(), CLICOMMAND_HELP) == 0) { display_help(); - return MAMERR_NONE; + return; } - /* showusage? */ - if (options_get_bool(options, CLIOPTION_SHOWUSAGE)) + // showusage? + if (strcmp(options.command(), CLICOMMAND_SHOWUSAGE) == 0) { - mame_printf_info("Usage: %s [%s] [options]\n\nOptions:\n", exename, GAMENOUN); - options_output_help(options, help_output); - return MAMERR_NONE; + astring helpstring; + mame_printf_info("Usage: %s [%s] [options]\n\nOptions:\n%s", exename, GAMENOUN, options.output_help(helpstring)); + return; } - /* validate? */ - if (options_get_bool(options, CLIOPTION_VALIDATE)) - return mame_validitychecks(*options, NULL); + // validate? + if (strcmp(options.command(), CLICOMMAND_VALIDATE) == 0) + { + validate_drivers(options); + return; + } - return -1; -} + // other commands need the INIs parsed + astring option_errors; + options.parse_standard_inis(option_errors); + if (option_errors) + printf("%s\n", option_errors.cstr()); + // createconfig? + if (strcmp(options.command(), CLICOMMAND_CREATECONFIG) == 0) + { + // attempt to open the output file + emu_file file(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); + if (file.open(CONFIGNAME ".ini") != FILERR_NONE) + throw emu_fatalerror("Unable to create file " CONFIGNAME ".ini\n"); + + // generate the updated INI + astring initext; + file.puts(options.output_ini(initext)); + return; + } -/*------------------------------------------------- - execute_commands - execute various frontend - commands --------------------------------------------------*/ + // showconfig? + if (strcmp(options.command(), CLICOMMAND_SHOWCONFIG) == 0) + { + // print the INI text + astring initext; + printf("%s\n", options.output_ini(initext)); + return; + } -static int execute_commands(core_options *options, const char *exename, const game_driver *driver) -{ + // all other commands call out to one of these helpers static const struct { const char *option; - int (*function)(core_options *options, const char *gamename); + void (*function)(emu_options &options, const char *gamename); } info_commands[] = { - { CLIOPTION_LISTXML, cli_info_listxml }, - { CLIOPTION_LISTFULL, cli_info_listfull }, - { CLIOPTION_LISTSOURCE, cli_info_listsource }, - { CLIOPTION_LISTCLONES, cli_info_listclones }, - { CLIOPTION_LISTBROTHERS, cli_info_listbrothers }, - { CLIOPTION_LISTCRC, cli_info_listcrc }, - { CLIOPTION_LISTDEVICES, cli_info_listdevices }, - { CLIOPTION_LISTROMS, cli_info_listroms }, - { CLIOPTION_LISTSAMPLES, cli_info_listsamples }, - { CLIOPTION_VERIFYROMS, info_verifyroms }, - { CLIOPTION_VERIFYSAMPLES, info_verifysamples }, - { CLIOPTION_LISTMEDIA, info_listmedia }, - { CLIOPTION_LISTSOFTWARE, info_listsoftware }, - { CLIOPTION_ROMIDENT, info_romident } + { CLICOMMAND_LISTXML, cli_info_listxml }, + { CLICOMMAND_LISTFULL, cli_info_listfull }, + { CLICOMMAND_LISTSOURCE, cli_info_listsource }, + { CLICOMMAND_LISTCLONES, cli_info_listclones }, + { CLICOMMAND_LISTBROTHERS, cli_info_listbrothers }, + { CLICOMMAND_LISTCRC, cli_info_listcrc }, + { CLICOMMAND_LISTDEVICES, cli_info_listdevices }, + { CLICOMMAND_LISTROMS, cli_info_listroms }, + { CLICOMMAND_LISTSAMPLES, cli_info_listsamples }, + { CLICOMMAND_VERIFYROMS, info_verifyroms }, + { CLICOMMAND_VERIFYSAMPLES, info_verifysamples }, + { CLICOMMAND_LISTMEDIA, info_listmedia }, + { CLICOMMAND_LISTSOFTWARE, info_listsoftware }, + { CLICOMMAND_ROMIDENT, info_romident } }; - int i; - - /* createconfig? */ - if (options_get_bool(options, CLIOPTION_CREATECONFIG)) - { - emu_file file(*options, NULL, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - - /* parse any relevant INI files before proceeding */ - mame_parse_ini_files(options, driver); - /* make the output filename */ - file_error filerr = file.open(CONFIGNAME ".ini"); - - /* error if unable to create the file */ - if (filerr != FILERR_NONE) - { - fprintf(stderr, "Unable to create file " CONFIGNAME ".ini\n"); - return MAMERR_FATALERROR; - } - - /* output the configuration and exit cleanly */ - options_output_ini_file(options, file); - return MAMERR_NONE; - } - - /* showconfig? */ - if (options_get_bool(options, CLIOPTION_SHOWCONFIG)) - { - /* parse any relevant INI files before proceeding */ - mame_parse_ini_files(options, driver); - options_output_ini_stdfile(options, stdout); - return MAMERR_NONE; - } - - /* informational commands? */ - for (i = 0; i < ARRAY_LENGTH(info_commands); i++) - if (options_get_bool(options, info_commands[i].option)) + // find the command + for (int cmdindex = 0; cmdindex < ARRAY_LENGTH(info_commands); cmdindex++) + if (strcmp(options.command(), info_commands[cmdindex].option) == 0) { - const char *gamename = options_get_string(options, OPTION_GAMENAME); - /* parse any relevant INI files before proceeding */ - mame_parse_ini_files(options, driver); - int retVal = (*info_commands[i].function)(options, (gamename[0] == 0) ? "*" : gamename); - if ( retVal == MAMERR_NO_SUCH_GAME) { - display_suggestions(gamename); - return MAMERR_NO_SUCH_GAME; - } - return retVal; + // parse any relevant INI files before proceeding + const char *sysname = options.system_name(); + (*info_commands[cmdindex].function)(options, (sysname[0] == 0) ? "*" : sysname); + return; } - return -1; + // if we get here, we don't know what has been requested + throw emu_fatalerror(MAMERR_INVALID_CONFIG, "Unknown command '%s' specified", options.command()); } @@ -370,24 +369,23 @@ static void display_help(void) or more games -------------------------------------------------*/ -int cli_info_listxml(core_options *options, const char *gamename) +void cli_info_listxml(emu_options &options, const char *gamename) { print_mame_xml(stdout, drivers, gamename); - return MAMERR_NONE; } /*------------------------------------------------- - cli_info_listfull - output the name and description - of one or more games + cli_info_listfull - output the name and + description of one or more games -------------------------------------------------*/ -int cli_info_listfull(core_options *options, const char *gamename) +void cli_info_listfull(emu_options &options, const char *gamename) { - int drvindex, count = 0; + int count = 0; /* iterate over drivers */ - for (drvindex = 0; drivers[drvindex] != NULL; drvindex++) + for (int drvindex = 0; drivers[drvindex] != NULL; drvindex++) if ((drivers[drvindex]->flags & GAME_NO_STANDALONE) == 0 && mame_strwildcmp(gamename, drivers[drvindex]->name) == 0) { /* print the header on the first one */ @@ -400,7 +398,8 @@ int cli_info_listfull(core_options *options, const char *gamename) } /* return an error if none found */ - return (count > 0) ? MAMERR_NONE : MAMERR_NO_SUCH_GAME; + if (count == 0) + throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "No matching games found for '%s'", gamename); } @@ -409,13 +408,13 @@ int cli_info_listfull(core_options *options, const char *gamename) filename of one or more games -------------------------------------------------*/ -int cli_info_listsource(core_options *options, const char *gamename) +void cli_info_listsource(emu_options &options, const char *gamename) { - int drvindex, count = 0; + int count = 0; astring filename; /* iterate over drivers */ - for (drvindex = 0; drivers[drvindex] != NULL; drvindex++) + for (int drvindex = 0; drivers[drvindex] != NULL; drvindex++) if (mame_strwildcmp(gamename, drivers[drvindex]->name) == 0) { /* output the remaining information */ @@ -424,7 +423,8 @@ int cli_info_listsource(core_options *options, const char *gamename) } /* return an error if none found */ - return (count > 0) ? MAMERR_NONE : MAMERR_NO_SUCH_GAME; + if (count == 0) + throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "No matching games found for '%s'", gamename); } @@ -433,20 +433,19 @@ int cli_info_listsource(core_options *options, const char *gamename) filename of one or more games -------------------------------------------------*/ -int cli_info_listclones(core_options *options, const char *gamename) +void cli_info_listclones(emu_options &options, const char *gamename) { - int drvindex, count = 0, drvcnt = 0; + int count = 0, drvcnt = 0; - for (drvindex = 0; drivers[drvindex] != NULL; drvindex++) - { + for (int drvindex = 0; drivers[drvindex] != NULL; drvindex++) if (mame_strwildcmp(gamename, drivers[drvindex]->name) == 0) - { drvcnt++; - } - } - if (drvcnt==0) return MAMERR_NO_SUCH_GAME; + + if (drvcnt == 0) + throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "No matching games found for '%s'", gamename); + /* iterate over drivers */ - for (drvindex = 0; drivers[drvindex] != NULL; drvindex++) + for (int drvindex = 0; drivers[drvindex] != NULL; drvindex++) { const game_driver *clone_of = driver_get_clone(drivers[drvindex]); @@ -463,8 +462,6 @@ int cli_info_listclones(core_options *options, const char *gamename) count++; } } - - return MAMERR_NONE; } @@ -473,25 +470,23 @@ int cli_info_listclones(core_options *options, const char *gamename) source filename of one or more games -------------------------------------------------*/ -int cli_info_listbrothers(core_options *options, const char *gamename) +void cli_info_listbrothers(emu_options &options, const char *gamename) { UINT8 *didit = global_alloc_array_clear(UINT8, driver_list_get_count(drivers)); - int drvindex, count = 0; + int count = 0; astring filename; /* iterate over drivers */ - for (drvindex = 0; drivers[drvindex] != NULL; drvindex++) + for (int drvindex = 0; drivers[drvindex] != NULL; drvindex++) if (!didit[drvindex] && mame_strwildcmp(gamename, drivers[drvindex]->name) == 0) { - int matchindex; - didit[drvindex] = TRUE; if (count > 0) mame_printf_info("\n"); mame_printf_info("%s ... other drivers in %s:\n", drivers[drvindex]->name, core_filename_extract_base(&filename, drivers[drvindex]->source_file, FALSE)->cstr()); /* now iterate again over drivers, finding those with the same source file */ - for (matchindex = 0; drivers[matchindex]; matchindex++) + for (int matchindex = 0; drivers[matchindex]; matchindex++) if (matchindex != drvindex && strcmp(drivers[drvindex]->source_file, drivers[matchindex]->source_file) == 0) { const char *matchstring = (mame_strwildcmp(gamename, drivers[matchindex]->name) == 0) ? "-> " : " "; @@ -509,7 +504,8 @@ int cli_info_listbrothers(core_options *options, const char *gamename) /* return an error if none found */ global_free(didit); - return (count > 0) ? MAMERR_NONE : MAMERR_NO_SUCH_GAME; + if (count == 0) + throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "No matching games found for '%s'", gamename); } @@ -518,12 +514,12 @@ int cli_info_listbrothers(core_options *options, const char *gamename) all ROMs referenced by MAME -------------------------------------------------*/ -int cli_info_listcrc(core_options *options, const char *gamename) +void cli_info_listcrc(emu_options &options, const char *gamename) { - int drvindex, count = 0; + int count = 0; /* iterate over drivers */ - for (drvindex = 0; drivers[drvindex] != NULL; drvindex++) + for (int drvindex = 0; drivers[drvindex] != NULL; drvindex++) if (mame_strwildcmp(gamename, drivers[drvindex]->name) == 0) { machine_config config(*drivers[drvindex]); @@ -545,7 +541,8 @@ int cli_info_listcrc(core_options *options, const char *gamename) } /* return an error if none found */ - return (count > 0) ? MAMERR_NONE : MAMERR_NO_SUCH_GAME; + if (count == 0) + throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "No matching games found for '%s'", gamename); } @@ -554,13 +551,13 @@ int cli_info_listcrc(core_options *options, const char *gamename) referenced by a given game or set of games -------------------------------------------------*/ -int cli_info_listroms(core_options *options, const char *gamename) +void cli_info_listroms(emu_options &options, const char *gamename) { - int drvindex, count = 0; + int count = 0; astring tempstr; /* iterate over drivers */ - for (drvindex = 0; drivers[drvindex] != NULL; drvindex++) + for (int drvindex = 0; drivers[drvindex] != NULL; drvindex++) if (mame_strwildcmp(gamename, drivers[drvindex]->name) == 0) { machine_config config(*drivers[drvindex]); @@ -569,7 +566,7 @@ int cli_info_listroms(core_options *options, const char *gamename) if (count > 0) mame_printf_info("\n"); mame_printf_info("This is the list of the ROMs required for driver \"%s\".\n" - "Name Size Checksum\n", drivers[drvindex]->name); + "Name Size Checksum\n", drivers[drvindex]->name); /* iterate over sources, regions and then ROMs within the region */ for (const rom_source *source = rom_first_source(config); source != NULL; source = rom_next_source(*source)) @@ -583,7 +580,7 @@ int cli_info_listroms(core_options *options, const char *gamename) /* start with the name */ const char *name = ROM_GETNAME(rom); - mame_printf_info("%-12s ", name); + mame_printf_info("%-20s ", name); /* output the length next */ if (length >= 0) @@ -609,7 +606,8 @@ int cli_info_listroms(core_options *options, const char *gamename) count++; } - return (count > 0) ? MAMERR_NONE : MAMERR_NO_SUCH_GAME; + if (count == 0) + throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "No matching games found for '%s'", gamename); } @@ -618,13 +616,12 @@ int cli_info_listroms(core_options *options, const char *gamename) referenced by a given game or set of games -------------------------------------------------*/ -int cli_info_listsamples(core_options *options, const char *gamename) +void cli_info_listsamples(emu_options &options, const char *gamename) { int count = 0; - int drvindex; /* iterate over drivers */ - for (drvindex = 0; drivers[drvindex] != NULL; drvindex++) + for (int drvindex = 0; drivers[drvindex] != NULL; drvindex++) if (mame_strwildcmp(gamename, drivers[drvindex]->name) == 0) { machine_config config(*drivers[drvindex]); @@ -646,7 +643,8 @@ int cli_info_listsamples(core_options *options, const char *gamename) count++; } - return (count > 0) ? MAMERR_NONE : MAMERR_NO_SUCH_GAME; + if (count == 0) + throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "No matching games found for '%s'", gamename); } @@ -656,24 +654,22 @@ int cli_info_listsamples(core_options *options, const char *gamename) games -------------------------------------------------*/ -int cli_info_listdevices(core_options *options, const char *gamename) +void cli_info_listdevices(emu_options &options, const char *gamename) { int count = 0; - int drvindex; /* iterate over drivers */ - for (drvindex = 0; drivers[drvindex] != NULL; drvindex++) + for (int drvindex = 0; drivers[drvindex] != NULL; drvindex++) if (mame_strwildcmp(gamename, drivers[drvindex]->name) == 0) { machine_config config(*drivers[drvindex]); - const device_config *devconfig; if (count != 0) printf("\n"); printf("Driver %s (%s):\n", drivers[drvindex]->name, drivers[drvindex]->description); /* iterate through devices */ - for (devconfig = config.m_devicelist.first(); devconfig != NULL; devconfig = devconfig->next()) + for (const device_config *devconfig = config.m_devicelist.first(); devconfig != NULL; devconfig = devconfig->next()) { printf(" %s ('%s')", devconfig->name(), devconfig->tag()); @@ -693,7 +689,8 @@ int cli_info_listdevices(core_options *options, const char *gamename) count++; } - return (count > 0) ? MAMERR_NONE : MAMERR_NO_SUCH_GAME; + if (count == 0) + throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "No matching games found for '%s'", gamename); } @@ -702,15 +699,14 @@ int cli_info_listdevices(core_options *options, const char *gamename) one or more games -------------------------------------------------*/ -static int info_verifyroms(core_options *options, const char *gamename) +static void info_verifyroms(emu_options &options, const char *gamename) { int correct = 0; int incorrect = 0; int notfound = 0; - int drvindex; /* iterate over drivers */ - for (drvindex = 0; drivers[drvindex] != NULL; drvindex++) + for (int drvindex = 0; drivers[drvindex] != NULL; drvindex++) if (mame_strwildcmp(gamename, drivers[drvindex]->name) == 0) { audit_record *audit; @@ -766,17 +762,17 @@ static int info_verifyroms(core_options *options, const char *gamename) if (correct + incorrect == 0) { if (notfound > 0) - mame_printf_info("romset \"%s\" not found!\n", gamename); + throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "romset \"%s\" not found!\n", gamename); else - mame_printf_info("romset \"%s\" not supported!\n", gamename); - return MAMERR_NO_SUCH_GAME; + throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "romset \"%s\" not supported!\n", gamename); } /* otherwise, print a summary */ else { - mame_printf_info("%d romsets found, %d were OK.\n", correct + incorrect, correct); - return (incorrect > 0) ? MAMERR_MISSING_FILES : MAMERR_NONE; + if (incorrect > 0) + throw emu_fatalerror(MAMERR_MISSING_FILES, "%d romsets found, %d were OK.\n", correct + incorrect, correct); + mame_printf_info("%d romsets found, %d were OK.\n", correct, correct); } } @@ -789,7 +785,7 @@ static int info_verifyroms(core_options *options, const char *gamename) identifying duplicate lists. -------------------------------------------------*/ -static int info_listsoftware(core_options *options, const char *gamename) +static void info_listsoftware(emu_options &options, const char *gamename) { FILE *out = stdout; int nr_lists = 0; @@ -894,7 +890,7 @@ static int info_listsoftware(core_options *options, const char *gamename) { if ( swlist->list_name[i] && *swlist->list_name[i] && (swlist->list_type == SOFTWARE_LIST_ORIGINAL_SYSTEM)) { - software_list *list = software_list_open( *options, swlist->list_name[i], FALSE, NULL ); + software_list *list = software_list_open( options, swlist->list_name[i], FALSE, NULL ); if ( list ) { @@ -1063,8 +1059,6 @@ static int info_listsoftware(core_options *options, const char *gamename) fprintf( out, "No software lists found for this system\n" ); global_free( lists ); - - return MAMERR_NONE; } @@ -1072,12 +1066,10 @@ static int info_listsoftware(core_options *options, const char *gamename) softlist_match_roms - scan for a matching software ROM by hash -------------------------------------------------*/ -static void softlist_match_roms(core_options *options, const hash_collection &hashes, int length, int *found) +static void softlist_match_roms(emu_options &options, const hash_collection &hashes, int length, int *found) { - int drvindex; - /* iterate over drivers */ - for (drvindex = 0; drivers[drvindex] != NULL; drvindex++) + for (int drvindex = 0; drivers[drvindex] != NULL; drvindex++) { machine_config config(*drivers[drvindex]); @@ -1089,7 +1081,7 @@ static void softlist_match_roms(core_options *options, const hash_collection &ha { if ( swlist->list_name[i] ) { - software_list *list = software_list_open( *options, swlist->list_name[i], FALSE, NULL ); + software_list *list = software_list_open( options, swlist->list_name[i], FALSE, NULL ); for ( software_info *swinfo = software_list_find( list, "*", NULL ); swinfo != NULL; swinfo = software_list_find( list, "*", swinfo ) ) { @@ -1128,10 +1120,9 @@ static void softlist_match_roms(core_options *options, const hash_collection &ha games -------------------------------------------------*/ -static int info_listmedia(core_options *options, const char *gamename) +static void info_listmedia(emu_options &options, const char *gamename) { int count = 0, devcount; - int drvindex; const device_config_image_interface *dev = NULL; const char *src; const char *driver_name; @@ -1143,7 +1134,7 @@ static int info_listmedia(core_options *options, const char *gamename) printf("---------- -------------------- ------------------------------------\n"); /* iterate over drivers */ - for (drvindex = 0; drivers[drvindex] != NULL; drvindex++) + for (int drvindex = 0; drivers[drvindex] != NULL; drvindex++) if (mame_strwildcmp(gamename, drivers[drvindex]->name) == 0) { /* allocate the machine config */ @@ -1183,7 +1174,8 @@ static int info_listmedia(core_options *options, const char *gamename) if (!count) printf("There are no Computers or Consoles named %s\n", gamename); - return (count > 0) ? MAMERR_NONE : MAMERR_NO_SUCH_GAME; + if (count == 0) + throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "No matching games found for '%s'", gamename); } @@ -1192,15 +1184,14 @@ static int info_listmedia(core_options *options, const char *gamename) one or more games -------------------------------------------------*/ -static int info_verifysamples(core_options *options, const char *gamename) +static void info_verifysamples(emu_options &options, const char *gamename) { int correct = 0; int incorrect = 0; int notfound = FALSE; - int drvindex; /* now iterate over drivers */ - for (drvindex = 0; drivers[drvindex] != NULL; drvindex++) + for (int drvindex = 0; drivers[drvindex] != NULL; drvindex++) if (mame_strwildcmp(gamename, drivers[drvindex]->name) == 0) { audit_record *audit; @@ -1255,15 +1246,17 @@ static int info_verifysamples(core_options *options, const char *gamename) if (correct + incorrect == 0) { if (!notfound) - mame_printf_error("sampleset \"%s\" not supported!\n", gamename); - return MAMERR_NO_SUCH_GAME; + throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "No matching games found for '%s'", gamename); + else + throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "No sample sets found for '%s'", gamename); } /* otherwise, print a summary */ else { - mame_printf_info("%d samplesets found, %d were OK.\n", correct + incorrect, correct); - return (incorrect > 0) ? MAMERR_MISSING_FILES : MAMERR_NONE; + if (incorrect > 0) + throw emu_fatalerror(MAMERR_MISSING_FILES, "%d sample sets found, %d were OK.\n", correct + incorrect, correct); + mame_printf_info("%d sample sets found, %d were OK.\n", correct, correct); } } @@ -1273,14 +1266,10 @@ static int info_verifysamples(core_options *options, const char *gamename) matches in our internal database -------------------------------------------------*/ -static int info_romident(core_options *options, const char *gamename) +static void info_romident(emu_options &options, const char *gamename) { romident_status status; - /* a NULL gamename is a fatal error */ - if (gamename == NULL) - return MAMERR_FATALERROR; - /* do the identification */ romident(options, gamename, &status); @@ -1289,13 +1278,13 @@ static int info_romident(core_options *options, const char *gamename) /* return the appropriate error code */ if (status.matches == status.total) - return MAMERR_NONE; + return; else if (status.matches == status.total - status.nonroms) - return MAMERR_IDENT_NONROMS; + throw emu_fatalerror(MAMERR_IDENT_NONROMS, ""); else if (status.matches > 0) - return MAMERR_IDENT_PARTIAL; + throw emu_fatalerror(MAMERR_IDENT_PARTIAL, ""); else - return MAMERR_IDENT_NONE; + throw emu_fatalerror(MAMERR_IDENT_NONE, ""); } @@ -1308,7 +1297,7 @@ static int info_romident(core_options *options, const char *gamename) romident - identify files -------------------------------------------------*/ -static void romident(core_options *options, const char *filename, romident_status *status) +static void romident(emu_options &options, const char *filename, romident_status *status) { osd_directory *directory; @@ -1373,7 +1362,7 @@ static void romident(core_options *options, const char *filename, romident_statu files -------------------------------------------------*/ -static void identify_file(core_options *options, const char *name, romident_status *status) +static void identify_file(emu_options &options, const char *name, romident_status *status) { file_error filerr; osd_file *file; @@ -1463,7 +1452,7 @@ static void identify_file(core_options *options, const char *name, romident_stat fusemap into raw data first -------------------------------------------------*/ -static void identify_data(core_options *options, const char *name, const UINT8 *data, int length, romident_status *status) +static void identify_data(emu_options &options, const char *name, const UINT8 *data, int length, romident_status *status) { UINT8 *tempjed = NULL; astring basename; @@ -1525,7 +1514,7 @@ static void identify_data(core_options *options, const char *name, const UINT8 * match_roms - scan for a matching ROM by hash -------------------------------------------------*/ -static void match_roms(core_options *options, const hash_collection &hashes, int length, int *found) +static void match_roms(emu_options &options, const hash_collection &hashes, int length, int *found) { int drvindex; diff --git a/src/emu/clifront.h b/src/emu/clifront.h index 111b21e5c3d..d240fdf160f 100644 --- a/src/emu/clifront.h +++ b/src/emu/clifront.h @@ -4,8 +4,36 @@ Command-line interface frontend for MAME. - Copyright Nicola Salmoria and the MAME Team. - Visit http://mamedev.org for licensing and usage restrictions. +**************************************************************************** + + Copyright Aaron Giles + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name 'MAME' nor the names of its contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. ***************************************************************************/ @@ -14,32 +42,53 @@ #ifndef __CLIFRONT_H__ #define __CLIFRONT_H__ -#include "options.h" +#include "emuopts.h" -/*************************************************************************** - CONSTANTS -***************************************************************************/ +//************************************************************************** +// CONSTANTS +//************************************************************************** + +// core commands +#define CLICOMMAND_HELP "help" +#define CLICOMMAND_VALIDATE "validate" + +// configuration commands +#define CLICOMMAND_CREATECONFIG "createconfig" +#define CLICOMMAND_SHOWCONFIG "showconfig" +#define CLICOMMAND_SHOWUSAGE "showusage" + +// frontend commands +#define CLICOMMAND_LISTXML "listxml" +#define CLICOMMAND_LISTFULL "listfull" +#define CLICOMMAND_LISTSOURCE "listsource" +#define CLICOMMAND_LISTCLONES "listclones" +#define CLICOMMAND_LISTBROTHERS "listbrothers" +#define CLICOMMAND_LISTCRC "listcrc" +#define CLICOMMAND_LISTROMS "listroms" +#define CLICOMMAND_LISTSAMPLES "listsamples" +#define CLICOMMAND_VERIFYROMS "verifyroms" +#define CLICOMMAND_VERIFYSAMPLES "verifysamples" +#define CLICOMMAND_ROMIDENT "romident" +#define CLICOMMAND_LISTDEVICES "listdevices" +#define CLICOMMAND_LISTMEDIA "listmedia" // needed by MESS +#define CLICOMMAND_LISTSOFTWARE "listsoftware" + + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class cli_options : public emu_options +{ +public: + // construction/destruction + cli_options(); -#define CLIOPTION_CREATECONFIG "createconfig" -#define CLIOPTION_SHOWCONFIG "showconfig" -#define CLIOPTION_SHOWUSAGE "showusage" -#define CLIOPTION_VALIDATE "validate" -#define CLIOPTION_HELP "help" -#define CLIOPTION_LISTXML "listxml" -#define CLIOPTION_LISTFULL "listfull" -#define CLIOPTION_LISTSOURCE "listsource" -#define CLIOPTION_LISTCLONES "listclones" -#define CLIOPTION_LISTBROTHERS "listbrothers" -#define CLIOPTION_LISTCRC "listcrc" -#define CLIOPTION_LISTDEVICES "listdevices" -#define CLIOPTION_LISTROMS "listroms" -#define CLIOPTION_LISTSAMPLES "listsamples" -#define CLIOPTION_VERIFYROMS "verifyroms" -#define CLIOPTION_VERIFYSAMPLES "verifysamples" -#define CLIOPTION_ROMIDENT "romident" -#define CLIOPTION_LISTMEDIA "listmedia" // needed by MESS -#define CLIOPTION_LISTSOFTWARE "listsoftware" +private: + static const options_entry s_option_entries[]; +}; @@ -47,17 +96,17 @@ FUNCTION PROTOTYPES ***************************************************************************/ -int cli_execute(int argc, char **argv, osd_interface &osd, const options_entry *osd_options); +int cli_execute(cli_options &options, osd_interface &osd, int argc, char **argv); /* informational functions */ -int cli_info_listxml(core_options *options, const char *gamename); -int cli_info_listfull(core_options *options, const char *gamename); -int cli_info_listsource(core_options *options, const char *gamename); -int cli_info_listclones(core_options *options, const char *gamename); -int cli_info_listbrothers(core_options *options, const char *gamename); -int cli_info_listcrc(core_options *options, const char *gamename); -int cli_info_listroms(core_options *options, const char *gamename); -int cli_info_listsamples(core_options *options, const char *gamename); -int cli_info_listdevices(core_options *options, const char *gamename); +void cli_info_listxml(emu_options &options, const char *gamename); +void cli_info_listfull(emu_options &options, const char *gamename); +void cli_info_listsource(emu_options &options, const char *gamename); +void cli_info_listclones(emu_options &options, const char *gamename); +void cli_info_listbrothers(emu_options &options, const char *gamename); +void cli_info_listcrc(emu_options &options, const char *gamename); +void cli_info_listroms(emu_options &options, const char *gamename); +void cli_info_listsamples(emu_options &options, const char *gamename); +void cli_info_listdevices(emu_options &options, const char *gamename); #endif /* __CLIFRONT_H__ */ diff --git a/src/emu/config.c b/src/emu/config.c index f20d8a2a10a..2cb5a7118ac 100644 --- a/src/emu/config.c +++ b/src/emu/config.c @@ -102,7 +102,7 @@ void config_register(running_machine *machine, const char *nodename, config_call int config_load_settings(running_machine *machine) { - const char *controller = options_get_string(&machine->options(), OPTION_CTRLR); + const char *controller = machine->options().ctrlr(); config_type *type; int loaded = 0; @@ -114,7 +114,7 @@ int config_load_settings(running_machine *machine) if (controller[0] != 0) { /* open the config file */ - emu_file file(machine->options(), SEARCHPATH_CTRLR, OPEN_FLAG_READ); + emu_file file(machine->options().ctrlr_path(), OPEN_FLAG_READ); file_error filerr = file.open(controller, ".cfg"); if (filerr != FILERR_NONE) @@ -126,7 +126,7 @@ int config_load_settings(running_machine *machine) } /* next load the defaults file */ - emu_file file(machine->options(), SEARCHPATH_CONFIG, OPEN_FLAG_READ); + emu_file file(machine->options().cfg_directory(), OPEN_FLAG_READ); file_error filerr = file.open("default.cfg"); if (filerr == FILERR_NONE) config_load_xml(machine, file, CONFIG_TYPE_DEFAULT); @@ -155,7 +155,7 @@ void config_save_settings(running_machine *machine) (*type->save)(machine, CONFIG_TYPE_INIT, NULL); /* save the defaults file */ - emu_file file(machine->options(), SEARCHPATH_CONFIG, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); + emu_file file(machine->options().cfg_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); file_error filerr = file.open("default.cfg"); if (filerr == FILERR_NONE) config_save_xml(machine, file, CONFIG_TYPE_DEFAULT); diff --git a/src/emu/crsshair.c b/src/emu/crsshair.c index 2c3d377259b..e098e38ea0a 100644 --- a/src/emu/crsshair.c +++ b/src/emu/crsshair.c @@ -158,7 +158,7 @@ static void create_bitmap(running_machine *machine, int player) global_free(global.bitmap[player]); machine->render().texture_free(global.texture[player]); - emu_file crossfile(machine->options(), OPTION_CROSSHAIRPATH, OPEN_FLAG_READ); + emu_file crossfile(machine->options().crosshair_path(), OPEN_FLAG_READ); if (global.name[player][0] != 0) { /* look for user specified file */ diff --git a/src/emu/debug/debugcmd.c b/src/emu/debug/debugcmd.c index 823abab8927..93d5edd9400 100644 --- a/src/emu/debug/debugcmd.c +++ b/src/emu/debug/debugcmd.c @@ -372,7 +372,7 @@ void debug_command_init(running_machine *machine) machine->add_notifier(MACHINE_NOTIFY_EXIT, debug_command_exit); /* set up the initial debugscript if specified */ - name = options_get_string(&machine->options(), OPTION_DEBUGSCRIPT); + name = machine->options().debug_script(); if (name[0] != 0) debug_cpu_source_script(machine, name); } @@ -2503,7 +2503,7 @@ static void execute_snap(running_machine *machine, int ref, int params, const ch astring fname(filename); if (fname.find(0, ".png") == -1) fname.cat(".png"); - emu_file file(machine->options(), SEARCHPATH_SCREENSHOT, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); + emu_file file(machine->options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); file_error filerr = file.open(fname); if (filerr != FILERR_NONE) diff --git a/src/emu/debug/debugcpu.c b/src/emu/debug/debugcpu.c index f959d20edc6..36d4af81dae 100644 --- a/src/emu/debug/debugcpu.c +++ b/src/emu/debug/debugcpu.c @@ -359,7 +359,7 @@ bool debug_comment_save(running_machine *machine) // flush the file if (found_comments) { - emu_file file(machine->options(), SEARCHPATH_COMMENT, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); + emu_file file(machine->options().comment_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); file_error filerr = file.open(machine->basename(), ".cmt"); if (filerr == FILERR_NONE) xml_file_write(root, file); @@ -385,7 +385,7 @@ bool debug_comment_save(running_machine *machine) bool debug_comment_load(running_machine *machine) { // open the file - emu_file file(machine->options(), SEARCHPATH_COMMENT, OPEN_FLAG_READ); + emu_file file(machine->options().comment_directory(), OPEN_FLAG_READ); file_error filerr = file.open(machine->basename(), ".cmt"); // if an error, just return false diff --git a/src/emu/devintrf.c b/src/emu/devintrf.c index 6f214b777ca..d80ade49c3e 100644 --- a/src/emu/devintrf.c +++ b/src/emu/devintrf.c @@ -269,7 +269,7 @@ void device_config_interface::interface_config_complete() // constructed //------------------------------------------------- -bool device_config_interface::interface_validity_check(core_options &options, const game_driver &driver) const +bool device_config_interface::interface_validity_check(emu_options &options, const game_driver &driver) const { return false; } @@ -336,7 +336,7 @@ void device_config::config_complete() // configuration has been constructed //------------------------------------------------- -bool device_config::validity_check(core_options &options, const game_driver &driver) const +bool device_config::validity_check(emu_options &options, const game_driver &driver) const { bool error = false; @@ -370,7 +370,7 @@ void device_config::device_config_complete() // the configuration has been constructed //------------------------------------------------- -bool device_config::device_validity_check(core_options &options, const game_driver &driver) const +bool device_config::device_validity_check(emu_options &options, const game_driver &driver) const { // indicate no error by default return false; diff --git a/src/emu/devintrf.h b/src/emu/devintrf.h index e5403690d34..1fdcea5b21a 100644 --- a/src/emu/devintrf.h +++ b/src/emu/devintrf.h @@ -292,7 +292,7 @@ public: // methods that wrap both interface-level and device-level behavior void config_complete(); - bool validity_check(core_options &options, const game_driver &driver) const; + bool validity_check(emu_options &options, const game_driver &driver) const; // configuration helpers static void static_set_clock(device_config *device, UINT32 clock) { device->m_clock = clock; } @@ -306,7 +306,7 @@ public: // optional operation overrides protected: virtual void device_config_complete(); - virtual bool device_validity_check(core_options &options, const game_driver &driver) const; + virtual bool device_validity_check(emu_options &options, const game_driver &driver) const; public: // optional information overrides @@ -361,7 +361,7 @@ public: // optional operation overrides virtual void interface_config_complete(); - virtual bool interface_validity_check(core_options &options, const game_driver &driver) const; + virtual bool interface_validity_check(emu_options &options, const game_driver &driver) const; protected: const device_config & m_device_config; diff --git a/src/emu/devlegcy.c b/src/emu/devlegcy.c index 1af3c5d46c0..0479a2e87d5 100644 --- a/src/emu/devlegcy.c +++ b/src/emu/devlegcy.c @@ -192,7 +192,7 @@ void legacy_device_config_base::static_set_inline_float(device_config *device, U // checks on a device configuration //------------------------------------------------- -bool legacy_device_config_base::device_validity_check(core_options &options, const game_driver &driver) const +bool legacy_device_config_base::device_validity_check(emu_options &options, const game_driver &driver) const { device_validity_check_func validity_func = reinterpret_cast<device_validity_check_func>(get_legacy_config_fct(DEVINFO_FCT_VALIDITY_CHECK)); if (validity_func != NULL) diff --git a/src/emu/devlegcy.h b/src/emu/devlegcy.h index 69972294a8b..01a772574b0 100644 --- a/src/emu/devlegcy.h +++ b/src/emu/devlegcy.h @@ -248,7 +248,7 @@ const device_type name = configclass::static_alloc_device_config #define DEVICE_GET_INFO_CALL(name) DEVICE_GET_INFO_NAME(name)(device, state, info) #define DEVICE_VALIDITY_CHECK_NAME(name) device_validity_check_##name -#define DEVICE_VALIDITY_CHECK(name) int DEVICE_VALIDITY_CHECK_NAME(name)(const game_driver *driver, const device_config *device, core_options &options) +#define DEVICE_VALIDITY_CHECK(name) int DEVICE_VALIDITY_CHECK_NAME(name)(const game_driver *driver, const device_config *device, emu_options &options) #define DEVICE_VALIDITY_CHECK_CALL(name) DEVICE_VALIDITY_CHECK_NAME(name)(driver, device) #define DEVICE_START_NAME(name) device_start_##name @@ -383,7 +383,7 @@ resource_pool &machine_get_pool(running_machine &machine); // device interface function types typedef void (*device_get_config_func)(const device_config *device, UINT32 state, deviceinfo *info); -typedef int (*device_validity_check_func)(const game_driver *driver, const device_config *device, core_options &options); +typedef int (*device_validity_check_func)(const game_driver *driver, const device_config *device, emu_options &options); typedef void (*device_start_func)(device_t *device); typedef void (*device_stop_func)(device_t *device); @@ -450,7 +450,7 @@ public: protected: // overrides - virtual bool device_validity_check(core_options &options, const game_driver &driver) const; + virtual bool device_validity_check(emu_options &options, const game_driver &driver) const; // access to legacy configuration info INT64 get_legacy_config_int(UINT32 state) const; diff --git a/src/emu/diexec.c b/src/emu/diexec.c index 43f28ecc8ba..ae703b650be 100644 --- a/src/emu/diexec.c +++ b/src/emu/diexec.c @@ -211,7 +211,7 @@ UINT32 device_config_execute_interface::execute_default_irq_vector() const // constructed //------------------------------------------------- -bool device_config_execute_interface::interface_validity_check(core_options &options, const game_driver &driver) const +bool device_config_execute_interface::interface_validity_check(emu_options &options, const game_driver &driver) const { const device_config *devconfig = crosscast<const device_config *>(this); bool error = false; diff --git a/src/emu/diexec.h b/src/emu/diexec.h index 9404c6e85de..65b398a4640 100644 --- a/src/emu/diexec.h +++ b/src/emu/diexec.h @@ -177,7 +177,7 @@ protected: virtual UINT32 execute_default_irq_vector() const; // optional operation overrides - virtual bool interface_validity_check(core_options &options, const game_driver &driver) const; + virtual bool interface_validity_check(emu_options &options, const game_driver &driver) const; bool m_disabled; device_interrupt_func m_vblank_interrupt; // for interrupts tied to VBLANK diff --git a/src/emu/dimemory.c b/src/emu/dimemory.c index 88845dac57a..4dafaf92cce 100644 --- a/src/emu/dimemory.c +++ b/src/emu/dimemory.c @@ -164,9 +164,9 @@ void device_config_memory_interface::static_set_addrmap(device_config *device, i // checks on the memory configuration //------------------------------------------------- -bool device_config_memory_interface::interface_validity_check(core_options &options, const game_driver &driver) const +bool device_config_memory_interface::interface_validity_check(emu_options &options, const game_driver &driver) const { - const device_config *devconfig = crosscast<const device_config *>(this); + const device_config *devconfig = &m_device_config; bool detected_overlap = DETECT_OVERLAPPING_MEMORY ? false : true; bool error = false; diff --git a/src/emu/dimemory.h b/src/emu/dimemory.h index 5cdbc12c544..023c9e60853 100644 --- a/src/emu/dimemory.h +++ b/src/emu/dimemory.h @@ -123,7 +123,7 @@ protected: virtual const address_space_config *memory_space_config(int spacenum) const = 0; // optional operation overrides - virtual bool interface_validity_check(core_options &options, const game_driver &driver) const; + virtual bool interface_validity_check(emu_options &options, const game_driver &driver) const; address_map_constructor m_address_map[ADDRESS_SPACES]; // address maps for each address space }; diff --git a/src/emu/disound.c b/src/emu/disound.c index e4ca9e4e1c7..4a1b31dc772 100644 --- a/src/emu/disound.c +++ b/src/emu/disound.c @@ -104,7 +104,7 @@ void device_config_sound_interface::static_reset_routes(device_config *device) // constructed //------------------------------------------------- -bool device_config_sound_interface::interface_validity_check(core_options &options, const game_driver &driver) const +bool device_config_sound_interface::interface_validity_check(emu_options &options, const game_driver &driver) const { bool error = false; diff --git a/src/emu/disound.h b/src/emu/disound.h index c51ec68439f..cb8a96af365 100644 --- a/src/emu/disound.h +++ b/src/emu/disound.h @@ -127,7 +127,7 @@ public: protected: // optional operation overrides - virtual bool interface_validity_check(core_options &options, const game_driver &driver) const; + virtual bool interface_validity_check(emu_options &options, const game_driver &driver) const; // internal state simple_list<sound_route> m_route_list; // list of sound routes diff --git a/src/emu/driver.c b/src/emu/driver.c index f27c12f6f7c..582d643168c 100644 --- a/src/emu/driver.c +++ b/src/emu/driver.c @@ -95,6 +95,21 @@ const game_driver *driver_get_clone(const game_driver *driver) /*------------------------------------------------- + driver_get_searchpath - return a search path + for a given driver +-------------------------------------------------*/ + +const char *driver_get_searchpath(const game_driver &driver, astring &string) +{ + // create the search path consisting of gamedrv[;parent[;...]] + string = driver.name; + for (const game_driver *parent = driver_get_clone(&driver); parent != NULL; parent = driver_get_clone(parent)) + string.cat(";").cat(parent->name); + return string; +} + + +/*------------------------------------------------- driver_list_get_approx_matches - find the best n matches to a driver name. -------------------------------------------------*/ diff --git a/src/emu/driver.h b/src/emu/driver.h index eb7aa6c3c35..fa38519c93f 100644 --- a/src/emu/driver.h +++ b/src/emu/driver.h @@ -190,6 +190,8 @@ const game_driver *driver_get_name(const char *name); const game_driver *driver_get_clone(const game_driver *driver); const game_driver *driver_get_compatible(const game_driver *drv); +const char *driver_get_searchpath(const game_driver &driver, astring &string); + void driver_list_get_approx_matches(const game_driver * const driverlist[], const char *name, int matches, const game_driver **list); int driver_list_get_count(const game_driver * const driverlist[]); diff --git a/src/emu/emucore.h b/src/emu/emucore.h index 086a4af1af7..b8801fc5159 100644 --- a/src/emu/emucore.h +++ b/src/emu/emucore.h @@ -308,6 +308,15 @@ public: osd_break_into_debugger(text); } + emu_fatalerror(int _exitcode, const char *format, ...) + : code(_exitcode) + { + va_list ap; + va_start(ap, format); + vsprintf(text, format, ap); + va_end(ap); + } + emu_fatalerror(int _exitcode, const char *format, va_list ap) : code(_exitcode) { diff --git a/src/emu/emuopts.c b/src/emu/emuopts.c index 4f1f677126d..730e09b3a29 100644 --- a/src/emu/emuopts.c +++ b/src/emu/emuopts.c @@ -4,8 +4,36 @@ Options file and command line management. - Copyright Nicola Salmoria and the MAME Team. - Visit http://mamedev.org for licensing and usage restrictions. +**************************************************************************** + + Copyright Aaron Giles + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name 'MAME' nor the names of its contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. ***************************************************************************/ @@ -16,296 +44,391 @@ -/*************************************************************************** - BUILT-IN (CORE) OPTIONS -***************************************************************************/ +//************************************************************************** +// CORE EMULATOR OPTIONS +//************************************************************************** -const options_entry mame_core_options[] = +const options_entry emu_options::s_option_entries[] = { - /* unadorned options - only a single one supported at the moment */ - { "<UNADORNED0>", NULL, 0, NULL }, - - /* config options */ - { NULL, NULL, OPTION_HEADER, "CORE CONFIGURATION OPTIONS" }, - { "readconfig;rc", "1", OPTION_BOOLEAN, "enable loading of configuration files" }, - { "writeconfig;wc", "0", OPTION_BOOLEAN, "writes configuration to (driver).ini on exit" }, - - /* seach path options */ - { NULL, NULL, OPTION_HEADER, "CORE SEARCH PATH OPTIONS" }, - { "rompath;rp;biospath;bp", "roms", 0, "path to ROMsets and hard disk images" }, - { "hashpath;hash_directory;hash","hash", 0, "path to hash files" }, - { "samplepath;sp", "samples", 0, "path to samplesets" }, - { "artpath;artwork_directory", "artwork", 0, "path to artwork files" }, - { "ctrlrpath;ctrlr_directory", "ctrlr", 0, "path to controller definitions" }, - { "inipath", ".;ini", 0, "path to ini files" }, - { "fontpath", ".", 0, "path to font files" }, - { "cheatpath", "cheat", 0, "path to cheat files" }, - { "crosshairpath", "crosshair", 0, "path to crosshair files" }, - - /* output directory options */ - { NULL, NULL, OPTION_HEADER, "CORE OUTPUT DIRECTORY OPTIONS" }, - { "cfg_directory", "cfg", 0, "directory to save configurations" }, - { "nvram_directory", "nvram", 0, "directory to save nvram contents" }, - { "memcard_directory", "memcard", 0, "directory to save memory card contents" }, - { "input_directory", "inp", 0, "directory to save input device logs" }, - { "state_directory", "sta", 0, "directory to save states" }, - { "snapshot_directory", "snap", 0, "directory to save screenshots" }, - { "diff_directory", "diff", 0, "directory to save hard drive image difference files" }, - { "comment_directory", "comments", 0, "directory to save debugger comments" }, - - /* state/playback options */ - { NULL, NULL, OPTION_HEADER, "CORE STATE/PLAYBACK OPTIONS" }, - { "state", NULL, 0, "saved state to load" }, - { "autosave", "0", OPTION_BOOLEAN, "enable automatic restore at startup, and automatic save at exit time" }, - { "playback;pb", NULL, 0, "playback an input file" }, - { "record;rec", NULL, 0, "record an input file" }, - { "mngwrite", NULL, 0, "optional filename to write a MNG movie of the current session" }, - { "aviwrite", NULL, 0, "optional filename to write an AVI movie of the current session" }, - { "wavwrite", NULL, 0, "optional filename to write a WAV file of the current session" }, - { "snapname", "%g/%i", 0, "override of the default snapshot/movie naming; %g == gamename, %i == index" }, - { "snapsize", "auto", 0, "specify snapshot/movie resolution (<width>x<height>) or 'auto' to use minimal size " }, - { "snapview", "internal", 0, "specify snapshot/movie view or 'internal' to use internal pixel-aspect views" }, - { "burnin", "0", OPTION_BOOLEAN, "create burn-in snapshots for each screen" }, - - /* performance options */ - { NULL, NULL, OPTION_HEADER, "CORE PERFORMANCE OPTIONS" }, - { "autoframeskip;afs", "0", OPTION_BOOLEAN, "enable automatic frameskip selection" }, - { "frameskip;fs(0-10)", "0", 0, "set frameskip to fixed value, 0-10 (autoframeskip must be disabled)" }, - { "seconds_to_run;str", "0", 0, "number of emulated seconds to run before automatically exiting" }, - { "throttle", "1", OPTION_BOOLEAN, "enable throttling to keep game running in sync with real time" }, - { "sleep", "1", OPTION_BOOLEAN, "enable sleeping, which gives time back to other applications when idle" }, - { "speed(0.01-100)", "1.0", 0, "controls the speed of gameplay, relative to realtime; smaller numbers are slower" }, - { "refreshspeed;rs", "0", OPTION_BOOLEAN, "automatically adjusts the speed of gameplay to keep the refresh rate lower than the screen" }, - - /* rotation options */ - { NULL, NULL, OPTION_HEADER, "CORE ROTATION OPTIONS" }, - { "rotate", "1", OPTION_BOOLEAN, "rotate the game screen according to the game's orientation needs it" }, - { "ror", "0", OPTION_BOOLEAN, "rotate screen clockwise 90 degrees" }, - { "rol", "0", OPTION_BOOLEAN, "rotate screen counterclockwise 90 degrees" }, - { "autoror", "0", OPTION_BOOLEAN, "automatically rotate screen clockwise 90 degrees if vertical" }, - { "autorol", "0", OPTION_BOOLEAN, "automatically rotate screen counterclockwise 90 degrees if vertical" }, - { "flipx", "0", OPTION_BOOLEAN, "flip screen left-right" }, - { "flipy", "0", OPTION_BOOLEAN, "flip screen upside-down" }, - - /* artwork options */ - { NULL, NULL, OPTION_HEADER, "CORE ARTWORK OPTIONS" }, - { "artwork_crop;artcrop", "0", OPTION_BOOLEAN, "crop artwork to game screen size" }, - { "use_backdrops;backdrop", "1", OPTION_BOOLEAN, "enable backdrops if artwork is enabled and available" }, - { "use_overlays;overlay", "1", OPTION_BOOLEAN, "enable overlays if artwork is enabled and available" }, - { "use_bezels;bezel", "1", OPTION_BOOLEAN, "enable bezels if artwork is enabled and available" }, - - /* screen options */ - { NULL, NULL, OPTION_HEADER, "CORE SCREEN OPTIONS" }, - { "brightness(0.1-2.0)", "1.0", 0, "default game screen brightness correction" }, - { "contrast(0.1-2.0)", "1.0", 0, "default game screen contrast correction" }, - { "gamma(0.1-3.0)", "1.0", 0, "default game screen gamma correction" }, - { "pause_brightness(0.0-1.0)", "0.65", 0, "amount to scale the screen brightness when paused" }, - { "effect", "none", 0, "name of a PNG file to use for visual effects, or 'none'" }, - - /* vector options */ - { NULL, NULL, OPTION_HEADER, "CORE VECTOR OPTIONS" }, - { "antialias;aa", "1", OPTION_BOOLEAN, "use antialiasing when drawing vectors" }, - { "beam", "1.0", 0, "set vector beam width" }, - { "flicker", "0", 0, "set vector flicker effect" }, - - /* sound options */ - { NULL, NULL, OPTION_HEADER, "CORE SOUND OPTIONS" }, - { "sound", "1", OPTION_BOOLEAN, "enable sound output" }, - { "samplerate;sr(1000-1000000)", "48000", 0, "set sound output sample rate" }, - { "samples", "1", OPTION_BOOLEAN, "enable the use of external samples if available" }, - { "volume;vol", "0", 0, "sound volume in decibels (-32 min, 0 max)" }, - - /* input options */ - { NULL, NULL, OPTION_HEADER, "CORE INPUT OPTIONS" }, - { "coin_lockout;coinlock", "1", OPTION_BOOLEAN, "enable coin lockouts to actually lock out coins" }, - { "ctrlr", NULL, 0, "preconfigure for specified controller" }, - { "mouse", "0", OPTION_BOOLEAN, "enable mouse input" }, - { "joystick;joy", "1", OPTION_BOOLEAN, "enable joystick input" }, - { "lightgun;gun", "0", OPTION_BOOLEAN, "enable lightgun input" }, - { "multikeyboard;multikey", "0", OPTION_BOOLEAN, "enable separate input from each keyboard device (if present)" }, - { "multimouse", "0", OPTION_BOOLEAN, "enable separate input from each mouse device (if present)" }, - { "steadykey;steady", "0", OPTION_BOOLEAN, "enable steadykey support" }, - { "offscreen_reload;reload", "0", OPTION_BOOLEAN, "convert lightgun button 2 into offscreen reload" }, - { "joystick_map;joymap", "auto", 0, "explicit joystick map, or auto to auto-select" }, - { "joystick_deadzone;joy_deadzone;jdz", "0.3", 0, "center deadzone range for joystick where change is ignored (0.0 center, 1.0 end)" }, - { "joystick_saturation;joy_saturation;jsat", "0.85", 0, "end of axis saturation range for joystick where change is ignored (0.0 center, 1.0 end)" }, - { "natural;nat", "0", OPTION_BOOLEAN, "specifies whether to use a natural keyboard or not" }, - { "uimodekey;umk", "auto", 0, "specifies the key used to toggle between full and partial UI mode" }, - - - /* input autoenable options */ - { NULL, NULL, OPTION_HEADER, "CORE INPUT AUTOMATIC ENABLE OPTIONS" }, - { "paddle_device;paddle", "keyboard", 0, "enable (none|keyboard|mouse|lightgun|joystick) if a paddle control is present" }, - { "adstick_device;adstick", "keyboard", 0, "enable (none|keyboard|mouse|lightgun|joystick) if an analog joystick control is present" }, - { "pedal_device;pedal", "keyboard", 0, "enable (none|keyboard|mouse|lightgun|joystick) if a pedal control is present" }, - { "dial_device;dial", "keyboard", 0, "enable (none|keyboard|mouse|lightgun|joystick) if a dial control is present" }, - { "trackball_device;trackball", "keyboard", 0, "enable (none|keyboard|mouse|lightgun|joystick) if a trackball control is present" }, - { "lightgun_device", "keyboard", 0, "enable (none|keyboard|mouse|lightgun|joystick) if a lightgun control is present" }, - { "positional_device", "keyboard", 0, "enable (none|keyboard|mouse|lightgun|joystick) if a positional control is present" }, - { "mouse_device", "mouse", 0, "enable (none|keyboard|mouse|lightgun|joystick) if a mouse control is present" }, - - /* debugging options */ - { NULL, NULL, OPTION_HEADER, "CORE DEBUGGING OPTIONS" }, - { "log", "0", OPTION_BOOLEAN, "generate an error.log file" }, - { "verbose;v", "0", OPTION_BOOLEAN, "display additional diagnostic information" }, - { "update_in_pause", "0", OPTION_BOOLEAN, "keep calling video updates while in pause" }, - { "debug;d", "0", OPTION_BOOLEAN, "enable/disable debugger" }, - { "debugscript", NULL, 0, "script for debugger" }, - { "debug_internal;di", "0", OPTION_BOOLEAN, "use the internal debugger for debugging" }, - - /* misc options */ - { NULL, NULL, OPTION_HEADER, "CORE MISC OPTIONS" }, - { "bios", NULL, OPTION_DRIVER_ONLY,"select the system BIOS to use" }, - { "cheat;c", "0", OPTION_BOOLEAN, "enable cheat subsystem" }, - { "skip_gameinfo", "0", OPTION_BOOLEAN, "skip displaying the information screen at startup" }, - { "uifont", "default", 0, "specify a font to use" }, - { "ramsize;ram", NULL, OPTION_DRIVER_ONLY,"size of RAM (if supported by driver)" }, - - /* image device options */ - { OPTION_ADDED_DEVICE_OPTIONS, "0", OPTION_BOOLEAN | OPTION_INTERNAL, "image device-specific options have been added" }, + // unadorned options - only a single one supported at the moment + { OPTION_SYSTEMNAME, NULL, OPTION_STRING, NULL }, + + // config options + { NULL, NULL, OPTION_HEADER, "CORE CONFIGURATION OPTIONS" }, + { OPTION_READCONFIG ";rc", "1", OPTION_BOOLEAN, "enable loading of configuration files" }, + { OPTION_WRITECONFIG ";wc", "0", OPTION_BOOLEAN, "writes configuration to (driver).ini on exit" }, + + // seach path options + { NULL, NULL, OPTION_HEADER, "CORE SEARCH PATH OPTIONS" }, + { OPTION_MEDIAPATH ";rp;biospath;bp", "roms", OPTION_STRING, "path to ROMsets and hard disk images" }, + { OPTION_HASHPATH ";hash_directory;hash", "hash", OPTION_STRING, "path to hash files" }, + { OPTION_SAMPLEPATH ";sp", "samples", OPTION_STRING, "path to samplesets" }, + { OPTION_ARTPATH, "artwork", OPTION_STRING, "path to artwork files" }, + { OPTION_CTRLRPATH, "ctrlr", OPTION_STRING, "path to controller definitions" }, + { OPTION_INIPATH, ".;ini", OPTION_STRING, "path to ini files" }, + { OPTION_FONTPATH, ".", OPTION_STRING, "path to font files" }, + { OPTION_CHEATPATH, "cheat", OPTION_STRING, "path to cheat files" }, + { OPTION_CROSSHAIRPATH, "crosshair", OPTION_STRING, "path to crosshair files" }, + + // output directory options + { NULL, NULL, OPTION_HEADER, "CORE OUTPUT DIRECTORY OPTIONS" }, + { OPTION_CFG_DIRECTORY, "cfg", OPTION_STRING, "directory to save configurations" }, + { OPTION_NVRAM_DIRECTORY, "nvram", OPTION_STRING, "directory to save nvram contents" }, + { OPTION_MEMCARD_DIRECTORY, "memcard", OPTION_STRING, "directory to save memory card contents" }, + { OPTION_INPUT_DIRECTORY, "inp", OPTION_STRING, "directory to save input device logs" }, + { OPTION_STATE_DIRECTORY, "sta", OPTION_STRING, "directory to save states" }, + { OPTION_SNAPSHOT_DIRECTORY, "snap", OPTION_STRING, "directory to save screenshots" }, + { OPTION_DIFF_DIRECTORY, "diff", OPTION_STRING, "directory to save hard drive image difference files" }, + { OPTION_COMMENT_DIRECTORY, "comments", OPTION_STRING, "directory to save debugger comments" }, + + // state/playback options + { NULL, NULL, OPTION_HEADER, "CORE STATE/PLAYBACK OPTIONS" }, + { OPTION_STATE, NULL, OPTION_STRING, "saved state to load" }, + { OPTION_AUTOSAVE, "0", OPTION_BOOLEAN, "enable automatic restore at startup, and automatic save at exit time" }, + { OPTION_PLAYBACK ";pb", NULL, OPTION_STRING, "playback an input file" }, + { OPTION_RECORD ";rec", NULL, OPTION_STRING, "record an input file" }, + { OPTION_MNGWRITE, NULL, OPTION_STRING, "optional filename to write a MNG movie of the current session" }, + { OPTION_AVIWRITE, NULL, OPTION_STRING, "optional filename to write an AVI movie of the current session" }, + { OPTION_WAVWRITE, NULL, OPTION_STRING, "optional filename to write a WAV file of the current session" }, + { OPTION_SNAPNAME, "%g/%i", OPTION_STRING, "override of the default snapshot/movie naming; %g == gamename, %i == index" }, + { OPTION_SNAPSIZE, "auto", OPTION_STRING, "specify snapshot/movie resolution (<width>x<height>) or 'auto' to use minimal size " }, + { OPTION_SNAPVIEW, "internal", OPTION_STRING, "specify snapshot/movie view or 'internal' to use internal pixel-aspect views" }, + { OPTION_BURNIN, "0", OPTION_BOOLEAN, "create burn-in snapshots for each screen" }, + + // performance options + { NULL, NULL, OPTION_HEADER, "CORE PERFORMANCE OPTIONS" }, + { OPTION_AUTOFRAMESKIP ";afs", "0", OPTION_BOOLEAN, "enable automatic frameskip selection" }, + { OPTION_FRAMESKIP ";fs(0-10)", "0", OPTION_INTEGER, "set frameskip to fixed value, 0-10 (autoframeskip must be disabled)" }, + { OPTION_SECONDS_TO_RUN ";str", "0", OPTION_INTEGER, "number of emulated seconds to run before automatically exiting" }, + { OPTION_THROTTLE, "1", OPTION_BOOLEAN, "enable throttling to keep game running in sync with real time" }, + { OPTION_SLEEP, "1", OPTION_BOOLEAN, "enable sleeping, which gives time back to other applications when idle" }, + { OPTION_SPEED "(0.01-100)", "1.0", OPTION_FLOAT, "controls the speed of gameplay, relative to realtime; smaller numbers are slower" }, + { OPTION_REFRESHSPEED ";rs", "0", OPTION_BOOLEAN, "automatically adjusts the speed of gameplay to keep the refresh rate lower than the screen" }, + + // rotation options + { NULL, NULL, OPTION_HEADER, "CORE ROTATION OPTIONS" }, + { OPTION_ROTATE, "1", OPTION_BOOLEAN, "rotate the game screen according to the game's orientation needs it" }, + { OPTION_ROR, "0", OPTION_BOOLEAN, "rotate screen clockwise 90 degrees" }, + { OPTION_ROL, "0", OPTION_BOOLEAN, "rotate screen counterclockwise 90 degrees" }, + { OPTION_AUTOROR, "0", OPTION_BOOLEAN, "automatically rotate screen clockwise 90 degrees if vertical" }, + { OPTION_AUTOROL, "0", OPTION_BOOLEAN, "automatically rotate screen counterclockwise 90 degrees if vertical" }, + { OPTION_FLIPX, "0", OPTION_BOOLEAN, "flip screen left-right" }, + { OPTION_FLIPY, "0", OPTION_BOOLEAN, "flip screen upside-down" }, + + // artwork options + { NULL, NULL, OPTION_HEADER, "CORE ARTWORK OPTIONS" }, + { OPTION_ARTWORK_CROP ";artcrop", "0", OPTION_BOOLEAN, "crop artwork to game screen size" }, + { OPTION_USE_BACKDROPS ";backdrop", "1", OPTION_BOOLEAN, "enable backdrops if artwork is enabled and available" }, + { OPTION_USE_OVERLAYS ";overlay", "1", OPTION_BOOLEAN, "enable overlays if artwork is enabled and available" }, + { OPTION_USE_BEZELS ";bezel", "1", OPTION_BOOLEAN, "enable bezels if artwork is enabled and available" }, + + // screen options + { NULL, NULL, OPTION_HEADER, "CORE SCREEN OPTIONS" }, + { OPTION_BRIGHTNESS "(0.1-2.0)", "1.0", OPTION_FLOAT, "default game screen brightness correction" }, + { OPTION_CONTRAST "(0.1-2.0)", "1.0", OPTION_FLOAT, "default game screen contrast correction" }, + { OPTION_GAMMA "(0.1-3.0)", "1.0", OPTION_FLOAT, "default game screen gamma correction" }, + { OPTION_PAUSE_BRIGHTNESS "(0.0-1.0)", "0.65", OPTION_FLOAT, "amount to scale the screen brightness when paused" }, + { OPTION_EFFECT, "none", OPTION_STRING, "name of a PNG file to use for visual effects, or 'none'" }, + + // vector options + { NULL, NULL, OPTION_HEADER, "CORE VECTOR OPTIONS" }, + { OPTION_ANTIALIAS ";aa", "1", OPTION_BOOLEAN, "use antialiasing when drawing vectors" }, + { OPTION_BEAM, "1.0", OPTION_FLOAT, "set vector beam width" }, + { OPTION_FLICKER, "0", OPTION_FLOAT, "set vector flicker effect" }, + + // sound options + { NULL, NULL, OPTION_HEADER, "CORE SOUND OPTIONS" }, + { OPTION_SOUND, "1", OPTION_BOOLEAN, "enable sound output" }, + { OPTION_SAMPLERATE ";sr(1000-1000000)", "48000", OPTION_INTEGER, "set sound output sample rate" }, + { OPTION_SAMPLES, "1", OPTION_BOOLEAN, "enable the use of external samples if available" }, + { OPTION_VOLUME ";vol", "0", OPTION_INTEGER, "sound volume in decibels (-32 min, 0 max)" }, + + // input options + { NULL, NULL, OPTION_HEADER, "CORE INPUT OPTIONS" }, + { OPTION_COIN_LOCKOUT ";coinlock", "1", OPTION_BOOLEAN, "enable coin lockouts to actually lock out coins" }, + { OPTION_CTRLR, NULL, OPTION_STRING, "preconfigure for specified controller" }, + { OPTION_MOUSE, "0", OPTION_BOOLEAN, "enable mouse input" }, + { OPTION_JOYSTICK ";joy", "1", OPTION_BOOLEAN, "enable joystick input" }, + { OPTION_LIGHTGUN ";gun", "0", OPTION_BOOLEAN, "enable lightgun input" }, + { OPTION_MULTIKEYBOARD ";multikey", "0", OPTION_BOOLEAN, "enable separate input from each keyboard device (if present)" }, + { OPTION_MULTIMOUSE, "0", OPTION_BOOLEAN, "enable separate input from each mouse device (if present)" }, + { OPTION_STEADYKEY ";steady", "0", OPTION_BOOLEAN, "enable steadykey support" }, + { OPTION_OFFSCREEN_RELOAD ";reload", "0", OPTION_BOOLEAN, "convert lightgun button 2 into offscreen reload" }, + { OPTION_JOYSTICK_MAP ";joymap", "auto", OPTION_STRING, "explicit joystick map, or auto to auto-select" }, + { OPTION_JOYSTICK_DEADZONE ";joy_deadzone;jdz", "0.3", OPTION_FLOAT, "center deadzone range for joystick where change is ignored (0.0 center, 1.0 end)" }, + { OPTION_JOYSTICK_SATURATION ";joy_saturation;jsat", "0.85", OPTION_FLOAT, "end of axis saturation range for joystick where change is ignored (0.0 center, 1.0 end)" }, + { OPTION_NATURAL_KEYBOARD ";nat", "0", OPTION_BOOLEAN, "specifies whether to use a natural keyboard or not" }, + + // input autoenable options + { NULL, NULL, OPTION_HEADER, "CORE INPUT AUTOMATIC ENABLE OPTIONS" }, + { OPTION_PADDLE_DEVICE ";paddle", "keyboard", OPTION_STRING, "enable (none|keyboard|mouse|lightgun|joystick) if a paddle control is present" }, + { OPTION_ADSTICK_DEVICE ";adstick", "keyboard", OPTION_STRING, "enable (none|keyboard|mouse|lightgun|joystick) if an analog joystick control is present" }, + { OPTION_PEDAL_DEVICE ";pedal", "keyboard", OPTION_STRING, "enable (none|keyboard|mouse|lightgun|joystick) if a pedal control is present" }, + { OPTION_DIAL_DEVICE ";dial", "keyboard", OPTION_STRING, "enable (none|keyboard|mouse|lightgun|joystick) if a dial control is present" }, + { OPTION_TRACKBALL_DEVICE ";trackball", "keyboard", OPTION_STRING, "enable (none|keyboard|mouse|lightgun|joystick) if a trackball control is present" }, + { OPTION_LIGHTGUN_DEVICE, "keyboard", OPTION_STRING, "enable (none|keyboard|mouse|lightgun|joystick) if a lightgun control is present" }, + { OPTION_POSITIONAL_DEVICE, "keyboard", OPTION_STRING, "enable (none|keyboard|mouse|lightgun|joystick) if a positional control is present" }, + { OPTION_MOUSE_DEVICE, "mouse", OPTION_STRING, "enable (none|keyboard|mouse|lightgun|joystick) if a mouse control is present" }, + + // debugging options + { NULL, NULL, OPTION_HEADER, "CORE DEBUGGING OPTIONS" }, + { OPTION_LOG, "0", OPTION_BOOLEAN, "generate an error.log file" }, + { OPTION_VERBOSE ";v", "0", OPTION_BOOLEAN, "display additional diagnostic information" }, + { OPTION_UPDATEINPAUSE, "0", OPTION_BOOLEAN, "keep calling video updates while in pause" }, + { OPTION_DEBUG ";d", "0", OPTION_BOOLEAN, "enable/disable debugger" }, + { OPTION_DEBUGSCRIPT, NULL, OPTION_STRING, "script for debugger" }, + { OPTION_DEBUG_INTERNAL ";di", "0", OPTION_BOOLEAN, "use the internal debugger for debugging" }, + + // misc options + { NULL, NULL, OPTION_HEADER, "CORE MISC OPTIONS" }, + { OPTION_BIOS, NULL, OPTION_STRING, "select the system BIOS to use" }, + { OPTION_CHEAT ";c", "0", OPTION_BOOLEAN, "enable cheat subsystem" }, + { OPTION_SKIP_GAMEINFO, "0", OPTION_BOOLEAN, "skip displaying the information screen at startup" }, + { OPTION_UI_FONT, "default", OPTION_STRING, "specify a font to use" }, + { OPTION_RAMSIZE ";ram", NULL, OPTION_STRING, "size of RAM (if supported by driver)" }, { NULL } }; -/*************************************************************************** - CORE IMPLEMENTATION -***************************************************************************/ +//************************************************************************** +// EMU OPTIONS +//************************************************************************** -/*------------------------------------------------- - memory_error - report a memory error --------------------------------------------------*/ +//------------------------------------------------- +// emu_options - constructor +//------------------------------------------------- -static void memory_error(const char *message) +emu_options::emu_options() { - fatalerror("%s", message); + add_entries(s_option_entries); } +//------------------------------------------------- +// add_device_options - add all of the device +// options for the configured system +//------------------------------------------------- -/*------------------------------------------------- - mame_puts_info - mame_puts_warning - mame_puts_error --------------------------------------------------*/ - -static void mame_puts_info(const char *s) +void emu_options::add_device_options() { - mame_printf_info("%s", s); -} + // remove any existing device options + remove_device_options(); -static void mame_puts_warning(const char *s) -{ - mame_printf_warning("%s", s); + // look up the system configured by name; if no match, do nothing + const game_driver *cursystem = system(); + if (cursystem == NULL) + return; + + // create the configuration + machine_config config(*cursystem); + + // iterate through all image devices + const device_config_image_interface *image = NULL; + bool first = true; + options_entry entry[2] = { { 0 }, { 0 } }; + for (bool gotone = config.m_devicelist.first(image); gotone; gotone = image->next(image)) + { + // first device? add the header as to be pretty + if (first) + { + first = false; + entry[0].name = NULL; + entry[0].description = "IMAGE DEVICES"; + entry[0].flags = OPTION_HEADER | OPTION_FLAG_DEVICE; + add_entries(entry); + } + + // retrieve info about the device instance + astring option_name; + option_name.printf("%s;%s", image->instance_name(), image->brief_instance_name()); + + // add the option + entry[0].name = option_name; + entry[0].description = NULL; + entry[0].flags = OPTION_STRING | OPTION_FLAG_DEVICE; + add_entries(entry, true); + } } -static void mame_puts_error(const char *s) + +//------------------------------------------------- +// remove_device_options - remove device options +//------------------------------------------------- + +void emu_options::remove_device_options() { - mame_printf_error("%s", s); + // iterate through options and remove interesting ones + entry *nextentry; + for (entry *curentry = first(); curentry != NULL; curentry = nextentry) + { + // pre-fetch the next entry in case we delete this one + nextentry = curentry->next(); + + // if this is a device option, nuke it + if ((curentry->flags() & OPTION_FLAG_DEVICE) != 0) + remove_entry(*curentry); + } } -/*------------------------------------------------- - image_get_device_option - accesses a device - option --------------------------------------------------*/ -const char *image_get_device_option(device_image_interface *image) -{ - const char *result = NULL; +//------------------------------------------------- +// parse_command_line - parse the command line +// and update the devices +//------------------------------------------------- - if (options_get_bool(&image->device().machine->options(), OPTION_ADDED_DEVICE_OPTIONS)) +bool emu_options::parse_command_line(int argc, char *argv[], astring &error_string) +{ + // remember the original system name + astring old_system_name(system_name()); + + // parse as normal + bool result = core_options::parse_command_line(argc, argv, OPTION_PRIORITY_CMDLINE, error_string); + + // if the system name changed, fix up the device options + if (old_system_name != system_name()) { - /* access the option */ - result = options_get_string_priority(&image->device().machine->options(), image->image_config().instance_name(), OPTION_PRIORITY_DRIVER_INI); + add_device_options(); + + // if we failed the first time, try parsing again with the new options in place + if (!result) + result = core_options::parse_command_line(argc, argv, OPTION_PRIORITY_CMDLINE, error_string); } return result; } -/*------------------------------------------------- - image_add_device_options - add all of the device - options for a specified device --------------------------------------------------*/ - -void image_add_device_options(core_options *opts, const game_driver *driver) -{ - int index = 0; - const device_config_image_interface *image = NULL; - /* create the configuration */ - machine_config config(*driver); +//------------------------------------------------- +// parse_standard_inis - parse the standard set +// of INI files +//------------------------------------------------- - /* enumerate our callback for every device */ - /* loop on each device instance */ - for (bool gotone = config.m_devicelist.first(image); gotone; gotone = image->next(image)) +void emu_options::parse_standard_inis(astring &error_string) +{ + // start with an empty string + error_string.reset(); + + // parse the INI file defined by the platform (e.g., "mame.ini") + // we do this twice so that the first file can change the INI path + parse_one_ini(CONFIGNAME, OPTION_PRIORITY_MAME_INI); + parse_one_ini(CONFIGNAME, OPTION_PRIORITY_MAME_INI, &error_string); + + // debug mode: parse "debug.ini" as well + if (debug()) + parse_one_ini("debug", OPTION_PRIORITY_DEBUG_INI, &error_string); + + // if we have a valid system driver, parse system-specific INI files + const game_driver *cursystem = system(); + if (cursystem == NULL) + return; + + // parse "vertical.ini" or "horizont.ini" + if (cursystem->flags & ORIENTATION_SWAP_XY) + parse_one_ini("vertical", OPTION_PRIORITY_ORIENTATION_INI, &error_string); + else + parse_one_ini("horizont", OPTION_PRIORITY_ORIENTATION_INI, &error_string); + + // parse "vector.ini" for vector games { - options_entry entry[2]; - astring dev_full_name; + machine_config config(*cursystem); + for (const screen_device_config *devconfig = config.first_screen(); devconfig != NULL; devconfig = devconfig->next_screen()) + if (devconfig->screen_type() == SCREEN_TYPE_VECTOR) + { + parse_one_ini("vector", OPTION_PRIORITY_VECTOR_INI, &error_string); + break; + } + } - /* first device? add the header as to be pretty */ - if (index == 0) - { - memset(entry, 0, sizeof(entry)); - entry[0].description = "IMAGE DEVICES"; - entry[0].flags = OPTION_HEADER; - options_add_entries(opts, entry); - } + // next parse "source/<sourcefile>.ini"; if that doesn't exist, try <sourcefile>.ini + astring sourcename; + core_filename_extract_base(&sourcename, cursystem->source_file, TRUE)->ins(0, "source" PATH_SEPARATOR); + if (!parse_one_ini(sourcename, OPTION_PRIORITY_SOURCE_INI, &error_string)) + { + core_filename_extract_base(&sourcename, cursystem->source_file, TRUE); + parse_one_ini(sourcename, OPTION_PRIORITY_SOURCE_INI, &error_string); + } - /* retrieve info about the device instance */ - dev_full_name.printf("%s;%s", image->instance_name(), image->brief_instance_name()); + // then parse the grandparent, parent, and system-specific INIs + const game_driver *parent = driver_get_clone(cursystem); + const game_driver *gparent = (parent != NULL) ? driver_get_clone(parent) : NULL; + if (gparent != NULL) + parse_one_ini(gparent->name, OPTION_PRIORITY_GPARENT_INI, &error_string); + if (parent != NULL) + parse_one_ini(parent->name, OPTION_PRIORITY_PARENT_INI, &error_string); + parse_one_ini(cursystem->name, OPTION_PRIORITY_DRIVER_INI, &error_string); +} - /* add the option */ - memset(entry, 0, sizeof(entry)); - entry[0].name = dev_full_name; - options_add_entries(opts, entry, TRUE); - index++; - } +//------------------------------------------------- +// system - return a pointer to the specified +// system driver, or NULL if no match +//------------------------------------------------- - /* record that we've added device options */ - options_set_bool(opts, OPTION_ADDED_DEVICE_OPTIONS, TRUE, OPTION_PRIORITY_CMDLINE); +const game_driver *emu_options::system() const +{ + astring tempstr; + return driver_get_name(*core_filename_extract_base(&tempstr, system_name(), TRUE)); } -/*------------------------------------------------- - image_driver_name_callback - called when we - parse the driver name, so we can add options - specific to that driver --------------------------------------------------*/ -static void image_driver_name_callback(core_options *opts, const char *arg) -{ - const game_driver *driver; +//------------------------------------------------- +// set_system_name - set a new system name +//------------------------------------------------- - /* only add these options if we have not yet added them */ - if (!options_get_bool(opts, OPTION_ADDED_DEVICE_OPTIONS)) +void emu_options::set_system_name(const char *name) +{ + // remember the original system name + astring old_system_name(system_name()); + + // if the system name changed, fix up the device options + if (old_system_name != name) { - driver = driver_get_name(arg); - if (driver != NULL) - { - image_add_device_options(opts, driver); - } + // first set the new name + astring error; + set_value(OPTION_SYSTEMNAME, name, OPTION_PRIORITY_CMDLINE, error); + assert(!error); + + // then add the options + add_device_options(); } } -/*------------------------------------------------- - mame_options_init - create core MAME options --------------------------------------------------*/ +//------------------------------------------------- +// device_option - return the value of the +// device-specific option +//------------------------------------------------- + +const char *emu_options::device_option(device_image_interface &image) +{ + return image.device().machine->options().value(image.image_config().instance_name()); +} + + +//------------------------------------------------- +// parse_one_ini - parse a single INI file +//------------------------------------------------- -core_options *mame_options_init(const options_entry *entries) +bool emu_options::parse_one_ini(const char *basename, int priority, astring *error_string) { - /* create MAME core options */ - core_options *opts = options_create(memory_error); + // don't parse if it has been disabled + if (!read_config()) + return false; + + // open the file; if we fail, that's ok + emu_file file(ini_path(), OPEN_FLAG_READ); + file_error filerr = file.open(basename, ".ini"); + if (filerr != FILERR_NONE) + return false; - /* set up output callbacks */ - options_set_output_callback(opts, OPTMSG_INFO, mame_puts_info); - options_set_output_callback(opts, OPTMSG_WARNING, mame_puts_warning); - options_set_output_callback(opts, OPTMSG_ERROR, mame_puts_error); + // parse the file + mame_printf_verbose("Parsing %s.ini\n", basename); + astring error; + bool result = parse_ini_file(file, priority, OPTION_PRIORITY_DRIVER_INI, error); - options_add_entries(opts, mame_core_options); - if (entries != NULL) - options_add_entries(opts, entries); + // append errors if requested + if (error && error_string != NULL) + error_string->catprintf("While parsing %s:\n%s\n", file.fullpath(), error.cstr()); - /* we need to dynamically add options when the device name is parsed */ - options_set_option_callback(opts, OPTION_GAMENAME, image_driver_name_callback); - return opts; + return result; } diff --git a/src/emu/emuopts.h b/src/emu/emuopts.h index 42661c7c4c2..6943338f16e 100644 --- a/src/emu/emuopts.h +++ b/src/emu/emuopts.h @@ -4,8 +4,36 @@ Options file and command line management. - Copyright Nicola Salmoria and the MAME Team. - Visit http://mamedev.org for licensing and usage restrictions. +**************************************************************************** + + Copyright Aaron Giles + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name 'MAME' nor the names of its contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. ***************************************************************************/ @@ -17,32 +45,37 @@ #include "options.h" - -/*************************************************************************** - CONSTANTS -***************************************************************************/ - -/* option priorities */ -#define OPTION_PRIORITY_CMDLINE OPTION_PRIORITY_HIGH -#define OPTION_PRIORITY_INI OPTION_PRIORITY_NORMAL -#define OPTION_PRIORITY_MAME_INI (OPTION_PRIORITY_NORMAL + 1) -#define OPTION_PRIORITY_DEBUG_INI (OPTION_PRIORITY_MAME_INI + 1) -#define OPTION_PRIORITY_ORIENTATION_INI (OPTION_PRIORITY_DEBUG_INI + 1) -#define OPTION_PRIORITY_VECTOR_INI (OPTION_PRIORITY_ORIENTATION_INI + 1) -#define OPTION_PRIORITY_SOURCE_INI (OPTION_PRIORITY_VECTOR_INI + 1) -#define OPTION_PRIORITY_GPARENT_INI (OPTION_PRIORITY_SOURCE_INI + 1) -#define OPTION_PRIORITY_PARENT_INI (OPTION_PRIORITY_GPARENT_INI + 1) -#define OPTION_PRIORITY_DRIVER_INI (OPTION_PRIORITY_PARENT_INI + 1) - -/* core options */ -#define OPTION_GAMENAME OPTION_UNADORNED(0) - -/* core configuration options */ +//************************************************************************** +// CONSTANTS +//************************************************************************** + +// option priorities +enum +{ + // command-line options are HIGH priority + OPTION_PRIORITY_CMDLINE = OPTION_PRIORITY_HIGH, + + // INI-based options are NORMAL priority, in increasing order: + OPTION_PRIORITY_INI = OPTION_PRIORITY_NORMAL, + OPTION_PRIORITY_MAME_INI, + OPTION_PRIORITY_DEBUG_INI, + OPTION_PRIORITY_ORIENTATION_INI, + OPTION_PRIORITY_VECTOR_INI, + OPTION_PRIORITY_SOURCE_INI, + OPTION_PRIORITY_GPARENT_INI, + OPTION_PRIORITY_PARENT_INI, + OPTION_PRIORITY_DRIVER_INI +}; + +// core options +#define OPTION_SYSTEMNAME core_options::unadorned(0) + +// core configuration options #define OPTION_READCONFIG "readconfig" #define OPTION_WRITECONFIG "writeconfig" -/* core search path options */ -#define OPTION_ROMPATH "rompath" +// core search path options +#define OPTION_MEDIAPATH "rompath" #define OPTION_HASHPATH "hashpath" #define OPTION_SAMPLEPATH "samplepath" #define OPTION_ARTPATH "artpath" @@ -52,7 +85,7 @@ #define OPTION_CHEATPATH "cheatpath" #define OPTION_CROSSHAIRPATH "crosshairpath" -/* core directory options */ +// core directory options #define OPTION_CFG_DIRECTORY "cfg_directory" #define OPTION_NVRAM_DIRECTORY "nvram_directory" #define OPTION_MEMCARD_DIRECTORY "memcard_directory" @@ -62,7 +95,7 @@ #define OPTION_DIFF_DIRECTORY "diff_directory" #define OPTION_COMMENT_DIRECTORY "comment_directory" -/* core state/playback options */ +// core state/playback options #define OPTION_STATE "state" #define OPTION_AUTOSAVE "autosave" #define OPTION_PLAYBACK "playback" @@ -75,7 +108,7 @@ #define OPTION_SNAPVIEW "snapview" #define OPTION_BURNIN "burnin" -/* core performance options */ +// core performance options #define OPTION_AUTOFRAMESKIP "autoframeskip" #define OPTION_FRAMESKIP "frameskip" #define OPTION_SECONDS_TO_RUN "seconds_to_run" @@ -84,7 +117,7 @@ #define OPTION_SPEED "speed" #define OPTION_REFRESHSPEED "refreshspeed" -/* core rotation options */ +// core rotation options #define OPTION_ROTATE "rotate" #define OPTION_ROR "ror" #define OPTION_ROL "rol" @@ -93,31 +126,31 @@ #define OPTION_FLIPX "flipx" #define OPTION_FLIPY "flipy" -/* core artwork options */ +// core artwork options #define OPTION_ARTWORK_CROP "artwork_crop" #define OPTION_USE_BACKDROPS "use_backdrops" #define OPTION_USE_OVERLAYS "use_overlays" #define OPTION_USE_BEZELS "use_bezels" -/* core screen options */ +// core screen options #define OPTION_BRIGHTNESS "brightness" #define OPTION_CONTRAST "contrast" #define OPTION_GAMMA "gamma" #define OPTION_PAUSE_BRIGHTNESS "pause_brightness" #define OPTION_EFFECT "effect" -/* core vector options */ +// core vector options #define OPTION_ANTIALIAS "antialias" #define OPTION_BEAM "beam" #define OPTION_FLICKER "flicker" -/* core sound options */ +// core sound options #define OPTION_SOUND "sound" #define OPTION_SAMPLERATE "samplerate" #define OPTION_SAMPLES "samples" #define OPTION_VOLUME "volume" -/* core input options */ +// core input options #define OPTION_COIN_LOCKOUT "coin_lockout" #define OPTION_CTRLR "ctrlr" #define OPTION_MOUSE "mouse" @@ -125,6 +158,14 @@ #define OPTION_LIGHTGUN "lightgun" #define OPTION_MULTIKEYBOARD "multikeyboard" #define OPTION_MULTIMOUSE "multimouse" +#define OPTION_STEADYKEY "steadykey" +#define OPTION_OFFSCREEN_RELOAD "offscreen_reload" +#define OPTION_JOYSTICK_MAP "joystick_map" +#define OPTION_JOYSTICK_DEADZONE "joystick_deadzone" +#define OPTION_JOYSTICK_SATURATION "joystick_saturation" +#define OPTION_NATURAL_KEYBOARD "natural" + +// input autoenable options #define OPTION_PADDLE_DEVICE "paddle_device" #define OPTION_ADSTICK_DEVICE "adstick_device" #define OPTION_PEDAL_DEVICE "pedal_device" @@ -133,57 +174,180 @@ #define OPTION_LIGHTGUN_DEVICE "lightgun_device" #define OPTION_POSITIONAL_DEVICE "positional_device" #define OPTION_MOUSE_DEVICE "mouse_device" -#define OPTION_JOYSTICK_MAP "joystick_map" -#define OPTION_JOYSTICK_DEADZONE "joystick_deadzone" -#define OPTION_JOYSTICK_SATURATION "joystick_saturation" -#define OPTION_STEADYKEY "steadykey" -#define OPTION_OFFSCREEN_RELOAD "offscreen_reload" -#define OPTION_NATURAL_KEYBOARD "natural" -/* core debugging options */ -#define OPTION_VERBOSE "verbose" +// core debugging options #define OPTION_LOG "log" +#define OPTION_VERBOSE "verbose" +#define OPTION_UPDATEINPAUSE "update_in_pause" #define OPTION_DEBUG "debug" #define OPTION_DEBUG_INTERNAL "debug_internal" #define OPTION_DEBUGSCRIPT "debugscript" -#define OPTION_UPDATEINPAUSE "update_in_pause" -/* core misc options */ +// core misc options #define OPTION_BIOS "bios" #define OPTION_CHEAT "cheat" #define OPTION_SKIP_GAMEINFO "skip_gameinfo" #define OPTION_UI_FONT "uifont" #define OPTION_RAMSIZE "ramsize" -/* image device options */ -#define OPTION_ADDED_DEVICE_OPTIONS "added_device_options" - - -/*************************************************************************** - GLOBALS -***************************************************************************/ - -extern const options_entry mame_core_options[]; +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** -/*************************************************************************** - TYPE DEFINITIONS -***************************************************************************/ - -/* referenced types from other classes */ +// forward references struct game_driver; -/*************************************************************************** - FUNCTION PROTOTYPES -***************************************************************************/ - -core_options *mame_options_init(const options_entry *entries); +class emu_options : public core_options +{ + static const UINT32 OPTION_FLAG_DEVICE = 0x80000000; + +public: + // construction/destruction + emu_options(); + + // parsing wrappers + bool parse_command_line(int argc, char *argv[], astring &error_string); + void parse_standard_inis(astring &error_string); + + // core options + const char *system_name() const { return value(OPTION_SYSTEMNAME); } + const game_driver *system() const; + void set_system_name(const char *name); + + // core configuration options + bool read_config() const { return bool_value(OPTION_READCONFIG); } + bool write_config() const { return bool_value(OPTION_WRITECONFIG); } + + // core search path options + const char *media_path() const { return value(OPTION_MEDIAPATH); } + const char *hash_path() const { return value(OPTION_HASHPATH); } + const char *sample_path() const { return value(OPTION_SAMPLEPATH); } + const char *art_path() const { return value(OPTION_ARTPATH); } + const char *ctrlr_path() const { return value(OPTION_CTRLRPATH); } + const char *ini_path() const { return value(OPTION_INIPATH); } + const char *font_path() const { return value(OPTION_FONTPATH); } + const char *cheat_path() const { return value(OPTION_CHEATPATH); } + const char *crosshair_path() const { return value(OPTION_CROSSHAIRPATH); } + + // core directory options + const char *cfg_directory() const { return value(OPTION_CFG_DIRECTORY); } + const char *nvram_directory() const { return value(OPTION_NVRAM_DIRECTORY); } + const char *memcard_directory() const { return value(OPTION_MEMCARD_DIRECTORY); } + const char *input_directory() const { return value(OPTION_INPUT_DIRECTORY); } + const char *state_directory() const { return value(OPTION_STATE_DIRECTORY); } + const char *snapshot_directory() const { return value(OPTION_SNAPSHOT_DIRECTORY); } + const char *diff_directory() const { return value(OPTION_DIFF_DIRECTORY); } + const char *comment_directory() const { return value(OPTION_COMMENT_DIRECTORY); } + + // core state/playback options + const char *state() const { return value(OPTION_STATE); } + bool autosave() const { return bool_value(OPTION_AUTOSAVE); } + const char *playback() const { return value(OPTION_PLAYBACK); } + const char *record() const { return value(OPTION_RECORD); } + const char *mng_write() const { return value(OPTION_MNGWRITE); } + const char *avi_write() const { return value(OPTION_AVIWRITE); } + const char *wav_write() const { return value(OPTION_WAVWRITE); } + const char *snap_name() const { return value(OPTION_SNAPNAME); } + const char *snap_size() const { return value(OPTION_SNAPSIZE); } + const char *snap_view() const { return value(OPTION_SNAPVIEW); } + bool burnin() const { return bool_value(OPTION_BURNIN); } + + // core performance options + bool auto_frameskip() const { return bool_value(OPTION_AUTOFRAMESKIP); } + int frameskip() const { return int_value(OPTION_FRAMESKIP); } + int seconds_to_run() const { return int_value(OPTION_SECONDS_TO_RUN); } + bool throttle() const { return bool_value(OPTION_THROTTLE); } + bool sleep() const { return bool_value(OPTION_SLEEP); } + float speed() const { return float_value(OPTION_SPEED); } + bool refresh_speed() const { return bool_value(OPTION_REFRESHSPEED); } + + // core rotation options + bool rotate() const { return bool_value(OPTION_ROTATE); } + bool ror() const { return bool_value(OPTION_ROR); } + bool rol() const { return bool_value(OPTION_ROL); } + bool auto_ror() const { return bool_value(OPTION_AUTOROR); } + bool auto_rol() const { return bool_value(OPTION_AUTOROL); } + bool flipx() const { return bool_value(OPTION_FLIPX); } + bool flipy() const { return bool_value(OPTION_FLIPY); } + + // core artwork options + bool artwork_crop() const { return bool_value(OPTION_ARTWORK_CROP); } + bool use_backdrops() const { return bool_value(OPTION_USE_BACKDROPS); } + bool use_overlays() const { return bool_value(OPTION_USE_OVERLAYS); } + bool use_bezels() const { return bool_value(OPTION_USE_BEZELS); } + + // core screen options + float brightness() const { return float_value(OPTION_BRIGHTNESS); } + float contrast() const { return float_value(OPTION_CONTRAST); } + float gamma() const { return float_value(OPTION_GAMMA); } + float pause_brightness() const { return float_value(OPTION_PAUSE_BRIGHTNESS); } + const char *effect() const { return value(OPTION_EFFECT); } + + // core vector options + bool antialias() const { return bool_value(OPTION_ANTIALIAS); } + float beam() const { return float_value(OPTION_BEAM); } + float flicker() const { return float_value(OPTION_FLICKER); } + + // core sound options + bool sound() const { return bool_value(OPTION_SOUND); } + int sample_rate() const { return int_value(OPTION_SAMPLERATE); } + bool samples() const { return bool_value(OPTION_SAMPLES); } + int volume() const { return int_value(OPTION_VOLUME); } + + // core input options + bool coin_lockout() const { return bool_value(OPTION_COIN_LOCKOUT); } + const char *ctrlr() const { return value(OPTION_CTRLR); } + bool mouse() const { return bool_value(OPTION_MOUSE); } + bool joystick() const { return bool_value(OPTION_JOYSTICK); } + bool lightgun() const { return bool_value(OPTION_LIGHTGUN); } + bool multi_keyboard() const { return bool_value(OPTION_MULTIKEYBOARD); } + bool multi_mouse() const { return bool_value(OPTION_MULTIMOUSE); } + const char *paddle_device() const { return value(OPTION_PADDLE_DEVICE); } + const char *adstick_device() const { return value(OPTION_ADSTICK_DEVICE); } + const char *pedal_device() const { return value(OPTION_PEDAL_DEVICE); } + const char *dial_device() const { return value(OPTION_DIAL_DEVICE); } + const char *trackball_device() const { return value(OPTION_TRACKBALL_DEVICE); } + const char *lightgun_device() const { return value(OPTION_LIGHTGUN_DEVICE); } + const char *positional_device() const { return value(OPTION_POSITIONAL_DEVICE); } + const char *mouse_device() const { return value(OPTION_MOUSE_DEVICE); } + const char *joystick_map() const { return value(OPTION_JOYSTICK_MAP); } + float joystick_deadzone() const { return float_value(OPTION_JOYSTICK_DEADZONE); } + float joystick_saturation() const { return float_value(OPTION_JOYSTICK_SATURATION); } + bool steadykey() const { return bool_value(OPTION_STEADYKEY); } + bool offscreen_reload() const { return bool_value(OPTION_OFFSCREEN_RELOAD); } + bool natural_keyboard() const { return bool_value(OPTION_NATURAL_KEYBOARD); } + + // core debugging options + bool verbose() const { return bool_value(OPTION_VERBOSE); } + bool log() const { return bool_value(OPTION_LOG); } + bool debug() const { return bool_value(OPTION_DEBUG); } + bool debug_internal() const { return bool_value(OPTION_DEBUG_INTERNAL); } + const char *debug_script() const { return value(OPTION_DEBUGSCRIPT); } + bool update_in_pause() const { return bool_value(OPTION_UPDATEINPAUSE); } + + // core misc options + const char *bios() const { return value(OPTION_BIOS); } + bool cheat() const { return bool_value(OPTION_CHEAT); } + bool skip_gameinfo() const { return bool_value(OPTION_SKIP_GAMEINFO); } + const char *ui_font() const { return value(OPTION_UI_FONT); } + const char *ram_size() const { return value(OPTION_RAMSIZE); } + + // device-specific options + const char *device_option(device_image_interface &image); + +private: + // device-specific option handling + void add_device_options(); + void remove_device_options(); + + // INI parsing helper + bool parse_one_ini(const char *basename, int priority, astring *error_string = NULL); + + static const options_entry s_option_entries[]; +}; -/* add the device options for a specified device */ -void image_add_device_options(core_options *opts, const game_driver *driver); -/* accesses a device option, by device and index */ -const char *image_get_device_option(device_image_interface *image); #endif /* __EMUOPTS_H__ */ diff --git a/src/emu/fileio.c b/src/emu/fileio.c index 2c8860c5070..d123fc2ff5d 100644 --- a/src/emu/fileio.c +++ b/src/emu/fileio.c @@ -40,7 +40,6 @@ #include "emu.h" #include "hash.h" #include "unzip.h" -#include "options.h" #include "fileio.h" @@ -56,8 +55,8 @@ const UINT32 OPEN_FLAG_HAS_CRC = 0x10000; // path_iterator - constructor //------------------------------------------------- -path_iterator::path_iterator(core_options &opts, const char *searchpath) - : m_base((searchpath != NULL && !osd_is_absolute_path(searchpath)) ? options_get_string(&opts, searchpath) : ""), +path_iterator::path_iterator(const char *rawsearchpath) + : m_base(rawsearchpath), m_current(m_base), m_index(0) { @@ -97,8 +96,8 @@ bool path_iterator::next(astring &buffer) // file_enumerator - constructor //------------------------------------------------- -file_enumerator::file_enumerator(core_options &options, const char *searchpath) - : m_iterator(options, searchpath), +file_enumerator::file_enumerator(const char *searchpath) + : m_iterator(searchpath), m_curdir(NULL), m_buflen(0) { @@ -159,9 +158,24 @@ const osd_directory_entry *file_enumerator::next() // emu_file - constructor //------------------------------------------------- -emu_file::emu_file(core_options &options, const char *searchpath, UINT32 openflags) +emu_file::emu_file(UINT32 openflags) : m_file(NULL), - m_iterator(options, searchpath), + m_iterator(""), + m_crc(0), + m_openflags(openflags), + m_zipfile(NULL), + m_zipdata(NULL), + m_ziplength(0), + m_remove_on_close(false) +{ + // sanity check the open flags + if ((m_openflags & OPEN_FLAG_HAS_CRC) && (m_openflags & OPEN_FLAG_WRITE)) + throw emu_fatalerror("Attempted to open a file for write with OPEN_FLAG_HAS_CRC"); +} + +emu_file::emu_file(const char *searchpath, UINT32 openflags) + : m_file(NULL), + m_iterator(searchpath), m_crc(0), m_openflags(openflags), m_zipfile(NULL), @@ -201,6 +215,16 @@ emu_file::operator core_file *() return m_file; } +emu_file::operator core_file &() +{ + // load the ZIP file now if we haven't yet + if (m_zipfile != NULL && load_zipped_file() != FILERR_NONE) + throw emu_fatalerror("operator core_file & used on invalid file"); + + // return the core file + return *m_file; +} + //------------------------------------------------- // hash - returns the hash for a file diff --git a/src/emu/fileio.h b/src/emu/fileio.h index dda8189877b..6cbe38c481d 100644 --- a/src/emu/fileio.h +++ b/src/emu/fileio.h @@ -48,43 +48,10 @@ //************************************************************************** -// CONSTANTS -//************************************************************************** - -// search paths -#define SEARCHPATH_RAW NULL -#define SEARCHPATH_LANGUAGE NULL -#define SEARCHPATH_DEBUGLOG NULL - -#define SEARCHPATH_ROM OPTION_ROMPATH -#define SEARCHPATH_IMAGE OPTION_ROMPATH -#define SEARCHPATH_HASH OPTION_HASHPATH -#define SEARCHPATH_SAMPLE OPTION_SAMPLEPATH -#define SEARCHPATH_ARTWORK OPTION_ARTPATH -#define SEARCHPATH_CTRLR OPTION_CTRLRPATH -#define SEARCHPATH_INI OPTION_INIPATH -#define SEARCHPATH_FONT OPTION_FONTPATH -#define SEARCHPATH_CHEAT OPTION_CHEATPATH -#define SEARCHPATH_CROSSHAIRPATH OPTION_CROSSHAIRPATH - -#define SEARCHPATH_IMAGE_DIFF OPTION_DIFF_DIRECTORY -#define SEARCHPATH_NVRAM OPTION_NVRAM_DIRECTORY -#define SEARCHPATH_CONFIG OPTION_CFG_DIRECTORY -#define SEARCHPATH_INPUTLOG OPTION_INPUT_DIRECTORY -#define SEARCHPATH_STATE OPTION_STATE_DIRECTORY -#define SEARCHPATH_MEMCARD OPTION_MEMCARD_DIRECTORY -#define SEARCHPATH_SCREENSHOT OPTION_SNAPSHOT_DIRECTORY -#define SEARCHPATH_MOVIE OPTION_SNAPSHOT_DIRECTORY -#define SEARCHPATH_COMMENT OPTION_COMMENT_DIRECTORY - - - -//************************************************************************** // TYPE DEFINITIONS //************************************************************************** // forward declarations -typedef struct _core_options core_options; typedef struct _zip_file_header zip_file_header; typedef struct _zip_file zip_file; @@ -96,7 +63,7 @@ class path_iterator { public: // construction/destruction - path_iterator(core_options &options, const char *searchpath = ""); + path_iterator(const char *searchpath); // getters bool next(astring &buffer); @@ -120,7 +87,7 @@ class file_enumerator { public: // construction/destruction - file_enumerator(core_options &opts, const char *searchpath); + file_enumerator(const char *searchpath); ~file_enumerator(); // iterator @@ -142,12 +109,14 @@ class emu_file { public: // file open/creation - emu_file(core_options &options, const char *searchpath, UINT32 openflags); + emu_file(UINT32 openflags); + emu_file(const char *searchpath, UINT32 openflags); virtual ~emu_file(); // getters operator core_file *(); - bool open() const { return (m_file != NULL); } + operator core_file &(); + bool is_open() const { return (m_file != NULL); } const char *filename() const { return m_filename; } const char *fullpath() const { return m_fullpath; } UINT32 openflags() const { return m_openflags; } diff --git a/src/emu/image.c b/src/emu/image.c index 1b9e3d021c3..690b8ace136 100644 --- a/src/emu/image.c +++ b/src/emu/image.c @@ -125,7 +125,7 @@ static void image_dirs_save(running_machine *machine, int config_type, xml_data_ INI files -------------------------------------------------*/ -static int write_config(core_options &options, const char *filename, const game_driver *gamedrv) +static int write_config(emu_options &options, const char *filename, const game_driver *gamedrv) { char buffer[128]; int retval = 1; @@ -136,11 +136,13 @@ static int write_config(core_options &options, const char *filename, const game_ filename = buffer; } - emu_file file(options, SEARCHPATH_INI, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE); + emu_file file(options.ini_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE); file_error filerr = file.open(filename); if (filerr == FILERR_NONE) { - options_output_ini_file(&options, file); + astring inistring; + options.output_ini(inistring); + file.puts(inistring); retval = 0; } return retval; @@ -154,7 +156,8 @@ static int write_config(core_options &options, const char *filename, const game_ static void image_options_extract(running_machine *machine) { /* only extract the device options if we've added them */ - if (options_get_bool(&machine->options(), OPTION_ADDED_DEVICE_OPTIONS)) { +// if (machine->options().bool_value(OPTION_ADDED_DEVICE_OPTIONS)) + { int index = 0; device_image_interface *image = NULL; @@ -163,14 +166,16 @@ static void image_options_extract(running_machine *machine) const char *filename = image->filename(); /* and set the option */ - options_set_string(&machine->options(), image->image_config().instance_name() , filename ? filename : "", OPTION_PRIORITY_CMDLINE); + astring error; + machine->options().set_value(image->image_config().instance_name(), filename ? filename : "", OPTION_PRIORITY_CMDLINE, error); + assert(!error); index++; } } /* write the config, if appropriate */ - if (options_get_bool(&machine->options(), OPTION_WRITECONFIG)) + if (machine->options().write_config()) write_config(machine->options(), NULL, machine->gamedrv); } @@ -206,7 +211,7 @@ void image_device_init(running_machine *machine) for (bool gotone = machine->m_devicelist.first(image); gotone; gotone = image->next(image)) { /* is an image specified for this image */ - image_name = image_get_device_option(image); + image_name = machine->options().device_option(*image); if ((image_name != NULL) && (image_name[0] != '\0')) { @@ -429,7 +434,7 @@ astring *image_info_astring(running_machine *machine, astring *string) to the function. -------------------------------------------------*/ -void image_battery_load_by_name(core_options &options, const char *filename, void *buffer, int length, int fill) +void image_battery_load_by_name(emu_options &options, const char *filename, void *buffer, int length, int fill) { file_error filerr; int bytes_read = 0; @@ -437,7 +442,7 @@ void image_battery_load_by_name(core_options &options, const char *filename, voi assert_always(buffer && (length > 0), "Must specify sensical buffer/length"); /* try to open the battery file and read it in, if possible */ - emu_file file(options, SEARCHPATH_NVRAM, OPEN_FLAG_READ); + emu_file file(options.nvram_directory(), OPEN_FLAG_READ); filerr = file.open(filename); if (filerr == FILERR_NONE) bytes_read = file.read(buffer, length); @@ -451,12 +456,12 @@ void image_battery_load_by_name(core_options &options, const char *filename, voi backed RAM for an image. A filename may be supplied to the function. -------------------------------------------------*/ -void image_battery_save_by_name(core_options &options, const char *filename, const void *buffer, int length) +void image_battery_save_by_name(emu_options &options, const char *filename, const void *buffer, int length) { assert_always(buffer && (length > 0), "Must specify sensical buffer/length"); /* try to open the battery file and write it out, if possible */ - emu_file file(options, SEARCHPATH_NVRAM, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); + emu_file file(options.nvram_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); file_error filerr = file.open(filename); if (filerr == FILERR_NONE) file.write(buffer, length); diff --git a/src/emu/image.h b/src/emu/image.h index 1cca37b3a82..3f082772104 100644 --- a/src/emu/image.h +++ b/src/emu/image.h @@ -25,8 +25,8 @@ void image_postdevice_init(running_machine *machine); extern struct io_procs image_ioprocs; -void image_battery_load_by_name(core_options &options, const char *filename, void *buffer, int length, int fill); -void image_battery_save_by_name(core_options &options, const char *filename, const void *buffer, int length); +void image_battery_load_by_name(emu_options &options, const char *filename, void *buffer, int length, int fill); +void image_battery_save_by_name(emu_options &options, const char *filename, const void *buffer, int length); astring *image_info_astring(running_machine *machine, astring *string); diff --git a/src/emu/imagedev/multcart.c b/src/emu/imagedev/multcart.c index 334060532d7..2af0be651b1 100644 --- a/src/emu/imagedev/multcart.c +++ b/src/emu/imagedev/multcart.c @@ -213,7 +213,7 @@ static multicart_open_error load_rom_resource(multicart_load_state *state, xml_d load_ram_resource -------------------------------------------------*/ -static multicart_open_error load_ram_resource(core_options &options, multicart_load_state *state, xml_data_node *resource_node, +static multicart_open_error load_ram_resource(emu_options &options, multicart_load_state *state, xml_data_node *resource_node, multicart_resource *resource) { const char *length_string; @@ -272,7 +272,7 @@ static multicart_open_error load_ram_resource(core_options &options, multicart_l load_resource -------------------------------------------------*/ -static multicart_open_error load_resource(core_options &options, multicart_load_state *state, xml_data_node *resource_node, +static multicart_open_error load_resource(emu_options &options, multicart_load_state *state, xml_data_node *resource_node, multicart_resource_type resource_type) { const char *id; @@ -328,7 +328,7 @@ static multicart_open_error load_resource(core_options &options, multicart_load_ load_all_resources -------------------------------------------------*/ -static multicart_open_error load_all_resources(core_options &options, multicart_load_state *state) +static multicart_open_error load_all_resources(emu_options &options, multicart_load_state *state) { multicart_open_error err; xml_data_node *resource_node; @@ -355,7 +355,7 @@ static multicart_open_error load_all_resources(core_options &options, multicart_ be freed on multicart_close. -------------------------------------------------*/ -static multicart_open_error save_ram_resources(core_options &options, multicart_t *cart) +static multicart_open_error save_ram_resources(emu_options &options, multicart_t *cart) { const multicart_resource *resource; @@ -461,7 +461,7 @@ static multicart_open_error load_all_sockets(multicart_load_state *state) multicart_open - opens a multicart -------------------------------------------------*/ -multicart_open_error multicart_open(core_options &options, const char *filename, const char *gamedrv, multicart_load_flags load_flags, multicart_t **cart) +multicart_open_error multicart_open(emu_options &options, const char *filename, const char *gamedrv, multicart_load_flags load_flags, multicart_t **cart) { multicart_open_error err; zip_error ziperr; @@ -601,7 +601,7 @@ done: multicart_close - closes a multicart -------------------------------------------------*/ -void multicart_close(core_options &options, multicart_t *cart) +void multicart_close(emu_options &options, multicart_t *cart) { save_ram_resources(options, cart); pool_free_lib(cart->data->pool); diff --git a/src/emu/imagedev/multcart.h b/src/emu/imagedev/multcart.h index 2beaade0b65..ddaea9e7ff1 100644 --- a/src/emu/imagedev/multcart.h +++ b/src/emu/imagedev/multcart.h @@ -92,9 +92,9 @@ const char *multicart_error_text(multicart_open_error error); ***************************************************************************/ /* opens a multicart */ -multicart_open_error multicart_open(core_options &options, const char *filename, const char *drvname, multicart_load_flags load_flags, multicart_t **cart); +multicart_open_error multicart_open(emu_options &options, const char *filename, const char *drvname, multicart_load_flags load_flags, multicart_t **cart); /* closes a multicart */ -void multicart_close(core_options &options, multicart_t *cart); +void multicart_close(emu_options &options, multicart_t *cart); #endif /* __MULTCART_H__ */ diff --git a/src/emu/inptport.c b/src/emu/inptport.c index bbd2a60a252..6e0a5aeea20 100644 --- a/src/emu/inptport.c +++ b/src/emu/inptport.c @@ -2036,7 +2036,7 @@ static astring *get_keyboard_key_name(const input_field_config *field) static void init_port_state(running_machine *machine) { - const char *joystick_map_default = options_get_string(&machine->options(), OPTION_JOYSTICK_MAP); + const char *joystick_map_default = machine->options().joystick_map(); input_port_private *portdata = machine->input_port_data; const input_field_config *field; const input_port_config *port; @@ -2148,7 +2148,7 @@ static void init_port_state(running_machine *machine) static void init_autoselect_devices(running_machine &machine, int type1, int type2, int type3, const char *option, const char *ananame) { const ioport_list &portlist = machine.m_portlist; - const char *stemp = options_get_string(&machine.options(), option); + const char *stemp = machine.options().value(option); input_device_class autoenable = DEVICE_CLASS_KEYBOARD; const char *autostring = "keyboard"; const input_field_config *field; @@ -2871,7 +2871,7 @@ static int frame_get_digital_field_state(const input_field_config *field, int mo } /* skip locked-out coin inputs */ - if (curstate && field->type >= IPT_COIN1 && field->type <= IPT_COIN12 && coin_lockout_get_state(field->port->machine, field->type - IPT_COIN1) && options_get_bool(&field->port->machine->options(), OPTION_COIN_LOCKOUT)) + if (curstate && field->type >= IPT_COIN1 && field->type <= IPT_COIN12 && coin_lockout_get_state(field->port->machine, field->type - IPT_COIN1) && field->port->machine->options().coin_lockout()) { ui_popup_time(3, "Coinlock disabled %s.", input_field_name(field)); return FALSE; @@ -4439,7 +4439,7 @@ static UINT64 playback_read_uint64(running_machine *machine) static time_t playback_init(running_machine *machine) { - const char *filename = options_get_string(&machine->options(), OPTION_PLAYBACK); + const char *filename = machine->options().playback(); input_port_private *portdata = machine->input_port_data; UINT8 header[INP_HEADER_SIZE]; time_t basetime; @@ -4449,7 +4449,7 @@ static time_t playback_init(running_machine *machine) return 0; /* open the playback file */ - portdata->playback_file = auto_alloc(machine, emu_file(machine->options(), SEARCHPATH_INPUTLOG, OPEN_FLAG_READ)); + portdata->playback_file = auto_alloc(machine, emu_file(machine->options().input_directory(), OPEN_FLAG_READ)); file_error filerr = portdata->playback_file->open(filename); assert_always(filerr == FILERR_NONE, "Failed to open file for playback"); @@ -4637,7 +4637,7 @@ static void record_write_uint64(running_machine *machine, UINT64 data) static void record_init(running_machine *machine) { - const char *filename = options_get_string(&machine->options(), OPTION_RECORD); + const char *filename = machine->options().record(); input_port_private *portdata = machine->input_port_data; UINT8 header[INP_HEADER_SIZE]; system_time systime; @@ -4647,7 +4647,7 @@ static void record_init(running_machine *machine) return; /* open the record file */ - portdata->record_file = auto_alloc(machine, emu_file(machine->options(), SEARCHPATH_INPUTLOG, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS)); + portdata->record_file = auto_alloc(machine, emu_file(machine->options().input_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS)); file_error filerr = portdata->record_file->open(filename); assert_always(filerr == FILERR_NONE, "Failed to open file for recording"); diff --git a/src/emu/input.c b/src/emu/input.c index 7f6a681abee..40d09320fda 100644 --- a/src/emu/input.c +++ b/src/emu/input.c @@ -591,24 +591,24 @@ void input_init(running_machine *machine) /* read input enable options */ device_list[DEVICE_CLASS_KEYBOARD].enabled = TRUE; - device_list[DEVICE_CLASS_MOUSE].enabled = options_get_bool(&machine->options(), OPTION_MOUSE); - device_list[DEVICE_CLASS_LIGHTGUN].enabled = options_get_bool(&machine->options(), OPTION_LIGHTGUN); - device_list[DEVICE_CLASS_JOYSTICK].enabled = options_get_bool(&machine->options(), OPTION_JOYSTICK); + device_list[DEVICE_CLASS_MOUSE].enabled = machine->options().mouse(); + device_list[DEVICE_CLASS_LIGHTGUN].enabled = machine->options().lightgun(); + device_list[DEVICE_CLASS_JOYSTICK].enabled = machine->options().joystick(); /* read input device multi options */ - device_list[DEVICE_CLASS_KEYBOARD].multi = options_get_bool(&machine->options(), OPTION_MULTIKEYBOARD); - device_list[DEVICE_CLASS_MOUSE].multi = options_get_bool(&machine->options(), OPTION_MULTIMOUSE); + device_list[DEVICE_CLASS_KEYBOARD].multi = machine->options().multi_keyboard(); + device_list[DEVICE_CLASS_MOUSE].multi = machine->options().multi_mouse(); device_list[DEVICE_CLASS_LIGHTGUN].multi = TRUE; device_list[DEVICE_CLASS_JOYSTICK].multi = TRUE; /* read other input options */ - state->steadykey_enabled = options_get_bool(&machine->options(), OPTION_STEADYKEY); - state->lightgun_reload_button = options_get_bool(&machine->options(), OPTION_OFFSCREEN_RELOAD); - state->joystick_deadzone = (INT32)(options_get_float(&machine->options(), OPTION_JOYSTICK_DEADZONE) * INPUT_ABSOLUTE_MAX); - state->joystick_saturation = (INT32)(options_get_float(&machine->options(), OPTION_JOYSTICK_SATURATION) * INPUT_ABSOLUTE_MAX); + state->steadykey_enabled = machine->options().steadykey(); + state->lightgun_reload_button = machine->options().offscreen_reload(); + state->joystick_deadzone = (INT32)(machine->options().joystick_deadzone() * INPUT_ABSOLUTE_MAX); + state->joystick_saturation = (INT32)(machine->options().joystick_saturation() * INPUT_ABSOLUTE_MAX); /* get the default joystick map */ - state->joystick_map_default = options_get_string(&machine->options(), OPTION_JOYSTICK_MAP); + state->joystick_map_default = machine->options().joystick_map(); if (state->joystick_map_default[0] == 0 || strcmp(state->joystick_map_default, "auto") == 0) state->joystick_map_default = joystick_map_8way; if (!joystick_map_parse(state->joystick_map_default, &map)) diff --git a/src/emu/machine.c b/src/emu/machine.c index ec7e0b145d3..01c9d19fc77 100644 --- a/src/emu/machine.c +++ b/src/emu/machine.c @@ -138,7 +138,7 @@ static char giant_string_buffer[65536] = { 0 }; // running_machine - constructor //------------------------------------------------- -running_machine::running_machine(const machine_config &_config, osd_interface &osd, core_options &options, bool exit_to_game_select) +running_machine::running_machine(const machine_config &_config, osd_interface &osd, emu_options &options, bool exit_to_game_select) : m_regionlist(m_respool), m_devicelist(m_respool), config(&_config), @@ -152,7 +152,7 @@ running_machine::running_machine(const machine_config &_config, osd_interface &o colortable(NULL), shadow_table(NULL), priority_bitmap(NULL), - sample_rate(options_get_int(&options, OPTION_SAMPLERATE)), + sample_rate(options.sample_rate()), debug_flags(0), ui_active(false), memory_data(NULL), @@ -216,8 +216,8 @@ running_machine::running_machine(const machine_config &_config, osd_interface &o } // fetch core options - if (options_get_bool(&m_options, OPTION_DEBUG)) - debug_flags = (DEBUG_FLAG_ENABLED | DEBUG_FLAG_CALL_HOOK) | (options_get_bool(&m_options, OPTION_DEBUG_INTERNAL) ? 0 : DEBUG_FLAG_OSD_ENABLED); + if (m_options.debug()) + debug_flags = (DEBUG_FLAG_ENABLED | DEBUG_FLAG_CALL_HOOK) | (m_options.debug_internal() ? 0 : DEBUG_FLAG_OSD_ENABLED); } @@ -328,12 +328,12 @@ void running_machine::start() m_devicelist.start_all(); // if we're coming in with a savegame request, process it now - const char *savegame = options_get_string(&m_options, OPTION_STATE); + const char *savegame = m_options.state(); if (savegame[0] != 0) schedule_load(savegame); // if we're in autosave mode, schedule a load - else if (options_get_bool(&m_options, OPTION_AUTOSAVE) && (m_game.flags & GAME_SUPPORTS_SAVE) != 0) + else if (m_options.autosave() && (m_game.flags & GAME_SUPPORTS_SAVE) != 0) schedule_load("auto"); // set up the cheat engine @@ -359,9 +359,9 @@ int running_machine::run(bool firstrun) m_current_phase = MACHINE_PHASE_INIT; // if we have a logfile, set up the callback - if (options_get_bool(&m_options, OPTION_LOG)) + if (m_options.log()) { - m_logfile = auto_alloc(this, emu_file(m_options, SEARCHPATH_DEBUGLOG, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS)); + m_logfile = auto_alloc(this, emu_file(NULL, 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); @@ -445,9 +445,9 @@ int running_machine::run(bool firstrun) void running_machine::schedule_exit() { // if we are in-game but we started with the select game menu, return to that instead - if (m_exit_to_game_select && options_get_string(&m_options, OPTION_GAMENAME)[0] != 0) + if (m_exit_to_game_select && m_options.system_name()[0] != 0) { - options_set_string(&m_options, OPTION_GAMENAME, "", OPTION_PRIORITY_CMDLINE); + m_options.set_system_name(""); ui_menu_force_game_select(this, &render().ui_container()); } @@ -459,7 +459,7 @@ void running_machine::schedule_exit() m_scheduler.eat_all_cycles(); // if we're autosaving on exit, schedule a save as well - if (options_get_bool(&m_options, OPTION_AUTOSAVE) && (m_game.flags & GAME_SUPPORTS_SAVE) && this->time() > attotime::zero) + if (m_options.autosave() && (m_game.flags & GAME_SUPPORTS_SAVE) && this->time() > attotime::zero) schedule_save("auto"); } @@ -525,7 +525,7 @@ void running_machine::set_saveload_filename(const char *filename) } else { - m_saveload_searchpath = SEARCHPATH_STATE; + m_saveload_searchpath = m_options.state_directory(); m_saveload_pending_file.cpy(basename()).cat(PATH_SEPARATOR).cat(filename).cat(".sta"); } } @@ -771,7 +771,7 @@ void running_machine::handle_saveload() file_error filerr = FILERR_NONE; // if no name, bail - emu_file file(m_options, m_saveload_searchpath, openflags); + emu_file file(m_saveload_searchpath, openflags); if (!m_saveload_pending_file) goto cancel; diff --git a/src/emu/machine.h b/src/emu/machine.h index c67dcfed88f..472b877cf8a 100644 --- a/src/emu/machine.h +++ b/src/emu/machine.h @@ -323,7 +323,7 @@ class running_machine : public bindable_object public: // construction/destruction - running_machine(const machine_config &config, osd_interface &osd, core_options &options, bool exit_to_game_select = false); + running_machine(const machine_config &config, osd_interface &osd, emu_options &options, bool exit_to_game_select = false); ~running_machine(); // fetch items by name @@ -337,7 +337,7 @@ public: // getters const char *basename() const { return m_basename; } - core_options &options() const { return m_options; } + emu_options &options() const { return m_options; } machine_phase phase() const { return m_current_phase; } bool paused() const { return m_paused || (m_current_phase != MACHINE_PHASE_RUNNING); } bool scheduled_event_pending() const { return m_exit_pending || m_hard_reset_pending; } @@ -477,7 +477,7 @@ private: state_manager m_state; // state manager device_scheduler m_scheduler; // scheduler object - core_options & m_options; + emu_options & m_options; osd_interface & m_osd; astring m_context; // context string diff --git a/src/emu/machine/at28c16.c b/src/emu/machine/at28c16.c index 7c3e84a03b5..8e0dc4d2f69 100644 --- a/src/emu/machine/at28c16.c +++ b/src/emu/machine/at28c16.c @@ -84,7 +84,7 @@ void at28c16_device_config::device_config_complete() // on this device //------------------------------------------------- -bool at28c16_device_config::device_validity_check( core_options &options, const game_driver &driver ) const +bool at28c16_device_config::device_validity_check( emu_options &options, const game_driver &driver ) const { return false; } diff --git a/src/emu/machine/at28c16.h b/src/emu/machine/at28c16.h index 32a1846fa31..b6b9857eee8 100644 --- a/src/emu/machine/at28c16.h +++ b/src/emu/machine/at28c16.h @@ -58,7 +58,7 @@ public: protected: // device_config overrides virtual void device_config_complete(); - virtual bool device_validity_check( core_options &options, const game_driver &driver ) const; + virtual bool device_validity_check( emu_options &options, const game_driver &driver ) const; // device_config_memory_interface overrides virtual const address_space_config *memory_space_config( int spacenum = 0 ) const; diff --git a/src/emu/machine/eeprom.c b/src/emu/machine/eeprom.c index ad94ee2e1f7..e2a189b5fe9 100644 --- a/src/emu/machine/eeprom.c +++ b/src/emu/machine/eeprom.c @@ -164,7 +164,7 @@ void eeprom_device_config::static_set_default_value(device_config *device, UINT1 // on this device //------------------------------------------------- -bool eeprom_device_config::device_validity_check(core_options &options, const game_driver &driver) const +bool eeprom_device_config::device_validity_check(emu_options &options, const game_driver &driver) const { bool error = false; diff --git a/src/emu/machine/eeprom.h b/src/emu/machine/eeprom.h index 4f5f3949143..966af2cc9c5 100644 --- a/src/emu/machine/eeprom.h +++ b/src/emu/machine/eeprom.h @@ -83,7 +83,7 @@ public: protected: // device_config overrides - virtual bool device_validity_check(core_options &options, const game_driver &driver) const; + virtual bool device_validity_check(emu_options &options, const game_driver &driver) const; // device_config_memory_interface overrides virtual const address_space_config *memory_space_config(int spacenum = 0) const; diff --git a/src/emu/machine/generic.c b/src/emu/machine/generic.c index 3562640138f..158aed8f9d0 100644 --- a/src/emu/machine/generic.c +++ b/src/emu/machine/generic.c @@ -323,7 +323,7 @@ void nvram_load(running_machine *machine) return; // open the file; if it exists, call everyone to read from it - emu_file file(machine->options(), SEARCHPATH_NVRAM, OPEN_FLAG_READ); + emu_file file(machine->options().nvram_directory(), OPEN_FLAG_READ); if (file.open(machine->basename(), ".nv") == FILERR_NONE) { // read data from general NVRAM handler first @@ -361,7 +361,7 @@ void nvram_save(running_machine *machine) return; // open the file; if it exists, call everyone to read from it - emu_file file(machine->options(), SEARCHPATH_NVRAM, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); + emu_file file(machine->options().nvram_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); if (file.open(machine->basename(), ".nv") == FILERR_NONE) { // write data via general NVRAM handler first @@ -407,13 +407,13 @@ int memcard_create(running_machine *machine, int index, int overwrite) astring fname(machine->basename(), PATH_SEPARATOR, name); if (!overwrite) { - emu_file testfile(machine->options(), SEARCHPATH_MEMCARD, OPEN_FLAG_READ); + emu_file testfile(machine->options().memcard_directory(), OPEN_FLAG_READ); if (testfile.open(fname) == FILERR_NONE) return 1; } /* create a new file */ - emu_file file(machine->options(), SEARCHPATH_MEMCARD, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); + emu_file file(machine->options().memcard_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); file_error filerr = file.open(fname); if (filerr != FILERR_NONE) return 1; @@ -446,7 +446,7 @@ int memcard_insert(running_machine *machine, int index) memcard_name(index, name); /* open the file; if we can't, it's an error */ - emu_file file(machine->options(), SEARCHPATH_MEMCARD, OPEN_FLAG_READ); + emu_file file(machine->options().memcard_directory(), OPEN_FLAG_READ); file_error filerr = file.open(machine->basename(), PATH_SEPARATOR, name); if (filerr != FILERR_NONE) return 1; @@ -479,7 +479,7 @@ void memcard_eject(running_machine &machine) memcard_name(state->memcard_inserted, name); /* open the file; if we can't, it's an error */ - emu_file file(machine.options(), SEARCHPATH_MEMCARD, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); + emu_file file(machine.options().memcard_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); file_error filerr = file.open(machine.basename(), PATH_SEPARATOR, name); if (filerr != FILERR_NONE) return; diff --git a/src/emu/machine/i2cmem.c b/src/emu/machine/i2cmem.c index 9e9f96aae32..c379f2c8e64 100644 --- a/src/emu/machine/i2cmem.c +++ b/src/emu/machine/i2cmem.c @@ -139,7 +139,7 @@ void i2cmem_device_config::device_config_complete() // on this device //------------------------------------------------- -bool i2cmem_device_config::device_validity_check( core_options &options, const game_driver &driver ) const +bool i2cmem_device_config::device_validity_check( emu_options &options, const game_driver &driver ) const { bool error = false; return error; diff --git a/src/emu/machine/i2cmem.h b/src/emu/machine/i2cmem.h index 5b997d570b8..8ecfd36bb9c 100644 --- a/src/emu/machine/i2cmem.h +++ b/src/emu/machine/i2cmem.h @@ -67,7 +67,7 @@ public: protected: // device_config overrides virtual void device_config_complete(); - virtual bool device_validity_check( core_options &options, const game_driver &driver ) const; + virtual bool device_validity_check( emu_options &options, const game_driver &driver ) const; // device_config_memory_interface overrides virtual const address_space_config *memory_space_config( int spacenum = 0 ) const; diff --git a/src/emu/machine/mb3773.c b/src/emu/machine/mb3773.c index 721fce80772..55dbbed0ae8 100644 --- a/src/emu/machine/mb3773.c +++ b/src/emu/machine/mb3773.c @@ -76,7 +76,7 @@ void mb3773_device_config::device_config_complete() // on this device //------------------------------------------------- -bool mb3773_device_config::device_validity_check( core_options &options, const game_driver &driver ) const +bool mb3773_device_config::device_validity_check( emu_options &options, const game_driver &driver ) const { return false; } diff --git a/src/emu/machine/mb3773.h b/src/emu/machine/mb3773.h index 6a2e25f8dec..80dbb855645 100644 --- a/src/emu/machine/mb3773.h +++ b/src/emu/machine/mb3773.h @@ -38,7 +38,7 @@ public: protected: // device_config overrides virtual void device_config_complete(); - virtual bool device_validity_check( core_options &options, const game_driver &driver ) const; + virtual bool device_validity_check( emu_options &options, const game_driver &driver ) const; }; diff --git a/src/emu/machine/ram.c b/src/emu/machine/ram.c index 397b04e6e3c..7a08d377fd0 100644 --- a/src/emu/machine/ram.c +++ b/src/emu/machine/ram.c @@ -100,7 +100,7 @@ static DEVICE_START( ram ) /* the device named 'ram' can get ram options from command line */ if (strcmp(device->tag(), RAM_TAG) == 0) { - const char *ramsize_string = options_get_string(&device->machine->options(), OPTION_RAMSIZE); + const char *ramsize_string = device->machine->options().ram_size(); if ((ramsize_string != NULL) && (ramsize_string[0] != '\0')) ram->size = ram_parse_string(ramsize_string); @@ -141,8 +141,8 @@ static DEVICE_VALIDITY_CHECK( ram ) if (device->tag()!=NULL && strcmp(device->tag(), RAM_TAG) == 0) { /* verify command line ram option */ - ramsize_string = options_get_string(&options, OPTION_RAMSIZE); - gamename_option = options_get_string(&options, OPTION_GAMENAME); + ramsize_string = options.ram_size(); + gamename_option = options.system_name(); if ((ramsize_string != NULL) && (ramsize_string[0] != '\0')) { diff --git a/src/emu/mame.c b/src/emu/mame.c index 06c42425e16..d0bff3af991 100644 --- a/src/emu/mame.c +++ b/src/emu/mame.c @@ -121,14 +121,6 @@ const char mame_disclaimer[] = /*************************************************************************** - FUNCTION PROTOTYPES -***************************************************************************/ - -static int parse_ini_file(core_options *options, const char *name, int priority); - - - -/*************************************************************************** CORE IMPLEMENTATION ***************************************************************************/ @@ -147,13 +139,13 @@ int mame_is_valid_machine(running_machine *machine) mame_execute - run the core emulation -------------------------------------------------*/ -int mame_execute(osd_interface &osd, core_options *options) +int mame_execute(emu_options &options, osd_interface &osd) { bool firstgame = true; bool firstrun = true; // extract the verbose printing option - if (options_get_bool(options, OPTION_VERBOSE)) + if (options.verbose()) print_verbose = true; // loop across multiple hard resets @@ -161,37 +153,34 @@ int mame_execute(osd_interface &osd, core_options *options) int error = MAMERR_NONE; while (error == MAMERR_NONE && !exit_pending) { - // convert the specified gamename to a driver - astring gamename; - core_filename_extract_base(&gamename, options_get_string(options, OPTION_GAMENAME), true); - const game_driver *driver = driver_get_name(gamename); - // if no driver, use the internal empty driver - if (driver == NULL) + const game_driver *system = options.system(); + if (system == NULL) { - driver = &GAME_NAME(empty); + system = &GAME_NAME(empty); if (firstgame) started_empty = true; } // otherwise, perform validity checks before anything else - else if (mame_validitychecks(*options, driver) != 0) - return MAMERR_FAILED_VALIDITY; + else + validate_drivers(options, system); firstgame = false; // parse any INI files as the first thing - if (options_get_bool(options, OPTION_READCONFIG)) + if (options.read_config()) { - options_revert(options, OPTION_PRIORITY_INI); - mame_parse_ini_files(options, driver); + options.revert(OPTION_PRIORITY_INI); + astring errors; + options.parse_standard_inis(errors); } // create the machine configuration - const machine_config *config = global_alloc(machine_config(*driver)); + const machine_config *config = global_alloc(machine_config(*system)); // create the machine structure and driver - running_machine *machine = global_alloc(running_machine(*config, osd, *options, started_empty)); + running_machine *machine = global_alloc(running_machine(*config, osd, options, started_empty)); // looooong term: remove this global_machine = machine; @@ -203,7 +192,7 @@ int mame_execute(osd_interface &osd, core_options *options) // check the state of the machine if (machine->new_driver_pending()) { - options_set_string(options, OPTION_GAMENAME, machine->new_driver_name(), OPTION_PRIORITY_CMDLINE); + options.set_system_name(machine->new_driver_name()); firstrun = true; } if (machine->exit_pending()) @@ -213,10 +202,6 @@ int mame_execute(osd_interface &osd, core_options *options) global_free(machine); global_free(config); global_machine = NULL; - if (firstrun) { - // clear flag for added devices - options_set_bool(options, OPTION_ADDED_DEVICE_OPTIONS, FALSE, OPTION_PRIORITY_CMDLINE); - } } // return an error @@ -467,95 +452,3 @@ void CLIB_DECL logerror(const char *format, ...) } } - - -/*************************************************************************** - INTERNAL INITIALIZATION LOGIC -***************************************************************************/ - -/*------------------------------------------------- - mame_parse_ini_files - parse the relevant INI - files and apply their options --------------------------------------------------*/ - -void mame_parse_ini_files(core_options *options, const game_driver *driver) -{ - /* parse the INI file defined by the platform (e.g., "mame.ini") */ - /* we do this twice so that the first file can change the INI path */ - parse_ini_file(options, CONFIGNAME, OPTION_PRIORITY_MAME_INI); - parse_ini_file(options, CONFIGNAME, OPTION_PRIORITY_MAME_INI); - - /* debug mode: parse "debug.ini" as well */ - if (options_get_bool(options, OPTION_DEBUG)) - parse_ini_file(options, "debug", OPTION_PRIORITY_DEBUG_INI); - - /* if we have a valid game driver, parse game-specific INI files */ - if (driver != NULL && driver != &GAME_NAME(empty)) - { - const game_driver *parent = driver_get_clone(driver); - const game_driver *gparent = (parent != NULL) ? driver_get_clone(parent) : NULL; - - /* parse "vertical.ini" or "horizont.ini" */ - if (driver->flags & ORIENTATION_SWAP_XY) - parse_ini_file(options, "vertical", OPTION_PRIORITY_ORIENTATION_INI); - else - parse_ini_file(options, "horizont", OPTION_PRIORITY_ORIENTATION_INI); - - /* parse "vector.ini" for vector games */ - { - machine_config config(*driver); - for (const screen_device_config *devconfig = config.first_screen(); devconfig != NULL; devconfig = devconfig->next_screen()) - if (devconfig->screen_type() == SCREEN_TYPE_VECTOR) - { - parse_ini_file(options, "vector", OPTION_PRIORITY_VECTOR_INI); - break; - } - } - - /* next parse "source/<sourcefile>.ini"; if that doesn't exist, try <sourcefile>.ini */ - astring sourcename; - core_filename_extract_base(&sourcename, driver->source_file, TRUE)->ins(0, "source" PATH_SEPARATOR); - if (!parse_ini_file(options, sourcename, OPTION_PRIORITY_SOURCE_INI)) - { - core_filename_extract_base(&sourcename, driver->source_file, TRUE); - parse_ini_file(options, sourcename, OPTION_PRIORITY_SOURCE_INI); - } - - /* then parent the grandparent, parent, and game-specific INIs */ - if (gparent != NULL) - parse_ini_file(options, gparent->name, OPTION_PRIORITY_GPARENT_INI); - if (parent != NULL) - parse_ini_file(options, parent->name, OPTION_PRIORITY_PARENT_INI); - - options_revert_driver_only(options, OPTION_PRIORITY_CMDLINE); - - parse_ini_file(options, driver->name, OPTION_PRIORITY_DRIVER_INI); - } -} - - -/*------------------------------------------------- - parse_ini_file - parse a single INI file --------------------------------------------------*/ - -static int parse_ini_file(core_options *options, const char *name, int priority) -{ - /* update game name so depending callback options could be added */ - if (priority == OPTION_PRIORITY_DRIVER_INI || priority == OPTION_PRIORITY_SOURCE_INI) - options_force_option_callback(options, OPTION_GAMENAME, name, priority); - - /* don't parse if it has been disabled */ - if (!options_get_bool(options, OPTION_READCONFIG)) - return FALSE; - - /* open the file; if we fail, that's ok */ - emu_file file(*options, SEARCHPATH_INI, OPEN_FLAG_READ); - file_error filerr = file.open(name, ".ini"); - if (filerr != FILERR_NONE) - return FALSE; - - /* parse the file and close it */ - mame_printf_verbose("Parsing %s.ini\n", name); - options_parse_ini_file(options, file, priority, OPTION_PRIORITY_DRIVER_INI); - return TRUE; -} diff --git a/src/emu/mame.h b/src/emu/mame.h index 23bf31d9596..5132fd3f659 100644 --- a/src/emu/mame.h +++ b/src/emu/mame.h @@ -95,8 +95,8 @@ extern const char build_version[]; /* ----- core system management ----- */ -/* execute as configured by the OPTION_GAMENAME option on the specified options */ -int mame_execute(osd_interface &osd, core_options *options); +/* execute as configured by the OPTION_SYSTEMNAME option on the specified options */ +int mame_execute(emu_options &options, osd_interface &osd); /* return true if the given machine is valid */ int mame_is_valid_machine(running_machine *machine); @@ -129,10 +129,6 @@ void mame_printf_debug(const char *format, ...) ATTR_PRINTF(1,2); /* ----- miscellaneous bits & pieces ----- */ -/* parse the configured INI files */ -void mame_parse_ini_files(core_options *options, const game_driver *driver); - - // pop-up a user visible message void CLIB_DECL popmessage(const char *format,...) ATTR_PRINTF(1,2); diff --git a/src/emu/mconfig.h b/src/emu/mconfig.h index 4744ba73599..3798131a191 100644 --- a/src/emu/mconfig.h +++ b/src/emu/mconfig.h @@ -131,6 +131,7 @@ public: // getters const game_driver &gamedrv() const { return m_gamedrv; } + const device_config *first_device() const { return m_devicelist.first(); } screen_device_config *first_screen() const; // public state diff --git a/src/emu/render.c b/src/emu/render.c index 94824986872..94f8d0799a4 100644 --- a/src/emu/render.c +++ b/src/emu/render.c @@ -721,9 +721,9 @@ render_container::render_container(render_manager &manager, screen_device *scree { // set the initial orientation and brightness/contrast/gamma m_user.m_orientation = manager.machine().gamedrv->flags & ORIENTATION_MASK; - m_user.m_brightness = options_get_float(&manager.machine().options(), OPTION_BRIGHTNESS); - m_user.m_contrast = options_get_float(&manager.machine().options(), OPTION_CONTRAST); - m_user.m_gamma = options_get_float(&manager.machine().options(), OPTION_GAMMA); + m_user.m_brightness = manager.machine().options().brightness(); + m_user.m_contrast = manager.machine().options().contrast(); + m_user.m_gamma = manager.machine().options().gamma(); } // allocate a client to the main palette @@ -1066,26 +1066,26 @@ render_target::render_target(render_manager &manager, const char *layoutfile, UI m_debug_containers(manager.machine().m_respool) { // determine the base layer configuration based on options - m_base_layerconfig.set_backdrops_enabled(options_get_bool(&manager.machine().options(), OPTION_USE_BACKDROPS)); - m_base_layerconfig.set_overlays_enabled(options_get_bool(&manager.machine().options(), OPTION_USE_OVERLAYS)); - m_base_layerconfig.set_bezels_enabled(options_get_bool(&manager.machine().options(), OPTION_USE_BEZELS)); - m_base_layerconfig.set_zoom_to_screen(options_get_bool(&manager.machine().options(), OPTION_ARTWORK_CROP)); + m_base_layerconfig.set_backdrops_enabled(manager.machine().options().use_backdrops()); + m_base_layerconfig.set_overlays_enabled(manager.machine().options().use_overlays()); + m_base_layerconfig.set_bezels_enabled(manager.machine().options().use_bezels()); + m_base_layerconfig.set_zoom_to_screen(manager.machine().options().artwork_crop()); // determine the base orientation based on options m_orientation = ROT0; - if (!options_get_bool(&manager.machine().options(), OPTION_ROTATE)) + if (!manager.machine().options().rotate()) m_base_orientation = orientation_reverse(manager.machine().gamedrv->flags & ORIENTATION_MASK); // rotate left/right - if (options_get_bool(&manager.machine().options(), OPTION_ROR) || (options_get_bool(&manager.machine().options(), OPTION_AUTOROR) && (manager.machine().gamedrv->flags & ORIENTATION_SWAP_XY))) + if (manager.machine().options().ror() || (manager.machine().options().auto_ror() && (manager.machine().gamedrv->flags & ORIENTATION_SWAP_XY))) m_base_orientation = orientation_add(ROT90, m_base_orientation); - if (options_get_bool(&manager.machine().options(), OPTION_ROL) || (options_get_bool(&manager.machine().options(), OPTION_AUTOROL) && (manager.machine().gamedrv->flags & ORIENTATION_SWAP_XY))) + if (manager.machine().options().rol() || (manager.machine().options().auto_rol() && (manager.machine().gamedrv->flags & ORIENTATION_SWAP_XY))) m_base_orientation = orientation_add(ROT270, m_base_orientation); // flip X/Y - if (options_get_bool(&manager.machine().options(), OPTION_FLIPX)) + if (manager.machine().options().flipx()) m_base_orientation ^= ORIENTATION_FLIP_X; - if (options_get_bool(&manager.machine().options(), OPTION_FLIPY)) + if (manager.machine().options().flipy()) m_base_orientation ^= ORIENTATION_FLIP_Y; // set the orientation and layerconfig equal to the base @@ -1680,7 +1680,7 @@ bool render_target::load_layout_file(const char *dirname, const char *filename) fname.ins(0, PATH_SEPARATOR).ins(0, dirname); // attempt to open the file; bail if we can't - emu_file layoutfile(manager().machine().options(), SEARCHPATH_ARTWORK, OPEN_FLAG_READ); + emu_file layoutfile(manager().machine().options().art_path(), OPEN_FLAG_READ); file_error filerr = layoutfile.open(fname); if (filerr != FILERR_NONE) return false; @@ -2796,19 +2796,19 @@ void render_manager::config_save(int config_type, xml_data_node *parentnode) container->get_user_settings(settings); // output the color controls - if (settings.m_brightness != options_get_float(&m_machine.options(), OPTION_BRIGHTNESS)) + if (settings.m_brightness != m_machine.options().brightness()) { xml_set_attribute_float(screennode, "brightness", settings.m_brightness); changed = true; } - if (settings.m_contrast != options_get_float(&m_machine.options(), OPTION_CONTRAST)) + if (settings.m_contrast != m_machine.options().contrast()) { xml_set_attribute_float(screennode, "contrast", settings.m_contrast); changed = true; } - if (settings.m_gamma != options_get_float(&m_machine.options(), OPTION_GAMMA)) + if (settings.m_gamma != m_machine.options().gamma()) { xml_set_attribute_float(screennode, "gamma", settings.m_gamma); changed = true; diff --git a/src/emu/rendfont.c b/src/emu/rendfont.c index 327332b5365..629e6b84533 100644 --- a/src/emu/rendfont.c +++ b/src/emu/rendfont.c @@ -139,7 +139,7 @@ render_font::render_font(render_manager &manager, const char *filename) return; // load the raw data instead - emu_file ramfile(manager.machine().options(), NULL, OPEN_FLAG_READ); + emu_file ramfile(OPEN_FLAG_READ); file_error filerr = ramfile.open_ram(font_uismall, sizeof(font_uismall)); if (filerr == FILERR_NONE) load_cached(ramfile, 0); @@ -412,7 +412,7 @@ float render_font::utf8string_width(float height, float aspect, const char *utf8 bool render_font::load_cached_bdf(const char *filename) { // first try to open the BDF itself - emu_file file(manager().machine().options(), SEARCHPATH_FONT, OPEN_FLAG_READ); + emu_file file(manager().machine().options().font_path(), OPEN_FLAG_READ); file_error filerr = file.open(filename); if (filerr != FILERR_NONE) return false; @@ -435,7 +435,7 @@ bool render_font::load_cached_bdf(const char *filename) // attempt to open the cached version of the font { - emu_file cachefile(manager().machine().options(), SEARCHPATH_FONT, OPEN_FLAG_READ); + emu_file cachefile(manager().machine().options().font_path(), OPEN_FLAG_READ); filerr = cachefile.open(cachedname); if (filerr == FILERR_NONE) { @@ -673,7 +673,7 @@ bool render_font::save_cached(const char *filename, UINT32 hash) mame_printf_warning("Generating cached BDF font...\n"); // attempt to open the file - emu_file file(manager().machine().options(), SEARCHPATH_FONT, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE); + emu_file file(manager().machine().options().font_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE); file_error filerr = file.open(filename); if (filerr != FILERR_NONE) return false; diff --git a/src/emu/rendlay.c b/src/emu/rendlay.c index 6b2f09ab623..7f71b73230c 100644 --- a/src/emu/rendlay.c +++ b/src/emu/rendlay.c @@ -611,7 +611,7 @@ layout_element::component::component(running_machine &machine, xml_data_node &co m_dirname = dirname; m_imagefile = xml_get_attribute_string_with_subst(machine, compnode, "file", ""); m_alphafile = xml_get_attribute_string_with_subst(machine, compnode, "alphafile", ""); - m_file = global_alloc(emu_file(machine.options(), OPTION_ARTPATH, OPEN_FLAG_READ)); + m_file = global_alloc(emu_file(machine.options().art_path(), OPEN_FLAG_READ)); } // text nodes diff --git a/src/emu/romload.c b/src/emu/romload.c index b5423281734..63969e4aabc 100644 --- a/src/emu/romload.c +++ b/src/emu/romload.c @@ -81,9 +81,9 @@ static void rom_exit(running_machine &machine); HELPERS (also used by devimage.c) ***************************************************************************/ -file_error common_process_file(core_options &options, const char *location, const char *ext, const rom_entry *romp, emu_file **image_file) +file_error common_process_file(emu_options &options, const char *location, const char *ext, const rom_entry *romp, emu_file **image_file) { - *image_file = global_alloc(emu_file(options, SEARCHPATH_IMAGE, OPEN_FLAG_READ)); + *image_file = global_alloc(emu_file(options.media_path(), OPEN_FLAG_READ)); file_error filerr; if (location != NULL && strcmp(location, "") != 0) @@ -99,9 +99,9 @@ file_error common_process_file(core_options &options, const char *location, cons return filerr; } -file_error common_process_file(core_options &options, const char *location, bool has_crc, UINT32 crc, const rom_entry *romp, emu_file **image_file) +file_error common_process_file(emu_options &options, const char *location, bool has_crc, UINT32 crc, const rom_entry *romp, emu_file **image_file) { - *image_file = global_alloc(emu_file(options, SEARCHPATH_IMAGE, OPEN_FLAG_READ)); + *image_file = global_alloc(emu_file(options.media_path(), OPEN_FLAG_READ)); file_error filerr; if (has_crc) @@ -330,7 +330,7 @@ static void CLIB_DECL ATTR_PRINTF(1,2) debugload(const char *string, ...) static void determine_bios_rom(rom_load_data *romdata) { - const char *specbios = options_get_string(&romdata->machine->options(), OPTION_BIOS); + const char *specbios = romdata->machine->options().bios(); const char *defaultname = NULL; const rom_entry *rom; int default_no = 1; @@ -1003,7 +1003,7 @@ static void process_rom_entries(rom_load_data *romdata, const char *regiontag, c checksum -------------------------------------------------*/ -chd_error open_disk_image(core_options &options, const game_driver *gamedrv, const rom_entry *romp, emu_file **image_file, chd_file **image_chd, const char *locationtag) +chd_error open_disk_image(emu_options &options, const game_driver *gamedrv, const rom_entry *romp, emu_file **image_file, chd_file **image_chd, const char *locationtag) { const game_driver *drv, *searchdrv; const rom_entry *region, *rom; @@ -1155,7 +1155,7 @@ chd_error open_disk_image(core_options &options, const game_driver *gamedrv, con open_disk_diff - open a DISK diff file -------------------------------------------------*/ -static chd_error open_disk_diff(core_options &options, const rom_entry *romp, chd_file *source, emu_file **diff_file, chd_file **diff_chd) +static chd_error open_disk_diff(emu_options &options, const rom_entry *romp, chd_file *source, emu_file **diff_file, chd_file **diff_chd) { astring fname(ROM_GETNAME(romp), ".dif"); chd_error err; @@ -1165,7 +1165,7 @@ static chd_error open_disk_diff(core_options &options, const rom_entry *romp, ch /* try to open the diff */ LOG(("Opening differencing image file: %s\n", fname.cstr())); - *diff_file = global_alloc(emu_file(options, SEARCHPATH_IMAGE_DIFF, OPEN_FLAG_READ | OPEN_FLAG_WRITE)); + *diff_file = global_alloc(emu_file(options.diff_directory(), OPEN_FLAG_READ | OPEN_FLAG_WRITE)); file_error filerr = (*diff_file)->open(fname); if (filerr != FILERR_NONE) { diff --git a/src/emu/romload.h b/src/emu/romload.h index 9177b18b9c0..68d842d1613 100644 --- a/src/emu/romload.h +++ b/src/emu/romload.h @@ -124,6 +124,7 @@ enum ***************************************************************************/ class machine_config; +class emu_options; typedef device_config rom_source; @@ -276,8 +277,8 @@ int rom_load_knownbad(running_machine *machine); /* ----- Helpers ----- */ -file_error common_process_file(core_options &options, const char *location, const char *ext, const rom_entry *romp, emu_file **image_file); -file_error common_process_file(core_options &options, const char *location, bool has_crc, UINT32 crc, const rom_entry *romp, emu_file **image_file); +file_error common_process_file(emu_options &options, const char *location, const char *ext, const rom_entry *romp, emu_file **image_file); +file_error common_process_file(emu_options &options, const char *location, bool has_crc, UINT32 crc, const rom_entry *romp, emu_file **image_file); /* ----- ROM iteration ----- */ @@ -314,7 +315,7 @@ astring &rom_region_name(astring &result, const game_driver *drv, const rom_sour /* ----- disk handling ----- */ /* open a disk image, searching up the parent and loading by checksum */ -chd_error open_disk_image(core_options &options, const game_driver *gamedrv, const rom_entry *romp, emu_file **image_file, chd_file **image_chd,const char *locationtag); +chd_error open_disk_image(emu_options &options, const game_driver *gamedrv, const rom_entry *romp, emu_file **image_file, chd_file **image_chd,const char *locationtag); /* return a pointer to the CHD file associated with the given region */ chd_file *get_disk_handle(running_machine *machine, const char *region); diff --git a/src/emu/screen.c b/src/emu/screen.c index 0c43c2b2504..185127c699c 100644 --- a/src/emu/screen.c +++ b/src/emu/screen.c @@ -228,7 +228,7 @@ void screen_device_config::static_set_default_position(device_config *device, do // configuration //------------------------------------------------- -bool screen_device_config::device_validity_check(core_options &options, const game_driver &driver) const +bool screen_device_config::device_validity_check(emu_options &options, const game_driver &driver) const { bool error = false; @@ -393,10 +393,10 @@ void screen_device::device_start() m_scanline_timer->adjust(time_until_pos(0)); // create burn-in bitmap - if (options_get_int(&machine->options(), OPTION_BURNIN) > 0) + if (machine->options().burnin()) { int width, height; - if (sscanf(options_get_string(&machine->options(), OPTION_SNAPSIZE), "%dx%d", &width, &height) != 2 || width == 0 || height == 0) + if (sscanf(machine->options().snap_size(), "%dx%d", &width, &height) != 2 || width == 0 || height == 0) width = height = 300; m_burnin = auto_alloc(machine, bitmap_t(width, height, BITMAP_FORMAT_INDEXED64)); if (m_burnin == NULL) @@ -405,7 +405,7 @@ void screen_device::device_start() } // load the effect overlay - const char *overname = options_get_string(&machine->options(), OPTION_EFFECT); + const char *overname = machine->options().effect(); if (overname != NULL && strcmp(overname, "none") != 0) load_effect_overlay(overname); @@ -1057,7 +1057,7 @@ void screen_device::finalize_burnin() // write the final PNG // compute the name and create the file - emu_file file(m_machine.options(), SEARCHPATH_SCREENSHOT, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); + emu_file file(m_machine.options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); file_error filerr = file.open(machine->basename(), PATH_SEPARATOR "burnin-", tag(), ".png") ; if (filerr == FILERR_NONE) { @@ -1094,7 +1094,7 @@ void screen_device::load_effect_overlay(const char *filename) fullname.cat(".png"); // load the file - emu_file file(m_machine.options(), OPTION_ARTPATH, OPEN_FLAG_READ); + emu_file file(m_machine.options().art_path(), OPEN_FLAG_READ); m_screen_overlay_bitmap = render_load_png(file, NULL, fullname, NULL, NULL); if (m_screen_overlay_bitmap != NULL) m_container->set_overlay(m_screen_overlay_bitmap); diff --git a/src/emu/screen.h b/src/emu/screen.h index 1de260f8b08..863f27d98d2 100644 --- a/src/emu/screen.h +++ b/src/emu/screen.h @@ -125,7 +125,7 @@ public: private: // device_config overrides - virtual bool device_validity_check(core_options &options, const game_driver &driver) const; + virtual bool device_validity_check(emu_options &options, const game_driver &driver) const; // inline configuration data screen_type_enum m_type; // type of screen diff --git a/src/emu/softlist.c b/src/emu/softlist.c index 212e488480e..31b0a9599b3 100644 --- a/src/emu/softlist.c +++ b/src/emu/softlist.c @@ -923,7 +923,7 @@ static int software_list_get_count(software_list *swlist) parent software, if any -------------------------------------------------*/ -const char *software_get_clone(core_options &options, char *swlist, const char *swname) +const char *software_get_clone(emu_options &options, char *swlist, const char *swname) { software_list *software_list_ptr = software_list_open(options, swlist, FALSE, NULL); const char *retval = NULL; @@ -943,7 +943,7 @@ const char *software_get_clone(core_options &options, char *swlist, const char * the software -------------------------------------------------*/ -UINT32 software_get_support(core_options &options, char *swlist, const char *swname) +UINT32 software_get_support(emu_options &options, char *swlist, const char *swname) { software_list *software_list_ptr = software_list_open(options, swlist, FALSE, NULL); UINT32 retval = 0; @@ -1016,7 +1016,7 @@ done: software_list_open -------------------------------------------------*/ -software_list *software_list_open(core_options &options, const char *listname, int is_preload, +software_list *software_list_open(emu_options &options, const char *listname, int is_preload, void (*error_proc)(const char *message)) { software_list *swlist = NULL; @@ -1039,7 +1039,7 @@ software_list *software_list_open(core_options &options, const char *listname, i swlist->error_proc = error_proc; /* open a file */ - swlist->file = global_alloc(emu_file(options, SEARCHPATH_HASH, OPEN_FLAG_READ)); + swlist->file = global_alloc(emu_file(options.hash_path(), OPEN_FLAG_READ)); filerr = swlist->file->open(listname, ".xml"); if (filerr != FILERR_NONE) goto error; diff --git a/src/emu/softlist.h b/src/emu/softlist.h index c04a167c8ed..d083b8a15c6 100644 --- a/src/emu/softlist.h +++ b/src/emu/softlist.h @@ -56,7 +56,7 @@ struct software_info typedef struct _software_list software_list; /* Handling a software list */ -software_list *software_list_open(core_options &options, const char *listname, int is_preload, void (*error_proc)(const char *message)); +software_list *software_list_open(emu_options &options, const char *listname, int is_preload, void (*error_proc)(const char *message)); void software_list_close(software_list *swlist); software_info *software_list_find(software_list *swlist, const char *look_for, software_info *prev); const char *software_list_get_description(software_list *swlist); @@ -66,8 +66,8 @@ software_part *software_find_part(software_info *sw, const char *partname, const software_part *software_part_next(software_part *part); /* helpers */ -const char *software_get_clone(core_options &options, char *swlist, const char *swname); -UINT32 software_get_support(core_options &options, char *swlist, const char *swname); +const char *software_get_clone(emu_options &options, char *swlist, const char *swname); +UINT32 software_get_support(emu_options &options, char *swlist, const char *swname); const char *software_part_get_feature(software_part *part, const char *feature_name); bool load_software_part(device_image_interface *image, const char *path, software_info **sw_info, software_part **sw_part, char **full_sw_name); diff --git a/src/emu/sound.c b/src/emu/sound.c index 56bcb780adb..bf10bf92990 100644 --- a/src/emu/sound.c +++ b/src/emu/sound.c @@ -773,15 +773,15 @@ sound_manager::sound_manager(running_machine &machine) m_rightmix(NULL), m_muted(0), m_attenuation(0), - m_nosound_mode(!options_get_bool(&machine.options(), OPTION_SOUND)), + m_nosound_mode(!machine.options().sound()), m_wavfile(NULL), m_stream_list(machine.m_respool), m_update_attoseconds(STREAMS_UPDATE_ATTOTIME.attoseconds), m_last_update(attotime::zero) { // get filename for WAV file or AVI file if specified - const char *wavfile = options_get_string(&machine.options(), OPTION_WAVWRITE); - const char *avifile = options_get_string(&machine.options(), OPTION_AVIWRITE); + const char *wavfile = machine.options().wav_write(); + const char *avifile = machine.options().avi_write(); // handle -nosound and lower sample rate if not recording WAV or AVI if (m_nosound_mode && wavfile[0] == 0 && avifile[0] == 0) @@ -809,7 +809,7 @@ sound_manager::sound_manager(running_machine &machine) state_save_register_global(&machine, m_last_update); // set the starting attenuation - set_attenuation(options_get_int(&machine.options(), OPTION_VOLUME)); + set_attenuation(machine.options().volume()); // start the periodic update flushing timer m_update_timer->adjust(STREAMS_UPDATE_ATTOTIME, 0, STREAMS_UPDATE_ATTOTIME); diff --git a/src/emu/sound/samples.c b/src/emu/sound/samples.c index 07d8754ba1b..b4bfdd059ce 100644 --- a/src/emu/sound/samples.c +++ b/src/emu/sound/samples.c @@ -184,7 +184,7 @@ loaded_samples *readsamples(running_machine *machine, const char *const *samplen int i; /* if the user doesn't want to use samples, bail */ - if (!options_get_bool(&machine->options(), OPTION_SAMPLES)) + if (!machine->options().samples()) return NULL; if (samplenames == 0 || samplenames[0] == 0) return NULL; @@ -206,7 +206,7 @@ loaded_samples *readsamples(running_machine *machine, const char *const *samplen for (i = 0; i < samples->total; i++) if (samplenames[i+skipfirst][0]) { - emu_file file(machine->options(), SEARCHPATH_SAMPLE, OPEN_FLAG_READ); + emu_file file(machine->options().sample_path(), OPEN_FLAG_READ); file_error filerr = file.open(basename, PATH_SEPARATOR, samplenames[i+skipfirst]); if (filerr != FILERR_NONE && skipfirst) diff --git a/src/emu/timer.c b/src/emu/timer.c index fbc1b132f67..bc9a4e8d396 100644 --- a/src/emu/timer.c +++ b/src/emu/timer.c @@ -200,7 +200,7 @@ void timer_device_config::static_set_ptr(device_config *device, void *ptr) // configuration //------------------------------------------------- -bool timer_device_config::device_validity_check(core_options &options, const game_driver &driver) const +bool timer_device_config::device_validity_check(emu_options &options, const game_driver &driver) const { bool error = false; diff --git a/src/emu/timer.h b/src/emu/timer.h index d488ea25fab..c8c38152031 100644 --- a/src/emu/timer.h +++ b/src/emu/timer.h @@ -128,7 +128,7 @@ public: private: // device_config overrides - virtual bool device_validity_check(core_options &options, const game_driver &driver) const; + virtual bool device_validity_check(emu_options &options, const game_driver &driver) const; // timer types enum timer_type diff --git a/src/emu/ui.c b/src/emu/ui.c index 847e4315093..12a39b98d4e 100644 --- a/src/emu/ui.c +++ b/src/emu/ui.c @@ -247,7 +247,7 @@ int ui_init(running_machine *machine) single_step = FALSE; ui_set_handler(handler_messagebox, 0); /* retrieve options */ - ui_use_natural_keyboard = options_get_bool(&machine->options(), OPTION_NATURAL_KEYBOARD); + ui_use_natural_keyboard = machine->options().natural_keyboard(); return 0; } @@ -273,8 +273,8 @@ static void ui_exit(running_machine &machine) int ui_display_startup_screens(running_machine *machine, int first_time, int show_disclaimer) { const int maxstate = 3; - int str = options_get_int(&machine->options(), OPTION_SECONDS_TO_RUN); - int show_gameinfo = !options_get_bool(&machine->options(), OPTION_SKIP_GAMEINFO); + int str = machine->options().seconds_to_run(); + int show_gameinfo = !machine->options().skip_gameinfo(); int show_warnings = TRUE; int state; @@ -375,7 +375,7 @@ void ui_update_and_render(running_machine *machine, render_container *container) /* if we're paused, dim the whole screen */ if (machine->phase() >= MACHINE_PHASE_RESET && (single_step || machine->paused())) { - int alpha = (1.0f - options_get_float(&machine->options(), OPTION_PAUSE_BRIGHTNESS)) * 255.0f; + int alpha = (1.0f - machine->options().pause_brightness()) * 255.0f; if (ui_menu_is_force_game_select()) alpha = 255; if (alpha > 255) @@ -412,7 +412,7 @@ render_font *ui_get_font(running_machine &machine) { /* allocate the font and messagebox string */ if (ui_font == NULL) - ui_font = machine.render().font_alloc(options_get_string(&machine.options(), OPTION_UI_FONT)); + ui_font = machine.render().font_alloc(machine.options().ui_font()); return ui_font; } @@ -1640,7 +1640,7 @@ static slider_state *slider_init(running_machine *machine) } /* add CPU overclocking (cheat only) */ - if (options_get_bool(&machine->options(), OPTION_CHEAT)) + if (machine->options().cheat()) { device_execute_interface *exec = NULL; for (bool gotone = machine->m_devicelist.first(exec); gotone; gotone = exec->next(exec)) @@ -1662,7 +1662,7 @@ static slider_state *slider_init(running_machine *machine) void *param = (void *)screen; /* add refresh rate tweaker */ - if (options_get_bool(&machine->options(), OPTION_CHEAT)) + if (machine->options().cheat()) { string.printf("%s Refresh Rate", slider_get_screen_desc(*screen)); *tailptr = slider_alloc(machine, string, -10000, 0, 10000, 1000, slider_refresh, param); @@ -2214,6 +2214,8 @@ int ui_get_use_natural_keyboard(running_machine *machine) void ui_set_use_natural_keyboard(running_machine *machine, int use_natural_keyboard) { ui_use_natural_keyboard = use_natural_keyboard; - options_set_bool(&machine->options(), OPTION_NATURAL_KEYBOARD, use_natural_keyboard, OPTION_PRIORITY_CMDLINE); + astring error; + machine->options().set_value(OPTION_NATURAL_KEYBOARD, use_natural_keyboard, OPTION_PRIORITY_CMDLINE, error); + assert(!error); } diff --git a/src/emu/uimenu.c b/src/emu/uimenu.c index eebd2ff9c68..a9fa5ec2acf 100644 --- a/src/emu/uimenu.c +++ b/src/emu/uimenu.c @@ -1405,7 +1405,7 @@ UINT32 ui_slider_ui_handler(running_machine *machine, render_container *containe void ui_menu_force_game_select(running_machine *machine, render_container *container) { - char *gamename = (char *)options_get_string(&machine->options(), OPTION_GAMENAME); + char *gamename = (char *)machine->options().system_name(); /* reset the menu stack */ ui_menu_stack_reset(machine); @@ -1570,7 +1570,7 @@ static void menu_main_populate(running_machine *machine, ui_menu *menu, void *st ui_menu_item_append(menu, "Crosshair Options", NULL, 0, (void *)menu_crosshair); /* add cheat menu */ - if (options_get_bool(&machine->options(), OPTION_CHEAT) && machine->cheat().first() != NULL) + if (machine->options().cheat() && machine->cheat().first() != NULL) ui_menu_item_append(menu, "Cheat", NULL, 0, (void *)menu_cheat); /* add memory card menu */ @@ -3299,7 +3299,7 @@ static void menu_crosshair_populate(running_machine *machine, ui_menu *menu) /* search for crosshair graphics */ /* open a path to the crosshairs */ - file_enumerator path(machine->options(), OPTION_CROSSHAIRPATH); + file_enumerator path(machine->options().crosshair_path()); const osd_directory_entry *dir; /* reset search flags */ int using_default = FALSE; @@ -3462,7 +3462,7 @@ static void menu_select_game(running_machine *machine, ui_menu *menu, void *para int audit_result; /* audit the game first to see if we're going to work */ - audit_records = audit_images(&menu->machine->options(), driver, AUDIT_VALIDATE_FAST, &audit); + audit_records = audit_images(menu->machine->options(), driver, AUDIT_VALIDATE_FAST, &audit); audit_result = audit_summary(driver, audit_records, audit, FALSE); if (audit_records > 0) global_free(audit); @@ -3614,7 +3614,7 @@ static void menu_select_game_build_driver_list(ui_menu *menu, select_game_state memset(found, 0, (driver_count + 7) / 8); /* open a path to the ROMs and find them in the array */ - file_enumerator path(menu->machine->options(), OPTION_ROMPATH); + file_enumerator path(menu->machine->options().media_path()); const osd_directory_entry *dir; /* iterate while we get new objects */ diff --git a/src/emu/validity.c b/src/emu/validity.c index 5291cd9329e..87924bdcaf2 100644 --- a/src/emu/validity.c +++ b/src/emu/validity.c @@ -1087,7 +1087,7 @@ static bool validate_inputs(const machine_config &config, int_map &defstr_map, i checks -------------------------------------------------*/ -static bool validate_devices(const machine_config &config, const ioport_list &portlist, region_array *rgninfo, core_options &options) +static bool validate_devices(const machine_config &config, const ioport_list &portlist, region_array *rgninfo, emu_options &options) { bool error = false; const game_driver &driver = config.gamedrv(); @@ -1119,10 +1119,10 @@ static bool validate_devices(const machine_config &config, const ioport_list &po /*------------------------------------------------- - mame_validitychecks - master validity checker + validate_drivers - master validity checker -------------------------------------------------*/ -bool mame_validitychecks(core_options &options, const game_driver *curdriver) +void validate_drivers(emu_options &options, const game_driver *curdriver) { osd_ticks_t prep = 0; osd_ticks_t expansion = 0; @@ -1249,5 +1249,7 @@ bool mame_validitychecks(core_options &options, const game_driver *curdriver) mame_printf_info("Input: %8dm\n", (int)(input_checks / 1000000)); #endif - return error; + // on a general error, throw rather than return + if (error) + throw emu_fatalerror(MAMERR_FAILED_VALIDITY, "Validity checks failed"); } diff --git a/src/emu/validity.h b/src/emu/validity.h index 71bcfaa8085..9864b229e61 100644 --- a/src/emu/validity.h +++ b/src/emu/validity.h @@ -14,7 +14,7 @@ #ifndef __VALIDITY_H__ #define __VALIDITY_H__ -bool mame_validitychecks(core_options &options, const game_driver *driver); +void validate_drivers(emu_options &options, const game_driver *driver = NULL); bool validate_tag(const game_driver &driver, const char *object, const char *tag); #endif diff --git a/src/emu/video.c b/src/emu/video.c index d7bf0f41284..9634deb1798 100644 --- a/src/emu/video.c +++ b/src/emu/video.c @@ -112,13 +112,13 @@ video_manager::video_manager(running_machine &machine) m_overall_real_ticks(0), m_overall_emutime(attotime::zero), m_overall_valid_counter(0), - m_throttle(options_get_bool(&machine.options(), OPTION_THROTTLE)), + m_throttle(machine.options().throttle()), m_fastforward(false), - m_seconds_to_run(options_get_int(&machine.options(), OPTION_SECONDS_TO_RUN)), - m_auto_frameskip(options_get_bool(&machine.options(), OPTION_AUTOFRAMESKIP)), + m_seconds_to_run(machine.options().seconds_to_run()), + m_auto_frameskip(machine.options().auto_frameskip()), m_speed(original_speed_setting()), m_empty_skip_count(0), - m_frameskip_level(options_get_int(&machine.options(), OPTION_FRAMESKIP)), + m_frameskip_level(machine.options().frameskip()), m_frameskip_counter(0), m_frameskip_adjust(0), m_skipping_this_frame(false), @@ -142,7 +142,7 @@ video_manager::video_manager(running_machine &machine) update_refresh_speed(); // create a render target for snapshots - const char *viewname = options_get_string(&machine.options(), OPTION_SNAPVIEW); + const char *viewname = machine.options().snap_view(); m_snap_native = (machine.primary_screen != NULL && (viewname[0] == 0 || strcmp(viewname, "native") == 0)); // the native target is hard-coded to our internal layout and has all options disabled @@ -165,15 +165,15 @@ video_manager::video_manager(running_machine &machine) } // extract snap resolution if present - if (sscanf(options_get_string(&machine.options(), OPTION_SNAPSIZE), "%dx%d", &m_snap_width, &m_snap_height) != 2) + if (sscanf(machine.options().snap_size(), "%dx%d", &m_snap_width, &m_snap_height) != 2) m_snap_width = m_snap_height = 0; // start recording movie if specified - const char *filename = options_get_string(&machine.options(), OPTION_MNGWRITE); + const char *filename = machine.options().mng_write(); if (filename[0] != 0) begin_recording(filename, MF_MNG); - filename = options_get_string(&machine.options(), OPTION_AVIWRITE); + filename = machine.options().avi_write(); if (filename[0] != 0) begin_recording(filename, MF_AVI); @@ -220,7 +220,7 @@ void video_manager::frame_update(bool debug) // only render sound and video if we're in the running phase int phase = m_machine.phase(); bool skipped_it = m_skipping_this_frame; - if (phase == MACHINE_PHASE_RUNNING && (!m_machine.paused() || options_get_bool(&m_machine.options(), OPTION_UPDATEINPAUSE))) + if (phase == MACHINE_PHASE_RUNNING && (!m_machine.paused() || m_machine.options().update_in_pause())) { bool anything_changed = finish_screen_updates(); @@ -366,7 +366,7 @@ void video_manager::save_active_screen_snapshots() for (screen_device *screen = m_machine.first_screen(); screen != NULL; screen = screen->next_screen()) if (m_machine.render().is_live(*screen)) { - emu_file file(m_machine.options(), SEARCHPATH_SCREENSHOT, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); + emu_file file(m_machine.options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); file_error filerr = open_next(file, "png"); if (filerr == FILERR_NONE) save_snapshot(screen, file); @@ -376,7 +376,7 @@ void video_manager::save_active_screen_snapshots() // otherwise, just write a single snapshot else { - emu_file file(m_machine.options(), SEARCHPATH_SCREENSHOT, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); + emu_file file(m_machine.options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); file_error filerr = open_next(file, "png"); if (filerr == FILERR_NONE) save_snapshot(NULL, file); @@ -425,7 +425,7 @@ void video_manager::begin_recording(const char *name, movie_format format) file_error filerr; astring fullpath; { - emu_file tempfile(m_machine.options(), SEARCHPATH_MOVIE, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); + emu_file tempfile(m_machine.options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); if (name != NULL) filerr = tempfile.open(name); else @@ -452,7 +452,7 @@ void video_manager::begin_recording(const char *name, movie_format format) else if (format == MF_MNG) { // create a new movie file and start recording - m_mngfile = auto_alloc(&m_machine, emu_file(m_machine.options(), SEARCHPATH_MOVIE, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS)); + m_mngfile = auto_alloc(&m_machine, emu_file(m_machine.options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS)); file_error filerr; if (name != NULL) filerr = m_mngfile->open(name); @@ -650,7 +650,7 @@ inline bool video_manager::effective_throttle() const inline int video_manager::original_speed_setting() const { - return options_get_float(&m_machine.options(), OPTION_SPEED) * 100.0 + 0.5; + return m_machine.options().speed() * 100.0 + 0.5; } @@ -850,7 +850,7 @@ osd_ticks_t video_manager::throttle_until_ticks(osd_ticks_t target_ticks) // we're allowed to sleep via the OSD code only if we're configured to do so // and we're not frameskipping due to autoframeskip, or if we're paused bool allowed_to_sleep = false; - if (options_get_bool(&m_machine.options(), OPTION_SLEEP) && (!effective_autoframeskip() || effective_frameskip() == 0)) + if (m_machine.options().sleep() && (!effective_autoframeskip() || effective_frameskip() == 0)) allowed_to_sleep = true; if (m_machine.paused()) allowed_to_sleep = true; @@ -956,7 +956,7 @@ void video_manager::update_frameskip() void video_manager::update_refresh_speed() { // only do this if the refreshspeed option is used - if (options_get_bool(&m_machine.options(), OPTION_REFRESHSPEED)) + if (m_machine.options().refresh_speed()) { float minrefresh = m_machine.render().max_update_rate(); if (minrefresh != 0) @@ -1043,7 +1043,7 @@ void video_manager::recompute_speed(attotime emutime) if (m_machine.primary_screen != NULL) { // create a final screenshot - emu_file file(m_machine.options(), SEARCHPATH_SCREENSHOT, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); + emu_file file(m_machine.options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); file_error filerr = file.open(m_machine.basename(), PATH_SEPARATOR "final.png"); if (filerr == FILERR_NONE) save_snapshot(m_machine.primary_screen, file); @@ -1105,7 +1105,7 @@ file_error video_manager::open_next(emu_file &file, const char *extension) UINT32 origflags = file.openflags(); // handle defaults - const char *snapname = options_get_string(&m_machine.options(), OPTION_SNAPNAME); + const char *snapname = m_machine.options().snap_name(); if (snapname == NULL || snapname[0] == 0) snapname = "%g/%i"; diff --git a/src/emu/video/vector.c b/src/emu/video/vector.c index 4d8711bf3da..94eb76a669c 100644 --- a/src/emu/video/vector.c +++ b/src/emu/video/vector.c @@ -175,10 +175,10 @@ float vector_get_beam(void) VIDEO_START( vector ) { - beam_width = options_get_float(&machine->options(), OPTION_BEAM); + beam_width = machine->options().beam(); /* Grab the settings for this session */ - vector_set_flicker(options_get_float(&machine->options(), OPTION_FLICKER)); + vector_set_flicker(machine->options().flicker()); vector_index = 0; @@ -256,7 +256,7 @@ void vector_clear_list (void) SCREEN_UPDATE( vector ) { - UINT32 flags = PRIMFLAG_ANTIALIAS(options_get_bool(&screen->machine->options(), OPTION_ANTIALIAS) ? 1 : 0) | PRIMFLAG_BLENDMODE(BLENDMODE_ADD); + UINT32 flags = PRIMFLAG_ANTIALIAS(screen->machine->options().antialias() ? 1 : 0) | PRIMFLAG_BLENDMODE(BLENDMODE_ADD); const rectangle &visarea = screen->visible_area(); float xscale = 1.0f / (65536 * (visarea.max_x - visarea.min_x)); float yscale = 1.0f / (65536 * (visarea.max_y - visarea.min_y)); diff --git a/src/ldplayer/ldplayer.c b/src/ldplayer/ldplayer.c index 5bb899b4033..97e47a00c01 100644 --- a/src/ldplayer/ldplayer.c +++ b/src/ldplayer/ldplayer.c @@ -93,7 +93,7 @@ static chd_file *get_disc(device_t *device) chd_file *image_chd = NULL; /* open a path to the ROMs and find the first CHD file */ - file_enumerator path(device->machine->options(), OPTION_ROMPATH); + file_enumerator path(device->machine->options().media_path()); const osd_directory_entry *dir; /* iterate while we get new objects */ @@ -112,7 +112,7 @@ static chd_file *get_disc(device_t *device) chd_error chderr; /* open the file itself via our search path */ - image_file = auto_alloc(device->machine, emu_file(device->machine->options(), SEARCHPATH_IMAGE, OPEN_FLAG_READ)); + image_file = auto_alloc(device->machine, emu_file(device->machine->options().media_path(), OPEN_FLAG_READ)); filerr = image_file->open(dir->name); if (filerr == FILERR_NONE) { diff --git a/src/lib/util/options.c b/src/lib/util/options.c index 9c735d5f3bf..3b7fcfa200d 100644 --- a/src/lib/util/options.c +++ b/src/lib/util/options.c @@ -45,101 +45,11 @@ -/*************************************************************************** - CONSTANTS -***************************************************************************/ - -#define MAX_ENTRY_NAMES 4 - - - -/*************************************************************************** - TYPE DEFINITIONS -***************************************************************************/ - -/* forward references */ -typedef struct _options_data options_data; - +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** -/* range parameter for minimum/maximum values */ -typedef union _options_range_parameter options_range_parameter; -union _options_range_parameter -{ - float f; - int i; -}; - - -/* hash table entries */ -typedef struct _options_hash_entry options_hash_entry; -struct _options_hash_entry -{ - options_hash_entry * next; /* link to the next entry */ - astring * name; /* name under the current link */ - options_data * data; /* link to associated options_data */ -}; - - -/* information about a single entry in the options */ -struct _options_data -{ - options_hash_entry links[MAX_ENTRY_NAMES]; /* array of hash table entries (one per name) */ - options_data * next; /* link to the next data */ - UINT32 flags; /* flags from the entry */ - UINT32 seqid; /* sequence ID; bumped on each change */ - int error_reported; /* have we reported an error on this option yet? */ - int priority; /* priority of the data set */ - astring * data; /* data for this item */ - astring * defdata; /* default data for this item */ - const char * description; /* description for this item */ - options_range_type range_type; /* the type of range to apply to this item */ - options_range_parameter range_minimum; /* the minimum of the range */ - options_range_parameter range_maximum; /* the maximum of the range */ - void (*callback)(core_options *opts, const char *arg); /* callback to be invoked when parsing */ -}; - - -/* structure holding information about a collection of options */ -struct _core_options -{ - void (*output[OPTMSG_COUNT])(const char *s);/* output callbacks */ - - /* linked list, for sequential iteration */ - options_data * datalist; /* linked list for sequential iteration */ - options_data ** datalist_nextptr; /* pointer to pointer to tail entry */ - - /* hashtable, for fast lookup */ - options_hash_entry * hashtable[101]; /* hash table for fast lookup */ -}; - - -/* information about an in-progress options enumeration */ -struct _options_enumerator -{ - options_data * current; -}; - - - -/*************************************************************************** - FUNCTION PROTOTYPES -***************************************************************************/ - -static options_data *find_entry_data(core_options *opts, const char *string, int is_command_line); -static void update_data(core_options *opts, options_data *data, const char *newdata, int priority); -static int parse_option_name(core_options *opts, const char *srcstring, options_data *data); - -static void message(core_options *opts, options_message msgtype, const char *format, ...) ATTR_PRINTF(3,4); -static UINT32 hash_value(core_options *opts, const char *str); -static void output_printf(void (*output)(const char *s), const char *format, ...) ATTR_PRINTF(2,3); - - - -/*************************************************************************** - GLOBAL VARIABLES -***************************************************************************/ - -const char *const option_unadorned[MAX_UNADORNED_OPTIONS] = +const char *const core_options::s_option_unadorned[MAX_UNADORNED_OPTIONS] = { "<UNADORNED0>", "<UNADORNED1>", @@ -161,448 +71,362 @@ const char *const option_unadorned[MAX_UNADORNED_OPTIONS] = -/*************************************************************************** - OPTIONS COLLECTION MANAGEMENT -***************************************************************************/ +//************************************************************************** +// CORE OPTIONS ENTRY +//************************************************************************** -/*------------------------------------------------- - options_create - creates a new instance of - core options --------------------------------------------------*/ +//------------------------------------------------- +// entry - constructor +//------------------------------------------------- -core_options *options_create(void (*fail)(const char *message)) +core_options::entry::entry(const options_entry &entrylist) + : m_next(NULL), + m_flags(entrylist.flags), + m_seqid(0), + m_error_reported(false), + m_priority(OPTION_PRIORITY_DEFAULT), + m_description(entrylist.description) { - /* allocate memory for the option block */ - core_options *opts = (core_options *)malloc(sizeof(*opts)); - if (opts == NULL) - goto error; - - /* and set up the structure */ - memset(opts, 0, sizeof(*opts)); - opts->datalist_nextptr = &opts->datalist; - return opts; - -error: - return NULL; + // copy in the name(s) as appropriate + if (entrylist.name != NULL) + { + // first extract any range + astring namestr(entrylist.name); + int lparen = namestr.chr(0, '('); + int dash = namestr.chr(lparen + 1, '-'); + int rparen = namestr.chr(dash + 1, ')'); + if (lparen != -1 && dash != -1 && rparen != -1) + { + m_minimum.cpysubstr(namestr, lparen + 1, dash - (lparen + 1)).trimspace(); + m_maximum.cpysubstr(namestr, dash + 1, rparen - (dash + 1)).trimspace(); + namestr.del(lparen, rparen + 1 - lparen); + } + + // then chop up any semicolon-separated names + int semi; + int nameindex = 0; + while ((semi = namestr.chr(0, ';')) != -1 && nameindex < ARRAY_LENGTH(m_name)) + { + m_name[nameindex++].cpysubstr(namestr, 0, semi); + namestr.del(0, semi + 1); + } + + // finally add the last item + if (nameindex < ARRAY_LENGTH(m_name)) + m_name[nameindex++] = namestr; + } + + // set the default value + if (entrylist.defvalue != NULL) + m_defdata = entrylist.defvalue; + m_data = m_defdata; } -/*------------------------------------------------- - options_free - frees an options object --------------------------------------------------*/ +//------------------------------------------------- +// set_value - update our data value +//------------------------------------------------- -void options_free(core_options *opts) +void core_options::entry::set_value(const char *newdata, int priority) { - options_data *data, *next; - - /* loop over data items and free them */ - for (data = opts->datalist; data != NULL; data = next) - { - int linknum; - - next = data->next; + // ignore if we don't have priority + if (priority < m_priority) + return; - /* free names */ - for (linknum = 0; linknum < ARRAY_LENGTH(data->links); linknum++) - if (data->links[linknum].name != NULL) - astring_free(data->links[linknum].name); + // set the data and priority, then bump the sequence + m_data = newdata; + m_priority = priority; + m_seqid++; +} - /* free strings */ - astring_free(data->data); - astring_free(data->defdata); - /* free the data itself */ - free(data); - } +//------------------------------------------------- +// set_default_value - set the default value of +// an option, and reset the current value to it +//------------------------------------------------- - /* free the options itself */ - free(opts); +void core_options::entry::set_default_value(const char *defvalue) +{ + m_data = defvalue; + m_defdata = defvalue; + m_priority = OPTION_PRIORITY_DEFAULT; } -/*------------------------------------------------- - options_set_output_callback - installs a callback - to be invoked when data is outputted in the - process of outputting options --------------------------------------------------*/ +//------------------------------------------------- +// revert - revert back to our default if we are +// at or below the given priority +//------------------------------------------------- -void options_set_output_callback(core_options *opts, options_message msgtype, void (*callback)(const char *s)) +void core_options::entry::revert(int priority) { - opts->output[msgtype] = callback; + // if our priority is low enough, revert to the default + if (m_priority <= priority) + { + m_data = m_defdata; + m_priority = OPTION_PRIORITY_DEFAULT; + } } -/*------------------------------------------------- - options_revert - revert options at or below - a certain priority back to their defaults --------------------------------------------------*/ -void options_revert(core_options *opts, int priority) +//************************************************************************** +// CORE OPTIONS +//************************************************************************** + +//------------------------------------------------- +// core_options - constructor +//------------------------------------------------- + +core_options::core_options() + : m_entrylist(NULL), + m_entrylist_tailptr(&m_entrylist) { - options_data *data; +} - /* iterate over options and revert to defaults if below the given priority */ - for (data = opts->datalist; data != NULL; data = data->next) - if (data->priority <= priority) - { - astring_cpy(data->data, data->defdata); - data->priority = OPTION_PRIORITY_DEFAULT; - } +core_options::core_options(const options_entry *entrylist) + : m_entrylist(NULL), + m_entrylist_tailptr(&m_entrylist) +{ + add_entries(entrylist); } -/*------------------------------------------------- - options_revert_driver_only - revert options - that are marked as driver only and are under - priority level --------------------------------------------------*/ +core_options::core_options(const options_entry *entrylist1, const options_entry *entrylist2) + : m_entrylist(NULL), + m_entrylist_tailptr(&m_entrylist) +{ + add_entries(entrylist1); + add_entries(entrylist2); +} -void options_revert_driver_only(core_options *opts, int priority) +core_options::core_options(const options_entry *entrylist1, const options_entry *entrylist2, const options_entry *entrylist3) + : m_entrylist(NULL), + m_entrylist_tailptr(&m_entrylist) { - options_data *data; + add_entries(entrylist1); + add_entries(entrylist2); + add_entries(entrylist3); +} - /* iterate over options and revert to defaults if below the given priority */ - for (data = opts->datalist; data != NULL; data = data->next) - if ((data->flags & OPTION_DRIVER_ONLY) && (data->priority < priority)) { - astring_cpy(data->data, data->defdata); - data->priority = OPTION_PRIORITY_DEFAULT; - } +core_options::core_options(const core_options &src) + : m_entrylist(NULL), + m_entrylist_tailptr(&m_entrylist) +{ + copyfrom(src); } -/*------------------------------------------------- - options_copy - copy options from one core_options - to another --------------------------------------------------*/ -int options_copy(core_options *dest_opts, core_options *src_opts) +//------------------------------------------------- +// ~core_options - destructor +//------------------------------------------------- + +core_options::~core_options() { - options_data *data; + // delete all entries from the list + while (m_entrylist != NULL) + remove_entry(*m_entrylist); +} - /* iterate over options in the destination */ - for (data = dest_opts->datalist; data != NULL; data = data->next) - if (!(data->flags & OPTION_HEADER)) - { - options_data *srcdata = find_entry_data(src_opts, astring_c(data->links[0].name), FALSE); - /* if the option exists in the source, set it in the destination */ - if (srcdata != NULL) - options_set_string(dest_opts, astring_c(srcdata->links[0].name), astring_c(srcdata->data), srcdata->priority); - } +//------------------------------------------------- +// operator= - assignment operator +//------------------------------------------------- - return TRUE; +core_options &core_options::operator=(const core_options &rhs) +{ + // ignore self-assignment + if (this != &rhs) + copyfrom(rhs); + return *this; } -/*------------------------------------------------- - options_equal - compare two sets of options --------------------------------------------------*/ +//------------------------------------------------- +// operator== - compare two sets of options +//------------------------------------------------- -int options_equal(core_options *opts1, core_options *opts2) +bool core_options::operator==(const core_options &rhs) { - options_data *data; - - /* iterate over options in the first list */ - for (data = opts1->datalist; data != NULL; data = data->next) - if (!(data->flags & OPTION_HEADER)) + // iterate over options in the first list + for (entry *curentry = m_entrylist; curentry != NULL; curentry = curentry->next()) + if (!curentry->is_header()) { - const char *value1 = options_get_string(opts1, astring_c(data->links[0].name)); - const char *value2 = options_get_string(opts2, astring_c(data->links[0].name)); - - /* if the values differ, return false */ - if (strcmp(value1, value2) != 0) - return FALSE; + // if the values differ, return false + if (strcmp(curentry->m_data, rhs.value(curentry->name())) != 0) + return false; } - return TRUE; + return true; } +//------------------------------------------------- +// operator!= - compare two sets of options +//------------------------------------------------- -/*************************************************************************** - OPTION DEFINITIONS -***************************************************************************/ +bool core_options::operator!=(const core_options &rhs) +{ + return !operator==(rhs); +} -/*------------------------------------------------- - options_add_entries - add entries to the - current options sets --------------------------------------------------*/ -int options_add_entries(core_options *opts, const options_entry *entrylist, int force) +//------------------------------------------------- +// add_entries - add entries to the current +// options sets +//------------------------------------------------- + +void core_options::add_entries(const options_entry *entrylist, bool override_existing) { - /* loop over entries until we hit a NULL name */ - for ( ; entrylist->name != NULL || (entrylist->flags & OPTION_HEADER); entrylist++) + // loop over entries until we hit a NULL name + for ( ; entrylist->name != NULL || (entrylist->flags & OPTION_HEADER) != 0; entrylist++) { - options_data *match = NULL; - int i; - - /* allocate a new item */ - options_data *data = (options_data *)malloc(sizeof(*data)); - if (data == NULL) - return FALSE; - memset(data, 0, sizeof(*data)); - - /* parse the option name */ - if (entrylist->name != NULL) - parse_option_name(opts, entrylist->name, data); - - /* do we match an existing entry? */ - for (i = 0; i < ARRAY_LENGTH(data->links) && match == NULL; i++) - if (data->links[i].name != NULL) - match = find_entry_data(opts, astring_c(data->links[i].name), FALSE); - - /* if so, throw away this entry and replace the data */ - if ((force == FALSE) && (match != NULL)) - { - /* free what we've allocated so far */ - for (i = 0; i < ARRAY_LENGTH(data->links); i++) - if (data->links[i].name != NULL) - astring_free(data->links[i].name); - free(data); - - /* use the matching entry as our data */ - data = match; - } - - /* otherwise, finish making the new entry */ - else + // allocate a new entry + entry *newentry = new entry(*entrylist); + if (newentry->name() != NULL) { - /* allocate strings */ - data->data = astring_alloc(); - data->defdata = astring_alloc(); - - /* copy the flags, and set the value equal to the default */ - data->flags = entrylist->flags; - data->description = entrylist->description; - - /* add us to the end of the sequential list */ - *opts->datalist_nextptr = data; - opts->datalist_nextptr = &data->next; - - /* add each name to the appropriate hash table with a link back to us */ - for (i = 0; i < ARRAY_LENGTH(data->links); i++) - if (data->links[i].name != NULL) + // see if we match an existing entry + entry *existing = m_entrymap.find(newentry->name()); + if (existing != NULL) + { + // if we're overriding existing entries, then remove the old one + if (override_existing) + remove_entry(*existing); + + // otherwise, just override the default and current values and throw out the new entry + else { - int hash_entry = hash_value(opts, astring_c(data->links[i].name)); - - /* set up link */ - data->links[i].data = data; - data->links[i].next = opts->hashtable[hash_entry]; - opts->hashtable[hash_entry] = &data->links[i]; + existing->set_default_value(newentry->value()); + delete newentry; + continue; } + } } - - /* copy in the data and default data values */ - if (entrylist->defvalue != NULL) - { - astring_cpyc(data->data, entrylist->defvalue); - astring_cpyc(data->defdata, entrylist->defvalue); - } - data->priority = OPTION_PRIORITY_DEFAULT; + + // add us to the list and maps + append_entry(*newentry); } - return TRUE; } -int options_add_entries(core_options *opts, const options_entry *entrylist) -{ - return options_add_entries(opts,entrylist,FALSE); -} -/*------------------------------------------------- - options_set_option_default_value - change the - default value of an option --------------------------------------------------*/ +//------------------------------------------------- +// set_default_value - change the default value +// of an option +//------------------------------------------------- -int options_set_option_default_value(core_options *opts, const char *name, const char *defvalue) +void core_options::set_default_value(const char *name, const char *defvalue) { - options_data *data = find_entry_data(opts, name, TRUE); - - /* if we don't have an entry for this, fail */ - if (data == NULL) - return FALSE; - - /* update the data and default data; note that we assume that data == defdata */ - astring_cpyc(data->data, defvalue); - astring_cpyc(data->defdata, defvalue); - data->priority = OPTION_PRIORITY_DEFAULT; - return TRUE; + // find the entry and bail if we can't + entry *curentry = m_entrymap.find(name); + if (curentry == NULL) + return; + + // update the data and default data + curentry->set_default_value(defvalue); } -/*------------------------------------------------- - options_set_option_callback - specifies a - callback to be invoked when parsing options --------------------------------------------------*/ +//------------------------------------------------- +// parse_command_line - parse a series of +// command line arguments +//------------------------------------------------- -int options_set_option_callback(core_options *opts, const char *name, void (*callback)(core_options *opts, const char *arg)) +bool core_options::parse_command_line(int argc, char **argv, int priority, astring &error_string) { - options_data *data = find_entry_data(opts, name, TRUE); - - /* if we don't find an entry, fail */ - if (data == NULL) - return FALSE; - - /* set the callback */ - data->callback = callback; - return TRUE; -} - - + // reset the errors and the command + error_string.reset(); + m_command.reset(); -/*************************************************************************** - OPTION DATA EXTRACTION -***************************************************************************/ - -/*------------------------------------------------- - options_parse_command_line - parse a series - of command line arguments --------------------------------------------------*/ - -int options_parse_command_line(core_options *opts, int argc, char **argv, int priority, int show_error) -{ + // iterate through arguments int unadorned_index = 0; - int arg; - for (arg = 1; arg < argc; arg++) + for (int arg = 1; arg < argc; arg++) { - const char *optionname; - options_data *data; - int is_unadorned; - - /* determine the entry name to search for */ - is_unadorned = (argv[arg][0] != '-'); - if (!is_unadorned) - optionname = &argv[arg][1]; - else - optionname = OPTION_UNADORNED(unadorned_index); - - /* find our entry */ - data = find_entry_data(opts, optionname, TRUE); - if (data == NULL) continue; - if ((data->flags & OPTION_COMMAND) != 0) { - // in case of any command force show error to TRUE - show_error = TRUE; - break; + // determine the entry name to search for + const char *curarg = argv[arg]; + bool is_unadorned = (curarg[0] != '-'); + const char *optionname = is_unadorned ? core_options::unadorned(unadorned_index++) : &curarg[1]; + + // find our entry; if not found, indicate invalid option + entry *curentry = m_entrymap.find(optionname); + if (curentry == NULL) + { + error_string.catprintf("Error: unknown option: %s\n", curarg); + return false; } - } - /* loop over commands, looking for options */ - for (arg = 1; arg < argc; arg++) - { - const char *optionname, *newdata; - options_data *data; - int is_unadorned; - - /* determine the entry name to search for */ - is_unadorned = (argv[arg][0] != '-'); - if (!is_unadorned) - optionname = &argv[arg][1]; - else - optionname = OPTION_UNADORNED(unadorned_index); - - /* find our entry */ - data = find_entry_data(opts, optionname, TRUE); - if (data == NULL) + + // process commands first + if (curentry->type() == OPTION_COMMAND) { - if (!show_error) continue; - message(opts, OPTMSG_ERROR, "Error: unknown option: %s\n", argv[arg]); - return 1; + // can only have one command + if (m_command) + { + error_string.catprintf("Error: multiple commands specified -%s and %s\n", m_command.cstr(), curarg); + return false; + } + m_command = curentry->name(); + continue; } - /* if unadorned, we have to bump the count (unless if the option repeats) */ - if (is_unadorned && !(data->flags & OPTION_REPEATS)) - unadorned_index++; - - /* get the data for this argument, special casing booleans */ - if ((data->flags & (OPTION_BOOLEAN | OPTION_COMMAND)) != 0) - newdata = (strncmp(&argv[arg][1], "no", 2) == 0) ? "0" : "1"; - else if (argv[arg][0] != '-') - newdata = argv[arg]; + // get the data for this argument, special casing booleans + const char *newdata; + if (curentry->type() == OPTION_BOOLEAN) + newdata = (strncmp(&curarg[1], "no", 2) == 0) ? "0" : "1"; + else if (is_unadorned) + newdata = curarg; else if (arg + 1 < argc) newdata = argv[++arg]; else { - message(opts, OPTMSG_ERROR, "Error: option %s expected a parameter\n", argv[arg]); - return 1; + error_string.catprintf("Error: option %s expected a parameter\n", curarg); + return false; } - /* if the option is deprecated or internal, don't process further */ - if ((data->flags & (OPTION_DEPRECATED | OPTION_INTERNAL)) != 0) - continue; - - /* invoke callback, if present */ - if (data->callback != NULL) - (*data->callback)(opts, newdata); - - /* allocate a new copy of data for this */ - update_data(opts, data, newdata, priority); + // set the new data + validate_and_set_data(*curentry, newdata, priority, error_string); } - return 0; -} - - -/*------------------------------------------------- - options_force_option_callback - set option value - and execute callback call --------------------------------------------------*/ - -int options_force_option_callback(core_options *opts, const char *optionname, const char *newval, int priority) -{ - options_data *data = find_entry_data(opts, optionname, TRUE); - if (data == NULL) - { - message(opts, OPTMSG_ERROR, "Error: unknown option: %s\n", optionname); - return 1; - } - - /* invoke callback, if present */ - if (data->callback != NULL) - (*data->callback)(opts, newval); - - /* allocate a new copy of data for this */ - update_data(opts, data, newval, priority); - return 0; + return true; } -/*------------------------------------------------- - options_parse_ini_file - parse a series - of entries in an INI file --------------------------------------------------*/ +//------------------------------------------------- +// parse_ini_file - parse a series of entries in +// an INI file +//------------------------------------------------- -int options_parse_ini_file(core_options *opts, core_file *inifile, int priority, int ignoreprio) +bool core_options::parse_ini_file(core_file &inifile, int priority, int ignore_priority, astring &error_string) { + // loop over lines in the file char buffer[4096]; - - /* loop over data */ - while (core_fgets(buffer, ARRAY_LENGTH(buffer), inifile) != NULL) + while (core_fgets(buffer, ARRAY_LENGTH(buffer), &inifile) != NULL) { - char *optionname, *optiondata, *temp; - options_data *data; - int inquotes = FALSE; - - /* find the name */ + // find the extent of the name + char *optionname; for (optionname = buffer; *optionname != 0; optionname++) if (!isspace((UINT8)*optionname)) break; - /* skip comments */ + // skip comments if (*optionname == 0 || *optionname == '#') continue; - /* scan forward to find the first space */ + // scan forward to find the first space + char *temp; for (temp = optionname; *temp != 0; temp++) if (isspace((UINT8)*temp)) break; - /* if we hit the end early, print a warning and continue */ + // if we hit the end early, print a warning and continue if (*temp == 0) { - message(opts, OPTMSG_WARNING, "Warning: invalid line in INI: %s", buffer); + error_string.catprintf("Warning: invalid line in INI: %s", buffer); continue; } - /* NULL-terminate */ + // NULL-terminate *temp++ = 0; - optiondata = temp; + char *optiondata = temp; - /* scan the data, stopping when we hit a comment */ + // scan the data, stopping when we hit a comment + bool inquotes = false; for (temp = optiondata; *temp != 0; temp++) { if (*temp == '"') @@ -612,645 +436,319 @@ int options_parse_ini_file(core_options *opts, core_file *inifile, int priority, } *temp = 0; - /* find our entry */ - data = find_entry_data(opts, optionname, FALSE); - if (data == NULL) + // find our entry + entry *curentry = m_entrymap.find(optionname); + if (curentry == NULL) { - if (priority >= ignoreprio) message(opts, OPTMSG_WARNING, "Warning: unknown option in INI: %s\n", optionname); + if (priority >= ignore_priority) + error_string.catprintf("Warning: unknown option in INI: %s\n", optionname); continue; } - if ((data->flags & (OPTION_DEPRECATED | OPTION_INTERNAL)) != 0) - continue; - /* allocate a new copy of data for this */ - update_data(opts, data, optiondata, priority); + // set the new data + validate_and_set_data(*curentry, optiondata, priority, error_string); } - return 0; + return true; } +//------------------------------------------------- +// revert - revert options at or below a certain +// priority back to their defaults +//------------------------------------------------- + +void core_options::revert(int priority) +{ + // iterate over options and revert to defaults if below the given priority + for (entry *curentry = m_entrylist; curentry != NULL; curentry = curentry->next()) + curentry->revert(priority); +} -/*************************************************************************** - OPTIONS OUTPUT -***************************************************************************/ -/*------------------------------------------------- - options_output_diff_ini_file - output the diff - of the current state from a base state to an - INI file --------------------------------------------------*/ +//------------------------------------------------- +// output_ini - output the options in INI format, +// only outputting entries that different from +// the optional diff +//------------------------------------------------- -void options_output_diff_ini_file(core_options *opts, core_options *baseopts, core_file *inifile) +const char *core_options::output_ini(astring &buffer, const core_options *diff) { - options_data *data; - const char *last_header = NULL; - const char *name; - const char *value; - options_data *basedata; + // INI files are complete, so always start with a blank buffer + buffer.reset(); - /* loop over all items */ - for (data = opts->datalist; data != NULL; data = data->next) + // loop over all items + const char *last_header = NULL; + for (entry *curentry = m_entrylist; curentry != NULL; curentry = curentry->next()) { - /* header: record description */ - if ((data->flags & OPTION_HEADER) != 0) - last_header = data->description; + // header: record description + if (curentry->is_header()) + last_header = curentry->description(); - /* otherwise, output entries for all non-deprecated and non-command items (if not in baseopts) */ - else if ((data->flags & (OPTION_DEPRECATED | OPTION_INTERNAL | OPTION_COMMAND)) == 0) + // otherwise, output entries for all non-command items + else if (!curentry->is_command()) { - /* get name and data of this value */ - name = astring_c(data->links[0].name); - value = astring_c(data->data); - - /* look up counterpart in baseopts, if baseopts is specified */ - basedata = (baseopts != NULL) ? find_entry_data(baseopts, name, FALSE) : NULL; - - /* is our data different, or not in baseopts? */ - if ((basedata == NULL) || (strcmp(value, astring_c(basedata->data)) != 0)) + // look up counterpart in diff, if diff is specified + const char *name = curentry->name(); + const char *value = curentry->value(); + if (diff == NULL || strcmp(value, diff->value(name)) != 0) { - /* output header, if we have one */ + // output header, if we have one if (last_header != NULL) { - core_fprintf(inifile, "\n#\n# %s\n#\n", last_header); + buffer.catprintf("\n#\n# %s\n#\n", last_header); last_header = NULL; } - /* and finally output the data */ + // and finally output the data if (strchr(value, ' ') != NULL) - core_fprintf(inifile, "%-25s \"%s\"\n", name, value); + buffer.catprintf("%-25s \"%s\"\n", name, value); else - core_fprintf(inifile, "%-25s %s\n", name, value); + buffer.catprintf("%-25s %s\n", name, value); } } } + return buffer; } -/*------------------------------------------------- - options_output_ini_file - output the current - state to an INI file --------------------------------------------------*/ - -void options_output_ini_file(core_options *opts, core_file *inifile) -{ - options_output_diff_ini_file(opts, NULL, inifile); -} - - -/*------------------------------------------------- - options_output_ini_file - output the current - state to an INI file --------------------------------------------------*/ - -void options_output_ini_stdfile(core_options *opts, FILE *inifile) -{ - options_data *data; - - /* loop over all items */ - for (data = opts->datalist; data != NULL; data = data->next) - { - /* header: just print */ - if ((data->flags & OPTION_HEADER) != 0) - fprintf(inifile, "\n#\n# %s\n#\n", data->description); - - /* otherwise, output entries for all non-deprecated and non-command items */ - else if ((data->flags & (OPTION_DEPRECATED | OPTION_INTERNAL | OPTION_COMMAND)) == 0) - { - if (astring_chr(data->data, 0, ' ') != -1) - fprintf(inifile, "%-25s \"%s\"\n", astring_c(data->links[0].name), astring_c(data->data)); - else - fprintf(inifile, "%-25s %s\n", astring_c(data->links[0].name), astring_c(data->data)); - } - } -} - - -/*------------------------------------------------- - options_output_help - output option help to - a file --------------------------------------------------*/ +//------------------------------------------------- +// output_help - output option help to a string +//------------------------------------------------- -void options_output_help(core_options *opts, void (*output)(const char *)) +const char *core_options::output_help(astring &buffer) { - options_data *data; - - /* loop over all items */ - for (data = opts->datalist; data != NULL; data = data->next) + // start empty + buffer.reset(); + + // loop over all items + for (entry *curentry = m_entrylist; curentry != NULL; curentry = curentry->next()) { - /* header: just print */ - if ((data->flags & OPTION_HEADER) != 0) - output_printf(output, "\n#\n# %s\n#\n", data->description); + // header: just print + if (curentry->is_header()) + buffer.catprintf("\n#\n# %s\n#\n", curentry->description()); - /* otherwise, output entries for all non-deprecated items */ - else if ((data->flags & (OPTION_DEPRECATED | OPTION_INTERNAL)) == 0 && data->description != NULL) - output_printf(output, "-%-20s%s\n", astring_c(data->links[0].name), data->description); + // otherwise, output entries for all non-deprecated items + else if (curentry->description() != NULL) + buffer.catprintf("-%-20s%s\n", curentry->name(), curentry->description()); } + return buffer; } +//------------------------------------------------- +// value - return the raw option value +//------------------------------------------------- -/*************************************************************************** - OPTIONS READING -***************************************************************************/ - -/*------------------------------------------------- - options_get_string - return data formatted - as a string --------------------------------------------------*/ - -const char *options_get_string(core_options *opts, const char *name) +const char *core_options::value(const char *name) const { - options_data *data = find_entry_data(opts, name, FALSE); - const char *value = ""; - - /* error if not found */ - if (data == NULL) - message(opts, OPTMSG_ERROR, "Unexpected option %s queried\n", name); - - /* copy if non-NULL */ - else - value = astring_c(data->data); - - return value; + entry *curentry = m_entrymap.find(name); + return (curentry != NULL) ? curentry->value() : ""; } -/*------------------------------------------------- - options_get_string_priority - return data - formatted as a string if priority is equal - or better --------------------------------------------------*/ +//------------------------------------------------- +// seqid - return the seqid for a given option +//------------------------------------------------- -const char *options_get_string_priority(core_options *opts, const char *name, int priority) +UINT32 core_options::seqid(const char *name) const { - options_data *data = find_entry_data(opts, name, FALSE); - const char *value = ""; - - /* error if not found */ - if (data == NULL) - message(opts, OPTMSG_ERROR, "Unexpected option %s queried\n", name); - - /* copy if non-NULL */ - else { - if (data->priority!=OPTION_PRIORITY_DEFAULT) { - if (priority > data->priority) return value; - } - value = astring_c(data->data); - } - - return value; + entry *curentry = m_entrymap.find(name); + return (curentry != NULL) ? curentry->seqid() : 0; } -/*------------------------------------------------- - options_get_bool - return data formatted as - a boolean --------------------------------------------------*/ +//------------------------------------------------- +// set_value - set the raw option value +//------------------------------------------------- -int options_get_bool(core_options *opts, const char *name) +bool core_options::set_value(const char *name, const char *value, int priority, astring &error_string) { - options_data *data = find_entry_data(opts, name, FALSE); - int value = FALSE; - - /* error if not found */ - if (data == NULL) - message(opts, OPTMSG_ERROR, "Unexpected boolean option %s queried\n", name); - - /* also error if we don't have a valid boolean value */ - else if (sscanf(astring_c(data->data), "%d", &value) != 1 || value < 0 || value > 1) + // find the entry first + entry *curentry = m_entrymap.find(name); + if (curentry == NULL) { - options_set_string(opts, name, astring_c(data->defdata), 0); - sscanf(astring_c(data->data), "%d", &value); - if (!data->error_reported) - { - message(opts, OPTMSG_ERROR, "Illegal boolean value for %s; reverting to %d\n", astring_c(data->links[0].name), value); - data->error_reported = TRUE; - } + error_string.catprintf("Attempted to set unknown option %s\n", name); + return false; } - return value; + + // validate and set the item normally + return validate_and_set_data(*curentry, value, priority, error_string); } - -/*------------------------------------------------- - options_get_int - return data formatted as - an integer --------------------------------------------------*/ - -int options_get_int(core_options *opts, const char *name) +bool core_options::set_value(const char *name, int value, int priority, astring &error_string) { - options_data *data = find_entry_data(opts, name, FALSE); - int value = 0; - - /* error if not found */ - if (data == NULL) - message(opts, OPTMSG_ERROR, "Unexpected integer option %s queried\n", name); - - /* also error if we don't have a valid integer value */ - else if (sscanf(astring_c(data->data), "%d", &value) != 1) - { - options_set_string(opts, name, astring_c(data->defdata), 0); - sscanf(astring_c(data->data), "%d", &value); - if (!data->error_reported) - { - message(opts, OPTMSG_ERROR, "Illegal integer value for %s; reverting to %d\n", astring_c(data->links[0].name), value); - data->error_reported = TRUE; - } - } - return value; + astring tempstr; + tempstr.printf("%d", value); + return set_value(name, tempstr.cstr(), priority, error_string); } - -/*------------------------------------------------- - options_get_float - return data formatted as - a float --------------------------------------------------*/ - -float options_get_float(core_options *opts, const char *name) +bool core_options::set_value(const char *name, float value, int priority, astring &error_string) { - options_data *data = find_entry_data(opts, name, FALSE); - float value = 0; - - /* error if not found */ - if (data == NULL) - message(opts, OPTMSG_ERROR, "Unexpected float option %s queried\n", name); - - /* also error if we don't have a valid floating point value */ - else if (sscanf(astring_c(data->data), "%f", &value) != 1) - { - options_set_string(opts, name, astring_c(data->defdata), 0); - sscanf(astring_c(data->data), "%f", &value); - if (!data->error_reported) - { - message(opts, OPTMSG_ERROR, "Illegal float value for %s; reverting to %f\n", astring_c(data->links[0].name), (double)value); - data->error_reported = TRUE; - } - } - return value; -} - - -/*------------------------------------------------- - options_get_seqid - return the seqid for an - entry --------------------------------------------------*/ - -UINT32 options_get_seqid(core_options *opts, const char *name) -{ - options_data *data = find_entry_data(opts, name, FALSE); - return (data == NULL) ? 0 : data->seqid; -} - - - -/*************************************************************************** - OPTIONS SETTING -***************************************************************************/ - -/*------------------------------------------------- - options_set_string - set a string value --------------------------------------------------*/ - -void options_set_string(core_options *opts, const char *name, const char *value, int priority) -{ - options_data *data = find_entry_data(opts, name, FALSE); - update_data(opts, data, value, priority); -} - - -/*------------------------------------------------- - options_set_bool - set a boolean value --------------------------------------------------*/ - -void options_set_bool(core_options *opts, const char *name, int value, int priority) -{ - char temp[4]; - sprintf(temp, "%d", value ? 1 : 0); - options_set_string(opts, name, temp, priority); -} - - -/*------------------------------------------------- - options_set_int - set an integer value --------------------------------------------------*/ - -void options_set_int(core_options *opts, const char *name, int value, int priority) -{ - char temp[20]; - sprintf(temp, "%d", value); - options_set_string(opts, name, temp, priority); + astring tempstr; + tempstr.printf("%f", value); + return set_value(name, tempstr.cstr(), priority, error_string); } -/*------------------------------------------------- - options_set_float - set a float value --------------------------------------------------*/ +//------------------------------------------------- +// reset - reset the options state, removing +// everything +//------------------------------------------------- -void options_set_float(core_options *opts, const char *name, float value, int priority) +void core_options::reset() { - char temp[100]; - sprintf(temp, "%f", value); - options_set_string(opts, name, temp, priority); -} - - - -/*************************************************************************** - OPTION DEFINITION QUERIES -***************************************************************************/ - -/*------------------------------------------------- - options_enumerator_begin - retrieve the range of - a float option --------------------------------------------------*/ - -options_enumerator *options_enumerator_begin(core_options *opts) -{ - options_enumerator *enumerator; - - /* allocate memory for the enumerator */ - enumerator = (options_enumerator *)malloc(sizeof(*enumerator)); - if (enumerator == NULL) - return NULL; - - /* start at the head of the list */ - enumerator->current = opts->datalist; - return enumerator; + // remove all entries from the list + while (m_entrylist != NULL) + remove_entry(*m_entrylist); + + // reset the map + m_entrymap.reset(); } +//------------------------------------------------- +// append_entry - append an entry to our list +// and index it in the map +//------------------------------------------------- -/*------------------------------------------------- - options_enumerator_next - returns the current - option and advances the enumerator --------------------------------------------------*/ - -const char *options_enumerator_next(options_enumerator *enumerator) +void core_options::append_entry(core_options::entry &newentry) { - astring *option_name = NULL; - - /* be sure to skip over false options */ - while (option_name == NULL && enumerator->current != NULL) - { - /* retrieve the current option name and advance the enumerator */ - option_name = enumerator->current->links[0].name; - enumerator->current = enumerator->current->next; - } - return (option_name != NULL) ? astring_c(option_name) : NULL; -} - - + // append to the list + *m_entrylist_tailptr = &newentry; + m_entrylist_tailptr = &newentry.m_next; -/*------------------------------------------------- - options_enumerator_free - disposes an options - enumerator --------------------------------------------------*/ - -void options_enumerator_free(options_enumerator *enumerator) -{ - free(enumerator); + // if we have names, add them to the map + for (int name = 0; name < ARRAY_LENGTH(newentry.m_name); name++) + if (newentry.m_name[name]) + m_entrymap.add(newentry.m_name[name], &newentry); } -/*------------------------------------------------- - options_get_range_type - determine the type - of range for a particular option --------------------------------------------------*/ +//------------------------------------------------- +// remove_entry - remove an entry from our list +// and map +//------------------------------------------------- -options_range_type options_get_range_type(core_options *opts, const char *name) +void core_options::remove_entry(core_options::entry &delentry) { - options_data *data = find_entry_data(opts, name, FALSE); - return data->range_type; -} - - -/*------------------------------------------------- - options_get_range_int - retrieve the range of - an integer option --------------------------------------------------*/ + // remove us from the list + entry *preventry = NULL; + for (entry *curentry = m_entrylist; curentry != NULL; curentry = curentry->next()) + if (curentry == &delentry) + { + // update link from previous to us + if (preventry != NULL) + preventry->m_next = delentry.m_next; + else + m_entrylist = delentry.m_next; + + // if we're the last item, update the next pointer + if (delentry.m_next == NULL) + { + if (preventry != NULL) + m_entrylist_tailptr = &preventry->m_next; + else + m_entrylist_tailptr = &m_entrylist; + } -void options_get_range_int(core_options *opts, const char *name, int *minval, int *maxval) -{ - options_data *data = find_entry_data(opts, name, FALSE); - *minval = data->range_minimum.i; - *maxval = data->range_maximum.i; + // remove all entries from the map + for (int name = 0; name < ARRAY_LENGTH(delentry.m_name); name++) + if (delentry.m_name[name]) + m_entrymap.remove(delentry.m_name[name]); + break; + } } +//------------------------------------------------- +// copyfrom - copy options from another set +//------------------------------------------------- -/*------------------------------------------------- - options_get_range_float - retrieve the range of - a float option --------------------------------------------------*/ - -void options_get_range_float(core_options *opts, const char *name, float *minval, float *maxval) +void core_options::copyfrom(const core_options &src) { - options_data *data = find_entry_data(opts, name, FALSE); - *minval = data->range_minimum.f; - *maxval = data->range_maximum.f; + // reset ourselves first + reset(); + + // iterate through the src options and make our own + for (entry *curentry = src.m_entrylist; curentry != NULL; curentry = curentry->next()) + append_entry(*new entry(*curentry)); } +//------------------------------------------------- +// validate_and_set_data - make sure the data is +// of the appropriate type and within range, +// then set it +//------------------------------------------------- -/*************************************************************************** - INTERNAL UTILITIES -***************************************************************************/ - -/*------------------------------------------------- - find_entry_data - locate an entry whose name - matches the given string --------------------------------------------------*/ - -static options_data *find_entry_data(core_options *opts, const char *string, int is_command_line) +bool core_options::validate_and_set_data(core_options::entry &curentry, const char *newdata, int priority, astring &error_string) { - int hash_entry = hash_value(opts, string); - options_hash_entry *link; - - /* scan all entries */ - for (link = opts->hashtable[hash_entry]; link != NULL; link = link->next) - if (!(link->data->flags & OPTION_HEADER) && link->name != NULL && astring_cmpc(link->name, string) == 0) - return link->data; - - /* haven't found it? if we are prefixed with "no", then try to search for that */ - if (is_command_line && string[0] == 'n' && string[1] == 'o') + // trim any whitespace + astring data(newdata); + data.trimspace(); + + // trim quotes + if (data.chr(0, '"') == 0 && data.rchr(0, '"') == data.len() - 1) { - options_data *data = find_entry_data(opts, &string[2], FALSE); - if (data != NULL && (data->flags & OPTION_BOOLEAN)) - return data; + data.del(0, 1); + data.del(data.len() - 1, 1); } - - /* didn't find it at all */ - return NULL; -} - - -/*------------------------------------------------- - update_data - update the data value for a - given entry --------------------------------------------------*/ - -static void update_data(core_options *opts, options_data *data, const char *newdata, int priority) -{ - const char *dataend = newdata + strlen(newdata) - 1; - const char *datastart = newdata; - float f; - int i; - - /* strip off leading/trailing spaces */ - while (isspace((UINT8)*datastart) && datastart <= dataend) - datastart++; - while (isspace((UINT8)*dataend) && datastart <= dataend) - dataend--; - - /* strip off quotes */ - if (datastart != dataend && *datastart == '"' && *dataend == '"') - datastart++, dataend--; - - /* check against range */ - switch (data->range_type) + + // validate the type of data and optionally the range + float fval; + int ival; + switch (curentry.type()) { - case OPTION_RANGE_NONE: - /* do nothing */ + // booleans must be 0 or 1 + case OPTION_BOOLEAN: + if (sscanf(data, "%d", &ival) != 1 || ival < 0 || ival > 1) + { + error_string.catprintf("Illegal boolean value for %s: \"%s\"; reverting to %s\n", curentry.name(), data.cstr(), curentry.value()); + return false; + } break; - - case OPTION_RANGE_INT: - /* check against integer range */ - i = 0; - if (sscanf(datastart, "%d", &i) != 1) + + // integers must be integral + case OPTION_INTEGER: + if (sscanf(data, "%d", &ival) != 1) { - message(opts, OPTMSG_ERROR, "Illegal integer value for %s; keeping value of %s\n", astring_c(data->links[0].name), astring_c(data->data)); - data->error_reported = TRUE; - return; + error_string.catprintf("Illegal integer value for %s: \"%s\"; reverting to %s\n", curentry.name(), data.cstr(), curentry.value()); + return false; } - if (i < data->range_minimum.i || i > data->range_maximum.i) + if (curentry.has_range() && (ival < atoi(curentry.minimum()) || ival > atoi(curentry.maximum()))) { - message(opts, OPTMSG_ERROR, "Invalid %s value (must be between %i and %i); keeping value of %s\n", - astring_c(data->links[0].name), data->range_minimum.i, data->range_maximum.i, astring_c(data->data)); - data->error_reported = TRUE; - return; + error_string.catprintf("Out-of-range integer value for %s: \"%s\" (must be between %s and %s); reverting to %s\n", curentry.name(), data.cstr(), curentry.minimum(), curentry.maximum(), curentry.value()); + return false; } break; - - case OPTION_RANGE_FLOAT: - /* check against float range */ - f = 0; - if (sscanf(datastart, "%f", &f) != 1) + + // floating-point values must be numeric + case OPTION_FLOAT: + if (sscanf(data, "%f", &fval) != 1) { - message(opts, OPTMSG_ERROR, "Illegal float value for %s; keeping value of %s\n", astring_c(data->links[0].name), astring_c(data->data)); - data->error_reported = TRUE; - return; + error_string.catprintf("Illegal float value for %s: \"%s\"; reverting to %s\n", curentry.name(), data.cstr(), curentry.value()); + return false; } - if (f < data->range_minimum.f || f > data->range_maximum.f) + if (curentry.has_range() && (fval < atof(curentry.minimum()) || fval > atof(curentry.maximum()))) { - message(opts, OPTMSG_ERROR, "Invalid %s value (must be between %f and %f); keeping value of %s\n", - astring_c(data->links[0].name), data->range_minimum.f, data->range_maximum.f, astring_c(data->data)); - data->error_reported = TRUE; - return; + error_string.catprintf("Out-of-range float value for %s: \"%s\" (must be between %s and %s); reverting to %s\n", curentry.name(), data.cstr(), curentry.minimum(), curentry.maximum(), curentry.value()); + return false; } break; - } - - /* ignore if we don't have priority */ - if (priority < data->priority) { - return; - } - /* allocate a copy of the data */ - astring_cpych(data->data, datastart, dataend + 1 - datastart); - data->priority = priority; - - /* bump the seqid and clear the error reporting */ - data->seqid++; - data->error_reported = FALSE; -} - - -/*------------------------------------------------- - parse_option_name - read data from an option_entry - name into an option_data structure --------------------------------------------------*/ - -static int parse_option_name(core_options *opts, const char *srcstring, options_data *data) -{ - const char *start; - const char *end = NULL; - int curentry; - - /* start with the original string and loop over entries */ - start = srcstring; - for (curentry = 0; curentry < ARRAY_LENGTH(data->links); curentry++) - { - /* find the end of this entry and copy the string */ - for (end = start; *end != 0 && *end != ';' && *end != '('; end++) - ; - data->links[curentry].name = astring_dupch(start, end - start); - - /* if we hit the end of the source, stop */ - if (*end != ';') + + // strings can be anything + case OPTION_STRING: break; - start = end + 1; - } - - /* have we found a range? */ - if (end != NULL && *end == '(') - { - if (sscanf(end, "(%d-%d)", &data->range_minimum.i, &data->range_maximum.i) == 2) - data->range_type = OPTION_RANGE_INT; - else if (sscanf(end, "(%f-%f)", &data->range_minimum.f, &data->range_maximum.f) == 2) - data->range_type = OPTION_RANGE_FLOAT; - } - return curentry; -} - - -/*------------------------------------------------- - message - outputs a message to a listener --------------------------------------------------*/ - -static void message(core_options *opts, options_message msgtype, const char *format, ...) -{ - char buf[1024]; - va_list argptr; - - /* output a message if there is a non-NULL handler for it */ - if (opts->output[msgtype] != NULL) - { - va_start(argptr, format); - vsprintf(buf, format, argptr); - va_end(argptr); - - (*opts->output[msgtype])(buf); + + // anything else is invalid + case OPTION_INVALID: + case OPTION_HEADER: + default: + error_string.catprintf("Attempted to set invalid option %s\n", curentry.name()); + return false; } -} - - -/*------------------------------------------------- - hash_value - computes the hash value for a string --------------------------------------------------*/ - -static UINT32 hash_value(core_options *opts, const char *str) -{ - UINT32 hash = 5381; - int c; - - while ((c = *str++) != 0) - hash = ((hash << 5) + hash) + c; - - return hash % ARRAY_LENGTH(opts->hashtable); -} - - -/*------------------------------------------------- - output_printf - outputs an arbitrary message - to a callback --------------------------------------------------*/ - -static void output_printf(void (*output)(const char *s), const char *format, ...) -{ - char buf[1024]; - va_list argptr; - - va_start(argptr, format); - vsprintf(buf, format, argptr); - va_end(argptr); - - output(buf); + + // set the data + curentry.set_value(data, priority); + return true; } diff --git a/src/lib/util/options.h b/src/lib/util/options.h index 0350b16bdb6..0ec2783dffd 100644 --- a/src/lib/util/options.h +++ b/src/lib/util/options.h @@ -42,216 +42,164 @@ #include "osdcore.h" #include "corefile.h" +#include "tagmap.h" -/*************************************************************************** - CONSTANTS -***************************************************************************/ - -/* unadorned option names */ -#define MAX_UNADORNED_OPTIONS 16 -#define OPTION_UNADORNED(x) (((x) < MAX_UNADORNED_OPTIONS) ? option_unadorned[x] : "") - -/* option flags */ -#define OPTION_BOOLEAN 0x0001 /* option is a boolean value */ -#define OPTION_DEPRECATED 0x0002 /* option is deprecated */ -#define OPTION_COMMAND 0x0004 /* option is a command */ -#define OPTION_HEADER 0x0008 /* text-only header */ -#define OPTION_INTERNAL 0x0010 /* option is internal-only */ -#define OPTION_REPEATS 0x0020 /* unadorned option repeats */ -#define OPTION_DRIVER_ONLY 0x0040 /* remove value if found in lower levels */ - -/* option priorities */ -#define OPTION_PRIORITY_DEFAULT 0 /* defaults are at 0 priority */ -#define OPTION_PRIORITY_LOW 50 /* low priority */ -#define OPTION_PRIORITY_NORMAL 100 /* normal priority */ -#define OPTION_PRIORITY_HIGH 150 /* high priority */ -#define OPTION_PRIORITY_MAXIMUM 255 /* maximum priority */ +//************************************************************************** +// CONSTANTS +//************************************************************************** +// option types +const UINT32 OPTION_TYPE_MASK = 0x0007; // up to 8 different types +enum +{ + OPTION_INVALID, // invalid + OPTION_HEADER, // a header item + OPTION_COMMAND, // a command + OPTION_BOOLEAN, // boolean option + OPTION_INTEGER, // integer option + OPTION_FLOAT, // floating-point option + OPTION_STRING // string option +}; +// option priorities +const int OPTION_PRIORITY_DEFAULT = 0; // defaults are at 0 priority +const int OPTION_PRIORITY_LOW = 50; // low priority +const int OPTION_PRIORITY_NORMAL = 100; // normal priority +const int OPTION_PRIORITY_HIGH = 150; // high priority +const int OPTION_PRIORITY_MAXIMUM = 255; // maximum priority -/*************************************************************************** - TYPE DEFINITIONS -***************************************************************************/ -/* opaque type representing a collection of options */ -typedef struct _core_options core_options; -/* opaque type use for enumeration of options */ -typedef struct _options_enumerator options_enumerator; +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** -/* describes a single option with its description and default value */ -typedef struct _options_entry options_entry; -struct _options_entry +// static structure describing a single option with its description and default value +struct options_entry { - const char * name; /* name on the command line */ - const char * defvalue; /* default value of this argument */ - UINT32 flags; /* flags to describe the option */ - const char * description; /* description for -showusage */ + const char * name; // name on the command line + const char * defvalue; // default value of this argument + UINT32 flags; // flags to describe the option + const char * description; // description for -showusage }; -/* output messages are one of the following types */ -enum _options_message -{ - OPTMSG_INFO, - OPTMSG_WARNING, - OPTMSG_ERROR, - OPTMSG_COUNT -}; -typedef enum _options_message options_message; -/* option ranges are one of the following types */ -enum _options_range_type +// structure holding information about a collection of options +class core_options { - OPTION_RANGE_NONE, - OPTION_RANGE_INT, - OPTION_RANGE_FLOAT + static const int MAX_UNADORNED_OPTIONS = 16; + +public: + // information about a single entry in the options + class entry + { + friend class core_options; + + // construction/destruction + entry(const options_entry &entry); + + public: + // getters + entry *next() const { return m_next; } + const char *name() const { return m_name[0] ? m_name[0].cstr() : NULL; } + const char *description() const { return m_description; } + const char *value() const { return m_data; } + const char *default_value() const { return m_defdata; } + const char *minimum() const { return m_minimum; } + const char *maximum() const { return m_maximum; } + UINT32 seqid() const { return m_seqid; } + int type() const { return (m_flags & OPTION_TYPE_MASK); } + UINT32 flags() const { return m_flags; } + bool is_header() const { return type() == OPTION_HEADER; } + bool is_command() const { return type() == OPTION_COMMAND; } + bool has_range() const { return (m_minimum && m_maximum); } + + // setters + void set_value(const char *newvalue, int priority); + void set_default_value(const char *defvalue); + void revert(int priority); + + private: + // internal state + entry * m_next; // link to the next data + UINT32 m_flags; // flags from the entry + UINT32 m_seqid; // sequence ID; bumped on each change + bool m_error_reported; // have we reported an error on this option yet? + int m_priority; // priority of the data set + const char * m_description; // description for this item + astring m_name[4]; // up to 4 names for the item + astring m_data; // data for this item + astring m_defdata; // default data for this item + astring m_minimum; // minimum value + astring m_maximum; // maximum value + }; + + // construction/destruction + core_options(); + core_options(const options_entry *entrylist); + core_options(const options_entry *entrylist1, const options_entry *entrylist2); + core_options(const options_entry *entrylist1, const options_entry *entrylist2, const options_entry *entrylist3); + core_options(const core_options &src); + virtual ~core_options(); + + // operators + core_options &operator=(const core_options &rhs); + bool operator==(const core_options &rhs); + bool operator!=(const core_options &rhs); + + // getters + entry *first() const { return m_entrylist; } + const char *command() const { return m_command; } + + // configuration + void add_entries(const options_entry *entrylist, bool override_existing = false); + void set_default_value(const char *name, const char *defvalue); + void remove_entry(entry &delentry); + + // parsing/input + bool parse_command_line(int argc, char **argv, int priority, astring &error_string); + bool parse_ini_file(core_file &inifile, int priority, int ignore_priority, astring &error_string); + + // reverting + void revert(int priority = OPTION_PRIORITY_MAXIMUM); + + // output + const char *output_ini(astring &buffer, const core_options *diff = NULL); + const char *output_help(astring &buffer); + + // reading + const char *value(const char *option) const; + bool bool_value(const char *name) const { return (atoi(value(name)) != 0); } + int int_value(const char *name) const { return atoi(value(name)); } + float float_value(const char *name) const { return atof(value(name)); } + UINT32 seqid(const char *name) const; + + // setting + void set_command(const char *command); + bool set_value(const char *name, const char *value, int priority, astring &error_string); + bool set_value(const char *name, int value, int priority, astring &error_string); + bool set_value(const char *name, float value, int priority, astring &error_string); + + // misc + static const char *unadorned(int x = 0) { return s_option_unadorned[MIN(x, MAX_UNADORNED_OPTIONS)]; } + +private: + // internal helpers + void reset(); + void append_entry(entry &newentry); + void copyfrom(const core_options &src); + bool validate_and_set_data(entry &curentry, const char *newdata, int priority, astring &error_string); + + // internal state + entry * m_entrylist; // head of list of entries + entry ** m_entrylist_tailptr; // pointer to tail of entry list + tagmap_t<entry *> m_entrymap; // map for fast lookup + astring m_command; // command found + static const char *const s_option_unadorned[]; // array of unadorned option "names" }; -typedef enum _options_range_type options_range_type; - - - -/*************************************************************************** - GLOBAL VARIABLES -***************************************************************************/ - -extern const char *const option_unadorned[MAX_UNADORNED_OPTIONS]; - - - -/*************************************************************************** - FUNCTION PROTOTYPES -***************************************************************************/ - - -/* ----- options collection management ----- */ - -/* create a new collection of options */ -core_options *options_create(void (*fail)(const char *message)); - -/* free a collection of options */ -void options_free(core_options *opts); - -/* set a callback for a particular class of message */ -void options_set_output_callback(core_options *opts, options_message msgtype, void (*callback)(const char *s)); - -/* revert options at or below a certain priority back to their defaults */ -void options_revert(core_options *opts, int priority); - -/* revert options that are marked as driver only */ -void options_revert_driver_only(core_options *opts, int priority); - -/* copy one collection of options into another */ -int options_copy(core_options *dest_opts, core_options *src_opts); - -/* compare two collections of options */ -int options_equal(core_options *opts1, core_options *opts2); - - - -/* ----- option definitions ----- */ - -/* add a set of entries to an options collection */ -int options_add_entries(core_options *opts, const options_entry *entrylist); - -/* add a set of entries to an options collection, and force recreation if true */ -int options_add_entries(core_options *opts, const options_entry *entrylist, int force); - -/* set the default value for a particular option entry */ -int options_set_option_default_value(core_options *opts, const char *name, const char *defvalue); - -/* set a callback for a particular option entry */ -int options_set_option_callback(core_options *opts, const char *name, void (*callback)(core_options *opts, const char *arg)); - - - -/* ----- option data extraction ----- */ - -/* parse option data from a command line */ -int options_parse_command_line(core_options *opts, int argc, char **argv, int priority, int show_error); - -/* set option value and execute callback call */ -int options_force_option_callback(core_options *opts, const char *optionname, const char *newval, int priority); - -/* parse option data from an INI file */ -int options_parse_ini_file(core_options *opts, core_file *inifile, int priority, int ignoreprio); - - - -/* ----- options output ----- */ - -/* output option data to an INI file */ -void options_output_ini_file(core_options *opts, core_file *inifile); - -/* output differing option data to an INI file */ -void options_output_diff_ini_file(core_options *opts, core_options *baseopts, core_file *inifile); - -/* output option data to a standard file handle */ -void options_output_ini_stdfile(core_options *opts, FILE *inifile); - -/* output help using the specified output function */ -void options_output_help(core_options *opts, void (*output)(const char *s)); - - - -/* ----- options reading ----- */ - -/* read an option as a string */ -const char *options_get_string(core_options *opts, const char *name); - -/* read an option as a string with priority */ -const char *options_get_string_priority(core_options *opts, const char *name, int priority); - -/* read an option as a boolean */ -int options_get_bool(core_options *opts, const char *name); - -/* read an option as an integer */ -int options_get_int(core_options *opts, const char *name); - -/* read an option as a floating point value */ -float options_get_float(core_options *opts, const char *name); - -/* read an option as a string */ -UINT32 options_get_seqid(core_options *opts, const char *name); - - - -/* ----- options setting ----- */ - -/* set an option as a string */ -void options_set_string(core_options *opts, const char *name, const char *value, int priority); - -/* set an option as a boolean */ -void options_set_bool(core_options *opts, const char *name, int value, int priority); - -/* set an option as an integer */ -void options_set_int(core_options *opts, const char *name, int value, int priority); - -/* set an option as a floating point value */ -void options_set_float(core_options *opts, const char *name, float value, int priority); - - - -/* ----- option definition queries ----- */ - -/* begin enumerating option definitions */ -options_enumerator *options_enumerator_begin(core_options *opts); - -/* get the next option in sequence */ -const char *options_enumerator_next(options_enumerator *enumerator); - -/* free memory allocated for enumeration */ -void options_enumerator_free(options_enumerator *enumerator); - -/* get the type of range for a given option */ -options_range_type options_get_range_type(core_options *opts, const char *name); - -/* return an integer range for a given option */ -void options_get_range_int(core_options *opts, const char *name, int *minval, int *maxval); -/* return a floating point range for a given option */ -void options_get_range_float(core_options *opts, const char *name, float *minval, float *maxval); #endif /* __OPTIONS_H__ */ diff --git a/src/mame/drivers/konamigx.c b/src/mame/drivers/konamigx.c index 337bc18abc1..81f91725abf 100644 --- a/src/mame/drivers/konamigx.c +++ b/src/mame/drivers/konamigx.c @@ -1983,8 +1983,8 @@ ROM_START(konamigx) ROM_REGION( 0x400000, "shared", ROMREGION_ERASE00 ) ROM_END -#define SPR_WOR_DROM_LOAD(name,offset,length,crc) ROMX_LOAD(name, offset, length, crc, ROM_GROUPSIZE(2) | ROM_SKIP(5)) -#define SPR_5TH_ROM_LOAD(name,offset,length,crc) ROMX_LOAD(name, offset, length, crc, ROM_GROUPSIZE(1) | ROM_SKIP(5)) +#define SPR_WOR_DROM_LOAD(name,offset,length,crc) ROMX_LOAD(name, offset, length, crc, ROM_GROUPWORD | ROM_SKIP(5)) +#define SPR_5TH_ROM_LOAD(name,offset,length,crc) ROMX_LOAD(name, offset, length, crc, ROM_GROUPBYTE | ROM_SKIP(5)) #define TILE_WORD_ROM_LOAD(name,offset,length,crc) ROMX_LOAD(name, offset, length, crc, ROM_GROUPDWORD | ROM_SKIP(1)) #define TILE_BYTE_ROM_LOAD(name,offset,length,crc) ROMX_LOAD(name, offset, length, crc, ROM_GROUPBYTE | ROM_SKIP(4)) diff --git a/src/mame/drivers/pinkiri8.c b/src/mame/drivers/pinkiri8.c index 8924840e548..7f3505ad898 100644 --- a/src/mame/drivers/pinkiri8.c +++ b/src/mame/drivers/pinkiri8.c @@ -74,7 +74,7 @@ public: virtual device_t *alloc_device(running_machine &machine) const; protected: virtual void device_config_complete(); - virtual bool device_validity_check(core_options &options, const game_driver &driver) const; + virtual bool device_validity_check(emu_options &options, const game_driver &driver) const; virtual const address_space_config *memory_space_config(int spacenum = 0) const; address_space_config m_space_config; }; @@ -117,7 +117,7 @@ void janshi_vdp_device_config::device_config_complete() // m_space_config = address_space_config("janshi_vdp", ENDIANNESS_BIG, 8, address_bits, 0, *ADDRESS_MAP_NAME(janshi_vdp_map8)); } -bool janshi_vdp_device_config::device_validity_check(core_options &options, const game_driver &driver) const +bool janshi_vdp_device_config::device_validity_check(emu_options &options, const game_driver &driver) const { bool error = false; return error; diff --git a/src/mame/machine/fddebug.c b/src/mame/machine/fddebug.c index b67982367c1..3dc6ce3ede2 100644 --- a/src/mame/machine/fddebug.c +++ b/src/mame/machine/fddebug.c @@ -584,7 +584,7 @@ static void load_overlay_file(running_machine *machine) int pcaddr; /* determine the filename and open the file */ - emu_file file(machine->options(), SEARCHPATH_RAW, OPEN_FLAG_READ); + emu_file file(OPEN_FLAG_READ); file_error filerr = file.open(machine->gamedrv->name, ".kov"); if (filerr == FILERR_NONE) { @@ -610,7 +610,7 @@ static void save_overlay_file(running_machine *machine) int pcaddr; /* determin the filename and open the file */ - emu_file file(machine->options(), SEARCHPATH_RAW, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE); + emu_file file(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE); file_error filerr = file.open(machine->gamedrv->name, ".kov"); if (filerr == FILERR_NONE) { @@ -753,7 +753,7 @@ static void execute_fdoutput(running_machine *machine, int ref, int params, cons fd1094_regenerate_key(machine); /* determin the filename and open the file */ - emu_file file(machine->options(), SEARCHPATH_RAW, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE); + emu_file file(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE); file_error filerr = file.open(param[0]); if (filerr == FILERR_NONE) file.write(keyregion, KEY_SIZE); @@ -1176,7 +1176,7 @@ static void execute_fddasm(running_machine *machine, int ref, int params, const filename = param[0]; /* open the file */ - emu_file file(machine->options(), SEARCHPATH_RAW, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE); + emu_file file(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE); file_error filerr = file.open(filename); if (filerr != FILERR_NONE) { diff --git a/src/mame/video/gp9001.c b/src/mame/video/gp9001.c index ef142c82741..a13427073de 100644 --- a/src/mame/video/gp9001.c +++ b/src/mame/video/gp9001.c @@ -234,7 +234,7 @@ void gp9001vdp_device_config::static_set_gfx_region(device_config *device, int g vdp->m_gfxregion = gfxregion; } -bool gp9001vdp_device_config::device_validity_check(core_options &options, const game_driver &driver) const +bool gp9001vdp_device_config::device_validity_check(emu_options &options, const game_driver &driver) const { bool error = false; return error; diff --git a/src/mame/video/gp9001.h b/src/mame/video/gp9001.h index da76b4d37fc..f49225126da 100644 --- a/src/mame/video/gp9001.h +++ b/src/mame/video/gp9001.h @@ -10,7 +10,7 @@ public: virtual device_t *alloc_device(running_machine &machine) const; static void static_set_gfx_region(device_config *device, int gfxregion); protected: - virtual bool device_validity_check(core_options &options, const game_driver &driver) const; + virtual bool device_validity_check(emu_options &options, const game_driver &driver) const; virtual const address_space_config *memory_space_config(int spacenum = 0) const; address_space_config m_space_config; UINT8 m_gfxregion; diff --git a/src/osd/sdl/draw13.c b/src/osd/sdl/draw13.c index be73eeb742b..71129e0cdc0 100644 --- a/src/osd/sdl/draw13.c +++ b/src/osd/sdl/draw13.c @@ -506,7 +506,7 @@ int draw13_init(running_machine &machine, sdl_draw_info *callbacks) // Load the GL library now - else MT will fail - stemp = options_get_string(&machine.options(), SDLOPTION_GL_LIB); + stemp = downcast<sdl_options &>(machine.options()).gl_lib(); if (stemp != NULL && strcmp(stemp, SDLOPTVAL_AUTO) == 0) stemp = NULL; diff --git a/src/osd/sdl/drawogl.c b/src/osd/sdl/drawogl.c index 59dfb6f5400..78a5b45c882 100644 --- a/src/osd/sdl/drawogl.c +++ b/src/osd/sdl/drawogl.c @@ -513,7 +513,7 @@ static void load_gl_lib(running_machine &machine) */ const char *stemp; - stemp = options_get_string(&machine.options(), SDLOPTION_GL_LIB); + stemp = downcast<sdl_options &>(machine.options()).gl_lib(); if (stemp != NULL && strcmp(stemp, SDLOPTVAL_AUTO) == 0) stemp = NULL; @@ -1241,7 +1241,7 @@ static int drawogl_window_draw(sdl_window_info *window, UINT32 dc, int update) // we're doing nothing 3d, so the Z-buffer is currently not interesting glDisable(GL_DEPTH_TEST); - if (options_get_bool(&window->machine->options(), OPTION_ANTIALIAS)) + if (window->machine->options().antialias()) { // enable antialiasing for lines glEnable(GL_LINE_SMOOTH); @@ -2973,9 +2973,9 @@ static void texture_shader_update(sdl_window_info *window, texture_info *texture container->get_user_settings(settings); //FIXME: Intended behaviour #if 1 - vid_attributes[0] = options_get_float(&window->machine->options(), OPTION_GAMMA); - vid_attributes[1] = options_get_float(&window->machine->options(), OPTION_CONTRAST); - vid_attributes[2] = options_get_float(&window->machine->options(), OPTION_BRIGHTNESS); + vid_attributes[0] = window->machine->options().gamma(); + vid_attributes[1] = window->machine->options().contrast(); + vid_attributes[2] = window->machine->options().brightness(); #else vid_attributes[0] = settings.gamma; vid_attributes[1] = settings.contrast; diff --git a/src/osd/sdl/input.c b/src/osd/sdl/input.c index 7945742cc73..5a13c86fd78 100644 --- a/src/osd/sdl/input.c +++ b/src/osd/sdl/input.c @@ -638,7 +638,7 @@ static void devmap_init(running_machine *machine, device_map_t *devmap, const ch const char *dev_name; sprintf(defname, "%s%d", opt, dev + 1); - dev_name = options_get_string(&machine->options(), defname); + dev_name = machine->options().value(defname); if (dev_name && *dev_name && strcmp(dev_name,SDLOPTVAL_AUTO)) { devmap->map[dev].name = remove_spaces(machine, dev_name); @@ -795,7 +795,7 @@ static void sdlinput_register_mice(running_machine *machine) { int index, physical_mouse; - mouse_enabled = options_get_bool(&machine->options(), OPTION_MOUSE); + mouse_enabled = machine->options().mouse(); devmap_init(machine, &mouse_map, SDLOPTION_MOUSEINDEX, 8, "Mouse mapping"); @@ -855,7 +855,7 @@ static void sdlinput_register_mice(running_machine *machine) devinfo = generic_device_alloc(&mouse_list, "System mouse"); devinfo->device = input_device_add(machine, DEVICE_CLASS_MOUSE, devinfo->name, devinfo); - mouse_enabled = options_get_bool(&machine->options(), OPTION_MOUSE); + mouse_enabled = machine->options().mouse(); // add the axes input_device_item_add(devinfo->device, "X", &devinfo->mouse.lX, ITEM_ID_XAXIS, generic_axis_get_state); @@ -942,10 +942,10 @@ static kt_table * sdlinput_read_keymap(running_machine *machine) char sks[21]; char kns[21]; - if (!options_get_bool(&machine->options(), SDLOPTION_KEYMAP)) + if (!machine->options().bool_value(SDLOPTION_KEYMAP)) return sdl_key_trans_table; - keymap_filename = (char *)options_get_string(&machine->options(), SDLOPTION_KEYMAP_FILE); + keymap_filename = (char *)downcast<sdl_options &>(machine->options()).keymap_file(); mame_printf_verbose("Keymap: Start reading keymap_file %s\n", keymap_filename); keymap_file = fopen(keymap_filename, "r"); @@ -1125,7 +1125,7 @@ void sdlinput_init(running_machine *machine) } // get Sixaxis special mode info - sixaxis_mode = options_get_bool(&machine->options(), SDLOPTION_SIXAXIS); + sixaxis_mode = downcast<sdl_options &>(machine->options()).sixaxis(); // register the joysticks sdlinput_register_joysticks(machine); @@ -1602,7 +1602,7 @@ void sdl_osd_interface::customize_input_type_list(input_type_desc *typelist) { // configurable UI mode switch case IPT_UI_TOGGLE_UI: - uimode = (const char *)options_get_string(&machine().options(), SDLOPTION_UIMODEKEY); + uimode = downcast<sdl_options &>(machine().options()).ui_mode_key(); if(!strcmp(uimode,"auto")) { #if defined(__APPLE__) && defined(__MACH__) mameid_code = lookup_mame_code("ITEM_ID_INSERT"); diff --git a/src/osd/sdl/osdsdl.h b/src/osd/sdl/osdsdl.h index 78a527ba990..5b70b9f2e1d 100644 --- a/src/osd/sdl/osdsdl.h +++ b/src/osd/sdl/osdsdl.h @@ -4,6 +4,7 @@ #include <SDL/SDL.h> #include "watchdog.h" +#include "clifront.h" //============================================================ // Temporary SDL 1.3 defines @@ -50,10 +51,10 @@ #define SDLOPTION_INIPATH "inipath" #define SDLOPTION_AUDIO_LATENCY "audio_latency" -#define SDLOPTION_SCREEN(x) "screen" x -#define SDLOPTION_ASPECT(x) "aspect" x -#define SDLOPTION_RESOLUTION(x) "resolution" x -#define SDLOPTION_VIEW(x) "view" x +#define SDLOPTION_SCREEN "screen" +#define SDLOPTION_ASPECT "aspect" +#define SDLOPTION_RESOLUTION "resolution" +#define SDLOPTION_VIEW "view" #define SDLOPTION_SDLVIDEOFPS "sdlvideofps" #define SDLOPTION_KEEPASPECT "keepaspect" #define SDLOPTION_WINDOW "window" @@ -87,8 +88,8 @@ #define SDLOPTION_KEYBINDEX "keyb_idx" #define SDLOPTION_MOUSEINDEX "mouse_index" -#define SDLOPTION_SHADER_MAME(x) "glsl_shader_mame" x -#define SDLOPTION_SHADER_SCREEN(x) "glsl_shader_screen" x +#define SDLOPTION_SHADER_MAME "glsl_shader_mame" +#define SDLOPTION_SHADER_SCREEN "glsl_shader_screen" #define SDLOPTION_GLSL_FILTER "gl_glsl_filter" #define SDLOPTION_GL_GLSL "gl_glsl" #define SDLOPTION_GL_PBO "gl_pbo" @@ -140,6 +141,97 @@ typedef void *osd_font; +//============================================================ +// TYPE DEFINITIONS +//============================================================ + +class sdl_options : public cli_options +{ +public: + // construction/destruction + sdl_options(); + + // debugging options + bool oslog() const { return bool_value(SDLOPTION_OSLOG); } + int watchdog() const { return int_value(SDLOPTION_WATCHDOG); } + + // performance options + bool multithreading() const { return bool_value(SDLOPTION_MULTITHREADING); } + const char *numprocessors() const { return value(SDLOPTION_NUMPROCESSORS); } + bool video_fps() const { return bool_value(SDLOPTION_SDLVIDEOFPS); } + int bench() const { return int_value(SDLOPTION_BENCH); } + + // video options + const char *video() const { return value(SDLOPTION_VIDEO); } + int numscreens() const { return int_value(SDLOPTION_NUMSCREENS); } + bool window() const { return bool_value(SDLOPTION_WINDOW); } + bool maximize() const { return bool_value(SDLOPTION_MAXIMIZE); } + bool keep_aspect() const { return bool_value(SDLOPTION_KEEPASPECT); } + bool uneven_stretch() const { return bool_value(SDLOPTION_UNEVENSTRETCH); } + bool centerh() const { return bool_value(SDLOPTION_CENTERH); } + bool centerv() const { return bool_value(SDLOPTION_CENTERV); } + bool wait_vsync() const { return bool_value(SDLOPTION_WAITVSYNC); } + bool sync_refresh() const { return bool_value(SDLOPTION_SYNCREFRESH); } + const char *scale_mode() const { return value(SDLOPTION_SCALEMODE); } + + // OpenGL specific options + bool filter() const { return bool_value(SDLOPTION_FILTER); } + int prescale() const { return bool_value(SDLOPTION_PRESCALE); } + bool gl_force_pow2_texture() const { return bool_value(SDLOPTION_GL_FORCEPOW2TEXTURE); } + bool gl_no_texture_rect() const { return bool_value(SDLOPTION_GL_NOTEXTURERECT); } + bool gl_vbo() const { return bool_value(SDLOPTION_GL_VBO); } + bool gl_pbo() const { return bool_value(SDLOPTION_GL_PBO); } + bool gl_glsl() const { return bool_value(SDLOPTION_GL_GLSL); } + bool glsl_filter() const { return bool_value(SDLOPTION_GLSL_FILTER); } + const char *shader_mame(int index) const { astring temp; return value(temp.format("%s%d", SDLOPTION_SHADER_MAME, index)); } + const char *shader_screen(int index) const { astring temp; return value(temp.format("%s%d", SDLOPTION_SHADER_SCREEN, index)); } + bool glsl_vid_attr() const { return bool_value(SDLOPTION_GL_GLSL_VID_ATTR); } + + // per-window options + const char *screen() const { return value(SDLOPTION_SCREEN); } + const char *aspect() const { return value(SDLOPTION_ASPECT); } + const char *resolution() const { return value(SDLOPTION_RESOLUTION); } + const char *view() const { return value(SDLOPTION_VIEW); } + const char *screen(int index) const { astring temp; return value(temp.format("%s%d", SDLOPTION_SCREEN, index)); } + const char *aspect(int index) const { astring temp; return value(temp.format("%s%d", SDLOPTION_ASPECT, index)); } + const char *resolution(int index) const { astring temp; return value(temp.format("%s%d", SDLOPTION_RESOLUTION, index)); } + const char *view(int index) const { astring temp; return value(temp.format("%s%d", SDLOPTION_VIEW, index)); } + + // full screen options + bool switch_res() const { return bool_value(SDLOPTION_SWITCHRES); } +#ifdef SDLMAME_X11 + bool use_all_heads() const { return bool_value(SDLOPTION_USEALLHEADS); } +#endif + + // sound options + int audio_latency() const { return int_value(SDLOPTION_AUDIO_LATENCY); } + + // keyboard mapping + bool keymap() const { return bool_value(SDLOPTION_KEYMAP); } + const char *keymap_file() const { return value(SDLOPTION_KEYMAP_FILE); } + const char *ui_mode_key() const { return value(SDLOPTION_UIMODEKEY); } + + // joystick mapping + const char *joy_index(int index) const { astring temp; return value(temp.format("%s%d", SDLOPTION_JOYINDEX, index)); } + bool sixaxis() const { return bool_value(SDLOPTION_SIXAXIS); } + +#if (SDL_VERSION_ATLEAST(1,3,0)) + const char *mouse_index(int index) const { astring temp; return value(temp.format("%s%d", SDLOPTION_MOUSEINDEX, index)); } + const char *keyboard_index(int index) const { astring temp; return value(temp.format("%s%d", SDLOPTION_KEYBINDEX, index)); } +#endif + + const char *video_driver() const { return value(SDLOPTION_VIDEODRIVER); } + const char *render_driver() const { return value(SDLOPTION_RENDERDRIVER); } + const char *audio_driver() const { return value(SDLOPTION_AUDIODRIVER); } +#if USE_OPENGL + const char *gl_lib() const { return value(SDLOPTION_GL_LIB); } +#endif + +private: + static const options_entry s_option_entries[]; +}; + + class sdl_osd_interface : public osd_interface { public: diff --git a/src/osd/sdl/sdlmain.c b/src/osd/sdl/sdlmain.c index a8b92d1bfec..b35c0b2db05 100644 --- a/src/osd/sdl/sdlmain.c +++ b/src/osd/sdl/sdlmain.c @@ -80,30 +80,30 @@ // Local variables //============================================================ -static const options_entry mame_sdl_options[] = +const options_entry sdl_options::s_option_entries[] = { - { SDLOPTION_INIPATH, INI_PATH, 0, "path to ini files" }, + { SDLOPTION_INIPATH, INI_PATH, OPTION_STRING, "path to ini files" }, // debugging options { NULL, NULL, OPTION_HEADER, "DEBUGGING OPTIONS" }, { SDLOPTION_OSLOG, "0", OPTION_BOOLEAN, "output error.log data to the system debugger" }, - { SDLOPTION_WATCHDOG ";wdog", "0", 0, "force the program to terminate if no updates within specified number of seconds" }, + { SDLOPTION_WATCHDOG ";wdog", "0", OPTION_INTEGER, "force the program to terminate if no updates within specified number of seconds" }, // performance options { NULL, NULL, OPTION_HEADER, "PERFORMANCE OPTIONS" }, { SDLOPTION_MULTITHREADING ";mt", "0", OPTION_BOOLEAN, "enable multithreading; this enables rendering and blitting on a separate thread" }, - { SDLOPTION_NUMPROCESSORS ";np", "auto", 0, "number of processors; this overrides the number the system reports" }, + { SDLOPTION_NUMPROCESSORS ";np", "auto", OPTION_INTEGER, "number of processors; this overrides the number the system reports" }, { SDLOPTION_SDLVIDEOFPS, "0", OPTION_BOOLEAN, "show sdl video performance" }, - { SDLOPTION_BENCH, "0", 0, "benchmark for the given number of emulated seconds; implies -video none -nosound -nothrottle" }, + { SDLOPTION_BENCH, "0", OPTION_INTEGER, "benchmark for the given number of emulated seconds; implies -video none -nosound -nothrottle" }, // video options { NULL, NULL, OPTION_HEADER, "VIDEO OPTIONS" }, // OS X can be trusted to have working hardware OpenGL, so default to it on for the best user experience #ifdef SDLMAME_MACOSX - { SDLOPTION_VIDEO, SDLOPTVAL_OPENGL, 0, "video output method: soft or opengl" }, + { SDLOPTION_VIDEO, SDLOPTVAL_OPENGL, OPTION_STRING, "video output method: soft or opengl" }, #else - { SDLOPTION_VIDEO, SDLOPTVAL_SOFT, 0, "video output method: soft or opengl" }, + { SDLOPTION_VIDEO, SDLOPTVAL_SOFT, OPTION_STRING, "video output method: soft or opengl" }, #endif - { SDLOPTION_NUMSCREENS, "1", 0, "number of screens to create; SDLMAME only supports 1 at this time" }, + { SDLOPTION_NUMSCREENS, "1", OPTION_INTEGER, "number of screens to create; SDLMAME only supports 1 at this time" }, { SDLOPTION_WINDOW ";w", "0", OPTION_BOOLEAN, "enable window mode; otherwise, full screen mode is assumed" }, { SDLOPTION_MAXIMIZE ";max", "1", OPTION_BOOLEAN, "default to maximized windows; otherwise, windows will be minimized" }, { SDLOPTION_KEEPASPECT ";ka", "1", OPTION_BOOLEAN, "constrain to the proper aspect ratio" }, @@ -115,70 +115,70 @@ static const options_entry mame_sdl_options[] = { SDLOPTION_SYNCREFRESH, "0", OPTION_BOOLEAN, "enable using the start of VBLANK for throttling instead of the game time" }, #endif #if (SDL_VERSION_ATLEAST(1,3,0)) - { SDLOPTION_SCALEMODE ";sm", SDLOPTVAL_NONE, 0, "Scale mode: none, hwblit, hwbest, yv12, yuy2, yv12x2, yuy2x2 (-video soft only)" }, + { SDLOPTION_SCALEMODE ";sm", SDLOPTVAL_NONE, OPTION_STRING, "Scale mode: none, hwblit, hwbest, yv12, yuy2, yv12x2, yuy2x2 (-video soft only)" }, #else - { SDLOPTION_SCALEMODE ";sm", SDLOPTVAL_NONE, 0, "Scale mode: none, async, yv12, yuy2, yv12x2, yuy2x2 (-video soft only)" }, + { SDLOPTION_SCALEMODE ";sm", SDLOPTVAL_NONE, OPTION_STRING, "Scale mode: none, async, yv12, yuy2, yv12x2, yuy2x2 (-video soft only)" }, #endif #if USE_OPENGL // OpenGL specific options { NULL, NULL, OPTION_HEADER, "OpenGL-SPECIFIC OPTIONS" }, { SDLOPTION_FILTER ";glfilter;flt", "1", OPTION_BOOLEAN, "enable bilinear filtering on screen output" }, - { SDLOPTION_PRESCALE, "1", 0, "scale screen rendering by this amount in software" }, + { SDLOPTION_PRESCALE, "1", OPTION_INTEGER, "scale screen rendering by this amount in software" }, { SDLOPTION_GL_FORCEPOW2TEXTURE, "0", OPTION_BOOLEAN, "force power of two textures (default no)" }, { SDLOPTION_GL_NOTEXTURERECT, "0", OPTION_BOOLEAN, "don't use OpenGL GL_ARB_texture_rectangle (default on)" }, { SDLOPTION_GL_VBO, "1", OPTION_BOOLEAN, "enable OpenGL VBO, if available (default on)" }, { SDLOPTION_GL_PBO, "1", OPTION_BOOLEAN, "enable OpenGL PBO, if available (default on)" }, { SDLOPTION_GL_GLSL, "0", OPTION_BOOLEAN, "enable OpenGL GLSL, if available (default off)" }, - { SDLOPTION_GLSL_FILTER, "1", 0, "enable OpenGL GLSL filtering instead of FF filtering 0-plain, 1-bilinear (default)" }, - { SDLOPTION_SHADER_MAME("0"), SDLOPTVAL_NONE, 0, "custom OpenGL GLSL shader set mame bitmap 0" }, - { SDLOPTION_SHADER_MAME("1"), SDLOPTVAL_NONE, 0, "custom OpenGL GLSL shader set mame bitmap 1" }, - { SDLOPTION_SHADER_MAME("2"), SDLOPTVAL_NONE, 0, "custom OpenGL GLSL shader set mame bitmap 2" }, - { SDLOPTION_SHADER_MAME("3"), SDLOPTVAL_NONE, 0, "custom OpenGL GLSL shader set mame bitmap 3" }, - { SDLOPTION_SHADER_MAME("4"), SDLOPTVAL_NONE, 0, "custom OpenGL GLSL shader set mame bitmap 4" }, - { SDLOPTION_SHADER_MAME("5"), SDLOPTVAL_NONE, 0, "custom OpenGL GLSL shader set mame bitmap 5" }, - { SDLOPTION_SHADER_MAME("6"), SDLOPTVAL_NONE, 0, "custom OpenGL GLSL shader set mame bitmap 6" }, - { SDLOPTION_SHADER_MAME("7"), SDLOPTVAL_NONE, 0, "custom OpenGL GLSL shader set mame bitmap 7" }, - { SDLOPTION_SHADER_MAME("8"), SDLOPTVAL_NONE, 0, "custom OpenGL GLSL shader set mame bitmap 8" }, - { SDLOPTION_SHADER_MAME("9"), SDLOPTVAL_NONE, 0, "custom OpenGL GLSL shader set mame bitmap 9" }, - { SDLOPTION_SHADER_SCREEN("0"), SDLOPTVAL_NONE, 0, "custom OpenGL GLSL shader screen bitmap 0" }, - { SDLOPTION_SHADER_SCREEN("1"), SDLOPTVAL_NONE, 0, "custom OpenGL GLSL shader screen bitmap 1" }, - { SDLOPTION_SHADER_SCREEN("2"), SDLOPTVAL_NONE, 0, "custom OpenGL GLSL shader screen bitmap 2" }, - { SDLOPTION_SHADER_SCREEN("3"), SDLOPTVAL_NONE, 0, "custom OpenGL GLSL shader screen bitmap 3" }, - { SDLOPTION_SHADER_SCREEN("4"), SDLOPTVAL_NONE, 0, "custom OpenGL GLSL shader screen bitmap 4" }, - { SDLOPTION_SHADER_SCREEN("5"), SDLOPTVAL_NONE, 0, "custom OpenGL GLSL shader screen bitmap 5" }, - { SDLOPTION_SHADER_SCREEN("6"), SDLOPTVAL_NONE, 0, "custom OpenGL GLSL shader screen bitmap 6" }, - { SDLOPTION_SHADER_SCREEN("7"), SDLOPTVAL_NONE, 0, "custom OpenGL GLSL shader screen bitmap 7" }, - { SDLOPTION_SHADER_SCREEN("8"), SDLOPTVAL_NONE, 0, "custom OpenGL GLSL shader screen bitmap 8" }, - { SDLOPTION_SHADER_SCREEN("9"), SDLOPTVAL_NONE, 0, "custom OpenGL GLSL shader screen bitmap 9" }, + { SDLOPTION_GLSL_FILTER, "1", OPTION_STRING, "enable OpenGL GLSL filtering instead of FF filtering 0-plain, 1-bilinear (default)" }, + { SDLOPTION_SHADER_MAME "0", SDLOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader set mame bitmap 0" }, + { SDLOPTION_SHADER_MAME "1", SDLOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader set mame bitmap 1" }, + { SDLOPTION_SHADER_MAME "2", SDLOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader set mame bitmap 2" }, + { SDLOPTION_SHADER_MAME "3", SDLOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader set mame bitmap 3" }, + { SDLOPTION_SHADER_MAME "4", SDLOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader set mame bitmap 4" }, + { SDLOPTION_SHADER_MAME "5", SDLOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader set mame bitmap 5" }, + { SDLOPTION_SHADER_MAME "6", SDLOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader set mame bitmap 6" }, + { SDLOPTION_SHADER_MAME "7", SDLOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader set mame bitmap 7" }, + { SDLOPTION_SHADER_MAME "8", SDLOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader set mame bitmap 8" }, + { SDLOPTION_SHADER_MAME "9", SDLOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader set mame bitmap 9" }, + { SDLOPTION_SHADER_SCREEN "0", SDLOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader screen bitmap 0" }, + { SDLOPTION_SHADER_SCREEN "1", SDLOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader screen bitmap 1" }, + { SDLOPTION_SHADER_SCREEN "2", SDLOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader screen bitmap 2" }, + { SDLOPTION_SHADER_SCREEN "3", SDLOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader screen bitmap 3" }, + { SDLOPTION_SHADER_SCREEN "4", SDLOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader screen bitmap 4" }, + { SDLOPTION_SHADER_SCREEN "5", SDLOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader screen bitmap 5" }, + { SDLOPTION_SHADER_SCREEN "6", SDLOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader screen bitmap 6" }, + { SDLOPTION_SHADER_SCREEN "7", SDLOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader screen bitmap 7" }, + { SDLOPTION_SHADER_SCREEN "8", SDLOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader screen bitmap 8" }, + { SDLOPTION_SHADER_SCREEN "9", SDLOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader screen bitmap 9" }, { SDLOPTION_GL_GLSL_VID_ATTR, "1", OPTION_BOOLEAN, "enable OpenGL GLSL handling of brightness and contrast. Better RGB game performance for free. (default)" }, #endif // per-window options - { NULL, NULL, OPTION_HEADER, "PER-WINDOW VIDEO OPTIONS" }, - { SDLOPTION_SCREEN(""), SDLOPTVAL_AUTO, 0, "explicit name of the first screen; 'auto' here will try to make a best guess" }, - { SDLOPTION_ASPECT("") ";screen_aspect", SDLOPTVAL_AUTO, 0, "aspect ratio for all screens; 'auto' here will try to make a best guess" }, - { SDLOPTION_RESOLUTION("") ";r", SDLOPTVAL_AUTO, 0, "preferred resolution for all screens; format is <width>x<height>[@<refreshrate>] or 'auto'" }, - { SDLOPTION_VIEW(""), SDLOPTVAL_AUTO, 0, "preferred view for all screens" }, - - { SDLOPTION_SCREEN("0"), SDLOPTVAL_AUTO, 0, "explicit name of the first screen; 'auto' here will try to make a best guess" }, - { SDLOPTION_ASPECT("0"), SDLOPTVAL_AUTO, 0, "aspect ratio of the first screen; 'auto' here will try to make a best guess" }, - { SDLOPTION_RESOLUTION("0") ";r0", SDLOPTVAL_AUTO, 0, "preferred resolution of the first screen; format is <width>x<height>[@<refreshrate>] or 'auto'" }, - { SDLOPTION_VIEW("0"), SDLOPTVAL_AUTO, 0, "preferred view for the first screen" }, - - { SDLOPTION_SCREEN("1"), SDLOPTVAL_AUTO, 0, "explicit name of the second screen; 'auto' here will try to make a best guess" }, - { SDLOPTION_ASPECT("1"), SDLOPTVAL_AUTO, 0, "aspect ratio of the second screen; 'auto' here will try to make a best guess" }, - { SDLOPTION_RESOLUTION("1") ";r1", SDLOPTVAL_AUTO, 0, "preferred resolution of the second screen; format is <width>x<height>[@<refreshrate>] or 'auto'" }, - { SDLOPTION_VIEW("1"), SDLOPTVAL_AUTO, 0, "preferred view for the second screen" }, - - { SDLOPTION_SCREEN("2"), SDLOPTVAL_AUTO, 0, "explicit name of the third screen; 'auto' here will try to make a best guess" }, - { SDLOPTION_ASPECT("2"), SDLOPTVAL_AUTO, 0, "aspect ratio of the third screen; 'auto' here will try to make a best guess" }, - { SDLOPTION_RESOLUTION("2") ";r2", SDLOPTVAL_AUTO, 0, "preferred resolution of the third screen; format is <width>x<height>[@<refreshrate>] or 'auto'" }, - { SDLOPTION_VIEW("2"), SDLOPTVAL_AUTO, 0, "preferred view for the third screen" }, - - { SDLOPTION_SCREEN("3"), SDLOPTVAL_AUTO, 0, "explicit name of the fourth screen; 'auto' here will try to make a best guess" }, - { SDLOPTION_ASPECT("3"), SDLOPTVAL_AUTO, 0, "aspect ratio of the fourth screen; 'auto' here will try to make a best guess" }, - { SDLOPTION_RESOLUTION("3") ";r3", SDLOPTVAL_AUTO, 0, "preferred resolution of the fourth screen; format is <width>x<height>[@<refreshrate>] or 'auto'" }, - { SDLOPTION_VIEW("3"), SDLOPTVAL_AUTO, 0, "preferred view for the fourth screen" }, + { NULL, NULL, OPTION_HEADER, "PER-WINDOW VIDEO OPTIONS" }, + { SDLOPTION_SCREEN, SDLOPTVAL_AUTO, OPTION_STRING, "explicit name of the first screen; 'auto' here will try to make a best guess" }, + { SDLOPTION_ASPECT ";screen_aspect", SDLOPTVAL_AUTO, OPTION_STRING, "aspect ratio for all screens; 'auto' here will try to make a best guess" }, + { SDLOPTION_RESOLUTION ";r", SDLOPTVAL_AUTO, OPTION_STRING, "preferred resolution for all screens; format is <width>x<height>[@<refreshrate>] or 'auto'" }, + { SDLOPTION_VIEW, SDLOPTVAL_AUTO, OPTION_STRING, "preferred view for all screens" }, + + { SDLOPTION_SCREEN "0", SDLOPTVAL_AUTO, OPTION_STRING, "explicit name of the first screen; 'auto' here will try to make a best guess" }, + { SDLOPTION_ASPECT "0", SDLOPTVAL_AUTO, OPTION_STRING, "aspect ratio of the first screen; 'auto' here will try to make a best guess" }, + { SDLOPTION_RESOLUTION "0;r0", SDLOPTVAL_AUTO, OPTION_STRING, "preferred resolution of the first screen; format is <width>x<height>[@<refreshrate>] or 'auto'" }, + { SDLOPTION_VIEW "0", SDLOPTVAL_AUTO, OPTION_STRING, "preferred view for the first screen" }, + + { SDLOPTION_SCREEN "1", SDLOPTVAL_AUTO, OPTION_STRING, "explicit name of the second screen; 'auto' here will try to make a best guess" }, + { SDLOPTION_ASPECT "1", SDLOPTVAL_AUTO, OPTION_STRING, "aspect ratio of the second screen; 'auto' here will try to make a best guess" }, + { SDLOPTION_RESOLUTION "1;r1", SDLOPTVAL_AUTO, OPTION_STRING, "preferred resolution of the second screen; format is <width>x<height>[@<refreshrate>] or 'auto'" }, + { SDLOPTION_VIEW "1", SDLOPTVAL_AUTO, OPTION_STRING, "preferred view for the second screen" }, + + { SDLOPTION_SCREEN "2", SDLOPTVAL_AUTO, OPTION_STRING, "explicit name of the third screen; 'auto' here will try to make a best guess" }, + { SDLOPTION_ASPECT "2", SDLOPTVAL_AUTO, OPTION_STRING, "aspect ratio of the third screen; 'auto' here will try to make a best guess" }, + { SDLOPTION_RESOLUTION "2;r2", SDLOPTVAL_AUTO, OPTION_STRING, "preferred resolution of the third screen; format is <width>x<height>[@<refreshrate>] or 'auto'" }, + { SDLOPTION_VIEW "2", SDLOPTVAL_AUTO, OPTION_STRING, "preferred view for the third screen" }, + + { SDLOPTION_SCREEN "3", SDLOPTVAL_AUTO, OPTION_STRING, "explicit name of the fourth screen; 'auto' here will try to make a best guess" }, + { SDLOPTION_ASPECT "3", SDLOPTVAL_AUTO, OPTION_STRING, "aspect ratio of the fourth screen; 'auto' here will try to make a best guess" }, + { SDLOPTION_RESOLUTION "3;r3", SDLOPTVAL_AUTO, OPTION_STRING, "preferred resolution of the fourth screen; format is <width>x<height>[@<refreshrate>] or 'auto'" }, + { SDLOPTION_VIEW "3", SDLOPTVAL_AUTO, OPTION_STRING, "preferred view for the fourth screen" }, // full screen options { NULL, NULL, OPTION_HEADER, "FULL SCREEN OPTIONS" }, @@ -189,55 +189,55 @@ static const options_entry mame_sdl_options[] = // sound options { NULL, NULL, OPTION_HEADER, "SOUND OPTIONS" }, - { SDLOPTION_AUDIO_LATENCY, "3", 0, "set audio latency (increase to reduce glitches, decrease for responsiveness)" }, + { SDLOPTION_AUDIO_LATENCY, "3", OPTION_INTEGER, "set audio latency (increase to reduce glitches, decrease for responsiveness)" }, // keyboard mapping { NULL, NULL, OPTION_HEADER, "SDL KEYBOARD MAPPING" }, { SDLOPTION_KEYMAP, "0", OPTION_BOOLEAN, "enable keymap" }, - { SDLOPTION_KEYMAP_FILE, "keymap.dat", 0, "keymap filename" }, + { SDLOPTION_KEYMAP_FILE, "keymap.dat", OPTION_STRING, "keymap filename" }, // joystick mapping { NULL, NULL, OPTION_HEADER, "SDL JOYSTICK MAPPING" }, - { SDLOPTION_JOYINDEX "1", SDLOPTVAL_AUTO, 0, "name of joystick mapped to joystick #1" }, - { SDLOPTION_JOYINDEX "2", SDLOPTVAL_AUTO, 0, "name of joystick mapped to joystick #2" }, - { SDLOPTION_JOYINDEX "3", SDLOPTVAL_AUTO, 0, "name of joystick mapped to joystick #3" }, - { SDLOPTION_JOYINDEX "4", SDLOPTVAL_AUTO, 0, "name of joystick mapped to joystick #4" }, - { SDLOPTION_JOYINDEX "5", SDLOPTVAL_AUTO, 0, "name of joystick mapped to joystick #5" }, - { SDLOPTION_JOYINDEX "6", SDLOPTVAL_AUTO, 0, "name of joystick mapped to joystick #6" }, - { SDLOPTION_JOYINDEX "7", SDLOPTVAL_AUTO, 0, "name of joystick mapped to joystick #7" }, - { SDLOPTION_JOYINDEX "8", SDLOPTVAL_AUTO, 0, "name of joystick mapped to joystick #8" }, + { SDLOPTION_JOYINDEX "1", SDLOPTVAL_AUTO, OPTION_STRING, "name of joystick mapped to joystick #1" }, + { SDLOPTION_JOYINDEX "2", SDLOPTVAL_AUTO, OPTION_STRING, "name of joystick mapped to joystick #2" }, + { SDLOPTION_JOYINDEX "3", SDLOPTVAL_AUTO, OPTION_STRING, "name of joystick mapped to joystick #3" }, + { SDLOPTION_JOYINDEX "4", SDLOPTVAL_AUTO, OPTION_STRING, "name of joystick mapped to joystick #4" }, + { SDLOPTION_JOYINDEX "5", SDLOPTVAL_AUTO, OPTION_STRING, "name of joystick mapped to joystick #5" }, + { SDLOPTION_JOYINDEX "6", SDLOPTVAL_AUTO, OPTION_STRING, "name of joystick mapped to joystick #6" }, + { SDLOPTION_JOYINDEX "7", SDLOPTVAL_AUTO, OPTION_STRING, "name of joystick mapped to joystick #7" }, + { SDLOPTION_JOYINDEX "8", SDLOPTVAL_AUTO, OPTION_STRING, "name of joystick mapped to joystick #8" }, { SDLOPTION_SIXAXIS, "0", OPTION_BOOLEAN, "Use special handling for PS3 Sixaxis controllers" }, #if (SDL_VERSION_ATLEAST(1,3,0)) { NULL, NULL, OPTION_HEADER, "SDL MOUSE MAPPING" }, - { SDLOPTION_MOUSEINDEX "1", SDLOPTVAL_AUTO, 0, "name of mouse mapped to mouse #1" }, - { SDLOPTION_MOUSEINDEX "2", SDLOPTVAL_AUTO, 0, "name of mouse mapped to mouse #2" }, - { SDLOPTION_MOUSEINDEX "3", SDLOPTVAL_AUTO, 0, "name of mouse mapped to mouse #3" }, - { SDLOPTION_MOUSEINDEX "4", SDLOPTVAL_AUTO, 0, "name of mouse mapped to mouse #4" }, - { SDLOPTION_MOUSEINDEX "5", SDLOPTVAL_AUTO, 0, "name of mouse mapped to mouse #5" }, - { SDLOPTION_MOUSEINDEX "6", SDLOPTVAL_AUTO, 0, "name of mouse mapped to mouse #6" }, - { SDLOPTION_MOUSEINDEX "7", SDLOPTVAL_AUTO, 0, "name of mouse mapped to mouse #7" }, - { SDLOPTION_MOUSEINDEX "8", SDLOPTVAL_AUTO, 0, "name of mouse mapped to mouse #8" }, + { SDLOPTION_MOUSEINDEX "1", SDLOPTVAL_AUTO, OPTION_STRING, "name of mouse mapped to mouse #1" }, + { SDLOPTION_MOUSEINDEX "2", SDLOPTVAL_AUTO, OPTION_STRING, "name of mouse mapped to mouse #2" }, + { SDLOPTION_MOUSEINDEX "3", SDLOPTVAL_AUTO, OPTION_STRING, "name of mouse mapped to mouse #3" }, + { SDLOPTION_MOUSEINDEX "4", SDLOPTVAL_AUTO, OPTION_STRING, "name of mouse mapped to mouse #4" }, + { SDLOPTION_MOUSEINDEX "5", SDLOPTVAL_AUTO, OPTION_STRING, "name of mouse mapped to mouse #5" }, + { SDLOPTION_MOUSEINDEX "6", SDLOPTVAL_AUTO, OPTION_STRING, "name of mouse mapped to mouse #6" }, + { SDLOPTION_MOUSEINDEX "7", SDLOPTVAL_AUTO, OPTION_STRING, "name of mouse mapped to mouse #7" }, + { SDLOPTION_MOUSEINDEX "8", SDLOPTVAL_AUTO, OPTION_STRING, "name of mouse mapped to mouse #8" }, { NULL, NULL, OPTION_HEADER, "SDL KEYBOARD MAPPING" }, - { SDLOPTION_KEYBINDEX "1", SDLOPTVAL_AUTO, 0, "name of keyboard mapped to keyboard #1" }, - { SDLOPTION_KEYBINDEX "2", SDLOPTVAL_AUTO, 0, "name of keyboard mapped to keyboard #2" }, - { SDLOPTION_KEYBINDEX "3", SDLOPTVAL_AUTO, 0, "name of keyboard mapped to keyboard #3" }, - { SDLOPTION_KEYBINDEX "4", SDLOPTVAL_AUTO, 0, "name of keyboard mapped to keyboard #4" }, - { SDLOPTION_KEYBINDEX "5", SDLOPTVAL_AUTO, 0, "name of keyboard mapped to keyboard #5" }, - { SDLOPTION_KEYBINDEX "6", SDLOPTVAL_AUTO, 0, "name of keyboard mapped to keyboard #6" }, - { SDLOPTION_KEYBINDEX "7", SDLOPTVAL_AUTO, 0, "name of keyboard mapped to keyboard #7" }, - { SDLOPTION_KEYBINDEX "8", SDLOPTVAL_AUTO, 0, "name of keyboard mapped to keyboard #8" }, + { SDLOPTION_KEYBINDEX "1", SDLOPTVAL_AUTO, OPTION_STRING, "name of keyboard mapped to keyboard #1" }, + { SDLOPTION_KEYBINDEX "2", SDLOPTVAL_AUTO, OPTION_STRING, "name of keyboard mapped to keyboard #2" }, + { SDLOPTION_KEYBINDEX "3", SDLOPTVAL_AUTO, OPTION_STRING, "name of keyboard mapped to keyboard #3" }, + { SDLOPTION_KEYBINDEX "4", SDLOPTVAL_AUTO, OPTION_STRING, "name of keyboard mapped to keyboard #4" }, + { SDLOPTION_KEYBINDEX "5", SDLOPTVAL_AUTO, OPTION_STRING, "name of keyboard mapped to keyboard #5" }, + { SDLOPTION_KEYBINDEX "6", SDLOPTVAL_AUTO, OPTION_STRING, "name of keyboard mapped to keyboard #6" }, + { SDLOPTION_KEYBINDEX "7", SDLOPTVAL_AUTO, OPTION_STRING, "name of keyboard mapped to keyboard #7" }, + { SDLOPTION_KEYBINDEX "8", SDLOPTVAL_AUTO, OPTION_STRING, "name of keyboard mapped to keyboard #8" }, #endif // SDL low level driver options { NULL, NULL, OPTION_HEADER, "SDL LOWLEVEL DRIVER OPTIONS" }, - { SDLOPTION_VIDEODRIVER ";vd", SDLOPTVAL_AUTO, 0, "sdl video driver to use ('x11', 'directfb', ... or 'auto' for SDL default" }, + { SDLOPTION_VIDEODRIVER ";vd", SDLOPTVAL_AUTO, OPTION_STRING, "sdl video driver to use ('x11', 'directfb', ... or 'auto' for SDL default" }, #if (SDL_VERSION_ATLEAST(1,3,0)) - { SDLOPTION_RENDERDRIVER ";rd", SDLOPTVAL_AUTO, 0, "sdl render driver to use ('software', 'opengl', 'directfb' ... or 'auto' for SDL default" }, + { SDLOPTION_RENDERDRIVER ";rd", SDLOPTVAL_AUTO, OPTION_STRING, "sdl render driver to use ('software', 'opengl', 'directfb' ... or 'auto' for SDL default" }, #endif - { SDLOPTION_AUDIODRIVER ";ad", SDLOPTVAL_AUTO, 0, "sdl audio driver to use ('alsa', 'arts', ... or 'auto' for SDL default" }, + { SDLOPTION_AUDIODRIVER ";ad", SDLOPTVAL_AUTO, OPTION_STRING, "sdl audio driver to use ('alsa', 'arts', ... or 'auto' for SDL default" }, #if USE_OPENGL - { SDLOPTION_GL_LIB, SDLOPTVAL_GLLIB, 0, "alternative libGL.so to use; 'auto' for system default" }, + { SDLOPTION_GL_LIB, SDLOPTVAL_GLLIB, OPTION_STRING, "alternative libGL.so to use; 'auto' for system default" }, #endif // End of list @@ -262,6 +262,16 @@ void MorphToPM() #endif //============================================================ +// sdl_options +//============================================================ + +sdl_options::sdl_options() +{ + add_entries(s_option_entries); +} + + +//============================================================ // main //============================================================ @@ -330,7 +340,8 @@ int main(int argc, char *argv[]) { sdl_osd_interface osd; - res = cli_execute(argc, argv, osd, mame_sdl_options); + sdl_options options; + res = cli_execute(options, osd, argc, argv); } #ifdef MALLOC_DEBUG @@ -524,27 +535,30 @@ void sdl_osd_interface::init(running_machine &machine) // call our parent osd_interface::init(machine); + sdl_options &options = downcast<sdl_options &>(machine.options()); const char *stemp; // determine if we are benchmarking, and adjust options appropriately - int bench = options_get_int(&machine.options(), SDLOPTION_BENCH); + int bench = options.bench(); + astring error_string; if (bench > 0) { - options_set_bool(&machine.options(), OPTION_THROTTLE, false, OPTION_PRIORITY_MAXIMUM); - options_set_bool(&machine.options(), OPTION_SOUND, false, OPTION_PRIORITY_MAXIMUM); - options_set_string(&machine.options(), SDLOPTION_VIDEO, "none", OPTION_PRIORITY_MAXIMUM); - options_set_int(&machine.options(), OPTION_SECONDS_TO_RUN, bench, OPTION_PRIORITY_MAXIMUM); + options.set_value(OPTION_THROTTLE, false, OPTION_PRIORITY_MAXIMUM, error_string); + options.set_value(OPTION_SOUND, false, OPTION_PRIORITY_MAXIMUM, error_string); + options.set_value(SDLOPTION_VIDEO, "none", OPTION_PRIORITY_MAXIMUM, error_string); + options.set_value(OPTION_SECONDS_TO_RUN, bench, OPTION_PRIORITY_MAXIMUM, error_string); + assert(!error_string); } // Some driver options - must be before audio init! - stemp = options_get_string(&machine.options(), SDLOPTION_AUDIODRIVER); + stemp = options.audio_driver(); if (stemp != NULL && strcmp(stemp, SDLOPTVAL_AUTO) != 0) { mame_printf_verbose("Setting SDL audiodriver '%s' ...\n", stemp); osd_setenv(SDLENV_AUDIODRIVER, stemp, 1); } - stemp = options_get_string(&machine.options(), SDLOPTION_VIDEODRIVER); + stemp = options.video_driver(); if (stemp != NULL && strcmp(stemp, SDLOPTVAL_AUTO) != 0) { mame_printf_verbose("Setting SDL videodriver '%s' ...\n", stemp); @@ -553,7 +567,7 @@ void sdl_osd_interface::init(running_machine &machine) if (SDL_VERSION_ATLEAST(1,3,0)) { - stemp = options_get_string(&machine.options(), SDLOPTION_RENDERDRIVER); + stemp = options.render_driver(); if (stemp != NULL && strcmp(stemp, SDLOPTVAL_AUTO) != 0) { mame_printf_verbose("Setting SDL renderdriver '%s' ...\n", stemp); @@ -566,7 +580,7 @@ void sdl_osd_interface::init(running_machine &machine) */ /* FIXME: move lib loading code from drawogl.c here */ - stemp = options_get_string(&machine.options(), SDLOPTION_GL_LIB); + stemp = options.gl_lib(); if (stemp != NULL && strcmp(stemp, SDLOPTVAL_AUTO) != 0) { osd_setenv("SDL_VIDEO_GL_DRIVER", stemp, 1); @@ -574,7 +588,7 @@ void sdl_osd_interface::init(running_machine &machine) } /* get number of processors */ - stemp = options_get_string(&machine.options(), SDLOPTION_NUMPROCESSORS); + stemp = options.numprocessors(); sdl_num_processors = 0; @@ -630,13 +644,13 @@ void sdl_osd_interface::init(running_machine &machine) sdloutput_init(&machine); - if (options_get_bool(&machine.options(), SDLOPTION_OSLOG)) + if (options.oslog()) machine.add_logerror_callback(output_oslog); /* now setup watchdog */ - int watchdog_timeout = options_get_int(&machine.options(), SDLOPTION_WATCHDOG); - int str = options_get_int(&machine.options(), OPTION_SECONDS_TO_RUN); + int watchdog_timeout = options.watchdog(); + int str = options.seconds_to_run(); /* only enable watchdog if seconds_to_run is enabled *and* relatively short (time taken from ui.c) */ if ((watchdog_timeout != 0) && (str > 0) && (str < 60*5 )) @@ -941,8 +955,8 @@ osd_font sdl_osd_interface::font_open(const char *_name, int &height) if (!font) { - mame_printf_verbose("Searching font %s in -%s\n", name.cstr(), SEARCHPATH_FONT); - emu_file file(machine().options(), SEARCHPATH_FONT, OPEN_FLAG_READ); + mame_printf_verbose("Searching font %s in -%s\n", name.cstr(), OPTION_FONTPATH); + emu_file file(machine().options().font_path(), OPEN_FLAG_READ); if (file.open(name) == FILERR_NONE) { astring full_name = file.fullpath(); diff --git a/src/osd/sdl/sound.c b/src/osd/sdl/sound.c index 56433dac5d2..90d740d40ea 100644 --- a/src/osd/sdl/sound.c +++ b/src/osd/sdl/sound.c @@ -464,7 +464,7 @@ static int sdl_init(running_machine *machine) sdl_xfer_samples = obtained.samples; - audio_latency = options_get_int(&machine->options(), SDLOPTION_AUDIO_LATENCY); + audio_latency = downcast<sdl_options &>(machine->options()).audio_latency(); // pin audio latency if (audio_latency > MAX_AUDIO_LATENCY) diff --git a/src/osd/sdl/video.c b/src/osd/sdl/video.c index 450954c2b04..07c1e395bc9 100644 --- a/src/osd/sdl/video.c +++ b/src/osd/sdl/video.c @@ -88,14 +88,14 @@ static sdl_monitor_info *sdl_monitor_list; static void video_exit(running_machine &machine); static void init_monitors(void); -static sdl_monitor_info *pick_monitor(core_options &options, int index); +static sdl_monitor_info *pick_monitor(sdl_options &options, int index); static void check_osd_inputs(running_machine *machine); static void extract_video_config(running_machine *machine); static void extract_window_config(running_machine *machine, int index, sdl_window_config *conf); -static float get_aspect(core_options &options, const char *name, int report_error); -static void get_resolution(core_options &options, const char *name, sdl_window_config *config, int report_error); +static float get_aspect(const char *defdata, const char *data, int report_error); +static void get_resolution(const char *defdata, const char *data, sdl_window_config *config, int report_error); //============================================================ @@ -116,30 +116,27 @@ int sdlvideo_init(running_machine *machine) init_monitors(); // we need the beam width in a float, contrary to what the core does. - video_config.beamwidth = options_get_float(&machine->options(), OPTION_BEAM); + video_config.beamwidth = machine->options().beam(); // initialize the window system so we can make windows if (sdlwindow_init(machine)) - goto error; + return 1; tc = machine->total_colors(); // create the windows + sdl_options &options = downcast<sdl_options &>(machine->options()); for (index = 0; index < video_config.numscreens; index++) { sdl_window_config conf; memset(&conf, 0, sizeof(conf)); extract_window_config(machine, index, &conf); conf.totalColors = tc; - if (sdlwindow_video_window_create(machine, index, pick_monitor(machine->options(), index), &conf)) - goto error; + if (sdlwindow_video_window_create(machine, index, pick_monitor(options, index), &conf)) + return 1; } - return 0; - -error: - return 1; } @@ -464,7 +461,7 @@ static void init_monitors(void) // allocate a new monitor info monitor = global_alloc_clear(sdl_monitor_info); - snprintf(monitor->monitor_device, sizeof(monitor->monitor_device)-1, "%s%d", SDLOPTION_SCREEN(""),i); + snprintf(monitor->monitor_device, sizeof(monitor->monitor_device)-1, "%s%d", SDLOPTION_SCREEN,i); SDL_SelectVideoDisplay(i); SDL_GetDesktopDisplayMode(&dmode); @@ -501,21 +498,18 @@ static void init_monitors(void) //============================================================ #if (SDL_VERSION_ATLEAST(1,3,0)) || defined(SDLMAME_WIN32) -static sdl_monitor_info *pick_monitor(core_options &options, int index) +static sdl_monitor_info *pick_monitor(sdl_options &options, int index) { sdl_monitor_info *monitor; const char *scrname; int moncount = 0; - char option[20]; float aspect; // get the screen option - sprintf(option, SDLOPTION_SCREEN("%d"), index); - scrname = options_get_string(&options, option); + scrname = options.screen(index); // get the aspect ratio - sprintf(option, SDLOPTION_ASPECT("%d"), index); - aspect = get_aspect(options, option, TRUE); + aspect = get_aspect(options.aspect(), options.aspect(index), TRUE); // look for a match in the name first if (scrname != NULL) @@ -543,15 +537,13 @@ finishit: return monitor; } #else -static sdl_monitor_info *pick_monitor(core_options &options, int index) +static sdl_monitor_info *pick_monitor(sdl_options &options, int index) { sdl_monitor_info *monitor; - char option[20]; float aspect; // get the aspect ratio - sprintf(option, SDLOPTION_ASPECT("%d"), index); - aspect = get_aspect(options, option, TRUE); + aspect = get_aspect(options.aspect(), options.aspect(index), TRUE); // return the primary just in case all else fails monitor = primary_monitor; @@ -614,11 +606,9 @@ static void check_osd_inputs(running_machine *machine) static void extract_window_config(running_machine *machine, int index, sdl_window_config *conf) { - char buf[20]; - - sprintf(buf,SDLOPTION_RESOLUTION("%d"), index); + sdl_options &options = downcast<sdl_options &>(machine->options()); // per-window options: extract the data - get_resolution(machine->options(), buf, conf, TRUE); + get_resolution(options.resolution(), options.resolution(index), conf, TRUE); } //============================================================ @@ -628,16 +618,17 @@ static void extract_window_config(running_machine *machine, int index, sdl_windo static void extract_video_config(running_machine *machine) { const char *stemp; + sdl_options &options = downcast<sdl_options &>(machine->options()); - video_config.perftest = options_get_bool(&machine->options(), SDLOPTION_SDLVIDEOFPS); + video_config.perftest = options.video_fps(); // global options: extract the data - video_config.windowed = options_get_bool(&machine->options(), SDLOPTION_WINDOW); - video_config.keepaspect = options_get_bool(&machine->options(), SDLOPTION_KEEPASPECT); - video_config.numscreens = options_get_int(&machine->options(), SDLOPTION_NUMSCREENS); - video_config.fullstretch = options_get_bool(&machine->options(), SDLOPTION_UNEVENSTRETCH); + video_config.windowed = options.window(); + video_config.keepaspect = options.keep_aspect(); + video_config.numscreens = options.numscreens(); + video_config.fullstretch = options.uneven_stretch(); #ifdef SDLMAME_X11 - video_config.restrictonemonitor = !options_get_bool(&machine->options(), SDLOPTION_USEALLHEADS); + video_config.restrictonemonitor = !options.use_all_heads(); #endif @@ -648,7 +639,7 @@ static void extract_video_config(running_machine *machine) video_config.novideo = 0; // d3d options: extract the data - stemp = options_get_string(&machine->options(), SDLOPTION_VIDEO); + stemp = options.video(); if (strcmp(stemp, SDLOPTVAL_SOFT) == 0) video_config.mode = VIDEO_MODE_SOFT; else if (strcmp(stemp, SDLOPTVAL_NONE) == 0) @@ -656,7 +647,7 @@ static void extract_video_config(running_machine *machine) video_config.mode = VIDEO_MODE_SOFT; video_config.novideo = 1; - if (options_get_int(&machine->options(), OPTION_SECONDS_TO_RUN) == 0) + if (options.seconds_to_run() == 0) mame_printf_warning("Warning: -video none doesn't make much sense without -seconds_to_run\n"); } else if (USE_OPENGL && (strcmp(stemp, SDLOPTVAL_OPENGL) == 0)) @@ -677,11 +668,11 @@ static void extract_video_config(running_machine *machine) video_config.mode = VIDEO_MODE_SOFT; } - video_config.switchres = options_get_bool(&machine->options(), SDLOPTION_SWITCHRES); - video_config.centerh = options_get_bool(&machine->options(), SDLOPTION_CENTERH); - video_config.centerv = options_get_bool(&machine->options(), SDLOPTION_CENTERV); - video_config.waitvsync = options_get_bool(&machine->options(), SDLOPTION_WAITVSYNC); - video_config.syncrefresh = options_get_bool(&machine->options(), SDLOPTION_SYNCREFRESH); + video_config.switchres = options.switch_res(); + video_config.centerh = options.centerh(); + video_config.centerv = options.centerv(); + video_config.waitvsync = options.wait_vsync(); + video_config.syncrefresh = options.sync_refresh(); if (!video_config.waitvsync && video_config.syncrefresh) { mame_printf_warning("-syncrefresh specified without -waitsync. Reverting to -nosyncrefresh\n"); @@ -690,12 +681,12 @@ static void extract_video_config(running_machine *machine) if (USE_OPENGL || SDL_VERSION_ATLEAST(1,3,0)) { - video_config.filter = options_get_bool(&machine->options(), SDLOPTION_FILTER); + video_config.filter = options.filter(); } if (USE_OPENGL) { - video_config.prescale = options_get_int(&machine->options(), SDLOPTION_PRESCALE); + video_config.prescale = options.prescale(); if (video_config.prescale < 1 || video_config.prescale > 3) { mame_printf_warning("Invalid prescale option, reverting to '1'\n"); @@ -703,25 +694,22 @@ static void extract_video_config(running_machine *machine) } // default to working video please video_config.prefer16bpp_tex = 0; - video_config.forcepow2texture = options_get_bool(&machine->options(), SDLOPTION_GL_FORCEPOW2TEXTURE)==1; - video_config.allowtexturerect = options_get_bool(&machine->options(), SDLOPTION_GL_NOTEXTURERECT)==0; - video_config.vbo = options_get_bool(&machine->options(), SDLOPTION_GL_VBO); - video_config.pbo = options_get_bool(&machine->options(), SDLOPTION_GL_PBO); - video_config.glsl = options_get_bool(&machine->options(), SDLOPTION_GL_GLSL); + video_config.forcepow2texture = options.gl_force_pow2_texture(); + video_config.allowtexturerect = options.gl_no_texture_rect(); + video_config.vbo = options.gl_vbo(); + video_config.pbo = options.gl_pbo(); + video_config.glsl = options.gl_glsl(); if ( video_config.glsl ) { int i; - static char buffer[20]; // gl_glsl_filter[0..9]? - video_config.glsl_filter = options_get_int (&machine->options(), SDLOPTION_GLSL_FILTER); + video_config.glsl_filter = options.glsl_filter(); video_config.glsl_shader_mamebm_num=0; for(i=0; i<GLSL_SHADER_MAX; i++) { - snprintf(buffer, 18, SDLOPTION_SHADER_MAME("%d"), i); buffer[17]=0; - - stemp = options_get_string(&machine->options(), buffer); + stemp = options.shader_mame(i); if (stemp && strcmp(stemp, SDLOPTVAL_NONE) != 0 && strlen(stemp)>0) { video_config.glsl_shader_mamebm[i] = (char *) malloc(strlen(stemp)+1); @@ -736,9 +724,7 @@ static void extract_video_config(running_machine *machine) for(i=0; i<GLSL_SHADER_MAX; i++) { - snprintf(buffer, 20, SDLOPTION_SHADER_SCREEN("%d"), i); buffer[19]=0; - - stemp = options_get_string(&machine->options(), buffer); + stemp = options.shader_screen(i); if (stemp && strcmp(stemp, SDLOPTVAL_NONE) != 0 && strlen(stemp)>0) { video_config.glsl_shader_scrn[i] = (char *) malloc(strlen(stemp)+1); @@ -749,13 +735,13 @@ static void extract_video_config(running_machine *machine) } } - video_config.glsl_vid_attributes = options_get_int (&machine->options(), SDLOPTION_GL_GLSL_VID_ATTR); + video_config.glsl_vid_attributes = options.glsl_vid_attr(); { // Disable feature: glsl_vid_attributes, as long we have the gamma calculation // disabled within the direct shaders .. -> too slow. // IMHO the gamma setting should be done global anyways, and for the whole system, // not just MAME .. - float gamma = options_get_float(&machine->options(), OPTION_GAMMA); + float gamma = options.gamma(); if (gamma != 1.0 && video_config.glsl_vid_attributes && video_config.glsl) { video_config.glsl_vid_attributes = FALSE; @@ -796,7 +782,7 @@ static void extract_video_config(running_machine *machine) } #endif // yuv settings ... - stemp = options_get_string(&machine->options(), SDLOPTION_SCALEMODE); + stemp = options.scale_mode(); video_config.scale_mode = drawsdl_scale_mode(stemp); if (video_config.scale_mode < 0) { @@ -815,10 +801,8 @@ static void extract_video_config(running_machine *machine) // get_aspect //============================================================ -static float get_aspect(core_options &options, const char *name, int report_error) +static float get_aspect(const char *defdata, const char *data, int report_error) { - const char *defdata = options_get_string(&options, SDLOPTION_ASPECT("")); - const char *data = options_get_string(&options, name); int num = 0, den = 1; if (strcmp(data, SDLOPTVAL_AUTO) == 0) @@ -828,7 +812,7 @@ static float get_aspect(core_options &options, const char *name, int report_erro data = defdata; } if (sscanf(data, "%d:%d", &num, &den) != 2 && report_error) - mame_printf_error("Illegal aspect ratio value for %s = %s\n", name, data); + mame_printf_error("Illegal aspect ratio value = %s\n", data); return (float)num / (float)den; } @@ -837,11 +821,8 @@ static float get_aspect(core_options &options, const char *name, int report_erro // get_resolution //============================================================ -static void get_resolution(core_options &options, const char *name, sdl_window_config *config, int report_error) +static void get_resolution(const char *defdata, const char *data, sdl_window_config *config, int report_error) { - const char *defdata = options_get_string(&options, SDLOPTION_RESOLUTION("")); - const char *data = options_get_string(&options, name); - config->width = config->height = config->depth = config->refresh = 0; if (strcmp(data, SDLOPTVAL_AUTO) == 0) { @@ -854,6 +835,6 @@ static void get_resolution(core_options &options, const char *name, sdl_window_c } if (sscanf(data, "%dx%dx%d@%d", &config->width, &config->height, &config->depth, &config->refresh) < 2 && report_error) - mame_printf_error("Illegal resolution value for %s = %s\n", name, data); + mame_printf_error("Illegal resolution value = %s\n", data); } diff --git a/src/osd/sdl/window.c b/src/osd/sdl/window.c index 73523faba5d..6998e75c637 100644 --- a/src/osd/sdl/window.c +++ b/src/osd/sdl/window.c @@ -123,7 +123,7 @@ static void get_min_bounds(sdl_window_info *window, int *window_width, int *wind static void get_max_bounds(sdl_window_info *window, int *window_width, int *window_height, int constrain); static void *complete_create_wt(void *param, int threadid); -static void set_starting_view(running_machine *machine, int index, sdl_window_info *window, const char *view); +static void set_starting_view(running_machine *machine, int index, sdl_window_info *window, const char *defview, const char *view); //============================================================ // clear the worker_param structure, inline - faster than memset @@ -206,7 +206,7 @@ int sdlwindow_init(running_machine *machine) { mame_printf_verbose("Enter sdlwindow_init\n"); // determine if we are using multithreading or not - multithreading_enabled = options_get_bool(&machine->options(), SDLOPTION_MULTITHREADING); + multithreading_enabled = downcast<sdl_options &>(machine->options()).multithreading(); // get the main thread ID before anything else main_threadid = SDL_ThreadID(); @@ -652,7 +652,6 @@ int sdlwindow_video_window_create(running_machine *machine, int index, sdl_monit { sdl_window_info *window; worker_param *wp = (worker_param *) osd_malloc(sizeof(worker_param)); - char option[20]; int result; ASSERT_MAIN_THREAD(); @@ -676,7 +675,8 @@ int sdlwindow_video_window_create(running_machine *machine, int index, sdl_monit // set the initial maximized state // FIXME: Does not belong here - window->startmaximized = options_get_bool(&machine->options(), SDLOPTION_MAXIMIZE); + sdl_options &options = downcast<sdl_options &>(machine->options()); + window->startmaximized = options.maximize(); if (!window->fullscreen) { @@ -698,8 +698,7 @@ int sdlwindow_video_window_create(running_machine *machine, int index, sdl_monit window->target = machine->render().target_alloc(); // set the specific view - sprintf(option, SDLOPTION_VIEW("%d"), index); - set_starting_view(machine, index, window, options_get_string(&machine->options(), option)); + set_starting_view(machine, index, window, options.view(), options.view(index)); // make the window title if (video_config.numscreens == 1) @@ -1010,9 +1009,8 @@ void sdlwindow_video_window_update(running_machine *machine, sdl_window_info *wi // (main thread) //============================================================ -static void set_starting_view(running_machine *machine, int index, sdl_window_info *window, const char *view) +static void set_starting_view(running_machine *machine, int index, sdl_window_info *window, const char *defview, const char *view) { - const char *defview = options_get_string(&machine->options(), SDLOPTION_VIEW( )); int viewindex; ASSERT_MAIN_THREAD(); diff --git a/src/osd/windows/debugwin.c b/src/osd/windows/debugwin.c index 2d76bf0fed3..7f99ac03033 100644 --- a/src/osd/windows/debugwin.c +++ b/src/osd/windows/debugwin.c @@ -427,11 +427,12 @@ void debugwin_init_windows(running_machine &machine) if (temp_dc != NULL) { - int size = options_get_int(&machine.options(), WINOPTION_DEBUGGER_FONT_SIZE); + windows_options &options = downcast<windows_options &>(machine.options()); + int size = options.debugger_font_size(); TCHAR *t_face; // create a standard font - t_face = tstring_from_utf8(options_get_string(&machine.options(), WINOPTION_DEBUGGER_FONT)); + t_face = tstring_from_utf8(options.debugger_font()); debug_font = CreateFont(-MulDiv(size, GetDeviceCaps(temp_dc, LOGPIXELSY), 72), 0, 0, 0, FW_MEDIUM, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_DONTCARE, t_face); osd_free(t_face); diff --git a/src/osd/windows/drawd3d.c b/src/osd/windows/drawd3d.c index cbab49d527b..08fc6a645e8 100644 --- a/src/osd/windows/drawd3d.c +++ b/src/osd/windows/drawd3d.c @@ -480,7 +480,7 @@ static void texture_update(d3d_info *d3d, const render_primitive *prim); int drawd3d_init(running_machine &machine, win_draw_callbacks *callbacks) { - int version = options_get_int(&machine.options(), WINOPTION_D3DVERSION); + int version = downcast<windows_options &>(machine.options()).d3d_version(); d3dintf = NULL; // try Direct3D 9 if requested @@ -537,7 +537,7 @@ static int drawd3d_window_init(win_window_info *window) // experimental: load a PNG to use for vector rendering; it is treated // as a brightness map - emu_file file(window->machine->options(), OPTION_ARTPATH, OPEN_FLAG_READ); + emu_file file(window->machine->options().art_path(), OPEN_FLAG_READ); d3d->vector_bitmap = render_load_png(file, NULL, "vector.png", NULL, NULL); if (d3d->vector_bitmap != NULL) { @@ -807,9 +807,10 @@ try_again: if (window->fullscreen) { // only set the gamma if it's not 1.0f - float brightness = options_get_float(&window->machine->options(), WINOPTION_FULLSCREENBRIGHTNESS); - float contrast = options_get_float(&window->machine->options(), WINOPTION_FULLLSCREENCONTRAST); - float gamma = options_get_float(&window->machine->options(), WINOPTION_FULLSCREENGAMMA); + windows_options &options = downcast<windows_options &>(window->machine->options()); + float brightness = options.full_screen_brightness(); + float contrast = options.full_screen_contrast(); + float gamma = options.full_screen_gamma(); if (brightness != 1.0f || contrast != 1.0f || gamma != 1.0f) { // warn if we can't do it diff --git a/src/osd/windows/drawdd.c b/src/osd/windows/drawdd.c index 8c826b69e42..595f0b6716e 100644 --- a/src/osd/windows/drawdd.c +++ b/src/osd/windows/drawdd.c @@ -613,9 +613,10 @@ static int ddraw_create_surfaces(win_window_info *window) if (window->fullscreen) { // only set the gamma if it's not 1.0f - float brightness = options_get_float(&window->machine->options(), WINOPTION_FULLSCREENBRIGHTNESS); - float contrast = options_get_float(&window->machine->options(), WINOPTION_FULLLSCREENCONTRAST); - float gamma = options_get_float(&window->machine->options(), WINOPTION_FULLSCREENGAMMA); + windows_options &options = downcast<windows_options &>(window->machine->options()); + float brightness = options.full_screen_brightness(); + float contrast = options.full_screen_contrast(); + float gamma = options.full_screen_gamma(); if (brightness != 1.0f || contrast != 1.0f || gamma != 1.0f) { // see if we can get a GammaControl object diff --git a/src/osd/windows/input.c b/src/osd/windows/input.c index b29964c7d9a..073bf6524f2 100644 --- a/src/osd/windows/input.c +++ b/src/osd/windows/input.c @@ -508,7 +508,7 @@ void wininput_init(running_machine *machine) assert_always(input_lock != NULL, "Failed to allocate input_lock"); // decode the options - lightgun_shared_axis_mode = options_get_bool(&machine->options(), WINOPTION_DUAL_LIGHTGUN); + lightgun_shared_axis_mode = downcast<windows_options &>(machine->options()).dual_lightgun(); // initialize RawInput and DirectInput (RawInput first so we can fall back) rawinput_init(machine); diff --git a/src/osd/windows/sound.c b/src/osd/windows/sound.c index acbfc7577a6..c103062e7b3 100644 --- a/src/osd/windows/sound.c +++ b/src/osd/windows/sound.c @@ -115,7 +115,7 @@ static void dsound_destroy_buffers(void); void winsound_init(running_machine *machine) { // if no sound, don't create anything - if (!options_get_bool(&machine->options(), OPTION_SOUND)) + if (!machine->options().sound()) return; // ensure we get called on the way out @@ -305,7 +305,7 @@ static HRESULT dsound_init(running_machine *machine) stream_format.nAvgBytesPerSec = stream_format.nSamplesPerSec * stream_format.nBlockAlign; // compute the buffer size based on the output sample rate - stream_buffer_size = stream_format.nSamplesPerSec * stream_format.nBlockAlign * options_get_int(&machine->options(), WINOPTION_AUDIO_LATENCY) / 10; + stream_buffer_size = stream_format.nSamplesPerSec * stream_format.nBlockAlign * downcast<windows_options &>(machine->options()).audio_latency() / 10; stream_buffer_size = (stream_buffer_size / 1024) * 1024; if (stream_buffer_size < 1024) stream_buffer_size = 1024; diff --git a/src/osd/windows/video.c b/src/osd/windows/video.c index fa4216ab75f..2a7f56a807f 100644 --- a/src/osd/windows/video.c +++ b/src/osd/windows/video.c @@ -92,13 +92,13 @@ static win_monitor_info *primary_monitor; static void winvideo_exit(running_machine &machine); static void init_monitors(void); static BOOL CALLBACK monitor_enum_callback(HMONITOR handle, HDC dc, LPRECT rect, LPARAM data); -static win_monitor_info *pick_monitor(core_options &options, int index); +static win_monitor_info *pick_monitor(windows_options &options, int index); static void check_osd_inputs(running_machine *machine); static void extract_video_config(running_machine *machine); -static float get_aspect(core_options &options, const char *name, int report_error); -static void get_resolution(core_options &options, const char *name, win_window_config *config, int report_error); +static float get_aspect(const char *defdata, const char *data, int report_error); +static void get_resolution(const char *defdata, const char *data, win_window_config *config, int report_error); @@ -123,8 +123,9 @@ void winvideo_init(running_machine *machine) winwindow_init(machine); // create the windows + windows_options &options = downcast<windows_options &>(machine->options()); for (index = 0; index < video_config.numscreens; index++) - winwindow_video_window_create(machine, index, pick_monitor(machine->options(), index), &video_config.window[index]); + winwindow_video_window_create(machine, index, pick_monitor(options, index), &video_config.window[index]); if (video_config.mode != VIDEO_MODE_NONE) SetForegroundWindow(win_window_list->hwnd); @@ -300,26 +301,23 @@ static BOOL CALLBACK monitor_enum_callback(HMONITOR handle, HDC dc, LPRECT rect, // pick_monitor //============================================================ -static win_monitor_info *pick_monitor(core_options &options, int index) +static win_monitor_info *pick_monitor(windows_options &options, int index) { const char *scrname, *scrname2; win_monitor_info *monitor; int moncount = 0; - char option[20]; float aspect; // get the screen option - scrname = options_get_string(&options, WINOPTION_SCREEN); - sprintf(option, "screen%d", index); - scrname2 = options_get_string(&options, option); + scrname = options.screen(); + scrname2 = options.screen(index); // decide which one we want to use if (strcmp(scrname2, "auto") != 0) scrname = scrname2; // get the aspect ratio - sprintf(option, "aspect%d", index); - aspect = get_aspect(options, option, TRUE); + aspect = get_aspect(options.aspect(), options.aspect(index), TRUE); // look for a match in the name first if (scrname[0] != 0) @@ -376,26 +374,28 @@ static void check_osd_inputs(running_machine *machine) static void extract_video_config(running_machine *machine) { + windows_options &options = downcast<windows_options &>(machine->options()); const char *stemp; // global options: extract the data - video_config.windowed = options_get_bool(&machine->options(), WINOPTION_WINDOW); - video_config.prescale = options_get_int(&machine->options(), WINOPTION_PRESCALE); - video_config.keepaspect = options_get_bool(&machine->options(), WINOPTION_KEEPASPECT); - video_config.numscreens = options_get_int(&machine->options(), WINOPTION_NUMSCREENS); + video_config.windowed = options.window(); + video_config.prescale = options.prescale(); + video_config.keepaspect = options.keep_aspect(); + video_config.numscreens = options.numscreens(); // if we are in debug mode, never go full screen if (machine->debug_flags & DEBUG_FLAG_OSD_ENABLED) video_config.windowed = TRUE; // per-window options: extract the data - get_resolution(machine->options(), WINOPTION_RESOLUTION0, &video_config.window[0], TRUE); - get_resolution(machine->options(), WINOPTION_RESOLUTION1, &video_config.window[1], TRUE); - get_resolution(machine->options(), WINOPTION_RESOLUTION2, &video_config.window[2], TRUE); - get_resolution(machine->options(), WINOPTION_RESOLUTION3, &video_config.window[3], TRUE); + const char *default_resolution = options.resolution(); + get_resolution(default_resolution, options.resolution(0), &video_config.window[0], TRUE); + get_resolution(default_resolution, options.resolution(1), &video_config.window[1], TRUE); + get_resolution(default_resolution, options.resolution(2), &video_config.window[2], TRUE); + get_resolution(default_resolution, options.resolution(3), &video_config.window[3], TRUE); // video options: extract the data - stemp = options_get_string(&machine->options(), WINOPTION_VIDEO); + stemp = options.video(); if (strcmp(stemp, "d3d") == 0) video_config.mode = VIDEO_MODE_D3D; else if (strcmp(stemp, "ddraw") == 0) @@ -405,7 +405,7 @@ static void extract_video_config(running_machine *machine) else if (strcmp(stemp, "none") == 0) { video_config.mode = VIDEO_MODE_NONE; - if (options_get_int(&machine->options(), OPTION_SECONDS_TO_RUN) == 0) + if (options.seconds_to_run() == 0) mame_printf_warning("Warning: -video none doesn't make much sense without -seconds_to_run\n"); } else @@ -413,29 +413,18 @@ static void extract_video_config(running_machine *machine) mame_printf_warning("Invalid video value %s; reverting to gdi\n", stemp); video_config.mode = VIDEO_MODE_GDI; } - video_config.waitvsync = options_get_bool(&machine->options(), WINOPTION_WAITVSYNC); - video_config.syncrefresh = options_get_bool(&machine->options(), WINOPTION_SYNCREFRESH); - video_config.triplebuf = options_get_bool(&machine->options(), WINOPTION_TRIPLEBUFFER); - video_config.switchres = options_get_bool(&machine->options(), WINOPTION_SWITCHRES); + video_config.waitvsync = options.wait_vsync(); + video_config.syncrefresh = options.sync_refresh(); + video_config.triplebuf = options.triple_buffer(); + video_config.switchres = options.switch_res(); // ddraw options: extract the data - video_config.hwstretch = options_get_bool(&machine->options(), WINOPTION_HWSTRETCH); + video_config.hwstretch = options.hwstretch(); // d3d options: extract the data - video_config.filter = options_get_bool(&machine->options(), WINOPTION_FILTER); + video_config.filter = options.filter(); if (video_config.prescale == 0) video_config.prescale = 1; - - // misc options: sanity check values - - // per-window options: sanity check values - - // d3d options: sanity check values - options_get_int(&machine->options(), WINOPTION_D3DVERSION); - - options_get_float(&machine->options(), WINOPTION_FULLSCREENBRIGHTNESS); - options_get_float(&machine->options(), WINOPTION_FULLLSCREENCONTRAST); - options_get_float(&machine->options(), WINOPTION_FULLSCREENGAMMA); } @@ -444,10 +433,8 @@ static void extract_video_config(running_machine *machine) // get_aspect //============================================================ -static float get_aspect(core_options &options, const char *name, int report_error) +static float get_aspect(const char *defdata, const char *data, int report_error) { - const char *defdata = options_get_string(&options, WINOPTION_ASPECT); - const char *data = options_get_string(&options, name); int num = 0, den = 1; if (strcmp(data, "auto") == 0) @@ -457,7 +444,7 @@ static float get_aspect(core_options &options, const char *name, int report_erro data = defdata; } if (sscanf(data, "%d:%d", &num, &den) != 2 && report_error) - mame_printf_error("Illegal aspect ratio value for %s = %s\n", name, data); + mame_printf_error("Illegal aspect ratio value = %s\n", data); return (float)num / (float)den; } @@ -467,11 +454,8 @@ static float get_aspect(core_options &options, const char *name, int report_erro // get_resolution //============================================================ -static void get_resolution(core_options &options, const char *name, win_window_config *config, int report_error) +static void get_resolution(const char *defdata, const char *data, win_window_config *config, int report_error) { - const char *defdata = options_get_string(&options, WINOPTION_RESOLUTION); - const char *data = options_get_string(&options, name); - config->width = config->height = config->refresh = 0; if (strcmp(data, "auto") == 0) { @@ -480,5 +464,5 @@ static void get_resolution(core_options &options, const char *name, win_window_c data = defdata; } if (sscanf(data, "%dx%d@%d", &config->width, &config->height, &config->refresh) < 2 && report_error) - mame_printf_error("Illegal resolution value for %s = %s\n", name, data); + mame_printf_error("Illegal resolution value = %s\n", data); } diff --git a/src/osd/windows/window.c b/src/osd/windows/window.c index adbdf8a1036..998dcb6e751 100644 --- a/src/osd/windows/window.c +++ b/src/osd/windows/window.c @@ -224,7 +224,7 @@ void winwindow_init(running_machine *machine) size_t temp; // determine if we are using multithreading or not - multithreading_enabled = options_get_bool(&machine->options(), WINOPTION_MULTITHREADING); + multithreading_enabled = downcast<windows_options &>(machine->options()).multithreading(); // get the main thread ID before anything else main_threadid = GetCurrentThreadId(); @@ -605,7 +605,6 @@ void winwindow_update_cursor_state(running_machine *machine) void winwindow_video_window_create(running_machine *machine, int index, win_monitor_info *monitor, const win_window_config *config) { win_window_info *window, *win; - char option[20]; assert(GetCurrentThreadId() == main_threadid); @@ -635,8 +634,8 @@ void winwindow_video_window_create(running_machine *machine, int index, win_moni window->target = machine->render().target_alloc(); // set the specific view - sprintf(option, "view%d", index); - set_starting_view(index, window, options_get_string(&machine->options(), option)); + windows_options &options = downcast<windows_options &>(machine->options()); + set_starting_view(index, window, options.view(index)); // remember the current values in case they change window->targetview = window->target->view(); @@ -650,7 +649,7 @@ void winwindow_video_window_create(running_machine *machine, int index, win_moni sprintf(window->title, APPNAME ": %s [%s] - Screen %d", machine->gamedrv->description, machine->gamedrv->name, index); // set the initial maximized state - window->startmaximized = options_get_bool(&machine->options(), WINOPTION_MAXIMIZE); + window->startmaximized = options.maximize(); // finish the window creation on the window thread if (multithreading_enabled) @@ -850,7 +849,7 @@ static void create_window_class(void) static void set_starting_view(int index, win_window_info *window, const char *view) { - const char *defview = options_get_string(&window->machine->options(), WINOPTION_VIEW); + const char *defview = downcast<windows_options &>(window->machine->options()).view(); int viewindex; assert(GetCurrentThreadId() == main_threadid); @@ -1121,7 +1120,8 @@ static int complete_create(win_window_info *window) monitorbounds = window->monitor->info.rcMonitor; // create the window menu if needed - if (options_get_bool(&window->machine->options(), "menu")) { + if (downcast<windows_options &>(window->machine->options()).menu()) + { if (win_create_menu(window->machine, &menu)) return 1; } diff --git a/src/osd/windows/winmain.c b/src/osd/windows/winmain.c index 30245f024f6..8ecd7e71852 100644 --- a/src/osd/windows/winmain.c +++ b/src/osd/windows/winmain.c @@ -285,86 +285,86 @@ static void winui_output_error(void *param, const char *format, va_list argptr); //************************************************************************** // struct definitions -const options_entry mame_win_options[] = +const options_entry windows_options::s_option_entries[] = { // debugging options - { NULL, NULL, OPTION_HEADER, "WINDOWS DEBUGGING OPTIONS" }, - { "oslog", "0", OPTION_BOOLEAN, "output error.log data to the system debugger" }, - { "watchdog;wdog", "0", 0, "force the program to terminate if no updates within specified number of seconds" }, - { "debugger_font;dfont", "Lucida Console", 0, "specifies the font to use for debugging; defaults to Lucida Console" }, - { "debugger_font_size;dfontsize", "9", 0, "specifies the font size to use for debugging; defaults to 9 pt" }, + { NULL, NULL, OPTION_HEADER, "WINDOWS DEBUGGING OPTIONS" }, + { WINOPTION_OSLOG, "0", OPTION_BOOLEAN, "output error.log data to the system debugger" }, + { WINOPTION_WATCHDOG ";wdog", "0", OPTION_INTEGER, "force the program to terminate if no updates within specified number of seconds" }, + { WINOPTION_DEBUGGER_FONT ";dfont", "Lucida Console", OPTION_STRING,"specifies the font to use for debugging; defaults to Lucida Console" }, + { WINOPTION_DEBUGGER_FONT_SIZE ";dfontsize", "9", OPTION_FLOAT, "specifies the font size to use for debugging; defaults to 9 pt" }, // performance options - { NULL, NULL, OPTION_HEADER, "WINDOWS PERFORMANCE OPTIONS" }, - { "priority(-15-1)", "0", 0, "thread priority for the main game thread; range from -15 to 1" }, - { "multithreading;mt", "0", OPTION_BOOLEAN, "enable multithreading; this enables rendering and blitting on a separate thread" }, - { "numprocessors;np", "auto", 0, "number of processors; this overrides the number the system reports" }, - { "profile", "0", 0, "enable profiling, specifying the stack depth to track" }, - { "bench", "0", 0, "benchmark for the given number of emulated seconds; implies -video none -nosound -nothrottle" }, + { NULL, NULL, OPTION_HEADER, "WINDOWS PERFORMANCE OPTIONS" }, + { WINOPTION_PRIORITY "(-15-1)", "0", OPTION_INTEGER, "thread priority for the main game thread; range from -15 to 1" }, + { WINOPTION_MULTITHREADING ";mt", "0", OPTION_BOOLEAN, "enable multithreading; this enables rendering and blitting on a separate thread" }, + { WINOPTION_NUMPROCESSORS ";np", "auto", OPTION_STRING, "number of processors; this overrides the number the system reports" }, + { WINOPTION_PROFILE, "0", OPTION_INTEGER, "enable profiling, specifying the stack depth to track" }, + { WINOPTION_BENCH, "0", OPTION_INTEGER, "benchmark for the given number of emulated seconds; implies -video none -nosound -nothrottle" }, // video options - { NULL, NULL, OPTION_HEADER, "WINDOWS VIDEO OPTIONS" }, - { "video", "d3d", 0, "video output method: none, gdi, ddraw, or d3d" }, - { "numscreens(1-4)", "1", 0, "number of screens to create; usually, you want just one" }, - { "window;w", "0", OPTION_BOOLEAN, "enable window mode; otherwise, full screen mode is assumed" }, - { "maximize;max", "1", OPTION_BOOLEAN, "default to maximized windows; otherwise, windows will be minimized" }, - { "keepaspect;ka", "1", OPTION_BOOLEAN, "constrain to the proper aspect ratio" }, - { "prescale", "1", 0, "scale screen rendering by this amount in software" }, - { "waitvsync", "0", OPTION_BOOLEAN, "enable waiting for the start of VBLANK before flipping screens; reduces tearing effects" }, - { "syncrefresh", "0", OPTION_BOOLEAN, "enable using the start of VBLANK for throttling instead of the game time" }, - { "menu", "0", OPTION_BOOLEAN, "enable menu bar if available by UI implementation" }, + { NULL, NULL, OPTION_HEADER, "WINDOWS VIDEO OPTIONS" }, + { WINOPTION_VIDEO, "d3d", OPTION_STRING, "video output method: none, gdi, ddraw, or d3d" }, + { WINOPTION_NUMSCREENS "(1-4)", "1", OPTION_INTEGER, "number of screens to create; usually, you want just one" }, + { WINOPTION_WINDOW ";w", "0", OPTION_BOOLEAN, "enable window mode; otherwise, full screen mode is assumed" }, + { WINOPTION_MAXIMIZE ";max", "1", OPTION_BOOLEAN, "default to maximized windows; otherwise, windows will be minimized" }, + { WINOPTION_KEEPASPECT ";ka", "1", OPTION_BOOLEAN, "constrain to the proper aspect ratio" }, + { WINOPTION_PRESCALE, "1", OPTION_INTEGER, "scale screen rendering by this amount in software" }, + { WINOPTION_WAITVSYNC, "0", OPTION_BOOLEAN, "enable waiting for the start of VBLANK before flipping screens; reduces tearing effects" }, + { WINOPTION_SYNCREFRESH, "0", OPTION_BOOLEAN, "enable using the start of VBLANK for throttling instead of the game time" }, + { WINOPTION_MENU, "0", OPTION_BOOLEAN, "enable menu bar if available by UI implementation" }, // DirectDraw-specific options - { NULL, NULL, OPTION_HEADER, "DIRECTDRAW-SPECIFIC OPTIONS" }, - { "hwstretch;hws", "1", OPTION_BOOLEAN, "enable hardware stretching" }, + { NULL, NULL, OPTION_HEADER, "DIRECTDRAW-SPECIFIC OPTIONS" }, + { WINOPTION_HWSTRETCH ";hws", "1", OPTION_BOOLEAN, "enable hardware stretching" }, // Direct3D-specific options - { NULL, NULL, OPTION_HEADER, "DIRECT3D-SPECIFIC OPTIONS" }, - { "d3dversion(8-9)", "9", 0, "specify the preferred Direct3D version (8 or 9)" }, - { "filter;d3dfilter;flt", "1", OPTION_BOOLEAN, "enable bilinear filtering on screen output" }, + { NULL, NULL, OPTION_HEADER, "DIRECT3D-SPECIFIC OPTIONS" }, + { WINOPTION_D3DVERSION "(8-9)", "9", OPTION_INTEGER, "specify the preferred Direct3D version (8 or 9)" }, + { WINOPTION_FILTER ";d3dfilter;flt", "1", OPTION_BOOLEAN, "enable bilinear filtering on screen output" }, // per-window options - { NULL, NULL, OPTION_HEADER, "PER-WINDOW VIDEO OPTIONS" }, - { "screen", "auto", 0, "explicit name of all screens; 'auto' here will try to make a best guess" }, - { "aspect;screen_aspect", "auto", 0, "aspect ratio for all screens; 'auto' here will try to make a best guess" }, - { "resolution;r", "auto", 0, "preferred resolution for all screens; format is <width>x<height>[@<refreshrate>] or 'auto'" }, - { "view", "auto", 0, "preferred view for all screens" }, - - { "screen0", "auto", 0, "explicit name of the first screen; 'auto' here will try to make a best guess" }, - { "aspect0", "auto", 0, "aspect ratio of the first screen; 'auto' here will try to make a best guess" }, - { "resolution0;r0", "auto", 0, "preferred resolution of the first screen; format is <width>x<height>[@<refreshrate>] or 'auto'" }, - { "view0", "auto", 0, "preferred view for the first screen" }, - - { "screen1", "auto", 0, "explicit name of the second screen; 'auto' here will try to make a best guess" }, - { "aspect1", "auto", 0, "aspect ratio of the second screen; 'auto' here will try to make a best guess" }, - { "resolution1;r1", "auto", 0, "preferred resolution of the second screen; format is <width>x<height>[@<refreshrate>] or 'auto'" }, - { "view1", "auto", 0, "preferred view for the second screen" }, - - { "screen2", "auto", 0, "explicit name of the third screen; 'auto' here will try to make a best guess" }, - { "aspect2", "auto", 0, "aspect ratio of the third screen; 'auto' here will try to make a best guess" }, - { "resolution2;r2", "auto", 0, "preferred resolution of the third screen; format is <width>x<height>[@<refreshrate>] or 'auto'" }, - { "view2", "auto", 0, "preferred view for the third screen" }, - - { "screen3", "auto", 0, "explicit name of the fourth screen; 'auto' here will try to make a best guess" }, - { "aspect3", "auto", 0, "aspect ratio of the fourth screen; 'auto' here will try to make a best guess" }, - { "resolution3;r3", "auto", 0, "preferred resolution of the fourth screen; format is <width>x<height>[@<refreshrate>] or 'auto'" }, - { "view3", "auto", 0, "preferred view for the fourth screen" }, + { NULL, NULL, OPTION_HEADER, "PER-WINDOW VIDEO OPTIONS" }, + { WINOPTION_SCREEN, "auto", OPTION_STRING, "explicit name of all screens; 'auto' here will try to make a best guess" }, + { WINOPTION_ASPECT ";screen_aspect", "auto", OPTION_STRING, "aspect ratio for all screens; 'auto' here will try to make a best guess" }, + { WINOPTION_RESOLUTION ";r", "auto", OPTION_STRING, "preferred resolution for all screens; format is <width>x<height>[@<refreshrate>] or 'auto'" }, + { WINOPTION_VIEW, "auto", OPTION_STRING, "preferred view for all screens" }, + + { WINOPTION_SCREEN "0", "auto", OPTION_STRING, "explicit name of the first screen; 'auto' here will try to make a best guess" }, + { WINOPTION_ASPECT "0", "auto", OPTION_STRING, "aspect ratio of the first screen; 'auto' here will try to make a best guess" }, + { WINOPTION_RESOLUTION "0;r0", "auto", OPTION_STRING, "preferred resolution of the first screen; format is <width>x<height>[@<refreshrate>] or 'auto'" }, + { WINOPTION_VIEW "0", "auto", OPTION_STRING, "preferred view for the first screen" }, + + { WINOPTION_SCREEN "1", "auto", OPTION_STRING, "explicit name of the second screen; 'auto' here will try to make a best guess" }, + { WINOPTION_ASPECT "1", "auto", OPTION_STRING, "aspect ratio of the second screen; 'auto' here will try to make a best guess" }, + { WINOPTION_RESOLUTION "1;r1", "auto", OPTION_STRING, "preferred resolution of the second screen; format is <width>x<height>[@<refreshrate>] or 'auto'" }, + { WINOPTION_VIEW "1", "auto", OPTION_STRING, "preferred view for the second screen" }, + + { WINOPTION_SCREEN "2", "auto", OPTION_STRING, "explicit name of the third screen; 'auto' here will try to make a best guess" }, + { WINOPTION_ASPECT "2", "auto", OPTION_STRING, "aspect ratio of the third screen; 'auto' here will try to make a best guess" }, + { WINOPTION_RESOLUTION "2;r2", "auto", OPTION_STRING, "preferred resolution of the third screen; format is <width>x<height>[@<refreshrate>] or 'auto'" }, + { WINOPTION_VIEW "2", "auto", OPTION_STRING, "preferred view for the third screen" }, + + { WINOPTION_SCREEN "3", "auto", OPTION_STRING, "explicit name of the fourth screen; 'auto' here will try to make a best guess" }, + { WINOPTION_ASPECT "3", "auto", OPTION_STRING, "aspect ratio of the fourth screen; 'auto' here will try to make a best guess" }, + { WINOPTION_RESOLUTION "3;r3", "auto", OPTION_STRING, "preferred resolution of the fourth screen; format is <width>x<height>[@<refreshrate>] or 'auto'" }, + { WINOPTION_VIEW "3", "auto", OPTION_STRING, "preferred view for the fourth screen" }, // full screen options - { NULL, NULL, OPTION_HEADER, "FULL SCREEN OPTIONS" }, - { "triplebuffer;tb", "0", OPTION_BOOLEAN, "enable triple buffering" }, - { "switchres", "0", OPTION_BOOLEAN, "enable resolution switching" }, - { "full_screen_brightness;fsb(0.1-2.0)","1.0", 0, "brightness value in full screen mode" }, - { "full_screen_contrast;fsc(0.1-2.0)", "1.0", 0, "contrast value in full screen mode" }, - { "full_screen_gamma;fsg(0.1-3.0)", "1.0", 0, "gamma value in full screen mode" }, + { NULL, NULL, OPTION_HEADER, "FULL SCREEN OPTIONS" }, + { WINOPTION_TRIPLEBUFFER ";tb", "0", OPTION_BOOLEAN, "enable triple buffering" }, + { WINOPTION_SWITCHRES, "0", OPTION_BOOLEAN, "enable resolution switching" }, + { WINOPTION_FULLSCREENBRIGHTNESS ";fsb(0.1-2.0)", "1.0", OPTION_FLOAT, "brightness value in full screen mode" }, + { WINOPTION_FULLLSCREENCONTRAST ";fsc(0.1-2.0)", "1.0", OPTION_FLOAT, "contrast value in full screen mode" }, + { WINOPTION_FULLSCREENGAMMA ";fsg(0.1-3.0)", "1.0", OPTION_FLOAT, "gamma value in full screen mode" }, // sound options - { NULL, NULL, OPTION_HEADER, "WINDOWS SOUND OPTIONS" }, - { "audio_latency(1-5)", "2", 0, "set audio latency (increase to reduce glitches)" }, + { NULL, NULL, OPTION_HEADER, "WINDOWS SOUND OPTIONS" }, + { WINOPTION_AUDIO_LATENCY "(1-5)", "2", OPTION_INTEGER, "set audio latency (increase to reduce glitches)" }, // input options - { NULL, NULL, OPTION_HEADER, "INPUT DEVICE OPTIONS" }, - { "dual_lightgun;dual", "0", OPTION_BOOLEAN, "enable dual lightgun input" }, + { NULL, NULL, OPTION_HEADER, "INPUT DEVICE OPTIONS" }, + { WINOPTION_DUAL_LIGHTGUN ";dual", "0", OPTION_BOOLEAN, "enable dual lightgun input" }, { NULL } }; @@ -413,8 +413,9 @@ int main(int argc, char *argv[]) // parse config and cmdline options DWORD result = 0; { + windows_options options; windows_osd_interface osd; - result = cli_execute(argc, argv, osd, mame_win_options); + result = cli_execute(options, osd, argc, argv); } // free symbols @@ -424,6 +425,16 @@ int main(int argc, char *argv[]) //============================================================ +// windows_options +//============================================================ + +windows_options::windows_options() +{ + add_entries(s_option_entries); +} + + +//============================================================ // control_handler //============================================================ @@ -516,35 +527,39 @@ void windows_osd_interface::init(running_machine &machine) osd_interface::init(machine); const char *stemp; + windows_options &options = downcast<windows_options &>(machine.options()); // determine if we are benchmarking, and adjust options appropriately - int bench = options_get_int(&machine.options(), WINOPTION_BENCH); + int bench = options.bench(); + astring error_string; if (bench > 0) { - options_set_bool(&machine.options(), OPTION_THROTTLE, false, OPTION_PRIORITY_MAXIMUM); - options_set_bool(&machine.options(), OPTION_SOUND, false, OPTION_PRIORITY_MAXIMUM); - options_set_string(&machine.options(), WINOPTION_VIDEO, "none", OPTION_PRIORITY_MAXIMUM); - options_set_int(&machine.options(), OPTION_SECONDS_TO_RUN, bench, OPTION_PRIORITY_MAXIMUM); + options.set_value(OPTION_THROTTLE, false, OPTION_PRIORITY_MAXIMUM, error_string); + options.set_value(OPTION_SOUND, false, OPTION_PRIORITY_MAXIMUM, error_string); + options.set_value(WINOPTION_VIDEO, "none", OPTION_PRIORITY_MAXIMUM, error_string); + options.set_value(OPTION_SECONDS_TO_RUN, bench, OPTION_PRIORITY_MAXIMUM, error_string); + assert(!error_string); } // determine if we are profiling, and adjust options appropriately - int profile = options_get_int(&machine.options(), WINOPTION_PROFILE); + int profile = options.profile(); if (profile > 0) { - options_set_bool(&machine.options(), OPTION_THROTTLE, false, OPTION_PRIORITY_MAXIMUM); - options_set_bool(&machine.options(), WINOPTION_MULTITHREADING, false, OPTION_PRIORITY_MAXIMUM); - options_set_int(&machine.options(), WINOPTION_NUMPROCESSORS, 1, OPTION_PRIORITY_MAXIMUM); + options.set_value(OPTION_THROTTLE, false, OPTION_PRIORITY_MAXIMUM, error_string); + options.set_value(WINOPTION_MULTITHREADING, false, OPTION_PRIORITY_MAXIMUM, error_string); + options.set_value(WINOPTION_NUMPROCESSORS, 1, OPTION_PRIORITY_MAXIMUM, error_string); + assert(!error_string); } // thread priority if (!(machine.debug_flags & DEBUG_FLAG_OSD_ENABLED)) - SetThreadPriority(GetCurrentThread(), options_get_int(&machine.options(), WINOPTION_PRIORITY)); + SetThreadPriority(GetCurrentThread(), options.priority()); // ensure we get called on the way out machine.add_notifier(MACHINE_NOTIFY_EXIT, osd_exit); // get number of processors - stemp = options_get_string(&machine.options(), WINOPTION_NUMPROCESSORS); + stemp = options.numprocessors(); osd_num_processors = 0; @@ -573,7 +588,7 @@ void windows_osd_interface::init(running_machine &machine) } // hook up the debugger log - if (options_get_bool(&machine.options(), WINOPTION_OSLOG)) + if (options.oslog()) machine.add_logerror_callback(output_oslog); // crank up the multimedia timer resolution to its max @@ -587,7 +602,7 @@ void windows_osd_interface::init(running_machine &machine) // mm_task = (*av_set_mm_thread_characteristics)(TEXT("Playback"), &task_index); // if a watchdog thread is requested, create one - int watchdog = options_get_int(&machine.options(), WINOPTION_WATCHDOG); + int watchdog = options.watchdog(); if (watchdog != 0) { watchdog_reset_event = CreateEvent(NULL, FALSE, FALSE, NULL); diff --git a/src/osd/windows/winmain.h b/src/osd/windows/winmain.h index a5c77665c15..0b8e2477ae7 100644 --- a/src/osd/windows/winmain.h +++ b/src/osd/windows/winmain.h @@ -39,7 +39,7 @@ // //============================================================ -#include "options.h" +#include "clifront.h" #include "osdepend.h" @@ -84,26 +84,6 @@ #define WINOPTION_RESOLUTION "resolution" #define WINOPTION_VIEW "view" -#define WINOPTION_SCREEN0 "screen0" -#define WINOPTION_ASPECT0 "aspect0" -#define WINOPTION_RESOLUTION0 "resolution0" -#define WINOPTION_VIEW0 "view0" - -#define WINOPTION_SCREEN1 "screen1" -#define WINOPTION_ASPECT1 "aspect1" -#define WINOPTION_RESOLUTION1 "resolution1" -#define WINOPTION_VIEW1 "view1" - -#define WINOPTION_SCREEN2 "screen2" -#define WINOPTION_ASPECT2 "aspect2" -#define WINOPTION_RESOLUTION2 "resolution2" -#define WINOPTION_VIEW2 "view2" - -#define WINOPTION_SCREEN3 "screen3" -#define WINOPTION_ASPECT3 "aspect3" -#define WINOPTION_RESOLUTION3 "resolution3" -#define WINOPTION_VIEW3 "view3" - // full screen options #define WINOPTION_TRIPLEBUFFER "triplebuffer" #define WINOPTION_SWITCHRES "switchres" @@ -120,6 +100,76 @@ //============================================================ +// TYPE DEFINITIONS +//============================================================ + +class windows_options : public cli_options +{ +public: + // construction/destruction + windows_options(); + + // debugging options + bool oslog() const { return bool_value(WINOPTION_OSLOG); } + int watchdog() const { return int_value(WINOPTION_WATCHDOG); } + const char *debugger_font() const { return value(WINOPTION_DEBUGGER_FONT); } + float debugger_font_size() const { return float_value(WINOPTION_DEBUGGER_FONT_SIZE); } + + // performance options + int priority() const { return int_value(WINOPTION_PRIORITY); } + bool multithreading() const { return bool_value(WINOPTION_MULTITHREADING); } + const char *numprocessors() const { return value(WINOPTION_NUMPROCESSORS); } + int profile() const { return int_value(WINOPTION_PROFILE); } + int bench() const { return int_value(WINOPTION_BENCH); } + + // video options + const char *video() const { return value(WINOPTION_VIDEO); } + int numscreens() const { return int_value(WINOPTION_NUMSCREENS); } + bool window() const { return bool_value(WINOPTION_WINDOW); } + bool maximize() const { return bool_value(WINOPTION_MAXIMIZE); } + bool keep_aspect() const { return bool_value(WINOPTION_KEEPASPECT); } + int prescale() const { return int_value(WINOPTION_PRESCALE); } + bool wait_vsync() const { return bool_value(WINOPTION_WAITVSYNC); } + bool sync_refresh() const { return bool_value(WINOPTION_SYNCREFRESH); } + bool menu() const { return bool_value(WINOPTION_MENU); } + + // DirectDraw-specific options + bool hwstretch() const { return bool_value(WINOPTION_HWSTRETCH); } + + // Direct3D-specific options + int d3d_version() const { return int_value(WINOPTION_D3DVERSION); } + bool filter() const { return bool_value(WINOPTION_FILTER); } + + // per-window options + const char *screen() const { return value(WINOPTION_SCREEN); } + const char *aspect() const { return value(WINOPTION_ASPECT); } + const char *resolution() const { return value(WINOPTION_RESOLUTION); } + const char *view() const { return value(WINOPTION_VIEW); } + const char *screen(int index) const { astring temp; return value(temp.format("%s%d", WINOPTION_SCREEN, index)); } + const char *aspect(int index) const { astring temp; return value(temp.format("%s%d", WINOPTION_ASPECT, index)); } + const char *resolution(int index) const { astring temp; return value(temp.format("%s%d", WINOPTION_RESOLUTION, index)); } + const char *view(int index) const { astring temp; return value(temp.format("%s%d", WINOPTION_VIEW, index)); } + + // full screen options + bool triple_buffer() const { return bool_value(WINOPTION_TRIPLEBUFFER); } + bool switch_res() const { return bool_value(WINOPTION_SWITCHRES); } + float full_screen_brightness() const { return float_value(WINOPTION_FULLSCREENBRIGHTNESS); } + float full_screen_contrast() const { return float_value(WINOPTION_FULLLSCREENCONTRAST); } + float full_screen_gamma() const { return float_value(WINOPTION_FULLSCREENGAMMA); } + + // sound options + int audio_latency() const { return int_value(WINOPTION_AUDIO_LATENCY); } + + // input options + bool dual_lightgun() const { return bool_value(WINOPTION_DUAL_LIGHTGUN); } + +private: + static const options_entry s_option_entries[]; +}; + + + +//============================================================ // MACROS //============================================================ |