mirror of
https://github.com/Polprzewodnikowy/N64FlashcartMenu.git
synced 2024-11-25 12:06:54 +01:00
Now with save support!
It is pretty messy!
This commit is contained in:
parent
e2acdfb28a
commit
eb24ed40eb
@ -22,48 +22,38 @@ static int items_in_dir = 1;
|
|||||||
|
|
||||||
static FILINFO current_fileinfo;
|
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");
|
FILE *fp = fopen(path, "rb");
|
||||||
printf("loading path: %s\n", path);
|
printf("loading path: %s\n", path);
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
printf("Error loading rom file header\n");
|
printf("Error loading rom file header\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// rom_header_t header; // malloc(size);
|
rom_header_t rom_header; // malloc(size);
|
||||||
|
|
||||||
uint64_t checksum;
|
|
||||||
char rom_title[14];
|
|
||||||
//char category_code[1];
|
|
||||||
uint16_t unique_id;
|
|
||||||
//char destination_code;
|
|
||||||
//char version;
|
|
||||||
|
|
||||||
fseek(fp, 0x10, SEEK_SET);
|
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);
|
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);
|
//fseek(fp, 0x3b, SEEK_SET);
|
||||||
//fread(&category_code, sizeof(char), 1, fp);
|
//fread(&media_type, sizeof(char), 1, fp);
|
||||||
fseek(fp, 0x3c, SEEK_SET);
|
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);
|
//fseek(fp, 0x3e, SEEK_SET);
|
||||||
//fread(&destination_code, sizeof(char), 1, fp);
|
//fread(&destination_market, sizeof(char), 1, fp);
|
||||||
//fseek(fp, 0x3f, SEEK_SET);
|
// fseek(fp, 0x3f, SEEK_SET);
|
||||||
//fread(&version, sizeof(char), 1, fp);
|
// fread(&version, sizeof(uint8_t), 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);
|
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
// header.check_code = check_code;
|
printf("ROM checksum: %llu\n", rom_header.checksum);
|
||||||
// header.game_code.unique_code = unique_code;
|
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!
|
// 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);
|
printf("%s\n", current_fileinfo.fname);
|
||||||
char tmp_buffer[280];
|
char tmp_buffer[280];
|
||||||
sprintf(tmp_buffer, "sd:/%s", current_fileinfo.fname);
|
sprintf(tmp_buffer, "sd:/%s", current_fileinfo.fname);
|
||||||
//rom_header_t temp_header =
|
rom_header_t temp_header = file_read_rom_header(tmp_buffer);
|
||||||
file_read_rom_header(tmp_buffer);
|
printf("uid as int: %d\n", temp_header.metadata.unique_identifier);
|
||||||
//printf("header: %d", temp_header.game_code.unique_code);
|
uint8_t save_type = rom_db_match_save_type(temp_header);
|
||||||
//uint8_t save_type = rom_db_match_save_type(temp_header);
|
|
||||||
|
|
||||||
//printf("save type: %d", save_type);
|
printf("save type: %d\n", save_type);
|
||||||
wait_ms(5000);
|
sprintf(tmp_buffer, "%s.%llu.sav", current_fileinfo.fname, temp_header.checksum);
|
||||||
// FIXME: we now need the header ID and CRC HI...
|
wait_ms(1000);
|
||||||
// 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");
|
|
||||||
|
|
||||||
//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!
|
break; //required!
|
||||||
}
|
}
|
||||||
|
@ -9,20 +9,20 @@ uint8_t rom_db_match_save_type(rom_header_t rom_header) {
|
|||||||
|
|
||||||
// First: Match by the `ED` Developer ID
|
// First: Match by the `ED` Developer ID
|
||||||
// TODO: if appropriate this can be improved with other unused codes... e.g. | `AA` | `ZZ`
|
// 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.
|
// FIXME: should probably just return the specified save type.
|
||||||
return DB_SAVE_TYPE_CART_SPECIFIED;
|
return DB_SAVE_TYPE_CART_SPECIFIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Second: Match the default entries for crc_high.
|
// Second: Match the default entries for crc_high.
|
||||||
// FIXME: use full check code, or pad.
|
// 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.checksum == 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.checksum == 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.checksum == 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.checksum == 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.checksum == 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.checksum == 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 == 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.
|
// 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++) {
|
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 = save_types[i];
|
||||||
// i = i == 1 ? DB_SAVE_TYPE_EEPROM_4K :
|
// i = i == 1 ? DB_SAVE_TYPE_EEPROM_4K :
|
||||||
// i == 2 ? DB_SAVE_TYPE_EEPROM_16K :
|
// i == 2 ? DB_SAVE_TYPE_EEPROM_16K :
|
||||||
|
@ -21,17 +21,56 @@
|
|||||||
// DestinationCode 0x3e
|
// DestinationCode 0x3e
|
||||||
// RomVersion 0x3f
|
// RomVersion 0x3f
|
||||||
|
|
||||||
typedef struct {
|
// typedef enum {
|
||||||
char category_code;
|
// N64_CART = 'N',
|
||||||
uint16_t unique_code;
|
// N64_DISK = 'D',
|
||||||
char destination_code;
|
// N64_CART_EXPANDABLE = 'C',
|
||||||
} game_code_t;
|
// 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 {
|
typedef struct {
|
||||||
uint64_t check_code;
|
// rom_media_type_t media_type;
|
||||||
char game_title[14];
|
uint16_t unique_identifier;
|
||||||
game_code_t game_code;
|
// char destination_market; //rom_destination_market_t
|
||||||
char version;
|
} rom_metadata_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint64_t checksum;
|
||||||
|
char title[14];
|
||||||
|
rom_metadata_t metadata;
|
||||||
|
// uint8_t version;
|
||||||
} rom_header_t;
|
} rom_header_t;
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user