mirror of
https://github.com/lindbergh-loader/lindbergh-loader.git
synced 2026-10-13 17:48:27 +03:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a5633bbf1d | ||
|
|
d72ac379ea | ||
|
|
988a9ee6e3 | ||
|
|
ea19a688cc | ||
|
|
c5fa5871d1 | ||
|
|
5be9aef4e0 |
+6
-1
@@ -1,9 +1,14 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
## [2.0.10]
|
||||
### Added
|
||||
- Config option to specify a path for the library libCg.so required for some shader compilation.
|
||||
- Improved folder patching for recompiled shaders (2Spicy, Rambo, Harly and HOD-EX).
|
||||
- Cleaned a bit of lindbergh elf.
|
||||
|
||||
## [2.0.9]
|
||||
- - lindbergh elf mostly redone to make the loader work as a stand alone mode.
|
||||
- lindbergh elf mostly redone to make the loader work as a stand alone mode (read guide.md).
|
||||
|
||||
## [2.0.8]
|
||||
### Added
|
||||
|
||||
@@ -224,3 +224,47 @@ flatpak install com.github.tchx84.Flatseal
|
||||
```
|
||||
|
||||
Then, run Flatseal and grant Lindbergh Loader access to additional directories.
|
||||
|
||||
### Stand alone mode
|
||||
|
||||
Now, you have the option to run the games without copying any files to the game's folder.
|
||||
Your system's 32 bit library folder, your current folder and the game's folder will be added to LD_LIBRARY_PATH env variable,
|
||||
so you can han the loader libs in any of those locations.
|
||||
|
||||
Passing -c option you can specify the location of the .conf file like this:
|
||||
|
||||
```
|
||||
./lindbergh -c /my/custom/folder/myconfig.conf
|
||||
```
|
||||
|
||||
## -g or --gamepath
|
||||
With this new option, you can specify the location of the game, where the game's ELF resides.
|
||||
|
||||
```
|
||||
./lindbergh -g /my/custom/folder/hod4/elf
|
||||
```
|
||||
|
||||
The loader will search for known elf files in that folder but you can also run it like this:
|
||||
|
||||
```
|
||||
./lindbergh myCustom.elf -g /my/custom/folder/hod4/elf
|
||||
```
|
||||
|
||||
The loader will load `myCustom.elf` inside the passed folder.
|
||||
|
||||
## Passing a folder containing an elf
|
||||
With this option, you pass a full path, including an ELF name like this:
|
||||
|
||||
```
|
||||
./lindbergh /my/custom/folder/hod4/elf/myCustom.elf
|
||||
```
|
||||
|
||||
The loader will load the ELF in that folder.
|
||||
|
||||
You can combine all options.
|
||||
|
||||
You can have the needed libraries in the folder where `lindbergh` resides, in the system's 32 bit lib folder or in the game's folder.
|
||||
The loader will try to find the files.
|
||||
|
||||
If by mistake, you pass both, a full path including an ELF and a path with -g option, the path passed with -g option will be omitted.
|
||||
Remember that if the path containg spaces, which is not recommended, pass the path inside double quotes or `\` before the space.
|
||||
|
||||
@@ -72,6 +72,10 @@ EMULATE_CARDREADER AUTO
|
||||
# Define the path to the eeprom.bin file
|
||||
# EEPROM_PATH eeprom.bin
|
||||
|
||||
# If set, the library libCG.so needed for 2Spicy, Harley, Rambo and HOD-Ex shader recompilation
|
||||
# will be loaded from the specifyied location. (include the name of file in the location)
|
||||
# LIBCG_PATH /my/file/location/myLibCg.so
|
||||
|
||||
# Set the GPU vendor (0 = Autodetect / 1 = NVidia / 2 = AMD / 3 = ATI(AMD-PRO) / 4 = Intel / 5 = Unknown)
|
||||
# GPU_VENDOR 0
|
||||
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
app-id: com.github.lindberghloader
|
||||
runtime: org.freedesktop.Platform
|
||||
runtime-version: &runtime-version '24.08' # Define runtime version alias
|
||||
runtime-version: &runtime-version '24.08'
|
||||
sdk: org.freedesktop.Sdk
|
||||
|
||||
# Define reusable aliases
|
||||
x-gl-versions: &gl-versions '24.08;1.4' # Define GL versions list alias
|
||||
x-gl-versions: &gl-versions '24.08;1.4'
|
||||
x-gl-merge-dirs: &gl-merge-dirs vulkan/icd.d;glvnd/egl_vendor.d;egl/egl_external_platform.d;OpenCL/vendors;lib/dri;lib/d3d;lib/gbm;vulkan/explicit_layer.d;vulkan/implicit_layer.d # Define GL merge dirs alias
|
||||
x-i386-build-options: &i386-build-options # Define 32-bit build options alias
|
||||
libdir: /app/lib32 # Default library install dir for autotools/meson etc.
|
||||
x-i386-build-options: &i386-build-options
|
||||
libdir: /app/lib32
|
||||
env:
|
||||
CC: /usr/lib/sdk/toolchain-i386/bin/i686-unknown-linux-gnu-gcc
|
||||
CXX: /usr/lib/sdk/toolchain-i386/bin/i686-unknown-linux-gnu-g++
|
||||
LD: /usr/lib/sdk/toolchain-i386/bin/i686-unknown-linux-gnu-ld
|
||||
LDFLAGS: "-L/app/lib32" # Add custom lib dir to linker search path during build
|
||||
LDFLAGS: "-L/app/lib32"
|
||||
|
||||
command: lindbergh
|
||||
|
||||
@@ -21,41 +20,33 @@ sdk-extensions:
|
||||
- org.freedesktop.Sdk.Extension.toolchain-i386
|
||||
- org.freedesktop.Sdk.Compat.i386
|
||||
|
||||
# Runtime arguments and permissions
|
||||
finish-args:
|
||||
# Environment variables needed at runtime
|
||||
- --env=LD_LIBRARY_PATH=/app/lib32:$LD_LIBRARY_PATH # Make custom 32-bit libs findable
|
||||
- --env=LD_LIBRARY_PATH=/app/lib32:$LD_LIBRARY_PATH
|
||||
- --env=LDFLAGS="-L/app/lib32"
|
||||
- --env=PATH=/app/bin:/usr/bin
|
||||
# Permissions
|
||||
- --allow=multiarch # Needed for running 32-bit code
|
||||
- --allow=multiarch
|
||||
- --share=ipc
|
||||
- --share=network
|
||||
- --socket=x11
|
||||
- --socket=wayland
|
||||
- --socket=pulseaudio
|
||||
# WARNING: --device=all grants broad hardware access. Consider using --device=dri and specific devices if possible.
|
||||
- --device=all
|
||||
# Filesystem access - adjust path as needed
|
||||
- --socket=pulseaudio
|
||||
- --filesystem=~/Games
|
||||
|
||||
# Runtime extensions automatically downloaded and installed with the app
|
||||
# Runtime extensions automatically downloaded and installed with the app (For some reason does not work)
|
||||
add-extensions:
|
||||
# 32-bit compatibility libraries from the runtime
|
||||
org.freedesktop.Platform.Compat.i386:
|
||||
directory: lib/i386-linux-gnu
|
||||
version: *runtime-version # Match the main runtime version
|
||||
# no-autodownload removed (or set to false) to ensure installation
|
||||
|
||||
version: *runtime-version
|
||||
|
||||
# 32-bit graphics driver extension
|
||||
org.freedesktop.Platform.GL32:
|
||||
directory: lib/i386-linux-gnu/GL
|
||||
versions: *gl-versions # Use defined GL versions list
|
||||
versions: *gl-versions
|
||||
subdirectories: true
|
||||
# no-autodownload removed (or set to false) to ensure installation
|
||||
autodelete: false
|
||||
add-ld-path: lib
|
||||
merge-dirs: *gl-merge-dirs # Use defined merge dirs list
|
||||
# Conditions for downloading and enabling the GL driver extension
|
||||
merge-dirs: *gl-merge-dirs
|
||||
download-if: active-gl-driver
|
||||
enable-if: active-gl-driver
|
||||
autoprune-unless: active-gl-driver
|
||||
@@ -75,12 +66,11 @@ modules:
|
||||
- name: libGLU
|
||||
buildsystem: autotools
|
||||
config-opts:
|
||||
- --host=i686-unknown-linux-gnu # Specify 32-bit target host
|
||||
- --prefix=/app # Base install prefix
|
||||
# --libdir=/app/lib32 should be handled by build-options->libdir
|
||||
- --host=i686-unknown-linux-gnu
|
||||
- --prefix=/app
|
||||
build-options:
|
||||
arch:
|
||||
x86_64: *i386-build-options # Apply 32-bit build options on 64-bit host
|
||||
x86_64: *i386-build-options
|
||||
sources:
|
||||
- type: archive
|
||||
url: https://mesa.freedesktop.org/archive/glu/glu-9.0.2.tar.xz
|
||||
@@ -91,15 +81,15 @@ modules:
|
||||
buildsystem: cmake
|
||||
config-opts:
|
||||
- -DCMAKE_BUILD_TYPE=Release
|
||||
- -DCMAKE_INSTALL_PREFIX=/app # Base install prefix
|
||||
- -DCMAKE_INSTALL_LIBDIR=/app/lib32 # Explicitly set library install dir for CMake
|
||||
- -DCMAKE_INSTALL_PREFIX=/app
|
||||
- -DCMAKE_INSTALL_LIBDIR=/app/lib32
|
||||
sources:
|
||||
- type: archive
|
||||
url: https://downloads.sourceforge.net/freeglut/freeglut-3.2.2.tar.gz
|
||||
sha256: c5944a082df0bba96b5756dddb1f75d0cd72ce27b5395c6c1dde85c2ff297a50
|
||||
build-options:
|
||||
arch:
|
||||
x86_64: *i386-build-options # Apply 32-bit build options
|
||||
x86_64: *i386-build-options
|
||||
|
||||
# Build 32-bit libFAudio (dynamic)
|
||||
- name: libFAudio-Dynamic
|
||||
@@ -107,40 +97,37 @@ modules:
|
||||
config-opts:
|
||||
- -DCMAKE_BUILD_TYPE=Release
|
||||
- -DCMAKE_INSTALL_PREFIX=/app
|
||||
- -DBUILD_SDL3=off # Assuming SDL3 integration is not needed
|
||||
- -DCMAKE_INSTALL_LIBDIR=/app/lib32 # Explicitly set library install dir
|
||||
- -DBUILD_SDL3=off
|
||||
- -DCMAKE_INSTALL_LIBDIR=/app/lib32
|
||||
build-options:
|
||||
arch:
|
||||
x86_64: *i386-build-options # Apply 32-bit build options
|
||||
x86_64: *i386-build-options
|
||||
env:
|
||||
# Specific flags needed for FAudio 32-bit build?
|
||||
CFLAGS: "-m32 -mstackrealign"
|
||||
CXXFLAGS: "-m32 -mstackrealign"
|
||||
sources:
|
||||
- type: git
|
||||
url: https://github.com/FNA-XNA/FAudio.git
|
||||
tag: "24.12" # Using a specific tag
|
||||
tag: "24.12"
|
||||
|
||||
# Build 32-bit libXmu
|
||||
- name: libxmu
|
||||
buildsystem: autotools
|
||||
config-opts:
|
||||
# --libdir=/app/lib32 should be handled by build-options->libdir
|
||||
- --prefix=/app
|
||||
- --with-shared # Ensure shared library is built
|
||||
- --with-shared
|
||||
sources:
|
||||
- type: archive
|
||||
url: https://xorg.freedesktop.org/releases/individual/lib/libXmu-1.2.1.tar.gz
|
||||
sha256: bf0902583dd1123856c11e0a5085bd3c6e9886fbbd44954464975fd7d52eb599
|
||||
build-options:
|
||||
arch:
|
||||
x86_64: *i386-build-options # Apply 32-bit build options (Standardized)
|
||||
x86_64: *i386-build-options
|
||||
|
||||
# Build 32-bit libmd
|
||||
- name: libmd
|
||||
buildsystem: autotools
|
||||
config-opts:
|
||||
# --libdir=/app/lib32 should be handled by build-options->libdir
|
||||
- --prefix=/app
|
||||
sources:
|
||||
- type: archive
|
||||
@@ -148,13 +135,12 @@ modules:
|
||||
sha256: 1bd6aa42275313af3141c7cf2e5b964e8b1fd488025caf2f971f43b00776b332
|
||||
build-options:
|
||||
arch:
|
||||
x86_64: *i386-build-options # Apply 32-bit build options
|
||||
x86_64: *i386-build-options
|
||||
|
||||
# Build 32-bit libbsd
|
||||
- name: libbsd
|
||||
buildsystem: autotools
|
||||
config-opts:
|
||||
# --libdir=/app/lib32 should be handled by build-options->libdir
|
||||
- --prefix=/app
|
||||
sources:
|
||||
- type: archive
|
||||
@@ -162,14 +148,12 @@ modules:
|
||||
sha256: b88cc9163d0c652aaf39a99991d974ddba1c3a9711db8f1b5838af2a14731014
|
||||
build-options:
|
||||
arch:
|
||||
x86_64: *i386-build-options # Apply 32-bit build options
|
||||
x86_64: *i386-build-options
|
||||
|
||||
# Build 32-bit ncurses (very old version)
|
||||
- name: ncurses
|
||||
# WARNING: ncurses 5.9 is very old. Consider updating if possible.
|
||||
buildsystem: autotools
|
||||
config-opts:
|
||||
# --libdir=/app/lib32 should be handled by build-options->libdir
|
||||
- --prefix=/app
|
||||
- --with-shared
|
||||
- --without-debug
|
||||
@@ -178,24 +162,22 @@ modules:
|
||||
url: https://ftp.gnu.org/pub/gnu/ncurses/ncurses-5.9.tar.gz
|
||||
sha256: 9046298fb440324c9d4135ecea7879ffed8546dd1b58e59430ea07a4633f563b
|
||||
- type: patch
|
||||
path: ./assets/ncurses-5.9.patch # Assuming this patch is necessary
|
||||
path: ./assets/ncurses-5.9.patch
|
||||
build-options:
|
||||
arch:
|
||||
x86_64: *i386-build-options # Apply 32-bit build options
|
||||
x86_64: *i386-build-options
|
||||
env:
|
||||
CPPFLAGS: "-P" # Often needed for ncurses builds
|
||||
CXXFLAGS: "-std=c++14" # Is C++14 really needed for ncurses build? Check this.
|
||||
CPPFLAGS: "-P"
|
||||
CXXFLAGS: "-std=c++14"
|
||||
|
||||
# Install pre-built 32-bit Nvidia Cg Toolkit (old)
|
||||
- name: nvidia-cg-toolkit
|
||||
# WARNING: Cg Toolkit is deprecated and old.
|
||||
buildsystem: simple
|
||||
build-commands:
|
||||
- install -Dm755 usr/lib/libCg.so /app/lib32/libCg.so
|
||||
- install -Dm755 usr/lib/libCgGL.so /app/lib32/libCgGL.so
|
||||
sources:
|
||||
- type: archive
|
||||
# Consider hosting this locally or finding a more reliable source if possible
|
||||
url: http://developer.download.nvidia.com/cg/Cg_3.1/Cg-3.1_April2012_x86.tgz
|
||||
sha256: cef3591e436f528852db0e8c145d3842f920e0c89bcfb219c466797cb7b18879
|
||||
|
||||
@@ -203,32 +185,27 @@ modules:
|
||||
- name: libsndio-dynamic
|
||||
buildsystem: autotools
|
||||
config-opts:
|
||||
# --libdir=/app/lib32 should be handled by build-options->libdir
|
||||
- --prefix=/app
|
||||
- --enable-dynamic # Build shared library
|
||||
# - --disable-static # Don't build static library
|
||||
- --enable-alsa # Enable ALSA backend
|
||||
- --enable-dynamic
|
||||
- --enable-alsa
|
||||
sources:
|
||||
- type: archive
|
||||
url: https://www.sndio.org/sndio-1.10.0.tar.gz
|
||||
sha256: bebd3bfd01c50c9376cf3e7814b9379bed9e17d0393b5113b7eb7a3d0d038c54
|
||||
build-options:
|
||||
arch:
|
||||
x86_64: *i386-build-options # Apply 32-bit build options
|
||||
x86_64: *i386-build-options
|
||||
|
||||
# Build 32-bit libopenal (old version)
|
||||
- name: libopenal
|
||||
# WARNING: OpenAL Soft 1.17.2 is quite old. Consider updating.
|
||||
buildsystem: cmake
|
||||
config-opts:
|
||||
- -DCMAKE_INSTALL_PREFIX=/app
|
||||
- -DCMAKE_INSTALL_LIBDIR=/app/lib32 # Explicitly set library install dir
|
||||
# Backend selection
|
||||
- -DCMAKE_INSTALL_LIBDIR=/app/lib32
|
||||
- -DALSOFT_BACKEND_PULSEAUDIO=ON
|
||||
- -DALSOFT_BACKEND_ALSA=ON
|
||||
- -DALSOFT_BACKEND_JACK=OFF
|
||||
- -DALSOFT_BACKEND_SNDIO=ON # Depends on libsndio-dynamic
|
||||
# Point to the previously built sndio library/headers
|
||||
- -DALSOFT_BACKEND_SNDIO=ON
|
||||
- -DSOUNDIO_INCLUDE_DIR=/app/include
|
||||
- -DSOUNDIO_LIBRARY=/app/lib32/libsndio.so
|
||||
sources:
|
||||
@@ -237,29 +214,20 @@ modules:
|
||||
sha256: 11ea176f6cbf9763dbce0953dd77ab72d032b4ad95f07afffb91844abb174033
|
||||
build-options:
|
||||
arch:
|
||||
x86_64: *i386-build-options # Apply 32-bit build options
|
||||
x86_64: *i386-build-options
|
||||
env:
|
||||
# Specific flags needed for OpenAL 32-bit build?
|
||||
CFLAGS: "-m32 -mstackrealign"
|
||||
CXXFLAGS: "-m32 -std=c++14 -mstackrealign" # Needs C++14?
|
||||
CXXFLAGS: "-m32 -std=c++14 -mstackrealign"
|
||||
|
||||
# Build 32-bit OpenSSL (extremely old and insecure version)
|
||||
- name: openssl
|
||||
# CRITICAL WARNING: OpenSSL 0.9.7 is extremely old, unsupported, and has known vulnerabilities.
|
||||
# This should be updated or removed if at all possible. Using it poses a security risk.
|
||||
buildsystem: simple
|
||||
build-commands:
|
||||
# Configure for 32-bit Linux (pentium target), shared libs, install to /app
|
||||
- ./Configure --prefix=/app --openssldir=/app/etc/ssl shared 386 no-asm no-krb5 linux-pentium
|
||||
# Build using the 32-bit toolchain
|
||||
# - make -j$(nproc) CC=/usr/lib/sdk/toolchain-i386/bin/i686-unknown-linux-gnu-gcc RANLIB=/usr/lib/sdk/toolchain-i386/bin/i686-unknown-linux-gnu-ranlib
|
||||
- make CC=/usr/lib/sdk/toolchain-i386/bin/i686-unknown-linux-gnu-gcc RANLIB=/usr/lib/sdk/toolchain-i386/bin/i686-unknown-linux-gnu-ranlib
|
||||
# Manually move built libraries to the target lib32 directory
|
||||
- install -d /app/lib32
|
||||
- mv libcrypto.so* /app/lib32/
|
||||
- mv libssl.so* /app/lib32/
|
||||
# Install headers (needed by other modules?) - will be cleaned later if not
|
||||
# - make install_hdrs
|
||||
sources:
|
||||
- type: archive
|
||||
url: https://github.com/openssl/openssl/archive/refs/tags/OpenSSL_0_9_7.tar.gz
|
||||
@@ -269,23 +237,16 @@ modules:
|
||||
- name: libpcsclite
|
||||
buildsystem: meson
|
||||
config-opts:
|
||||
# --libdir=/app/lib32 should be handled by build-options->libdir
|
||||
# - -Dprefix=/app
|
||||
- -Dpolkit=false # Disable polkit integration
|
||||
- -Dlibsystemd=false # Disable systemd integration
|
||||
# -Dudevrulesdir=no # Might be needed if it tries to install udev rules
|
||||
- -Dpolkit=false
|
||||
- -Dlibsystemd=false
|
||||
build-options:
|
||||
arch:
|
||||
x86_64: *i386-build-options # Apply 32-bit build options
|
||||
x86_64: *i386-build-options
|
||||
env:
|
||||
# Meson cross-compilation setup often requires explicit flags and paths
|
||||
CFLAGS: "-m32"
|
||||
CXXFLAGS: "-m32"
|
||||
LDFLAGS: "-m32 -L/app/lib32" # Ensure LDFLAGS includes -L/app/lib32
|
||||
# Point pkg-config to custom and SDK 32-bit locations
|
||||
LDFLAGS: "-m32 -L/app/lib32"
|
||||
PKG_CONFIG_PATH: "/app/lib32/pkgconfig:/usr/lib/i386-linux-gnu/pkgconfig:/usr/lib/sdk/toolchain-i386/lib/pkgconfig"
|
||||
# LD_LIBRARY_PATH might not be needed here if LDFLAGS is sufficient for linking stage
|
||||
# LD_LIBRARY_PATH: "/app/lib32:/usr/lib/i386-linux-gnu/pkgconfig:$LD_LIBRARY_PATH"
|
||||
sources:
|
||||
- type: archive
|
||||
url: https://pcsclite.apdu.fr/files/pcsc-lite-2.3.1.tar.xz
|
||||
@@ -295,59 +256,50 @@ modules:
|
||||
- name: lindbergh-loader
|
||||
buildsystem: simple
|
||||
build-commands:
|
||||
# Ensure make finds the libraries built in previous steps
|
||||
- export LD_LIBRARY_PATH=/app/lib32:$LD_LIBRARY_PATH
|
||||
- make -j$(nproc) # Build the application
|
||||
# Install application binary and required libraries/symlinks
|
||||
- make -j$(nproc)
|
||||
- mkdir -p /app/lib/i386-linux-gnu
|
||||
- mkdir -p /app/lib/i386-linux-gnu/GL
|
||||
- install -Dm755 ./build/lindbergh /app/bin/
|
||||
- install -Dm755 ./build/lindbergh.so /app/lib32/
|
||||
- install -Dm755 ./build/libsegaapi.so /app/lib32/
|
||||
- install -Dm755 ./build/libkswapapi.so /app/lib32/
|
||||
- install -Dm755 ./build/libposixtime.so /app/lib32/
|
||||
# Install bundled library? Make sure this doesn't conflict with nvidia-cg-toolkit
|
||||
- install -Dm755 ./libs/libCg.so /app/lib32/libCg2.so
|
||||
# Create necessary symlinks in the lib32 directory
|
||||
- ln -sf libposixtime.so /app/lib32/libposixtime.so.1
|
||||
- ln -sf libposixtime.so /app/lib32/libposixtime.so.2.4
|
||||
- ln -sf libopenal.so.1 /app/lib32/libopenal.so.0 # Link to correct openal versioned so
|
||||
- ln -sf libopenal.so.1 /app/lib32/libopenal.so.0
|
||||
- ln -sf libkswapapi.so /app/lib32/libGLcore.so.1
|
||||
- ln -sf libkswapapi.so /app/lib32/libnvidia-tls.so.1
|
||||
- mv /app/lib/libopenal* /app/lib32/
|
||||
build-options:
|
||||
arch:
|
||||
x86_64: *i386-build-options # Apply 32-bit build options (for env vars mainly)
|
||||
x86_64: *i386-build-options
|
||||
sources:
|
||||
- type: dir
|
||||
path: ../.. # Assumes source code is one level up from manifest directory
|
||||
path: ../..
|
||||
|
||||
# Setup dynamic linker configuration
|
||||
- name: bundle-setup
|
||||
buildsystem: simple
|
||||
build-commands:
|
||||
# Install ld.so.conf to ensure /app/lib32 is searched by the dynamic linker
|
||||
- install -Dm644 -t /app/etc ld.so.conf
|
||||
sources:
|
||||
- type: file
|
||||
path: ./assets/ld.so.conf # Assumes this file contains "/app/lib32"
|
||||
path: ./assets/ld.so.conf
|
||||
|
||||
# Cleanup unnecessary files to reduce final flatpak size
|
||||
- name: cleanup
|
||||
buildsystem: simple
|
||||
build-commands:
|
||||
# Remove static libraries and libtool archives
|
||||
- find /app/lib32 -name '*.a' -type f -delete
|
||||
- find /app/lib32 -name '*.la' -type f -delete
|
||||
# Remove any executables other than the main command
|
||||
#- find /app/bin -mindepth 1 ! -name "lindbergh" -exec rm -f {} \;
|
||||
# Remove development/debugging/documentation files
|
||||
#- rm -rf /app/lib/pkgconfig /app/lib32/pkgconfig /app/share/pkgconfig
|
||||
#- rm -rf /app/lib32/cmake /app/lib/debug /app/include /app/man /app/share /app/etc/bash_completion.d
|
||||
# Remove specific libraries if they are not needed at runtime
|
||||
# (These were in the original, assuming they are safe to remove)
|
||||
- find /app/bin -mindepth 1 ! -name "lindbergh" -exec rm -f {} \;
|
||||
- rm -rf /app/lib/pkgconfig /app/lib32/pkgconfig /app/share/pkgconfig
|
||||
- rm -rf /app/lib32/cmake /app/lib/debug /app/include /app/man /app/share /app/etc/bash_completion.d
|
||||
- rm -f /app/lib32/libmenu.so*
|
||||
- rm -f /app/lib32/libform.so*
|
||||
- rm -f /app/lib32/libpanel.so*
|
||||
- rm -f /app/lib32/libXmuu.so*
|
||||
#- rm -f /app/lib32/libbsd.so*
|
||||
# Remove ncurses terminfo db if not needed
|
||||
- rm -rf /app/lib/terminfo
|
||||
- rm -f /app/lib32/libbsd.so*
|
||||
- rm -rf /app/lib/terminfo
|
||||
|
||||
@@ -1113,6 +1113,9 @@ int readConfig(FILE *configFile, EmulatorConfig *config)
|
||||
else if (strcmp(command, "SRAM_PATH") == 0)
|
||||
strcpy(config->sramPath, getNextToken(NULL, " ", &saveptr));
|
||||
|
||||
else if (strcmp(command, "LIBCG_PATH") == 0)
|
||||
strcpy(config->libCgPath, getNextToken(NULL, " ", &saveptr));
|
||||
|
||||
else if (strcmp(command, "EMULATE_RIDEBOARD") == 0) {
|
||||
int defaultValue = config->emulateRideboard;
|
||||
config->emulateRideboard = getNextIntOrAuto(saveptr, defaultValue);
|
||||
@@ -1529,6 +1532,7 @@ int initConfig(const char* configFilePath)
|
||||
config.lindberghColour = YELLOW;
|
||||
strcpy(config.eepromPath, "eeprom.bin");
|
||||
strcpy(config.sramPath, "sram.bin");
|
||||
strcpy(config.libCgPath, "");
|
||||
strcpy(config.jvsPath, "/dev/ttyUSB0");
|
||||
strcpy(config.serial1Path, "/dev/ttyS0");
|
||||
strcpy(config.serial2Path, "/dev/ttyS1");
|
||||
|
||||
@@ -232,6 +232,7 @@ typedef struct
|
||||
int fullscreen;
|
||||
char eepromPath[MAX_PATH_LENGTH];
|
||||
char sramPath[MAX_PATH_LENGTH];
|
||||
char libCgPath[MAX_PATH_LENGTH];
|
||||
char jvsPath[MAX_PATH_LENGTH];
|
||||
char serial1Path[MAX_PATH_LENGTH];
|
||||
char serial2Path[MAX_PATH_LENGTH];
|
||||
|
||||
+284
-10
@@ -95,6 +95,12 @@ static int callback(struct dl_phdr_info *info, size_t size, void *data);
|
||||
|
||||
uint16_t basePortAddress = 0xFFFF;
|
||||
|
||||
/**
|
||||
* @brief Signal handler for SIGSEGV.
|
||||
*
|
||||
* This function handles segmentation faults (SIGSEGV) and attempts to recover
|
||||
* from certain types of memory access errors, particularly those related to I/O ports.
|
||||
*/
|
||||
/**
|
||||
* Signal handler for the SIGSEGV signal, which is triggered when a process tries to access an illegal memory location.
|
||||
* @param signal
|
||||
@@ -177,6 +183,13 @@ static void handleSegfault(int signal, siginfo_t *info, void *ptr)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Trims leading and trailing whitespace and quotes from a string.
|
||||
*
|
||||
* This function removes leading and trailing whitespace characters, as well as
|
||||
* single and double quotes, from the input string.
|
||||
* @param str The string to trim.
|
||||
*/
|
||||
char *trimOS_ID(char *str)
|
||||
{
|
||||
if (!str)
|
||||
@@ -198,6 +211,12 @@ char *trimOS_ID(char *str)
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if the operating system is Debian-based.
|
||||
*
|
||||
* This function reads the /etc/os-release file to determine if the current
|
||||
* operating system is Debian or Ubuntu, or a derivative of them.
|
||||
*/
|
||||
bool checkOS_ID()
|
||||
{
|
||||
FILE *fp = fopen("/etc/os-release", "r");
|
||||
@@ -249,6 +268,12 @@ bool checkOS_ID()
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialization function for the hook library.
|
||||
*
|
||||
* This function is called automatically when the library is loaded. It sets up
|
||||
* signal handlers, initializes configuration, and performs other setup tasks.
|
||||
*/
|
||||
void __attribute__((constructor)) hook_init()
|
||||
{
|
||||
// Get offsets of the Game's ELF and calculate CRC32.
|
||||
@@ -277,7 +302,6 @@ void __attribute__((constructor)) hook_init()
|
||||
}
|
||||
|
||||
getGPUVendor();
|
||||
|
||||
if (initPatch() != 0)
|
||||
exit(1);
|
||||
|
||||
@@ -360,6 +384,13 @@ void __attribute__((constructor)) hook_init()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hook for the opendir function.
|
||||
*
|
||||
* This function intercepts calls to opendir and redirects them to different
|
||||
* directories based on the game ID.
|
||||
* @param dirname The name of the directory to open.
|
||||
*/
|
||||
DIR *opendir(const char *dirname)
|
||||
{
|
||||
DIR *(*_opendir)(const char *dirname) = dlsym(RTLD_NEXT, "opendir");
|
||||
@@ -395,6 +426,13 @@ DIR *opendir(const char *dirname)
|
||||
return _opendir(dirname);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hook for the remove function.
|
||||
*
|
||||
* This function intercepts calls to remove and redirects them to different
|
||||
* paths based on the game ID.
|
||||
* @param path The path to remove.
|
||||
*/
|
||||
int remove(const char *path)
|
||||
{
|
||||
int (*_remove)(const char *path) = dlsym(RTLD_NEXT, "remove");
|
||||
@@ -416,6 +454,13 @@ int remove(const char *path)
|
||||
return _remove(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hook for the mkdir function.
|
||||
*
|
||||
* This function intercepts calls to mkdir and redirects them to different
|
||||
* paths based on the game ID.
|
||||
* @param path The path to create.
|
||||
*/
|
||||
int mkdir(const char *path, mode_t mode)
|
||||
{
|
||||
int (*_mkdir)(const char *path, mode_t mode) = dlsym(RTLD_NEXT, "mkdir");
|
||||
@@ -437,6 +482,13 @@ int mkdir(const char *path, mode_t mode)
|
||||
return _mkdir(path, mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hook for the __xstat64 function.
|
||||
*
|
||||
* This function intercepts calls to __xstat64 and redirects them to different
|
||||
* paths based on the game ID.
|
||||
* @param path The path to stat.
|
||||
*/
|
||||
int __xstat64(int ver, const char *path, struct stat64 *stat_buf)
|
||||
{
|
||||
int (*___xstat64)(int ver, const char *path, struct stat64 *stat_buf) = dlsym(RTLD_NEXT, "__xstat64");
|
||||
@@ -448,6 +500,13 @@ int __xstat64(int ver, const char *path, struct stat64 *stat_buf)
|
||||
return ___xstat64(ver, path, stat_buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hook for the open function.
|
||||
*
|
||||
* This function intercepts calls to open and redirects them to different
|
||||
* files or devices based on the pathname.
|
||||
* @param pathname The path to open.
|
||||
*/
|
||||
int open(const char *pathname, int flags, ...)
|
||||
{
|
||||
va_list args;
|
||||
@@ -534,6 +593,13 @@ int open(const char *pathname, int flags, ...)
|
||||
return _open(pathname, flags, mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hook for the open64 function.
|
||||
*
|
||||
* This function intercepts calls to open64 and redirects them to different
|
||||
* files or devices based on the pathname.
|
||||
* @param pathname The path to open.
|
||||
*/
|
||||
int open64(const char *pathname, int flags, ...)
|
||||
{
|
||||
va_list args;
|
||||
@@ -544,6 +610,13 @@ int open64(const char *pathname, int flags, ...)
|
||||
return open(pathname, flags, mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hook for the fopen function.
|
||||
*
|
||||
* This function intercepts calls to fopen and redirects them to different
|
||||
* files based on the pathname.
|
||||
* @param pathname The path to open.
|
||||
*/
|
||||
FILE *fopen(const char *restrict pathname, const char *restrict mode)
|
||||
{
|
||||
FILE *(*_fopen)(const char *restrict pathname, const char *restrict mode) = dlsym(RTLD_NEXT, "fopen");
|
||||
@@ -690,7 +763,6 @@ FILE *fopen(const char *restrict pathname, const char *restrict mode)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cachedShaderFilesLoaded)
|
||||
{
|
||||
void *addr = __builtin_return_address(0);
|
||||
@@ -757,6 +829,13 @@ FILE *fopen(const char *restrict pathname, const char *restrict mode)
|
||||
return _fopen(pathname, mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hook for the fopen64 function.
|
||||
*
|
||||
* This function intercepts calls to fopen64 and redirects them to different
|
||||
* files based on the pathname.
|
||||
* @param pathname The path to open.
|
||||
*/
|
||||
FILE *fopen64(const char *pathname, const char *mode)
|
||||
{
|
||||
FILE *(*_fopen64)(const char *restrict pathname, const char *restrict mode) = dlsym(RTLD_NEXT, "fopen64");
|
||||
@@ -857,6 +936,13 @@ FILE *fopen64(const char *pathname, const char *mode)
|
||||
return _fopen64(pathname, mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hook for the fclose function.
|
||||
*
|
||||
* This function intercepts calls to fclose and performs cleanup operations
|
||||
* for the file hooks.
|
||||
* @param stream The file stream to close.
|
||||
*/
|
||||
int fclose(FILE *stream)
|
||||
{
|
||||
int (*_fclose)(FILE *stream) = dlsym(RTLD_NEXT, "fclose");
|
||||
@@ -878,6 +964,14 @@ int fclose(FILE *stream)
|
||||
}
|
||||
return _fclose(stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hook for the openat function.
|
||||
*
|
||||
* This function intercepts calls to openat and redirects them to different
|
||||
* files or devices based on the pathname.
|
||||
* @param pathname The path to open.
|
||||
*/
|
||||
int openat(int dirfd, const char *pathname, int flags, ...)
|
||||
{
|
||||
int (*_openat)(int dirfd, const char *pathname, int flags) = dlsym(RTLD_NEXT, "openat");
|
||||
@@ -892,6 +986,13 @@ int openat(int dirfd, const char *pathname, int flags, ...)
|
||||
return _openat(dirfd, pathname, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hook for the close function.
|
||||
*
|
||||
* This function intercepts calls to close and performs cleanup operations
|
||||
* for the file hooks.
|
||||
* @param fd The file descriptor to close.
|
||||
*/
|
||||
int close(int fd)
|
||||
{
|
||||
int (*_close)(int fd) = dlsym(RTLD_NEXT, "close");
|
||||
@@ -908,6 +1009,13 @@ int close(int fd)
|
||||
return _close(fd);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hook for the fgets function.
|
||||
*
|
||||
* This function intercepts calls to fgets and redirects them to different
|
||||
* files based on the stream.
|
||||
* @param stream The file stream to read from.
|
||||
*/
|
||||
char *fgets(char *str, int n, FILE *stream)
|
||||
{
|
||||
char *(*_fgets)(char *str, int n, FILE *stream) = dlsym(RTLD_NEXT, "fgets");
|
||||
@@ -945,6 +1053,13 @@ char *fgets(char *str, int n, FILE *stream)
|
||||
return _fgets(str, n, stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hook for the read function.
|
||||
*
|
||||
* This function intercepts calls to read and redirects them to different
|
||||
* files or devices based on the file descriptor.
|
||||
* @param fd The file descriptor to read from.
|
||||
*/
|
||||
ssize_t read(int fd, void *buf, size_t count)
|
||||
{
|
||||
int (*_read)(int fd, void *buf, size_t count) = dlsym(RTLD_NEXT, "read");
|
||||
@@ -994,6 +1109,13 @@ ssize_t read(int fd, void *buf, size_t count)
|
||||
return _read(fd, buf, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hook for the fread function.
|
||||
*
|
||||
* This function intercepts calls to fread and redirects them to different
|
||||
* files based on the stream.
|
||||
* @param stream The file stream to read from.
|
||||
*/
|
||||
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");
|
||||
@@ -1046,6 +1168,13 @@ size_t fread(void *buf, size_t size, size_t count, FILE *stream)
|
||||
return _fread(buf, size, count, stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hook for the ftell function.
|
||||
*
|
||||
* This function intercepts calls to ftell and redirects them to different
|
||||
* files based on the stream.
|
||||
* @param stream The file stream to get the position from.
|
||||
*/
|
||||
long int ftell(FILE *stream)
|
||||
{
|
||||
long int (*_ftell)(FILE *stream) = dlsym(RTLD_NEXT, "ftell");
|
||||
@@ -1067,6 +1196,13 @@ long int ftell(FILE *stream)
|
||||
return _ftell(stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hook for the fseek function.
|
||||
*
|
||||
* This function intercepts calls to fseek and redirects them to different
|
||||
* files based on the stream.
|
||||
* @param stream The file stream to seek in.
|
||||
*/
|
||||
int fseek(FILE *stream, long int offset, int whence)
|
||||
{
|
||||
int (*_fseek)(FILE *stream, long int offset, int whence) = dlsym(RTLD_NEXT, "fseek");
|
||||
@@ -1090,6 +1226,13 @@ int fseek(FILE *stream, long int offset, int whence)
|
||||
return _fseek(stream, offset, whence);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hook for the rewind function.
|
||||
*
|
||||
* This function intercepts calls to rewind and redirects them to different
|
||||
* files based on the stream.
|
||||
* @param stream The file stream to rewind.
|
||||
*/
|
||||
void rewind(FILE *stream)
|
||||
{
|
||||
void (*_rewind)(FILE *stream) = dlsym(RTLD_NEXT, "rewind");
|
||||
@@ -1103,6 +1246,13 @@ void rewind(FILE *stream)
|
||||
_rewind(stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hook for the write function.
|
||||
*
|
||||
* This function intercepts calls to write and redirects them to different
|
||||
* files or devices based on the file descriptor.
|
||||
* @param fd The file descriptor to write to.
|
||||
*/
|
||||
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");
|
||||
@@ -1141,6 +1291,13 @@ ssize_t write(int fd, const void *buf, size_t count)
|
||||
return _write(fd, buf, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hook for the ioctl function.
|
||||
*
|
||||
* This function intercepts calls to ioctl and redirects them to different
|
||||
* devices based on the file descriptor.
|
||||
* @param fd The file descriptor to perform the ioctl on.
|
||||
*/
|
||||
int ioctl(int fd, unsigned int request, void *data)
|
||||
{
|
||||
int (*_ioctl)(int fd, int request, void *data) = dlsym(RTLD_NEXT, "ioctl");
|
||||
@@ -1170,6 +1327,13 @@ int ioctl(int fd, unsigned int request, void *data)
|
||||
return _ioctl(fd, request, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hook for the tcgetattr function.
|
||||
*
|
||||
* This function intercepts calls to tcgetattr and redirects them to different
|
||||
* devices based on the file descriptor.
|
||||
* @param fd The file descriptor to get the attributes from.
|
||||
*/
|
||||
int tcgetattr(int fd, struct termios *termios_p)
|
||||
{
|
||||
int (*_tcgetattr)(int fd, struct termios *termios_p) = dlsym(RTLD_NEXT, "tcgetattr");
|
||||
@@ -1180,6 +1344,13 @@ int tcgetattr(int fd, struct termios *termios_p)
|
||||
return _tcgetattr(fd, termios_p);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hook for the tcsetattr function.
|
||||
*
|
||||
* This function intercepts calls to tcsetattr and redirects them to different
|
||||
* devices based on the file descriptor.
|
||||
* @param fd The file descriptor to set the attributes on.
|
||||
*/
|
||||
int tcsetattr(int fd, int optional_actions, const struct termios *termios_p)
|
||||
{
|
||||
int (*_tcsetattr)(int fd, int optional_actions, const struct termios *termios_p) = dlsym(RTLD_NEXT, "tcsetattr");
|
||||
@@ -1190,6 +1361,13 @@ int tcsetattr(int fd, int optional_actions, const struct termios *termios_p)
|
||||
return _tcsetattr(fd, optional_actions, termios_p);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hook for the cfgetispeed function.
|
||||
*
|
||||
* This function intercepts calls to cfgetispeed and redirects them to different
|
||||
* devices based on the file descriptor.
|
||||
* @param termios_p The termios structure to get the input speed from.
|
||||
*/
|
||||
speed_t cfgetispeed(const struct termios *termios_p)
|
||||
{
|
||||
speed_t (*_cfgetispeed)(const struct termios *termios_p) = dlsym(RTLD_NEXT, "cfgetispeed");
|
||||
@@ -1200,6 +1378,13 @@ speed_t cfgetispeed(const struct termios *termios_p)
|
||||
return _cfgetispeed(termios_p);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hook for the cfgetospeed function.
|
||||
*
|
||||
* This function intercepts calls to cfgetospeed and redirects them to different
|
||||
* devices based on the file descriptor.
|
||||
* @param termios_p The termios structure to get the output speed from.
|
||||
*/
|
||||
speed_t cfgetospeed(const struct termios *termios_p)
|
||||
{
|
||||
speed_t (*_cfgetospeed)(const struct termios *termios_p) = dlsym(RTLD_NEXT, "cfgetospeed");
|
||||
@@ -1210,6 +1395,13 @@ speed_t cfgetospeed(const struct termios *termios_p)
|
||||
return _cfgetospeed(termios_p);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hook for the cfsetispeed function.
|
||||
*
|
||||
* This function intercepts calls to cfsetispeed and redirects them to different
|
||||
* devices based on the file descriptor.
|
||||
* @param termios_p The termios structure to set the input speed on.
|
||||
*/
|
||||
int cfsetispeed(struct termios *termios_p, speed_t speed)
|
||||
{
|
||||
int (*_cfsetispeed)(struct termios *termios_p, speed_t speed) = dlsym(RTLD_NEXT, "cfsetispeed");
|
||||
@@ -1220,6 +1412,13 @@ int cfsetispeed(struct termios *termios_p, speed_t speed)
|
||||
return _cfsetispeed(termios_p, speed);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hook for the cfsetospeed function.
|
||||
*
|
||||
* This function intercepts calls to cfsetospeed and redirects them to different
|
||||
* devices based on the file descriptor.
|
||||
* @param termios_p The termios structure to set the output speed on.
|
||||
*/
|
||||
int cfsetospeed(struct termios *termios_p, speed_t speed)
|
||||
{
|
||||
int (*_cfsetospeed)(struct termios *termios_p, speed_t speed) = dlsym(RTLD_NEXT, "cfsetospeed");
|
||||
@@ -1230,6 +1429,14 @@ int cfsetospeed(struct termios *termios_p, speed_t speed)
|
||||
return _cfsetospeed(termios_p, speed);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hook for the select function.
|
||||
*
|
||||
* This function intercepts calls to select and redirects them to different
|
||||
* devices based on the file descriptor.
|
||||
* @param nfds The highest file descriptor number plus one.
|
||||
* @param readfds The file descriptors to check for readability.
|
||||
*/
|
||||
int select(int nfds, fd_set *restrict readfds, fd_set *restrict writefds, fd_set *restrict exceptfds,
|
||||
struct timeval *restrict timeout)
|
||||
{
|
||||
@@ -1254,6 +1461,13 @@ int select(int nfds, fd_set *restrict readfds, fd_set *restrict writefds, fd_set
|
||||
return _select(nfds, readfds, writefds, exceptfds, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hook for the system function.
|
||||
*
|
||||
* This function intercepts calls to system and redirects them to different
|
||||
* commands based on the command string.
|
||||
* @param command The command to execute.
|
||||
*/
|
||||
int system(const char *command)
|
||||
{
|
||||
int (*_system)(const char *command) = dlsym(RTLD_NEXT, "system");
|
||||
@@ -1291,6 +1505,36 @@ int system(const char *command)
|
||||
return _system(command);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hook for the strncpy function.
|
||||
*
|
||||
* This function intercepts calls to strncpy and redirects them to different
|
||||
* strings based on the game ID.
|
||||
* @param dest The destination string.
|
||||
*/
|
||||
char *strncpy(char *dest, const char *src, size_t n)
|
||||
{
|
||||
char *(*_strncpy)(char *dest, const char *src, size_t n) = dlsym(RTLD_NEXT, "strncpy");
|
||||
|
||||
switch (gId)
|
||||
{
|
||||
case HARLEY_DAVIDSON:
|
||||
case RAMBO:
|
||||
case THE_HOUSE_OF_THE_DEAD_EX:
|
||||
case TOO_SPICY:
|
||||
if (getConfig()->GPUVendor != NVIDIA_GPU && (strstr(src, "../fs/compiledshader") != NULL || strstr(src, "../fs/compiled") != NULL))
|
||||
return _strncpy(dest, "../fs/compiledmesa", n);
|
||||
}
|
||||
return _strncpy(dest, src, n);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hook for the iopl function.
|
||||
*
|
||||
* This function intercepts calls to iopl and always returns 0.
|
||||
* @param level The I/O privilege level to set.
|
||||
* @return Always returns 0.
|
||||
*/
|
||||
int iopl(int level)
|
||||
{
|
||||
return 0;
|
||||
@@ -1306,10 +1550,11 @@ void kswap_collect(void *p)
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for function used by Primevil
|
||||
* @param base The number to raise to the exponent
|
||||
* @param exp The exponent to raise the number to
|
||||
* @return The result of raising the number to the exponent
|
||||
* @brief Hook for the powf function.
|
||||
*
|
||||
* This function intercepts calls to powf and redirects them to pow.
|
||||
* @param base The base number.
|
||||
* @param exponent The exponent.
|
||||
*/
|
||||
float powf(float base, float exponent)
|
||||
{
|
||||
@@ -1324,6 +1569,13 @@ int sem_wait(sem_t *sem)
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Gets the machine's IP address.
|
||||
*
|
||||
* This function retrieves the machine's IP address and stores it in the
|
||||
* provided sockaddr_in structure.
|
||||
* @param addr The sockaddr_in structure to store the IP address in.
|
||||
*/
|
||||
int get_machine_ip(struct sockaddr_in *addr)
|
||||
{
|
||||
struct ifaddrs *ifaddr, *ifa;
|
||||
@@ -1396,7 +1648,11 @@ int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function to get the offset and size of the execution program in memory of the ELF we hook to.
|
||||
* @brief Callback function for dl_iterate_phdr.
|
||||
*
|
||||
* This function is called for each program header in the loaded shared
|
||||
* objects. It is used to calculate the CRC32 of the ELF file.
|
||||
* @param info Information about the program header.
|
||||
*/
|
||||
static int callback(struct dl_phdr_info *info, size_t size, void *data)
|
||||
{
|
||||
@@ -1408,7 +1664,11 @@ static int callback(struct dl_phdr_info *info, size_t size, void *data)
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the game changing the DISPLAY environment variable
|
||||
* @brief Hook for the setenv function.
|
||||
*
|
||||
* This function intercepts calls to setenv and prevents the game from
|
||||
* changing the DISPLAY environment variable.
|
||||
* @param name The name of the environment variable.
|
||||
*/
|
||||
int setenv(const char *name, const char *value, int overwrite)
|
||||
{
|
||||
@@ -1423,7 +1683,10 @@ int setenv(const char *name, const char *value, int overwrite)
|
||||
}
|
||||
|
||||
/**
|
||||
* Fake the TEA_DIR environment variable to games that require it to run
|
||||
* @brief Hook for the getenv function.
|
||||
*
|
||||
* This function iFake the TEA_DIR environment variable to games that require it to run
|
||||
* @param name The name of the environment variable.
|
||||
*/
|
||||
char *getenv(const char *name)
|
||||
{
|
||||
@@ -1470,7 +1733,11 @@ char *getenv(const char *name)
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the game unsetting the DISPLAY environment variable
|
||||
* @brief Hook for the unsetenv function.
|
||||
*
|
||||
* This function intercepts calls to unsetenv and prevents the game from
|
||||
* unsetting the DISPLAY environment variable.
|
||||
* @param name The name of the environment variable.
|
||||
*/
|
||||
int unsetenv(const char *name)
|
||||
{
|
||||
@@ -1497,6 +1764,13 @@ char *__strdup(const char *string)
|
||||
return ___strdup(string);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hook for the localtime_r function.
|
||||
*
|
||||
* This function intercepts calls to localtime_r and redirects them to different
|
||||
* times based on the game ID.
|
||||
* @param timep The time to convert.
|
||||
*/
|
||||
struct tm *localtime_r(const time_t *timep, struct tm *result)
|
||||
{
|
||||
struct tm *(*_localtime_r)(const time_t *, struct tm *) =
|
||||
|
||||
+31
-15
@@ -19,6 +19,7 @@
|
||||
#define PRELOAD_FILE_NAME "lindbergh.so"
|
||||
#define TEAM "bobbydilley, retrofan, dkeruza-neo, doozer, francesco, rolel, caviar-x"
|
||||
#define LINDBERGH_CONFIG_PATH "LINDBERGH_CONFIG_PATH"
|
||||
#define LINDBERGH_LOADER_CURRENT_DIR "LINDBERGH_LOADER_CURRENT_DIR"
|
||||
#define MAX_PATH_LEN 1024
|
||||
|
||||
/**
|
||||
@@ -230,6 +231,19 @@ int calculateFileCRC32(const char *filename, uint32_t *crc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool hasSpaces(const char *str)
|
||||
{
|
||||
if (!str)
|
||||
return false;
|
||||
while (*str)
|
||||
{
|
||||
if (*str == ' ')
|
||||
return true;
|
||||
str++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if the ELF file is clean based on its CRC32.
|
||||
*
|
||||
@@ -237,7 +251,7 @@ int calculateFileCRC32(const char *filename, uint32_t *crc)
|
||||
* against a list of known clean ELF CRC32 values.
|
||||
* @param command The command line string containing the path to the ELF file.
|
||||
*/
|
||||
void isCleanElf(char *command)
|
||||
void checkIfElfisClean(char *command)
|
||||
{
|
||||
char *last_space = strrchr(command, ' ');
|
||||
size_t length;
|
||||
@@ -511,6 +525,7 @@ void setEnvironmentVariables(char *ldLibPath, char *curDir, char *gameDir, int z
|
||||
setenv("__GLX_VENDOR_LIBRARY_NAME", "nvidia", 1);
|
||||
setenv("__NV_PRIME_RENDER_OFFLOAD", "1", 1);
|
||||
}
|
||||
setenv("LINDBERGH_LOADER_CURRENT_DIR", curDir, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -690,6 +705,12 @@ int main(int argc, char *argv[])
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (hasSpaces(curDir))
|
||||
{
|
||||
log_warn("The current path contains spaces, this most likely will cause issues.");
|
||||
log_warn("Please, make sure you don't use spaces in the path.");
|
||||
}
|
||||
|
||||
char command[PATH_MAX] = {0};
|
||||
char *forcedGameDir;
|
||||
char *forcedGameElf;
|
||||
@@ -796,26 +817,16 @@ int main(int argc, char *argv[])
|
||||
|
||||
char *ldPreloadLibrary = findLDPreloadLibrary();
|
||||
|
||||
if (strcmp(ldPreloadLibrary, PRELOAD_FILE_NAME) == 0)
|
||||
{
|
||||
char lindberghSoPath[MAX_PATH_LEN];
|
||||
if (gameDir[0] != '\0')
|
||||
snprintf(lindberghSoPath, strlen(gameDir) + sizeof(PRELOAD_FILE_NAME) + 1, "%s/%s", gameDir, PRELOAD_FILE_NAME);
|
||||
|
||||
if (access(lindberghSoPath, F_OK) != 0)
|
||||
{
|
||||
log_error("The preload object lindbergh.so was not found.");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
ldPreloadLibrary = strdup(lindberghSoPath);
|
||||
}
|
||||
if (strcmp(curDir, gameDir) == 0)
|
||||
ldPreloadLibrary = PRELOAD_FILE_NAME;
|
||||
|
||||
// Ensure environment variables are set correctly
|
||||
setEnvironmentVariables(ldPreloadLibrary, curDir, gameDir, zink, nvidia);
|
||||
|
||||
if (testMode)
|
||||
testModePath(command);
|
||||
isCleanElf(command);
|
||||
|
||||
checkIfElfisClean(command);
|
||||
|
||||
if (gdb)
|
||||
{
|
||||
@@ -827,6 +838,11 @@ int main(int argc, char *argv[])
|
||||
|
||||
if (extConfigPath != NULL && extConfigPath[0] != '\0')
|
||||
{
|
||||
if (hasSpaces(extConfigPath))
|
||||
{
|
||||
log_warn("The config path contains spaces, this most likely will cause issues.");
|
||||
log_warn("Please, make sure you don't use spaces in the path.");
|
||||
}
|
||||
setenv(LINDBERGH_CONFIG_PATH, extConfigPath, 1);
|
||||
}
|
||||
|
||||
|
||||
+4
-11
@@ -628,11 +628,9 @@ int initPatch()
|
||||
|
||||
if (GPUVendor != NVIDIA_GPU)
|
||||
{
|
||||
cacheModedShaderFiles();
|
||||
loadLibCg();
|
||||
cacheModedShaderFiles();
|
||||
cacheNnstdshader();
|
||||
patchMemory(0x082d4437, "9090909090"); // Stop the folder rename
|
||||
patchMemory(0x088a6127, "66732f636f6d70696c65646d657361"); // Change folder to compiledshdmesa
|
||||
patchMemory(0x082646b3, "01"); // Compile using CGC
|
||||
replaceCallAtAddress(0x082d48ac, compileWithCGC);
|
||||
replaceCallAtAddress(0x082d4b3b, compileWithCGC);
|
||||
@@ -2059,12 +2057,9 @@ int initPatch()
|
||||
{
|
||||
loadLibCg();
|
||||
cacheNnstdshader();
|
||||
patchMemory(0x08200c17, "9090909090"); // Stop the folder rename
|
||||
patchMemory(0x084173e7, "66732f636f6d70696c65646d657361"); // Change folder to compiledshdmesa
|
||||
patchMemory(0x080b3d71, "01"); // Compile using CGC
|
||||
replaceCallAtAddress(0x082015bf, compileWithCGC);
|
||||
replaceCallAtAddress(0x082012c1, compileWithCGC);
|
||||
// patchMemory(0x080b3d65, "00"); // Force recompile shaders
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -2487,9 +2482,8 @@ int initPatch()
|
||||
// Mesa Patches
|
||||
if (GPUVendor != NVIDIA_GPU)
|
||||
{
|
||||
patchMemory(0x08503bfa, "6d657361"); // Rename compile folder to compmesa
|
||||
cacheModedShaderFiles();
|
||||
loadLibCg();
|
||||
cacheModedShaderFiles();
|
||||
cacheNnstdshader();
|
||||
replaceCallAtAddress(0x08370aa7, compileWithCGC);
|
||||
replaceCallAtAddress(0x08370bb6, compileWithCGC);
|
||||
@@ -2550,10 +2544,9 @@ int initPatch()
|
||||
if (GPUVendor != NVIDIA_GPU)
|
||||
{
|
||||
loadLibCg();
|
||||
cacheNnstdshader();
|
||||
patchMemory(0x081ef9d8, "01"); // Force the game to recompile the shaders using cgc
|
||||
patchMemory(0x08413f04, "646d657361"); // Changes compiledshader folder to compiledshdmesa
|
||||
cacheModedShaderFiles();
|
||||
cacheNnstdshader();
|
||||
patchMemory(0x081ef9d8, "01"); // Force the game to recompile the shaders using cgc
|
||||
replaceCallAtAddress(0x08259fe5, compileWithCGC);
|
||||
replaceCallAtAddress(0x0825a089, compileWithCGC);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef __i386__
|
||||
#define __i386__
|
||||
|
||||
#include "log.h"
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#undef __x86_64__
|
||||
@@ -22,6 +23,7 @@
|
||||
#include "../libxdiff/xdiff/xdiff.h"
|
||||
#include "config.h"
|
||||
#include "patch.h"
|
||||
#include "log.h"
|
||||
|
||||
#include "shader_work/2spicy.h"
|
||||
#include "shader_work/abc.h"
|
||||
@@ -1541,41 +1543,99 @@ int parseCgcArgs(const char *input, const char ***compilerArgs, const char **out
|
||||
return 0;
|
||||
}
|
||||
|
||||
void loadLibCg()
|
||||
char *findLibCg()
|
||||
{
|
||||
int isFlatpak = 0;
|
||||
void *handle = dlopen("./libCg.so", RTLD_NOW);
|
||||
if (!handle)
|
||||
const char *foundPath = NULL;
|
||||
FILE *libCgF = NULL;
|
||||
|
||||
char *pathsToCheck[] = {NULL, "/app/lib32/libCg2.so", "./libCg.so", NULL};
|
||||
|
||||
if (strcmp(getConfig()->libCgPath, "") != 0)
|
||||
{
|
||||
handle = dlopen("/app/lib32/libCg2.so", RTLD_NOW);
|
||||
if (!handle)
|
||||
pathsToCheck[0] = getConfig()->libCgPath;
|
||||
}
|
||||
|
||||
const char *currentDir = getenv("LINDBERGH_LOADER_CURRENT_DIR");
|
||||
if (currentDir != NULL)
|
||||
{
|
||||
size_t pathLen = strlen(currentDir) + strlen("/libCg.so") + 1;
|
||||
pathsToCheck[3] = malloc(pathLen);
|
||||
if (pathsToCheck[3] != NULL)
|
||||
{
|
||||
fprintf(stderr, "Error: Unable to load library libCg.so %s\n", dlerror());
|
||||
fprintf(stderr, "Error: libCg.so version 2.0 is needed to compile the shaders in the game's folder.\n");
|
||||
exit(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
isFlatpak = 1;
|
||||
snprintf(pathsToCheck[3], pathLen, "%s/%s", currentDir, "libCg.so");
|
||||
}
|
||||
}
|
||||
|
||||
char libCgVersion[9];
|
||||
FILE *libF;
|
||||
if (isFlatpak)
|
||||
libF = fopen("/app/lib32/libCg2.so", "r");
|
||||
else
|
||||
libF = fopen("./libCg.so", "r");
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
if (pathsToCheck[i] == NULL)
|
||||
continue;
|
||||
|
||||
fseek(libF, 0x226d84, SEEK_SET);
|
||||
fread(libCgVersion, 9, 1, libF);
|
||||
fclose(libF);
|
||||
if (access(pathsToCheck[i], F_OK) == 0)
|
||||
{
|
||||
foundPath = pathsToCheck[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundPath != pathsToCheck[3] && pathsToCheck[3] != NULL)
|
||||
{
|
||||
free(pathsToCheck[3]);
|
||||
}
|
||||
|
||||
if (foundPath == NULL)
|
||||
{
|
||||
log_error("Error: Unable to find library libCg.so\n");
|
||||
log_error("Error: libCg.so version 2.0 is needed to compile the shaders in the game's folder.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
char libCgVersion[9] = {0};
|
||||
libCgF = fopen(foundPath, "rb");
|
||||
if (libCgF == NULL)
|
||||
{
|
||||
log_error("Failed to open: %s\n", foundPath);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
fseek(libCgF, 0x226d84L, SEEK_SET);
|
||||
if (fread(libCgVersion, 1, sizeof(libCgVersion) - 1, libCgF) != sizeof(libCgVersion) - 1)
|
||||
{
|
||||
log_error("Failed to read version from: %s\n", foundPath);
|
||||
fclose(libCgF);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fclose(libCgF);
|
||||
|
||||
if (strcmp(libCgVersion, "2.0.0.12") != 0)
|
||||
{
|
||||
printf("ERROR: Wrong libCg.so, version 2.0.0.12 is needed.\n");
|
||||
exit(1);
|
||||
log_error("ERROR: Wrong libCg.so version '%s', version 2.0.0.12 is needed.\n", libCgVersion);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
char *resultPath = strdup(foundPath);
|
||||
if (resultPath == NULL)
|
||||
{
|
||||
log_error("Error allocating memory for result path");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return resultPath;
|
||||
}
|
||||
|
||||
void loadLibCg()
|
||||
{
|
||||
void *handle;
|
||||
char *libCgFilePath = findLibCg();
|
||||
|
||||
handle = dlopen(libCgFilePath, RTLD_NOW);
|
||||
if (!handle)
|
||||
{
|
||||
log_error("Error: Unable to find library libCg.so\n");
|
||||
log_error("Error: libCg.so version 2.0 is needed to compile the shaders in the game's folder.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
free(libCgFilePath);
|
||||
dlerror();
|
||||
|
||||
char *error;
|
||||
|
||||
Reference in New Issue
Block a user