Added new function mame_fclose_and_open_next() which will close a file

and then keep searching the searchpath for the next valid file. Did some
internal rearranging in fileio.c to make this work.

Changed cheat search so that it loads *all* cheat files in all search
paths. Note that it is easy to end up with duplicate entries this way.
Some currently disabled code is present which filters out duplicates,
but the logic for doing this is quite unclear with the presence of
text-only cheats, which is why the code is disabled for now.
This commit is contained in:
Aaron Giles 2009-09-03 15:54:07 +00:00
parent 43b28f89a5
commit a0dc0e0196
3 changed files with 125 additions and 76 deletions

View File

@ -93,6 +93,9 @@
CONSTANTS
***************************************************************************/
/* turn this on to enable removing duplicate cheats; not sure if we should */
#define REMOVE_DUPLICATE_CHEATS 0
#define CHEAT_VERSION 1
#define DEFAULT_TEMP_VARIABLES 10
@ -959,76 +962,99 @@ static void cheat_execute_script(cheat_private *cheatinfo, cheat_entry *cheat, s
static cheat_entry *cheat_list_load(running_machine *machine, const char *filename)
{
xml_data_node *rootnode, *mamecheatnode, *cheatnode;
xml_data_node *rootnode = NULL;
cheat_entry *cheatlist = NULL;
cheat_entry **cheattailptr;
xml_parse_options options;
xml_parse_error error;
mame_file *cheatfile;
cheat_entry **cheattailptr = &cheatlist;
mame_file *cheatfile = NULL;
file_error filerr;
astring *fname;
int version;
/* open the file with the proper name */
fname = astring_assemble_2(astring_alloc(), filename, ".xml");
filerr = mame_fopen(SEARCHPATH_CHEAT, astring_c(fname), OPEN_FLAG_READ, &cheatfile);
astring_free(fname);
/* if that failed, return nothing */
if (filerr != FILERR_NONE)
return NULL;
/* read the XML file into internal data structures */
memset(&options, 0, sizeof(options));
options.error = &error;
rootnode = xml_file_read(mame_core_file(cheatfile), &options);
mame_fclose(cheatfile);
/* if unable to parse the file, just bail */
if (rootnode == NULL)
/* loop over all instrances of the files found in our search paths */
while (filerr == FILERR_NONE)
{
mame_printf_error("%s.xml(%d): error parsing XML (%s)\n", filename, error.error_line, error.error_message);
return NULL;
}
xml_data_node *mamecheatnode, *cheatnode;
xml_parse_options options;
xml_parse_error error;
cheat_entry *scannode;
int version;
/* find the layout node */
mamecheatnode = xml_get_sibling(rootnode->child, "mamecheat");
if (mamecheatnode == NULL)
{
mame_printf_error("%s.xml: missing mamecheatnode node", filename);
goto error;
}
mame_printf_verbose("Loading cheats file from %s\n", mame_file_full_name(cheatfile));
/* read the XML file into internal data structures */
memset(&options, 0, sizeof(options));
options.error = &error;
rootnode = xml_file_read(mame_core_file(cheatfile), &options);
/* validate the config data version */
version = xml_get_attribute_int(mamecheatnode, "version", 0);
if (version != CHEAT_VERSION)
{
mame_printf_error("%s.xml(%d): Invalid cheat XML file: unsupported version", filename, mamecheatnode->line);
goto error;
}
/* parse all the elements */
cheatlist = NULL;
cheattailptr = &cheatlist;
for (cheatnode = xml_get_sibling(mamecheatnode->child, "cheat"); cheatnode != NULL; cheatnode = xml_get_sibling(cheatnode->next, "cheat"))
{
/* load this entry */
cheat_entry *curcheat = cheat_entry_load(machine, filename, cheatnode);
if (curcheat == NULL)
/* if unable to parse the file, just bail */
if (rootnode == NULL)
{
mame_printf_error("%s.xml(%d): error parsing XML (%s)\n", filename, error.error_line, error.error_message);
goto error;
}
/* add to the end of the list */
*cheattailptr = curcheat;
cheattailptr = &curcheat->next;
/* find the layout node */
mamecheatnode = xml_get_sibling(rootnode->child, "mamecheat");
if (mamecheatnode == NULL)
{
mame_printf_error("%s.xml: missing mamecheatnode node", filename);
goto error;
}
/* validate the config data version */
version = xml_get_attribute_int(mamecheatnode, "version", 0);
if (version != CHEAT_VERSION)
{
mame_printf_error("%s.xml(%d): Invalid cheat XML file: unsupported version", filename, mamecheatnode->line);
goto error;
}
/* parse all the elements */
for (cheatnode = xml_get_sibling(mamecheatnode->child, "cheat"); cheatnode != NULL; cheatnode = xml_get_sibling(cheatnode->next, "cheat"))
{
/* load this entry */
cheat_entry *curcheat = cheat_entry_load(machine, filename, cheatnode);
if (curcheat == NULL)
goto error;
/* make sure we're not a duplicate */
scannode = NULL;
if (REMOVE_DUPLICATE_CHEATS)
for (scannode = cheatlist; scannode != NULL; scannode = scannode->next)
if (astring_cmp(scannode->description, curcheat->description) == 0)
{
mame_printf_verbose("Ignoring duplicate cheat '%s' from file %s\n", astring_c(curcheat->description), mame_file_full_name(cheatfile));
break;
}
/* add to the end of the list */
if (scannode == NULL)
{
*cheattailptr = curcheat;
cheattailptr = &curcheat->next;
}
}
/* free the file and loop for the next one */
xml_file_free(rootnode);
/* open the next file in sequence */
filerr = mame_fclose_and_open_next(&cheatfile, astring_c(fname), OPEN_FLAG_READ);
}
/* free the file and exit */
xml_file_free(rootnode);
/* release memory and return the cheat list */
astring_free(fname);
return cheatlist;
error:
cheat_list_free(cheatlist);
xml_file_free(rootnode);
if (cheatfile != NULL)
mame_fclose(cheatfile);
astring_free(fname);
return NULL;
}

View File

@ -38,6 +38,15 @@
TYPE DEFINITIONS
***************************************************************************/
typedef struct _path_iterator path_iterator;
struct _path_iterator
{
const char * base;
const char * cur;
int index;
};
/* typedef struct _mame_file mame_file -- declared in fileio.h */
struct _mame_file
{
@ -46,6 +55,7 @@ struct _mame_file
#endif
astring * filename; /* full filename */
core_file * file; /* core file pointer */
path_iterator iterator; /* iterator for paths */
UINT32 openflags; /* flags we used for the open */
char hash[HASH_BUF_SIZE]; /* hash data for the file */
zip_file * zipfile; /* ZIP file pointer */
@ -54,15 +64,6 @@ struct _mame_file
};
typedef struct _path_iterator path_iterator;
struct _path_iterator
{
const char * base;
const char * cur;
int index;
};
/* typedef struct _mame_path mame_path -- declared in fileio.h */
struct _mame_path
{
@ -82,7 +83,7 @@ struct _mame_path
static void fileio_exit(running_machine *machine);
/* file open/close */
static file_error fopen_internal(core_options *opts, const char *searchpath, const char *filename, UINT32 crc, UINT32 flags, mame_file **file);
static file_error fopen_internal(core_options *opts, path_iterator *iterator, const char *filename, UINT32 crc, UINT32 flags, mame_file **file);
static file_error fopen_attempt_zipped(astring *fullname, UINT32 crc, UINT32 openflags, mame_file *file);
/* path iteration */
@ -134,7 +135,9 @@ static void fileio_exit(running_machine *machine)
file_error mame_fopen(const char *searchpath, const char *filename, UINT32 openflags, mame_file **file)
{
return fopen_internal(mame_options(), searchpath, filename, 0, openflags, file);
path_iterator iterator;
path_iterator_init(&iterator, mame_options(), searchpath);
return fopen_internal(mame_options(), &iterator, filename, 0, openflags, file);
}
@ -145,6 +148,8 @@ file_error mame_fopen(const char *searchpath, const char *filename, UINT32 openf
file_error mame_fopen_crc(const char *searchpath, const char *filename, UINT32 crc, UINT32 openflags, mame_file **file)
{
path_iterator iterator;
path_iterator_init(&iterator, mame_options(), searchpath);
return mame_fopen_crc_options(mame_options(), searchpath, filename, crc, openflags, file);
}
@ -156,7 +161,9 @@ file_error mame_fopen_crc(const char *searchpath, const char *filename, UINT32 c
file_error mame_fopen_options(core_options *opts, const char *searchpath, const char *filename, UINT32 openflags, mame_file **file)
{
return fopen_internal(opts, searchpath, filename, 0, openflags, file);
path_iterator iterator;
path_iterator_init(&iterator, opts, searchpath);
return fopen_internal(opts, &iterator, filename, 0, openflags, file);
}
@ -167,7 +174,9 @@ file_error mame_fopen_options(core_options *opts, const char *searchpath, const
file_error mame_fopen_crc_options(core_options *opts, const char *searchpath, const char *filename, UINT32 crc, UINT32 openflags, mame_file **file)
{
return fopen_internal(opts, searchpath, filename, crc, openflags | OPEN_FLAG_HAS_CRC, file);
path_iterator iterator;
path_iterator_init(&iterator, opts, searchpath);
return fopen_internal(opts, &iterator, filename, crc, openflags | OPEN_FLAG_HAS_CRC, file);
}
@ -212,10 +221,9 @@ error:
fopen_internal - open a file
-------------------------------------------------*/
static file_error fopen_internal(core_options *opts, const char *searchpath, const char *filename, UINT32 crc, UINT32 openflags, mame_file **file)
static file_error fopen_internal(core_options *opts, path_iterator *iterator, const char *filename, UINT32 crc, UINT32 openflags, mame_file **file)
{
file_error filerr = FILERR_NOT_FOUND;
path_iterator iterator;
/* can either have a hash or open for write, but not both */
if ((openflags & OPEN_FLAG_HAS_CRC) && (openflags & OPEN_FLAG_WRITE))
@ -233,16 +241,9 @@ static file_error fopen_internal(core_options *opts, const char *searchpath, con
(*file)->debug_cookie = DEBUG_COOKIE;
#endif
/* if the path is absolute, null out the search path */
if (searchpath != NULL && osd_is_absolute_path(searchpath))
searchpath = NULL;
/* determine the maximum length of a composed filename, plus some extra space for .zip extensions */
path_iterator_init(&iterator, opts, searchpath);
/* loop over paths */
(*file)->filename = astring_alloc();
while (path_iterator_get_next(&iterator, (*file)->filename))
while (path_iterator_get_next(iterator, (*file)->filename))
{
/* compute the full pathname */
if (astring_len((*file)->filename) > 0)
@ -262,9 +263,13 @@ static file_error fopen_internal(core_options *opts, const char *searchpath, con
break;
}
}
/* if we succeeded, save the iterator */
if (filerr == FILERR_NONE)
(*file)->iterator = *iterator;
/* handle errors and return */
if (filerr != FILERR_NONE)
else
{
mame_fclose(*file);
*file = NULL;
@ -388,6 +393,21 @@ void mame_fclose(mame_file *file)
}
/*-------------------------------------------------
mame_fclose_and_open_next - close an open
file, and open the next entry in the original
searchpath
-------------------------------------------------*/
file_error mame_fclose_and_open_next(mame_file **file, const char *filename, UINT32 openflags)
{
path_iterator iterator = (*file)->iterator;
mame_fclose(*file);
*file = NULL;
return fopen_internal(mame_options(), &iterator, filename, 0, openflags, file);
}
/*-------------------------------------------------
mame_fcompress - enable/disable streaming file
compression via zlib; level is 0 to disable
@ -803,7 +823,7 @@ static void path_iterator_init(path_iterator *iterator, core_options *opts, cons
{
/* reset the structure */
memset(iterator, 0, sizeof(*iterator));
iterator->base = (searchpath != NULL) ? options_get_string(opts, searchpath) : "";
iterator->base = (searchpath != NULL && !osd_is_absolute_path(searchpath)) ? options_get_string(opts, searchpath) : "";
iterator->cur = iterator->base;
}

View File

@ -99,6 +99,9 @@ file_error mame_fopen_ram(const void *data, UINT32 length, UINT32 openflags, mam
/* close an open file */
void mame_fclose(mame_file *file);
/* close an open file, and open the next entry in the original searchpath*/
file_error mame_fclose_and_open_next(mame_file **file, const char *filename, UINT32 openflags);
/* enable/disable streaming file compression via zlib; level is 0 to disable compression, or up to 9 for max compression */
file_error mame_fcompress(mame_file *file, int compress);