Compare commits

...
Author SHA1 Message Date
dkeruza 3c3f0f5eb5 Update ci.yml 2025-02-03 16:05:21 -05:00
dkeruza-neo fe2c749bb0 Fixes. Added ELF clean checker. 2025-02-02 17:51:24 +01:00
Bobby Dilley d3e6027139 Update guide.md 2025-01-28 17:42:07 +00:00
Bobby Dilley 565a9208b7 Update guide.md 2025-01-28 15:36:05 +00:00
Bobby Dilley be78a23a31 Make dkeruza happy 2025-01-28 15:24:06 +00:00
Bobby Dilley 8942c510ec Look for /dev/dsp and /dev/dsp1 2025-01-28 10:45:35 +00:00
Bobby Dilley 685d569a08 Remove not needed message 2025-01-28 10:16:06 +00:00
Bobby Dilley 5f19cdc44c Fix wrong error message 2025-01-28 10:11:55 +00:00
Bobby Dilley be1b88b92f Merge remote-tracking branch 'caviar/master' 2025-01-28 10:01:27 +00:00
Synth_Magic 51eaec106c Do changes as requested 2025-01-10 22:03:06 +08:00
Synth Magic dcae95fe03 rename linux/limits.h to limits.h 2025-01-10 20:54:24 +08:00
Synth_Magic fbc76dfe5e Add config path sepcification 2025-01-10 20:52:07 +08:00
17 changed files with 3082 additions and 2898 deletions
+1 -1
View File
@@ -42,7 +42,7 @@ jobs:
# Archive the build directory as an artifact for debugging
- name: Archive build directory
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: build-output
path: ./build
+9 -1
View File
@@ -2,7 +2,15 @@
All notable changes to this project will be documented in this file.
## [2.0.2]
## [2.0.3]
### Added
- Display a warning when loading an Elf that is not clean.
- Added to the lib folder, common libraries that are usually missing.
### Fixed
- Missing patch in HOD-EX.
- Alows to run a game that does not support Card reader if option enabled in conf file.
## [2.0.2] 2025-01-27
### Added
- InitialD 5 SBRY added.
- HOD4 SP CPU Frequency fix.
+17 -2
View File
@@ -48,11 +48,26 @@ sudo ln -s /lib/i386-linux-gnu/libglut.so /lib/i386-linux-gnu/libglut.so.3
### Let's Go Jungle Rev A
- The game must be run in export mode to have the stereo sound option.
The game must be run in export mode to have the stereo sound option.
### Outrun 2 SP SDX
- You need to set `SKIP_OUTRUN_CABINET_CHECK` to 1 in `lindbergh.conf` to play in DX, SDX or Standard cabinet types.
You need to set `SKIP_OUTRUN_CABINET_CHECK` to 1 in `lindbergh.conf` to play in DX, SDX or Standard cabinet types.
### Ghost Squad / 2Spicy
You may have sound issues such as the game complaining that the system cannot open `/dev[/sound]/dsp`. You **must not** use the `libopenal.so.0` files that came with the game, please delete those if you've moved them into your game folder. Do the following:
```
sudo apt install pipewire-audio-client-libraries:i386
sudo cp /usr/share/doc/pipewire/examples/alsa.conf.d/99-pipewire-default.conf /etc/alsa/conf.d/
```
Then in the game folder you must create a symlink to the `libopenal.so.1` library installed on your system:
```
ln -s /usr/lib/i386-linux-gnu/libopenal.so.1 libopenal.so.0
```
## Configuration File : lindbergh.conf
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+11 -8
View File
@@ -38,25 +38,28 @@ void initWriteCmd(int fdIdx)
int initCardReader()
{
initReadCmd(0);
initReadCmd(1);
initWriteCmd(0);
initWriteCmd(1);
uint32_t gId = getConfig()->crc32;
if (gId != VIRTUA_TENNIS_3 && gId != VIRTUA_TENNIS_3_TEST && gId != VIRTUA_TENNIS_3_REVA && gId != VIRTUA_TENNIS_3_REVA_TEST &&
gId != VIRTUA_TENNIS_3_REVB && gId != VIRTUA_TENNIS_3_REVB_TEST && gId != VIRTUA_TENNIS_3_REVC &&
gId != VIRTUA_TENNIS_3_REVC_TEST && gId != R_TUNED)
{
printf("Game does not support Card Reader, please disable the card reader emulation in the config file.\n");
return -1;
printf("Warning: This Game does not support Card Reader, please disable the card reader emulation in the config file.\n");
printf(" I will disable the card reader for you.\n");
EmulatorConfig *config = getConfig();
config->emulateCardreader = 0;
return 0;
}
if (getConfig()->emulateCardreader && getConfig()->emulateDriveboard && gId != R_TUNED)
{
printf("Game does not support Card Reader and Driver Board emulation enabled at the same time.\n");
printf("Warning: This Game does not support Card Reader and Driver Board emulation enabled at the same time.\n");
printf("Please disable Drive Board emulations in the config file.\n");
return -1;
}
initReadCmd(0);
initReadCmd(1);
initWriteCmd(0);
initWriteCmd(1);
return 0;
}
+615 -603
View File
File diff suppressed because it is too large Load Diff
+3 -2
View File
@@ -2,6 +2,7 @@
#define CONFIG_H
#include <stdint.h>
#include <sys/types.h>
#define MAX_PATH_LENGTH 1024
#define INPUT_STRING_LENGTH 256
@@ -71,7 +72,6 @@
#define VIRTUA_FIGHTER_5_REVB 0x8953bd52 // DVP-0008B
#define VIRTUA_FIGHTER_5_REVE 0x4c2edbf6 // DVP-0008E
#define VIRTUA_FIGHTER_5_EXPORT 0xec474630 // DVP-0043
#define VIRTUA_FIGHTER_5_FINAL_SHOWDOWN 0x48 // DVP-5019 or does not exist
#define VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVA 0xbae2be62 // DVP-5019A
#define VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB 0x7cee1d81 // DVP-5020
#define VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB_6000 0x34c0d02 // DVP-5020 ver 6.00 (Weird public version)
@@ -279,8 +279,9 @@ typedef struct
int borderEnabled;
} EmulatorConfig;
uint32_t get_crc32(const char *s, ssize_t n);
KeyMapping getDefaultKeymap();
int initConfig();
int initConfig(const char* configFilePath);
EmulatorConfig *getConfig();
char *getGameName();
char *getDVPName();
+3 -25
View File
@@ -30,8 +30,6 @@
#include <ifaddrs.h>
#include <dirent.h>
#include "hook.h"
#include "baseboard.h"
#include "config.h"
#include "driveboard.h"
@@ -185,7 +183,9 @@ void __attribute__((constructor)) hook_init()
act.sa_flags = SA_SIGINFO;
sigaction(SIGSEGV, &act, NULL);
initConfig();
char *(*_getenv)(const char *name) = dlsym(RTLD_NEXT, "getenv");
char* envPath = _getenv("LINDBERGH_CONFIG_PATH");
initConfig(envPath);
if (getConfig()->fpsLimiter == 1)
{
@@ -1199,28 +1199,6 @@ 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 < 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.
*/
-4
View File
@@ -1,4 +0,0 @@
#include <stdint.h>
#include <stddef.h>
uint32_t get_crc32(const char *s, size_t n);
+166 -2
View File
@@ -12,6 +12,7 @@
#define LD_PRELOAD "LD_PRELOAD"
#define PRELOAD_FILE_NAME "lindbergh.so"
#define TEAM "bobbydilley, retrofan, dkeruza-neo, doozer, francesco, rolel, caviar-x"
#define LINDBERGH_CONFIG_PATH "LINDBERGH_CONFIG_PATH"
uint32_t elf_crc = 0;
@@ -39,6 +40,151 @@ char *games[] = {"main.exe",
"a.elf",
"END"};
/**
* An array containin clean games elf's CRC32
*/
uint32_t cleanElfCRC32[] = {
0x51C4D2F6, // DVP-0003A | hod4M.elf
0x1348BCA8, // DVP-0003A | hod4testM.elf
0x0AAE384E, // DVP-0003B | hod4M.elf
0x352AA797, // DVP-0003B | hod4testM.elf
0x42EED61A, // DVP-0003C | hod4M.elf
0x6DA6E511, // DVP-0003C | hod4testM.elf
0x0E4BF4B1, // DVP-0005 | vt3_Lindbergh
0x9E48AB5B, // DVP-0005 | vt3_testmode
0xE4C64D01, // DVP-0005A | vt3_Lindbergh
0x9C0E77E5, // DVP-0005A | vt3_testmode
0xA4BDB9E2, // DVP-0005B | vt3_Lindbergh
0x74E25472, // DVP-0005B | vt3_testmode
0x987AE3FF, // DVP-0005C | vt3_Lindbergh
0x1E4271A4, // DVP-0005C | vt3_testmode
0xD409B70C, // DVP-0008 | vf5
0x08EBC0DB, // DVP-0008A | vf5
0xA47FBA2D, // DVP-0008B | vf5
0x8CA46167, // DVP-0008C | vf5
0x75946796, // DVP-0008E | vf5
0x2C8F5D57, // DVP-0009 | abc
0x13D90755, // DVP-0009A | abc
0x633AD6FB, // DVP-0009B | abc
0xD39825A8, // DVP-0010 | hod4M.elf
0x0745CF0A, // DVP-0010 | hod4testM.elf
0x13E59583, // DVP-0010B | hod4M.elf
0x302FEB00, // DVP-0010B | hod4testM.elf
0x04E08C99, // DVP-0011 | lgj_final
0x0C3D3CC3, // DVP-0011A | lgj_final
0xD9660B2E, // DVP-0015 | JenTest
0x821C3404, // DVP-0015 | Jennifer
0x13AF8581, // DVP-0015A | JenTest
0xB2CE9B23, // DVP-0015A | Jennifer
0xCC32DEAE, // DVP-0018 | abc
0x17114BC1, // DVP-0018A | abc
0x22905D60, // DVP-0019A | id4.elf
0x43582D48, // DVP-0019B | id4.elf
0x2D2A18C1, // DVP-0019C | id4.elf
0x9BFD0D98, // DVP-0019D | id4.elf
0x9CF9BBCC, // DVP-0019G | id4.elf
0xFA0F6AB0, // DVP-0027A | apacheM.elf
0x9D414D18, // DVP-0029A | vsg
0xC345E213, // DVP-0030B | id4.elf
0x98E6A516, // DVP-0030C | id4.elf
0xF67365C9, // DVP-0030D | id4.elf
0x8BDD31BA, // DVP-0031 | abc
0x3DF37873, // DVP-0031A | abc
0xDD8BB792, // DVP-0036A | lgjsp_app
0xB0A96E34, // DVP-0043 | vf5
0xF99E5635, // DVP-0044 | drive.elf
0x4143F6B4, // DVP-0048A | main.exe
0x653BC83B, // DVP-0057 | a.elf
0x04D88552, // DVP-0057B | a.elf
0x089D6051, // DVP-0060 | dsr
0x317F3B90, // DVP-0063 | hodexRI.elf
0x3A5EEC69, // DVP-0063 | hodextestR.elf
0x81E02850, // DVP-0069 | ramboM.elf
0xE4F202BB, // DVP-0070A | id5.elf
0x2E6732A3, // DVP-0070F | id5.elf
0xF99A3CDB, // DVP-0075 | id5.elf
0x05647A8E, // DVP-0079 | hummer_Master.elf
0x4442EA15, // DVP-0083 | hummer_Master.elf
0x8DF6BBF9, // DVP-0084 | id5.elf
0x2AF8004E, // DVP-0084A | id5.elf
0xB95528F4, // DVP-5004 | vf5
0x012E4898, // DVP-5004D | vf5
0x74465F9F, // DVP-5004G | vf5
0x75B48E22, // DVP-5007 | chopperM.elf
0xFCB9D941, // DVP-5019A | vf5
0xAB70901C, // DVP-5020 | vf5
0x6BAA510D, // DVP-5020 | vf5 | Ver 6.000
};
int cleanElfCRC32Count = sizeof(cleanElfCRC32) / sizeof(uint32_t);
uint32_t calcCrc32(uint32_t crc, uint8_t data)
{
crc ^= data; // No shift needed; working in LSB-first order
for (int i = 0; i < 8; i++)
{
if (crc & 1)
{
crc = (crc >> 1) ^ 0xEDB88320;
}
else
{
crc = (crc >> 1);
}
}
return crc;
}
int lookupCrcTable(uint32_t crc)
{
for (int x = 0; x < cleanElfCRC32Count; x++)
{
if (cleanElfCRC32[x] == crc)
return 1;
}
return 0;
}
void isCleanElf(char *command)
{
const char *space_pos = strchr(command, ' ');
size_t length = space_pos ? (size_t)(space_pos - command) : strlen(command);
char elfName[256];
strncpy(elfName, command, length);
elfName[length] = '\0';
FILE *file = fopen(elfName, "rb");
if (!file)
{
log_error("Could not calculate the Elf CRC32.");
return;
}
uint32_t crc = 0xFFFFFFFF;
uint8_t buffer[4096];
size_t bytesRead;
while ((bytesRead = fread(buffer, 1, sizeof(buffer), file)) > 0)
{
for (size_t i = 0; i < bytesRead; i++)
{
crc = calcCrc32(crc, buffer[i]);
}
}
fclose(file);
crc = crc ^ 0xFFFFFFFF;
if (!lookupCrcTable(crc))
{
printf("\033[1;31m");
printf("Warning: The ELF you are running is not Clean and might cause unwanted behavior.\n");
printf(" Make sure you ELF and game dump are clean before reporting issues.\n");
printf("\033[0m");
}
}
/**
* Tests if the game uses a seperate elf for test mode
* and updates the command line to this elf.
@@ -119,6 +265,7 @@ void printUsage(char *argv[])
printf(" --list-controllers Lists available controllers and inputs\n");
printf(" --version Displays the version of the loader and team's names\n");
printf(" --help Displays this usage text\n");
printf(" --config | -c Specifies configuration path\n");
}
/**
@@ -248,8 +395,9 @@ int main(int argc, char *argv[])
int gdb = 0;
int forceGame = 0;
int segaboot = 0;
char extConfigPath[PATH_MAX] = {0};
char forceGamePath[128] = {0};
for (int i = 1; i < argc; i++)
{
if (strcmp(argv[i], "-t") == 0 || strcmp(argv[i], "--test") == 0)
@@ -269,7 +417,16 @@ int main(int argc, char *argv[])
gdb = 1;
continue;
}
if (strcmp(argv[i], "-c") == 0 || strcmp(argv[i], "--config") == 0)
{
if (i+1 >= argc)
{
break;
}
strncpy(extConfigPath, argv[i+1], PATH_MAX);
i += 1;
continue;
}
// Treat the argument as the game name
strcpy(forceGamePath, argv[i]);
forceGame = 1;
@@ -298,6 +455,8 @@ int main(int argc, char *argv[])
if (testMode)
testModePath(command);
isCleanElf(command);
if (gdb)
{
char temp[128];
@@ -306,6 +465,11 @@ int main(int argc, char *argv[])
strcpy(command, temp);
}
if (extConfigPath[0] != '\0')
{
setenv(LINDBERGH_CONFIG_PATH,extConfigPath,1);
}
log_info("Starting $ %s", command);
return system(command);
-1
View File
@@ -4,7 +4,6 @@
#include <stdarg.h>
#include <stdio.h>
#include <time.h>
// Structure to hold the formatted message and its size
+1571 -1568
View File
File diff suppressed because it is too large Load Diff
+681 -679
View File
File diff suppressed because it is too large Load Diff
+5 -2
View File
@@ -2,6 +2,7 @@
#include "securityboard.h"
#include "log.h"
#include "config.h"
#define SECURITY_BOARD_FRONT_PANEL 0x38
#define SECURITY_BOARD_FRONT_PANEL_NON_ROOT 0x1038
@@ -51,8 +52,10 @@ int securityBoardSetDipResolution(int width, int height)
setResolutionDips(1, 1, 0);
else if (width == 1360 && height == 768)
setResolutionDips(1, 1, 1);
else
log_warn("Resolution not compatible, using 640 x 480\n");
else {
if(getConfig()->showDebugMessages)
log_warn("Resolution not original, setting dips to 640 x 480.\n");
}
return 0;
}