diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index d2f2e97..0000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,73 +0,0 @@ -name: Build and Release Lindbergh - -on: - push: - branches: - - master - pull_request: - branches: - - master - -permissions: - contents: write - -jobs: - build-and-release: - runs-on: ubuntu-latest - - steps: - # Checkout the repository - - name: Checkout repository - uses: actions/checkout@v3 - - # Set up Docker Buildx - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - - # Build the Docker image - - name: Build Docker image - run: | - docker build --target lindbergh-build -t lindbergh-loader . - - # Extract build artifacts - - name: Extract build artifacts - run: | - docker create --name lindbergh-builder lindbergh-loader - docker cp lindbergh-builder:/output ./build - docker rm lindbergh-builder - - # Compress the build directory - - name: Compress build directory - run: tar -czvf build.tar.gz -C ./build . - - # Archive the build directory as an artifact for debugging - - name: Archive build directory - uses: actions/upload-artifact@v4 - with: - name: build-output - path: ./build - - # Create a GitHub release and capture the upload URL (only on push events) - - name: Create Release - if: github.event_name == 'push' - id: create_release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: v${{ github.run_number }} - release_name: "Build v${{ github.run_number }}" - draft: false - prerelease: false - - # Upload the compressed build artifact to the release (only on push events) - - name: Upload Release Asset - if: github.event_name == 'push' - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ./build.tar.gz - asset_name: build.tar.gz - asset_content_type: application/gzip diff --git a/.github/workflows/flatpak-build.yml b/.github/workflows/flatpak-build.yml new file mode 100644 index 0000000..e17a7f9 --- /dev/null +++ b/.github/workflows/flatpak-build.yml @@ -0,0 +1,44 @@ +name: 📦 Linux Flatpak + +on: + workflow_call: + workflow_dispatch: + +jobs: + linux-flatpak-build: + name: "Build" + + runs-on: ubuntu-latest + container: + image: ghcr.io/flathub-infra/flatpak-github-actions:kde-6.8 + options: --privileged + timeout-minutes: 60 + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + set-safe-directory: ${{ env.GITHUB_WORKSPACE }} + + # Work around container ownership issue + - name: Set Safe Directory + shell: bash + run: git config --global --add safe.directory "*" + + - name: Build Flatpak + uses: flathub-infra/flatpak-github-actions/flatpak-builder@master + with: + bundle: lindbergh-loader.flatpak + upload-artifact: false + manifest-path: scripts/flatpak/com.github.lindberghloader.yml + build-bundle: true + verbose: true + branch: stable + cache: true + restore-cache: true + cache-key: flatpak-${{ hashFiles('scripts/flatpak/*.yaml') }} + + - name: Upload Flatpak + uses: actions/upload-artifact@v4 + with: + name: "linux-flatpak" + path: "lindbergh-loader.flatpak" diff --git a/.github/workflows/linux-build.yml b/.github/workflows/linux-build.yml new file mode 100644 index 0000000..d424499 --- /dev/null +++ b/.github/workflows/linux-build.yml @@ -0,0 +1,45 @@ +name: Build and Release Lindbergh + +on: + workflow_call: + workflow_dispatch: + +permissions: + contents: write + +jobs: + build-and-release: + runs-on: ubuntu-latest + + steps: + # Checkout the repository + - name: Checkout repository + uses: actions/checkout@v3 + + # Set up Docker Buildx + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + # Build the Docker image + - name: Build Docker image + run: | + docker build --target lindbergh-build -t lindbergh-loader . + + # Extract build artifacts + - name: Extract build artifacts + run: | + docker create --name lindbergh-builder lindbergh-loader + docker cp lindbergh-builder:/output ./build + docker rm lindbergh-builder + + # Compress the build directory + - name: Compress build directory + run: tar -czvf build.tar.gz -C ./build . + + # Archive the build directory as an artifact for debugging + - name: Archive build directory + uses: actions/upload-artifact@v4 + with: + name: linux-build + path: build.tar.gz + diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..a4a01de --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,48 @@ +name: Automated Builds + +on: + workflow_dispatch: + pull_request: + paths-ignore: + - '**.md' + - '.github/ISSUE_TEMPLATE/*' + push: + branches: + - main + paths-ignore: + - '**.md' + - '.github/ISSUE_TEMPLATE/*' + +jobs: + linux-build: + name: 💻 Linux + uses: "./.github/workflows/linux-build.yml" + linux-flatpak: + name: 📦 Linux Flatpak + uses: "./.github/workflows/flatpak-build.yml" + + create-release: + name: 📤 Create Release + needs: [linux-build, linux-flatpak] + runs-on: ubuntu-22.04 + if: github.ref == 'refs/heads/main' + steps: + - name: Download Artifacts + uses: actions/download-artifact@v4 + with: + path: ./artifacts/ + + - name: Display Downloaded Artifacts + run: find ./artifacts/ + + - name: Create Preview Release + if: github.ref == 'refs/heads/main' + uses: "marvinpinto/action-automatic-releases@latest" + with: + repo_token: "${{ secrets.GITHUB_TOKEN }}" + automatic_release_tag: v${{ github.run_number }} + prerelease: false + title: "Build v${{ github.run_number }}" + files: | + ./artifacts/linux-flatpak/lindbergh-loader.flatpak + ./artifacts/linux-build/build.tar.gz diff --git a/docs/changelog b/docs/changelog index e2edcb5..279c680 100644 --- a/docs/changelog +++ b/docs/changelog @@ -2,7 +2,25 @@ All notable changes to this project will be documented in this file. -## [2.0.3] +## [2.0.4] +### Added + - Boost render res option for Rambo, LGJ, HOD4, HOD-EX, ID4/ID5, 2Spicy and Harley. + - Flatpak build as a bundle. (For installation, read the guide in docs folder.) + - Add COINS with evdev for player 2. + - Merged code that adds support for COINS with evdev. + - Makefile, lindbergh.c and shader_patches.c changes to support Flatpak. + - "--zink" option in lindbergh elf to run the games using Zink. + - "--nvidia" option in lindbergh elf to force the secondary nVidia GPU in laptops. + - Click and drag in PH touchscreen. + - Hide custom crosshair cursor in PH when not needed. + - Custom mouse cursors working with X11, GLX and Glut. + - Custom mouse cursor in Primeval Hunt TouchScreen. + - TouchScreen emulation fro Primeval Hunt + - Display a warning if the distro you are running is not based on Debian. + - Cleaned up most of the code changing Ifs to Switch and sorting Alphabetically. + - Let's go Jungle and Let's go Jungle Special resolution patches. + +## [2.0.3] 2025-02-02 ### Added - Display a warning when loading an Elf that is not clean. - Added to the lib folder, common libraries that are usually missing. diff --git a/docs/guide.md b/docs/guide.md index 3822f80..7833f0e 100644 --- a/docs/guide.md +++ b/docs/guide.md @@ -4,31 +4,67 @@ The follow list of games are supported. It is worth noting that there are multiple releases of these games, and some specific releases may not be supported. -| Game Name | Game ID | DVP | NVidia | Intel (Mesa) | AMD (Mesa) | AMD (proprietary) | -|---------------------------------|---------|----------|--------|--------------|------------|-------------------| -| 2 Spicy | SBMV | DVP-0027 | ✓ | ✓ | ✓ | ✓ | -| After Burner Climax | SBLR | DVP-0009 | ✓ | ✓ | ✓ | | -| Ghost Squad Evolution | SBNJ | DVP-0029 | ✓ | ✓ | ✓ | ✓ | -| Harley Davidson | SBRG | DVP-5007 | ✓ | ✓ | ✓ | ✓ | -| Hummer Extreme | SBST | DVP-0079 | ✓ | ✓ | ✓ | ✓ | -| Hummer | SBQN | DVP-0057 | ✓ | ✓ | ✓ | ✓ | -| Let's Go Jungle | SBLU | DVP-0011 | ✓ | ✓ | ✓ | | -| Let's Go Jungle Special | SBNR | DVP-0036 | ✓ | ✓ | ✓ | | -| Outrun 2 SP SDX | SBMB | DVP-0015 | ✓ | ✓ | ✓ | ✓ | -| R-Tuned | SBQW | DVP-0060 | ✓ | ✓ | ✓ | ✓ | -| Race TV | SBPF | DVP-0044 | ✓ | ✓ | ✓ | ✓ | -| Rambo | SBQL | DVP-0069 | ✓ | ✓ | ✓ | ✓ | -| The House of the Dead 4 | SBLC | DVP-0003 | ✓ | ✓ | ✓ | ✓ | -| The House of the Dead 4 Special | SBLS | DVP-0010 | ✓ | ✓ | ✓ | ✓ | -| The House of the Dead Ex | SBRC | DVP-0063 | ✓ | ✓ | ✓ | ✓ | -| Virtua Fighter 5 | SBLM | DVP-0008 | ✓ | ✓ | ✓ | ✓ | -| Virtua Fighter 5 R | SBQU | DVP-5004 | ✓ | ✓ | ✓ | ✓ | -| Virtua Fighter 5 FS | SBUV | DVP-5019 | ✓ | ✓ | ✓ | ✓ | -| Initial D 4 | SBNK | DVP-0030 | ✓ | ✓ | ✓ | ✓ | -| Initial D 5 | SBTS | DVP-0075 | ✓ | ✓ | ✓ | | -| Virtua Tennis 3 | SBKX | DVP-0005 | ✓ | ✓ | ✓ | ✓ | -| Primeval Hunt | SBPP | DVP-0048 | ✓ | ✓ | ✓ | ✓ | - +| Game Name | Game ID | DVP | NVidia | Intel (Mesa) | AMD (Mesa) | AMD (proprietary) | +|--------------------------------------------------|---------|-----------|--------|--------------|------------|-------------------| +| After Burner Climax | SBLR | DVP-0009 | ✓ | ✓ | ✓ | | +| After Burner Climax Rev A | SBLR | DVP-0009A | ✓ | ✓ | ✓ | | +| After Burner Climax Rev B | SBLR | DVP-0009B | ✓ | ✓ | ✓ | | +| After Burner Climax SDX | SBMN | DVP-0018 | ✓ | ✓ | ✓ | | +| After Burner Climax SDX Rev A | SBMN | DVP-0018A | ✓ | ✓ | ✓ | | +| After Burner Climax SE | SBLR | DVP-0031 | ✓ | ✓ | ✓ | | +| After Burner Climax SE Rev A | SBLR | DVP-0031A | ✓ | ✓ | ✓ | | +| Ghost Squad Evolution | SBNJ | DVP-0029 | ✓ | ✓ | ✓ | ✓ | +| Harley Davidson | SBRG | DVP-5007 | ✓ | ✓ | ✓ | ✓ | +| Hummer | SBQN | DVP-0057B | ✓ | ✓ | ✓ | ✓ | +| Hummer SDLX | SBST | DVP-0057 | ✓ | ✓ | ✓ | ✓ | +| Hummer Extreme | SBST | DVP-0079 | ✓ | ✓ | ✓ | ✓ | +| Hummer Extreme MDX | SBST | DVP-0083 | ✓ | ✓ | ✓ | ✓ | +| Initial D Arcade Stage 4 Rev A | SBML | DVP-0019A | ✓ | ✓ | ✓ | ✓ | +| Initial D Arcade Stage 4 Rev B | SBML | DVP-0019B | ✓ | ✓ | ✓ | ✓ | +| Initial D Arcade Stage 4 Rev C | SBML | DVP-0019C | ✓ | ✓ | ✓ | ✓ | +| Initial D Arcade Stage 4 Rev D | SBML | DVP-0019D | ✓ | ✓ | ✓ | ✓ | +| Initial D Arcade Stage 4 Rev G | SBML | DVP-0019G | ✓ | ✓ | ✓ | ✓ | +| Initial D Arcade Stage 4 Export Rev B | SBNK | DVP-0030B | ✓ | ✓ | ✓ | ✓ | +| Initial D Arcade Stage 4 Export Rev C | SBNK | DVP-0030C | ✓ | ✓ | ✓ | ✓ | +| Initial D Arcade Stage 4 Export Rev D | SBNK | DVP-0030D | ✓ | ✓ | ✓ | ✓ | +| Initial D 5 EXP | SBRY | DVP-0075 | ✓ | ✓ | ✓ | | +| Initial D 5 EXP 2.0 | SBTS | DVP-0084 | ✓ | ✓ | ✓ | | +| Initial D 5 EXP 2.0 Rev A | SBQN | DVP-0084A | ✓ | ✓ | ✓ | | +| Initial D Arcade Stage 5 Rev A | SBQZ | DVP-0070A | ✓ | ✓ | ✓ | | +| Initial D Arcade Stage 5 Rev F | SBQZ | DVP-0070F | ✓ | ✓ | ✓ | | +| Let's Go Jungle | SBLU | DVP-0011 | ✓ | ✓ | ✓ | | +| Let's Go Jungle! Rev A | SBLU | DVP-0011A | ✓ | ✓ | ✓ | | +| Let's Go Jungle Special | SBNR | DVP-0036 | ✓ | ✓ | ✓ | | +| SEGA Network Taisen Mahjong MJ4 | SBPN | DVP-0049G | ✓ | ✓ | ✓ | ✓ | +| SEGA Network Taisen Mahjong MJ4 Evolution | SBTA | DVP-0081 | ✓ | ✓ | ✓ | ✓ | +| Outrun 2 SP SDX | SBMB | DVP-0015 | ✓ | ✓ | ✓ | ✓ | +| Outrun 2 SP SDX Rev A | SBMB | DVP-0015A | ✓ | ✓ | ✓ | ✓ | +| Primeval Hunt | SBPP | DVP-0048 | ✓ | ✓ | ✓ | ✓ | +| Rambo | SBQL | DVP-0069 | ✓ | ✓ | ✓ | ✓ | +| R-Tuned | SBQW | DVP-0060 | ✓ | ✓ | ✓ | ✓ | +| Sega Race TV | SBPF | DVP-0044 | ✓ | ✓ | ✓ | ✓ | +| The House of the Dead 4 Rev A | SBLC | DVP-0003A | ✓ | ✓ | ✓ | ✓ | +| The House of the Dead 4 Rev B | SBLC | DVP-0003B | ✓ | ✓ | ✓ | ✓ | +| The House of the Dead 4 Rev C | SBLC | DVP-0003C | ✓ | ✓ | ✓ | ✓ | +| The House of the Dead 4 Special | SBLS | DVP-0010 | ✓ | ✓ | ✓ | ✓ | +| The House of the Dead 4 Special Rev B | SBLS | DVP-0010B | ✓ | ✓ | ✓ | ✓ | +| The House of the Dead Ex | SBRC | DVP-0063 | ✓ | ✓ | ✓ | ✓ | +| Too Spicy | SBMV | DVP-0027 | ✓ | ✓ | ✓ | ✓ | +| Virtua Fighter 5 | SBLM | DVP-0008 | ✓ | ✓ | ✓ | ✓ | +| Virtua Fighter 5 Rev A | SBLM | DVP-0008A | ✓ | ✓ | ✓ | ✓ | +| Virtua Fighter 5 Rev B | SBLM | DVP-0008B | ✓ | ✓ | ✓ | ✓ | +| Virtua Fighter 5 Rev E (Public Version C) | SBLM | DVP-0008E | ✓ | ✓ | ✓ | ✓ | +| Virtua Fighter 5 Export | SBLM | DVP-0043 | ✓ | ✓ | ✓ | ✓ | +| Virtua Fighter 5 Final Showdown REV A | SBUV | DVP-5019 | ✓ | ✓ | ✓ | ✓ | +| Virtua Fighter 5 Final Showdown REV B | SBXX | DVP-5020 | ✓ | ✓ | ✓ | ✓ | +| Virtua Fighter 5 Final Showdown REV B ver 6.0000 | SBXX | DVP-5020 | ✓ | ✓ | ✓ | ✓ | +| Virtua Fighter 5 R | SBQU | DVP-5004 | ✓ | ✓ | ✓ | ✓ | +| Virtua Fighter 5 R Rev D | SBQU | DVP-5004D | ✓ | ✓ | ✓ | ✓ | +| Virtua Fighter 5 R Rev G | SBQU | DVP-5004G | ✓ | ✓ | ✓ | ✓ | +| Virtua Tennis 3 | SBKX | DVP-0005 | ✓ | ✓ | ✓ | ✓ | +| Virtua Tennis 3 Rev A | SBKX | DVP-0005A | ✓ | ✓ | ✓ | ✓ | +| Virtua Tennis 3 Rev B | SBKX | DVP-0005B | ✓ | ✓ | ✓ | ✓ | +| Virtua Tennis 3 Rev C | SBKX | DVP-0005C | ✓ | ✓ | ✓ | ✓ | ## Game Issues & Fixes @@ -48,26 +84,11 @@ 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. - -### 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 -``` +- You need to set `SKIP_OUTRUN_CABINET_CHECK` to 1 in `lindbergh.conf` to play in DX, SDX or Standard cabinet types. ## Configuration File : lindbergh.conf @@ -135,3 +156,67 @@ Will cause input on analogue input 1 to be clamped as follows: There are currently no audio options that you can set. If you have a stereo sound card installed then the audio will be downmixed to stereo. If you have a 5.1 sound card installed and the game supports surround sound, each surround channel should be passed through properly and should play sound as it was originally intended. + +## Installing and Running the Flatpak + +### Prerequisites + +Before installing the main package, ensure that Flatpak is set up on your system. If Flatpak is not installed, follow the official [Flatpak setup guide](https://flatpak.org/setup/). + +### Installation + +Once downloaded, install Lindbergh Loader by running the following command in your terminal: + +``` +flatpak install lindbergh-loader-dev.flatpak +``` + +Additionally, install the required dependencies: + +``` +flatpak install org.freedesktop.Platform.Compat.i386//24.08 +flatpak install org.freedesktop.Platform.GL32.default//24.08 +``` +Intel GPU Users (VAAPI Support): + +``` +flatpak install org.freedesktop.Platform.VAAPI.Intel.i386//24.08 +``` + +NVIDIA GPU Users (Driver Support): + +If your system uses an NVIDIA GPU, you need to install the matching NVIDIA driver package for your system. +To check your NVIDIA driver version, run: + +``` +nvidia-smi +``` +Then, install the corresponding Flatpak package, replacing 570-86-16 with your actual driver version: + +``` +flatpak install org.freedesktop.Platform.GL32.nvidia-570-86-16 +``` + +### Running Lindbergh Loader + +Once installed, launch the application with: + +``` +flatpak run com.github.lindberghloader.dev +``` + +### Managing Game Locations + +By default, games should be added to: + +``` +~/Games +``` + +If you need to add more locations, install Flatseal: + +``` +flatpak install com.github.tchx84.Flatseal +``` + +Then, run Flatseal and grant Lindbergh Loader access to additional directories. diff --git a/docs/lindbergh.conf b/docs/lindbergh.conf index 9a4a712..d9e124b 100644 --- a/docs/lindbergh.conf +++ b/docs/lindbergh.conf @@ -1,5 +1,5 @@ # SEGA Lindbergh Emulator Configuration File -# By the Lindbergh Development Team +# By the Lindbergh Development Team 2024-2025 # Set the requested dip switch width here WIDTH AUTO @@ -7,28 +7,31 @@ WIDTH AUTO # Set the requested dip switch height here HEIGHT AUTO +# Boost render resolution in HOD4/2Spicy/Harley/Rambo/HOD-EX/ID4/ID5 and LGJ +# BOOST_RENDER_RES 1 + # Set if the emulator should go full screen -FULLSCREEN 0 +# FULLSCREEN 0 # Sets the Input Mode # Mode 0: will use both SDL/X11 and EVDEV inputs (default) # Mode 1: will use SDL/X11 inputs only # Mode 2: will use EVDEV raw inputs only, which should be configured at the bottom of the settings file -INPUT_MODE 0 +# INPUT_MODE 0 # Set to 1 if you want to disable SDL (Fixes SRTV boost bar) -NO_SDL 0 +# NO_SDL 0 # Set the Region ( JP/US/EX ) -REGION EX +# REGION EX # Set if you want the game to be Free Play -FREEPLAY 1 +# FREEPLAY 1 # 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 JVS_PATH if it has been defined. -EMULATE_JVS 1 +# 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 one of the serial ports @@ -41,8 +44,12 @@ EMULATE_DRIVEBOARD AUTO # 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 one of the serial ports EMULATE_MOTIONBOARD AUTO + # Set if the loader should emulate the card reader in Virtua Tenis 3 -# EMULATE_CARDREADER 1 +EMULATE_CARDREADER AUTO + +# Set to 1 if the loader should emulate the touchscreen with the mouse in PH. +# EMULATE_TOUCHSCREEN 1 # Card File for reader 1 # CARDFILE_01 Card_01.crd @@ -51,7 +58,7 @@ EMULATE_MOTIONBOARD AUTO # CARDFILE_02 Card_02.crd # Define the path to pass the JVS packets to if JVS is not being emulated. -JVS_PATH /dev/ttyUSB0 +# JVS_PATH /dev/ttyUSB0 # Define the path to pass the first serial port to if it's not being emulated. # SERIAL_1_PATH /dev/ttyUSB0 @@ -60,47 +67,47 @@ JVS_PATH /dev/ttyUSB0 # SERIAL_2_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 the GPU vendor (0 = Autodetect / 1 = NVidia / 2 = AMD / 3 = ATI(AMD-PRO) / 4 = Intel / 5 = Unknown) -GPU_VENDOR 0 +# GPU_VENDOR 0 # Set if you want to see debug messages in the console -DEBUG_MSGS 0 +# DEBUG_MSGS 0 # Set if you'd like to add a border for optical light gun tracking -BORDER_ENABLED 0 +# BORDER_ENABLED 0 # Set the thickness of the white border as a percentage of the width of the screen -WHITE_BORDER_PERCENTAGE 2 +# WHITE_BORDER_PERCENTAGE 2 # Set the thickness of the black border which sits around the # white border as a percentage of the width of the screen -BLACK_BORDER_PERCENTAGE 0 +# BLACK_BORDER_PERCENTAGE 0 # Set to true if you experience flickering in hummer -HUMMER_FLICKER_FIX 0 +# HUMMER_FLICKER_FIX 0 # Set to keep the aspect ratio (4:3) in games like Sega Race TV and Primeval Hunt -KEEP_ASPECT_RATIO 0 +# KEEP_ASPECT_RATIO 0 # Set to 0 if you want to disable the Glare effect in OutRun -OUTRUN_LENS_GLARE_ENABLED 1 +# OUTRUN_LENS_GLARE_ENABLED 1 # Set to 1 to bypass cabinet checks including drive board and tower in Outrun 2 SP SDX -SKIP_OUTRUN_CABINET_CHECK 0 +# SKIP_OUTRUN_CABINET_CHECK 0 # Set to 1 if you want to limit the FPS in games that are not limited like OutRun2 -FPS_LIMITER_ENABLED 0 +# FPS_LIMITER_ENABLED 0 # Set the target FPS (will only work if FPS_LIMITER_ENABLED = 1) -FPS_TARGET 60 +# FPS_TARGET 60 # Set to 1 if you want to render LGJ using the mesa patches instead of nVidia (fixes some glitches) -LGJ_RENDER_WITH_MESA 1 +# LGJ_RENDER_WITH_MESA 1 # Set the Primeval Hunt mode # Mode 0: Default (Side by Side) @@ -108,37 +115,48 @@ LGJ_RENDER_WITH_MESA 1 # Mode 2: Side by Side # Mode 3: 3ds mode 1 (Touch screen to the right) # Mode 4: 3ds mode 2 (Touch screen to the bottom) -PRIMEVAL_HUNT_MODE 1 +# PRIMEVAL_HUNT_MODE 1 # Disble to use the original fonts instead of the built in font in the loader -DISABLE_BUILTIN_FONT 0 +# DISABLE_BUILTIN_FONT 0 # Disble to use the original logos instead of the built in logos in the loader -DISABLE_BUILTIN_LOGOS 0 +# DISABLE_BUILTIN_LOGOS 0 # Set to 0 to enable the mouse pointer/Cursor -HIDE_CURSOR 1 +# HIDE_CURSOR 1 # Set the custom mouse pointer from a PNG file (Usefull for shooting games) # CUSTOM_CURSOR myCustomCursor.png # Set the width of the custom cursor -CUSTOM_CURSOR_WIDTH 32 +# CUSTOM_CURSOR_WIDTH 32 # Set the height of the custom cursor -CUSTOM_CURSOR_HEIGHT 32 +# CUSTOM_CURSOR_HEIGHT 32 + +# Set a custom cursor for the touch screen in Primeval Hunt +# PH_TOUCH_CURSOR myCustomHandCursor.png + +# Set the width of the custom cursor +# PH_TOUCH_CURSOR_WIDTH 32 + +# Set the height of the custom cursor +# PH_TOUCH_CURSOR_HEIGHT 32 # Hacky way to make MJ4 work at prohibited times? # MJ4_ENABLED_ALL_THE_TIME 1 # Sets the IP address in the eeprom for Outrun link (you have to put your NIC ip) # OR2_IP 192.168.1.2 +# OR2_NETMASK 255.255.255.0 + # House of the dead 4 speed fix set the frequency of your CPU in Ghz (The speed reported by the manufacturer) # CPU_FREQ_GHZ 4.0 # Set the colour of the lindbergh to change the Segaboot logo # Possible colours are: YELLOW, RED, BLUE, SILVER, REDEX -LINDBERGH_COLOUR YELLOW +# LINDBERGH_COLOUR YELLOW # X11 MODE (Input Mode 1) # To find the value pairs for these run `xev` on linux diff --git a/scripts/flatpak/.gitignore b/scripts/flatpak/.gitignore new file mode 100644 index 0000000..60b1a16 --- /dev/null +++ b/scripts/flatpak/.gitignore @@ -0,0 +1,4 @@ +.flatpak-builder/ +build/ +repo/ +*.flatpak diff --git a/scripts/flatpak/assets/ld.so.conf b/scripts/flatpak/assets/ld.so.conf new file mode 100644 index 0000000..46a5635 --- /dev/null +++ b/scripts/flatpak/assets/ld.so.conf @@ -0,0 +1,4 @@ +# We just make any GL32 extension have higher priority +include /run/flatpak/ld.so.conf.d/app-*-org.freedesktop.Platform.GL32.*.conf +/app/lib32 +/app/lib/i386-linux-gnu \ No newline at end of file diff --git a/scripts/flatpak/assets/libstdc++.so.5 b/scripts/flatpak/assets/libstdc++.so.5 new file mode 100644 index 0000000..e733843 Binary files /dev/null and b/scripts/flatpak/assets/libstdc++.so.5 differ diff --git a/scripts/flatpak/assets/ncurses-5.9.patch b/scripts/flatpak/assets/ncurses-5.9.patch new file mode 100644 index 0000000..7a2f8a5 --- /dev/null +++ b/scripts/flatpak/assets/ncurses-5.9.patch @@ -0,0 +1,36 @@ +diff --color -ruN ncurses-5.9.orig/c++/cursesf.h ncurses-5.9/c++/cursesf.h +--- ncurses-5.9.orig/c++/cursesf.h 2005-08-13 20:08:24.000000000 +0200 ++++ ncurses-5.9/c++/cursesf.h 2025-02-21 14:45:57.002814632 +0100 +@@ -703,7 +703,7 @@ + virtual ~NCursesUserForm() { + }; + +- inline T* UserData (void) const { ++ inline T* UserData (void) { + return reinterpret_cast(get_user ()); + }; + +diff --color -ruN ncurses-5.9.orig/c++/cursesm.h ncurses-5.9/c++/cursesm.h +--- ncurses-5.9.orig/c++/cursesm.h 2005-08-13 20:10:36.000000000 +0200 ++++ ncurses-5.9/c++/cursesm.h 2025-02-21 14:47:21.238076003 +0100 +@@ -659,7 +659,7 @@ + virtual ~NCursesUserMenu() { + }; + +- inline T* UserData (void) const { ++ inline T* UserData (void) { + return reinterpret_cast(get_user ()); + }; + +diff --color -ruN ncurses-5.9.orig/c++/cursesp.h ncurses-5.9/c++/cursesp.h +--- ncurses-5.9.orig/c++/cursesp.h 2008-08-16 19:20:23.000000000 +0200 ++++ ncurses-5.9/c++/cursesp.h 2025-02-21 14:45:19.718735744 +0100 +@@ -251,7 +251,7 @@ + + virtual ~NCursesUserPanel() {}; + +- T* UserData (void) const ++ T* UserData (void) + { + return reinterpret_cast(get_user ()); + }; diff --git a/scripts/flatpak/com.github.lindberghloader.yml b/scripts/flatpak/com.github.lindberghloader.yml new file mode 100644 index 0000000..64b6f49 --- /dev/null +++ b/scripts/flatpak/com.github.lindberghloader.yml @@ -0,0 +1,323 @@ +app-id: com.github.lindberghloader +runtime: org.freedesktop.Platform +runtime-version: &runtime-version '24.08' +x-gl-version: &gl-version '1.4' +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 +sdk: org.freedesktop.Sdk +command: lindbergh + +sdk-extensions: + - org.freedesktop.Sdk.Extension.toolchain-i386 + - org.freedesktop.Sdk.Compat.i386 + +x-arch-build-options: + i386: &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" + +finish-args: + - --env=LD_LIBRARY_PATH=/app/lib32:$LD_LIBRARY_PATH + - --env=LDFLAGS="-L/app/lib32" + - --env=PATH=/app/bin:/usr/bin + - --allow=multiarch + - --share=ipc + - --share=network + - --socket=x11 + - --socket=wayland + - --device=all + - --socket=pulseaudio + - --filesystem=~/Games + +add-extensions: + org.freedesktop.Platform.Compat.i386: + directory: lib/i386-linux-gnu + version: *runtime-version + no-autodownload: true + + org.freedesktop.Platform.Compat.i386.Debug: + directory: lib/debug/lib/i386-linux-gnu + version: *runtime-version + no-autodownload: true + + org.freedesktop.Platform.GL32: + directory: lib/i386-linux-gnu/GL + version: *gl-version + versions: *gl-versions + subdirectories: true + no-autodownload: true + autodelete: false + add-ld-path: lib + merge-dirs: *gl-merge-dirs + download-if: active-gl-driver + enable-if: active-gl-driver + autoprune-unless: active-gl-driver + + org.freedesktop.Platform.GL32.Debug: + directory: lib/debug/lib/i386-linux-gnu/GL + version: *gl-version + versions: *gl-versions + subdirectories: true + no-autodownload: true + merge-dirs: *gl-merge-dirs + enable-if: active-gl-driver + autoprune-unless: active-gl-driver + +modules: + - name: libstdcxx5 + buildsystem: simple + build-commands: + - mkdir -p /app/lib32 + - install -Dm644 libstdc++.so.5 /app/lib32/libstdc++.so.5 + sources: + - type: file + path: ./assets/libstdc++.so.5 + + - name: libGLU + buildsystem: autotools + config-opts: + - --host=i686-unknown-linux-gnu + - --prefix=/app + build-options: + arch: + x86_64: *i386-build-options + sources: + - type: archive + url: https://mesa.freedesktop.org/archive/glu/glu-9.0.2.tar.xz + sha256: 6e7280ff585c6a1d9dfcdf2fca489251634b3377bfc33c29e4002466a38d02d4 + + - name: freeglut + buildsystem: cmake + config-opts: + - -DCMAKE_BUILD_TYPE=Release + - -DCMAKE_INSTALL_PREFIX=/app + 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 + + - name: libFAudio-Dynamic + buildsystem: cmake-ninja + config-opts: + - -DCMAKE_BUILD_TYPE=Release + - -DCMAKE_INSTALL_PREFIX=/app + - -DBUILD_SDL3=off + - -DCMAKE_INSTALL_LIBDIR=/app/lib32 + build-options: + arch: + x86_64: *i386-build-options + env: + CFLAGS: "-m32 -mstackrealign" + CXXFLAGS: "-m32 -mstackrealign" + sources: + - type: git + url: https://github.com/FNA-XNA/FAudio.git + tag: "24.12" + + - name: libxmu + buildsystem: autotools + config-opts: + - --libdir=/app/lib32 + - --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 + 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 + libdir: /app/lib32 + + - name: libmd + buildsystem: autotools + config-opts: + - --libdir=/app/lib32 + sources: + - type: archive + url: https://archive.hadrons.org/software/libmd/libmd-1.1.0.tar.xz + sha256: 1bd6aa42275313af3141c7cf2e5b964e8b1fd488025caf2f971f43b00776b332 + build-options: + arch: + x86_64: *i386-build-options + + - name: libbsd + buildsystem: autotools + config-opts: + - --libdir=/app/lib32 + sources: + - type: archive + url: https://libbsd.freedesktop.org/releases/libbsd-0.12.2.tar.xz + sha256: b88cc9163d0c652aaf39a99991d974ddba1c3a9711db8f1b5838af2a14731014 + build-options: + arch: + x86_64: *i386-build-options + + - name: ncurses + buildsystem: autotools + config-opts: + - --libdir=/app/lib32 + - --with-shared + - --without-debug + sources: + - type: archive + url: https://ftp.gnu.org/pub/gnu/ncurses/ncurses-5.9.tar.gz + sha256: 9046298fb440324c9d4135ecea7879ffed8546dd1b58e59430ea07a4633f563b + - type: patch + path: ./assets/ncurses-5.9.patch + build-options: + arch: + x86_64: *i386-build-options + env: + CPPFLAGS: "-P" + CXXFLAGS: "-std=c++14" + + - name: nvidia-cg-toolkit + 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 + url: http://developer.download.nvidia.com/cg/Cg_3.1/Cg-3.1_April2012_x86.tgz + sha256: cef3591e436f528852db0e8c145d3842f920e0c89bcfb219c466797cb7b18879 + + - name: libsndio-dynamic + buildsystem: autotools + config-opts: + - --libdir=/app/lib32 + - --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 + + - name: libsndio-static + buildsystem: autotools + config-opts: + - --libdir=/app/lib32 + - --enable-static + - --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 + + - name: libopenal + buildsystem: cmake + config-opts: + - -DCMAKE_INSTALL_LIBDIR=/app/lib32 + - -DALSOFT_BACKEND_PULSEAUDIO=ON + - -DALSOFT_BACKEND_ALSA=ON + - -DALSOFT_BACKEND_JACK=OFF + - -DALSOFT_BACKEND_SNDIO=ON + - -DSOUNDIO_INCLUDE_DIR=/app/include + - -DSOUNDIO_LIBRARY=/app/lib32/libsndio.so + sources: + - type: archive + url: https://github.com/kcat/openal-soft/archive/refs/tags/openal-soft-1.17.2.tar.gz + sha256: 11ea176f6cbf9763dbce0953dd77ab72d032b4ad95f07afffb91844abb174033 + build-options: + arch: + x86_64: *i386-build-options + env: + CFLAGS: "-m32 -mstackrealign" + CXXFLAGS: "-m32 -std=c++14 -mstackrealign" + + - name: openssl + buildsystem: simple + build-commands: + - ./Configure --prefix=/app --openssldir=/app/etc/ssl shared 386 no-asm no-krb5 linux-pentium + - 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 + - mv libcrypto.* /app/lib32 + - mv libssl.* /app/lib32 + sources: + - type: archive + url: https://github.com/openssl/openssl/archive/refs/tags/OpenSSL_0_9_7.tar.gz + sha256: 14e3a90f75994689e8c1bef098a97021f225a1a1623a7b8012079bd8b2eca1e8 + + - name: libpcsclite + buildsystem: meson + config-opts: + - --libdir=/app/lib32 + - -Dpolkit=false + - -Dlibsystemd=false + build-options: + arch: + x86_64: *i386-build-options + env: + CFLAGS: "-m32" + CXXFLAGS: "-m32" + LDFLAGS: "-m32" + PKG_CONFIG_PATH: "/app/lib32/pkgconfig:/usr/lib/i386-linux-gnu/pkgconfig" + 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 + sha256: a641d44d57affe1edd8365dd75307afc307e7eefb4e7ad839f6f146baa41ed56 + + - name: lindbergh-loader + buildsystem: simple + build-commands: + - export LD_LIBRARY_PATH=/app/lib32:$LD_LIBRARY_PATH + - make + - mkdir -p /app/bin + - 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 -Dm755 ./libs/libCg.so /app/lib32/libCg2.so + - ln -s -f libposixtime.so /app/lib32/libposixtime.so.1 + - ln -s -f libposixtime.so /app/lib32/libposixtime.so.2.4 + - ln -s -f libopenal.so /app/lib32/libopenal.so.0 + - ln -s -f libkswapapi.so /app/lib32/libGLcore.so.1 + - ln -s -f libkswapapi.so /app/lib32/libnvidia-tls.so.1 + - mv /app/lib/libopenal* /app/lib32/ + build-options: + arch: + x86_64: *i386-build-options + sources: + - type: dir + path: ../.. + + - name: bundle-setup + buildsystem: simple + build-commands: + - install -Dm644 -t /app/etc ld.so.conf + sources: + - type: file + path: ./assets/ld.so.conf + + - name: cleanup + buildsystem: simple + build-commands: + - find /app/lib /app/lib32 -name '*.a' -type f -delete + - find /app/lib /app/lib32 -name '*.la' -type f -delete + - find /app/bin -mindepth 1 ! -name "lindbergh*" -exec rm -f {} \; + - rm -d /app/lib/terminfo + - rm -rf /app/lib/pkgconfig /app/lib32/pkgconfig /app/share/pkgconfig /app/lib32/cmake /app/lib/debug /app/include /app/man /app/share + - rm /app/lib32/libmenu.* + - rm /app/lib32/libform.* + - rm /app/lib32/libpanel.* + - rm /app/lib32/libXmuu.* + - rm /app/lib32/libbsd.so diff --git a/src/lindbergh/card_reader.c b/src/lindbergh/card_reader.c index cfa054b..ba83c47 100644 --- a/src/lindbergh/card_reader.c +++ b/src/lindbergh/card_reader.c @@ -1,7 +1,6 @@ #include #include #include -#include #include #include #include @@ -11,6 +10,8 @@ #define BLOCKSIZE 8 +extern uint32_t gId; + uint8_t cardHeader[] = {0x08, 0x00, 0x00, 0x00, 0x81, 0x00, 0x59, 0xda, 0x00, 0x00, 0x54, 0x4d, 0x50, 0x06, 0x03, 0x23, 0x10, 0x41, 0x62, 0xad, 0x00, 0x2b, 0x0b, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0x71, 0x52, 0x70, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfd, 0xd2}; @@ -38,17 +39,27 @@ void initWriteCmd(int fdIdx) int initCardReader() { - 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) + EmulatorConfig *config = getConfig(); + + switch (gId) { - 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(); + case R_TUNED: + case VIRTUA_TENNIS_3: + case VIRTUA_TENNIS_3_TEST: + case VIRTUA_TENNIS_3_REVA: + case VIRTUA_TENNIS_3_REVA_TEST: + case VIRTUA_TENNIS_3_REVB: + case VIRTUA_TENNIS_3_REVB_TEST: + case VIRTUA_TENNIS_3_REVC: + case VIRTUA_TENNIS_3_REVC_TEST: + // Code for supported games + break; + default: + printf("Warning: This Game does not support Card Reader, I will disable the card reader for you.\n"); config->emulateCardreader = 0; return 0; } + if (getConfig()->emulateCardreader && getConfig()->emulateDriveboard && gId != R_TUNED) { printf("Warning: This Game does not support Card Reader and Driver Board emulation enabled at the same time.\n"); diff --git a/src/lindbergh/config.c b/src/lindbergh/config.c index 2bae715..1ae5b8c 100644 --- a/src/lindbergh/config.c +++ b/src/lindbergh/config.c @@ -619,6 +619,7 @@ static int detectGame(uint32_t elf_crc) config.gameReleaseYear = "2008"; config.gameNativeResolutions = "640x480"; config.emulateDriveboard = 1; + config.emulateCardreader = 1; config.gameStatus = WORKING; config.gameType = DRIVING; config.width = 640; @@ -947,6 +948,7 @@ static int detectGame(uint32_t elf_crc) config.gameID = "SBKX"; config.gameReleaseYear = "2006"; config.gameNativeResolutions = "640x480, 1360x768"; + config.emulateCardreader = 1; config.gameStatus = WORKING; config.width = 1360; config.height = 768; @@ -962,6 +964,7 @@ static int detectGame(uint32_t elf_crc) config.gameID = "SBKX"; config.gameReleaseYear = "2006"; config.gameNativeResolutions = "640x480, 1360x768"; + config.emulateCardreader = 1; config.gameType = FIGHTING; config.gameStatus = WORKING; config.width = 1360; @@ -978,6 +981,7 @@ static int detectGame(uint32_t elf_crc) config.gameID = "SBKX"; config.gameReleaseYear = "2006"; config.gameNativeResolutions = "640x480, 1360x768"; + config.emulateCardreader = 1; config.gameType = FIGHTING; config.gameStatus = WORKING; config.width = 1360; @@ -994,6 +998,7 @@ static int detectGame(uint32_t elf_crc) config.gameID = "SBKX"; config.gameReleaseYear = "2006"; config.gameNativeResolutions = "640x480, 1360x768"; + config.emulateCardreader = 1; config.gameType = FIGHTING; config.gameStatus = WORKING; config.width = 1360; @@ -1069,7 +1074,7 @@ int getNextIntOrAuto(char *saveptr, int defaultValue) { strcpy(nextToken, getNextToken(NULL, " ", &saveptr)); toLowerCase(nextToken); - if(strcmp(nextToken, "auto") == 0) + if (strcmp(nextToken, "auto") == 0) return defaultValue; return atoi(nextToken); @@ -1099,6 +1104,9 @@ int readConfig(FILE *configFile, EmulatorConfig *config) config->height = getNextIntOrAuto(saveptr, defaultValue); } + else if (strcmp(command, "BOOST_RENDER_RES") == 0) + config->boostRenderRes = atoi(getNextToken(NULL, " ", &saveptr)); + else if (strcmp(command, "EEPROM_PATH") == 0) strcpy(config->eepromPath, getNextToken(NULL, " ", &saveptr)); @@ -1121,7 +1129,13 @@ int readConfig(FILE *configFile, EmulatorConfig *config) } else if (strcmp(command, "EMULATE_CARDREADER") == 0) - config->emulateCardreader = atoi(getNextToken(NULL, " ", &saveptr)); + { + int defaultValue = config->emulateCardreader; + config->emulateCardreader = getNextIntOrAuto(saveptr, defaultValue); + } + + else if (strcmp(command, "EMULATE_TOUCHSCREEN") == 0) + config->emulateTouchscreen = atoi(getNextToken(NULL, " ", &saveptr)); else if (strcmp(command, "CARDFILE_01") == 0) strcpy(config->cardFile1, getNextToken(NULL, " ", &saveptr)); @@ -1237,6 +1251,15 @@ int readConfig(FILE *configFile, EmulatorConfig *config) else if (strcmp(command, "CUSTOM_CURSOR_HEIGHT") == 0) config->customCursorHeight = atoi(getNextToken(NULL, " ", &saveptr)); + else if (strcmp(command, "PH_TOUCH_CURSOR") == 0) + strcpy(config->phTouchCursor, getNextToken(NULL, " ", &saveptr)); + + else if (strcmp(command, "PH_TOUCH_CURSOR_WIDTH") == 0) + config->phTouchCursorWidth = atoi(getNextToken(NULL, " ", &saveptr)); + + else if (strcmp(command, "PH_TOUCH_CURSOR_HEIGHT") == 0) + config->phTouchCursorHeight = atoi(getNextToken(NULL, " ", &saveptr)); + else if (strcmp(command, "MJ4_ENABLED_ALL_THE_TIME") == 0) config->phMode = atoi(getNextToken(NULL, " ", &saveptr)); @@ -1380,6 +1403,8 @@ int readConfig(FILE *configFile, EmulatorConfig *config) strncpy(config->arcadeInputs.player2_button_9, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1); else if (strcmp(command, "PLAYER_2_BUTTON_10") == 0) strncpy(config->arcadeInputs.player2_button_10, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1); + else if (strcmp(command, "PLAYER_2_COIN") == 0) + strncpy(config->arcadeInputs.player2_coin, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1); // Analogue inputs else if (strcmp(command, "ANALOGUE_1") == 0) @@ -1496,6 +1521,7 @@ int initConfig(const char* configFilePath) config.emulateDriveboard = 0; config.emulateMotionboard = 0; config.emulateCardreader = 0; + config.emulateTouchscreen = 0; strcpy(config.cardFile1, "Card_01.crd"); strcpy(config.cardFile2, "Card_02.crd"); config.emulateJVS = 1; @@ -1508,6 +1534,7 @@ int initConfig(const char* configFilePath) strcpy(config.serial2Path, "/dev/ttyS1"); config.width = 640; config.height = 480; + config.boostRenderRes = 1; config.region = EX; config.freeplay = -1; config.showDebugMessages = 0; @@ -1528,13 +1555,16 @@ int initConfig(const char* configFilePath) config.fpsLimiter = 0; config.fpsTarget = 60; config.noSDL = 0; - config.phMode = 1; + config.phMode = 2; config.disableBuiltinFont = 0; config.disableBuiltinLogos = 0; config.hideCursor = 1; strcpy(config.customCursor, ""); config.customCursorWidth = 32; config.customCursorHeight = 32; + strcpy(config.phTouchCursor, ""); + config.phTouchCursorWidth = 32; + config.phTouchCursorHeight = 32; config.mj4EnabledAtT = 0; strcpy(config.or2IP, ""); diff --git a/src/lindbergh/config.h b/src/lindbergh/config.h index ff0385e..0f22635 100644 --- a/src/lindbergh/config.h +++ b/src/lindbergh/config.h @@ -202,7 +202,8 @@ typedef struct { char player2_button_8[INPUT_STRING_LENGTH]; char player2_button_9[INPUT_STRING_LENGTH]; char player2_button_10[INPUT_STRING_LENGTH]; - + char player2_coin[INPUT_STRING_LENGTH]; + // Analogue inputs char analogue_1[INPUT_STRING_LENGTH]; char analogue_2[INPUT_STRING_LENGTH]; @@ -225,6 +226,7 @@ typedef struct int emulateDriveboard; int emulateMotionboard; int emulateCardreader; + int emulateTouchscreen; char cardFile1[MAX_PATH_LENGTH]; char cardFile2[MAX_PATH_LENGTH]; int emulateJVS; @@ -236,6 +238,7 @@ typedef struct char serial2Path[MAX_PATH_LENGTH]; int width; int height; + int boostRenderRes; Colour lindberghColour; GameStatus gameStatus; GameType gameType; @@ -268,6 +271,9 @@ typedef struct char customCursor[MAX_PATH_LENGTH]; int customCursorWidth; int customCursorHeight; + char phTouchCursor[MAX_PATH_LENGTH]; + int phTouchCursorWidth; + int phTouchCursorHeight; int mj4EnabledAtT; char or2IP[16]; char or2Netmask[16]; diff --git a/src/lindbergh/customcursor.c b/src/lindbergh/customcursor.c new file mode 100644 index 0000000..0d9fb3f --- /dev/null +++ b/src/lindbergh/customcursor.c @@ -0,0 +1,229 @@ +#include +#include +#include +#include +#include +#define STB_IMAGE_IMPLEMENTATION +#include "stb_image.h" +#define STBI_ONLY_PNG +#define STBI_SUPPORT_ZLIB +#define STBI_NO_SIMD + + +#include +#include +#include + +#include "config.h" + +extern Display *x11Display; +extern Window window; + +void *customCursor; +void *phTouchCursor; +void *blankCursor; + +SDL_Surface *createSurfaceFromStb(unsigned char *data, int width, int height, int channels) +{ + Uint32 rmask, gmask, bmask, amask; + if (channels == 4) + { + rmask = 0x000000FF; + gmask = 0x0000FF00; + bmask = 0x00FF0000; + amask = 0xFF000000; + } + else if (channels == 3) + { + rmask = 0x000000FF; + gmask = 0x0000FF00; + bmask = 0x00FF0000; + amask = 0; + } + else + { + fprintf(stderr, "Unsupported image format with %d channels.\n", channels); + return NULL; + } + + return SDL_CreateRGBSurfaceFrom(data, width, height, channels * 8, width * channels, rmask, gmask, bmask, amask); +} + +int loadNewCursor(const char *cursorFileName, void **cursor, int customWidth, int customHeight) +{ + int width, height, channels; + unsigned char *imageData = stbi_load(cursorFileName, &width, &height, &channels, 0); + if (!imageData) + { + fprintf(stderr, "Failed to load image: %s\n", cursorFileName); + return 0; + } + + SDL_Surface *originalSurface = createSurfaceFromStb(imageData, width, height, channels); + if (!originalSurface) + { + stbi_image_free(imageData); + return 0; + } + + SDL_Surface *resizedSurface = + SDL_CreateRGBSurface(0, customWidth, customHeight, originalSurface->format->BitsPerPixel, originalSurface->format->Rmask, + originalSurface->format->Gmask, originalSurface->format->Bmask, originalSurface->format->Amask); + if (!resizedSurface) + { + fprintf(stderr, "SDL_CreateRGBSurface Error: %s\n", SDL_GetError()); + SDL_FreeSurface(originalSurface); + stbi_image_free(imageData); + return 0; + } + + SDL_Rect srcRect = {0, 0, originalSurface->w, originalSurface->h}; + SDL_Rect destRect = {0, 0, customWidth, customHeight}; + if (SDL_BlitScaled(originalSurface, &srcRect, resizedSurface, &destRect) != 0) + { + fprintf(stderr, "SDL_BlitScaled Error: %s\n", SDL_GetError()); + SDL_FreeSurface(resizedSurface); + SDL_FreeSurface(originalSurface); + stbi_image_free(imageData); + return 0; + } + + if (getConfig()->noSDL == 0) + { + *cursor = SDL_CreateColorCursor(resizedSurface, customWidth / 2, customHeight / 2); + if (!*cursor) + { + fprintf(stderr, "SDL_CreateColorCursor Error: %s\n", SDL_GetError()); + SDL_FreeSurface(resizedSurface); + SDL_FreeSurface(originalSurface); + stbi_image_free(imageData); + return 0; + } + + SDL_FreeSurface(resizedSurface); + SDL_FreeSurface(originalSurface); + } + else + { + XcursorImage *xcursor = XcursorImageCreate(resizedSurface->w, resizedSurface->h); + if (!xcursor) + return None; + + xcursor->xhot = customWidth / 2; + xcursor->yhot = customHeight / 2; + xcursor->width = resizedSurface->w; + xcursor->height = resizedSurface->h; + + // Convert SDL surface to Xcursor format (32-bit ARGB) + for (int y = 0; y < resizedSurface->h; ++y) + { + for (int x = 0; x < resizedSurface->w; ++x) + { + Uint32 pixel = ((Uint32 *)resizedSurface->pixels)[y * resizedSurface->w + x]; + Uint8 r, g, b, a; + SDL_GetRGBA(pixel, resizedSurface->format, &r, &g, &b, &a); + xcursor->pixels[y * resizedSurface->w + x] = (a << 24) | (r << 16) | (g << 8) | b; + } + } + + *cursor = (void*)XcursorImageLoadCursor(x11Display, xcursor); + XcursorImageDestroy(xcursor); + + } + return 1; +} + +void loadCursors() +{ + if (strcmp(getConfig()->customCursor, "") != 0) + { + if (!loadNewCursor(getConfig()->customCursor, (void *)&customCursor, getConfig()->customCursorWidth, + getConfig()->customCursorHeight)) + { + fprintf(stderr, "Custom cursor could not be loaded!\n"); + exit(1); + } + } + + if (strcmp(getConfig()->phTouchCursor, "") != 0) + { + if (!loadNewCursor(getConfig()->phTouchCursor, (void *)&phTouchCursor, getConfig()->phTouchCursorWidth, + getConfig()->phTouchCursorHeight)) + + { + fprintf(stderr, "Custom cursor could not be loaded!\n"); + exit(1); + } + } + + if(getConfig()->noSDL) + { + XColor dummyColor; + Pixmap blankPixmap; + blankPixmap = XCreatePixmap(x11Display, window, 1, 1, 1); + if (!blankPixmap) + { + fprintf(stderr, "Failed to create blank pixmap\n"); + } + + blankCursor = (void*)XCreatePixmapCursor(x11Display, blankPixmap, blankPixmap, &dummyColor, &dummyColor, 0, 0); + if (!blankCursor) + { + fprintf(stderr, "Failed to create blank cursor\n"); + XFreePixmap(x11Display, blankPixmap); + } + } +} + +void setCursor(void *cursor) +{ + if (getConfig()->noSDL == 0) + { + if (SDL_GetCursor() != NULL) + SDL_SetCursor(cursor); + } + else + { + XDefineCursor(x11Display, window, (Cursor)cursor); + XFlush(x11Display); + } +} + +void hideCursor() +{ + if (getConfig()->noSDL == 0) + { + SDL_ShowCursor(SDL_DISABLE); + } + else + { + XDefineCursor(x11Display, window, (Cursor)blankCursor); + XFlush(x11Display); + } +} + +void showCursor() +{ + if (getConfig()->noSDL == 0) + { + SDL_ShowCursor(SDL_ENABLE); + } + else + { + XDefineCursor(x11Display, window, (Cursor)customCursor); + XFlush(x11Display); + } +} + +void showPhCursor() +{ + if (getConfig()->noSDL == 0) + { + SDL_ShowCursor(SDL_ENABLE); + } + else + { + XDefineCursor(x11Display, window, (Cursor)phTouchCursor); + XFlush(x11Display); + } +} \ No newline at end of file diff --git a/src/lindbergh/customcursor.h b/src/lindbergh/customcursor.h new file mode 100644 index 0000000..edcd541 --- /dev/null +++ b/src/lindbergh/customcursor.h @@ -0,0 +1,10 @@ +#ifndef CUSTOM_CURSORS_H +#define CUSTOM_CURSORS_H + +int loadNewCursor(const char *cursorFileName, void **cursor, int customWidth, int customHeight); +void loadCursors(); +void setCursor(void *cursor); +void hideCursor(); +void showCursor(); +void showPhCursor(); +#endif diff --git a/src/lindbergh/eeprom.c b/src/lindbergh/eeprom.c index 4859806..02d1ef2 100644 --- a/src/lindbergh/eeprom.c +++ b/src/lindbergh/eeprom.c @@ -16,6 +16,8 @@ #define I2C_SEEK 2 #define I2C_WRITE 3 +extern uint32_t gId; + union i2c_smbus_data { uint8_t byte; uint16_t word; @@ -68,36 +70,40 @@ int initEeprom() setFreeplay(eeprom, getConfig()->freeplay); } - if ((getConfig()->crc32 == LETS_GO_JUNGLE_SPECIAL) || (getConfig()->crc32 == THE_HOUSE_OF_THE_DEAD_EX) || - (getConfig()->crc32 == THE_HOUSE_OF_THE_DEAD_4_SPECIAL) || - (getConfig()->crc32 == THE_HOUSE_OF_THE_DEAD_4_SPECIAL_REVB)) + switch (gId) { + case LETS_GO_JUNGLE_SPECIAL: + case THE_HOUSE_OF_THE_DEAD_EX: + case THE_HOUSE_OF_THE_DEAD_4_SPECIAL: + case THE_HOUSE_OF_THE_DEAD_4_SPECIAL_REVB: if (fixCreditSection(eeprom) != 0) { printf("Error initializing eeprom settings."); fclose(eeprom); return 1; } - } - - if (getConfig()->crc32 == HUMMER || getConfig()->crc32 == HUMMER_SDLX || getConfig()->crc32 == HUMMER_EXTREME || - getConfig()->crc32 == HUMMER_EXTREME_MDX) - { + break; + case HUMMER: + case HUMMER_SDLX: + case HUMMER_EXTREME: + case HUMMER_EXTREME_MDX: if (fixCoinAssignmentsHummer(eeprom) != 0) { printf("Error initializing eeprom settings."); fclose(eeprom); return 1; } - } - - if ((getConfig()->crc32 == OUTRUN_2_SP_SDX || getConfig()->crc32 == OUTRUN_2_SP_SDX_REVA) && strcmp(getConfig()->or2IP, "") != 0) - { - if (setIP(eeprom, getConfig()->or2IP, getConfig()->or2Netmask) != 0) + break; + case OUTRUN_2_SP_SDX: + case OUTRUN_2_SP_SDX_REVA: + if (strcmp(getConfig()->or2IP, "") != 0) { - printf("Error setting the new IP address."); - fclose(eeprom); - return 1; + if (setIP(eeprom, getConfig()->or2IP, getConfig()->or2Netmask) != 0) + { + printf("Error setting the new IP address."); + fclose(eeprom); + return 1; + } } } diff --git a/src/lindbergh/eeprom_settings.c b/src/lindbergh/eeprom_settings.c index 545ff01..8cb2642 100644 --- a/src/lindbergh/eeprom_settings.c +++ b/src/lindbergh/eeprom_settings.c @@ -3,7 +3,6 @@ #include #include -#include "config.h" #include "eeprom_settings.h" uint32_t crc32_table[255]; diff --git a/src/lindbergh/evdevinput.c b/src/lindbergh/evdevinput.c index 84e1d38..ffe5e31 100644 --- a/src/lindbergh/evdevinput.c +++ b/src/lindbergh/evdevinput.c @@ -59,6 +59,7 @@ ArcadeInput arcadeInputs[] = {{"TEST_BUTTON", 0, BUTTON_TEST, 1}, {"PLAYER_2_BUTTON_8", 2, BUTTON_8, 1}, {"PLAYER_2_BUTTON_9", 2, BUTTON_9, 1}, {"PLAYER_2_BUTTON_10", 2, BUTTON_10, 1}, + {"PLAYER_2_COIN", 2, COIN, 1}, {"ANALOGUE_1", 0, ANALOGUE_1, 1}, {"ANALOGUE_2", 0, ANALOGUE_2, 1}, @@ -921,18 +922,19 @@ static ControllerStatus listControllers(Controllers *controllers) strcat(controllerInput->inputName, "_"); strcat(controllerInput->inputName, codename(EV_KEY, code)); normaliseName(controllerInput->inputName); - if(snprintf(controllerInput->inputTechName, SIZE, "%s:KEY:%i", controllers->controller[i].path, code) >= 1024) { - // hum ok, truncated value - } - strcpy(controllerInput->inputTechNegName, "-"); // unassignable value (not "" while some conf are empty) + // if(snprintf(controllerInput->inputTechName, SIZE, "%s:KEY:%i", controllers->controller[i].path, + // code) >= 1024) { + // // hum ok, truncated value + // } + // strcpy(controllerInput->inputTechNegName, "-"); // unassignable value (not "" while some conf are empty) } } } if (test_bit(EV_ABS, bit[0])) { - ioctl(controller, EVIOCGBIT(EV_ABS, ABS_MAX), bit[EV_ABS]); - for (int code = 0; code < ABS_MAX; code++) + ioctl(controller, EVIOCGBIT(EV_ABS, KEY_MAX), bit[EV_ABS]); + for (int code = 0; code < KEY_MAX; code++) { if (test_bit(code, bit[EV_ABS])) { @@ -946,12 +948,14 @@ static ControllerStatus listControllers(Controllers *controllers) strcat(controllerInput->inputName, "_"); strcat(controllerInput->inputName, codename(EV_ABS, code)); normaliseName(controllerInput->inputName); - if(snprintf(controllerInput->inputTechName, SIZE, "%s:ABS:%i", controllers->controller[i].path, code) >= 1024) { - // hum ok, truncated value - } - if(snprintf(controllerInput->inputTechNegName, SIZE, "%s:ABS_NEG:%i", controllers->controller[i].path, code) >= 1024) { - // hum ok, truncated value - } + // if(snprintf(controllerInput->inputTechName, SIZE, "%s:ABS:%i", controllers->controller[i].path, + // code) >= 1024) { + // // hum ok, truncated value + // } + // if(snprintf(controllerInput->inputTechNegName, SIZE, "%s:ABS_NEG:%i", + // controllers->controller[i].path, code) >= 1024) { + // // hum ok, truncated value + // } ControllerInput *minControllerInput = &controllers->controller[i].inputs[controllers->controller[i].inputCount++]; @@ -960,12 +964,14 @@ static ControllerStatus listControllers(Controllers *controllers) minControllerInput->specialFunction = ANALOGUE_TO_DIGITAL_MIN; strcpy(minControllerInput->inputName, controllerInput->inputName); strcat(minControllerInput->inputName, "_MIN"); - if(snprintf(minControllerInput->inputTechName, SIZE, "%s:ABS:%i:MIN", controllers->controller[i].path, code) >= 1024) { - // hum ok, truncated value - } - if(snprintf(minControllerInput->inputTechNegName, SIZE, "%s:ABS_NEG:%i:MIN", controllers->controller[i].path, code) >= 1024) { - // hum ok, truncated value - } + // if(snprintf(minControllerInput->inputTechName, SIZE, "%s:ABS:%i:MIN", + // controllers->controller[i].path, code) >= 1024) { + // // hum ok, truncated value + // } + // if(snprintf(minControllerInput->inputTechNegName, SIZE, "%s:ABS_NEG:%i:MIN", + // controllers->controller[i].path, code) >= 1024) { + // // hum ok, truncated value + // } ControllerInput *maxControllerInput = &controllers->controller[i].inputs[controllers->controller[i].inputCount++]; @@ -974,24 +980,27 @@ static ControllerStatus listControllers(Controllers *controllers) maxControllerInput->specialFunction = ANALOGUE_TO_DIGITAL_MAX; strcpy(maxControllerInput->inputName, controllerInput->inputName); strcat(maxControllerInput->inputName, "_MAX"); - if(snprintf(maxControllerInput->inputTechName, SIZE, "%s:ABS:%i:MAX", controllers->controller[i].path, code) >= 1024) { - // hum ok, truncated value - } - if(snprintf(maxControllerInput->inputTechNegName, SIZE, "%s:ABS_NEG:%i:MAX", controllers->controller[i].path, code) >= 1024) { - // hum ok, truncated value - } - - ControllerInput *shakeControllerInput = - &controllers->controller[i].inputs[controllers->controller[i].inputCount++]; - shakeControllerInput->evType = EV_ABS; - shakeControllerInput->evCode = code; - shakeControllerInput->specialFunction = ANALOGUE_SHAKE; - strcpy(shakeControllerInput->inputName, controllerInput->inputName); - strcat(shakeControllerInput->inputName, "_SHAKE"); - if(snprintf(shakeControllerInput->inputTechName, SIZE, "%s:ABS:%i:SHAKE", controllers->controller[i].path, code) >= 1024) { - // hum ok, truncated value - } + // if(snprintf(maxControllerInput->inputTechName, SIZE, "%s:ABS:%i:MAX", + // controllers->controller[i].path, code) >= 1024) { + // // hum ok, truncated value + // } + // if(snprintf(maxControllerInput->inputTechNegName, SIZE, "%s:ABS_NEG:%i:MAX", + // controllers->controller[i].path, code) >= 1024) { + // // hum ok, truncated value + // } + // ControllerInput *shakeControllerInput = + // &controllers->controller[i].inputs[controllers->controller[i].inputCount++]; + // shakeControllerInput->evType = EV_ABS; + // shakeControllerInput->evCode = code; + // shakeControllerInput->specialFunction = ANALOGUE_SHAKE; + // strcpy(shakeControllerInput->inputName, controllerInput->inputName); + // strcat(shakeControllerInput->inputName, "_SHAKE"); + // if(snprintf(shakeControllerInput->inputTechName, SIZE, "%s:ABS:%i:SHAKE", + // controllers->controller[i].path, code) >= 1024) { + // // hum ok, truncated value + // } + // struct input_absinfo absoluteFeatures; ioctl(controller, EVIOCGABS(code), &absoluteFeatures); controllers->controller[i].absMin[code] = absoluteFeatures.minimum; @@ -1183,6 +1192,8 @@ char *getMapping(char *mapping) return "TEST_BUTTON"; if (strcmp(mapping, config->arcadeInputs.player1_coin) == 0) return "PLAYER_1_COIN"; + if (strcmp(mapping, config->arcadeInputs.player2_coin) == 0) + return "PLAYER_2_COIN"; // Player 1 controls if (strcmp(mapping, config->arcadeInputs.player1_button_start) == 0) @@ -1429,9 +1440,15 @@ ControllerStatus startControllerThreads(Controllers *controllers) if (strstr(input.name, "ANALOGUE") != NULL) controllers->controller[i].keyTriggers[controllers->controller[i].inputs[j].evCode].isAnalogue = 1; - if (strcmp(input.name, "PLAYER_1_COIN") == 0) { + if (strcmp(input.name, "PLAYER_1_COIN") == 0) + { controllers->controller[i].keyTriggers[controllers->controller[i].inputs[j].evCode].isCoin = 1; - } + } + + if (strcmp(input.name, "PLAYER_2_COIN") == 0) + { + controllers->controller[i].keyTriggers[controllers->controller[i].inputs[j].evCode].isCoin = 1; + } } break; diff --git a/src/lindbergh/evdevinput.h b/src/lindbergh/evdevinput.h index 373b131..462c30d 100644 --- a/src/lindbergh/evdevinput.h +++ b/src/lindbergh/evdevinput.h @@ -2,7 +2,7 @@ #include -#define SIZE 1024 +#define SIZE 128 #define CONTROLLER_THREAD_MAX 256 @@ -69,12 +69,12 @@ typedef struct typedef struct { char name[SIZE]; - char path[SIZE]; - char physicalLocation[SIZE]; + char path[320]; + char physicalLocation[128]; int absMax[ABS_MAX]; int absMin[ABS_MAX]; - ControllerInput inputs[SIZE]; + ControllerInput inputs[320]; int inputCount; ArcadeInput keyTriggers[KEY_MAX]; diff --git a/src/lindbergh/gluthooks.c b/src/lindbergh/gluthooks.c index 64b59de..88dd6cd 100644 --- a/src/lindbergh/gluthooks.c +++ b/src/lindbergh/gluthooks.c @@ -24,6 +24,7 @@ #include "border.h" #include "resolution.h" +extern uint32_t gId; extern SDL_Window *SDLwindow; extern char SDLgameTitle[]; extern fps_limit fpsLimit; @@ -36,7 +37,9 @@ void *idleFunc = NULL; void FGAPIENTRY glutInit(int *argcp, char **argv) { - if (*argcp > 1 && getConfig()->crc32 == SEGA_RACE_TV) + void FGAPIENTRY (*_glutInit)(int *argcp, char **argv) = dlsym(RTLD_NEXT, "glutInit"); + + if (*argcp > 1 && gId == SEGA_RACE_TV) { if (isTestMode()) { @@ -45,8 +48,14 @@ void FGAPIENTRY glutInit(int *argcp, char **argv) printf("Forced to use SDL to make Test mode render fine.\n"); } } - GLUTGame = true; + if (getConfig()->noSDL) + { + _glutInit(argcp, argv); + return; + } + + GLUTGame = true; initSDL(argcp, argv); } @@ -102,10 +111,13 @@ void FGAPIENTRY glutSwapBuffers(void) return; } - int gId = config->crc32; - if (gId == OUTRUN_2_SP_SDX || gId == OUTRUN_2_SP_SDX_REVA || gId == OUTRUN_2_SP_SDX_REVA_TEST || gId == OUTRUN_2_SP_SDX_REVA_TEST2 || - gId == OUTRUN_2_SP_SDX_TEST) + switch (gId) { + case OUTRUN_2_SP_SDX: + case OUTRUN_2_SP_SDX_REVA: + case OUTRUN_2_SP_SDX_REVA_TEST: + case OUTRUN_2_SP_SDX_REVA_TEST2: + case OUTRUN_2_SP_SDX_TEST: pollEvents(); } @@ -174,11 +186,15 @@ void FGAPIENTRY glutSetCursor(int glutCursor) if (getConfig()->noSDL) { void FGAPIENTRY (*_glutSetCursor)(int glutCursor) = dlsym(RTLD_NEXT, "glutSetCursor"); - _glutSetCursor(glutCursor); + if(strcmp(getConfig()->customCursor, "") == 0) + _glutSetCursor(glutCursor); return; } - SDL_Cursor *cursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); - SDL_SetCursor(cursor); + if (strcmp(getConfig()->customCursor, "") == 0) + { + SDL_Cursor *cursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); + SDL_SetCursor(cursor); + } } void FGAPIENTRY glutDisplayFunc(void (*callback)(void)) diff --git a/src/lindbergh/glxhooks.c b/src/lindbergh/glxhooks.c index aaeff97..c78ba3f 100644 --- a/src/lindbergh/glxhooks.c +++ b/src/lindbergh/glxhooks.c @@ -1,4 +1,3 @@ -#include #define GL_GLEXT_PROTOTYPES #ifndef __i386__ #define __i386__ @@ -20,6 +19,7 @@ #include #include #include +#include #include "fps_limiter.h" #include "sdlcalls.h" @@ -28,11 +28,12 @@ #include "border.h" bool sdlGame = false; +extern uint32_t gId; extern SDL_Window *SDLwindow; extern SDL_GLContext SDLcontext; extern char SDLgameTitle[]; extern fps_limit fpsLimit; -extern Window win; +extern Window window; void glXSwapBuffers(Display *dpy, GLXDrawable drawable) { @@ -43,14 +44,22 @@ void glXSwapBuffers(Display *dpy, GLXDrawable drawable) if (config->borderEnabled) drawGameBorder(config->width, config->height, config->whiteBorderPercentage, config->blackBorderPercentage); - int gId = getConfig()->crc32; - if (getConfig()->noSDL && (gId == OUTRUN_2_SP_SDX || gId == OUTRUN_2_SP_SDX_REVA || gId == OUTRUN_2_SP_SDX_REVA_TEST || - gId == OUTRUN_2_SP_SDX_REVA_TEST2 || gId == OUTRUN_2_SP_SDX_TEST)) + if (getConfig()->noSDL) { - XEvent event; - while (XPending(dpy)) + switch (gId) { - XNextEvent(dpy, &event); + case OUTRUN_2_SP_SDX: + case OUTRUN_2_SP_SDX_REVA: + case OUTRUN_2_SP_SDX_REVA_TEST: + case OUTRUN_2_SP_SDX_REVA_TEST2: + case OUTRUN_2_SP_SDX_TEST: + { + XEvent event; + while (XPending(dpy)) + { + XNextEvent(dpy, &event); + } + } } } else @@ -76,7 +85,7 @@ void glXSwapBuffers(Display *dpy, GLXDrawable drawable) if (getConfig()->noSDL) { - XStoreName(dpy, win, ""); + XStoreName(dpy, window, ""); return; } char windowTitle[512]; @@ -229,28 +238,37 @@ GLXFBConfig *glXChooseFBConfig(Display *dpy, int screen, const int *attrib_list, GLXFBConfig *(*_glXChooseFBConfig)(Display *dpy, int screen, const int *attrib_list, int *nelements) = dlsym(RTLD_NEXT, "glXChooseFBConfig"); - int gId = getConfig()->crc32; char *__GLX_VENDOR_LIBRARY_NAME = getenv("__GLX_VENDOR_LIBRARY_NAME"); char *__NV_PRIME_RENDER_OFFLOAD = getenv("__NV_PRIME_RENDER_OFFLOAD"); if (__GLX_VENDOR_LIBRARY_NAME == NULL) __GLX_VENDOR_LIBRARY_NAME = " "; if (__NV_PRIME_RENDER_OFFLOAD == NULL) __NV_PRIME_RENDER_OFFLOAD = " "; - if ((strcmp(__GLX_VENDOR_LIBRARY_NAME, "nvidia") == 0) && (strcmp(__NV_PRIME_RENDER_OFFLOAD, "1") == 0) && - ((gId == THE_HOUSE_OF_THE_DEAD_4_REVA) || (gId == THE_HOUSE_OF_THE_DEAD_4_REVB) || - (gId == THE_HOUSE_OF_THE_DEAD_4_REVC) || (gId == THE_HOUSE_OF_THE_DEAD_4_SPECIAL) || - (gId == THE_HOUSE_OF_THE_DEAD_4_SPECIAL_REVB) || (gId == THE_HOUSE_OF_THE_DEAD_EX) || (gId == TOO_SPICY))) + + switch (gId) { - for (int i = 0; attrib_list[i] != None; i += 2) + case THE_HOUSE_OF_THE_DEAD_4_REVA: + case THE_HOUSE_OF_THE_DEAD_4_REVB: + case THE_HOUSE_OF_THE_DEAD_4_REVC: + case THE_HOUSE_OF_THE_DEAD_4_SPECIAL: + case THE_HOUSE_OF_THE_DEAD_4_SPECIAL_REVB: + case THE_HOUSE_OF_THE_DEAD_EX: + case TOO_SPICY: + { + if (strcmp(__GLX_VENDOR_LIBRARY_NAME, "nvidia") == 0 && strcmp(__NV_PRIME_RENDER_OFFLOAD, "1") == 0) { - if (attrib_list[i] == GLX_DOUBLEBUFFER) + for (int i = 0; attrib_list[i] != None; i += 2) { - int *ptr = (int *)&attrib_list[i + 1]; - patchMemory((intptr_t)ptr, "01"); - setVariable((intptr_t)ptr, GLX_DONT_CARE); + if (attrib_list[i] == GLX_DOUBLEBUFFER) + { + int *ptr = (int *)&attrib_list[i + 1]; + patchMemory((intptr_t)ptr, "01"); + setVariable((intptr_t)ptr, GLX_DONT_CARE); + } } } } + } return _glXChooseFBConfig(dpy, screen, attrib_list, nelements); } @@ -306,20 +324,31 @@ GLXFBConfigSGIX *glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_lis __GLX_VENDOR_LIBRARY_NAME = " "; if (__NV_PRIME_RENDER_OFFLOAD == NULL) __NV_PRIME_RENDER_OFFLOAD = " "; - if ((strcmp(__GLX_VENDOR_LIBRARY_NAME, "nvidia") == 0) && (strcmp(__NV_PRIME_RENDER_OFFLOAD, "1") == 0) && - ((gId == INITIALD_4_REVA) || (gId == INITIALD_4_REVB) || (gId == INITIALD_4_REVC) || (gId == INITIALD_4_REVD) || - (gId == INITIALD_4_REVG) || (gId == INITIALD_4_EXP_REVB) || (gId == INITIALD_4_EXP_REVC) || - gId == INITIALD_4_EXP_REVD)) + + switch (gId) { - for (int i = 0; attrib_list[i] != None; i += 2) + case INITIALD_4_REVA: + case INITIALD_4_REVB: + case INITIALD_4_REVC: + case INITIALD_4_REVD: + case INITIALD_4_REVG: + case INITIALD_4_EXP_REVB: + case INITIALD_4_EXP_REVC: + case INITIALD_4_EXP_REVD: + { + if (strcmp(__GLX_VENDOR_LIBRARY_NAME, "nvidia") == 0 && strcmp(__NV_PRIME_RENDER_OFFLOAD, "1") == 0) { - if (attrib_list[i] == GLX_DOUBLEBUFFER) + for (int i = 0; attrib_list[i] != None; i += 2) { - int *ptr = (int *)&attrib_list[i + 1]; - patchMemory((intptr_t)ptr, "01"); + if (attrib_list[i] == GLX_DOUBLEBUFFER) + { + int *ptr = (int *)&attrib_list[i + 1]; + patchMemory((intptr_t)ptr, "01"); + } } } } + } return glXChooseFBConfig(dpy, screen, attrib_list, nelements); } diff --git a/src/lindbergh/hook.c b/src/lindbergh/hook.c index 76746f8..4722a53 100644 --- a/src/lindbergh/hook.c +++ b/src/lindbergh/hook.c @@ -46,6 +46,7 @@ #include "fps_limiter.h" #include "evdevinput.h" #include "card_reader.h" +#include "touchscreen.h" #include "log.h" #include "resources/font.h" #include "resources/logo.h" @@ -80,9 +81,12 @@ int logoTGAidx = 0; uint32_t elf_crc = 0; +uint32_t gId = 0; + extern int hummerExtremeShaderFileIndex; extern bool cachedShaderFilesLoaded; extern char vf5StageNameAbbr[5]; +bool phShowCursorInGame = false; extern fps_limit fpsLimit; Controllers controllers = {0}; @@ -102,7 +106,9 @@ 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]; + // uint8_t *code = (uint8_t *)ctx->uc_mcontext.gregs[REG_EIP]; + greg_t eip_value = ctx->uc_mcontext.gregs[REG_EIP]; + uint8_t *code = (uint8_t *)(uintptr_t)eip_value; // Use uintptr_t to ensure proper alignment switch (*code) { @@ -171,9 +177,36 @@ static void handleSegfault(int signal, siginfo_t *info, void *ptr) } } +char *checkIDlike() +{ + FILE *file = fopen("/etc/os-release", "r"); + if (!file) + { + perror("Failed to open /etc/os-release"); + return NULL; + } + + char line[256]; + char *result = NULL; + + while (fgets(line, sizeof(line), file)) + { + if (strncmp(line, "ID_LIKE=", 8) == 0) + { + char *id_like = strchr(line, '='); + if (id_like) + { + result = strdup(id_like); + break; + } + } + } + fclose(file); + return result; +} + void __attribute__((constructor)) hook_init() { - // Get offsets of the Game's ELF and calculate CRC32. dl_iterate_phdr(callback, NULL); @@ -183,15 +216,27 @@ void __attribute__((constructor)) hook_init() act.sa_flags = SA_SIGINFO; sigaction(SIGSEGV, &act, NULL); - char *(*_getenv)(const char *name) = dlsym(RTLD_NEXT, "getenv"); - char* envPath = _getenv("LINDBERGH_CONFIG_PATH"); + char *envPath = getenv("LINDBERGH_CONFIG_PATH"); initConfig(envPath); + gId = getConfig()->crc32; + + char *id_like = checkIDlike(); + if (id_like == NULL) + { + log_warn("Unable to get system info on current OS"); + } + else if (strstr(id_like, "debian") == NULL) + { + log_warn("Seems like you're not in debian-like system. There might be unexpected issues."); + } + if (getConfig()->fpsLimiter == 1) { fpsLimit.targetFrameTime = 1000000 / getConfig()->fpsTarget; fpsLimit.frameEnd = Clock_now(); } + getGPUVendor(); if (initPatch() != 0) @@ -236,8 +281,6 @@ void __attribute__((constructor)) hook_init() if (initControllers(&controllers) != 0) exit(1); - - securityBoardSetDipResolution(getConfig()->width, getConfig()->height); printf("\nSEGA Lindbergh Emulator\nBy the Lindbergh Development Team 2025\n\n"); @@ -255,16 +298,26 @@ void __attribute__((constructor)) hook_init() } printf("\n"); - if (getConfig()->GPUVendor == ATI_GPU && - ((getConfig()->crc32 == LETS_GO_JUNGLE) || (getConfig()->crc32 == LETS_GO_JUNGLE_REVA) || - (getConfig()->crc32 == LETS_GO_JUNGLE_SPECIAL) || (getConfig()->crc32 == AFTER_BURNER_CLIMAX) || - (getConfig()->crc32 == AFTER_BURNER_CLIMAX_REVA) || (getConfig()->crc32 == AFTER_BURNER_CLIMAX_REVB) || - (getConfig()->crc32 == AFTER_BURNER_CLIMAX_SDX) || (getConfig()->crc32 == AFTER_BURNER_CLIMAX_SDX_REVA) || - (getConfig()->crc32 == AFTER_BURNER_CLIMAX_SE) || (getConfig()->crc32 == AFTER_BURNER_CLIMAX_SE_REVA) || - (getConfig()->crc32 == INITIALD_5_JAP_REVA) || (getConfig()->crc32 == INITIALD_5_JAP_REVF) || - (getConfig()->crc32 == INITIALD_5_EXP_20) || (getConfig()->crc32 == INITIALD_5_EXP_20A))) + switch (gId) { - printf("WARNING: Game %s is unsupported in AMD GPU with ATI driver\n", getGameName()); + case LETS_GO_JUNGLE: + case LETS_GO_JUNGLE_REVA: + case LETS_GO_JUNGLE_SPECIAL: + case AFTER_BURNER_CLIMAX: + case AFTER_BURNER_CLIMAX_REVA: + case AFTER_BURNER_CLIMAX_REVB: + case AFTER_BURNER_CLIMAX_SDX: + case AFTER_BURNER_CLIMAX_SDX_REVA: + case AFTER_BURNER_CLIMAX_SE: + case AFTER_BURNER_CLIMAX_SE_REVA: + case INITIALD_5_JAP_REVA: + case INITIALD_5_JAP_REVF: + case INITIALD_5_EXP_20: + case INITIALD_5_EXP_20A: + if (getConfig()->GPUVendor == ATI_GPU) + { + printf("WARNING: Game %s is unsupported in AMD GPU with ATI driver\n", getGameName()); + } } } @@ -272,9 +325,13 @@ DIR *opendir(const char *dirname) { DIR *(*_opendir)(const char *dirname) = dlsym(RTLD_NEXT, "opendir"); - int gId = getConfig()->crc32; - if (gId == INITIALD_5_EXP || gId == INITIALD_5_EXP_20 || gId == INITIALD_5_EXP_20A || gId == INITIALD_5_JAP_REVA || gId == INITIALD_5_JAP_REVF) + switch (gId) { + case INITIALD_5_EXP: + case INITIALD_5_EXP_20: + case INITIALD_5_EXP_20A: + case INITIALD_5_JAP_REVA: + case INITIALD_5_JAP_REVF: if (strcmp(dirname, "/tmp/") == 0) { return _opendir(dirname + 1); @@ -317,10 +374,11 @@ int open(const char *pathname, int flags, ...) if (strcmp(pathname, "/dev/ttyS0") == 0 || strcmp(pathname, "/dev/tts/0") == 0) { - if (getConfig()->emulateDriveboard == 0 && getConfig()->emulateRideboard == 0 && getConfig()->emulateCardreader == 0) + if (getConfig()->emulateDriveboard == 0 && getConfig()->emulateRideboard == 0 && getConfig()->emulateCardreader == 0 && + getConfig()->emulateTouchscreen == 0) return _open(getConfig()->serial1Path, flags, mode); - if (hooks[SERIAL0] != -1 && getConfig()->emulateCardreader && getConfig()->crc32 != R_TUNED) + if (hooks[SERIAL0] != -1 && getConfig()->emulateCardreader && gId != R_TUNED) { return hooks[SERIAL0]; } @@ -328,7 +386,7 @@ int open(const char *pathname, int flags, ...) hooks[SERIAL0] = _open(HOOK_FILE_NAME, flags, mode); printf("Warning: SERIAL0 Opened %d\n", hooks[SERIAL0]); - if (getConfig()->emulateCardreader == 1 && getConfig()->crc32 != R_TUNED) + if (getConfig()->emulateCardreader == 1 && gId != R_TUNED) cardReaderSetFd(0, hooks[SERIAL0], getConfig()->cardFile1); return hooks[SERIAL0]; @@ -339,7 +397,7 @@ int open(const char *pathname, int flags, ...) if (getConfig()->emulateDriveboard == 0 && getConfig()->emulateMotionboard == 0 && getConfig()->emulateCardreader == 0) return _open(getConfig()->serial2Path, flags, mode); - if (hooks[SERIAL1] != -1 && getConfig()->emulateCardreader && getConfig()->crc32 != R_TUNED) + if (hooks[SERIAL1] != -1 && getConfig()->emulateCardreader && gId != R_TUNED) { return hooks[SERIAL1]; } @@ -393,6 +451,11 @@ FILE *fopen(const char *restrict pathname, const char *restrict mode) { FILE *(*_fopen)(const char *restrict pathname, const char *restrict mode) = dlsym(RTLD_NEXT, "fopen"); + if (strcmp(pathname, "/proc/net/route") == 0) + { + return NULL; + } + if (strcmp(pathname, "/root/lindbergrc") == 0) { return _fopen("lindbergrc", mode); @@ -515,13 +578,6 @@ FILE *fopen(const char *restrict pathname, const char *restrict mode) return 0; } - if (strcmp("./../fs/data/cse_credit.bnk", pathname) == 0) - { - void *addr = __builtin_return_address(0); - fileHooks[FILE_HARLEY] = _fopen(pathname, mode); - return fileHooks[FILE_HARLEY]; - } - if (cachedShaderFilesLoaded) { void *addr = __builtin_return_address(0); @@ -554,15 +610,35 @@ FILE *fopen(const char *restrict pathname, const char *restrict mode) } } - int gId = getConfig()->crc32; - if (gId == INITIALD_5_EXP || gId == INITIALD_5_EXP_20 || gId == INITIALD_5_EXP_20A || gId == INITIALD_5_JAP_REVA || gId == INITIALD_5_JAP_REVF) + switch (gId) { + case INITIALD_5_EXP: + case INITIALD_5_EXP_20: + case INITIALD_5_EXP_20A: + case INITIALD_5_JAP_REVA: + case INITIALD_5_JAP_REVF: if (strncmp(pathname, "/tmp/", 5) == 0) { return fopen(pathname + 1, mode); } } + if (gId == PRIMEVAL_HUNT) + { + if (strstr(pathname, "/data/lua/texture/start_stage") != NULL) + phShowCursorInGame = true; + else if (strstr(pathname, "/data/texture/weapon_select/") != NULL) + phShowCursorInGame = false; + else if (strstr(pathname, "/data/texture/stage_select/") != NULL) + phShowCursorInGame = false; + else if (strstr(pathname, "/data/texture/name_entry/") != NULL) + phShowCursorInGame = false; + else if (strstr(pathname, "/data/texture/game_end/") != NULL) + phShowCursorInGame = false; + else if (strstr(pathname, "/data/lua/stage/bonus_0") != NULL) + phShowCursorInGame = true; + } + // printf("Path= %s\n", pathname); return _fopen(pathname, mode); @@ -636,28 +712,31 @@ FILE *fopen64(const char *pathname, const char *mode) } } - if ((getConfig()->crc32 == HUMMER) || (getConfig()->crc32 == HUMMER_SDLX) || - (getConfig()->crc32 == HUMMER_EXTREME) || (getConfig()->crc32 == HUMMER_EXTREME_MDX)) + int idx; + switch (gId) { - int idx; + case HUMMER: + case HUMMER_SDLX: + case HUMMER_EXTREME: + case HUMMER_EXTREME_MDX: if (shaderFileInList(pathname, &idx)) { hummerExtremeShaderFileIndex = idx; } - } - - if ((getConfig()->crc32 == VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVA || getConfig()->crc32 == VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB || - getConfig()->crc32 == VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB_6000) && - (getConfig()->GPUVendor != NVIDIA_GPU && getConfig()->GPUVendor != ATI_GPU)) - { - char *filename = basename((char *)pathname); - if (strstr(filename, "light_") || strstr(filename, "glow_")) + break; + case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVA: + case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB: + case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB_6000: + if (getConfig()->GPUVendor != NVIDIA_GPU && getConfig()->GPUVendor != ATI_GPU) { - printf("Stage: %s\n", filename); - char *start = strchr(filename, '_') + 1; - char *end = strstr(filename, ".txt"); - strncpy(vf5StageNameAbbr, start, end - start); - vf5StageNameAbbr[end - start] = '\0'; + char *filename = basename((char *)pathname); + if (strstr(filename, "light_") || strstr(filename, "glow_")) + { + char *start = strchr(filename, '_') + 1; + char *end = strstr(filename, ".txt"); + strncpy(vf5StageNameAbbr, start, end - start); + vf5StageNameAbbr[end - start] = '\0'; + } } } @@ -785,6 +864,11 @@ ssize_t read(int fd, void *buf, size_t count) // If we don't hook the serial just reply with nothing if (fd == hooks[SERIAL0] || fd == hooks[SERIAL1]) { + if (gId == PRIMEVAL_HUNT && getConfig()->emulateTouchscreen == 1) + { + phRead(fd, buf, count); + return 1; + } return -1; } @@ -817,10 +901,10 @@ size_t fread(void *buf, size_t size, size_t count, FILE *stream) return freadReplace(buf, size, count, fileRead[FILE_RW2]); } - if (stream == fileHooks[FILE_HARLEY]) - { - return harleyFreadReplace(buf, size, count, fileHooks[FILE_HARLEY]); - } + // if (stream == fileHooks[FILE_HARLEY]) + // { + // return harleyFreadReplace(buf, size, count, fileHooks[FILE_HARLEY]); + // } if (stream == fileHooks[FILE_FONT_ABC]) { @@ -926,7 +1010,7 @@ ssize_t write(int fd, const void *buf, size_t count) return driveboardWrite(fd, buf, count); } - if (fd == hooks[SERIAL1] && getConfig()->emulateDriveboard && getConfig()->crc32 != R_TUNED) + if (fd == hooks[SERIAL1] && getConfig()->emulateDriveboard && gId != R_TUNED) { return driveboardWrite(fd, buf, count); } @@ -960,10 +1044,9 @@ int ioctl(int fd, unsigned int request, void *data) return baseboardIoctl(fd, request, data); } - // Just accept any IOCTL on serial ports and ignore it if (fd == hooks[SERIAL0] || fd == hooks[SERIAL1]) { - if (request == 0x541b && getConfig()->crc32 == R_TUNED && fd == hooks[SERIAL1]) + if (request == 0x541b && gId == R_TUNED && fd == hooks[SERIAL1]) { uint8_t d = 1; memcpy(data, &d, sizeof(uint8_t)); @@ -1232,26 +1315,40 @@ int setenv(const char *name, const char *value, int overwrite) char *getenv(const char *name) { char *(*_getenv)(const char *name) = dlsym(RTLD_NEXT, "getenv"); - int gId = getConfig()->crc32; - if ((strcmp(name, "TEA_DIR") == 0) && - ((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 == RAMBO)) || (gId == TOO_SPICY))) + + if (strcmp(name, "TEA_DIR") == 0) { - 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; + switch (gId) + { + case VIRTUA_TENNIS_3: + case VIRTUA_TENNIS_3_TEST: + case VIRTUA_TENNIS_3_REVA: + case VIRTUA_TENNIS_3_REVA_TEST: + case VIRTUA_TENNIS_3_REVB: + case VIRTUA_TENNIS_3_REVB_TEST: + case VIRTUA_TENNIS_3_REVC: + case VIRTUA_TENNIS_3_REVC_TEST: + case RAMBO: + case TOO_SPICY: + { + if (getcwd(envpath, 100) == NULL) + return ""; + char *ptr = strrchr(envpath, '/'); + if (ptr == NULL) + return ""; + *ptr = '\0'; + return envpath; + } + break; + default: + { + if (getcwd(envpath, 100) == NULL) + return ""; + return envpath; + } + } } + if (strcmp(name, "__GL_SYNC_TO_VBLANK") == 0) { return ""; @@ -1292,7 +1389,7 @@ struct tm *localtime_r(const time_t *timep, struct tm *result) struct tm *(*_localtime_r)(const time_t *, struct tm *) = (struct tm * (*)(const time_t *, struct tm *)) dlsym(RTLD_NEXT, "localtime_r"); - if ((getConfig()->crc32 == MJ4_REVG || getConfig()->crc32 == MJ4_EVO) && getConfig()->mj4EnabledAtT == 1) + if ((gId == MJ4_REVG || gId == MJ4_EVO) && getConfig()->mj4EnabledAtT == 1) { time_t target_time = 1735286445; struct tm *res = _localtime_r(&target_time, result); diff --git a/src/lindbergh/input.c b/src/lindbergh/input.c index 9aa8530..82f4548 100644 --- a/src/lindbergh/input.c +++ b/src/lindbergh/input.c @@ -1,11 +1,15 @@ #ifndef __i386__ #define __i386__ +#include "customcursor.h" #endif #undef __x86_64__ #include #include "jvs.h" #include "config.h" +#include "customcursor.h" +#include "patch.h" +#include "touchscreen.h" #include #include @@ -20,6 +24,12 @@ GameType gameType = SHOOTING; int jvsAnalogueInBits = 10; extern int phX, phY, phW, phH; +extern int phX2, phY2, phW2, phH2; +int phIsDragging = 0; + +extern void *customCursor; +extern void *phTouchCursor; +extern bool phShowCursorInGame; int initInput() { @@ -35,6 +45,105 @@ int initInput() return 0; } +void phTouchScreenCursor(int mX, int mY, int *motX, int *motY) +{ + if (getConfig()->emulateTouchscreen) + { + switch (getConfig()->phMode) + { + case 0: + case 2: + case 3: + if ((mX >= phX2 && mX <= (phX2 + phW2) && mY >= phY2 && mY <= (phY2 + phH2)) && getConfig()->hideCursor == 0) + { + setCursor(phTouchCursor); + showPhCursor(); + } + else if (getConfig()->hideCursor == 1 || phShowCursorInGame == false) + { + hideCursor(); + } + else if (phShowCursorInGame && getConfig()->hideCursor == 0) + { + setCursor(customCursor); + showCursor(); + } + break; + case 4: + if ((mX >= phX2 && mX <= (phX2 + phW2) && mY >= (phY2 + phH) && mY <= (phY2 + (phH2 + phH))) && getConfig()->hideCursor == 0) + { + setCursor(phTouchCursor); + showPhCursor(); + } + else if (getConfig()->hideCursor == 1 || phShowCursorInGame == false) + { + hideCursor(); + } + else if (phShowCursorInGame && getConfig()->hideCursor == 0) + { + setCursor(customCursor); + showCursor(); + } + } + } + if (mX < phX) + *motX = phX; + if (mX > (phW + phX)) + *motX = (phW + phX) - 1; + if (mY > phH + phY) + *motY = (phH + phY) - 1; + if (mY < phY) + *motY = phY; +} + +void phTouchClick(int mX, int mY, int type) +{ + int x, y; + bool insideTouchScreen = false; + switch (getConfig()->phMode) + { + case 0: + case 2: + case 3: + if (mX >= phX2 && mX <= (phX2 + phW2) && mY >= phY2 && mY <= (phY2 + phH2)) + { + x = mX - phW; + y = mY - phY2; + insideTouchScreen = true; + } + break; + case 4: + if (mX >= phX2 && mX <= (phX2 + phW2) && mY >= (phY2 + phH) && mY <= (phY2 + (phH2 + phH))) + { + x = mX - phX2; + y = mY - phH; + insideTouchScreen = true; + } + } + if (insideTouchScreen) + { + if (type == ButtonPress) + phCoordinates(x, y, phW2, phH2, ButtonPress); + else if (type == SDL_MOUSEBUTTONDOWN) + phCoordinates(x, y, phW2, phH2, SDL_MOUSEBUTTONDOWN); + else if (type == ButtonRelease) + phCoordinates(x, y, phW2, phH2, ButtonRelease); + else if (type == SDL_MOUSEBUTTONUP) + phCoordinates(x, y, phW2, phH2, SDL_MOUSEBUTTONUP); + else if (type == MotionNotify) + phCoordinates(x, y, phW2, phH2, MotionNotify); + else if (type == SDL_MOUSEMOTION) + phCoordinates(x, y, phW2, phH2, SDL_MOUSEMOTION); + } + else + { + if (getConfig()->noSDL) + setSwitch(PLAYER_1, BUTTON_1, type == ButtonPress); + else + setSwitch(PLAYER_1, BUTTON_1, type == SDL_MOUSEBUTTONDOWN); + } +} + /** * Button mapping used for driving games */ @@ -281,16 +390,15 @@ int XNextEventShooting(Display *display, XEvent *event_return, int returnValue) { int mX = event_return->xmotion.x; int mY = event_return->xmotion.y; - if (mX < phX) - mX = phX; - if (mX > (phW + phX)) - mX = (phW + phX) - 1; - if (mY > phH + phY) - mY = (phH + phY) - 1; - if (mY < phY) - mY = phY; - setAnalogue(ANALOGUE_1, ((double)(mX - phX) / (double)phW) * pow(2, jvsAnalogueInBits)); - setAnalogue(ANALOGUE_2, ((double)(mY - phY) / (double)phH) * pow(2, jvsAnalogueInBits)); + + if (phIsDragging) + phTouchClick(mX, mY, event_return->type); + + int motX = mX, motY = mY; + phTouchScreenCursor(mX, mY, &motX, &motY); + + setAnalogue(ANALOGUE_1, ((double)(motX - phX) / (double)phW) * pow(2, jvsAnalogueInBits)); + setAnalogue(ANALOGUE_2, ((double)(motY - phY) / (double)phH) * pow(2, jvsAnalogueInBits)); } else { @@ -335,7 +443,17 @@ int XNextEventShooting(Display *display, XEvent *event_return, int returnValue) { if (event_return->xbutton.button == 1) // Trigger { - setSwitch(PLAYER_1, BUTTON_1, event_return->type == ButtonPress); + if (getConfig()->crc32 == PRIMEVAL_HUNT && getConfig()->emulateTouchscreen) + { + int mX = event_return->xmotion.x; + int mY = event_return->xmotion.y; + phTouchClick(mX, mY, event_return->type); + phIsDragging = (event_return->type == ButtonPress ? 1 : 0); + } + else + { + setSwitch(PLAYER_1, BUTTON_1, event_return->type == ButtonPress); + } } else if (event_return->xbutton.button == 3) // Reload { @@ -534,16 +652,15 @@ void sdlEventShooting(SDL_Event *event) { int mX = event->motion.x; int mY = event->motion.y; - if (mX < phX) - mX = phX; - if (mX > (phW + phX)) - mX = (phW + phX) - 1; - if (mY > phH + phY) - mY = (phH + phY) - 1; - if (mY < phY) - mY = phY; - setAnalogue(ANALOGUE_1, ((double)(mX - phX) / (double)phW) * pow(2, jvsAnalogueInBits)); - setAnalogue(ANALOGUE_2, ((double)(mY - phY) / (double)phH) * pow(2, jvsAnalogueInBits)); + + if (phIsDragging) + phTouchClick(mX, mY, event->type); + + int motX = mX, motY = mY; + phTouchScreenCursor(mX, mY, &motX, &motY); + + setAnalogue(ANALOGUE_1, ((double)(motX - phX) / (double)phW) * pow(2, jvsAnalogueInBits)); + setAnalogue(ANALOGUE_2, ((double)(motY - phY) / (double)phH) * pow(2, jvsAnalogueInBits)); } else { @@ -587,7 +704,17 @@ void sdlEventShooting(SDL_Event *event) { if (event->button.button == SDL_BUTTON_LEFT) // Trigger { - setSwitch(PLAYER_1, BUTTON_1, event->type == SDL_MOUSEBUTTONDOWN); + if (getConfig()->crc32 == PRIMEVAL_HUNT && getConfig()->emulateTouchscreen) + { + int mX = event->motion.x; + int mY = event->motion.y; + phTouchClick(mX, mY, event->type); + phIsDragging = (event->type == SDL_MOUSEBUTTONDOWN ? 1 : 0); + } + else + { + setSwitch(PLAYER_1, BUTTON_1, event->type == SDL_MOUSEBUTTONDOWN); + } } else if (event->button.button == SDL_BUTTON_RIGHT) // Reload { diff --git a/src/lindbergh/lindbergh.c b/src/lindbergh/lindbergh.c index 3eb7f30..e143b1b 100644 --- a/src/lindbergh/lindbergh.c +++ b/src/lindbergh/lindbergh.c @@ -85,6 +85,7 @@ uint32_t cleanElfCRC32[] = { 0x9BFD0D98, // DVP-0019D | id4.elf 0x9CF9BBCC, // DVP-0019G | id4.elf 0xFA0F6AB0, // DVP-0027A | apacheM.elf + 0x5A7F315E, // DVP-0027A | apachetestM.elf 0x9D414D18, // DVP-0029A | vsg 0xC345E213, // DVP-0030B | id4.elf 0x98E6A516, // DVP-0030C | id4.elf @@ -182,6 +183,7 @@ void isCleanElf(char *command) 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(" If you are sure the ELF is clean, please report it to us.\n"); printf("\033[0m"); } } @@ -215,7 +217,7 @@ void testModePath(char *name) if (strcmp(name, "./apacheM.elf") == 0) { - strcpy(name, "./apacheTestM.elf"); + strcpy(name, "./apachetestM.elf"); return; } @@ -233,7 +235,7 @@ void testModePath(char *name) * Makes sure the environment variables are set correctly * to run the game. */ -void setEnvironmentVariables(int isFlatpak, int zink) +void setEnvironmentVariables(int isFlatpak, int zink, int nvidia) { // Ensure the library path is set correctly char libraryPath[128] = {0}; @@ -254,9 +256,15 @@ void setEnvironmentVariables(int isFlatpak, int zink) setenv(LD_PRELOAD, PRELOAD_FILE_NAME, 1); else setenv(LD_PRELOAD, PRELOAD_FILE_FLATPAK, 1); - - if(zink) + + if (zink) setenv("MESA_LOADER_DRIVER_OVERRIDE", "zink", 1); + + if (nvidia) + { + setenv("__GLX_VENDOR_LIBRARY_NAME", "nvidia", 1); + setenv("__NV_PRIME_RENDER_OFFLOAD", "1", 1); + } } /** @@ -268,6 +276,8 @@ void printUsage(char *argv[]) printf("Options:\n"); printf(" --test | -t Runs the test mode\n"); printf(" --segaboot | -s Runs segaboot\n"); + printf(" --zink | -z Runs with Zink\n"); + printf(" --nvidia | -n Runs with nVidia GPU when is as a secondary GPU in a laptop\n"); printf(" --gdb Runs with GDB\n"); printf(" --list-controllers Lists available controllers and inputs\n"); printf(" --version Displays the version of the loader and team's names\n"); @@ -408,6 +418,7 @@ int main(int argc, char *argv[]) int testMode = 0; int gdb = 0; int zink = 0; + int nvidia = 0; int forceGame = 0; int segaboot = 0; char extConfigPath[PATH_MAX] = {0}; @@ -433,19 +444,25 @@ int main(int argc, char *argv[]) continue; } - if (strcmp(argv[i], "--zink") == 0) + if (strcmp(argv[i], "-z") == 0 || strcmp(argv[i], "--ziink") == 0) { zink = 1; continue; } - + + if (strcmp(argv[i], "-n") == 0 || strcmp(argv[i], "--nvidia") == 0) + { + nvidia = 1; + continue; + } + if (strcmp(argv[i], "-c") == 0 || strcmp(argv[i], "--config") == 0) { - if (i+1 >= argc) + if (i + 1 >= argc) { break; } - strncpy(extConfigPath, argv[i+1], PATH_MAX); + strncpy(extConfigPath, argv[i + 1], PATH_MAX); i += 1; continue; } @@ -455,8 +472,8 @@ int main(int argc, char *argv[]) } // Ensure environment variables are set correctly - setEnvironmentVariables(isFlatpak, zink); - + setEnvironmentVariables(isFlatpak, zink, nvidia); + char command[128] = {0}; strcpy(command, "./"); if (forceGame) @@ -492,7 +509,7 @@ int main(int argc, char *argv[]) if (extConfigPath[0] != '\0') { - setenv(LINDBERGH_CONFIG_PATH,extConfigPath,1); + setenv(LINDBERGH_CONFIG_PATH, extConfigPath, 1); } log_info("Starting $ %s", command); diff --git a/src/lindbergh/patch.c b/src/lindbergh/patch.c index 473fa73..ccbb639 100644 --- a/src/lindbergh/patch.c +++ b/src/lindbergh/patch.c @@ -1,13 +1,11 @@ #ifndef _GNU_SOURCE #define _GNU_SOURCE -#include #endif #include #define GL_GLEXT_PROTOTYPES #include "patch.h" #include -#include #include #include @@ -24,13 +22,19 @@ #include "shader_patches.h" #include "glxhooks.h" #include "log.h" +#include "customcursor.h" +extern uint32_t gId; char elfID[4]; void *amDipswContextAddr; extern void *glVertex3fPatchRetAddrABC[4]; extern void *glVertex3fNoPatchRetAddrABC[4]; void *hod4CursorHideShowCAVEAddress; +extern void *customCursor; +extern void *phTouchCursor; +extern void *blankCursor; + void setVariable(size_t address, size_t value) { int pagesize = sysconf(_SC_PAGE_SIZE); @@ -175,7 +179,6 @@ int amDongleUpdate() int amDongleUserInfoEx(int a, int b, char *_arcadeContext) { - uint32_t gId = getConfig()->crc32; char *gameID; switch (gId) { @@ -322,9 +325,8 @@ int or2snprintf(char *s, size_t n, const char *format, ...) return ret; } - // printf hook, used by OR2 -int patchedPrintf(char *format,...) +int patchedPrintf(char *format, ...) { if (format == NULL) return 0; @@ -370,7 +372,7 @@ void hod4CursorHideShow(int param1) { if (hod4PrevValue != 3 || hod4InTutorial) { - SDL_ShowCursor(SDL_DISABLE); + hideCursor(); } hod4PrevValue = 0; } @@ -379,7 +381,7 @@ void hod4CursorHideShow(int param1) { if (!hod4InTutorial) { - SDL_ShowCursor(SDL_ENABLE); + showCursor(); hod4PrevValue = 3; } } @@ -392,7 +394,7 @@ void hod4CursorHideShow(int param1) case 5: case 11: { - SDL_ShowCursor(SDL_DISABLE); + hideCursor(); } } } @@ -421,8 +423,9 @@ int hod4VsPrintf(char *str, const char *format, va_list arg) int initPatch() { EmulatorConfig *config = getConfig(); + int GPUVendor = getConfig()->GPUVendor; - switch (config->crc32) + switch (gId) { case AFTER_BURNER_CLIMAX: // DVP-0009 { @@ -440,7 +443,7 @@ int initPatch() detourFunction(0x081e2a9c, amDipswInit); detourFunction(0x081e2b38, amDipswExit); - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x0804e1e4, gl_ProgramStringARB); } @@ -462,7 +465,7 @@ int initPatch() detourFunction(0x081e31e4, amDipswInit); detourFunction(0x081e3280, amDipswExit); - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x0804e1e4, gl_ProgramStringARB); } @@ -484,7 +487,7 @@ int initPatch() detourFunction(0x081e3248, amDipswInit); detourFunction(0x081e32e4, amDipswExit); - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x0804e1ec, gl_ProgramStringARB); } @@ -505,7 +508,7 @@ int initPatch() detourFunction(0x081e47a4, amDipswInit); detourFunction(0x081e4840, amDipswExit); - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x0804e244, gl_ProgramStringARB); } @@ -527,7 +530,7 @@ int initPatch() detourFunction(0x081e478c, amDipswInit); detourFunction(0x081e4828, amDipswExit); - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x0804e24c, gl_ProgramStringARB); } @@ -549,7 +552,7 @@ int initPatch() detourFunction(0x081e3294, amDipswInit); detourFunction(0x081e3330, amDipswExit); - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x0804e1e4, gl_ProgramStringARB); } @@ -571,7 +574,7 @@ int initPatch() detourFunction(0x081e327c, amDipswInit); detourFunction(0x081e3318, amDipswExit); - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x0804e1ec, gl_ProgramStringARB); } @@ -601,7 +604,7 @@ int initPatch() detourFunction(0x080e7f94, stubRetZero); cacheModedShaderFiles(); - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { gsEvoElfShaderPatcher(); detourFunction(0x0804c334, gl_ProgramStringARB); @@ -623,7 +626,7 @@ int initPatch() detourFunction(0x08394825, amDipswGetData); detourFunction(0x08395da5, amDongleUserInfoEx); - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { cacheModedShaderFiles(); loadLibCg(); @@ -910,7 +913,7 @@ int initPatch() setVariable(0x0857f0e9, 0x000126e9); // Avoid Full Screen set from Game patchMemory(0x087bc56c, "ab"); // Skips initialization - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x08078860, gl_MultiTexCoord2fARB); detourFunction(0x080788d0, gl_Color4ub); @@ -965,7 +968,7 @@ int initPatch() setVariable(0x0857ee69, 0x000126e9); // Avoid Full Screen set from Game patchMemory(0x087bc2ec, "eb"); // Skips initialization - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x08078860, gl_MultiTexCoord2fARB); detourFunction(0x080788d0, gl_Color4ub); @@ -1020,7 +1023,7 @@ int initPatch() setVariable(0x08580979, 0x000126e9); // Avoid Full Screen set from Game patchMemory(0x087beb6c, "5b"); // Skips initialization - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x080788ec, gl_MultiTexCoord2fARB); detourFunction(0x0807895c, gl_Color4ub); @@ -1076,7 +1079,7 @@ int initPatch() patchMemory(0x08799adc, "df"); // Skips initialization setVariable(0x085593c9, 0x000126e9); // Avoid Full Screen set from Game - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x08078980, gl_MultiTexCoord2fARB); detourFunction(0x080789f0, gl_Color4ub); @@ -1132,7 +1135,7 @@ int initPatch() patchMemory(0x08799d9c, "cf"); // Skips initialization setVariable(0x08559609, 0x000126e9); // Avoid Full Screen set from Game - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x080789a4, gl_MultiTexCoord2fARB); detourFunction(0x08078a14, gl_Color4ub); @@ -1188,7 +1191,7 @@ int initPatch() patchMemory(0x087a2efc, "ff"); // Skips initialization setVariable(0x08561e79, 0x000126e9); // Avoid Full Screen set from Game - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x080789a4, gl_MultiTexCoord2fARB); detourFunction(0x08078a14, gl_Color4ub); @@ -1244,7 +1247,7 @@ int initPatch() patchMemory(0x087a025c, "6f"); // Skips initialization setVariable(0x0855f519, 0x000126e9); // Avoid Full Screen set from Game - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x080789a4, gl_MultiTexCoord2fARB); detourFunction(0x08078a14, gl_Color4ub); @@ -1300,7 +1303,7 @@ int initPatch() patchMemory(0x087e9ebc, "3f36"); // Skips initialization setVariable(0x08599819, 0x000126e9); // Avoid Full Screen set from Game - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x0807a298, gl_MultiTexCoord2fARB); detourFunction(0x0807a308, gl_Color4ub); @@ -1358,7 +1361,7 @@ int initPatch() patchMemory(0x08789a49, "e92601000090"); // Prevents Full Screen set from the game // Mesa Patches - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x0807a3f0, gl_MultiTexCoord2fARB); detourFunction(0x0807a470, gl_Color4ub); @@ -1424,7 +1427,7 @@ int initPatch() detourFunction(0x089382e0, stubRetZero); // Eliminates amsInit Function // Mesa Patches - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x0807a6c0, gl_MultiTexCoord2fARB); detourFunction(0x0807a740, gl_Color4ub); @@ -1490,7 +1493,7 @@ int initPatch() detourFunction(0x08938530, stubRetZero); // Eliminates amsInit Function // Mesa Patches - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x0807a6c0, gl_MultiTexCoord2fARB); detourFunction(0x0807a740, gl_Color4ub); @@ -1548,7 +1551,7 @@ int initPatch() patchMemory(0x08441f99, "eb60"); // tickInitAddress // Mesa Patches - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x0807a3f0, gl_MultiTexCoord2fARB); detourFunction(0x0807a470, gl_Color4ub); @@ -1613,7 +1616,7 @@ int initPatch() detourFunction(0x0850fba0, stubRetZero); // isUseServerBox // Mesa Patches - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x0807a42c, gl_MultiTexCoord2fARB); detourFunction(0x0807a4ac, gl_Color4ub); @@ -1629,54 +1632,6 @@ int initPatch() patchMemory(0x0875e1ae, "00"); // Fix cutscenes } break; - case LETS_GO_JUNGLE_REVA: - { - if (config->showDebugMessages == 1) - { - setVariable(0x08c10604, 2); // amBackupDebugLevel - setVariable(0x08c10620, 2); // amCreditDebugLevel - setVariable(0x08c10878, 2); // amDipswDebugLevel - setVariable(0x08c1087c, 2); // amDongleDebugLevel - setVariable(0x08c10880, 2); // amEepromDebugLevel - setVariable(0x08c10884, 2); // amHwmonitorDebugLevel - setVariable(0x08c10888, 2); // amJvsDebugLevel - setVariable(0x08c1088c, 2); // amLibDebugLevel - setVariable(0x08c10890, 2); // amMiscDebugLevel - setVariable(0x08c10898, 2); // amSysDataDebugLevel - setVariable(0x08c108a0, 2); // bcLibDebugLevel - setVariable(0x08c10894, 2); // amOsinfoDebugLevel - setVariable(0x08c108a4, 0x0FFFFFFF); // s_logMask - detourFunction(0x08074a8c, _putConsole); // Debug Messages - } - // Security - detourFunction(0x084e9fbc, amDongleInit); - detourFunction(0x084ea378, amDongleIsAvailable); - detourFunction(0x084ea29c, amDongleUpdate); - patchMemory(0x0807b86a, "9090"); // Patch initializeArcadeBackup - // Fixes - amDipswContextAddr = (void *)0x08c43e08; // Address of amDipswContext - detourFunction(0x084e9de0, amDipswInit); - detourFunction(0x084e9e7c, amDipswExit); - detourFunction(0x084e9ef2, amDipswGetData); - detourFunction(0x084e9f6a, amDipswSetLed); - patchMemory(0x084125f0, "9090"); // No full screen - - // Mesa Patches - if (getConfig()->GPUVendor != NVIDIA_GPU || getConfig()->lgjRenderWithMesa) - { - detourFunction(0x08071790, gl_MultiTexCoord2fARB); - detourFunction(0x08071800, gl_Color4ub); - detourFunction(0x08071a30, gl_Vertex3f); - detourFunction(0x08072080, gl_TexCoord2f); - detourFunction(0x08072110, cg_GLIsProfileSupported); - detourFunction(0x08071e50, gl_ProgramStringARB); - cacheModedShaderFiles(); - } - detourFunction(0x080722e0, gl_ProgramParameters4fvNV); - // patchMemory(0x083f4626, "909090909090"); - detourFunction(0x08072520, gl_XGetProcAddressARB); - } - break; case LETS_GO_JUNGLE: { if (config->showDebugMessages == 1) @@ -1710,7 +1665,7 @@ int initPatch() patchMemory(0x0840d858, "9090"); // No full screen // Mesa Patches - if (getConfig()->GPUVendor != NVIDIA_GPU || getConfig()->lgjRenderWithMesa) + if (GPUVendor != NVIDIA_GPU || getConfig()->lgjRenderWithMesa) { detourFunction(0x080716e4, gl_MultiTexCoord2fARB); detourFunction(0x08071754, gl_Color4ub); @@ -1725,6 +1680,54 @@ int initPatch() detourFunction(0x08072454, gl_XGetProcAddressARB); } break; + case LETS_GO_JUNGLE_REVA: + { + if (config->showDebugMessages == 1) + { + setVariable(0x08c10604, 2); // amBackupDebugLevel + setVariable(0x08c10620, 2); // amCreditDebugLevel + setVariable(0x08c10878, 2); // amDipswDebugLevel + setVariable(0x08c1087c, 2); // amDongleDebugLevel + setVariable(0x08c10880, 2); // amEepromDebugLevel + setVariable(0x08c10884, 2); // amHwmonitorDebugLevel + setVariable(0x08c10888, 2); // amJvsDebugLevel + setVariable(0x08c1088c, 2); // amLibDebugLevel + setVariable(0x08c10890, 2); // amMiscDebugLevel + setVariable(0x08c10898, 2); // amSysDataDebugLevel + setVariable(0x08c108a0, 2); // bcLibDebugLevel + setVariable(0x08c10894, 2); // amOsinfoDebugLevel + setVariable(0x08c108a4, 0x0FFFFFFF); // s_logMask + detourFunction(0x08074a8c, _putConsole); // Debug Messages + } + // Security + detourFunction(0x084e9fbc, amDongleInit); + detourFunction(0x084ea378, amDongleIsAvailable); + detourFunction(0x084ea29c, amDongleUpdate); + patchMemory(0x0807b86a, "9090"); // Patch initializeArcadeBackup + // Fixes + amDipswContextAddr = (void *)0x08c43e08; // Address of amDipswContext + detourFunction(0x084e9de0, amDipswInit); + detourFunction(0x084e9e7c, amDipswExit); + detourFunction(0x084e9ef2, amDipswGetData); + detourFunction(0x084e9f6a, amDipswSetLed); + patchMemory(0x084125f0, "9090"); // No full screen + + // Mesa Patches + if (GPUVendor != NVIDIA_GPU || getConfig()->lgjRenderWithMesa) + { + detourFunction(0x08071790, gl_MultiTexCoord2fARB); + detourFunction(0x08071800, gl_Color4ub); + detourFunction(0x08071a30, gl_Vertex3f); + detourFunction(0x08072080, gl_TexCoord2f); + detourFunction(0x08072110, cg_GLIsProfileSupported); + detourFunction(0x08071e50, gl_ProgramStringARB); + cacheModedShaderFiles(); + } + detourFunction(0x080722e0, gl_ProgramParameters4fvNV); + // patchMemory(0x083f4626, "909090909090"); + detourFunction(0x08072520, gl_XGetProcAddressARB); + } + break; case LETS_GO_JUNGLE_SPECIAL: { if (config->showDebugMessages == 1) @@ -1758,7 +1761,7 @@ int initPatch() patchMemory(0x08438954, "9090"); // No full screen // Mesa Patches - if (getConfig()->GPUVendor != NVIDIA_GPU || getConfig()->lgjRenderWithMesa) + if (GPUVendor != NVIDIA_GPU || getConfig()->lgjRenderWithMesa) { detourFunction(0x080718e0, gl_MultiTexCoord2fARB); detourFunction(0x08071950, gl_Color4ub); @@ -1773,6 +1776,32 @@ int initPatch() detourFunction(0x080726c0, gl_XGetProcAddressARB); } break; + case MJ4_EVO: + { + detourFunction(0x08840b61, amDongleInit); + detourFunction(0x0883f3ed, amDongleIsAvailable); + detourFunction(0x0883f40a, amDongleIsDevelop); + detourFunction(0x0883ff0e, amDongleUpdate); + + // Fixes and patches to bypss network check + amDipswContextAddr = (void *)0x0af8ff3c; // Address of amDipswContext + detourFunction(0x0883f180, amDipswInit); + detourFunction(0x0883f204, amDipswExit); + detourFunction(0x0883f279, amDipswGetData); + detourFunction(0x0883f2ef, amDipswSetLed); + + patchMemory(0x080ea0d1, "909090909090"); + detourFunction(0x080e327c, stubRetZero); // skip checks + detourFunction(0x080ee4fa, stubRetZero); + patchMemory(0x080ea0bf, "75"); + patchMemory(0x08c035b8, "00"); + + if (GPUVendor != NVIDIA_GPU) + { + detourFunction(0x08051314, gl_ProgramStringARB); + } + } + break; case MJ4_REVG: { setVariable(0x0acf85d4, 2); @@ -1818,38 +1847,12 @@ int initPatch() patchMemory(0x08732fd3, "2e2f00"); // Patch /home/disk2 folder // Mesa Patches - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x08050ebc, gl_ProgramStringARB); } } break; - case MJ4_EVO: - { - detourFunction(0x08840b61, amDongleInit); - detourFunction(0x0883f3ed, amDongleIsAvailable); - detourFunction(0x0883f40a, amDongleIsDevelop); - detourFunction(0x0883ff0e, amDongleUpdate); - - // Fixes and patches to bypss network check - amDipswContextAddr = (void *)0x0af8ff3c; // Address of amDipswContext - detourFunction(0x0883f180, amDipswInit); - detourFunction(0x0883f204, amDipswExit); - detourFunction(0x0883f279, amDipswGetData); - detourFunction(0x0883f2ef, amDipswSetLed); - - patchMemory(0x080ea0d1, "909090909090"); - detourFunction(0x080e327c, stubRetZero); // skip checks - detourFunction(0x080ee4fa, stubRetZero); - patchMemory(0x080ea0bf, "75"); - patchMemory(0x08c035b8, "00"); - - if (getConfig()->GPUVendor != NVIDIA_GPU) - { - detourFunction(0x08051314, gl_ProgramStringARB); - } - } - break; case OUTRUN_2_SP_SDX: { if (config->showDebugMessages == 1) @@ -1888,7 +1891,7 @@ int initPatch() // Shader Patches detourFunction(0x0804ca98, gl_ProgramStringARB); - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x0804cf38, glGenProgramsARB); // Replaces glGenProgramsNV detourFunction(0x0804c548, gl_BindProgramNV); // Replaces glBindProgramNV @@ -1906,26 +1909,6 @@ int initPatch() detourFunction(0x0804d148, or2snprintf); // Fixes a bug in snprintf libc 2.39?? } break; - case OUTRUN_2_SP_SDX_TEST: - { - // Security - detourFunction(0x08066204, amDongleInit); - detourFunction(0x08066585, amDongleIsAvailable); - detourFunction(0x080664a9, amDongleUpdate); - detourFunction(0x080665a5, amDongleIsDevelop); - - // Fixes - amDipswContextAddr = (void *)0x080980e8; // Address of amDipswContext - detourFunction(0x08066028, amDipswInit); - detourFunction(0x080660c4, amDipswExit); - detourFunction(0x0806613a, amDipswGetData); - detourFunction(0x080661b2, amDipswSetLed); // Stub amDipswSetLed - detourFunction(0x08066028, amDipswInit); - - // Patch to allow selection of all cabinet types - patchMemory(0x08054a88, "9090909090"); - } - break; case OUTRUN_2_SP_SDX_REVA: { if (config->showDebugMessages == 1) @@ -1967,7 +1950,7 @@ int initPatch() // Shader Patches detourFunction(0x0804ca98, gl_ProgramStringARB); - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x0804cf38, glGenProgramsARB); // Replaces glGenProgramsNV detourFunction(0x0804c548, gl_BindProgramNV); // Replaces glBindProgramNV @@ -2014,6 +1997,26 @@ int initPatch() patchMemory(0x08054ac4, "9090909090"); } break; + case OUTRUN_2_SP_SDX_TEST: + { + // Security + detourFunction(0x08066204, amDongleInit); + detourFunction(0x08066585, amDongleIsAvailable); + detourFunction(0x080664a9, amDongleUpdate); + detourFunction(0x080665a5, amDongleIsDevelop); + + // Fixes + amDipswContextAddr = (void *)0x080980e8; // Address of amDipswContext + detourFunction(0x08066028, amDipswInit); + detourFunction(0x080660c4, amDipswExit); + detourFunction(0x0806613a, amDipswGetData); + detourFunction(0x080661b2, amDipswSetLed); // Stub amDipswSetLed + detourFunction(0x08066028, amDipswInit); + + // Patch to allow selection of all cabinet types + patchMemory(0x08054a88, "9090909090"); + } + break; case PRIMEVAL_HUNT: { // Security @@ -2052,7 +2055,7 @@ int initPatch() detourFunction(0x082c3103, amDipswSetLed); cacheModedShaderFiles(); // Mesa Patches - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { loadLibCg(); cacheNnstdshader(); @@ -2087,7 +2090,7 @@ int initPatch() patchMemory(0x838C498, "2e2f524f4d5f4c414e472f656e00"); // Patch /home/disk0 folder // Mesa Patches - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x080507e8, gl_ProgramStringARB); } @@ -2143,7 +2146,7 @@ int initPatch() srtvElfShaderPatcher(); // Mesa Patches - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { patchMemory(0x082d3ce9, "9090"); // Force GL_NVX_conditional_render } @@ -2406,22 +2409,6 @@ int initPatch() } } break; - case THE_HOUSE_OF_THE_DEAD_4_SPECIAL_TEST: - { - detourFunction(0x0806e9ec, amDongleInit); - detourFunction(0x0806ecff, amDongleIsAvailable); - detourFunction(0x0806ec66, amDongleUpdate); - // Fixes - amDipswContextAddr = (void *)0x080b2e88; // Address of amDipswContext - detourFunction(0x0806e794, amDipswInit); - detourFunction(0x0806e829, amDipswExit); - detourFunction(0x0806e89f, amDipswGetData); - detourFunction(0x0806e917, amDipswSetLed); - - // CPU patch to support AMD processors - patchMemory(0x08054bf0, "9090909090"); //__intel_new_proc_init_P - } - break; case THE_HOUSE_OF_THE_DEAD_4_SPECIAL_REVB: { detourFunction(0x08363438, amDongleInit); @@ -2464,6 +2451,22 @@ int initPatch() patchMemory(0x08054820, "9090909090"); //__intel_new_proc_init_P } break; + case THE_HOUSE_OF_THE_DEAD_4_SPECIAL_TEST: + { + detourFunction(0x0806e9ec, amDongleInit); + detourFunction(0x0806ecff, amDongleIsAvailable); + detourFunction(0x0806ec66, amDongleUpdate); + // Fixes + amDipswContextAddr = (void *)0x080b2e88; // Address of amDipswContext + detourFunction(0x0806e794, amDipswInit); + detourFunction(0x0806e829, amDipswExit); + detourFunction(0x0806e89f, amDipswGetData); + detourFunction(0x0806e917, amDipswSetLed); + + // CPU patch to support AMD processors + patchMemory(0x08054bf0, "9090909090"); //__intel_new_proc_init_P + } + break; case THE_HOUSE_OF_THE_DEAD_EX: { detourFunction(0x084ba886, amDongleInit); @@ -2482,7 +2485,7 @@ int initPatch() patchMemory(0x0804e4a7, "9090909090"); //__intel_new_proc_init_P // Mesa Patches - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { patchMemory(0x08503bfa, "6d657361"); // Rename compile folder to compmesa cacheModedShaderFiles(); @@ -2528,6 +2531,7 @@ int initPatch() patchMemory(0x08210f3c, "9090909090909090"); patchMemory(0x08210f45, "01"); patchMemory(0x08210f49, "909090"); + patchMemory(0x082ef5d0, "9090909090"); // Fixes amDipswContextAddr = (void *)0x0c8ed0cc; detourFunction(0x08318f84, amDipswInit); @@ -2543,7 +2547,7 @@ int initPatch() detourFunction(0x081cbcd2, stubRetOne); // Mesa Patches - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { loadLibCg(); cacheNnstdshader(); @@ -2607,7 +2611,7 @@ int initPatch() patchMemory(0x080a36de, "9090909090"); patchMemory(0x080a35ed, "ffffffff"); patchMemory(0x080a3620, "ffffffff"); - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x08051b9c, gl_ProgramStringARB); } @@ -2630,7 +2634,7 @@ int initPatch() detourFunction(0x08094d28, stubRetZero); patchMemory(0x080a29a5, "EB"); - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x0805160c, gl_ProgramStringARB); } @@ -2661,11 +2665,11 @@ int initPatch() patchMemory(0x88AB0C1, "2e2f666f6f3100"); // Patch /home/disk2 folder patchMemory(0x88AB0D2, "2e2f666f6f3200"); // Patch /home/disk2 folder patchMemory(0x89C8F24, "2e2f00"); // Patch /home/disk2 folder - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x08052aa4, gl_ProgramStringARB); } - if (getConfig()->GPUVendor != NVIDIA_GPU || getConfig()->GPUVendor == ATI_GPU) + if (GPUVendor != NVIDIA_GPU || GPUVendor == ATI_GPU) { hookVf5FSExposure(0x08148279, 0x0814844a, 0x08148b42, 0x08148d52); } @@ -2696,11 +2700,11 @@ int initPatch() patchMemory(0x88CACBD, "2e2f666f6f3100"); // Patch /home/disk2 folder patchMemory(0x88CACCE, "2e2f666f6f3200"); // Patch /home/disk2 folder patchMemory(0x89DE5AA, "2e2f00"); // Patch /home/disk2 folder - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x08052840, gl_ProgramStringARB); } - if (getConfig()->GPUVendor != NVIDIA_GPU || getConfig()->GPUVendor == ATI_GPU) + if (GPUVendor != NVIDIA_GPU || GPUVendor == ATI_GPU) { hookVf5FSExposure(0x08148a47, 0x08148c18, 0x08149310, 0x08149520); } @@ -2732,11 +2736,11 @@ int initPatch() patchMemory(0x88CD4AE, "2e2f666f6f3200"); // Patch /home/disk2 folder patchMemory(0x89ED9C4, "2e2f00"); // Patch /home/disk2 folder - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x08052b20, gl_ProgramStringARB); } - if (getConfig()->GPUVendor != NVIDIA_GPU || getConfig()->GPUVendor == ATI_GPU) + if (GPUVendor != NVIDIA_GPU || GPUVendor == ATI_GPU) { hookVf5FSExposure(0x081489f7, 0x08148bc8, 0x081492c0, 0x081494d0); } @@ -2769,7 +2773,7 @@ int initPatch() patchMemory(0x0810030c, "ffffffff"); patchMemory(0x08100313, "ffffffff"); - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x08052a68, gl_ProgramStringARB); } @@ -2802,7 +2806,7 @@ int initPatch() patchMemory(0x08119204, "ffffffff"); patchMemory(0x0811920b, "ffffffff"); - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x08052a84, gl_ProgramStringARB); } @@ -2835,7 +2839,7 @@ int initPatch() patchMemory(0x08119384, "ffffffff"); patchMemory(0x0811938b, "ffffffff"); - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x08052a70, gl_ProgramStringARB); } @@ -2873,7 +2877,7 @@ int initPatch() patchMemory(0x080a6356, "9090909090"); patchMemory(0x080a6265, "ffffffff"); patchMemory(0x080a6298, "ffffffff"); - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x08051c4c, gl_ProgramStringARB); } @@ -2909,7 +2913,7 @@ int initPatch() patchMemory(0x080b5682, "9090909090"); patchMemory(0x080B5591, "ffffffff"); patchMemory(0x080B55C4, "ffffffff"); - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x08052088, gl_ProgramStringARB); } @@ -2946,7 +2950,7 @@ int initPatch() patchMemory(0x080e16b6, "9090909090"); patchMemory(0x080e15bd, "ffffffff"); patchMemory(0x080e15f7, "ffffffff"); - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x08052fbc, gl_ProgramStringARB); } @@ -2954,7 +2958,6 @@ int initPatch() patchMemory(0x080e173c, "B810000000"); } break; - case VIRTUA_TENNIS_3: { if (config->showDebugMessages == 1) @@ -2972,12 +2975,12 @@ int initPatch() detourFunction(0x0831beb9, amDipswExit); detourFunction(0x0831bf2f, amDipswGetData); detourFunction(0x0831bfa7, stubRetZero); - setVariable(0x0827a7c7, 0x34891beb); // Disable Fullscreen set from the game + setVariable(0x0827a7c7, 0x34891beb); // Disable Fullscreen set from the game detourFunction(0x08177acc, stubRetOne); // Patch seterror // Mesa - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x0804d458, cg_GLGetLatestProfile); detourFunction(0x0804dcd8, cg_GLIsProfileSupported); @@ -2994,37 +2997,6 @@ int initPatch() } } break; - case VIRTUA_TENNIS_3_TEST: - { - if (config->showDebugMessages == 1) - { - // Debug - detourFunction(0x08054c64, _putConsole); // Debug Messages - } - // Security - detourFunction(0x0815f060, amDongleInit); - detourFunction(0x0815f373, amDongleIsAvailable); - detourFunction(0x0815f2da, amDongleUpdate); - // Fixes - amDipswContextAddr = (void *)0x085e4a6c; // Address of amDipswContext - detourFunction(0x0815c9b0, amDipswInit); - detourFunction(0x0815ca45, amDipswExit); - detourFunction(0x0815cabb, amDipswGetData); - detourFunction(0x0815cb33, amDipswSetLed); - patchMemory(0x0806f983, "EB"); // Avoid Full Screen set from Game - - // Mesa Patches - if (getConfig()->GPUVendor != NVIDIA_GPU) - { - detourFunction(0x0804ce54, cg_GLIsProfileSupported); - detourFunction(0x0804c724, gl_Color4ub); - detourFunction(0x0804c8b4, gl_Vertex3f); - detourFunction(0x0804cdc4, gl_TexCoord2f); - patchMemory(0x0806a01a, "31FF90"); - cacheModedShaderFiles(); - } - } - break; case VIRTUA_TENNIS_3_REVA: { if (config->showDebugMessages == 1) @@ -3042,11 +3014,11 @@ int initPatch() detourFunction(0x0831bf5d, amDipswExit); detourFunction(0x0831bfd3, amDipswGetData); detourFunction(0x0831c04b, stubRetZero); - setVariable(0x0827a7f7, 0x34891beb); // Disable Fullscreen set from the game - detourFunction(0x08177afc, stubRetOne); // Patch seterror + setVariable(0x0827a7f7, 0x34891beb); // Disable Fullscreen set from the game + detourFunction(0x08177afc, stubRetOne); // Patch seterror // Mesa - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x0804d458, cg_GLGetLatestProfile); detourFunction(0x0804dcd8, cg_GLIsProfileSupported); @@ -3083,7 +3055,7 @@ int initPatch() patchMemory(0x0806fd8f, "EB"); // Avoid Full Screen set from Game // Mesa Patches - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x0804ce54, cg_GLIsProfileSupported); detourFunction(0x0804c724, gl_Color4ub); @@ -3111,11 +3083,11 @@ int initPatch() detourFunction(0x0831c149, amDipswExit); detourFunction(0x0831c1bf, amDipswGetData); detourFunction(0x0831c237, stubRetZero); - setVariable(0x0827a9e3, 0x34891beb); // Disable Fullscreen set from the game - detourFunction(0x08177bf0, stubRetOne); // Patch seterror + setVariable(0x0827a9e3, 0x34891beb); // Disable Fullscreen set from the game + detourFunction(0x08177bf0, stubRetOne); // Patch seterror // Mesa - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x0804d458, cg_GLGetLatestProfile); detourFunction(0x0804dcd8, cg_GLIsProfileSupported); @@ -3152,7 +3124,7 @@ int initPatch() patchMemory(0x0806fa33, "EB"); // Avoid Full Screen set from Game // Mesa Patches - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x0804ce54, cg_GLIsProfileSupported); detourFunction(0x0804c724, gl_Color4ub); @@ -3180,11 +3152,11 @@ int initPatch() detourFunction(0x0831c561, amDipswExit); detourFunction(0x0831c5d7, amDipswGetData); detourFunction(0x0831c64f, stubRetZero); - setVariable(0x0827ae1b, 0x34891beb); // Disable Fullscreen set from the game - detourFunction(0x08177c1c, stubRetOne); // Patch seterror + setVariable(0x0827ae1b, 0x34891beb); // Disable Fullscreen set from the game + detourFunction(0x08177c1c, stubRetOne); // Patch seterror // Mesa - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x0804d458, cg_GLGetLatestProfile); detourFunction(0x0804dcd8, cg_GLIsProfileSupported); @@ -3228,7 +3200,7 @@ int initPatch() patchMemory(0x0806fe3f, "EB"); // Avoid Full Screen set from Game // Mesa Patches - if (getConfig()->GPUVendor != NVIDIA_GPU) + if (GPUVendor != NVIDIA_GPU) { detourFunction(0x0804ce54, cg_GLIsProfileSupported); detourFunction(0x0804c724, gl_Color4ub); @@ -3239,6 +3211,37 @@ int initPatch() } } break; + case VIRTUA_TENNIS_3_TEST: + { + if (config->showDebugMessages == 1) + { + // Debug + detourFunction(0x08054c64, _putConsole); // Debug Messages + } + // Security + detourFunction(0x0815f060, amDongleInit); + detourFunction(0x0815f373, amDongleIsAvailable); + detourFunction(0x0815f2da, amDongleUpdate); + // Fixes + amDipswContextAddr = (void *)0x085e4a6c; // Address of amDipswContext + detourFunction(0x0815c9b0, amDipswInit); + detourFunction(0x0815ca45, amDipswExit); + detourFunction(0x0815cabb, amDipswGetData); + detourFunction(0x0815cb33, amDipswSetLed); + patchMemory(0x0806f983, "EB"); // Avoid Full Screen set from Game + + // Mesa Patches + if (GPUVendor != NVIDIA_GPU) + { + detourFunction(0x0804ce54, cg_GLIsProfileSupported); + detourFunction(0x0804c724, gl_Color4ub); + detourFunction(0x0804c8b4, gl_Vertex3f); + detourFunction(0x0804cdc4, gl_TexCoord2f); + patchMemory(0x0806a01a, "31FF90"); + cacheModedShaderFiles(); + } + } + break; default: break; } diff --git a/src/lindbergh/resolution.c b/src/lindbergh/resolution.c index ee0ca07..950727b 100644 --- a/src/lindbergh/resolution.c +++ b/src/lindbergh/resolution.c @@ -1,5 +1,6 @@ #include "config.h" #include +#include #include #include #include @@ -15,17 +16,22 @@ #include "patch.h" #include "resolution.h" +extern uint32_t gId; +extern SDL_Window *SDLwindow; +int gWidth, gHeight; + int srtvX = 0; int srtvW, srtvH; int phX, phY, phW, phH; +int phX2, phY2, phW2, phH2; int vf5FSwidth; void *glVertex3fPatchRetAddrABC[4]; void *glVertex3fNoPatchRetAddrABC[4]; -GLenum curTargetABC = 0; -GLuint curTextureIDABC = 0; +GLenum curTarget = 0; +GLuint curTextureID = 0; const GLfloat *texCoordABC[4]; vertexABC vABC[4]; @@ -62,16 +68,7 @@ int idTextShift = 0; float id4NewCaptionY; float idShiftX = 0.0; float isShiftY = 0.0; - -uint32_t harleyCreditsOffsets[] = { - 0x000000e8, 0x0000012c, 0x00000170, 0x00000468, 0x000004ac, 0x000004f0, 0x00000578, 0x000005bc, 0x00000a88, 0x00000c48, 0x00000c8c, - 0x00000e98, 0x00000edc, 0x00000f20, 0x00000f64, 0x00000fa8, 0x00000fec, 0x00001030, 0x00001074, 0x000010b8, 0x00001638, 0x0000167c, - 0x000016c0, 0x00001704, 0x00001748, 0x0000178c, 0x000017d0, 0x00001814, 0x00001da8, 0x00001dec, 0x00002008, 0x0000204c, 0x00002090, - 0x000020d4, 0x00002118, 0x0000215c, 0x000021a0, 0x000021e4, 0x00002228, 0x000027a8, 0x000027e0, 0x00002830, 0x00002874, 0x000028b8, - 0x000028fc, 0x00002940, 0x00002e48, 0x00002e8c, 0x000030a8, 0x000030ec, 0x00003130, 0x00003174, 0x000034b8, 0x000034fc, 0x00003540, - 0x00003584, 0x000038b8, 0x000038fc, 0x00003b58, 0x00003b9c, 0x00003f48, 0x000041c8, 0x0000420c, 0x00004250, 0x00004294}; - -int harleyCreditsOffsetsSize = 65; +bool myEnableScaling = false; int hummerRespatch() { @@ -80,58 +77,17 @@ int hummerRespatch() (addr == (void *)0x080d8b4f) || (addr == (void *)0x080d8bbb) || (addr == (void *)0x08159eb0) || (addr == (void *)0x08159eec) || (addr == (void *)0x08159f64) || (addr == (void *)0x08163490) || (addr == (void *)0x081634cc) || (addr == (void *)0x08163544)) { - return getConfig()->width - 1; + return gWidth - 1; } else if ((addr == (void *)0x080d8b78) || (addr == (void *)0x080d8bae) || (addr == (void *)0x080d8c1a) || (addr == (void *)0x080d8b34) || (addr == (void *)0x080d8b6a) || (addr == (void *)0x080d8bd6) || (addr == (void *)0x08159ece) || (addr == (void *)0x08159f0a) || (addr == (void *)0x08159f82) || (addr == (void *)0x081634ae) || (addr == (void *)0x081634ea) || (addr == (void *)0x08163562)) { - return getConfig()->height; + return gHeight; } return 1280; } -size_t harleyFreadReplace(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"); - - int s = _fread(buf, size, count, stream); - if (getConfig()->width == 1360 || getConfig()->width == 640) - return s; - - for (int x = 0; x < harleyCreditsOffsetsSize; x++) - { - float oldX, idx; - idx = 1.2; //((float)getConfig()->width / 1360.0) * 0.81459; - memcpy(&oldX, buf + harleyCreditsOffsets[x], sizeof(float)); - float newX = oldX - (((float)getConfig()->width - 1360.0) / 2); - float newY = (((600.0 * (float)getConfig()->height) / 768.0) - 600.0) * -1; - - if (getConfig()->width > 1920) - { - newX = oldX - ((((float)getConfig()->width - 1360.0) / 2) / idx); - newY = (((600.0 * (float)getConfig()->height) / 768.0) - (600.0 * idx)) * -1; - // Move the words "CREDIT(S)" and "TO START" and "TO CONTINUE" a little to the right - if (harleyCreditsOffsets[x] == 0x00000f20 || harleyCreditsOffsets[x] == 0x00001030 || harleyCreditsOffsets[x] == 0x00000f64 || - harleyCreditsOffsets[x] == 0x00001074 || harleyCreditsOffsets[x] == 0x0000167c || harleyCreditsOffsets[x] == 0x00001814 || - harleyCreditsOffsets[x] == 0x00001638 || harleyCreditsOffsets[x] == 0x000017d0) - { - newX -= idx * 10; - } - // Do not scale "TO START" and "TO CONTINUE" - if (harleyCreditsOffsets[x] != 0x0000167c && harleyCreditsOffsets[x] != 0x00001814 && harleyCreditsOffsets[x] != 0x00000f64 && - harleyCreditsOffsets[x] != 0x00001074) - { - memcpy(buf + harleyCreditsOffsets[x] - 8, &idx, sizeof(float)); - memcpy(buf + harleyCreditsOffsets[x] - 12, &idx, sizeof(float)); - } - } - memcpy(buf + harleyCreditsOffsets[x], &newX, sizeof(float)); - memcpy(buf + harleyCreditsOffsets[x] + 4, &newY, sizeof(float)); - } - return s; -} - /** * Function which games use to scale the output, some games behave well when this is changed * others less so. @@ -144,13 +100,13 @@ void glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdou void *returnAddress = __builtin_return_address(0); - switch (getConfig()->crc32) + switch (gId) { case THE_HOUSE_OF_THE_DEAD_4_REVA: case THE_HOUSE_OF_THE_DEAD_4_REVB: case THE_HOUSE_OF_THE_DEAD_4_REVC: { - if ((getConfig()->width != 1280 && getConfig()->height != 768) || (getConfig()->width != 640 && getConfig()->height != 480)) + if ((gWidth != 1280 && gHeight != 768) || (gWidth != 640 && gHeight != 480)) { right = 1280.0; bottom = 720.0; @@ -160,7 +116,7 @@ void glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdou case THE_HOUSE_OF_THE_DEAD_4_SPECIAL: case THE_HOUSE_OF_THE_DEAD_4_SPECIAL_REVB: { - if (getConfig()->width != 1024 && getConfig()->height != 768) + if (gWidth != 1024 && gHeight != 768) { if (right == 1024.0 && bottom == 768.0) { @@ -172,9 +128,9 @@ void glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdou break; case SEGA_RACE_TV: { - if (getConfig()->width != 640 && getConfig()->height != 480) + if (gWidth != 640 && gHeight != 480) { - if ((right == 640.0 && bottom == 480.0) && (getConfig()->width != 640 && getConfig()->height != 480)) + if ((right == 640.0 && bottom == 480.0) && (gWidth != 640 && gHeight != 480)) { right = 600000.0; bottom = 600000.0; @@ -184,7 +140,7 @@ void glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdou break; case THE_HOUSE_OF_THE_DEAD_EX: { - if (getConfig()->width != 1280 && getConfig()->height != 768) + if (gWidth != 1360 && gHeight != 768) { right = 600.0; bottom = 480.0; @@ -208,17 +164,17 @@ void glViewport(GLint x, GLint y, GLsizei width, GLsizei height) void *returnAddress = __builtin_return_address(0); - switch (getConfig()->crc32) + switch (gId) { case HUMMER: case HUMMER_SDLX: { - if (getConfig()->width != 1280 && getConfig()->height != 768) + if (gWidth != 1280 && gHeight != 768) { if (width == 1280 && height == 768) { - width = getConfig()->width; - height = getConfig()->height; + width = gWidth; + height = gHeight; } } } @@ -229,12 +185,12 @@ void glViewport(GLint x, GLint y, GLsizei width, GLsizei height) case OUTRUN_2_SP_SDX_REVA_TEST: case OUTRUN_2_SP_SDX_REVA_TEST2: { - if (getConfig()->width != 800 && getConfig()->height != 480) + if (gWidth != 800 && gHeight != 480) { if ((width >= 800) && (width != 1024)) { - width = getConfig()->width; - height = getConfig()->height; + width = gWidth; + height = gHeight; } } } @@ -242,7 +198,7 @@ void glViewport(GLint x, GLint y, GLsizei width, GLsizei height) case SEGA_RACE_TV: { - if (getConfig()->width != 640 && getConfig()->height != 480) + if (gWidth != 640 && gHeight != 480) { if (width == 640 && height == 480 && returnAddress == (void *)0x08123932) { @@ -258,30 +214,30 @@ void glViewport(GLint x, GLint y, GLsizei width, GLsizei height) } } break; - case THE_HOUSE_OF_THE_DEAD_4_REVA: + // case THE_HOUSE_OF_THE_DEAD_4_REVA: + // case THE_HOUSE_OF_THE_DEAD_4_REVB: + // case THE_HOUSE_OF_THE_DEAD_4_REVC: case THE_HOUSE_OF_THE_DEAD_4_REVA_TEST: - case THE_HOUSE_OF_THE_DEAD_4_REVB: case THE_HOUSE_OF_THE_DEAD_4_REVB_TEST: - case THE_HOUSE_OF_THE_DEAD_4_REVC: case THE_HOUSE_OF_THE_DEAD_4_REVC_TEST: case THE_HOUSE_OF_THE_DEAD_EX_TEST: { if (width == 640 && height == 480) { - width = getConfig()->width; - height = getConfig()->height; + width = gWidth; + height = gHeight; } } break; case THE_HOUSE_OF_THE_DEAD_4_SPECIAL: case THE_HOUSE_OF_THE_DEAD_4_SPECIAL_REVB: { - if (getConfig()->width != 1024 && getConfig()->height != 768) + if (gWidth != 1024 && gHeight != 768) { if (width == 1024 && height == 768) { - width = getConfig()->width; - height = getConfig()->height; + width = gWidth; + height = gHeight; x = 250; y = 100; } @@ -295,11 +251,33 @@ void glViewport(GLint x, GLint y, GLsizei width, GLsizei height) case VIRTUA_FIGHTER_5_R_REVD: case VIRTUA_FIGHTER_5_R_REVG: { - if ((getConfig()->width != 640 && getConfig()->height != 480) || (getConfig()->width != 1280 && getConfig()->height != 768)) + if ((gWidth != 640 && gHeight != 480) || (gWidth != 1280 && gHeight != 768)) { if (width == vf5FSwidth) { - width = getConfig()->width; + width = gWidth; + } + } + } + break; + case PRIMEVAL_HUNT: + { + if (isTestMode() && gWidth != 1280 && gHeight != 480) + { + if (getConfig()->keepAspectRatio) + { + width = gWidth / 2; + height = ((gWidth / 2) / 4) * 3; + y = (gHeight - height) / 2; + } + else + { + width = gWidth / 2; + height = gHeight; + } + if (x == 640) + { + x = width = gWidth / 2; } } } @@ -317,9 +295,9 @@ void glTexImage2D(unsigned int target, int level, int internalformat, int width, void (*_glTexImage2D)(unsigned int target, int level, int internalformat, int width, int height, int border, unsigned int format, unsigned int type, const void *pixels) = dlsym(RTLD_NEXT, "glTexImage2D"); - if (getConfig()->width != 800 && getConfig()->height != 480) + if (gWidth != 800 && gHeight != 480) { - switch (getConfig()->crc32) + switch (gId) { case OUTRUN_2_SP_SDX: case OUTRUN_2_SP_SDX_REVA: @@ -327,8 +305,8 @@ void glTexImage2D(unsigned int target, int level, int internalformat, int width, void *addr = __builtin_return_address(0); if ((width >= 800) && (width != 1024) && (addr != (void *)0x80d78d5) && (addr != (void *)0x080d7941)) { - width = getConfig()->width; - height = getConfig()->height; + width = gWidth; + height = gHeight; } } break; @@ -344,7 +322,7 @@ void glTexParameteri(unsigned int target, unsigned int pname, int param) void (*_glTexParameteri)(unsigned int, unsigned int, int) = dlsym(RTLD_NEXT, "glTexParameteri"); - switch (getConfig()->crc32) + switch (gId) { case OUTRUN_2_SP_SDX: case OUTRUN_2_SP_SDX_REVA: @@ -390,10 +368,10 @@ int isTestMode() return false; } -void glBindTextureABC(GLenum target, GLuint texture) +void myGlBindTexture(GLenum target, GLuint texture) { - curTargetABC = target; - curTextureIDABC = texture; + // const char *targetName = ""; + // switch (target) void (*_glBindTexture)(GLenum, GLuint) = dlsym(RTLD_NEXT, "glBindTexture"); _glBindTexture(target, texture); @@ -403,17 +381,17 @@ void scaleABCVertex() { for (int idx = 0; idx < 4; idx++) { - vABC[idx].x *= (getConfig()->width / 640.0); - vABC[idx].y *= (getConfig()->height / 480.0); + vABC[idx].x *= (gWidth / 640.0); + vABC[idx].y *= (gHeight / 480.0); } } void scaleNumbers() { lockedCountABC++; - float newFontWidth = 8 * ((getConfig()->height / 480.0) * 0.8); - float newFontHeight = 16 * ((getConfig()->height / 480.0) * 0.8); - float newY = 8.0 * (getConfig()->height / 480.0); + float newFontWidth = 8 * ((gHeight / 480.0) * 0.8); + float newFontHeight = 16 * ((gHeight / 480.0) * 0.8); + float newY = 8.0 * (gHeight / 480.0); switch (lockedCountABC) { case 1: @@ -459,7 +437,7 @@ void scaleByAngle(float percentage, float shift) { percentage = (percentage == 0.0 ? 1 : percentage / 100.0); float sizeX, sizeY, newHalfSizeX, newHalfSizeY; - float idx = (getConfig()->height / 480.0) * percentage; + float idx = (gHeight / 480.0) * percentage; switch ((int)angleABC) { case 0: @@ -533,7 +511,7 @@ void shiftTarget(float percentage) { percentage = percentage / 100; float size, newHalfSize; - float idx = (getConfig()->height / 480.0) * percentage; + float idx = (gHeight / 480.0) * percentage; switch ((int)angleABC) { case 0: @@ -599,7 +577,7 @@ void glVertex3fABC1(GLfloat x, GLfloat y, GLfloat z) return; } - if (curTargetABC == GL_TEXTURE_2D && (getConfig()->width != 640 || getConfig()->height != 480)) + if (curTarget == GL_TEXTURE_2D && (gWidth != 640 || gHeight != 480)) { float sizeX, sizeY; sizeX = vABC[1].x - vABC[0].x; @@ -610,16 +588,16 @@ void glVertex3fABC1(GLfloat x, GLfloat y, GLfloat z) // Cut scene video if (textureIDABC == 0x20350) { - float idx = (getConfig()->height / 480.0); + float idx = (gHeight / 480.0); if (vABC[2].y < 65.0 && vABC[3].y < 65.0) { vABC[2].y *= idx * 1.5; vABC[3].y *= idx * 1.5; } - else if ((vABC[0].y > (getConfig()->height - 65.0)) && (vABC[1].y > (getConfig()->height - 65.0))) + else if ((vABC[0].y > (gHeight - 65.0)) && (vABC[1].y > (gHeight - 65.0))) { - vABC[0].y += (getConfig()->height - vABC[0].y) - ((getConfig()->height - vABC[0].y) * (idx * 1.5)); - vABC[1].y += (getConfig()->height - vABC[1].y) - ((getConfig()->height - vABC[1].y) * (idx * 1.5)); + vABC[0].y += (gHeight - vABC[0].y) - ((gHeight - vABC[0].y) * (idx * 1.5)); + vABC[1].y += (gHeight - vABC[1].y) - ((gHeight - vABC[1].y) * (idx * 1.5)); } scale = false; } @@ -670,14 +648,14 @@ void glVertex3fABC1(GLfloat x, GLfloat y, GLfloat z) // Press Start Button / Insert Coins else if (textureIDABC == 0x20138 || textureIDABC == 0x2013a) { - float newSizeX = sizeX * (getConfig()->width / 640.0); - float newSizeY = sizeY * (getConfig()->height / 480.0); - vABC[0].x = (getConfig()->width - newSizeX) / 2; + float newSizeX = sizeX * (gWidth / 640.0); + float newSizeY = sizeY * (gHeight / 480.0); + vABC[0].x = (gWidth - newSizeX) / 2; vABC[1].x = vABC[0].x + newSizeX; vABC[2].x = vABC[1].x; vABC[3].x = vABC[0].x; - vABC[0].y = getConfig()->height - ((newSizeY * 2) + 30); + vABC[0].y = gHeight - ((newSizeY * 2) + 30); vABC[1].y = vABC[0].y; vABC[2].y = vABC[0].y + newSizeY; vABC[3].y = vABC[0].y + newSizeY; @@ -686,17 +664,17 @@ void glVertex3fABC1(GLfloat x, GLfloat y, GLfloat z) // FREE PLAY / Credits / Credit count else if (textureIDABC >= 0x20057 && textureIDABC <= 0x20062) { - float newSizeX = sizeX * (getConfig()->width / 640.0); - float newSizeY = sizeY * (getConfig()->height / 480.0); + float newSizeX = sizeX * (gWidth / 640.0); + float newSizeY = sizeY * (gHeight / 480.0); - vABC[0].x = (getConfig()->width - newSizeX) / 2; + vABC[0].x = (gWidth - newSizeX) / 2; if (sizeX == 88.0) { - vABC[0].x -= (16 * (getConfig()->width / 640.0)) * 1.5; + vABC[0].x -= (16 * (gWidth / 640.0)) * 1.5; } if (sizeX == 16.0) { - float creditsSize = (88 * (getConfig()->width / 640.0)) / 2; + float creditsSize = (88 * (gWidth / 640.0)) / 2; if (prevCreditXABC == x) creditCountABC = 1; if (creditCountABC == 0) @@ -716,7 +694,7 @@ void glVertex3fABC1(GLfloat x, GLfloat y, GLfloat z) vABC[2].x = vABC[1].x; vABC[3].x = vABC[0].x; - vABC[0].y = getConfig()->height - (newSizeY + 20); + vABC[0].y = gHeight - (newSizeY + 20); vABC[1].y = vABC[0].y; vABC[2].y = vABC[0].y + newSizeY; vABC[3].y = vABC[0].y + newSizeY; @@ -726,8 +704,8 @@ void glVertex3fABC1(GLfloat x, GLfloat y, GLfloat z) else if (textureIDABC == 0x20064) { - float sizeIncX = 26.0 * (getConfig()->height / 480.0); - float sizeIncY = 8.0 * (getConfig()->height / 480.0); + float sizeIncX = 26.0 * (gHeight / 480.0); + float sizeIncY = 8.0 * (gHeight / 480.0); vABC[0].x -= sizeIncX / 2.0; vABC[1].x += sizeIncX / 2.0; vABC[2].x += sizeIncX / 2.0; @@ -760,8 +738,8 @@ void glVertex3fABC1(GLfloat x, GLfloat y, GLfloat z) { for (int x = 0; x < 4; x++) { - vABC[x].x = vABC[x].x * (getConfig()->width / 640.0); - vABC[x].y = vABC[x].y * (getConfig()->height / 480.0); + vABC[x].x = vABC[x].x * (gWidth / 640.0); + vABC[x].y = vABC[x].y * (gHeight / 480.0); } scale = false; } @@ -774,7 +752,7 @@ void glVertex3fABC1(GLfloat x, GLfloat y, GLfloat z) // Green arrows in the crosshair else if (textureIDABC == 0x2014c) { - float shift = (20.0 * (getConfig()->height / 480.0) - 20.0) / 2.0; + float shift = (20.0 * (gHeight / 480.0) - 20.0) / 2.0; scaleByAngle(80, shift - 5.0); switch ((int)angleABC) { @@ -825,8 +803,8 @@ void glVertex3fABC1(GLfloat x, GLfloat y, GLfloat z) else if (textureIDABC == 0x20141 || textureIDABC == 0x20142 || textureIDABC == 0x20143 || textureIDABC == 0x20144 || textureIDABC == 0x20145) { - float sizeIncX = 6.0 * (getConfig()->height / 480.0) - 6.0; - float sizeIncY = 10.0 * (getConfig()->height / 480.0) - 10.0; + float sizeIncX = 6.0 * (gHeight / 480.0) - 6.0; + float sizeIncY = 10.0 * (gHeight / 480.0) - 10.0; vABC[0].x -= sizeIncX / 2.0; vABC[0].y -= sizeIncY / 2.0; vABC[1].x += sizeIncX / 2.0; @@ -840,8 +818,8 @@ void glVertex3fABC1(GLfloat x, GLfloat y, GLfloat z) // 0x201E2 Friend, 0x201e3 Target, 0x201C5 Enemy and 0x201C6 Missile words else if (textureIDABC == 0x201E2 || textureIDABC == 0x201e3 || textureIDABC == 0x201C5 || textureIDABC == 0x201C6) { - float newHalfSizeX = ((sizeX * ((getConfig()->height / 480.0) * 0.8)) - sizeX) / 2.0; - float newSizeY = (sizeY * ((getConfig()->height / 480.0) * 0.8)) - sizeY; + float newHalfSizeX = ((sizeX * ((gHeight / 480.0) * 0.8)) - sizeX) / 2.0; + float newSizeY = (sizeY * ((gHeight / 480.0) * 0.8)) - sizeY; vABC[0].x -= newHalfSizeX; vABC[0].y -= newSizeY * 2; vABC[1].x += newHalfSizeX; @@ -859,8 +837,8 @@ void glVertex3fABC1(GLfloat x, GLfloat y, GLfloat z) textureIDABC == 0x20312 || textureIDABC == 0x201e4 || textureIDABC == 0x201e5 || textureIDABC == 0x201e6 || textureIDABC == 0x201C7) { - float newHalfSizeX = ((sizeX * ((getConfig()->height / 480.0) * 0.8)) - sizeX) / 2.0; - float newSizeY = (sizeY * ((getConfig()->height / 480.0) * 0.8)) - sizeY; + float newHalfSizeX = ((sizeX * ((gHeight / 480.0) * 0.8)) - sizeX) / 2.0; + float newSizeY = (sizeY * ((gHeight / 480.0) * 0.8)) - sizeY; vABC[0].x -= newHalfSizeX; vABC[0].y -= newSizeY; vABC[1].x += newHalfSizeX; @@ -872,8 +850,8 @@ void glVertex3fABC1(GLfloat x, GLfloat y, GLfloat z) // Fonts and Subtitles in Cut scene Y position else if (textureIDABC == 0x30008) { - int width = getConfig()->width; - int height = getConfig()->height; + int width = gWidth; + int height = gHeight; float idx = ((height / 480.0) / 10) + 1; float heightShiftUp = height * ((((height / 2.0) - 216) / height) - 0.05); if (vABC[0].y == ((height / 2.0) - 216) || vABC[0].y == (((height / 2.0) - 216) + sizeY + 2)) @@ -893,8 +871,8 @@ void glVertex3fABC1(GLfloat x, GLfloat y, GLfloat z) vABC[3].y -= sizeY - 16; scaleABCVertex(); - float widthScaleIdx = getConfig()->width / 640.0; - float fontSizeScaled = 8 * (getConfig()->height / 480.0); + float widthScaleIdx = gWidth / 640.0; + float fontSizeScaled = 8 * (gHeight / 480.0); float fontWidthAfterScaled = 8 * widthScaleIdx; if (originalPosition == (374 - fontSizeScaled)) { @@ -932,7 +910,7 @@ void glVertex3fABC1(GLfloat x, GLfloat y, GLfloat z) { for (int x = 0; x < 4; x++) { - vABC[x].y *= ((getConfig()->height / 480.0) / 10) + 1; + vABC[x].y *= ((gHeight / 480.0) / 10) + 1; } } scale = false; @@ -954,8 +932,8 @@ void glVertex3fABC2(GLfloat x, GLfloat y, GLfloat z) { void (*_glVertex3f)(GLfloat x, GLfloat y, GLfloat z) = dlsym(RTLD_NEXT, "glVertex3f"); - GLfloat scaledX = x * (getConfig()->width / 640.0); - GLfloat scaledY = y * (getConfig()->height / 480.0); + GLfloat scaledX = x * (gWidth / 640.0); + GLfloat scaledY = y * (gHeight / 480.0); _glVertex3f(scaledX, scaledY, z); } @@ -977,7 +955,7 @@ void glClearColorPH(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) void vf5WidthFix(void *param1) { - if (getConfig()->width > 1920) + if (gWidth > 1920) setVariable(0x86eb208, 1920); (((void (*)(void *))0x080d4c24)(param1)); } @@ -1015,11 +993,11 @@ void idDisplayTexture(void *p1, void *p2, int p3, int p4, int p5) { float newX = 0; if (p4 > 200) - newX = ((float)getConfig()->width / 2) - ((1360.0 / 2) - p4); + newX = ((float)gWidth / 2) - ((1360.0 / 2) - p4); else newX = p4; - float newY = (float)getConfig()->height * (p5 / 768.0); + float newY = (float)gHeight * (p5 / 768.0); idDisplayTextureFixCAVE(p1, p2, p3, (int)newX, (int)newY); } @@ -1040,7 +1018,7 @@ void calculateShift(int W, int H, float *ShiftX, float *ShiftY, bool right) void idDrawBallon(void *p1, void *p2, float p3, float p4, float p5, float p6, float p7, bool p8) { - calculateShift(getConfig()->width, getConfig()->height, &idShiftX, &isShiftY, p8); + calculateShift(gWidth, gHeight, &idShiftX, &isShiftY, p8); idDrawBallonFixCAVE(p1, p2, p3 + idShiftX, p4 + isShiftY, p5, p6, p7, p8); } @@ -1062,8 +1040,8 @@ void idTestText(long p1, long p2, unsigned int p3, char *p4) void patchABCMarkers(uint32_t addrCtrlEnemyInfo, uint32_t addrCtrlPlayerRivalFont, uint32_t addrCtrlEnemyPursuit2d) { // ctrl_enemy_information - newWidthRange_CEI_ABC = getConfig()->width + 100.0; - newHeightRange_CEI_ABC = getConfig()->height + 68.0; + newWidthRange_CEI_ABC = gWidth + 100.0; + newHeightRange_CEI_ABC = gHeight + 68.0; uint32_t *widthRangePtr_CEI = (uint32_t *)&newWidthRange_CEI_ABC; // 750 uint32_t *heightRangePtr_CEI = (uint32_t *)&newHeightRange_CEI_ABC; // 548 setVariable(addrCtrlEnemyInfo + 0x127, (size_t)widthRangePtr_CEI); // 750 @@ -1072,18 +1050,18 @@ void patchABCMarkers(uint32_t addrCtrlEnemyInfo, uint32_t addrCtrlPlayerRivalFon setVariable(addrCtrlEnemyInfo + 0x44c, (size_t)heightRangePtr_CEI); // 548 // Ctrl_Enemy_Pursuit_2d and Ctrl_Player, Rival_Font - newWidthABC = (float)getConfig()->width; // 640 - newHeightABC = (float)getConfig()->height; // 480 - newReducedWidthABC = (float)getConfig()->width - 40; // 600 - newReducedHeightABC = (float)getConfig()->height - 40; // 440 - newHalfWidthABC = (float)getConfig()->width / 2.0; // 320 - newHalfHeightABC = (float)getConfig()->height / 2.0; // 240 - newWidthRangeABC = getConfig()->width + 90.0; // 730 - newHeightRangeABC = getConfig()->height + 90.0; // 570 - new410ABC = (getConfig()->width / 2.0) + 90.0; // 410 - new330ABC = (getConfig()->height / 2.0) + 90.0; // 330 - new280ABC = (getConfig()->width / 2.0) - 40.0; // 280 - new200ABC = (getConfig()->height / 2.0) - 40.0; // 200 + newWidthABC = (float)gWidth; // 640 + newHeightABC = (float)gHeight; // 480 + newReducedWidthABC = (float)gWidth - 40; // 600 + newReducedHeightABC = (float)gHeight - 40; // 440 + newHalfWidthABC = (float)gWidth / 2.0; // 320 + newHalfHeightABC = (float)gHeight / 2.0; // 240 + newWidthRangeABC = gWidth + 90.0; // 730 + newHeightRangeABC = gHeight + 90.0; // 570 + new410ABC = (gWidth / 2.0) + 90.0; // 410 + new330ABC = (gHeight / 2.0) + 90.0; // 330 + new280ABC = (gWidth / 2.0) - 40.0; // 280 + new200ABC = (gHeight / 2.0) - 40.0; // 200 newWidthPtrABC = (uint32_t *)&newWidthABC; newHeightPtrABC = (uint32_t *)&newHeightABC; @@ -1147,7 +1125,7 @@ void patchABCMarkers(uint32_t addrCtrlEnemyInfo, uint32_t addrCtrlPlayerRivalFon void hookABCGLFunctions(uint32_t glBindTextureAddr, uint32_t glVertex3fAddr1, uint32_t glVertex3fAddr2) { - replaceCallAtAddress(glBindTextureAddr, glBindTextureABC); + replaceCallAtAddress(glBindTextureAddr, myGlBindTexture); replaceCallAtAddress(glVertex3fAddr1, glTexCoord2fvABC); replaceCallAtAddress(glVertex3fAddr1 + 0x1f, glVertex3fABC1); @@ -1197,11 +1175,11 @@ void glVertex3fHOD4(GLfloat x, GLfloat y, GLfloat z) void *returnAddress = __builtin_return_address(0); - float scaleX = getConfig()->width / 1280.0f; - float scaleY = getConfig()->height / 768.0f; + float scaleX = gWidth / 1280.0f; + float scaleY = gHeight / 768.0f; - float TestX = ((((getConfig()->width - 1280.0) / 2.0) * 1.1116317809) / 1280.0) * (1.5 / scaleX); - float TestY = ((((getConfig()->height - 768.0) / 2.0) * 0.666979044) / 768.0) * (1.5 / scaleX); + float TestX = ((((gWidth - 1280.0) / 2.0) * 1.1116317809) / 1280.0) * (1.5 / scaleX); + float TestY = ((((gHeight - 768.0) / 2.0) * 0.666979044) / 768.0) * (1.5 / scaleX); float OffsetX = TestX; // test float OffsetY = TestY; @@ -1212,7 +1190,7 @@ void glVertex3fHOD4(GLfloat x, GLfloat y, GLfloat z) if (z == -1.510000f) { // logo 2d elemtents target - if (curTextureIDGE != 260) // target boss fight + if (curTextureID != 260) // target boss fight { x += OffsetX; y -= OffsetY; @@ -1290,18 +1268,54 @@ void glVertex3fHOD4(GLfloat x, GLfloat y, GLfloat z) _glVertex3f(x, y, z); } +void glVertex3fHarley(GLfloat x, GLfloat y, GLfloat z) +{ + int (*_glVertex3f)(GLfloat x, GLfloat y, GLfloat z) = dlsym(RTLD_NEXT, "glVertex3f"); + + float scaleX = gWidth / 1360.0f; + float scaleY = gHeight / 768.0f; + + float OffsetX = ((gWidth - 1360.0) / 2.0) * 0.85; + float OffsetY = ((gHeight - 768.0) / 2.0) * 0.85; + + if (curTextureID == 71) + { + + x += OffsetX; + y -= OffsetY; + x *= scaleX; + y *= scaleY; + } + void *addr = __builtin_return_address(0); + // printf("glVertex3f is hooked: x=%f, y=%f, z=%f\n", x, y, z); + // printf("z values: %.10f\n", z); + + // if ( z == -3517.2272949219f){ //1360x768 + // if ( z == -4271.795898f){ //900p + if (z == -5300.7529296875) + { // 1080p + printf("glVertex3f hooked: x=%f, y=%f, z=%f, addr: %p\n", x, y, z, addr); + x -= 350; + y += 150; + } + + _glVertex3f(x, y, z); +} int initResolutionPatches() { - switch (getConfig()->crc32) + gWidth = getConfig()->width; + gHeight = getConfig()->height; + + switch (gId) { case AFTER_BURNER_CLIMAX: { - if (getConfig()->width == 640 && getConfig()->height == 480) + if (gWidth == 640 && gHeight == 480) break; - setVariable(0x082c0308, getConfig()->width); - setVariable(0x082c030c, getConfig()->height); - float newFontScale = getConfig()->height / 480.0; + setVariable(0x082c0308, gWidth); + setVariable(0x082c030c, gHeight); + float newFontScale = gHeight / 480.0; unsigned int *newFontScalePtr = (unsigned int *)&newFontScale; setVariable(0x0806cd72, *newFontScalePtr); abcDrawSpriteCAVEAddress = (void *)0x08076a28 + 6; @@ -1313,11 +1327,11 @@ int initResolutionPatches() break; case AFTER_BURNER_CLIMAX_REVA: { - if (getConfig()->width == 640 && getConfig()->height == 480) + if (gWidth == 640 && gHeight == 480) break; - setVariable(0x082c0a68, getConfig()->width); - setVariable(0x082c0a6c, getConfig()->height); - float newFontScale = getConfig()->height / 480.0; + setVariable(0x082c0a68, gWidth); + setVariable(0x082c0a6c, gHeight); + float newFontScale = gHeight / 480.0; unsigned int *newFontScalePtr = (unsigned int *)&newFontScale; setVariable(0x0806cd6a, *newFontScalePtr); abcDrawSpriteCAVEAddress = (void *)0x08076a20 + 6; @@ -1329,11 +1343,11 @@ int initResolutionPatches() break; case AFTER_BURNER_CLIMAX_REVB: { - if (getConfig()->width == 640 && getConfig()->height == 480) + if (gWidth == 640 && gHeight == 480) break; - setVariable(0x082C0AE8, getConfig()->width); - setVariable(0x082C0AEC, getConfig()->height); - float newFontScale = getConfig()->height / 480.0; + setVariable(0x082C0AE8, gWidth); + setVariable(0x082C0AEC, gHeight); + float newFontScale = gHeight / 480.0; unsigned int *newFontScalePtr = (unsigned int *)&newFontScale; setVariable(0x0806cd72, *newFontScalePtr); abcDrawSpriteCAVEAddress = (void *)0x08076a28 + 6; @@ -1345,11 +1359,11 @@ int initResolutionPatches() break; case AFTER_BURNER_CLIMAX_SDX: { - if (getConfig()->width == 640 && getConfig()->height == 480) + if (gWidth == 640 && gHeight == 480) break; - setVariable(0x082c2228, getConfig()->width); - setVariable(0x082c222c, getConfig()->height); - float newFontScale = getConfig()->height / 480.0; + setVariable(0x082c2228, gWidth); + setVariable(0x082c222c, gHeight); + float newFontScale = gHeight / 480.0; unsigned int *newFontScalePtr = (unsigned int *)&newFontScale; setVariable(0x0806ce2e, *newFontScalePtr); abcDrawSpriteCAVEAddress = (void *)0x08076ae4 + 6; @@ -1361,11 +1375,11 @@ int initResolutionPatches() break; case AFTER_BURNER_CLIMAX_SDX_REVA: { - if (getConfig()->width == 640 && getConfig()->height == 480) + if (gWidth == 640 && gHeight == 480) break; - setVariable(0x082c2228, getConfig()->width); - setVariable(0x082c222c, getConfig()->height); - float newFontScale = getConfig()->height / 480.0; + setVariable(0x082c2228, gWidth); + setVariable(0x082c222c, gHeight); + float newFontScale = gHeight / 480.0; unsigned int *newFontScalePtr = (unsigned int *)&newFontScale; setVariable(0x0806ce36, *newFontScalePtr); abcDrawSpriteCAVEAddress = (void *)0x08076aec + 6; @@ -1377,11 +1391,11 @@ int initResolutionPatches() break; case AFTER_BURNER_CLIMAX_SE: { - if (getConfig()->width == 640 && getConfig()->height == 480) + if (gWidth == 640 && gHeight == 480) break; - setVariable(0x082c0b28, getConfig()->width); - setVariable(0x082c0b2c, getConfig()->height); - float newFontScale = getConfig()->height / 480.0; + setVariable(0x082c0b28, gWidth); + setVariable(0x082c0b2c, gHeight); + float newFontScale = gHeight / 480.0; unsigned int *newFontScalePtr = (unsigned int *)&newFontScale; setVariable(0x0806cd6a, *newFontScalePtr); abcDrawSpriteCAVEAddress = (void *)0x08076a20 + 6; @@ -1393,11 +1407,11 @@ int initResolutionPatches() break; case AFTER_BURNER_CLIMAX_SE_REVA: { - if (getConfig()->width == 640 && getConfig()->height == 480) + if (gWidth == 640 && gHeight == 480) break; - setVariable(0x082c0b28, getConfig()->width); - setVariable(0x082c0b2c, getConfig()->height); - float newFontScale = getConfig()->height / 480.0; + setVariable(0x082c0b28, gWidth); + setVariable(0x082c0b2c, gHeight); + float newFontScale = gHeight / 480.0; unsigned int *newFontScalePtr = (unsigned int *)&newFontScale; setVariable(0x0806cd72, *newFontScalePtr); abcDrawSpriteCAVEAddress = (void *)0x08076a28 + 6; @@ -1417,10 +1431,21 @@ int initResolutionPatches() break; case HARLEY_DAVIDSON: { - if (getConfig()->width <= 1360 && getConfig()->height <= 768) + int w = gWidth; + int h = gHeight; + if (gWidth == 1360 && gHeight == 768) + { + if (getConfig()->boostRenderRes) + { + setVariable(0x088a55e0, w); // render res + patchMemory(0x08056c31, "9090909090"); + } break; - int w = getConfig()->width; - int h = getConfig()->height; + } + else if (gWidth == 640 && gHeight == 480) + { + break; + } setVariable(0x088a57e0, w); // main res setVariable(0x088a57e4, h); setVariable(0x088a57e8, w); @@ -1433,16 +1458,15 @@ int initResolutionPatches() patchMemory(0x082a8500, "9090909090"); // restype patchMemory(0x088a55e4, "14"); patchMemory(0x082a2412, "00008040"); // Fixes white logo background. - if (getConfig()->width > 1360) - { - unsigned int idx = ((21 * h) / 768) + 1; - setVariable(0x082a250e, idx); - } + unsigned int idx = ((21 * h) / 768) + 1; + setVariable(0x082a250e, idx); + detourFunction(0x0804c700, glVertex3fHarley); + detourFunction(0x0804d220, myGlBindTexture); } break; case HUMMER: { - if (getConfig()->width <= 1280 && getConfig()->height <= 768) + if (gWidth <= 1280 && gHeight <= 768) break; replaceCallAtAddress(0x080d8b58, hummerRespatch); replaceCallAtAddress(0x080d8b73, hummerRespatch); @@ -1454,7 +1478,7 @@ int initResolutionPatches() break; case HUMMER_EXTREME: { - if (getConfig()->width <= 1280 && getConfig()->height <= 768) + if (gWidth <= 1280 && gHeight <= 768) break; replaceCallAtAddress(0x08159eab, hummerRespatch); replaceCallAtAddress(0x08159ec9, hummerRespatch); @@ -1466,7 +1490,7 @@ int initResolutionPatches() break; case HUMMER_EXTREME_MDX: { - if (getConfig()->width <= 1280 && getConfig()->height <= 768) + if (gWidth <= 1280 && gHeight <= 768) break; replaceCallAtAddress(0x0816348b, hummerRespatch); replaceCallAtAddress(0x081634a9, hummerRespatch); @@ -1478,7 +1502,7 @@ int initResolutionPatches() break; case HUMMER_SDLX: { - if (getConfig()->width <= 1280 && getConfig()->height <= 768) + if (gWidth <= 1280 && gHeight <= 768) break; replaceCallAtAddress(0x080d8b14, hummerRespatch); replaceCallAtAddress(0x080d8b2f, hummerRespatch); @@ -1490,24 +1514,34 @@ int initResolutionPatches() break; case INITIALD_4_EXP_REVB: { - if (getConfig()->width == 1360 && getConfig()->height == 768) + if (gWidth == 1360 && gHeight == 768) + { + if (getConfig()->boostRenderRes) + { + setVariable(0x082560a2, gWidth); // Set ResX + setVariable(0x08256162, gWidth); // Set ResX + setVariable(0x08256222, gWidth); // Set ResX + setVariable(0x08256281, gWidth); // Set ResX + } break; - setVariable(0x0837979d, 0x0000f0e9); // Force set resolution - setVariable(0x08379893, getConfig()->width); // Set ResX - setVariable(0x08379898, getConfig()->height); // Set ResY + } + setVariable(0x0837979d, 0x0000f0e9); // Force set resolution + setVariable(0x08379893, gWidth); // Set ResX + setVariable(0x08379898, gHeight); // Set ResY // Renderbuffer Resolution - setVariable(0x082560a2, getConfig()->width); // Set ResX - setVariable(0x0825609a, getConfig()->height); // Set ResY - setVariable(0x08256162, getConfig()->width); // Set ResX - setVariable(0x0825615a, getConfig()->height); // Set ResY - setVariable(0x08256222, getConfig()->width); // Set ResX - setVariable(0x0825621a, getConfig()->height); // Set ResY - setVariable(0x08256281, getConfig()->width); // Set ResX - setVariable(0x08256279, getConfig()->height); // Set ResY - setVariable(0x08256b27, getConfig()->width); // Set ResX - setVariable(0x08256b1f, getConfig()->height); // Set ResY - setVariable(0x08256bb2, getConfig()->width); // Set ResX - setVariable(0x08256baa, getConfig()->height); // Set ResY + setVariable(0x082560a2, gWidth); // Set ResX + setVariable(0x0825609a, gHeight); // Set ResY + setVariable(0x08256162, gWidth); // Set ResX + setVariable(0x0825615a, gHeight); // Set ResY + setVariable(0x08256222, gWidth); // Set ResX + setVariable(0x0825621a, gHeight); // Set ResY + setVariable(0x08256281, gWidth); // Set ResX + setVariable(0x08256279, gHeight); // Set ResY + + setVariable(0x08256b27, gWidth); // Set ResX + setVariable(0x08256b1f, gHeight); // Set ResY + setVariable(0x08256bb2, gWidth); // Set ResX + setVariable(0x08256baa, gHeight); // Set ResY idDisplayTextureCAVEAddress = (void *)0x08337360 + 5; detourFunction(0x08337360, idDisplayTexture); @@ -1516,7 +1550,7 @@ int initResolutionPatches() patchMemory(0x0857dfe9, "01"); // FSAA Enabled setVariable(0x089ea1d0, 1); // FSAA Quality // Fix Subtitles Position - id4NewCaptionY = ((getConfig()->height - 768.0) / 2) + 64.0; + id4NewCaptionY = ((gHeight - 768.0) / 2) + 64.0; detourFunction(0x081f0f91, yTxtPatch); id4NewCaptionYCAVEAddress = (void *)(0x081f0f91 + 8); // Ballon fix @@ -1525,10 +1559,10 @@ int initResolutionPatches() detourFunction(0x081ef2ee, idDrawBallon); replaceCallAtAddress(0x081f084a, id4DrawText); // Scale Testmode text - if (isTestMode() && getConfig()->width >= 1920) + if (isTestMode() && gWidth >= 1920) { patchMemory(0x0899bb78, "02"); - idTextShift = (getConfig()->width == 1920 ? 27 : ((1920 / getConfig()->width) * 27) + 2); + idTextShift = (gWidth == 1920 ? 27 : ((1920 / gWidth) * 27) + 2); idTestTextAddress = (void *)0x08579e92; replaceCallAtAddress(0x0835a1fe, idTestText); } @@ -1536,24 +1570,33 @@ int initResolutionPatches() break; case INITIALD_4_EXP_REVC: { - if (getConfig()->width == 1360 && getConfig()->height == 768) + if (gWidth == 1360 && gHeight == 768) + { + if (getConfig()->boostRenderRes) + { + setVariable(0x08256192, gWidth); // Set ResX + setVariable(0x08256252, gWidth); // Set ResX + setVariable(0x08256312, gWidth); // Set ResX + setVariable(0x08256371, gWidth); // Set ResX + } break; - setVariable(0x0837961d, 0x0000f0e9); // Force set resolution - setVariable(0x08379713, getConfig()->width); // Set ResX - setVariable(0x08379718, getConfig()->height); // Set ResY + } + setVariable(0x0837961d, 0x0000f0e9); // Force set resolution + setVariable(0x08379713, gWidth); // Set ResX + setVariable(0x08379718, gHeight); // Set ResY // Renderbuffer Resolution - setVariable(0x08256192, getConfig()->width); // Set ResX - setVariable(0x0825618a, getConfig()->height); // Set ResY - setVariable(0x08256252, getConfig()->width); // Set ResX - setVariable(0x0825624a, getConfig()->height); // Set ResY - setVariable(0x08256312, getConfig()->width); // Set ResX - setVariable(0x0825630a, getConfig()->height); // Set ResY - setVariable(0x08256371, getConfig()->width); // Set ResX - setVariable(0x08256369, getConfig()->height); // Set ResY - setVariable(0x08256c17, getConfig()->width); // Set ResX - setVariable(0x08256c0f, getConfig()->height); // Set ResY - setVariable(0x08256ca2, getConfig()->width); // Set ResX - setVariable(0x08256c9a, getConfig()->height); // Set ResY + setVariable(0x08256192, gWidth); // Set ResX + setVariable(0x0825618a, gHeight); // Set ResY + setVariable(0x08256252, gWidth); // Set ResX + setVariable(0x0825624a, gHeight); // Set ResY + setVariable(0x08256312, gWidth); // Set ResX + setVariable(0x0825630a, gHeight); // Set ResY + setVariable(0x08256371, gWidth); // Set ResX + setVariable(0x08256369, gHeight); // Set ResY + setVariable(0x08256c17, gWidth); // Set ResX + setVariable(0x08256c0f, gHeight); // Set ResY + setVariable(0x08256ca2, gWidth); // Set ResX + setVariable(0x08256c9a, gHeight); // Set ResY idDisplayTextureCAVEAddress = (void *)0x08337200 + 5; detourFunction(0x08337200, idDisplayTexture); @@ -1562,10 +1605,10 @@ int initResolutionPatches() patchMemory(0x0857dd69, "01"); // FSAA Enabled setVariable(0x089ea1d0, 1); // FSAA Quality // Fix Subtitles - float newCaptionY = ((getConfig()->height - 768.0) / 2) + 64.0; + float newCaptionY = ((gHeight - 768.0) / 2) + 64.0; setVariable(0x089a7d58, *(unsigned int *)&newCaptionY); // Fix Subtitles Position - id4NewCaptionY = ((getConfig()->height - 768.0) / 2) + 64.0; + id4NewCaptionY = ((gHeight - 768.0) / 2) + 64.0; detourFunction(0x081f1051, yTxtPatch); id4NewCaptionYCAVEAddress = (void *)(0x081f1051 + 8); // Ballon fix @@ -1574,10 +1617,10 @@ int initResolutionPatches() detourFunction(0x081ef39e, idDrawBallon); replaceCallAtAddress(0x081f08fc, id4DrawText); // Scale Testmode text - if (isTestMode() && getConfig()->width >= 1920) + if (isTestMode() && gWidth >= 1920) { patchMemory(0x0899bb78, "02"); - idTextShift = (getConfig()->width == 1920 ? 27 : ((1920 / getConfig()->width) * 27) + 2); + idTextShift = (gWidth == 1920 ? 27 : ((1920 / gWidth) * 27) + 2); idTestTextAddress = (void *)0x08579c12; replaceCallAtAddress(0x0835a09e, idTestText); } @@ -1585,24 +1628,33 @@ int initResolutionPatches() break; case INITIALD_4_EXP_REVD: { - if (getConfig()->width == 1360 && getConfig()->height == 768) + if (gWidth == 1360 && gHeight == 768) + { + if (getConfig()->boostRenderRes) + { + setVariable(0x0825728a, gWidth); // Set ResX + setVariable(0x0825734a, gWidth); // Set ResX + setVariable(0x0825740a, gWidth); // Set ResX + setVariable(0x08257469, gWidth); // Set ResX + } break; - setVariable(0x0837b12d, 0x0000f0e9); // Force set resolution - setVariable(0x0837b223, getConfig()->width); // Set ResX - setVariable(0x0837b228, getConfig()->height); // Set ResY + } + setVariable(0x0837b12d, 0x0000f0e9); // Force set resolution + setVariable(0x0837b223, gWidth); // Set ResX + setVariable(0x0837b228, gHeight); // Set ResY // Renderbuffer Resolution - setVariable(0x0825728a, getConfig()->width); // Set ResX - setVariable(0x08257282, getConfig()->height); // Set ResY - setVariable(0x0825734a, getConfig()->width); // Set ResX - setVariable(0x08257342, getConfig()->height); // Set ResY - setVariable(0x0825740a, getConfig()->width); // Set ResX - setVariable(0x08257402, getConfig()->height); // Set ResY - setVariable(0x08257469, getConfig()->width); // Set ResX - setVariable(0x08257461, getConfig()->height); // Set ResY - setVariable(0x08257d0f, getConfig()->width); // Set ResX - setVariable(0x08257d07, getConfig()->height); // Set ResY - setVariable(0x08257d9a, getConfig()->width); // Set ResX - setVariable(0x08257d92, getConfig()->height); // Set ResY + setVariable(0x0825728a, gWidth); // Set ResX + setVariable(0x08257282, gHeight); // Set ResY + setVariable(0x0825734a, gWidth); // Set ResX + setVariable(0x08257342, gHeight); // Set ResY + setVariable(0x0825740a, gWidth); // Set ResX + setVariable(0x08257402, gHeight); // Set ResY + setVariable(0x08257469, gWidth); // Set ResX + setVariable(0x08257461, gHeight); // Set ResY + setVariable(0x08257d0f, gWidth); // Set ResX + setVariable(0x08257d07, gHeight); // Set ResY + setVariable(0x08257d9a, gWidth); // Set ResX + setVariable(0x08257d92, gHeight); // Set ResY idDisplayTextureCAVEAddress = (void *)0x08338d50 + 5; detourFunction(0x08338d50, idDisplayTexture); @@ -1611,7 +1663,7 @@ int initResolutionPatches() patchMemory(0x0857f879, "01"); // FSAA Enabled setVariable(0x089ed930, 1); // FSAA Quality // Fix Subtitles Position - id4NewCaptionY = ((getConfig()->height - 768.0) / 2) + 64.0; + id4NewCaptionY = ((gHeight - 768.0) / 2) + 64.0; detourFunction(0x081f2061, yTxtPatch); id4NewCaptionYCAVEAddress = (void *)(0x081f2061 + 8); // Ballon fix @@ -1620,10 +1672,10 @@ int initResolutionPatches() detourFunction(0x081f03be, idDrawBallon); replaceCallAtAddress(0x081f191a, id4DrawText); // Scale Testmode text - if (isTestMode() && getConfig()->width >= 1920) + if (isTestMode() && gWidth >= 1920) { patchMemory(0x0899f2d8, "02"); - idTextShift = (getConfig()->width == 1920 ? 27 : ((1920 / getConfig()->width) * 27) + 2); + idTextShift = (gWidth == 1920 ? 27 : ((1920 / gWidth) * 27) + 2); idTestTextAddress = (void *)0x0857b722; replaceCallAtAddress(0x0835bbee, idTestText); } @@ -1631,24 +1683,33 @@ int initResolutionPatches() break; case INITIALD_4_REVA: { - if (getConfig()->width == 1360 && getConfig()->height == 768) + if (gWidth == 1360 && gHeight == 768) + { + if (getConfig()->boostRenderRes) + { + setVariable(0x08247e77, gWidth); // Set ResX + setVariable(0x08247f37, gWidth); // Set ResX + setVariable(0x08247ff7, gWidth); // Set ResX + setVariable(0x08248056, gWidth); // Set ResX + } break; + } setVariable(0x0835640d, 0x0000f0e9); // Force set resolution - setVariable(0x08356503, getConfig()->width); // Set ResX - setVariable(0x08356508, getConfig()->height); // Set ResY + setVariable(0x08356503, gWidth); // Set ResX + setVariable(0x08356508, gHeight); // Set ResY // Renderbuffer Resolution - setVariable(0x08247e77, getConfig()->width); // Set ResX - setVariable(0x08247e6f, getConfig()->height); // Set ResY - setVariable(0x08247f37, getConfig()->width); // Set ResX - setVariable(0x08247f2f, getConfig()->height); // Set ResY - setVariable(0x08247ff7, getConfig()->width); // Set ResX - setVariable(0x08247fef, getConfig()->height); // Set ResY - setVariable(0x08248056, getConfig()->width); // Set ResX - setVariable(0x0824804e, getConfig()->height); // Set ResY - setVariable(0x082487e7, getConfig()->width); // Set ResX - setVariable(0x082487df, getConfig()->height); // Set ResY - setVariable(0x08248872, getConfig()->width); // Set ResX - setVariable(0x0824886a, getConfig()->height); // Set ResY + setVariable(0x08247e77, gWidth); // Set ResX + setVariable(0x08247e6f, gHeight); // Set ResY + setVariable(0x08247f37, gWidth); // Set ResX + setVariable(0x08247f2f, gHeight); // Set ResY + setVariable(0x08247ff7, gWidth); // Set ResX + setVariable(0x08247fef, gHeight); // Set ResY + setVariable(0x08248056, gWidth); // Set ResX + setVariable(0x0824804e, gHeight); // Set ResY + setVariable(0x082487e7, gWidth); // Set ResX + setVariable(0x082487df, gHeight); // Set ResY + setVariable(0x08248872, gWidth); // Set ResX + setVariable(0x0824886a, gHeight); // Set ResY idDisplayTextureCAVEAddress = (void *)0x083188a0 + 5; detourFunction(0x083188a0, idDisplayTexture); @@ -1665,24 +1726,33 @@ int initResolutionPatches() break; case INITIALD_4_REVB: { - if (getConfig()->width == 1360 && getConfig()->height == 768) + if (gWidth == 1360 && gHeight == 768) + { + if (getConfig()->boostRenderRes) + { + setVariable(0x08248037, gWidth); // Set ResX + setVariable(0x082480f7, gWidth); // Set ResX + setVariable(0x082481b7, gWidth); // Set ResX + setVariable(0x08248216, gWidth); // Set ResX + } break; + } setVariable(0x0835664d, 0x0000f0e9); // Force set resolution - setVariable(0x08356743, getConfig()->width); // Set ResX - setVariable(0x08356748, getConfig()->height); // Set ResY + setVariable(0x08356743, gWidth); // Set ResX + setVariable(0x08356748, gHeight); // Set ResY // Renderbuffer Resolution - setVariable(0x08248037, getConfig()->width); // Set ResX - setVariable(0x0824802f, getConfig()->height); // Set ResY - setVariable(0x082480f7, getConfig()->width); // Set ResX - setVariable(0x082480ef, getConfig()->height); // Set ResY - setVariable(0x082481b7, getConfig()->width); // Set ResX - setVariable(0x082481af, getConfig()->height); // Set ResY - setVariable(0x08248216, getConfig()->width); // Set ResX - setVariable(0x0824820e, getConfig()->height); // Set ResY - setVariable(0x082489a7, getConfig()->width); // Set ResX - setVariable(0x0824899f, getConfig()->height); // Set ResY - setVariable(0x08248a32, getConfig()->width); // Set ResX - setVariable(0x08248a2a, getConfig()->height); // Set ResY + setVariable(0x08248037, gWidth); // Set ResX + setVariable(0x0824802f, gHeight); // Set ResY + setVariable(0x082480f7, gWidth); // Set ResX + setVariable(0x082480ef, gHeight); // Set ResY + setVariable(0x082481b7, gWidth); // Set ResX + setVariable(0x082481af, gHeight); // Set ResY + setVariable(0x08248216, gWidth); // Set ResX + setVariable(0x0824820e, gHeight); // Set ResY + setVariable(0x082489a7, gWidth); // Set ResX + setVariable(0x0824899f, gHeight); // Set ResY + setVariable(0x08248a32, gWidth); // Set ResX + setVariable(0x08248a2a, gHeight); // Set ResY idDisplayTextureCAVEAddress = (void *)0x08318ab0 + 5; detourFunction(0x08318ab0, idDisplayTexture); @@ -1699,24 +1769,33 @@ int initResolutionPatches() break; case INITIALD_4_REVC: { - if (getConfig()->width == 1360 && getConfig()->height == 768) + if (gWidth == 1360 && gHeight == 768) + { + if (getConfig()->boostRenderRes) + { + setVariable(0x08248ad7, gWidth); // Set ResX + setVariable(0x08248b97, gWidth); // Set ResX + setVariable(0x08248c57, gWidth); // Set ResX + setVariable(0x08248cb6, gWidth); // Set ResX + } break; + } setVariable(0x0835eebd, 0x0000f0e9); // Force set resolution - setVariable(0x0835efb3, getConfig()->width); // Set ResX - setVariable(0x0835efb8, getConfig()->height); // Set ResY + setVariable(0x0835efb3, gWidth); // Set ResX + setVariable(0x0835efb8, gHeight); // Set ResY // Renderbuffer Resolution - setVariable(0x08248ad7, getConfig()->width); // Set ResX - setVariable(0x08248acf, getConfig()->height); // Set ResY - setVariable(0x08248b97, getConfig()->width); // Set ResX - setVariable(0x08248b8f, getConfig()->height); // Set ResY - setVariable(0x08248c57, getConfig()->width); // Set ResX - setVariable(0x08248c4f, getConfig()->height); // Set ResY - setVariable(0x08248cb6, getConfig()->width); // Set ResX - setVariable(0x08248cae, getConfig()->height); // Set ResY - setVariable(0x08249447, getConfig()->width); // Set ResX - setVariable(0x0824943f, getConfig()->height); // Set ResY - setVariable(0x082494d2, getConfig()->width); // Set ResX - setVariable(0x082494ca, getConfig()->height); // Set ResY + setVariable(0x08248ad7, gWidth); // Set ResX + setVariable(0x08248acf, gHeight); // Set ResY + setVariable(0x08248b97, gWidth); // Set ResX + setVariable(0x08248b8f, gHeight); // Set ResY + setVariable(0x08248c57, gWidth); // Set ResX + setVariable(0x08248c4f, gHeight); // Set ResY + setVariable(0x08248cb6, gWidth); // Set ResX + setVariable(0x08248cae, gHeight); // Set ResY + setVariable(0x08249447, gWidth); // Set ResX + setVariable(0x0824943f, gHeight); // Set ResY + setVariable(0x082494d2, gWidth); // Set ResX + setVariable(0x082494ca, gHeight); // Set ResY idDisplayTextureCAVEAddress = (void *)0x0831ea60 + 5; detourFunction(0x0831ea60, idDisplayTexture); @@ -1733,24 +1812,33 @@ int initResolutionPatches() break; case INITIALD_4_REVD: { - if (getConfig()->width == 1360 && getConfig()->height == 768) + if (gWidth == 1360 && gHeight == 768) + { + if (getConfig()->boostRenderRes) + { + setVariable(0x08248f47, gWidth); // Set ResX + setVariable(0x08249007, gWidth); // Set ResX + setVariable(0x082490c7, gWidth); // Set ResX + setVariable(0x08249126, gWidth); // Set ResX + } break; + } setVariable(0x0835c55d, 0x0000f0e9); // Force set resolution - setVariable(0x0835c653, getConfig()->width); // Set ResX - setVariable(0x0835c658, getConfig()->height); // Set ResY + setVariable(0x0835c653, gWidth); // Set ResX + setVariable(0x0835c658, gHeight); // Set ResY // Renderbuffer Resolution - setVariable(0x08248f47, getConfig()->width); // Set ResX - setVariable(0x08248f3f, getConfig()->height); // Set ResY - setVariable(0x08249007, getConfig()->width); // Set ResX - setVariable(0x08248fff, getConfig()->height); // Set ResY - setVariable(0x082490c7, getConfig()->width); // Set ResX - setVariable(0x082490bf, getConfig()->height); // Set ResY - setVariable(0x08249126, getConfig()->width); // Set ResX - setVariable(0x0824911e, getConfig()->height); // Set ResY - setVariable(0x082498b7, getConfig()->width); // Set ResX - setVariable(0x082498af, getConfig()->height); // Set ResY - setVariable(0x08249942, getConfig()->width); // Set ResX - setVariable(0x0824993a, getConfig()->height); // Set ResY + setVariable(0x08248f47, gWidth); // Set ResX + setVariable(0x08248f3f, gHeight); // Set ResY + setVariable(0x08249007, gWidth); // Set ResX + setVariable(0x08248fff, gHeight); // Set ResY + setVariable(0x082490c7, gWidth); // Set ResX + setVariable(0x082490bf, gHeight); // Set ResY + setVariable(0x08249126, gWidth); // Set ResX + setVariable(0x0824911e, gHeight); // Set ResY + setVariable(0x082498b7, gWidth); // Set ResX + setVariable(0x082498af, gHeight); // Set ResY + setVariable(0x08249942, gWidth); // Set ResX + setVariable(0x0824993a, gHeight); // Set ResY idDisplayTextureCAVEAddress = (void *)0x0831bf90 + 5; detourFunction(0x0831bf90, idDisplayTexture); @@ -1767,24 +1855,33 @@ int initResolutionPatches() break; case INITIALD_4_REVG: { - if (getConfig()->width == 1360 && getConfig()->height == 768) + if (gWidth == 1360 && gHeight == 768) + { + if (getConfig()->boostRenderRes) + { + setVariable(0x08262eda, gWidth); // Set ResX + setVariable(0x08262f9a, gWidth); // Set ResX + setVariable(0x0826305a, gWidth); // Set ResX + setVariable(0x082630b9, gWidth); // Set ResX + } break; + } setVariable(0x08393fbd, 0x0000f0e9); // Force set resolution - setVariable(0x083940b3, getConfig()->width); // Set ResX - setVariable(0x083940b8, getConfig()->height); // Set ResY + setVariable(0x083940b3, gWidth); // Set ResX + setVariable(0x083940b8, gHeight); // Set ResY // Renderbuffer Resolution - setVariable(0x08262eda, getConfig()->width); // Set ResX - setVariable(0x08262ed2, getConfig()->height); // Set ResY - setVariable(0x08262f9a, getConfig()->width); // Set ResX - setVariable(0x08262f92, getConfig()->height); // Set ResY - setVariable(0x0826305a, getConfig()->width); // Set ResX - setVariable(0x08263052, getConfig()->height); // Set ResY - setVariable(0x082630b9, getConfig()->width); // Set ResX - setVariable(0x082630b1, getConfig()->height); // Set ResY - setVariable(0x0826395f, getConfig()->width); // Set ResX - setVariable(0x08263957, getConfig()->height); // Set ResY - setVariable(0x082639ea, getConfig()->width); // Set ResX - setVariable(0x082639e2, getConfig()->height); // Set ResY + setVariable(0x08262eda, gWidth); // Set ResX + setVariable(0x08262ed2, gHeight); // Set ResY + setVariable(0x08262f9a, gWidth); // Set ResX + setVariable(0x08262f92, gHeight); // Set ResY + setVariable(0x0826305a, gWidth); // Set ResX + setVariable(0x08263052, gHeight); // Set ResY + setVariable(0x082630b9, gWidth); // Set ResX + setVariable(0x082630b1, gHeight); // Set ResY + setVariable(0x0826395f, gWidth); // Set ResX + setVariable(0x08263957, gHeight); // Set ResY + setVariable(0x082639ea, gWidth); // Set ResX + setVariable(0x082639e2, gHeight); // Set ResY idDisplayTextureCAVEAddress = (void *)0x083502b0 + 5; detourFunction(0x083502b0, idDisplayTexture); @@ -1798,10 +1895,10 @@ int initResolutionPatches() detourFunction(0x081f2b7e, idDrawBallon); replaceCallAtAddress(0x081f40da, id4DrawText); // Scale Testmode text - if (isTestMode() && getConfig()->width >= 1920) + if (isTestMode() && gWidth >= 1920) { patchMemory(0x089e15d8, "02"); - idTextShift = (getConfig()->width == 1920 ? 27 : ((1920 / getConfig()->width) * 27) + 2); + idTextShift = (gWidth == 1920 ? 27 : ((1920 / gWidth) * 27) + 2); idTestTextAddress = (void *)0x085945c2; replaceCallAtAddress(0x083748ce, idTestText); } @@ -1809,30 +1906,38 @@ int initResolutionPatches() break; case INITIALD_5_EXP: { - if (getConfig()->width == 1360 && getConfig()->height == 768) + bool origRes = (gWidth == 1360 && gHeight == 768); + if (!getConfig()->boostRenderRes && origRes) + { break; - patchMemory(0x0853d8cd, "E9f000"); // Accept different Resolutions - setVariable(0x0853d9c3, getConfig()->width); // Set ResX - setVariable(0x0853d9c8, getConfig()->height); // Set ResY + } + if (gWidth >= 1360 && gHeight >= 768) + { + patchMemory(0x08356054, "bb01000000eb6b"); // Prevents renrer.ini from loading + setVariable(0x08355f30, gWidth); // Framebuffer Main Width + setVariable(0x08355f37, gHeight); // Framebuffer Main Height + setVariable(0x08355fd1, 256); // Framebuffer Road Specular width + setVariable(0x08355fd8, 256); // Framebuffer Road Specular height + setVariable(0x08355ff7, gWidth); // Framebuffer Glare Width + setVariable(0x08355ffe, gHeight); // Framebuffer Glare Height + setVariable(0x08356024, gWidth >> 2); // Framebuffer Reduced width + patchMemory(0x08356049, "00000001"); // Enable Cube Secular + if (origRes) + break; + } + patchMemory(0x0853d8cd, "E9f000"); // Accept different Resolutions + setVariable(0x0853d9c3, gWidth); // Set ResX + setVariable(0x0853d9c8, gHeight); // Set ResY - patchMemory(0x08356054, "bb01000000eb6b"); // Prevents renrer.ini from loading - setVariable(0x08355f30, getConfig()->width); // Framebuffer Main Width - setVariable(0x08355f37, getConfig()->height); // Framebuffer Main Height - setVariable(0x08355fd1, 256); // Framebuffer Road Specular width - setVariable(0x08355fd8, 256); // Framebuffer Road Specular height - setVariable(0x08355ff7, getConfig()->width); // Framebuffer Glare Width - setVariable(0x08355ffe, getConfig()->height); // Framebuffer Glare Height - setVariable(0x08356024, getConfig()->width >> 2); // Framebuffer Reduced width - patchMemory(0x08356049, "00000001"); // Enable Cube Secular // Fix Press start and Insert coins text idDisplayTextureCAVEAddress = (void *)0x084e2470 + 5; detourFunction(0x084e2470, idDisplayTexture); // setViewport for track selection screen - setVariable(0x08215cae, (int)(getConfig()->height * (112.0 / 768))); - setVariable(0x08215cb6, (int)(getConfig()->width * (724.0 / 1315))); - setVariable(0x08215cbe, (int)(getConfig()->height * (592.0 / 768))); - setVariable(0x08215cc6, (int)(getConfig()->width * (962.0 / 1315))); - setVariable(0x08215cce, getConfig()->height); + setVariable(0x08215cae, (int)(gHeight * (112.0 / 768))); + setVariable(0x08215cb6, (int)(gWidth * (724.0 / 1315))); + setVariable(0x08215cbe, (int)(gHeight * (592.0 / 768))); + setVariable(0x08215cc6, (int)(gWidth * (962.0 / 1315))); + setVariable(0x08215cce, gHeight); // FSAA patchMemory(0x0875aaa6, "9090"); patchMemory(0x08788949, "01"); // FSAA Enabled @@ -1844,15 +1949,15 @@ int initResolutionPatches() replaceCallAtAddress(0x08254b68, idBalloonPut); replaceCallAtAddress(0x08254c29, idBalloonPut); // START and VIEW CHANGE Text fix - float explanationScaleX = getConfig()->width - (1360.0 - 815.0); - float explanationScaleY = (getConfig()->height / 768.0) * 680.0; + float explanationScaleX = gWidth - (1360.0 - 815.0); + float explanationScaleY = (gHeight / 768.0) * 680.0; setVariable(0x0826ac45, *(unsigned int *)&explanationScaleY); setVariable(0x0826acbd, *(unsigned int *)&explanationScaleX); // Scale Testmode text - if (isTestMode() && getConfig()->width >= 1920) + if (isTestMode() && gWidth >= 1920) { patchMemory(0x08c55ca0, "02"); - idTextShift = (getConfig()->width == 1920 ? 27 : ((1920 / getConfig()->width) * 27) + 2); + idTextShift = (gWidth == 1920 ? 27 : ((1920 / gWidth) * 27) + 2); idTestTextAddress = (void *)0x08775c1c; replaceCallAtAddress(0x0850853e, idTestText); } @@ -1860,30 +1965,37 @@ int initResolutionPatches() break; case INITIALD_5_EXP_20: { - if (getConfig()->width == 1360 && getConfig()->height == 768) + bool origRes = (gWidth == 1360 && gHeight == 768); + if (!getConfig()->boostRenderRes && origRes) + { break; - patchMemory(0x0855a48d, "E9f000"); // Accept different Resolutions - setVariable(0x0855a583, getConfig()->width); // Set ResX - setVariable(0x0855a588, getConfig()->height); // Set ResY - - patchMemory(0x08363c24, "bb01000000eb6b"); // Prevents renrer.ini from loading - setVariable(0x08363b00, getConfig()->width); // Framebuffer Main Width - setVariable(0x08363b07, getConfig()->height); // Framebuffer Main Height - setVariable(0x08363ba1, 256); // Framebuffer Road Specular width - setVariable(0x08363ba8, 256); // Framebuffer Road Specular height - setVariable(0x08363bc7, getConfig()->width); // Framebuffer Glare Width - setVariable(0x08363bce, getConfig()->height); // Framebuffer Glare Height - setVariable(0x08363bf4, getConfig()->width >> 2); // Framebuffer Reduced width - patchMemory(0x08363c19, "00000001"); // Enable Cube Secular + } + if (gWidth >= 1360 && gHeight >= 768) + { + patchMemory(0x08363c24, "bb01000000eb6b"); // Prevents renrer.ini from loading + setVariable(0x08363b00, gWidth); // Framebuffer Main Width + setVariable(0x08363b07, gHeight); // Framebuffer Main Height + setVariable(0x08363ba1, 256); // Framebuffer Road Specular width + setVariable(0x08363ba8, 256); // Framebuffer Road Specular height + setVariable(0x08363bc7, gWidth); // Framebuffer Glare Width + setVariable(0x08363bce, gHeight); // Framebuffer Glare Height + setVariable(0x08363bf4, gWidth >> 2); // Framebuffer Reduced width + patchMemory(0x08363c19, "00000001"); // Enable Cube Secular + if (origRes) + break; + } + patchMemory(0x0855a48d, "E9f000"); // Accept different Resolutions + setVariable(0x0855a583, gWidth); // Set ResX + setVariable(0x0855a588, gHeight); // Set ResY // Fix Press start and Insert coins text idDisplayTextureCAVEAddress = (void *)0x084fdfa0 + 5; detourFunction(0x084fdfa0, idDisplayTexture); // setViewport for track selection screen - setVariable(0x0821e75e, (int)(getConfig()->height * (112.0 / 768))); - setVariable(0x0821e766, (int)(getConfig()->width * (724.0 / 1315))); - setVariable(0x0821e76e, (int)(getConfig()->height * (592.0 / 768))); - setVariable(0x0821e776, (int)(getConfig()->width * (962.0 / 1315))); - setVariable(0x0821e77e, getConfig()->height); + setVariable(0x0821e75e, (int)(gHeight * (112.0 / 768))); + setVariable(0x0821e766, (int)(gWidth * (724.0 / 1315))); + setVariable(0x0821e76e, (int)(gHeight * (592.0 / 768))); + setVariable(0x0821e776, (int)(gWidth * (962.0 / 1315))); + setVariable(0x0821e77e, gHeight); // FSAA patchMemory(0x087775f6, "9090"); patchMemory(0x087a5499, "01"); // FSAA Enabled @@ -1895,15 +2007,15 @@ int initResolutionPatches() replaceCallAtAddress(0x0825d4e8, idBalloonPut); replaceCallAtAddress(0x0825d5a9, idBalloonPut); // START and VIEW CHANGE Text fix - float explanationScaleX = getConfig()->width - (1360.0 - 815.0); - float explanationScaleY = (getConfig()->height / 768.0) * 680.0; + float explanationScaleX = gWidth - (1360.0 - 815.0); + float explanationScaleY = (gHeight / 768.0) * 680.0; setVariable(0x082737b5, *(unsigned int *)&explanationScaleY); setVariable(0x0827382d, *(unsigned int *)&explanationScaleX); // Scale Testmode text - if (isTestMode() && getConfig()->width >= 1920) + if (isTestMode() && gWidth >= 1920) { patchMemory(0x08ca3d00, "02"); - idTextShift = (getConfig()->width == 1920 ? 27 : ((1920 / getConfig()->width) * 27) + 2); + idTextShift = (gWidth == 1920 ? 27 : ((1920 / gWidth) * 27) + 2); idTestTextAddress = (void *)0x0879276c; replaceCallAtAddress(0x0852528a, idTestText); } @@ -1911,30 +2023,38 @@ int initResolutionPatches() break; case INITIALD_5_EXP_20A: { - if (getConfig()->width == 1360 && getConfig()->height == 768) + bool origRes = (gWidth == 1360 && gHeight == 768); + if (!getConfig()->boostRenderRes && origRes) + { break; - patchMemory(0x0855a6dd, "E9f000"); // Accept different Resolutions - setVariable(0x0855a7d3, getConfig()->width); // Set ResX - setVariable(0x0855a7d8, getConfig()->height); // Set ResY + } + if (gWidth >= 1360 && gHeight >= 768) + { + patchMemory(0x08363d94, "bb01000000eb6b"); // Prevents renrer.ini from loading + setVariable(0x08363c70, gWidth); // Framebuffer Main Width + setVariable(0x08363c77, gHeight); // Framebuffer Main Height + setVariable(0x08363d11, 256); // Framebuffer Road Specular width + setVariable(0x08363d18, 256); // Framebuffer Road Specular height + setVariable(0x08363d37, gWidth); // Framebuffer Glare Width + setVariable(0x08363d3e, gHeight); // Framebuffer Glare Height + setVariable(0x08363d64, gWidth >> 2); // Framebuffer Reduced width + patchMemory(0x08363d89, "00000001"); // Enable Cube Secular + if (origRes) + break; + } + patchMemory(0x0855a6dd, "E9f000"); // Accept different Resolutions + setVariable(0x0855a7d3, gWidth); // Set ResX + setVariable(0x0855a7d8, gHeight); // Set ResY - patchMemory(0x08363d94, "bb01000000eb6b"); // Prevents renrer.ini from loading - setVariable(0x08363c70, getConfig()->width); // Framebuffer Main Width - setVariable(0x08363c77, getConfig()->height); // Framebuffer Main Height - setVariable(0x08363d11, 256); // Framebuffer Road Specular width - setVariable(0x08363d18, 256); // Framebuffer Road Specular height - setVariable(0x08363d37, getConfig()->width); // Framebuffer Glare Width - setVariable(0x08363d3e, getConfig()->height); // Framebuffer Glare Height - setVariable(0x08363d64, getConfig()->width >> 2); // Framebuffer Reduced width - patchMemory(0x08363d89, "00000001"); // Enable Cube Secular // Fix Press start and Insert coins text idDisplayTextureCAVEAddress = (void *)0x084fe1d0 + 5; detourFunction(0x084fe1d0, idDisplayTexture); // setViewport for track selection screen - setVariable(0x0821e8ee, (int)(getConfig()->height * (112.0 / 768))); - setVariable(0x0821e8f6, (int)(getConfig()->width * (724.0 / 1315))); - setVariable(0x0821e8fe, (int)(getConfig()->height * (592.0 / 768))); - setVariable(0x0821e906, (int)(getConfig()->width * (962.0 / 1315))); - setVariable(0x0821e90e, getConfig()->height); + setVariable(0x0821e8ee, (int)(gHeight * (112.0 / 768))); + setVariable(0x0821e8f6, (int)(gWidth * (724.0 / 1315))); + setVariable(0x0821e8fe, (int)(gHeight * (592.0 / 768))); + setVariable(0x0821e906, (int)(gWidth * (962.0 / 1315))); + setVariable(0x0821e90e, gHeight); // FSAA patchMemory(0x08777846, "9090"); patchMemory(0x087a56e9, "01"); // FSAA Enabled @@ -1946,15 +2066,15 @@ int initResolutionPatches() replaceCallAtAddress(0x0825d656, idBalloonPut); replaceCallAtAddress(0x0825d717, idBalloonPut); // START and VIEW CHANGE Text fix - float explanationScaleX = getConfig()->width - (1360.0 - 815.0); - float explanationScaleY = (getConfig()->height / 768.0) * 680.0; + float explanationScaleX = gWidth - (1360.0 - 815.0); + float explanationScaleY = (gHeight / 768.0) * 680.0; setVariable(0x08273915, *(unsigned int *)&explanationScaleY); setVariable(0x0827398d, *(unsigned int *)&explanationScaleX); // Scale Testmode text - if (isTestMode() && getConfig()->width >= 1920) + if (isTestMode() && gWidth >= 1920) { patchMemory(0x08ca3d00, "02"); - idTextShift = (getConfig()->width == 1920 ? 27 : ((1920 / getConfig()->width) * 27) + 2); + idTextShift = (gWidth == 1920 ? 27 : ((1920 / gWidth) * 27) + 2); idTestTextAddress = (void *)0x087929bc; replaceCallAtAddress(0x085254ea, idTestText); } @@ -1962,30 +2082,38 @@ int initResolutionPatches() break; case INITIALD_5_JAP_REVA: // ID5 - DVP-0070A { - if (getConfig()->width == 1360 && getConfig()->height == 768) + bool origRes = (gWidth == 1360 && gHeight == 768); + if (!getConfig()->boostRenderRes && origRes) + { break; - patchMemory(0x0853ccdd, "E9f000"); // Accept different Resolutions - setVariable(0x0853cdd3, getConfig()->width); // Set ResX - setVariable(0x0853cdd8, getConfig()->height); // Set ResY + } + if (gWidth >= 1360 && gHeight >= 768) + { + patchMemory(0x083557f4, "bb01000000eb6b"); // Prevents renrer.ini from loading + setVariable(0x083556d0, gWidth); // Framebuffer Main Width + setVariable(0x083556d7, gHeight); // Framebuffer Main Height + setVariable(0x08355771, 256); // Framebuffer Road Specular width + setVariable(0x08355778, 256); // Framebuffer Road Specular height + setVariable(0x08355797, gWidth); // Framebuffer Glare Width + setVariable(0x0835579e, gHeight); // Framebuffer Glare Height + setVariable(0x083557c4, gWidth >> 2); // Framebuffer Reduced width + patchMemory(0x083557e9, "00000001"); // Enable Cube Secular + if (origRes) + break; + } + patchMemory(0x0853ccdd, "E9f000"); // Accept different Resolutions + setVariable(0x0853cdd3, gWidth); // Set ResX + setVariable(0x0853cdd8, gHeight); // Set ResY - patchMemory(0x083557f4, "bb01000000eb6b"); // Prevents renrer.ini from loading - setVariable(0x083556d0, getConfig()->width); // Framebuffer Main Width - setVariable(0x083556d7, getConfig()->height); // Framebuffer Main Height - setVariable(0x08355771, 256); // Framebuffer Road Specular width - setVariable(0x08355778, 256); // Framebuffer Road Specular height - setVariable(0x08355797, getConfig()->width); // Framebuffer Glare Width - setVariable(0x0835579e, getConfig()->height); // Framebuffer Glare Height - setVariable(0x083557c4, getConfig()->width >> 2); // Framebuffer Reduced width - patchMemory(0x083557e9, "00000001"); // Enable Cube Secular // Fix Press start and Insert coins text idDisplayTextureCAVEAddress = (void *)0x084e1770 + 5; detourFunction(0x084e1770, idDisplayTexture); // setViewport for track selection screen - setVariable(0x08214b9e, (int)(getConfig()->height * (112.0 / 768))); - setVariable(0x08214ba6, (int)(getConfig()->width * (724.0 / 1315))); - setVariable(0x08214bae, (int)(getConfig()->height * (592.0 / 768))); - setVariable(0x08214bb6, (int)(getConfig()->width * (962.0 / 1315))); - setVariable(0x08214bbe, getConfig()->height); + setVariable(0x08214b9e, (int)(gHeight * (112.0 / 768))); + setVariable(0x08214ba6, (int)(gWidth * (724.0 / 1315))); + setVariable(0x08214bae, (int)(gHeight * (592.0 / 768))); + setVariable(0x08214bb6, (int)(gWidth * (962.0 / 1315))); + setVariable(0x08214bbe, gHeight); // FSAA patchMemory(0x08759eb6, "9090"); patchMemory(0x08787d59, "01"); // FSAA Enabled @@ -1997,15 +2125,15 @@ int initResolutionPatches() replaceCallAtAddress(0x08253b48, idBalloonPut); replaceCallAtAddress(0x08253c09, idBalloonPut); // START and VIEW CHANGE Text fix - float explanationScaleX = getConfig()->width - (1360.0 - 815.0); - float explanationScaleY = (getConfig()->height / 768.0) * 680.0; + float explanationScaleX = gWidth - (1360.0 - 815.0); + float explanationScaleY = (gHeight / 768.0) * 680.0; setVariable(0x08269c25, *(unsigned int *)&explanationScaleY); setVariable(0x08269c9d, *(unsigned int *)&explanationScaleX); // Scale Testmode text - if (isTestMode() && getConfig()->width >= 1920) + if (isTestMode() && gWidth >= 1920) { patchMemory(0x08c55b80, "02"); - idTextShift = (getConfig()->width == 1920 ? 27 : ((1920 / getConfig()->width) * 27) + 2); + idTextShift = (gWidth == 1920 ? 27 : ((1920 / gWidth) * 27) + 2); idTestTextAddress = (void *)0x0877502c; replaceCallAtAddress(0x0850783e, idTestText); } @@ -2013,30 +2141,38 @@ int initResolutionPatches() break; case INITIALD_5_JAP_REVF: // ID5 - DVP-0070F { - if (getConfig()->width == 1360 && getConfig()->height == 768) + bool origRes = (gWidth == 1360 && gHeight == 768); + if (!getConfig()->boostRenderRes && origRes) + { break; - patchMemory(0x08556bbd, "E9f000"); // Accept different Resolutions - setVariable(0x08556cb3, getConfig()->width); // Set ResX - setVariable(0x08556cb8, getConfig()->height); // Set ResY + } + if (gWidth >= 1360 && gHeight >= 768) + { + patchMemory(0x08364484, "bb01000000eb6b"); // Prevents renrer.ini from loading + setVariable(0x08364360, gWidth); // Framebuffer Main Width + setVariable(0x08364367, gHeight); // Framebuffer Main Height + setVariable(0x08364401, 256); // Framebuffer Road Specular width + setVariable(0x08364408, 256); // Framebuffer Road Specular height + setVariable(0x08364427, gWidth); // Framebuffer Glare Width + setVariable(0x0836442e, gHeight); // Framebuffer Glare Height + setVariable(0x08364454, gWidth >> 2); // Framebuffer Reduced width + patchMemory(0x08364479, "00000001"); // Enable Cube Secular + if (origRes) + break; + } + patchMemory(0x08556bbd, "E9f000"); // Accept different Resolutions + setVariable(0x08556cb3, gWidth); // Set ResX + setVariable(0x08556cb8, gHeight); // Set ResY - patchMemory(0x08364484, "bb01000000eb6b"); // Prevents renrer.ini from loading - setVariable(0x08364360, getConfig()->width); // Framebuffer Main Width - setVariable(0x08364367, getConfig()->height); // Framebuffer Main Height - setVariable(0x08364401, 256); // Framebuffer Road Specular width - setVariable(0x08364408, 256); // Framebuffer Road Specular height - setVariable(0x08364427, getConfig()->width); // Framebuffer Glare Width - setVariable(0x0836442e, getConfig()->height); // Framebuffer Glare Height - setVariable(0x08364454, getConfig()->width >> 2); // Framebuffer Reduced width - patchMemory(0x08364479, "00000001"); // Enable Cube Secular // Fix Press start and Insert coins text idDisplayTextureCAVEAddress = (void *)0x084fa3c0 + 5; detourFunction(0x084fa3c0, idDisplayTexture); // setViewport for track selection screen - setVariable(0x0821ec6e, (int)(getConfig()->height * (112.0 / 768))); - setVariable(0x0821ec76, (int)(getConfig()->width * (724.0 / 1315))); - setVariable(0x0821ec7e, (int)(getConfig()->height * (592.0 / 768))); - setVariable(0x0821ec86, (int)(getConfig()->width * (962.0 / 1315))); - setVariable(0x0821ec8e, getConfig()->height); + setVariable(0x0821ec6e, (int)(gHeight * (112.0 / 768))); + setVariable(0x0821ec76, (int)(gWidth * (724.0 / 1315))); + setVariable(0x0821ec7e, (int)(gHeight * (592.0 / 768))); + setVariable(0x0821ec86, (int)(gWidth * (962.0 / 1315))); + setVariable(0x0821ec8e, gHeight); // FSAA patchMemory(0x08773d26, "9090"); patchMemory(0x087a1bc9, "01"); // FSAA Enabled @@ -2048,15 +2184,15 @@ int initResolutionPatches() replaceCallAtAddress(0x0825d9f8, idBalloonPut); replaceCallAtAddress(0x0825dab9, idBalloonPut); // START and VIEW CHANGE Text fix - float explanationScaleX = getConfig()->width - (1360.0 - 815.0); - float explanationScaleY = (getConfig()->height / 768.0) * 680.0; + float explanationScaleX = gWidth - (1360.0 - 815.0); + float explanationScaleY = (gHeight / 768.0) * 680.0; setVariable(0x08273ce5, *(unsigned int *)&explanationScaleY); setVariable(0x08273d5d, *(unsigned int *)&explanationScaleX); // Scale Testmode text - if (isTestMode() && getConfig()->width >= 1920) + if (isTestMode() && gWidth >= 1920) { patchMemory(0x08c92040, "02"); - idTextShift = (getConfig()->width == 1920 ? 27 : ((1920 / getConfig()->width) * 27) + 2); + idTextShift = (gWidth == 1920 ? 27 : ((1920 / gWidth) * 27) + 2); idTestTextAddress = (void *)0x0878ee9c; replaceCallAtAddress(0x08521aaa, idTestText); } @@ -2064,24 +2200,67 @@ int initResolutionPatches() break; case LETS_GO_JUNGLE_REVA: { - setVariable(0x082e1323, getConfig()->width); // Set ResX - setVariable(0x082e1330, getConfig()->height); // Set ResY + setVariable(0x082e1323, gWidth); // Set ResX + setVariable(0x082e1330, gHeight); // Set ResY // FSAA patchMemory(0x082e12ff, "01"); + + // Render Res + setVariable(0x080ce59a, gWidth); // 800 + setVariable(0x080ce5a4, gHeight); // 600 } break; case LETS_GO_JUNGLE: { - setVariable(0x082E006b, getConfig()->width); // Set ResX - setVariable(0x082E0078, getConfig()->height); // Set ResY + setVariable(0x082E006b, gWidth); // Set ResX + setVariable(0x082E0078, gHeight); // Set ResY // FSAA patchMemory(0x082e0047, "01"); + + // Render Res + setVariable(0x080ce2f2, gWidth); // 800 + setVariable(0x080ce2fc, gHeight); // 600 } break; case LETS_GO_JUNGLE_SPECIAL: { - // setVariable(0x08303C4B, 0x00000780); // Set ResX - // setVariable(0x08303C58, 0x00000438); // Set ResY + if ((gWidth == 1024 && gHeight == 768) || (gWidth == 2048 && gHeight == 768)) + break; + setVariable(0x08303C4B, gWidth * 2); // Set ResX Width x 2 + setVariable(0x08303C58, gHeight); // Set ResY + + setVariable(0x080d6e8c, gWidth); // 1024 + setVariable(0x080d6e96, gHeight); // 768 + + setVariable(0x080d6ea0, gWidth); // 800 + setVariable(0x080d6eaa, gHeight); // 600 + + setVariable(0x080cf6ac, gWidth); // 800 + setVariable(0x080cf6b9, gHeight); // 600 + patchMemory(0x08303c27, "01"); // FSAA + + float newWidthLGJ = (float)gWidth; + float newHeightLGJ = (float)gHeight; + uint32_t *newWidthPtrLGJ = (uint32_t *)&newWidthLGJ; + uint32_t *newHeightPtrLGJ = (uint32_t *)&newHeightLGJ; + + float newWidth2LGJ = (float)gWidth * 2.0; + uint32_t *newWidth2PtrLGJ = (uint32_t *)&newWidth2LGJ; + unsigned int address = 0x080cb730; + + float newWidthHLGJ = (float)gWidth / 2.0; + uint32_t *newWidthHPtrLGJ = (uint32_t *)&newWidthHLGJ; + float newWidthSLGJ = 1360.0 / (float)gWidth; + uint32_t *newWidthSPtrLGJ = (uint32_t *)&newWidthSLGJ; + unsigned int addressC = 0x080cb3be; + + setVariable(0x082dcd10, (size_t)newHeightPtrLGJ); // LGJSceneManagerbegin + + setVariable(address, (size_t)newHeightPtrLGJ); // StageSelect + setVariable(address + 0xF, (size_t)newWidth2PtrLGJ); + + setVariable(addressC, (size_t)newWidthHPtrLGJ); // StageSelectonCursor + setVariable(addressC + 0x8, (size_t)newWidthSPtrLGJ); } break; case MJ4_REVG: @@ -2089,27 +2268,27 @@ int initResolutionPatches() // Not Supported yet. // patchMemory(0x080524a1, "01"); // Enable Anti Alias // patchMemory(0x08053668, "b80a000000"); // Skips resolution set by the Dip Switches. - // vf5FSwidth = (getConfig()->height * 4) / 3; + // vf5FSwidth = (gHeight * 4) / 3; // setVariable(0x08901598, vf5FSwidth); - // setVariable(0x0890159c, getConfig()->height); + // setVariable(0x0890159c, gHeight); // setVariable(0x089015a4, vf5FSwidth); - // setVariable(0x089015a8, getConfig()->height); + // setVariable(0x089015a8, gHeight); // setVariable(0x08901544, vf5FSwidth); - // setVariable(0x08901548, getConfig()->height); + // setVariable(0x08901548, gHeight); // setVariable(0x0890158c, vf5FSwidth); - // setVariable(0x08901590, getConfig()->height); + // setVariable(0x08901590, gHeight); } break; case OUTRUN_2_SP_SDX: { - if (getConfig()->width <= 800 && getConfig()->height <= 480) + if (gWidth <= 800 && gHeight <= 480) break; // If resolution is not the native of the game this patch kind of fix the Sun when the LensGlare effect is // shown. - if ((getConfig()->width > 800) && (getConfig()->height > 480)) + if ((gWidth > 800) && (gHeight > 480)) { patchMemory(0x080e8e72, "9090909090"); // removes a call to a light function patchMemory(0x080e8e83, "9090909090"); // removes a call to a light function @@ -2125,17 +2304,17 @@ int initResolutionPatches() break; case OUTRUN_2_SP_SDX_TEST: { - setVariable(0x0804a490, getConfig()->width); - setVariable(0x0804a4ad, getConfig()->height); + setVariable(0x0804a490, gWidth); + setVariable(0x0804a4ad, gHeight); } break; case OUTRUN_2_SP_SDX_REVA: { - if (getConfig()->width <= 800 && getConfig()->height <= 480) + if (gWidth <= 800 && gHeight <= 480) break; // If resolution is not the native of the game this patch kind of fix the Sun when the LensGlare effect is // shown. - if ((getConfig()->width > 800) && (getConfig()->height > 480)) + if ((gWidth > 800) && (gHeight > 480)) { patchMemory(0x080e8e06, "9090909090"); // removes a call to a light function patchMemory(0x080e8e17, "9090909090"); // removes a call to a light function @@ -2169,21 +2348,26 @@ int initResolutionPatches() case OUTRUN_2_SP_SDX_REVA_TEST: case OUTRUN_2_SP_SDX_REVA_TEST2: { - if (getConfig()->width <= 800 && getConfig()->height <= 480) + if (gWidth <= 800 && gHeight <= 480) break; - setVariable(0x0804a490, getConfig()->width); - setVariable(0x0804a4ad, getConfig()->height); + setVariable(0x0804a490, gWidth); + setVariable(0x0804a4ad, gHeight); } break; case PRIMEVAL_HUNT: { - if (getConfig()->width <= 640 && getConfig()->height <= 480) + if (gWidth <= 1280 && gHeight <= 480) break; + + if (isTestMode()) + { + EmulatorConfig *config = getConfig(); + config->phMode = 2; + } phX = 0; phY = 0; - phW = getConfig()->width; - phH = getConfig()->height; - int phX2, phY2, phW2, phH2; + phW = gWidth; + phH = gHeight; switch (getConfig()->phMode) { case 0: @@ -2194,8 +2378,8 @@ int initResolutionPatches() { if (getConfig()->keepAspectRatio) { - phX = (getConfig()->width - (getConfig()->height / 3) * 4) / 2; - phW = (getConfig()->height / 3) * 4; + phX = (gWidth - (gHeight / 3) * 4) / 2; + phW = (gHeight / 3) * 4; } phW2 = 0; phH2 = 0; @@ -2207,8 +2391,8 @@ int initResolutionPatches() { if (getConfig()->keepAspectRatio) { - phH = ((getConfig()->width / 2) / 4) * 3; - phY = (getConfig()->height - phH) / 2; + phH = ((gWidth / 2) / 4) * 3; + phY = (gHeight - phH) / 2; } phX = 0; phW = phW / 2; @@ -2222,26 +2406,26 @@ int initResolutionPatches() { // We always force 4:3 aspect ratio for this mode. phX = 0; - phW = (getConfig()->height / 3) * 4; - phH2 = ((getConfig()->width - phW) / 4) * 3; + phW = (gHeight / 3) * 4; + phH2 = ((gWidth - phW) / 4) * 3; phX2 = phW; phY2 = (phH - phH2) / 2; - phW2 = getConfig()->width - phW; + phW2 = gWidth - phW; } break; - case 4: + case 4: // 3ds Mode 1 (Small screen to the bottom) { // We always force 4:3 aspect ratio for this mode. - phW = (getConfig()->height / 3) * 4; - phX2 = (getConfig()->width / 2) - ((getConfig()->width - phW) / 2); - phW2 = getConfig()->width - phW; + phW = (gHeight / 3) * 4; + phX2 = (gWidth / 2) - ((gWidth - phW) / 2); + phW2 = gWidth - phW; phY2 = 0; // phH - ((phW2 / 4) * 3); phH2 = (phW2 / 4) * 3; phW = phW - phW2; phH = phH - phH2; - phX = (getConfig()->width - (phH / 3) * 4) / 2; + phX = (gWidth - (phH / 3) * 4) / 2; phY = phH2; } break; @@ -2250,7 +2434,6 @@ int initResolutionPatches() setVariable(0x0805b0fd, phY); // Y 1st screen setVariable(0x0805b0f5, phW); // Width 1st screen setVariable(0x0805b0ed, phH); // Height 1st screen - setVariable(0x0805afa2, phX2); // X 2nd screen setVariable(0x0805af9b, phY2); // Y 2st screen setVariable(0x0805af93, phW2); // Width 2nd screen @@ -2259,16 +2442,34 @@ int initResolutionPatches() detourFunction(0x0804c628, glClearColorPH); if (getConfig()->phMode == 4) // In mode 4, the screens are inverted. phY = 0; + + // Test Menu + if (isTestMode()) + { + setVariable(0x0807f95d, gHeight); // test HxW + setVariable(0x0807f965, gWidth); + + setVariable(0x08055d3e, gHeight); // text right screen HxW + setVariable(0x08055d46, gWidth / 2); + } } break; case RAMBO: { - if (getConfig()->width <= 1360 && getConfig()->height <= 768) + if (gWidth == 1360 && gHeight == 768) + { + if (getConfig()->boostRenderRes) + setVariable(0x08416df0, gWidth); // render res break; - patchMemory(0x080c70d0, "9090909090"); // setresolutiontype - setVariable(0x08416df0, getConfig()->width); // render res - setVariable(0x08416d60, getConfig()->width); // main res - setVariable(0x08416d64, getConfig()->height); + } + else if (gWidth == 640 && gHeight == 480) + { + break; + } + patchMemory(0x080c70d0, "9090909090"); // setresolutiontype + setVariable(0x08416df0, gWidth); // render res + setVariable(0x08416d60, gWidth); // main res + setVariable(0x08416d64, gHeight); patchMemory(0x08416d68, "5005"); // Allwinres patchMemory(0x08416d6c, "0003"); @@ -2281,8 +2482,8 @@ int initResolutionPatches() { patchMemory(0x08051c2b, "01"); // Enable Anti Alias patchMemory(0x08052d58, "b80a000000"); // Skips resolution set by the Dip Switches. - setVariable(0x083c7db8, getConfig()->width); - setVariable(0x083c7dbc, getConfig()->height); + setVariable(0x083c7db8, gWidth); + setVariable(0x083c7dbc, gHeight); patchMemory(0x083c7dc0, "00"); } break; @@ -2294,8 +2495,8 @@ int initResolutionPatches() patchMemory(0x08050c12, "07"); patchMemory(0x08050c25, "07"); patchMemory(0x08050c37, "07"); - setVariable(0x08064611, getConfig()->width); - setVariable(0x080645c6, getConfig()->height); + setVariable(0x08064611, gWidth); + setVariable(0x080645c6, gHeight); } break; case SEGABOOT_2_4: @@ -2307,103 +2508,124 @@ int initResolutionPatches() patchMemory(0x080597c7, "07"); patchMemory(0x08059780, "07"); patchMemory(0x08059768, "07"); - setVariable(0x0809129d, getConfig()->width); - setVariable(0x08091252, getConfig()->height); + setVariable(0x0809129d, gWidth); + setVariable(0x08091252, gHeight); } break; case SEGA_RACE_TV: { - if (getConfig()->width == 640 && getConfig()->height == 480) + if (gWidth == 640 && gHeight == 480) break; if (getConfig()->keepAspectRatio) { - srtvX = (getConfig()->width - (getConfig()->height / 3) * 4) / 2; - srtvW = (getConfig()->height / 3) * 4; + srtvX = (gWidth - (gHeight / 3) * 4) / 2; + srtvW = (gHeight / 3) * 4; } else { - srtvW = getConfig()->width; + srtvW = gWidth; } - srtvH = getConfig()->height; + srtvH = gHeight; } break; case THE_HOUSE_OF_THE_DEAD_4_REVA: { - if (getConfig()->width <= 1280 && getConfig()->height <= 768) + if (gWidth == 1280 && gHeight == 768) + { + if (getConfig()->boostRenderRes) + setVariable(0x084c9dbc, 1280); + return 0; + } + else if (gWidth == 640 && gHeight == 480) + { break; + } patchMemory(0x0804d142, "9090909090"); // setresolutiontype // patchMemory(0x084c9dbc, "0005"); // patchMemory(0x08448458, "0005"); // patchMemory(0x0844845c, "0003"); - setVariable(0x084c9dbc, getConfig()->width); - setVariable(0x08448458, getConfig()->width); - setVariable(0x0844845c, getConfig()->height); + setVariable(0x084c9dbc, gWidth); + setVariable(0x08448458, gWidth); + setVariable(0x0844845c, gHeight); patchMemory(0x08448460, "0005"); patchMemory(0x08448464, "0003"); patchMemory(0x0817ff6d, "e80ed5ecff"); // call crtgetresolution patchMemory(0x08448468, "0005"); // set crtgetresolution to 640x480 patchMemory(0x0844846c, "0003"); - setVariable(0x08448338, getConfig()->width); - setVariable(0x0844833c, getConfig()->height); + setVariable(0x08448338, gWidth); + setVariable(0x0844833c, gHeight); detourFunction(0x0804c024, glVertex3fHOD4); - detourFunction(0x0804ca54, glBindTextureGE); + detourFunction(0x0804ca54, myGlBindTexture); } break; case THE_HOUSE_OF_THE_DEAD_4_REVB: { - if (getConfig()->width <= 1280 && getConfig()->height <= 768) + if (gWidth == 1280 && gHeight == 768) + { + if (getConfig()->boostRenderRes) + setVariable(0x084c3a9c, 1280); + return 0; + } + else if (gWidth == 640 && gHeight == 480) + { break; + } patchMemory(0x0804d174, "9090909090"); // setresolutiontype - setVariable(0x084c3a9c, getConfig()->width); - setVariable(0x08443118, getConfig()->width); - setVariable(0x0844311c, getConfig()->height); + setVariable(0x084c3a9c, gWidth); + setVariable(0x08443118, gWidth); + setVariable(0x0844311c, gHeight); patchMemory(0x08443120, "0005"); patchMemory(0x08443124, "0003"); patchMemory(0x0818080d, "e89eccecff"); // call crtgetresolution patchMemory(0x08443128, "0005"); // set crtgetresolution to 640x480 patchMemory(0x0844312c, "0003"); - setVariable(0x08442ff8, getConfig()->width); - setVariable(0x08442ffc, getConfig()->height); + setVariable(0x08442ff8, gWidth); + setVariable(0x08442ffc, gHeight); detourFunction(0x0804c014, glVertex3fHOD4); - detourFunction(0x0804ca84, glBindTextureGE); + detourFunction(0x0804ca84, myGlBindTexture); } break; case THE_HOUSE_OF_THE_DEAD_4_REVC: { - if (getConfig()->width <= 1280 && getConfig()->height <= 768) + if (gWidth == 1280 && gHeight == 768) { - setVariable(0x084c3a9c, 1280); + if (getConfig()->boostRenderRes) + setVariable(0x084c3a9c, 1280); return 0; } + else if (gWidth == 640 && gHeight == 480) + { + break; + } patchMemory(0x0804d174, "9090909090"); // setresolutiontype - setVariable(0x084c3a9c, getConfig()->width); - setVariable(0x08443118, getConfig()->width); - setVariable(0x0844311c, getConfig()->height); + setVariable(0x084c3a9c, gWidth); + setVariable(0x08443118, gWidth); + setVariable(0x0844311c, gHeight); patchMemory(0x08443120, "0005"); // gallwinres (2D) patchMemory(0x08443124, "0003"); patchMemory(0x0818080d, "e89eccecff"); // sideselect fix patchMemory(0x08443128, "0005"); patchMemory(0x0844312c, "0003"); - setVariable(0x08442ff8, getConfig()->width); - setVariable(0x08442ffc, getConfig()->height); + setVariable(0x08442ff8, gWidth); + setVariable(0x08442ffc, gHeight); detourFunction(0x0804c014, glVertex3fHOD4); - detourFunction(0x0804ca84, glBindTextureGE); + detourFunction(0x0804ca84, myGlBindTexture); } break; case THE_HOUSE_OF_THE_DEAD_4_SPECIAL: { - if (getConfig()->width <= 1024 && getConfig()->height <= 768) + if (gWidth <= 1024 && gHeight <= 768) break; patchMemory(0x0804d2f4, "9090909090"); // setresolutiontype - setVariable(0x084563c4, getConfig()->width); - setVariable(0x08424448, getConfig()->width); - setVariable(0x0842444c, getConfig()->height); + setVariable(0x084563c4, gWidth); + setVariable(0x08424448, gWidth); + setVariable(0x0842444c, gHeight); patchMemory(0x0815bfa9, "e8de7f0100"); // sideselect fix patchMemory(0x08424450, "0004"); patchMemory(0x08424454, "0003"); @@ -2411,12 +2633,12 @@ int initResolutionPatches() break; case THE_HOUSE_OF_THE_DEAD_4_SPECIAL_REVB: { - if (getConfig()->width <= 1024 && getConfig()->height <= 768) + if (gWidth <= 1024 && gHeight <= 768) break; patchMemory(0x0804d7e2, "9090909090"); // setresolutiontype - setVariable(0x084c35c4, getConfig()->width); - setVariable(0x08491648, getConfig()->width); - setVariable(0x0849164c, getConfig()->height); + setVariable(0x084c35c4, gWidth); + setVariable(0x08491648, gWidth); + setVariable(0x0849164c, gHeight); patchMemory(0x081b268f, "e8264d0200"); // sideselect fix patchMemory(0x08491650, "0004"); patchMemory(0x08491654, "0003"); @@ -2424,159 +2646,185 @@ int initResolutionPatches() break; case THE_HOUSE_OF_THE_DEAD_EX: { + if (gWidth == 1360 && gHeight == 768) + { + if (getConfig()->boostRenderRes) + setVariable(0x087aa080, 1280); // render res + break; + } + else if (gWidth == 640 && gHeight == 480) + { + break; + } } break; case TOO_SPICY: { - patchMemory(0x08202b22, "0005"); // render res 1280 + if (gWidth == 1280 && gHeight == 768) + { + if (getConfig()->boostRenderRes) + setVariable(0x08202b22, 1280); // render res + break; + } + else if (gWidth == 640 && gHeight == 480) + { + break; + } + } + break; + case TOO_SPICY_TEST: + { + if (gWidth <= 1280 && gHeight <= 768) + break; + setVariable(0x080565b3, gWidth); + setVariable(0x080565bb, gHeight); } break; case VIRTUA_FIGHTER_5: { - if ((getConfig()->width == 640 && getConfig()->height == 480) || (getConfig()->width == 1280 && getConfig()->height == 768)) + if ((gWidth == 640 && gHeight == 480) || (gWidth == 1280 && gHeight == 768)) return 0; patchMemory(0x08054057, "b80a000000"); // Skips resolution set by the Dip Switches. - setVariable(0x0847cf58, getConfig()->width); - setVariable(0x0847cf5c, getConfig()->height); + setVariable(0x0847cf58, gWidth); + setVariable(0x0847cf5c, gHeight); replaceCallAtAddress(0x080d40c4, vf5WidthFix); } break; case VIRTUA_FIGHTER_5_EXPORT: { - if ((getConfig()->width == 640 && getConfig()->height == 480) || (getConfig()->width == 1280 && getConfig()->height == 768)) + if ((gWidth == 640 && gHeight == 480) || (gWidth == 1280 && gHeight == 768)) break; patchMemory(0x08052b97, "01"); // Enable Anti Alias patchMemory(0x08053c67, "b80a000000"); // Skips resolution set by the Dip Switches. - setVariable(0x085259f8, getConfig()->width); - setVariable(0x085259fc, getConfig()->height); + setVariable(0x085259f8, gWidth); + setVariable(0x085259fc, gHeight); } break; case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVA: { - if ((getConfig()->width == 640 && getConfig()->height == 480) || (getConfig()->width == 1280 && getConfig()->height == 768)) + if ((gWidth == 640 && gHeight == 480) || (gWidth == 1280 && gHeight == 768)) break; patchMemory(0x08054b5e, "01"); // Enable Anti Alias patchMemory(0x08055980, "b80a000000"); // Skips resolution set by the Dip Switches. - vf5FSwidth = (getConfig()->height * 5) / 3; + vf5FSwidth = (gHeight * 5) / 3; setVariable(0x088b2bd8, vf5FSwidth); - setVariable(0x088b2bdc, getConfig()->height); - setVariable(0x088b2bec, getConfig()->width); - setVariable(0x088b2bf0, getConfig()->height); + setVariable(0x088b2bdc, gHeight); + setVariable(0x088b2bec, gWidth); + setVariable(0x088b2bf0, gHeight); } break; case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB: { - if ((getConfig()->width == 640 && getConfig()->height == 480) || (getConfig()->width == 1280 && getConfig()->height == 768)) + if ((gWidth == 640 && gHeight == 480) || (gWidth == 1280 && gHeight == 768)) break; patchMemory(0x080548c4, "01"); // Enable Anti Alias patchMemory(0x080556e6, "b80a000000"); // Skips resolution set by the Dip Switches. - vf5FSwidth = (getConfig()->height * 5) / 3; + vf5FSwidth = (gHeight * 5) / 3; setVariable(0x088d2b78, vf5FSwidth); - setVariable(0x088d2b7c, getConfig()->height); - setVariable(0x088d2b8c, getConfig()->width); - setVariable(0x088d2b90, getConfig()->height); + setVariable(0x088d2b7c, gHeight); + setVariable(0x088d2b8c, gWidth); + setVariable(0x088d2b90, gHeight); } break; case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB_6000: { - if ((getConfig()->width == 640 && getConfig()->height == 480) || (getConfig()->width == 1280 && getConfig()->height == 768)) + if ((gWidth == 640 && gHeight == 480) || (gWidth == 1280 && gHeight == 768)) break; patchMemory(0x08054bfe, "01"); // Enable Anti Alias patchMemory(0x08055a20, "b80a000000"); // Skips resolution set by the Dip Switches. - vf5FSwidth = (getConfig()->height * 5) / 3; + vf5FSwidth = (gHeight * 5) / 3; setVariable(0x088d53d8, vf5FSwidth); - setVariable(0x088d53dc, getConfig()->height); - setVariable(0x088d53ec, getConfig()->width); - setVariable(0x088d53f0, getConfig()->height); + setVariable(0x088d53dc, gHeight); + setVariable(0x088d53ec, gWidth); + setVariable(0x088d53f0, gHeight); } break; case VIRTUA_FIGHTER_5_R: { - if ((getConfig()->width == 640 && getConfig()->height == 480) || (getConfig()->width == 1280 && getConfig()->height == 768)) + if ((gWidth == 640 && gHeight == 480) || (gWidth == 1280 && gHeight == 768)) break; patchMemory(0x0805421a, "01"); // Enable Anti Alias patchMemory(0x080554b0, "b80a000000"); // Skips resolution set by the Dip Switches. - vf5FSwidth = (getConfig()->height * 5) / 3; + vf5FSwidth = (gHeight * 5) / 3; setVariable(0x08767d58, vf5FSwidth); - setVariable(0x08767d5c, getConfig()->height); - setVariable(0x08767d6c, getConfig()->width); - setVariable(0x08767d70, getConfig()->height); + setVariable(0x08767d5c, gHeight); + setVariable(0x08767d6c, gWidth); + setVariable(0x08767d70, gHeight); } break; case VIRTUA_FIGHTER_5_R_REVD: { - if ((getConfig()->width == 640 && getConfig()->height == 480) || (getConfig()->width == 1280 && getConfig()->height == 768)) + if ((gWidth == 640 && gHeight == 480) || (gWidth == 1280 && gHeight == 768)) break; patchMemory(0x080543aa, "01"); // Enable Anti Alias patchMemory(0x080555f6, "b80a000000"); // Skips resolution set by the Dip Switches. - vf5FSwidth = (getConfig()->height * 5) / 3; + vf5FSwidth = (gHeight * 5) / 3; setVariable(0x08822b18, vf5FSwidth); - setVariable(0x08822b1c, getConfig()->height); - setVariable(0x08822b2c, getConfig()->width); - setVariable(0x08822b30, getConfig()->height); + setVariable(0x08822b1c, gHeight); + setVariable(0x08822b2c, gWidth); + setVariable(0x08822b30, gHeight); } break; case VIRTUA_FIGHTER_5_R_REVG: { - if ((getConfig()->width == 640 && getConfig()->height == 480) || (getConfig()->width == 1280 && getConfig()->height == 768)) + if ((gWidth == 640 && gHeight == 480) || (gWidth == 1280 && gHeight == 768)) break; patchMemory(0x0805436a, "01"); // Enable Anti Alias patchMemory(0x0805577c, "b80a000000"); // Skips resolution set by the Dip Switches. - vf5FSwidth = (getConfig()->height * 5) / 3; + vf5FSwidth = (gHeight * 5) / 3; setVariable(0x0887d4d8, vf5FSwidth); - setVariable(0x0887d4dc, getConfig()->height); - setVariable(0x0887d4ec, getConfig()->width); - setVariable(0x0887d4f0, getConfig()->height); + setVariable(0x0887d4dc, gHeight); + setVariable(0x0887d4ec, gWidth); + setVariable(0x0887d4f0, gHeight); } break; case VIRTUA_FIGHTER_5_REVA: { - if ((getConfig()->width == 640 && getConfig()->height == 480) || (getConfig()->width == 1280 && getConfig()->height == 768)) + if ((gWidth == 640 && gHeight == 480) || (gWidth == 1280 && gHeight == 768)) break; patchMemory(0x8053167, "01"); // Enable Anti Alias patchMemory(0x080541af, "b80a000000"); // Skips resolution set by the Dip Switches. - setVariable(0x08487df8, getConfig()->width); - setVariable(0x08487dfc, getConfig()->height); + setVariable(0x08487df8, gWidth); + setVariable(0x08487dfc, gHeight); } break; case VIRTUA_FIGHTER_5_REVB: { - if ((getConfig()->width == 640 && getConfig()->height == 480) || (getConfig()->width == 1280 && getConfig()->height == 768)) + if ((gWidth == 640 && gHeight == 480) || (gWidth == 1280 && gHeight == 768)) break; patchMemory(0x08053673, "01"); // Enable Anti Alias patchMemory(0x080546cf, "b80a000000"); // Skips resolution set by the Dip Switches. - setVariable(0x08536bb8, getConfig()->width); - setVariable(0x08536bbc, getConfig()->height); + setVariable(0x08536bb8, gWidth); + setVariable(0x08536bbc, gHeight); } break; case VIRTUA_FIGHTER_5_REVE: // Also the public REV C version { - if ((getConfig()->width == 640 && getConfig()->height == 480) || (getConfig()->width == 1280 && getConfig()->height == 768)) + if ((gWidth == 640 && gHeight == 480) || (gWidth == 1280 && gHeight == 768)) break; patchMemory(0x080546c7, "01"); // Enable Anti Alias patchMemory(0x080557a3, "b80a000000"); // Skips resolution set by the Dip Switches. - setVariable(0x085efb18, getConfig()->width); - setVariable(0x085efb1c, getConfig()->height); + setVariable(0x085efb18, gWidth); + setVariable(0x085efb1c, gHeight); } break; - case VIRTUA_TENNIS_3: { - if (getConfig()->width <= 1360 && getConfig()->height <= 768) + if (gWidth <= 1360 && gHeight <= 768) break; patchMemory(0x081759b3, "9090"); - setVariable(0x081759bb, getConfig()->width); - setVariable(0x081759c5, getConfig()->height); + setVariable(0x081759bb, gWidth); + setVariable(0x081759c5, gHeight); // setPerspective - newVT3 = getConfig()->width / 1360.0; + newVT3 = gWidth / 1360.0; intnewVT3PTr = (uint32_t *)&newVT3; setVariable(0x082682b6, (size_t)intnewVT3PTr); // vecToScr_check - newVT3HW = (getConfig()->width / 1360.0) * 320.0; - newVT3HH = (getConfig()->height / 768.0) * 240.0; + newVT3HW = (gWidth / 1360.0) * 320.0; + newVT3HH = (gHeight / 768.0) * 240.0; intnewVT3HWPTr = (uint32_t *)&newVT3HW; intnewVT3HHPTr = (uint32_t *)&newVT3HH; uint32_t addressvt31 = 0x0817a55e; @@ -2586,21 +2834,21 @@ int initResolutionPatches() break; case VIRTUA_TENNIS_3_REVA: { - if (getConfig()->width <= 1360 && getConfig()->height <= 768) + if (gWidth <= 1360 && gHeight <= 768) break; patchMemory(0x081759e3, "9090"); - setVariable(0x081759eb, getConfig()->width); - setVariable(0x081759f5, getConfig()->height); + setVariable(0x081759eb, gWidth); + setVariable(0x081759f5, gHeight); // setPerspective - newVT3 = getConfig()->width / 1360.0; + newVT3 = gWidth / 1360.0; intnewVT3PTr = (uint32_t *)&newVT3; setVariable(0x082682e6, (size_t)intnewVT3PTr); // vecToScr_check - newVT3HW = (getConfig()->width / 1360.0) * 320.0; - newVT3HH = (getConfig()->height / 768.0) * 240.0; + newVT3HW = (gWidth / 1360.0) * 320.0; + newVT3HH = (gHeight / 768.0) * 240.0; intnewVT3HWPTr = (uint32_t *)&newVT3HW; intnewVT3HHPTr = (uint32_t *)&newVT3HH; uint32_t addressvt31 = 0x0817a58e; @@ -2610,21 +2858,21 @@ int initResolutionPatches() break; case VIRTUA_TENNIS_3_REVB: { - if (getConfig()->width <= 1360 && getConfig()->height <= 768) + if (gWidth <= 1360 && gHeight <= 768) break; patchMemory(0x08175ad7, "9090"); - setVariable(0x08175adf, getConfig()->width); - setVariable(0x08175ae9, getConfig()->height); + setVariable(0x08175adf, gWidth); + setVariable(0x08175ae9, gHeight); // setPerspective - newVT3 = getConfig()->width / 1360.0; + newVT3 = gWidth / 1360.0; intnewVT3PTr = (uint32_t *)&newVT3; setVariable(0x082684d2, (size_t)intnewVT3PTr); // vecToScr_check - newVT3HW = (getConfig()->width / 1360.0) * 320.0; - newVT3HH = (getConfig()->height / 768.0) * 240.0; + newVT3HW = (gWidth / 1360.0) * 320.0; + newVT3HH = (gHeight / 768.0) * 240.0; intnewVT3HWPTr = (uint32_t *)&newVT3HW; intnewVT3HHPTr = (uint32_t *)&newVT3HH; uint32_t addressvt31 = 0x0817a77a; @@ -2634,21 +2882,21 @@ int initResolutionPatches() break; case VIRTUA_TENNIS_3_REVC: { - if (getConfig()->width <= 1360 && getConfig()->height <= 768) + if (gWidth <= 1360 && gHeight <= 768) break; patchMemory(0x08175b03, "9090"); - setVariable(0x08175b0b, getConfig()->width); - setVariable(0x08175b15, getConfig()->height); + setVariable(0x08175b0b, gWidth); + setVariable(0x08175b15, gHeight); // setPerspective - newVT3 = getConfig()->width / 1360.0; + newVT3 = gWidth / 1360.0; intnewVT3PTr = (uint32_t *)&newVT3; setVariable(0x082684fe, (size_t)intnewVT3PTr); // vecToScr_check - newVT3HW = (getConfig()->width / 1360.0) * 320.0; - newVT3HH = (getConfig()->height / 768.0) * 240.0; + newVT3HW = (gWidth / 1360.0) * 320.0; + newVT3HH = (gHeight / 768.0) * 240.0; intnewVT3HWPTr = (uint32_t *)&newVT3HW; intnewVT3HHPTr = (uint32_t *)&newVT3HH; uint32_t addressvt31 = 0x0817a7a6; @@ -2658,8 +2906,8 @@ int initResolutionPatches() break; case VIRTUA_TENNIS_3_REVC_TEST: { - setVariable(0x0806fb3b, getConfig()->width); - setVariable(0x0806fb04, getConfig()->height); + setVariable(0x0806fb3b, gWidth); + setVariable(0x0806fb04, gHeight); } break; default: diff --git a/src/lindbergh/sdlcalls.c b/src/lindbergh/sdlcalls.c index 1e26432..946e1c0 100644 --- a/src/lindbergh/sdlcalls.c +++ b/src/lindbergh/sdlcalls.c @@ -14,13 +14,9 @@ #include "input.h" #include "sdlcalls.h" #include "fps_limiter.h" -#define STB_IMAGE_IMPLEMENTATION -#include "stb_image.h" - -#define STBI_ONLY_PNG -#define STBI_SUPPORT_ZLIB -#define STBI_NO_SIMD +#include "customcursor.h" +extern uint32_t gId; bool SDLWindowCreated = false; extern bool GLUTGame; SDL_Window *SDLwindow; @@ -30,6 +26,11 @@ Window x11Window; char SDLgameTitle[256] = {0}; extern fps_limit fpsLimit; +extern void *customCursor; +extern void *phTouchCursor; + +int glutInitialized = 0; + void GLAPIENTRY openglDebugCallback2(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam) { @@ -50,125 +51,32 @@ void GLAPIENTRY openglDebugCallback2(GLenum source, GLenum type, GLuint id, GLen } } -SDL_Surface *createSurfaceFromStb(unsigned char *data, int width, int height, int channels) -{ - Uint32 rmask, gmask, bmask, amask; - - if (channels == 4) - { // RGBA - rmask = 0x000000FF; - gmask = 0x0000FF00; - bmask = 0x00FF0000; - amask = 0xFF000000; - } - else if (channels == 3) - { // RGB - rmask = 0x000000FF; - gmask = 0x0000FF00; - bmask = 0x00FF0000; - amask = 0; - } - else - { - fprintf(stderr, "Unsupported image format with %d channels.\n", channels); - return NULL; - } - - SDL_Surface *surface = SDL_CreateRGBSurfaceFrom(data, width, height, channels * 8, width * channels, rmask, gmask, bmask, amask); - - if (!surface) - { - fprintf(stderr, "SDL_CreateRGBSurfaceFrom Error: %s\n", SDL_GetError()); - } - return surface; -} - -int loadNewCursor(char *cursorFileName) -{ - int width, height, channels; - unsigned char *imageData = stbi_load(cursorFileName, &width, &height, &channels, 0); - if (!imageData) - { - fprintf(stderr, "Failed to load image: %s\n", cursorFileName); - SDL_Quit(); - return 0; - } - - SDL_Surface *originalSurface = createSurfaceFromStb(imageData, width, height, channels); - if (!originalSurface) - { - stbi_image_free(imageData); - SDL_Quit(); - return 0; - } - - int newWidth = getConfig()->customCursorWidth; - int newHeight = getConfig()->customCursorHeight; - SDL_Surface *resizedSurface = - SDL_CreateRGBSurface(0, newWidth, newHeight, originalSurface->format->BitsPerPixel, originalSurface->format->Rmask, - originalSurface->format->Gmask, originalSurface->format->Bmask, originalSurface->format->Amask); - if (!resizedSurface) - { - fprintf(stderr, "SDL_CreateRGBSurface Error: %s\n", SDL_GetError()); - SDL_FreeSurface(originalSurface); - stbi_image_free(imageData); - SDL_Quit(); - return 0; - } - - SDL_Rect srcRect = {0, 0, originalSurface->w, originalSurface->h}; - SDL_Rect destRect = {0, 0, newWidth, newHeight}; - if (SDL_BlitScaled(originalSurface, &srcRect, resizedSurface, &destRect) != 0) - { - fprintf(stderr, "SDL_BlitScaled Error: %s\n", SDL_GetError()); - SDL_FreeSurface(resizedSurface); - SDL_FreeSurface(originalSurface); - stbi_image_free(imageData); - SDL_Quit(); - return 0; - } - - SDL_Cursor *customCursor = SDL_CreateColorCursor(resizedSurface, newWidth / 2, newHeight / 2); - if (!customCursor) - { - fprintf(stderr, "SDL_CreateColorCursor Error: %s\n", SDL_GetError()); - SDL_FreeSurface(resizedSurface); - SDL_FreeSurface(originalSurface); - stbi_image_free(imageData); - SDL_Quit(); - return 0; - } - - SDL_SetCursor(customCursor); - - SDL_FreeSurface(resizedSurface); - SDL_FreeSurface(originalSurface); - stbi_image_free(imageData); - - return 1; -} - void initSDL(int *argcp, char **argv) { - int gId = getConfig()->crc32; - void FGAPIENTRY (*_glutInit)(int *argcp, char **argv) = dlsym(RTLD_NEXT, "glutInit"); - if (getConfig()->noSDL && GLUTGame) + switch (gId) { - _glutInit(argcp, argv); - return; + case OUTRUN_2_SP_SDX_TEST: + case OUTRUN_2_SP_SDX_REVA_TEST: + case OUTRUN_2_SP_SDX_REVA_TEST2: + if (!glutInitialized) + { + glutInitialized = 1; + _glutInit(argcp, argv); + return; + } } - if ((gId == OUTRUN_2_SP_SDX_TEST || gId == OUTRUN_2_SP_SDX_REVA_TEST || gId == OUTRUN_2_SP_SDX_REVA_TEST2) && GLUTGame) - { - _glutInit(argcp, argv); - } - - if ((gId == AFTER_BURNER_CLIMAX) || (gId == AFTER_BURNER_CLIMAX_REVA) || (gId == AFTER_BURNER_CLIMAX_REVB) || - (gId == AFTER_BURNER_CLIMAX_SDX) || (gId == AFTER_BURNER_CLIMAX_SDX_REVA) || (gId == AFTER_BURNER_CLIMAX_SE) || - (gId == AFTER_BURNER_CLIMAX_SE_REVA)) + switch (gId) { + case AFTER_BURNER_CLIMAX: + case AFTER_BURNER_CLIMAX_REVA: + case AFTER_BURNER_CLIMAX_REVB: + case AFTER_BURNER_CLIMAX_SDX: + case AFTER_BURNER_CLIMAX_SDX_REVA: + case AFTER_BURNER_CLIMAX_SE: + case AFTER_BURNER_CLIMAX_SE_REVA: setenv("SDL_VIDEODRIVER", "x11", 1); } @@ -183,14 +91,31 @@ void initSDL(int *argcp, char **argv) SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); // Double buffering SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 1); // 24-bit depth buffer SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); // Set the alpha size to 8 bits - if (gId == AFTER_BURNER_CLIMAX || gId == AFTER_BURNER_CLIMAX_REVA || gId == AFTER_BURNER_CLIMAX_REVB || - gId == AFTER_BURNER_CLIMAX_SDX || gId == AFTER_BURNER_CLIMAX_SDX_REVA || gId == AFTER_BURNER_CLIMAX_SE || - gId == AFTER_BURNER_CLIMAX_SE_REVA || gId == R_TUNED || gId == VIRTUA_FIGHTER_5 || gId == VIRTUA_FIGHTER_5_REVA || - gId == VIRTUA_FIGHTER_5_REVB || gId == VIRTUA_FIGHTER_5_REVE || gId == VIRTUA_FIGHTER_5_EXPORT || gId == VIRTUA_FIGHTER_5_R || - gId == VIRTUA_FIGHTER_5_R_REVD || gId == VIRTUA_FIGHTER_5_R_REVG || gId == VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVA || - gId == VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB || gId == VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB_6000 || gId == GHOST_SQUAD_EVOLUTION || - gId == SEGA_RACE_TV || gId == MJ4_REVG || gId == MJ4_EVO) + switch (gId) { + case AFTER_BURNER_CLIMAX: + case AFTER_BURNER_CLIMAX_REVA: + case AFTER_BURNER_CLIMAX_REVB: + case AFTER_BURNER_CLIMAX_SDX: + case AFTER_BURNER_CLIMAX_SDX_REVA: + case AFTER_BURNER_CLIMAX_SE: + case AFTER_BURNER_CLIMAX_SE_REVA: + case R_TUNED: + case VIRTUA_FIGHTER_5: + case VIRTUA_FIGHTER_5_REVA: + case VIRTUA_FIGHTER_5_REVB: + case VIRTUA_FIGHTER_5_REVE: + case VIRTUA_FIGHTER_5_EXPORT: + case VIRTUA_FIGHTER_5_R: + case VIRTUA_FIGHTER_5_R_REVD: + case VIRTUA_FIGHTER_5_R_REVG: + case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVA: + case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB: + case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB_6000: + case GHOST_SQUAD_EVOLUTION: + case SEGA_RACE_TV: + case MJ4_REVG: + case MJ4_EVO: SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1); } @@ -236,18 +161,12 @@ void initSDL(int *argcp, char **argv) if (getConfig()->fullscreen) { SDL_SetWindowFullscreen(SDLwindow, SDL_WINDOW_FULLSCREEN); - } - - if (strcmp(getConfig()->customCursor, "") != 0) - { - if (!loadNewCursor(getConfig()->customCursor)) - { - fprintf(stderr, "Custom cursor could not be loaded!\n"); - exit(1); - } } - if (getConfig()->hideCursor) + loadCursors(); + setCursor(customCursor); + + if (getConfig()->hideCursor || gId == PRIMEVAL_HUNT) SDL_ShowCursor(SDL_DISABLE); } diff --git a/src/lindbergh/securityboard.c b/src/lindbergh/securityboard.c index f91ab48..fa17ef5 100644 --- a/src/lindbergh/securityboard.c +++ b/src/lindbergh/securityboard.c @@ -1,8 +1,8 @@ #include +#include "config.h" #include "securityboard.h" #include "log.h" -#include "config.h" #define SECURITY_BOARD_FRONT_PANEL 0x38 #define SECURITY_BOARD_FRONT_PANEL_NON_ROOT 0x1038 diff --git a/src/lindbergh/shader_patches.c b/src/lindbergh/shader_patches.c index 61e1cb3..5e55932 100644 --- a/src/lindbergh/shader_patches.c +++ b/src/lindbergh/shader_patches.c @@ -23,11 +23,30 @@ #include "../libxdiff/xdiff/xdiff.h" #include "config.h" #include "patch.h" -#include "shader_work/shaders.h" + +#include "shader_work/2spicy.h" +#include "shader_work/abc.h" +#include "shader_work/gsevo.h" +#include "shader_work/harley.h" +#include "shader_work/hod4.h" +#include "shader_work/hod4sp.h" +#include "shader_work/hodex.h" +#include "shader_work/hummer.h" +#include "shader_work/id.h" +#include "shader_work/lgj.h" +#include "shader_work/mj4.h" +#include "shader_work/or2.h" +#include "shader_work/primeval.h" +#include "shader_work/rambo.h" +#include "shader_work/rtuned.h" +#include "shader_work/srtv.h" +#include "shader_work/vf5.h" +#include "shader_work/vt3.h" #define MAX_FILENAME_LENGTH 256 #define XDLT_STD_BLKSIZE (1024 * 8) +extern uint32_t gId; char tmpShader[150000]; bool cachedShaderFilesLoaded = false; int idxError = 0; @@ -262,8 +281,7 @@ void glEnable(GLenum cap) { void *(*_glEnable)(GLenum cap) = dlsym(RTLD_NEXT, "glEnable"); - if ((cap == GL_FRAGMENT_PROGRAM_NV) && - ((getConfig()->crc32 == OUTRUN_2_SP_SDX) || (getConfig()->crc32 == OUTRUN_2_SP_SDX_REVA)) && + if ((cap == GL_FRAGMENT_PROGRAM_NV) && ((gId == OUTRUN_2_SP_SDX) || (gId == OUTRUN_2_SP_SDX_REVA)) && (getConfig()->GPUVendor != NVIDIA_GPU)) { cap = GL_FRAGMENT_PROGRAM_ARB; @@ -278,8 +296,7 @@ void glDisable(GLenum cap) { void *(*_glDisable)(GLenum cap) = dlsym(RTLD_NEXT, "glDisable"); - if ((cap == GL_FRAGMENT_PROGRAM_NV) && - ((getConfig()->crc32 == OUTRUN_2_SP_SDX) || (getConfig()->crc32 == OUTRUN_2_SP_SDX_REVA)) && + if ((cap == GL_FRAGMENT_PROGRAM_NV) && ((gId == OUTRUN_2_SP_SDX) || (gId == OUTRUN_2_SP_SDX_REVA)) && (getConfig()->GPUVendor != NVIDIA_GPU)) { cap = GL_FRAGMENT_PROGRAM_ARB; @@ -433,17 +450,16 @@ void srtvElfShaderPatcher() */ bool shaderFileInList(const char *pathname, int *idx) { - uint32_t gId = getConfig()->crc32; char cwd[256]; int gpuVendor = getConfig()->GPUVendor; - if (gId == GHOST_SQUAD_EVOLUTION) + switch (gId) { + case GHOST_SQUAD_EVOLUTION: if (getConfig()->GPUVendor != NVIDIA_GPU) { for (int x = 0; x < gsevoShaderPatchesCount; x++) { - if ((strcmp(gsevoMesaShaderPatches[x].fileName, pathname) == 0) && - (gsevoMesaShaderPatches[x].shaderBufferSize != 0)) + if ((strcmp(gsevoMesaShaderPatches[x].fileName, pathname) == 0) && (gsevoMesaShaderPatches[x].shaderBufferSize != 0)) { *idx = x; return true; @@ -455,8 +471,7 @@ bool shaderFileInList(const char *pathname, int *idx) { for (int x = 0; x < gsevoShaderPatchesCount; x++) { - if ((strcmp(gsevoNvidiaShaderPatches[x].fileName, pathname) == 0) && - (gsevoNvidiaShaderPatches[x].shaderBufferSize != 0)) + if ((strcmp(gsevoNvidiaShaderPatches[x].fileName, pathname) == 0) && (gsevoNvidiaShaderPatches[x].shaderBufferSize != 0)) { *idx = x; return true; @@ -464,9 +479,8 @@ bool shaderFileInList(const char *pathname, int *idx) } return false; } - } - else if (gId == RAMBO) - { + break; + case RAMBO: if (getConfig()->GPUVendor != NVIDIA_GPU) { for (int x = 0; x < ramboMesaShaderPatchesCount; x++) @@ -493,22 +507,20 @@ bool shaderFileInList(const char *pathname, int *idx) } return false; } - } - else if (gId == THE_HOUSE_OF_THE_DEAD_4_REVA || gId == THE_HOUSE_OF_THE_DEAD_4_REVB || gId == THE_HOUSE_OF_THE_DEAD_4_REVC) - { + case THE_HOUSE_OF_THE_DEAD_4_REVA: + case THE_HOUSE_OF_THE_DEAD_4_REVB: + case THE_HOUSE_OF_THE_DEAD_4_REVC: for (int x = 0; x < hod4ShaderPatchesCount; x++) { - if ((strcmp(hod4ShaderPatches[x].fileName, basename((char *)pathname)) == 0) && - (hod4ShaderPatches[x].shaderBufferSize != 0)) + if ((strcmp(hod4ShaderPatches[x].fileName, basename((char *)pathname)) == 0) && (hod4ShaderPatches[x].shaderBufferSize != 0)) { *idx = x; return true; } } return false; - } - else if (gId == THE_HOUSE_OF_THE_DEAD_4_SPECIAL || gId == THE_HOUSE_OF_THE_DEAD_4_SPECIAL_REVB) - { + case THE_HOUSE_OF_THE_DEAD_4_SPECIAL: + case THE_HOUSE_OF_THE_DEAD_4_SPECIAL_REVB: for (int x = 0; x < hod4spShaderPatchesCount; x++) { if ((strcmp(hod4spShaderPatches[x].fileName, basename((char *)pathname)) == 0) && @@ -519,9 +531,7 @@ bool shaderFileInList(const char *pathname, int *idx) } } return false; - } - else if (gId == HARLEY_DAVIDSON) - { + case HARLEY_DAVIDSON: for (int x = 0; x < harleyShaderPatchesCount; x++) { if ((strcmp(harleyShaderPatches[x].fileName, basename((char *)pathname)) == 0) && @@ -532,9 +542,7 @@ bool shaderFileInList(const char *pathname, int *idx) } } return false; - } - else if (gId == PRIMEVAL_HUNT) - { + case PRIMEVAL_HUNT: for (int x = 0; x < phShaderPatchesCount; x++) { if ((strcmp(basename((char *)phShaderPatches[x].fileName), basename((char *)pathname)) == 0) && @@ -545,10 +553,10 @@ bool shaderFileInList(const char *pathname, int *idx) } } return false; - } - else if (gId == HUMMER || gId == HUMMER_SDLX || gId == HUMMER_EXTREME || gId == HUMMER_EXTREME_MDX) - { - + case HUMMER: + case HUMMER_SDLX: + case HUMMER_EXTREME: + case HUMMER_EXTREME_MDX: for (int x = 0; x < hummerFilesToModCount; x++) { if ((strcmp(basename((char *)hummerShaderFilesToMod[x].fileName), basename((char *)pathname)) == 0) && @@ -559,28 +567,31 @@ bool shaderFileInList(const char *pathname, int *idx) } } return false; - } - else if (gId == TOO_SPICY && gpuVendor != NVIDIA_GPU) - { - for (int x = 0; x < tooSpicyShaderPatchesCount; x++) + case TOO_SPICY: + if (gpuVendor != NVIDIA_GPU) { - if ((strcmp(tooSpicyShaderPatches[x].fileName, basename((char *)pathname)) == 0) && - (tooSpicyShaderPatches[x].shaderBufferSize != 0)) + for (int x = 0; x < tooSpicyShaderPatchesCount; x++) { - *idx = x; - return true; + if ((strcmp(tooSpicyShaderPatches[x].fileName, basename((char *)pathname)) == 0) && + (tooSpicyShaderPatches[x].shaderBufferSize != 0)) + { + *idx = x; + return true; + } } } return false; - } - else if (gId == THE_HOUSE_OF_THE_DEAD_EX && gpuVendor != NVIDIA_GPU) - { - for (int x = 0; x < hodexShaderPatchesCount; x++) + case THE_HOUSE_OF_THE_DEAD_EX: + if (gpuVendor != NVIDIA_GPU) { - if ((strcmp(hodexShaderPatches[x].fileName, basename((char *)pathname)) == 0) && (hodexShaderPatches[x].shaderBufferSize != 0)) + for (int x = 0; x < hodexShaderPatchesCount; x++) { - *idx = x; - return true; + if ((strcmp(hodexShaderPatches[x].fileName, basename((char *)pathname)) == 0) && + (hodexShaderPatches[x].shaderBufferSize != 0)) + { + *idx = x; + return true; + } } } return false; @@ -593,49 +604,83 @@ bool shaderFileInList(const char *pathname, int *idx) ShaderFilesToMod *filesToMod; int filesToModCount; - if ((gId == LETS_GO_JUNGLE || gId == LETS_GO_JUNGLE_REVA || gId == LETS_GO_JUNGLE_SPECIAL) && - (gpuVendor != NVIDIA_GPU || getConfig()->lgjRenderWithMesa == 1)) + switch (gId) { + case LETS_GO_JUNGLE: + case LETS_GO_JUNGLE_REVA: + case LETS_GO_JUNGLE_SPECIAL: + if (gpuVendor == NVIDIA_GPU && getConfig()->lgjRenderWithMesa != 1) + return false; filesToMod = lgjShaderFilesToMod; filesToModCount = lgjFilesToModCount; searchFolder1 = "/shader/Cg"; searchFolder2 = "/extraShader/Cg"; format = "%s/inc%s"; - } + break; + case INITIALD_4_EXP_REVB: + case INITIALD_4_EXP_REVC: + case INITIALD_4_EXP_REVD: + case INITIALD_4_REVA: + case INITIALD_4_REVB: + case INITIALD_4_REVC: + case INITIALD_4_REVD: + case INITIALD_4_REVG: + case INITIALD_5_JAP_REVA: + case INITIALD_5_JAP_REVF: + case INITIALD_5_EXP: + case INITIALD_5_EXP_20: + case INITIALD_5_EXP_20A: + if (gpuVendor == NVIDIA_GPU) + return false; - else if ((gId == INITIALD_4_EXP_REVB || gId == INITIALD_4_EXP_REVC || gId == INITIALD_4_EXP_REVD || gId == INITIALD_4_REVA || - gId == INITIALD_4_REVB || gId == INITIALD_4_REVC || gId == INITIALD_4_REVD || gId == INITIALD_4_REVG || - gId == INITIALD_5_JAP_REVA || gId == INITIALD_5_JAP_REVF || gId == INITIALD_5_EXP || gId == INITIALD_5_EXP_20 || - gId == INITIALD_5_EXP_20A) && - gpuVendor != NVIDIA_GPU) - { + // Set default values filesToMod = idShaderFilesToMod; filesToModCount = idFilesToModCount; - if (gId == INITIALD_4_REVA || gId == INITIALD_4_REVB || gId == INITIALD_4_REVC || gId == INITIALD_4_REVD || gId == INITIALD_4_REVG) - { - filesToMod = id4jShaderFilesToMod; - filesToModCount = id4FilesToModCount; - } searchFolder1 = "/shader/Cg/inc"; searchFolder2 = "/data/Shader"; - if (gId == INITIALD_5_JAP_REVA || gId == INITIALD_5_JAP_REVF || gId == INITIALD_5_EXP || gId == INITIALD_5_EXP_20 || - gId == INITIALD_5_EXP_20A) - { - searchFolder2 = "/data/V5SHADER"; - } format = "%s%s"; - } - else 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) && - gpuVendor != NVIDIA_GPU) - { + + switch (gId) + { + case INITIALD_4_REVA: + case INITIALD_4_REVB: + case INITIALD_4_REVC: + case INITIALD_4_REVD: + case INITIALD_4_REVG: + filesToMod = id4jShaderFilesToMod; + filesToModCount = id4FilesToModCount; + break; + } + + switch (gId) + { + case INITIALD_5_JAP_REVA: + case INITIALD_5_JAP_REVF: + case INITIALD_5_EXP: + case INITIALD_5_EXP_20: + case INITIALD_5_EXP_20A: + searchFolder2 = "/data/V5SHADER"; + break; + } + break; + case VIRTUA_TENNIS_3: + case VIRTUA_TENNIS_3_TEST: + case VIRTUA_TENNIS_3_REVA: + case VIRTUA_TENNIS_3_REVA_TEST: + case VIRTUA_TENNIS_3_REVB: + case VIRTUA_TENNIS_3_REVB_TEST: + case VIRTUA_TENNIS_3_REVC: + case VIRTUA_TENNIS_3_REVC_TEST: + if (gpuVendor == NVIDIA_GPU) + return false; + filesToMod = vt3ShaderFilesToMod; filesToModCount = vt3FilesToModCount; searchFolder1 = "/shader/Cg/inc"; searchFolder2 = "/shader"; format = "%s%s"; } + if (strstr(pathname, searchFolder1) != NULL) { sprintf((void *)searchFileName, format, searchFolder1, fName); @@ -648,6 +693,7 @@ bool shaderFileInList(const char *pathname, int *idx) { return false; } + for (int x = 0; x < filesToModCount; x++) { if (strcmp(filesToMod[x].fileName, searchFileName) == 0) @@ -665,71 +711,70 @@ bool shaderFileInList(const char *pathname, int *idx) */ long int ftellGetShaderSize(int idx) { - uint32_t gId = getConfig()->crc32; - if (gId == GHOST_SQUAD_EVOLUTION) - { - if (getConfig()->GPUVendor != NVIDIA_GPU) - { - return gsevoMesaShaderPatches[idx].shaderBufferSize; - } - return gsevoNvidiaShaderPatches[idx].shaderBufferSize; - } - else if (gId == LETS_GO_JUNGLE || gId == LETS_GO_JUNGLE_REVA || gId == LETS_GO_JUNGLE_SPECIAL) + switch (gId) { + case GHOST_SQUAD_EVOLUTION: + return getConfig()->GPUVendor != NVIDIA_GPU ? gsevoMesaShaderPatches[idx].shaderBufferSize + : gsevoNvidiaShaderPatches[idx].shaderBufferSize; + + case LETS_GO_JUNGLE: + case LETS_GO_JUNGLE_REVA: + case LETS_GO_JUNGLE_SPECIAL: return lgjShaderFilesToMod[idx].shaderBufferSize; - } - else if (gId == INITIALD_4_EXP_REVB || gId == INITIALD_4_EXP_REVC || gId == INITIALD_4_EXP_REVD || gId == INITIALD_5_JAP_REVA || - gId == INITIALD_5_JAP_REVF || gId == INITIALD_5_EXP || gId == INITIALD_5_EXP_20 || gId == INITIALD_5_EXP_20A) - { + + case INITIALD_4_EXP_REVB: + case INITIALD_4_EXP_REVC: + case INITIALD_4_EXP_REVD: + case INITIALD_5_JAP_REVA: + case INITIALD_5_JAP_REVF: + case INITIALD_5_EXP: + case INITIALD_5_EXP_20: + case INITIALD_5_EXP_20A: return idShaderFilesToMod[idx].shaderBufferSize; - } - else if (gId == INITIALD_4_REVA || gId == INITIALD_4_REVB || gId == INITIALD_4_REVC || gId == INITIALD_4_REVD || gId == INITIALD_4_REVG) - { + + case INITIALD_4_REVA: + case INITIALD_4_REVB: + case INITIALD_4_REVC: + case INITIALD_4_REVD: + case INITIALD_4_REVG: return id4jShaderFilesToMod[idx].shaderBufferSize; - } - else 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) - { + + case VIRTUA_TENNIS_3: + case VIRTUA_TENNIS_3_TEST: + case VIRTUA_TENNIS_3_REVA: + case VIRTUA_TENNIS_3_REVA_TEST: + case VIRTUA_TENNIS_3_REVB: + case VIRTUA_TENNIS_3_REVB_TEST: + case VIRTUA_TENNIS_3_REVC: + case VIRTUA_TENNIS_3_REVC_TEST: return vt3ShaderFilesToMod[idx].shaderBufferSize; - } - else if (gId == TOO_SPICY) - { + + case TOO_SPICY: return tooSpicyShaderPatches[idx].shaderBufferSize; - } - else if (gId == RAMBO) - { - if (getConfig()->GPUVendor != NVIDIA_GPU) - { - return ramboMesaShaderPatches[idx].shaderBufferSize; - } - else - { - return ramboNvidiaShaderPatches[idx].shaderBufferSize; - } - } - else if (gId == THE_HOUSE_OF_THE_DEAD_4_REVA || gId == THE_HOUSE_OF_THE_DEAD_4_REVB || gId == THE_HOUSE_OF_THE_DEAD_4_REVC) - { + + case RAMBO: + return getConfig()->GPUVendor != NVIDIA_GPU ? ramboMesaShaderPatches[idx].shaderBufferSize + : ramboNvidiaShaderPatches[idx].shaderBufferSize; + + case THE_HOUSE_OF_THE_DEAD_4_REVA: + case THE_HOUSE_OF_THE_DEAD_4_REVB: + case THE_HOUSE_OF_THE_DEAD_4_REVC: return hod4ShaderPatches[idx].shaderBufferSize; - } - else if (gId == THE_HOUSE_OF_THE_DEAD_4_SPECIAL || gId == THE_HOUSE_OF_THE_DEAD_4_SPECIAL_REVB) - { + + case THE_HOUSE_OF_THE_DEAD_4_SPECIAL: + case THE_HOUSE_OF_THE_DEAD_4_SPECIAL_REVB: return hod4spShaderPatches[idx].shaderBufferSize; - } - else if (gId == THE_HOUSE_OF_THE_DEAD_EX) - { + case THE_HOUSE_OF_THE_DEAD_EX: return hodexShaderPatches[idx].shaderBufferSize; - } - else if (gId == HUMMER || gId == HUMMER_SDLX || gId == HUMMER_EXTREME || gId == HUMMER_EXTREME_MDX) - { + + case HUMMER: + case HUMMER_SDLX: + case HUMMER_EXTREME: + case HUMMER_EXTREME_MDX: return hummerShaderFilesToMod[idx].shaderBufferSize; - } - else if (gId == PRIMEVAL_HUNT) - { + case PRIMEVAL_HUNT: return phShaderPatches[idx].shaderBufferSize; - } - else if (gId == HARLEY_DAVIDSON) - { + case HARLEY_DAVIDSON: return harleyShaderPatches[idx].shaderBufferSize; } return -1; @@ -741,9 +786,9 @@ long int ftellGetShaderSize(int idx) */ size_t freadReplace(void *buf, size_t size, size_t count, int idx) { - uint32_t gId = getConfig()->crc32; - if (gId == GHOST_SQUAD_EVOLUTION) + switch (gId) { + case GHOST_SQUAD_EVOLUTION: if (getConfig()->GPUVendor != NVIDIA_GPU) { memcpy(buf, gsevoMesaShaderPatches[idx].shaderBuffer, gsevoMesaShaderPatches[idx].shaderBufferSize); @@ -753,37 +798,48 @@ size_t freadReplace(void *buf, size_t size, size_t count, int idx) memcpy(buf, gsevoNvidiaShaderPatches[idx].shaderBuffer, gsevoNvidiaShaderPatches[idx].shaderBufferSize); } return 1; - } - else if (gId == LETS_GO_JUNGLE || gId == LETS_GO_JUNGLE_REVA || gId == LETS_GO_JUNGLE_SPECIAL) - { + + case LETS_GO_JUNGLE: + case LETS_GO_JUNGLE_REVA: + case LETS_GO_JUNGLE_SPECIAL: memcpy(buf, lgjShaderFilesToMod[idx].shaderBuffer, size); return size; - } - else if (gId == INITIALD_4_EXP_REVB || gId == INITIALD_4_EXP_REVC || gId == INITIALD_4_EXP_REVD || gId == INITIALD_5_JAP_REVA || - gId == INITIALD_5_JAP_REVF || gId == INITIALD_5_EXP || gId == INITIALD_5_EXP_20 || gId == INITIALD_5_EXP_20A) - { + + case INITIALD_4_EXP_REVB: + case INITIALD_4_EXP_REVC: + case INITIALD_4_EXP_REVD: + case INITIALD_5_JAP_REVA: + case INITIALD_5_JAP_REVF: + case INITIALD_5_EXP: + case INITIALD_5_EXP_20: + case INITIALD_5_EXP_20A: memcpy(buf, idShaderFilesToMod[idx].shaderBuffer, size); return size; - } - else if (gId == INITIALD_4_REVA || gId == INITIALD_4_REVB || gId == INITIALD_4_REVC || gId == INITIALD_4_REVD || gId == INITIALD_4_REVG) - { + + case INITIALD_4_REVA: + case INITIALD_4_REVB: + case INITIALD_4_REVC: + case INITIALD_4_REVD: + case INITIALD_4_REVG: memcpy(buf, id4jShaderFilesToMod[idx].shaderBuffer, size); return size; - } - else 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) - { + + case VIRTUA_TENNIS_3: + case VIRTUA_TENNIS_3_TEST: + case VIRTUA_TENNIS_3_REVA: + case VIRTUA_TENNIS_3_REVA_TEST: + case VIRTUA_TENNIS_3_REVB: + case VIRTUA_TENNIS_3_REVB_TEST: + case VIRTUA_TENNIS_3_REVC: + case VIRTUA_TENNIS_3_REVC_TEST: memcpy(buf, vt3ShaderFilesToMod[idx].shaderBuffer, size); return size; - } - else if (gId == TOO_SPICY) - { + + case TOO_SPICY: memcpy(buf, tooSpicyShaderPatches[idx].shaderBuffer, tooSpicyShaderPatches[idx].shaderBufferSize); return tooSpicyShaderPatches[idx].shaderBufferSize; - } - else if (gId == RAMBO) - { + + case RAMBO: if (getConfig()->GPUVendor != NVIDIA_GPU) { memcpy(buf, ramboMesaShaderPatches[idx].shaderBuffer, ramboMesaShaderPatches[idx].shaderBufferSize); @@ -794,38 +850,40 @@ size_t freadReplace(void *buf, size_t size, size_t count, int idx) memcpy(buf, ramboNvidiaShaderPatches[idx].shaderBuffer, ramboNvidiaShaderPatches[idx].shaderBufferSize); return ramboNvidiaShaderPatches[idx].shaderBufferSize; } - } - else if (gId == THE_HOUSE_OF_THE_DEAD_4_REVA || gId == THE_HOUSE_OF_THE_DEAD_4_REVB || gId == THE_HOUSE_OF_THE_DEAD_4_REVC) - { + + case THE_HOUSE_OF_THE_DEAD_4_REVA: + case THE_HOUSE_OF_THE_DEAD_4_REVB: + case THE_HOUSE_OF_THE_DEAD_4_REVC: memcpy(buf, hod4ShaderPatches[idx].shaderBuffer, hod4ShaderPatches[idx].shaderBufferSize); return hod4ShaderPatches[idx].shaderBufferSize; - } - else if (gId == THE_HOUSE_OF_THE_DEAD_4_SPECIAL || gId == THE_HOUSE_OF_THE_DEAD_4_SPECIAL_REVB) - { + + case THE_HOUSE_OF_THE_DEAD_4_SPECIAL: + case THE_HOUSE_OF_THE_DEAD_4_SPECIAL_REVB: memcpy(buf, hod4spShaderPatches[idx].shaderBuffer, hod4spShaderPatches[idx].shaderBufferSize); return hod4spShaderPatches[idx].shaderBufferSize; - } - else if (gId == THE_HOUSE_OF_THE_DEAD_EX) - { + + case THE_HOUSE_OF_THE_DEAD_EX: memcpy(buf, hodexShaderPatches[idx].shaderBuffer, hodexShaderPatches[idx].shaderBufferSize); return hodexShaderPatches[idx].shaderBufferSize; - } - else if (gId == HUMMER || gId == HUMMER_SDLX || gId == HUMMER_EXTREME || gId == HUMMER_EXTREME_MDX) - { + + case HUMMER: + case HUMMER_SDLX: + case HUMMER_EXTREME: + case HUMMER_EXTREME_MDX: memcpy(buf, hummerShaderFilesToMod[idx].shaderBuffer, hummerShaderFilesToMod[idx].shaderBufferSize); return hummerShaderFilesToMod[idx].shaderBufferSize; - } - else if (gId == PRIMEVAL_HUNT) - { + + case PRIMEVAL_HUNT: memcpy(buf, phShaderPatches[idx].shaderBuffer, phShaderPatches[idx].shaderBufferSize); return phShaderPatches[idx].shaderBufferSize; - } - else if (gId == HARLEY_DAVIDSON) - { + + case HARLEY_DAVIDSON: memcpy(buf, harleyShaderPatches[idx].shaderBuffer, harleyShaderPatches[idx].shaderBufferSize); return harleyShaderPatches[idx].shaderBufferSize; + + default: + return -1; } - return -1; } /** @@ -838,13 +896,23 @@ char *cgGetProgramString(char *program, int e) { char *(*_cgGetProgramString)(char *program, int e) = dlsym(RTLD_NEXT, "cgGetProgramString"); - uint32_t gId = getConfig()->crc32; - - if (gId != INITIALD_4_EXP_REVB && gId != INITIALD_4_EXP_REVC && gId != INITIALD_4_EXP_REVD && gId != INITIALD_4_REVA && - gId != INITIALD_4_REVB && gId != INITIALD_4_REVC && gId != INITIALD_4_REVD && gId != INITIALD_4_REVG && - gId != INITIALD_5_JAP_REVA && gId != INITIALD_5_JAP_REVF && gId != INITIALD_5_EXP && gId != INITIALD_5_EXP_20 && - gId != INITIALD_5_EXP_20A) + switch (gId) { + case INITIALD_4_EXP_REVB: + case INITIALD_4_EXP_REVC: + case INITIALD_4_EXP_REVD: + case INITIALD_4_REVA: + case INITIALD_4_REVB: + case INITIALD_4_REVC: + case INITIALD_4_REVD: + case INITIALD_4_REVG: + case INITIALD_5_JAP_REVA: + case INITIALD_5_JAP_REVF: + case INITIALD_5_EXP: + case INITIALD_5_EXP_20: + case INITIALD_5_EXP_20A: + break; + default: return _cgGetProgramString(program, e); } @@ -870,33 +938,36 @@ char *cgGetProgramString(char *program, int e) */ void gl_ProgramStringARB(int target, int program_fmt, int program_len, char *program) { - uint32_t gId = getConfig()->crc32; + char *newProgram; + int newProgramLen; + void *addr = __builtin_return_address(0); - if (gId == GHOST_SQUAD_EVOLUTION) + switch (gId) { - void *addr = __builtin_return_address(0); + case GHOST_SQUAD_EVOLUTION: if (addr == (void *)0x8179fab) { - char *newProgram; newProgram = replaceInBlock(program, gsevoSet1, gsevoSetCount1, "", ""); int newProgramLen = strlen(newProgram); program = newProgram; program_len = newProgramLen; } - } - else if ((gId == LETS_GO_JUNGLE) || (gId == LETS_GO_JUNGLE_REVA) || gId == LETS_GO_JUNGLE_SPECIAL) - { - char *newProgram; + break; + case LETS_GO_JUNGLE: + case LETS_GO_JUNGLE_REVA: + case LETS_GO_JUNGLE_SPECIAL: newProgram = replaceInBlock(program, lgjCompiledShadersPatch, lgjCompiledShadersPatchCount, "", ""); - int newProgramLen = strlen(newProgram); + newProgramLen = strlen(newProgram); program = newProgram; program_len = newProgramLen; - } - else if ((gId == AFTER_BURNER_CLIMAX) || (gId == AFTER_BURNER_CLIMAX_REVA) || (gId == AFTER_BURNER_CLIMAX_REVB) || - (gId == AFTER_BURNER_CLIMAX_SDX) || (gId == AFTER_BURNER_CLIMAX_SDX_REVA) || - (gId == AFTER_BURNER_CLIMAX_SE) || (gId == AFTER_BURNER_CLIMAX_SE_REVA)) - { - char *newProgram; + break; + case AFTER_BURNER_CLIMAX: + case AFTER_BURNER_CLIMAX_REVA: + case AFTER_BURNER_CLIMAX_REVB: + case AFTER_BURNER_CLIMAX_SDX: + case AFTER_BURNER_CLIMAX_SDX_REVA: + case AFTER_BURNER_CLIMAX_SE: + case AFTER_BURNER_CLIMAX_SE_REVA: if (target == GL_VERTEX_PROGRAM_ARB) { newProgram = replaceInBlock(program, abcVsMesa, abcVsMesaCount, "", ""); @@ -905,13 +976,12 @@ void gl_ProgramStringARB(int target, int program_fmt, int program_len, char *pro { newProgram = replaceInBlock(program, abcFsMesa, abcFsMesaCount, "", ""); } - int newProgramLen = strlen(newProgram); + newProgramLen = strlen(newProgram); program = newProgram; program_len = newProgramLen; - } - else if ((gId == OUTRUN_2_SP_SDX) || (gId == OUTRUN_2_SP_SDX_REVA)) - { - char *newProgram; + break; + case OUTRUN_2_SP_SDX: + case OUTRUN_2_SP_SDX_REVA: if (target == GL_VERTEX_PROGRAM_ARB) { if (getConfig()->GPUVendor == NVIDIA_GPU) @@ -928,17 +998,21 @@ void gl_ProgramStringARB(int target, int program_fmt, int program_len, char *pro else newProgram = replaceInBlock(program, orFsMesa, orFsMesaCount, "", ""); } - int newProgramLen = strlen(newProgram); + newProgramLen = strlen(newProgram); program = newProgram; program_len = newProgramLen; - } - else if (gId == VIRTUA_FIGHTER_5 || gId == VIRTUA_FIGHTER_5_REVA || gId == VIRTUA_FIGHTER_5_REVB || - gId == VIRTUA_FIGHTER_5_REVE || gId == VIRTUA_FIGHTER_5_REVE || gId == VIRTUA_FIGHTER_5_EXPORT || - gId == VIRTUA_FIGHTER_5_R || gId == VIRTUA_FIGHTER_5_R_REVD || gId == VIRTUA_FIGHTER_5_R_REVG || - gId == VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVA || gId == VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB || - gId == VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB_6000) - { - char *newProgram; + break; + case VIRTUA_FIGHTER_5: + case VIRTUA_FIGHTER_5_REVA: + case VIRTUA_FIGHTER_5_REVB: + case VIRTUA_FIGHTER_5_REVE: + case VIRTUA_FIGHTER_5_EXPORT: + case VIRTUA_FIGHTER_5_R: + case VIRTUA_FIGHTER_5_R_REVD: + case VIRTUA_FIGHTER_5_R_REVG: + case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVA: + case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB: + case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB_6000: if (target == GL_VERTEX_PROGRAM_ARB) { if (getConfig()->GPUVendor == ATI_GPU) @@ -962,13 +1036,11 @@ void gl_ProgramStringARB(int target, int program_fmt, int program_len, char *pro else newProgram = replaceInBlock(program, vf5FsMesa, vf5FsMesaCount, "", ""); } - int newProgramLen = strlen(newProgram); + newProgramLen = strlen(newProgram); program = newProgram; program_len = newProgramLen; - } - else if (gId == R_TUNED) - { - char *newProgram; + break; + case R_TUNED: if (target == GL_VERTEX_PROGRAM_ARB) { newProgram = replaceInBlock(program, rtunedVsMesa, rtunedVsMesaCount, "", ""); @@ -977,13 +1049,12 @@ void gl_ProgramStringARB(int target, int program_fmt, int program_len, char *pro { newProgram = replaceInBlock(program, rtunedFsMesa, rtunedFsMesaCount, "", ""); } - int newProgramLen = strlen(newProgram); + newProgramLen = strlen(newProgram); program = newProgram; program_len = newProgramLen; - } - else if (gId == MJ4_REVG || gId == MJ4_EVO) - { - char *newProgram; + break; + case MJ4_REVG: + case MJ4_EVO: if (target == GL_VERTEX_PROGRAM_ARB) { newProgram = replaceInBlock(program, mj4VsMesa, mj4VsMesaCount, "", ""); @@ -992,29 +1063,40 @@ void gl_ProgramStringARB(int target, int program_fmt, int program_len, char *pro { newProgram = replaceInBlock(program, mj4FsMesa, mj4FsMesaCount, "", ""); } - int newProgramLen = strlen(newProgram); + newProgramLen = strlen(newProgram); program = newProgram; program_len = newProgramLen; } glProgramStringARB(target, program_fmt, program_len, program); - if ((gId == VIRTUA_FIGHTER_5 || gId == VIRTUA_FIGHTER_5_REVA || gId == VIRTUA_FIGHTER_5_REVB || - gId == VIRTUA_FIGHTER_5_REVE || gId == VIRTUA_FIGHTER_5_REVE || gId == VIRTUA_FIGHTER_5_EXPORT || - gId == VIRTUA_FIGHTER_5_R || gId == VIRTUA_FIGHTER_5_R_REVD || gId == VIRTUA_FIGHTER_5_R_REVG || gId == VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVA || - gId == VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB || gId == VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB_6000) && - getConfig()->GPUVendor == ATI_GPU) + switch (gId) { - int err = glGetError(); - if (err == 1282) + case VIRTUA_FIGHTER_5: + case VIRTUA_FIGHTER_5_REVA: + case VIRTUA_FIGHTER_5_REVB: + case VIRTUA_FIGHTER_5_REVE: + case VIRTUA_FIGHTER_5_EXPORT: + case VIRTUA_FIGHTER_5_R: + case VIRTUA_FIGHTER_5_R_REVD: + case VIRTUA_FIGHTER_5_R_REVG: + case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVA: + case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB: + case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB_6000: + if (getConfig()->GPUVendor == ATI_GPU) { - char *newProgram; - newProgram = replaceInBlock(program, vf5VsAti2, vf5VsAtiCount2, "", ""); - int newProgramLen = strlen(newProgram); - program = newProgram; - program_len = newProgramLen; - glProgramStringARB(target, program_fmt, program_len, program); + int err = glGetError(); + if (err == 1282) + { + char *newProgram; + newProgram = replaceInBlock(program, vf5VsAti2, vf5VsAtiCount2, "", ""); + int newProgramLen = strlen(newProgram); + program = newProgram; + program_len = newProgramLen; + glProgramStringARB(target, program_fmt, program_len, program); + } } } + if ((getConfig()->showDebugMessages)) { GLint result; @@ -1088,31 +1170,34 @@ char *cgCreateProgram(uint32_t context, int program_type, const char *program, i char *(*_cgCreateProgram)(uint32_t context, int program_type, const char *program, int profile, const char *entry, const char **args) = dlsym(RTLD_NEXT, "cgCreateProgram"); - 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 != INITIALD_4_EXP_REVB && gId != INITIALD_4_EXP_REVC && gId != INITIALD_4_EXP_REVD && - gId != LETS_GO_JUNGLE && gId != LETS_GO_JUNGLE_REVA && gId != LETS_GO_JUNGLE_SPECIAL && gId != INITIALD_4_REVA && - gId != INITIALD_4_REVB && gId != INITIALD_4_REVC && gId != INITIALD_4_REVD && gId != INITIALD_4_REVG && - gId != INITIALD_5_JAP_REVA && gId != INITIALD_5_JAP_REVF && gId != INITIALD_5_EXP && gId != INITIALD_5_EXP_20 && - gId != INITIALD_5_EXP_20A) || - (getConfig()->GPUVendor == NVIDIA_GPU)) + if (getConfig()->GPUVendor == NVIDIA_GPU) { if ((gId != LETS_GO_JUNGLE && gId != LETS_GO_JUNGLE_REVA && gId != LETS_GO_JUNGLE_SPECIAL) || getConfig()->lgjRenderWithMesa == 0) return _cgCreateProgram(context, program_type, program, profile, entry, args); } - if (gId == INITIALD_4_EXP_REVB || gId == INITIALD_4_EXP_REVC || gId == INITIALD_4_EXP_REVD || gId == INITIALD_4_REVA || - gId == INITIALD_4_REVB || gId == INITIALD_4_REVC || gId == INITIALD_4_REVD || gId == INITIALD_4_REVG || - gId == INITIALD_5_JAP_REVA || gId == INITIALD_5_JAP_REVF || gId == INITIALD_5_EXP || gId == INITIALD_5_EXP_20 || - gId == INITIALD_5_EXP_20A) + switch (gId) { + case INITIALD_4_EXP_REVB: + case INITIALD_4_EXP_REVC: + case INITIALD_4_EXP_REVD: + case INITIALD_4_REVA: + case INITIALD_4_REVB: + case INITIALD_4_REVC: + case INITIALD_4_REVD: + case INITIALD_4_REVG: + case INITIALD_5_JAP_REVA: + case INITIALD_5_JAP_REVF: + case INITIALD_5_EXP: + case INITIALD_5_EXP_20: + case INITIALD_5_EXP_20A: if ((profile == 6148) || (profile == 6150) || profile == 7001) profile = 6150; else if ((profile == 6149) || (profile == 6151) || profile == 7000) profile = 7000; else printf("profile %d not supported\n", profile); + break; } const char *op6150[] = {"NumTemps=31", "MaxInstructions=1024", "MaxAddressRegs=1", "MaxLocalParams=256", NULL}; @@ -1139,23 +1224,30 @@ char *cgCreateProgram(uint32_t context, int program_type, const char *program, i void gl_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count, const GLcharARB **const string, const GLint *length) { - uint32_t gId = getConfig()->crc32; - if (gId != SEGA_RACE_TV && gId != HUMMER && gId != HUMMER_SDLX && gId != HUMMER_EXTREME && gId != HUMMER_EXTREME_MDX) + switch (gId) { + case SEGA_RACE_TV: + case HUMMER: + case HUMMER_SDLX: + case HUMMER_EXTREME: + case HUMMER_EXTREME_MDX: + break; + default: glShaderSourceARB(shaderObj, count, string, length); return; } char *newProgram = malloc(250000); - if (gId == SEGA_RACE_TV) + switch (gId) { - void *addr = __builtin_return_address(0); // load the address of the function that called glShaderSourceARB - + case SEGA_RACE_TV: + { + void *addr = __builtin_return_address(0); if (addr <= (void *)0x82fd823) { newProgram = strdup(*string); } - else if (addr == (void *)0x84bbff1) // check the address to apply the patches in the right place. + else if (addr == (void *)0x84bbff1) { if (getConfig()->GPUVendor != NVIDIA_GPU) { @@ -1168,7 +1260,7 @@ void gl_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count, const GLcharARB ** newProgram = replaceInBlock(newProgram, srtvVsNvidia, srtvVsNvidiaCount, "", ""); } } - else if (addr == (void *)0x084bc06b) // check the address to apply the patches in the right place. + else if (addr == (void *)0x084bc06b) { if (getConfig()->GPUVendor != NVIDIA_GPU) { @@ -1181,12 +1273,15 @@ void gl_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count, const GLcharARB ** } } } - else if (gId == HUMMER || gId == HUMMER_SDLX || gId == HUMMER_EXTREME || gId == HUMMER_EXTREME_MDX) + break; + case HUMMER: + case HUMMER_SDLX: + case HUMMER_EXTREME: + case HUMMER_EXTREME_MDX: { void *addr = __builtin_return_address(0); - if ((addr != (void *)0x830a501) && (addr != (void *)0x830a485) && (addr != (void *)0x08319841) && - (addr != (void *)0x083197c5) && (addr != (void *)0x83af939) && (addr != (void *)0x83af9b3) && - (addr != (void *)0x83b0515) && (addr != (void *)0x83b058f)) + if ((addr != (void *)0x830a501) && (addr != (void *)0x830a485) && (addr != (void *)0x08319841) && (addr != (void *)0x083197c5) && + (addr != (void *)0x83af939) && (addr != (void *)0x83af9b3) && (addr != (void *)0x83b0515) && (addr != (void *)0x83b058f)) { sprintf(newProgram, "%s", hummerShaderFilesToMod[hummerExtremeShaderFileIndex].shaderBuffer); } @@ -1196,6 +1291,12 @@ void gl_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count, const GLcharARB ** return; } } + break; + default: + glShaderSourceARB(shaderObj, count, string, length); + return; + } + const char *newString = malloc(250000); memset((void *)newString, '\0', 250000); newString = strdup(newProgram); @@ -1220,8 +1321,7 @@ void gl_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count, const GLcharARB ** void *gl_XGetProcAddressARB(const unsigned char *procName) { int dbgMsg = getConfig()->showDebugMessages; - if (getConfig()->crc32 != HUMMER && getConfig()->crc32 != HUMMER_SDLX && getConfig()->crc32 != HUMMER_EXTREME && - getConfig()->crc32 != HUMMER_EXTREME_MDX) + if (gId != HUMMER && gId != HUMMER_SDLX && gId != HUMMER_EXTREME && gId != HUMMER_EXTREME_MDX) { if (strcmp((const char *)procName, "glGenOcclusionQueriesNV") == 0) { @@ -1372,14 +1472,26 @@ void glBindTexture(GLenum target, GLuint texture) { void (*_glBindTexture)(GLenum target, GLuint texture) = dlsym(RTLD_NEXT, "glBindTexture"); _glBindTexture(target, texture); - int gId = getConfig()->crc32; - if ((gId == VIRTUA_FIGHTER_5 || gId == VIRTUA_FIGHTER_5_REVA || gId == VIRTUA_FIGHTER_5_REVB || - gId == VIRTUA_FIGHTER_5_REVE || gId == VIRTUA_FIGHTER_5_EXPORT || gId == VIRTUA_FIGHTER_5_R || - gId == VIRTUA_FIGHTER_5_R_REVD || gId == VIRTUA_FIGHTER_5_R_REVG ||gId == VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVA || - gId == VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB || gId == VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB_6000) && - getConfig()->GPUVendor != NVIDIA_GPU) + switch (gId) { - glTexParameterf(target, GL_TEXTURE_LOD_BIAS, -10.0f); // Adjust LOD bias + case VIRTUA_FIGHTER_5: + case VIRTUA_FIGHTER_5_REVA: + case VIRTUA_FIGHTER_5_REVB: + case VIRTUA_FIGHTER_5_REVE: + case VIRTUA_FIGHTER_5_EXPORT: + case VIRTUA_FIGHTER_5_R: + case VIRTUA_FIGHTER_5_R_REVD: + case VIRTUA_FIGHTER_5_R_REVG: + case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVA: + case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB: + case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB_6000: + if (getConfig()->GPUVendor != NVIDIA_GPU) + { + glTexParameterf(target, GL_TEXTURE_LOD_BIAS, -10.0f); // Adjust LOD bias + } + break; + default: + break; } } @@ -1612,7 +1724,7 @@ int xdlt_load_mmfile(char const *path, mmfile_t *mf) int pos = 0; long size; char *blk; - uint32_t gId = getConfig()->crc32; + if (xdl_init_mmfile(mf, XDLT_STD_BLKSIZE, XDL_MMF_ATOMIC) < 0) { exit(1); @@ -1677,13 +1789,30 @@ int handle_patch(void *priv, mmbuffer_t *mb, int nbuf) */ void cacheModedShaderFiles() { - uint32_t gId = getConfig()->crc32; char cwd[256]; char fullPath[512]; char shaderBuffer[100000]; char *newProgram; - if ((gId == LETS_GO_JUNGLE) || (gId == LETS_GO_JUNGLE_REVA) || (gId == LETS_GO_JUNGLE_SPECIAL)) + ShaderFilesToMod *shaderFilesToMod; + int filesToModCount; + + memallocator_t malt; + malt.priv = NULL; + malt.malloc = wrap_malloc; + malt.free = wrap_free; + malt.realloc = wrap_realloc; + xdl_set_allocator(&malt); + mmfile_t patchedFile; + ShaderFilesToPatch *shaderFilesToPatch; + int shaderFilesToPatchCount; + char folderName[50]; + sprintf(folderName, "/../fs/shader/"); + + switch (gId) { + case LETS_GO_JUNGLE: + case LETS_GO_JUNGLE_REVA: + case LETS_GO_JUNGLE_SPECIAL: for (int x = 0; x < lgjFilesToModCount; x++) { getcwd(cwd, sizeof(cwd)); @@ -1702,14 +1831,20 @@ void cacheModedShaderFiles() lgjShaderFilesToMod[x].shaderBuffer = strndup(newProgram, strlen(newProgram)); free(newProgram); } - } - else if (gId == INITIALD_4_EXP_REVB || gId == INITIALD_4_EXP_REVC || gId == INITIALD_4_EXP_REVD || gId == INITIALD_4_REVA || - gId == INITIALD_4_REVB || gId == INITIALD_4_REVC || gId == INITIALD_4_REVD || gId == INITIALD_4_REVG || - gId == INITIALD_5_JAP_REVA || gId == INITIALD_5_JAP_REVF || gId == INITIALD_5_EXP || gId == INITIALD_5_EXP_20 || - gId == INITIALD_5_EXP_20A) - { - ShaderFilesToMod *shaderFilesToMod; - int filesToModCount; + break; + case INITIALD_4_EXP_REVB: + case INITIALD_4_EXP_REVC: + case INITIALD_4_EXP_REVD: + case INITIALD_4_REVA: + case INITIALD_4_REVB: + case INITIALD_4_REVC: + case INITIALD_4_REVD: + case INITIALD_4_REVG: + case INITIALD_5_JAP_REVA: + case INITIALD_5_JAP_REVF: + case INITIALD_5_EXP: + case INITIALD_5_EXP_20: + case INITIALD_5_EXP_20A: if (gId == INITIALD_4_REVA || gId == INITIALD_4_REVB || gId == INITIALD_4_REVC || gId == INITIALD_4_REVD || gId == INITIALD_4_REVG) { shaderFilesToMod = id4jShaderFilesToMod; @@ -1733,8 +1868,7 @@ void cacheModedShaderFiles() loadShader(fullPath, shaderBuffer); if (strcmp(shaderFilesToMod[x].fileName, "/data/V5SHADER/effect_p.fx") == 0) { - newProgram = - replaceInBlock(shaderBuffer, id5ShaderReplaceSetForSmoke, id5ShaderReplaceSetForSmokeCount, "", ""); + newProgram = replaceInBlock(shaderBuffer, id5ShaderReplaceSetForSmoke, id5ShaderReplaceSetForSmokeCount, "", ""); } else if (strcmp(shaderFilesToMod[x].fileName, "/data/Shader/effect_p.fx") == 0) { @@ -1743,19 +1877,22 @@ void cacheModedShaderFiles() else { newProgram = replaceInBlock(shaderBuffer, attribsSet, attribsSetCount, "struct\tVS_INPUT_P", ""); - newProgram = - replaceInBlock(newProgram, attribsSet, attribsSetCount, "struct VS_INPUT", "struct VS_OUTPUT"); + newProgram = replaceInBlock(newProgram, attribsSet, attribsSetCount, "struct VS_INPUT", "struct VS_OUTPUT"); newProgram = replaceInBlock(newProgram, idShaderReplaceSet, idShaderReplaceCount, "", ""); } shaderFilesToMod[x].shaderBufferSize = strlen(newProgram); shaderFilesToMod[x].shaderBuffer = strndup(newProgram, strlen(newProgram)); free(newProgram); } - } - else 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) - { + break; + case VIRTUA_TENNIS_3: + case VIRTUA_TENNIS_3_TEST: + case VIRTUA_TENNIS_3_REVA: + case VIRTUA_TENNIS_3_REVA_TEST: + case VIRTUA_TENNIS_3_REVB: + case VIRTUA_TENNIS_3_REVB_TEST: + case VIRTUA_TENNIS_3_REVC: + case VIRTUA_TENNIS_3_REVC_TEST: for (int x = 0; x < vt3FilesToModCount; x++) { getcwd(cwd, sizeof(cwd)); @@ -1769,9 +1906,11 @@ void cacheModedShaderFiles() vt3ShaderFilesToMod[x].shaderBuffer = strndup(newProgram, strlen(newProgram)); free(newProgram); } - } - else if ((gId == HUMMER) || (gId == HUMMER_SDLX) || (gId == HUMMER_EXTREME) || (gId == HUMMER_EXTREME_MDX)) - { + break; + case HUMMER: + case HUMMER_SDLX: + case HUMMER_EXTREME: + case HUMMER_EXTREME_MDX: for (int x = 0; x < hummerFilesToModCount; x++) { getcwd(cwd, sizeof(cwd)); @@ -1784,34 +1923,21 @@ void cacheModedShaderFiles() } if (getConfig()->hummerFlickerFix) { - newProgram = - replaceInBlock(newProgram, hummerShaderReplaceFlicker, hummerShaderReplaceFlickerCount, "", ""); + newProgram = replaceInBlock(newProgram, hummerShaderReplaceFlicker, hummerShaderReplaceFlickerCount, "", ""); } hummerShaderFilesToMod[x].shaderBufferSize = strlen(newProgram); hummerShaderFilesToMod[x].shaderBuffer = strndup(newProgram, strlen(newProgram)); free(newProgram); } - } - else - { - memallocator_t malt; - malt.priv = NULL; - malt.malloc = wrap_malloc; - malt.free = wrap_free; - malt.realloc = wrap_realloc; - xdl_set_allocator(&malt); - mmfile_t patchedFile; - ShaderFilesToPatch *shaderFilesToPatch; - int shaderFilesToPatchCount; - char folderName[50]; - sprintf(folderName, "/../fs/shader/"); - if (gId == TOO_SPICY) + break; + default: + switch (gId) { + case TOO_SPICY: shaderFilesToPatch = tooSpicyShaderPatches; shaderFilesToPatchCount = tooSpicyShaderPatchesCount; - } - else if (gId == RAMBO) - { + break; + case RAMBO: if (getConfig()->GPUVendor != NVIDIA_GPU) { shaderFilesToPatch = ramboMesaShaderPatches; @@ -1822,37 +1948,34 @@ void cacheModedShaderFiles() shaderFilesToPatch = ramboNvidiaShaderPatches; shaderFilesToPatchCount = ramboNvidiaShaderPatchesCount; } - } - else if (gId == HARLEY_DAVIDSON) - { + break; + case HARLEY_DAVIDSON: shaderFilesToPatch = harleyShaderPatches; shaderFilesToPatchCount = harleyShaderPatchesCount; - } - else if (gId == THE_HOUSE_OF_THE_DEAD_EX) - { + break; + case THE_HOUSE_OF_THE_DEAD_EX: shaderFilesToPatch = hodexShaderPatches; shaderFilesToPatchCount = hodexShaderPatchesCount; - } - else if (gId == THE_HOUSE_OF_THE_DEAD_4_REVA || gId == THE_HOUSE_OF_THE_DEAD_4_REVB || gId == THE_HOUSE_OF_THE_DEAD_4_REVC) - { + break; + case THE_HOUSE_OF_THE_DEAD_4_REVA: + case THE_HOUSE_OF_THE_DEAD_4_REVB: + case THE_HOUSE_OF_THE_DEAD_4_REVC: sprintf(folderName, "/../fs/dat/"); shaderFilesToPatchCount = hod4ShaderPatchesCount; shaderFilesToPatch = hod4ShaderPatches; - } - else if (gId == THE_HOUSE_OF_THE_DEAD_4_SPECIAL || gId == THE_HOUSE_OF_THE_DEAD_4_SPECIAL_REVB) - { + break; + case THE_HOUSE_OF_THE_DEAD_4_SPECIAL: + case THE_HOUSE_OF_THE_DEAD_4_SPECIAL_REVB: sprintf(folderName, "/../fs/dat/"); shaderFilesToPatchCount = hod4spShaderPatchesCount; shaderFilesToPatch = hod4spShaderPatches; - } - else if (gId == PRIMEVAL_HUNT) - { + break; + case PRIMEVAL_HUNT: sprintf(folderName, "/../data/nnstdshader/"); shaderFilesToPatchCount = phShaderPatchesCount; shaderFilesToPatch = phShaderPatches; - } - else if (gId == GHOST_SQUAD_EVOLUTION) - { + break; + case GHOST_SQUAD_EVOLUTION: shaderFilesToPatchCount = gsevoShaderPatchesCount; sprintf(folderName, "/%s", ""); if (getConfig()->GPUVendor != NVIDIA_GPU) @@ -1863,7 +1986,9 @@ void cacheModedShaderFiles() { shaderFilesToPatch = gsevoNvidiaShaderPatches; } + break; } + for (int x = 0; x < shaderFilesToPatchCount; x++) { mmfile_t oriFile, patch; diff --git a/src/lindbergh/stb_image.h b/src/lindbergh/stb_image.h index e4919b4..8ae27e0 100644 --- a/src/lindbergh/stb_image.h +++ b/src/lindbergh/stb_image.h @@ -702,14 +702,14 @@ static int stbi__sse2_available() static int stbi__sse2_available() { -//#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 408 // GCC 4.8 or later - // GCC 4.8+ has a nice way to do this - //return __builtin_cpu_supports("sse2"); -//#else - // portable way to do this, preferably without using GCC inline ASM? - // just bail for now. - return 0; -//#endif + // #if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 408 // GCC 4.8 or later + // // GCC 4.8+ has a nice way to do this + // return __builtin_cpu_supports("sse2"); + // #else + // portable way to do this, preferably without using GCC inline ASM? + // just bail for now. + return 0; + // #endif } #endif #endif diff --git a/src/lindbergh/touchscreen.c b/src/lindbergh/touchscreen.c new file mode 100644 index 0000000..2a55ce0 --- /dev/null +++ b/src/lindbergh/touchscreen.c @@ -0,0 +1,85 @@ +#include +#include +#include +#include +#include +#include + +char phSendBuf[10]; +bool phBufferFilled = false; +int phCommand = 1; +int phCommandByte = 0; +uint16_t coordX; +uint16_t coordY; +#define TOUCH_START 0x81 +#define TOUCH_TOUCHING 0x82 +#define TOUCH_END 0x84 + +void phCoordinates(int x, int y, int w, int h, int button) +{ + coordX = (float)x / ((float)w * 0.0002441406); + coordY = (float)y / ((float)h * 0.0002441406); + memset(phSendBuf, 0, sizeof(phSendBuf)); + + if (button == SDL_MOUSEBUTTONDOWN || button == ButtonPress) + { + phSendBuf[2] = TOUCH_START; + phCommand = 1; + } + else if (button == SDL_MOUSEBUTTONUP || button == ButtonRelease) + { + phSendBuf[2] = TOUCH_END; + phCommand = 3; + } + else if (button == SDL_MOUSEMOTION || button == MotionNotify) + { + phSendBuf[2] = TOUCH_TOUCHING; + phCommand = 2; + } + phSendBuf[0] = 0x55; + phSendBuf[1] = 0x54; + phSendBuf[3] = (char)(coordX & 0xFF); + phSendBuf[4] = (char)((coordX >> 8) & 0xff); + phSendBuf[5] = (char)(coordY & 0xFF); + phSendBuf[6] = (char)((coordY >> 8) & 0xff); + + phBufferFilled = true; +} + +uint8_t phCalcChecksum() +{ + int8_t checksum = -0x56; + for (int x = 0; x < 9;x++) + { + checksum += phSendBuf[x]; + } + return (uint8_t)(checksum & 0xff); +} + +ssize_t phRead(int fd, void *buf, size_t count) +{ + if(!phBufferFilled) + return 0; + + + if(phCommandByte == 9) + { + switch (phCommand) + { + case 1: + phCommand = 2; + break; + case 2: + phSendBuf[2] = TOUCH_TOUCHING; + break; + case 3: + phBufferFilled = false; + } + phSendBuf[9] = phCalcChecksum(); + } + memcpy(buf, &phSendBuf[phCommandByte], sizeof(char)); + phCommandByte++; + if (phCommandByte == 10) + phCommandByte = 0; + return 1; +} \ No newline at end of file diff --git a/src/lindbergh/touchscreen.h b/src/lindbergh/touchscreen.h new file mode 100644 index 0000000..81eafbd --- /dev/null +++ b/src/lindbergh/touchscreen.h @@ -0,0 +1,9 @@ +#ifndef TOUCHSCREEN_H +#define TOUCHSCREEN_H + +#include + +void phCoordinates(int x, int y, int w, int h, int button); +ssize_t phRead(int fd, void *buf, size_t count); + +#endif \ No newline at end of file diff --git a/src/lindbergh/x11hooks.c b/src/lindbergh/x11hooks.c index cf2d5a2..5760548 100644 --- a/src/lindbergh/x11hooks.c +++ b/src/lindbergh/x11hooks.c @@ -19,6 +19,7 @@ #include "securityboard.h" #include "fps_limiter.h" #include "sdlcalls.h" +#include "customcursor.h" extern bool SDLWindowCreated; extern bool gettingGPUVendor; @@ -26,11 +27,14 @@ extern bool GLUTGame; bool creatingWindow = false; -Window win; +Window window; extern Display *x11Display; extern Window x11Window; +extern void *customCursor; +extern void *phTouchCursor; + /** * Stop the house of the dead games turning keyboard repeating off. */ @@ -42,12 +46,17 @@ int XAutoRepeatOff(Display *display) Display *XOpenDisplay(const char *display_name) { Display *(*_XOpenDisplay)(const char *display_name) = dlsym(RTLD_NEXT, "XOpenDisplay"); - if (SDLWindowCreated || gettingGPUVendor || GLUTGame || getConfig()->noSDL) - return _XOpenDisplay(display_name); - creatingWindow = true; - initSDL(0, 0); - creatingWindow = false; + if (SDLWindowCreated || gettingGPUVendor || getConfig()->noSDL) + { + x11Display = _XOpenDisplay(display_name); + } + else + { + creatingWindow = true; + initSDL(0, 0); + creatingWindow = false; + } return x11Display; } @@ -61,19 +70,16 @@ Window XCreateWindow(Display *display, Window parent, int x, int y, unsigned int if ((gettingGPUVendor || creatingWindow) || (GLUTGame && getConfig()->noSDL == 0)) { - Window window = _XCreateWindow(display, parent, x, y, width, height, border_width, depth, class, visual, - valueMask, attributes); - return window; + window = _XCreateWindow(display, parent, x, y, width, height, border_width, depth, class, visual, valueMask, attributes); } - - if (getConfig()->noSDL) + else if (getConfig()->noSDL) { width = getConfig()->width; height = getConfig()->height; attributes->event_mask = attributes->event_mask | KeyPressMask | KeyReleaseMask | PointerMotionMask; - Window window = _XCreateWindow(display, parent, x, y, width, height, border_width, depth, class, visual, valueMask, attributes); + window = _XCreateWindow(display, parent, x, y, width, height, border_width, depth, class, visual, valueMask, attributes); printf(" X11 RESOLUTION: %dx%d\n\n", width, height); if (getConfig()->fullscreen) @@ -82,13 +88,17 @@ Window XCreateWindow(Display *display, Window parent, int x, int y, unsigned int Atom wm_fullscreen = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", true); XChangeProperty(display, window, wm_state, XA_ATOM, 32, PropModeReplace, (unsigned char *)&wm_fullscreen, 1); } - win = window; + x11Window = window; + loadCursors(); + setCursor(customCursor); + if (getConfig()->hideCursor) + hideCursor(); } else { - win = x11Window; + window = x11Window; } - return win; + return window; } int XGrabPointer(Display *display, Window grab_window, Bool owner_events, unsigned int event_mask, int pointer_mode, @@ -203,38 +213,6 @@ int XF86VidModeGetAllModeLines(Display *display, int screen, int *modecount_retu return true; } -// Cursor XCreatePixmapCursor(Display *display, Pixmap source, Pixmap mask, XColor *fg, XColor *bg, unsigned int x, -// unsigned int y) -// { -// int (*_XCreatePixmapCursor)(Display *display, Pixmap source, Pixmap mask, XColor *fg, XColor *bg, unsigned int x, -// unsigned int y) = dlsym(RTLD_NEXT, "XCreatePixmapCursor"); -// if (SDLGame) -// return 0; -// return _XCreatePixmapCursor(display, source, mask, fg, bg, x, y); -// } - -// int XFreePixmap(Display *display, Pixmap pixmap) -// { -// int (*_XFreePixmap)(Display *display, Pixmap pixmap) = dlsym(RTLD_NEXT, "XFreePixmap"); -// if (SDLGame) -// return 0; -// return _XFreePixmap(display, pixmap); -// } - -// Pixmap XCreateBitmapFromData(Display *display, Drawable drawable, const char *data, unsigned int x, unsigned int y) -// { -// Pixmap (*_XCreateBitmapFromData)(Display *display, Drawable drawable, const char *data, unsigned int x, -// unsigned int y) = dlsym(RTLD_NEXT, "XCreateBitmapFromData"); -// if (SDLGame) -// return 0; -// return _XCreateBitmapFromData(display, drawable, data, x, y); -// } - -// int XDefineCursor(Display *display, Window w, Cursor cursor) -// { -// return 0; -// } - typedef unsigned int uint; void glGenFencesNV(int n, uint *fences)