From 6a223f62e204af84dd4d01a89dfe5f0c3195d1d7 Mon Sep 17 00:00:00 2001 From: Marcoen Hirschberg Date: Sun, 1 May 2022 23:18:57 +0200 Subject: [PATCH] Psx region autodetect (#589) --- support/psx/psx.cpp | 87 ++++++++++++++++++++++++++++++++------------- 1 file changed, 62 insertions(+), 25 deletions(-) diff --git a/support/psx/psx.cpp b/support/psx/psx.cpp index 1b03de4..bb3dc80 100644 --- a/support/psx/psx.cpp +++ b/support/psx/psx.cpp @@ -369,15 +369,34 @@ struct disk_t uint32_t track_count; uint32_t total_lba; uint32_t total_bcd; - uint32_t reserved; + uint16_t libcrypt_mask; + uint16_t metadata; // lower 2 bits encode the region, the other bits are reseved track_t track[99]; }; +enum region_t +{ + UNKNOWN = 0, + JP, + US, + EU +}; + +const char* region_string(region_t region) +{ + switch (region) + { + case region_t::JP: return "Japan"; + case region_t::US: return "USA"; + case region_t::EU: return "Europe"; + default: return "Unknown"; + } +} + #define BCD(v) ((uint8_t)((((v)/10) << 4) | ((v)%10))) -void send_cue(toc_t *table) +void send_cue_and_metadata(toc_t *table, uint16_t libcrypt_mask, enum region_t region) { - disk_t *disk = new disk_t; if (disk) { @@ -390,6 +409,8 @@ void send_cue(toc_t *table) } memset(disk, 0, sizeof(disk_t)); + disk->libcrypt_mask = libcrypt_mask; + disk->metadata = region; // the lower 2 bits of metadata contain the region disk->track_count = (BCD(table->last) << 8) | table->last; disk->total_lba = table->end; int m = (disk->total_lba / 75) / 60; @@ -520,24 +541,37 @@ void psx_read_cd(uint8_t *buffer, int lba, int cnt) #define ROOT_FOLDER_LBA 150 + 22 -const char* game_id_prefixes[] +struct region_info_t { - "SCES", - "SLES", - "SCUS", - "SLUS", - "SCPM", - "SLPM", - "SCPS", - "SLPS", + const char* game_id_prefix; + enum region_t region; }; -const char* psx_get_game_id() +const region_info_t region_info_table[] +{ + { "SCES", region_t::EU }, + { "SLES", region_t::EU }, + { "SCUS", region_t::US }, + { "SLUS", region_t::US }, + { "SCPM", region_t::JP }, + { "SLPM", region_t::JP }, + { "SCPS", region_t::JP }, + { "SLPS", region_t::JP }, +}; + +struct game_info_t +{ + const char* game_id; + region_t region; +}; + +game_info_t psx_get_game_info() { uint8_t buffer[CD_SECTOR_LEN]; static char game_id[11]; memset(game_id, 0, sizeof(game_id)); + enum region_t game_region = UNKNOWN; for (int sector = ROOT_FOLDER_LBA; sector < ROOT_FOLDER_LBA + 3; ++sector) { @@ -545,9 +579,10 @@ const char* psx_get_game_id() //hexdump(buffer, CD_SECTOR_LEN); char* start = nullptr; - for (const char* prefix : game_id_prefixes) + for (const auto& region_info : region_info_table) { - start = (char*)memmem(buffer, CD_SECTOR_LEN, prefix, 4); + game_region = region_info.region; + start = (char*)memmem(buffer, CD_SECTOR_LEN, region_info.game_id_prefix, 4); if (start) break; } @@ -575,10 +610,15 @@ const char* psx_get_game_id() const size_t max_length = sizeof(game_id) - 1; if (size > max_length) size = max_length; - return (char*)memcpy(game_id, start, size); + return { (const char*)memcpy(game_id, start, size), game_region }; } - return game_id; + return { game_id, region_t::UNKNOWN }; +} + +const char* psx_get_game_id() +{ + return psx_get_game_info().game_id; } static void mount_cd(int size, int index) @@ -608,7 +648,9 @@ void psx_mount_cd(int f_index, int s_index, const char *filename) { if (load_cd_image(filename, &toc) && toc.last) { - printf("GAME ID: %s\n", psx_get_game_id()); + game_info_t game_info = psx_get_game_info(); + const char* game_id = game_info.game_id; + printf("Game ID: %s, region: %s\n", game_id, region_string(game_info.region)); int name_len = strlen(filename); @@ -671,15 +713,13 @@ void psx_mount_cd(int f_index, int s_index, const char *filename) } } - send_cue(&toc); - uint16_t mask = 0; fileTYPE sbi_file = {}; bool has_sbi_file = false; // search for .sbi file in PSX/sbi.zip - sprintf(buf, "%s/sbi.zip/%s.sbi", HomeDir(), psx_get_game_id()); + sprintf(buf, "%s/sbi.zip/%s.sbi", HomeDir(), game_id); has_sbi_file = (FileOpen(&sbi_file, buf, 1)); if (!has_sbi_file) @@ -696,10 +736,7 @@ void psx_mount_cd(int f_index, int s_index, const char *filename) mask = libCryptMask(&sbi_file); } - user_io_set_index(250); - user_io_set_download(1); - user_io_file_tx_data((const uint8_t*)&mask, 2); - user_io_set_download(0); + send_cue_and_metadata(&toc, mask, game_info.region); user_io_set_index(f_index); process_ss(filename, name_len != 0);