From a257a21e30b1d4c72e7d200a814c2b44c5b8fe35 Mon Sep 17 00:00:00 2001 From: dkeruza Date: Mon, 20 Nov 2023 14:13:29 -0500 Subject: [PATCH 01/31] CRC32-Patches --- src/hookcrc32/Makefile | 17 ++++ src/hookcrc32/hookcrc32.c | 95 ++++++++++++++++++ src/libkswapapi/libkswapapi.o | Bin 2372 -> 0 bytes src/lindbergh/config.c | 66 ++++++++----- src/lindbergh/config.h | 6 +- src/lindbergh/hook.c | 116 ++++++++++++++++++++-- src/lindbergh/hook.h | 9 ++ src/lindbergh/patch.c | 180 +++++++++++++++++++++------------- 8 files changed, 389 insertions(+), 100 deletions(-) create mode 100644 src/hookcrc32/Makefile create mode 100644 src/hookcrc32/hookcrc32.c delete mode 100644 src/libkswapapi/libkswapapi.o diff --git a/src/hookcrc32/Makefile b/src/hookcrc32/Makefile new file mode 100644 index 0000000..4a2e6f4 --- /dev/null +++ b/src/hookcrc32/Makefile @@ -0,0 +1,17 @@ +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 + +hookcrc32.so: $(OBJS) + $(LD) $(OBJS) $(LDFLAGS) $(CFLAGS) -o hookcrc32.so + rm -f *.o + +clean: + rm -f hookcrc32.so diff --git a/src/hookcrc32/hookcrc32.c b/src/hookcrc32/hookcrc32.c new file mode 100644 index 0000000..4181782 --- /dev/null +++ b/src/hookcrc32/hookcrc32.c @@ -0,0 +1,95 @@ +#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/libkswapapi/libkswapapi.o b/src/libkswapapi/libkswapapi.o deleted file mode 100644 index d4806865b4a39307621c0ae291c38e493b109776..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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}IoEAmyL #include #include #include @@ -13,6 +15,7 @@ #include #include #include +#include #include "hook.h" @@ -38,19 +41,33 @@ int hooks[5] = {-1, -1, -1, -1}; FILE *fileHooks[2] = {NULL, NULL}; int fileRead[2] = {0, 0}; +uint32_t elf_crc = 0; + +cpuvendor cpu_vendor = {0}; + +static int callback(struct dl_phdr_info *info, size_t size, void *data); uint16_t basePortAddress = 0xFFFF; +/** + * Signal handler for the SIGSEGV signal, which is triggered when a process tries to access an illegal memory location. + * @param signal + * @param info + * @param ptr + */ static void handleSegfault(int signal, siginfo_t *info, void *ptr) { ucontext_t *ctx = ptr; + // 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)); switch (*code) { case 0xED: { + // Get the port number from the EDX register uint16_t port = ctx->uc_mcontext.gregs[REG_EDX] & 0xFFFF; // The first port called is usually random, but everything after that @@ -60,9 +77,11 @@ static void handleSegfault(int signal, siginfo_t *info, void *ptr) if (basePortAddress == 0xFFFF) basePortAddress = port; + // Adjust the port number if necessary if (port > 0x38) port = port - basePortAddress; + // Call the security board input function with the port number and data securityBoardIn(port, (uint32_t *)&(ctx->uc_mcontext.gregs[REG_EAX])); ctx->uc_mcontext.gregs[REG_EIP]++; @@ -70,15 +89,17 @@ static void handleSegfault(int signal, siginfo_t *info, void *ptr) } break; - case 0xE7: // OUT IMMIDIATE + case 0xE7: // OUT IMMEDIATE { + // Increment the instruction pointer by two to skip over this instruction ctx->uc_mcontext.gregs[REG_EIP] += 2; return; } break; - case 0xE6: // OUT IMMIDIATE + case 0xE6: // OUT IMMEDIATE { + // Increment the instruction pointer by two to skip over this instruction ctx->uc_mcontext.gregs[REG_EIP] += 2; return; } @@ -108,9 +129,14 @@ 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. + dl_iterate_phdr(callback, NULL); + // Get CPU ID + getCPUID(); // Implement SIGSEGV handler struct sigaction act; @@ -118,9 +144,9 @@ void __attribute__((constructor)) hook_init() act.sa_flags = SA_SIGINFO; sigaction(SIGSEGV, &act, NULL); - initConfig(); + initConfig(elf_crc); - if (initPatch() != 0) + if(initPatch() != 0) exit(1); if (initEeprom() != 0) @@ -206,18 +232,30 @@ int open64(const char *pathname, int flags) return open(pathname, flags); } - - FILE *fopen(const char *restrict pathname, const char *restrict mode) { FILE *(*_fopen)(const char *restrict pathname, const char *restrict mode) = dlsym(RTLD_NEXT, "fopen"); - // printf("fopen %s\n", pathname); if (strcmp(pathname, "/root/lindbergrc") == 0) { return _fopen("lindbergrc", mode); } + if (strcmp(pathname, "/usr/lib/boot/logo.tga") == 0) + { + return _fopen("logo.tga", mode); + } + + if (strcmp(pathname, "/usr/lib/boot/LucidaConsole_12.tga") == 0) + { + return _fopen("LucidaConsole_12.tga", mode); + } + + if (strcmp(pathname, "/usr/lib/boot/LucidaConsole_12.abc") == 0) + { + return _fopen("LucidaConsole_12.abc", mode); + } + if (strcmp(pathname, "/proc/cpuinfo") == 0) { fileRead[CPUINFO] = 0; @@ -242,6 +280,25 @@ FILE *fopen64(const char *pathname, const char *mode) return fileHooks[OSRELEASE]; } + if (strcmp(pathname, "/usr/lib/boot/logo_red.tga") == 0) + { + return _fopen64("logo_red.tga", mode); + } + + if (strcmp(pathname, "/usr/lib/boot/logo.tga") == 0) + { + return _fopen64("logo.tga", mode); + } + + if (strcmp(pathname, "/usr/lib/boot/SEGA_KakuGothic-DB-Roman_12.tga") == 0) + { + return _fopen64("SEGA_KakuGothic-DB-Roman_12.tga", mode); + } + + if (strcmp(pathname, "/usr/lib/boot/SEGA_KakuGothic-DB-Roman_12.abc") == 0) + { + return _fopen64("SEGA_KakuGothic-DB-Roman_12.abc", mode); + } return _fopen64(pathname, mode); } @@ -465,7 +522,7 @@ float powf(float base, float exponent) return (float)pow((double)base, (double)exponent); } -/** This might be required for some games +/* int sem_wait(sem_t *sem) { int (*original_sem_wait)(sem_t * sem) = dlsym(RTLD_NEXT, "sem_wait"); @@ -476,6 +533,10 @@ int sem_wait(sem_t *sem) /** * Hook function used by Harley Davidson to change IPs to localhost * Currently does nothing. + * @param sockfd + * @param addr + * @param addrlen + * @return */ int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { @@ -491,6 +552,45 @@ int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) return _connect(sockfd, addr, addrlen); } +/** + * Function to calculate CRC32 checksum in memory. +*/ +uint32_t get_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; +} + +/** + * 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) +{ + 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); + } + return 1; +} + +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); +} + /** * Stop the game changing the DISPLAY environment variable */ diff --git a/src/lindbergh/hook.h b/src/lindbergh/hook.h index e69de29..36e0d2a 100644 --- a/src/lindbergh/hook.h +++ b/src/lindbergh/hook.h @@ -0,0 +1,9 @@ +uint32_t get_crc32(const char *s,size_t n); +void getCPUID(); +typedef struct +{ + unsigned ebx; + unsigned edx; + unsigned ecx; +}cpuvendor; + diff --git a/src/lindbergh/patch.c b/src/lindbergh/patch.c index 6d5beaa..05b6478 100644 --- a/src/lindbergh/patch.c +++ b/src/lindbergh/patch.c @@ -5,6 +5,9 @@ #include "patch.h" #include "config.h" +#include "hook.h" + +extern cpuvendor cpu_vendor; static void setVariable(uint32_t address, uint32_t value) { @@ -14,7 +17,7 @@ static void setVariable(uint32_t address, uint32_t value) void *toModify = (void *)(address - (address % pagesize)); - int prot = mprotect(toModify, pagesize, PROT_WRITE); + int prot = mprotect(toModify, pagesize, PROT_EXEC | PROT_WRITE); if (prot != 0) { printf("Error: Cannot unprotect memory region to change variable (%d)\n", prot); @@ -70,75 +73,116 @@ int initPatch() switch (game) { - case RTUNED: - { - detourFunction(0x08366846, amDongleInit); - detourFunction(0x08365301, amDongleIsAvailable); - detourFunction(0x08365cf7, amDongleUpdate); - } - break; - - case SRTV: - { - detourFunction(0x084d5b40, amDongleInit); - detourFunction(0x084d45f9, amDongleIsAvailable); - detourFunction(0x084d4fef, amDongleUpdate); - } - break; - - case ABC: - { - detourFunction(0x081e3424, amDongleInit); - detourFunction(0x081e3772, amDongleIsAvailable); - detourFunction(0x081e369e, amDongleUpdate); - } - break; - case OUTRUN: - { - setVariable(0x0893a24c, 2); // amBackupDebugLevel - setVariable(0x0893a260, 2); // amCreditDebugLevel - setVariable(0x0893a4b8, 2); // amDipswDebugLevel - setVariable(0x0893a4bc, 2); // amDongleDebugLevel - setVariable(0x0893a4c0, 2); // amEepromDebugLevel - setVariable(0x0893a4c4, 2); // amHwmonitorDebugLevel - setVariable(0x0893a4c8, 2); // amJvsDebugLevel - setVariable(0x0893a4cc, 2); // amLibDebugLevel - setVariable(0x0893a4d0, 2); // amMiscDebugLevel - setVariable(0x0893a4d4, 2); // amOsinfoDebugLevel - setVariable(0x0893a4d8, 2); // amSysDataDebugLevel - setVariable(0x0893a4e0, 2); // bcLibDebugLevel - detourFunction(0x08190e80, amDongleInit); - detourFunction(0x08191201, amDongleIsAvailable); - detourFunction(0x08191125, amDongleUpdate); - } - break; + case RTUNED: + { + detourFunction(0x08366846, amDongleInit); + detourFunction(0x08365301, amDongleIsAvailable); + detourFunction(0x08365cf7, amDongleUpdate); + } + break; - case THE_HOUSE_OF_THE_DEAD_4: - { - setVariable(0x0a737c60, 2); // amBackupDebugLevel - setVariable(0x0a737c64, 2); // amChunkDataDebugLevel - setVariable(0x0a737c80, 2); // amCreditDebugLevel - setVariable(0x0a737ed8, 2); // amDipswDebugLevel - setVariable(0x0a737edc, 2); // amDiskDebugLevel - setVariable(0x0a737ee0, 2); // amDongleDebugLevel - setVariable(0x0a737ee4, 2); // amEepromDebugLevel - setVariable(0x0a737ee8, 2); // amHmDebugLevel - setVariable(0x0a737ef0, 2); // amJvsDebugLevel - setVariable(0x0a737f14, 2); // amLibDebugLevel - setVariable(0x0a737f18, 2); // amMiscDebugLevel - setVariable(0x0a737f1c, 2); // amSysDataDebugLevel - setVariable(0x0a737f20, 2); // bcLibDebugLevel - setVariable(0x0a737f24, 0x0FFFFFFF); // s_logMask - detourFunction(0x08320178, amDongleInit); - detourFunction(0x08320459, amDongleIsAvailable); - detourFunction(0x083203c0, amDongleUpdate); - } - break; + case SRTV: + { + detourFunction(0x084d5b40, amDongleInit); + detourFunction(0x084d45f9, amDongleIsAvailable); + detourFunction(0x084d4fef, amDongleUpdate); + } + break; + case ABC_2006: + { + setVariable(0x0a0a37e4, 2); // amBackupDebugLevel + setVariable(0x0a0a3800, 2); // amCreditDebugLevel + setVariable(0x0a0a3a58, 2); // amDipswDebugLevel + setVariable(0x0a0a3a5c, 2); // amDongleDebugLevel + setVariable(0x0a0a3a60, 2); // amEepromDebugLevel + setVariable(0x0a0a3a64, 2); // amHwmonitorDebugLevel + setVariable(0x0a0a3a68, 2); // amJvsDebugLevel + setVariable(0x0a0a3a6c, 2); // amLibDebugLevel + setVariable(0x0a0a3a70, 2); // amMiscDebugLevel + setVariable(0x0a0a3a74, 2); // amOsinfoDebugLevel + setVariable(0x0a0a3a78, 2); // amSysDataDebugLevel + setVariable(0x0a0a3a80, 2); // bcLibDebugLevel + detourFunction(0x081e4980, amDongleInit); + detourFunction(0x081e4cce, amDongleIsAvailable); + detourFunction(0x081e4bfa, amDongleUpdate); + } + break; + case ABC_2007: + { + setVariable(0x0a0a0d24, 2); // amBackupDebugLevel + setVariable(0x0a0a0d40, 2); // amCreditDebugLevel + setVariable(0x0a0a0f98, 2); // amDipswDebugLevel + setVariable(0x0a0a0f9c, 2); // amDongleDebugLevel + setVariable(0x0a0a0fa0, 2); // amEepromDebugLevel + setVariable(0x0a0a0fa4, 2); // amHwmonitorDebugLevel + setVariable(0x0a0a0fa8, 2); // amJvsDebugLevel + setVariable(0x0a0a0fac, 2); // amLibDebugLevel + setVariable(0x0a0a0fb0, 2); // amMiscDebugLevel + setVariable(0x0a0a0fb4, 2); // amOsinfoDebugLevel + setVariable(0x0a0a0fb8, 2); // amSysDataDebugLevel + setVariable(0x0a0a0fc0, 2); // bcLibDebugLevel + detourFunction(0x081e3424, amDongleInit); + detourFunction(0x081e3772, amDongleIsAvailable); + detourFunction(0x081e369e, amDongleUpdate); + } + break; + case OUTRUN: + { + setVariable(0x0893a24c, 2); // amBackupDebugLevel + setVariable(0x0893a260, 2); // amCreditDebugLevel + setVariable(0x0893a4b8, 2); // amDipswDebugLevel + setVariable(0x0893a4bc, 2); // amDongleDebugLevel + setVariable(0x0893a4c0, 2); // amEepromDebugLevel + setVariable(0x0893a4c4, 2); // amHwmonitorDebugLevel + setVariable(0x0893a4c8, 2); // amJvsDebugLevel + setVariable(0x0893a4cc, 2); // amLibDebugLevel + setVariable(0x0893a4d0, 2); // amMiscDebugLevel + setVariable(0x0893a4d4, 2); // amOsinfoDebugLevel + setVariable(0x0893a4d8, 2); // amSysDataDebugLevel + setVariable(0x0893a4e0, 2); // bcLibDebugLevel + detourFunction(0x08190e80, amDongleInit); + detourFunction(0x08191201, amDongleIsAvailable); + detourFunction(0x08191125, amDongleUpdate); + } + break; - default: - // Don't do any patches for random games + case THE_HOUSE_OF_THE_DEAD_4: + { + setVariable(0x0a737c60, 2); // amBackupDebugLevel + setVariable(0x0a737c64, 2); // amChunkDataDebugLevel + setVariable(0x0a737c80, 2); // amCreditDebugLevel + setVariable(0x0a737ed8, 2); // amDipswDebugLevel + setVariable(0x0a737edc, 2); // amDiskDebugLevel + setVariable(0x0a737ee0, 2); // amDongleDebugLevel + setVariable(0x0a737ee4, 2); // amEepromDebugLevel + setVariable(0x0a737ee8, 2); // amHmDebugLevel + setVariable(0x0a737ef0, 2); // amJvsDebugLevel + setVariable(0x0a737f14, 2); // amLibDebugLevel + setVariable(0x0a737f18, 2); // amMiscDebugLevel + setVariable(0x0a737f1c, 2); // amSysDataDebugLevel + setVariable(0x0a737f20, 2); // bcLibDebugLevel + setVariable(0x0a737f24, 0x0FFFFFFF); // s_logMask + detourFunction(0x08320178, amDongleInit); + detourFunction(0x08320459, amDongleIsAvailable); + detourFunction(0x083203c0, amDongleUpdate); + setVariable(0x0837d6aa, cpu_vendor.ebx); + setVariable(0x0837d6ba, cpu_vendor.edx); + setVariable(0x0837d6c5, cpu_vendor.ecx); + } + break; + case THE_HOUSE_OF_THE_DEAD_4_TEST: + { + detourFunction(0x080677a0, amDongleInit); + detourFunction(0x08067a81, amDongleIsAvailable); + detourFunction(0x080679e8, amDongleUpdate); + setVariable(0x0807217a, cpu_vendor.ebx); + setVariable(0x0807218a, cpu_vendor.edx); + setVariable(0x08072195, cpu_vendor.ecx); + } + break; + default: + // Don't do any patches for random games break; } - return 0; -} +} \ No newline at end of file From f142ffebcc6868fa29b121f17db11654b0ed9f8f Mon Sep 17 00:00:00 2001 From: dkeruza Date: Mon, 20 Nov 2023 14:55:32 -0500 Subject: [PATCH 02/31] VF5-REVC --- Makefile | 2 +- src/hookcrc32/hookcrc32.so | Bin 0 -> 16980 bytes src/libkswapapi/libkswapapi.o | Bin 0 -> 2372 bytes src/lindbergh/config.c | 8 ++++++++ src/lindbergh/config.h | 3 ++- src/lindbergh/patch.c | 7 +++++++ 6 files changed, 18 insertions(+), 2 deletions(-) create mode 100755 src/hookcrc32/hookcrc32.so create mode 100644 src/libkswapapi/libkswapapi.o diff --git a/Makefile b/Makefile index dd1d8fc..5bdf27b 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ CC=gcc -m32 -CFLAGS = -g -O0 -fPIC -m32 -D_GNU_SOURCE -Wall -Werror -Wno-unused-variable -Wno-unused-function +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 diff --git a/src/hookcrc32/hookcrc32.so b/src/hookcrc32/hookcrc32.so new file mode 100755 index 0000000000000000000000000000000000000000..01742def06663b65b0449fbf971c17262855bb45 GIT binary patch literal 16980 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 qX7MNL-G$_D7xP( Date: Mon, 20 Nov 2023 15:01:27 -0500 Subject: [PATCH 03/31] Fixed missing _GNU_SOURCE in grqphics.changes --- src/lindbergh/graphics.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lindbergh/graphics.c b/src/lindbergh/graphics.c index 104da34..383e5e0 100644 --- a/src/lindbergh/graphics.c +++ b/src/lindbergh/graphics.c @@ -1,3 +1,4 @@ +#define _GNU_SOURCE #include #include #include From 0ee6d12393260905761ddfd233ef557c430c9eed Mon Sep 17 00:00:00 2001 From: dkeruza Date: Wed, 22 Nov 2023 15:45:41 -0500 Subject: [PATCH 04/31] more patches / cleaned CRC / added game status. --- src/hookcrc32/hookcrc32.c | 2 +- src/hookcrc32/hookcrc32.so | Bin 16980 -> 16900 bytes src/lindbergh/config.c | 47 ++++++++++++++++------ src/lindbergh/config.h | 11 ++++++ src/lindbergh/hook.c | 12 +++++- src/lindbergh/patch.c | 77 +++++++++++++++++++++++++++++++++++++ 6 files changed, 134 insertions(+), 15 deletions(-) diff --git a/src/hookcrc32/hookcrc32.c b/src/hookcrc32/hookcrc32.c index 4181782..9f7e5fc 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 01742def06663b65b0449fbf971c17262855bb45..ff67e24d404dd061a664ecd403e913281ddf5ee3 100755 GIT binary patch delta 2159 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 = RED; } - else printf("Error: Unknown settings command %s\n", command); } @@ -214,7 +240,7 @@ int readConfig(FILE *configFile, EmulatorConfig *config) return 0; } -int initConfig(uint32_t elf_crc) +int initConfig() { config.emulateRideboard = 0; config.emulateDriveboard = 0; @@ -230,14 +256,11 @@ int initConfig(uint32_t elf_crc) strcpy(config.rideboardPath, "none"); config.width = 1024; config.height = 768; - if (detectGame(elf_crc) != 0) + config.crc32 = elf_crc; + if (detectGame(config.crc32) != 0) { printf("Warning: Unsure what game this is, using default configuration values.\n"); } - else - { - printf("Game Detected: %s\n", getGameName()); - } configFile = fopen(CONFIG_PATH, "r"); diff --git a/src/lindbergh/config.h b/src/lindbergh/config.h index 03dece1..b0f2c7c 100644 --- a/src/lindbergh/config.h +++ b/src/lindbergh/config.h @@ -13,8 +13,10 @@ typedef enum OUTRUN, OUTRUN_TEST, LETS_GO_JUNGLE, + LETS_GO_JUNGLE_SPECIAL, ABC_2006, ABC_2007, + ID4, SRTV, RTUNED, VT3, @@ -27,6 +29,12 @@ typedef enum RED } Colour; +typedef enum +{ + WORKING, + NOT_WORKING +}GameStatus; + typedef struct { int emulateRideboard; @@ -44,6 +52,9 @@ typedef struct int height; Game game; Colour lindberghColour; + GameStatus gameStatus; + uint32_t crc32; + } EmulatorConfig; int initConfig(); diff --git a/src/lindbergh/hook.c b/src/lindbergh/hook.c index 610a0c4..eeb4756 100644 --- a/src/lindbergh/hook.c +++ b/src/lindbergh/hook.c @@ -144,7 +144,7 @@ void __attribute__((constructor)) hook_init() act.sa_flags = SA_SIGINFO; sigaction(SIGSEGV, &act, NULL); - initConfig(elf_crc); + initConfig(); if(initPatch() != 0) exit(1); @@ -175,7 +175,15 @@ void __attribute__((constructor)) hook_init() securityBoardSetDipResolution(getConfig()->width, getConfig()->height); - printf("Now emulating %s\n", getGameName()); + printf("Now emulating %s", getGameName()); + if(getConfig()->gameStatus == WORKING) + { + printf((" - Game is in working state.\n")); + } + else + { + printf((" - Game is in NOT WORKING state.\n")); + } } int open(const char *pathname, int flags) diff --git a/src/lindbergh/patch.c b/src/lindbergh/patch.c index 8366481..635d3b0 100644 --- a/src/lindbergh/patch.c +++ b/src/lindbergh/patch.c @@ -67,6 +67,20 @@ int amDongleUpdate() return 0; } +void _putConsole(char *param1, char *param2) +{ + if(param2 >=0 ) + { + printf(param1, (int)param2); + printf("\n"); + } + else + { + printf("%s\n", param1); + } + return; +} + int initPatch() { Game game = getConfig()->game; @@ -187,6 +201,69 @@ int initPatch() detourFunction(0x085c62f0, amDongleUpdate); } 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 + detourFunction(0x084e50d8, amDongleInit); + detourFunction(0x084e5459, amDongleIsAvailable); + detourFunction(0x084e537d, amDongleUpdate); + //detourFunction(0x08074a8c, _putConsole); + setVariable(0x0840b06f, 0xc48306eb); // Patch to initialize???? + } + break; + case LETS_GO_JUNGLE_SPECIAL: + { + setVariable(0x08c453e4, 2); // amBackupDebugLevel + setVariable(0x08c45400, 2); // amCreditDebugLevel + setVariable(0x08c45658, 2); // amDipswDebugLevel + setVariable(0x08c4565c, 2); // amDongleDebugLevel + setVariable(0x08c45660, 2); // amEepromDebugLevel + setVariable(0x08c45664, 2); // amHwmonitorDebugLevel + setVariable(0x08c45668, 2); // amJvsDebugLevel + setVariable(0x08c4566c, 2); // amLibDebugLevel + setVariable(0x08c45670, 2); // amMiscDebugLevel + setVariable(0x08c45678, 2); // amSysDataDebugLevel + setVariable(0x08c45680, 2); // bcLibDebugLevel + setVariable(0x08c45674, 2); // amOsinfoDebugLevel + setVariable(0x08c45684, 0x0FFFFFFF); // s_logMask + detourFunction(0x08510320, amDongleInit); + detourFunction(0x085106dc, amDongleIsAvailable); + detourFunction(0x08510600, amDongleUpdate); + detourFunction(0x08075012, _putConsole); + } + break; + case ID4: + { + setVariable(0x08d71750, 2); // amBackupDebugLevel + setVariable(0x08d71760, 2); // amCreditDebugLevel + setVariable(0x08d719b8, 2); // amDipswDebugLevel + setVariable(0x08d719bc, 2); // amDongleDebugLevel + setVariable(0x08d719c0, 2); // amEepromDebugLevel + setVariable(0x08d719c4, 2); // amHwmonitorDebugLevel + setVariable(0x08d719c8, 2); // amJvsDebugLevel + setVariable(0x08d719cc, 2); // amLibDebugLevel + setVariable(0x08d719d0, 2); // amMiscDebugLevel + setVariable(0x08d719d8, 2); // amSysDataDebugLevel + setVariable(0x08d719e0, 2); // bcLibDebugLevel + setVariable(0x08d719d4, 2); // amOsinfoDebugLevel + setVariable(0x08d719e4, 0x0FFFFFFF); // s_logMask + detourFunction(0x086e2336, amDongleInit); + detourFunction(0x086e0d81, amDongleIsAvailable); + detourFunction(0x086e17e5, amDongleUpdate); + detourFunction(0x0808f9a8, _putConsole); + } default: // Don't do any patches for random games break; From 339187d643fd3e2265d3b65fd61eda49a7b28767 Mon Sep 17 00:00:00 2001 From: dkeruza Date: Wed, 29 Nov 2023 13:49:03 -0500 Subject: [PATCH 05/31] More patches. VF5.C working. --- src/libkswapapi/libkswapapi.o | Bin 2372 -> 2372 bytes src/lindbergh/config.c | 2 +- src/lindbergh/graphics.c | 1 + src/lindbergh/hook.c | 9 +- src/lindbergh/patch.c | 470 ++++++++++++++++++++-------------- src/lindbergh/securityboard.c | 1 + 6 files changed, 293 insertions(+), 190 deletions(-) diff --git a/src/libkswapapi/libkswapapi.o b/src/libkswapapi/libkswapapi.o index 2ffbc242e2f71c0f038c7947fec16a2c640ac71e..d4806865b4a39307621c0ae291c38e493b109776 100644 GIT binary patch delta 1059 zcmZ8gO=uHA6rS15Y?7L!o1Zq+wkD-&D|GWy3Ze-9L}`mf3O3-us+(=vgrvJ6yRmrC z;!(8FFrWu}&_kgIJ@n>LX(@Uuy$KahLIp44v4#5HBq^l>`~JT7J>GjWyBXRHEyou> zFe1)~kb@*jItc|^f$v}Ynf>gGUwa3KhldP<%hMY#U1vAOz;wX}k`96N1wd?}4=2)4 zL_$s7SVzR@$~ahZ1!AYslIlQr`3MctbAj+FInW)buk}iAZq&Di=UYXPJc%@d{ZYCf z@Pnk-3w+eB8p(1oSF#uMie4!aa?D8>Vh-q=iB`H8^Mo1glO(7h7!M7rT+SN~|4C#1 z(L33ACVeq}DKU~r@uyTw=(%#<2GDkNqoh@;mIF1c zs%AToIClgXW!)~c;G$&$V9Xx#NwQ$g=aY|%NKW3&+a<@Uz%=GeE?=E1XcJ{ipUGDV z8O>xa#|N{yn(5RU?P=+n@Y2tQQ;F0_B7LC|7nkCL-Qb#Rg~_(v9HIBbxA zV=)@xx)SCGO!eM_v5^(w9ZHN&@@XZ?Clpm!0}S7pOXRL7Dw_gtg0Cz6-U6_$3DyrK z#@>N7#;LoX?ST~+`B&VkckQTl)*WLWc%4%Mdj;4hz;Fu@z6#iV!2a;R?l9kVt85G= z7(y@f9x?zrI*!C2D4iYa5P)qp{wL555PEps6Apd_4+#(uXPGZ~qP?47!`4L07{&)6 lh6X#tzj(U+yFf?*5f`rV-=1#fgPd{EZjV=G+u(gi?>_`}x2XUC delta 1066 zcma)4OGuPa6h8OP+yNN4FeSkH@n$R(KxSlG3zMDK!k^rh;3r+G*(v?wsvN+M&x#r z2#A9%p(ax2h@vx4MQ%z0g%Cemni=?7C`e461TRA+c&oh4p8LEg zK}v$qKBZnOv0qBW51qSg4Q38oncieJnX$6zY;Pu=$ykYtcF8)GUtos;PfuUBekgkS z>Dv6Qe0987DVOcy0;Q%ZGj?j$uB1-bH|=tzI%Cf+q{`E?rGh;-In`6H4Byb$GFHJ`SJ@_+yGa!RK`kTUnN+{v_MNo1iEt+PW*tAPHUb zh5{d8;G-Izb-m(^MBl^0-OE8)?lqnY9@3lMj^-ao*uai^=+oQY4)wxCH0*q_(`Twx IWNh>97o4K0N&o-= diff --git a/src/lindbergh/config.c b/src/lindbergh/config.c index 3802adf..4b70060 100644 --- a/src/lindbergh/config.c +++ b/src/lindbergh/config.c @@ -135,7 +135,7 @@ static int detectGame(uint32_t elf_crc) if (elf_crc == 0x1bf1b627) { config.game = VF5_REVC; - config.gameStatus = NOT_WORKING; + config.gameStatus = WORKING; return 0; } diff --git a/src/lindbergh/graphics.c b/src/lindbergh/graphics.c index 383e5e0..bb7c369 100644 --- a/src/lindbergh/graphics.c +++ b/src/lindbergh/graphics.c @@ -163,6 +163,7 @@ int XNextEvent(Display *display, XEvent *event_return) { case 28: setSwitch(SYSTEM, BUTTON_TEST, event_return->type == KeyPress); + //securityBoardSetSwitch(BUTTON_TEST, 1); break; case 39: setSwitch(PLAYER_1, BUTTON_SERVICE, event_return->type == KeyPress); diff --git a/src/lindbergh/hook.c b/src/lindbergh/hook.c index eeb4756..0202d09 100644 --- a/src/lindbergh/hook.c +++ b/src/lindbergh/hook.c @@ -59,10 +59,12 @@ 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)); + printf("Code: 0x%08x - Port: 0x%08x\n", *code, (ctx->uc_mcontext.gregs[REG_EDX] & 0xFFFF) - basePortAddress); switch (*code) { case 0xED: @@ -138,6 +140,11 @@ 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; diff --git a/src/lindbergh/patch.c b/src/lindbergh/patch.c index 635d3b0..ce2328c 100644 --- a/src/lindbergh/patch.c +++ b/src/lindbergh/patch.c @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -23,10 +24,28 @@ static void setVariable(uint32_t address, uint32_t value) printf("Error: Cannot unprotect memory region to change variable (%d)\n", prot); return; } - + // printf("Variable: %8X , Value: %8X\n",(uint32_t)variable, value); *variable = value; } +static void setMem(uint32_t address, uint32_t value, int size) +{ + int pagesize = sysconf(_SC_PAGE_SIZE); + + uint32_t *variable = (uint32_t *)address; + + void *toModify = (void *)(address - (address % pagesize)); + + int prot = mprotect(toModify, pagesize, PROT_EXEC | PROT_WRITE); + if (prot != 0) + { + printf("Error: Cannot unprotect memory region to change variable (%d)\n", prot); + return; + } + // printf("Variable: %8X , Value: %8X\n",(uint32_t)variable, value); + memccpy((void *)variable, (void *)value, 1, size); +} + static void detourFunction(uint32_t address, void *function) { int pagesize = sysconf(_SC_PAGE_SIZE); @@ -47,11 +66,16 @@ static void detourFunction(uint32_t address, void *function) cave[4] = (jumpAddress >> (8 * 3)) & 0xFF; cave[3] = (jumpAddress >> (8 * 2)) & 0xFF; cave[2] = (jumpAddress >> (8 * 1)) & 0xFF; - cave[1] = (jumpAddress)&0xFF; + cave[1] = (jumpAddress) & 0xFF; memcpy((void *)address, cave, 5); } +int stub0() +{ + return 0; +} + int amDongleInit() { return 0; @@ -67,18 +91,55 @@ int amDongleUpdate() return 0; } -void _putConsole(char *param1, char *param2) +void _putConsole(const char *format, ...) { - if(param2 >=0 ) + va_list args; + va_start(args, format); + + while (*format) { - printf(param1, (int)param2); - printf("\n"); + if (*format == '%') + { + format++; + if ((*format == 'd') || (*format == 'n')) + { + printf("%d", va_arg(args, int)); + } + else if (*format == 's') + { + printf("%s", va_arg(args, char *)); + } + else if (*format == 'u') + { + printf("%u", va_arg(args, unsigned int)); + } + else if (*format == '0') + { + format ++; + if (*format == '2') + { + format++; + printf("%02X", va_arg(args, int)); + } + else if (*format == '4') + { + format++; + printf("%04X", va_arg(args, unsigned int)); + } + } + else + { + printf("\nFormat: %c.\n", *format); + } + } + else + { + putchar(*format); + } + format++; } - else - { - printf("%s\n", param1); - } - return; + va_end(args); + printf("\n"); } int initPatch() @@ -87,185 +148,218 @@ int initPatch() switch (game) { - case RTUNED: - { - detourFunction(0x08366846, amDongleInit); - detourFunction(0x08365301, amDongleIsAvailable); - detourFunction(0x08365cf7, amDongleUpdate); - } - break; + case RTUNED: + { + detourFunction(0x08366846, amDongleInit); + detourFunction(0x08365301, amDongleIsAvailable); + detourFunction(0x08365cf7, amDongleUpdate); + } + break; - case SRTV: - { - detourFunction(0x084d5b40, amDongleInit); - detourFunction(0x084d45f9, amDongleIsAvailable); - detourFunction(0x084d4fef, amDongleUpdate); - } - break; - case ABC_2006: - { - setVariable(0x0a0a37e4, 2); // amBackupDebugLevel - setVariable(0x0a0a3800, 2); // amCreditDebugLevel - setVariable(0x0a0a3a58, 2); // amDipswDebugLevel - setVariable(0x0a0a3a5c, 2); // amDongleDebugLevel - setVariable(0x0a0a3a60, 2); // amEepromDebugLevel - setVariable(0x0a0a3a64, 2); // amHwmonitorDebugLevel - setVariable(0x0a0a3a68, 2); // amJvsDebugLevel - setVariable(0x0a0a3a6c, 2); // amLibDebugLevel - setVariable(0x0a0a3a70, 2); // amMiscDebugLevel - setVariable(0x0a0a3a74, 2); // amOsinfoDebugLevel - setVariable(0x0a0a3a78, 2); // amSysDataDebugLevel - setVariable(0x0a0a3a80, 2); // bcLibDebugLevel - detourFunction(0x081e4980, amDongleInit); - detourFunction(0x081e4cce, amDongleIsAvailable); - detourFunction(0x081e4bfa, amDongleUpdate); - } - break; - case ABC_2007: - { - setVariable(0x0a0a0d24, 2); // amBackupDebugLevel - setVariable(0x0a0a0d40, 2); // amCreditDebugLevel - setVariable(0x0a0a0f98, 2); // amDipswDebugLevel - setVariable(0x0a0a0f9c, 2); // amDongleDebugLevel - setVariable(0x0a0a0fa0, 2); // amEepromDebugLevel - setVariable(0x0a0a0fa4, 2); // amHwmonitorDebugLevel - setVariable(0x0a0a0fa8, 2); // amJvsDebugLevel - setVariable(0x0a0a0fac, 2); // amLibDebugLevel - setVariable(0x0a0a0fb0, 2); // amMiscDebugLevel - setVariable(0x0a0a0fb4, 2); // amOsinfoDebugLevel - setVariable(0x0a0a0fb8, 2); // amSysDataDebugLevel - setVariable(0x0a0a0fc0, 2); // bcLibDebugLevel - detourFunction(0x081e3424, amDongleInit); - detourFunction(0x081e3772, amDongleIsAvailable); - detourFunction(0x081e369e, amDongleUpdate); - } - break; - case OUTRUN: - { - setVariable(0x0893a24c, 2); // amBackupDebugLevel - setVariable(0x0893a260, 2); // amCreditDebugLevel - setVariable(0x0893a4b8, 2); // amDipswDebugLevel - setVariable(0x0893a4bc, 2); // amDongleDebugLevel - setVariable(0x0893a4c0, 2); // amEepromDebugLevel - setVariable(0x0893a4c4, 2); // amHwmonitorDebugLevel - setVariable(0x0893a4c8, 2); // amJvsDebugLevel - setVariable(0x0893a4cc, 2); // amLibDebugLevel - setVariable(0x0893a4d0, 2); // amMiscDebugLevel - setVariable(0x0893a4d4, 2); // amOsinfoDebugLevel - setVariable(0x0893a4d8, 2); // amSysDataDebugLevel - setVariable(0x0893a4e0, 2); // bcLibDebugLevel - detourFunction(0x08190e80, amDongleInit); - detourFunction(0x08191201, amDongleIsAvailable); - detourFunction(0x08191125, amDongleUpdate); - } - break; + case SRTV: + { + detourFunction(0x084d5b40, amDongleInit); + detourFunction(0x084d45f9, amDongleIsAvailable); + detourFunction(0x084d4fef, amDongleUpdate); + } + break; + case ABC_2006: + { + setVariable(0x0a0a37e4, 2); // amBackupDebugLevel + setVariable(0x0a0a3800, 2); // amCreditDebugLevel + setVariable(0x0a0a3a58, 2); // amDipswDebugLevel + setVariable(0x0a0a3a5c, 2); // amDongleDebugLevel + setVariable(0x0a0a3a60, 2); // amEepromDebugLevel + setVariable(0x0a0a3a64, 2); // amHwmonitorDebugLevel + setVariable(0x0a0a3a68, 2); // amJvsDebugLevel + setVariable(0x0a0a3a6c, 2); // amLibDebugLevel + setVariable(0x0a0a3a70, 2); // amMiscDebugLevel + setVariable(0x0a0a3a74, 2); // amOsinfoDebugLevel + setVariable(0x0a0a3a78, 2); // amSysDataDebugLevel + setVariable(0x0a0a3a80, 2); // bcLibDebugLevel + detourFunction(0x081e4980, amDongleInit); + detourFunction(0x081e4cce, amDongleIsAvailable); + detourFunction(0x081e4bfa, amDongleUpdate); + } + break; + case ABC_2007: + { + setVariable(0x0a0a0d24, 2); // amBackupDebugLevel + setVariable(0x0a0a0d40, 2); // amCreditDebugLevel + setVariable(0x0a0a0f98, 2); // amDipswDebugLevel + setVariable(0x0a0a0f9c, 2); // amDongleDebugLevel + setVariable(0x0a0a0fa0, 2); // amEepromDebugLevel + setVariable(0x0a0a0fa4, 2); // amHwmonitorDebugLevel + setVariable(0x0a0a0fa8, 2); // amJvsDebugLevel + setVariable(0x0a0a0fac, 2); // amLibDebugLevel + setVariable(0x0a0a0fb0, 2); // amMiscDebugLevel + setVariable(0x0a0a0fb4, 2); // amOsinfoDebugLevel + setVariable(0x0a0a0fb8, 2); // amSysDataDebugLevel + setVariable(0x0a0a0fc0, 2); // bcLibDebugLevel + detourFunction(0x081e3424, amDongleInit); + detourFunction(0x081e3772, amDongleIsAvailable); + detourFunction(0x081e369e, amDongleUpdate); + setVariable(0x081e7945, 0x00000001); //Test + } + break; + case OUTRUN: + { + setVariable(0x0893a24c, 2); // amBackupDebugLevel + setVariable(0x0893a260, 2); // amCreditDebugLevel + setVariable(0x0893a4b8, 2); // amDipswDebugLevel + setVariable(0x0893a4bc, 2); // amDongleDebugLevel + setVariable(0x0893a4c0, 2); // amEepromDebugLevel + setVariable(0x0893a4c4, 2); // amHwmonitorDebugLevel + setVariable(0x0893a4c8, 2); // amJvsDebugLevel + setVariable(0x0893a4cc, 2); // amLibDebugLevel + setVariable(0x0893a4d0, 2); // amMiscDebugLevel + setVariable(0x0893a4d4, 2); // amOsinfoDebugLevel + setVariable(0x0893a4d8, 2); // amSysDataDebugLevel + setVariable(0x0893a4e0, 2); // bcLibDebugLevel + detourFunction(0x08190e80, amDongleInit); + detourFunction(0x08191201, amDongleIsAvailable); + detourFunction(0x08191125, amDongleUpdate); + } + break; - case THE_HOUSE_OF_THE_DEAD_4: - { - setVariable(0x0a737c60, 2); // amBackupDebugLevel - setVariable(0x0a737c64, 2); // amChunkDataDebugLevel - setVariable(0x0a737c80, 2); // amCreditDebugLevel - setVariable(0x0a737ed8, 2); // amDipswDebugLevel - setVariable(0x0a737edc, 2); // amDiskDebugLevel - setVariable(0x0a737ee0, 2); // amDongleDebugLevel - setVariable(0x0a737ee4, 2); // amEepromDebugLevel - setVariable(0x0a737ee8, 2); // amHmDebugLevel - setVariable(0x0a737ef0, 2); // amJvsDebugLevel - setVariable(0x0a737f14, 2); // amLibDebugLevel - setVariable(0x0a737f18, 2); // amMiscDebugLevel - setVariable(0x0a737f1c, 2); // amSysDataDebugLevel - setVariable(0x0a737f20, 2); // bcLibDebugLevel - setVariable(0x0a737f24, 0x0FFFFFFF); // s_logMask - detourFunction(0x08320178, amDongleInit); - detourFunction(0x08320459, amDongleIsAvailable); - detourFunction(0x083203c0, amDongleUpdate); - setVariable(0x0837d6aa, cpu_vendor.ebx); - setVariable(0x0837d6ba, cpu_vendor.edx); - setVariable(0x0837d6c5, cpu_vendor.ecx); - } - break; - case THE_HOUSE_OF_THE_DEAD_4_TEST: - { - detourFunction(0x080677a0, amDongleInit); - detourFunction(0x08067a81, amDongleIsAvailable); - detourFunction(0x080679e8, amDongleUpdate); - setVariable(0x0807217a, cpu_vendor.ebx); - setVariable(0x0807218a, cpu_vendor.edx); - setVariable(0x08072195, cpu_vendor.ecx); - } - break; - case VF5_REVC: - { - detourFunction(0x085c6010, amDongleInit); - detourFunction(0x085c63cc, amDongleIsAvailable); - detourFunction(0x085c62f0, amDongleUpdate); - } - 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 - detourFunction(0x084e50d8, amDongleInit); - detourFunction(0x084e5459, amDongleIsAvailable); - detourFunction(0x084e537d, amDongleUpdate); - //detourFunction(0x08074a8c, _putConsole); - setVariable(0x0840b06f, 0xc48306eb); // Patch to initialize???? - } - break; - case LETS_GO_JUNGLE_SPECIAL: - { - setVariable(0x08c453e4, 2); // amBackupDebugLevel - setVariable(0x08c45400, 2); // amCreditDebugLevel - setVariable(0x08c45658, 2); // amDipswDebugLevel - setVariable(0x08c4565c, 2); // amDongleDebugLevel - setVariable(0x08c45660, 2); // amEepromDebugLevel - setVariable(0x08c45664, 2); // amHwmonitorDebugLevel - setVariable(0x08c45668, 2); // amJvsDebugLevel - setVariable(0x08c4566c, 2); // amLibDebugLevel - setVariable(0x08c45670, 2); // amMiscDebugLevel - setVariable(0x08c45678, 2); // amSysDataDebugLevel - setVariable(0x08c45680, 2); // bcLibDebugLevel - setVariable(0x08c45674, 2); // amOsinfoDebugLevel - setVariable(0x08c45684, 0x0FFFFFFF); // s_logMask - detourFunction(0x08510320, amDongleInit); - detourFunction(0x085106dc, amDongleIsAvailable); - detourFunction(0x08510600, amDongleUpdate); - detourFunction(0x08075012, _putConsole); - } - break; - case ID4: - { - setVariable(0x08d71750, 2); // amBackupDebugLevel - setVariable(0x08d71760, 2); // amCreditDebugLevel - setVariable(0x08d719b8, 2); // amDipswDebugLevel - setVariable(0x08d719bc, 2); // amDongleDebugLevel - setVariable(0x08d719c0, 2); // amEepromDebugLevel - setVariable(0x08d719c4, 2); // amHwmonitorDebugLevel - setVariable(0x08d719c8, 2); // amJvsDebugLevel - setVariable(0x08d719cc, 2); // amLibDebugLevel - setVariable(0x08d719d0, 2); // amMiscDebugLevel - setVariable(0x08d719d8, 2); // amSysDataDebugLevel - setVariable(0x08d719e0, 2); // bcLibDebugLevel - setVariable(0x08d719d4, 2); // amOsinfoDebugLevel - setVariable(0x08d719e4, 0x0FFFFFFF); // s_logMask - detourFunction(0x086e2336, amDongleInit); - detourFunction(0x086e0d81, amDongleIsAvailable); - detourFunction(0x086e17e5, amDongleUpdate); - detourFunction(0x0808f9a8, _putConsole); - } - default: - // Don't do any patches for random games + case THE_HOUSE_OF_THE_DEAD_4: + { + setVariable(0x0a737c60, 2); // amBackupDebugLevel + setVariable(0x0a737c64, 2); // amChunkDataDebugLevel + setVariable(0x0a737c80, 2); // amCreditDebugLevel + setVariable(0x0a737ed8, 2); // amDipswDebugLevel + setVariable(0x0a737edc, 2); // amDiskDebugLevel + setVariable(0x0a737ee0, 2); // amDongleDebugLevel + setVariable(0x0a737ee4, 2); // amEepromDebugLevel + setVariable(0x0a737ee8, 2); // amHmDebugLevel + setVariable(0x0a737ef0, 2); // amJvsDebugLevel + setVariable(0x0a737f14, 2); // amLibDebugLevel + setVariable(0x0a737f18, 2); // amMiscDebugLevel + setVariable(0x0a737f1c, 2); // amSysDataDebugLevel + setVariable(0x0a737f20, 2); // bcLibDebugLevel + setVariable(0x0a737f24, 0x0FFFFFFF); // s_logMask + detourFunction(0x08320178, amDongleInit); + detourFunction(0x08320459, amDongleIsAvailable); + detourFunction(0x083203c0, amDongleUpdate); + setVariable(0x0837d6aa, cpu_vendor.ebx); + setVariable(0x0837d6ba, cpu_vendor.edx); + setVariable(0x0837d6c5, cpu_vendor.ecx); + } + break; + case THE_HOUSE_OF_THE_DEAD_4_TEST: + { + detourFunction(0x080677a0, amDongleInit); + detourFunction(0x08067a81, amDongleIsAvailable); + detourFunction(0x080679e8, amDongleUpdate); + setVariable(0x0807217a, cpu_vendor.ebx); + setVariable(0x0807218a, cpu_vendor.edx); + setVariable(0x08072195, cpu_vendor.ecx); + } + break; + case VF5_REVC: + { + 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 + } + 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 + detourFunction(0x084e50d8, amDongleInit); + detourFunction(0x084e5459, amDongleIsAvailable); + detourFunction(0x084e537d, amDongleUpdate); + detourFunction(0x08074a8c, _putConsole); + 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 + + detourFunction(0x084e4efc, stub0); // Stub amDipswInit + detourFunction(0x084e500e, stub0); // Stub amDipswGetData + detourFunction(0x084e5086, stub0); // Stub amDipswSetLed + detourFunction(0x084e4f98, stub0); // Stub amDipswExit + setVariable(0x0840d858, 0x1c899090); // No more Full Screen from the Game + //From Teknoparrot + 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: + { + setVariable(0x08c453e4, 2); // amBackupDebugLevel + setVariable(0x08c45400, 2); // amCreditDebugLevel + setVariable(0x08c45658, 2); // amDipswDebugLevel + setVariable(0x08c4565c, 2); // amDongleDebugLevel + setVariable(0x08c45660, 2); // amEepromDebugLevel + setVariable(0x08c45664, 2); // amHwmonitorDebugLevel + setVariable(0x08c45668, 2); // amJvsDebugLevel + setVariable(0x08c4566c, 2); // amLibDebugLevel + setVariable(0x08c45670, 2); // amMiscDebugLevel + setVariable(0x08c45678, 2); // amSysDataDebugLevel + setVariable(0x08c45680, 2); // bcLibDebugLevel + setVariable(0x08c45674, 2); // amOsinfoDebugLevel + setVariable(0x08c45684, 0x0FFFFFFF); // s_logMask + 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 + } + break; + case ID4: + { + setVariable(0x08d71750, 2); // amBackupDebugLevel + setVariable(0x08d71760, 2); // amCreditDebugLevel + setVariable(0x08d719b8, 2); // amDipswDebugLevel + setVariable(0x08d719bc, 2); // amDongleDebugLevel + setVariable(0x08d719c0, 2); // amEepromDebugLevel + setVariable(0x08d719c4, 2); // amHwmonitorDebugLevel + setVariable(0x08d719c8, 2); // amJvsDebugLevel + setVariable(0x08d719cc, 2); // amLibDebugLevel + setVariable(0x08d719d0, 2); // amMiscDebugLevel + setVariable(0x08d719d8, 2); // amSysDataDebugLevel + setVariable(0x08d719e0, 2); // bcLibDebugLevel + setVariable(0x08d719d4, 2); // amOsinfoDebugLevel + setVariable(0x08d719e4, 0x0FFFFFFF); // s_logMask + detourFunction(0x086e2336, amDongleInit); + detourFunction(0x086e0d81, amDongleIsAvailable); + detourFunction(0x086e17e5, amDongleUpdate); + 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 + } + default: + // Don't do any patches for random games break; } return 0; diff --git a/src/lindbergh/securityboard.c b/src/lindbergh/securityboard.c index e2e4238..149a7ce 100644 --- a/src/lindbergh/securityboard.c +++ b/src/lindbergh/securityboard.c @@ -77,6 +77,7 @@ int securityBoardSetDipSwitch(int switchNumber, int value) int securityBoardSetSwitch(JVSInput switchNumber, int value) { + printf("Pressed\n"); switch (switchNumber) { case BUTTON_TEST: From a2d0c53eb3044aef4c54a1d3917c2b8decba30ff Mon Sep 17 00:00:00 2001 From: Bobby Dilley Date: Sun, 3 Dec 2023 10:33:12 +0000 Subject: [PATCH 06/31] 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 07/31] 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 08/31] 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 09/31] 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 10/31] 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 11/31] 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 12/31] 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 59c18b3c2ca9379bae7a21e132d89a49b4cca150 Mon Sep 17 00:00:00 2001 From: Bobby Dilley Date: Tue, 12 Dec 2023 14:00:52 +0000 Subject: [PATCH 13/31] Add all games --- .vscode/settings.json | 3 +- docs/games.txt | 94 ++++++++++++++++++++++ docs/lindbergh.conf | 41 ++++++---- src/hookcrc32/Makefile | 17 ---- src/hookcrc32/hookcrc32.c | 95 ---------------------- src/hookcrc32/hookcrc32.so | Bin 16900 -> 0 bytes src/lindbergh/config.c | 160 ++++++++++++++++++++++++++----------- src/lindbergh/config.h | 53 ++++++++---- src/lindbergh/graphics.c | 6 +- src/lindbergh/hook.c | 12 +-- src/lindbergh/jvs.c | 14 +++- src/lindbergh/patch.c | 83 +++++++++++-------- 12 files changed, 343 insertions(+), 235 deletions(-) create mode 100644 docs/games.txt delete mode 100644 src/hookcrc32/Makefile delete mode 100644 src/hookcrc32/hookcrc32.c delete mode 100755 src/hookcrc32/hookcrc32.so diff --git a/.vscode/settings.json b/.vscode/settings.json index 71a6611..fdc3f2f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,6 +8,7 @@ "stdarg.h": "c", "ioctl.h": "c", "segaeax.h": "c", - "passthrough.h": "c" + "passthrough.h": "c", + "pthread.h": "c" } } diff --git a/docs/games.txt b/docs/games.txt new file mode 100644 index 0000000..4a99a71 --- /dev/null +++ b/docs/games.txt @@ -0,0 +1,94 @@ + +2SPICY +After Burner +After Burner Climax +After Burner Climax [Rev.A] +After Burner Climax [Rev.B] +After Burner Climax SDX +After Burner Climax SDX [Rev.A] +AMI-GYO +Ami No.3 +Answer x Answer +Answer x Answer 2 +Answer x Answer Live! +Blackjack Nailed Ace +Club Majesty - Extend - Cloud Nine +Club Majesty - Extend - Wheel Maniacs +Club Majesty Formal: Attractive Deck Poker +Club Majesty Formal: Cosmic Challenge +Club Majesty Formal: Cosmic Challenge [Rev.C] +Club Majesty: Gatling Poker +Club Majesty: Where's Wally! +Derby Owners Club 2008 Feel the Rush +Derby Owners Club 2009 Ride for the live +Ghost Squad Evolution +Harley Davidson King of the Road +HOTD4 +HOTD4SP +HOTD EX +Hummer +Hummer Extreme +Hummer Extreme Edition MDX +Info Station 2 [Rev.C] +Initial D Arcade Stage 4 +Initial D Arcade Stage 4 [Rev.A] +Initial D Arcade Stage 4 [Rev.B] +Initial D Arcade Stage 4 [Rev.C] +Initial D Arcade Stage 4 [Rev.D] +Initial D Arcade Stage 4 [Rev.G] +Initial D Arcade Stage 5 +Initial D Arcade Stage 5 Exp 2.0 +Initial D Arcade Stage 5 [Rev.A] +Let's Go Jungle +Let's Go Jungle Special +MJ4 Evolution +Outrun 2 SP SDX +Outrun 2 SP SDX [Rev.A] +Primeval Hunt +Rambo +Rambo (China) +Router Update (for VTF) +R-Tuned +Sangokushi Taisen 2 +Sangokushi Taisen 3 +Sega Network Casino Club STD +Sega Network Casino Club Ver.2 +Sega Network Casino Club Ver.2 [Rev.B] +Sega Network Casino Club Ver.3 +Sega Race TV +Sengokushi Taisen3 War Begins +Star Horse 2 Fifth Expansion [Rev.B] +Star Horse 2 Fifth Expansion [Rev.D] +Star Horse 2 Fifth Expansion [Rev.E] +Star Horse 2 Final Destination +Starhorse 2 Fourth Ambition +Star Horse 2 Fourth Ambition +Star Horse 2 New Generation +Star Horse 2 Second Fusion +Star Horse 2 Third Evolution +Star Horse 2 Third Evolution (Hong Kong) +Taisen Mahjong 4 (1.0) +Taisen Mahjong 4 (2.0) +Taisen Mahjong 4 (3.0) +Taisen Mahjong 4 (4.0) +Taisen Mahjong 4 (5.0) +Taisen Mahjong 4 (6.0) +Taisen Mahjong 4 (7.0) +Taisen Mahjong 4 (8.0) +toAmi-Gyo +to AMI GYO +VBIOS Update (2.0) +VBIOS Update (3.0) +VBIOS Update (for VTF) +Virtua Fighter 5 +Virtua Fighter 5 Final Showdown +Virtua Fighter 5 Final Showdown [Rev.A] +Virtua Fighter 5 R +Virtua Fighter 5 [Rev.A] +Virtua Fighter 5 [Rev.B] +Virtua Fighter 5 [Rev.E] +Virtua Fighter 5 R [Rev.D] +Virtua Tennis 3 +World Club Championship Football 2008-2009 +World Club Championship Football 2009-2010 [ASIA] +World Club Championship Football 2009-2010 [JP] diff --git a/docs/lindbergh.conf b/docs/lindbergh.conf index d88f2a1..4964038 100644 --- a/docs/lindbergh.conf +++ b/docs/lindbergh.conf @@ -22,26 +22,26 @@ WIDTH 640 # Set the requested dip switch height here 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 - -# 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 - -# 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 - # 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 +# 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 + +# 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 + +# 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 + # Define the path to pass the JVS packets to # JVS_PATH /dev/ttyUSB0 @@ -54,5 +54,14 @@ EMULATE_JVS 1 # Define the path to pass the motionboard packets to # MOTIONBOARD_PATH /dev/ttyUSB0 +# Define the path to the sram.bin file +# SRAM_PATH sram.bin + +# Define the path to the eeprom.bin file +# EEPROM_PATH eeprom.bin + # Set if the emulator should go full screen -FULLSCREEN 0 +# FULLSCREEN 0 + +# Set if you would like to apply AMD CPU / GPU Fixes +# AMD_FIX 0 diff --git a/src/hookcrc32/Makefile b/src/hookcrc32/Makefile deleted file mode 100644 index 4a2e6f4..0000000 --- a/src/hookcrc32/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -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 - -hookcrc32.so: $(OBJS) - $(LD) $(OBJS) $(LDFLAGS) $(CFLAGS) -o hookcrc32.so - rm -f *.o - -clean: - rm -f hookcrc32.so diff --git a/src/hookcrc32/hookcrc32.c b/src/hookcrc32/hookcrc32.c deleted file mode 100644 index 9f7e5fc..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/hookcrc32/hookcrc32.so b/src/hookcrc32/hookcrc32.so deleted file mode 100755 index ff67e24d404dd061a664ecd403e913281ddf5ee3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16900 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 KP3?qFi~j=@&`u`+ diff --git a/src/lindbergh/config.c b/src/lindbergh/config.c index 4b70060..0e3452d 100644 --- a/src/lindbergh/config.c +++ b/src/lindbergh/config.c @@ -36,7 +36,7 @@ static int detectGame(uint32_t elf_crc) if (elf_crc == 0x93ea7e11) { config.game = SEGABOOT_2_4; - config.gameStatus = NOT_WORKING; + config.gameStatus = WORKING; return 0; } @@ -56,7 +56,7 @@ static int detectGame(uint32_t elf_crc) if (elf_crc == 0x6d055308) { - config.game = OUTRUN; + config.game = OUTRUN_2_SP_SDX_REVA; config.emulateDriveboard = 1; config.emulateMotionboard = 1; config.gameStatus = WORKING; @@ -65,7 +65,7 @@ static int detectGame(uint32_t elf_crc) if (elf_crc == 0xffdccaaa) { - config.game = OUTRUN_TEST; + config.game = OUTRUN_2_SP_SDX_REVA_TEST; config.emulateDriveboard = 1; config.emulateMotionboard = 1; config.gameStatus = WORKING; @@ -75,7 +75,7 @@ static int detectGame(uint32_t elf_crc) if (elf_crc == 0xd4726d61) { config.game = LETS_GO_JUNGLE; - config.gameStatus = NOT_WORKING; + config.gameStatus = WORKING; return 0; } @@ -88,98 +88,157 @@ static int detectGame(uint32_t elf_crc) if (elf_crc == 0xcc02de7d) { - config.game = ABC_2006; + config.game = AFTER_BURNER_CLIMAX; config.gameStatus = WORKING; return 0; } if (elf_crc == 0x152530dd) { - config.game = ABC_2007; + config.game = AFTER_BURNER_CLIMAX_REVA; config.gameStatus = WORKING; return 0; } if (elf_crc == 0x4e9ccf33) { - config.game = ID4; + config.game = INITIALD_4; 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 == 0xb05d9bbe) - { - config.game = RTUNED; - config.emulateDriveboard = 1; - config.emulateMotionboard = 1; + config.game = SEGA_RACE_TV; config.gameStatus = WORKING; return 0; } - + + if (elf_crc == 0xb05d9bbe) + { + config.game = R_TUNED; + config.gameStatus = WORKING; + return 0; + } + if (elf_crc == 0xc4b7e89) { - config.game = VT3; + config.game = VIRTUA_TENNIS_3; config.gameStatus = NOT_WORKING; return 0; } if (elf_crc == 0x1bf1b627) { - config.game = VF5_REVC; + config.game = VIRTUA_FIGHTER_5_REVC; config.gameStatus = WORKING; return 0; } - + + if (elf_crc == 0x3CC635EE) + { + config.game = SEGABOOT_2_4; + config.gameStatus = WORKING; + return 0; + } + config.game = UNKNOWN; return 1; } char *getGameName() { + char *unknownGameTitle = "Unknown Game"; switch (config.game) { + case AFTER_BURNER_CLIMAX: + return "After Burner Climax"; + case AFTER_BURNER_CLIMAX_REVA: + return "After Burner Climax Rev A"; + case AFTER_BURNER_CLIMAX_REVB: + return "After Burner Climax Rev B"; + case AFTER_BURNER_CLIMAX_SDX: + return "After Burner Climax SDX"; + case AFTER_BURNER_CLIMAX_SDX_REVA: + return "After Burner Climax SDX Rev A"; + case GHOST_SQUAD_EVOLUTION: + return "Ghost Squad Evolution"; + case HARLEY_DAVIDSON: + return "Harley Davidson: King of the Road"; + case HUMMER: + return "Hummer"; + case HUMMER_EXTREME: + return "Hummer Extreme"; + case HUMMER_EXTREME_MDX: + return "Hummer Extreme MDX"; + case INITIALD_4: + return "Initial D Arcade Stage 4"; + case INITIALD_5: + return "Initial D Arcade Stage 5"; + case LETS_GO_JUNGLE: + return "Let's Go Jungle! Lost on the Island of Spice!"; + case LETS_GO_JUNGLE_SPECIAL: + return "Let's Go Jungle! Special!"; + case OUTRUN_2_SP_SDX: + return "Outrun 2 SP SDX"; + case OUTRUN_2_SP_SDX_REVA: + return "Outrun 2 SP SDX Rev A"; + case OUTRUN_2_SP_SDX_REVA_TEST: + return "Outrun 2 SP SDX Rev A Test Mode"; + case OUTRUN_2_SP_SDX_TEST: + return "Outrun 2 SP SDX Test Mode"; + case PRIMEVAL_HUNT: + return "Primeval Hunt"; + case RAMBO: + return "Rambo"; + case RAMBO_CHINA: + return "Rambo China Release"; + case R_TUNED: + return "RTuned"; case SEGABOOT: - return "SEGABOOT"; + return "Segaboot"; case SEGABOOT_2_4: - return "SEGABOOT 2.4"; + return "Segaboot from 2.4 Kernel"; case SEGABOOT_2_6: - return "SEGABOOT 2.6"; - case OUTRUN: - return "Outrun 2 SP"; + return "Segaboot from 2.6 Kernel"; + case SEGA_RACE_TV: + return "SEGA Race TV"; case THE_HOUSE_OF_THE_DEAD_4: return "The House of the Dead 4"; + case THE_HOUSE_OF_THE_DEAD_4_SPECIAL: + return "The House of the Dead 4 Special"; + case THE_HOUSE_OF_THE_DEAD_4_SPECIAL_TEST: + return "The House of the Dead 4 Special Test Mode"; case THE_HOUSE_OF_THE_DEAD_4_TEST: - return "The House of the Dead 4 - Test Menu"; - case LETS_GO_JUNGLE: - return "Let's Go Jungle! Lost on the Island of Spice"; - case LETS_GO_JUNGLE_SPECIAL: - return "Let's Go Jungle Special"; - case ABC_2006: - case ABC_2007: - return "After Burner Climax"; - case ID4: - return "Initial D 4"; - case SRTV: - return "SEGA Race TV"; - case RTUNED: - return "R-Tuned Ultimate Street Racing"; - case VT3: + return "The House of the Dead 4 Test Mode"; + case THE_HOUSE_OF_THE_DEAD_EX: + return "The House of the Dead Ex"; + case TOO_SPICY: + return "2 Step : 2 Spicy"; + case UNKNOWN: + return unknownGameTitle; + case VIRTUA_FIGHTER_5: + return "Virtua Fighter 5"; + case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN: + return "Virtua Fighter 5 Final Showdown"; + case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVA: + return "Virtua Fighter 5 Final Showdown Rev A"; + case VIRTUA_FIGHTER_5_R: + return " Virtua Fighter 5 R"; + case VIRTUA_FIGHTER_5_REVA: + return "Virtua Fighter 5 Rev A"; + case VIRTUA_FIGHTER_5_REVB: + return "Virtua Fighter 5 Rev B"; + case VIRTUA_FIGHTER_5_REVC: + return "Virtua Fighter 5 Rev C"; + case VIRTUA_FIGHTER_5_R_REVD: + return "Virtua Fighter 5 Rev D"; + case VIRTUA_TENNIS_3: return "Virtua Tennis 3"; - case VF5_REVC: - return "Virtua Fighter 5 - RevC"; default: - return "Unknown Game"; + return unknownGameTitle; } - return "Unknown Game"; + return unknownGameTitle; } int readConfig(FILE *configFile, EmulatorConfig *config) @@ -223,6 +282,9 @@ int readConfig(FILE *configFile, EmulatorConfig *config) else if (strcmp(command, "EMULATE_JVS") == 0) config->emulateJVS = atoi(getNextToken(NULL, " ", &saveptr)); + else if (strcmp(command, "AMD_FIX") == 0) + config->amdFix = atoi(getNextToken(NULL, " ", &saveptr)); + else if (strcmp(command, "JVS_PATH") == 0) strcpy(config->jvsPath, getNextToken(NULL, " ", &saveptr)); @@ -246,6 +308,7 @@ int initConfig() config.emulateDriveboard = 0; config.emulateMotionboard = 0; config.emulateJVS = 1; + config.amdFix = 0; config.fullscreen = 0; config.lindberghColour = YELLOW; strcpy(config.eepromPath, "eeprom.bin"); @@ -257,9 +320,10 @@ int initConfig() config.width = 1024; config.height = 768; config.crc32 = elf_crc; + if (detectGame(config.crc32) != 0) { - printf("Warning: Unsure what game this is, using default configuration values.\n"); + printf("Warning: Unsure what game this is. Please submit this new game to the GitHub repository: https://github.com/bobbydilley/lindbergh-loader/issues/new?title=Please+add+new+game+0x%X&body=I+tried+to+launch+the+following+game:\n", config.crc32); } configFile = fopen(CONFIG_PATH, "r"); diff --git a/src/lindbergh/config.h b/src/lindbergh/config.h index b0f2c7c..09af474 100644 --- a/src/lindbergh/config.h +++ b/src/lindbergh/config.h @@ -4,23 +4,48 @@ typedef enum { - UNKNOWN, + AFTER_BURNER_CLIMAX, + AFTER_BURNER_CLIMAX_REVA, + AFTER_BURNER_CLIMAX_REVB, + AFTER_BURNER_CLIMAX_SDX, + AFTER_BURNER_CLIMAX_SDX_REVA, + GHOST_SQUAD_EVOLUTION, + HARLEY_DAVIDSON, + HUMMER, + HUMMER_EXTREME, + HUMMER_EXTREME_MDX, + INITIALD_4, + INITIALD_5, + LETS_GO_JUNGLE, + LETS_GO_JUNGLE_SPECIAL, + OUTRUN_2_SP_SDX, + OUTRUN_2_SP_SDX_REVA, + OUTRUN_2_SP_SDX_REVA_TEST, + OUTRUN_2_SP_SDX_TEST, + PRIMEVAL_HUNT, + RAMBO, + RAMBO_CHINA, + R_TUNED, SEGABOOT, SEGABOOT_2_4, SEGABOOT_2_6, + SEGA_RACE_TV, THE_HOUSE_OF_THE_DEAD_4, + THE_HOUSE_OF_THE_DEAD_4_SPECIAL, + THE_HOUSE_OF_THE_DEAD_4_SPECIAL_TEST, THE_HOUSE_OF_THE_DEAD_4_TEST, - OUTRUN, - OUTRUN_TEST, - LETS_GO_JUNGLE, - LETS_GO_JUNGLE_SPECIAL, - ABC_2006, - ABC_2007, - ID4, - SRTV, - RTUNED, - VT3, - VF5_REVC + THE_HOUSE_OF_THE_DEAD_EX, + TOO_SPICY, + UNKNOWN, + VIRTUA_FIGHTER_5, + VIRTUA_FIGHTER_5_FINAL_SHOWDOWN, + VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVA, + VIRTUA_FIGHTER_5_R, + VIRTUA_FIGHTER_5_REVA, + VIRTUA_FIGHTER_5_REVB, + VIRTUA_FIGHTER_5_REVC, + VIRTUA_FIGHTER_5_R_REVD, + VIRTUA_TENNIS_3 } Game; typedef enum @@ -33,7 +58,7 @@ typedef enum { WORKING, NOT_WORKING -}GameStatus; +} GameStatus; typedef struct { @@ -50,11 +75,11 @@ typedef struct char driveboardPath[MAX_PATH_LENGTH]; int width; int height; + int amdFix; Game game; Colour lindberghColour; GameStatus gameStatus; uint32_t crc32; - } EmulatorConfig; int initConfig(); diff --git a/src/lindbergh/graphics.c b/src/lindbergh/graphics.c index bb7c369..53ea574 100644 --- a/src/lindbergh/graphics.c +++ b/src/lindbergh/graphics.c @@ -30,7 +30,8 @@ FGAPI int FGAPIENTRY glutEnterGameMode() glutCreateWindow(gameTitle); // Outrun doesn't run the glutMainLoop through, so we'll do that here - if (getConfig()->game == OUTRUN || getConfig()->game == OUTRUN_TEST) + Game game = getConfig()->game; + if (game == OUTRUN_2_SP_SDX || game == OUTRUN_2_SP_SDX_TEST || game == OUTRUN_2_SP_SDX_REVA || game == OUTRUN_2_SP_SDX_REVA_TEST) { pthread_t glutMainLoopID; pthread_create(&glutMainLoopID, NULL, &glutMainLoopThread, NULL); @@ -163,7 +164,6 @@ int XNextEvent(Display *display, XEvent *event_return) { case 28: setSwitch(SYSTEM, BUTTON_TEST, event_return->type == KeyPress); - //securityBoardSetSwitch(BUTTON_TEST, 1); break; case 39: setSwitch(PLAYER_1, BUTTON_SERVICE, event_return->type == KeyPress); @@ -286,4 +286,4 @@ void glGenFencesNV(int n, uint *fences) void glDeleteFencesNV(int a, const uint *b) { return; -} \ No newline at end of file +} diff --git a/src/lindbergh/hook.c b/src/lindbergh/hook.c index 0202d09..8b9831f 100644 --- a/src/lindbergh/hook.c +++ b/src/lindbergh/hook.c @@ -64,7 +64,6 @@ static void handleSegfault(int signal, siginfo_t *info, void *ptr) // 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); switch (*code) { case 0xED: @@ -134,17 +133,14 @@ 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"); + printf("SEGA Lindbergh Loader\nRobert Dilley 2023\nNot for public consumption\n\n"); + // Get offsets of the Game's ELF and calculate CRC32. dl_iterate_phdr(callback, NULL); + // 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; @@ -634,4 +630,4 @@ int unsetenv(const char *name) } return _unsetenv(name); -} \ No newline at end of file +} diff --git a/src/lindbergh/jvs.c b/src/lindbergh/jvs.c index bdd8208..3756c9c 100644 --- a/src/lindbergh/jvs.c +++ b/src/lindbergh/jvs.c @@ -3,6 +3,7 @@ #include #include #include +#include /* POSIX threads API to create and manage threads in the program */ /* The in and out packets used to read and write to and from*/ JVSPacket inputPacket, outputPacket; @@ -13,6 +14,8 @@ unsigned char outputBuffer[JVS_MAX_PACKET_SIZE], inputBuffer[JVS_MAX_PACKET_SIZE /* Holds the status of the sense line */ int senseLine = 3; +pthread_mutex_t jvsMutex = PTHREAD_MUTEX_INITIALIZER; + JVSIO io = {0}; /** @@ -177,6 +180,8 @@ JVSStatus processPacket() /* Set the entire packet success line */ outputPacket.data[outputPacket.length++] = STATUS_SUCCESS; + pthread_mutex_lock(&jvsMutex); + while (index < inputPacket.length - 1) { int size = 1; @@ -470,6 +475,8 @@ JVSStatus processPacket() index += size; } + pthread_mutex_unlock(&jvsMutex); + writePacket(&outputPacket); return JVS_STATUS_SUCCESS; @@ -559,6 +566,8 @@ JVSStatus readPacket(JVSPacket *packet) */ JVSStatus writePacket(JVSPacket *packet) { + + /* Get pointer to raw data in packet */ unsigned char *packetPointer = (unsigned char *)packet; @@ -600,7 +609,7 @@ JVSStatus writePacket(JVSPacket *packet) /** * Gets the sense line value - * + * * Values are: * 3 = no device, after a RESET * 1 = address assigned @@ -638,7 +647,10 @@ int incrementCoin(JVSPlayer player, int amount) int setAnalogue(JVSInput channel, int value) { + pthread_mutex_lock(&jvsMutex); io.state.analogueChannel[channel] = value; + pthread_mutex_unlock(&jvsMutex); + return 1; } diff --git a/src/lindbergh/patch.c b/src/lindbergh/patch.c index ce2328c..633b177 100644 --- a/src/lindbergh/patch.c +++ b/src/lindbergh/patch.c @@ -24,7 +24,6 @@ static void setVariable(uint32_t address, uint32_t value) printf("Error: Cannot unprotect memory region to change variable (%d)\n", prot); return; } - // printf("Variable: %8X , Value: %8X\n",(uint32_t)variable, value); *variable = value; } @@ -42,7 +41,6 @@ static void setMem(uint32_t address, uint32_t value, int size) printf("Error: Cannot unprotect memory region to change variable (%d)\n", prot); return; } - // printf("Variable: %8X , Value: %8X\n",(uint32_t)variable, value); memccpy((void *)variable, (void *)value, 1, size); } @@ -115,7 +113,7 @@ void _putConsole(const char *format, ...) } else if (*format == '0') { - format ++; + format++; if (*format == '2') { format++; @@ -144,11 +142,11 @@ void _putConsole(const char *format, ...) int initPatch() { - Game game = getConfig()->game; + EmulatorConfig *config = getConfig(); - switch (game) + switch (config->game) { - case RTUNED: + case R_TUNED: { detourFunction(0x08366846, amDongleInit); detourFunction(0x08365301, amDongleIsAvailable); @@ -156,14 +154,14 @@ int initPatch() } break; - case SRTV: + case SEGA_RACE_TV: { detourFunction(0x084d5b40, amDongleInit); detourFunction(0x084d45f9, amDongleIsAvailable); detourFunction(0x084d4fef, amDongleUpdate); } break; - case ABC_2006: + case AFTER_BURNER_CLIMAX_REVA: { setVariable(0x0a0a37e4, 2); // amBackupDebugLevel setVariable(0x0a0a3800, 2); // amCreditDebugLevel @@ -177,12 +175,13 @@ int initPatch() setVariable(0x0a0a3a74, 2); // amOsinfoDebugLevel setVariable(0x0a0a3a78, 2); // amSysDataDebugLevel setVariable(0x0a0a3a80, 2); // bcLibDebugLevel + detourFunction(0x081e4980, amDongleInit); detourFunction(0x081e4cce, amDongleIsAvailable); detourFunction(0x081e4bfa, amDongleUpdate); } break; - case ABC_2007: + case AFTER_BURNER_CLIMAX_REVB: { setVariable(0x0a0a0d24, 2); // amBackupDebugLevel setVariable(0x0a0a0d40, 2); // amCreditDebugLevel @@ -196,13 +195,14 @@ int initPatch() setVariable(0x0a0a0fb4, 2); // amOsinfoDebugLevel setVariable(0x0a0a0fb8, 2); // amSysDataDebugLevel setVariable(0x0a0a0fc0, 2); // bcLibDebugLevel + detourFunction(0x081e3424, amDongleInit); detourFunction(0x081e3772, amDongleIsAvailable); detourFunction(0x081e369e, amDongleUpdate); - setVariable(0x081e7945, 0x00000001); //Test + setVariable(0x081e7945, 0x00000001); // Test } break; - case OUTRUN: + case OUTRUN_2_SP_SDX_REVA: { setVariable(0x0893a24c, 2); // amBackupDebugLevel setVariable(0x0893a260, 2); // amCreditDebugLevel @@ -216,6 +216,7 @@ int initPatch() setVariable(0x0893a4d4, 2); // amOsinfoDebugLevel setVariable(0x0893a4d8, 2); // amSysDataDebugLevel setVariable(0x0893a4e0, 2); // bcLibDebugLevel + detourFunction(0x08190e80, amDongleInit); detourFunction(0x08191201, amDongleIsAvailable); detourFunction(0x08191125, amDongleUpdate); @@ -238,12 +239,17 @@ int initPatch() setVariable(0x0a737f1c, 2); // amSysDataDebugLevel setVariable(0x0a737f20, 2); // bcLibDebugLevel setVariable(0x0a737f24, 0x0FFFFFFF); // s_logMask + detourFunction(0x08320178, amDongleInit); detourFunction(0x08320459, amDongleIsAvailable); detourFunction(0x083203c0, amDongleUpdate); - setVariable(0x0837d6aa, cpu_vendor.ebx); - setVariable(0x0837d6ba, cpu_vendor.edx); - setVariable(0x0837d6c5, cpu_vendor.ecx); + + if (config->amdFix) + { + setVariable(0x0837d6aa, cpu_vendor.ebx); + setVariable(0x0837d6ba, cpu_vendor.edx); + setVariable(0x0837d6c5, cpu_vendor.ecx); + } } break; case THE_HOUSE_OF_THE_DEAD_4_TEST: @@ -251,24 +257,29 @@ int initPatch() detourFunction(0x080677a0, amDongleInit); detourFunction(0x08067a81, amDongleIsAvailable); detourFunction(0x080679e8, amDongleUpdate); - setVariable(0x0807217a, cpu_vendor.ebx); - setVariable(0x0807218a, cpu_vendor.edx); - setVariable(0x08072195, cpu_vendor.ecx); + + if (config->amdFix) + { + setVariable(0x0807217a, cpu_vendor.ebx); + setVariable(0x0807218a, cpu_vendor.edx); + setVariable(0x08072195, cpu_vendor.ecx); + } } break; - case VF5_REVC: + case VIRTUA_FIGHTER_5_REVC: { 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 } break; + case LETS_GO_JUNGLE: { setVariable(0x08c083a4, 2); // amBackupDebugLevel @@ -291,20 +302,25 @@ int initPatch() 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, 0x00000280); // Set ResX + // setVariable(0x082E0078, 0x000001E0); // Set ResY detourFunction(0x084e4efc, stub0); // Stub amDipswInit detourFunction(0x084e500e, stub0); // Stub amDipswGetData detourFunction(0x084e5086, stub0); // Stub amDipswSetLed detourFunction(0x084e4f98, stub0); // Stub amDipswExit + setVariable(0x0840d858, 0x1c899090); // No more Full Screen from the Game - //From Teknoparrot - setVariable(0x083ef701, 0x00036ee9); // AMDFIX - setVariable(0x084032e0, 0x8b90c933); // fix shader compilation with AMD GPUs - setVariable(0x08523950, 0x000000c3); // Remove ADXM_SetupFramework (Not necessary) + + if (config->amdFix) + { + 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: { setVariable(0x08c453e4, 2); // amBackupDebugLevel @@ -324,8 +340,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 @@ -334,7 +350,8 @@ int initPatch() setVariable(0x08438954, 0x1c899090); // No more Full Screen from the Game } break; - case ID4: + + case INITIALD_4: { setVariable(0x08d71750, 2); // amBackupDebugLevel setVariable(0x08d71760, 2); // amCreditDebugLevel @@ -349,10 +366,12 @@ int initPatch() setVariable(0x08d719e0, 2); // bcLibDebugLevel setVariable(0x08d719d4, 2); // amOsinfoDebugLevel setVariable(0x08d719e4, 0x0FFFFFFF); // s_logMask + detourFunction(0x086e2336, amDongleInit); detourFunction(0x086e0d81, amDongleIsAvailable); detourFunction(0x086e17e5, amDongleUpdate); detourFunction(0x0808f9a8, _putConsole); + setVariable(0x080dad63, 0x90909090); // Patch acpSystem::checkDongle setVariable(0x080dad67, 0xE8C3C990); // Patch acpSystem::checkDongle setVariable(0x0807e609, 0x90909090); // Patch initializeArcadeBackup @@ -363,4 +382,4 @@ int initPatch() break; } return 0; -} \ No newline at end of file +} From c2e29d9e268a681590a5ec66d1267184e394f33e Mon Sep 17 00:00:00 2001 From: Bobby Dilley Date: Tue, 12 Dec 2023 15:27:37 +0000 Subject: [PATCH 14/31] Refactor --- .vscode/settings.json | 5 +- Makefile | 3 + docs/lindbergh.conf | 28 +-- docs/supported.md | 17 +- src/libkswapapi/libkswapapi.o | Bin 2372 -> 2332 bytes src/lindbergh/config.c | 52 ++++- src/lindbergh/config.h | 13 +- src/lindbergh/eeprom.c | 14 ++ src/lindbergh/eeprom_settings.c | 332 ++++++++++++++++++++++++++++++++ src/lindbergh/eeprom_settings.h | 5 + src/lindbergh/graphics.c | 96 --------- src/lindbergh/hook.c | 135 ++++++++++--- src/lindbergh/input.c | 117 +++++++++++ src/lindbergh/input.h | 1 + src/lindbergh/patch.c | 144 ++++++++++++-- src/lindbergh/pcidata.h | 28 +++ src/lindbergh/securityboard.c | 25 ++- 17 files changed, 831 insertions(+), 184 deletions(-) create mode 100644 src/lindbergh/eeprom_settings.c create mode 100644 src/lindbergh/eeprom_settings.h create mode 100644 src/lindbergh/input.c create mode 100644 src/lindbergh/input.h create mode 100644 src/lindbergh/pcidata.h diff --git a/.vscode/settings.json b/.vscode/settings.json index fdc3f2f..b959085 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,6 +9,7 @@ "ioctl.h": "c", "segaeax.h": "c", "passthrough.h": "c", - "pthread.h": "c" - } + "config.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 4964038..af609cf 100644 --- a/docs/lindbergh.conf +++ b/docs/lindbergh.conf @@ -30,38 +30,44 @@ EMULATE_JVS 1 # 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 # Define the path to pass the JVS packets to -# JVS_PATH /dev/ttyUSB0 +JVS_PATH /dev/ttyUSB0 # Define the path to pass the rideboard packets to -# RIDEBOARD_PATH /dev/ttyUSB0 +RIDEBOARD_PATH /dev/ttyUSB0 # Define the path to pass the driveboard packets to -# DRIVEBOARD_PATH /dev/ttyUSB0 +DRIVEBOARD_PATH /dev/ttyUSB0 # Define the path to pass the motionboard packets to -# MOTIONBOARD_PATH /dev/ttyUSB0 +MOTIONBOARD_PATH /dev/ttyUSB0 # Define the path to the sram.bin file -# SRAM_PATH sram.bin +SRAM_PATH sram.bin # Define the path to the eeprom.bin file -# EEPROM_PATH eeprom.bin +EEPROM_PATH eeprom.bin # Set if the emulator should go full screen -# FULLSCREEN 0 +FULLSCREEN 0 # Set if you would like to apply AMD CPU / GPU Fixes -# AMD_FIX 0 +AMD_FIX 0 + +# Set the Region ( JP/US/EX ) +REGION EX + +# Set if you want the game to be Free Play +FREEPLAY 1 diff --git a/docs/supported.md b/docs/supported.md index 9ea9245..c51c564 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 @@ -19,20 +20,12 @@ Working is defined by getting into attract mode and running the game, but not ne - The House Of The Dead 4 Special - The House Of The Dead Ex - Virtua Fighter 5 - -## Games that do not work or haven't been tested - -- Hummer - Initial D 4 -- Initial D 5 -- Let's Go Jungle -- Primevil - Virtua Tennis 3 -## How to run specific games +## Games that current do not work -### Let's Go Jungle +- Hummer +- Initial D 5 +- Primevil -No, this game will not start. - -```LD_LIBRARY_PATH=$LD_LIBRARY_PATH:. LD_PRELOAD=lindbergh.so TEA_DIR=`pwd` ./lgj_final``` diff --git a/src/libkswapapi/libkswapapi.o b/src/libkswapapi/libkswapapi.o index d4806865b4a39307621c0ae291c38e493b109776..b98c5e37f05a2c49f9df11265a9f1f5950b84cb5 100644 GIT binary patch delta 928 zcmb7CL1+^}6#X-sNz#_KNt(9UT9aCJE3})Wv1 z2k{~m!*~(nK~I8u@ZhC*P*AWQ^yW=L(1XxR&m#E#HdU{F`2W5C=FjZ>`THi)h}?;b z8}-5ddOCW3hKLjiAAkgh0S@~(z(PAf@)n2)_;)qYI0i2IR7%&ybwT=q7+Fi?ODj&oF4^|g#0jUmH5nhCw`)bWhWlCLR&q2| z^U~C{u`w$-ez+;?b!qy&M>?)Ip)+~$z@%)r# zH1r4GeKY6SwZ#QIud`5fD`aI$D=SXXC97C+9SdU`t-6`)lGZ9c@Dba>@Ld}R;a;Nf zR=uraBBaCqAraLRep8&*7rppd_UeW|g#4M`RA*5;tG~)Fy#?)n{srv;v}sQ}8VHGR zdNyE+oUR2-<-^Z)Mn4P;DHr_?>rJq8(C+DNur07hU|rphaRL&ra{%2&lOwzmdEQ)M zm2E@nFR~~67L+%j&a;<#J=hz54bDSKdm2$gzX+P`L4)WOlx}#7{t@g~@1V?h7v9?v LQcrQUPn`V*Yo(`F delta 985 zcmZ8gO-vI(6rS1b>@G;lwna&;(Ip_&gl=0xLLep(s{tbt4m9x~hEfVNK-;ui4Hxlh z)P(vDUO33jgC2+%4jwQNqBmpW!Gv(raPVS0LW19HTVj}G-uK@3es<=)+4aC~V9nz1 zsvY6gzpa;#QqO)K9-o|?2+kN=o7#Eq>Dn2E>cNKOJ&-Lvh&^dzwbg(r61lEPkQ`sX z1F06lU6h(qMY@M^Kfme=o>P5cpPvUbvmG9r4~10UV0Fu@yuMl8>z!`YL>ilrRahS+ z=SMy-B$r3S=H*f*wv?M$EI&>c)5RQP{~2~hhA>=1xF-t|2%ixx`-C!29{g*=Nb6qd8GN4bnsD8+7N%ZpB-h_B^mXR@XFh3HZt zJ)12tHj+#ZTGvuDmAq522JAjN9!*qSEAgZ^ZpZuV#Pu5Qwy;H>2^$}m9ov>|Rk7)# z(xtiAzD>WBX@9NVaJWllg8J1V-c0jq?5^3M>puS(J8;HsJ!5m$VA^OyEw38zD=6Xx zHX~V%kn0$;#Ae21eTnDm7?Oy?cSvkvth>%f>%5x}A>IroVeY3d;tFr0v=*deVeDn%Zp^x7ib+^ww5fIS1^TW<#2eV7#Pv>b2+eZiZs;a|OZW7MFz{X`UG9Z$ ziY-jQpbf-60RNl*=t0^CKZ*h4dx}G_UqQ039S;It^<4NQ`|3 zC)43}*BX?ux-Oyd0(POJ$!r)~u5Eg0M7;Zmjw4;p#H3F~SZVRlfzd6#BJYR1#Xm@t Bnoj@# diff --git a/src/lindbergh/config.c b/src/lindbergh/config.c index 0e3452d..75a4fb8 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; @@ -124,6 +131,13 @@ static int detectGame(uint32_t elf_crc) if (elf_crc == 0xc4b7e89) { config.game = VIRTUA_TENNIS_3; + config.gameStatus = WORKING; + return 0; + } + + if (elf_crc == 0xffe3b0fd) + { + config.game = VIRTUA_TENNIS_3_TEST; config.gameStatus = NOT_WORKING; return 0; } @@ -198,9 +212,11 @@ char *getGameName() case SEGABOOT: return "Segaboot"; case SEGABOOT_2_4: - return "Segaboot from 2.4 Kernel"; + return "SEGABOOT 2.4"; + case SEGABOOT_2_4_SYM: + return "SEGABOOT 2.4 Symbols"; case SEGABOOT_2_6: - return "Segaboot from 2.6 Kernel"; + return "SEGABOOT 2.6"; case SEGA_RACE_TV: return "SEGA Race TV"; case THE_HOUSE_OF_THE_DEAD_4: @@ -235,6 +251,8 @@ char *getGameName() return "Virtua Fighter 5 Rev D"; case VIRTUA_TENNIS_3: return "Virtua Tennis 3"; + case VIRTUA_TENNIS_3_TEST: + return "Virtua Tennis 3 - Testmode"; default: return unknownGameTitle; } @@ -288,6 +306,18 @@ int readConfig(FILE *configFile, EmulatorConfig *config) else if (strcmp(command, "JVS_PATH") == 0) strcpy(config->jvsPath, getNextToken(NULL, " ", &saveptr)); + else if (strcmp(command, "RIDEBOARD_PATH") == 0) + strcpy(config->rideboardPath, getNextToken(NULL, " ", &saveptr)); + + else if (strcmp(command, "DRIVEBOARD_PATH") == 0) + strcpy(config->driveboardPath, getNextToken(NULL, " ", &saveptr)); + + else if (strcmp(command, "MOTIONBOARD_PATH") == 0) + strcpy(config->motionboardPath, getNextToken(NULL, " ", &saveptr)); + + else if (strcmp(command, "FREEPLAY") == 0) + config->freeplay = atoi(getNextToken(NULL, " ", &saveptr)); + else if (strcmp(command, "LINDBERGH_COLOUR") == 0) { char colour[256]; @@ -295,6 +325,19 @@ int readConfig(FILE *configFile, EmulatorConfig *config) if (strcmp(colour, "RED") == 0) config->lindberghColour = 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 printf("Error: Unknown settings command %s\n", command); } @@ -320,10 +363,11 @@ 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. Please submit this new game to the GitHub repository: https://github.com/bobbydilley/lindbergh-loader/issues/new?title=Please+add+new+game+0x%X&body=I+tried+to+launch+the+following+game:\n", config.crc32); + printf("Warning: Unsure what game with CRC 0x%X is. Please submit this new game to the GitHub repository: https://github.com/bobbydilley/lindbergh-loader/issues/new?title=Please+add+new+game+0x%X&body=I+tried+to+launch+the+following+game:\n", config.crc32, config.crc32); } configFile = fopen(CONFIG_PATH, "r"); diff --git a/src/lindbergh/config.h b/src/lindbergh/config.h index 09af474..bc21378 100644 --- a/src/lindbergh/config.h +++ b/src/lindbergh/config.h @@ -28,6 +28,7 @@ typedef enum R_TUNED, SEGABOOT, SEGABOOT_2_4, + SEGABOOT_2_4_SYM, SEGABOOT_2_6, SEGA_RACE_TV, THE_HOUSE_OF_THE_DEAD_4, @@ -45,7 +46,8 @@ typedef enum VIRTUA_FIGHTER_5_REVB, VIRTUA_FIGHTER_5_REVC, VIRTUA_FIGHTER_5_R_REVD, - VIRTUA_TENNIS_3 + VIRTUA_TENNIS_3, + VIRTUA_TENNIS_3_TEST } Game; typedef enum @@ -60,6 +62,13 @@ typedef enum NOT_WORKING } GameStatus; +typedef enum +{ + JP, + US, + EX +} GameRegion; + typedef struct { int emulateRideboard; @@ -80,6 +89,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/graphics.c b/src/lindbergh/graphics.c index 53ea574..b4e7343 100644 --- a/src/lindbergh/graphics.c +++ b/src/lindbergh/graphics.c @@ -142,102 +142,6 @@ int XStoreName(Display *display, Window w, const char *window_name) return _XStoreName(display, w, gameTitle); } -int XNextEvent(Display *display, XEvent *event_return) -{ - - int (*_XNextEvent)(Display *display, XEvent *event_return) = dlsym(RTLD_NEXT, "XNextEvent"); - int returnValue = _XNextEvent(display, event_return); - - // Return now if we're not emulating JVS - if (!getConfig()->emulateJVS) - { - return returnValue; - } - - switch (event_return->type) - { - - case KeyRelease: - case KeyPress: - { - switch (event_return->xkey.keycode) - { - case 28: - setSwitch(SYSTEM, BUTTON_TEST, event_return->type == KeyPress); - break; - case 39: - setSwitch(PLAYER_1, BUTTON_SERVICE, event_return->type == KeyPress); - break; - case 14: - incrementCoin(PLAYER_1, event_return->type == KeyPress); - break; - case 15: - incrementCoin(PLAYER_2, event_return->type == KeyPress); - break; - case 111: - setSwitch(PLAYER_1, BUTTON_UP, event_return->type == KeyPress); - break; - case 116: - setSwitch(PLAYER_1, BUTTON_DOWN, event_return->type == KeyPress); - break; - case 113: - setSwitch(PLAYER_1, BUTTON_LEFT, event_return->type == KeyPress); - break; - case 114: - setSwitch(PLAYER_1, BUTTON_RIGHT, event_return->type == KeyPress); - break; - case 10: - setSwitch(PLAYER_1, BUTTON_START, event_return->type == KeyPress); - break; - case 24: - setSwitch(PLAYER_1, BUTTON_1, event_return->type == KeyPress); - break; - case 25: - setSwitch(PLAYER_1, BUTTON_2, event_return->type == KeyPress); - break; - case 26: - setSwitch(PLAYER_1, BUTTON_3, event_return->type == KeyPress); - break; - case 27: - setSwitch(PLAYER_1, BUTTON_4, event_return->type == KeyPress); - break; - default: - break; - } - } - break; - - case MotionNotify: - { - setAnalogue(ANALOGUE_1, ((double)event_return->xmotion.x / (double)getConfig()->width) * 255); - setAnalogue(ANALOGUE_2, ((double)event_return->xmotion.y / (double)getConfig()->height) * 255); - } - break; - - case ButtonPress: - case ButtonRelease: - { - switch (event_return->xbutton.button) - { - case 1: // Trigger - setSwitch(PLAYER_1, BUTTON_1, event_return->type == ButtonPress); - break; - case 3: // Reload - setSwitch(PLAYER_1, BUTTON_2, event_return->type == ButtonPress); - break; - case 9: // Gun Button - setSwitch(PLAYER_1, BUTTON_3, event_return->type == ButtonPress); - break; - default: - break; - } - } - break; - } - - return returnValue; -} - int XSetStandardProperties(Display *display, Window window, const char *window_name, const char *icon_name, Pixmap icon_pixmap, char **argv, int argc, XSizeHints *hints) { int (*_XSetStandardProperties)(Display *display, Window window, const char *window_name, const char *icon_name, Pixmap icon_pixmap, char **argv, int argc, XSizeHints *hints) = dlsym(RTLD_NEXT, "XSetStandardProperties"); diff --git a/src/lindbergh/hook.c b/src/lindbergh/hook.c index 8b9831f..802901f 100644 --- a/src/lindbergh/hook.c +++ b/src/lindbergh/hook.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "hook.h" @@ -27,6 +28,8 @@ #include "rideboard.h" #include "securityboard.h" #include "patch.h" +#include "pcidata.h" +#include "input.h" #define HOOK_FILE_NAME "/dev/zero" @@ -37,10 +40,12 @@ #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}; +char envpath[100]; uint32_t elf_crc = 0; cpuvendor cpu_vendor = {0}; @@ -59,8 +64,6 @@ 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]; @@ -130,7 +133,6 @@ static void handleSegfault(int signal, siginfo_t *info, void *ptr) } } - void __attribute__((constructor)) hook_init() { printf("SEGA Lindbergh Loader\nRobert Dilley 2023\nNot for public consumption\n\n"); @@ -149,7 +151,7 @@ void __attribute__((constructor)) hook_init() initConfig(); - if(initPatch() != 0) + if (initPatch() != 0) exit(1); if (initEeprom() != 0) @@ -176,10 +178,13 @@ void __attribute__((constructor)) hook_init() exit(1); } + if(initInput() != 0) + exit(1); + 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")); } @@ -198,14 +203,12 @@ int open(const char *pathname, int flags) if (strcmp(pathname, "/dev/lbb") == 0) { hooks[BASEBOARD] = _open(HOOK_FILE_NAME, flags); - printf("Baseboard opened %d\n", hooks[BASEBOARD]); return hooks[BASEBOARD]; } if (strcmp(pathname, "/dev/i2c/0") == 0) { hooks[EEPROM] = _open(HOOK_FILE_NAME, flags); - printf("EEPROM opened %d\n", hooks[EEPROM]); return hooks[EEPROM]; } @@ -215,7 +218,7 @@ int open(const char *pathname, int flags) return -1; hooks[SERIAL0] = _open(HOOK_FILE_NAME, flags); - printf("SERIAL0 Opened %d\n", hooks[SERIAL0]); + printf("Warning: SERIAL0 Opened %d\n", hooks[SERIAL0]); return hooks[SERIAL0]; } @@ -225,7 +228,7 @@ int open(const char *pathname, int flags) return -1; hooks[SERIAL1] = _open(HOOK_FILE_NAME, flags); - printf("SERIAL1 opened %d\n", hooks[SERIAL1]); + printf("Warning: SERIAL1 opened %d\n", hooks[SERIAL1]); return hooks[SERIAL1]; } @@ -252,7 +255,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); } @@ -274,6 +277,26 @@ 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); + } + + 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); } @@ -313,6 +336,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"); @@ -404,6 +441,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"); @@ -565,31 +614,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; } @@ -599,7 +651,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); } /** @@ -617,6 +669,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 == VIRTUA_TENNIS_3) + { + 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/input.c b/src/lindbergh/input.c new file mode 100644 index 0000000..5268cf2 --- /dev/null +++ b/src/lindbergh/input.c @@ -0,0 +1,117 @@ +#define _GNU_SOURCE + +#include "jvs.h" + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +int initInput() +{ + return 0; +} + +int XNextEvent(Display *display, XEvent *event_return) +{ + + int (*_XNextEvent)(Display *display, XEvent *event_return) = dlsym(RTLD_NEXT, "XNextEvent"); + int returnValue = _XNextEvent(display, event_return); + + // Return now if we're not emulating JVS + if (!getConfig()->emulateJVS) + { + return returnValue; + } + + switch (event_return->type) + { + + case KeyRelease: + case KeyPress: + { + switch (event_return->xkey.keycode) + { + case 28: + setSwitch(SYSTEM, BUTTON_TEST, event_return->type == KeyPress); + break; + case 39: + setSwitch(PLAYER_1, BUTTON_SERVICE, event_return->type == KeyPress); + break; + case 14: + incrementCoin(PLAYER_1, event_return->type == KeyPress); + break; + case 15: + incrementCoin(PLAYER_2, event_return->type == KeyPress); + break; + case 111: + setSwitch(PLAYER_1, BUTTON_UP, event_return->type == KeyPress); + break; + case 116: + setSwitch(PLAYER_1, BUTTON_DOWN, event_return->type == KeyPress); + break; + case 113: + setSwitch(PLAYER_1, BUTTON_LEFT, event_return->type == KeyPress); + break; + case 114: + setSwitch(PLAYER_1, BUTTON_RIGHT, event_return->type == KeyPress); + break; + case 10: + setSwitch(PLAYER_1, BUTTON_START, event_return->type == KeyPress); + break; + case 24: + setSwitch(PLAYER_1, BUTTON_1, event_return->type == KeyPress); + break; + case 25: + setSwitch(PLAYER_1, BUTTON_2, event_return->type == KeyPress); + break; + case 26: + setSwitch(PLAYER_1, BUTTON_3, event_return->type == KeyPress); + break; + case 27: + setSwitch(PLAYER_1, BUTTON_4, event_return->type == KeyPress); + break; + default: + break; + } + } + break; + + case MotionNotify: + { + setAnalogue(ANALOGUE_1, ((double)event_return->xmotion.x / (double)getConfig()->width) * 255); + setAnalogue(ANALOGUE_2, ((double)event_return->xmotion.y / (double)getConfig()->height) * 255); + } + break; + + case ButtonPress: + case ButtonRelease: + { + switch (event_return->xbutton.button) + { + case 1: // Trigger + setSwitch(PLAYER_1, BUTTON_1, event_return->type == ButtonPress); + break; + case 3: // Reload + setSwitch(PLAYER_1, BUTTON_2, event_return->type == ButtonPress); + break; + case 9: // Gun Button + setSwitch(PLAYER_1, BUTTON_3, event_return->type == ButtonPress); + break; + default: + break; + } + } + break; + } + + return returnValue; +} diff --git a/src/lindbergh/input.h b/src/lindbergh/input.h new file mode 100644 index 0000000..ec59b90 --- /dev/null +++ b/src/lindbergh/input.h @@ -0,0 +1 @@ +int initInput(); diff --git a/src/lindbergh/patch.c b/src/lindbergh/patch.c index 633b177..2f3f6f7 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; @@ -89,6 +90,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; @@ -159,6 +230,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 AFTER_BURNER_CLIMAX_REVA: @@ -282,28 +357,31 @@ int initPatch() 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 + 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, 0x00000280); // Set ResX + // setVariable(0x082E0078, 0x000001E0); // Set ResY detourFunction(0x084e4efc, stub0); // Stub amDipswInit detourFunction(0x084e500e, stub0); // Stub amDipswGetData @@ -366,10 +444,12 @@ int initPatch() setVariable(0x08d719e0, 2); // bcLibDebugLevel setVariable(0x08d719d4, 2); // amOsinfoDebugLevel setVariable(0x08d719e4, 0x0FFFFFFF); // s_logMask - + detourFunction(0x086e2336, amDongleInit); detourFunction(0x086e0d81, amDongleIsAvailable); detourFunction(0x086e17e5, amDongleUpdate); + detourFunction(0x086e0c0d, amDipswGetData); + detourFunction(0x086e0c84, stub0); detourFunction(0x0808f9a8, _putConsole); setVariable(0x080dad63, 0x90909090); // Patch acpSystem::checkDongle @@ -377,6 +457,36 @@ int initPatch() 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 VIRTUA_TENNIS_3: + { + detourFunction(0x0831c724, amDongleInit); + detourFunction(0x0831ca37, amDongleIsAvailable); + detourFunction(0x0831c99e, amDongleUpdate); + detourFunction(0x0831c5d7, amDipswGetData); + detourFunction(0x0831c64f, stub0); + setVariable(0x0827ae1b, 0x34891beb); // Disable Fullscreen + } + case VIRTUA_TENNIS_3_TEST: + { + 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 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 945e9574ef016fd11e2d0c2c14afb754960f30c8 Mon Sep 17 00:00:00 2001 From: dkeruza Date: Tue, 12 Dec 2023 21:51:34 -0500 Subject: [PATCH 15/31] 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 16/31] 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); From cba7e535aa9cd7efaa04d279791dad242ae75968 Mon Sep 17 00:00:00 2001 From: Bobby Dilley Date: Wed, 13 Dec 2023 14:06:48 +0000 Subject: [PATCH 17/31] Merge --- src/lindbergh/hook.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/lindbergh/hook.c b/src/lindbergh/hook.c index 6572f95..de68be1 100644 --- a/src/lindbergh/hook.c +++ b/src/lindbergh/hook.c @@ -31,7 +31,7 @@ #include "pcidata.h" <<<<<<< HEAD #include "input.h" -======= + ======= >>>>>>> More-patching #define HOOK_FILE_NAME "/dev/zero" @@ -45,7 +45,7 @@ #define OSRELEASE 1 #define PCI_CARD_1F0 2 -int hooks[5] = {-1, -1, -1, -1}; + int hooks[5] = {-1, -1, -1, -1}; FILE *fileHooks[3] = {NULL, NULL, NULL}; int fileRead[3] = {0, 0, 0}; char envpath[100]; @@ -140,10 +140,10 @@ void __attribute__((constructor)) hook_init() { printf("SEGA Lindbergh Loader\nRobert Dilley 2023\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 @@ -181,7 +181,7 @@ void __attribute__((constructor)) hook_init() exit(1); } - if(initInput() != 0) + if (initInput() != 0) exit(1); securityBoardSetDipResolution(getConfig()->width, getConfig()->height); @@ -674,17 +674,13 @@ int setenv(const char *name, const char *value, int 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"); -<<<<<<< HEAD - if ((strcmp(name, "TEA_DIR") == 0) && getConfig()->game == VIRTUA_TENNIS_3) -======= - if ((strcmp(name, "TEA_DIR") == 0) && ((getConfig()->game == VT3) || (getConfig()->game == VT3_TESTMODE) || - ((getConfig()->game == RAMBO)) || (getConfig()->game == TOO_SPICY))) ->>>>>>> More-patching + if ((strcmp(name, "TEA_DIR") == 0) && ((getConfig()->game == VIRTUA_TENNIS_3) || (getConfig()->game == VIRTUA_TENNIS_3_TEST) || + ((getConfig()->game == RAMBO)) || (getConfig()->game == TOO_SPICY))) { if (getcwd(envpath, 100) == NULL) return ""; From 711e27f489276c787f8ca05c132ead97cc61b798 Mon Sep 17 00:00:00 2001 From: Bobby Dilley Date: Wed, 13 Dec 2023 14:13:52 +0000 Subject: [PATCH 18/31] complete merge --- src/lindbergh/hook.c | 3 - src/lindbergh/patch.c | 225 +++++++++++------------------------------- 2 files changed, 57 insertions(+), 171 deletions(-) diff --git a/src/lindbergh/hook.c b/src/lindbergh/hook.c index de68be1..80eb031 100644 --- a/src/lindbergh/hook.c +++ b/src/lindbergh/hook.c @@ -29,10 +29,7 @@ #include "securityboard.h" #include "patch.h" #include "pcidata.h" -<<<<<<< HEAD #include "input.h" - ======= ->>>>>>> More-patching #define HOOK_FILE_NAME "/dev/zero" diff --git a/src/lindbergh/patch.c b/src/lindbergh/patch.c index b0da6ef..25cae21 100644 --- a/src/lindbergh/patch.c +++ b/src/lindbergh/patch.c @@ -237,16 +237,9 @@ int initPatch() detourFunction(0x084d5b40, amDongleInit); detourFunction(0x084d45f9, amDongleIsAvailable); detourFunction(0x084d4fef, amDongleUpdate); -<<<<<<< HEAD - detourFunction(0x084d44fc, stub0); - detourFunction(0x084d4485, amDipswGetData); - detourFunction(0x084d9118, amLibInit); - detourFunction(0x084d438c, amDipswInit); -======= // Fixes detourFunction(0x084d44fc, stubRetZero); // Stub amDipswSetLed detourFunction(0x084d4485, amDipswGetData); ->>>>>>> More-patching } break; case AFTER_BURNER_CLIMAX_REVA: @@ -264,11 +257,7 @@ int initPatch() setVariable(0x0a0a3a74, 2); // amOsinfoDebugLevel setVariable(0x0a0a3a78, 2); // amSysDataDebugLevel setVariable(0x0a0a3a80, 2); // bcLibDebugLevel -<<<<<<< HEAD - -======= // Security ->>>>>>> More-patching detourFunction(0x081e4980, amDongleInit); detourFunction(0x081e4cce, amDongleIsAvailable); detourFunction(0x081e4bfa, amDongleUpdate); @@ -294,13 +283,6 @@ int initPatch() setVariable(0x0a0a0fb4, 2); // amOsinfoDebugLevel setVariable(0x0a0a0fb8, 2); // amSysDataDebugLevel setVariable(0x0a0a0fc0, 2); // bcLibDebugLevel -<<<<<<< HEAD - - detourFunction(0x081e3424, amDongleInit); - detourFunction(0x081e3772, amDongleIsAvailable); - detourFunction(0x081e369e, amDongleUpdate); - setVariable(0x081e7945, 0x00000001); // Test -======= // Security detourFunction(0x081e3424, amDongleInit); detourFunction(0x081e3772, amDongleIsAvailable); @@ -308,7 +290,6 @@ int initPatch() // Fixes detourFunction(0x081e335a, amDipswGetData); detourFunction(0x081e33d2, stubRetZero); // Stub amDipswSetLed ->>>>>>> More-patching } break; case OUTRUN_2_SP_SDX_REVA: @@ -326,11 +307,7 @@ int initPatch() setVariable(0x0893a4d4, 2); // amOsinfoDebugLevel setVariable(0x0893a4d8, 2); // amSysDataDebugLevel setVariable(0x0893a4e0, 2); // bcLibDebugLevel -<<<<<<< HEAD - -======= // Security ->>>>>>> More-patching detourFunction(0x08190e80, amDongleInit); detourFunction(0x08191201, amDongleIsAvailable); detourFunction(0x08191125, amDongleUpdate); @@ -357,19 +334,7 @@ int initPatch() setVariable(0x0a737f1c, 2); // amSysDataDebugLevel setVariable(0x0a737f20, 2); // bcLibDebugLevel setVariable(0x0a737f24, 0x0FFFFFFF); // s_logMask -<<<<<<< HEAD - detourFunction(0x08320178, amDongleInit); - detourFunction(0x08320459, amDongleIsAvailable); - detourFunction(0x083203c0, amDongleUpdate); - - if (config->amdFix) - { - setVariable(0x0837d6aa, cpu_vendor.ebx); - setVariable(0x0837d6ba, cpu_vendor.edx); - setVariable(0x0837d6c5, cpu_vendor.ecx); - } -======= // Security detourFunction(0x08320178, amDongleInit); detourFunction(0x08320459, amDongleIsAvailable); @@ -378,25 +343,30 @@ int initPatch() 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); ->>>>>>> More-patching + if (config->amdFix) + { + 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 + // Security detourFunction(0x0831ad04, amDongleInit); detourFunction(0x0831b017, amDongleIsAvailable); detourFunction(0x0831af7e, amDongleUpdate); - //// Fixes + // 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); + // CPU patch to support AMD processors + if (config->amdFix) + { + setVariable(0x0837963a, cpu_vendor.ebx); + setVariable(0x0837964a, cpu_vendor.edx); + setVariable(0x08379655, cpu_vendor.ecx); + } } break; case THE_HOUSE_OF_THE_DEAD_4_TEST: @@ -404,8 +374,10 @@ int initPatch() detourFunction(0x080677a0, amDongleInit); detourFunction(0x08067a81, amDongleIsAvailable); detourFunction(0x080679e8, amDongleUpdate); -<<<<<<< HEAD - + // Fixes + detourFunction(0x08067653, amDipswGetData); + detourFunction(0x080676cb, stubRetZero); // Stub amDipswSetLed + // CPU patch to support AMD processors if (config->amdFix) { setVariable(0x0807217a, cpu_vendor.ebx); @@ -414,18 +386,7 @@ int initPatch() } } break; - case VIRTUA_FIGHTER_5_REVC: -======= - // 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_SP: + case THE_HOUSE_OF_THE_DEAD_4_SPECIAL: { detourFunction(0x08363438, amDongleInit); detourFunction(0x0836374b, amDongleIsAvailable); @@ -434,12 +395,15 @@ int initPatch() 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); + if (config->amdFix) + { + setVariable(0x083cef0a, cpu_vendor.ebx); + setVariable(0x083cef1a, cpu_vendor.edx); + setVariable(0x083cef25, cpu_vendor.ecx); + } } break; - case THE_HOUSE_OF_THE_DEAD_SP_TEST: + case THE_HOUSE_OF_THE_DEAD_4_SPECIAL_TEST: { detourFunction(0x0806e914, amDongleInit); detourFunction(0x0806ec27, amDongleIsAvailable); @@ -448,9 +412,12 @@ int initPatch() 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); + if (config->amdFix) + { + setVariable(0x0807a3ba, cpu_vendor.ebx); + setVariable(0x0807a3ca, cpu_vendor.edx); + setVariable(0x0807a3d5, cpu_vendor.ecx); + } } break; case THE_HOUSE_OF_THE_DEAD_EX: @@ -462,9 +429,12 @@ int initPatch() 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); + if (config->amdFix) + { + setVariable(0x0849E2AD, cpu_vendor.ebx); + setVariable(0x0849E2B7, cpu_vendor.edx); + setVariable(0x0849E2C1, cpu_vendor.ecx); + } } break; case THE_HOUSE_OF_THE_DEAD_EX_TEST: @@ -476,26 +446,20 @@ int initPatch() 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); + if (config->amdFix) + { + setVariable(0x080847BD, cpu_vendor.ebx); + setVariable(0x080847C7, cpu_vendor.edx); + setVariable(0x080847D1, cpu_vendor.ecx); + } } break; - case VF5_REVC: ->>>>>>> More-patching + case VIRTUA_FIGHTER_5_REVC: { // Security detourFunction(0x085c6010, amDongleInit); detourFunction(0x085c63cc, amDongleIsAvailable); detourFunction(0x085c62f0, amDongleUpdate); -<<<<<<< HEAD - 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 @@ -505,7 +469,6 @@ int initPatch() detourFunction(0x0840ab90, stubRetZero); // Stub returns 0 setVariable(0x080e17af, 0x000000b8); // Patch IDK what setVariable(0x080e17b3, 0x01e88300); // Patch IDK what ->>>>>>> More-patching } break; @@ -525,33 +488,6 @@ int initPatch() setVariable(0x08c08634, 2); // amOsinfoDebugLevel setVariable(0x08c08644, 0x0FFFFFFF); // s_logMask detourFunction(0x08074a8c, _putConsole); // Debug Messages -<<<<<<< HEAD - - 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, 0x00000280); // Set ResX - // setVariable(0x082E0078, 0x000001E0); // Set ResY - - detourFunction(0x084e4efc, stub0); // Stub amDipswInit - detourFunction(0x084e500e, stub0); // Stub amDipswGetData - detourFunction(0x084e5086, stub0); // Stub amDipswSetLed - detourFunction(0x084e4f98, stub0); // Stub amDipswExit - - setVariable(0x0840d858, 0x1c899090); // No more Full Screen from the Game - - if (config->amdFix) - { - setVariable(0x083ef701, 0x00036ee9); // AMDFIX - setVariable(0x084032e0, 0x8b90c933); // fix shader compilation with AMD GPUs - setVariable(0x08523950, 0x000000c3); // Remove ADXM_SetupFramework (Not necessary) - } -======= // Security detourFunction(0x084e50d8, amDongleInit); detourFunction(0x084e5459, amDongleIsAvailable); @@ -571,7 +507,6 @@ int initPatch() // setVariable(0x083ef701, 0x00036ee9); // AMDFIX // setVariable(0x084032e0, 0x8b90c933); // fix shader compilation with AMD GPUs // setVariable(0x08523950, 0x000000c3); // Remove ADXM_SetupFramework (Not necessary) ->>>>>>> More-patching } break; @@ -595,12 +530,6 @@ int initPatch() detourFunction(0x08510320, amDongleInit); detourFunction(0x085106dc, amDongleIsAvailable); detourFunction(0x08510600, amDongleUpdate); -<<<<<<< HEAD - detourFunction(0x08075012, _putConsole); - // setVariable(0x08303C4B, 0x00000780); // Set ResX - // setVariable(0x08303C58, 0x00000438); // Set ResY -======= ->>>>>>> More-patching setVariable(0x080dad63, 0x90909090); // Patch acpSystem::checkDongle setVariable(0x080dad67, 0xE8C3C990); // Patch acpSystem::checkDongle setVariable(0x0807e609, 0xc2839090); // Patch initializeArcadeBackup @@ -631,22 +560,6 @@ int initPatch() setVariable(0x08d719e0, 2); // bcLibDebugLevel setVariable(0x08d719d4, 2); // amOsinfoDebugLevel setVariable(0x08d719e4, 0x0FFFFFFF); // s_logMask -<<<<<<< HEAD - - 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; -======= // detourFunction(0x0808f9a8, _putConsole); // Crashes the game sometimes. // Security detourFunction(0x086e2336, amDongleInit); @@ -680,17 +593,16 @@ int initPatch() setVariable(0x08248a2a, 0x00000438); // Set ResY */ - // Hooked in graphics.c - //setVariable(0x085599f2, 0x0001d2e9); // Force not supported resolutions - //setVariable(0x085599f6, 0x01bb0000); // Force not supported resolutions + // 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: + case INITIALD_4_REVE: { // Debug // detourFunction(0x08090478, _putConsole); // Crashes the game sometimes. @@ -714,40 +626,15 @@ int initPatch() // setVariable(0x085700d3, 0x8990c031); // Fix something with the Shaders?? } break; ->>>>>>> More-patching case SEGABOOT_2_4_SYM: { detourFunction(0x0805e8b0, amDongleInit); detourFunction(0x0805ebc3, amDongleIsAvailable); detourFunction(0x0805eb2a, amDongleUpdate); -<<<<<<< HEAD - // detourFunction(0x08062cf8, amLibInit); - // detourFunction(0x0805c200, amDipswInit); detourFunction(0x0805c30b, amDipswGetData); } break; case VIRTUA_TENNIS_3: - { - detourFunction(0x0831c724, amDongleInit); - detourFunction(0x0831ca37, amDongleIsAvailable); - detourFunction(0x0831c99e, amDongleUpdate); - detourFunction(0x0831c5d7, amDipswGetData); - detourFunction(0x0831c64f, stub0); - setVariable(0x0827ae1b, 0x34891beb); // Disable Fullscreen - } - case VIRTUA_TENNIS_3_TEST: - { - detourFunction(0x0815f610, amDongleInit); - detourFunction(0x0815f923, amDongleIsAvailable); - detourFunction(0x0815f88a, amDongleUpdate); - detourFunction(0x0815d06b, amDipswGetData); - detourFunction(0x0815d0e3, stub0); - // setVariable(0x0827ae1b, 0x34891beb); //Disable Fullscreen -======= - detourFunction(0x0805c30b, amDipswGetData); - } - break; - case VT3: { // Security detourFunction(0x0831c724, amDongleInit); @@ -759,7 +646,7 @@ int initPatch() setVariable(0x0827ae1b, 0x34891beb); // Disable Fullscreen set from the game } break; - case VT3_TESTMODE: + case VIRTUA_TENNIS_3_TEST: { // Security detourFunction(0x0815f610, amDongleInit); @@ -787,14 +674,16 @@ int initPatch() detourFunction(0x0831cf02, amDongleInit); detourFunction(0x0831b94d, amDongleIsAvailable); detourFunction(0x0831c3b1, amDongleUpdate); - // Fixes + // 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); ->>>>>>> More-patching + if (config->amdFix) + { + setVariable(0x08399ADA, cpu_vendor.ebx); + setVariable(0x08399AEA, cpu_vendor.edx); + setVariable(0x08399AF5, cpu_vendor.ecx); + } } break; default: From 38f81fb887c3a3abcb9afe57ffe88851cdcb8673 Mon Sep 17 00:00:00 2001 From: dkeruza Date: Mon, 18 Dec 2023 00:32:09 -0500 Subject: [PATCH 19/31] Syntax error and fix for some games that do not support Freeplay. --- src/libkswapapi/libkswapapi.o | Bin 0 -> 2264 bytes src/lindbergh/config.c | 4 +-- src/lindbergh/eeprom.c | 52 +++++++++++++++++++++----------- src/lindbergh/eeprom_settings.c | 13 ++++++++ src/lindbergh/eeprom_settings.h | 1 + src/lindbergh/hook.c | 2 +- src/lindbergh/jvs.c | 6 +--- src/lindbergh/patch.c | 7 +++-- 8 files changed, 58 insertions(+), 27 deletions(-) create mode 100644 src/libkswapapi/libkswapapi.o diff --git a/src/libkswapapi/libkswapapi.o b/src/libkswapapi/libkswapapi.o new file mode 100644 index 0000000000000000000000000000000000000000..0ae0ad7d2db3dbc8d94864cb6594f895ed703966 GIT binary patch literal 2264 zcma)7TWB0r7(O$z8)J5Jueq3N#?mH{X2;DY*4PWpgAwsnx z62a#C!8#ZgxpJx7k%X9p9EQ&Vq5*%^R1Xb5zC)WFq z#E$ftv8)-Jj+?QCQ^{emyn4z-nz3jb$4rW^V@UD*yQHM zV|S)D4}Z0_@x^3vA~v!0<>tn8Dj7?6SrZji9d7fxolOUu<_~=Q`<2#v8;Mu6yLB@U zi@K-#KM`ZY!$-|79Qx6{C&pfE7&?je2!Rl^QM;*{sQEG*wGT|vE}RzH#Y(L$8VX&4 zgRLi%WXlI@Dqq!ys>7+=t^&yr z_wUi8d-R$;dabDSEj)h%_IoH0(V$m|-heLem|IHA$8(BHR%XvT+BV+W%DSFi%-G)I zT7KDb)`dNmnjRWV+0&z=&y392GlN5^5u0V%YrRUyQ&(Y@E1_$6jA|mT)+fvUIR#x0R&XO;9u7weft$I#o+1IoAHLF-E6y1_{zFgK_v=>Uw3W{b+ zg|#AX`oHN1MAiqQ`JLo@JpjfN%D3cuwu3p-YEn7>a&CYmHScYZIjsX=(mUuo<5&+* zA?vaJAux0JETmK!c2-sIFf5G!uQ)jah^ycxAlBo#6{&isV30D4f~XHksl2Eh<_GU_ z0|yv@jrZWMlW{EZELhcsD6W9VDEOp&dFV=}>wB}$jo6MN#jsv%c5NABdc$D-0$CY7|#UaSdVcZ z`l#yt0i*h+GMq8wk9-73YVhAr>5L(L3TEGxdmjYeLy>y7?_gk#iaQP=I9n?28^i?r zvLB8**w`2RE${RtSPN!x3H5FQ`R!sp>oJeAno)>i97>XcPwF20tp(${QQ#L91XOYV E0N$$l%>V!Z literal 0 HcmV?d00001 diff --git a/src/lindbergh/config.c b/src/lindbergh/config.c index 14a161b..3dba27d 100644 --- a/src/lindbergh/config.c +++ b/src/lindbergh/config.c @@ -430,8 +430,8 @@ int initConfig() config.width = 1024; config.height = 768; config.crc32 = elf_crc; - config.region = US; - config.freeplay = 1; + config.region = -1; + config.freeplay = -1; if (detectGame(config.crc32) != 0) { printf("Warning: Unsure what game with CRC 0x%X is. Please submit this new game to the GitHub repository: https://github.com/bobbydilley/lindbergh-loader/issues/new?title=Please+add+new+game+0x%X&body=I+tried+to+launch+the+following+game:\n", config.crc32, config.crc32); diff --git a/src/lindbergh/eeprom.c b/src/lindbergh/eeprom.c index 072632c..9b6f45a 100644 --- a/src/lindbergh/eeprom.c +++ b/src/lindbergh/eeprom.c @@ -6,7 +6,7 @@ #include "eeprom_settings.h" #include "config.h" -#define I2C_SMBUS_BLOCK_MAX 32 +#define I2C_SMBUS_BLOCK_MAX 32 #define I2C_GET_FUNCTIONS 0x705 #define I2C_SMBUS_TRANSFER 0x720 #define I2C_SET_SLAVE_MODE 0x703 @@ -15,17 +15,19 @@ #define I2C_SEEK 2 #define I2C_WRITE 3 -union i2c_smbus_data { - uint8_t byte; - uint16_t word; - uint8_t block[I2C_SMBUS_BLOCK_MAX + 2]; +union i2c_smbus_data +{ + uint8_t byte; + uint16_t word; + uint8_t block[I2C_SMBUS_BLOCK_MAX + 2]; }; -struct i2c_smbus_ioctl_data { - uint8_t read_write; - uint8_t command; - uint32_t size; - union i2c_smbus_data *data; +struct i2c_smbus_ioctl_data +{ + uint8_t read_write; + uint8_t command; + uint32_t size; + union i2c_smbus_data *data; }; FILE *eeprom = NULL; @@ -47,18 +49,34 @@ int initEeprom() eeprom = fopen(eepromPath, "rb+"); - if(eepromSettingsInit(eeprom) !=0) + 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); + + if (getConfig()->region != -1) + { + if (getRegion() != getConfig()->region) + setRegion(eeprom, getConfig()->region); + } + + if (getConfig()->freeplay != -1) + { + if (getFreeplay() != getConfig()->freeplay) + setFreeplay(eeprom, getConfig()->freeplay); + } + + if ((getConfig()->game == LETS_GO_JUNGLE_SPECIAL) || (getConfig()->game == THE_HOUSE_OF_THE_DEAD_EX) || (getConfig()->game == THE_HOUSE_OF_THE_DEAD_4_SPECIAL)) + { + if (fixCreditSection(eeprom) != 0) + { + printf("Error initializing eeprom settings."); + fclose(eeprom); + return 1; + } + } fseek(eeprom, 0, SEEK_SET); diff --git a/src/lindbergh/eeprom_settings.c b/src/lindbergh/eeprom_settings.c index faf6001..07aba1d 100644 --- a/src/lindbergh/eeprom_settings.c +++ b/src/lindbergh/eeprom_settings.c @@ -199,6 +199,19 @@ int setFreeplay(FILE *eeprom, int freeplay) return 0; } +int fixCreditSection(FILE *eeprom) +{ + eepromBuffer[eepromOffsetTable[CREDIT].offset + 36] = 0; + eepromBuffer[eepromOffsetTable[CREDIT].offset + 39] = 0; + addCRCtoBuffer(CREDIT); + if (writeSectiontoFile(eeprom, CREDIT) != 0) + { + printf("Error setting Free Play."); + return 1; + } + return 0; +} + int eepromSettingsInit( FILE *eeprom) { build_crc32_table(); diff --git a/src/lindbergh/eeprom_settings.h b/src/lindbergh/eeprom_settings.h index 39f7173..fde2f48 100644 --- a/src/lindbergh/eeprom_settings.h +++ b/src/lindbergh/eeprom_settings.h @@ -3,3 +3,4 @@ int getRegion(); int getFreeplay(); int setRegion(FILE *eeprom, int region); int setFreeplay(FILE *eeprom, int freeplay); +int fixCreditSection(FILE *eeprom); diff --git a/src/lindbergh/hook.c b/src/lindbergh/hook.c index 80eb031..fbe1ef0 100644 --- a/src/lindbergh/hook.c +++ b/src/lindbergh/hook.c @@ -42,7 +42,7 @@ #define OSRELEASE 1 #define PCI_CARD_1F0 2 - int hooks[5] = {-1, -1, -1, -1}; +int hooks[5] = {-1, -1, -1, -1}; FILE *fileHooks[3] = {NULL, NULL, NULL}; int fileRead[3] = {0, 0, 0}; char envpath[100]; diff --git a/src/lindbergh/jvs.c b/src/lindbergh/jvs.c index 655efde..8534b54 100644 --- a/src/lindbergh/jvs.c +++ b/src/lindbergh/jvs.c @@ -35,7 +35,7 @@ int initJVS() io.capabilities.players = 2; io.capabilities.analogueInBits = 8; io.capabilities.rightAlignBits = 0; - io.capabilities.analogueInChannels = 20; + io.capabilities.analogueInChannels = 8; io.capabilities.generalPurposeOutputs = 20; io.capabilities.commandVersion = 19; io.capabilities.jvsVersion = 48; @@ -265,8 +265,6 @@ 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++) { @@ -569,8 +567,6 @@ JVSStatus readPacket(JVSPacket *packet) */ JVSStatus writePacket(JVSPacket *packet) { - - /* Get pointer to raw data in packet */ unsigned char *packetPointer = (unsigned char *)packet; diff --git a/src/lindbergh/patch.c b/src/lindbergh/patch.c index 25cae21..870b867 100644 --- a/src/lindbergh/patch.c +++ b/src/lindbergh/patch.c @@ -494,7 +494,7 @@ int initPatch() detourFunction(0x084e537d, amDongleUpdate); setVariable(0x080d1f02, 0x90909090); // Patch acpSystem::checkDongle setVariable(0x080d1f06, 0xE8C3C990); // Patch acpSystem::checkDongle - setVariable(0x0807b76a, 0xc2839090); // Patch initializeArcadeBackup + setVariable(0x0807b76d, 0xc2839090); // Patch initializeArcadeBackup // Fixes detourFunction(0x084e500e, amDipswGetData); detourFunction(0x084e5086, stubRetZero); // Stub amDipswSetLed @@ -532,7 +532,8 @@ int initPatch() detourFunction(0x08510600, amDongleUpdate); setVariable(0x080dad63, 0x90909090); // Patch acpSystem::checkDongle setVariable(0x080dad67, 0xE8C3C990); // Patch acpSystem::checkDongle - setVariable(0x0807e609, 0xc2839090); // Patch initializeArcadeBackup + setVariable(0x0807e609, 0x90909090); // Patch initializeArcadeBackup + setVariable(0x0807e60d, 0xc2839090); // Patch initializeArcadeBackup // Fixes detourFunction(0x08510256, amDipswGetData); detourFunction(0x085102ce, stubRetZero); // Stub amDipswSetLed @@ -648,6 +649,8 @@ int initPatch() break; case VIRTUA_TENNIS_3_TEST: { + // Debug + detourFunction(0x08054d14, _putConsole); // Crashes the game sometimes. // Security detourFunction(0x0815f610, amDongleInit); detourFunction(0x0815f923, amDongleIsAvailable); From 02a965c98259eeff6b8b1002c2b622b8bf8ae2e1 Mon Sep 17 00:00:00 2001 From: dkeruza Date: Tue, 19 Dec 2023 21:36:53 -0500 Subject: [PATCH 20/31] HOD4 SP --- src/lindbergh/hook.c | 0 src/lindbergh/patch.c | 3 +++ 2 files changed, 3 insertions(+) mode change 100644 => 100755 src/lindbergh/hook.c diff --git a/src/lindbergh/hook.c b/src/lindbergh/hook.c old mode 100644 new mode 100755 diff --git a/src/lindbergh/patch.c b/src/lindbergh/patch.c index 870b867..b5cc905 100644 --- a/src/lindbergh/patch.c +++ b/src/lindbergh/patch.c @@ -401,6 +401,9 @@ int initPatch() setVariable(0x083cef1a, cpu_vendor.edx); setVariable(0x083cef25, cpu_vendor.ecx); } + // Workaround + if (remove("/var/tmp/atr_init") == 1) + printf("atr_init deleted.\n"); } break; case THE_HOUSE_OF_THE_DEAD_4_SPECIAL_TEST: From b41d6c38206f50dc1c3858b9a17c99c8cfd8a3b6 Mon Sep 17 00:00:00 2001 From: dkeruza Date: Tue, 19 Dec 2023 23:08:44 -0500 Subject: [PATCH 21/31] Fixed patch removal by mistake --- src/lindbergh/eeprom_settings.c | 6 +++--- src/lindbergh/patch.c | 9 ++++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/lindbergh/eeprom_settings.c b/src/lindbergh/eeprom_settings.c index 07aba1d..1c9bae6 100644 --- a/src/lindbergh/eeprom_settings.c +++ b/src/lindbergh/eeprom_settings.c @@ -171,7 +171,7 @@ int setRegion(FILE *eeprom, int region) addCRCtoBuffer(STATIC); if (writeSectiontoFile(eeprom, STATIC) != 0) { - printf("Error setting the ."); + printf("Error writing to eeprom."); return 1; } return 0; @@ -193,7 +193,7 @@ int setFreeplay(FILE *eeprom, int freeplay) addCRCtoBuffer(CREDIT); if (writeSectiontoFile(eeprom, CREDIT) != 0) { - printf("Error setting Free Play."); + printf("Error writing to eeprom."); return 1; } return 0; @@ -206,7 +206,7 @@ int fixCreditSection(FILE *eeprom) addCRCtoBuffer(CREDIT); if (writeSectiontoFile(eeprom, CREDIT) != 0) { - printf("Error setting Free Play."); + printf("Error writing to eeprom."); return 1; } return 0; diff --git a/src/lindbergh/patch.c b/src/lindbergh/patch.c index b5cc905..e29625f 100644 --- a/src/lindbergh/patch.c +++ b/src/lindbergh/patch.c @@ -391,6 +391,8 @@ int initPatch() detourFunction(0x08363438, amDongleInit); detourFunction(0x0836374b, amDongleIsAvailable); detourFunction(0x083636b2, amDongleUpdate); + setVariable(0x081f9491, 0x148b9090); + setVariable(0x081f9499, 0x01000000); // Fixes detourFunction(0x08360e93, amDipswGetData); detourFunction(0x08360f0b, stubRetZero); // Stub amDipswSetLed @@ -401,9 +403,10 @@ int initPatch() setVariable(0x083cef1a, cpu_vendor.edx); setVariable(0x083cef25, cpu_vendor.ecx); } - // Workaround - if (remove("/var/tmp/atr_init") == 1) + // Workaroud + if(remove("/var/tmp/atr_init") == 1) printf("atr_init deleted.\n"); + } break; case THE_HOUSE_OF_THE_DEAD_4_SPECIAL_TEST: @@ -497,7 +500,7 @@ int initPatch() detourFunction(0x084e537d, amDongleUpdate); setVariable(0x080d1f02, 0x90909090); // Patch acpSystem::checkDongle setVariable(0x080d1f06, 0xE8C3C990); // Patch acpSystem::checkDongle - setVariable(0x0807b76d, 0xc2839090); // Patch initializeArcadeBackup + setVariable(0x0807b76a, 0xc2839090); // Patch initializeArcadeBackup // Fixes detourFunction(0x084e500e, amDipswGetData); detourFunction(0x084e5086, stubRetZero); // Stub amDipswSetLed From 8e4f424c858ab9b1050343f6f924cd61275b70d5 Mon Sep 17 00:00:00 2001 From: dkeruza Date: Wed, 20 Dec 2023 12:30:33 -0500 Subject: [PATCH 22/31] A few changes --- docs/lindbergh.conf | 6 +- src/lindbergh/config.c | 8 +- src/lindbergh/config.h | 2 +- src/lindbergh/hook.c | 3 +- src/lindbergh/hook.h | 1 + src/lindbergh/patch.c | 320 ++++++++++++++++++++++------------------- 6 files changed, 186 insertions(+), 154 deletions(-) diff --git a/docs/lindbergh.conf b/docs/lindbergh.conf index 03cd9f8..287eb17 100644 --- a/docs/lindbergh.conf +++ b/docs/lindbergh.conf @@ -62,11 +62,11 @@ EEPROM_PATH eeprom.bin # Set if the emulator should go full screen FULLSCREEN 0 -# Set if you would like to apply AMD CPU / GPU Fixes -AMD_FIX 0 - # Set the Region ( JP/US/EX ) REGION EX # Set if you want the game to be Free Play FREEPLAY 1 + +# Set if you want to see degug messages in the console +DEBUG_MSGS 0 \ No newline at end of file diff --git a/src/lindbergh/config.c b/src/lindbergh/config.c index 3dba27d..ace2783 100644 --- a/src/lindbergh/config.c +++ b/src/lindbergh/config.c @@ -367,9 +367,6 @@ int readConfig(FILE *configFile, EmulatorConfig *config) else if (strcmp(command, "EMULATE_JVS") == 0) config->emulateJVS = atoi(getNextToken(NULL, " ", &saveptr)); - else if (strcmp(command, "AMD_FIX") == 0) - config->amdFix = atoi(getNextToken(NULL, " ", &saveptr)); - else if (strcmp(command, "JVS_PATH") == 0) strcpy(config->jvsPath, getNextToken(NULL, " ", &saveptr)); @@ -405,6 +402,9 @@ int readConfig(FILE *configFile, EmulatorConfig *config) config->region = EX; } + else if (strcmp(command, "DEBUG_MSGS") == 0) + config->debug_msgs = atoi(getNextToken(NULL, " ", &saveptr)); + else printf("Error: Unknown settings command %s\n", command); } @@ -418,7 +418,6 @@ int initConfig() config.emulateDriveboard = 0; config.emulateMotionboard = 0; config.emulateJVS = 1; - config.amdFix = 0; config.fullscreen = 0; config.lindberghColour = YELLOW; strcpy(config.eepromPath, "eeprom.bin"); @@ -432,6 +431,7 @@ int initConfig() config.crc32 = elf_crc; config.region = -1; config.freeplay = -1; + config.debug_msgs = 1; if (detectGame(config.crc32) != 0) { printf("Warning: Unsure what game with CRC 0x%X is. Please submit this new game to the GitHub repository: https://github.com/bobbydilley/lindbergh-loader/issues/new?title=Please+add+new+game+0x%X&body=I+tried+to+launch+the+following+game:\n", config.crc32, config.crc32); diff --git a/src/lindbergh/config.h b/src/lindbergh/config.h index 6468272..d5e20b3 100644 --- a/src/lindbergh/config.h +++ b/src/lindbergh/config.h @@ -87,13 +87,13 @@ typedef struct char driveboardPath[MAX_PATH_LENGTH]; int width; int height; - int amdFix; Game game; Colour lindberghColour; GameStatus gameStatus; uint32_t crc32; GameRegion region; int freeplay; + int debug_msgs; } EmulatorConfig; int initConfig(); diff --git a/src/lindbergh/hook.c b/src/lindbergh/hook.c index fbe1ef0..dedc090 100755 --- a/src/lindbergh/hook.c +++ b/src/lindbergh/hook.c @@ -651,7 +651,8 @@ 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); + sprintf(cpu_vendor.cpuid, "%.4s%.4s%.4s", (const char *)&cpu_vendor.ebx, (const char *)&cpu_vendor.edx, (const char *)&cpu_vendor.ecx); + printf("CPU Vendor: %s\n", cpu_vendor.cpuid); } /** diff --git a/src/lindbergh/hook.h b/src/lindbergh/hook.h index 2b215b2..2c17972 100644 --- a/src/lindbergh/hook.h +++ b/src/lindbergh/hook.h @@ -6,4 +6,5 @@ typedef struct unsigned ebx; unsigned edx; unsigned ecx; + char cpuid[20]; }cpuvendor; diff --git a/src/lindbergh/patch.c b/src/lindbergh/patch.c index e29625f..be6d1ca 100644 --- a/src/lindbergh/patch.c +++ b/src/lindbergh/patch.c @@ -28,11 +28,29 @@ static void setVariable(uint32_t address, uint32_t value) *variable = value; } -static void setMem(uint32_t address, uint32_t value, int size) +static void patchMemory(uint32_t address, char *value) { - int pagesize = sysconf(_SC_PAGE_SIZE); + + size_t size = strlen((void*)value); + printf("Size=%d\n", size); + if(size % 2 != 0) + { + printf("Patch value should be even.\n"); + exit(1); + } - uint32_t *variable = (uint32_t *)address; + char buf[size/2]; + char tmpchr[3]; + char *p = value; + for(int i=0; i < size; i++) + { + memcpy(tmpchr, p, 2); + tmpchr[2] = '\0'; + buf[i] = (int)strtol(tmpchr, NULL, 16); + p += 2; + } + + int pagesize = sysconf(_SC_PAGE_SIZE); void *toModify = (void *)(address - (address % pagesize)); @@ -42,7 +60,8 @@ static void setMem(uint32_t address, uint32_t value, int size) printf("Error: Cannot unprotect memory region to change variable (%d)\n", prot); return; } - memccpy((void *)variable, (void *)value, 1, size); + + memcpy((uint32_t *)address, buf, size/2); } static void detourFunction(uint32_t address, void *function) @@ -244,19 +263,22 @@ int initPatch() break; case AFTER_BURNER_CLIMAX_REVA: { - // Debug Messages - setVariable(0x0a0a37e4, 2); // amBackupDebugLevel - setVariable(0x0a0a3800, 2); // amCreditDebugLevel - setVariable(0x0a0a3a58, 2); // amDipswDebugLevel - setVariable(0x0a0a3a5c, 2); // amDongleDebugLevel - setVariable(0x0a0a3a60, 2); // amEepromDebugLevel - setVariable(0x0a0a3a64, 2); // amHwmonitorDebugLevel - setVariable(0x0a0a3a68, 2); // amJvsDebugLevel - setVariable(0x0a0a3a6c, 2); // amLibDebugLevel - setVariable(0x0a0a3a70, 2); // amMiscDebugLevel - setVariable(0x0a0a3a74, 2); // amOsinfoDebugLevel - setVariable(0x0a0a3a78, 2); // amSysDataDebugLevel - setVariable(0x0a0a3a80, 2); // bcLibDebugLevel + if (config->debug_msgs == 1) + { + // Debug Messages + setVariable(0x0a0a37e4, 2); // amBackupDebugLevel + setVariable(0x0a0a3800, 2); // amCreditDebugLevel + setVariable(0x0a0a3a58, 2); // amDipswDebugLevel + setVariable(0x0a0a3a5c, 2); // amDongleDebugLevel + setVariable(0x0a0a3a60, 2); // amEepromDebugLevel + setVariable(0x0a0a3a64, 2); // amHwmonitorDebugLevel + setVariable(0x0a0a3a68, 2); // amJvsDebugLevel + setVariable(0x0a0a3a6c, 2); // amLibDebugLevel + setVariable(0x0a0a3a70, 2); // amMiscDebugLevel + setVariable(0x0a0a3a74, 2); // amOsinfoDebugLevel + setVariable(0x0a0a3a78, 2); // amSysDataDebugLevel + setVariable(0x0a0a3a80, 2); // bcLibDebugLevel + } // Security detourFunction(0x081e4980, amDongleInit); detourFunction(0x081e4cce, amDongleIsAvailable); @@ -265,24 +287,27 @@ int initPatch() detourFunction(0x081e48b6, amDipswGetData); detourFunction(0x081e492e, stubRetZero); // Stub amDipswSetLed // Does not work - setVariable(0x08061c31, 0x0000000c); // Force HD resolution + //setVariable(0x08061c31, 0x0000000c); // Force HD resolution } break; case AFTER_BURNER_CLIMAX_REVB: { - // Debug Messages - setVariable(0x0a0a0d24, 2); // amBackupDebugLevel - setVariable(0x0a0a0d40, 2); // amCreditDebugLevel - setVariable(0x0a0a0f98, 2); // amDipswDebugLevel - setVariable(0x0a0a0f9c, 2); // amDongleDebugLevel - setVariable(0x0a0a0fa0, 2); // amEepromDebugLevel - setVariable(0x0a0a0fa4, 2); // amHwmonitorDebugLevel - setVariable(0x0a0a0fa8, 2); // amJvsDebugLevel - setVariable(0x0a0a0fac, 2); // amLibDebugLevel - setVariable(0x0a0a0fb0, 2); // amMiscDebugLevel - setVariable(0x0a0a0fb4, 2); // amOsinfoDebugLevel - setVariable(0x0a0a0fb8, 2); // amSysDataDebugLevel - setVariable(0x0a0a0fc0, 2); // bcLibDebugLevel + if (config->debug_msgs == 1) + { + // Debug Messages + setVariable(0x0a0a0d24, 2); // amBackupDebugLevel + setVariable(0x0a0a0d40, 2); // amCreditDebugLevel + setVariable(0x0a0a0f98, 2); // amDipswDebugLevel + setVariable(0x0a0a0f9c, 2); // amDongleDebugLevel + setVariable(0x0a0a0fa0, 2); // amEepromDebugLevel + setVariable(0x0a0a0fa4, 2); // amHwmonitorDebugLevel + setVariable(0x0a0a0fa8, 2); // amJvsDebugLevel + setVariable(0x0a0a0fac, 2); // amLibDebugLevel + setVariable(0x0a0a0fb0, 2); // amMiscDebugLevel + setVariable(0x0a0a0fb4, 2); // amOsinfoDebugLevel + setVariable(0x0a0a0fb8, 2); // amSysDataDebugLevel + setVariable(0x0a0a0fc0, 2); // bcLibDebugLevel + } // Security detourFunction(0x081e3424, amDongleInit); detourFunction(0x081e3772, amDongleIsAvailable); @@ -294,19 +319,22 @@ int initPatch() break; case OUTRUN_2_SP_SDX_REVA: { - // Debug Messages - setVariable(0x0893a24c, 2); // amBackupDebugLevel - setVariable(0x0893a260, 2); // amCreditDebugLevel - setVariable(0x0893a4b8, 2); // amDipswDebugLevel - setVariable(0x0893a4bc, 2); // amDongleDebugLevel - setVariable(0x0893a4c0, 2); // amEepromDebugLevel - setVariable(0x0893a4c4, 2); // amHwmonitorDebugLevel - setVariable(0x0893a4c8, 2); // amJvsDebugLevel - setVariable(0x0893a4cc, 2); // amLibDebugLevel - setVariable(0x0893a4d0, 2); // amMiscDebugLevel - setVariable(0x0893a4d4, 2); // amOsinfoDebugLevel - setVariable(0x0893a4d8, 2); // amSysDataDebugLevel - setVariable(0x0893a4e0, 2); // bcLibDebugLevel + if (config->debug_msgs == 1) + { + // Debug Messages + setVariable(0x0893a24c, 2); // amBackupDebugLevel + setVariable(0x0893a260, 2); // amCreditDebugLevel + setVariable(0x0893a4b8, 2); // amDipswDebugLevel + setVariable(0x0893a4bc, 2); // amDongleDebugLevel + setVariable(0x0893a4c0, 2); // amEepromDebugLevel + setVariable(0x0893a4c4, 2); // amHwmonitorDebugLevel + setVariable(0x0893a4c8, 2); // amJvsDebugLevel + setVariable(0x0893a4cc, 2); // amLibDebugLevel + setVariable(0x0893a4d0, 2); // amMiscDebugLevel + setVariable(0x0893a4d4, 2); // amOsinfoDebugLevel + setVariable(0x0893a4d8, 2); // amSysDataDebugLevel + setVariable(0x0893a4e0, 2); // bcLibDebugLevel + } // Security detourFunction(0x08190e80, amDongleInit); detourFunction(0x08191201, amDongleIsAvailable); @@ -319,22 +347,24 @@ int initPatch() case THE_HOUSE_OF_THE_DEAD_4: { - // Debug Messages - setVariable(0x0a737c60, 2); // amBackupDebugLevel - setVariable(0x0a737c64, 2); // amChunkDataDebugLevel - setVariable(0x0a737c80, 2); // amCreditDebugLevel - setVariable(0x0a737ed8, 2); // amDipswDebugLevel - setVariable(0x0a737edc, 2); // amDiskDebugLevel - setVariable(0x0a737ee0, 2); // amDongleDebugLevel - setVariable(0x0a737ee4, 2); // amEepromDebugLevel - setVariable(0x0a737ee8, 2); // amHmDebugLevel - setVariable(0x0a737ef0, 2); // amJvsDebugLevel - setVariable(0x0a737f14, 2); // amLibDebugLevel - setVariable(0x0a737f18, 2); // amMiscDebugLevel - setVariable(0x0a737f1c, 2); // amSysDataDebugLevel - setVariable(0x0a737f20, 2); // bcLibDebugLevel - setVariable(0x0a737f24, 0x0FFFFFFF); // s_logMask - + if (config->debug_msgs == 1) + { + // Debug Messages + setVariable(0x0a737c60, 2); // amBackupDebugLevel + setVariable(0x0a737c64, 2); // amChunkDataDebugLevel + setVariable(0x0a737c80, 2); // amCreditDebugLevel + setVariable(0x0a737ed8, 2); // amDipswDebugLevel + setVariable(0x0a737edc, 2); // amDiskDebugLevel + setVariable(0x0a737ee0, 2); // amDongleDebugLevel + setVariable(0x0a737ee4, 2); // amEepromDebugLevel + setVariable(0x0a737ee8, 2); // amHmDebugLevel + setVariable(0x0a737ef0, 2); // amJvsDebugLevel + setVariable(0x0a737f14, 2); // amLibDebugLevel + setVariable(0x0a737f18, 2); // amMiscDebugLevel + setVariable(0x0a737f1c, 2); // amSysDataDebugLevel + setVariable(0x0a737f20, 2); // bcLibDebugLevel + setVariable(0x0a737f24, 0x0FFFFFFF); // s_logMask + } // Security detourFunction(0x08320178, amDongleInit); detourFunction(0x08320459, amDongleIsAvailable); @@ -343,7 +373,7 @@ int initPatch() detourFunction(0x0831ddd7, amDipswGetData); detourFunction(0x0831de4f, stubRetZero); // Stub amDipswSetLed // CPU patch to support AMD processors - if (config->amdFix) + if (strcmp("AuthenticAMD", cpu_vendor.cpuid) == 0) { setVariable(0x0837d6aa, cpu_vendor.ebx); setVariable(0x0837d6ba, cpu_vendor.edx); @@ -361,7 +391,7 @@ int initPatch() detourFunction(0x0831875f, amDipswGetData); detourFunction(0x083187d7, stubRetZero); // Stub amDipswSetLed // CPU patch to support AMD processors - if (config->amdFix) + if (strcmp("AuthenticAMD", cpu_vendor.cpuid) == 0) { setVariable(0x0837963a, cpu_vendor.ebx); setVariable(0x0837964a, cpu_vendor.edx); @@ -378,7 +408,7 @@ int initPatch() detourFunction(0x08067653, amDipswGetData); detourFunction(0x080676cb, stubRetZero); // Stub amDipswSetLed // CPU patch to support AMD processors - if (config->amdFix) + if (strcmp("AuthenticAMD", cpu_vendor.cpuid) == 0) { setVariable(0x0807217a, cpu_vendor.ebx); setVariable(0x0807218a, cpu_vendor.edx); @@ -391,22 +421,21 @@ int initPatch() detourFunction(0x08363438, amDongleInit); detourFunction(0x0836374b, amDongleIsAvailable); detourFunction(0x083636b2, amDongleUpdate); - setVariable(0x081f9491, 0x148b9090); - setVariable(0x081f9499, 0x01000000); + patchMemory(0x081f9491, "9090"); + patchMemory(0x081f9499, "01"); // Fixes detourFunction(0x08360e93, amDipswGetData); detourFunction(0x08360f0b, stubRetZero); // Stub amDipswSetLed // CPU patch to support AMD processors - if (config->amdFix) + if (strcmp("AuthenticAMD", cpu_vendor.cpuid) == 0) { setVariable(0x083cef0a, cpu_vendor.ebx); setVariable(0x083cef1a, cpu_vendor.edx); setVariable(0x083cef25, cpu_vendor.ecx); } // Workaroud - if(remove("/var/tmp/atr_init") == 1) + if (remove("/var/tmp/atr_init") == 1) printf("atr_init deleted.\n"); - } break; case THE_HOUSE_OF_THE_DEAD_4_SPECIAL_TEST: @@ -418,7 +447,7 @@ int initPatch() detourFunction(0x0806e7c7, amDipswGetData); detourFunction(0x0806e83f, stubRetZero); // Stub amDipswSetLed // CPU patch to support AMD processors - if (config->amdFix) + if (strcmp("AuthenticAMD", cpu_vendor.cpuid) == 0) { setVariable(0x0807a3ba, cpu_vendor.ebx); setVariable(0x0807a3ca, cpu_vendor.edx); @@ -435,7 +464,7 @@ int initPatch() detourFunction(0x084b6a69, amDipswGetData); detourFunction(0x084b6adf, stubRetZero); // Stub amDipswSetLed // CPU patch to support AMD processors - if (config->amdFix) + if (strcmp("AuthenticAMD", cpu_vendor.cpuid) == 0) { setVariable(0x0849E2AD, cpu_vendor.ebx); setVariable(0x0849E2B7, cpu_vendor.edx); @@ -452,7 +481,7 @@ int initPatch() detourFunction(0x080772dd, amDipswGetData); detourFunction(0x08077353, stubRetZero); // Stub amDipswSetLed // CPU patch to support AMD processors - if (config->amdFix) + if (strcmp("AuthenticAMD", cpu_vendor.cpuid) == 0) { setVariable(0x080847BD, cpu_vendor.ebx); setVariable(0x080847C7, cpu_vendor.edx); @@ -473,38 +502,38 @@ int initPatch() 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 + patchMemory(0x080e17af, "b800000000"); // 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 - detourFunction(0x08074a8c, _putConsole); // Debug Messages + if (config->debug_msgs == 1) + { + 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); - setVariable(0x080d1f02, 0x90909090); // Patch acpSystem::checkDongle - setVariable(0x080d1f06, 0xE8C3C990); // Patch acpSystem::checkDongle - setVariable(0x0807b76a, 0xc2839090); // Patch initializeArcadeBackup + patchMemory(0x0807b76a, "9090"); // Patch initializeArcadeBackup // Fixes detourFunction(0x084e500e, amDipswGetData); detourFunction(0x084e5086, stubRetZero); // Stub amDipswSetLed - setVariable(0x0840d858, 0x1c899090); // No more Full Screen from the Game + patchMemory(0x0840d858, "9090"); // No more Full Screen from the Game // Set Resolution // setVariable(0x082E006b, 0x00000780); // Set ResX // setVariable(0x082E0078, 0x00000438); // Set ResY @@ -518,56 +547,57 @@ int initPatch() case LETS_GO_JUNGLE_SPECIAL: { - setVariable(0x08c453e4, 2); // amBackupDebugLevel - setVariable(0x08c45400, 2); // amCreditDebugLevel - setVariable(0x08c45658, 2); // amDipswDebugLevel - setVariable(0x08c4565c, 2); // amDongleDebugLevel - setVariable(0x08c45660, 2); // amEepromDebugLevel - setVariable(0x08c45664, 2); // amHwmonitorDebugLevel - setVariable(0x08c45668, 2); // amJvsDebugLevel - setVariable(0x08c4566c, 2); // amLibDebugLevel - setVariable(0x08c45670, 2); // amMiscDebugLevel - setVariable(0x08c45678, 2); // amSysDataDebugLevel - setVariable(0x08c45680, 2); // bcLibDebugLevel - setVariable(0x08c45674, 2); // amOsinfoDebugLevel - setVariable(0x08c45684, 0x0FFFFFFF); // s_logMask - detourFunction(0x08075012, _putConsole); + if (config->debug_msgs == 1) + { + setVariable(0x08c453e4, 2); // amBackupDebugLevel + setVariable(0x08c45400, 2); // amCreditDebugLevel + setVariable(0x08c45658, 2); // amDipswDebugLevel + setVariable(0x08c4565c, 2); // amDongleDebugLevel + setVariable(0x08c45660, 2); // amEepromDebugLevel + setVariable(0x08c45664, 2); // amHwmonitorDebugLevel + setVariable(0x08c45668, 2); // amJvsDebugLevel + setVariable(0x08c4566c, 2); // amLibDebugLevel + setVariable(0x08c45670, 2); // amMiscDebugLevel + setVariable(0x08c45678, 2); // amSysDataDebugLevel + 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); - setVariable(0x080dad63, 0x90909090); // Patch acpSystem::checkDongle - setVariable(0x080dad67, 0xE8C3C990); // Patch acpSystem::checkDongle - setVariable(0x0807e609, 0x90909090); // Patch initializeArcadeBackup - setVariable(0x0807e60d, 0xc2839090); // Patch initializeArcadeBackup + patchMemory(0x0807e609, "909090909090"); // Fixes detourFunction(0x08510256, amDipswGetData); detourFunction(0x085102ce, stubRetZero); // Stub amDipswSetLed - setVariable(0x08438954, 0x1c899090); // No more Full Screen from the Game + patchMemory(0x08438954, "9090"); // 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 INITIALD_4: { - setVariable(0x08d71750, 2); // amBackupDebugLevel - setVariable(0x08d71760, 2); // amCreditDebugLevel - setVariable(0x08d719b8, 2); // amDipswDebugLevel - setVariable(0x08d719bc, 2); // amDongleDebugLevel - setVariable(0x08d719c0, 2); // amEepromDebugLevel - setVariable(0x08d719c4, 2); // amHwmonitorDebugLevel - setVariable(0x08d719c8, 2); // amJvsDebugLevel - setVariable(0x08d719cc, 2); // amLibDebugLevel - setVariable(0x08d719d0, 2); // amMiscDebugLevel - setVariable(0x08d719d8, 2); // amSysDataDebugLevel - setVariable(0x08d719e0, 2); // bcLibDebugLevel - setVariable(0x08d719d4, 2); // amOsinfoDebugLevel - setVariable(0x08d719e4, 0x0FFFFFFF); // s_logMask - // detourFunction(0x0808f9a8, _putConsole); // Crashes the game sometimes. + if (config->debug_msgs == 1) + { + setVariable(0x08d71750, 2); // amBackupDebugLevel + setVariable(0x08d71760, 2); // amCreditDebugLevel + setVariable(0x08d719b8, 2); // amDipswDebugLevel + setVariable(0x08d719bc, 2); // amDongleDebugLevel + setVariable(0x08d719c0, 2); // amEepromDebugLevel + setVariable(0x08d719c4, 2); // amHwmonitorDebugLevel + setVariable(0x08d719c8, 2); // amJvsDebugLevel + setVariable(0x08d719cc, 2); // amLibDebugLevel + setVariable(0x08d719d0, 2); // amMiscDebugLevel + setVariable(0x08d719d8, 2); // amSysDataDebugLevel + 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); @@ -576,13 +606,13 @@ int initPatch() detourFunction(0x086e0c0d, amDipswGetData); detourFunction(0x086e0c84, stubRetZero); // amDipswSetLED detourFunction(0x0821e6dc, stubRetOne); // isEthLinkUp - setVariable(0x082cb411, 0x0927c020); // tickInitStoreNetwork - setVariable(0x082cb6d9, 0x000150e9); // tickWaitDHCP - setVariable(0x082cb6dd, 0x448b5100); // tickWaitDHCP + patchMemory(0x082cb412, "c0270900"); // tickInitStoreNetwork + patchMemory(0x082cb6d9, "e950010000"); // tickWaitDHCP // Set Resolution - setVariable(0x0835664d, 0x0000f0e9); // Force resolution set - setVariable(0x08356743, 0x00000780); // Set ResX - setVariable(0x08356748, 0x00000438); // Set ResY + //patchMemory(0x0835664d, "e9f000"); // 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 @@ -600,10 +630,6 @@ int initPatch() 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 @@ -611,8 +637,11 @@ int initPatch() break; case INITIALD_4_REVE: { - // Debug - // detourFunction(0x08090478, _putConsole); // Crashes the game sometimes. + if (config->debug_msgs == 1) + { + // Debug + detourFunction(0x08090478, _putConsole); // Crashes the game sometimes. + } // Security detourFunction(0x087106e6, amDongleInit); detourFunction(0x0870f131, amDongleIsAvailable); @@ -620,11 +649,9 @@ int initPatch() // 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 + patchMemory(0x082df87d, "e954010000"); // tickWaitDHCP + patchMemory(0x082e0ec9, "eb60"); // tickInitAddress // setVariable(0x08580979, 0x000126e9); // Avoid Full Screen set from Game // Set Resolution // setVariable(0x0837b12d, 0x0000f0e9); // Force set resolution @@ -655,8 +682,11 @@ int initPatch() break; case VIRTUA_TENNIS_3_TEST: { - // Debug - detourFunction(0x08054d14, _putConsole); // Crashes the game sometimes. + if (config->debug_msgs == 1) + { + // Debug + detourFunction(0x08054d14, _putConsole); // Crashes the game sometimes. + } // Security detourFunction(0x0815f610, amDongleInit); detourFunction(0x0815f923, amDongleIsAvailable); @@ -687,7 +717,7 @@ int initPatch() detourFunction(0x0831907d, amDipswGetData); detourFunction(0x083190f4, stubRetZero); // CPU patch to support AMD processors - if (config->amdFix) + if (strcmp("AuthenticAMD", cpu_vendor.cpuid) == 0) { setVariable(0x08399ADA, cpu_vendor.ebx); setVariable(0x08399AEA, cpu_vendor.edx); From 88122173222dab0223d114a1b834209c4deabff2 Mon Sep 17 00:00:00 2001 From: Bobby Dilley Date: Thu, 28 Dec 2023 21:56:37 +0000 Subject: [PATCH 23/31] Add lindbergh utility --- Makefile | 9 +- src/lindbergh/lindbergh.c | 173 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 180 insertions(+), 2 deletions(-) create mode 100644 src/lindbergh/lindbergh.c diff --git a/Makefile b/Makefile index b74ad07..74aee06 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,11 @@ BUILD = build OBJS := $(patsubst %.c,%.o,$(wildcard src/lindbergh/*.c)) -all: lindbergh.so libsegaapi.so libkswapapi.so +all: lindbergh lindbergh.so libsegaapi.so libkswapapi.so + +lindbergh: src/lindbergh/lindbergh.c + mkdir -p $(BUILD) + $(CC) src/lindbergh/lindbergh.c -o $(BUILD)/lindbergh lindbergh.so: $(OBJS) mkdir -p $(BUILD) @@ -23,9 +27,10 @@ libsegaapi.so: src/libsegaapi/segaapi.o libkswapapi.so: src/libkswapapi/libkswapapi.o $(LIBSEGA_LD) $(LIBSEGA_LDFLAGS) src/libkswapapi/libkswapapi.o -L/usr/lib/i386-linux-gnu -fPIC -shared -o $(BUILD)/libkswapapi.so + rm -f src/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 + rm -f src/libkswapapi/*.o diff --git a/src/lindbergh/lindbergh.c b/src/lindbergh/lindbergh.c new file mode 100644 index 0000000..b0d6dfd --- /dev/null +++ b/src/lindbergh/lindbergh.c @@ -0,0 +1,173 @@ +#include +#include +#include +#include + +#define LD_LIBRARY_PATH "LD_LIBRARY_PATH" +#define LD_PRELOAD "LD_PRELOAD" +#define PRELOAD_FILE_NAME "lindbergh.so" + +// List of all lindbergh executables known, not including the test executables +char *games[] = {"amiM.elf", "abc", "hod4M.elf", "lgj_final", "vt3", "id4.elf", "id5.elf", "lgjsp_app", "gsevo", "vf5", "apacheM.elf", "END"}; + +/** + * Tests if the game uses a seperate elf for test mode + * and updates the command line to this elf. + * + * @param name The command path to run + */ +void testModePath(char *name) +{ + // Check if a different testmode elf is used + if (strcmp(name, "./hod4M.elf") == 0) + { + strcpy(name, "./hod4testM.elf"); + return; + } + + if (strcmp(name, "./Jennifer") == 0) + { + strcpy(name, "../JenTest/JenTest"); + return; + } + + if (strcmp(name, "./apacheM.elf") == 0) + { + strcpy(name, "./apacheTestM.elf"); + return; + } + + // Otherwise add the standard -t to the end + strcat(name, " -t"); +} + +/** + * Makes sure the environment variables are set correctly + * to run the game. + */ +void setEnvironmentVariables() +{ + // Ensure the library path is set correctly + char libraryPath[128] = {0}; + + const char *currentLibraryPath = getenv(LD_LIBRARY_PATH); + if (currentLibraryPath != NULL) + { + strcat(libraryPath, currentLibraryPath); + strcat(libraryPath, ":"); + } + + strcat(libraryPath, ".:lib"); + + setenv(LD_LIBRARY_PATH, libraryPath, 1); + + // Ensure the preload path is set correctly + setenv(LD_PRELOAD, PRELOAD_FILE_NAME, 1); +} + +/** + * Prints the usage for the loader + */ +void printUsage(char *argv[]) +{ + printf("%s [GAME_PATH] [OPTIONS]\n", argv[0]); + printf("Options:\n"); + printf(" --test | -t Runs the test mode\n"); + printf(" --help Displays this usage text\n"); +} + +/** + * Small utility to automatically detect the game and run it without + * having to type a long string in. + */ +int main(int argc, char *argv[]) +{ + + // Ensure environment variables are set correctly + setEnvironmentVariables(); + + // Look for the games + struct dirent *ent; + DIR *dir = opendir("."); + + if (dir == NULL) + { + printf("Error: Could not list files in current directory.\n"); + return EXIT_FAILURE; + } + + char *game = NULL; + + int lindberghSharedObjectFound = 0; + + while ((ent = readdir(dir)) != NULL) + { + + if (ent->d_type != DT_REG) + continue; + + if (strcmp(ent->d_name, PRELOAD_FILE_NAME) == 0) + { + lindberghSharedObjectFound = 1; + continue; + } + + int index = 0; + while (1) + { + if (strcmp(games[index], "END") == 0) + break; + + if (strcmp(ent->d_name, games[index]) == 0) + { + game = games[index]; + break; + } + + index++; + } + + if (game != NULL) + break; + } + + closedir(dir); + + if (argc > 1) + { + if (strcmp(argv[1], "--help") == 0) + { + printUsage(argv); + return EXIT_SUCCESS; + } + } + + if (!lindberghSharedObjectFound) + { + printf("Error: The preload object lindbergh.so was not found in this directory.\n"); + return EXIT_FAILURE; + } + + if (game == NULL) + { + printf("Error: No lindbergh game found in this directory.\n"); + return EXIT_FAILURE; + } + + // Build up the command to start the game + char command[128]; + strcpy(command, "./"); + strcat(command, game); + + if (argc > 1) + { + if (strcmp(argv[1], "-t") == 0 || strcmp(argv[1], "--test") == 0) + { + testModePath(command); + } + } + + printf("$ %s\n", command); + + return system(command); +} From 73227a2a8372bc7b73a9fabe0b1b844bba497b5e Mon Sep 17 00:00:00 2001 From: Bobby Dilley Date: Thu, 28 Dec 2023 22:01:57 +0000 Subject: [PATCH 24/31] Add Initial D 4 Name --- src/libkswapapi/libkswapapi.o | Bin 2264 -> 0 bytes src/lindbergh/config.c | 2 ++ 2 files changed, 2 insertions(+) delete mode 100644 src/libkswapapi/libkswapapi.o diff --git a/src/libkswapapi/libkswapapi.o b/src/libkswapapi/libkswapapi.o deleted file mode 100644 index 0ae0ad7d2db3dbc8d94864cb6594f895ed703966..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2264 zcma)7TWB0r7(O$z8)J5Jueq3N#?mH{X2;DY*4PWpgAwsnx z62a#C!8#ZgxpJx7k%X9p9EQ&Vq5*%^R1Xb5zC)WFq z#E$ftv8)-Jj+?QCQ^{emyn4z-nz3jb$4rW^V@UD*yQHM zV|S)D4}Z0_@x^3vA~v!0<>tn8Dj7?6SrZji9d7fxolOUu<_~=Q`<2#v8;Mu6yLB@U zi@K-#KM`ZY!$-|79Qx6{C&pfE7&?je2!Rl^QM;*{sQEG*wGT|vE}RzH#Y(L$8VX&4 zgRLi%WXlI@Dqq!ys>7+=t^&yr z_wUi8d-R$;dabDSEj)h%_IoH0(V$m|-heLem|IHA$8(BHR%XvT+BV+W%DSFi%-G)I zT7KDb)`dNmnjRWV+0&z=&y392GlN5^5u0V%YrRUyQ&(Y@E1_$6jA|mT)+fvUIR#x0R&XO;9u7weft$I#o+1IoAHLF-E6y1_{zFgK_v=>Uw3W{b+ zg|#AX`oHN1MAiqQ`JLo@JpjfN%D3cuwu3p-YEn7>a&CYmHScYZIjsX=(mUuo<5&+* zA?vaJAux0JETmK!c2-sIFf5G!uQ)jah^ycxAlBo#6{&isV30D4f~XHksl2Eh<_GU_ z0|yv@jrZWMlW{EZELhcsD6W9VDEOp&dFV=}>wB}$jo6MN#jsv%c5NABdc$D-0$CY7|#UaSdVcZ z`l#yt0i*h+GMq8wk9-73YVhAr>5L(L3TEGxdmjYeLy>y7?_gk#iaQP=I9n?28^i?r zvLB8**w`2RE${RtSPN!x3H5FQ`R!sp>oJeAno)>i97>XcPwF20tp(${QQ#L91XOYV E0N$$l%>V!Z diff --git a/src/lindbergh/config.c b/src/lindbergh/config.c index ace2783..9d8b34a 100644 --- a/src/lindbergh/config.c +++ b/src/lindbergh/config.c @@ -320,6 +320,8 @@ char *getGameName() return "Virtua Tennis 3 Test Mode"; case THE_HOUSE_OF_THE_DEAD_4_STRIPPED: return "The House of the Dead 4"; + case INITIALD_4_REVE: + return "Initial D 4 Exp Rev E"; default: return unknownGameTitle; } From dff8639a5b68200c55c39f262c444097f0368a07 Mon Sep 17 00:00:00 2001 From: Bobby Dilley Date: Thu, 28 Dec 2023 22:09:55 +0000 Subject: [PATCH 25/31] Add gdb mode to lindbergh util --- src/lindbergh/lindbergh.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/lindbergh/lindbergh.c b/src/lindbergh/lindbergh.c index b0d6dfd..70621a7 100644 --- a/src/lindbergh/lindbergh.c +++ b/src/lindbergh/lindbergh.c @@ -73,6 +73,7 @@ void printUsage(char *argv[]) printf("%s [GAME_PATH] [OPTIONS]\n", argv[0]); printf("Options:\n"); printf(" --test | -t Runs the test mode\n"); + printf(" --gdb Runs with GDB\n"); printf(" --help Displays this usage text\n"); } @@ -133,13 +134,10 @@ int main(int argc, char *argv[]) closedir(dir); - if (argc > 1) + if (argc > 1 && strcmp(argv[1], "--help") == 0) { - if (strcmp(argv[1], "--help") == 0) - { - printUsage(argv); - return EXIT_SUCCESS; - } + printUsage(argv); + return EXIT_SUCCESS; } if (!lindberghSharedObjectFound) @@ -159,12 +157,20 @@ int main(int argc, char *argv[]) strcpy(command, "./"); strcat(command, game); - if (argc > 1) + for (int i = 1; i < argc; i++) { - if (strcmp(argv[1], "-t") == 0 || strcmp(argv[1], "--test") == 0) + if (strcmp(argv[i], "-t") == 0 || strcmp(argv[i], "--test") == 0) { testModePath(command); } + + if (strcmp(argv[i], "--gdb") == 0) + { + char temp[128]; + strcpy(temp, "gdb "); + strcat(temp, command); + strcpy(command, temp); + } } printf("$ %s\n", command); From 098f717725ab2282f5e26fb1ab57382942dfcfea Mon Sep 17 00:00:00 2001 From: Bobby Dilley Date: Thu, 28 Dec 2023 22:23:38 +0000 Subject: [PATCH 26/31] fix some logic --- src/lindbergh/lindbergh.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lindbergh/lindbergh.c b/src/lindbergh/lindbergh.c index 70621a7..9c89c50 100644 --- a/src/lindbergh/lindbergh.c +++ b/src/lindbergh/lindbergh.c @@ -114,7 +114,7 @@ int main(int argc, char *argv[]) } int index = 0; - while (1) + while (game == NULL) { if (strcmp(games[index], "END") == 0) break; @@ -128,7 +128,7 @@ int main(int argc, char *argv[]) index++; } - if (game != NULL) + if (game != NULL && lindberghSharedObjectFound) break; } From 788bd1131d94ee7b83a03efa5bf5bb0de0516d7a Mon Sep 17 00:00:00 2001 From: Bobby Dilley Date: Thu, 28 Dec 2023 22:52:05 +0000 Subject: [PATCH 27/31] Update README --- README.md | 2 ++ docs/supported.md | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4b687c3..0ab9dc0 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,8 @@ A default configuration file is provided in `docs/lindbergh.conf`. It should be I recomend that you do not run this as root, and instead use the usergroups for input/dialout to give the emulator access to what it needs. The Lindbergh games expect full control of the Linux OS and with root privilages it is possible that they could cause damage to your computer. +A `lindbergh` executable is provided in the build directory to easily run the games. Place it in the same directory as the game elf, and run `./lindbergh` to automatically start the game with the correct environment variables set, or run `./lindbergh -t` for test mode. + ## Controls Currently the controls are set up for The House of the Dead 4. diff --git a/docs/supported.md b/docs/supported.md index 3aaec8d..d23d335 100644 --- a/docs/supported.md +++ b/docs/supported.md @@ -11,7 +11,7 @@ Working is defined by getting into attract mode and running the game, but not ne - Ghost Squad Evolution - Harley Davidson - Let's Go Jungle -- Let's Go Jungle Special (boots to ride error) +- Let's Go Jungle Special - Outrun 2 SP SDX - R-Tuned - Race TV From 432597be1356b003ab80ee0b4431da12a4e45139 Mon Sep 17 00:00:00 2001 From: Bobby Dilley Date: Thu, 28 Dec 2023 23:00:45 +0000 Subject: [PATCH 28/31] Update README.md --- README.md | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 0ab9dc0..eb61255 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,12 @@ # SEGA Lindbergh Emulator -This project aims to hook and emulate the various different parts of the SEGA Lindbergh allowing the games to run on modern versions of Linux. +This alpha stage project emulates the SEGA Lindbergh, allowing games to run on modern Linux computers with any NVIDIA graphics card. You can view the supported titles [here.](docs/supported.md) -You will need an nvidia graphics card and I have tested with the latest version of Ubuntu. - -Please be aware that the project is in very early stages, and there will be lots of issues with all games. - ## Dependencies -First make sure you have up to date nVidia drivers for your computer, and then install the following: +First make sure you have up to date NVIDIA drivers and then install the following: ``` sudo dpkg --add-architecture i386 @@ -32,7 +28,7 @@ sudo addgroup $USER dialout sudo addgroup $USER input ``` -To build, run the makefile, and then copy the contents of the build directory into your game directory and run. +To build, run the makefile, and then copy the contents of the build directory into the game directory and run. ``` make @@ -41,11 +37,11 @@ cd ~/the-house-of-the-dead-4/disk0/elf LD_PRELOAD=lindbergh.so LD_LIBRARY_PATH=$LD_LIBRARY_PATH:. ./hod4M.elf ``` -Some games will require extra libraries like `libposixtime.so`. These can be found in any dumps of the Lindbergh CF image. +Some games will require extra libraries like `libposixtime.so`, which can be found in dumps of the Lindbergh CF image. -A default configuration file is provided in `docs/lindbergh.conf`. It should be placed in the same folder as the game is run from. If no config file is present a default setting will be used. +A default configuration file is provided in `docs/lindbergh.conf`. It should be placed in the same folder the game is run from. If no config file is present a default setting will be used. -I recomend that you do not run this as root, and instead use the usergroups for input/dialout to give the emulator access to what it needs. The Lindbergh games expect full control of the Linux OS and with root privilages it is possible that they could cause damage to your computer. +Do not run this as root, instead use the usergroups for input/dialout to give the emulator access to what it needs. Lindbergh games expect full control of the Linux OS and with root privilages it is possible that they could cause damage to your computer. A `lindbergh` executable is provided in the build directory to easily run the games. Place it in the same directory as the game elf, and run `./lindbergh` to automatically start the game with the correct environment variables set, or run `./lindbergh -t` for test mode. @@ -64,5 +60,4 @@ Currently the controls are set up for The House of the Dead 4. ## Thanks -This project has been built by referencing things made by Teknoparrot, Doozer and JayFoxRox and from contributions by Rolel and -dkeruza-neo and extensive testing by Francesco so thanks to all of them! +This project has been built by referencing earlier projects by Teknoparrot and JayFoxRox and from contributions by Doozer, Rolel and dkeruza-neo with extensive testing by Francesco - thanks to all of them! From d6625d3068f9c6e8ef6a5ed7379e315a554ff360 Mon Sep 17 00:00:00 2001 From: Bobby Dilley Date: Fri, 29 Dec 2023 14:02:24 +0000 Subject: [PATCH 29/31] Fix JVS and Tidy Up --- docs/lindbergh.conf | 2 +- src/lindbergh/baseboard.c | 7 +++-- src/lindbergh/config.c | 19 ++++-------- src/lindbergh/config.h | 2 +- src/lindbergh/graphics.c | 7 ++--- src/lindbergh/hook.c | 23 ++++++++------ src/lindbergh/input.c | 7 +++-- src/lindbergh/jvs.c | 19 +++++++----- src/lindbergh/jvs.h | 4 +-- src/lindbergh/lindbergh.c | 2 +- src/lindbergh/patch.c | 63 ++++++++++++++++++++++++++------------- 11 files changed, 88 insertions(+), 67 deletions(-) diff --git a/docs/lindbergh.conf b/docs/lindbergh.conf index 287eb17..e1e60e1 100644 --- a/docs/lindbergh.conf +++ b/docs/lindbergh.conf @@ -69,4 +69,4 @@ REGION EX FREEPLAY 1 # Set if you want to see degug messages in the console -DEBUG_MSGS 0 \ No newline at end of file +DEBUG_MSGS 0 diff --git a/src/lindbergh/baseboard.c b/src/lindbergh/baseboard.c index e2d6fca..0b2835d 100644 --- a/src/lindbergh/baseboard.c +++ b/src/lindbergh/baseboard.c @@ -60,6 +60,7 @@ uint8_t sharedMemory[1024 * 32] = {0}; int selectReply = -1; int jvsFileDescriptor = -1; +int jvsPacketSize = -1; int initBaseboard() { @@ -192,7 +193,7 @@ int baseboardIoctl(int fd, unsigned int request, void *data) if (getConfig()->emulateJVS) { - processPacket(); + processPacket(&jvsPacketSize); } else if (jvsFileDescriptor >= 0) { @@ -251,9 +252,9 @@ int baseboardIoctl(int fd, unsigned int request, void *data) { if (getConfig()->emulateJVS) { - memcpy(&sharedMemory[jvsCommand.destAddress], outputBuffer, outputPacket.length + 3); + memcpy(&sharedMemory[jvsCommand.destAddress], outputBuffer, jvsPacketSize); _data[2] = jvsCommand.destAddress; - _data[3] = outputPacket.length + 3; + _data[3] = jvsPacketSize; _data[1] = 1; // Set the status to success } else if (jvsFileDescriptor >= 0) diff --git a/src/lindbergh/config.c b/src/lindbergh/config.c index 9d8b34a..76ed77a 100644 --- a/src/lindbergh/config.c +++ b/src/lindbergh/config.c @@ -47,13 +47,6 @@ 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; @@ -279,7 +272,7 @@ char *getGameName() case SEGABOOT_2_4: return "SEGABOOT 2.4"; case SEGABOOT_2_4_SYM: - return "SEGABOOT 2.4 Symbols"; + return "SEGABOOT 2.4 with Symbols"; case SEGABOOT_2_6: return "SEGABOOT 2.6"; case SEGA_RACE_TV: @@ -319,7 +312,7 @@ char *getGameName() case VIRTUA_TENNIS_3_TEST: return "Virtua Tennis 3 Test Mode"; case THE_HOUSE_OF_THE_DEAD_4_STRIPPED: - return "The House of the Dead 4"; + return "The House of the Dead 4 Rev C"; case INITIALD_4_REVE: return "Initial D 4 Exp Rev E"; default: @@ -405,7 +398,7 @@ int readConfig(FILE *configFile, EmulatorConfig *config) } else if (strcmp(command, "DEBUG_MSGS") == 0) - config->debug_msgs = atoi(getNextToken(NULL, " ", &saveptr)); + config->showDebugMessages = atoi(getNextToken(NULL, " ", &saveptr)); else printf("Error: Unknown settings command %s\n", command); @@ -428,12 +421,12 @@ int initConfig() strcpy(config.driveboardPath, "none"); strcpy(config.motionboardPath, "none"); strcpy(config.rideboardPath, "none"); - config.width = 1024; - config.height = 768; + config.width = 640; + config.height = 480; config.crc32 = elf_crc; config.region = -1; config.freeplay = -1; - config.debug_msgs = 1; + config.showDebugMessages = 0; if (detectGame(config.crc32) != 0) { printf("Warning: Unsure what game with CRC 0x%X is. Please submit this new game to the GitHub repository: https://github.com/bobbydilley/lindbergh-loader/issues/new?title=Please+add+new+game+0x%X&body=I+tried+to+launch+the+following+game:\n", config.crc32, config.crc32); diff --git a/src/lindbergh/config.h b/src/lindbergh/config.h index d5e20b3..4db28d0 100644 --- a/src/lindbergh/config.h +++ b/src/lindbergh/config.h @@ -93,7 +93,7 @@ typedef struct uint32_t crc32; GameRegion region; int freeplay; - int debug_msgs; + int showDebugMessages; } EmulatorConfig; int initConfig(); diff --git a/src/lindbergh/graphics.c b/src/lindbergh/graphics.c index c4dad88..96f0876 100644 --- a/src/lindbergh/graphics.c +++ b/src/lindbergh/graphics.c @@ -26,7 +26,6 @@ FGAPI int FGAPIENTRY glutEnterGameMode() { char gameTitle[256] = {0}; strcat(gameTitle, getGameName()); - strcat(gameTitle, " (GLUT)"); glutCreateWindow(gameTitle); // Outrun doesn't run the glutMainLoop through, so we'll do that here @@ -53,7 +52,7 @@ FGAPI void FGAPIENTRY glutSetCursor(int cursor) FGAPI void FGAPIENTRY glutGameModeString(const char *string) { - printf("glutGameModeString: %s\n", string); + // printf("glutGameModeString: %s\n", string); char gameModeString[1024]; strcpy(gameModeString, string); @@ -100,7 +99,7 @@ Window XCreateWindow(Display *display, Window parent, int x, int y, unsigned int // attributes->override_redirect = False; Window window = _XCreateWindow(display, parent, x, y, width, height, border_width, depth, class, visual, valueMask, attributes); - printf("XCreateWindow Resolution %d %d %d %d\n", x, y, width, height); + printf("The resolution is %dx%d \n", width, height); if (getConfig()->fullscreen) { @@ -138,7 +137,6 @@ int XStoreName(Display *display, Window w, const char *window_name) int (*_XStoreName)(Display *display, Window w, const char *window_name) = dlsym(RTLD_NEXT, "XStoreName"); char gameTitle[256] = {0}; strcat(gameTitle, getGameName()); - strcat(gameTitle, " (X11)"); return _XStoreName(display, w, gameTitle); } @@ -147,7 +145,6 @@ int XSetStandardProperties(Display *display, Window window, const char *window_n int (*_XSetStandardProperties)(Display *display, Window window, const char *window_name, const char *icon_name, Pixmap icon_pixmap, char **argv, int argc, XSizeHints *hints) = dlsym(RTLD_NEXT, "XSetStandardProperties"); char gameTitle[256] = {0}; strcat(gameTitle, getGameName()); - strcat(gameTitle, " (X11)"); return _XSetStandardProperties(display, window, gameTitle, icon_name, icon_pixmap, argv, argc, hints); } diff --git a/src/lindbergh/hook.c b/src/lindbergh/hook.c index dedc090..2ba3580 100755 --- a/src/lindbergh/hook.c +++ b/src/lindbergh/hook.c @@ -183,14 +183,14 @@ void __attribute__((constructor)) hook_init() securityBoardSetDipResolution(getConfig()->width, getConfig()->height); - printf("Now emulating %s", getGameName()); + printf("Now starting %s", getGameName()); if (getConfig()->gameStatus == WORKING) { - printf((" - Game is in working state.\n")); + printf((", this game is working.\n")); } else { - printf((" - Game is in NOT WORKING state.\n")); + printf((", this game is NOT working.\n")); } } @@ -545,15 +545,14 @@ int system(const char *command) return 0; if (strcmp(command, "uname -r | grep mvl") == 0) - { - EmulatorConfig *config = getConfig(); - config->game = SEGABOOT_2_4; return 0; - } if (strstr(command, "hwclock") != NULL) return 0; + if (strstr(command, "losetup") != NULL) + return 0; + return _system(command); } @@ -607,7 +606,10 @@ int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) // Change the IP to connect to to 127.0.0.1 // in_pointer->sin_addr.s_addr = inet_addr("127.0.0.1"); char *some_addr = inet_ntoa(in_pointer->sin_addr); - printf("Connecting to %s\n", some_addr); + if (getConfig()->showDebugMessages) + { + printf("Connecting to %s\n", some_addr); + } return _connect(sockfd, addr, addrlen); } @@ -652,7 +654,10 @@ void getCPUID() eax = 0; __get_cpuid(0, &eax, &cpu_vendor.ebx, &cpu_vendor.ecx, &cpu_vendor.edx); sprintf(cpu_vendor.cpuid, "%.4s%.4s%.4s", (const char *)&cpu_vendor.ebx, (const char *)&cpu_vendor.edx, (const char *)&cpu_vendor.ecx); - printf("CPU Vendor: %s\n", cpu_vendor.cpuid); + if (getConfig()->showDebugMessages) + { + printf("Detected CPU Vendor: %s\n", cpu_vendor.cpuid); + } } /** diff --git a/src/lindbergh/input.c b/src/lindbergh/input.c index 5268cf2..fbc9a1c 100644 --- a/src/lindbergh/input.c +++ b/src/lindbergh/input.c @@ -13,11 +13,12 @@ #include #include #include +#include int initInput() { - return 0; + return 0; } int XNextEvent(Display *display, XEvent *event_return) @@ -87,8 +88,8 @@ int XNextEvent(Display *display, XEvent *event_return) case MotionNotify: { - setAnalogue(ANALOGUE_1, ((double)event_return->xmotion.x / (double)getConfig()->width) * 255); - setAnalogue(ANALOGUE_2, ((double)event_return->xmotion.y / (double)getConfig()->height) * 255); + setAnalogue(ANALOGUE_1, ((double)event_return->xmotion.x / (double)getConfig()->width) * pow(2, 10)); + setAnalogue(ANALOGUE_2, ((double)event_return->xmotion.y / (double)getConfig()->height) * pow(2, 10)); } break; diff --git a/src/lindbergh/jvs.c b/src/lindbergh/jvs.c index 8534b54..3128e7f 100644 --- a/src/lindbergh/jvs.c +++ b/src/lindbergh/jvs.c @@ -33,7 +33,7 @@ int initJVS() io.capabilities.switches = 14; io.capabilities.coins = 2; io.capabilities.players = 2; - io.capabilities.analogueInBits = 8; + io.capabilities.analogueInBits = 10; io.capabilities.rightAlignBits = 0; io.capabilities.analogueInChannels = 8; io.capabilities.generalPurposeOutputs = 20; @@ -163,7 +163,7 @@ void writeFeatures(JVSPacket *outputPacket, JVSCapabilities *capabilities) * * @returns The status of the entire operation */ -JVSStatus processPacket() +JVSStatus processPacket(int *packetSize) { readPacket(&inputPacket); @@ -265,11 +265,11 @@ JVSStatus processPacket() outputPacket.data[outputPacket.length] = REPORT_SUCCESS; outputPacket.data[outputPacket.length + 1] = io.state.inputSwitch[0]; outputPacket.length += 2; - + 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)); } } @@ -278,7 +278,7 @@ JVSStatus processPacket() case CMD_READ_COINS: { - ////printf("CMD_READ_COINS\n"); + // printf("CMD_READ_COINS\n"); size = 2; int numberCoinSlots = inputPacket.data[index + 1]; outputPacket.data[outputPacket.length++] = REPORT_SUCCESS; @@ -294,7 +294,7 @@ JVSStatus processPacket() case CMD_READ_ANALOGS: { - // printf("CMD_READ_ANALOGS\n"); + // printf("CMD_READ_ANALOGS %d\n", inputPacket.data[index + 1]); size = 2; outputPacket.data[outputPacket.length++] = REPORT_SUCCESS; @@ -478,7 +478,7 @@ JVSStatus processPacket() pthread_mutex_unlock(&jvsMutex); - writePacket(&outputPacket); + writePacket(&outputPacket, packetSize); return JVS_STATUS_SUCCESS; } @@ -565,7 +565,7 @@ JVSStatus readPacket(JVSPacket *packet) * * @param packet The packet to send */ -JVSStatus writePacket(JVSPacket *packet) +JVSStatus writePacket(JVSPacket *packet, int *packetSize) { /* Get pointer to raw data in packet */ unsigned char *packetPointer = (unsigned char *)packet; @@ -603,6 +603,9 @@ JVSStatus writePacket(JVSPacket *packet) outputBuffer[outputIndex++] = checksum; } + // Communicate the output size based on the now escaped bytes + *packetSize = outputIndex; + return JVS_STATUS_SUCCESS; } diff --git a/src/lindbergh/jvs.h b/src/lindbergh/jvs.h index d31c553..d3c0793 100644 --- a/src/lindbergh/jvs.h +++ b/src/lindbergh/jvs.h @@ -223,10 +223,10 @@ typedef enum int initJVS(); -JVSStatus processPacket(); +JVSStatus processPacket(int* packetSize); JVSStatus readPacket(JVSPacket *packet); -JVSStatus writePacket(JVSPacket *packet); +JVSStatus writePacket(JVSPacket *packet, int* packetSize); /* The in and out packets used to read and write to and from*/ extern JVSPacket inputPacket, outputPacket; diff --git a/src/lindbergh/lindbergh.c b/src/lindbergh/lindbergh.c index 9c89c50..a2445ed 100644 --- a/src/lindbergh/lindbergh.c +++ b/src/lindbergh/lindbergh.c @@ -8,7 +8,7 @@ #define PRELOAD_FILE_NAME "lindbergh.so" // List of all lindbergh executables known, not including the test executables -char *games[] = {"amiM.elf", "abc", "hod4M.elf", "lgj_final", "vt3", "id4.elf", "id5.elf", "lgjsp_app", "gsevo", "vf5", "apacheM.elf", "END"}; +char *games[] = {"segaboot", "amiM.elf", "abc", "hod4M.elf", "lgj_final", "vt3", "id4.elf", "id5.elf", "lgjsp_app", "gsevo", "vf5", "apacheM.elf", "END"}; /** * Tests if the game uses a seperate elf for test mode diff --git a/src/lindbergh/patch.c b/src/lindbergh/patch.c index be6d1ca..5498de1 100644 --- a/src/lindbergh/patch.c +++ b/src/lindbergh/patch.c @@ -30,19 +30,19 @@ static void setVariable(uint32_t address, uint32_t value) static void patchMemory(uint32_t address, char *value) { - - size_t size = strlen((void*)value); + + size_t size = strlen((void *)value); printf("Size=%d\n", size); - if(size % 2 != 0) + if (size % 2 != 0) { printf("Patch value should be even.\n"); exit(1); } - char buf[size/2]; + char buf[size / 2]; char tmpchr[3]; char *p = value; - for(int i=0; i < size; i++) + for (int i = 0; i < size; i++) { memcpy(tmpchr, p, 2); tmpchr[2] = '\0'; @@ -61,7 +61,7 @@ static void patchMemory(uint32_t address, char *value) return; } - memcpy((uint32_t *)address, buf, size/2); + memcpy((uint32_t *)address, buf, size / 2); } static void detourFunction(uint32_t address, void *function) @@ -263,7 +263,7 @@ int initPatch() break; case AFTER_BURNER_CLIMAX_REVA: { - if (config->debug_msgs == 1) + if (config->showDebugMessages == 1) { // Debug Messages setVariable(0x0a0a37e4, 2); // amBackupDebugLevel @@ -287,12 +287,12 @@ int initPatch() detourFunction(0x081e48b6, amDipswGetData); detourFunction(0x081e492e, stubRetZero); // Stub amDipswSetLed // Does not work - //setVariable(0x08061c31, 0x0000000c); // Force HD resolution + // setVariable(0x08061c31, 0x0000000c); // Force HD resolution } break; case AFTER_BURNER_CLIMAX_REVB: { - if (config->debug_msgs == 1) + if (config->showDebugMessages == 1) { // Debug Messages setVariable(0x0a0a0d24, 2); // amBackupDebugLevel @@ -319,7 +319,7 @@ int initPatch() break; case OUTRUN_2_SP_SDX_REVA: { - if (config->debug_msgs == 1) + if (config->showDebugMessages == 1) { // Debug Messages setVariable(0x0893a24c, 2); // amBackupDebugLevel @@ -347,7 +347,7 @@ int initPatch() case THE_HOUSE_OF_THE_DEAD_4: { - if (config->debug_msgs == 1) + if (config->showDebugMessages == 1) { // Debug Messages setVariable(0x0a737c60, 2); // amBackupDebugLevel @@ -508,7 +508,7 @@ int initPatch() case LETS_GO_JUNGLE: { - if (config->debug_msgs == 1) + if (config->showDebugMessages == 1) { setVariable(0x08c083a4, 2); // amBackupDebugLevel setVariable(0x08c083c0, 2); // amCreditDebugLevel @@ -529,7 +529,7 @@ int initPatch() detourFunction(0x084e50d8, amDongleInit); detourFunction(0x084e5459, amDongleIsAvailable); detourFunction(0x084e537d, amDongleUpdate); - patchMemory(0x0807b76a, "9090"); // Patch initializeArcadeBackup + patchMemory(0x0807b76a, "9090"); // Patch initializeArcadeBackup // Fixes detourFunction(0x084e500e, amDipswGetData); detourFunction(0x084e5086, stubRetZero); // Stub amDipswSetLed @@ -547,7 +547,7 @@ int initPatch() case LETS_GO_JUNGLE_SPECIAL: { - if (config->debug_msgs == 1) + if (config->showDebugMessages == 1) { setVariable(0x08c453e4, 2); // amBackupDebugLevel setVariable(0x08c45400, 2); // amCreditDebugLevel @@ -581,7 +581,7 @@ int initPatch() case INITIALD_4: { - if (config->debug_msgs == 1) + if (config->showDebugMessages == 1) { setVariable(0x08d71750, 2); // amBackupDebugLevel setVariable(0x08d71760, 2); // amCreditDebugLevel @@ -609,10 +609,10 @@ int initPatch() patchMemory(0x082cb412, "c0270900"); // tickInitStoreNetwork patchMemory(0x082cb6d9, "e950010000"); // tickWaitDHCP // Set Resolution - //patchMemory(0x0835664d, "e9f000"); // Force resolution set - //setVariable(0x08356743, 0x00000780); // Set ResX - //setVariable(0x08356748, 0x00000438); // Set ResY - + // patchMemory(0x0835664d, "e9f000"); // 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 @@ -637,7 +637,7 @@ int initPatch() break; case INITIALD_4_REVE: { - if (config->debug_msgs == 1) + if (config->showDebugMessages == 1) { // Debug detourFunction(0x08090478, _putConsole); // Crashes the game sometimes. @@ -662,6 +662,27 @@ int initPatch() break; case SEGABOOT_2_4_SYM: { + if (config->showDebugMessages == 1) + { + setVariable(0x0808da48, 2); // amAdtecDebugLevel + setVariable(0x0808cf8c, 2); // amAtaDebugLevel + setVariable(0x0808cf90, 2); // amBackupDebugLevel + setVariable(0x0808cf94, 2); // amChunkDataDebugLevel + setVariable(0x0808cfa0, 2); // amCreditDebugLevel + setVariable(0x0808d1f8, 2); // amDipswDebugLevel + setVariable(0x0808d1fc, 2); // amDiskDebugLevel + setVariable(0x0808d200, 2); // amDongleDebugLevel + setVariable(0x0808d204, 2); // amEepromDebugLevel + setVariable(0x0808d208, 2); // amHmDebugLevel + setVariable(0x0808d210, 2); // amJvsDebugLevel + setVariable(0x0808d214, 2); // amLibDebugLevel + setVariable(0x0808d218, 2); // amMiscDebugLevel + setVariable(0x0808d21c, 2); // amSysDataDebugLevel + setVariable(0x0808d220, 2); // bcLibDebugLevel + setVariable(0x0808cf58, 2); // g_DebugLevel + setVariable(0x0808d224, 0x0FFFFFFF); // logmask + } + detourFunction(0x0805e8b0, amDongleInit); detourFunction(0x0805ebc3, amDongleIsAvailable); detourFunction(0x0805eb2a, amDongleUpdate); @@ -682,7 +703,7 @@ int initPatch() break; case VIRTUA_TENNIS_3_TEST: { - if (config->debug_msgs == 1) + if (config->showDebugMessages == 1) { // Debug detourFunction(0x08054d14, _putConsole); // Crashes the game sometimes. From 03ff0e692312187e749e17608fe539b99637d138 Mon Sep 17 00:00:00 2001 From: Bobby Dilley Date: Fri, 29 Dec 2023 14:14:19 +0000 Subject: [PATCH 30/31] Fix rideboard --- src/lindbergh/hook.c | 2 +- src/lindbergh/lindbergh.c | 2 +- src/lindbergh/patch.c | 5 +---- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/lindbergh/hook.c b/src/lindbergh/hook.c index 2ba3580..d6588cb 100755 --- a/src/lindbergh/hook.c +++ b/src/lindbergh/hook.c @@ -183,7 +183,7 @@ void __attribute__((constructor)) hook_init() securityBoardSetDipResolution(getConfig()->width, getConfig()->height); - printf("Now starting %s", getGameName()); + printf("Now starting \"%s\"", getGameName()); if (getConfig()->gameStatus == WORKING) { printf((", this game is working.\n")); diff --git a/src/lindbergh/lindbergh.c b/src/lindbergh/lindbergh.c index a2445ed..013857b 100644 --- a/src/lindbergh/lindbergh.c +++ b/src/lindbergh/lindbergh.c @@ -8,7 +8,7 @@ #define PRELOAD_FILE_NAME "lindbergh.so" // List of all lindbergh executables known, not including the test executables -char *games[] = {"segaboot", "amiM.elf", "abc", "hod4M.elf", "lgj_final", "vt3", "id4.elf", "id5.elf", "lgjsp_app", "gsevo", "vf5", "apacheM.elf", "END"}; +char *games[] = {"Jennifer", "segaboot", "amiM.elf", "abc", "hod4M.elf", "lgj_final", "vt3", "id4.elf", "id5.elf", "lgjsp_app", "gsevo", "vf5", "apacheM.elf", "END"}; /** * Tests if the game uses a seperate elf for test mode diff --git a/src/lindbergh/patch.c b/src/lindbergh/patch.c index 5498de1..572ffd5 100644 --- a/src/lindbergh/patch.c +++ b/src/lindbergh/patch.c @@ -32,7 +32,7 @@ static void patchMemory(uint32_t address, char *value) { size_t size = strlen((void *)value); - printf("Size=%d\n", size); + // printf("Size=%d\n", size); if (size % 2 != 0) { printf("Patch value should be even.\n"); @@ -433,9 +433,6 @@ int initPatch() setVariable(0x083cef1a, cpu_vendor.edx); setVariable(0x083cef25, cpu_vendor.ecx); } - // Workaroud - if (remove("/var/tmp/atr_init") == 1) - printf("atr_init deleted.\n"); } break; case THE_HOUSE_OF_THE_DEAD_4_SPECIAL_TEST: From 95bc966da3a545a1be908f0ca72588c304d18836 Mon Sep 17 00:00:00 2001 From: Bobby Dilley Date: Fri, 29 Dec 2023 14:16:50 +0000 Subject: [PATCH 31/31] Fix hotd key repeat issue --- src/lindbergh/graphics.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/lindbergh/graphics.c b/src/lindbergh/graphics.c index 96f0876..cdb539c 100644 --- a/src/lindbergh/graphics.c +++ b/src/lindbergh/graphics.c @@ -86,6 +86,14 @@ FGAPI void FGAPIENTRY glutGameModeString(const char *string) } } +/** + * Stop the house of the dead games turning keyboard repeating off. + */ +int XAutoRepeatOff(Display *display) +{ + return 0; +} + Window XCreateWindow(Display *display, Window parent, int x, int y, unsigned int width, unsigned int height, unsigned int border_width, int depth, unsigned int class, Visual *visual, unsigned long valueMask, XSetWindowAttributes *attributes) {