emuopts.c: Added a new option -statename which allows to specify the location of state saving,

relative to -state_directory (whose usage remains unchanged). Syntax is basically the same 
as snapname, allowing for the  / character as path separator, %g as the driver name, and 
%d_[media] as the image name mounted in the "media" device. 

For example, using -statename foo/%g when running "mame wrally" will store save states into 
the folder sta/foo/wrally/ ; using -statename %g/%d_cart when running "mess nes -cart smb" 
will store save states into the folder sta/nes/smb/ ; using -statename %g/%d_cdrm when
running "mess pce -cart cdsys -cdrm draculax" will store save states into sta/pce/draculax/
Specifying a media switch which is not available (e.g. %d_cdrm in a c64) or a media switch
where no image is mounted (e.g. %d_cdrm in pce while playing a hucard game) will revert
the option to its default value %g and save states will be stored in sta/*gamename*/ as in
previous versions. [Fabio Priuli]

Needless to say, this option is very useful with home computers and consoles in MESS since it
allows to have 36 save slots for each game instead of 36 for the whole system library

Notice that a clean compile is required, due to the addition to the running_machine class
This commit is contained in:
Fabio Priuli 2013-05-28 05:12:28 +00:00
parent b8b819fae7
commit 8d7e236c83
5 changed files with 129 additions and 5 deletions

View file

@ -525,10 +525,15 @@ Core state/playback options
find the next empty value for %i and use that for a filename. The
default is %g/%i, which creates a separate folder for each game,
and names the snapshots under it starting with 0000 and increasing
from there. In the case of using different media, you can use the
%d_[media] indicator. Replace [media] with the default media being
used. In the example: 'mess nes megaman2u -snapname %g/%d_cart'
snapshots will then be placed in 'snaps\nes\megaman2u.png'
from there. In addition to the above, for drivers using different
media, like carts or floppy disks, you can also use the %d_[media]
indicator. Replace [media] with the media switch you want to use.
A few examples: if you use 'mame robby -snapname foo/%g%i' snapshots
will be saved as 'snaps\foo\robby0000.png' , 'snaps\foo\robby0001.png'
and so on ; if you use 'mess nes -cart robby -snapname %g/%d_cart'
snapshots will be saved as 'snaps\nes\robby.png' ; if you use
'mess c64 -flop1 robby -snapname %g/%d_flop1/%i' snapshots will be
saved as 'snaps\c64\robby\0000.png'.
-snapsize <width>x<height>
@ -554,6 +559,23 @@ Core state/playback options
<viewname> can also be 'auto', which selects the first view with all
screens present. The default value is 'internal'.
-statename <name>
Describes how MAME should store save state files, relative to the
state_directory path. <name> is a string that provides a template that
is used to generate a relative path. Two simple substitutions are
provided: the / character represents the path separator on any target
platform (even Windows); the string %g represents the driver name of
the current game. The default is %g, which creates a separate folder for
each game. In addition to the above, for drivers using different
media, like carts or floppy disks, you can also use the %d_[media]
indicator. Replace [media] with the media switch you want to use.
A few examples: if you use 'mame robby -statename foo/%g' save states
will be stored inside 'sta\foo\robby\' ; if you use 'mess nes -cart
robby -statename %g/%d_cart' save states will be stored inside
'sta\nes\robby\' ; if you use 'mess c64 -flop1 robby -statename
%g/%d_flop1' save states will be stored inside 'sta\c64\robby\'.
-[no]burnin
Tracks brightness of the screen during play and at the end of

View file

@ -95,6 +95,7 @@ const options_entry emu_options::s_option_entries[] =
{ 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_STATENAME, "%g", OPTION_STRING, "override of the default state subfolder naming; %g == gamename" },
{ OPTION_BURNIN, "0", OPTION_BOOLEAN, "create burn-in snapshots for each screen" },
// performance options

View file

