psx: add cheats (#551)
* PSX: implement game ID * initialize cheats for PSX
This commit is contained in:
committed by
GitHub
parent
9ace959408
commit
652a8423d3
41
cheats.cpp
41
cheats.cpp
@@ -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))
|
||||
|
||||
1
menu.cpp
1
menu.cpp
@@ -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
|
||||
{
|
||||
|
||||
@@ -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?
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user