Compare commits

...
20 Commits
Author SHA1 Message Date
dkeruza-neo 03ccfd3449 Forgot to uncomment code. 2025-03-09 03:42:05 -04:00
dkeruza-neo 4e82f6fdef Again 2025-03-09 01:53:29 -05:00
dkeruza-neo ccf54ab6ad Fix release number? 2025-03-09 01:50:41 -05:00
dkeruza-neo 1fb45a1e5c Fixed autobuild script. 2025-03-09 00:49:25 -05:00
dkeruza-neo 9bbc0f983e Check the changelog. 2025-03-09 00:44:55 -05:00
dkeruza cc500aa7ef Merge pull request #62 from nadenislamarre/evdev-keys
evdev: add technical input values
2025-03-08 16:00:54 -05:00
dkeruza cafd6276c3 Workaround 6 2025-02-27 16:26:25 -05:00
dkeruza a2dbf1cbda Workaround 5 2025-02-27 15:43:56 -05:00
dkeruza 74d61985ec Workaround 4 2025-02-27 15:41:17 -05:00
dkeruza 4d0996b905 Workaround 3 2025-02-27 15:29:33 -05:00
dkeruza 52cb3eaf6b Workaround 2 2025-02-27 14:42:30 -05:00
dkeruza 8b6604efc5 Workaround - Ups2 2025-02-27 00:13:27 -05:00
dkeruza 7b426f0d11 Workaround - Ups 2025-02-27 00:11:06 -05:00
dkeruza 442d03b144 Update lindbergh.cWorkaround 2025-02-26 22:14:11 -05:00
dkeruza 50a1a35f7f Workaround 2025-02-26 22:05:53 -05:00
dkeruza 728c308835 Workaround 2025-02-17 22:14:12 -05:00
dkeruza 543ebe4817 Workaround 2025-02-17 22:12:40 -05:00
Nicolas Adenis-Lamarre 1f20a51aba evdev: add abs to key mapping
Signed-off-by: Nicolas Adenis-Lamarre <nicolas.adenis.lamarre@gmail.com>
2025-02-01 10:24:22 +01:00
Nicolas Adenis-Lamarre 8347b61468 evdev: add shake special event
Signed-off-by: Nicolas Adenis-Lamarre <nicolas.adenis.lamarre@gmail.com>
2025-01-27 21:47:52 +01:00
Nicolas Adenis-Lamarre 3642e2392b evdev: add technical input values
Signed-off-by: Nicolas Adenis-Lamarre <nicolas.adenis.lamarre@gmail.com>
2025-01-24 22:35:38 +01:00
36 changed files with 3368 additions and 1669 deletions
-73
View File
@@ -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
+44
View File
@@ -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"
+45
View File
@@ -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
+56
View File
@@ -0,0 +1,56 @@
name: Automated Builds
on:
workflow_dispatch:
pull_request:
paths-ignore:
- '**.md'
- '.github/ISSUE_TEMPLATE/*'
push:
branches:
- master
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/master'
steps:
- name: Download Artifacts
uses: actions/download-artifact@v4
with:
path: ./artifacts/
- name: Display Downloaded Artifacts
run: find ./artifacts/
- name: Add 161 to github.run_number
run: |
NEW_RUN_NUMBER=$(( ${{ github.run_number }} + 161 ))
echo "NEW_RUN_NUMBER=$NEW_RUN_NUMBER" >> $GITHUB_ENV
# - name: Display Updated Number
# run: echo "Updated Run Number: ${{ env.NEW_RUN_NUMBER }}"
- name: Create Preview Release
if: github.ref == 'refs/heads/master'
uses: "marvinpinto/action-automatic-releases@latest"
with:
repo_token: "${{ secrets.GITHUB_TOKEN }}"
automatic_release_tag: v${{ env.NEW_RUN_NUMBER }}
prerelease: false
title: "Build v${{ env.NEW_RUN_NUMBER }}"
files: |
./artifacts/linux-flatpak/lindbergh-loader.flatpak
./artifacts/linux-build/build.tar.gz
+10 -9
View File
@@ -1,7 +1,8 @@
CC = gcc -m32 -pthread CC ?= gcc
CFLAGS = -g -fPIC -m32 -Wall -Werror -Wno-misleading-indentation -Wno-unused-but-set-variable -Wno-unused-variable -Wno-unused-function -D_GNU_SOURCE -Wno-char-subscripts CFLAGS = -g -fPIC -m32 -pthread -Wall -Werror -Wno-misleading-indentation -Wno-unused-but-set-variable -Wno-unused-variable -Wno-unused-function -D_GNU_SOURCE -Wno-char-subscripts
LD = g++ -m32 CXX ?= g++
LDFLAGS = -Wl,-z,defs -rdynamic -static-libgcc -lc -ldl -lGL -lglut -lX11 -lSDL2 -lm -lpthread -shared -nostdlib -lasound -L./src/libxdiff -lxdiff LD = $(CXX)
LDFLAGS = -m32 -Wl,-z,defs -rdynamic -static-libgcc -lc -ldl -lGL -lglut -lX11 -lXcursor -lSDL2 -lm -lpthread -shared -nostdlib -lasound -L./src/libxdiff -lxdiff -L/app/lib32
BUILD = build BUILD = build
@@ -17,14 +18,14 @@ all: lindbergh libxdiff.a lindbergh.so libsegaapi.so libkswapapi.so libposixtime
lindbergh: src/lindbergh/lindbergh.c src/lindbergh/log.c src/lindbergh/log.h src/lindbergh/jvs.c src/lindbergh/jvs.h src/lindbergh/config.h src/lindbergh/config.c src/lindbergh/evdevinput.h src/lindbergh/evdevinput.c lindbergh: src/lindbergh/lindbergh.c src/lindbergh/log.c src/lindbergh/log.h src/lindbergh/jvs.c src/lindbergh/jvs.h src/lindbergh/config.h src/lindbergh/config.c src/lindbergh/evdevinput.h src/lindbergh/evdevinput.c
mkdir -p $(BUILD) mkdir -p $(BUILD)
$(CC) src/lindbergh/lindbergh.c src/lindbergh/log.h src/lindbergh/log.c src/lindbergh/jvs.h src/lindbergh/jvs.c src/lindbergh/config.h src/lindbergh/config.c src/lindbergh/evdevinput.c src/lindbergh/evdevinput.h -o $(BUILD)/lindbergh -lm $(CC) -m32 src/lindbergh/lindbergh.c src/lindbergh/log.h src/lindbergh/log.c src/lindbergh/jvs.h src/lindbergh/jvs.c src/lindbergh/config.h src/lindbergh/config.c src/lindbergh/evdevinput.c src/lindbergh/evdevinput.h -o $(BUILD)/lindbergh -lm
libxdiff.a: $(XDIFF_OBJS) libxdiff.a: $(XDIFF_OBJS)
mkdir -p $(BUILD) mkdir -p $(BUILD)
ar rcs src/libxdiff/libxdiff.a $(XDIFF_OBJS) ar rcs src/libxdiff/libxdiff.a $(XDIFF_OBJS)
src/libxdiff/xdiff/%.o: src/libxdiff/xdiff/%.c src/libxdiff/xdiff/%.o: src/libxdiff/xdiff/%.c
$(CC) -DHAVE_CONFIG_H -fPIC -c $< -o $@ $(CC) -m32 -DHAVE_CONFIG_H -fPIC -c $< -o $@
lindbergh.so: $(OBJS) lindbergh.so: $(OBJS)
mkdir -p $(BUILD) mkdir -p $(BUILD)
@@ -34,13 +35,13 @@ lindbergh.so: $(OBJS)
$(CC) $(CFLAGS) -c $< -o $@ $(CC) $(CFLAGS) -c $< -o $@
libsegaapi.so: src/libsegaapi/libsegaapi.o libsegaapi.so: src/libsegaapi/libsegaapi.o
gcc -m32 -O0 -g src/libsegaapi/libsegaapi.c -lFAudio -fPIC -shared -o $(BUILD)/libsegaapi.so $(CC) -m32 -O0 -g src/libsegaapi/libsegaapi.c -lFAudio -L/app/lib32 -fPIC -shared -o $(BUILD)/libsegaapi.so
libkswapapi.so: src/libkswapapi/libkswapapi.o libkswapapi.so: src/libkswapapi/libkswapapi.o
$(CC) src/libkswapapi/libkswapapi.o -fPIC -shared -o $(BUILD)/libkswapapi.so $(CC) -m32 src/libkswapapi/libkswapapi.o -fPIC -shared -o $(BUILD)/libkswapapi.so
libposixtime.so: libposixtime.so:
$(CC) src/libposixtime/libposixtime.c src/libposixtime/libposixtime.h -m32 -shared -o $(BUILD)/libposixtime.so $(CC) -m32 src/libposixtime/libposixtime.c src/libposixtime/libposixtime.h -m32 -shared -o $(BUILD)/libposixtime.so
ln -s -f libposixtime.so $(BUILD)/libposixtime.so.1 ln -s -f libposixtime.so $(BUILD)/libposixtime.so.1
ln -s -f libposixtime.so $(BUILD)/libposixtime.so.2.4 ln -s -f libposixtime.so $(BUILD)/libposixtime.so.2.4
+19 -1
View File
@@ -2,7 +2,25 @@
All notable changes to this project will be documented in this file. 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 ### Added
- Display a warning when loading an Elf that is not clean. - Display a warning when loading an Elf that is not clean.
- Added to the lib folder, common libraries that are usually missing. - Added to the lib folder, common libraries that are usually missing.
+127 -42
View File
@@ -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. 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) | | Game Name | Game ID | DVP | NVidia | Intel (Mesa) | AMD (Mesa) | AMD (proprietary) |
|---------------------------------|---------|----------|--------|--------------|------------|-------------------| |--------------------------------------------------|---------|-----------|--------|--------------|------------|-------------------|
| 2 Spicy | SBMV | DVP-0027 | ✓ | ✓ | ✓ | ✓ | | After Burner Climax | SBLR | DVP-0009 | ✓ | ✓ | ✓ | |
| After Burner Climax | SBLR | DVP-0009 | ✓ | ✓ | ✓ | | | After Burner Climax Rev A | SBLR | DVP-0009A | ✓ | ✓ | ✓ | |
| Ghost Squad Evolution | SBNJ | DVP-0029 | ✓ | ✓ | ✓ | ✓ | | After Burner Climax Rev B | SBLR | DVP-0009B | ✓ | ✓ | ✓ | |
| Harley Davidson | SBRG | DVP-5007 | ✓ | ✓ | ✓ | ✓ | | After Burner Climax SDX | SBMN | DVP-0018 | ✓ | ✓ | ✓ | |
| Hummer Extreme | SBST | DVP-0079 | ✓ | ✓ | ✓ | ✓ | | After Burner Climax SDX Rev A | SBMN | DVP-0018A | ✓ | ✓ | ✓ | |
| Hummer | SBQN | DVP-0057 | ✓ | ✓ | ✓ | ✓ | | After Burner Climax SE | SBLR | DVP-0031 | ✓ | ✓ | ✓ | |
| Let's Go Jungle | SBLU | DVP-0011 | ✓ | ✓ | ✓ | | | After Burner Climax SE Rev A | SBLR | DVP-0031A | ✓ | ✓ | ✓ | |
| Let's Go Jungle Special | SBNR | DVP-0036 | ✓ | ✓ | ✓ | | | Ghost Squad Evolution | SBNJ | DVP-0029 | ✓ | ✓ | ✓ | ✓ |
| Outrun 2 SP SDX | SBMB | DVP-0015 | ✓ | ✓ | ✓ | ✓ | | Harley Davidson | SBRG | DVP-5007 | ✓ | ✓ | ✓ | ✓ |
| R-Tuned | SBQW | DVP-0060 | ✓ | ✓ | ✓ | ✓ | | Hummer | SBQN | DVP-0057B | ✓ | ✓ | ✓ | ✓ |
| Race TV | SBPF | DVP-0044 | ✓ | ✓ | ✓ | ✓ | | Hummer SDLX | SBST | DVP-0057 | ✓ | ✓ | ✓ | ✓ |
| Rambo | SBQL | DVP-0069 | ✓ | ✓ | ✓ | ✓ | | Hummer Extreme | SBST | DVP-0079 | ✓ | ✓ | ✓ | ✓ |
| The House of the Dead 4 | SBLC | DVP-0003 | ✓ | ✓ | ✓ | ✓ | | Hummer Extreme MDX | SBST | DVP-0083 | ✓ | ✓ | ✓ | ✓ |
| The House of the Dead 4 Special | SBLS | DVP-0010 | ✓ | ✓ | ✓ | ✓ | | Initial D Arcade Stage 4 Rev A | SBML | DVP-0019A | ✓ | ✓ | ✓ | ✓ |
| The House of the Dead Ex | SBRC | DVP-0063 | ✓ | ✓ | ✓ | ✓ | | Initial D Arcade Stage 4 Rev B | SBML | DVP-0019B | ✓ | ✓ | ✓ | ✓ |
| Virtua Fighter 5 | SBLM | DVP-0008 | ✓ | ✓ | ✓ | ✓ | | Initial D Arcade Stage 4 Rev C | SBML | DVP-0019C | ✓ | ✓ | ✓ | ✓ |
| Virtua Fighter 5 R | SBQU | DVP-5004 | ✓ | ✓ | ✓ | ✓ | | Initial D Arcade Stage 4 Rev D | SBML | DVP-0019D | ✓ | ✓ | ✓ | ✓ |
| Virtua Fighter 5 FS | SBUV | DVP-5019 | ✓ | ✓ | ✓ | ✓ | | Initial D Arcade Stage 4 Rev G | SBML | DVP-0019G | ✓ | ✓ | ✓ | ✓ |
| Initial D 4 | SBNK | DVP-0030 | ✓ | ✓ | ✓ | ✓ | | Initial D Arcade Stage 4 Export Rev B | SBNK | DVP-0030B | ✓ | ✓ | ✓ | ✓ |
| Initial D 5 | SBTS | DVP-0075 | ✓ | ✓ | ✓ | | | Initial D Arcade Stage 4 Export Rev C | SBNK | DVP-0030C | ✓ | ✓ | ✓ | ✓ |
| Virtua Tennis 3 | SBKX | DVP-0005 | ✓ | ✓ | ✓ | ✓ | | Initial D Arcade Stage 4 Export Rev D | SBNK | DVP-0030D | ✓ | ✓ | ✓ | ✓ |
| Primeval Hunt | SBPP | DVP-0048 | ✓ | ✓ | ✓ | ✓ | | 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 ## 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 ### 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 ### Outrun 2 SP SDX
You need to set `SKIP_OUTRUN_CABINET_CHECK` to 1 in `lindbergh.conf` to play in DX, SDX or Standard cabinet types. - You need to set `SKIP_OUTRUN_CABINET_CHECK` to 1 in `lindbergh.conf` to play in DX, SDX or Standard cabinet types.
### Ghost Squad / 2Spicy
You may have sound issues such as the game complaining that the system cannot open `/dev[/sound]/dsp`. You **must not** use the `libopenal.so.0` files that came with the game, please delete those if you've moved them into your game folder. Do the following:
```
sudo apt install pipewire-audio-client-libraries:i386
sudo cp /usr/share/doc/pipewire/examples/alsa.conf.d/99-pipewire-default.conf /etc/alsa/conf.d/
```
Then in the game folder you must create a symlink to the `libopenal.so.1` library installed on your system:
```
ln -s /usr/lib/i386-linux-gnu/libopenal.so.1 libopenal.so.0
```
## Configuration File : lindbergh.conf ## 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. 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.
+48 -30
View File
@@ -1,5 +1,5 @@
# SEGA Lindbergh Emulator Configuration File # SEGA Lindbergh Emulator Configuration File
# By the Lindbergh Development Team # By the Lindbergh Development Team 2024-2025
# Set the requested dip switch width here # Set the requested dip switch width here
WIDTH AUTO WIDTH AUTO
@@ -7,28 +7,31 @@ WIDTH AUTO
# Set the requested dip switch height here # Set the requested dip switch height here
HEIGHT AUTO 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 # Set if the emulator should go full screen
FULLSCREEN 0 # FULLSCREEN 0
# Sets the Input Mode # Sets the Input Mode
# Mode 0: will use both SDL/X11 and EVDEV inputs (default) # Mode 0: will use both SDL/X11 and EVDEV inputs (default)
# Mode 1: will use SDL/X11 inputs only # 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 # 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) # 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 ) # Set the Region ( JP/US/EX )
REGION EX # REGION EX
# Set if you want the game to be Free Play # 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. # 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 # 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. # 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 # 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 # 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 # 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 # If this is set to 0, then the emulator will route the traffic to one of the serial ports
EMULATE_MOTIONBOARD AUTO EMULATE_MOTIONBOARD AUTO
# Set if the loader should emulate the card reader in Virtua Tenis 3 # 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 # Card File for reader 1
# CARDFILE_01 Card_01.crd # CARDFILE_01 Card_01.crd
@@ -51,7 +58,7 @@ EMULATE_MOTIONBOARD AUTO
# CARDFILE_02 Card_02.crd # CARDFILE_02 Card_02.crd
# Define the path to pass the JVS packets to if JVS is not being emulated. # 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. # Define the path to pass the first serial port to if it's not being emulated.
# SERIAL_1_PATH /dev/ttyUSB0 # SERIAL_1_PATH /dev/ttyUSB0
@@ -60,47 +67,47 @@ JVS_PATH /dev/ttyUSB0
# SERIAL_2_PATH /dev/ttyUSB0 # SERIAL_2_PATH /dev/ttyUSB0
# Define the path to the sram.bin file # Define the path to the sram.bin file
SRAM_PATH sram.bin # SRAM_PATH sram.bin
# Define the path to the eeprom.bin file # 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) # 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 # 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 # 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 # 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 # Set the thickness of the black border which sits around the
# white border as a percentage of the width of the screen # 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 # 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 # 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 # 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 # 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 # 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) # 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) # 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 # Set the Primeval Hunt mode
# Mode 0: Default (Side by Side) # Mode 0: Default (Side by Side)
@@ -108,37 +115,48 @@ LGJ_RENDER_WITH_MESA 1
# Mode 2: Side by Side # Mode 2: Side by Side
# Mode 3: 3ds mode 1 (Touch screen to the right) # Mode 3: 3ds mode 1 (Touch screen to the right)
# Mode 4: 3ds mode 2 (Touch screen to the bottom) # 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 # 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 # 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 # 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) # Set the custom mouse pointer from a PNG file (Usefull for shooting games)
# CUSTOM_CURSOR myCustomCursor.png # CUSTOM_CURSOR myCustomCursor.png
# Set the width of the custom cursor # Set the width of the custom cursor
CUSTOM_CURSOR_WIDTH 32 # CUSTOM_CURSOR_WIDTH 32
# Set the height of the custom cursor # 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? # Hacky way to make MJ4 work at prohibited times?
# MJ4_ENABLED_ALL_THE_TIME 1 # MJ4_ENABLED_ALL_THE_TIME 1
# Sets the IP address in the eeprom for Outrun link (you have to put your NIC ip) # Sets the IP address in the eeprom for Outrun link (you have to put your NIC ip)
# OR2_IP 192.168.1.2 # 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) # 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 # CPU_FREQ_GHZ 4.0
# Set the colour of the lindbergh to change the Segaboot logo # Set the colour of the lindbergh to change the Segaboot logo
# Possible colours are: YELLOW, RED, BLUE, SILVER, REDEX # Possible colours are: YELLOW, RED, BLUE, SILVER, REDEX
LINDBERGH_COLOUR YELLOW # LINDBERGH_COLOUR YELLOW
# X11 MODE (Input Mode 1) # X11 MODE (Input Mode 1)
# To find the value pairs for these run `xev` on linux # To find the value pairs for these run `xev` on linux
+4
View File
@@ -0,0 +1,4 @@
.flatpak-builder/
build/
repo/
*.flatpak
+4
View File
@@ -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
Binary file not shown.
+36
View File
@@ -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<T*>(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<T*>(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<T*>(get_user ());
};
@@ -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
+19 -8
View File
@@ -1,7 +1,6 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
@@ -11,6 +10,8 @@
#define BLOCKSIZE 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, 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, 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}; 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() int initCardReader()
{ {
uint32_t gId = getConfig()->crc32; EmulatorConfig *config = getConfig();
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 && switch (gId)
gId != VIRTUA_TENNIS_3_REVC_TEST && gId != R_TUNED)
{ {
printf("Warning: This Game does not support Card Reader, please disable the card reader emulation in the config file.\n"); case R_TUNED:
printf(" I will disable the card reader for you.\n"); case VIRTUA_TENNIS_3:
EmulatorConfig *config = getConfig(); 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; config->emulateCardreader = 0;
return 0; return 0;
} }
if (getConfig()->emulateCardreader && getConfig()->emulateDriveboard && gId != R_TUNED) 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"); printf("Warning: This Game does not support Card Reader and Driver Board emulation enabled at the same time.\n");
+35 -3
View File
@@ -619,6 +619,7 @@ static int detectGame(uint32_t elf_crc)
config.gameReleaseYear = "2008"; config.gameReleaseYear = "2008";
config.gameNativeResolutions = "640x480"; config.gameNativeResolutions = "640x480";
config.emulateDriveboard = 1; config.emulateDriveboard = 1;
config.emulateCardreader = 1;
config.gameStatus = WORKING; config.gameStatus = WORKING;
config.gameType = DRIVING; config.gameType = DRIVING;
config.width = 640; config.width = 640;
@@ -947,6 +948,7 @@ static int detectGame(uint32_t elf_crc)
config.gameID = "SBKX"; config.gameID = "SBKX";
config.gameReleaseYear = "2006"; config.gameReleaseYear = "2006";
config.gameNativeResolutions = "640x480, 1360x768"; config.gameNativeResolutions = "640x480, 1360x768";
config.emulateCardreader = 1;
config.gameStatus = WORKING; config.gameStatus = WORKING;
config.width = 1360; config.width = 1360;
config.height = 768; config.height = 768;
@@ -962,6 +964,7 @@ static int detectGame(uint32_t elf_crc)
config.gameID = "SBKX"; config.gameID = "SBKX";
config.gameReleaseYear = "2006"; config.gameReleaseYear = "2006";
config.gameNativeResolutions = "640x480, 1360x768"; config.gameNativeResolutions = "640x480, 1360x768";
config.emulateCardreader = 1;
config.gameType = FIGHTING; config.gameType = FIGHTING;
config.gameStatus = WORKING; config.gameStatus = WORKING;
config.width = 1360; config.width = 1360;
@@ -978,6 +981,7 @@ static int detectGame(uint32_t elf_crc)
config.gameID = "SBKX"; config.gameID = "SBKX";
config.gameReleaseYear = "2006"; config.gameReleaseYear = "2006";
config.gameNativeResolutions = "640x480, 1360x768"; config.gameNativeResolutions = "640x480, 1360x768";
config.emulateCardreader = 1;
config.gameType = FIGHTING; config.gameType = FIGHTING;
config.gameStatus = WORKING; config.gameStatus = WORKING;
config.width = 1360; config.width = 1360;
@@ -994,6 +998,7 @@ static int detectGame(uint32_t elf_crc)
config.gameID = "SBKX"; config.gameID = "SBKX";
config.gameReleaseYear = "2006"; config.gameReleaseYear = "2006";
config.gameNativeResolutions = "640x480, 1360x768"; config.gameNativeResolutions = "640x480, 1360x768";
config.emulateCardreader = 1;
config.gameType = FIGHTING; config.gameType = FIGHTING;
config.gameStatus = WORKING; config.gameStatus = WORKING;
config.width = 1360; config.width = 1360;
@@ -1069,7 +1074,7 @@ int getNextIntOrAuto(char *saveptr, int defaultValue) {
strcpy(nextToken, getNextToken(NULL, " ", &saveptr)); strcpy(nextToken, getNextToken(NULL, " ", &saveptr));
toLowerCase(nextToken); toLowerCase(nextToken);
if(strcmp(nextToken, "auto") == 0) if (strcmp(nextToken, "auto") == 0)
return defaultValue; return defaultValue;
return atoi(nextToken); return atoi(nextToken);
@@ -1099,6 +1104,9 @@ int readConfig(FILE *configFile, EmulatorConfig *config)
config->height = getNextIntOrAuto(saveptr, defaultValue); 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) else if (strcmp(command, "EEPROM_PATH") == 0)
strcpy(config->eepromPath, getNextToken(NULL, " ", &saveptr)); strcpy(config->eepromPath, getNextToken(NULL, " ", &saveptr));
@@ -1121,7 +1129,13 @@ int readConfig(FILE *configFile, EmulatorConfig *config)
} }
else if (strcmp(command, "EMULATE_CARDREADER") == 0) 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) else if (strcmp(command, "CARDFILE_01") == 0)
strcpy(config->cardFile1, getNextToken(NULL, " ", &saveptr)); strcpy(config->cardFile1, getNextToken(NULL, " ", &saveptr));
@@ -1237,6 +1251,15 @@ int readConfig(FILE *configFile, EmulatorConfig *config)
else if (strcmp(command, "CUSTOM_CURSOR_HEIGHT") == 0) else if (strcmp(command, "CUSTOM_CURSOR_HEIGHT") == 0)
config->customCursorHeight = atoi(getNextToken(NULL, " ", &saveptr)); 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) else if (strcmp(command, "MJ4_ENABLED_ALL_THE_TIME") == 0)
config->phMode = atoi(getNextToken(NULL, " ", &saveptr)); config->phMode = atoi(getNextToken(NULL, " ", &saveptr));
@@ -1339,6 +1362,8 @@ int readConfig(FILE *configFile, EmulatorConfig *config)
strncpy(config->arcadeInputs.player1_button_9, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1); strncpy(config->arcadeInputs.player1_button_9, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "PLAYER_1_BUTTON_10") == 0) else if (strcmp(command, "PLAYER_1_BUTTON_10") == 0)
strncpy(config->arcadeInputs.player1_button_10, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1); strncpy(config->arcadeInputs.player1_button_10, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "PLAYER_1_COIN") == 0)
strncpy(config->arcadeInputs.player1_coin, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1);
// Player 2 controls // Player 2 controls
else if (strcmp(command, "PLAYER_2_BUTTON_START") == 0) else if (strcmp(command, "PLAYER_2_BUTTON_START") == 0)
@@ -1378,6 +1403,8 @@ int readConfig(FILE *configFile, EmulatorConfig *config)
strncpy(config->arcadeInputs.player2_button_9, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1); strncpy(config->arcadeInputs.player2_button_9, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1);
else if (strcmp(command, "PLAYER_2_BUTTON_10") == 0) else if (strcmp(command, "PLAYER_2_BUTTON_10") == 0)
strncpy(config->arcadeInputs.player2_button_10, getNextToken(NULL, " ", &saveptr), INPUT_STRING_LENGTH - 1); 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 // Analogue inputs
else if (strcmp(command, "ANALOGUE_1") == 0) else if (strcmp(command, "ANALOGUE_1") == 0)
@@ -1494,6 +1521,7 @@ int initConfig(const char* configFilePath)
config.emulateDriveboard = 0; config.emulateDriveboard = 0;
config.emulateMotionboard = 0; config.emulateMotionboard = 0;
config.emulateCardreader = 0; config.emulateCardreader = 0;
config.emulateTouchscreen = 0;
strcpy(config.cardFile1, "Card_01.crd"); strcpy(config.cardFile1, "Card_01.crd");
strcpy(config.cardFile2, "Card_02.crd"); strcpy(config.cardFile2, "Card_02.crd");
config.emulateJVS = 1; config.emulateJVS = 1;
@@ -1506,6 +1534,7 @@ int initConfig(const char* configFilePath)
strcpy(config.serial2Path, "/dev/ttyS1"); strcpy(config.serial2Path, "/dev/ttyS1");
config.width = 640; config.width = 640;
config.height = 480; config.height = 480;
config.boostRenderRes = 1;
config.region = EX; config.region = EX;
config.freeplay = -1; config.freeplay = -1;
config.showDebugMessages = 0; config.showDebugMessages = 0;
@@ -1526,13 +1555,16 @@ int initConfig(const char* configFilePath)
config.fpsLimiter = 0; config.fpsLimiter = 0;
config.fpsTarget = 60; config.fpsTarget = 60;
config.noSDL = 0; config.noSDL = 0;
config.phMode = 1; config.phMode = 2;
config.disableBuiltinFont = 0; config.disableBuiltinFont = 0;
config.disableBuiltinLogos = 0; config.disableBuiltinLogos = 0;
config.hideCursor = 1; config.hideCursor = 1;
strcpy(config.customCursor, ""); strcpy(config.customCursor, "");
config.customCursorWidth = 32; config.customCursorWidth = 32;
config.customCursorHeight = 32; config.customCursorHeight = 32;
strcpy(config.phTouchCursor, "");
config.phTouchCursorWidth = 32;
config.phTouchCursorHeight = 32;
config.mj4EnabledAtT = 0; config.mj4EnabledAtT = 0;
strcpy(config.or2IP, ""); strcpy(config.or2IP, "");
+8 -1
View File
@@ -183,6 +183,7 @@ typedef struct {
char player1_button_8[INPUT_STRING_LENGTH]; char player1_button_8[INPUT_STRING_LENGTH];
char player1_button_9[INPUT_STRING_LENGTH]; char player1_button_9[INPUT_STRING_LENGTH];
char player1_button_10[INPUT_STRING_LENGTH]; char player1_button_10[INPUT_STRING_LENGTH];
char player1_coin[INPUT_STRING_LENGTH];
// Player 2 controls // Player 2 controls
char player2_button_start[INPUT_STRING_LENGTH]; char player2_button_start[INPUT_STRING_LENGTH];
@@ -201,7 +202,8 @@ typedef struct {
char player2_button_8[INPUT_STRING_LENGTH]; char player2_button_8[INPUT_STRING_LENGTH];
char player2_button_9[INPUT_STRING_LENGTH]; char player2_button_9[INPUT_STRING_LENGTH];
char player2_button_10[INPUT_STRING_LENGTH]; char player2_button_10[INPUT_STRING_LENGTH];
char player2_coin[INPUT_STRING_LENGTH];
// Analogue inputs // Analogue inputs
char analogue_1[INPUT_STRING_LENGTH]; char analogue_1[INPUT_STRING_LENGTH];
char analogue_2[INPUT_STRING_LENGTH]; char analogue_2[INPUT_STRING_LENGTH];
@@ -224,6 +226,7 @@ typedef struct
int emulateDriveboard; int emulateDriveboard;
int emulateMotionboard; int emulateMotionboard;
int emulateCardreader; int emulateCardreader;
int emulateTouchscreen;
char cardFile1[MAX_PATH_LENGTH]; char cardFile1[MAX_PATH_LENGTH];
char cardFile2[MAX_PATH_LENGTH]; char cardFile2[MAX_PATH_LENGTH];
int emulateJVS; int emulateJVS;
@@ -235,6 +238,7 @@ typedef struct
char serial2Path[MAX_PATH_LENGTH]; char serial2Path[MAX_PATH_LENGTH];
int width; int width;
int height; int height;
int boostRenderRes;
Colour lindberghColour; Colour lindberghColour;
GameStatus gameStatus; GameStatus gameStatus;
GameType gameType; GameType gameType;
@@ -267,6 +271,9 @@ typedef struct
char customCursor[MAX_PATH_LENGTH]; char customCursor[MAX_PATH_LENGTH];
int customCursorWidth; int customCursorWidth;
int customCursorHeight; int customCursorHeight;
char phTouchCursor[MAX_PATH_LENGTH];
int phTouchCursorWidth;
int phTouchCursorHeight;
int mj4EnabledAtT; int mj4EnabledAtT;
char or2IP[16]; char or2IP[16];
char or2Netmask[16]; char or2Netmask[16];
+229
View File
@@ -0,0 +1,229 @@
#include <SDL2/SDL_events.h>
#include <SDL2/SDL_mouse.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#define STBI_ONLY_PNG
#define STBI_SUPPORT_ZLIB
#define STBI_NO_SIMD
#include <SDL2/SDL.h>
#include <X11/Xlib.h>
#include <X11/Xcursor/Xcursor.h>
#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);
}
}
+10
View File
@@ -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
+22 -16
View File
@@ -16,6 +16,8 @@
#define I2C_SEEK 2 #define I2C_SEEK 2
#define I2C_WRITE 3 #define I2C_WRITE 3
extern uint32_t gId;
union i2c_smbus_data { union i2c_smbus_data {
uint8_t byte; uint8_t byte;
uint16_t word; uint16_t word;
@@ -68,36 +70,40 @@ int initEeprom()
setFreeplay(eeprom, getConfig()->freeplay); setFreeplay(eeprom, getConfig()->freeplay);
} }
if ((getConfig()->crc32 == LETS_GO_JUNGLE_SPECIAL) || (getConfig()->crc32 == THE_HOUSE_OF_THE_DEAD_EX) || switch (gId)
(getConfig()->crc32 == THE_HOUSE_OF_THE_DEAD_4_SPECIAL) ||
(getConfig()->crc32 == THE_HOUSE_OF_THE_DEAD_4_SPECIAL_REVB))
{ {
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) if (fixCreditSection(eeprom) != 0)
{ {
printf("Error initializing eeprom settings."); printf("Error initializing eeprom settings.");
fclose(eeprom); fclose(eeprom);
return 1; return 1;
} }
} break;
case HUMMER:
if (getConfig()->crc32 == HUMMER || getConfig()->crc32 == HUMMER_SDLX || getConfig()->crc32 == HUMMER_EXTREME || case HUMMER_SDLX:
getConfig()->crc32 == HUMMER_EXTREME_MDX) case HUMMER_EXTREME:
{ case HUMMER_EXTREME_MDX:
if (fixCoinAssignmentsHummer(eeprom) != 0) if (fixCoinAssignmentsHummer(eeprom) != 0)
{ {
printf("Error initializing eeprom settings."); printf("Error initializing eeprom settings.");
fclose(eeprom); fclose(eeprom);
return 1; return 1;
} }
} break;
case OUTRUN_2_SP_SDX:
if ((getConfig()->crc32 == OUTRUN_2_SP_SDX || getConfig()->crc32 == OUTRUN_2_SP_SDX_REVA) && strcmp(getConfig()->or2IP, "") != 0) case OUTRUN_2_SP_SDX_REVA:
{ if (strcmp(getConfig()->or2IP, "") != 0)
if (setIP(eeprom, getConfig()->or2IP, getConfig()->or2Netmask) != 0)
{ {
printf("Error setting the new IP address."); if (setIP(eeprom, getConfig()->or2IP, getConfig()->or2Netmask) != 0)
fclose(eeprom); {
return 1; printf("Error setting the new IP address.");
fclose(eeprom);
return 1;
}
} }
} }
-1
View File
@@ -3,7 +3,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "config.h"
#include "eeprom_settings.h" #include "eeprom_settings.h"
uint32_t crc32_table[255]; uint32_t crc32_table[255];
+155 -18
View File
@@ -41,6 +41,7 @@ ArcadeInput arcadeInputs[] = {{"TEST_BUTTON", 0, BUTTON_TEST, 1},
{"PLAYER_1_BUTTON_8", 1, BUTTON_8, 1}, {"PLAYER_1_BUTTON_8", 1, BUTTON_8, 1},
{"PLAYER_1_BUTTON_9", 1, BUTTON_9, 1}, {"PLAYER_1_BUTTON_9", 1, BUTTON_9, 1},
{"PLAYER_1_BUTTON_10", 1, BUTTON_10, 1}, {"PLAYER_1_BUTTON_10", 1, BUTTON_10, 1},
{"PLAYER_1_COIN", 1, COIN, 1},
{"PLAYER_2_BUTTON_START", 2, BUTTON_START, 1}, {"PLAYER_2_BUTTON_START", 2, BUTTON_START, 1},
{"PLAYER_2_BUTTON_SERVICE", 2, BUTTON_SERVICE, 1}, {"PLAYER_2_BUTTON_SERVICE", 2, BUTTON_SERVICE, 1},
@@ -58,6 +59,7 @@ ArcadeInput arcadeInputs[] = {{"TEST_BUTTON", 0, BUTTON_TEST, 1},
{"PLAYER_2_BUTTON_8", 2, BUTTON_8, 1}, {"PLAYER_2_BUTTON_8", 2, BUTTON_8, 1},
{"PLAYER_2_BUTTON_9", 2, BUTTON_9, 1}, {"PLAYER_2_BUTTON_9", 2, BUTTON_9, 1},
{"PLAYER_2_BUTTON_10", 2, BUTTON_10, 1}, {"PLAYER_2_BUTTON_10", 2, BUTTON_10, 1},
{"PLAYER_2_COIN", 2, COIN, 1},
{"ANALOGUE_1", 0, ANALOGUE_1, 1}, {"ANALOGUE_1", 0, ANALOGUE_1, 1},
{"ANALOGUE_2", 0, ANALOGUE_2, 1}, {"ANALOGUE_2", 0, ANALOGUE_2, 1},
@@ -920,6 +922,11 @@ static ControllerStatus listControllers(Controllers *controllers)
strcat(controllerInput->inputName, "_"); strcat(controllerInput->inputName, "_");
strcat(controllerInput->inputName, codename(EV_KEY, code)); strcat(controllerInput->inputName, codename(EV_KEY, code));
normaliseName(controllerInput->inputName); 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)
} }
} }
} }
@@ -941,6 +948,14 @@ static ControllerStatus listControllers(Controllers *controllers)
strcat(controllerInput->inputName, "_"); strcat(controllerInput->inputName, "_");
strcat(controllerInput->inputName, codename(EV_ABS, code)); strcat(controllerInput->inputName, codename(EV_ABS, code));
normaliseName(controllerInput->inputName); 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
}
ControllerInput *minControllerInput = ControllerInput *minControllerInput =
&controllers->controller[i].inputs[controllers->controller[i].inputCount++]; &controllers->controller[i].inputs[controllers->controller[i].inputCount++];
@@ -949,6 +964,15 @@ static ControllerStatus listControllers(Controllers *controllers)
minControllerInput->specialFunction = ANALOGUE_TO_DIGITAL_MIN; minControllerInput->specialFunction = ANALOGUE_TO_DIGITAL_MIN;
strcpy(minControllerInput->inputName, controllerInput->inputName); strcpy(minControllerInput->inputName, controllerInput->inputName);
strcat(minControllerInput->inputName, "_MIN"); 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
}
ControllerInput *maxControllerInput = ControllerInput *maxControllerInput =
&controllers->controller[i].inputs[controllers->controller[i].inputCount++]; &controllers->controller[i].inputs[controllers->controller[i].inputCount++];
@@ -957,6 +981,27 @@ static ControllerStatus listControllers(Controllers *controllers)
maxControllerInput->specialFunction = ANALOGUE_TO_DIGITAL_MAX; maxControllerInput->specialFunction = ANALOGUE_TO_DIGITAL_MAX;
strcpy(maxControllerInput->inputName, controllerInput->inputName); strcpy(maxControllerInput->inputName, controllerInput->inputName);
strcat(maxControllerInput->inputName, "_MAX"); 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
}
struct input_absinfo absoluteFeatures; struct input_absinfo absoluteFeatures;
ioctl(controller, EVIOCGABS(code), &absoluteFeatures); ioctl(controller, EVIOCGABS(code), &absoluteFeatures);
@@ -1048,8 +1093,13 @@ void *controllerThread(void *_args)
continue; continue;
} }
setSwitch(args->controller->keyTriggers[event.code].player, if(args->controller->keyTriggers[event.code].isCoin == 1) {
args->controller->keyTriggers[event.code].channel, event.value == 0 ? 0 : 1); if(event.value == 1)
incrementCoin(args->controller->keyTriggers[event.code].player, 1);
} else
setSwitch(args->controller->keyTriggers[event.code].player,
args->controller->keyTriggers[event.code].channel, event.value == 0 ? 0 : 1);
} }
break; break;
@@ -1059,31 +1109,67 @@ void *controllerThread(void *_args)
((double)event.value - (double)args->controller->absMin[event.code]) / ((double)event.value - (double)args->controller->absMin[event.code]) /
((double)args->controller->absMax[event.code] - (double)args->controller->absMin[event.code]); ((double)args->controller->absMax[event.code] - (double)args->controller->absMin[event.code]);
if(args->controller->absTriggers[event.code].isNeg == 1) {
scaled = 1.0 - scaled;
}
if (args->controller->absTriggers[event.code].enabled) if (args->controller->absTriggers[event.code].enabled)
{ {
int channel = args->controller->absTriggers[event.code].channel; int channel = args->controller->absTriggers[event.code].channel;
// Deadzone handling
if (scaled < analogue_deadzones[channel].start_max) if (args->controller->absTriggers[event.code].isAnalogue) {
// Deadzone handling
if (scaled < analogue_deadzones[channel].start_max)
scaled = 0.0; scaled = 0.0;
if (scaled > analogue_deadzones[channel].middle_min && scaled < analogue_deadzones[channel].middle_max) if (scaled > analogue_deadzones[channel].middle_min && scaled < analogue_deadzones[channel].middle_max)
scaled = 0.5; scaled = 0.5;
if (scaled > analogue_deadzones[channel].end_min) if (scaled > analogue_deadzones[channel].end_min)
scaled = 1.0; scaled = 1.0;
setAnalogue(channel, scaled * (pow(2, jvsBits) - 1));
setAnalogue(channel, scaled * (pow(2, jvsBits) - 1)); } else {
setSwitch(args->controller->absTriggers[event.code].player,
args->controller->absTriggers[event.code].channel, scaled < 0.8 ? 0 : 1);
}
} }
if (args->controller->absTriggers[event.code].minEnabled) if(event.value <= ((args->controller->absMin[event.code] + args->controller->absMax[event.code]) / 2)) {
{ if (args->controller->absTriggers[event.code].minEnabled)
setSwitch(args->controller->absTriggers[event.code].minPlayer, {
args->controller->absTriggers[event.code].minChannel, scaled < 0.2); int channel = args->controller->absTriggers[event.code].minChannel;
if (args->controller->absTriggers[event.code].isAnalogue) {
setAnalogue(channel, scaled < 0.2 ? 0.0 : pow(2, jvsBits) * 1.0);
} else {
setSwitch(args->controller->absTriggers[event.code].minPlayer,
args->controller->absTriggers[event.code].minChannel, scaled < 0.2 ? 1 : 0);
}
}
} }
if (args->controller->absTriggers[event.code].maxEnabled) if(event.value >= ((args->controller->absMin[event.code] + args->controller->absMax[event.code]) / 2)) {
{ if (args->controller->absTriggers[event.code].maxEnabled)
setSwitch(args->controller->absTriggers[event.code].maxPlayer, {
args->controller->absTriggers[event.code].maxChannel, scaled > 0.8); int channel = args->controller->absTriggers[event.code].maxChannel;
if (args->controller->absTriggers[event.code].isAnalogue) {
setAnalogue(channel, scaled > 0.8 ? pow(2, jvsBits) : 0.0);
} else {
setSwitch(args->controller->absTriggers[event.code].maxPlayer,
args->controller->absTriggers[event.code].maxChannel, scaled > 0.8 ? 1 : 0);
}
}
} }
if (args->controller->absTriggers[event.code].shakeEnabled)
{
int channel = args->controller->absTriggers[event.code].shakeChannel;
if( (scaled > args->controller->absTriggers[event.code].shakePreviousScaled && scaled - args->controller->absTriggers[event.code].shakePreviousScaled > 0.1) ||
(scaled < args->controller->absTriggers[event.code].shakePreviousScaled && -scaled + args->controller->absTriggers[event.code].shakePreviousScaled > 0.1)) {
setAnalogue(channel, 0);
} else {
setAnalogue(channel, pow(2, jvsBits) / 2);
}
args->controller->absTriggers[event.code].shakePreviousScaled = scaled;
}
} }
break; break;
@@ -1106,6 +1192,10 @@ char *getMapping(char *mapping)
// Test button // Test button
if (strcmp(mapping, config->arcadeInputs.test) == 0) if (strcmp(mapping, config->arcadeInputs.test) == 0)
return "TEST_BUTTON"; 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 // Player 1 controls
if (strcmp(mapping, config->arcadeInputs.player1_button_start) == 0) if (strcmp(mapping, config->arcadeInputs.player1_button_start) == 0)
@@ -1232,19 +1322,35 @@ ControllerStatus startControllerThreads(Controllers *controllers)
controllers->controller[i].absTriggers[j].enabled = 0; controllers->controller[i].absTriggers[j].enabled = 0;
controllers->controller[i].absTriggers[j].minEnabled = 0; controllers->controller[i].absTriggers[j].minEnabled = 0;
controllers->controller[i].absTriggers[j].maxEnabled = 0; controllers->controller[i].absTriggers[j].maxEnabled = 0;
controllers->controller[i].absTriggers[j].shakeEnabled = 0;
controllers->controller[i].absTriggers[j].isNeg = 0;
controllers->controller[i].absTriggers[j].isAnalogue = 1;
} }
for (int j = 0; j < KEY_MAX; j++) for (int j = 0; j < KEY_MAX; j++)
{ {
controllers->controller[i].keyTriggers[j].enabled = 0; controllers->controller[i].keyTriggers[j].enabled = 0;
controllers->controller[i].keyTriggers[j].isAnalogue = 0; controllers->controller[i].keyTriggers[j].isAnalogue = 0;
controllers->controller[i].keyTriggers[j].isCoin = 0;
} }
for (int j = 0; j < controllers->controller[i].inputCount; j++) for (int j = 0; j < controllers->controller[i].inputCount; j++)
{ {
char *mapping = getMapping(controllers->controller[i].inputs[j].inputName); char *mapping = getMapping(controllers->controller[i].inputs[j].inputName);
if (mapping == NULL) int negabs = 0;
continue;
if (mapping == NULL) {
// give a 2nd chance with a techninal mapping
mapping = getMapping(controllers->controller[i].inputs[j].inputTechName);
if (mapping == NULL) {
// give a 3rd change with negativ technical mapping
mapping = getMapping(controllers->controller[i].inputs[j].inputTechNegName);
negabs = 1;
if (mapping == NULL) {
continue;
}
}
}
ArcadeInput input = {0}; ArcadeInput input = {0};
ControllerStatus status = getArcadeInputByName(mapping, &input); ControllerStatus status = getArcadeInputByName(mapping, &input);
@@ -1269,6 +1375,9 @@ ControllerStatus startControllerThreads(Controllers *controllers)
input.name); input.name);
controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].player = controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].player =
input.player; input.player;
controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].isNeg = negabs;
if (strstr(input.name, "ANALOGUE") == NULL)
controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].isAnalogue = 0;
} }
break; break;
@@ -1281,6 +1390,9 @@ ControllerStatus startControllerThreads(Controllers *controllers)
input.name); input.name);
controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].maxPlayer = controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].maxPlayer =
input.player; input.player;
controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].isNeg = negabs;
if (strstr(input.name, "ANALOGUE") == NULL)
controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].isAnalogue = 0;
} }
break; break;
@@ -1293,6 +1405,21 @@ ControllerStatus startControllerThreads(Controllers *controllers)
input.name); input.name);
controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].minPlayer = controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].minPlayer =
input.player; input.player;
controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].isNeg = negabs;
if (strstr(input.name, "ANALOGUE") == NULL)
controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].isAnalogue = 0;
}
break;
case ANALOGUE_SHAKE:
{
controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].shakeEnabled = 1;
controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].shakeChannel =
input.channel;
strcpy(controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].shakeName,
input.name);
controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].shakePlayer =
input.player;
} }
break; break;
@@ -1314,6 +1441,16 @@ ControllerStatus startControllerThreads(Controllers *controllers)
if (strstr(input.name, "ANALOGUE") != NULL) if (strstr(input.name, "ANALOGUE") != NULL)
controllers->controller[i].keyTriggers[controllers->controller[i].inputs[j].evCode].isAnalogue = 1; controllers->controller[i].keyTriggers[controllers->controller[i].inputs[j].evCode].isAnalogue = 1;
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; break;
+17 -5
View File
@@ -2,7 +2,7 @@
#include <linux/input-event-codes.h> #include <linux/input-event-codes.h>
#define SIZE 1024 #define SIZE 128
#define CONTROLLER_THREAD_MAX 256 #define CONTROLLER_THREAD_MAX 256
@@ -31,6 +31,15 @@ typedef struct
int maxEnabled; int maxEnabled;
int isAnalogue; int isAnalogue;
int isNeg; // reversed axis
char shakeName[SIZE];
int shakeChannel;
int shakeEnabled;
int shakePlayer;
double shakePreviousScaled;
int isCoin;
} ArcadeInput; } ArcadeInput;
typedef enum typedef enum
@@ -43,12 +52,15 @@ typedef enum {
NO_SPECIAL_FUNCTION = 0, NO_SPECIAL_FUNCTION = 0,
ANALOGUE_TO_DIGITAL_MAX, ANALOGUE_TO_DIGITAL_MAX,
ANALOGUE_TO_DIGITAL_MIN, ANALOGUE_TO_DIGITAL_MIN,
DIGITAL_TO_ANALOGUE DIGITAL_TO_ANALOGUE,
ANALOGUE_SHAKE
} SpecialFunction; } SpecialFunction;
typedef struct typedef struct
{ {
char inputName[SIZE]; char inputName[SIZE];
char inputTechName[SIZE];
char inputTechNegName[SIZE];
int evType; int evType;
int evCode; int evCode;
SpecialFunction specialFunction; SpecialFunction specialFunction;
@@ -57,12 +69,12 @@ typedef struct
typedef struct typedef struct
{ {
char name[SIZE]; char name[SIZE];
char path[SIZE]; char path[320];
char physicalLocation[SIZE]; char physicalLocation[128];
int absMax[ABS_MAX]; int absMax[ABS_MAX];
int absMin[ABS_MAX]; int absMin[ABS_MAX];
ControllerInput inputs[SIZE]; ControllerInput inputs[320];
int inputCount; int inputCount;
ArcadeInput keyTriggers[KEY_MAX]; ArcadeInput keyTriggers[KEY_MAX];
+24 -8
View File
@@ -24,6 +24,7 @@
#include "border.h" #include "border.h"
#include "resolution.h" #include "resolution.h"
extern uint32_t gId;
extern SDL_Window *SDLwindow; extern SDL_Window *SDLwindow;
extern char SDLgameTitle[]; extern char SDLgameTitle[];
extern fps_limit fpsLimit; extern fps_limit fpsLimit;
@@ -36,7 +37,9 @@ void *idleFunc = NULL;
void FGAPIENTRY glutInit(int *argcp, char **argv) 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()) 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"); 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); initSDL(argcp, argv);
} }
@@ -102,10 +111,13 @@ void FGAPIENTRY glutSwapBuffers(void)
return; return;
} }
int gId = config->crc32; switch (gId)
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)
{ {
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(); pollEvents();
} }
@@ -174,11 +186,15 @@ void FGAPIENTRY glutSetCursor(int glutCursor)
if (getConfig()->noSDL) if (getConfig()->noSDL)
{ {
void FGAPIENTRY (*_glutSetCursor)(int glutCursor) = dlsym(RTLD_NEXT, "glutSetCursor"); void FGAPIENTRY (*_glutSetCursor)(int glutCursor) = dlsym(RTLD_NEXT, "glutSetCursor");
_glutSetCursor(glutCursor); if(strcmp(getConfig()->customCursor, "") == 0)
_glutSetCursor(glutCursor);
return; return;
} }
SDL_Cursor *cursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); if (strcmp(getConfig()->customCursor, "") == 0)
SDL_SetCursor(cursor); {
SDL_Cursor *cursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
SDL_SetCursor(cursor);
}
} }
void FGAPIENTRY glutDisplayFunc(void (*callback)(void)) void FGAPIENTRY glutDisplayFunc(void (*callback)(void))
+56 -27
View File
@@ -1,4 +1,3 @@
#include <complex.h>
#define GL_GLEXT_PROTOTYPES #define GL_GLEXT_PROTOTYPES
#ifndef __i386__ #ifndef __i386__
#define __i386__ #define __i386__
@@ -20,6 +19,7 @@
#include <dlfcn.h> #include <dlfcn.h>
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include <sys/time.h> #include <sys/time.h>
#include <stdio.h>
#include "fps_limiter.h" #include "fps_limiter.h"
#include "sdlcalls.h" #include "sdlcalls.h"
@@ -28,11 +28,12 @@
#include "border.h" #include "border.h"
bool sdlGame = false; bool sdlGame = false;
extern uint32_t gId;
extern SDL_Window *SDLwindow; extern SDL_Window *SDLwindow;
extern SDL_GLContext SDLcontext; extern SDL_GLContext SDLcontext;
extern char SDLgameTitle[]; extern char SDLgameTitle[];
extern fps_limit fpsLimit; extern fps_limit fpsLimit;
extern Window win; extern Window window;
void glXSwapBuffers(Display *dpy, GLXDrawable drawable) void glXSwapBuffers(Display *dpy, GLXDrawable drawable)
{ {
@@ -43,14 +44,22 @@ void glXSwapBuffers(Display *dpy, GLXDrawable drawable)
if (config->borderEnabled) if (config->borderEnabled)
drawGameBorder(config->width, config->height, config->whiteBorderPercentage, config->blackBorderPercentage); drawGameBorder(config->width, config->height, config->whiteBorderPercentage, config->blackBorderPercentage);
int gId = getConfig()->crc32; if (getConfig()->noSDL)
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))
{ {
XEvent event; switch (gId)
while (XPending(dpy))
{ {
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 else
@@ -76,7 +85,7 @@ void glXSwapBuffers(Display *dpy, GLXDrawable drawable)
if (getConfig()->noSDL) if (getConfig()->noSDL)
{ {
XStoreName(dpy, win, ""); XStoreName(dpy, window, "");
return; return;
} }
char windowTitle[512]; 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) = GLXFBConfig *(*_glXChooseFBConfig)(Display *dpy, int screen, const int *attrib_list, int *nelements) =
dlsym(RTLD_NEXT, "glXChooseFBConfig"); dlsym(RTLD_NEXT, "glXChooseFBConfig");
int gId = getConfig()->crc32;
char *__GLX_VENDOR_LIBRARY_NAME = getenv("__GLX_VENDOR_LIBRARY_NAME"); char *__GLX_VENDOR_LIBRARY_NAME = getenv("__GLX_VENDOR_LIBRARY_NAME");
char *__NV_PRIME_RENDER_OFFLOAD = getenv("__NV_PRIME_RENDER_OFFLOAD"); char *__NV_PRIME_RENDER_OFFLOAD = getenv("__NV_PRIME_RENDER_OFFLOAD");
if (__GLX_VENDOR_LIBRARY_NAME == NULL) if (__GLX_VENDOR_LIBRARY_NAME == NULL)
__GLX_VENDOR_LIBRARY_NAME = " "; __GLX_VENDOR_LIBRARY_NAME = " ";
if (__NV_PRIME_RENDER_OFFLOAD == NULL) if (__NV_PRIME_RENDER_OFFLOAD == NULL)
__NV_PRIME_RENDER_OFFLOAD = " "; __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) || switch (gId)
(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)))
{ {
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]; if (attrib_list[i] == GLX_DOUBLEBUFFER)
patchMemory((intptr_t)ptr, "01"); {
setVariable((intptr_t)ptr, GLX_DONT_CARE); 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); return _glXChooseFBConfig(dpy, screen, attrib_list, nelements);
} }
@@ -306,20 +324,31 @@ GLXFBConfigSGIX *glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_lis
__GLX_VENDOR_LIBRARY_NAME = " "; __GLX_VENDOR_LIBRARY_NAME = " ";
if (__NV_PRIME_RENDER_OFFLOAD == NULL) if (__NV_PRIME_RENDER_OFFLOAD == NULL)
__NV_PRIME_RENDER_OFFLOAD = " "; __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) || switch (gId)
(gId == INITIALD_4_REVG) || (gId == INITIALD_4_EXP_REVB) || (gId == INITIALD_4_EXP_REVC) ||
gId == INITIALD_4_EXP_REVD))
{ {
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]; if (attrib_list[i] == GLX_DOUBLEBUFFER)
patchMemory((intptr_t)ptr, "01"); {
int *ptr = (int *)&attrib_list[i + 1];
patchMemory((intptr_t)ptr, "01");
}
} }
} }
} }
}
return glXChooseFBConfig(dpy, screen, attrib_list, nelements); return glXChooseFBConfig(dpy, screen, attrib_list, nelements);
} }
+169 -72
View File
@@ -46,6 +46,7 @@
#include "fps_limiter.h" #include "fps_limiter.h"
#include "evdevinput.h" #include "evdevinput.h"
#include "card_reader.h" #include "card_reader.h"
#include "touchscreen.h"
#include "log.h" #include "log.h"
#include "resources/font.h" #include "resources/font.h"
#include "resources/logo.h" #include "resources/logo.h"
@@ -80,9 +81,12 @@ int logoTGAidx = 0;
uint32_t elf_crc = 0; uint32_t elf_crc = 0;
uint32_t gId = 0;
extern int hummerExtremeShaderFileIndex; extern int hummerExtremeShaderFileIndex;
extern bool cachedShaderFilesLoaded; extern bool cachedShaderFilesLoaded;
extern char vf5StageNameAbbr[5]; extern char vf5StageNameAbbr[5];
bool phShowCursorInGame = false;
extern fps_limit fpsLimit; extern fps_limit fpsLimit;
Controllers controllers = {0}; Controllers controllers = {0};
@@ -102,7 +106,9 @@ static void handleSegfault(int signal, siginfo_t *info, void *ptr)
ucontext_t *ctx = ptr; ucontext_t *ctx = ptr;
// Get the address of the instruction causing the segfault // 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) 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() void __attribute__((constructor)) hook_init()
{ {
// Get offsets of the Game's ELF and calculate CRC32. // Get offsets of the Game's ELF and calculate CRC32.
dl_iterate_phdr(callback, NULL); dl_iterate_phdr(callback, NULL);
@@ -183,15 +216,27 @@ void __attribute__((constructor)) hook_init()
act.sa_flags = SA_SIGINFO; act.sa_flags = SA_SIGINFO;
sigaction(SIGSEGV, &act, NULL); 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); 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) if (getConfig()->fpsLimiter == 1)
{ {
fpsLimit.targetFrameTime = 1000000 / getConfig()->fpsTarget; fpsLimit.targetFrameTime = 1000000 / getConfig()->fpsTarget;
fpsLimit.frameEnd = Clock_now(); fpsLimit.frameEnd = Clock_now();
} }
getGPUVendor(); getGPUVendor();
if (initPatch() != 0) if (initPatch() != 0)
@@ -236,8 +281,6 @@ void __attribute__((constructor)) hook_init()
if (initControllers(&controllers) != 0) if (initControllers(&controllers) != 0)
exit(1); exit(1);
securityBoardSetDipResolution(getConfig()->width, getConfig()->height); securityBoardSetDipResolution(getConfig()->width, getConfig()->height);
printf("\nSEGA Lindbergh Emulator\nBy the Lindbergh Development Team 2025\n\n"); printf("\nSEGA Lindbergh Emulator\nBy the Lindbergh Development Team 2025\n\n");
@@ -255,16 +298,26 @@ void __attribute__((constructor)) hook_init()
} }
printf("\n"); printf("\n");
if (getConfig()->GPUVendor == ATI_GPU && switch (gId)
((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)))
{ {
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"); DIR *(*_opendir)(const char *dirname) = dlsym(RTLD_NEXT, "opendir");
int gId = getConfig()->crc32; switch (gId)
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)
{ {
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) if (strcmp(dirname, "/tmp/") == 0)
{ {
return _opendir(dirname + 1); 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 (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); 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]; return hooks[SERIAL0];
} }
@@ -328,7 +386,7 @@ int open(const char *pathname, int flags, ...)
hooks[SERIAL0] = _open(HOOK_FILE_NAME, flags, mode); hooks[SERIAL0] = _open(HOOK_FILE_NAME, flags, mode);
printf("Warning: SERIAL0 Opened %d\n", hooks[SERIAL0]); 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); cardReaderSetFd(0, hooks[SERIAL0], getConfig()->cardFile1);
return hooks[SERIAL0]; return hooks[SERIAL0];
@@ -339,7 +397,7 @@ int open(const char *pathname, int flags, ...)
if (getConfig()->emulateDriveboard == 0 && getConfig()->emulateMotionboard == 0 && getConfig()->emulateCardreader == 0) if (getConfig()->emulateDriveboard == 0 && getConfig()->emulateMotionboard == 0 && getConfig()->emulateCardreader == 0)
return _open(getConfig()->serial2Path, flags, mode); 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]; 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"); 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) if (strcmp(pathname, "/root/lindbergrc") == 0)
{ {
return _fopen("lindbergrc", mode); return _fopen("lindbergrc", mode);
@@ -515,13 +578,6 @@ FILE *fopen(const char *restrict pathname, const char *restrict mode)
return 0; 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) if (cachedShaderFilesLoaded)
{ {
void *addr = __builtin_return_address(0); void *addr = __builtin_return_address(0);
@@ -554,15 +610,35 @@ FILE *fopen(const char *restrict pathname, const char *restrict mode)
} }
} }
int gId = getConfig()->crc32; switch (gId)
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)
{ {
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) if (strncmp(pathname, "/tmp/", 5) == 0)
{ {
return fopen(pathname + 1, mode); 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); // printf("Path= %s\n", pathname);
return _fopen(pathname, mode); return _fopen(pathname, mode);
@@ -636,28 +712,31 @@ FILE *fopen64(const char *pathname, const char *mode)
} }
} }
if ((getConfig()->crc32 == HUMMER) || (getConfig()->crc32 == HUMMER_SDLX) || int idx;
(getConfig()->crc32 == HUMMER_EXTREME) || (getConfig()->crc32 == HUMMER_EXTREME_MDX)) switch (gId)
{ {
int idx; case HUMMER:
case HUMMER_SDLX:
case HUMMER_EXTREME:
case HUMMER_EXTREME_MDX:
if (shaderFileInList(pathname, &idx)) if (shaderFileInList(pathname, &idx))
{ {
hummerExtremeShaderFileIndex = idx; hummerExtremeShaderFileIndex = idx;
} }
} break;
case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVA:
if ((getConfig()->crc32 == VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVA || getConfig()->crc32 == VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB || case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB:
getConfig()->crc32 == VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB_6000) && case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB_6000:
(getConfig()->GPUVendor != NVIDIA_GPU && getConfig()->GPUVendor != ATI_GPU)) if (getConfig()->GPUVendor != NVIDIA_GPU && getConfig()->GPUVendor != ATI_GPU)
{
char *filename = basename((char *)pathname);
if (strstr(filename, "light_") || strstr(filename, "glow_"))
{ {
printf("Stage: %s\n", filename); char *filename = basename((char *)pathname);
char *start = strchr(filename, '_') + 1; if (strstr(filename, "light_") || strstr(filename, "glow_"))
char *end = strstr(filename, ".txt"); {
strncpy(vf5StageNameAbbr, start, end - start); char *start = strchr(filename, '_') + 1;
vf5StageNameAbbr[end - start] = '\0'; 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 we don't hook the serial just reply with nothing
if (fd == hooks[SERIAL0] || fd == hooks[SERIAL1]) if (fd == hooks[SERIAL0] || fd == hooks[SERIAL1])
{ {
if (gId == PRIMEVAL_HUNT && getConfig()->emulateTouchscreen == 1)
{
phRead(fd, buf, count);
return 1;
}
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]); return freadReplace(buf, size, count, fileRead[FILE_RW2]);
} }
if (stream == fileHooks[FILE_HARLEY]) // if (stream == fileHooks[FILE_HARLEY])
{ // {
return harleyFreadReplace(buf, size, count, fileHooks[FILE_HARLEY]); // return harleyFreadReplace(buf, size, count, fileHooks[FILE_HARLEY]);
} // }
if (stream == fileHooks[FILE_FONT_ABC]) 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); 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); return driveboardWrite(fd, buf, count);
} }
@@ -960,10 +1044,9 @@ int ioctl(int fd, unsigned int request, void *data)
return baseboardIoctl(fd, request, data); return baseboardIoctl(fd, request, data);
} }
// Just accept any IOCTL on serial ports and ignore it
if (fd == hooks[SERIAL0] || fd == hooks[SERIAL1]) 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; uint8_t d = 1;
memcpy(data, &d, sizeof(uint8_t)); 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)
{ {
char *(*_getenv)(const char *name) = dlsym(RTLD_NEXT, "getenv"); char *(*_getenv)(const char *name) = dlsym(RTLD_NEXT, "getenv");
int gId = getConfig()->crc32;
if ((strcmp(name, "TEA_DIR") == 0) && 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 (getcwd(envpath, 100) == NULL) switch (gId)
return ""; {
char *ptr = strrchr(envpath, '/'); case VIRTUA_TENNIS_3:
if (ptr == NULL) case VIRTUA_TENNIS_3_TEST:
return ""; case VIRTUA_TENNIS_3_REVA:
*ptr = '\0'; case VIRTUA_TENNIS_3_REVA_TEST:
return envpath; case VIRTUA_TENNIS_3_REVB:
} case VIRTUA_TENNIS_3_REVB_TEST:
else if (strcmp(name, "TEA_DIR") == 0) case VIRTUA_TENNIS_3_REVC:
{ case VIRTUA_TENNIS_3_REVC_TEST:
if (getcwd(envpath, 100) == NULL) case RAMBO:
return ""; case TOO_SPICY:
return envpath; {
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) if (strcmp(name, "__GL_SYNC_TO_VBLANK") == 0)
{ {
return ""; 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 *(*_localtime_r)(const time_t *, struct tm *) =
(struct tm * (*)(const time_t *, struct tm *)) dlsym(RTLD_NEXT, "localtime_r"); (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; time_t target_time = 1735286445;
struct tm *res = _localtime_r(&target_time, result); struct tm *res = _localtime_r(&target_time, result);
+154 -24
View File
@@ -1,11 +1,15 @@
#ifndef __i386__ #ifndef __i386__
#define __i386__ #define __i386__
#include "customcursor.h"
#endif #endif
#undef __x86_64__ #undef __x86_64__
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include "jvs.h" #include "jvs.h"
#include "config.h" #include "config.h"
#include "customcursor.h"
#include "patch.h"
#include "touchscreen.h"
#include <GL/freeglut.h> #include <GL/freeglut.h>
#include <GL/glx.h> #include <GL/glx.h>
@@ -20,6 +24,12 @@
GameType gameType = SHOOTING; GameType gameType = SHOOTING;
int jvsAnalogueInBits = 10; int jvsAnalogueInBits = 10;
extern int phX, phY, phW, phH; 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() int initInput()
{ {
@@ -35,6 +45,105 @@ int initInput()
return 0; 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 * 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 mX = event_return->xmotion.x;
int mY = event_return->xmotion.y; int mY = event_return->xmotion.y;
if (mX < phX)
mX = phX; if (phIsDragging)
if (mX > (phW + phX)) phTouchClick(mX, mY, event_return->type);
mX = (phW + phX) - 1;
if (mY > phH + phY) int motX = mX, motY = mY;
mY = (phH + phY) - 1; phTouchScreenCursor(mX, mY, &motX, &motY);
if (mY < phY)
mY = phY; setAnalogue(ANALOGUE_1, ((double)(motX - phX) / (double)phW) * pow(2, jvsAnalogueInBits));
setAnalogue(ANALOGUE_1, ((double)(mX - phX) / (double)phW) * pow(2, jvsAnalogueInBits)); setAnalogue(ANALOGUE_2, ((double)(motY - phY) / (double)phH) * pow(2, jvsAnalogueInBits));
setAnalogue(ANALOGUE_2, ((double)(mY - phY) / (double)phH) * pow(2, jvsAnalogueInBits));
} }
else else
{ {
@@ -335,7 +443,17 @@ int XNextEventShooting(Display *display, XEvent *event_return, int returnValue)
{ {
if (event_return->xbutton.button == 1) // Trigger 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 else if (event_return->xbutton.button == 3) // Reload
{ {
@@ -503,10 +621,13 @@ void sdlEventShooting(SDL_Event *event)
setSwitch(PLAYER_2, BUTTON_1, event->type == SDL_KEYDOWN); setSwitch(PLAYER_2, BUTTON_1, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_x) else if (event->key.keysym.sym == SDLK_x)
setSwitch(PLAYER_2, BUTTON_1, event->type == SDL_KEYDOWN); setSwitch(PLAYER_2, BUTTON_2, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_c) else if (event->key.keysym.sym == SDLK_c)
setSwitch(PLAYER_2, BUTTON_1, event->type == SDL_KEYDOWN); setSwitch(PLAYER_2, BUTTON_3, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_v)
setSwitch(PLAYER_2, BUTTON_4, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_u) else if (event->key.keysym.sym == SDLK_u)
setSwitch(PLAYER_2, BUTTON_UP, event->type == SDL_KEYDOWN); setSwitch(PLAYER_2, BUTTON_UP, event->type == SDL_KEYDOWN);
@@ -534,16 +655,15 @@ void sdlEventShooting(SDL_Event *event)
{ {
int mX = event->motion.x; int mX = event->motion.x;
int mY = event->motion.y; int mY = event->motion.y;
if (mX < phX)
mX = phX; if (phIsDragging)
if (mX > (phW + phX)) phTouchClick(mX, mY, event->type);
mX = (phW + phX) - 1;
if (mY > phH + phY) int motX = mX, motY = mY;
mY = (phH + phY) - 1; phTouchScreenCursor(mX, mY, &motX, &motY);
if (mY < phY)
mY = phY; setAnalogue(ANALOGUE_1, ((double)(motX - phX) / (double)phW) * pow(2, jvsAnalogueInBits));
setAnalogue(ANALOGUE_1, ((double)(mX - phX) / (double)phW) * pow(2, jvsAnalogueInBits)); setAnalogue(ANALOGUE_2, ((double)(motY - phY) / (double)phH) * pow(2, jvsAnalogueInBits));
setAnalogue(ANALOGUE_2, ((double)(mY - phY) / (double)phH) * pow(2, jvsAnalogueInBits));
} }
else else
{ {
@@ -587,7 +707,17 @@ void sdlEventShooting(SDL_Event *event)
{ {
if (event->button.button == SDL_BUTTON_LEFT) // Trigger 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 else if (event->button.button == SDL_BUTTON_RIGHT) // Reload
{ {
+53 -11
View File
@@ -11,6 +11,7 @@
#define LD_LIBRARY_PATH "LD_LIBRARY_PATH" #define LD_LIBRARY_PATH "LD_LIBRARY_PATH"
#define LD_PRELOAD "LD_PRELOAD" #define LD_PRELOAD "LD_PRELOAD"
#define PRELOAD_FILE_NAME "lindbergh.so" #define PRELOAD_FILE_NAME "lindbergh.so"
#define PRELOAD_FILE_FLATPAK "/app/lib32/lindbergh.so"
#define TEAM "bobbydilley, retrofan, dkeruza-neo, doozer, francesco, rolel, caviar-x" #define TEAM "bobbydilley, retrofan, dkeruza-neo, doozer, francesco, rolel, caviar-x"
#define LINDBERGH_CONFIG_PATH "LINDBERGH_CONFIG_PATH" #define LINDBERGH_CONFIG_PATH "LINDBERGH_CONFIG_PATH"
@@ -84,6 +85,7 @@ uint32_t cleanElfCRC32[] = {
0x9BFD0D98, // DVP-0019D | id4.elf 0x9BFD0D98, // DVP-0019D | id4.elf
0x9CF9BBCC, // DVP-0019G | id4.elf 0x9CF9BBCC, // DVP-0019G | id4.elf
0xFA0F6AB0, // DVP-0027A | apacheM.elf 0xFA0F6AB0, // DVP-0027A | apacheM.elf
0x5A7F315E, // DVP-0027A | apachetestM.elf
0x9D414D18, // DVP-0029A | vsg 0x9D414D18, // DVP-0029A | vsg
0xC345E213, // DVP-0030B | id4.elf 0xC345E213, // DVP-0030B | id4.elf
0x98E6A516, // DVP-0030C | id4.elf 0x98E6A516, // DVP-0030C | id4.elf
@@ -181,6 +183,7 @@ void isCleanElf(char *command)
printf("\033[1;31m"); printf("\033[1;31m");
printf("Warning: The ELF you are running is not Clean and might cause unwanted behavior.\n"); 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(" 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"); printf("\033[0m");
} }
} }
@@ -214,7 +217,7 @@ void testModePath(char *name)
if (strcmp(name, "./apacheM.elf") == 0) if (strcmp(name, "./apacheM.elf") == 0)
{ {
strcpy(name, "./apacheTestM.elf"); strcpy(name, "./apachetestM.elf");
return; return;
} }
@@ -232,7 +235,7 @@ void testModePath(char *name)
* Makes sure the environment variables are set correctly * Makes sure the environment variables are set correctly
* to run the game. * to run the game.
*/ */
void setEnvironmentVariables() void setEnvironmentVariables(int isFlatpak, int zink, int nvidia)
{ {
// Ensure the library path is set correctly // Ensure the library path is set correctly
char libraryPath[128] = {0}; char libraryPath[128] = {0};
@@ -249,7 +252,19 @@ void setEnvironmentVariables()
setenv(LD_LIBRARY_PATH, libraryPath, 1); setenv(LD_LIBRARY_PATH, libraryPath, 1);
// Ensure the preload path is set correctly // Ensure the preload path is set correctly
setenv(LD_PRELOAD, PRELOAD_FILE_NAME, 1); if (!isFlatpak)
setenv(LD_PRELOAD, PRELOAD_FILE_NAME, 1);
else
setenv(LD_PRELOAD, PRELOAD_FILE_FLATPAK, 1);
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);
}
} }
/** /**
@@ -261,6 +276,8 @@ void printUsage(char *argv[])
printf("Options:\n"); printf("Options:\n");
printf(" --test | -t Runs the test mode\n"); printf(" --test | -t Runs the test mode\n");
printf(" --segaboot | -s Runs segaboot\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(" --gdb Runs with GDB\n");
printf(" --list-controllers Lists available controllers and inputs\n"); printf(" --list-controllers Lists available controllers and inputs\n");
printf(" --version Displays the version of the loader and team's names\n"); printf(" --version Displays the version of the loader and team's names\n");
@@ -316,9 +333,6 @@ void printVersion() {
*/ */
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
// Ensure environment variables are set correctly
setEnvironmentVariables();
// Check for --version before directory operations // Check for --version before directory operations
if (argc > 1 && strcmp(argv[1], "--version") == 0) { if (argc > 1 && strcmp(argv[1], "--version") == 0) {
printVersion(); printVersion();
@@ -338,6 +352,7 @@ int main(int argc, char *argv[])
char *game = NULL; char *game = NULL;
int lindberghSharedObjectFound = 0; int lindberghSharedObjectFound = 0;
int isFlatpak = 0;
while ((ent = readdir(dir)) != NULL) while ((ent = readdir(dir)) != NULL)
{ {
@@ -385,14 +400,25 @@ int main(int argc, char *argv[])
if (!lindberghSharedObjectFound) if (!lindberghSharedObjectFound)
{ {
log_error("The preload object lindbergh.so was not found in this directory."); FILE *file = fopen(PRELOAD_FILE_FLATPAK, "r");
return EXIT_FAILURE; if (file)
{
fclose(file);
isFlatpak = 1;
}
else
{
log_error("The preload object lindbergh.so was not found in this directory.");
return EXIT_FAILURE;
}
} }
// Build up the command to start the game // Build up the command to start the game
int testMode = 0; int testMode = 0;
int gdb = 0; int gdb = 0;
int zink = 0;
int nvidia = 0;
int forceGame = 0; int forceGame = 0;
int segaboot = 0; int segaboot = 0;
char extConfigPath[PATH_MAX] = {0}; char extConfigPath[PATH_MAX] = {0};
@@ -417,13 +443,26 @@ int main(int argc, char *argv[])
gdb = 1; gdb = 1;
continue; continue;
} }
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 (strcmp(argv[i], "-c") == 0 || strcmp(argv[i], "--config") == 0)
{ {
if (i+1 >= argc) if (i + 1 >= argc)
{ {
break; break;
} }
strncpy(extConfigPath, argv[i+1], PATH_MAX); strncpy(extConfigPath, argv[i + 1], PATH_MAX);
i += 1; i += 1;
continue; continue;
} }
@@ -432,6 +471,9 @@ int main(int argc, char *argv[])
forceGame = 1; forceGame = 1;
} }
// Ensure environment variables are set correctly
setEnvironmentVariables(isFlatpak, zink, nvidia);
char command[128] = {0}; char command[128] = {0};
strcpy(command, "./"); strcpy(command, "./");
if (forceGame) if (forceGame)
@@ -467,7 +509,7 @@ int main(int argc, char *argv[])
if (extConfigPath[0] != '\0') if (extConfigPath[0] != '\0')
{ {
setenv(LINDBERGH_CONFIG_PATH,extConfigPath,1); setenv(LINDBERGH_CONFIG_PATH, extConfigPath, 1);
} }
log_info("Starting $ %s", command); log_info("Starting $ %s", command);
+214 -211
View File
@@ -1,13 +1,11 @@
#ifndef _GNU_SOURCE #ifndef _GNU_SOURCE
#define _GNU_SOURCE #define _GNU_SOURCE
#include <SDL2/SDL_events.h>
#endif #endif
#include <time.h> #include <time.h>
#define GL_GLEXT_PROTOTYPES #define GL_GLEXT_PROTOTYPES
#include "patch.h" #include "patch.h"
#include <GL/glx.h> #include <GL/glx.h>
#include <SDL2/SDL.h>
#include <dlfcn.h> #include <dlfcn.h>
#include <stdarg.h> #include <stdarg.h>
@@ -24,13 +22,19 @@
#include "shader_patches.h" #include "shader_patches.h"
#include "glxhooks.h" #include "glxhooks.h"
#include "log.h" #include "log.h"
#include "customcursor.h"
extern uint32_t gId;
char elfID[4]; char elfID[4];
void *amDipswContextAddr; void *amDipswContextAddr;
extern void *glVertex3fPatchRetAddrABC[4]; extern void *glVertex3fPatchRetAddrABC[4];
extern void *glVertex3fNoPatchRetAddrABC[4]; extern void *glVertex3fNoPatchRetAddrABC[4];
void *hod4CursorHideShowCAVEAddress; void *hod4CursorHideShowCAVEAddress;
extern void *customCursor;
extern void *phTouchCursor;
extern void *blankCursor;
void setVariable(size_t address, size_t value) void setVariable(size_t address, size_t value)
{ {
int pagesize = sysconf(_SC_PAGE_SIZE); int pagesize = sysconf(_SC_PAGE_SIZE);
@@ -175,7 +179,6 @@ int amDongleUpdate()
int amDongleUserInfoEx(int a, int b, char *_arcadeContext) int amDongleUserInfoEx(int a, int b, char *_arcadeContext)
{ {
uint32_t gId = getConfig()->crc32;
char *gameID; char *gameID;
switch (gId) switch (gId)
{ {
@@ -322,9 +325,8 @@ int or2snprintf(char *s, size_t n, const char *format, ...)
return ret; return ret;
} }
// printf hook, used by OR2 // printf hook, used by OR2
int patchedPrintf(char *format,...) int patchedPrintf(char *format, ...)
{ {
if (format == NULL) if (format == NULL)
return 0; return 0;
@@ -370,7 +372,7 @@ void hod4CursorHideShow(int param1)
{ {
if (hod4PrevValue != 3 || hod4InTutorial) if (hod4PrevValue != 3 || hod4InTutorial)
{ {
SDL_ShowCursor(SDL_DISABLE); hideCursor();
} }
hod4PrevValue = 0; hod4PrevValue = 0;
} }
@@ -379,7 +381,7 @@ void hod4CursorHideShow(int param1)
{ {
if (!hod4InTutorial) if (!hod4InTutorial)
{ {
SDL_ShowCursor(SDL_ENABLE); showCursor();
hod4PrevValue = 3; hod4PrevValue = 3;
} }
} }
@@ -392,7 +394,7 @@ void hod4CursorHideShow(int param1)
case 5: case 5:
case 11: case 11:
{ {
SDL_ShowCursor(SDL_DISABLE); hideCursor();
} }
} }
} }
@@ -421,8 +423,9 @@ int hod4VsPrintf(char *str, const char *format, va_list arg)
int initPatch() int initPatch()
{ {
EmulatorConfig *config = getConfig(); EmulatorConfig *config = getConfig();
int GPUVendor = getConfig()->GPUVendor;
switch (config->crc32) switch (gId)
{ {
case AFTER_BURNER_CLIMAX: // DVP-0009 case AFTER_BURNER_CLIMAX: // DVP-0009
{ {
@@ -440,7 +443,7 @@ int initPatch()
detourFunction(0x081e2a9c, amDipswInit); detourFunction(0x081e2a9c, amDipswInit);
detourFunction(0x081e2b38, amDipswExit); detourFunction(0x081e2b38, amDipswExit);
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x0804e1e4, gl_ProgramStringARB); detourFunction(0x0804e1e4, gl_ProgramStringARB);
} }
@@ -462,7 +465,7 @@ int initPatch()
detourFunction(0x081e31e4, amDipswInit); detourFunction(0x081e31e4, amDipswInit);
detourFunction(0x081e3280, amDipswExit); detourFunction(0x081e3280, amDipswExit);
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x0804e1e4, gl_ProgramStringARB); detourFunction(0x0804e1e4, gl_ProgramStringARB);
} }
@@ -484,7 +487,7 @@ int initPatch()
detourFunction(0x081e3248, amDipswInit); detourFunction(0x081e3248, amDipswInit);
detourFunction(0x081e32e4, amDipswExit); detourFunction(0x081e32e4, amDipswExit);
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x0804e1ec, gl_ProgramStringARB); detourFunction(0x0804e1ec, gl_ProgramStringARB);
} }
@@ -505,7 +508,7 @@ int initPatch()
detourFunction(0x081e47a4, amDipswInit); detourFunction(0x081e47a4, amDipswInit);
detourFunction(0x081e4840, amDipswExit); detourFunction(0x081e4840, amDipswExit);
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x0804e244, gl_ProgramStringARB); detourFunction(0x0804e244, gl_ProgramStringARB);
} }
@@ -527,7 +530,7 @@ int initPatch()
detourFunction(0x081e478c, amDipswInit); detourFunction(0x081e478c, amDipswInit);
detourFunction(0x081e4828, amDipswExit); detourFunction(0x081e4828, amDipswExit);
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x0804e24c, gl_ProgramStringARB); detourFunction(0x0804e24c, gl_ProgramStringARB);
} }
@@ -549,7 +552,7 @@ int initPatch()
detourFunction(0x081e3294, amDipswInit); detourFunction(0x081e3294, amDipswInit);
detourFunction(0x081e3330, amDipswExit); detourFunction(0x081e3330, amDipswExit);
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x0804e1e4, gl_ProgramStringARB); detourFunction(0x0804e1e4, gl_ProgramStringARB);
} }
@@ -571,7 +574,7 @@ int initPatch()
detourFunction(0x081e327c, amDipswInit); detourFunction(0x081e327c, amDipswInit);
detourFunction(0x081e3318, amDipswExit); detourFunction(0x081e3318, amDipswExit);
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x0804e1ec, gl_ProgramStringARB); detourFunction(0x0804e1ec, gl_ProgramStringARB);
} }
@@ -601,7 +604,7 @@ int initPatch()
detourFunction(0x080e7f94, stubRetZero); detourFunction(0x080e7f94, stubRetZero);
cacheModedShaderFiles(); cacheModedShaderFiles();
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
gsEvoElfShaderPatcher(); gsEvoElfShaderPatcher();
detourFunction(0x0804c334, gl_ProgramStringARB); detourFunction(0x0804c334, gl_ProgramStringARB);
@@ -623,7 +626,7 @@ int initPatch()
detourFunction(0x08394825, amDipswGetData); detourFunction(0x08394825, amDipswGetData);
detourFunction(0x08395da5, amDongleUserInfoEx); detourFunction(0x08395da5, amDongleUserInfoEx);
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
cacheModedShaderFiles(); cacheModedShaderFiles();
loadLibCg(); loadLibCg();
@@ -910,7 +913,7 @@ int initPatch()
setVariable(0x0857f0e9, 0x000126e9); // Avoid Full Screen set from Game setVariable(0x0857f0e9, 0x000126e9); // Avoid Full Screen set from Game
patchMemory(0x087bc56c, "ab"); // Skips initialization patchMemory(0x087bc56c, "ab"); // Skips initialization
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x08078860, gl_MultiTexCoord2fARB); detourFunction(0x08078860, gl_MultiTexCoord2fARB);
detourFunction(0x080788d0, gl_Color4ub); detourFunction(0x080788d0, gl_Color4ub);
@@ -965,7 +968,7 @@ int initPatch()
setVariable(0x0857ee69, 0x000126e9); // Avoid Full Screen set from Game setVariable(0x0857ee69, 0x000126e9); // Avoid Full Screen set from Game
patchMemory(0x087bc2ec, "eb"); // Skips initialization patchMemory(0x087bc2ec, "eb"); // Skips initialization
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x08078860, gl_MultiTexCoord2fARB); detourFunction(0x08078860, gl_MultiTexCoord2fARB);
detourFunction(0x080788d0, gl_Color4ub); detourFunction(0x080788d0, gl_Color4ub);
@@ -1020,7 +1023,7 @@ int initPatch()
setVariable(0x08580979, 0x000126e9); // Avoid Full Screen set from Game setVariable(0x08580979, 0x000126e9); // Avoid Full Screen set from Game
patchMemory(0x087beb6c, "5b"); // Skips initialization patchMemory(0x087beb6c, "5b"); // Skips initialization
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x080788ec, gl_MultiTexCoord2fARB); detourFunction(0x080788ec, gl_MultiTexCoord2fARB);
detourFunction(0x0807895c, gl_Color4ub); detourFunction(0x0807895c, gl_Color4ub);
@@ -1076,7 +1079,7 @@ int initPatch()
patchMemory(0x08799adc, "df"); // Skips initialization patchMemory(0x08799adc, "df"); // Skips initialization
setVariable(0x085593c9, 0x000126e9); // Avoid Full Screen set from Game setVariable(0x085593c9, 0x000126e9); // Avoid Full Screen set from Game
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x08078980, gl_MultiTexCoord2fARB); detourFunction(0x08078980, gl_MultiTexCoord2fARB);
detourFunction(0x080789f0, gl_Color4ub); detourFunction(0x080789f0, gl_Color4ub);
@@ -1132,7 +1135,7 @@ int initPatch()
patchMemory(0x08799d9c, "cf"); // Skips initialization patchMemory(0x08799d9c, "cf"); // Skips initialization
setVariable(0x08559609, 0x000126e9); // Avoid Full Screen set from Game setVariable(0x08559609, 0x000126e9); // Avoid Full Screen set from Game
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x080789a4, gl_MultiTexCoord2fARB); detourFunction(0x080789a4, gl_MultiTexCoord2fARB);
detourFunction(0x08078a14, gl_Color4ub); detourFunction(0x08078a14, gl_Color4ub);
@@ -1188,7 +1191,7 @@ int initPatch()
patchMemory(0x087a2efc, "ff"); // Skips initialization patchMemory(0x087a2efc, "ff"); // Skips initialization
setVariable(0x08561e79, 0x000126e9); // Avoid Full Screen set from Game setVariable(0x08561e79, 0x000126e9); // Avoid Full Screen set from Game
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x080789a4, gl_MultiTexCoord2fARB); detourFunction(0x080789a4, gl_MultiTexCoord2fARB);
detourFunction(0x08078a14, gl_Color4ub); detourFunction(0x08078a14, gl_Color4ub);
@@ -1244,7 +1247,7 @@ int initPatch()
patchMemory(0x087a025c, "6f"); // Skips initialization patchMemory(0x087a025c, "6f"); // Skips initialization
setVariable(0x0855f519, 0x000126e9); // Avoid Full Screen set from Game setVariable(0x0855f519, 0x000126e9); // Avoid Full Screen set from Game
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x080789a4, gl_MultiTexCoord2fARB); detourFunction(0x080789a4, gl_MultiTexCoord2fARB);
detourFunction(0x08078a14, gl_Color4ub); detourFunction(0x08078a14, gl_Color4ub);
@@ -1300,7 +1303,7 @@ int initPatch()
patchMemory(0x087e9ebc, "3f36"); // Skips initialization patchMemory(0x087e9ebc, "3f36"); // Skips initialization
setVariable(0x08599819, 0x000126e9); // Avoid Full Screen set from Game setVariable(0x08599819, 0x000126e9); // Avoid Full Screen set from Game
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x0807a298, gl_MultiTexCoord2fARB); detourFunction(0x0807a298, gl_MultiTexCoord2fARB);
detourFunction(0x0807a308, gl_Color4ub); detourFunction(0x0807a308, gl_Color4ub);
@@ -1358,7 +1361,7 @@ int initPatch()
patchMemory(0x08789a49, "e92601000090"); // Prevents Full Screen set from the game patchMemory(0x08789a49, "e92601000090"); // Prevents Full Screen set from the game
// Mesa Patches // Mesa Patches
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x0807a3f0, gl_MultiTexCoord2fARB); detourFunction(0x0807a3f0, gl_MultiTexCoord2fARB);
detourFunction(0x0807a470, gl_Color4ub); detourFunction(0x0807a470, gl_Color4ub);
@@ -1424,7 +1427,7 @@ int initPatch()
detourFunction(0x089382e0, stubRetZero); // Eliminates amsInit Function detourFunction(0x089382e0, stubRetZero); // Eliminates amsInit Function
// Mesa Patches // Mesa Patches
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x0807a6c0, gl_MultiTexCoord2fARB); detourFunction(0x0807a6c0, gl_MultiTexCoord2fARB);
detourFunction(0x0807a740, gl_Color4ub); detourFunction(0x0807a740, gl_Color4ub);
@@ -1490,7 +1493,7 @@ int initPatch()
detourFunction(0x08938530, stubRetZero); // Eliminates amsInit Function detourFunction(0x08938530, stubRetZero); // Eliminates amsInit Function
// Mesa Patches // Mesa Patches
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x0807a6c0, gl_MultiTexCoord2fARB); detourFunction(0x0807a6c0, gl_MultiTexCoord2fARB);
detourFunction(0x0807a740, gl_Color4ub); detourFunction(0x0807a740, gl_Color4ub);
@@ -1548,7 +1551,7 @@ int initPatch()
patchMemory(0x08441f99, "eb60"); // tickInitAddress patchMemory(0x08441f99, "eb60"); // tickInitAddress
// Mesa Patches // Mesa Patches
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x0807a3f0, gl_MultiTexCoord2fARB); detourFunction(0x0807a3f0, gl_MultiTexCoord2fARB);
detourFunction(0x0807a470, gl_Color4ub); detourFunction(0x0807a470, gl_Color4ub);
@@ -1613,7 +1616,7 @@ int initPatch()
detourFunction(0x0850fba0, stubRetZero); // isUseServerBox detourFunction(0x0850fba0, stubRetZero); // isUseServerBox
// Mesa Patches // Mesa Patches
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x0807a42c, gl_MultiTexCoord2fARB); detourFunction(0x0807a42c, gl_MultiTexCoord2fARB);
detourFunction(0x0807a4ac, gl_Color4ub); detourFunction(0x0807a4ac, gl_Color4ub);
@@ -1629,54 +1632,6 @@ int initPatch()
patchMemory(0x0875e1ae, "00"); // Fix cutscenes patchMemory(0x0875e1ae, "00"); // Fix cutscenes
} }
break; 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: case LETS_GO_JUNGLE:
{ {
if (config->showDebugMessages == 1) if (config->showDebugMessages == 1)
@@ -1710,7 +1665,7 @@ int initPatch()
patchMemory(0x0840d858, "9090"); // No full screen patchMemory(0x0840d858, "9090"); // No full screen
// Mesa Patches // Mesa Patches
if (getConfig()->GPUVendor != NVIDIA_GPU || getConfig()->lgjRenderWithMesa) if (GPUVendor != NVIDIA_GPU || getConfig()->lgjRenderWithMesa)
{ {
detourFunction(0x080716e4, gl_MultiTexCoord2fARB); detourFunction(0x080716e4, gl_MultiTexCoord2fARB);
detourFunction(0x08071754, gl_Color4ub); detourFunction(0x08071754, gl_Color4ub);
@@ -1725,6 +1680,54 @@ int initPatch()
detourFunction(0x08072454, gl_XGetProcAddressARB); detourFunction(0x08072454, gl_XGetProcAddressARB);
} }
break; 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: case LETS_GO_JUNGLE_SPECIAL:
{ {
if (config->showDebugMessages == 1) if (config->showDebugMessages == 1)
@@ -1758,7 +1761,7 @@ int initPatch()
patchMemory(0x08438954, "9090"); // No full screen patchMemory(0x08438954, "9090"); // No full screen
// Mesa Patches // Mesa Patches
if (getConfig()->GPUVendor != NVIDIA_GPU || getConfig()->lgjRenderWithMesa) if (GPUVendor != NVIDIA_GPU || getConfig()->lgjRenderWithMesa)
{ {
detourFunction(0x080718e0, gl_MultiTexCoord2fARB); detourFunction(0x080718e0, gl_MultiTexCoord2fARB);
detourFunction(0x08071950, gl_Color4ub); detourFunction(0x08071950, gl_Color4ub);
@@ -1773,6 +1776,32 @@ int initPatch()
detourFunction(0x080726c0, gl_XGetProcAddressARB); detourFunction(0x080726c0, gl_XGetProcAddressARB);
} }
break; 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: case MJ4_REVG:
{ {
setVariable(0x0acf85d4, 2); setVariable(0x0acf85d4, 2);
@@ -1818,38 +1847,12 @@ int initPatch()
patchMemory(0x08732fd3, "2e2f00"); // Patch /home/disk2 folder patchMemory(0x08732fd3, "2e2f00"); // Patch /home/disk2 folder
// Mesa Patches // Mesa Patches
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x08050ebc, gl_ProgramStringARB); detourFunction(0x08050ebc, gl_ProgramStringARB);
} }
} }
break; 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: case OUTRUN_2_SP_SDX:
{ {
if (config->showDebugMessages == 1) if (config->showDebugMessages == 1)
@@ -1888,7 +1891,7 @@ int initPatch()
// Shader Patches // Shader Patches
detourFunction(0x0804ca98, gl_ProgramStringARB); detourFunction(0x0804ca98, gl_ProgramStringARB);
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x0804cf38, glGenProgramsARB); // Replaces glGenProgramsNV detourFunction(0x0804cf38, glGenProgramsARB); // Replaces glGenProgramsNV
detourFunction(0x0804c548, gl_BindProgramNV); // Replaces glBindProgramNV detourFunction(0x0804c548, gl_BindProgramNV); // Replaces glBindProgramNV
@@ -1906,26 +1909,6 @@ int initPatch()
detourFunction(0x0804d148, or2snprintf); // Fixes a bug in snprintf libc 2.39?? detourFunction(0x0804d148, or2snprintf); // Fixes a bug in snprintf libc 2.39??
} }
break; 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: case OUTRUN_2_SP_SDX_REVA:
{ {
if (config->showDebugMessages == 1) if (config->showDebugMessages == 1)
@@ -1967,7 +1950,7 @@ int initPatch()
// Shader Patches // Shader Patches
detourFunction(0x0804ca98, gl_ProgramStringARB); detourFunction(0x0804ca98, gl_ProgramStringARB);
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x0804cf38, glGenProgramsARB); // Replaces glGenProgramsNV detourFunction(0x0804cf38, glGenProgramsARB); // Replaces glGenProgramsNV
detourFunction(0x0804c548, gl_BindProgramNV); // Replaces glBindProgramNV detourFunction(0x0804c548, gl_BindProgramNV); // Replaces glBindProgramNV
@@ -2014,6 +1997,26 @@ int initPatch()
patchMemory(0x08054ac4, "9090909090"); patchMemory(0x08054ac4, "9090909090");
} }
break; 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: case PRIMEVAL_HUNT:
{ {
// Security // Security
@@ -2052,7 +2055,7 @@ int initPatch()
detourFunction(0x082c3103, amDipswSetLed); detourFunction(0x082c3103, amDipswSetLed);
cacheModedShaderFiles(); cacheModedShaderFiles();
// Mesa Patches // Mesa Patches
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
loadLibCg(); loadLibCg();
cacheNnstdshader(); cacheNnstdshader();
@@ -2087,7 +2090,7 @@ int initPatch()
patchMemory(0x838C498, "2e2f524f4d5f4c414e472f656e00"); // Patch /home/disk0 folder patchMemory(0x838C498, "2e2f524f4d5f4c414e472f656e00"); // Patch /home/disk0 folder
// Mesa Patches // Mesa Patches
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x080507e8, gl_ProgramStringARB); detourFunction(0x080507e8, gl_ProgramStringARB);
} }
@@ -2143,7 +2146,7 @@ int initPatch()
srtvElfShaderPatcher(); srtvElfShaderPatcher();
// Mesa Patches // Mesa Patches
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
patchMemory(0x082d3ce9, "9090"); // Force GL_NVX_conditional_render patchMemory(0x082d3ce9, "9090"); // Force GL_NVX_conditional_render
} }
@@ -2406,22 +2409,6 @@ int initPatch()
} }
} }
break; 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: case THE_HOUSE_OF_THE_DEAD_4_SPECIAL_REVB:
{ {
detourFunction(0x08363438, amDongleInit); detourFunction(0x08363438, amDongleInit);
@@ -2464,6 +2451,22 @@ int initPatch()
patchMemory(0x08054820, "9090909090"); //__intel_new_proc_init_P patchMemory(0x08054820, "9090909090"); //__intel_new_proc_init_P
} }
break; 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: case THE_HOUSE_OF_THE_DEAD_EX:
{ {
detourFunction(0x084ba886, amDongleInit); detourFunction(0x084ba886, amDongleInit);
@@ -2482,7 +2485,7 @@ int initPatch()
patchMemory(0x0804e4a7, "9090909090"); //__intel_new_proc_init_P patchMemory(0x0804e4a7, "9090909090"); //__intel_new_proc_init_P
// Mesa Patches // Mesa Patches
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
patchMemory(0x08503bfa, "6d657361"); // Rename compile folder to compmesa patchMemory(0x08503bfa, "6d657361"); // Rename compile folder to compmesa
cacheModedShaderFiles(); cacheModedShaderFiles();
@@ -2528,6 +2531,7 @@ int initPatch()
patchMemory(0x08210f3c, "9090909090909090"); patchMemory(0x08210f3c, "9090909090909090");
patchMemory(0x08210f45, "01"); patchMemory(0x08210f45, "01");
patchMemory(0x08210f49, "909090"); patchMemory(0x08210f49, "909090");
patchMemory(0x082ef5d0, "9090909090");
// Fixes // Fixes
amDipswContextAddr = (void *)0x0c8ed0cc; amDipswContextAddr = (void *)0x0c8ed0cc;
detourFunction(0x08318f84, amDipswInit); detourFunction(0x08318f84, amDipswInit);
@@ -2543,7 +2547,7 @@ int initPatch()
detourFunction(0x081cbcd2, stubRetOne); detourFunction(0x081cbcd2, stubRetOne);
// Mesa Patches // Mesa Patches
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
loadLibCg(); loadLibCg();
cacheNnstdshader(); cacheNnstdshader();
@@ -2607,7 +2611,7 @@ int initPatch()
patchMemory(0x080a36de, "9090909090"); patchMemory(0x080a36de, "9090909090");
patchMemory(0x080a35ed, "ffffffff"); patchMemory(0x080a35ed, "ffffffff");
patchMemory(0x080a3620, "ffffffff"); patchMemory(0x080a3620, "ffffffff");
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x08051b9c, gl_ProgramStringARB); detourFunction(0x08051b9c, gl_ProgramStringARB);
} }
@@ -2630,7 +2634,7 @@ int initPatch()
detourFunction(0x08094d28, stubRetZero); detourFunction(0x08094d28, stubRetZero);
patchMemory(0x080a29a5, "EB"); patchMemory(0x080a29a5, "EB");
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x0805160c, gl_ProgramStringARB); detourFunction(0x0805160c, gl_ProgramStringARB);
} }
@@ -2661,11 +2665,11 @@ int initPatch()
patchMemory(0x88AB0C1, "2e2f666f6f3100"); // Patch /home/disk2 folder patchMemory(0x88AB0C1, "2e2f666f6f3100"); // Patch /home/disk2 folder
patchMemory(0x88AB0D2, "2e2f666f6f3200"); // Patch /home/disk2 folder patchMemory(0x88AB0D2, "2e2f666f6f3200"); // Patch /home/disk2 folder
patchMemory(0x89C8F24, "2e2f00"); // Patch /home/disk2 folder patchMemory(0x89C8F24, "2e2f00"); // Patch /home/disk2 folder
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x08052aa4, gl_ProgramStringARB); 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); hookVf5FSExposure(0x08148279, 0x0814844a, 0x08148b42, 0x08148d52);
} }
@@ -2696,11 +2700,11 @@ int initPatch()
patchMemory(0x88CACBD, "2e2f666f6f3100"); // Patch /home/disk2 folder patchMemory(0x88CACBD, "2e2f666f6f3100"); // Patch /home/disk2 folder
patchMemory(0x88CACCE, "2e2f666f6f3200"); // Patch /home/disk2 folder patchMemory(0x88CACCE, "2e2f666f6f3200"); // Patch /home/disk2 folder
patchMemory(0x89DE5AA, "2e2f00"); // Patch /home/disk2 folder patchMemory(0x89DE5AA, "2e2f00"); // Patch /home/disk2 folder
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x08052840, gl_ProgramStringARB); 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); hookVf5FSExposure(0x08148a47, 0x08148c18, 0x08149310, 0x08149520);
} }
@@ -2732,11 +2736,11 @@ int initPatch()
patchMemory(0x88CD4AE, "2e2f666f6f3200"); // Patch /home/disk2 folder patchMemory(0x88CD4AE, "2e2f666f6f3200"); // Patch /home/disk2 folder
patchMemory(0x89ED9C4, "2e2f00"); // Patch /home/disk2 folder patchMemory(0x89ED9C4, "2e2f00"); // Patch /home/disk2 folder
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x08052b20, gl_ProgramStringARB); 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); hookVf5FSExposure(0x081489f7, 0x08148bc8, 0x081492c0, 0x081494d0);
} }
@@ -2769,7 +2773,7 @@ int initPatch()
patchMemory(0x0810030c, "ffffffff"); patchMemory(0x0810030c, "ffffffff");
patchMemory(0x08100313, "ffffffff"); patchMemory(0x08100313, "ffffffff");
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x08052a68, gl_ProgramStringARB); detourFunction(0x08052a68, gl_ProgramStringARB);
} }
@@ -2802,7 +2806,7 @@ int initPatch()
patchMemory(0x08119204, "ffffffff"); patchMemory(0x08119204, "ffffffff");
patchMemory(0x0811920b, "ffffffff"); patchMemory(0x0811920b, "ffffffff");
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x08052a84, gl_ProgramStringARB); detourFunction(0x08052a84, gl_ProgramStringARB);
} }
@@ -2835,7 +2839,7 @@ int initPatch()
patchMemory(0x08119384, "ffffffff"); patchMemory(0x08119384, "ffffffff");
patchMemory(0x0811938b, "ffffffff"); patchMemory(0x0811938b, "ffffffff");
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x08052a70, gl_ProgramStringARB); detourFunction(0x08052a70, gl_ProgramStringARB);
} }
@@ -2873,7 +2877,7 @@ int initPatch()
patchMemory(0x080a6356, "9090909090"); patchMemory(0x080a6356, "9090909090");
patchMemory(0x080a6265, "ffffffff"); patchMemory(0x080a6265, "ffffffff");
patchMemory(0x080a6298, "ffffffff"); patchMemory(0x080a6298, "ffffffff");
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x08051c4c, gl_ProgramStringARB); detourFunction(0x08051c4c, gl_ProgramStringARB);
} }
@@ -2909,7 +2913,7 @@ int initPatch()
patchMemory(0x080b5682, "9090909090"); patchMemory(0x080b5682, "9090909090");
patchMemory(0x080B5591, "ffffffff"); patchMemory(0x080B5591, "ffffffff");
patchMemory(0x080B55C4, "ffffffff"); patchMemory(0x080B55C4, "ffffffff");
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x08052088, gl_ProgramStringARB); detourFunction(0x08052088, gl_ProgramStringARB);
} }
@@ -2946,7 +2950,7 @@ int initPatch()
patchMemory(0x080e16b6, "9090909090"); patchMemory(0x080e16b6, "9090909090");
patchMemory(0x080e15bd, "ffffffff"); patchMemory(0x080e15bd, "ffffffff");
patchMemory(0x080e15f7, "ffffffff"); patchMemory(0x080e15f7, "ffffffff");
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x08052fbc, gl_ProgramStringARB); detourFunction(0x08052fbc, gl_ProgramStringARB);
} }
@@ -2954,7 +2958,6 @@ int initPatch()
patchMemory(0x080e173c, "B810000000"); patchMemory(0x080e173c, "B810000000");
} }
break; break;
case VIRTUA_TENNIS_3: case VIRTUA_TENNIS_3:
{ {
if (config->showDebugMessages == 1) if (config->showDebugMessages == 1)
@@ -2972,12 +2975,12 @@ int initPatch()
detourFunction(0x0831beb9, amDipswExit); detourFunction(0x0831beb9, amDipswExit);
detourFunction(0x0831bf2f, amDipswGetData); detourFunction(0x0831bf2f, amDipswGetData);
detourFunction(0x0831bfa7, stubRetZero); 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 detourFunction(0x08177acc, stubRetOne); // Patch seterror
// Mesa // Mesa
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x0804d458, cg_GLGetLatestProfile); detourFunction(0x0804d458, cg_GLGetLatestProfile);
detourFunction(0x0804dcd8, cg_GLIsProfileSupported); detourFunction(0x0804dcd8, cg_GLIsProfileSupported);
@@ -2994,37 +2997,6 @@ int initPatch()
} }
} }
break; 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: case VIRTUA_TENNIS_3_REVA:
{ {
if (config->showDebugMessages == 1) if (config->showDebugMessages == 1)
@@ -3042,11 +3014,11 @@ int initPatch()
detourFunction(0x0831bf5d, amDipswExit); detourFunction(0x0831bf5d, amDipswExit);
detourFunction(0x0831bfd3, amDipswGetData); detourFunction(0x0831bfd3, amDipswGetData);
detourFunction(0x0831c04b, stubRetZero); detourFunction(0x0831c04b, stubRetZero);
setVariable(0x0827a7f7, 0x34891beb); // Disable Fullscreen set from the game setVariable(0x0827a7f7, 0x34891beb); // Disable Fullscreen set from the game
detourFunction(0x08177afc, stubRetOne); // Patch seterror detourFunction(0x08177afc, stubRetOne); // Patch seterror
// Mesa // Mesa
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x0804d458, cg_GLGetLatestProfile); detourFunction(0x0804d458, cg_GLGetLatestProfile);
detourFunction(0x0804dcd8, cg_GLIsProfileSupported); detourFunction(0x0804dcd8, cg_GLIsProfileSupported);
@@ -3083,7 +3055,7 @@ int initPatch()
patchMemory(0x0806fd8f, "EB"); // Avoid Full Screen set from Game patchMemory(0x0806fd8f, "EB"); // Avoid Full Screen set from Game
// Mesa Patches // Mesa Patches
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x0804ce54, cg_GLIsProfileSupported); detourFunction(0x0804ce54, cg_GLIsProfileSupported);
detourFunction(0x0804c724, gl_Color4ub); detourFunction(0x0804c724, gl_Color4ub);
@@ -3111,11 +3083,11 @@ int initPatch()
detourFunction(0x0831c149, amDipswExit); detourFunction(0x0831c149, amDipswExit);
detourFunction(0x0831c1bf, amDipswGetData); detourFunction(0x0831c1bf, amDipswGetData);
detourFunction(0x0831c237, stubRetZero); detourFunction(0x0831c237, stubRetZero);
setVariable(0x0827a9e3, 0x34891beb); // Disable Fullscreen set from the game setVariable(0x0827a9e3, 0x34891beb); // Disable Fullscreen set from the game
detourFunction(0x08177bf0, stubRetOne); // Patch seterror detourFunction(0x08177bf0, stubRetOne); // Patch seterror
// Mesa // Mesa
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x0804d458, cg_GLGetLatestProfile); detourFunction(0x0804d458, cg_GLGetLatestProfile);
detourFunction(0x0804dcd8, cg_GLIsProfileSupported); detourFunction(0x0804dcd8, cg_GLIsProfileSupported);
@@ -3152,7 +3124,7 @@ int initPatch()
patchMemory(0x0806fa33, "EB"); // Avoid Full Screen set from Game patchMemory(0x0806fa33, "EB"); // Avoid Full Screen set from Game
// Mesa Patches // Mesa Patches
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x0804ce54, cg_GLIsProfileSupported); detourFunction(0x0804ce54, cg_GLIsProfileSupported);
detourFunction(0x0804c724, gl_Color4ub); detourFunction(0x0804c724, gl_Color4ub);
@@ -3180,11 +3152,11 @@ int initPatch()
detourFunction(0x0831c561, amDipswExit); detourFunction(0x0831c561, amDipswExit);
detourFunction(0x0831c5d7, amDipswGetData); detourFunction(0x0831c5d7, amDipswGetData);
detourFunction(0x0831c64f, stubRetZero); detourFunction(0x0831c64f, stubRetZero);
setVariable(0x0827ae1b, 0x34891beb); // Disable Fullscreen set from the game setVariable(0x0827ae1b, 0x34891beb); // Disable Fullscreen set from the game
detourFunction(0x08177c1c, stubRetOne); // Patch seterror detourFunction(0x08177c1c, stubRetOne); // Patch seterror
// Mesa // Mesa
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x0804d458, cg_GLGetLatestProfile); detourFunction(0x0804d458, cg_GLGetLatestProfile);
detourFunction(0x0804dcd8, cg_GLIsProfileSupported); detourFunction(0x0804dcd8, cg_GLIsProfileSupported);
@@ -3228,7 +3200,7 @@ int initPatch()
patchMemory(0x0806fe3f, "EB"); // Avoid Full Screen set from Game patchMemory(0x0806fe3f, "EB"); // Avoid Full Screen set from Game
// Mesa Patches // Mesa Patches
if (getConfig()->GPUVendor != NVIDIA_GPU) if (GPUVendor != NVIDIA_GPU)
{ {
detourFunction(0x0804ce54, cg_GLIsProfileSupported); detourFunction(0x0804ce54, cg_GLIsProfileSupported);
detourFunction(0x0804c724, gl_Color4ub); detourFunction(0x0804c724, gl_Color4ub);
@@ -3239,6 +3211,37 @@ int initPatch()
} }
} }
break; 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: default:
break; break;
} }
+842 -594
View File
File diff suppressed because it is too large Load Diff
+53 -134
View File
@@ -14,13 +14,9 @@
#include "input.h" #include "input.h"
#include "sdlcalls.h" #include "sdlcalls.h"
#include "fps_limiter.h" #include "fps_limiter.h"
#define STB_IMAGE_IMPLEMENTATION #include "customcursor.h"
#include "stb_image.h"
#define STBI_ONLY_PNG
#define STBI_SUPPORT_ZLIB
#define STBI_NO_SIMD
extern uint32_t gId;
bool SDLWindowCreated = false; bool SDLWindowCreated = false;
extern bool GLUTGame; extern bool GLUTGame;
SDL_Window *SDLwindow; SDL_Window *SDLwindow;
@@ -30,6 +26,11 @@ Window x11Window;
char SDLgameTitle[256] = {0}; char SDLgameTitle[256] = {0};
extern fps_limit fpsLimit; 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, void GLAPIENTRY openglDebugCallback2(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
const GLchar *message, const void *userParam) 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) void initSDL(int *argcp, char **argv)
{ {
int gId = getConfig()->crc32;
void FGAPIENTRY (*_glutInit)(int *argcp, char **argv) = dlsym(RTLD_NEXT, "glutInit"); void FGAPIENTRY (*_glutInit)(int *argcp, char **argv) = dlsym(RTLD_NEXT, "glutInit");
if (getConfig()->noSDL && GLUTGame) switch (gId)
{ {
_glutInit(argcp, argv); case OUTRUN_2_SP_SDX_TEST:
return; 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) switch (gId)
{
_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))
{ {
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); 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_DOUBLEBUFFER, 1); // Double buffering
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 1); // 24-bit depth buffer 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 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 || switch (gId)
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)
{ {
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); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1);
} }
@@ -236,18 +161,12 @@ void initSDL(int *argcp, char **argv)
if (getConfig()->fullscreen) if (getConfig()->fullscreen)
{ {
SDL_SetWindowFullscreen(SDLwindow, SDL_WINDOW_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); SDL_ShowCursor(SDL_DISABLE);
} }
+1 -1
View File
@@ -1,8 +1,8 @@
#include <stdio.h> #include <stdio.h>
#include "config.h"
#include "securityboard.h" #include "securityboard.h"
#include "log.h" #include "log.h"
#include "config.h"
#define SECURITY_BOARD_FRONT_PANEL 0x38 #define SECURITY_BOARD_FRONT_PANEL 0x38
#define SECURITY_BOARD_FRONT_PANEL_NON_ROOT 0x1038 #define SECURITY_BOARD_FRONT_PANEL_NON_ROOT 0x1038
File diff suppressed because it is too large Load Diff
+8 -8
View File
@@ -702,14 +702,14 @@ static int stbi__sse2_available()
static int stbi__sse2_available() static int stbi__sse2_available()
{ {
#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 408 // GCC 4.8 or later // #if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 408 // GCC 4.8 or later
// GCC 4.8+ has a nice way to do this // // GCC 4.8+ has a nice way to do this
return __builtin_cpu_supports("sse2"); // return __builtin_cpu_supports("sse2");
#else // #else
// portable way to do this, preferably without using GCC inline ASM? // portable way to do this, preferably without using GCC inline ASM?
// just bail for now. // just bail for now.
return 0; return 0;
#endif // #endif
} }
#endif #endif
#endif #endif
+85
View File
@@ -0,0 +1,85 @@
#include <SDL2/SDL_events.h>
#include <X11/X.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>
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;
}
+9
View File
@@ -0,0 +1,9 @@
#ifndef TOUCHSCREEN_H
#define TOUCHSCREEN_H
#include <sys/types.h>
void phCoordinates(int x, int y, int w, int h, int button);
ssize_t phRead(int fd, void *buf, size_t count);
#endif
+25 -47
View File
@@ -19,6 +19,7 @@
#include "securityboard.h" #include "securityboard.h"
#include "fps_limiter.h" #include "fps_limiter.h"
#include "sdlcalls.h" #include "sdlcalls.h"
#include "customcursor.h"
extern bool SDLWindowCreated; extern bool SDLWindowCreated;
extern bool gettingGPUVendor; extern bool gettingGPUVendor;
@@ -26,11 +27,14 @@ extern bool GLUTGame;
bool creatingWindow = false; bool creatingWindow = false;
Window win; Window window;
extern Display *x11Display; extern Display *x11Display;
extern Window x11Window; extern Window x11Window;
extern void *customCursor;
extern void *phTouchCursor;
/** /**
* Stop the house of the dead games turning keyboard repeating off. * 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)
{ {
Display *(*_XOpenDisplay)(const char *display_name) = dlsym(RTLD_NEXT, "XOpenDisplay"); Display *(*_XOpenDisplay)(const char *display_name) = dlsym(RTLD_NEXT, "XOpenDisplay");
if (SDLWindowCreated || gettingGPUVendor || GLUTGame || getConfig()->noSDL)
return _XOpenDisplay(display_name);
creatingWindow = true; if (SDLWindowCreated || gettingGPUVendor || getConfig()->noSDL)
initSDL(0, 0); {
creatingWindow = false; x11Display = _XOpenDisplay(display_name);
}
else
{
creatingWindow = true;
initSDL(0, 0);
creatingWindow = false;
}
return x11Display; 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)) if ((gettingGPUVendor || creatingWindow) || (GLUTGame && getConfig()->noSDL == 0))
{ {
Window window = _XCreateWindow(display, parent, x, y, width, height, border_width, depth, class, visual, window = _XCreateWindow(display, parent, x, y, width, height, border_width, depth, class, visual, valueMask, attributes);
valueMask, attributes);
return window;
} }
else if (getConfig()->noSDL)
if (getConfig()->noSDL)
{ {
width = getConfig()->width; width = getConfig()->width;
height = getConfig()->height; height = getConfig()->height;
attributes->event_mask = attributes->event_mask | KeyPressMask | KeyReleaseMask | PointerMotionMask; 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); printf(" X11 RESOLUTION: %dx%d\n\n", width, height);
if (getConfig()->fullscreen) 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); Atom wm_fullscreen = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", true);
XChangeProperty(display, window, wm_state, XA_ATOM, 32, PropModeReplace, (unsigned char *)&wm_fullscreen, 1); 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 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, 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; 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; typedef unsigned int uint;
void glGenFencesNV(int n, uint *fences) void glGenFencesNV(int n, uint *fences)