From 7bcebc692d2e12f1667ccb2afbf7c82723e73420 Mon Sep 17 00:00:00 2001 From: rofl0r Date: Mon, 21 Mar 2022 18:46:41 +0000 Subject: [PATCH] rom loader: return error rather than dying it's ok to just die when loading a rom fails for a command line app, but for an application that's running e.g. on a game console or handheld with a menu system, it's not really tolerable. with this change, the frontend has to check for error return code (i.e. not 0), and then get the error message via loader_get_error() and decide on whether to abort or just do something else (like returning to the rom selection menu). --- inflate.c | 12 ++++++------ inflate.h | 2 +- loader.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++------------- loader.h | 5 ++++- main.c | 5 ++++- 5 files changed, 63 insertions(+), 22 deletions(-) diff --git a/inflate.c b/inflate.c index f4db757..81b8256 100644 --- a/inflate.c +++ b/inflate.c @@ -272,7 +272,7 @@ get_data (const unsigned char *data, long *p, const unsigned int hlit_code_table[HLIT_TSIZE], const char hdist_size_table[HDIST_TSIZE], const unsigned int hdist_code_table[HDIST_TSIZE], - void (* callback) (unsigned char d)) + int (* callback) (unsigned char d)) /* Do the actual uncompressing. Call callback on each character * uncompressed. */ { @@ -286,7 +286,7 @@ get_data (const unsigned char *data, long *p, /* Literal */ { pushout ((unsigned char) b); - callback ((unsigned char) b); + if(callback ((unsigned char) b)) return -1; } else if ( b == 256 ) /* End of block */ @@ -375,7 +375,7 @@ get_data (const unsigned char *data, long *p, ch = pushin (dist); pushout (ch); - callback (ch); + if (callback (ch)) return -1; } } } @@ -384,7 +384,7 @@ get_data (const unsigned char *data, long *p, static int inflate (const unsigned char *data, long *p, - void (* callback) (unsigned char d)) + int (* callback) (unsigned char d)) /* Main uncompression function for the deflate method */ { char blast, btype; @@ -444,7 +444,7 @@ inflate (const unsigned char *data, long *p, { b = read_bits (data, p, 8); pushout (b); - callback (b); + if (callback (b)) return -1; } } else @@ -458,7 +458,7 @@ inflate (const unsigned char *data, long *p, int unzip (const unsigned char *data, long *p, - void (* callback) (unsigned char d)) + int (* callback) (unsigned char d)) /* Uncompress gzipped data. data is a pointer to the data, p is * a pointer to a long that is initialized to 0 (unless for some * reason you want to start uncompressing further down the data), diff --git a/inflate.h b/inflate.h index d2a1215..f64a4ac 100644 --- a/inflate.h +++ b/inflate.h @@ -1,7 +1,7 @@ #ifndef INFLATE_H #define INFLATE_H -int unzip (const unsigned char *data, long *p, void (* callback) (unsigned char d)); +int unzip (const unsigned char *data, long *p, int (* callback) (unsigned char d)); #endif diff --git a/loader.c b/loader.c index 319e0a1..978adbf 100644 --- a/loader.c +++ b/loader.c @@ -6,10 +6,12 @@ #include #include +#include #include #include #include "defs.h" +#include "loader.h" #include "regs.h" #include "mem.h" #include "hw.h" @@ -133,16 +135,36 @@ static byte *loadfile(FILE *f, int *len) static byte *inf_buf; static int inf_pos, inf_len; +static char* loader_error; -static void inflate_callback(byte b) +char* loader_get_error(void) +{ + return loader_error; +} + +void loader_set_error(char *fmt, ...) +{ + char buf[1024]; + va_list ap; + va_start(ap, fmt); + vsnprintf(buf, sizeof buf, fmt, ap); + va_end(ap); + loader_error = strdup(buf); +} + +static int inflate_callback(byte b) { if (inf_pos >= inf_len) { inf_len += 512; inf_buf = realloc(inf_buf, inf_len); - if (!inf_buf) die("out of memory inflating file @ %d bytes\n", inf_pos); + if (!inf_buf) { + loader_set_error("out of memory inflating file @ %d bytes\n", inf_pos); + return -1; + } } inf_buf[inf_pos++] = b; + return 0; } static byte *gunzip(byte *data, int *len) { @@ -155,10 +177,11 @@ static byte *gunzip(byte *data, int *len) { return inf_buf; } -static void write_dec(byte *data, int len) { +static int write_dec(byte *data, int len) { int i; for(i=0; i < len; i++) - inflate_callback(data[i]); + if(inflate_callback(data[i])) return -1; + return 0; } static int unxz(byte *data, int len) { @@ -184,13 +207,13 @@ static int unxz(byte *data, int len) { while (1) { ret = xz_dec_run(s, &b); if(b.out_pos == sizeof(out)) { - write_dec(out, sizeof(out)); + if(write_dec(out, sizeof(out))) goto err; b.out_pos = 0; } if(ret == XZ_OK) continue; - write_dec(out, b.out_pos); + if(write_dec(out, b.out_pos)) goto err; if(ret == XZ_STREAM_END) { xz_dec_end(s); @@ -228,7 +251,10 @@ static FILE* rom_loadfile(char *fn, byte** data, int *len) { FILE *f; if (strcmp(fn, "-")) f = fopen(fn, "rb"); else f = stdin; - if (!f) die("cannot open rom file: %s\n", fn); + if (!f) { + loader_set_error("cannot open rom file: %s\n", fn); + return f; + } *data = loadfile(f, len); *data = decompress(*data, len); return f; @@ -241,6 +267,7 @@ int bootrom_load() { REG(RI_BOOT) = 0xff; if (!bootroms[hw.cgb] || !bootroms[hw.cgb][0]) return 0; f = rom_loadfile(bootroms[hw.cgb], &data, &len); + if(!f) return -1; bootrom.bank = realloc(data, 16384); memset(bootrom.bank[0]+len, 0xff, 16384-len); memcpy(bootrom.bank[0]+0x100, rom.bank[0]+0x100, 0x100); @@ -255,6 +282,7 @@ int rom_load() byte c, *data, *header; int len = 0, rlen; f = rom_loadfile(romfile, &data, &len); + if(!f) return -1; header = data; memcpy(rom.name, header+0x0134, 16); @@ -269,8 +297,14 @@ int rom_load() mbc.romsize = romsize_table[header[0x0148]]; mbc.ramsize = ramsize_table[header[0x0149]]; - if (!mbc.romsize) die("unknown ROM size %02X\n", header[0x0148]); - if (!mbc.ramsize) die("unknown SRAM size %02X\n", header[0x0149]); + if (!mbc.romsize) { + loader_set_error("unknown ROM size %02X\n", header[0x0148]); + return -1; + } + if (!mbc.ramsize) { + loader_set_error("unknown SRAM size %02X\n", header[0x0149]); + return -1; + } rlen = 16384 * mbc.romsize; @@ -435,14 +469,14 @@ static void cleanup() /* IDEA - if error, write emergency savestate..? */ } -void loader_init(char *s) +int loader_init(char *s) { char *name, *p; sys_checkdir(savedir, 1); /* needs to be writable */ romfile = s; - rom_load(); + if(rom_load()) return -1; bootrom_load(); vid_settitle(rom.name); if (savename && *savename) @@ -458,7 +492,7 @@ void loader_init(char *s) if (p) *p = 0; } else name = ldup(rom.name); - + saveprefix = malloc(strlen(savedir) + strlen(name) + 2); sprintf(saveprefix, "%s/%s", savedir, name); @@ -469,11 +503,12 @@ void loader_init(char *s) rtcfile = malloc(strlen(saveprefix) + 5); strcpy(rtcfile, saveprefix); strcat(rtcfile, ".rtc"); - + sram_load(); rtc_load(); atexit(cleanup); + return 0; } rcvar_t loader_exports[] = diff --git a/loader.h b/loader.h index b86d930..da108e4 100644 --- a/loader.h +++ b/loader.h @@ -21,7 +21,10 @@ int rom_load(); int sram_load(); int sram_save(); -void loader_init(char *s); +int loader_init(char *s); +char *loader_get_error(); +void loader_set_error(char *fmt, ...); + void state_save(int n); void state_load(int n); diff --git a/main.c b/main.c index 1b2d42a..d92407c 100644 --- a/main.c +++ b/main.c @@ -148,7 +148,10 @@ static void help(char *name) static void rominfo(char* fn) { extern int rom_load_simple(char *fn); - rom_load_simple(fn); + if(rom_load_simple(fn)) { + fprintf(stderr, "rom load failed: %s\n", loader_get_error()?loader_get_error():""); + exit(1); + } printf( "rom name:\t%s\n" "mbc type:\t%s\n" "rom size:\t%u KB\n" -- 2.11.4.GIT