@ -107,6 +107,7 @@ enum
#define OPTION_SNAPNAME "snapname"
#define OPTION_SNAPSIZE "snapsize"
#define OPTION_SNAPVIEW "snapview"
#define OPTION_STATENAME "statename"
#define OPTION_BURNIN "burnin"
// core performance options
@ -266,6 +267,7 @@ public:
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); }
const char *state_name() const { return value(OPTION_STATENAME); }
bool burnin() const { return bool_value(OPTION_BURNIN); }
// core performance options

View file

@ -544,6 +544,101 @@ void running_machine::schedule_new_driver(const game_driver &driver)
}
//-------------------------------------------------
// get_statename - allow to specify a subfolder of
// the state directory for state loading/saving,
// very useful for MESS and consoles or computers
// where you can have separate folders for diff
// software
//-------------------------------------------------
astring running_machine::get_statename(const char *option)
{
astring statename_str("");
if (option == NULL || option[0] == 0)
statename_str.cpy("%g");
else
statename_str.cpy(option);
// strip any extension in the provided statename
int index = statename_str.rchr(0, '.');
if (index != -1)
statename_str.substr(0, index);
// handle %d in the template (for image devices)
astring statename_dev("%d_");
int pos = statename_str.find(0, statename_dev);
if (pos != -1)
{
// if more %d are found, revert to default and ignore them all
if (statename_str.find(pos + 3, statename_dev) != -1)
statename_str.cpy("%g");
// else if there is a single %d, try to create the correct snapname
else
{
int name_found = 0;
// find length of the device name
int end1 = statename_str.find(pos + 3, "/");
int end2 = statename_str.find(pos + 3, "%");
int end = -1;
if ((end1 != -1) && (end2 != -1))
end = MIN(end1, end2);
else if (end1 != -1)
end = end1;
else if (end2 != -1)
end = end2;
else
end = statename_str.len();
if (end - pos < 3)
fatalerror("Something very wrong is going on!!!\n");
// copy the device name to an astring
astring devname_str;
devname_str.cpysubstr(statename_str, pos + 3, end - pos - 3);
//printf("check template: %s\n", devname_str.cstr());
// verify that there is such a device for this system
image_interface_iterator iter(root_device());
for (device_image_interface *image = iter.first(); image != NULL; image = iter.next())
{
// get the device name
astring tempdevname(image->brief_instance_name());
//printf("check device: %s\n", tempdevname.cstr());
if (devname_str.cmp(tempdevname) == 0)
{
// verify that such a device has an image mounted
if (image->basename_noext() != NULL)
{
astring filename(image->basename_noext());
// setup snapname and remove the %d_
statename_str.replace(0, devname_str, filename);
statename_str.del(pos, 3);
//printf("check image: %s\n", filename.cstr());
name_found = 1;
}
}
}
// or fallback to default
if (name_found == 0)
statename_str.cpy("%g");
}
}
// substitute path and gamename up front
statename_str.replace(0, "/", PATH_SEPARATOR);
statename_str.replace(0, "%g", basename());
return statename_str;
}
//-------------------------------------------------
// set_saveload_filename - specifies the filename
// for state loading/saving
@ -560,7 +655,10 @@ void running_machine::set_saveload_filename(const char *filename)
else
{
m_saveload_searchpath = options().state_directory();
m_saveload_pending_file.cpy(basename()).cat(PATH_SEPARATOR).cat(filename).cat(".sta");
// take into account the statename option
const char *stateopt = options().state_name();
astring statename = get_statename(stateopt);
m_saveload_pending_file.cpy(statename.cstr()).cat(PATH_SEPARATOR).cat(filename).cat(".sta");
}
}

View file

@ -318,6 +318,7 @@ private:
// internal helpers
void start();
void set_saveload_filename(const char *filename);
astring get_statename(const char *statename_opt);
void fill_systime(system_time &systime, time_t t);
void handle_saveload();
void soft_reset(void *ptr = NULL, INT32 param = 0);