From eb24ed40eb396524d2875a28c7aa9efc0c72e15b Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Wed, 7 Jun 2023 01:50:05 +0100 Subject: [PATCH] Now with save support! It is pretty messy! --- src/menu/menu_main.c | 64 ++++++++++++++++------------------------- src/menu/rom_database.c | 18 ++++++------ src/menu/rom_database.h | 57 ++++++++++++++++++++++++++++++------ 3 files changed, 82 insertions(+), 57 deletions(-) diff --git a/src/menu/menu_main.c b/src/menu/menu_main.c index 6ca0adb5..67e3f942 100644 --- a/src/menu/menu_main.c +++ b/src/menu/menu_main.c @@ -22,48 +22,38 @@ static int items_in_dir = 1; static FILINFO current_fileinfo; -void file_read_rom_header(char *path) { +rom_header_t file_read_rom_header(char *path) { FILE *fp = fopen(path, "rb"); printf("loading path: %s\n", path); if (!fp) { printf("Error loading rom file header\n"); } - // rom_header_t header; // malloc(size); - - uint64_t checksum; - char rom_title[14]; - //char category_code[1]; - uint16_t unique_id; - //char destination_code; - //char version; + rom_header_t rom_header; // malloc(size); fseek(fp, 0x10, SEEK_SET); - fread(&checksum, sizeof(uint64_t), 1, fp); + fread(&rom_header.checksum, sizeof(uint64_t), 1, fp); fseek(fp, 0x20, SEEK_SET); - fread(&rom_title, sizeof(rom_title), 1, fp); + fread(&rom_header.title, sizeof(rom_header.title), 1, fp); //fseek(fp, 0x3b, SEEK_SET); - //fread(&category_code, sizeof(char), 1, fp); + //fread(&media_type, sizeof(char), 1, fp); fseek(fp, 0x3c, SEEK_SET); - fread(&unique_id, sizeof(uint16_t), 1, fp); + fread(&rom_header.metadata.unique_identifier, sizeof(rom_header.metadata.unique_identifier), 1, fp); //fseek(fp, 0x3e, SEEK_SET); - //fread(&destination_code, sizeof(char), 1, fp); - //fseek(fp, 0x3f, SEEK_SET); - //fread(&version, sizeof(char), 1, fp); - - printf("ROM checksum: %llu\n", checksum); - printf("ROM title: %s\n", rom_title); - //printf("ROM cat type code: %c\n", category_code); - printf("ROM unique id: %hu\n", unique_id); - //printf("ROM dest market code: %c\n", destination_code); - //printf("ROM ver code: %c\n", version); + //fread(&destination_market, sizeof(char), 1, fp); + // fseek(fp, 0x3f, SEEK_SET); + // fread(&version, sizeof(uint8_t), 1, fp); fclose(fp); - // header.check_code = check_code; - // header.game_code.unique_code = unique_code; + printf("ROM checksum: %llu\n", rom_header.checksum); + printf("ROM title: %s\n", rom_header.title); + //printf("ROM media type code: %s\n", (char *) &media_type); + printf("ROM unique id: %s\n", (char *) &rom_header.metadata.unique_identifier); + //printf("ROM dest market code: %s\n", (char *) &rom_header.metadata.destination_market); + //printf("ROM version: %hu\n", rom_header.version); - // return header; + return rom_header; } // FIXME: use newlib rather than fatfs to do this! @@ -204,21 +194,17 @@ void menu_main_init (settings_t *settings) { printf("%s\n", current_fileinfo.fname); char tmp_buffer[280]; sprintf(tmp_buffer, "sd:/%s", current_fileinfo.fname); - //rom_header_t temp_header = - file_read_rom_header(tmp_buffer); - //printf("header: %d", temp_header.game_code.unique_code); - //uint8_t save_type = rom_db_match_save_type(temp_header); + rom_header_t temp_header = file_read_rom_header(tmp_buffer); + printf("uid as int: %d\n", temp_header.metadata.unique_identifier); + uint8_t save_type = rom_db_match_save_type(temp_header); - //printf("save type: %d", save_type); - wait_ms(5000); - // FIXME: we now need the header ID and CRC HI... - // f_read - // crc_high = (buff[0x10] << 24) | (buff[0x11] << 16) | (buff[0x12] << 8) | (buff[0x13] << 0); - // crc_low = (buff[0x14] << 24) | (buff[0x15] << 16) | (buff[0x16] << 8) | (buff[0x17] << 0); - // id = (buff[0x3c] << 8) | buff[0x3d]; - //assertf(flashcart_load_save("current_filename.sav", rom_db_match_save_type(id, crc), false) == FLASHCART_OK, "ROM load save error"); + printf("save type: %d\n", save_type); + sprintf(tmp_buffer, "%s.%llu.sav", current_fileinfo.fname, temp_header.checksum); + wait_ms(1000); - //assertf(flashcart_load_rom(current_fileinfo.fname) == FLASHCART_OK, "ROM load error"); + assertf(flashcart_load_save(tmp_buffer, (flashcart_save_type_t)save_type, true) == FLASHCART_OK, "ROM load save error"); + + assertf(flashcart_load_rom(current_fileinfo.fname) == FLASHCART_OK, "ROM load error"); break; //required! } diff --git a/src/menu/rom_database.c b/src/menu/rom_database.c index 88f45b62..5a074cd0 100644 --- a/src/menu/rom_database.c +++ b/src/menu/rom_database.c @@ -9,20 +9,20 @@ uint8_t rom_db_match_save_type(rom_header_t rom_header) { // First: Match by the `ED` Developer ID // TODO: if appropriate this can be improved with other unused codes... e.g. | `AA` | `ZZ` - if (rom_header.game_code.unique_code == *(uint16_t *)"ED") { + if (rom_header.metadata.unique_identifier == *(uint16_t *)"ED") { // FIXME: should probably just return the specified save type. return DB_SAVE_TYPE_CART_SPECIFIED; } // Second: Match the default entries for crc_high. // FIXME: use full check code, or pad. - if (rom_header.check_code == 0xbcb1f89f)return DB_SAVE_TYPE_EEPROM_4K; // kirby v1.3 - if (rom_header.check_code == 0x46039fb4)return DB_SAVE_TYPE_EEPROM_16K; // kirby U - if (rom_header.check_code == 0x0d93ba11)return DB_SAVE_TYPE_EEPROM_16K; // kirby U - if (rom_header.check_code == 0xce84793d)return DB_SAVE_TYPE_SRAM; // donkey kong f2 - if (rom_header.check_code == 0x4cbc3b56)return DB_SAVE_TYPE_SRAM; // DMTJ 64DD game - if (rom_header.check_code == 0x0dd4abab)return DB_SAVE_TYPE_EEPROM_16K; // DK Retail kiosk demo (shares ID with Dinosaur planet, but hacks are unlikely)! - if (rom_header.check_code == 0xeb85ebc9)return DB_SAVE_TYPE_FLASHRAM; // DOUBUTSU BANCHOU (ANIMAL LEADER, Cubivore) - Contains no game ID + if (rom_header.checksum == 0xbcb1f89f)return DB_SAVE_TYPE_EEPROM_4K; // kirby v1.3 + if (rom_header.checksum == 0x46039fb4)return DB_SAVE_TYPE_EEPROM_16K; // kirby U + if (rom_header.checksum == 0x0d93ba11)return DB_SAVE_TYPE_EEPROM_16K; // kirby U + if (rom_header.checksum == 0xce84793d)return DB_SAVE_TYPE_SRAM; // donkey kong f2 + if (rom_header.checksum == 0x4cbc3b56)return DB_SAVE_TYPE_SRAM; // DMTJ 64DD game + if (rom_header.checksum == 0x0dd4abab)return DB_SAVE_TYPE_EEPROM_16K; // DK Retail kiosk demo (shares ID with Dinosaur planet, but hacks are unlikely)! + if (rom_header.checksum == 0xeb85ebc9)return DB_SAVE_TYPE_FLASHRAM; // DOUBUTSU BANCHOU (ANIMAL LEADER, Cubivore) - Contains no game ID // FIXME: we need to take into account the Category (first char) and the Region code (last char) before a general match of the ID. @@ -82,7 +82,7 @@ uint8_t rom_db_match_save_type(rom_header_t rom_header) { for (int i = 0; save_types[i] != 0xff; i++) { - if (rom_header.game_code.unique_code == *(uint16_t *) cart_ids[i]) { + if (rom_header.metadata.unique_identifier == *(uint16_t *) cart_ids[i]) { i = save_types[i]; // i = i == 1 ? DB_SAVE_TYPE_EEPROM_4K : // i == 2 ? DB_SAVE_TYPE_EEPROM_16K : diff --git a/src/menu/rom_database.h b/src/menu/rom_database.h index 44e658c7..75ab6846 100644 --- a/src/menu/rom_database.h +++ b/src/menu/rom_database.h @@ -21,17 +21,56 @@ // DestinationCode 0x3e // RomVersion 0x3f -typedef struct { - char category_code; - uint16_t unique_code; - char destination_code; -} game_code_t; +// typedef enum { +// N64_CART = 'N', +// N64_DISK = 'D', +// N64_CART_EXPANDABLE = 'C', +// N64_DISK_EXPANDABLE = 'E', +// N64_ALECK64 = 'Z', +// //UNKNOWN = NULL +// } rom_media_type_t; + +// typedef enum { +// MARKET_ALL = 'A', +// MARKET_BRAZIL = 'B', +// MARKET_CHINA = 'C', +// MARKET_GERMANY = 'D', +// MARKET_USA = 'E', +// MARKET_FRANCE = 'F', +// MARKET_GATEWAY64_NTSC = 'G', +// MARKET_NETHERLANDS = 'H', +// MARKET_ITALY = 'I', +// MARKET_JAPAN = 'J', +// MARKET_KOREA = 'K', +// MARKET_GATEWAY64_PAL = 'L', +// MARKET_UNKNOWN_M = 'M', +// MARKET_CANADA = 'N', +// MARKET_UNKNOWN_O = 'O', +// MARKET_EUROPE_P = 'P', +// MARKET_UNKNOWN_Q = 'Q', +// MARKET_UNKNOWN_R = 'R', +// MARKET_SPAIN = 'S', +// MARKET_UNKNOWN_T = 'T', +// MARKET_AUSTRAILA = 'U', +// MARKET_UNKNOWN_V = 'V', +// MARKET_SCANDINAVAIA = 'W', +// MARKET_EUROPE_X = 'X', +// MARKET_EUROPE_Y = 'Y', +// MARKET_EUROPE_Z = 'Z', +// //MARKET_UNKNOWN = NULL +// } rom_destination_market_t; typedef struct { - uint64_t check_code; - char game_title[14]; - game_code_t game_code; - char version; + // rom_media_type_t media_type; + uint16_t unique_identifier; + // char destination_market; //rom_destination_market_t +} rom_metadata_t; + +typedef struct { + uint64_t checksum; + char title[14]; + rom_metadata_t metadata; + // uint8_t version; } rom_header_t;