MRA: lookup rom parts by CRC first if "crc" attribute exists
MRA: supported ordered list "zip" attribute, (use '|' as delimiter)
This commit is contained in:
98
file_io.cpp
98
file_io.cpp
@@ -235,6 +235,104 @@ void FileClose(fileTYPE *file)
|
||||
file->filp = nullptr;
|
||||
}
|
||||
|
||||
|
||||
int zip_search_by_crc(mz_zip_archive *zipArchive, uint32_t crc32)
|
||||
{
|
||||
|
||||
for (unsigned int file_index = 0; file_index < zipArchive->m_total_files; file_index++)
|
||||
{
|
||||
mz_zip_archive_file_stat s;
|
||||
if (mz_zip_reader_file_stat(zipArchive, file_index, &s))
|
||||
{
|
||||
if (s.m_crc32 == crc32)
|
||||
{
|
||||
return file_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int FileOpenZip(fileTYPE *file, const char *name, uint32_t crc32, int mode, char mute)
|
||||
{
|
||||
make_fullpath((char*)name, mode);
|
||||
FileClose(file);
|
||||
file->mode = 0;
|
||||
file->type = 0;
|
||||
|
||||
char *p = strrchr(full_path, '/');
|
||||
strcpy(file->name, (mode == -1) ? full_path : p + 1);
|
||||
|
||||
char *zip_path, *file_path;
|
||||
if ((mode != -1) && FileIsZipped(full_path, &zip_path, &file_path))
|
||||
{
|
||||
if (mode & O_RDWR || mode & O_WRONLY)
|
||||
{
|
||||
if(!mute) printf("FileOpenZip(mode) Zip:%s, writing to zipped files is not supported.\n",
|
||||
full_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
file->zip = new fileZipArchive{};
|
||||
if (!mz_zip_reader_init_file(&file->zip->archive, zip_path, 0))
|
||||
{
|
||||
if(!mute) printf("FileOpenZip(mz_zip_reader_init_file) Zip:%s, error:%s\n", zip_path,
|
||||
mz_zip_get_error_string(mz_zip_get_last_error(&file->zip->archive)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (crc32)
|
||||
{
|
||||
file->zip->index = zip_search_by_crc(&file->zip->archive, crc32);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (file->zip->index < 0 || !crc32)
|
||||
{
|
||||
file->zip->index = mz_zip_reader_locate_file(&file->zip->archive, file_path, NULL, 0);
|
||||
}
|
||||
|
||||
if (file->zip->index < 0)
|
||||
{
|
||||
if(!mute) printf("FileOpenZip(mz_zip_reader_locate_file) Zip:%s, file:%s, error: %s\n",
|
||||
zip_path, file_path,
|
||||
mz_zip_get_error_string(mz_zip_get_last_error(&file->zip->archive)));
|
||||
FileClose(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
mz_zip_archive_file_stat s;
|
||||
if (!mz_zip_reader_file_stat(&file->zip->archive, file->zip->index, &s))
|
||||
{
|
||||
if(!mute) printf("FileOpenZip(mz_zip_reader_file_stat) Zip:%s, file:%s, error:%s\n",
|
||||
zip_path, file_path,
|
||||
mz_zip_get_error_string(mz_zip_get_last_error(&file->zip->archive)));
|
||||
FileClose(file);
|
||||
return 0;
|
||||
}
|
||||
file->size = s.m_uncomp_size;
|
||||
|
||||
file->zip->iter = mz_zip_reader_extract_iter_new(&file->zip->archive, file->zip->index, 0);
|
||||
if (!file->zip->iter)
|
||||
{
|
||||
if(!mute) printf("FileOpenZip(mz_zip_reader_extract_iter_new) Zip:%s, file:%s, error:%s\n",
|
||||
zip_path, file_path,
|
||||
mz_zip_get_error_string(mz_zip_get_last_error(&file->zip->archive)));
|
||||
FileClose(file);
|
||||
return 0;
|
||||
}
|
||||
file->zip->offset = 0;
|
||||
file->offset = 0;
|
||||
file->mode = mode;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int FileOpenEx(fileTYPE *file, const char *name, int mode, char mute)
|
||||
{
|
||||
make_fullpath((char*)name, mode);
|
||||
|
||||
@@ -59,6 +59,7 @@ int getStorage(int from_setting);
|
||||
void setStorage(int dev);
|
||||
int isUSBMounted();
|
||||
|
||||
int FileOpenZip(fileTYPE *file, const char *name, uint32_t crc32, int mode, char mute = 0);
|
||||
int FileOpenEx(fileTYPE *file, const char *name, int mode, char mute = 0);
|
||||
int FileOpen(fileTYPE *file, const char *name, char mute = 0);
|
||||
void FileClose(fileTYPE *file);
|
||||
|
||||
@@ -31,6 +31,7 @@ struct arc_struct {
|
||||
int patchaddr;
|
||||
int validrom0;
|
||||
int insidesw;
|
||||
uint32_t crc;
|
||||
buffer_data *data;
|
||||
struct MD5Context context;
|
||||
};
|
||||
@@ -156,12 +157,12 @@ static int file_data(const uint8_t *buf, uint16_t chunk, struct MD5Context *md5c
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int file_file(const char *name, int start, int len, struct MD5Context *md5context)
|
||||
static int file_file(const char *name, uint32_t crc32, int start, int len, struct MD5Context *md5context)
|
||||
{
|
||||
char mute = 0;
|
||||
fileTYPE f = {};
|
||||
static uint8_t buf[4096];
|
||||
if (!FileOpen(&f, name, mute)) return 0;
|
||||
if (!FileOpenZip(&f, name, crc32, mute)) return 0;
|
||||
if (start) FileSeek(&f, start, SEEK_SET);
|
||||
unsigned long bytes2send = f.size;
|
||||
if (len > 0 && len < (int)bytes2send) bytes2send = len;
|
||||
@@ -310,6 +311,7 @@ static int xml_send_rom(XMLEvent evt, const XMLNode* node, SXML_CHAR* text, cons
|
||||
arc_info->offset = 0;
|
||||
arc_info->length = -1;
|
||||
arc_info->repeat = 1;
|
||||
arc_info->crc = 0;
|
||||
|
||||
/* on the beginning of a rom tag, we need to reset the state*/
|
||||
if (!strcasecmp(node->tag, "rom"))
|
||||
@@ -381,6 +383,10 @@ static int xml_send_rom(XMLEvent evt, const XMLNode* node, SXML_CHAR* text, cons
|
||||
{
|
||||
arc_info->repeat = atoi(node->attributes[i].value);
|
||||
}
|
||||
if (!strcasecmp(node->attributes[i].name, "crc") && !strcasecmp(node->tag, "part"))
|
||||
{
|
||||
arc_info->crc = (uint32_t)strtoul(node->attributes[i].value, NULL, 16);
|
||||
}
|
||||
if (!strcasecmp(node->attributes[i].name, "offset") && !strcasecmp(node->tag, "patch"))
|
||||
{
|
||||
arc_info->patchaddr = strtoul(node->attributes[i].value, NULL, 0);
|
||||
@@ -553,8 +559,10 @@ static int xml_send_rom(XMLEvent evt, const XMLNode* node, SXML_CHAR* text, cons
|
||||
if (arc_info->romindex == 0 && arc_info->validrom0 == 1) break;
|
||||
char fname[kBigTextSize * 2 + 16];
|
||||
int start, length, repeat;
|
||||
uint32_t crc32;
|
||||
repeat = arc_info->repeat;
|
||||
start = arc_info->offset;
|
||||
crc32 = arc_info->crc;
|
||||
length = 0;
|
||||
if (arc_info->length > 0) length = arc_info->length;
|
||||
//printf("partname[%s]\n",arc_info->partname);
|
||||
@@ -567,21 +575,44 @@ static int xml_send_rom(XMLEvent evt, const XMLNode* node, SXML_CHAR* text, cons
|
||||
//user_io_file_tx_body_filepart(getFullPath(fname),0,0);
|
||||
if (strlen(arc_info->partname))
|
||||
{
|
||||
char *zipname = (strlen(arc_info->partzipname)) ? arc_info->partzipname : arc_info->zipname;
|
||||
const char *root = get_arcade_root(0);
|
||||
sprintf(fname, (zipname[0] == '/') ? "%s%s/%s" : "%s/mame/%s/%s", root, zipname, arc_info->partname);
|
||||
char zipnames_list[kBigTextSize];
|
||||
|
||||
printf("file: %s, start=%d, len=%d\n", fname, start, length);
|
||||
for (int i = 0; i < repeat; i++)
|
||||
if (strlen(arc_info->partzipname))
|
||||
{
|
||||
int result = file_file(fname, start, length, &arc_info->context);
|
||||
strcpy(zipnames_list, arc_info->partzipname);
|
||||
} else {
|
||||
strcpy(zipnames_list, arc_info->zipname);
|
||||
}
|
||||
|
||||
char *zipname = NULL;
|
||||
char *zipptr = zipnames_list;
|
||||
const char *root = get_arcade_root(0);
|
||||
int result = 0;
|
||||
while ((zipname = strsep(&zipptr, "|")) != NULL)
|
||||
{
|
||||
sprintf(fname, (zipname[0] == '/') ? "%s%s/%s" : "%s/mame/%s/%s", root, zipname, arc_info->partname);
|
||||
|
||||
// we should check file not found error for the zip
|
||||
if (result == 0)
|
||||
printf("file: %s, start=%d, len=%d\n", fname, start, length);
|
||||
for (int i = 0; i < repeat; i++)
|
||||
{
|
||||
printf("%s does not exist\n", fname);
|
||||
snprintf(arc_info->error_msg, kBigTextSize, "%s\nFile Not Found", fname + strlen(root));
|
||||
result = file_file(fname, crc32, start, length, &arc_info->context);
|
||||
|
||||
// we should check file not found error for the zip
|
||||
if (result == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (result == 0)
|
||||
{
|
||||
printf("%s does not exist\n", arc_info->partname);
|
||||
snprintf(arc_info->error_msg, kBigTextSize, "%s\nFile Not Found", arc_info->partname);
|
||||
}
|
||||
}
|
||||
else // we have binary data?
|
||||
|
||||
Reference in New Issue
Block a user