Now with save support!

It is pretty messy!
This commit is contained in:
Robin Jones 2023-06-07 01:50:05 +01:00
parent e2acdfb28a
commit eb24ed40eb
3 changed files with 82 additions and 57 deletions

View File

@ -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!
}

View File

@ -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 :

View File

@ -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;