diff --git a/cheats.cpp b/cheats.cpp index 5e86f7c..31b07cc 100644 --- a/cheats.cpp +++ b/cheats.cpp @@ -49,8 +49,49 @@ struct CheatComp static char cheat_zip[1024] = {}; -void cheats_init(char *rom_path) -{ +int find_by_crc(uint32_t romcrc) +{ + sprintf(cheat_zip, "%s/cheats/%s", getRootDir(), HomeDir); + DIR *d = opendir(cheat_zip); + if (!d) + { + printf("Couldn't open dir: %s\n", cheat_zip); + return 0; + } + + struct dirent *de = 0; + while((de = readdir(d))) + { + if (de->d_type == DT_REG) + { + char *ext = strcasestr(de->d_name, ".zip"); + if (ext && (ext - de->d_name) > 10) + { + ext -= 10; + if (ext[0] == '[' && ext[9] == ']') + { + uint32_t crc = 0; + if (sscanf(ext, "[%X].zip", &crc) == 1) + { + if (crc == romcrc) + { + strcat(cheat_zip, "/"); + strcat(cheat_zip, de->d_name); + closedir(d); + return 1; + } + } + } + } + } + } + + closedir(d); + return 0; +} + +void cheats_init(char *rom_path, uint32_t romcrc) +{ cheats.clear(); loaded = 0; cheat_zip[0] = 0; @@ -68,9 +109,9 @@ void cheats_init(char *rom_path) { memset(&_z, 0, sizeof(_z)); - char *rom_name = strrchr(rom_path, '/'); - if (!rom_name) return; - + char *rom_name = strrchr(rom_path, '/'); + if (!rom_name) return; + sprintf(cheat_zip, "%s/cheats/%s%s", getRootDir(), HomeDir, rom_name); char *p = strrchr(cheat_zip, '.'); if (p) *p = 0; @@ -78,11 +119,17 @@ void cheats_init(char *rom_path) if (!mz_zip_reader_init_file(&_z, cheat_zip, 0)) { - printf("no cheat file %s\n", cheat_zip); - return; + memset(&_z, 0, sizeof(_z)); + if (!find_by_crc(romcrc) || !mz_zip_reader_init_file(&_z, cheat_zip, 0)) + { + printf("no cheat file found\n"); + return; + } } } + printf("Using cheat file: %s\n", cheat_zip); + mz_zip_archive *z = new mz_zip_archive(_z); for (size_t i = 0; i < mz_zip_reader_get_num_files(z); i++) { @@ -325,6 +372,6 @@ void cheats_toggle() } int cheats_loaded() -{ +{ return loaded; } \ No newline at end of file diff --git a/cheats.h b/cheats.h index fd9e886..4201675 100644 --- a/cheats.h +++ b/cheats.h @@ -1,7 +1,7 @@ #ifndef CHEATS_H #define CHEATS_H -void cheats_init(char *rom_path); +void cheats_init(char *rom_path, uint32_t romcrc); int cheats_available(); void cheats_scan(int mode); void cheats_scroll_name(); diff --git a/menu.cpp b/menu.cpp index 7eddf13..0d329ff 100644 --- a/menu.cpp +++ b/menu.cpp @@ -1414,7 +1414,7 @@ void HandleUI(void) printf("File selected: %s\n", SelectedPath); user_io_store_filename(SelectedPath); user_io_file_tx(SelectedPath, user_io_ext_idx(SelectedPath, fs_pFileExt) << 6 | (menusub + 1), opensave); - cheats_init(SelectedPath); + if(user_io_use_cheats()) cheats_init(SelectedPath, user_io_get_file_crc()); menustate = MENU_NONE1; break; diff --git a/user_io.cpp b/user_io.cpp index 5780291..307e82d 100644 --- a/user_io.cpp +++ b/user_io.cpp @@ -11,7 +11,6 @@ #include #include "lib/lodepng/lodepng.h" - #include "hardware.h" #include "osd.h" #include "user_io.h" @@ -29,6 +28,7 @@ #include "bootcore.h" #include "charrom.h" #include "scaler.h" +#include "miniz.h" #include "support.h" @@ -297,6 +297,8 @@ int user_io_get_joy_transl() return joy_transl; } +static int use_cheats = 0; + static void parse_config() { int i = 0; @@ -362,6 +364,11 @@ static void parse_config() substrcpy(s + strlen(s), p, 1); OsdCoreNameSet(s); } + + if (p[0] == 'C') + { + use_cheats = 1; + } } i++; } while (p || i<3); @@ -1290,6 +1297,17 @@ static void send_pcolchr(const char* name, unsigned char index, int type) } } +static uint32_t file_crc; +uint32_t user_io_get_file_crc() +{ + return file_crc; +} + +int user_io_use_cheats() +{ + return use_cheats; +} + int user_io_file_tx(const char* name, unsigned char index, char opensave, char mute, char composite) { fileTYPE f = {}; @@ -1351,6 +1369,7 @@ int user_io_file_tx(const char* name, unsigned char index, char opensave, char m spi_write(buf, 512, fio_size); DisableFpga(); + //strip original SNES ROM header if present (not used) if (bytes2send & 512) { bytes2send -= 512; @@ -1358,6 +1377,9 @@ int user_io_file_tx(const char* name, unsigned char index, char opensave, char m } } + file_crc = 0; + uint32_t skip = bytes2send & 0x3FF; // skip possible header up to 1023 bytes + while (bytes2send) { printf("."); @@ -1372,8 +1394,16 @@ int user_io_file_tx(const char* name, unsigned char index, char opensave, char m DisableFpga(); bytes2send -= chunk; + + if (skip >= chunk) skip -= chunk; + else + { + file_crc = crc32(file_crc, buf + skip, chunk - skip); + skip = 0; + } } printf("\n"); + printf("CRC32: %08X\n", file_crc); } FileClose(&f); diff --git a/user_io.h b/user_io.h index 94a4fa6..4eca6ee 100644 --- a/user_io.h +++ b/user_io.h @@ -188,6 +188,7 @@ void user_io_serial_tx(char *, uint16_t); char *user_io_8bit_get_string(char); uint32_t user_io_8bit_set_status(uint32_t, uint32_t); int user_io_file_tx(const char* name, unsigned char index = 0, char opensave = 0, char mute = 0, char composite = 0); +uint32_t user_io_get_file_crc(); int user_io_file_mount(char *name, unsigned char index = 0, char pre = 0); char user_io_serial_status(serial_status_t *, uint8_t); char *user_io_get_core_name(); @@ -251,5 +252,6 @@ void set_volume(int cmd); int get_volume(); void user_io_store_filename(char *filename); +int user_io_use_cheats(); #endif // USER_IO_H