mirror of
https://github.com/holub/mame
synced 2025-05-17 19:24:59 +03:00
hashfile moved from MESS to emu section (needed for now in image support until softlist implementation is finished), this doesn't affect mame side (no whatsnew)
This commit is contained in:
parent
861db1eb49
commit
d2a7b5f332
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -604,6 +604,8 @@ src/emu/fileio.c svneol=native#text/plain
|
|||||||
src/emu/fileio.h svneol=native#text/plain
|
src/emu/fileio.h svneol=native#text/plain
|
||||||
src/emu/hash.c svneol=native#text/plain
|
src/emu/hash.c svneol=native#text/plain
|
||||||
src/emu/hash.h svneol=native#text/plain
|
src/emu/hash.h svneol=native#text/plain
|
||||||
|
src/emu/hashfile.c svneol=native#text/plain
|
||||||
|
src/emu/hashfile.h svneol=native#text/plain
|
||||||
src/emu/info.c svneol=native#text/plain
|
src/emu/info.c svneol=native#text/plain
|
||||||
src/emu/info.h svneol=native#text/plain
|
src/emu/info.h svneol=native#text/plain
|
||||||
src/emu/inptport.c svneol=native#text/plain
|
src/emu/inptport.c svneol=native#text/plain
|
||||||
|
@ -63,6 +63,7 @@ EMUOBJS = \
|
|||||||
$(EMUOBJ)/emupal.o \
|
$(EMUOBJ)/emupal.o \
|
||||||
$(EMUOBJ)/fileio.o \
|
$(EMUOBJ)/fileio.o \
|
||||||
$(EMUOBJ)/hash.o \
|
$(EMUOBJ)/hash.o \
|
||||||
|
$(EMUOBJ)/hashfile.o \
|
||||||
$(EMUOBJ)/info.o \
|
$(EMUOBJ)/info.o \
|
||||||
$(EMUOBJ)/input.o \
|
$(EMUOBJ)/input.o \
|
||||||
$(EMUOBJ)/inputseq.o \
|
$(EMUOBJ)/inputseq.o \
|
||||||
|
591
src/emu/hashfile.c
Normal file
591
src/emu/hashfile.c
Normal file
@ -0,0 +1,591 @@
|
|||||||
|
/*********************************************************************
|
||||||
|
|
||||||
|
hashfile.c
|
||||||
|
|
||||||
|
Code for parsing hash info (*.hsi) files
|
||||||
|
|
||||||
|
*********************************************************************/
|
||||||
|
|
||||||
|
#include "hashfile.h"
|
||||||
|
#include "pool.h"
|
||||||
|
#include "expat.h"
|
||||||
|
#include "emuopts.h"
|
||||||
|
/***************************************************************************
|
||||||
|
TYPE DEFINITIONS
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
struct _hash_file
|
||||||
|
{
|
||||||
|
mame_file *file;
|
||||||
|
object_pool *pool;
|
||||||
|
unsigned int functions[IO_COUNT];
|
||||||
|
|
||||||
|
hash_info **preloaded_hashes;
|
||||||
|
int preloaded_hash_count;
|
||||||
|
|
||||||
|
void (*error_proc)(const char *message);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
enum hash_parse_position
|
||||||
|
{
|
||||||
|
POS_ROOT,
|
||||||
|
POS_MAIN,
|
||||||
|
POS_HASH
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct hash_parse_state
|
||||||
|
{
|
||||||
|
XML_Parser parser;
|
||||||
|
hash_file *hashfile;
|
||||||
|
int done;
|
||||||
|
|
||||||
|
int (*selector_proc)(hash_file *hashfile, void *param, const char *name, const char *hash);
|
||||||
|
void (*use_proc)(hash_file *hashfile, void *param, hash_info *hi);
|
||||||
|
void (*error_proc)(const char *message);
|
||||||
|
void *param;
|
||||||
|
|
||||||
|
enum hash_parse_position pos;
|
||||||
|
char **text_dest;
|
||||||
|
hash_info *hi;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
PROTOTYPES
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
static void *expat_malloc(size_t size);
|
||||||
|
static void *expat_realloc(void *ptr, size_t size);
|
||||||
|
static void expat_free(void *ptr);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
CORE IMPLEMENTATION
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
parse_error
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
static void ATTR_PRINTF(2,3) parse_error(struct hash_parse_state *state, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
char buf[256];
|
||||||
|
va_list va;
|
||||||
|
|
||||||
|
if (state->error_proc)
|
||||||
|
{
|
||||||
|
va_start(va, fmt);
|
||||||
|
vsnprintf(buf, ARRAY_LENGTH(buf), fmt, va);
|
||||||
|
va_end(va);
|
||||||
|
(*state->error_proc)(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
unknown_tag
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
static void unknown_tag(struct hash_parse_state *state, const char *tagname)
|
||||||
|
{
|
||||||
|
parse_error(state, "[%lu:%lu]: Unknown tag: %s\n",
|
||||||
|
XML_GetCurrentLineNumber(state->parser),
|
||||||
|
XML_GetCurrentColumnNumber(state->parser),
|
||||||
|
tagname);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
unknown_attribute
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
static void unknown_attribute(struct hash_parse_state *state, const char *attrname)
|
||||||
|
{
|
||||||
|
parse_error(state, "[%lu:%lu]: Unknown attribute: %s\n",
|
||||||
|
XML_GetCurrentLineNumber(state->parser),
|
||||||
|
XML_GetCurrentColumnNumber(state->parser),
|
||||||
|
attrname);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
unknown_attribute_value
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
static void unknown_attribute_value(struct hash_parse_state *state,
|
||||||
|
const char *attrname, const char *attrvalue)
|
||||||
|
{
|
||||||
|
parse_error(state, "[%lu:%lu]: Unknown attribute value: %s\n",
|
||||||
|
XML_GetCurrentLineNumber(state->parser),
|
||||||
|
XML_GetCurrentColumnNumber(state->parser),
|
||||||
|
attrvalue);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
start_handler
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
static void start_handler(void *data, const char *tagname, const char **attributes)
|
||||||
|
{
|
||||||
|
struct hash_parse_state *state = (struct hash_parse_state *) data;
|
||||||
|
const char *name;
|
||||||
|
hash_info *hi;
|
||||||
|
char **text_dest;
|
||||||
|
char hash_string[HASH_BUF_SIZE];
|
||||||
|
unsigned int functions, all_functions;
|
||||||
|
iodevice_t device;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
switch(state->pos)
|
||||||
|
{
|
||||||
|
case POS_ROOT:
|
||||||
|
if (!strcmp(tagname, "hashfile"))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unknown_tag(state, tagname);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case POS_MAIN:
|
||||||
|
if (!strcmp(tagname, "hash"))
|
||||||
|
{
|
||||||
|
// we are now examining a hash tag
|
||||||
|
name = NULL;
|
||||||
|
memset(hash_string, 0, sizeof(hash_string));
|
||||||
|
all_functions = 0;
|
||||||
|
device = IO_COUNT;
|
||||||
|
|
||||||
|
while(attributes[0])
|
||||||
|
{
|
||||||
|
functions = 0;
|
||||||
|
if (!strcmp(attributes[0], "name"))
|
||||||
|
{
|
||||||
|
/* name attribute */
|
||||||
|
name = attributes[1];
|
||||||
|
}
|
||||||
|
else if (!strcmp(attributes[0], "crc32"))
|
||||||
|
{
|
||||||
|
/* crc32 attribute */
|
||||||
|
functions = HASH_CRC;
|
||||||
|
}
|
||||||
|
else if (!strcmp(attributes[0], "md5"))
|
||||||
|
{
|
||||||
|
/* md5 attribute */
|
||||||
|
functions = HASH_MD5;
|
||||||
|
}
|
||||||
|
else if (!strcmp(attributes[0], "sha1"))
|
||||||
|
{
|
||||||
|
/* sha1 attribute */
|
||||||
|
functions = HASH_SHA1;
|
||||||
|
}
|
||||||
|
else if (!strcmp(attributes[0], "type"))
|
||||||
|
{
|
||||||
|
/* type attribute */
|
||||||
|
i = 0;//device_typeid(attributes[1]);
|
||||||
|
if (i < 0)
|
||||||
|
unknown_attribute_value(state, attributes[0], attributes[1]);
|
||||||
|
else
|
||||||
|
device = (iodevice_t) i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* unknown attribute */
|
||||||
|
unknown_attribute(state, attributes[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (functions)
|
||||||
|
{
|
||||||
|
hash_data_insert_printable_checksum(hash_string, functions, attributes[1]);
|
||||||
|
all_functions |= functions;
|
||||||
|
}
|
||||||
|
|
||||||
|
attributes += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device == IO_COUNT)
|
||||||
|
{
|
||||||
|
for (i = 0; i < IO_COUNT; i++)
|
||||||
|
state->hashfile->functions[i] |= all_functions;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
state->hashfile->functions[device] |= all_functions;
|
||||||
|
|
||||||
|
/* do we use this hash? */
|
||||||
|
if (!state->selector_proc || state->selector_proc(state->hashfile, state->param, name, hash_string))
|
||||||
|
{
|
||||||
|
hi = (hash_info*)pool_malloc_lib(state->hashfile->pool, sizeof(hash_info));
|
||||||
|
if (!hi)
|
||||||
|
return;
|
||||||
|
memset(hi, 0, sizeof(*hi));
|
||||||
|
|
||||||
|
hi->longname = pool_strdup_lib(state->hashfile->pool, name);
|
||||||
|
if (!hi->longname)
|
||||||
|
return;
|
||||||
|
|
||||||
|
strcpy(hi->hash, hash_string);
|
||||||
|
state->hi = hi;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unknown_tag(state, tagname);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case POS_HASH:
|
||||||
|
text_dest = NULL;
|
||||||
|
|
||||||
|
if (!strcmp(tagname, "year"))
|
||||||
|
text_dest = (char **) &state->hi->year;
|
||||||
|
else if (!strcmp(tagname, "manufacturer"))
|
||||||
|
text_dest = (char **) &state->hi->manufacturer;
|
||||||
|
else if (!strcmp(tagname, "status"))
|
||||||
|
text_dest = (char **) &state->hi->playable;
|
||||||
|
else if (!strcmp(tagname, "pcb"))
|
||||||
|
text_dest = (char **) &state->hi->pcb;
|
||||||
|
else if (!strcmp(tagname, "extrainfo"))
|
||||||
|
text_dest = (char **) &state->hi->extrainfo;
|
||||||
|
else
|
||||||
|
unknown_tag(state, tagname);
|
||||||
|
|
||||||
|
if (text_dest && state->hi)
|
||||||
|
state->text_dest = text_dest;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
state->pos = (hash_parse_position) (state->pos + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
end_handler
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
static void end_handler(void *data, const char *name)
|
||||||
|
{
|
||||||
|
struct hash_parse_state *state = (struct hash_parse_state *) data;
|
||||||
|
state->text_dest = NULL;
|
||||||
|
|
||||||
|
state->pos = (hash_parse_position) (state->pos - 1);
|
||||||
|
switch(state->pos)
|
||||||
|
{
|
||||||
|
case POS_ROOT:
|
||||||
|
case POS_HASH:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case POS_MAIN:
|
||||||
|
if (state->hi)
|
||||||
|
{
|
||||||
|
if (state->use_proc)
|
||||||
|
(*state->use_proc)(state->hashfile, state->param, state->hi);
|
||||||
|
state->hi = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
data_handler
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
static void data_handler(void *data, const XML_Char *s, int len)
|
||||||
|
{
|
||||||
|
struct hash_parse_state *state = (struct hash_parse_state *) data;
|
||||||
|
int text_len;
|
||||||
|
char *text;
|
||||||
|
|
||||||
|
if (state->text_dest)
|
||||||
|
{
|
||||||
|
text = *state->text_dest;
|
||||||
|
|
||||||
|
text_len = text ? strlen(text) : 0;
|
||||||
|
text = (char*)pool_realloc_lib(state->hashfile->pool, text, text_len + len + 1);
|
||||||
|
if (!text)
|
||||||
|
return;
|
||||||
|
|
||||||
|
memcpy(&text[text_len], s, len);
|
||||||
|
text[text_len + len] = '\0';
|
||||||
|
*state->text_dest = text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
hashfile_parse
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
static void hashfile_parse(hash_file *hashfile,
|
||||||
|
int (*selector_proc)(hash_file *hashfile, void *param, const char *name, const char *hash),
|
||||||
|
void (*use_proc)(hash_file *hashfile, void *param, hash_info *hi),
|
||||||
|
void (*error_proc)(const char *message),
|
||||||
|
void *param)
|
||||||
|
{
|
||||||
|
struct hash_parse_state state;
|
||||||
|
char buf[1024];
|
||||||
|
UINT32 len;
|
||||||
|
XML_Memory_Handling_Suite memcallbacks;
|
||||||
|
|
||||||
|
mame_fseek(hashfile->file, 0, SEEK_SET);
|
||||||
|
|
||||||
|
memset(&state, 0, sizeof(state));
|
||||||
|
state.hashfile = hashfile;
|
||||||
|
state.selector_proc = selector_proc;
|
||||||
|
state.use_proc = use_proc;
|
||||||
|
state.error_proc = error_proc;
|
||||||
|
state.param = param;
|
||||||
|
|
||||||
|
/* create the XML parser */
|
||||||
|
memcallbacks.malloc_fcn = expat_malloc;
|
||||||
|
memcallbacks.realloc_fcn = expat_realloc;
|
||||||
|
memcallbacks.free_fcn = expat_free;
|
||||||
|
state.parser = XML_ParserCreate_MM(NULL, &memcallbacks, NULL);
|
||||||
|
if (!state.parser)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
XML_SetUserData(state.parser, &state);
|
||||||
|
XML_SetElementHandler(state.parser, start_handler, end_handler);
|
||||||
|
XML_SetCharacterDataHandler(state.parser, data_handler);
|
||||||
|
|
||||||
|
while(!state.done)
|
||||||
|
{
|
||||||
|
len = mame_fread(hashfile->file, buf, sizeof(buf));
|
||||||
|
state.done = mame_feof(hashfile->file);
|
||||||
|
if (XML_Parse(state.parser, buf, len, state.done) == XML_STATUS_ERROR)
|
||||||
|
{
|
||||||
|
parse_error(&state, "[%lu:%lu]: %s\n",
|
||||||
|
XML_GetCurrentLineNumber(state.parser),
|
||||||
|
XML_GetCurrentColumnNumber(state.parser),
|
||||||
|
XML_ErrorString(XML_GetErrorCode(state.parser)));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (state.parser)
|
||||||
|
XML_ParserFree(state.parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
preload_use_proc
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
static void preload_use_proc(hash_file *hashfile, void *param, hash_info *hi)
|
||||||
|
{
|
||||||
|
hash_info **new_preloaded_hashes;
|
||||||
|
|
||||||
|
new_preloaded_hashes = (hash_info **)pool_realloc_lib(hashfile->pool, hashfile->preloaded_hashes,
|
||||||
|
(hashfile->preloaded_hash_count + 1) * sizeof(*new_preloaded_hashes));
|
||||||
|
if (!new_preloaded_hashes)
|
||||||
|
return;
|
||||||
|
|
||||||
|
hashfile->preloaded_hashes = new_preloaded_hashes;
|
||||||
|
hashfile->preloaded_hashes[hashfile->preloaded_hash_count++] = hi;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
hashfile_open_options
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
hash_file *hashfile_open_options(core_options *opts, const char *sysname, int is_preload,
|
||||||
|
void (*error_proc)(const char *message))
|
||||||
|
{
|
||||||
|
file_error filerr;
|
||||||
|
astring *fname;
|
||||||
|
hash_file *hashfile = NULL;
|
||||||
|
object_pool *pool = NULL;
|
||||||
|
|
||||||
|
/* create a pool for this hash file */
|
||||||
|
pool = pool_alloc_lib(error_proc);
|
||||||
|
if (!pool)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
/* allocate space for this hash file */
|
||||||
|
hashfile = (hash_file *) pool_malloc_lib(pool, sizeof(*hashfile));
|
||||||
|
if (!hashfile)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
/* set up the hashfile structure */
|
||||||
|
memset(hashfile, 0, sizeof(*hashfile));
|
||||||
|
hashfile->pool = pool;
|
||||||
|
hashfile->error_proc = error_proc;
|
||||||
|
|
||||||
|
/* open a file */
|
||||||
|
fname = astring_assemble_2(astring_alloc(), sysname, ".hsi");
|
||||||
|
filerr = mame_fopen_options(opts, SEARCHPATH_HASH, astring_c(fname), OPEN_FLAG_READ, &hashfile->file);
|
||||||
|
astring_free(fname);
|
||||||
|
|
||||||
|
if (filerr != FILERR_NONE)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (is_preload)
|
||||||
|
hashfile_parse(hashfile, NULL, preload_use_proc, hashfile->error_proc, NULL);
|
||||||
|
|
||||||
|
return hashfile;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (hashfile != NULL)
|
||||||
|
hashfile_close(hashfile);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
hashfile_open
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
hash_file *hashfile_open(const char *sysname, int is_preload,
|
||||||
|
void (*error_proc)(const char *message))
|
||||||
|
{
|
||||||
|
return hashfile_open_options(mame_options(), sysname, is_preload, error_proc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
hashfile_close
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
void hashfile_close(hash_file *hashfile)
|
||||||
|
{
|
||||||
|
if (hashfile->file)
|
||||||
|
mame_fclose(hashfile->file);
|
||||||
|
pool_free_lib(hashfile->pool);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
singular_selector_proc
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
struct hashlookup_params
|
||||||
|
{
|
||||||
|
const char *hash;
|
||||||
|
hash_info *hi;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int singular_selector_proc(hash_file *hashfile, void *param, const char *name, const char *hash)
|
||||||
|
{
|
||||||
|
struct hashlookup_params *hlparams = (struct hashlookup_params *) param;
|
||||||
|
return hash_data_is_equal(hash, hlparams->hash,
|
||||||
|
hash_data_used_functions(hash)) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
singular_use_proc
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
static void singular_use_proc(hash_file *hashfile, void *param, hash_info *hi)
|
||||||
|
{
|
||||||
|
struct hashlookup_params *hlparams = (struct hashlookup_params *) param;
|
||||||
|
hlparams->hi = hi;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
hashfile_lookup
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
const hash_info *hashfile_lookup(hash_file *hashfile, const char *hash)
|
||||||
|
{
|
||||||
|
struct hashlookup_params param;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
param.hash = hash;
|
||||||
|
param.hi = NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < hashfile->preloaded_hash_count; i++)
|
||||||
|
{
|
||||||
|
if (singular_selector_proc(hashfile, ¶m, NULL, hashfile->preloaded_hashes[i]->hash))
|
||||||
|
return hashfile->preloaded_hashes[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
hashfile_parse(hashfile, singular_selector_proc, singular_use_proc,
|
||||||
|
hashfile->error_proc, (void *) ¶m);
|
||||||
|
return param.hi;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
hashfile_functions_used
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
unsigned int hashfile_functions_used(hash_file *hashfile, iodevice_t devtype)
|
||||||
|
{
|
||||||
|
assert(devtype >= 0);
|
||||||
|
assert(devtype < IO_COUNT);
|
||||||
|
return hashfile->functions[devtype];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
hashfile_verify
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
int hashfile_verify(const char *sysname, void (*my_error_proc)(const char *message))
|
||||||
|
{
|
||||||
|
hash_file *hashfile;
|
||||||
|
|
||||||
|
hashfile = hashfile_open(sysname, FALSE, my_error_proc);
|
||||||
|
if (!hashfile)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
hashfile_parse(hashfile, NULL, NULL, my_error_proc, NULL);
|
||||||
|
hashfile_close(hashfile);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
EXPAT INTERFACES
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
expat_malloc/expat_realloc/expat_free -
|
||||||
|
wrappers for memory allocation functions so
|
||||||
|
that they pass through out memory tracking
|
||||||
|
systems
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
static void *expat_malloc(size_t size)
|
||||||
|
{
|
||||||
|
return global_alloc_array_clear(UINT8,size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *expat_realloc(void *ptr, size_t size)
|
||||||
|
{
|
||||||
|
if (ptr) global_free(ptr);
|
||||||
|
return global_alloc_array_clear(UINT8,size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void expat_free(void *ptr)
|
||||||
|
{
|
||||||
|
global_free(ptr);
|
||||||
|
}
|
62
src/emu/hashfile.h
Normal file
62
src/emu/hashfile.h
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/*********************************************************************
|
||||||
|
|
||||||
|
hashfile.h
|
||||||
|
|
||||||
|
Code for parsing hash info (*.hsi) files
|
||||||
|
|
||||||
|
*********************************************************************/
|
||||||
|
|
||||||
|
#ifndef __HASHFILE_H__
|
||||||
|
#define __HASHFILE_H__
|
||||||
|
|
||||||
|
#include "emu.h"
|
||||||
|
#include "hash.h"
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
TYPE DEFINITIONS
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
typedef struct _hash_info hash_info;
|
||||||
|
struct _hash_info
|
||||||
|
{
|
||||||
|
char hash[HASH_BUF_SIZE];
|
||||||
|
const char *longname;
|
||||||
|
const char *manufacturer;
|
||||||
|
const char *year;
|
||||||
|
const char *playable;
|
||||||
|
const char *pcb;
|
||||||
|
const char *extrainfo;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _hash_file hash_file;
|
||||||
|
|
||||||
|
typedef void (*hashfile_error_func)(const char *message);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
FUNCTION PROTOTYPES
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/* opens a hash file; if is_preload is non-zero, the entire file is preloaded */
|
||||||
|
hash_file *hashfile_open(const char *sysname, int is_preload, hashfile_error_func error_proc);
|
||||||
|
|
||||||
|
/* opens a hash file; if is_preload is non-zero, the entire file is preloaded */
|
||||||
|
hash_file *hashfile_open_options(core_options *opts, const char *sysname, int is_preload,
|
||||||
|
hashfile_error_func error_proc);
|
||||||
|
|
||||||
|
/* closes a hash file and associated resources */
|
||||||
|
void hashfile_close(hash_file *hashfile);
|
||||||
|
|
||||||
|
/* looks up information in a hash file */
|
||||||
|
const hash_info *hashfile_lookup(hash_file *hashfile, const char *hash);
|
||||||
|
|
||||||
|
/* performs a syntax check on a hash file */
|
||||||
|
int hashfile_verify(const char *sysname, void (*error_proc)(const char *message));
|
||||||
|
|
||||||
|
/* returns the functions used in this hash file */
|
||||||
|
unsigned int hashfile_functions_used(hash_file *hashfile, iodevice_t devtype);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __HASHFILE_H__ */
|
Loading…
Reference in New Issue
Block a user