From a2d0c53eb3044aef4c54a1d3917c2b8decba30ff Mon Sep 17 00:00:00 2001 From: Bobby Dilley Date: Sun, 3 Dec 2023 10:33:12 +0000 Subject: [PATCH 1/9] Update supported.md --- docs/supported.md | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/docs/supported.md b/docs/supported.md index 9ea9245..0b8fe10 100644 --- a/docs/supported.md +++ b/docs/supported.md @@ -10,6 +10,7 @@ Working is defined by getting into attract mode and running the game, but not ne - After Burner Climax - Ghost Squad Evolution - Harley Davidson +- Let's Go Jungle - Let's Go Jungle Special (boots to ride error) - Outrun 2 SP SDX - R-Tuned @@ -25,14 +26,5 @@ Working is defined by getting into attract mode and running the game, but not ne - Hummer - Initial D 4 - Initial D 5 -- Let's Go Jungle - Primevil - Virtua Tennis 3 - -## How to run specific games - -### Let's Go Jungle - -No, this game will not start. - -```LD_LIBRARY_PATH=$LD_LIBRARY_PATH:. LD_PRELOAD=lindbergh.so TEA_DIR=`pwd` ./lgj_final``` From bb5ff8b27d56ed5e372f93b543dcc33b67d7ad23 Mon Sep 17 00:00:00 2001 From: Bobby Dilley Date: Sun, 3 Dec 2023 10:38:34 +0000 Subject: [PATCH 2/9] Update lindbergh.conf --- docs/lindbergh.conf | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/docs/lindbergh.conf b/docs/lindbergh.conf index d88f2a1..a7ae4ab 100644 --- a/docs/lindbergh.conf +++ b/docs/lindbergh.conf @@ -25,22 +25,22 @@ HEIGHT 480 # Set if the emulator should emulate the rideboard used in the special games here # If this is set to 0, then the emulator will route the traffic to the serial device # defined in RIDEBOARD_PATH if it has been defined. -EMULATE_RIDEBOARD 0 +# EMULATE_RIDEBOARD 0 # Set if the emulator should emulate the driveboard used in driving games here # If this is set to 0, then the emulator will route the traffic to the serial device # defined in DRIVEBOARD_PATH if it has been defined. -EMULATE_DRIVEBOARD 0 +# EMULATE_DRIVEBOARD 0 # Set if the emulator should emulate the motion board from Outrun 2 SP SDX here # If this is set to 0, then the emulator will route the traffic to the serial device # defined in MOTIONBOARD_PATH if it has been defined. -EMULATE_MOTIONBOARD 0 +# EMULATE_MOTIONBOARD 0 # Set if the emulator should emulate JVS and use the keyboard/mouse for controls. # If this is set to 0, then the emulator will route the traffic to the serial device # defined in RIDEBOARD_PATH if it has been defined. -EMULATE_JVS 1 +# EMULATE_JVS 1 # Define the path to pass the JVS packets to # JVS_PATH /dev/ttyUSB0 @@ -55,4 +55,12 @@ EMULATE_JVS 1 # MOTIONBOARD_PATH /dev/ttyUSB0 # Set if the emulator should go full screen -FULLSCREEN 0 +# FULLSCREEN 0 + +# Patches a function at an address to return a number +# PATCH_RETURN A0000 1 + +# Patches a memory location to the following +# PATCH A0000 909090 + + From 9c6116ee05f5afd7801d74d7f6f51e5d91a04987 Mon Sep 17 00:00:00 2001 From: dkeruza Date: Mon, 4 Dec 2023 02:08:38 -0500 Subject: [PATCH 3/9] Added eeprom settings. --- .vscode/settings.json | 3 +- Makefile | 3 + docs/lindbergh.conf | 6 + src/libkswapapi/libkswapapi.o | Bin 2372 -> 2264 bytes src/lindbergh/config.c | 15 ++ src/lindbergh/config.h | 10 +- src/lindbergh/eeprom.c | 14 ++ src/lindbergh/eeprom_settings.c | 332 ++++++++++++++++++++++++++++++++ src/lindbergh/eeprom_settings.h | 5 + src/lindbergh/hook.c | 15 +- 10 files changed, 400 insertions(+), 3 deletions(-) create mode 100644 src/lindbergh/eeprom_settings.c create mode 100644 src/lindbergh/eeprom_settings.h diff --git a/.vscode/settings.json b/.vscode/settings.json index 71a6611..e5a1ae4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,5 +9,6 @@ "ioctl.h": "c", "segaeax.h": "c", "passthrough.h": "c" - } + }, + "C_Cpp.errorSquiggles": "disabled" } diff --git a/Makefile b/Makefile index 5bdf27b..b74ad07 100644 --- a/Makefile +++ b/Makefile @@ -26,3 +26,6 @@ libkswapapi.so: src/libkswapapi/libkswapapi.o clean: rm -rf $(BUILD) + rm -f src/lindbergh/*.o + rm -f src/libsegaapi/*.o + rm -f src/libkswapapi/*.o \ No newline at end of file diff --git a/docs/lindbergh.conf b/docs/lindbergh.conf index a7ae4ab..91573c8 100644 --- a/docs/lindbergh.conf +++ b/docs/lindbergh.conf @@ -64,3 +64,9 @@ HEIGHT 480 # PATCH A0000 909090 + +# Set the Region ( JP/US/EX ) +REGION US + +# Set if you want the game to be Free Play +FREEPLAY 1 \ No newline at end of file diff --git a/src/libkswapapi/libkswapapi.o b/src/libkswapapi/libkswapapi.o index d4806865b4a39307621c0ae291c38e493b109776..0ae0ad7d2db3dbc8d94864cb6594f895ed703966 100644 GIT binary patch delta 1064 zcmZ8fT}abW6uR|cI!Z^4ZI^)X;5)VQNC+2?ihC-o8sFxo%Tvh5i<~dJWs1S!5Zp~+uKCgO_ z-r%*cXNx}P-OC1p(`jIxqpBfp;(Id9=_*^HZRUOvpPYH=oigIIlr(|JERDH=obx}K z83a@h3SyIvf)79?@GR*(?OdTn=1i7ASb;1@Wxh+25MSTYuK3FiDrMzvue(g~dc5VH zDo>f>I#ce&GCDRGsh#SJ3`U0g!?3%D!>4K|sw!QT6^g4*akY9B*U7ekpPe2V?>^TR zK07cF36D|{y3x%fPRzZFuf&6^@ut{^@qnu-7Tv!RjO}|HkG^UOG`bq&Z(`Bb=76im z;cisxOCy#W_PpJBy~U4y&K7J&y)75{s`125W;|B)gw^}~)rtex-uwTZQ7jFb52Yy~ zgyDrt4`C-nTw+r2(;wkDluB>MA-|MtpeKn3w$Q>3Cj%8AhQ)k@ zD)Bn)w!SygGuGEN&_5UvVR@+ND|SrKl+gF2>*hlBVneoZqcEvUbk|i|<#R=?+Qyqj zr`nG7lVlNdY9rVKwPK(=NE@_H%xKL8&0y36ACzPfhxmZGLe|*iS+IKXMKX&Tjgfy8 zL5*GaZM)0`MEpiXtGJ^n(QU%-NMy#~Z@?F67aJODMY7}q939wB2@Qb0(Y+*6gGheC zX+@$r`ynifNJ+LNK1+GI%dpXSjDJgVKpgZI(;6IdwBkRp*1-rYM)sw hYYQ_jAz=v?%~~hcwS{s6-V#W>+p06lPGqc;^%q7Ft2_Vz literal 2372 zcma)6O>7%Q6rSCO9pJMYbV`|et8 zT}mkoNMVVgB*fRbfn`yVbK;bESlP!Q|2g^iy}b{AyZhJi@o|npw_d;VQTE9@n_#ob zKP%6Jju&zKpcFzpsA+~&o?srOlb>&avwF}yLN4Bz1*S3D z<%=b&c%|@s;d0^W64lG6KV2!wS;Xgrl^0Z2mBk2eJ)utc#QQL#)MqcY`d+E|rxza3Gw&AwF zv$cxTjgJDa6@@|Ak1PG)W;U!} zj&pcv$!_|I)AO99)ejDA_fR++we6K_HD`N${nfQyXZPAlZOvh-JTQYRPk^4pRoN|x z7O`rHRJ`b=YV?d8u1ArcY?hoaDUWpDQRFMI|t-6F9Qj$>3yRwTCZ|3|5+gOagPZ*19JZ~ z`}Zs~^#3ovDty%a_z?i}@!keZKI#om+b*z1MuV|Ym#(9QWXsU84sI`V^Iq41CI+nd z0=P*=gRupW4NucuV3~{tV|xQ~`nzAH`p3V5`R;q*O$<}yA+Qz$#`ZQ8>3rWJ0q@N^ zxL+pU$KV;mJ`%1&_7#zm$OYLV&iGCL&(~s~Cko`1f`k8+> z?Ytl1M<8R2-z_kFBLl|oJ1Eli-iBccI@Zg-ApKZ>Iu}IoEAmyLlindberghColour = RED; } + else if (strcmp(command, "REGION") == 0) + { + char region[256]; + strcpy(region, getNextToken(NULL, " ", &saveptr)); + if (strcmp(region, "JP") == 0) + config->region = JP; + else if (strcmp(region, "US") == 0) + config->region = US; + else + config->region = EX; + } + else if (strcmp(command, "FREEPLAY") == 0) + config->freeplay = atoi(getNextToken(NULL, " ", &saveptr)); else printf("Error: Unknown settings command %s\n", command); } @@ -257,6 +270,8 @@ int initConfig() config.width = 1024; config.height = 768; config.crc32 = elf_crc; + config.region = US; + config.freeplay = 1; if (detectGame(config.crc32) != 0) { printf("Warning: Unsure what game this is, using default configuration values.\n"); diff --git a/src/lindbergh/config.h b/src/lindbergh/config.h index b0f2c7c..e3ac82d 100644 --- a/src/lindbergh/config.h +++ b/src/lindbergh/config.h @@ -35,6 +35,13 @@ typedef enum NOT_WORKING }GameStatus; +typedef enum +{ + JP, + US, + EX +}gameRegion; + typedef struct { int emulateRideboard; @@ -54,7 +61,8 @@ typedef struct Colour lindberghColour; GameStatus gameStatus; uint32_t crc32; - + gameRegion region; + int freeplay; } EmulatorConfig; int initConfig(); diff --git a/src/lindbergh/eeprom.c b/src/lindbergh/eeprom.c index c814309..072632c 100644 --- a/src/lindbergh/eeprom.c +++ b/src/lindbergh/eeprom.c @@ -3,6 +3,7 @@ #include #include "eeprom.h" +#include "eeprom_settings.h" #include "config.h" #define I2C_SMBUS_BLOCK_MAX 32 @@ -46,6 +47,19 @@ int initEeprom() eeprom = fopen(eepromPath, "rb+"); + if(eepromSettingsInit(eeprom) !=0) + { + printf("Error initializing eeprom settings."); + fclose(eeprom); + return 1; + } + + if(getRegion() != getConfig()->region) + setRegion(eeprom, getConfig()->region); + + if(getFreeplay() != getConfig()->freeplay) + setFreeplay(eeprom, getConfig()->freeplay); + fseek(eeprom, 0, SEEK_SET); return 0; diff --git a/src/lindbergh/eeprom_settings.c b/src/lindbergh/eeprom_settings.c new file mode 100644 index 0000000..faf6001 --- /dev/null +++ b/src/lindbergh/eeprom_settings.c @@ -0,0 +1,332 @@ +#include +#include +#include +#include + +#include "config.h" +#include "eeprom_settings.h" + +uint32_t crc32_table[255]; + +typedef struct +{ + uint16_t offset; + uint16_t size; +} eepromOffsets; + +typedef enum +{ + STATIC, + NETWORK_TYPE, + ETH0, + ETH1, + CREDIT, + BACKUP +} eepromSection; + +eepromOffsets eepromOffsetTable[] = { + {0x0000, 0x0020}, // amSysDataRecord_Static + {0x00A0, 0x0010}, // amSysDataRecord_NetworkType + {0x00B0, 0x0020}, // amSysDataRecord_Eth0 + {0x00D0, 0x0020}, // amSysDataRecord_Eth1 + {0x0100, 0x0040}, // amSysDataRecord_Credit + {0x0400, 0x0060}}; // amSysDataRecord_Backup + +unsigned char eepromBuffer[512]; + +void build_crc32_table() +{ + for (uint32_t i = 0; i < 256; i++) + { + uint32_t ch = i; + uint32_t crc = 0; + for (size_t j = 0; j < 8; j++) + { + uint32_t b = (ch ^ crc) & 1; + crc >>= 1; + if (b) + crc = crc ^ 0xEDB88320; + ch >>= 1; + } + crc32_table[i] = crc; + } +} + +uint32_t gen_crc(int section, size_t n) +{ + unsigned char *buff = &eepromBuffer[eepromOffsetTable[section].offset + 4]; + unsigned long crc = 0xfffffffful; + size_t i; + for (i = 0; i < n; i++) + crc = crc32_table[*buff++ ^ (crc & 0xff)] ^ (crc >> 8); + return (crc); +} + +void addCRCtoBuffer(int section) +{ + uint32_t crc = gen_crc(section, eepromOffsetTable[section].size - 4); + memcpy(&eepromBuffer[eepromOffsetTable[section].offset], &crc, sizeof(uint32_t)); +} + +int fillBuffer(FILE *file) +{ + fseek(file, 0, SEEK_SET); + int b = fread(eepromBuffer, 1, 512, file); + if (b < 512) + return 1; + return 0; +} + +int checkCRCinBuffer(int section) +{ + uint32_t crc; + memcpy(&crc, &eepromBuffer[eepromOffsetTable[section].offset], 4); + if (crc != gen_crc(section, eepromOffsetTable[section].size - 4)) + return 1; + return 0; +} + +int createStaticSection() +{ + unsigned char *buff = &eepromBuffer[eepromOffsetTable[STATIC].offset]; + memset(buff, 0, eepromOffsetTable[STATIC].size); + buff[14] = 0; + memcpy(buff + 15, "AAGX-01A00009999", 16); + return 0; +} + +int createNetworkTypeSection() +{ + memset(&eepromBuffer[eepromOffsetTable[NETWORK_TYPE].offset], 0, + eepromOffsetTable[NETWORK_TYPE].size); + return 0; +} + +int createEthSection(int section) +{ + unsigned char *buff = &eepromBuffer[eepromOffsetTable[section].offset]; + memset(buff, 0, eepromOffsetTable[section].size); + uint32_t value = 1; + memcpy(buff + 8, &value, sizeof(uint32_t)); + value = inet_addr("10.0.0.1"); + if (section == ETH1) + value += (1 << 24); + memcpy(buff + 12, &value, sizeof(uint32_t)); + value = inet_addr("255.255.255.0"); + memcpy(buff + 16, &value, sizeof(uint32_t)); + value = inet_addr("0.0.0.0"); + memcpy(buff + 20, &value, sizeof(uint32_t)); + memcpy(buff + 24, &value, sizeof(uint32_t)); + memcpy(buff + 28, &value, sizeof(uint32_t)); + return 0; +} + +int createCreditSection() +{ + unsigned char *buff = &eepromBuffer[eepromOffsetTable[CREDIT].offset]; + memset(buff, 0, eepromOffsetTable[CREDIT].size); + buff[32] = 99; + buff[33] = 9; + buff[34] = 4; + buff[35] = 0; // Coin chute type [COMMON (Default) / INDIVIDUAL] + buff[36] = 1; // Service Type [COMMON / INDIVIDUAL (Default)] + buff[38] = 1; // + buff[39] = 0; // Freeplay set to 1 + buff[40] = 1; // Credits Chute #1 + buff[41] = 1; // Credits Chute #1 + buff[42] = 0; // + buff[43] = 1; // Coins + for (size_t i = 0; i < 8; i++) + { + buff[44 + i] = 1; + } + return 0; +} + +int writeSectiontoFile(FILE *file, int section) +{ + unsigned char *buff = &eepromBuffer[eepromOffsetTable[section].offset]; + // Original + if (fseek(file, eepromOffsetTable[section].offset, SEEK_SET) != 0) + return 1; + if (fwrite(buff, eepromOffsetTable[section].size, 1, file) != 1) + return 1; + + // Duplicate + if (fseek(file, eepromOffsetTable[section].offset + 0x200, SEEK_SET) != 0) + return 1; + if (fwrite(buff, eepromOffsetTable[section].size, 1, file) != 1) + return 1; + return 0; +} + +int getRegion() +{ + return eepromBuffer[14]; +} + +int setRegion(FILE *eeprom, int region) +{ + eepromBuffer[14] = region; + addCRCtoBuffer(STATIC); + if (writeSectiontoFile(eeprom, STATIC) != 0) + { + printf("Error setting the ."); + return 1; + } + return 0; +} + +int getFreeplay() +{ + return eepromBuffer[eepromOffsetTable[CREDIT].offset + 39]; +} + +int setFreeplay(FILE *eeprom, int freeplay) +{ + if (createCreditSection() != 0) + { + printf("Error setting Free Play."); + return 1; + } + eepromBuffer[eepromOffsetTable[CREDIT].offset + 39] = freeplay; + addCRCtoBuffer(CREDIT); + if (writeSectiontoFile(eeprom, CREDIT) != 0) + { + printf("Error setting Free Play."); + return 1; + } + return 0; +} + +int eepromSettingsInit( FILE *eeprom) +{ + build_crc32_table(); + + eeprom = fopen("eeprom.bin", "r+b"); + if (eeprom == NULL) + { + printf("eeprom.bin cannot be opened, let's create a new one.\n"); + eeprom = fopen("eeprom.bin", "w+b"); + } + fseek(eeprom, 0, SEEK_END); + int size = ftell(eeprom); + fseek(eeprom, 0, SEEK_SET); + if (size >= 832) // eeprom initialized at least by SEGABOOT + { + fillBuffer(eeprom); // Fills buffer with 1st 512 bytes of the eeprom file + if (checkCRCinBuffer(STATIC) != 0) + { + // Create section from scratch + if (createStaticSection() != 0) + { + printf("Error creating Static Section.\n"); + return 1; + } + else + { + addCRCtoBuffer(STATIC); + if (writeSectiontoFile(eeprom, STATIC) != 0) + { + printf("Error writing to eeprom.bin [STATIC]."); + return 1; + } + } + } + if (checkCRCinBuffer(NETWORK_TYPE) != 0) + { + // Create section from scratch + if (createNetworkTypeSection() != 0) + { + printf("Error creating NetworkType Section.\n"); + return 1; + } + else + { + addCRCtoBuffer(NETWORK_TYPE); + if (writeSectiontoFile(eeprom, NETWORK_TYPE) != 0) + { + printf("Error writing to eeprom.bin [NETWORK_TYPE]."); + return 1; + } + } + } + if (checkCRCinBuffer(ETH0) != 0) + { + // Create section from scratch + if (createEthSection(ETH0) != 0) + { + printf("Error creating Eth0 Section.\n"); + return 1; + } + else + { + addCRCtoBuffer(ETH0); + if (writeSectiontoFile(eeprom, ETH0) != 0) + { + printf("Error writing to eeprom.bin [ETH0]."); + return 1; + } + } + } + if (checkCRCinBuffer(ETH1) != 0) + { + // Create section from scratch + if (createEthSection(ETH1) != 0) + { + printf("Error creating Eth0 Section.\n"); + return 1; + } + else + { + addCRCtoBuffer(ETH1); + if (writeSectiontoFile(eeprom, ETH1) != 0) + { + printf("Error writing to eeprom.bin [ETH1]."); + return 1; + } + } + } + if (checkCRCinBuffer(CREDIT) != 0) + { + // Create section from scratch + if (createCreditSection() != 0) + { + printf("Error creating CREDIT Section.\n"); + return 1; + } + else + { + addCRCtoBuffer(CREDIT); + if (writeSectiontoFile(eeprom, NETWORK_TYPE) != 0) + { + printf("Error writing to eeprom.bin [CREDIT]]."); + return 1; + } + } + } + } + else + { + // Create all sections from scratch + if ((createStaticSection() != 0) || (createNetworkTypeSection() != 0) || + (createEthSection(ETH0) != 0) || (createEthSection(ETH1) != 0) || (createCreditSection() != 0)) + { + printf("Error creating section from scratch.\n"); + return 1; + } + addCRCtoBuffer(STATIC); + addCRCtoBuffer(NETWORK_TYPE); + addCRCtoBuffer(ETH0); + addCRCtoBuffer(ETH1); + addCRCtoBuffer(CREDIT); + if ((writeSectiontoFile(eeprom, STATIC) != 0) || (writeSectiontoFile(eeprom, NETWORK_TYPE) != 0) || + (writeSectiontoFile(eeprom, ETH0) != 0) || (writeSectiontoFile(eeprom, ETH1) != 0) || + (writeSectiontoFile(eeprom, CREDIT) != 0)) + { + printf("Error writing section from scratch.\n"); + return 1; + } + } + return 0; +} diff --git a/src/lindbergh/eeprom_settings.h b/src/lindbergh/eeprom_settings.h new file mode 100644 index 0000000..39f7173 --- /dev/null +++ b/src/lindbergh/eeprom_settings.h @@ -0,0 +1,5 @@ +int eepromSettingsInit(FILE *eeprom); +int getRegion(); +int getFreeplay(); +int setRegion(FILE *eeprom, int region); +int setFreeplay(FILE *eeprom, int freeplay); diff --git a/src/lindbergh/hook.c b/src/lindbergh/hook.c index 0202d09..1dbc367 100644 --- a/src/lindbergh/hook.c +++ b/src/lindbergh/hook.c @@ -256,7 +256,7 @@ FILE *fopen(const char *restrict pathname, const char *restrict mode) return _fopen("lindbergrc", mode); } - if (strcmp(pathname, "/usr/lib/boot/logo.tga") == 0) + if ((strcmp(pathname, "/usr/lib/boot/logo.tga") == 0) || (strcmp(pathname, "/usr/lib/boot/logo.tga") == 0)) { return _fopen("logo.tga", mode); } @@ -278,6 +278,19 @@ FILE *fopen(const char *restrict pathname, const char *restrict mode) return fileHooks[CPUINFO]; } + if (strcmp(pathname, "/usr/lib/boot/logo_red.tga") == 0) + { + return _fopen("logo_red.tga", mode); + } + if (strcmp(pathname, "/usr/lib/boot/SEGA_KakuGothic-DB-Roman_12.tga") == 0) + { + return _fopen("SEGA_KakuGothic-DB-Roman_12.tga", mode); + } + + if (strcmp(pathname, "/usr/lib/boot/SEGA_KakuGothic-DB-Roman_12.abc") == 0) + { + return _fopen("SEGA_KakuGothic-DB-Roman_12.abc", mode); + } return _fopen(pathname, mode); } From f4b05f1e972e18745956a9bc1934ef11cbe59759 Mon Sep 17 00:00:00 2001 From: dkeruza Date: Mon, 4 Dec 2023 02:15:58 -0500 Subject: [PATCH 4/9] Fixed missing # --- docs/lindbergh.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/lindbergh.conf b/docs/lindbergh.conf index 91573c8..8f9e2c7 100644 --- a/docs/lindbergh.conf +++ b/docs/lindbergh.conf @@ -66,7 +66,7 @@ HEIGHT 480 # Set the Region ( JP/US/EX ) -REGION US +# REGION US # Set if you want the game to be Free Play -FREEPLAY 1 \ No newline at end of file +# FREEPLAY 1 \ No newline at end of file From a460db00765b52321d7a030a494e3d5296147aee Mon Sep 17 00:00:00 2001 From: dkeruza Date: Wed, 6 Dec 2023 12:01:12 -0500 Subject: [PATCH 5/9] amDipswGetData- PCI_Card --- src/hookcrc32/hookcrc32.c | 2 +- src/hookcrc32/hookcrc32.so | Bin 16900 -> 17020 bytes src/lindbergh/config.c | 9 +++ src/lindbergh/config.h | 1 + src/lindbergh/graphics.c | 3 +- src/lindbergh/hook.c | 48 ++++++++++--- src/lindbergh/patch.c | 129 +++++++++++++++++++++++++++++----- src/lindbergh/pcidata.h | 28 ++++++++ src/lindbergh/securityboard.c | 25 ++++--- 9 files changed, 204 insertions(+), 41 deletions(-) create mode 100644 src/lindbergh/pcidata.h diff --git a/src/hookcrc32/hookcrc32.c b/src/hookcrc32/hookcrc32.c index 9f7e5fc..4181782 100644 --- a/src/hookcrc32/hookcrc32.c +++ b/src/hookcrc32/hookcrc32.c @@ -74,7 +74,7 @@ __attribute__((__constructor__)) static void setup(void) { dl_iterate_phdr(callback, NULL); //real_main = dlsym(RTLD_NEXT, "main"); - //exit(0); + exit(0); } __attribute__((__destructor__)) diff --git a/src/hookcrc32/hookcrc32.so b/src/hookcrc32/hookcrc32.so index ff67e24d404dd061a664ecd403e913281ddf5ee3..1744282b972c3c36632d8e9758806f9860b7cf5b 100755 GIT binary patch delta 2849 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 E0~wMiasU7T diff --git a/src/lindbergh/config.c b/src/lindbergh/config.c index ab5c00e..6af9b06 100644 --- a/src/lindbergh/config.c +++ b/src/lindbergh/config.c @@ -40,6 +40,13 @@ static int detectGame(uint32_t elf_crc) return 0; } + if(elf_crc == 0x3cc635ee) + { + config.game = SEGABOOT_2_4_SYM; + config.gameStatus = WORKING; + return 0; + } + if (elf_crc == 0xbc0c9ffa) { config.game = THE_HOUSE_OF_THE_DEAD_4; @@ -151,6 +158,8 @@ char *getGameName() return "SEGABOOT"; case SEGABOOT_2_4: return "SEGABOOT 2.4"; + case SEGABOOT_2_4_SYM: + return "SEGABOOT 2.4"; case SEGABOOT_2_6: return "SEGABOOT 2.6"; case OUTRUN: diff --git a/src/lindbergh/config.h b/src/lindbergh/config.h index e3ac82d..94e19ba 100644 --- a/src/lindbergh/config.h +++ b/src/lindbergh/config.h @@ -7,6 +7,7 @@ typedef enum UNKNOWN, SEGABOOT, SEGABOOT_2_4, + SEGABOOT_2_4_SYM, SEGABOOT_2_6, THE_HOUSE_OF_THE_DEAD_4, THE_HOUSE_OF_THE_DEAD_4_TEST, diff --git a/src/lindbergh/graphics.c b/src/lindbergh/graphics.c index bb7c369..11973a5 100644 --- a/src/lindbergh/graphics.c +++ b/src/lindbergh/graphics.c @@ -163,10 +163,11 @@ int XNextEvent(Display *display, XEvent *event_return) { case 28: setSwitch(SYSTEM, BUTTON_TEST, event_return->type == KeyPress); - //securityBoardSetSwitch(BUTTON_TEST, 1); + //securityBoardSetSwitch(BUTTON_TEST, event_return->type == KeyPress); break; case 39: setSwitch(PLAYER_1, BUTTON_SERVICE, event_return->type == KeyPress); + //securityBoardSetSwitch(BUTTON_SERVICE, event_return->type == KeyPress); break; case 14: incrementCoin(PLAYER_1, event_return->type == KeyPress); diff --git a/src/lindbergh/hook.c b/src/lindbergh/hook.c index 1dbc367..bc2b8d8 100644 --- a/src/lindbergh/hook.c +++ b/src/lindbergh/hook.c @@ -27,6 +27,7 @@ #include "rideboard.h" #include "securityboard.h" #include "patch.h" +#include "pcidata.h" #define HOOK_FILE_NAME "/dev/zero" @@ -37,10 +38,11 @@ #define CPUINFO 0 #define OSRELEASE 1 +#define PCI_CARD_1F0 2 int hooks[5] = {-1, -1, -1, -1}; -FILE *fileHooks[2] = {NULL, NULL}; -int fileRead[2] = {0, 0}; +FILE *fileHooks[3] = {NULL, NULL, NULL}; +int fileRead[3] = {0, 0, 0}; uint32_t elf_crc = 0; cpuvendor cpu_vendor = {0}; @@ -59,12 +61,10 @@ static void handleSegfault(int signal, siginfo_t *info, void *ptr) { ucontext_t *ctx = ptr; - //printf("Caught segfault at address %p\n", info->si_addr); - // Get the address of the instruction causing the segfault uint8_t *code = (uint8_t *)ctx->uc_mcontext.gregs[REG_EIP]; - printf("Code: 0x%08x - Port: 0x%08x\n", *code, (ctx->uc_mcontext.gregs[REG_EDX] & 0xFFFF) - basePortAddress); + printf("Code: 0x%08x - Port: 0x%08x\n", *code, (ctx->uc_mcontext.gregs[REG_EDX] & 0xFFFF)); switch (*code) { case 0xED: @@ -140,11 +140,6 @@ void __attribute__((constructor)) hook_init() // Get CPU ID getCPUID(); - FILE *file = fopen("dump_unpatched.bin","w+b"); - - fwrite((void *)0x08048000,0x630fac,1,file); - fclose(file); - // Implement SIGSEGV handler struct sigaction act; act.sa_sigaction = handleSegfault; @@ -291,6 +286,13 @@ FILE *fopen(const char *restrict pathname, const char *restrict mode) { return _fopen("SEGA_KakuGothic-DB-Roman_12.abc", mode); } + + if (strcmp(pathname, "/proc/bus/pci/00/1f.0") == 0) + { + fileRead[PCI_CARD_1F0] = 0; + fileHooks[PCI_CARD_1F0] = _fopen(HOOK_FILE_NAME, mode); + return fileHooks[PCI_CARD_1F0]; + } return _fopen(pathname, mode); } @@ -330,6 +332,20 @@ FILE *fopen64(const char *pathname, const char *mode) return _fopen64(pathname, mode); } +int fclose(FILE *stream) +{ + int (*_fclose)(FILE * stream) = dlsym(RTLD_NEXT, "fclose"); + for (int i = 0; i < 3; i++) + { + if(fileHooks[i] == stream) + { + int r = _fclose(stream); + fileHooks[i] = NULL; + return r; + } + } + return _fclose(stream); +} int openat(int dirfd, const char *pathname, int flags) { int (*_openat)(int dirfd, const char *pathname, int flags) = dlsym(RTLD_NEXT, "openat"); @@ -421,6 +437,18 @@ ssize_t read(int fd, void *buf, size_t count) return _read(fd, buf, count); } +size_t fread(void *buf, size_t size, size_t count, FILE *stream) +{ + size_t (*_fread)(void *buf, size_t size, size_t count, FILE *stream) = dlsym(RTLD_NEXT, "fread"); + + if(stream == fileHooks[PCI_CARD_1F0]) + { + memcpy(buf, pcidata, 68); + return 68; + } + return _fread(buf, size, count, stream); +} + ssize_t write(int fd, const void *buf, size_t count) { int (*_write)(int fd, const void *buf, size_t count) = dlsym(RTLD_NEXT, "write"); diff --git a/src/lindbergh/patch.c b/src/lindbergh/patch.c index ce2328c..3920cc1 100644 --- a/src/lindbergh/patch.c +++ b/src/lindbergh/patch.c @@ -7,6 +7,7 @@ #include "patch.h" #include "config.h" #include "hook.h" +#include "securityboard.h" extern cpuvendor cpu_vendor; @@ -91,6 +92,76 @@ int amDongleUpdate() return 0; } +int amLibInit() +{ + uint32_t *amLibContext = (uint32_t *)0x08dfa2c0;//0x0809cb00; + *amLibContext = 1; + uint32_t *amLibInitializad = (uint32_t *)0x08dfa2c4;//0x0809cb04; + uint16_t *amLibPort1 = (uint16_t *)(0x08dfa2c4 + 4);//(0x0809cb04 + 4); + uint16_t *amLibPort2 = (uint16_t *)(0x08dfa2c4 + 4);//(0x0809cb04 + 6); + uint32_t *bcLibInitialized = (uint32_t *)(0x08dfa2c4 + 8);//0x0809cb0c; + *amLibInitializad = 1; + *amLibPort1 = 0xd000; + *amLibPort2 = 0x0004; + *bcLibInitialized = 0; + int res = ((int (*)(void))0x084dedc4)();//0x08065d80)(); + if (res == 1) + *bcLibInitialized = 1; + return 0; +} + +int amDipswInit() +{ + uint32_t *amDipswContext = (uint32_t *)0x08df9cec;//0x0809c12c; + uint32_t *amDipswContext1 = (uint32_t *)(0x08df9cec + 4);//(0x0809c12c + 4); + uint32_t *amDipswContext2 = (uint32_t *)(0x08df9cec + 8);//(0x0809c12c + 8); + uint32_t *amDipswContext3 = (uint32_t *)(0x08df9cec + 12);//(0x0809c12c + 12); + //typedef void *(*___constant_c_and_count_memset)(uint32_t *, int, size_t); + //___constant_c_and_count_memset func = (___constant_c_and_count_memset)//0x0805c3d5; + //func(amDipswContext, 0, 4); + *amDipswContext = 1; + *amDipswContext1 = 1; + *amDipswContext2 = 1; + *amDipswContext3 = 1; + return 0; +} + +void print_binary(unsigned int number) +{ + if (number >> 1) + { + print_binary(number >> 1); + } + putc((number & 1) ? '1' : '0', stdout); +} + +int amDipswGetData(uint8_t *dip) +{ + //printf("amDipswGetData Called!!!!!\n"); + uint8_t result; + uint32_t data; + + securityBoardIn(0x38, &data); + + result = (~data & 4) != 0; // Test Button + if ((~data & 8) != 0) + result |= 2; // Service Button + if ((~data & 0x10) != 0) + result |= 4; // ?? + if ((char)data >= 0) + result |= 8; // ?? + if ((~data & 0x100) != 0) + result |= 0x10; // Rotation + if ((~data & 0x200) != 0) + result |= 0x20; // Resolution Dip 4 + if ((~data & 0x400) != 0) + result |= 0x40; // Resolution Dip 5 + if ((~data & 0x800) != 0) + result |= 0x80; // Resolution Dip 6 + *dip = result; + return 0; +} + void _putConsole(const char *format, ...) { va_list args; @@ -115,7 +186,7 @@ void _putConsole(const char *format, ...) } else if (*format == '0') { - format ++; + format++; if (*format == '2') { format++; @@ -161,6 +232,10 @@ int initPatch() detourFunction(0x084d5b40, amDongleInit); detourFunction(0x084d45f9, amDongleIsAvailable); detourFunction(0x084d4fef, amDongleUpdate); + detourFunction(0x084d44fc, stub0); + detourFunction(0x084d4485, amDipswGetData); + detourFunction(0x084d9118, amLibInit); + detourFunction(0x084d438c, amDipswInit); } break; case ABC_2006: @@ -199,7 +274,7 @@ int initPatch() detourFunction(0x081e3424, amDongleInit); detourFunction(0x081e3772, amDongleIsAvailable); detourFunction(0x081e369e, amDongleUpdate); - setVariable(0x081e7945, 0x00000001); //Test + setVariable(0x081e7945, 0x00000001); // Test } break; case OUTRUN: @@ -261,10 +336,10 @@ int initPatch() detourFunction(0x085c6010, amDongleInit); detourFunction(0x085c63cc, amDongleIsAvailable); detourFunction(0x085c62f0, amDongleUpdate); - detourFunction(0x080b3426, stub0); // Stub returns 0 - detourFunction(0x080cb6d4, stub0); // Stub returns 0 - detourFunction(0x0840889e, stub0); // Stub returns 0 - detourFunction(0x0840ab90, stub0); // Stub returns 0 + detourFunction(0x080b3426, stub0); // Stub returns 0 + detourFunction(0x080cb6d4, stub0); // Stub returns 0 + detourFunction(0x0840889e, stub0); // Stub returns 0 + detourFunction(0x0840ab90, stub0); // Stub returns 0 setVariable(0x080e17af, 0x000000b8); // Patch IDK what setVariable(0x080e17b3, 0x01e88300); // Patch IDK what } @@ -284,22 +359,22 @@ int initPatch() setVariable(0x08c08640, 2); // bcLibDebugLevel setVariable(0x08c08634, 2); // amOsinfoDebugLevel setVariable(0x08c08644, 0x0FFFFFFF); // s_logMask + detourFunction(0x08074a8c, _putConsole); // Debug Messages + detourFunction(0x084e50d8, amDongleInit); detourFunction(0x084e5459, amDongleIsAvailable); detourFunction(0x084e537d, amDongleUpdate); - detourFunction(0x08074a8c, _putConsole); + detourFunction(0x084e500e, amDipswGetData); + setVariable(0x080d1f02, 0x90909090); // Patch acpSystem::checkDongle setVariable(0x080d1f06, 0xE8C3C990); // Patch acpSystem::checkDongle setVariable(0x0807b76a, 0xc2839090); // Patch initializeArcadeBackup -// setVariable(0x082E006b, 0x00000280); // Set ResX -// setVariable(0x082E0078, 0x000001E0); // Set ResY + setVariable(0x082E006b, 0x00000780); // Set ResX + setVariable(0x082E0078, 0x00000438); // Set ResY - detourFunction(0x084e4efc, stub0); // Stub amDipswInit - detourFunction(0x084e500e, stub0); // Stub amDipswGetData - detourFunction(0x084e5086, stub0); // Stub amDipswSetLed - detourFunction(0x084e4f98, stub0); // Stub amDipswExit + detourFunction(0x084e5086, stub0); // Stub amDipswSetLed setVariable(0x0840d858, 0x1c899090); // No more Full Screen from the Game - //From Teknoparrot + // From Teknoparrot AMDFIX setVariable(0x083ef701, 0x00036ee9); // AMDFIX setVariable(0x084032e0, 0x8b90c933); // fix shader compilation with AMD GPUs setVariable(0x08523950, 0x000000c3); // Remove ADXM_SetupFramework (Not necessary) @@ -324,8 +399,8 @@ int initPatch() detourFunction(0x085106dc, amDongleIsAvailable); detourFunction(0x08510600, amDongleUpdate); detourFunction(0x08075012, _putConsole); - //setVariable(0x08303C4B, 0x00000780); // Set ResX - //setVariable(0x08303C58, 0x00000438); // Set ResY + // setVariable(0x08303C4B, 0x00000780); // Set ResX + // setVariable(0x08303C58, 0x00000438); // Set ResY setVariable(0x080dad63, 0x90909090); // Patch acpSystem::checkDongle setVariable(0x080dad67, 0xE8C3C990); // Patch acpSystem::checkDongle setVariable(0x0807e609, 0x90909090); // Patch initializeArcadeBackup @@ -352,12 +427,34 @@ int initPatch() detourFunction(0x086e2336, amDongleInit); detourFunction(0x086e0d81, amDongleIsAvailable); detourFunction(0x086e17e5, amDongleUpdate); + detourFunction(0x086e0c0d, amDipswGetData); + detourFunction(0x086e0c84, stub0); detourFunction(0x0808f9a8, _putConsole); setVariable(0x080dad63, 0x90909090); // Patch acpSystem::checkDongle setVariable(0x080dad67, 0xE8C3C990); // Patch acpSystem::checkDongle setVariable(0x0807e609, 0x90909090); // Patch initializeArcadeBackup setVariable(0x0807e60D, 0xC2839090); // Patch initializeArcadeBackup } + break; + case SEGABOOT_2_4_SYM: + { + detourFunction(0x0805e8b0, amDongleInit); + detourFunction(0x0805ebc3, amDongleIsAvailable); + detourFunction(0x0805eb2a, amDongleUpdate); + //detourFunction(0x08062cf8, amLibInit); + //detourFunction(0x0805c200, amDipswInit); + detourFunction(0x0805c30b, amDipswGetData); + } + break; + case VT3: + { + detourFunction(0x0831c724, amDongleInit); + detourFunction(0x0831ca37, amDongleIsAvailable); + detourFunction(0x0831c99e, amDongleUpdate); + detourFunction(0x0831c5d7, amDipswGetData); + detourFunction(0x0831c64f, stub0); + } + break; default: // Don't do any patches for random games break; diff --git a/src/lindbergh/pcidata.h b/src/lindbergh/pcidata.h new file mode 100644 index 0000000..b9614ee --- /dev/null +++ b/src/lindbergh/pcidata.h @@ -0,0 +1,28 @@ +const char pcidata[256] = { + 0x86, 0x80, 0x18, 0x29, 0x03, 0x01, 0x00, 0x00, 0x02, 0x00, 0x01, + 0x06, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf4, 0x1a, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x8a, 0x8b, + 0x8b, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x8a, 0x8b, 0x8b, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, + 0xd1, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const int pcidata_length = 256; \ No newline at end of file diff --git a/src/lindbergh/securityboard.c b/src/lindbergh/securityboard.c index 149a7ce..3b5415e 100644 --- a/src/lindbergh/securityboard.c +++ b/src/lindbergh/securityboard.c @@ -77,7 +77,6 @@ int securityBoardSetDipSwitch(int switchNumber, int value) int securityBoardSetSwitch(JVSInput switchNumber, int value) { - printf("Pressed\n"); switch (switchNumber) { case BUTTON_TEST: @@ -107,26 +106,26 @@ int securityBoardIn(uint16_t port, uint32_t *data) case SECURITY_BOARD_FRONT_PANEL: { uint32_t result = 0xFFFFFFFF; - if (securityBoard.serviceSwitch) - result &= ~0x08; - if (securityBoard.testSwitch) - result &= ~0x04; - if (securityBoard.dipSwitch[6]) + if (securityBoard.dipSwitch[6]) // bit12 result &= ~0x800; // DIP 6 - if (securityBoard.dipSwitch[5]) + if (securityBoard.dipSwitch[5]) // bit11 result &= ~0x400; // DIP 5 - if (securityBoard.dipSwitch[4]) + if (securityBoard.dipSwitch[4]) // bit10 result &= ~0x200; // DIP 4 - if (securityBoard.dipSwitch[3]) + if (securityBoard.dipSwitch[3]) // bit9 result &= ~0x100; // DIP 3 - if (securityBoard.dipSwitch[2]) + if (securityBoard.dipSwitch[2]) // bit8 result &= ~0x80; // DIP 2 - if (securityBoard.dipSwitch[1]) + if (securityBoard.dipSwitch[1]) // bit7 result &= ~0x40; // DIP 1 - if (securityBoard.dipSwitch[8]) + if (securityBoard.dipSwitch[8]) // bit6 result &= ~0x20; - if (securityBoard.dipSwitch[7]) + if (securityBoard.dipSwitch[7]) // bit5 result &= ~0x10; + if (securityBoard.serviceSwitch) // bit4 + result &= ~0x08; + if (securityBoard.testSwitch) // bit3 + result &= ~0x04; *data = result; } break; From a4b81bdb8547cc775cac177b4c886ae74e5fc502 Mon Sep 17 00:00:00 2001 From: dkeruza Date: Wed, 6 Dec 2023 15:15:48 -0500 Subject: [PATCH 6/9] getenv --- src/lindbergh/hook.c | 82 +++++++++++++++++++++++++++++-------------- src/lindbergh/patch.c | 1 + 2 files changed, 57 insertions(+), 26 deletions(-) diff --git a/src/lindbergh/hook.c b/src/lindbergh/hook.c index bc2b8d8..22eb038 100644 --- a/src/lindbergh/hook.c +++ b/src/lindbergh/hook.c @@ -43,6 +43,7 @@ int hooks[5] = {-1, -1, -1, -1}; FILE *fileHooks[3] = {NULL, NULL, NULL}; int fileRead[3] = {0, 0, 0}; +char envpath[100]; uint32_t elf_crc = 0; cpuvendor cpu_vendor = {0}; @@ -131,13 +132,12 @@ static void handleSegfault(int signal, siginfo_t *info, void *ptr) } } - void __attribute__((constructor)) hook_init() { printf("SEGA Lindbergh Loader\nRobert Dilley 2022\nNot for public consumption\n\n"); - // Get offsets of the Game's ELF and calculate CRC32. + // Get offsets of the Game's ELF and calculate CRC32. dl_iterate_phdr(callback, NULL); - // Get CPU ID + // Get CPU ID getCPUID(); // Implement SIGSEGV handler @@ -148,7 +148,7 @@ void __attribute__((constructor)) hook_init() initConfig(); - if(initPatch() != 0) + if (initPatch() != 0) exit(1); if (initEeprom() != 0) @@ -178,7 +178,7 @@ void __attribute__((constructor)) hook_init() securityBoardSetDipResolution(getConfig()->width, getConfig()->height); printf("Now emulating %s", getGameName()); - if(getConfig()->gameStatus == WORKING) + if (getConfig()->gameStatus == WORKING) { printf((" - Game is in working state.\n")); } @@ -290,7 +290,7 @@ FILE *fopen(const char *restrict pathname, const char *restrict mode) if (strcmp(pathname, "/proc/bus/pci/00/1f.0") == 0) { fileRead[PCI_CARD_1F0] = 0; - fileHooks[PCI_CARD_1F0] = _fopen(HOOK_FILE_NAME, mode); + fileHooks[PCI_CARD_1F0] = _fopen(HOOK_FILE_NAME, mode); return fileHooks[PCI_CARD_1F0]; } return _fopen(pathname, mode); @@ -334,10 +334,10 @@ FILE *fopen64(const char *pathname, const char *mode) int fclose(FILE *stream) { - int (*_fclose)(FILE * stream) = dlsym(RTLD_NEXT, "fclose"); + int (*_fclose)(FILE *stream) = dlsym(RTLD_NEXT, "fclose"); for (int i = 0; i < 3; i++) { - if(fileHooks[i] == stream) + if (fileHooks[i] == stream) { int r = _fclose(stream); fileHooks[i] = NULL; @@ -440,8 +440,8 @@ ssize_t read(int fd, void *buf, size_t count) size_t fread(void *buf, size_t size, size_t count, FILE *stream) { size_t (*_fread)(void *buf, size_t size, size_t count, FILE *stream) = dlsym(RTLD_NEXT, "fread"); - - if(stream == fileHooks[PCI_CARD_1F0]) + + if (stream == fileHooks[PCI_CARD_1F0]) { memcpy(buf, pcidata, 68); return 68; @@ -610,31 +610,34 @@ int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) /** * Function to calculate CRC32 checksum in memory. -*/ -uint32_t get_crc32(const char *s,size_t n) + */ +uint32_t get_crc32(const char *s, size_t n) { - uint32_t crc=0xFFFFFFFF; + uint32_t crc = 0xFFFFFFFF; - for(size_t i=0;i>=1; - if(b) crc=crc^0xEDB88320; - ch>>=1; - } + for (size_t i = 0; i < n; i++) + { + char ch = s[i]; + for (size_t j = 0; j < 8; j++) + { + uint32_t b = (ch ^ crc) & 1; + crc >>= 1; + if (b) + crc = crc ^ 0xEDB88320; + ch >>= 1; + } } return ~crc; } /** * Callback function to get the offset and size of the execution program in memory of the ELF we hook to. -*/ -static int callback(struct dl_phdr_info *info, size_t size, void *data) + */ +static int callback(struct dl_phdr_info *info, size_t size, void *data) { - if((info->dlpi_phnum >= 3) && (info->dlpi_phdr[2].p_type == PT_LOAD) && (info->dlpi_phdr[2].p_flags == 5)) + if ((info->dlpi_phnum >= 3) && (info->dlpi_phdr[2].p_type == PT_LOAD) && (info->dlpi_phdr[2].p_flags == 5)) { - elf_crc = get_crc32((void *)(info->dlpi_addr + info->dlpi_phdr[2].p_vaddr+10),128); + elf_crc = get_crc32((void *)(info->dlpi_addr + info->dlpi_phdr[2].p_vaddr + 10), 128); } return 1; } @@ -644,7 +647,7 @@ void getCPUID() unsigned eax; eax = 0; __get_cpuid(0, &eax, &cpu_vendor.ebx, &cpu_vendor.ecx, &cpu_vendor.edx); - printf("CPU Vendor: %.4s%.4s%.4s\n", (const char*)&cpu_vendor.ebx,(const char*)&cpu_vendor.edx,(const char*)&cpu_vendor.ecx); + printf("CPU Vendor: %.4s%.4s%.4s\n", (const char *)&cpu_vendor.ebx, (const char *)&cpu_vendor.edx, (const char *)&cpu_vendor.ecx); } /** @@ -662,6 +665,33 @@ int setenv(const char *name, const char *value, int overwrite) return _setenv(name, value, overwrite); } +/** + * Fake the TEA_DIR environment variable to games that require it to run +*/ +char *getenv(const char *name) +{ + char *(*_getenv)(const char *name) = dlsym(RTLD_NEXT, "getenv"); + + if ((strcmp(name, "TEA_DIR") == 0) && getConfig()->game == VT3) + { + if (getcwd(envpath, 100) == NULL) + return ""; + char *ptr = strrchr(envpath, '/'); + if (ptr == NULL) + return ""; + *ptr = '\0'; + return envpath; + } + else if (strcmp(name, "TEA_DIR") == 0) + { + if (getcwd(envpath, 100) == NULL) + return ""; + return envpath; + } + + return _getenv(name); +} + /** * Stop the game unsetting the DISPLAY environment variable */ diff --git a/src/lindbergh/patch.c b/src/lindbergh/patch.c index 3920cc1..1a23e14 100644 --- a/src/lindbergh/patch.c +++ b/src/lindbergh/patch.c @@ -453,6 +453,7 @@ int initPatch() detourFunction(0x0831c99e, amDongleUpdate); detourFunction(0x0831c5d7, amDipswGetData); detourFunction(0x0831c64f, stub0); + setVariable(0x0827ae1b, 0x34891beb); //Disable Fullscreen } break; default: From f38162cd096bd92a20adad426611504f85f02c01 Mon Sep 17 00:00:00 2001 From: dkeruza Date: Wed, 6 Dec 2023 17:00:57 -0500 Subject: [PATCH 7/9] VT3_testmode --- src/lindbergh/config.c | 9 +++++++++ src/lindbergh/config.h | 1 + src/lindbergh/hook.c | 1 + src/lindbergh/patch.c | 9 +++++++++ 4 files changed, 20 insertions(+) diff --git a/src/lindbergh/config.c b/src/lindbergh/config.c index 6af9b06..bc9dd31 100644 --- a/src/lindbergh/config.c +++ b/src/lindbergh/config.c @@ -135,6 +135,13 @@ static int detectGame(uint32_t elf_crc) if (elf_crc == 0xc4b7e89) { config.game = VT3; + config.gameStatus = WORKING; + return 0; + } + + if (elf_crc == 0xffe3b0fd) + { + config.game = VT3_TESTMODE; config.gameStatus = NOT_WORKING; return 0; } @@ -183,6 +190,8 @@ char *getGameName() return "R-Tuned Ultimate Street Racing"; case VT3: return "Virtua Tennis 3"; + case VT3_TESTMODE: + return "Virtua Tennis 3 - Testmode"; case VF5_REVC: return "Virtua Fighter 5 - RevC"; default: diff --git a/src/lindbergh/config.h b/src/lindbergh/config.h index 94e19ba..f6891ad 100644 --- a/src/lindbergh/config.h +++ b/src/lindbergh/config.h @@ -21,6 +21,7 @@ typedef enum SRTV, RTUNED, VT3, + VT3_TESTMODE, VF5_REVC } Game; diff --git a/src/lindbergh/hook.c b/src/lindbergh/hook.c index 22eb038..0919cb6 100644 --- a/src/lindbergh/hook.c +++ b/src/lindbergh/hook.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "hook.h" diff --git a/src/lindbergh/patch.c b/src/lindbergh/patch.c index 1a23e14..79b3b77 100644 --- a/src/lindbergh/patch.c +++ b/src/lindbergh/patch.c @@ -455,6 +455,15 @@ int initPatch() detourFunction(0x0831c64f, stub0); setVariable(0x0827ae1b, 0x34891beb); //Disable Fullscreen } + case VT3_TESTMODE: + { + detourFunction(0x0815f610, amDongleInit); + detourFunction(0x0815f923, amDongleIsAvailable); + detourFunction(0x0815f88a, amDongleUpdate); + detourFunction(0x0815d06b, amDipswGetData); + detourFunction(0x0815d0e3, stub0); + //setVariable(0x0827ae1b, 0x34891beb); //Disable Fullscreen + } break; default: // Don't do any patches for random games From 945e9574ef016fd11e2d0c2c14afb754960f30c8 Mon Sep 17 00:00:00 2001 From: dkeruza Date: Tue, 12 Dec 2023 21:51:34 -0500 Subject: [PATCH 8/9] XF86 hook, more games, cleanin up a bit. --- .vscode/c_cpp_properties.json | 22 ++ .vscode/settings.json | 4 +- src/hookcrc32/Makefile | 8 +- src/hookcrc32/{hookcrc32.so => getcrc} | Bin 17020 -> 17756 bytes src/hookcrc32/getcrc.c | 38 +++ src/hookcrc32/hookcrc32.c | 95 -------- src/lindbergh/baseboard.c | 1 + src/lindbergh/config.c | 56 ++++- src/lindbergh/config.h | 6 + src/lindbergh/graphics.c | 24 +- src/lindbergh/hook.c | 3 +- src/lindbergh/hook.h | 2 +- src/lindbergh/jvs.c | 6 +- src/lindbergh/patch.c | 314 +++++++++++++++++++------ 14 files changed, 396 insertions(+), 183 deletions(-) create mode 100644 .vscode/c_cpp_properties.json rename src/hookcrc32/{hookcrc32.so => getcrc} (51%) create mode 100644 src/hookcrc32/getcrc.c delete mode 100644 src/hookcrc32/hookcrc32.c diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..9f0e080 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,22 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${default}" + ], + "defines": [ + "__USE_POSIX", + "__USE_MISC" + ], + "cppStandard": "gnu++17", + "cStandard": "c99", + "intelliSenseMode": "linux-gcc-x86", + "forcedInclude": [ + "${workspaceFolder}/../vscode-preinclude.h" + ], + "compilerArgs": [] + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index e5a1ae4..af2744c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,5 +10,7 @@ "segaeax.h": "c", "passthrough.h": "c" }, - "C_Cpp.errorSquiggles": "disabled" + "C_Cpp.errorSquiggles": "disabled", + "C_Cpp.default.intelliSenseMode": "linux-gcc-x86", + "C_Cpp.default.compilerPath": "/usr/bin/gcc" } diff --git a/src/hookcrc32/Makefile b/src/hookcrc32/Makefile index 4a2e6f4..697b510 100644 --- a/src/hookcrc32/Makefile +++ b/src/hookcrc32/Makefile @@ -1,17 +1,15 @@ CC=gcc -m32 CFLAGS = -g -O0 -fPIC -m32 -Wall -Werror -Wno-unused-variable -Wno-unused-function -LD = g++ -m32 -LDFLAGS = -Wl,-z,defs -rdynamic -static-libstdc++ -static-libgcc -lc -ldl -lGL -lglut -lX11 -lm -lpthread -shared -nostdlib BUILD = build OBJS := $(patsubst %.c,%.o,$(wildcard *.c)) -all: hookcrc32.so +all: getcrc hookcrc32.so: $(OBJS) - $(LD) $(OBJS) $(LDFLAGS) $(CFLAGS) -o hookcrc32.so + $(LD) $(OBJS) $(LDFLAGS) $(CFLAGS) -o getcrc rm -f *.o clean: - rm -f hookcrc32.so + rm -f getcrc diff --git a/src/hookcrc32/hookcrc32.so b/src/hookcrc32/getcrc similarity index 51% rename from src/hookcrc32/hookcrc32.so rename to src/hookcrc32/getcrc index 1744282b972c3c36632d8e9758806f9860b7cf5b..adce8c35755f1b77cca371f717916aa765c5025d 100755 GIT binary patch literal 17756 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 +#include + + +uint32_t __crc32(const char *s, size_t n) { + uint32_t crc = 0xFFFFFFFF; + + for (size_t i = 0; i < n; i++) { + char ch = s[i]; + for (size_t j = 0; j < 8; j++) { + uint32_t b = (ch ^ crc) & 1; + crc >>= 1; + if (b) + crc = crc ^ 0xEDB88320; + ch >>= 1; + } + } + return ~crc; +} + +int main(int argc, char *argv[]) +{ + printf("You have entered %d arguments:\n", argc); + + for (int i = 0; i < argc; i++) { + printf("%s\n", argv[i]); + } + FILE *f; + char buffer[128]; + int crc = 0; + f = fopen(argv[1], "r+b"); + fseek(f, 10, SEEK_SET); + fread(buffer,128,1,f); + crc = __crc32(buffer, 128); + printf("Crc32: 0x%x\n", crc); + + return 0; +} diff --git a/src/hookcrc32/hookcrc32.c b/src/hookcrc32/hookcrc32.c deleted file mode 100644 index 4181782..0000000 --- a/src/hookcrc32/hookcrc32.c +++ /dev/null @@ -1,95 +0,0 @@ -#define _GNU_SOURCE -#include -#include -#include -#include - -static struct { - ElfW(Addr) start, end; -} *segments; -static int n; -static int (*real_main)(int argc,char **argv); - -uint32_t __crc32(const char *s,size_t n) { - uint32_t crc=0xFFFFFFFF; - - for(size_t i=0;i>=1; - if(b) crc=crc^0xEDB88320; - ch>>=1; - } - } - return ~crc; -} - -static int callback(struct dl_phdr_info *info, size_t size, void *data) { - /*n = info->dlpi_phnum; - segments = malloc(n * sizeof *segments); - for(int i = 0; i < n; ++i) { - segments[i].start = info->dlpi_addr + info->dlpi_phdr[i].p_vaddr; - segments[i].end = info->dlpi_addr + info->dlpi_phdr[i].p_vaddr + info->dlpi_phdr[i].p_memsz; - } - char *type; - int p_type; - printf("Name: \"%s\" (%d segments)\n", info->dlpi_name, info->dlpi_phnum); - for (int j = 0; j < info->dlpi_phnum; j++) { - p_type = info->dlpi_phdr[j].p_type; - type = (p_type == PT_LOAD) ? "PT_LOAD" : - (p_type == PT_DYNAMIC) ? "PT_DYNAMIC" : - (p_type == PT_INTERP) ? "PT_INTERP" : - (p_type == PT_NOTE) ? "PT_NOTE" : - (p_type == PT_INTERP) ? "PT_INTERP" : - (p_type == PT_PHDR) ? "PT_PHDR" : - (p_type == PT_TLS) ? "PT_TLS" : - (p_type == PT_GNU_EH_FRAME) ? "PT_GNU_EH_FRAME" : - (p_type == PT_GNU_STACK) ? "PT_GNU_STACK" : - (p_type == PT_GNU_RELRO) ? "PT_GNU_RELRO" : NULL; - - printf(" %2d: [%14p; memsz:0x%7x; size:0x%7x] flags: 0x%x; ", j, - (void *) (info->dlpi_addr + info->dlpi_phdr[j].p_vaddr), - info->dlpi_phdr[j].p_memsz, info->dlpi_phdr[j].p_filesz ,info->dlpi_phdr[j].p_flags); - if (type != NULL) - printf("%s\n", type); - else - printf("[other (0x%x)]\n", p_type);*/ - if((info->dlpi_phnum >= 3) && (info->dlpi_phdr[2].p_type == PT_LOAD) && (info->dlpi_phdr[2].p_flags == 5)) - { - // printf("Aca voy a dumpear el codigo:\n"); - //FILE *file = fopen("dump.bin","w+b"); - - //fwrite((void *)(info->dlpi_addr + info->dlpi_phdr[2].p_vaddr)+10,128,1,file); - //fclose(file); - int crc = 0; - crc = __crc32((void *)(info->dlpi_addr + info->dlpi_phdr[2].p_vaddr+10),128); - printf("Crc32: 0x%x\n",crc); - } - //} - return 1; -} - -__attribute__((__constructor__)) -static void setup(void) { - dl_iterate_phdr(callback, NULL); - //real_main = dlsym(RTLD_NEXT, "main"); - exit(0); -} - -__attribute__((__destructor__)) -static void teardown(void) { - free(segments); -} -/* -__attribute__((__noinline__)) -int main(int argc,char **argv) { - ElfW(Addr) addr = (ElfW(Addr))__builtin_extract_return_addr(__builtin_return_address(0)); - for(int i = 0; i < n; ++i) { - if(addr >= segments[i].start && addr < segments[i].end) { - // Do Nothing - return 0; - } - } - return real_main(argc, argv); -}*/ \ No newline at end of file diff --git a/src/lindbergh/baseboard.c b/src/lindbergh/baseboard.c index 970611a..e2d6fca 100644 --- a/src/lindbergh/baseboard.c +++ b/src/lindbergh/baseboard.c @@ -4,6 +4,7 @@ #include /* File control definitions */ #include /* Error number definitions */ #include /* Standard library functions like malloc, free, exit, and atoi */ +#include #include "baseboard.h" diff --git a/src/lindbergh/config.c b/src/lindbergh/config.c index bc9dd31..f6d4188 100644 --- a/src/lindbergh/config.c +++ b/src/lindbergh/config.c @@ -54,6 +54,13 @@ static int detectGame(uint32_t elf_crc) return 0; } + if (elf_crc == 0x5df569f5) + { + config.game = THE_HOUSE_OF_THE_DEAD_4_STRIPPED; + config.gameStatus = WORKING; + return 0; + } + if (elf_crc == 0x7235bda8) { config.game = THE_HOUSE_OF_THE_DEAD_4_TEST; @@ -61,6 +68,20 @@ static int detectGame(uint32_t elf_crc) return 0; } + if (elf_crc == 0x85c0c22a) + { + config.game = THE_HOUSE_OF_THE_DEAD_EX; + config.gameStatus = WORKING; + return 0; + } + + if (elf_crc == 0xb9a166bb) + { + config.game = THE_HOUSE_OF_THE_DEAD_EX_TEST; + config.gameStatus = WORKING; + return 0; + } + if (elf_crc == 0x6d055308) { config.game = OUTRUN; @@ -114,11 +135,24 @@ static int detectGame(uint32_t elf_crc) return 0; } + if (elf_crc == 0x7f3f9f0c) + { + config.game = ID4_E; + config.gameStatus = NOT_WORKING; + return 0; + } + if (elf_crc == 0xfb096f81) { config.game = SRTV; config.emulateDriveboard = 1; - config.emulateMotionboard = 1; + config.gameStatus = NOT_WORKING; + return 0; + } + + if (elf_crc == 0x77ebac34) + { + config.game = RAMBO; config.gameStatus = NOT_WORKING; return 0; } @@ -127,11 +161,17 @@ static int detectGame(uint32_t elf_crc) { config.game = RTUNED; config.emulateDriveboard = 1; - config.emulateMotionboard = 1; config.gameStatus = WORKING; return 0; } + if (elf_crc == 0x4c768eb4) + { + config.game = TOO_SPICY; + config.gameStatus = WORKING; + return 0; + } + if (elf_crc == 0xc4b7e89) { config.game = VT3; @@ -175,6 +215,12 @@ char *getGameName() return "The House of the Dead 4"; case THE_HOUSE_OF_THE_DEAD_4_TEST: return "The House of the Dead 4 - Test Menu"; + case THE_HOUSE_OF_THE_DEAD_4_STRIPPED: + return "The House of the Dead 4"; + case THE_HOUSE_OF_THE_DEAD_EX: + return "The House of the Dead EX"; + case THE_HOUSE_OF_THE_DEAD_EX_TEST: + return "The House of the Dead EX - Test Menu"; case LETS_GO_JUNGLE: return "Let's Go Jungle! Lost on the Island of Spice"; case LETS_GO_JUNGLE_SPECIAL: @@ -184,10 +230,16 @@ char *getGameName() return "After Burner Climax"; case ID4: return "Initial D 4"; + case ID4_E: + return "Initial D 4 Export"; case SRTV: return "SEGA Race TV"; + case RAMBO: + return "Rambo"; case RTUNED: return "R-Tuned Ultimate Street Racing"; + case TOO_SPICY: + return "Too Spicy"; case VT3: return "Virtua Tennis 3"; case VT3_TESTMODE: diff --git a/src/lindbergh/config.h b/src/lindbergh/config.h index f6891ad..70c478d 100644 --- a/src/lindbergh/config.h +++ b/src/lindbergh/config.h @@ -11,6 +11,9 @@ typedef enum SEGABOOT_2_6, THE_HOUSE_OF_THE_DEAD_4, THE_HOUSE_OF_THE_DEAD_4_TEST, + THE_HOUSE_OF_THE_DEAD_4_STRIPPED, + THE_HOUSE_OF_THE_DEAD_EX, + THE_HOUSE_OF_THE_DEAD_EX_TEST, OUTRUN, OUTRUN_TEST, LETS_GO_JUNGLE, @@ -18,8 +21,11 @@ typedef enum ABC_2006, ABC_2007, ID4, + ID4_E, SRTV, + RAMBO, RTUNED, + TOO_SPICY, VT3, VT3_TESTMODE, VF5_REVC diff --git a/src/lindbergh/graphics.c b/src/lindbergh/graphics.c index 11973a5..5ce49c9 100644 --- a/src/lindbergh/graphics.c +++ b/src/lindbergh/graphics.c @@ -163,11 +163,11 @@ int XNextEvent(Display *display, XEvent *event_return) { case 28: setSwitch(SYSTEM, BUTTON_TEST, event_return->type == KeyPress); - //securityBoardSetSwitch(BUTTON_TEST, event_return->type == KeyPress); + // securityBoardSetSwitch(BUTTON_TEST, event_return->type == KeyPress); break; case 39: setSwitch(PLAYER_1, BUTTON_SERVICE, event_return->type == KeyPress); - //securityBoardSetSwitch(BUTTON_SERVICE, event_return->type == KeyPress); + // securityBoardSetSwitch(BUTTON_SERVICE, event_return->type == KeyPress); break; case 14: incrementCoin(PLAYER_1, event_return->type == KeyPress); @@ -248,11 +248,29 @@ int XSetStandardProperties(Display *display, Window window, const char *window_n return _XSetStandardProperties(display, window, gameTitle, icon_name, icon_pixmap, argv, argc, hints); } -Bool XF86VidModeSwitchToMode(Display *display, int screen, XF86VidModeModeInfo *modeline) +Bool XF86VidModeSwitchToMode(Display *display, int screen, XF86VidModeModeInfo *modesinfo) { return 0; } +int XF86VidModeGetAllModeLines(Display *display, int screen, int *modecount_return, XF86VidModeModeInfo ***modesinfo) +{ + int (*_XF86VidModeGetAllModeLines)(Display *display, int screen, int *modecount_return, XF86VidModeModeInfo ***modesinfo) = dlsym(RTLD_NEXT, "XF86VidModeGetAllModeLines"); + + if (_XF86VidModeGetAllModeLines(display, screen, modecount_return, modesinfo) != 1) + { + printf("Error: Could not get list of screen modes.\n"); + exit(1); + } + else + { + XF86VidModeModeInfo **modes = *modesinfo; + modes[0]->hdisplay = getConfig()->width; + modes[0]->vdisplay = getConfig()->height; + } + return true; +} + typedef unsigned int uint; int glXSwapIntervalSGI(int interval) diff --git a/src/lindbergh/hook.c b/src/lindbergh/hook.c index 0919cb6..41eaf09 100644 --- a/src/lindbergh/hook.c +++ b/src/lindbergh/hook.c @@ -673,7 +673,8 @@ char *getenv(const char *name) { char *(*_getenv)(const char *name) = dlsym(RTLD_NEXT, "getenv"); - if ((strcmp(name, "TEA_DIR") == 0) && getConfig()->game == VT3) + if ((strcmp(name, "TEA_DIR") == 0) && ((getConfig()->game == VT3) || (getConfig()->game == VT3_TESTMODE) || + ((getConfig()->game == RAMBO)) || (getConfig()->game == TOO_SPICY))) { if (getcwd(envpath, 100) == NULL) return ""; diff --git a/src/lindbergh/hook.h b/src/lindbergh/hook.h index 36e0d2a..2b215b2 100644 --- a/src/lindbergh/hook.h +++ b/src/lindbergh/hook.h @@ -1,3 +1,4 @@ + uint32_t get_crc32(const char *s,size_t n); void getCPUID(); typedef struct @@ -6,4 +7,3 @@ typedef struct unsigned edx; unsigned ecx; }cpuvendor; - diff --git a/src/lindbergh/jvs.c b/src/lindbergh/jvs.c index bdd8208..0f8d57b 100644 --- a/src/lindbergh/jvs.c +++ b/src/lindbergh/jvs.c @@ -260,10 +260,13 @@ JVSStatus processPacket() outputPacket.data[outputPacket.length] = REPORT_SUCCESS; outputPacket.data[outputPacket.length + 1] = io.state.inputSwitch[0]; outputPacket.length += 2; + + //printf("SW=%08d\r", io.state.inputSwitch[0]); + for (int i = 0; i < inputPacket.data[index + 1]; i++) { for (int j = 0; j < inputPacket.data[index + 2]; j++) - { + { outputPacket.data[outputPacket.length++] = io.state.inputSwitch[i + 1] >> (8 - (j * 8)); } } @@ -623,7 +626,6 @@ int setSwitch(JVSPlayer player, JVSInput switchNumber, int value) { io.state.inputSwitch[player] &= ~switchNumber; } - return 1; } diff --git a/src/lindbergh/patch.c b/src/lindbergh/patch.c index 79b3b77..02e7790 100644 --- a/src/lindbergh/patch.c +++ b/src/lindbergh/patch.c @@ -72,11 +72,16 @@ static void detourFunction(uint32_t address, void *function) memcpy((void *)address, cave, 5); } -int stub0() +int stubRetZero() { return 0; } +int stubRetOne() +{ + return 1; +} + int amDongleInit() { return 0; @@ -94,17 +99,17 @@ int amDongleUpdate() int amLibInit() { - uint32_t *amLibContext = (uint32_t *)0x08dfa2c0;//0x0809cb00; + uint32_t *amLibContext = (uint32_t *)0x08dfa2c0; // 0x0809cb00; *amLibContext = 1; - uint32_t *amLibInitializad = (uint32_t *)0x08dfa2c4;//0x0809cb04; - uint16_t *amLibPort1 = (uint16_t *)(0x08dfa2c4 + 4);//(0x0809cb04 + 4); - uint16_t *amLibPort2 = (uint16_t *)(0x08dfa2c4 + 4);//(0x0809cb04 + 6); - uint32_t *bcLibInitialized = (uint32_t *)(0x08dfa2c4 + 8);//0x0809cb0c; + uint32_t *amLibInitializad = (uint32_t *)0x08dfa2c4; // 0x0809cb04; + uint16_t *amLibPort1 = (uint16_t *)(0x08dfa2c4 + 4); //(0x0809cb04 + 4); + uint16_t *amLibPort2 = (uint16_t *)(0x08dfa2c4 + 4); //(0x0809cb04 + 6); + uint32_t *bcLibInitialized = (uint32_t *)(0x08dfa2c4 + 8); // 0x0809cb0c; *amLibInitializad = 1; *amLibPort1 = 0xd000; *amLibPort2 = 0x0004; *bcLibInitialized = 0; - int res = ((int (*)(void))0x084dedc4)();//0x08065d80)(); + int res = ((int (*)(void))0x084dedc4)(); // 0x08065d80)(); if (res == 1) *bcLibInitialized = 1; return 0; @@ -112,13 +117,13 @@ int amLibInit() int amDipswInit() { - uint32_t *amDipswContext = (uint32_t *)0x08df9cec;//0x0809c12c; - uint32_t *amDipswContext1 = (uint32_t *)(0x08df9cec + 4);//(0x0809c12c + 4); - uint32_t *amDipswContext2 = (uint32_t *)(0x08df9cec + 8);//(0x0809c12c + 8); - uint32_t *amDipswContext3 = (uint32_t *)(0x08df9cec + 12);//(0x0809c12c + 12); - //typedef void *(*___constant_c_and_count_memset)(uint32_t *, int, size_t); + uint32_t *amDipswContext = (uint32_t *)0x08df9cec; // 0x0809c12c; + uint32_t *amDipswContext1 = (uint32_t *)(0x08df9cec + 4); //(0x0809c12c + 4); + uint32_t *amDipswContext2 = (uint32_t *)(0x08df9cec + 8); //(0x0809c12c + 8); + uint32_t *amDipswContext3 = (uint32_t *)(0x08df9cec + 12); //(0x0809c12c + 12); + // typedef void *(*___constant_c_and_count_memset)(uint32_t *, int, size_t); //___constant_c_and_count_memset func = (___constant_c_and_count_memset)//0x0805c3d5; - //func(amDipswContext, 0, 4); + // func(amDipswContext, 0, 4); *amDipswContext = 1; *amDipswContext1 = 1; *amDipswContext2 = 1; @@ -137,7 +142,7 @@ void print_binary(unsigned int number) int amDipswGetData(uint8_t *dip) { - //printf("amDipswGetData Called!!!!!\n"); + // printf("amDipswGetData Called!!!!!\n"); uint8_t result; uint32_t data; @@ -145,19 +150,19 @@ int amDipswGetData(uint8_t *dip) result = (~data & 4) != 0; // Test Button if ((~data & 8) != 0) - result |= 2; // Service Button + result |= 2; // Service Button if ((~data & 0x10) != 0) - result |= 4; // ?? + result |= 4; // ?? if ((char)data >= 0) - result |= 8; // ?? + result |= 8; // ?? if ((~data & 0x100) != 0) - result |= 0x10; // Rotation + result |= 0x10; // Rotation if ((~data & 0x200) != 0) - result |= 0x20; // Resolution Dip 4 + result |= 0x20; // Resolution Dip 4 if ((~data & 0x400) != 0) - result |= 0x40; // Resolution Dip 5 + result |= 0x40; // Resolution Dip 5 if ((~data & 0x800) != 0) - result |= 0x80; // Resolution Dip 6 + result |= 0x80; // Resolution Dip 6 *dip = result; return 0; } @@ -221,6 +226,7 @@ int initPatch() { case RTUNED: { + // Security detourFunction(0x08366846, amDongleInit); detourFunction(0x08365301, amDongleIsAvailable); detourFunction(0x08365cf7, amDongleUpdate); @@ -229,17 +235,18 @@ int initPatch() case SRTV: { + // Security detourFunction(0x084d5b40, amDongleInit); detourFunction(0x084d45f9, amDongleIsAvailable); detourFunction(0x084d4fef, amDongleUpdate); - detourFunction(0x084d44fc, stub0); + // Fixes + detourFunction(0x084d44fc, stubRetZero); // Stub amDipswSetLed detourFunction(0x084d4485, amDipswGetData); - detourFunction(0x084d9118, amLibInit); - detourFunction(0x084d438c, amDipswInit); } break; case ABC_2006: { + // Debug Messages setVariable(0x0a0a37e4, 2); // amBackupDebugLevel setVariable(0x0a0a3800, 2); // amCreditDebugLevel setVariable(0x0a0a3a58, 2); // amDipswDebugLevel @@ -252,13 +259,20 @@ int initPatch() setVariable(0x0a0a3a74, 2); // amOsinfoDebugLevel setVariable(0x0a0a3a78, 2); // amSysDataDebugLevel setVariable(0x0a0a3a80, 2); // bcLibDebugLevel + // Security detourFunction(0x081e4980, amDongleInit); detourFunction(0x081e4cce, amDongleIsAvailable); detourFunction(0x081e4bfa, amDongleUpdate); + // Fixes + detourFunction(0x081e48b6, amDipswGetData); + detourFunction(0x081e492e, stubRetZero); // Stub amDipswSetLed + // Does not work + setVariable(0x08061c31, 0x0000000c); // Force HD resolution } break; case ABC_2007: { + // Debug Messages setVariable(0x0a0a0d24, 2); // amBackupDebugLevel setVariable(0x0a0a0d40, 2); // amCreditDebugLevel setVariable(0x0a0a0f98, 2); // amDipswDebugLevel @@ -271,14 +285,18 @@ int initPatch() setVariable(0x0a0a0fb4, 2); // amOsinfoDebugLevel setVariable(0x0a0a0fb8, 2); // amSysDataDebugLevel setVariable(0x0a0a0fc0, 2); // bcLibDebugLevel + // Security detourFunction(0x081e3424, amDongleInit); detourFunction(0x081e3772, amDongleIsAvailable); detourFunction(0x081e369e, amDongleUpdate); - setVariable(0x081e7945, 0x00000001); // Test + // Fixes + detourFunction(0x081e335a, amDipswGetData); + detourFunction(0x081e33d2, stubRetZero); // Stub amDipswSetLed } break; case OUTRUN: { + // Debug Messages setVariable(0x0893a24c, 2); // amBackupDebugLevel setVariable(0x0893a260, 2); // amCreditDebugLevel setVariable(0x0893a4b8, 2); // amDipswDebugLevel @@ -291,14 +309,19 @@ int initPatch() setVariable(0x0893a4d4, 2); // amOsinfoDebugLevel setVariable(0x0893a4d8, 2); // amSysDataDebugLevel setVariable(0x0893a4e0, 2); // bcLibDebugLevel + // Security detourFunction(0x08190e80, amDongleInit); detourFunction(0x08191201, amDongleIsAvailable); detourFunction(0x08191125, amDongleUpdate); + // Fixes + detourFunction(0x08190db6, amDipswGetData); + detourFunction(0x08190e2e, stubRetZero); // Stub amDipswSetLed } break; case THE_HOUSE_OF_THE_DEAD_4: { + // Debug Messages setVariable(0x0a737c60, 2); // amBackupDebugLevel setVariable(0x0a737c64, 2); // amChunkDataDebugLevel setVariable(0x0a737c80, 2); // amCreditDebugLevel @@ -313,71 +336,128 @@ int initPatch() setVariable(0x0a737f1c, 2); // amSysDataDebugLevel setVariable(0x0a737f20, 2); // bcLibDebugLevel setVariable(0x0a737f24, 0x0FFFFFFF); // s_logMask + // Security detourFunction(0x08320178, amDongleInit); detourFunction(0x08320459, amDongleIsAvailable); detourFunction(0x083203c0, amDongleUpdate); + // Fixes + detourFunction(0x0831ddd7, amDipswGetData); + detourFunction(0x0831de4f, stubRetZero); // Stub amDipswSetLed + // CPU patch to support AMD processors setVariable(0x0837d6aa, cpu_vendor.ebx); setVariable(0x0837d6ba, cpu_vendor.edx); setVariable(0x0837d6c5, cpu_vendor.ecx); } break; + case THE_HOUSE_OF_THE_DEAD_4_STRIPPED: + { + //// Security + detourFunction(0x0831ad04, amDongleInit); + detourFunction(0x0831b017, amDongleIsAvailable); + detourFunction(0x0831af7e, amDongleUpdate); + //// Fixes + detourFunction(0x0831875f, amDipswGetData); + detourFunction(0x083187d7, stubRetZero); // Stub amDipswSetLed + //// CPU patch to support AMD processors + setVariable(0x0837963a, cpu_vendor.ebx); + setVariable(0x0837964a, cpu_vendor.edx); + setVariable(0x08379655, cpu_vendor.ecx); + } + break; case THE_HOUSE_OF_THE_DEAD_4_TEST: { detourFunction(0x080677a0, amDongleInit); detourFunction(0x08067a81, amDongleIsAvailable); detourFunction(0x080679e8, amDongleUpdate); + // Fixes + detourFunction(0x08067653, amDipswGetData); + detourFunction(0x080676cb, stubRetZero); // Stub amDipswSetLed + // CPU patch to support AMD processors setVariable(0x0807217a, cpu_vendor.ebx); setVariable(0x0807218a, cpu_vendor.edx); setVariable(0x08072195, cpu_vendor.ecx); } break; + case THE_HOUSE_OF_THE_DEAD_EX: + { + detourFunction(0x084ba886, amDongleInit); + detourFunction(0x084b9341, amDongleIsAvailable); + detourFunction(0x084b9d37, amDongleUpdate); + // Fixes + detourFunction(0x084b6a69, amDipswGetData); + detourFunction(0x084b6adf, stubRetZero); // Stub amDipswSetLed + // CPU patch to support AMD processors + setVariable(0x0849E2AD, cpu_vendor.ebx); + setVariable(0x0849E2B7, cpu_vendor.edx); + setVariable(0x0849E2C1, cpu_vendor.ecx); + } + break; + case THE_HOUSE_OF_THE_DEAD_EX_TEST: + { + detourFunction(0x08078996, amDongleInit); + detourFunction(0x08077451, amDongleIsAvailable); + detourFunction(0x08077e47, amDongleUpdate); + // Fixes + detourFunction(0x080772dd, amDipswGetData); + detourFunction(0x08077353, stubRetZero); // Stub amDipswSetLed + // CPU patch to support AMD processors + setVariable(0x080847BD, cpu_vendor.ebx); + setVariable(0x080847C7, cpu_vendor.edx); + setVariable(0x080847D1, cpu_vendor.ecx); + } + break; case VF5_REVC: { + // Security detourFunction(0x085c6010, amDongleInit); detourFunction(0x085c63cc, amDongleIsAvailable); detourFunction(0x085c62f0, amDongleUpdate); - detourFunction(0x080b3426, stub0); // Stub returns 0 - detourFunction(0x080cb6d4, stub0); // Stub returns 0 - detourFunction(0x0840889e, stub0); // Stub returns 0 - detourFunction(0x0840ab90, stub0); // Stub returns 0 - setVariable(0x080e17af, 0x000000b8); // Patch IDK what - setVariable(0x080e17b3, 0x01e88300); // Patch IDK what + // Fixes and patches to bypss network check + detourFunction(0x085c5f46, amDipswGetData); + detourFunction(0x085c5fbe, stubRetZero); // Stub amDipswSetLed + detourFunction(0x080b3426, stubRetZero); // Stub returns 0 + detourFunction(0x080cb6d4, stubRetZero); // Stub returns 0 + detourFunction(0x0840889e, stubRetZero); // Stub returns 0 + detourFunction(0x0840ab90, stubRetZero); // Stub returns 0 + setVariable(0x080e17af, 0x000000b8); // Patch IDK what + setVariable(0x080e17b3, 0x01e88300); // Patch IDK what } break; case LETS_GO_JUNGLE: { - setVariable(0x08c083a4, 2); // amBackupDebugLevel - setVariable(0x08c083c0, 2); // amCreditDebugLevel - setVariable(0x08c08618, 2); // amDipswDebugLevel - setVariable(0x08c0861c, 2); // amDongleDebugLevel - setVariable(0x08c08620, 2); // amEepromDebugLevel - setVariable(0x08c08624, 2); // amHwmonitorDebugLevel - setVariable(0x08c08628, 2); // amJvsDebugLevel - setVariable(0x08c0862c, 2); // amLibDebugLevel - setVariable(0x08c08630, 2); // amMiscDebugLevel - setVariable(0x08c08638, 2); // amSysDataDebugLevel - setVariable(0x08c08640, 2); // bcLibDebugLevel - setVariable(0x08c08634, 2); // amOsinfoDebugLevel - setVariable(0x08c08644, 0x0FFFFFFF); // s_logMask + setVariable(0x08c083a4, 2); // amBackupDebugLevel + setVariable(0x08c083c0, 2); // amCreditDebugLevel + setVariable(0x08c08618, 2); // amDipswDebugLevel + setVariable(0x08c0861c, 2); // amDongleDebugLevel + setVariable(0x08c08620, 2); // amEepromDebugLevel + setVariable(0x08c08624, 2); // amHwmonitorDebugLevel + setVariable(0x08c08628, 2); // amJvsDebugLevel + setVariable(0x08c0862c, 2); // amLibDebugLevel + setVariable(0x08c08630, 2); // amMiscDebugLevel + setVariable(0x08c08638, 2); // amSysDataDebugLevel + setVariable(0x08c08640, 2); // bcLibDebugLevel + setVariable(0x08c08634, 2); // amOsinfoDebugLevel + setVariable(0x08c08644, 0x0FFFFFFF); // s_logMask detourFunction(0x08074a8c, _putConsole); // Debug Messages - + // Security detourFunction(0x084e50d8, amDongleInit); detourFunction(0x084e5459, amDongleIsAvailable); detourFunction(0x084e537d, amDongleUpdate); - detourFunction(0x084e500e, amDipswGetData); - setVariable(0x080d1f02, 0x90909090); // Patch acpSystem::checkDongle setVariable(0x080d1f06, 0xE8C3C990); // Patch acpSystem::checkDongle setVariable(0x0807b76a, 0xc2839090); // Patch initializeArcadeBackup - setVariable(0x082E006b, 0x00000780); // Set ResX - setVariable(0x082E0078, 0x00000438); // Set ResY + // Fixes + detourFunction(0x084e500e, amDipswGetData); + detourFunction(0x084e5086, stubRetZero); // Stub amDipswSetLed + setVariable(0x0840d858, 0x1c899090); // No more Full Screen from the Game + // Set Resolution + // setVariable(0x082E006b, 0x00000780); // Set ResX + // setVariable(0x082E0078, 0x00000438); // Set ResY - detourFunction(0x084e5086, stub0); // Stub amDipswSetLed - setVariable(0x0840d858, 0x1c899090); // No more Full Screen from the Game // From Teknoparrot AMDFIX - setVariable(0x083ef701, 0x00036ee9); // AMDFIX - setVariable(0x084032e0, 0x8b90c933); // fix shader compilation with AMD GPUs - setVariable(0x08523950, 0x000000c3); // Remove ADXM_SetupFramework (Not necessary) + // setVariable(0x083ef701, 0x00036ee9); // AMDFIX + // setVariable(0x084032e0, 0x8b90c933); // fix shader compilation with AMD GPUs + // setVariable(0x08523950, 0x000000c3); // Remove ADXM_SetupFramework (Not necessary) } break; case LETS_GO_JUNGLE_SPECIAL: @@ -395,18 +475,23 @@ int initPatch() setVariable(0x08c45680, 2); // bcLibDebugLevel setVariable(0x08c45674, 2); // amOsinfoDebugLevel setVariable(0x08c45684, 0x0FFFFFFF); // s_logMask + detourFunction(0x08075012, _putConsole); + // Security detourFunction(0x08510320, amDongleInit); detourFunction(0x085106dc, amDongleIsAvailable); detourFunction(0x08510600, amDongleUpdate); - detourFunction(0x08075012, _putConsole); - // setVariable(0x08303C4B, 0x00000780); // Set ResX - // setVariable(0x08303C58, 0x00000438); // Set ResY setVariable(0x080dad63, 0x90909090); // Patch acpSystem::checkDongle setVariable(0x080dad67, 0xE8C3C990); // Patch acpSystem::checkDongle - setVariable(0x0807e609, 0x90909090); // Patch initializeArcadeBackup - setVariable(0x0807e60D, 0xC2839090); // Patch initializeArcadeBackup - setVariable(0x087d47f7, 0x62ab8500); // Seat Test?? - setVariable(0x08438954, 0x1c899090); // No more Full Screen from the Game + setVariable(0x0807e609, 0xc2839090); // Patch initializeArcadeBackup + // Fixes + detourFunction(0x08510256, amDipswGetData); + detourFunction(0x085102ce, stubRetZero); // Stub amDipswSetLed + setVariable(0x08438954, 0x1c899090); // No more Full Screen from the Game + // Set Resolution + // setVariable(0x08303C4B, 0x00000780); // Set ResX + // setVariable(0x08303C58, 0x00000438); // Set ResY + + // setVariable(0x087d47f7, 0x62ab8500); // Seat Test?? } break; case ID4: @@ -424,16 +509,71 @@ int initPatch() setVariable(0x08d719e0, 2); // bcLibDebugLevel setVariable(0x08d719d4, 2); // amOsinfoDebugLevel setVariable(0x08d719e4, 0x0FFFFFFF); // s_logMask + // detourFunction(0x0808f9a8, _putConsole); // Crashes the game sometimes. + // Security detourFunction(0x086e2336, amDongleInit); detourFunction(0x086e0d81, amDongleIsAvailable); detourFunction(0x086e17e5, amDongleUpdate); + // Fixes detourFunction(0x086e0c0d, amDipswGetData); - detourFunction(0x086e0c84, stub0); - detourFunction(0x0808f9a8, _putConsole); - setVariable(0x080dad63, 0x90909090); // Patch acpSystem::checkDongle - setVariable(0x080dad67, 0xE8C3C990); // Patch acpSystem::checkDongle - setVariable(0x0807e609, 0x90909090); // Patch initializeArcadeBackup - setVariable(0x0807e60D, 0xC2839090); // Patch initializeArcadeBackup + detourFunction(0x086e0c84, stubRetZero); // amDipswSetLED + detourFunction(0x0821e6dc, stubRetOne); // isEthLinkUp + setVariable(0x082cb411, 0x0927c020); // tickInitStoreNetwork + setVariable(0x082cb6d9, 0x000150e9); // tickWaitDHCP + setVariable(0x082cb6dd, 0x448b5100); // tickWaitDHCP + // Set Resolution + setVariable(0x0835664d, 0x0000f0e9); // Force resolution set + setVariable(0x08356743, 0x00000780); // Set ResX + setVariable(0x08356748, 0x00000438); // Set ResY + // FrameBuffer Resolution (No effect that I know) + /* + setVariable(0x08248037, 0x00000780); // Set ResX + setVariable(0x0824802f, 0x00000438); // Set ResY + setVariable(0x082480f7, 0x00000780); // Set ResX + setVariable(0x082480ef, 0x00000438); // Set ResY + setVariable(0x082481b7, 0x00000780); // Set ResX + setVariable(0x082481af, 0x00000438); // Set ResY + setVariable(0x08248216, 0x00000780); // Set ResX + setVariable(0x0824820e, 0x00000438); // Set ResY + + setVariable(0x082489a7, 0x00000780); // Set ResX + setVariable(0x0824899f, 0x00000438); // Set ResY + setVariable(0x08248a32, 0x00000780); // Set ResX + setVariable(0x08248a2a, 0x00000438); // Set ResY + */ + + + // Hooked in graphics.c + //setVariable(0x085599f2, 0x0001d2e9); // Force not supported resolutions + //setVariable(0x085599f6, 0x01bb0000); // Force not supported resolutions + + // IDK if the following work (taken from TP) + // setVariable(0x08548ef3, 0x8990c031); // Shader Compiler + // setVariable(0x08799d8c, 0x082c9f52); // childTerminationHanlder + } + break; + case ID4_E: + { + // Debug + // detourFunction(0x08090478, _putConsole); // Crashes the game sometimes. + // Security + detourFunction(0x087106e6, amDongleInit); + detourFunction(0x0870f131, amDongleIsAvailable); + detourFunction(0x0870fb95, amDongleUpdate); + // Fixes + detourFunction(0x0870efbd, amDipswGetData); + detourFunction(0x0870f034, stubRetZero); // amDipswSetLed + setVariable(0x087a05e8, 0x08194748); // PTR_~cRealCardIF SIGSEV + detourFunction(0x08230fde, stubRetOne); // isEthLinkUp + setVariable(0x082df87d, 0x000154e9); // tickWaitDHCP + setVariable(0x082df881, 0x448b5100); // tickWaitDHCP + setVariable(0x082e0ec9, 0x3d8960eb); // tickInitAddress + // setVariable(0x08580979, 0x000126e9); // Avoid Full Screen set from Game + // Set Resolution + // setVariable(0x0837b12d, 0x0000f0e9); // Force set resolution + // setVariable(0x0837b223, 0x00000550); // Set ResX + // setVariable(0x0837b228, 0x00000300); // Set ResY + // setVariable(0x085700d3, 0x8990c031); // Fix something with the Shaders?? } break; case SEGABOOT_2_4_SYM: @@ -441,28 +581,56 @@ int initPatch() detourFunction(0x0805e8b0, amDongleInit); detourFunction(0x0805ebc3, amDongleIsAvailable); detourFunction(0x0805eb2a, amDongleUpdate); - //detourFunction(0x08062cf8, amLibInit); - //detourFunction(0x0805c200, amDipswInit); detourFunction(0x0805c30b, amDipswGetData); } break; case VT3: { + // Security detourFunction(0x0831c724, amDongleInit); detourFunction(0x0831ca37, amDongleIsAvailable); detourFunction(0x0831c99e, amDongleUpdate); + // Fixes detourFunction(0x0831c5d7, amDipswGetData); - detourFunction(0x0831c64f, stub0); - setVariable(0x0827ae1b, 0x34891beb); //Disable Fullscreen + detourFunction(0x0831c64f, stubRetZero); + setVariable(0x0827ae1b, 0x34891beb); // Disable Fullscreen set from the game } + break; case VT3_TESTMODE: { + // Security detourFunction(0x0815f610, amDongleInit); detourFunction(0x0815f923, amDongleIsAvailable); detourFunction(0x0815f88a, amDongleUpdate); + // Fixes detourFunction(0x0815d06b, amDipswGetData); - detourFunction(0x0815d0e3, stub0); - //setVariable(0x0827ae1b, 0x34891beb); //Disable Fullscreen + detourFunction(0x0815d0e3, stubRetZero); + } + break; + case RAMBO: + { + // Security + detourFunction(0x082c4746, amDongleInit); + detourFunction(0x082c3201, amDongleIsAvailable); + detourFunction(0x082c3bf7, amDongleUpdate); + // Fixes + detourFunction(0x082c308d, amDipswGetData); + detourFunction(0x082c3103, stubRetZero); + } + break; + case TOO_SPICY: + { + // Security + detourFunction(0x0831cf02, amDongleInit); + detourFunction(0x0831b94d, amDongleIsAvailable); + detourFunction(0x0831c3b1, amDongleUpdate); + // Fixes + detourFunction(0x0831907d, amDipswGetData); + detourFunction(0x083190f4, stubRetZero); + // CPU patch to support AMD processors + setVariable(0x08399ADA, cpu_vendor.ebx); + setVariable(0x08399AEA, cpu_vendor.edx); + setVariable(0x08399AF5, cpu_vendor.ecx); } break; default: From a1c71144f4754e86d5c4686b4df9eb216d678237 Mon Sep 17 00:00:00 2001 From: dkeruza Date: Wed, 13 Dec 2023 00:32:28 -0500 Subject: [PATCH 9/9] HOD SP added --- src/lindbergh/config.c | 18 ++++++++++++++++++ src/lindbergh/config.h | 2 ++ src/lindbergh/patch.c | 28 ++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/src/lindbergh/config.c b/src/lindbergh/config.c index f6d4188..248dd35 100644 --- a/src/lindbergh/config.c +++ b/src/lindbergh/config.c @@ -68,6 +68,20 @@ static int detectGame(uint32_t elf_crc) return 0; } + if (elf_crc == 0x12266f81) + { + config.game = THE_HOUSE_OF_THE_DEAD_SP; + config.gameStatus = WORKING; + return 0; + } + + if (elf_crc == 0x83ba3b45) + { + config.game = THE_HOUSE_OF_THE_DEAD_SP_TEST; + config.gameStatus = WORKING; + return 0; + } + if (elf_crc == 0x85c0c22a) { config.game = THE_HOUSE_OF_THE_DEAD_EX; @@ -217,6 +231,10 @@ char *getGameName() return "The House of the Dead 4 - Test Menu"; case THE_HOUSE_OF_THE_DEAD_4_STRIPPED: return "The House of the Dead 4"; + case THE_HOUSE_OF_THE_DEAD_SP: + return "House of the Dead 4 Special"; + case THE_HOUSE_OF_THE_DEAD_SP_TEST: + return "House of the Dead 4 Special - Test Menu"; case THE_HOUSE_OF_THE_DEAD_EX: return "The House of the Dead EX"; case THE_HOUSE_OF_THE_DEAD_EX_TEST: diff --git a/src/lindbergh/config.h b/src/lindbergh/config.h index 70c478d..42bab98 100644 --- a/src/lindbergh/config.h +++ b/src/lindbergh/config.h @@ -12,6 +12,8 @@ typedef enum THE_HOUSE_OF_THE_DEAD_4, THE_HOUSE_OF_THE_DEAD_4_TEST, THE_HOUSE_OF_THE_DEAD_4_STRIPPED, + THE_HOUSE_OF_THE_DEAD_SP, + THE_HOUSE_OF_THE_DEAD_SP_TEST, THE_HOUSE_OF_THE_DEAD_EX, THE_HOUSE_OF_THE_DEAD_EX_TEST, OUTRUN, diff --git a/src/lindbergh/patch.c b/src/lindbergh/patch.c index 02e7790..705cf8d 100644 --- a/src/lindbergh/patch.c +++ b/src/lindbergh/patch.c @@ -378,6 +378,34 @@ int initPatch() setVariable(0x08072195, cpu_vendor.ecx); } break; + case THE_HOUSE_OF_THE_DEAD_SP: + { + detourFunction(0x08363438, amDongleInit); + detourFunction(0x0836374b, amDongleIsAvailable); + detourFunction(0x083636b2, amDongleUpdate); + // Fixes + detourFunction(0x08360e93, amDipswGetData); + detourFunction(0x08360f0b, stubRetZero); // Stub amDipswSetLed + // CPU patch to support AMD processors + setVariable(0x083cef0a, cpu_vendor.ebx); + setVariable(0x083cef1a, cpu_vendor.edx); + setVariable(0x083cef25, cpu_vendor.ecx); + } + break; + case THE_HOUSE_OF_THE_DEAD_SP_TEST: + { + detourFunction(0x0806e914, amDongleInit); + detourFunction(0x0806ec27, amDongleIsAvailable); + detourFunction(0x0806eb8e, amDongleUpdate); + // Fixes + detourFunction(0x0806e7c7, amDipswGetData); + detourFunction(0x0806e83f, stubRetZero); // Stub amDipswSetLed + // CPU patch to support AMD processors + setVariable(0x0807a3ba, cpu_vendor.ebx); + setVariable(0x0807a3ca, cpu_vendor.edx); + setVariable(0x0807a3d5, cpu_vendor.ecx); + } + break; case THE_HOUSE_OF_THE_DEAD_EX: { detourFunction(0x084ba886, amDongleInit);