diff --git a/README.md b/README.md index 045a7824a..71a0242d6 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ There are minor graphics- and gameplay-related issues, and possibly occasional c * experimental high framerate support (up to 240 FPS): * set `Game.TickRateDivisor` to `0` in `pd.ini` to activate; * in practice the game will have issues running faster than ~165 FPS, so use VSync or `Video.FramerateLimit` to cap it. +* emulate the Transfer Pak functionality the game has on the Nintendo 64 to unlock some cheats automatically. Currently only 32-bit platforms are supported, namely x86 Windows and Linux. Note that 32-bit binaries will still work on 64-bit versions of those platforms, @@ -58,6 +59,8 @@ If you want to use a PAL or JPN ROM instead, put them into the `data` directory * PAL: ROM name `pd.pal-final.z64`, EXE name `pd.pal.exe`. * JPN: ROM name `pd.jpn-final.z64`, EXE name `pd.jpn.exe`. +Optionally, you can also put your Perfect Dark for GameBoy Color ROM named `pd.gbc` in the `data` directory if you want to emulate having the Nintendo 64's Transfer Pak and unlock some cheats automatically. + Additional information can be found in the [wiki](https://github.com/fgsfdsfgs/perfect_dark/wiki). A GPU supporting OpenGL 3.0 or above is required to run the port. diff --git a/port/include/romdata.h b/port/include/romdata.h index d1d411f1e..d72c411ed 100644 --- a/port/include/romdata.h +++ b/port/include/romdata.h @@ -22,4 +22,6 @@ u8 *romdataSegGetData(const char *segName); u8 *romdataSegGetDataEnd(const char *segName); u32 romdataSegGetSize(const char *segName); +void gbcRomCheck(void); + #endif diff --git a/port/src/main.c b/port/src/main.c index e31e090a2..fb225e6f6 100644 --- a/port/src/main.c +++ b/port/src/main.c @@ -107,6 +107,7 @@ int main(int argc, const char **argv) inputInit(); audioInit(); romdataInit(); + gbcRomCheck(); gameInit(); diff --git a/port/src/romdata.c b/port/src/romdata.c index effc67e65..20fc55557 100644 --- a/port/src/romdata.c +++ b/port/src/romdata.c @@ -11,6 +11,9 @@ #include "system.h" #include "preprocess.h" #include "platform.h" +#ifndef PLATFORM_N64 +#include "bss.h" +#endif /** * asset files and ROM segments can be replaced by optional external files, @@ -51,6 +54,9 @@ #define ROMDATA_MAX_FILES 2048 +#define GBC_ROM_NAME "pd.gbc" +#define GBC_ROM_SIZE 4194304 + u8 *g_RomFile; u32 g_RomFileSize; @@ -386,6 +392,45 @@ s32 romdataInit(void) return 0; } +void gbcRomCheck(void) +{ + u32 gbcRomSize; + u8* gbcRomFile = fsFileLoad(GBC_ROM_NAME, &gbcRomSize); + + if (!gbcRomFile) { + return; + } + + if (gbcRomSize != GBC_ROM_SIZE) { + free(gbcRomFile); + return; + } + + // ROM title + + if (memcmp(gbcRomFile + 0x134, "PerfDark VPDE", 15) != 0) { + free(gbcRomFile); + return; + } + + // Licensee code + + if (memcmp(gbcRomFile + 0x144, "4Y", 2) != 0) { + free(gbcRomFile); + return; + } + + // Header and global checksums + + if (gbcRomFile[0x14D] != 0xA1 || gbcRomFile[0x14E] != 0xAD || gbcRomFile[0x14F] != 0x0F) { + free(gbcRomFile); + return; + } + + g_validGbcRomFound = true; + free(gbcRomFile); +} + s32 romdataFileGetSize(s32 fileNum) { if (fileNum < 1 || fileNum >= ROMDATA_MAX_FILES) { diff --git a/src/game/pak.c b/src/game/pak.c index c58b59de3..09c2fef7d 100644 --- a/src/game/pak.c +++ b/src/game/pak.c @@ -329,6 +329,10 @@ u8 g_PaksPlugged = 0; bool var80075d14 = true; #endif +#ifndef PLATFORM_N64 +bool g_validGbcRomFound = false; +#endif + u32 pakGetBlockSize(s8 device) { return device == SAVEDEVICE_GAMEPAK ? 0x10 : 0x20; @@ -5982,6 +5986,7 @@ s32 pak0f11e750(s8 device) bool gbpakIsAnyPerfectDark(void) { +#ifdef PLATFORM_N64 s8 i; for (i = 0; i < MAX_PLAYERS; i++) { @@ -5991,6 +5996,9 @@ bool gbpakIsAnyPerfectDark(void) } return false; +#else + return g_validGbcRomFound; +#endif } /** diff --git a/src/include/bss.h b/src/include/bss.h index e07a9d931..a322a9a50 100644 --- a/src/include/bss.h +++ b/src/include/bss.h @@ -293,5 +293,8 @@ extern struct bossfile g_BossFile; extern struct chrdata *g_MpBotChrPtrs[MAX_BOTS]; extern s32 g_JpnMaxCacheItems; extern s32 var8009d370jf; +#ifndef PLATFORM_N64 +extern bool g_validGbcRomFound; +#endif #endif