mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-12-26 11:11:48 +01:00
.fixed potential memory issue when loading CD game after a large ROM file
.added support for upper-case ROM file extensions .modified load_archive behavior so that it does not overwrite original filename with uncompressed name anymore .replaced use of strcmp by memcmp
This commit is contained in:
parent
2b8656c27f
commit
47040dbba6
@ -348,7 +348,7 @@ void gen_tmss_w(unsigned int offset, unsigned int data)
|
||||
WRITE_WORD(tmss, offset, data);
|
||||
|
||||
/* VDP requires "SEGA" value to be written in TMSS register */
|
||||
if (strncmp((char *)tmss, "SEGA", 4) == 0)
|
||||
if (memcmp((char *)tmss, "SEGA", 4) == 0)
|
||||
{
|
||||
for (i=0xc0; i<0xe0; i+=8)
|
||||
{
|
||||
|
@ -61,7 +61,7 @@ static int config_load(void)
|
||||
char version[16];
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
fread(version, 16, 1, fp);
|
||||
if (strncmp(version,CONFIG_VERSION,16))
|
||||
if (memcmp(version,CONFIG_VERSION,16))
|
||||
{
|
||||
fclose(fp);
|
||||
return 0;
|
||||
|
@ -83,37 +83,7 @@ static inline u16 FLIP16 (u16 b)
|
||||
return c;
|
||||
}
|
||||
|
||||
void get_zipfilename(char *filename)
|
||||
{
|
||||
char in[CHUNKSIZE];
|
||||
|
||||
/* Open file */
|
||||
FILE *fd = fopen(filename, "rb");
|
||||
if (!fd) return;
|
||||
|
||||
/* Read first 2 bytes */
|
||||
fread(in, 2, 1, fd);
|
||||
|
||||
/* Detect Zip file */
|
||||
if (memcmp(in, "PK", 2) == 0)
|
||||
{
|
||||
/* Read remaining header data */
|
||||
fread(in + 2, sizeof(PKZIPHEADER) - 2, 1, fd);
|
||||
|
||||
/* Zip header pointer */
|
||||
PKZIPHEADER *pkzip = (PKZIPHEADER *) in;
|
||||
|
||||
/* Return compressed file name */
|
||||
int len = FLIP16(pkzip->filenameLength);
|
||||
if (len >= MAXPATHLEN) len = MAXPATHLEN - 1;
|
||||
fread(filename, len, 1, fd);
|
||||
filename[len] = 0;
|
||||
}
|
||||
|
||||
fclose(fd);
|
||||
}
|
||||
|
||||
int load_archive(char *filename, unsigned char *buffer, int maxsize)
|
||||
int load_archive(char *filename, unsigned char *buffer, int maxsize, char *extension)
|
||||
{
|
||||
int size = 0;
|
||||
char in[CHUNKSIZE];
|
||||
@ -132,7 +102,7 @@ int load_archive(char *filename, unsigned char *buffer, int maxsize)
|
||||
/* Mega CD BIOS are required files */
|
||||
if (!strcmp(filename,CD_BIOS_US) || !strcmp(filename,CD_BIOS_EU) || !strcmp(filename,CD_BIOS_JP))
|
||||
{
|
||||
sprintf(msg,"Unable to open CD BIOS");
|
||||
sprintf(msg,"Unable to open %s", filename + 14);
|
||||
}
|
||||
|
||||
if (!fd)
|
||||
@ -187,19 +157,23 @@ int load_archive(char *filename, unsigned char *buffer, int maxsize)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Compressed filename offset */
|
||||
int offset = sizeof (PKZIPHEADER) + FLIP16(pkzip->filenameLength);
|
||||
|
||||
if (extension)
|
||||
{
|
||||
memcpy(extension, &in[offset - 3], 3);
|
||||
extension[3] = 0;
|
||||
}
|
||||
|
||||
|
||||
/* Initial Zip buffer offset */
|
||||
int offset = sizeof (PKZIPHEADER) + FLIP16(pkzip->filenameLength) + FLIP16(pkzip->extraDataLength);
|
||||
offset += FLIP16(pkzip->extraDataLength);
|
||||
zs.next_in = (Bytef *)&in[offset];
|
||||
|
||||
/* Initial Zip remaining chunk size */
|
||||
zs.avail_in = CHUNKSIZE - offset;
|
||||
|
||||
/* Overwrite input filename with compressed filename */
|
||||
offset = FLIP16(pkzip->filenameLength);
|
||||
if (offset >= MAXPATHLEN) offset = MAXPATHLEN - 1;
|
||||
strncpy(filename, &in[sizeof(PKZIPHEADER)], offset);
|
||||
filename[offset] = 0;
|
||||
|
||||
/* Start unzipping file */
|
||||
do
|
||||
{
|
||||
@ -255,6 +229,13 @@ int load_archive(char *filename, unsigned char *buffer, int maxsize)
|
||||
sprintf((char *)msg,"Loading %d bytes ...", size);
|
||||
GUI_MsgBoxOpen("Information", (char *)msg, 1);
|
||||
|
||||
/* filename extension */
|
||||
if (extension)
|
||||
{
|
||||
memcpy(extension, &filename[strlen(filename) - 3], 3);
|
||||
extension[3] = 0;
|
||||
}
|
||||
|
||||
/* Read into buffer */
|
||||
int left = size;
|
||||
while (left > CHUNKSIZE)
|
||||
|
@ -42,6 +42,6 @@
|
||||
#define _FILEIO_H_
|
||||
|
||||
/* Function prototypes */
|
||||
int load_archive(char *filename, unsigned char *buffer, int maxsize);
|
||||
int load_archive(char *filename, unsigned char *buffer, int maxsize, char *extension);
|
||||
|
||||
#endif /* _FILEIO_H_ */
|
||||
|
@ -118,7 +118,7 @@ static void init_machine(void)
|
||||
fclose(fp);
|
||||
|
||||
/* check BOOT ROM */
|
||||
if (!strncmp((char *)(boot_rom + 0x120),"GENESIS OS", 10))
|
||||
if (!memcmp((char *)(boot_rom + 0x120),"GENESIS OS", 10))
|
||||
{
|
||||
/* mark Genesis BIOS as loaded */
|
||||
system_bios = SYSTEM_MD;
|
||||
|
@ -403,13 +403,13 @@ int load_bios(void)
|
||||
switch (region_code)
|
||||
{
|
||||
case REGION_USA:
|
||||
size = load_archive(CD_BIOS_US, scd.bootrom, sizeof(scd.bootrom));
|
||||
size = load_archive(CD_BIOS_US, scd.bootrom, sizeof(scd.bootrom), 0);
|
||||
break;
|
||||
case REGION_EUROPE:
|
||||
size = load_archive(CD_BIOS_EU, scd.bootrom, sizeof(scd.bootrom));
|
||||
size = load_archive(CD_BIOS_EU, scd.bootrom, sizeof(scd.bootrom), 0);
|
||||
break;
|
||||
default:
|
||||
size = load_archive(CD_BIOS_JP, scd.bootrom, sizeof(scd.bootrom));
|
||||
size = load_archive(CD_BIOS_JP, scd.bootrom, sizeof(scd.bootrom), 0);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -458,7 +458,7 @@ int load_bios(void)
|
||||
if (cart.romsize <= 0x400000)
|
||||
{
|
||||
/* load Game Gear "BIOS" file */
|
||||
size = load_archive(GG_BIOS, cart.rom + 0x400000, 0x100000);
|
||||
size = load_archive(GG_BIOS, cart.rom + 0x400000, 0x100000, 0);
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
@ -489,13 +489,13 @@ int load_bios(void)
|
||||
switch (region_code)
|
||||
{
|
||||
case REGION_USA:
|
||||
size = load_archive(MS_BIOS_US, cart.rom + 0x400000, 0x100000);
|
||||
size = load_archive(MS_BIOS_US, cart.rom + 0x400000, 0x100000, 0);
|
||||
break;
|
||||
case REGION_EUROPE:
|
||||
size = load_archive(MS_BIOS_EU, cart.rom + 0x400000, 0x100000);
|
||||
size = load_archive(MS_BIOS_EU, cart.rom + 0x400000, 0x100000, 0);
|
||||
break;
|
||||
default:
|
||||
size = load_archive(MS_BIOS_JP, cart.rom + 0x400000, 0x100000);
|
||||
size = load_archive(MS_BIOS_JP, cart.rom + 0x400000, 0x100000, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -548,9 +548,13 @@ int load_rom(char *filename)
|
||||
{
|
||||
cdd_unload();
|
||||
}
|
||||
else
|
||||
{
|
||||
cdd.loaded = 0;
|
||||
}
|
||||
|
||||
/* .cue file support */
|
||||
if (!strncmp(".cue", &filename[strlen(filename) - 4], 4))
|
||||
if (!memcmp(".cue", &filename[strlen(filename) - 4], 4))
|
||||
{
|
||||
/* open associated .bin file */
|
||||
strncpy(&filename[strlen(filename) - 4], ".bin", 4);
|
||||
@ -565,7 +569,7 @@ int load_rom(char *filename)
|
||||
}
|
||||
|
||||
/* auto-detect CD image file */
|
||||
if (!strncmp("SEGADISCSYSTEM", buf + 0x10, 14))
|
||||
if (!memcmp("SEGADISCSYSTEM", buf + 0x10, 14))
|
||||
{
|
||||
/* file header pointer (BIN format) */
|
||||
header = buf + 0x10;
|
||||
@ -573,7 +577,7 @@ int load_rom(char *filename)
|
||||
/* enable CD hardware */
|
||||
system_hw = SYSTEM_MCD;
|
||||
}
|
||||
else if (!strncmp("SEGADISCSYSTEM", buf, 14))
|
||||
else if (!memcmp("SEGADISCSYSTEM", buf, 14))
|
||||
{
|
||||
/* file header pointer (ISO format) */
|
||||
header = buf;
|
||||
@ -583,25 +587,29 @@ int load_rom(char *filename)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* load file into ROM buffer (input filename is overwritten by uncompressed filename) */
|
||||
int size = load_archive(filename, cart.rom, sizeof(cart.rom));
|
||||
/* load file into ROM buffer */
|
||||
char extension[4];
|
||||
int size = load_archive(filename, cart.rom, sizeof(cart.rom), extension);
|
||||
if (!size) return(0);
|
||||
|
||||
/* mark CD BIOS as unloaded */
|
||||
system_bios &= ~0x10;
|
||||
|
||||
/* convert lower case to upper case */
|
||||
*(uint32 *)(extension) &= 0xdfdfdfdf;
|
||||
|
||||
/* Auto-detect system hardware from ROM file extension */
|
||||
if (!strncmp(".sms", &filename[strlen(filename) - 4], 4))
|
||||
if (!memcmp("SMS", &extension[0], 3))
|
||||
{
|
||||
/* Master System II hardware */
|
||||
system_hw = SYSTEM_SMS2;
|
||||
}
|
||||
else if (!strncmp(".gg", &filename[strlen(filename) - 3], 3))
|
||||
else if (!memcmp("GG", &extension[1], 2))
|
||||
{
|
||||
/* Game Gear hardware (GG mode) */
|
||||
system_hw = SYSTEM_GG;
|
||||
}
|
||||
else if (!strncmp(".sg", &filename[strlen(filename) - 3], 3))
|
||||
else if (!memcmp("SG", &extension[1], 2))
|
||||
{
|
||||
/* SG-1000 hardware */
|
||||
system_hw = SYSTEM_SG;
|
||||
@ -612,7 +620,7 @@ int load_rom(char *filename)
|
||||
system_hw = SYSTEM_MD;
|
||||
|
||||
/* Decode .MDX format */
|
||||
if (!strncmp(".mdx", &filename[strlen(filename) - 4], 4))
|
||||
if (!memcmp("MDX", &extension[0], 3))
|
||||
{
|
||||
for (i = 4; i < size - 1; i++)
|
||||
{
|
||||
@ -623,7 +631,7 @@ int load_rom(char *filename)
|
||||
}
|
||||
|
||||
/* auto-detect 512 byte extra header */
|
||||
if (strncmp((char *)(cart.rom + 0x100),"SEGA", 4) && ((size / 512) & 1))
|
||||
if (memcmp((char *)(cart.rom + 0x100), "SEGA", 4) && ((size / 512) & 1))
|
||||
{
|
||||
/* remove header */
|
||||
size -= 512;
|
||||
@ -817,12 +825,12 @@ void get_region(char *romheader)
|
||||
int country = 0;
|
||||
|
||||
/* from Gens */
|
||||
if (!strncmp(rominfo.country, "eur", 3)) country |= 8;
|
||||
else if (!strncmp(rominfo.country, "EUR", 3)) country |= 8;
|
||||
else if (!strncmp(rominfo.country, "jap", 3)) country |= 1;
|
||||
else if (!strncmp(rominfo.country, "JAP", 3)) country |= 1;
|
||||
else if (!strncmp(rominfo.country, "usa", 3)) country |= 4;
|
||||
else if (!strncmp(rominfo.country, "USA", 3)) country |= 4;
|
||||
if (!memcmp(rominfo.country, "eur", 3)) country |= 8;
|
||||
else if (!memcmp(rominfo.country, "EUR", 3)) country |= 8;
|
||||
else if (!memcmp(rominfo.country, "jap", 3)) country |= 1;
|
||||
else if (!memcmp(rominfo.country, "JAP", 3)) country |= 1;
|
||||
else if (!memcmp(rominfo.country, "usa", 3)) country |= 4;
|
||||
else if (!memcmp(rominfo.country, "USA", 3)) country |= 4;
|
||||
else
|
||||
{
|
||||
int i;
|
||||
|
@ -46,7 +46,7 @@ int state_load(unsigned char *state)
|
||||
char version[17];
|
||||
load_param(version,16);
|
||||
version[16] = 0;
|
||||
if (strncmp(version,STATE_VERSION,11))
|
||||
if (memcmp(version,STATE_VERSION,11))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
@ -45,9 +45,8 @@
|
||||
#include <zlib.h>
|
||||
|
||||
static int check_zip(char *filename);
|
||||
static int gzsize(gzFile *gd);
|
||||
|
||||
int load_archive(char *filename, unsigned char *buffer, int maxsize)
|
||||
int load_archive(char *filename, unsigned char *buffer, int maxsize, char *extension)
|
||||
{
|
||||
int size = 0;
|
||||
|
||||
@ -55,6 +54,7 @@ int load_archive(char *filename, unsigned char *buffer, int maxsize)
|
||||
{
|
||||
unz_file_info info;
|
||||
int ret = 0;
|
||||
char fname[256];
|
||||
|
||||
/* Attempt to open the archive */
|
||||
unzFile *fd = unzOpen(filename);
|
||||
@ -69,13 +69,20 @@ int load_archive(char *filename, unsigned char *buffer, int maxsize)
|
||||
}
|
||||
|
||||
/* Get file informations and update filename */
|
||||
ret = unzGetCurrentFileInfo(fd, &info, filename, 128, NULL, 0, NULL, 0);
|
||||
ret = unzGetCurrentFileInfo(fd, &info, fname, 256, NULL, 0, NULL, 0);
|
||||
if(ret != UNZ_OK)
|
||||
{
|
||||
unzClose(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Compressed filename extension */
|
||||
if (extension)
|
||||
{
|
||||
strncpy(extension, &fname[strlen(fname) - 3], 3);
|
||||
extension[3] = 0;
|
||||
}
|
||||
|
||||
/* Open the file for reading */
|
||||
ret = unzOpenCurrentFile(fd);
|
||||
if(ret != UNZ_OK)
|
||||
@ -121,6 +128,13 @@ int load_archive(char *filename, unsigned char *buffer, int maxsize)
|
||||
/* Read file data */
|
||||
size = gzread(gd, buffer, maxsize);
|
||||
|
||||
/* filename extension */
|
||||
if (extension)
|
||||
{
|
||||
strncpy(extension, &filename[strlen(filename) - 3], 3);
|
||||
extension[3] = 0;
|
||||
}
|
||||
|
||||
/* Close file */
|
||||
gzclose(gd);
|
||||
}
|
||||
@ -143,25 +157,3 @@ static int check_zip(char *filename)
|
||||
if(memcmp(buf, "PK", 2) == 0) return (1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Returns the size of a GZ compressed file.
|
||||
*/
|
||||
static int gzsize(gzFile *gd)
|
||||
{
|
||||
#define CHUNKSIZE (0x10000)
|
||||
int size = 0, length = 0;
|
||||
unsigned char buffer[CHUNKSIZE];
|
||||
gzrewind(gd);
|
||||
do
|
||||
{
|
||||
size = gzread(gd, buffer, CHUNKSIZE);
|
||||
if(size <= 0) break;
|
||||
length += size;
|
||||
}
|
||||
while (!gzeof(gd));
|
||||
gzrewind(gd);
|
||||
return (length);
|
||||
#undef CHUNKSIZE
|
||||
}
|
||||
|
@ -43,6 +43,6 @@
|
||||
#define _FILEIO_H_
|
||||
|
||||
/* Function prototypes */
|
||||
extern int load_archive(char *filename, unsigned char *buffer, int maxsize);
|
||||
extern int load_archive(char *filename, unsigned char *buffer, int maxsize, char *extension);
|
||||
|
||||
#endif /* _FILEIO_H_ */
|
||||
|
@ -701,7 +701,7 @@ int main (int argc, char **argv)
|
||||
fclose(fp);
|
||||
|
||||
/* check BOOT ROM */
|
||||
if (!strncmp((char *)(boot_rom + 0x120),"GENESIS OS", 10))
|
||||
if (!memcmp((char *)(boot_rom + 0x120),"GENESIS OS", 10))
|
||||
{
|
||||
/* mark Genesis BIOS as loaded */
|
||||
system_bios = SYSTEM_MD;
|
||||
|
Loading…
Reference in New Issue
Block a user