psx: add cheats (#551)

* PSX: implement game ID

* initialize cheats for PSX
This commit is contained in:
Marcoen Hirschberg
2022-02-21 17:31:51 +01:00
committed by GitHub
parent 9ace959408
commit 652a8423d3
4 changed files with 110 additions and 1 deletions

View File

@@ -122,6 +122,36 @@ static int find_in_same_dir(const char *name)
return 0;
}
bool cheat_init_psx(mz_zip_archive* _z, const char* rom_path)
{
// lookup based on file name
const char *rom_name = strrchr(rom_path, '/');
if (rom_name)
{
sprintf(cheat_zip, "%s/cheats/%s%s", getRootDir(), CoreName, rom_name);
char *p = strrchr(cheat_zip, '.');
if (p) *p = 0;
strcat(cheat_zip, ".zip");
printf("Trying cheat file: %s\n", cheat_zip);
memset(_z, 0, sizeof(mz_zip_archive));
if (mz_zip_reader_init_file(_z, cheat_zip, 0)) return true;
}
// lookup based on game ID
const char* game_id = psx_get_game_id();
if (game_id && game_id[0])
{
sprintf(cheat_zip, "%s/cheats/%s/%s.zip", getRootDir(), CoreName, psx_get_game_id());
printf("Trying cheat file: %s\n", cheat_zip);
memset(_z, 0, sizeof(mz_zip_archive));
if (mz_zip_reader_init_file(_z, cheat_zip, 0)) return true;
}
return false;
}
void cheats_init(const char *rom_path, uint32_t romcrc)
{
cheats.clear();
@@ -143,7 +173,16 @@ void cheats_init(const char *rom_path, uint32_t romcrc)
}
mz_zip_archive _z = {};
if (!mz_zip_reader_init_file(&_z, cheat_zip, 0))
if (is_psx() && !mz_zip_reader_init_file(&_z, cheat_zip, 0))
{
if (!cheat_init_psx(&_z, rom_path))
{
printf("no cheat file found\n");
return;
}
}
else if (!mz_zip_reader_init_file(&_z, cheat_zip, 0))
{
memset(&_z, 0, sizeof(_z));
if (!(pcecd_using_cd() || is_megacd()) || !find_in_same_dir(rom_path) || !mz_zip_reader_init_file(&_z, cheat_zip, 0))

View File

@@ -2257,6 +2257,7 @@ void HandleUI(void)
else if (is_psx() && ioctl_index == 1)
{
psx_mount_cd(user_io_ext_idx(selPath, fs_pFileExt) << 6 | (menusub + 1), ioctl_index, selPath);
cheats_init(selPath, 0);
}
else
{

View File

@@ -4,6 +4,9 @@
#include <string.h>
#include <inttypes.h>
#include <string>
#include <vector>
#include "../../file_io.h"
#include "../../user_io.h"
#include "../../spi.h"
@@ -497,6 +500,69 @@ void psx_read_cd(uint8_t *buffer, int lba, int cnt)
}
}
#define ROOT_FOLDER_LBA 150 + 22
std::vector<std::string> game_id_prefixes
{
"SCES",
"SLES",
"SCUS",
"SLUS",
"SCPM",
"SLPM",
"SCPS",
"SLPS",
};
const char* psx_get_game_id()
{
uint8_t buffer[CD_SECTOR_LEN];
static char game_id[11];
memset(game_id, 0, sizeof(game_id));
for (int sector = ROOT_FOLDER_LBA; sector < ROOT_FOLDER_LBA + 3; ++sector)
{
psx_read_cd(buffer, sector, 1);
//hexdump(buffer, CD_SECTOR_LEN);
char* start = nullptr;
for (const auto& prefix : game_id_prefixes)
{
start = (char*)memmem(buffer, CD_SECTOR_LEN, prefix.c_str(), prefix.size());
if (start) break;
}
if (!start) continue;
const size_t start_pos = start - (char*)buffer;
char* end = (char*)memmem(start, CD_SECTOR_LEN - start_pos, ";1", 2);
if (!end) continue;
size_t size = end - start;
// file is usually in CCCC_DDD.DD format, normalize to CCCC-DDDDD
if (size == 11)
{
if (start[4] == '_') start[4] = '-';
if (start[8] == '.')
{
start[8] = start[9];
start[9] = start[10];
--size;
}
}
const size_t max_length = sizeof(game_id) - 1;
if (size > max_length) size = max_length;
return (char*)memcpy(game_id, start, size);
}
return game_id;
}
static void mount_cd(int size, int index)
{
spi_uio_cmd_cont(UIO_SET_SDINFO);
@@ -523,6 +589,8 @@ 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());
int name_len = strlen(filename);
if (toc.tracks[0].type) // is first track a data?

View File

@@ -4,5 +4,6 @@
void psx_mount_cd(int f_index, int s_index, const char *filename);
void psx_fill_blanksave(uint8_t *buffer, uint32_t lba, int cnt);
void psx_read_cd(uint8_t *buffer, int lba, int cnt);
const char* psx_get_game_id();
#endif