diff options
author | 2011-03-03 17:05:24 +0000 | |
---|---|---|
committer | 2011-03-03 17:05:24 +0000 | |
commit | 06ee6804dd5d1157a079e02d46abb6612571f21f (patch) | |
tree | 831cd82cc7cf6d493e6b5e9a7bf7d956733cf663 /src | |
parent | e870e8d7bce1bda126a3ea06391d587dc9b57f01 (diff) |
Converted core_options to a class. Removed a bunch of marginal
functionality in favor of alternate mechanisms. Errors are
now reported via an astring rather than via callbacks. Every
option must now specify a type (command, integer, float, string,
boolean, etc). Command behavior has changed so that only one
command is permitted. [Aaron Giles]
Changed fileio system to accept just a raw searchpath instead of
an options/option name combination. [Aaron Giles]
Created emu_options class dervied from core_options which wraps
core emulator options. Added mechanisms to cleanly change the
system name and add/remove system-specific options, versus the
old way using callbacks. Also added read accessors for all the
options, to ensure consistency in how parameters are handled.
Changed most core systems to access emu_options instead of
core_options. Also changed machine->options() to return emu_options.
[Aaron Giles]
Created cli_options class derived from emu_options which adds the
command-line specific options. Updated clifront code to leverage
the new class and the new core behaviors. cli_execute() now accepts
a cli_options object when called. [Aaron Giles]
Updated both SDL and Windows to have their own options classes,
derived from cli_options, which add the OSD-specific options on
top of everything else. Added accessors for all the options so
that queries are strongly typed and simplified. [Aaron Giles]
Out of whatsnew: I've surely screwed up some stuff, though I have
smoke tested a bunch of things. Let me know if you hit anything odd.
Also I know this change will impact the WINUI stuff, please let me
know if there are issues. All the functionality necessary should
still be present. If it's not obvious, please talk to me before
adding stuff to the core_options class.
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 //============================================================ |