Super release

This commit is contained in:
dkeruza-neo
2025-09-15 16:12:07 -04:00
parent b3b3e15357
commit ae6e4c6e56
137 changed files with 46210 additions and 18935 deletions
+18 -3
View File
@@ -2,7 +2,6 @@ name: 🐧 Linux AppImage
on:
workflow_call:
workflow_dispatch:
jobs:
linux-appimage:
@@ -10,9 +9,14 @@ jobs:
runs-on: ubuntu-22.04
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- name: Checkout code
uses: actions/checkout@v4
- name: Download version.h artifact
uses: actions/download-artifact@v4
with:
fetch-depth: 0
name: version-file
path: src/lindbergh/
- name: Install Packages
run: scripts/appimage/install-packages.sh
@@ -20,6 +24,9 @@ jobs:
- name: Build Deps
run: scripts/appimage/build-deps.sh
- name: Pack Libs
run: scripts/appimage/pack-libs.sh
- name: Compile Build
shell: bash
run: |
@@ -31,3 +38,11 @@ jobs:
with:
name: "linux-appimage"
path: "lindbergh-loader.AppImage"
- name: Upload SDL3 and FAudio
uses: actions/upload-artifact@v4
with:
name: SDL3-FAudio
path: |
libs/libs.tar
libs/includes.tar
+13 -3
View File
@@ -14,10 +14,20 @@ jobs:
options: --privileged
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
- name: Checkout code
uses: actions/checkout@v4
- name: Download version.h artifact
uses: actions/download-artifact@v4
with:
fetch-depth: 0
set-safe-directory: ${{ env.GITHUB_WORKSPACE }}
name: version-file
path: src/lindbergh/
- name: Download SDL3 libs
uses: actions/download-artifact@v4
with:
name: SDL3-FAudio
path: libs/
# Work around container ownership issue
- name: Set Safe Directory
+14 -7
View File
@@ -2,19 +2,26 @@ 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
- name: Checkout code
uses: actions/checkout@v4
- name: Download version.h artifact
uses: actions/download-artifact@v4
with:
name: version-file
path: src/lindbergh/
- name: Download SDL3 libs
uses: actions/download-artifact@v4
with:
name: SDL3-FAudio
path: libs/
# Set up Docker Buildx
- name: Set up Docker Buildx
+73 -50
View File
@@ -4,14 +4,14 @@ on:
workflow_dispatch:
pull_request:
branches:
- master
- main
paths-ignore:
- '**.md'
- '.github/ISSUE_TEMPLATE/*'
- '.docs/changelog'
push:
branches:
- master
- main
paths-ignore:
- '**.md'
- '.github/ISSUE_TEMPLATE/*'
@@ -19,49 +19,22 @@ on:
- '.github/workflows/*'
jobs:
linux-build:
name: 💻 Linux
uses: "./.github/workflows/linux-build.yml"
linux-flatpak:
name: 📦 Linux Flatpak
uses: "./.github/workflows/flatpak-build.yml"
linux-appimage:
name: 📦 Linux AppImage
uses: "./.github/workflows/appimage-build.yml"
create-release:
name: 📤 Create Release
needs: [linux-build, linux-flatpak, linux-appimage]
prepare-source:
name: ⚙️ Prepare Source
runs-on: ubuntu-22.04
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
outputs:
release_version: ${{ steps.get_version.outputs.RELEASE_VERSION }}
release_tag: ${{ steps.get_version.outputs.RELEASE_TAG }}
steps:
# Step 1: Checkout the code to access Git history and tags
- name: Checkout code
uses: actions/checkout@v4
with:
# Fetch all history and tags, necessary for git tag command
fetch-depth: 0
# Step 2: Download artifacts from previous build jobs
- name: Download Artifacts
uses: actions/download-artifact@v4
with:
path: ./artifacts/
# Optional: Display downloaded artifacts for debugging
- name: Display Downloaded Artifacts
run: find ./artifacts/
# Step 3: Extract the latest version from changelog.md
- name: Extract Version from Changelog
- name: Extract Version and Update version.h
id: get_version
run: |
# Define the path to the changelog file (adjust if it's not at the root)
CHANGELOG_FILE="./docs/changelog"
VERSION_FILE="src/lindbergh/version.h"
echo "Attempting to extract version from $CHANGELOG_FILE..."
# Check if the changelog file exists
if [[ ! -f "$CHANGELOG_FILE" ]]; then
echo "Error: Changelog file '$CHANGELOG_FILE' not found."
exit 1
@@ -77,26 +50,76 @@ jobs:
echo "Found version: $VERSION"
# Set environment variables for the release step
# RELEASE_TAG often includes a 'v' prefix, RELEASE_VERSION is the plain version
echo "RELEASE_VERSION=$VERSION" >> $GITHUB_ENV
echo "RELEASE_TAG=v$VERSION" >> $GITHUB_ENV # Add 'v' prefix for the tag
echo "Using tag: v$VERSION"
MAJOR=$(echo $VERSION | cut -d. -f1)
MINOR=$(echo $VERSION | cut -d. -f2)
UPDATE=$(echo $VERSION | cut -d. -f3)
if [ -z "$UPDATE" ]; then
UPDATE=0
fi
if [[ ! -f "$VERSION_FILE" ]]; then
echo "Error: Version file '$VERSION_FILE' not found."
exit 1
fi
sed -i "s/\(#define MAJOR_VERSION \).*/\1$MAJOR/" "$VERSION_FILE"
sed -i "s/\(#define MINOR_VERSION \).*/\1$MINOR/" "$VERSION_FILE"
sed -i "s/\(#define UPDATE_VERSION \).*/\1$UPDATE/" "$VERSION_FILE"
echo "Updated $VERSION_FILE with version $MAJOR.$MINOR.$UPDATE"
echo "RELEASE_VERSION=$VERSION" >> $GITHUB_OUTPUT
echo "RELEASE_TAG=v$VERSION" >> $GITHUB_OUTPUT
- name: Upload version.h artifact
uses: actions/upload-artifact@v4
with:
name: version-file
path: src/lindbergh/version.h
linux-appimage:
name: 📦 Linux AppImage
needs: prepare-source
uses: "./.github/workflows/appimage-build.yml"
linux-build:
name: 💻 Linux
needs: [prepare-source, linux-appimage]
uses: "./.github/workflows/linux-build.yml"
linux-flatpak:
name: 📦 Linux Flatpak
needs: [prepare-source, linux-appimage]
uses: "./.github/workflows/flatpak-build.yml"
create-release:
name: 📤 Create Release
needs: [linux-build, linux-flatpak, linux-appimage, prepare-source]
runs-on: ubuntu-22.04
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Download Artifacts
uses: actions/download-artifact@v4
with:
path: ./artifacts/
- name: Display Downloaded Artifacts
run: find ./artifacts/
# Step 4: Create the release using the calculated tag
- name: Create Release
uses: "marvinpinto/action-automatic-releases@latest"
with:
repo_token: "${{ secrets.GITHUB_TOKEN }}"
# Use the environment variable set in the previous step
# automatic_release_tag: ${{ env.NEXT_TAG }}
automatic_release_tag: ${{ env.RELEASE_TAG }}
# Keep prerelease as false unless you want preview releases
automatic_release_tag: ${{ needs.prepare-source.outputs.release_tag }}
prerelease: false
# Update the title to use the new tag
# title: "Build ${{ env.NEXT_TAG }}"
title: "Build ${{ env.RELEASE_TAG }}"
title: "Build ${{ needs.prepare-source.outputs.release_tag }}"
files: |
./artifacts/linux-flatpak/lindbergh-loader.flatpak
./artifacts/linux-build/build.tar.gz
./artifacts/linux-appimage/lindbergh-loader.AppImage
./artifacts/linux-appimage/lindbergh-loader.AppImage
+1
View File
@@ -6,6 +6,7 @@ tmp/
*.bin
/*.conf
src/lindbergh/*.o
src/lindbergh/shaderWork/*.o
src/libxdiff/xdiff/*.o
src/libxdiff/*.a
src/libkswapapi/*.o
+18 -19
View File
@@ -12,27 +12,28 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build)
# Source files for various targets
file(GLOB LIND_OBJS "src/lindbergh/*.c")
file(GLOB LIND_OBJS "src/lindbergh/*.c" "src/lindbergh/shaderWork/*.c")
list(FILTER LIND_OBJS EXCLUDE REGEX "src/lindbergh/lindbergh.c")
file(GLOB XDIFF_SRCS "src/libxdiff/xdiff/*.c")
# Custom compiler and linker flags
set(LINDBERGH_EXE -m32)
set(LINDBERGH_EXE -m32 -DCOMPILING_LINDBERGH_ELF)
set(LINDBERGH_C_FLAGS -g -fPIC -m32 -Wall -Werror -Wno-unused-variable -Wno-unused-function -D_GNU_SOURCE)
#SET(CMAKE_C_FLAGS_DEBUG -g)
SET(CMAKE_C_FLAGS_RELEASE -O3)
set(LINDBERGH_CXX_FLAGS ${LINDBERGH_C_FLAGS} -std=c++11)
set(LIBXDIFF_C_FLAGS -DHAVE_CONFIG_H -fPIC -m32)
set(LIBSEGAAPI_CXX_FLAGS -m32 -fPIC -shared)
set(LIBSEGAAPI_LINKER_FLAGS -m32 -lFAudio)
set(SHARED_LINKER_FLAGS -m32 -Wl,-z,defs -rdynamic -static-libstdc++ -static-libgcc -lc -ldl -lGL -lglut -lX11 -lXcursor -lSDL2 -lm -lpthread -shared -lstdc++ -nostdlib -lasound)
set(LIBSEGAAPI_C_FLAGS -m32 -fPIC -shared)
set(LIBSEGAAPI_LINKER_FLAGS -m32 -Wl,-Bstatic -lFAudio -Wl,-Bdynamic -lm)
set(SHARED_LINKER_FLAGS -m32 -Wl,-z,defs -rdynamic -static-libstdc++ -static-libgcc -lc -ldl -lGL -lglut -lX11 -lXcursor -lSDL3 -lSDL3_ttf -lSDL3_image -ludev -lm -lpthread -shared -lstdc++ -nostdlib)
# Build executable for lindbergh
add_executable(lindyloader src/lindbergh/lindbergh.c src/lindbergh/evdevinput.c src/lindbergh/evdevinput.h src/lindbergh/log.c src/lindbergh/log.h src/lindbergh/jvs.c src/lindbergh/jvs.h src/lindbergh/config.h src/lindbergh/config.c)
add_executable(lindyloader src/lindbergh/lindbergh.c src/lindbergh/iniParser.c src/lindbergh/sdlInput.c src/lindbergh/controlIniGen.c src/lindbergh/log.c src/lindbergh/jvs.c src/lindbergh/config.c src/lindbergh/evdevInput.c src/lindbergh/gameData.c src/lindbergh/configIni.c)
set_target_properties(lindyloader PROPERTIES OUTPUT_NAME "lindbergh")
set_target_properties(lindyloader PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} LINK_FLAGS "-m32 -lm")
# set_target_properties(lindyloader PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} LINK_FLAGS "-m32 -lm -lSDL3")
target_compile_options(lindyloader PRIVATE ${LINDBERGH_EXE})
# target_link_libraries(lindyloader "-m32 -lm -sdl3")
target_link_libraries(lindyloader PRIVATE lindbergh m SDL3)
# Build static library libxdiff.a with its own flags
add_library(xdiff STATIC ${XDIFF_SRCS})
@@ -43,12 +44,12 @@ target_compile_options(xdiff PRIVATE ${LIBXDIFF_C_FLAGS})
add_library(lindbergh SHARED ${LIND_OBJS})
set_target_properties(lindbergh PROPERTIES PREFIX "")
target_link_libraries(lindbergh xdiff ${SHARED_LINKER_FLAGS})
target_compile_options(lindbergh PRIVATE ${LINDBERGH_EXE})
target_compile_options(lindbergh PRIVATE ${LINDBERGH_C_FLAGS})
# Build shared library libsegaapi.so
add_library(segaapi SHARED src/libsegaapi/libsegaapi.c)
target_link_libraries(segaapi FAudio ${LIBSEGAAPI_LINKER_FLAGS})
target_compile_options(segaapi PRIVATE ${LIBSEGAAPI_CXX_FLAGS})
target_link_libraries(segaapi ${LIBSEGAAPI_LINKER_FLAGS})
target_compile_options(segaapi PRIVATE ${LIBSEGAAPI_C_FLAGS})
# Build shared library libkswapapi.so
add_library(kswapapi SHARED src/libkswapapi/libkswapapi.c)
@@ -63,12 +64,10 @@ add_custom_command(TARGET posixtime POST_BUILD
COMMAND ln -s -f libposixtime.so ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libposixtime.so.2.4)
target_compile_options(posixtime PRIVATE ${LINDBERGH_C_FLAGS})
# Custom clean rule
add_custom_target(cleanall
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/build
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/src/lindbergh/*.o
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/src/libsegaapi/*.o
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/src/libkswapapi/*.o
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/src/libxdiff/*.a
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/src/libxdiff/xdiff/*.o
# Example: List of extra files and directories to remove during 'make clean'
set(MY_EXTRA_CLEAN_STUFF
"${CMAKE_BINARY_DIR}/build/libposixtime.so.1" # A specific log file
"${CMAKE_BINARY_DIR}/build/libposixtime.so.2.4" # A directory with generated reports
)
set_directory_properties(PROPERTIES ADDITIONAL_CLEAN_FILES "${MY_EXTRA_CLEAN_STUFF}")
+25 -2
View File
@@ -5,9 +5,27 @@ RUN dpkg --add-architecture i386 \
&& apt install -y --no-install-recommends \
build-essential \
gcc-multilib \
g++-multilib \
cmake \
fuse \
freeglut3-dev:i386 \
libsdl2-dev:i386 \
libfaudio-dev:i386 \
libvdpau1:i386 \
libstdc++5:i386 \
libxmu6:i386 \
libpcsclite1:i386 \
libncurses5:i386 \
unzip \
libudev-dev:i386 \
zlib1g:i386 \
libgpg-error0:i386 \
libxcursor-dev:i386 \
libxfixes-dev:i386 \
libxi-dev:i386 \
libxrandr-dev:i386 \
libxss-dev:i386 \
libxxf86vm-dev:i386 \
git \
&& apt clean \
&& rm -rf /var/lib/apt/lists/*
@@ -15,5 +33,10 @@ WORKDIR /lindbergh-loader
COPY . .
RUN ls
RUN tar -xf libs/libs.tar -C /usr/lib/i386-linux-gnu
RUN tar -xf libs/includes.tar -C /usr/include
# Explicitly set the output directory
RUN make && mkdir -p /output && cp -r ./build /output
RUN make && mkdir -p /output && cp -r ./build /output
+8 -4
View File
@@ -2,7 +2,7 @@ CC ?= gcc
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
CXX ?= g++
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
LDFLAGS = -m32 -Wl,-z,defs -rdynamic -static-libgcc -lc -ldl -lGL -lglut -lX11 -lXcursor -lSDL3 -lSDL3_image -lSDL3_ttf -lm -ludev -lpthread -shared -nostdlib -L./src/libxdiff -lxdiff -L/app/lib32
BUILD = build
@@ -12,13 +12,15 @@ XDIFF_SRCS = xdiffi.c xprepare.c xpatchi.c xmerge3.c xemit.c xmissing.c xutils.c
XDIFF_OBJS = $(patsubst %.c,src/libxdiff/xdiff/%.o,$(XDIFF_SRCS))
OBJS := $(patsubst %.c,%.o,$(wildcard src/lindbergh/*.c))
OBJS := $(patsubst %.c,%.o,$(wildcard src/lindbergh/shaderWork/*.c)) $(OBJS)
OBJS := $(filter-out src/lindbergh/lindbergh.o, $(OBJS))
all: lindbergh libxdiff.a lindbergh.so libsegaapi.so libkswapapi.so libposixtime.so
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/iniParser.c src/lindbergh/sdlInput.c src/lindbergh/controlIniGen.c src/lindbergh/log.c src/lindbergh/jvs.c src/lindbergh/config.c src/lindbergh/evdevInput.c src/lindbergh/gameData.c src/lindbergh/configIni.c
mkdir -p $(BUILD)
$(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
$(CC) -m32 -DCOMPILING_LINDBERGH_ELF src/lindbergh/lindbergh.c src/lindbergh/iniParser.c src/lindbergh/sdlInput.c src/lindbergh/controlIniGen.c src/lindbergh/log.c src/lindbergh/jvs.c src/lindbergh/config.c src/lindbergh/evdevInput.c src/lindbergh/gameData.c src/lindbergh/configIni.c -o $(BUILD)/lindbergh -lm -lSDL3 -L/app/lib32
libxdiff.a: $(XDIFF_OBJS)
mkdir -p $(BUILD)
@@ -35,7 +37,7 @@ lindbergh.so: $(OBJS)
$(CC) $(CFLAGS) -c $< -o $@
libsegaapi.so: src/libsegaapi/libsegaapi.o
$(CC) -m32 -O0 -g src/libsegaapi/libsegaapi.c -lFAudio -L/app/lib32 -fPIC -shared -o $(BUILD)/libsegaapi.so
$(CC) -m32 -O0 -g src/libsegaapi/libsegaapi.c -Wl,-Bstatic -lFAudio -Wl,-Bdynamic -L/app/lib32 -fPIC -shared -o $(BUILD)/libsegaapi.so
libkswapapi.so: src/libkswapapi/libkswapapi.o
$(CC) -m32 src/libkswapapi/libkswapapi.o -fPIC -shared -o $(BUILD)/libkswapapi.so
@@ -51,12 +53,14 @@ clean:
rm -f $(BUILD)/libsegaapi.so
rm -f $(BUILD)/lindbergh
rm -f src/lindbergh/*.o
rm -f src/lindbergh/shaderWork/*.o
rm -f src/libsegaapi/*.o
#clean all rule
cleanall:
rm -rf $(BUILD)
rm -f src/lindbergh/*.o
rm -f src/lindbergh/shaderWork/*.o
rm -f src/libsegaapi/*.o
rm -f src/libkswapapi/*.o
rm -f src/libxdiff/*.a
+8 -3
View File
@@ -1,4 +1,4 @@
[![Actions Status](https://github.com/lindbergh-loader/lindbergh-loader/actions/workflows/main.yml/badge.svg)](https://github.com/lindbergh-loader/lindbergh-loader/actions)
[![Actions Status](https://github.com/lindbergh-loader/lindbergh-loader/actions/workflows/ci.yml/badge.svg)](https://github.com/lindbergh-loader/lindbergh-loader/actions)
# SEGA Lindbergh Emulator
@@ -10,13 +10,16 @@ If you need any help please ask the community in the [arcade community discord](
## Building & Running
In order to build the loader you will need to install the following dependencies in a Linux environment. We recommend Ubuntu 22.04 LTS as default, but it may work in various configurations like WSL2, Debian, etc.
In order to build the loader you will need to install the following dependencies in a Linux environment. We recommend Ubuntu 22.04 LTS, but it will run in almost any modern distro using the AppImage or the Flatpak..
Please note other dependencies might be required to run games (see the [guide](docs/guide.md)).
```shell
sudo dpkg --add-architecture i386
sudo apt update
sudo apt install git build-essential gcc-multilib freeglut3-dev:i386 libsdl2-dev:i386 libfaudio-dev:i386
sudo apt install build-essential gcc-multilib g++-multilib cmake fuse freeglut3-dev:i386 libvdpau1:i386 libstdc++5:i386 libxmu6:i386 \
libpcsclite1:i386 libncurses5:i386 unzip libsndio-dev libsndio-dev:i386 pulseaudio-utils:i386 zlib1g:i386 libgpg-error0:i386 \
libasound2 libasound2-dev libasound2:i386 libasound2-dev:i386 libfreetype6-dev:i386 libdbus-1-dev libpulse-dev libdbus-1-dev:i386 \
libudev-dev:i386 libxcursor-dev:i386 libxfixes-dev:i386 libxi-dev:i386 libxrandr-dev:i386 libxss-dev:i386 libxxf86vm-dev:i386 git
```
This emulator will need access to the input devices and serial devices on your computer. You should add your user account to the following groups and then _restart your computer_.
@@ -30,9 +33,11 @@ Then you should clone the repository, change directory into it and run make.
```shell
git clone git@github.com:lindbergh-loader/lindbergh-loader.git
cd lindbergh-loader
./scripts/appimage/build-deps.sh
make
```
You should then copy the contents of the build directory to your game directory and run `./lindbergh` for the game, or `./lindbergh -t` for test mode. Please note you might need to set the game executable as "executable" using `chmod +x`.
```shell
Binary file not shown.
+34 -14
View File
@@ -2,23 +2,43 @@
All notable changes to this project will be documented in this file.
## [2.0.14]
## [2.1.0]
### Added
- Rambo DVP-0078 (China version) support.
- ID5 DVP-0070C support.
- AxA games added.
- An option to set a percentage to reduce the travel in ID games steering wheel.
- An option to change the language in ID5 EXP (DVP-0084 and DVP-0084A) to Chinese.
- An option to change the way the Guns are shown in Rambo.
- New controls guide in pdf format inside docs folder.
- Change the Outrun Testmode font to a built in font that scales with the resolution set.
- An option in lindberg elf to specify a comunity built game controller database.
- An option in lindberg elf to generate a default controls.ini.
- An option to in lindberg elf generate a default lindbergh.ini file.
- SDL controls configuration using logical names.
- SDL input remade with separate configuration file.
- Option to make Primeval Hunt test mode load as a single screen.
- Blitting to support stretching with fullscreen on the fly. (F11 to switch from / to fullscreen).
- Bobby's birthday checking!
- FPS target to float.
### Fixed
- a bub in config.c where MJ4_ENABLED_ALL_THE_TIME was using the wrong variable.
## [2.0.13]
### Added
- Clear window when the game is loading to prevent ghosting in SDL
- Prevent the created windows to resize/maximize.
- Version in github now matches the version in the changelog.
### Fixed
- Fixed a bug in Let's Go Jungle Special Resolution Patch.
- Prevent the created windows to resize/maximize in LGJ games and PH (Cause issues).
### Code changes
- config file format changed to ini (TOML format).
- Removed X11 completely and only SDL is used to create windows and handle controls.
- Cleaned the shader patches files.
- Moved all the network related code to a new file.
- Moved all the shader caching to a new file.
- Refactored config.c to make it more readable.
- Cleaned the code, fixed all the variables, functions and file names to use the same naming convention.
- Cleaned unnecessary global variables in resolution.c
- Fixed a bug in that prevented the loader to start when the current folder contained spaces and lindbergh.so was there.
- Replaced stb_image with SDL_image.
- Switched to SDL3
- Version in github now matches the version in the changelog.
- FPS target to float.
- Clear window background when the game is loading to prevent ghosting in SDL
### Fixed
- a bug in config.c where MJ4_ENABLED_ALL_THE_TIME was using the wrong variable.
- Fixed a bug in Let's Go Jungle Special Resolution Patch.
- Fixed a bug that prevented the loader to start when the current folder contained spaces and lindbergh.so was there.
## [2.0.12]
### Added
+15 -3
View File
@@ -31,6 +31,7 @@ The follow list of games are supported. It is worth noting that there are multip
| 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 C | SBQZ | DVP-0070C | ✓ | ✓ | ✓ | |
| 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 | ✓ | ✓ | ✓ | |
@@ -41,6 +42,7 @@ The follow list of games are supported. It is worth noting that there are multip
| Outrun 2 SP SDX Rev A | SBMB | DVP-0015A | ✓ | ✓ | ✓ | ✓ |
| Primeval Hunt | SBPP | DVP-0048 | ✓ | ✓ | ✓ | ✓ |
| Rambo | SBQL | DVP-0069 | ✓ | ✓ | ✓ | ✓ |
| Rambo (China) | SBSS | DVP-0078 | ✓ | ✓ | ✓ | ✓ |
| R-Tuned | SBQW | DVP-0060 | ✓ | ✓ | ✓ | ✓ |
| Sega Race TV | SBPF | DVP-0044 | ✓ | ✓ | ✓ | ✓ |
| The House of the Dead 4 Rev A | SBLC | DVP-0003A | ✓ | ✓ | ✓ | ✓ |
@@ -88,15 +90,15 @@ sudo ln -s /lib/i386-linux-gnu/libglut.so /lib/i386-linux-gnu/libglut.so.3
### 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.ini` to play in DX, SDX or Standard cabinet types.
### Hummer (all versions)
The games will ask for libGLcore.so.1 and libnvidia-tls.so.1 you can copy for example libkswapapi.so as libGLcore.so.1 and libnvidia-tls.so.1 and the game will work fine.
## Configuration File : lindbergh.conf
## Configuration File : lindbergh.ini
All configurable options are set and explained in the [`lindbergh.conf`](lindbergh.conf) file itself, and should be reasonably easy to understand. This chapter further explains some of those setup options.
All configurable options are set and explained in the [`lindbergh.ini`](lindbergh.ini) file itself, and should be reasonably easy to understand. This chapter further explains some of those setup options.
You will see the value `AUTO` by default for some of the config options. This is present when the emulator might set that config value to multiple different things itself. For example rideboard emulation is set to `AUTO` so that the emulator doesn't enable it for all games, and only turns it on for the special games that require it. If it was set to `1` it would always emulate the rideboard on serial port 2, and if it was set to `0` it would never emulate it.
@@ -268,3 +270,13 @@ The loader will try to find the files.
If by mistake, you pass both, a full path including an ELF and a path with -g option, the path passed with -g option will be omitted.
Remember that if the path containg spaces, which is not recommended, pass the path inside double quotes or `\` before the space.
## Creating lindbergh.ini or controls.ini
```
./lindbergh --create --help
```
Will give you instructions on how to use the new commands.
-228
View File
@@ -1,228 +0,0 @@
# SEGA Lindbergh Emulator Configuration File
# By the Lindbergh Development Team 2024-2025
# Set the requested dip switch width here
WIDTH AUTO
# Set the requested dip switch height here
HEIGHT AUTO
# Boost render resolution in HOD4/2Spicy/Harley/Rambo/HOD-EX/ID4/ID5 and LGJ
# BOOST_RENDER_RES 1
# Set if the emulator should go full screen
# FULLSCREEN 0
# Sets the Input Mode
# Mode 0: will use both SDL/X11 and EVDEV inputs (default)
# Mode 1: will use SDL/X11 inputs only
# Mode 2: will use EVDEV raw inputs only, which should be configured at the bottom of the settings file
# INPUT_MODE 0
# Set to 1 if you want to disable SDL (Fixes SRTV boost bar)
# NO_SDL 0
# Set the Region ( JP/US/EX )
# REGION EX
# Set if you want the game to be Free Play
# FREEPLAY 1
# Set if the emulator should emulate JVS and use the keyboard/mouse for controls.
# If this is set to 0, then the emulator will route the traffic to the serial device
# defined in JVS_PATH if it has been defined.
# EMULATE_JVS 1
# 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
EMULATE_RIDEBOARD AUTO
# Set if the emulator should emulate the driveboard used in driving games here
# If this is set to 0, then the emulator will route the traffic to one of the serial ports
EMULATE_DRIVEBOARD AUTO
# Set if the emulator should emulate the motion board from Outrun 2 SP SDX here
# If this is set to 0, then the emulator will route the traffic to one of the serial ports
EMULATE_MOTIONBOARD AUTO
# Set if the loader should emulate the card reader in Virtua Tenis 3
EMULATE_CARDREADER AUTO
# Set to 1 if the loader should emulate the touchscreen with the mouse in PH.
# EMULATE_TOUCHSCREEN 1
# Card File for reader 1
# CARDFILE_01 Card_01.crd
# Card File for reader 2
# CARDFILE_02 Card_02.crd
# Define the path to pass the JVS packets to if JVS is not being emulated.
# JVS_PATH /dev/ttyUSB0
# Define the path to pass the first serial port to if it's not being emulated.
# SERIAL_1_PATH /dev/ttyUSB0
# Define the path to pass the second serial port to if it's not being emulated.
# SERIAL_2_PATH /dev/ttyUSB0
# Define the path to the sram.bin file
# SRAM_PATH sram.bin
# Define the path to the eeprom.bin file
# EEPROM_PATH eeprom.bin
# If set, the library libCG.so needed for 2Spicy, Harley, Rambo and HOD-Ex shader recompilation
# will be loaded from the specifyied location. (include the name of file in the location)
# LIBCG_PATH /my/file/location/myLibCg.so
# Set the GPU vendor (0 = Autodetect / 1 = NVidia / 2 = AMD / 3 = ATI(AMD-PRO) / 4 = Intel / 5 = Unknown)
# GPU_VENDOR 0
# Set if you want to see debug messages in the console
# DEBUG_MSGS 0
# Set if you'd like to add a border for optical light gun tracking
# BORDER_ENABLED 0
# Set the thickness of the white border as a percentage of the width of the screen
# WHITE_BORDER_PERCENTAGE 2
# Set the thickness of the black border which sits around the
# white border as a percentage of the width of the screen
# BLACK_BORDER_PERCENTAGE 0
# Set to true if you experience flickering in hummer
# HUMMER_FLICKER_FIX 0
# Set to keep the aspect ratio (4:3) in games like Sega Race TV and Primeval Hunt
# KEEP_ASPECT_RATIO 0
# Set to 0 if you want to disable the Glare effect in OutRun
# OUTRUN_LENS_GLARE_ENABLED 1
# Set to 1 to bypass cabinet checks including drive board and tower in Outrun 2 SP SDX
# SKIP_OUTRUN_CABINET_CHECK 0
# Set to 1 if you want to limit the FPS in games that are not limited like OutRun2
# FPS_LIMITER_ENABLED 0
# Set the target FPS (will only work if FPS_LIMITER_ENABLED = 1)
# FPS_TARGET 60
# Set to 1 if you want to render LGJ using the mesa patches instead of nVidia (fixes some glitches)
# LGJ_RENDER_WITH_MESA 1
# Set the Primeval Hunt mode
# Mode 0: Default (Side by Side)
# Mode 1: No touch screen
# Mode 2: Side by Side
# Mode 3: 3ds mode 1 (Touch screen to the right)
# Mode 4: 3ds mode 2 (Touch screen to the bottom)
# PRIMEVAL_HUNT_MODE 1
# Disble to use the original fonts instead of the built in font in the loader
# DISABLE_BUILTIN_FONT 0
# Disble to use the original logos instead of the built in logos in the loader
# DISABLE_BUILTIN_LOGOS 0
# Set to 0 to enable the mouse pointer/Cursor
# HIDE_CURSOR 1
# Set the custom mouse pointer from a PNG file (Usefull for shooting games)
# CUSTOM_CURSOR myCustomCursor.png
# Set the width of the custom cursor
# CUSTOM_CURSOR_WIDTH 32
# Set the height of the custom cursor
# CUSTOM_CURSOR_HEIGHT 32
# Set a custom cursor for the touch screen in Primeval Hunt
# PH_TOUCH_CURSOR myCustomHandCursor.png
# Set the width of the custom cursor
# PH_TOUCH_CURSOR_WIDTH 32
# Set the height of the custom cursor
# PH_TOUCH_CURSOR_HEIGHT 32
# Hacky way to make MJ4 work at prohibited times?
# MJ4_ENABLED_ALL_THE_TIME 1
# Sets the IP address in the eeprom for Outrun link (you have to put your NIC ip)
# OR2_IP 192.168.1.2
# OR2_NETMASK 255.255.255.0
# House of the dead 4 speed fix set the frequency of your CPU in Ghz (The speed reported by the manufacturer)
# CPU_FREQ_GHZ 4.0
# Set the colour of the lindbergh to change the Segaboot logo
# Possible colours are: YELLOW, RED, BLUE, SILVER, REDEX
# LINDBERGH_COLOUR YELLOW
# X11 MODE (Input Mode 1)
# To find the value pairs for these run `xev` on linux
TEST_KEY 28 # t
PLAYER_1_START_KEY 10 # 1
PLAYER_1_SERVICE_KEY 39 # s
PLAYER_1_COIN_KEY 14 # 5
PLAYER_1_UP_KEY 111 # Up
PLAYER_1_DOWN_KEY 116 # Down
PLAYER_1_LEFT_KEY 113 # Left
PLAYER_1_RIGHT_KEY 114 # Right
PLAYER_1_BUTTON_1_KEY 24 # q
PLAYER_1_BUTTON_2_KEY 25 # w
PLAYER_1_BUTTON_3_KEY 26 # e
PLAYER_1_BUTTON_4_KEY 27 # r
# EVDEV MODE (Input Mode 2)
# To find the value pairs for these run ./lindbergh --list-controllers
# TEST_BUTTON AT_TRANSLATED_SET_2_KEYBOARD_KEY_Z
# PLAYER_1_BUTTON_START AT_TRANSLATED_SET_2_KEYBOARD_KEY_1
# PLAYER_1_BUTTON_SERVICE AT_TRANSLATED_SET_2_KEYBOARD_KEY_S
# PLAYER_1_BUTTON_UP AT_TRANSLATED_SET_2_KEYBOARD_KEY_UP
# PLAYER_1_BUTTON_DOWN AT_TRANSLATED_SET_2_KEYBOARD_KEY_DOWN
# PLAYER_1_BUTTON_LEFT AT_TRANSLATED_SET_2_KEYBOARD_KEY_LEFT
# PLAYER_1_BUTTON_RIGHT AT_TRANSLATED_SET_2_KEYBOARD_KEY_RIGHT
# PLAYER_1_BUTTON_1 AT_TRANSLATED_SET_2_KEYBOARD_KEY_Q
# PLAYER_1_BUTTON_2 AT_TRANSLATED_SET_2_KEYBOARD_KEY_W
# PLAYER_1_BUTTON_3 AT_TRANSLATED_SET_2_KEYBOARD_KEY_E
# PLAYER_1_BUTTON_4 AT_TRANSLATED_SET_2_KEYBOARD_KEY_R
# PLAYER_1_BUTTON_5 AT_TRANSLATED_SET_2_KEYBOARD_KEY_T
# PLAYER_1_BUTTON_6 AT_TRANSLATED_SET_2_KEYBOARD_KEY_Y
# PLAYER_1_BUTTON_7 AT_TRANSLATED_SET_2_KEYBOARD_KEY_I
# PLAYER_1_BUTTON_8 AT_TRANSLATED_SET_2_KEYBOARD_KEY_O
# PLAYER_2_BUTTON_START AT_TRANSLATED_SET_2_KEYBOARD_KEY_1
# PLAYER_2_BUTTON_SERVICE AT_TRANSLATED_SET_2_KEYBOARD_KEY_S
# PLAYER_2_BUTTON_UP AT_TRANSLATED_SET_2_KEYBOARD_KEY_UP
# PLAYER_2_BUTTON_DOWN AT_TRANSLATED_SET_2_KEYBOARD_KEY_DOWN
# PLAYER_2_BUTTON_LEFT AT_TRANSLATED_SET_2_KEYBOARD_KEY_LEFT
# PLAYER_2_BUTTON_RIGHT AT_TRANSLATED_SET_2_KEYBOARD_KEY_RIGHT
# PLAYER_2_BUTTON_1 AT_TRANSLATED_SET_2_KEYBOARD_KEY_Q
# PLAYER_2_BUTTON_2 AT_TRANSLATED_SET_2_KEYBOARD_KEY_W
# PLAYER_2_BUTTON_3 AT_TRANSLATED_SET_2_KEYBOARD_KEY_E
# PLAYER_2_BUTTON_4 AT_TRANSLATED_SET_2_KEYBOARD_KEY_R
# PLAYER_2_BUTTON_5 AT_TRANSLATED_SET_2_KEYBOARD_KEY_T
# PLAYER_2_BUTTON_6 AT_TRANSLATED_SET_2_KEYBOARD_KEY_Y
# PLAYER_2_BUTTON_7 AT_TRANSLATED_SET_2_KEYBOARD_KEY_I
# PLAYER_2_BUTTON_8 AT_TRANSLATED_SET_2_KEYBOARD_KEY_O
# ANALOGUE_1 SYNPS_2_SYNAPTICS_TOUCHPAD_ABS_X
# ANALOGUE_2 SYNPS_2_SYNAPTICS_TOUCHPAD_ABS_Y
# ANALOGUE_3 SYNPS_2_SYNAPTICS_TOUCHPAD_ABS_Z
# ANALOGUE_4 SYNPS_2_SYNAPTICS_TOUCHPAD_ABS_RZ
# ANALOGUE_DEADZONE_1 0 0 0
# ANALOGUE_DEADZONE_2 0 0 0
# ANALOGUE_DEADZONE_3 0 0 0
# ANALOGUE_DEADZONE_4 0 0 0
# ANALOGUE_DEADZONE_5 0 0 0
# ANALOGUE_DEADZONE_6 0 0 0
# ANALOGUE_DEADZONE_7 0 0 0
# ANALOGUE_DEADZONE_8 0 0 0
+38 -18
View File
@@ -6,25 +6,45 @@ OUTPUT_FOLDER=$(realpath "./$APPIMAGEDIRNAME")
mkdir build-deps
cd build-deps
# Build openal
wget https://github.com/kcat/openal-soft/archive/refs/tags/openal-soft-1.17.2.tar.gz
tar -xzf openal-soft-1.17.2.tar.gz
cd openal-soft-openal-soft-1.17.2/build
CFLAGS="-m32 -mstackrealign" CXXFLAGS="-m32 -std=c++14 -mstackrealign" cmake ../ -DALSOFT_BACKEND_PULSEAUDIO=ON -DALSOFT_BACKEND_ALSA=ON -DALSOFT_BACKEND_JACK=OFF -DALSOFT_BACKEND_SNDIO=ON
# Build SDL3
git clone https://github.com/libsdl-org/SDL.git
cd SDL
mkdir build
cd build
cmake ../ -DCMAKE_C_FLAGS=-m32 -DCMAKE_INSTALL_PREFIX=/usr
make -j4
sudo cp libopenal.so.1.17.2 /usr/lib/i386-linux-gnu/libopenal.so.0
sudo make install
cd ../../
# Build libSSL and libCrypto
wget https://github.com/openssl/openssl/archive/refs/tags/OpenSSL_0_9_7.tar.gz
tar -xzf OpenSSL_0_9_7.tar.gz
cd openssl-OpenSSL_0_9_7
cp ../../scripts/appimage/patches/openssl-0.9.7.patch .
./Configure shared 386 no-asm no-krb5 linux-pentium -m32
patch -p1 < openssl-0.9.7.patch
CFLAGS=-m32 make
sudo cp libcrypto.so.0.9.7 /usr/lib/i386-linux-gnu
sudo cp libssl.so.0.9.7 /usr/lib/i386-linux-gnu
# Build SDL3_ttf
git clone https://github.com/libsdl-org/SDL_ttf.git
cd SDL_ttf
mkdir build
cd build
cmake ../ -DCMAKE_C_FLAGS=-m32 -DCMAKE_INSTALL_PREFIX=/usr
make -j4
sudo make install
cd ../../
# Build SDL3_image
git clone https://github.com/libsdl-org/SDL_image.git
cd SDL_image
mkdir build
cd build
cmake ../ -DCMAKE_C_FLAGS=-m32 -DCMAKE_INSTALL_PREFIX=/usr
make -j4
sudo make install
cd ../../
# Build libFAudio
git clone https://github.com/FNA-XNA/FAudio.git
cd FAudio
mkdir build
cd build
cmake ../ -DCMAKE_C_FLAGS=-m32 -DCMAKE_INSTALL_PREFIX=/usr -DBUILD_SHARED_LIBS=off
make -j4
sudo make install
cd ../../../
+5 -3
View File
@@ -4,8 +4,10 @@ echo "Install Packages Running..."
sudo dpkg --add-architecture i386
sudo apt update
sudo apt -y install --no-install-recommends \
build-essential gcc-multilib g++-multilib cmake fuse freeglut3-dev:i386 libsdl2-dev:i386 libfaudio-dev:i386 libvdpau1:i386 \
libstdc++5:i386 libxmu6:i386 libpcsclite1:i386 libncurses5:i386 unzip libsndio-dev:i386
build-essential gcc-multilib g++-multilib cmake fuse freeglut3-dev:i386 libvdpau1:i386 libstdc++5:i386 libxmu6:i386 \
libpcsclite1:i386 libncurses5:i386 unzip libsndio-dev libsndio-dev:i386 pulseaudio-utils:i386 zlib1g:i386 libgpg-error0:i386 \
libasound2 libasound2-dev libasound2:i386 libasound2-dev:i386 libfreetype6-dev:i386 libdbus-1-dev libpulse-dev libdbus-1-dev:i386 \
libudev-dev:i386 libxcursor-dev:i386 libxfixes-dev:i386 libxi-dev:i386 libxrandr-dev:i386 libxss-dev:i386 libxxf86vm-dev:i386 git
sudo add-apt-repository ppa:kisak/kisak-mesa -y
sudo add-apt-repository ppa:kisak/turtle -y
sudo apt update -y && sudo apt upgrade -y
+14 -6
View File
@@ -4,6 +4,7 @@ APPIMAGENAME=lindbergh-loader
APPIMAGEDIRNAME=lindbergh-loader.AppDir
declare -a ADDED_LIBS=(
"libfreetype.so.6"
"libOpenGL.so.0"
"libGLdispatch.so.0"
"libGLX.so"
@@ -22,16 +23,18 @@ declare -a ADDED_LIBS=(
"libxcb-dri3.so.0"
"libxcb-glx.so.0"
"libXmu.so.6"
"libXrandr.so.2"
"libncurses.so.5"
"libpcsclite.so.1"
"libstdc++.so.5"
"libdrm.so.2"
"libexpat.so.1"
"libm.so.6"
"libopenal.so.0"
"libcrypto.so.0.9.7"
"libssl.so.0.9.7"
"libuuid.so.1"
"libz.so.1"
"libgpg-error.so.0"
"libstdc++.so.6"
"libudev.so.1"
"libsndio.so.7"
)
set -e
@@ -55,6 +58,7 @@ for lib in "${ADDED_LIBS[@]}"; do
ADDED_LIBS_ARGS+=("--library=/usr/lib/i386-linux-gnu/$lib")
done
ADDED_LIBS_ARGS+=("--library=/usr/lib/i386-linux-gnu/pulseaudio/libpulsedsp.so")
echo "Copying files into AppDir..."
mkdir -p "$OUTPUT_FOLDER/usr/bin"
@@ -76,7 +80,7 @@ cp libkswapapi.so $OUTPUT_FOLDER/usr/lib
cp libsegaapi.so $OUTPUT_FOLDER/usr/lib
cp lindbergh.so $OUTPUT_FOLDER/usr/lib
cp libposixtime.so $OUTPUT_FOLDER/usr/lib
mv lindbergh $OUTPUT_FOLDER/usr/bin
cp lindbergh $OUTPUT_FOLDER/usr/bin
mkdir -p $OUTPUT_FOLDER/usr/lib/dri
cp /usr/lib/i386-linux-gnu/dri/* $OUTPUT_FOLDER/usr/lib/dri
cd ..
@@ -93,11 +97,15 @@ mv $OUTPUT_FOLDER/usr/lib/libposixtime.so $OUTPUT_FOLDER/usr/lib32
mv $OUTPUT_FOLDER/usr/lib/dri $OUTPUT_FOLDER/usr/lib32
unzip libs/Cg-3.1.zip -d $OUTPUT_FOLDER/usr/lib32
cp libs/libCg.so $OUTPUT_FOLDER/usr/lib32/libCg2.so
cp libs/libCg.so $OUTPUT_FOLDER/usr/lib32/libCg2.so
cp libs/libopenal.so.0 $OUTPUT_FOLDER/usr/lib32/libopenal.so.0
cp libs/libcrypto.so.0.9.7 $OUTPUT_FOLDER/usr/lib32/libcrypto.so.0.9.7
cp libs/libssl.so.0.9.7 $OUTPUT_FOLDER/usr/lib32/libssl.so.0.9.7
ln -s -f libposixtime.so $OUTPUT_FOLDER/usr/lib32/libposixtime.so.1
ln -s -f libposixtime.so $OUTPUT_FOLDER/usr/lib32/libposixtime.so.2.4
ln -s -f libkswapapi.so $OUTPUT_FOLDER/usr/lib32/libGLcore.so.1
ln -s -f libkswapapi.so $OUTPUT_FOLDER/usr/lib32/libnvidia-tls.so.1
ln -s -f libGLX.so $OUTPUT_FOLDER/usr/lib32/libGLX.so.0
echo "Generating AppImage..."
rm -f "$APPIMAGENAME.AppImage"
+6
View File
@@ -0,0 +1,6 @@
cd libs
find /usr/lib/i386-linux-gnu -name "libSDL3*" -exec sh -c 'tar -rf libs.tar -C /usr/lib/i386-linux-gnu $(basename {})' \;
find /usr/lib/i386-linux-gnu -name "libFAudio*" -exec sh -c 'tar -rf libs.tar -C /usr/lib/i386-linux-gnu $(basename {})' \;
tar -cf includes.tar -C /usr/include SDL3 SDL3_image SDL3_ttf FAudio.h FAudioFX.h
cd ..
@@ -1,13 +0,0 @@
diff -ruN openssl-OpenSSL_0_9_7.orig/Makefile.ssl openssl-OpenSSL_0_9_7/Makefile.ssl
--- openssl-OpenSSL_0_9_7.orig/Makefile.ssl 2025-04-14 05:05:11.162340308 +0000
+++ openssl-OpenSSL_0_9_7/Makefile.ssl 2025-04-14 05:06:22.261420144 +0000
@@ -198,7 +198,7 @@
SHARED_SSL=libssl$(SHLIB_EXT)
SHARED_LIBS=$(SHARED_CRYPTO) $(SHARED_SSL)
SHARED_LIBS_LINK_EXTS=.so.$(SHLIB_MAJOR) .so
-SHARED_LDFLAGS=
+SHARED_LDFLAGS=-m32
GENERAL= Makefile
BASENAME= openssl
+122 -122
View File
@@ -1,27 +1,28 @@
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
x-gl-versions: &gl-versions '24.08;1.4'
x-gl-merge-dirs: &gl-merge-dirs vulkan/icd.d;glvnd/egl_vendor.d;egl/egl_external_platform.d;OpenCL/vendors;lib/dri;lib/d3d;lib/gbm;vulkan/explicit_layer.d;vulkan/implicit_layer.d # Define GL merge dirs alias
x-i386-build-options: &i386-build-options
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"
command: lindbergh
# SDK extensions needed for building 32-bit components
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
@@ -32,17 +33,23 @@ finish-args:
- --socket=pulseaudio
- --filesystem=~/Games
# Runtime extensions automatically downloaded and installed with the app (For some reason does not work)
add-extensions:
org.freedesktop.Platform.Compat.i386:
directory: lib/i386-linux-gnu
version: *runtime-version
# 32-bit graphics driver extension
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
versions: *gl-versions
version: *gl-version
versions: *gl-versions
subdirectories: true
no-autodownload: true
autodelete: false
add-ld-path: lib
merge-dirs: *gl-merge-dirs
@@ -50,8 +57,17 @@ add-extensions:
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:
# Pre-built 32-bit library (if required)
- name: libstdcxx5
buildsystem: simple
build-commands:
@@ -61,7 +77,16 @@ modules:
- type: file
path: ./assets/libstdc++.so.5
# Build 32-bit libGLU
- name: SDL3-FAudio
buildsystem: simple
build-commands:
- tar -xf libs/libs.tar -C /app/lib32
- mkdir -p /app/include
- tar -xf libs/includes.tar -C /app/include
sources:
- type: dir
path: ../..
- name: libGLU
buildsystem: autotools
config-opts:
@@ -72,16 +97,14 @@ modules:
x86_64: *i386-build-options
sources:
- type: archive
url: https://archive.mesa3d.org/glu/glu-9.0.2.tar.xz
url: https://mesa.freedesktop.org/archive/glu/glu-9.0.2.tar.xz
sha256: 6e7280ff585c6a1d9dfcdf2fca489251634b3377bfc33c29e4002466a38d02d4
# Build 32-bit freeglut
- name: freeglut
buildsystem: cmake
config-opts:
- -DCMAKE_BUILD_TYPE=Release
- -DCMAKE_INSTALL_PREFIX=/app
- -DCMAKE_INSTALL_LIBDIR=/app/lib32
sources:
- type: archive
url: https://downloads.sourceforge.net/freeglut/freeglut-3.2.2.tar.gz
@@ -90,44 +113,75 @@ modules:
arch:
x86_64: *i386-build-options
# Build 32-bit libFAudio (dynamic)
- name: libFAudio-Dynamic
buildsystem: cmake-ninja
- name: libsndio-dynamic
buildsystem: autotools
config-opts:
- -DCMAKE_BUILD_TYPE=Release
- -DCMAKE_INSTALL_PREFIX=/app
- -DBUILD_SDL3=off
- -DCMAKE_INSTALL_LIBDIR=/app/lib32
- --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
env:
CFLAGS: "-m32 -mstackrealign"
CXXFLAGS: "-m32 -mstackrealign"
sources:
- type: git
url: https://github.com/FNA-XNA/FAudio.git
tag: "24.12"
# Build 32-bit libXmu
- 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: libFAudio-Static
# buildsystem: cmake-ninja
# config-opts:
# - -DCMAKE_BUILD_TYPE=Release
# - -DCMAKE_INSTALL_PREFIX=/app
# - -DBUILD_SHARED_LIBS=off
# - -DCMAKE_INSTALL_LIBDIR=/app/lib32
# build-options:
# arch:
# x86_64: *i386-build-options
# env:
# CFLAGS: "-m32 -mstackrealign"
# CXXFLAGS: "-m32 -mstackrealign"
# LDFLAGS: "-m32 -mstackrealign"
# 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: git
# url: https://github.com/FNA-XNA/FAudio.git
# branch: "master"
- name: libxmu
buildsystem: autotools
config-opts:
- --prefix=/app
- --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
# Build 32-bit libmd
- name: libmd
buildsystem: autotools
config-opts:
- --prefix=/app
- --libdir=/app/lib32
sources:
- type: archive
url: https://archive.hadrons.org/software/libmd/libmd-1.1.0.tar.xz
@@ -136,11 +190,10 @@ modules:
arch:
x86_64: *i386-build-options
# Build 32-bit libbsd
- name: libbsd
buildsystem: autotools
config-opts:
- --prefix=/app
- --libdir=/app/lib32
sources:
- type: archive
url: https://libbsd.freedesktop.org/releases/libbsd-0.12.2.tar.xz
@@ -149,11 +202,10 @@ modules:
arch:
x86_64: *i386-build-options
# Build 32-bit ncurses (very old version)
- name: ncurses
buildsystem: autotools
config-opts:
- --prefix=/app
- --libdir=/app/lib32
- --with-shared
- --without-debug
sources:
@@ -169,7 +221,6 @@ modules:
CPPFLAGS: "-P"
CXXFLAGS: "-std=c++14"
# Install pre-built 32-bit Nvidia Cg Toolkit (old)
- name: nvidia-cg-toolkit
buildsystem: simple
build-commands:
@@ -180,62 +231,10 @@ modules:
url: http://developer.download.nvidia.com/cg/Cg_3.1/Cg-3.1_April2012_x86.tgz
sha256: cef3591e436f528852db0e8c145d3842f920e0c89bcfb219c466797cb7b18879
# Build 32-bit libsndio (dynamic)
- name: libsndio-dynamic
buildsystem: autotools
config-opts:
- --prefix=/app
- --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
# Build 32-bit libopenal (old version)
- name: libopenal
buildsystem: cmake
config-opts:
- -DCMAKE_INSTALL_PREFIX=/app
- -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"
# Build 32-bit OpenSSL (extremely old and insecure version)
- 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
- install -d /app/lib32
- mv libcrypto.so* /app/lib32/
- mv libssl.so* /app/lib32/
sources:
- type: archive
url: https://github.com/openssl/openssl/archive/refs/tags/OpenSSL_0_9_7.tar.gz
sha256: 14e3a90f75994689e8c1bef098a97021f225a1a1623a7b8012079bd8b2eca1e8
# Build 32-bit libpcsclite
- name: libpcsclite
buildsystem: meson
config-opts:
- --libdir=/app/lib32
- -Dpolkit=false
- -Dlibsystemd=false
build-options:
@@ -244,19 +243,20 @@ modules:
env:
CFLAGS: "-m32"
CXXFLAGS: "-m32"
LDFLAGS: "-m32 -L/app/lib32"
PKG_CONFIG_PATH: "/app/lib32/pkgconfig:/usr/lib/i386-linux-gnu/pkgconfig:/usr/lib/sdk/toolchain-i386/lib/pkgconfig"
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
# Build the main application (lindbergh-loader)
- name: lindbergh-loader
buildsystem: simple
build-commands:
- export LD_LIBRARY_PATH=/app/lib32:$LD_LIBRARY_PATH
- make -j$(nproc)
- 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/
@@ -265,20 +265,22 @@ modules:
- install -Dm755 ./build/libkswapapi.so /app/lib32/
- install -Dm755 ./build/libposixtime.so /app/lib32/
- install -Dm755 ./libs/libCg.so /app/lib32/libCg2.so
- ln -sf libposixtime.so /app/lib32/libposixtime.so.1
- ln -sf libposixtime.so /app/lib32/libposixtime.so.2.4
- ln -sf libopenal.so.1 /app/lib32/libopenal.so.0
- ln -sf libkswapapi.so /app/lib32/libGLcore.so.1
- ln -sf libkswapapi.so /app/lib32/libnvidia-tls.so.1
- mv /app/lib/libopenal* /app/lib32/
- install -Dm755 ./libs/libopenal.so.0 /app/lib32/libopenal.so.0
- install -Dm755 ./libs/libcrypto.so.0.9.7 /app/lib32/libcrypto.so.0.9.7
- install -Dm755 ./libs/libssl.so.0.9.7 /app/lib32/libssl.so.0.9.7
- ln -s -f libposixtime.so /app/lib32/libposixtime.so.1
- ln -s -f libposixtime.so /app/lib32/libposixtime.so.2.4
- ln -s -f libkswapapi.so /app/lib32/libGLcore.so.1
- ln -s -f libkswapapi.so /app/lib32/libnvidia-tls.so.1
build-options:
arch:
x86_64: *i386-build-options
env:
CFLAGS: "-I/app/include"
sources:
- type: dir
path: ../..
# Setup dynamic linker configuration
- name: bundle-setup
buildsystem: simple
build-commands:
@@ -287,18 +289,16 @@ modules:
- type: file
path: ./assets/ld.so.conf
# Cleanup unnecessary files to reduce final flatpak size
- name: cleanup
buildsystem: simple
build-commands:
- find /app/lib32 -name '*.a' -type f -delete
- find /app/lib32 -name '*.la' -type f -delete
- find /app/bin -mindepth 1 ! -name "lindbergh" -exec rm -f {} \;
- rm -rf /app/lib/pkgconfig /app/lib32/pkgconfig /app/share/pkgconfig
- rm -rf /app/lib32/cmake /app/lib/debug /app/include /app/man /app/share /app/etc/bash_completion.d
- rm -f /app/lib32/libmenu.so*
- rm -f /app/lib32/libform.so*
- rm -f /app/lib32/libpanel.so*
- rm -f /app/lib32/libXmuu.so*
- rm -f /app/lib32/libbsd.so*
- rm -rf /app/lib/terminfo
- 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
@@ -1,12 +1,6 @@
#include <stdio.h> /* Standard input/output definitions */
#include <string.h> /* String function definitions */
#include <unistd.h> /* UNIX standard function definitions */
#include <fcntl.h> /* File control definitions */
#include <stdlib.h> /* Standard library functions like malloc, free, exit, and atoi */
#include <unistd.h>
#include <sys/select.h>
#include "baseboard.h"
#include "config.h"
#include "jvs.h"
#include "passthrough.h"
@@ -133,7 +127,7 @@ int baseboardSelect(int nfds, fd_set *restrict readfds, fd_set *restrict writefd
return selectReply;
}
int baseboardIoctl(int fd, unsigned int request, void *data)
int baseboardIoctl(int fd, unsigned long request, void *data)
{
switch (request)
{
@@ -162,7 +156,7 @@ int baseboardIoctl(int fd, unsigned int request, void *data)
case BASEBOARD_SEEK_SHM:
{
sharedMemoryIndex = (unsigned int)data;
sharedMemoryIndex = (size_t)data;
return 0;
}
break;
@@ -302,7 +296,7 @@ int baseboardIoctl(int fd, unsigned int request, void *data)
break;
default:
printf("Error: Unknown baseboard ioctl %X\n", request);
printf("Error: Unknown baseboard ioctl %lX\n", request);
}
return 0;
@@ -1,9 +1,11 @@
#include <stdio.h>
#include <sys/select.h>
int initBaseboard();
ssize_t baseboardRead(int fd, void *buf, size_t count);
ssize_t baseboardWrite(int fd, const void *buf, size_t count);
int baseboardIoctl(int fd, unsigned int request, void *data);
int baseboardSelect(int nfds, fd_set *restrict readfds, fd_set *restrict writefds, fd_set *restrict exceptfds, struct timeval *restrict timeout);
int baseboardIoctl(int fd, unsigned long request, void *data);
int baseboardSelect(int nfds, fd_set *restrict readfds, fd_set *restrict writefds, fd_set *restrict exceptfds,
struct timeval *restrict timeout);
+158
View File
@@ -0,0 +1,158 @@
#include <dlfcn.h>
#define GL_GLEXT_PROTOTYPES
#ifndef __i386__
#define __i386__
#endif
#undef __x86_64__
#include <GL/glx.h>
#include <SDL3/SDL.h>
#include <stdbool.h>
#include "blitStretching.h"
#include "config.h"
#include "log.h"
#include "resolution.h"
extern uint32_t gId;
extern int gGrp;
extern int gWidth;
extern int gHeight;
extern SDL_Window *sdlWindow;
int blitWidth = 0;
int blitHeight = 0;
int fboInitialized = false;
GLuint fboId = 0;
GLuint fboTextureId = 0;
int drawableW = 1;
int drawableH = 1;
Dest dest;
void initBlitting()
{
blitSetWidthandHeightSize();
blitInitializeFbo();
dest.gameScale = 1.0f;
}
void blitSetWidthandHeightSize()
{
if (gGrp == GROUP_ID4_EXP || gGrp == GROUP_ID4_JAP || gGrp == GROUP_ID5)
{
if (isTestMode())
{
blitWidth = 1360;
blitHeight = 768;
}
else
{
blitWidth = gWidth;
blitHeight = gHeight;
}
}
else if (gId == GHOST_SQUAD_EVOLUTION || gGrp == GROUP_VT3_TEST)
{
blitWidth = 640;
blitHeight = 480;
}
else if (gId == QUIZ_AXA || gId == QUIZ_AXA_LIVE || gId == MJ4_REVG || gId == MJ4_EVO)
{
blitWidth = 1024;
blitHeight = 768;
}
else
{
blitWidth = gWidth;
blitHeight = gHeight;
}
}
int blitInitializeFbo()
{
glGenFramebuffers(1, &fboId);
if (fboId == 0)
{
log_error("Failed to generate FBO.\n");
return 0;
}
glBindFramebuffer(GL_FRAMEBUFFER, fboId);
glGenTextures(1, &fboTextureId);
if (fboTextureId == 0)
{
log_error("Failed to generate FBO texture.\n");
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDeleteFramebuffers(1, &fboId);
fboId = 0;
return 0;
}
glBindTexture(GL_TEXTURE_2D, fboTextureId);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, blitWidth, blitHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fboTextureId, 0);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)
{
log_error("FBO is not complete! Status: 0x%x\n", status);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDeleteTextures(1, &fboTextureId);
glDeleteFramebuffers(1, &fboId);
fboTextureId = 0;
fboId = 0;
return 0;
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
fboInitialized = true;
return 1;
}
void blitStretch()
{
if (!fboInitialized)
return;
if (fboInitialized && fboId > 0 && fboTextureId > 0 && sdlWindow)
{
SDL_GetWindowSizeInPixels(sdlWindow, &drawableW, &drawableH);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboId);
glBlitFramebuffer(0, 0, blitWidth, blitHeight, 0, 0, blitWidth, blitHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
float gameAspect = (float)blitWidth / (float)blitHeight;
float windowAspect = (float)drawableW / (float)drawableH;
dest.W = drawableW;
dest.H = drawableH;
if (windowAspect > gameAspect)
{
dest.W = (GLsizei)(drawableH * gameAspect);
dest.X = (drawableW - dest.W) / 2;
}
else if (windowAspect < gameAspect)
{
dest.H = (GLsizei)(drawableW / gameAspect);
dest.Y = (drawableH - dest.H) / 2;
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glBindFramebuffer(GL_READ_FRAMEBUFFER, fboId);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glReadBuffer(GL_COLOR_ATTACHMENT0);
glBlitFramebuffer(0, 0, blitWidth, blitHeight, dest.X, dest.Y, dest.X + dest.W, dest.Y + dest.H, GL_COLOR_BUFFER_BIT, GL_LINEAR);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
}
+16
View File
@@ -0,0 +1,16 @@
#pragma once
#include <stdbool.h>
typedef struct
{
int W;
int H;
int X;
int Y;
float gameScale;
} Dest;
void initBlitting();
void blitSetWidthandHeightSize();
int blitInitializeFbo();
void blitStretch();
@@ -1,16 +1,19 @@
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "cardReader.h"
#include "config.h"
#include "card_reader.h"
#include "flowControl.h"
#include "log.h"
#define BLOCKSIZE 8
extern uint32_t gId;
extern int gGrp;
bool cardReaderInitialized = false;
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,
@@ -41,29 +44,17 @@ int initCardReader()
{
EmulatorConfig *config = getConfig();
switch (gId)
if (gGrp != GROUP_VT3 && gGrp != GROUP_VT3_TEST && gId != R_TUNED)
{
case R_TUNED:
case VIRTUA_TENNIS_3:
case VIRTUA_TENNIS_3_TEST:
case VIRTUA_TENNIS_3_REVA:
case VIRTUA_TENNIS_3_REVA_TEST:
case VIRTUA_TENNIS_3_REVB:
case VIRTUA_TENNIS_3_REVB_TEST:
case VIRTUA_TENNIS_3_REVC:
case VIRTUA_TENNIS_3_REVC_TEST:
// Code for supported games
break;
default:
printf("Warning: This Game does not support Card Reader, I will disable the card reader for you.\n");
config->emulateCardreader = 0;
log_warn("Warning: This Game does not support Card Reader, I will disable the card reader for you.\n");
config->emulateHW210CardReader = 0;
return 0;
}
if (getConfig()->emulateCardreader && getConfig()->emulateDriveboard && gId != R_TUNED)
if (config->emulateHW210CardReader && config->emulateDriveboard && gId != R_TUNED)
{
printf("Warning: This Game does not support Card Reader and Driver Board emulation enabled at the same time.\n");
printf("Please disable Drive Board emulations in the config file.\n");
log_warn("Warning: This Game does not support Card Reader and Driver Board emulation enabled at the same time.\n");
log_warn("Please disable Drive Board emulations in the config file.\n");
return -1;
}
@@ -71,6 +62,7 @@ int initCardReader()
initReadCmd(1);
initWriteCmd(0);
initWriteCmd(1);
cardReaderInitialized = true;
return 0;
}
@@ -174,7 +166,7 @@ void buildOutputBuffer(int fdIdx, uint8_t cmd)
break;
default:
{
printf("Command not supported.\n");
log_error("Command not supported.\n");
}
}
readCmd[fdIdx].cmdLen = packetLen + 5;
@@ -183,10 +175,13 @@ void buildOutputBuffer(int fdIdx, uint8_t cmd)
size_t cardReaderWrite(int fd, const void *buf, size_t count)
{
if (!cardReaderInitialized)
return -1;
int fdIdx = carReaderGetFdIdx(fd);
if (writeCmd[fdIdx].cmdCompleted)
{
printf("Something went wrong, a write command was issued after the command was completed.\n");
log_error("Something went wrong, a write command was issued after the command was completed.\n");
}
if (writeCmd[fdIdx].recBytes == 4)
@@ -208,6 +203,9 @@ size_t cardReaderWrite(int fd, const void *buf, size_t count)
size_t cardReaderRead(int fd, void *buf, size_t count)
{
if (!cardReaderInitialized)
return -1;
int fdIdx = carReaderGetFdIdx(fd);
if (!writeCmd[fdIdx].cmdCompleted || readCmd[fdIdx].cmdCompleted)
return -1;
@@ -242,6 +240,6 @@ void cardReaderSetFd(int serial, int fd, char *fName)
fseek(crdFile, 0x7c7, SEEK_CUR);
fwrite(&z, 1, 1, crdFile);
fclose(crdFile);
printf("Cardfile %s created.\n", fName);
log_info("Cardfile %s created.\n", fName);
}
}
@@ -1,5 +1,6 @@
#pragma once
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <sys/types.h>
+389 -1505
View File
File diff suppressed because it is too large Load Diff
+55 -16
View File
@@ -1,5 +1,6 @@
#pragma once
#include <SDL3/SDL_keycode.h>
#include <stdint.h>
#include <sys/types.h>
@@ -18,7 +19,7 @@
#define HUMMER 0x4e6d5c64 // DVP-0057B
#define HUMMER_SDLX 0xf3778f44 // DVP-0057
#define HUMMER_EXTREME 0x7129c32b // DVP-0079
#define HUMMER_EXTREME_MDX 0xfeaf8484 // DVP-0084
#define HUMMER_EXTREME_MDX 0xfeaf8484 // DVP-0083
#define INITIALD_4_REVA 0x361d1cbe // DVP-0019A
#define INITIALD_4_REVB 0x606914be // DVP-0019B
#define INITIALD_4_REVC 0x50f1c269 // DVP-0019C
@@ -28,6 +29,7 @@
#define INITIALD_4_EXP_REVC 0x65ea22e3 // DVP-0030C
#define INITIALD_4_EXP_REVD 0x62cc73a9 // DVP-0030D
#define INITIALD_5_JAP_REVA 0xb3183112 // DVP-0070A
#define INITIALD_5_JAP_REVC 0xda04e5e0 // DVP-0070C
#define INITIALD_5_JAP_REVF 0xfc3dc85d // DVP-0070F
#define INITIALD_5_EXP 0x701b88cf // DVP-0075
#define INITIALD_5_EXP_20 0x77c6b58b // DVP-0084
@@ -43,8 +45,10 @@
#define OUTRUN_2_SP_SDX_REVA_TEST2 0x4ee20716 // DVP-0015A
#define OUTRUN_2_SP_SDX_TEST 0xf1c89eae // DVP-0015
#define PRIMEVAL_HUNT 0x6868215c // DVP-0048A
#define QUIZ_AXA 0x434dee4 // DVP-0025H
#define QUIZ_AXA_LIVE 0x7103fafc // DVP-0087D
#define RAMBO 0x48f49dd // DVP-0069
#define RAMBO_CHINA 0x0025 // DVP-????
#define RAMBO_CHINA 0xad864fec // DVP-0078
#define R_TUNED 0xa68d053d // DVP-0060
#define SEGABOOT 0x0027 // DVP-????
#define SEGABOOT_2_4 0x38d56318 // DVP-????
@@ -112,12 +116,31 @@ typedef enum
{
SHOOTING,
DRIVING,
HARLEY,
FIGHTING,
DIGITAL,
ABC,
MAHJONG
} GameType;
typedef enum
{
GROUP_ABC,
GROUP_HOD4,
GROUP_HOD4_TEST,
GROUP_HOD4_SP,
GROUP_HOD4_SP_TEST,
GROUP_HUMMER,
GROUP_ID4_EXP,
GROUP_ID4_JAP,
GROUP_ID5,
GROUP_LGJ,
GROUP_OUTRUN,
GROUP_OUTRUN_TEST,
GROUP_RAMBO,
GROUP_VF5,
GROUP_VT3,
GROUP_VT3_TEST
} GameGroup;
typedef enum
{
AUTO_DETECT_GPU,
@@ -224,7 +247,7 @@ typedef struct
int emulateRideboard;
int emulateDriveboard;
int emulateMotionboard;
int emulateCardreader;
int emulateHW210CardReader;
int emulateTouchscreen;
char cardFile1[MAX_PATH_LENGTH];
char cardFile2[MAX_PATH_LENGTH];
@@ -242,6 +265,7 @@ typedef struct
Colour lindberghColour;
GameStatus gameStatus;
GameType gameType;
GameGroup gameGroup;
KeyMapping keymap;
uint32_t crc32;
GameRegion region;
@@ -249,6 +273,7 @@ typedef struct
int showDebugMessages;
char *gameID;
char *gameTitle;
char *gameShortTitle;
char *gameDVP;
Colour gameLindberghColour;
char *gameReleaseYear;
@@ -263,40 +288,54 @@ typedef struct
int fpsLimiter;
float fpsTarget;
int lgjRenderWithMesa;
int noSDL;
int phMode;
int ramboGunsSwitch;
int id5ChineseLanguage;
float idSteeringPercentageReduction;
int phScreenMode;
int phTestScreenSingle;
int disableBuiltinFont;
int disableBuiltinLogos;
int hideCursor;
int customCursorEnabled;
char customCursor[MAX_PATH_LENGTH];
int customCursorWidth;
int customCursorHeight;
char phTouchCursor[MAX_PATH_LENGTH];
int phTouchCursorWidth;
int phTouchCursorHeight;
char touchCursor[MAX_PATH_LENGTH];
int touchCursorWidth;
int touchCursorHeight;
int mj4EnabledAtT;
int enableNetworkPatches;
char idIpSeat1[16];
char idIpSeat2[16];
char nicName[20];
char or2IP[16];
char or2Netmask[16];
char IpCab1[16];
char IpCab2[16];
char IpCab3[16];
char IpCab4[16];
char tooSpicyIpCab1[16];
char tooSpicyIpCab2[16];
char srtvIP[16];
float cpuFreqGhz;
ArcadeInputs arcadeInputs;
int inputMode; // 0 = both, 1 = SDL/X11 only, 2 = EVDEV only
int inputMode; // 0 = both, 1 = SDL, 2 = EVDEV only
int skipOutrunCabinetCheck;
float whiteBorderPercentage;
float blackBorderPercentage;
int borderEnabled;
} EmulatorConfig;
uint32_t get_crc32(const char *s, ssize_t n);
KeyMapping getDefaultKeymap();
int initConfig(const char* configFilePath);
void setDefaultValues(EmulatorConfig *cfg);
EmulatorConfig *getConfig();
char *getGameName();
char *getDVPName();
char *getGameID();
char *getDvpName();
char *getGameId();
int getGameLindberghColour();
char *getGameReleaseYear();
char *getGameNativeResolutions();
const char *getLindberghColourString(Colour lindberghColour);
const char *getGameRegionString(GameRegion region);
const char *getGpuTypeString(GpuType gpuType);
extern SDL_Keycode getSDLKeycode(const char *input);
+198
View File
@@ -0,0 +1,198 @@
#include "configIni.h"
#include "config.h"
#include "log.h"
#include <stdio.h>
void createDefaultIni(const char *filePath)
{
FILE *file = fopen(filePath, "w");
if (!file)
{
log_error("Could not create default INI file at %s", filePath);
return;
}
EmulatorConfig defaults;
setDefaultValues(&defaults);
fprintf(file, "# SEGA Lindbergh Emulator Configuration File\n");
fprintf(file, "# By the Lindbergh Development Team 2024-2025\n\n");
// [Display]
fprintf(file, "[Display]\n");
fprintf(file, "# Set the width resolution here\nWIDTH = AUTO\n\n");
fprintf(file, "# Set the height resolution here\nHEIGHT = AUTO\n\n");
fprintf(file, "# Boost render resolution in HOD4/2Spicy/Harley/Rambo/HOD-EX/ID4/ID5 and LGJ\n");
fprintf(file, "BOOST_RENDER_RES = %s\n\n", defaults.boostRenderRes ? "true" : "false");
fprintf(file, "# Set to true for full screen\nFULLSCREEN = %s\n\n", defaults.fullscreen ? "true" : "false");
fprintf(file, "# Set to true if you\'d like to add a border for optical light gun tracking\n");
fprintf(file, "BORDER_ENABLED = %s\n\n", defaults.borderEnabled ? "true" : "false");
fprintf(file, "# Set the thickness of the white border as a percentage of the width of the screen\n");
fprintf(file, "WHITE_BORDER_PERCENTAGE = %.0f\n\n", defaults.whiteBorderPercentage * 100);
fprintf(file, "# Set the thickness of the black border which sits around the\n");
fprintf(file, "# white border as a percentage of the width of the screen\n");
fprintf(file, "BLACK_BORDER_PERCENTAGE = %.0f\n\n", defaults.blackBorderPercentage * 100);
fprintf(file, "# Set to keep the aspect ratio in games like Sega Race TV Primeval Hunt and LGJ-SP\n");
fprintf(file, "KEEP_ASPECT_RATIO = %s\n\n", defaults.keepAspectRatio ? "true" : "false");
fprintf(file, "# Set to true to enable the mouse pointer/Cursor\nHIDE_CURSOR = %s\n\n", defaults.hideCursor ? "true" : "false");
// [Input]
fprintf(file, "[Input]\n");
fprintf(file, "# Sets the Input Mode (1: SDL, 2: EVDEV\n");
fprintf(file, "INPUT_MODE = %d\n\n", defaults.inputMode);
// [Emulation]
fprintf(file, "[Emulation]\n");
fprintf(file, "# Set the Region (JP/US/EX)\nREGION = EX\n\n");
fprintf(file, "# Set to true for Free Play, none to leave as default\nFREEPLAY = none\n\n");
fprintf(file, "# Set to true to emulate JVS and use the keyboard/mouse for controls.\n");
fprintf(file, "# If this is set to false, the loader will route the traffic to the serial device\n");
fprintf(file, "# defined in JVS_PATH if it has been defined.\nEMULATE_JVS = %s\n\n", defaults.emulateJVS ? "true" : "false");
fprintf(file, "# Set to true to emulate the rideboard used in the SPECIAL games\n");
fprintf(file, "# If this is set to false, then the emulator will route the traffic to one of the serial ports\n");
fprintf(file, "EMULATE_RIDEBOARD = AUTO\n\n");
fprintf(file, "# Set to true to emulate the driveboard used in driving games\n");
fprintf(file, "# If this is set to false, then the emulator will route the traffic to one of the serial ports\n");
fprintf(file, "EMULATE_DRIVEBOARD = AUTO\n\n");
fprintf(file, "# Set to true to emulate the motion board from Outrun 2 SP SDX\n");
fprintf(file, "# If this is set to false, then the emulator will route the traffic to one of the serial ports\n");
fprintf(file, "EMULATE_MOTIONBOARD = AUTO\n\n");
fprintf(file, "# Set to true to enable card reader emulation in Virtua Tennis 3 or R-Tuned\nEMULATE_HW210_CARDREADER = AUTO\n\n");
fprintf(file, "# Set to true to enable touchscreen emulation with the mouse\nEMULATE_TOUCHSCREEN = AUTO\n\n");
// [Cards]
fprintf(file, "[Cards]\n");
fprintf(file, "# Card File for reader 1 in VT3 or R-Tuned\nCARDFILE_01 = \"%s\"\n\n", defaults.cardFile1);
fprintf(file, "# Card File for reader 2 in VT3 or R-Tuned\nCARDFILE_02 = \"%s\"\n\n", defaults.cardFile2);
// [Paths]
fprintf(file, "[Paths]\n");
fprintf(file, "# Define the path to pass the JVS packets to if JVS is not being emulated\nJVS_PATH = \"%s\"\n\n", defaults.jvsPath);
fprintf(file, "# Define the path to pass the first serial port to\nSERIAL_1_PATH = \"%s\"\n\n", defaults.serial1Path);
fprintf(file, "# Define the path to pass the second serial port to\nSERIAL_2_PATH = \"%s\"\n\n", defaults.serial2Path);
fprintf(file, "# Define the path to the sram.bin file\nSRAM_PATH = \"%s\"\n\n", defaults.sramPath);
fprintf(file, "# Define the path to the eeprom.bin file\nEEPROM_PATH = \"%s\"\n\n", defaults.eepromPath);
fprintf(file, "# If set, libCG.so needed for 2Spicy, Harley, Rambo and HOD-Ex shader recompilation\n");
fprintf(file, "# will be loaded from the specified location. (include the name of file in the location ");
fprintf(file, "For Example: /my/file/location/myLibCg.so)\nLIBCG_PATH = \"%s\"\n\n", defaults.libCgPath);
// [Graphics]
fprintf(file, "[Graphics]\n");
fprintf(file, "# Set the GPU vendor (0 = Autodetect / 1 = NVidia / 2 = AMD / 3 = ATI / 4 = Intel)\n");
fprintf(file, "GPU_VENDOR = %d\n\n", defaults.GPUVendor);
fprintf(file, "# Set to true if you experience flickering in hummer\n");
fprintf(file, "HUMMER_FLICKER_FIX = %s\n\n", defaults.hummerFlickerFix ? "true" : "false");
fprintf(file, "# Set to false if you don't want to limit the FPS\n");
fprintf(file, "FPS_LIMITER_ENABLED = %s\n\n", defaults.fpsLimiter ? "true" : "false");
fprintf(file, "# Set the target FPS (will only work if FPS_LIMITER_ENABLED = 1)\nFPS_TARGET = %.1f\n\n", defaults.fpsTarget);
fprintf(file, "# Set to true if you want to render LGJ using the mesa patches\n");
fprintf(file, "LGJ_RENDER_WITH_MESA = %s\n\n", defaults.lgjRenderWithMesa ? "true" : "false");
fprintf(file, "# Disable to use the original fonts instead of the built in font\n");
fprintf(file, "DISABLE_BUILTIN_FONT = %s\n\n", defaults.disableBuiltinFont ? "true" : "false");
fprintf(file, "# Disable to use the original logos instead of the built in logos\n");
fprintf(file, "DISABLE_BUILTIN_LOGOS = %s\n\n", defaults.disableBuiltinLogos ? "true" : "false");
// [Cursor]
fprintf(file, "[Cursor]\n");
fprintf(file, "# If true, a custom mouse cursor will be used loaded from a png file set in CUSTOM_CURSOR\n");
fprintf(file, "# Ovewrites HIDE_CURSOR\n");
fprintf(file, "CUSTOM_CURSOR_ENABLED = %s\n\n", defaults.customCursorEnabled ? "true" : "false");
fprintf(file, "# Set the custom mouse pointer from a PNG file (Usefull for shooting games)\n");
fprintf(file, "CUSTOM_CURSOR = \"%s\"\n\n", defaults.customCursor);
fprintf(file, "# Set the width of the custom cursor\nCUSTOM_CURSOR_WIDTH = %d\n\n", defaults.customCursorWidth);
fprintf(file, "# Set the height of the custom cursor\nCUSTOM_CURSOR_HEIGHT = %d\n\n", defaults.customCursorHeight);
fprintf(file, "# Set a custom cursor for the touch screen in Primeval Hunt\n");
fprintf(file, "TOUCH_CURSOR = \"%s\"\n\n", defaults.touchCursor);
fprintf(file, "# Set the width of the custom cursor\nTOUCH_CURSOR_WIDTH = %d\n\n", defaults.touchCursorWidth);
fprintf(file, "# Set the height of the custom cursor\nTOUCH_CURSOR_HEIGHT = %d\n\n", defaults.touchCursorHeight);
// [GameSpecific]
fprintf(file, "[GameSpecific]\n");
fprintf(file, "# Set Primeval Hunt\n# Mode 0: Default (side by side)\n# Mode 1: No Touch screen\n# Mode 2: Side By Side\n");
fprintf(file, "# Mode 3: 3ds mode 1 (Touch screen to the right)\n# Mode 4: 3ds mode 2 (Touch screen to the bottom)\n");
fprintf(file, "PRIMEVAL_HUNT_SCREEN_MODE = %d\n\n", defaults.phScreenMode);
fprintf(file, "# Set Primeval Hunt Test mode screen to single screen\n");
fprintf(file, "PRIMEVAL_HUNT_TEST_SCREEN_SINGLE = %s\n\n", defaults.phTestScreenSingle ? "true" : "false");
fprintf(file, "# Set to true to bypass cabinet checks including drive board and tower in Outrun 2 SP SDX\n");
fprintf(file, "SKIP_OUTRUN_CABINET_CHECK = %s\n\n", defaults.skipOutrunCabinetCheck ? "true" : "false");
fprintf(file, "# Set to false if you want to disable the Glare effect in OutRun\n");
fprintf(file, "OUTRUN_LENS_GLARE_ENABLED = %s\n\n", defaults.outrunLensGlareEnabled ? "true" : "false");
fprintf(file, "# Hacky way to make MJ4 and AxA work at prohibited times\nMJ4_ENABLED_ALL_THE_TIME = %s\n\n",
defaults.mj4EnabledAtT ? "true" : "false");
fprintf(file, "# House of the dead 4 speed fix, set the frequency of your CPU in Ghz\nCPU_FREQ_GHZ = %.1f\n\n", defaults.cpuFreqGhz);
fprintf(file, "# Set to true if you want to chnge the way the guns are show in Rambo\n");
fprintf(file, "RAMBO_GUNS_SWITCH = false\n\n");
fprintf(file, "# Set to true to set the language in Chinese for ID5 DVP-0084 and DVP-0084A\n");
fprintf(file, "ID5_CHINESE_LANGUAGE = %s\n\n", defaults.id5ChineseLanguage ? "true" : "false");
fprintf(file, "# Set the percentage of the steering wheel travel reduction\n");
fprintf(file, "ID_STEERING_REDUCTION_PERCENTAGE = %.1f\n\n", defaults.idSteeringPercentageReduction);
// [System]
fprintf(file, "[System]\n");
fprintf(file, "# Set to true to see debug messages in the console\n");
fprintf(file, "DEBUG_MSGS = %s\n\n", defaults.showDebugMessages ? "true" : "false");
fprintf(file, "# Set the colour of the lindbergh (YELLOW, RED, BLUE, SILVER, REDEX)\nLINDBERGH_COLOUR = YELLOW\n\n");
// [Network]
fprintf(file, "[Network]\n");
fprintf(file, "# If true, the loader will apply the following network patches depending on the game\n");
fprintf(file, "ENABLE_NETWORK_PATCHES = %s\n\n", defaults.enableNetworkPatches ? "true" : "false");
fprintf(file, "# Sets the name of the Network Interface Card\nNIC_NAME = \"enp0s1\"\n\n");
fprintf(file, "# ID4 and ID5 network configuration per seat\nID_IP_SEAT_1 = \"192.168.1.2\"\nID_IP_SEAT_2 = \"192.168.1.3\"\n\n");
fprintf(file, "# Sets the IP address and Netmask for Outrun link (you have to put your NIC ip)\n");
fprintf(file, "OR2_IPADDRESS = \"192.168.1.2\"\nOR2_NETMASK = \"255.255.255.0\"\n\n");
fprintf(file, "# Harley / Hummer and R-Tuned IP address for each Cabinet\n");
fprintf(file, "IP_CAB1 = \"192.168.1.2\"\nIP_CAB2 = \"192.168.1.3\"\nIP_CAB3 = \"192.168.1.4\"\nIP_CAB4 = \"192.168.1.5\"\n\n");
fprintf(file, "# Sets the IP address of each cabinet for network play in 2Spicy\n");
fprintf(file, "2SPICY_IP_CAB1 = \"192.168.1.2\"\n2SPICY_IP_CAB2 = \"192.168.1.3\"\n\n");
fprintf(file, "# Sets the IP address for SRTV\nSRTV_IPADDRESS = \"192.168.1.2\"\n\n");
// [EVDEV]
fprintf(file, "[EVDEV]\n");
fprintf(file, "# EVDEV MODE (Input Mode 2)\n# To find the value pairs for these run ./lindbergh --list-controllers\n\n");
fprintf(file, "#TEST_BUTTON = \"AT_TRANSLATED_SET_2_KEYBOARD_KEY_T\"\n\n");
fprintf(file, "#PLAYER_1_COIN = \"AT_TRANSLATED_SET_2_KEYBOARD_KEY_5\"\n");
fprintf(file, "#PLAYER_1_BUTTON_START = \"AT_TRANSLATED_SET_2_KEYBOARD_KEY_1\n");
fprintf(file, "#PLAYER_1_BUTTON_SERVICE = \"AT_TRANSLATED_SET_2_KEYBOARD_KEY_S\"\n");
fprintf(file, "#PLAYER_1_BUTTON_UP = \"AT_TRANSLATED_SET_2_KEYBOARD_KEY_UP\"\n");
fprintf(file, "#PLAYER_1_BUTTON_DOWN = \"AT_TRANSLATED_SET_2_KEYBOARD_KEY_DOWN\"\n");
fprintf(file, "#PLAYER_1_BUTTON_LEFT = \"AT_TRANSLATED_SET_2_KEYBOARD_KEY_LEFT\"\n");
fprintf(file, "#PLAYER_1_BUTTON_RIGHT = \"AT_TRANSLATED_SET_2_KEYBOARD_KEY_RIGHT\"\n");
fprintf(file, "#PLAYER_1_BUTTON_1 = \"AT_TRANSLATED_SET_2_KEYBOARD_KEY_Q\"\n");
fprintf(file, "#PLAYER_1_BUTTON_2 = \"AT_TRANSLATED_SET_2_KEYBOARD_KEY_W\"\n");
fprintf(file, "#PLAYER_1_BUTTON_3 = \"AT_TRANSLATED_SET_2_KEYBOARD_KEY_E\"\n");
fprintf(file, "#PLAYER_1_BUTTON_4 = \"AT_TRANSLATED_SET_2_KEYBOARD_KEY_R\"\n");
fprintf(file, "#PLAYER_1_BUTTON_5 = \"AT_TRANSLATED_SET_2_KEYBOARD_KEY_Y\"\n");
fprintf(file, "#PLAYER_1_BUTTON_6 = \"AT_TRANSLATED_SET_2_KEYBOARD_KEY_U\"\n");
fprintf(file, "#PLAYER_1_BUTTON_7 = \"AT_TRANSLATED_SET_2_KEYBOARD_KEY_I\"\n");
fprintf(file, "#PLAYER_1_BUTTON_8 = \"AT_TRANSLATED_SET_2_KEYBOARD_KEY_O\"\n\n");
fprintf(file, "#PLAYER_1_COIN = \"AT_TRANSLATED_SET_2_KEYBOARD_KEY_6\"\n");
fprintf(file, "#PLAYER_2_BUTTON_START = \"AT_TRANSLATED_SET_2_KEYBOARD_KEY_1\"\n");
fprintf(file, "#PLAYER_2_BUTTON_SERVICE = \"AT_TRANSLATED_SET_2_KEYBOARD_KEY_S\"\n");
fprintf(file, "#PLAYER_2_BUTTON_UP = \"AT_TRANSLATED_SET_2_KEYBOARD_KEY_UP\"\n");
fprintf(file, "#PLAYER_2_BUTTON_DOWN = \"AT_TRANSLATED_SET_2_KEYBOARD_KEY_DOWN\"\n");
fprintf(file, "#PLAYER_2_BUTTON_LEFT = \"AT_TRANSLATED_SET_2_KEYBOARD_KEY_LEFT\"\n");
fprintf(file, "#PLAYER_2_BUTTON_RIGHT = \"AT_TRANSLATED_SET_2_KEYBOARD_KEY_RIGHT\"\n");
fprintf(file, "#PLAYER_2_BUTTON_1 = \"AT_TRANSLATED_SET_2_KEYBOARD_KEY_Q\"\n");
fprintf(file, "#PLAYER_2_BUTTON_2 = \"AT_TRANSLATED_SET_2_KEYBOARD_KEY_W\"\n");
fprintf(file, "#PLAYER_2_BUTTON_3 = \"AT_TRANSLATED_SET_2_KEYBOARD_KEY_E\"\n");
fprintf(file, "#PLAYER_2_BUTTON_4 = \"AT_TRANSLATED_SET_2_KEYBOARD_KEY_R\"\n");
fprintf(file, "#PLAYER_2_BUTTON_5 = \"AT_TRANSLATED_SET_2_KEYBOARD_KEY_Y\"\n");
fprintf(file, "#PLAYER_2_BUTTON_6 = \"AT_TRANSLATED_SET_2_KEYBOARD_KEY_U\"\n");
fprintf(file, "#PLAYER_2_BUTTON_7 = \"AT_TRANSLATED_SET_2_KEYBOARD_KEY_I\"\n");
fprintf(file, "#PLAYER_2_BUTTON_8 = \"AT_TRANSLATED_SET_2_KEYBOARD_KEY_O\"\n\n");
fprintf(file, "#ANALOGUE_1 = \"SYNPS_2_SYNAPTICS_TOUCHPAD_ABS_X\"\n");
fprintf(file, "#ANALOGUE_2 = \"SYNPS_2_SYNAPTICS_TOUCHPAD_ABS_Y\"\n");
fprintf(file, "#ANALOGUE_3 = \"SYNPS_2_SYNAPTICS_TOUCHPAD_ABS_Z\"\n");
fprintf(file, "#ANALOGUE_4 = \"SYNPS_2_SYNAPTICS_TOUCHPAD_ABS_RZ\"\n");
fprintf(file, "#ANALOGUE_5 = \"SYNPS_2_SYNAPTICS_TOUCHPAD_ABS_X2\"\n");
fprintf(file, "#ANALOGUE_6 = \"SYNPS_2_SYNAPTICS_TOUCHPAD_ABS_Y2\"\n");
fprintf(file, "#ANALOGUE_7 = \"SYNPS_2_SYNAPTICS_TOUCHPAD_ABS_Z2\"\n");
fprintf(file, "#ANALOGUE_8 = \"SYNPS_2_SYNAPTICS_TOUCHPAD_ABS_RZ2\"\n\n");
for (int x = 1; x < 9; x++)
fprintf(file, "#ANALOGUE_DEADZONE_%d = 0 0 0\n", x);
fprintf(file, "\n");
fclose(file);
}
+6
View File
@@ -0,0 +1,6 @@
#ifndef CONFIG_INI_H
#define CONFIG_INI_H
void createDefaultIni(const char *filePath);
#endif // CONFIG_INI_H
-205
View File
@@ -1,205 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define CONFIG_TEMP_FILE_NAME ".lindbergh.conf.tmp"
#include "config_file.h"
char *getConfigErrorString(ConfigStatus status)
{
switch (status)
{
case CONFIG_STATUS_COMMAND_NOT_FOUND:
return "The key you looked for could not be found";
case CONFIG_STATUS_FAILURE:
return "There was a generic failure";
case CONFIG_STATUS_SUCCESS:
return "The operation was successful";
case CONFIG_STATUS_NOT_ENOUGH_ARGUMENTS:
return "The config file did not have enough arguments to complete your request";
case CONFIG_STATUS_CANNOT_OPEN_FILE:
return "The config file could not be opened";
default:
return "This config status enum doesn't have an error string associated.";
}
}
static char *getNextToken(char *buffer, char *seperator, char **saveptr)
{
char *token = strtok_r(buffer, seperator, saveptr);
if (token == NULL)
return NULL;
for (int i = 0; i < (int)strlen(token); i++)
{
if ((token[i] == '\n') || (token[i] == '\r'))
{
token[i] = 0;
}
}
return token;
}
ConfigStatus processConfig(Config *config, char *path)
{
config->path = path;
config->file = fopen(config->path, "r");
config->configPairIndex = 0;
if (config->file == NULL)
{
return CONFIG_STATUS_CANNOT_OPEN_FILE;
}
char buffer[CONFIG_MAX_LINE_LENGTH];
char *saveptr = NULL;
while (fgets(buffer, CONFIG_MAX_LINE_LENGTH, config->file))
{
// Ignore any lines that start with a comment
if (buffer[0] == '#' || buffer[0] == 0 || buffer[0] == ' ' || buffer[0] == '\r' || buffer[0] == '\n')
continue;
ConfigPair *configPair = &config->configPairs[config->configPairIndex];
strcpy(configPair->command, getNextToken(buffer, " ", &saveptr));
configPair->argumentIndex = 0;
char *argument = getNextToken(NULL, " ", &saveptr);
while (argument != NULL && argument[0] != 0)
{
strcpy(configPair->argument[configPair->argumentIndex++], argument);
argument = getNextToken(NULL, " ", &saveptr);
}
config->configPairIndex++;
}
fclose(config->file);
return CONFIG_STATUS_SUCCESS;
}
ConfigStatus getConfigArgumentString(Config *config, char *key, int n, char *value)
{
for (int i = 0; i < config->configPairIndex; i++)
{
if (strcmp(config->configPairs[i].command, key) == 0)
{
if (n >= config->configPairs[i].argumentIndex)
return CONFIG_STATUS_NOT_ENOUGH_ARGUMENTS;
strcpy(value, config->configPairs[i].argument[n]);
return CONFIG_STATUS_SUCCESS;
}
}
return CONFIG_STATUS_COMMAND_NOT_FOUND;
}
ConfigStatus getConfigArgumentInt(Config *config, char *key, int n, int *value)
{
for (int i = 0; i < config->configPairIndex; i++)
{
if (strcmp(config->configPairs[i].command, key) == 0)
{
if (n >= config->configPairs[i].argumentIndex)
return CONFIG_STATUS_NOT_ENOUGH_ARGUMENTS;
*value = atoi(config->configPairs[i].argument[i]);
return CONFIG_STATUS_SUCCESS;
}
}
return CONFIG_STATUS_COMMAND_NOT_FOUND;
}
ConfigStatus getConfigString(Config *config, char *key, char *value)
{
return getConfigArgumentString(config, key, 0, value);
}
ConfigStatus getConfigInt(Config *config, char *key, int *value)
{
return getConfigArgumentInt(config, key, 0, value);
}
ConfigStatus writeConfigString(Config *config, char *key, char *value)
{
config->file = fopen(config->path, "r");
if (config->file == NULL)
{
return CONFIG_STATUS_FAILURE;
}
FILE *tempFile = fopen(CONFIG_TEMP_FILE_NAME, "w");
if (tempFile == NULL)
{
return CONFIG_STATUS_FAILURE;
}
char buffer[CONFIG_MAX_LINE_LENGTH];
char *saveptr = NULL;
char inspectionBuffer[CONFIG_MAX_LINE_LENGTH];
char writeBuffer[CONFIG_MAX_LINE_LENGTH];
strcpy(writeBuffer, key);
strcat(writeBuffer, " ");
strcat(writeBuffer, value);
strcat(writeBuffer, "\n");
int lineWasReplaced = 0;
while (fgets(buffer, CONFIG_MAX_LINE_LENGTH, config->file))
{
strcpy(inspectionBuffer, buffer);
char *token = getNextToken(inspectionBuffer, " ", &saveptr);
if (strcmp(token, key) == 0)
{
lineWasReplaced = 1;
// If there is no value just delete the line
if (strcmp(value, "") == 0)
continue;
fputs(writeBuffer, tempFile);
continue;
}
fputs(buffer, tempFile);
}
// If the file doesn't end with a new line, write one.
if (buffer[strlen(buffer) - 1] != '\n')
fputs("\n", tempFile);
// If no line was replaced add it in at the end
if (!lineWasReplaced)
fputs(writeBuffer, tempFile);
fclose(config->file);
fclose(tempFile);
// Now re-write the old file with the new temp file name
remove(config->path);
rename(CONFIG_TEMP_FILE_NAME, config->path);
return processConfig(config, config->path);
}
ConfigStatus writeConfigInt(Config *config, char *key, int value)
{
char stringValue[CONFIG_MAX_LINE_LENGTH];
sprintf(stringValue, "%d", value);
return writeConfigString(config, key, stringValue);
}
ConfigStatus deleteConfig(Config *config, char *key)
{
return writeConfigString(config, key, "");
}
-45
View File
@@ -1,45 +0,0 @@
#include <stdlib.h>
#define CONFIG_MAX_LINE_LENGTH 2048
#define MAX_ARGUMENT_AMOUNT 4
#define MAX_CONFIG_LINES 100
typedef enum
{
CONFIG_STATUS_SUCCESS,
CONFIG_STATUS_FAILURE,
CONFIG_STATUS_COMMAND_NOT_FOUND,
CONFIG_STATUS_NOT_ENOUGH_ARGUMENTS,
CONFIG_STATUS_CANNOT_OPEN_FILE
} ConfigStatus;
typedef struct {
char command[CONFIG_MAX_LINE_LENGTH];
char argument[MAX_ARGUMENT_AMOUNT][CONFIG_MAX_LINE_LENGTH];
int argumentIndex;
} ConfigPair;
typedef struct
{
FILE *file;
char* path;
int configPairIndex;
ConfigPair configPairs[MAX_CONFIG_LINES];
} Config;
char* getConfigErrorString(ConfigStatus status);
ConfigStatus processConfig(Config *config, char *path);
ConfigStatus getConfigString(Config *config, char* key, char* value);
ConfigStatus getConfigArgumentString(Config *config, char* key, int n, char* value);
ConfigStatus getConfigInt(Config *config, char* key, int* value);
ConfigStatus getConfigArgumentInt(Config *config, char* key, int n, int* value);
ConfigStatus writeConfigString(Config *config, char* key, char* value);
ConfigStatus writeConfigInt(Config *config, char* key, int value);
ConfigStatus deleteConfig(Config *config, char* key);
+397
View File
@@ -0,0 +1,397 @@
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include "controlIniGen.h"
#include "iniParser.h"
#include "sdlInput.h"
const ControlBinding gDefaultCommonBindings[] = {
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_T, AXIS_MODE_DIGITAL, 0, false, SYSTEM, LA_Test},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_5, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Coin},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_6, AXIS_MODE_DIGITAL, 0, false, PLAYER_2, LA_Coin},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_1, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Start},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_2, AXIS_MODE_DIGITAL, 0, false, PLAYER_2, LA_Start},
{INPUT_TYPE_JOY_BUTTON, 0, 11, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Start},
{INPUT_TYPE_GAMEPAD_BUTTON, 0, SDL_GAMEPAD_BUTTON_START, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Start},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_S, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Service},
{INPUT_TYPE_JOY_BUTTON, 0, 10, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Service},
{INPUT_TYPE_GAMEPAD_BUTTON, 0, SDL_GAMEPAD_BUTTON_BACK, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Service},
};
const size_t gDefaultCommonBindingsSize = sizeof(gDefaultCommonBindings) / sizeof(gDefaultCommonBindings[0]);
const ControlBinding gDefaultDigitalBindings[] = {
// Keyboard
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_UP, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Up},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_DOWN, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Down},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_LEFT, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Left},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_RIGHT, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Right},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_Q, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Button1},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_W, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Button2},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_E, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Button3},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_F7, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Card1Insert},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_F8, AXIS_MODE_DIGITAL, 0, false, PLAYER_2, LA_Card2Insert},
// Controller
{INPUT_TYPE_GAMEPAD_BUTTON, 0, SDL_GAMEPAD_BUTTON_DPAD_UP, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Up},
{INPUT_TYPE_GAMEPAD_BUTTON, 0, SDL_GAMEPAD_BUTTON_DPAD_DOWN, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Down},
{INPUT_TYPE_GAMEPAD_BUTTON, 0, SDL_GAMEPAD_BUTTON_DPAD_LEFT, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Left},
{INPUT_TYPE_GAMEPAD_BUTTON, 0, SDL_GAMEPAD_BUTTON_DPAD_RIGHT, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Right},
{INPUT_TYPE_GAMEPAD_BUTTON, 0, SDL_GAMEPAD_BUTTON_SOUTH, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Button1},
{INPUT_TYPE_GAMEPAD_BUTTON, 0, SDL_GAMEPAD_BUTTON_EAST, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Button2},
{INPUT_TYPE_GAMEPAD_BUTTON, 0, SDL_GAMEPAD_BUTTON_WEST, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Button3},
{INPUT_TYPE_GAMEPAD_AXIS, 0, SDL_GAMEPAD_AXIS_LEFTY, AXIS_MODE_DIGITAL, -1, false, PLAYER_1, LA_Up},
{INPUT_TYPE_GAMEPAD_AXIS, 0, SDL_GAMEPAD_AXIS_LEFTY, AXIS_MODE_DIGITAL, 1, false, PLAYER_1, LA_Down},
{INPUT_TYPE_GAMEPAD_AXIS, 0, SDL_GAMEPAD_AXIS_LEFTX, AXIS_MODE_DIGITAL, 1, false, PLAYER_1, LA_Right},
{INPUT_TYPE_GAMEPAD_AXIS, 0, SDL_GAMEPAD_AXIS_LEFTX, AXIS_MODE_DIGITAL, -1, false, PLAYER_1, LA_Left},
{INPUT_TYPE_GAMEPAD_BUTTON, 0, SDL_GAMEPAD_BUTTON_GUIDE, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Card1Insert},
{INPUT_TYPE_GAMEPAD_BUTTON, 1, SDL_GAMEPAD_BUTTON_GUIDE, AXIS_MODE_DIGITAL, 0, false, PLAYER_2, LA_Card2Insert},
// Joystick
{INPUT_TYPE_JOY_HAT, 0, 0, AXIS_MODE_DIGITAL, SDL_HAT_UP, false, PLAYER_1, LA_Up},
{INPUT_TYPE_JOY_HAT, 0, 0, AXIS_MODE_DIGITAL, SDL_HAT_DOWN, false, PLAYER_1, LA_Down},
{INPUT_TYPE_JOY_HAT, 0, 0, AXIS_MODE_DIGITAL, SDL_HAT_LEFT, false, PLAYER_1, LA_Left},
{INPUT_TYPE_JOY_HAT, 0, 0, AXIS_MODE_DIGITAL, SDL_HAT_RIGHT, false, PLAYER_1, LA_Right},
{INPUT_TYPE_JOY_BUTTON, 0, 0, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Button1},
{INPUT_TYPE_JOY_BUTTON, 0, 1, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Button2},
{INPUT_TYPE_JOY_BUTTON, 0, 2, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Button3},
{INPUT_TYPE_JOY_AXIS, 0, 1, AXIS_MODE_DIGITAL, -1, false, PLAYER_1, LA_Up},
{INPUT_TYPE_JOY_AXIS, 0, 1, AXIS_MODE_DIGITAL, 1, false, PLAYER_1, LA_Down},
{INPUT_TYPE_JOY_AXIS, 0, 0, AXIS_MODE_DIGITAL, -1, false, PLAYER_1, LA_Left},
{INPUT_TYPE_JOY_AXIS, 0, 0, AXIS_MODE_DIGITAL, 1, false, PLAYER_1, LA_Right},
{INPUT_TYPE_JOY_BUTTON, 0, 11, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Card1Insert},
{INPUT_TYPE_JOY_BUTTON, 1, 11, AXIS_MODE_DIGITAL, 0, false, PLAYER_2, LA_Card2Insert},
};
const size_t gDefaultDigitalBindingsSize = sizeof(gDefaultDigitalBindings) / sizeof(gDefaultDigitalBindings[0]);
const ControlBinding gDefaultDrivingBindings[] = {
// Keyboard
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_LEFT, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Steer_Left},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_RIGHT, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Steer_Right},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_UP, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Gas_Digital},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_DOWN, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Brake_Digital},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_V, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_ViewChange},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_Q, AXIS_MODE_DIGITAL, 0, false, PLAYER_2, LA_Boost},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_W, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_BoostRight},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_A, AXIS_MODE_DIGITAL, 0, false, PLAYER_2, LA_GearUp},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_Z, AXIS_MODE_DIGITAL, 0, false, PLAYER_2, LA_GearDown},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_M, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_MusicChange},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_I, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Up},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_K, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Down},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_J, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Left},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_L, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Right},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_F7, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_CardInsert},
// Controller
{INPUT_TYPE_GAMEPAD_AXIS, 0, SDL_GAMEPAD_AXIS_LEFTX, AXIS_MODE_FULL, 0, false, PLAYER_1, LA_Steer},
{INPUT_TYPE_GAMEPAD_AXIS, 0, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER, AXIS_MODE_FULL, 0, false, PLAYER_1, LA_Gas},
{INPUT_TYPE_GAMEPAD_AXIS, 0, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, AXIS_MODE_FULL, 0, false, PLAYER_1, LA_Brake},
{INPUT_TYPE_GAMEPAD_BUTTON, 0, SDL_GAMEPAD_BUTTON_SOUTH, AXIS_MODE_DIGITAL, 0, false, PLAYER_2, LA_Boost},
{INPUT_TYPE_GAMEPAD_BUTTON, 0, SDL_GAMEPAD_BUTTON_EAST, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_BoostRight},
{INPUT_TYPE_GAMEPAD_BUTTON, 0, SDL_GAMEPAD_BUTTON_NORTH, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_ViewChange},
{INPUT_TYPE_GAMEPAD_BUTTON, 0, SDL_GAMEPAD_BUTTON_WEST, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_MusicChange},
{INPUT_TYPE_GAMEPAD_BUTTON, 0, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER, AXIS_MODE_DIGITAL, 0, false, PLAYER_2, LA_GearUp},
{INPUT_TYPE_GAMEPAD_BUTTON, 0, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER, AXIS_MODE_DIGITAL, 0, false, PLAYER_2, LA_GearDown},
{INPUT_TYPE_GAMEPAD_BUTTON, 0, SDL_GAMEPAD_BUTTON_DPAD_UP, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Up},
{INPUT_TYPE_GAMEPAD_BUTTON, 0, SDL_GAMEPAD_BUTTON_DPAD_DOWN, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Down},
{INPUT_TYPE_GAMEPAD_BUTTON, 0, SDL_GAMEPAD_BUTTON_DPAD_LEFT, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Left},
{INPUT_TYPE_GAMEPAD_BUTTON, 0, SDL_GAMEPAD_BUTTON_DPAD_RIGHT, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Right},
{INPUT_TYPE_GAMEPAD_BUTTON, 0, SDL_GAMEPAD_BUTTON_GUIDE, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_CardInsert},
// Joystick
{INPUT_TYPE_JOY_AXIS, 0, 0, AXIS_MODE_FULL, 0, false, PLAYER_1, LA_Steer},
{INPUT_TYPE_JOY_AXIS, 0, 5, AXIS_MODE_FULL, 0, false, PLAYER_1, LA_Gas},
{INPUT_TYPE_JOY_AXIS, 0, 2, AXIS_MODE_FULL, 0, false, PLAYER_1, LA_Brake},
{INPUT_TYPE_JOY_BUTTON, 0, 0, AXIS_MODE_DIGITAL, 0, false, PLAYER_2, LA_Boost},
{INPUT_TYPE_JOY_BUTTON, 0, 1, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_BoostRight},
{INPUT_TYPE_JOY_BUTTON, 0, 2, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_ViewChange},
{INPUT_TYPE_JOY_BUTTON, 0, 5, AXIS_MODE_DIGITAL, 0, false, PLAYER_2, LA_GearUp},
{INPUT_TYPE_JOY_BUTTON, 0, 4, AXIS_MODE_DIGITAL, 0, false, PLAYER_2, LA_GearDown},
{INPUT_TYPE_JOY_BUTTON, 0, 3, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_MusicChange},
{INPUT_TYPE_JOY_HAT, 0, 0, AXIS_MODE_DIGITAL, SDL_HAT_UP, false, PLAYER_1, LA_Up},
{INPUT_TYPE_JOY_HAT, 0, 0, AXIS_MODE_DIGITAL, SDL_HAT_DOWN, false, PLAYER_1, LA_Down},
{INPUT_TYPE_JOY_HAT, 0, 0, AXIS_MODE_DIGITAL, SDL_HAT_LEFT, false, PLAYER_1, LA_Left},
{INPUT_TYPE_JOY_HAT, 0, 0, AXIS_MODE_DIGITAL, SDL_HAT_RIGHT, false, PLAYER_1, LA_Right},
{INPUT_TYPE_JOY_BUTTON, 0, 12, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_CardInsert},
};
const size_t gDefaultDrivingBindingsSize = sizeof(gDefaultDrivingBindings) / sizeof(gDefaultDrivingBindings[0]);
const ControlBinding gDefaultAbcBindings[] = {
// Keyboard
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_LEFT, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_ABC_Left},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_RIGHT, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_ABC_Right},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_UP, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_ABC_Up},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_DOWN, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_ABC_Down},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_A, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Throttle_Accelerate},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_Z, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Throttle_Slowdown},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_Q, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_GunTrigger},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_W, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_MissileTrigger},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_E, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_ClimaxSwitch},
// Controller
{INPUT_TYPE_GAMEPAD_AXIS, 0, SDL_GAMEPAD_AXIS_LEFTX, AXIS_MODE_FULL, 0, false, PLAYER_1, LA_ABC_X},
{INPUT_TYPE_GAMEPAD_AXIS, 0, SDL_GAMEPAD_AXIS_LEFTY, AXIS_MODE_FULL, 0, false, PLAYER_1, LA_ABC_Y},
{INPUT_TYPE_GAMEPAD_AXIS, 0, SDL_GAMEPAD_AXIS_RIGHTY, AXIS_MODE_FULL, 0, true, PLAYER_1, LA_Throttle},
{INPUT_TYPE_GAMEPAD_AXIS, 0, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER, AXIS_MODE_POSITIVE_HALF, 0, false, PLAYER_1, LA_Throttle},
{INPUT_TYPE_GAMEPAD_AXIS, 0, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, AXIS_MODE_NEGATIVE_HALF, 0, false, PLAYER_1, LA_Throttle},
{INPUT_TYPE_GAMEPAD_BUTTON, 0, SDL_GAMEPAD_BUTTON_SOUTH, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_GunTrigger},
{INPUT_TYPE_GAMEPAD_BUTTON, 0, SDL_GAMEPAD_BUTTON_EAST, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_MissileTrigger},
{INPUT_TYPE_GAMEPAD_BUTTON, 0, SDL_GAMEPAD_BUTTON_NORTH, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_ClimaxSwitch},
// Joystick
{INPUT_TYPE_JOY_AXIS, 0, 0, AXIS_MODE_FULL, 0, false, PLAYER_1, LA_ABC_X},
{INPUT_TYPE_JOY_AXIS, 0, 1, AXIS_MODE_FULL, 0, false, PLAYER_1, LA_ABC_Y},
{INPUT_TYPE_JOY_AXIS, 0, 4, AXIS_MODE_FULL, 0, true, PLAYER_1, LA_Throttle},
{INPUT_TYPE_JOY_AXIS, 0, 5, AXIS_MODE_POSITIVE_HALF, 0, false, PLAYER_1, LA_Throttle},
{INPUT_TYPE_JOY_AXIS, 0, 4, AXIS_MODE_NEGATIVE_HALF, 0, false, PLAYER_1, LA_Throttle},
{INPUT_TYPE_JOY_BUTTON, 0, 0, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_GunTrigger},
{INPUT_TYPE_JOY_BUTTON, 0, 1, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_MissileTrigger},
{INPUT_TYPE_JOY_BUTTON, 0, 4, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_ClimaxSwitch},
};
const size_t gDefaultAbcBindingsSize = sizeof(gDefaultAbcBindings) / sizeof(gDefaultAbcBindings[0]);
const ControlBinding gDefaultShootingBindings[] = {
// Mouse / Gun
{INPUT_TYPE_MOUSE_AXIS, 0, 0, AXIS_MODE_FULL, 0, false, PLAYER_1, LA_GunX},
{INPUT_TYPE_MOUSE_AXIS, 0, 1, AXIS_MODE_FULL, 0, false, PLAYER_1, LA_GunY},
{INPUT_TYPE_MOUSE_BUTTON, 0, SDL_BUTTON_LEFT, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Trigger},
{INPUT_TYPE_MOUSE_BUTTON, 0, SDL_BUTTON_RIGHT, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Reload},
{INPUT_TYPE_MOUSE_BUTTON, 0, SDL_BUTTON_MIDDLE, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_GunButton},
// {INPUT_TYPE_MOUSE_AXIS, 0, 0, AXIS_MODE_FULL, 0, false, PLAYER_2, LA_GunX},
// {INPUT_TYPE_MOUSE_AXIS, 0, 1, AXIS_MODE_FULL, 0, false, PLAYER_2, LA_GunY},
// {INPUT_TYPE_MOUSE_BUTTON, 0, SDL_BUTTON_LEFT, AXIS_MODE_DIGITAL, 0, false, PLAYER_2, LA_Trigger},
// {INPUT_TYPE_MOUSE_BUTTON, 0, SDL_BUTTON_RIGHT, AXIS_MODE_DIGITAL, 0, false, PLAYER_2, LA_Reload},
// {INPUT_TYPE_MOUSE_BUTTON, 0, SDL_BUTTON_MIDDLE, AXIS_MODE_DIGITAL, 0, false, PLAYER_2, LA_GunButton},
// Keyboard
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_Q, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Trigger},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_W, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_Reload},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_E, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_GunButton},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_R, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_ActionButton},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_LEFT, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_PedalLeft},
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_RIGHT, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_PedalRight},
};
const size_t gDefaultShootingBindingsSize = sizeof(gDefaultShootingBindings) / sizeof(gDefaultShootingBindings[0]);
const ControlBinding gDefaultMahjongBindings[] = {
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_Y, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_A}, // A
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_U, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_B}, // B
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_I, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_C}, // C
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_O, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_D}, // D
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_G, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_E}, // E
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_H, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_F}, // F
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_J, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_G}, // G
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_K, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_H}, // H
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_L, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_I}, // I
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_V, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_J}, // J
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_B, AXIS_MODE_DIGITAL, 0, false, PLAYER_1, LA_K}, // K
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_N, AXIS_MODE_DIGITAL, 0, false, PLAYER_2, LA_L}, // L
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_M, AXIS_MODE_DIGITAL, 0, false, PLAYER_2, LA_M}, // M
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_COMMA, AXIS_MODE_DIGITAL, 0, false, PLAYER_2, LA_N}, // N
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_F1, AXIS_MODE_DIGITAL, 0, false, PLAYER_2, LA_Chi}, // CHI
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_F2, AXIS_MODE_DIGITAL, 0, false, PLAYER_2, LA_Pon}, // PON
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_F3, AXIS_MODE_DIGITAL, 0, false, PLAYER_2, LA_Kan}, // KAN
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_F4, AXIS_MODE_DIGITAL, 0, false, PLAYER_2, LA_Reach}, // REACH
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_F5, AXIS_MODE_DIGITAL, 0, false, PLAYER_2, LA_Agari}, // AGARI
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_F6, AXIS_MODE_DIGITAL, 0, false, PLAYER_2, LA_Cancel}, // CANCEL
{INPUT_TYPE_KEY, 0, SDL_SCANCODE_F7, AXIS_MODE_DIGITAL, 0, false, PLAYER_2, LA_CardInsert}, // Cards In
};
const size_t gDefaultMahjongBindingsSize = sizeof(gDefaultMahjongBindings) / sizeof(gDefaultMahjongBindings[0]);
char *toUpperCase(const char *str)
{
char *result = (char *)malloc(strlen(str) + 1);
if (result == NULL)
return NULL;
int i = 0;
while (str[i] != '\0')
{
result[i] = toupper((unsigned char)str[i]);
i++;
}
result[i] = '\0';
return result;
}
/**
* @brief Helper function to convert a ControlBinding struct back into an INI string.
* This is the reverse of parseSdlSource, used for generating a default controls.ini.
* @param binding Pointer to the ControlBinding to convert.
* @param buffer Character buffer to write the string into.
* @param buffer_size The size of the character buffer.
*/
static void getBindingString(const ControlBinding *binding, char *buffer, size_t buffer_size)
{
char temp_buffer[128] = {0};
switch (binding->type)
{
case INPUT_TYPE_KEY:
snprintf(temp_buffer, sizeof(temp_buffer), "KEY_%s", SDL_GetScancodeName(binding->sdlId));
break;
case INPUT_TYPE_MOUSE_BUTTON:
if (binding->sdlId == SDL_BUTTON_LEFT)
strcpy(temp_buffer, "MOUSE_LEFT_BUTTON");
else if (binding->sdlId == SDL_BUTTON_RIGHT)
strcpy(temp_buffer, "MOUSE_RIGHT_BUTTON");
else if (binding->sdlId == SDL_BUTTON_MIDDLE)
strcpy(temp_buffer, "MOUSE_MIDDLE_BUTTON");
else
snprintf(temp_buffer, sizeof(temp_buffer), "MOUSE_BUTTON_%d", binding->sdlId);
break;
case INPUT_TYPE_MOUSE_AXIS:
snprintf(temp_buffer, sizeof(temp_buffer), "MOUSE_AXIS_%c", binding->sdlId == 0 ? 'X' : 'Y');
break;
case INPUT_TYPE_JOY_BUTTON:
snprintf(temp_buffer, sizeof(temp_buffer), "JOY%d_BUTTON_%d", binding->deviceIndex, binding->sdlId);
break;
case INPUT_TYPE_JOY_HAT:
if (binding->axisThreshold == SDL_HAT_UP)
snprintf(temp_buffer, sizeof(temp_buffer), "JOY%d_HAT%d_UP", binding->deviceIndex, binding->sdlId);
else if (binding->axisThreshold == SDL_HAT_DOWN)
snprintf(temp_buffer, sizeof(temp_buffer), "JOY%d_HAT%d_DOWN", binding->deviceIndex, binding->sdlId);
else if (binding->axisThreshold == SDL_HAT_LEFT)
snprintf(temp_buffer, sizeof(temp_buffer), "JOY%d_HAT%d_LEFT", binding->deviceIndex, binding->sdlId);
else if (binding->axisThreshold == SDL_HAT_RIGHT)
snprintf(temp_buffer, sizeof(temp_buffer), "JOY%d_HAT%d_RIGHT", binding->deviceIndex, binding->sdlId);
break;
case INPUT_TYPE_GAMEPAD_BUTTON:
snprintf(temp_buffer, sizeof(temp_buffer), "GC%d_BUTTON_%s", binding->deviceIndex,
toUpperCase(SDL_GetGamepadStringForButton(binding->sdlId)));
break;
case INPUT_TYPE_JOY_AXIS:
case INPUT_TYPE_GAMEPAD_AXIS:
{
char prefix[64];
if (binding->type == INPUT_TYPE_JOY_AXIS)
snprintf(prefix, sizeof(prefix), "JOY%d_AXIS_%d", binding->deviceIndex, binding->sdlId);
else
snprintf(prefix, sizeof(prefix), "GC%d_AXIS_%s", binding->deviceIndex,
toUpperCase(SDL_GetGamepadStringForAxis(binding->sdlId)));
switch (binding->axisMode)
{
case AXIS_MODE_DIGITAL:
if (binding->axisThreshold > 0)
snprintf(temp_buffer, sizeof(temp_buffer), "%s_POSITIVE", prefix);
else
snprintf(temp_buffer, sizeof(temp_buffer), "%s_NEGATIVE", prefix);
break;
case AXIS_MODE_POSITIVE_HALF:
snprintf(temp_buffer, sizeof(temp_buffer), "%s_POSITIVE_HALF", prefix);
break;
case AXIS_MODE_NEGATIVE_HALF:
snprintf(temp_buffer, sizeof(temp_buffer), "%s_NEGATIVE_HALF", prefix);
break;
case AXIS_MODE_FULL:
default:
strcpy(temp_buffer, prefix);
break;
}
break;
}
default:
break;
}
if (binding->isInverted)
{
strncat(temp_buffer, "_INVERTED", sizeof(temp_buffer) - strlen(temp_buffer) - 1);
}
strncpy(buffer, temp_buffer, buffer_size);
}
/**
* @brief Helper to add a set of default bindings to an in-memory INI config.
*/
static void addBindingsToIni(IniConfig *cfg, const char *section_name, const ControlBinding *bindings, size_t count)
{
for (size_t i = 0; i < count; i++)
{
const ControlBinding *b = &bindings[i];
char action_str[128];
char binding_str[128];
getLogicalActionString(b, action_str, sizeof(action_str), section_name);
getBindingString(b, binding_str, sizeof(binding_str));
IniSection *sec = iniGetSection(cfg, section_name);
IniKeyValuePair *pair = NULL;
if (sec)
{
for (int j = 0; j < sec->numPairs; j++)
{
if (strcmp(sec->pairs[j].key, action_str) == 0)
{
pair = &sec->pairs[j];
break;
}
}
}
if (pair)
{ // Key already exists, append to it
char new_value[1024];
snprintf(new_value, sizeof(new_value), "%s, %s", pair->value, binding_str);
iniSetValue(cfg, section_name, action_str, new_value);
}
else
{ // New key, just set it
iniSetValue(cfg, section_name, action_str, binding_str);
}
}
}
/**
* @brief Generates a default controls.ini file based on the hardcoded default binding arrays.
*/
void createDefaultControlsIni(const char *fileName)
{
printf("Generating default controls.ini from built-in bindings...\n");
IniConfig *ini = calloc(1, sizeof(IniConfig));
if (!ini)
{
perror("Failed to allocate memory for INI config");
return;
}
iniSetValue(ini, "Config", "Steer_DeadZone", "8000");
iniSetValue(ini, "Config", "Gas_DeadZone", "500");
iniSetValue(ini, "Config", "Brake_DeadZone", "500");
iniSetValue(ini, "Config", "ABC_X_DeadZone", "8000");
iniSetValue(ini, "Config", "ABC_Y_DeadZone", "8000");
iniSetValue(ini, "Config", "Throttle_DeadZone", "8000");
iniSetValue(ini, "Config", "ShakeIncreaseRate", "10.0");
iniSetValue(ini, "Config", "ShakeDecayRate", "0.95");
addBindingsToIni(ini, "Common", gDefaultCommonBindings, gDefaultCommonBindingsSize);
addBindingsToIni(ini, "Digital", gDefaultDigitalBindings, gDefaultDigitalBindingsSize);
addBindingsToIni(ini, "Driving", gDefaultDrivingBindings, gDefaultDrivingBindingsSize);
addBindingsToIni(ini, "ABC", gDefaultAbcBindings, gDefaultAbcBindingsSize);
addBindingsToIni(ini, "Shooting", gDefaultShootingBindings, gDefaultShootingBindingsSize);
addBindingsToIni(ini, "Mahjong", gDefaultMahjongBindings, gDefaultMahjongBindingsSize);
if (iniSave(ini, fileName) == 0)
{
printf("Default %s has been created successfully.\n", fileName);
}
else
{
fprintf(stderr, "ERROR: Failed to create %s.\n", fileName);
}
iniFree(ini);
}
+8
View File
@@ -0,0 +1,8 @@
#pragma once
/**
* @brief Generates a default controls.ini file based on the hardcoded default binding arrays.
* This ensures the generated INI is always in sync with the application's default behavior.
* @param fileName The name of the file to create (e.g., "controls.ini").
*/
void createDefaultControlsIni(const char *fileName);
+171
View File
@@ -0,0 +1,171 @@
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <dlfcn.h>
#include <stdbool.h>
#include <SDL3/SDL.h>
#include <SDL3_image/SDL_image.h>
#include <SDL3/SDL_surface.h>
#include <stdlib.h>
#include <time.h>
#include <X11/Xlib.h>
#include "config.h"
#include "customCursor.h"
extern uint32_t gId;
SDL_Cursor *customCursor = NULL;
SDL_Cursor *touchCursor = NULL;
uint32_t hod4PrevValue;
bool hod4InTutorial = false;
void (*CPlayer_MainOri)(int);
int loadNewCursor(const char *cursorFileName, SDL_Cursor **cursor, int customWidth, int customHeight, int hotX, int hotY)
{
SDL_Surface *originalSurface = IMG_Load(cursorFileName);
if (!originalSurface)
{
fprintf(stderr, "Failed to load image %s: %s\n", cursorFileName, SDL_GetError());
return 0;
}
SDL_Surface *scaledSurface = SDL_ScaleSurface(originalSurface, customWidth, customHeight, SDL_SCALEMODE_NEAREST);
SDL_DestroySurface(originalSurface);
if (!scaledSurface)
{
fprintf(stderr, "SDL_ScaleSurface Error: %s\n", SDL_GetError());
return 0;
}
*cursor = SDL_CreateColorCursor(scaledSurface, hotX, hotY);
if (!*cursor)
{
fprintf(stderr, "SDL_CreateColorCursor Error: %s\n", SDL_GetError());
}
SDL_DestroySurface(scaledSurface);
return 1;
}
void loadCursors()
{
if (getConfig()->customCursorEnabled && strcmp(getConfig()->customCursor, "") != 0)
{
if (!loadNewCursor(getConfig()->customCursor, (void *)&customCursor, getConfig()->customCursorWidth,
getConfig()->customCursorHeight, getConfig()->customCursorWidth / 2, getConfig()->customCursorHeight / 2))
{
fprintf(stderr, "Custom cursor could not be loaded!\n");
exit(1);
}
}
if (getConfig()->customCursorEnabled && strcmp(getConfig()->touchCursor, "") != 0)
{
if (!loadNewCursor(getConfig()->touchCursor, (void *)&touchCursor, getConfig()->touchCursorWidth, getConfig()->touchCursorHeight, 15,
15))
{
fprintf(stderr, "Custom Touch cursor could not be loaded!\n");
exit(1);
}
}
}
void setCursor(void *cursor)
{
if (SDL_GetCursor() != NULL)
SDL_SetCursor(cursor);
}
void hideCursor()
{
SDL_HideCursor();
}
void showCursor()
{
SDL_ShowCursor();
}
void showPhCursor()
{
SDL_ShowCursor();
}
int XDefineCursor(Display *display, Window w, Cursor cursor)
{
int (*_xDefineCursor)(Display *, Window, Cursor) = dlsym(RTLD_NEXT, "XDefineCursor");
if (gId == QUIZ_AXA || gId == QUIZ_AXA_LIVE)
return 0;
return _xDefineCursor(display, w, cursor);
}
// Functions to Show and Hide the cursor in HOD4 while not necessary
void CPlayer_Main(int param1)
{
uint32_t value = *(unsigned int *)(uintptr_t)(param1 + 0x38);
if (!getConfig()->hideCursor)
{
switch (value)
{
case 0:
{
if (hod4PrevValue != 3 || hod4InTutorial)
{
hideCursor();
}
hod4PrevValue = 0;
}
break;
case 3:
{
if (!hod4InTutorial)
{
showCursor();
hod4PrevValue = 3;
}
}
break;
case 4:
{
hod4InTutorial = false;
}
case 2:
case 5:
case 11:
{
hideCursor();
}
}
}
CPlayer_MainOri(param1);
}
// Functions to Show and Hide the cursor in HOD4 while not necessary
int hod4VsPrintf(char *str, const char *format, va_list arg)
{
int (*_vsprintf)(char *str, const char *format, va_list arg) = dlsym(RTLD_NEXT, "vsprintf");
int res = _vsprintf(str, format, arg);
if (strcmp(str, "free : tutorial\n") == 0)
{
hod4InTutorial = false;
}
if (strcmp(str, "entry : tutorial\n") == 0)
{
hod4InTutorial = true;
}
return res;
}
+13
View File
@@ -0,0 +1,13 @@
#pragma once
#include <SDL3/SDL_mouse.h>
#include <stdio.h>
int loadNewCursor(const char *cursorFileName, SDL_Cursor **cursor, int customWidth, int customHeight, int hotX, int hotY);
void loadCursors();
void setCursor(void *cursor);
void hideCursor();
void showCursor();
void showPhCursor();
void CPlayer_Main(int param1);
int hod4VsPrintf(char *str, const char *format, va_list arg);
-229
View File
@@ -1,229 +0,0 @@
#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);
}
}
-7
View File
@@ -1,7 +0,0 @@
int loadNewCursor(const char *cursorFileName, void **cursor, int customWidth, int customHeight);
void loadCursors();
void setCursor(void *cursor);
void hideCursor();
void showCursor();
void showPhCursor();
@@ -1,6 +1,6 @@
#include "string.h"
#include "driveboard.h"
#include "driveBoard.h"
#include "jvs.h"
#define DRIVEBOARD_READY 0x00
+2 -6
View File
@@ -1,11 +1,7 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "config.h"
#include "eeprom.h"
#include "eeprom_settings.h"
#include "eepromSettings.h"
#define I2C_SMBUS_BLOCK_MAX 32
#define I2C_GET_FUNCTIONS 0x705
@@ -96,7 +92,7 @@ int initEeprom()
break;
case OUTRUN_2_SP_SDX:
case OUTRUN_2_SP_SDX_REVA:
if (strcmp(getConfig()->or2IP, "") != 0)
if (getConfig()->enableNetworkPatches && strcmp(getConfig()->or2IP, "") != 0 && strcmp(getConfig()->or2Netmask, "") != 0)
{
if (setIP(eeprom, getConfig()->or2IP, getConfig()->or2Netmask) != 0)
{
@@ -1,17 +1,15 @@
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "eeprom_settings.h"
#include "eepromSettings.h"
uint32_t crc32_table[255];
uint32_t crc32Table[255];
typedef struct
{
uint16_t offset;
uint16_t size;
} eepromOffsets;
} EepromOffsets;
typedef enum
{
@@ -21,9 +19,9 @@ typedef enum
ETH1,
CREDIT,
BACKUP
} eepromSection;
} EepromSection;
eepromOffsets eepromOffsetTable[] = {
EepromOffsets eepromOffsetTable[] = {
{0x0000, 0x0020}, // amSysDataRecord_Static
{0x00A0, 0x0010}, // amSysDataRecord_NetworkType
{0x00B0, 0x0020}, // amSysDataRecord_Eth0
@@ -33,7 +31,7 @@ eepromOffsets eepromOffsetTable[] = {
unsigned char eepromBuffer[512];
void build_crc32_table()
void buildCrc32Table()
{
for (uint32_t i = 0; i < 256; i++)
{
@@ -47,23 +45,23 @@ void build_crc32_table()
crc = crc ^ 0xEDB88320;
ch >>= 1;
}
crc32_table[i] = crc;
crc32Table[i] = crc;
}
}
uint32_t gen_crc(int section, size_t n)
uint32_t genCrc(int section, size_t n)
{
unsigned char *buff = &eepromBuffer[eepromOffsetTable[section].offset + 4];
unsigned long crc = 0xfffffffful;
size_t i;
for (i = 0; i < n; i++)
crc = crc32_table[*buff++ ^ (crc & 0xff)] ^ (crc >> 8);
crc = crc32Table[*buff++ ^ (crc & 0xff)] ^ (crc >> 8);
return (crc);
}
void addCRCtoBuffer(int section)
{
uint32_t crc = gen_crc(section, eepromOffsetTable[section].size - 4);
uint32_t crc = genCrc(section, eepromOffsetTable[section].size - 4);
memcpy(&eepromBuffer[eepromOffsetTable[section].offset], &crc, sizeof(uint32_t));
}
@@ -80,7 +78,7 @@ int checkCRCinBuffer(int section)
{
uint32_t crc;
memcpy(&crc, &eepromBuffer[eepromOffsetTable[section].offset], 4);
if (crc != gen_crc(section, eepromOffsetTable[section].size - 4))
if (crc != genCrc(section, eepromOffsetTable[section].size - 4))
return 1;
return 0;
}
@@ -244,7 +242,7 @@ int setIP(FILE *eeprom, char *ipAddress, char *netMask)
int eepromSettingsInit( FILE *eeprom)
{
build_crc32_table();
buildCrc32Table();
eeprom = fopen("eeprom.bin", "r+b");
if (eeprom == NULL)
@@ -1,19 +1,26 @@
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#ifndef __i386__
#define __i386__
#endif
#undef __x86_64__
#include <ctype.h>
#include <dirent.h>
#include <dlfcn.h>
#include <fcntl.h>
#include <linux/input.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <math.h>
#include "evdevinput.h"
#include "evdevInput.h"
#include "config.h"
#include "jvs.h"
#include "log.h"
extern uint32_t gId;
extern int gGrp;
int jvsBits = 10;
#define BITS_PER_LONG (sizeof(long) * 8)
@@ -23,6 +30,9 @@ int jvsBits = 10;
#define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)
#define NAME_ELEMENT(element) [element] = #element
int (*mySelect)(int nfds, fd_set *restrict readfds, fd_set *restrict writefds, fd_set *restrict exceptfds,
struct timeval *restrict timeout) = NULL;
ArcadeInput arcadeInputs[] = {{"TEST_BUTTON", 0, BUTTON_TEST, 1},
{"PLAYER_1_BUTTON_START", 1, BUTTON_START, 1},
@@ -79,9 +89,8 @@ static const char *const events[EV_MAX + 1] = {
};
static const int maxval[EV_MAX + 1] = {
[0 ... EV_MAX] = -1, [EV_SYN] = SYN_MAX, [EV_KEY] = KEY_MAX, [EV_REL] = REL_MAX,
[EV_ABS] = ABS_MAX, [EV_MSC] = MSC_MAX, [EV_SW] = SW_MAX, [EV_LED] = LED_MAX,
[EV_SND] = SND_MAX, [EV_REP] = REP_MAX, [EV_FF] = FF_MAX, [EV_FF_STATUS] = FF_STATUS_MAX,
[0 ... EV_MAX] = -1, [EV_SYN] = SYN_MAX, [EV_KEY] = KEY_MAX, [EV_REL] = REL_MAX, [EV_ABS] = ABS_MAX, [EV_MSC] = MSC_MAX,
[EV_SW] = SW_MAX, [EV_LED] = LED_MAX, [EV_SND] = SND_MAX, [EV_REP] = REP_MAX, [EV_FF] = FF_MAX, [EV_FF_STATUS] = FF_STATUS_MAX,
};
static const char *const absolutes[ABS_MAX + 1] = {
@@ -774,6 +783,7 @@ static const char *const *const names[EV_MAX + 1] = {
[0 ... EV_MAX] = NULL,
[EV_KEY] = keys,
[EV_ABS] = absolutes,
// [EV_REL] = relatives,
};
typedef struct
@@ -808,7 +818,7 @@ static int isEventDevice(const struct dirent *dir)
return strncmp("event", dir->d_name, 5) == 0;
}
ControllerStatus stopControllers(Controllers *controllers)
ControllerStatus stopEvdevControllers(Controllers *controllers)
{
controllers->threadsRunning = 0;
for (int i = 0; i < controllers->threadIndex; i++)
@@ -825,15 +835,15 @@ void normaliseName(char *string)
for (size_t j = 0; j < strlen(string); j++)
{
string[j] = toupper(string[j]);
if (string[j] == ' ' || string[j] == '/' || string[j] == '(' || string[j] == ',' || string[j] == '=' ||
string[j] == '-' || string[j] == ')')
if (string[j] == ' ' || string[j] == '/' || string[j] == '(' || string[j] == ',' || string[j] == '=' || string[j] == '-' ||
string[j] == ')')
{
string[j] = '_';
}
}
}
static ControllerStatus listControllers(Controllers *controllers)
ControllerStatus loadEvdevControllers(Controllers *controllers)
{
struct dirent **namelist;
controllers->count = scandir("/dev/input", &namelist, isEventDevice, alphasort);
@@ -851,8 +861,7 @@ static ControllerStatus listControllers(Controllers *controllers)
for (int i = 0; i < controllers->count; i++)
{
snprintf(controllers->controller[i].path, sizeof(controllers->controller[i].path), "%s/%s", "/dev/input",
namelist[i]->d_name);
snprintf(controllers->controller[i].path, sizeof(controllers->controller[i].path), "%s/%s", "/dev/input", namelist[i]->d_name);
free(namelist[i]);
controllers->controller[i].enabled = 0;
@@ -889,8 +898,7 @@ static ControllerStatus listControllers(Controllers *controllers)
}
// Get the controllers physical location
ioctl(controller, EVIOCGPHYS(sizeof(controllers->controller[i].physicalLocation)),
controllers->controller[i].physicalLocation);
ioctl(controller, EVIOCGPHYS(sizeof(controllers->controller[i].physicalLocation)), controllers->controller[i].physicalLocation);
for (size_t j = 0; j < strlen(controllers->controller[i].physicalLocation); j++)
{
if (controllers->controller[i].physicalLocation[j] == '/')
@@ -912,14 +920,14 @@ static ControllerStatus listControllers(Controllers *controllers)
{
if (test_bit(code, bit[EV_KEY]))
{
if(controllers->controller[i].inputCount >= MAX_INPUTS) { // the number of input is limited
fprintf(stderr, "warning, maximum number of inputs reached !\n");
break;
if (controllers->controller[i].inputCount >= MAX_INPUTS)
{ // the number of input is limited
fprintf(stderr, "warning, maximum number of inputs reached !\n");
break;
}
controllers->controller[i].enabled = 1;
ControllerInput *controllerInput =
&controllers->controller[i].inputs[controllers->controller[i].inputCount++];
ControllerInput *controllerInput = &controllers->controller[i].inputs[controllers->controller[i].inputCount++];
controllerInput->evType = EV_KEY;
controllerInput->evCode = code;
controllerInput->specialFunction = NO_SPECIAL_FUNCTION;
@@ -944,8 +952,7 @@ static ControllerStatus listControllers(Controllers *controllers)
if (test_bit(code, bit[EV_ABS]))
{
controllers->controller[i].enabled = 1;
ControllerInput *controllerInput =
&controllers->controller[i].inputs[controllers->controller[i].inputCount++];
ControllerInput *controllerInput = &controllers->controller[i].inputs[controllers->controller[i].inputCount++];
controllerInput->evType = EV_ABS;
controllerInput->evCode = code;
controllerInput->specialFunction = NO_SPECIAL_FUNCTION;
@@ -962,8 +969,7 @@ static ControllerStatus listControllers(Controllers *controllers)
// hum ok, truncated value
}
ControllerInput *minControllerInput =
&controllers->controller[i].inputs[controllers->controller[i].inputCount++];
ControllerInput *minControllerInput = &controllers->controller[i].inputs[controllers->controller[i].inputCount++];
minControllerInput->evType = EV_ABS;
minControllerInput->evCode = code;
minControllerInput->specialFunction = ANALOGUE_TO_DIGITAL_MIN;
@@ -979,8 +985,7 @@ static ControllerStatus listControllers(Controllers *controllers)
// hum ok, truncated value
}
ControllerInput *maxControllerInput =
&controllers->controller[i].inputs[controllers->controller[i].inputCount++];
ControllerInput *maxControllerInput = &controllers->controller[i].inputs[controllers->controller[i].inputCount++];
maxControllerInput->evType = EV_ABS;
maxControllerInput->evCode = code;
maxControllerInput->specialFunction = ANALOGUE_TO_DIGITAL_MAX;
@@ -1012,7 +1017,6 @@ static ControllerStatus listControllers(Controllers *controllers)
ioctl(controller, EVIOCGABS(code), &absoluteFeatures);
controllers->controller[i].absMin[code] = absoluteFeatures.minimum;
controllers->controller[i].absMax[code] = absoluteFeatures.maximum;
}
}
}
@@ -1028,8 +1032,7 @@ static ControllerStatus listControllers(Controllers *controllers)
for (int j = 0; j < controllers->count - 1 - i; j++)
{
Controller tmp;
if (strcmp(controllers->controller[j].physicalLocation, controllers->controller[j + 1].physicalLocation) >
0)
if (strcmp(controllers->controller[j].physicalLocation, controllers->controller[j + 1].physicalLocation) > 0)
{
tmp = controllers->controller[j];
controllers->controller[j] = controllers->controller[j + 1];
@@ -1041,6 +1044,7 @@ static ControllerStatus listControllers(Controllers *controllers)
return CONTROLLER_STATUS_SUCCESS;
}
#ifndef COMPILING_LINDBERGH_ELF
void *controllerThread(void *_args)
{
ThreadArguments *args = (ThreadArguments *)_args;
@@ -1064,7 +1068,8 @@ void *controllerThread(void *_args)
args->controllers->threadsRunning = 1;
for (int i = 0; i < 8; ++i) {
for (int i = 0; i < 8; ++i)
{
analogue_deadzones[i].start_max = args->analogue_deadzone_start[i] / 100.0;
analogue_deadzones[i].middle_min = 0.5 - (args->analogue_deadzone_middle[i] / 100.0);
analogue_deadzones[i].middle_max = 0.5 + (args->analogue_deadzone_middle[i] / 100.0);
@@ -1079,7 +1084,7 @@ void *controllerThread(void *_args)
tv.tv_sec = 0;
tv.tv_usec = 2 * 1000;
if (select(fd + 1, &file_descriptor, NULL, NULL, &tv) < 1)
if (mySelect(fd + 1, &file_descriptor, NULL, NULL, &tv) < 1)
continue;
if (read(fd, &event, sizeof(event)) == sizeof(event))
@@ -1087,100 +1092,148 @@ void *controllerThread(void *_args)
switch (event.type)
{
case EV_KEY:
{
if (!args->controller->keyTriggers[event.code].enabled)
continue;
if (args->controller->keyTriggers[event.code].isAnalogue)
case EV_KEY:
{
setAnalogue(args->controller->keyTriggers[event.code].channel,
event.value == 0 ? 0 : 1 * (pow(2, jvsBits) - 1));
continue;
}
if (!args->controller->keyTriggers[event.code].enabled)
continue;
if(args->controller->keyTriggers[event.code].isCoin == 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;
case EV_ABS:
{
double scaled =
((double)event.value - (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)
{
int channel = args->controller->absTriggers[event.code].channel;
if (args->controller->absTriggers[event.code].isAnalogue) {
// Deadzone handling
if (scaled < analogue_deadzones[channel].start_max)
scaled = 0.0;
if (scaled > analogue_deadzones[channel].middle_min && scaled < analogue_deadzones[channel].middle_max)
scaled = 0.5;
if (scaled > analogue_deadzones[channel].end_min)
scaled = 1.0;
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(event.value <= ((args->controller->absMin[event.code] + args->controller->absMax[event.code]) / 2)) {
if (args->controller->absTriggers[event.code].minEnabled)
if (args->controller->keyTriggers[event.code].isAnalogue)
{
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);
}
setAnalogue(args->controller->keyTriggers[event.code].channel, event.value == 0 ? 0 : 1 * (pow(2, jvsBits) - 1));
continue;
}
}
if(event.value >= ((args->controller->absMin[event.code] + args->controller->absMax[event.code]) / 2)) {
if (args->controller->absTriggers[event.code].maxEnabled)
if (args->controller->keyTriggers[event.code].isCoin == 1)
{
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 (event.value == 1)
incrementCoin(args->controller->keyTriggers[event.code].player, 1);
}
}
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;
else
setSwitch(args->controller->keyTriggers[event.code].player, args->controller->keyTriggers[event.code].channel,
event.value == 0 ? 0 : 1);
default:
}
break;
case EV_ABS:
{
double scaled = ((double)event.value - (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)
{
int channel = args->controller->absTriggers[event.code].channel;
if (args->controller->absTriggers[event.code].isAnalogue)
{
// Deadzone handling
if (scaled < analogue_deadzones[channel].start_max)
scaled = 0.0;
if (scaled > analogue_deadzones[channel].middle_min && scaled < analogue_deadzones[channel].middle_max)
scaled = 0.5;
if (scaled > analogue_deadzones[channel].end_min)
scaled = 1.0;
// uint32_t gId = getConfig()->crc32;
if (channel == ANALOGUE_1 || channel == ANALOGUE_2)
{
args->controller->lastAnalogueValue[channel] = scaled;
double x_pos = (channel == ANALOGUE_1) ? scaled : args->controller->lastAnalogueValue[ANALOGUE_1];
double y_pos = (channel == ANALOGUE_2) ? scaled : args->controller->lastAnalogueValue[ANALOGUE_2];
if (x_pos <= 0.01 || x_pos >= 0.99 || y_pos <= 0.01 || y_pos >= 0.99)
{
// log_info("Off-screen detected - X: %f, Y: %f", x_pos, y_pos);
switch (gId)
{
case GHOST_SQUAD_EVOLUTION:
// log_info("GSE: Triggering reload via BUTTON_2");
setSwitch(1, BUTTON_2, 1);
break;
}
}
else
{
setSwitch(1, BUTTON_2, 0);
}
}
if(channel == ANALOGUE_1 && (gGrp == GROUP_ID4_EXP || gGrp == GROUP_ID4_JAP || gGrp == GROUP_ID5))
scaled = (scaled - 0.5f) * 0.35f + 0.5f;
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 (event.value <= ((args->controller->absMin[event.code] + args->controller->absMax[event.code]) / 2))
{
if (args->controller->absTriggers[event.code].minEnabled)
{
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 (event.value >= ((args->controller->absMin[event.code] + args->controller->absMax[event.code]) / 2))
{
if (args->controller->absTriggers[event.code].maxEnabled)
{
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;
default:
break;
}
}
}
@@ -1313,11 +1366,6 @@ ControllerStatus getArcadeInputByName(char *name, ArcadeInput *input)
ControllerStatus startControllerThreads(Controllers *controllers)
{
// Don't start EVDEV threads if SDL/X11-only mode is enabled
if (getConfig()->inputMode == 1) {
return CONTROLLER_STATUS_SUCCESS;
}
for (int i = 0; i < controllers->count; i++)
{
if (!controllers->controller[i].enabled)
@@ -1330,7 +1378,7 @@ ControllerStatus startControllerThreads(Controllers *controllers)
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;
controllers->controller[i].absTriggers[j].isAnalogue = 1;
}
for (int j = 0; j < KEY_MAX; j++)
@@ -1345,17 +1393,20 @@ ControllerStatus startControllerThreads(Controllers *controllers)
char *mapping = getMapping(controllers->controller[i].inputs[j].inputName);
int negabs = 0;
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;
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};
@@ -1368,102 +1419,92 @@ ControllerStatus startControllerThreads(Controllers *controllers)
switch (controllers->controller[i].inputs[j].evType)
{
case EV_ABS:
{
switch (controllers->controller[i].inputs[j].specialFunction)
case EV_ABS:
{
case NO_SPECIAL_FUNCTION:
{
controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].enabled = 1;
controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].channel =
input.channel;
strncpy(controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].name,
input.name, SIZE);
controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].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;
switch (controllers->controller[i].inputs[j].specialFunction)
{
case NO_SPECIAL_FUNCTION:
{
controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].enabled = 1;
controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].channel = input.channel;
strncpy(controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].name, input.name,
SIZE);
controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].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_TO_DIGITAL_MAX:
{
controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].maxEnabled = 1;
controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].maxChannel = input.channel;
strncpy(controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].maxName, input.name,
SIZE);
controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].maxPlayer = 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_TO_DIGITAL_MIN:
{
controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].minEnabled = 1;
controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].minChannel = input.channel;
strncpy(controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].minName, input.name,
SIZE);
controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].minPlayer = 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;
strncpy(controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].shakeName,
input.name, SIZE);
controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].shakePlayer = input.player;
}
break;
default:
break;
}
}
break;
case ANALOGUE_TO_DIGITAL_MAX:
case EV_KEY:
{
controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].maxEnabled = 1;
controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].maxChannel =
input.channel;
strncpy(controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].maxName,
input.name, SIZE);
controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].maxPlayer =
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;
controllers->controller[i].keyTriggers[controllers->controller[i].inputs[j].evCode].enabled = 1;
controllers->controller[i].keyTriggers[controllers->controller[i].inputs[j].evCode].channel = input.channel;
strncpy(controllers->controller[i].keyTriggers[controllers->controller[i].inputs[j].evCode].name, input.name, SIZE);
controllers->controller[i].keyTriggers[controllers->controller[i].inputs[j].evCode].player = input.player;
case ANALOGUE_TO_DIGITAL_MIN:
{
controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].minEnabled = 1;
controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].minChannel =
input.channel;
strncpy(controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].minName,
input.name, SIZE);
controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].minPlayer =
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;
if (strstr(input.name, "ANALOGUE") != NULL)
controllers->controller[i].keyTriggers[controllers->controller[i].inputs[j].evCode].isAnalogue = 1;
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;
strncpy(controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].shakeName,
input.name, SIZE);
controllers->controller[i].absTriggers[controllers->controller[i].inputs[j].evCode].shakePlayer =
input.player;
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;
default:
break;
}
}
break;
case EV_KEY:
{
controllers->controller[i].keyTriggers[controllers->controller[i].inputs[j].evCode].enabled = 1;
controllers->controller[i].keyTriggers[controllers->controller[i].inputs[j].evCode].channel =
input.channel;
strncpy(controllers->controller[i].keyTriggers[controllers->controller[i].inputs[j].evCode].name,
input.name, SIZE);
controllers->controller[i].keyTriggers[controllers->controller[i].inputs[j].evCode].player =
input.player;
if (strstr(input.name, "ANALOGUE") != NULL)
controllers->controller[i].keyTriggers[controllers->controller[i].inputs[j].evCode].isAnalogue = 1;
if (strcmp(input.name, "PLAYER_1_COIN") == 0)
{
controllers->controller[i].keyTriggers[controllers->controller[i].inputs[j].evCode].isCoin = 1;
printf("Warining: Unknown mapping type\n");
}
if (strcmp(input.name, "PLAYER_2_COIN") == 0)
{
controllers->controller[i].keyTriggers[controllers->controller[i].inputs[j].evCode].isCoin = 1;
}
}
break;
default:
{
printf("Warining: Unknown mapping type\n");
}
}
}
@@ -1485,8 +1526,10 @@ ControllerStatus startControllerThreads(Controllers *controllers)
ThreadArguments *args = malloc(sizeof(ThreadArguments));
args->controller = &controllers->controller[i];
args->controllers = controllers;
memcpy(args->analogue_deadzone_start, config->arcadeInputs.analogue_deadzone_start, sizeof(config->arcadeInputs.analogue_deadzone_start));
memcpy(args->analogue_deadzone_middle, config->arcadeInputs.analogue_deadzone_middle, sizeof(config->arcadeInputs.analogue_deadzone_middle));
memcpy(args->analogue_deadzone_start, config->arcadeInputs.analogue_deadzone_start,
sizeof(config->arcadeInputs.analogue_deadzone_start));
memcpy(args->analogue_deadzone_middle, config->arcadeInputs.analogue_deadzone_middle,
sizeof(config->arcadeInputs.analogue_deadzone_middle));
memcpy(args->analogue_deadzone_end, config->arcadeInputs.analogue_deadzone_end, sizeof(config->arcadeInputs.analogue_deadzone_end));
pthread_create(&controllers->thread[controllers->threadIndex++], NULL, controllerThread, args);
controllers->controller[i].inUse = 1;
@@ -1495,21 +1538,30 @@ ControllerStatus startControllerThreads(Controllers *controllers)
return CONTROLLER_STATUS_SUCCESS;
}
ControllerStatus initControllers(Controllers *controllers)
#endif
ControllerStatus initEvdevControllers(Controllers *controllers)
{
// Don't start EVDEV if SDL mode is enabled
if (getConfig()->inputMode == 1)
{
return CONTROLLER_STATUS_SUCCESS;
}
mySelect = dlsym(RTLD_NEXT, "select");
if (loadEvdevControllers(controllers) != CONTROLLER_STATUS_SUCCESS)
{
return CONTROLLER_STATUS_ERROR;
}
jvsBits = getJVSIO()->capabilities.analogueInBits;
controllers->threadIndex = 0;
if (listControllers(controllers) != CONTROLLER_STATUS_SUCCESS)
{
return CONTROLLER_STATUS_ERROR;
}
#ifndef COMPILING_LINDBERGH_ELF
if (startControllerThreads(controllers) != CONTROLLER_STATUS_SUCCESS)
{
return CONTROLLER_STATUS_ERROR;
}
#endif
return CONTROLLER_STATUS_SUCCESS;
}
@@ -82,6 +82,7 @@ typedef struct
int enabled;
int inUse;
double lastAnalogueValue[8];
} Controller;
@@ -95,6 +96,6 @@ typedef struct
int threadsRunning;
} Controllers;
ControllerStatus initControllers(Controllers *controllers);
ControllerStatus stopControllers(Controllers *controllers);
ControllerStatus initEvdevControllers(Controllers *controllers);
ControllerStatus stopEvdevControllers(Controllers *controllers);
ControllerStatus loadEvdevControllers(Controllers *controllers);
+268
View File
@@ -0,0 +1,268 @@
#include <elf.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include "flowControl.h"
#include "log.h"
void setVariable(size_t address, size_t value)
{
int pagesize = sysconf(_SC_PAGE_SIZE);
size_t *variable = (size_t *)address;
void *toModify = (void *)(address - (address % pagesize));
int prot = mprotect(toModify, pagesize, PROT_EXEC | PROT_WRITE);
if (prot != 0)
{
log_error("Error: Cannot unprotect memory region to change variable (%d)\n", prot);
return;
}
*variable = value;
}
void patchMemoryFromString(size_t address, char *value)
{
size_t size = strlen((void *)value);
if (size % 2 != 0)
{
log_error("Patch sting len should be even.\n");
exit(EXIT_FAILURE);
}
char buf[size / 2];
char tmpchr[3];
char *p = value;
for (int i = 0; i < size; i++)
{
memcpy(tmpchr, p, 2);
tmpchr[2] = '\0';
buf[i] = (int)strtol(tmpchr, NULL, 16);
p += 2;
}
int pagesize = sysconf(_SC_PAGE_SIZE);
void *toModify = (void *)(address - (address % pagesize));
int prot = mprotect(toModify, pagesize, PROT_EXEC | PROT_WRITE);
if (prot != 0)
{
log_error("Error: Cannot unprotect memory region to change variable (%d)\n", prot);
return;
}
memcpy((void *)address, buf, size / 2);
}
void detourFunction(size_t address, void *function)
{
int pagesize = sysconf(_SC_PAGE_SIZE);
void *toModify = (void *)(address - (address % pagesize));
int prot = mprotect(toModify, pagesize, PROT_EXEC | PROT_WRITE);
if (prot != 0)
{
log_error("Error: Cannot detour memory region to change variable (%d)\n", prot);
return;
}
uint32_t jumpAddress = (function - (void *)address) - 5;
// Build the assembly to make the function jump
char cave[5] = {0xE9, 0x00, 0x00, 0x00, 0x00};
cave[4] = (jumpAddress >> (8 * 3)) & 0xFF;
cave[3] = (jumpAddress >> (8 * 2)) & 0xFF;
cave[2] = (jumpAddress >> (8 * 1)) & 0xFF;
cave[1] = (jumpAddress) & 0xFF;
memcpy((void *)address, cave, 5);
}
void replaceCallAtAddress(size_t address, void *function)
{
uint32_t offset = function - (void *)(address)-5;
int pagesize = sysconf(_SC_PAGE_SIZE);
void *toModify = (void *)(address - (address % pagesize));
int prot = mprotect(toModify, pagesize, PROT_EXEC | PROT_WRITE);
if (prot != 0)
{
log_error("Error: Cannot detour memory region to change variable (%d)\n", prot);
return;
}
uint32_t callAddress = (function - (void *)address) - 5;
char cave[5] = {0xE8, 0x00, 0x00, 0x00, 0x00};
cave[4] = (callAddress >> (8 * 3)) & 0xFF;
cave[3] = (callAddress >> (8 * 2)) & 0xFF;
cave[2] = (callAddress >> (8 * 1)) & 0xFF;
cave[1] = (callAddress) & 0xFF;
memcpy((void *)address, cave, 5);
}
int stubRetZero()
{
return 0;
}
void stubReturn()
{
return;
}
int stubRetOne()
{
return 1;
}
int stubRetMinusOne()
{
return -1;
}
char stubRetZeroChar()
{
return 0x00;
}
static size_t pageAlignDown(size_t addr)
{
size_t pagesize = sysconf(_SC_PAGESIZE);
return addr & ~(pagesize - 1);
}
int patchMemory(void *address, const void *data, size_t size)
{
size_t page_start = pageAlignDown((size_t)address);
size_t page_size = size + ((size_t)address - page_start);
if (mprotect((void *)page_start, page_size, PROT_READ | PROT_WRITE | PROT_EXEC) != 0)
{
log_error("Error in mprotect.");
return -1;
}
memcpy(address, data, size);
return 0;
}
void *trampolineHook(void *target, void *replacement, size_t saveSize)
{
void *trampoline = mmap(NULL, saveSize + 5, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (trampoline == MAP_FAILED)
{
perror("mmap");
return NULL;
}
uintptr_t src = (uintptr_t)target;
uintptr_t dst = (uintptr_t)replacement;
// Save original bytes
memcpy(trampoline, target, saveSize);
// Append jmp back after saved bytes
((uint8_t *)trampoline)[saveSize] = 0xE9;
uintptr_t jump_from = (uintptr_t)trampoline + saveSize;
uintptr_t jump_to = src + saveSize;
*(uint32_t *)((uint8_t *)trampoline + saveSize + 1) = (uint32_t)(jump_to - (jump_from + 5));
// Patch original
uint8_t jmp[5] = {0xE9};
*(uint32_t *)&jmp[1] = (uint32_t)(dst - src - 5);
if (patchMemory(target, jmp, sizeof(jmp)) != 0)
{
log_error("Error patching original function at %p\n", target);
}
return trampoline;
}
uintptr_t getBaseAddress()
{
FILE *fp = fopen("/proc/self/maps", "r");
if (!fp)
return 0;
uint32_t base = 0;
fscanf(fp, "%x-", &base);
fclose(fp);
return base;
}
void *findStaticFnAddr(const char *functionName)
{
int fd = open("/proc/self/exe", O_RDONLY);
if (fd < 0)
return NULL;
struct stat st;
if (fstat(fd, &st) < 0)
{
close(fd);
return NULL;
}
uint8_t *data = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
close(fd);
if (data == MAP_FAILED)
return NULL;
Elf32_Ehdr *ehdr = (Elf32_Ehdr *)data;
Elf32_Shdr *shdrs = (Elf32_Shdr *)(data + ehdr->e_shoff);
const char *shstrtab = (const char *)(data + shdrs[ehdr->e_shstrndx].sh_offset);
Elf32_Shdr *symtabHdr = NULL, *strtabHdr = NULL;
// Locate .symtab and .strtab
for (int i = 0; i < ehdr->e_shnum; i++)
{
const char *secname = shstrtab + shdrs[i].sh_name;
if (strcmp(secname, ".symtab") == 0)
{
symtabHdr = &shdrs[i];
}
else if (strcmp(secname, ".strtab") == 0)
{
strtabHdr = &shdrs[i];
}
}
if (!symtabHdr || !strtabHdr)
{
munmap(data, st.st_size);
return NULL;
}
// Check if the binary is PIE (ET_DYN)
int isPie = (ehdr->e_type == ET_DYN);
uintptr_t base = isPie ? getBaseAddress() : 0;
Elf32_Sym *symtab = (Elf32_Sym *)(data + symtabHdr->sh_offset);
const char *strtab = (const char *)(data + strtabHdr->sh_offset);
int numSyms = symtabHdr->sh_size / sizeof(Elf32_Sym);
for (int i = 0; i < numSyms; i++)
{
const char *sym_name = strtab + symtab[i].st_name;
if (strcmp(sym_name, functionName) == 0)
{
uintptr_t addr = symtab[i].st_value;
munmap(data, st.st_size);
return (void *)(base + addr);
}
}
munmap(data, st.st_size);
return NULL;
}
+15
View File
@@ -0,0 +1,15 @@
#pragma once
#include <stdio.h>
void setVariable(size_t address, size_t value);
void patchMemoryFromString(size_t address, char *value);
void detourFunction(size_t address, void *function);
void replaceCallAtAddress(size_t address, void *function);
void stubReturn();
int stubRetZero();
int stubRetOne();
int stubRetMinusOne();
char stubRetZeroChar();
void *trampolineHook(void *target, void *replacement, size_t saveSize);
void *findStaticFnAddr(const char *functionName);
@@ -1,14 +1,24 @@
#include <sys/time.h>
#include <stdio.h>
#include <sys/time.h>
#include <unistd.h>
#include "fps_limiter.h"
#include "config.h"
#include "fpsLimiter.h"
fps_limit fpsLimit;
FpsLimit fpsLimit;
double lastTime = 0.0;
int frameCount = 0;
double fps = 0.0;
void initFpsLimiter()
{
if (getConfig()->fpsLimiter == 1)
{
fpsLimit.targetFrameTime = 1000000 / getConfig()->fpsTarget;
fpsLimit.frameEnd = clockNow();
}
}
double getTimeInMilliseconds()
{
struct timeval time;
@@ -37,14 +47,21 @@ double calculateFps()
return fps;
}
long Clock_now()
long clockNow()
{
struct timeval time_now;
gettimeofday(&time_now, NULL);
return time_now.tv_sec * 1000000L + time_now.tv_usec;
}
void FpsLimiter(fps_limit *stats)
void frameTiming()
{
fpsLimit.frameStart = clockNow();
fpsLimiter(&fpsLimit);
fpsLimit.frameEnd = clockNow();
}
void fpsLimiter(FpsLimit *stats)
{
stats->sleepTime = stats->targetFrameTime - (stats->frameStart - stats->frameEnd);
@@ -54,7 +71,7 @@ void FpsLimiter(fps_limit *stats)
usleep(adjustedSleep);
stats->frameOverhead = (Clock_now() - stats->frameStart) - adjustedSleep;
stats->frameOverhead = (clockNow() - stats->frameStart) - adjustedSleep;
if (stats->frameOverhead > stats->targetFrameTime / 2)
{
@@ -7,8 +7,10 @@ typedef struct
long frameEnd; // End time of the frame
long sleepTime; // Sleep time to maintain the frame rate
long frameOverhead; // Overhead time in the frame
} fps_limit;
} FpsLimit;
long Clock_now();
void FpsLimiter(fps_limit *stats);
void initFpsLimiter();
long clockNow();
void fpsLimiter(FpsLimit *stats);
double calculateFps();
void frameTiming();
File diff suppressed because it is too large Load Diff
+1
View File
@@ -0,0 +1 @@
void loadSDLControllerMappings();
+96
View File
@@ -0,0 +1,96 @@
#include "gameData.h"
#include "config.h"
static const GameData gameData[] = {
{AFTER_BURNER_CLIMAX, "After Burner Climax", "abc", "DVP-0009", "SBLR", "2006", "640x480", WORKING, SEGA_TYPE_1, ABC, 640, 480, GROUP_ABC, 0, 0, 0, 0, 0, 0, YELLOW},
{AFTER_BURNER_CLIMAX_REVA, "After Burner Climax Rev A", "abc-rev-a", "DVP-0009A", "SBLR", "2006", "640x480", WORKING, SEGA_TYPE_1, ABC, 640, 480, GROUP_ABC, 0, 0, 0, 0, 0, 0, YELLOW},
{AFTER_BURNER_CLIMAX_REVB, "After Burner Climax Rev B", "abc-rev-b", "DVP-0009B", "SBLR", "2006", "640x480", WORKING, SEGA_TYPE_1, ABC, 640, 480, GROUP_ABC, 0, 0, 0, 0, 0, 0, YELLOW},
{AFTER_BURNER_CLIMAX_SDX, "After Burner Climax SDX", "abc-sdx", "DVP-0018", "SBMN", "2006 ?", "640x480", WORKING, SEGA_TYPE_1, ABC, 640, 480, GROUP_ABC, 0, 0, 0, 0, 0, 0, YELLOW},
{AFTER_BURNER_CLIMAX_SDX_REVA, "After Burner Climax SDX Rev A", "abc-sdx-rev-a", "DVP-0018A", "SBMN", "2006 ?", "640x480", WORKING, SEGA_TYPE_1, ABC, 640, 480, GROUP_ABC, 0, 0, 0, 0, 0, 0, YELLOW},
{AFTER_BURNER_CLIMAX_SE, "After Burner Climax SE", "abc-se", "DVP-0031", "SBLR", "2006 ?", "", WORKING, SEGA_TYPE_1, ABC, 640, 480, GROUP_ABC, 0, 0, 0, 0, 0, 0, YELLOW},
{AFTER_BURNER_CLIMAX_SE_REVA, "After Burner Climax SE Rev A", "abc-se-rev-a", "DVP-0031A", "SBLR", "2006 ?", "", WORKING, SEGA_TYPE_1, ABC, 640, 480, GROUP_ABC, 0, 0, 0, 0, 0, 0, YELLOW},
{GHOST_SQUAD_EVOLUTION, "Ghost Squad Evolution", "gsevo", "DVP-0029A", "SBNJ", "2007", "640x480", WORKING, SEGA_TYPE_1, SHOOTING, 640, 480, -1, 0, 0, 0, 0, 0, 0, RED},
{HARLEY_DAVIDSON, "Harley-Davidson: King of the Road", "harley", "DVP-5007", "SBRG", "2009", "1360x768", WORKING, SEGA_TYPE_3, DRIVING, 1360, 768, -1, 0, 0, 0, 0, 0, 0, RED},
{HUMMER, "Hummer", "hummer", "DVP-0057B", "SBQN", "2008", "1280x768", WORKING, SEGA_TYPE_3, DRIVING, 1280, 768, GROUP_HUMMER, 0, 0, 0, 0, 0, 0, YELLOW},
{HUMMER_EXTREME, "Hummer Extreme", "hummer-ext", "DVP-0079", "SBST", "2009", "", WORKING, SEGA_TYPE_3, DRIVING, 1280, 768, GROUP_HUMMER, 0, 0, 0, 0, 0, 0, YELLOW},
{HUMMER_EXTREME_MDX, "Hummer Extreme MDX", "hummer-ext-mdx", "DVP-0083", "SBST", "2009", "1280x768", WORKING, SEGA_TYPE_3, DRIVING, 1280, 768, GROUP_HUMMER, 0, 0, 0, 0, 0, 0, YELLOW},
{HUMMER_SDLX, "Hummer SDLX", "hummer-sdlx", "DVP-0057", "SBST", "2008", "", WORKING, SEGA_TYPE_3, DRIVING, 1280, 768, GROUP_HUMMER, 0, 0, 0, 0, 0, 0, YELLOW},
{INITIALD_4_EXP_REVB, "Initial D Arcade Stage 4 Export Rev B", "id4-exp-rev-b", "DVP-0030B", "SBNK", "2007", "1360x768", WORKING, SEGA_TYPE_3, DRIVING, 1360, 768, GROUP_ID4_EXP, 0, 0, 0, 0, 1, 0, YELLOW},
{INITIALD_4_EXP_REVC, "Initial D Arcade Stage 4 Export Rev C", "id4-exp-rev-c", "DVP-0030C", "SBNK", "2007", "1360x768", WORKING, SEGA_TYPE_3, DRIVING, 1360, 768, GROUP_ID4_EXP, 0, 0, 0, 0, 1, 0, YELLOW},
{INITIALD_4_EXP_REVD, "Initial D Arcade Stage 4 Export Rev D", "id4-exp-rev-d", "DVP-0030D", "SBNK", "2007", "1360x768", WORKING, SEGA_TYPE_3, DRIVING, 1360, 768, GROUP_ID4_EXP, 0, 0, 0, 0, 1, 0, YELLOW},
{INITIALD_4_REVA, "Initial D Arcade Stage 4 Rev A", "id4-rev-a", "DVP-0019A", "SBML", "2007", "1360x768", WORKING, SEGA_TYPE_3, DRIVING, 1360, 768, GROUP_ID4_JAP, 0, 0, 0, 0, 1, 0, YELLOW},
{INITIALD_4_REVB, "Initial D Arcade Stage 4 Rev B", "id4-rev-b", "DVP-0019B", "SBML", "2007", "1360x768", WORKING, SEGA_TYPE_3, DRIVING, 1360, 768, GROUP_ID4_JAP, 0, 0, 0, 0, 1, 0, YELLOW},
{INITIALD_4_REVC, "Initial D Arcade Stage 4 Rev C", "id4-rev-c", "DVP-0019C", "SBML", "2007", "1360x768", WORKING, SEGA_TYPE_3, DRIVING, 1360, 768, GROUP_ID4_JAP, 0, 0, 0, 0, 1, 0, YELLOW},
{INITIALD_4_REVD, "Initial D Arcade Stage 4 Rev D", "id4-rev-d", "DVP-0019D", "SBML", "2007", "1360x768", WORKING, SEGA_TYPE_3, DRIVING, 1360, 768, GROUP_ID4_JAP, 0, 0, 0, 0, 1, 0, YELLOW},
{INITIALD_4_REVG, "Initial D Arcade Stage 4 Rev G", "id4-rev-g", "DVP-0019G", "SBML", "2007", "1360x768", WORKING, SEGA_TYPE_3, DRIVING, 1360, 768, GROUP_ID4_JAP, 0, 0, 0, 0, 1, 0, YELLOW},
{INITIALD_5_EXP, "Initial D5 EXP", "id5-exp", "DVP-0075", "SBRY", "2009", "1360x768", WORKING, SEGA_TYPE_3, DRIVING, 1360, 768, GROUP_ID5, 0, 0, 0, 0, 1, 0, YELLOW},
{INITIALD_5_EXP_20, "Initial D5 EXP 2.0", "id5-exp-20", "DVP-0084", "SBTS", "2009", "1360x768", WORKING, SEGA_TYPE_3, DRIVING, 1360, 768, GROUP_ID5, 0, 0, 0, 0, 1, 0, YELLOW},
{INITIALD_5_EXP_20A, "Initial D5 5 EXP 2.0", "id5-exp-20a", "DVP-0084A", "SBTS", "2009", "1360x768", WORKING, SEGA_TYPE_3, DRIVING, 1360, 768, GROUP_ID5, 0, 0, 0, 0, 1, 0, YELLOW},
{INITIALD_5_JAP_REVA, "Initial D Arcade Stage 5 Rev A", "id5-jap-rev-a", "DVP-0070A", "SBQZ", "2009", "1360x768", WORKING, SEGA_TYPE_3, DRIVING, 1360, 768, GROUP_ID5, 0, 0, 0, 0, 1, 0, YELLOW},
{INITIALD_5_JAP_REVC, "Initial D Arcade Stage 5 Rev C", "id5-jap-rev-c", "DVP-0070C", "SBQZ", "2009", "1360x768", WORKING, SEGA_TYPE_3, DRIVING, 1360, 768, GROUP_ID5, 0, 0, 0, 0, 1, 0, YELLOW},
{INITIALD_5_JAP_REVF, "Initial D Arcade Stage 5 Rev F", "id5-jap-rev-f", "DVP-0070F", "SBQZ", "2009", "1360x768", WORKING, SEGA_TYPE_3, DRIVING, 1360, 768, GROUP_ID5, 0, 0, 0, 0, 1, 0, YELLOW},
{LETS_GO_JUNGLE, "Let's Go Jungle! Lost on the Island of Spice!", "lgj", "DVP-0011", "SBLU", "2006", "1360x768", WORKING, SEGA_TYPE_3, SHOOTING, 1360, 768, GROUP_LGJ, 0, 0, 0, 0, 0, 0, YELLOW},
{LETS_GO_JUNGLE_REVA, "Let's Go Jungle! Lost on the Island of Spice! Rev A", "lgj-rev-a", "DVP-0011A", "SBLU", "2006", "1360x768", WORKING, SEGA_TYPE_3, SHOOTING, 1360, 768, GROUP_LGJ, 0, 0, 0, 0, 0, 0, YELLOW},
{LETS_GO_JUNGLE_SPECIAL, "Let's Go Jungle! Special!", "lgj-sp", "DVP-0036", "SBNR", "2007", "1024x768", WORKING, SEGA_TYPE_3, SHOOTING, 1024, 768, GROUP_LGJ, 1, 0, 0, 0, 0, 0, YELLOW},
{MJ4_EVO, "SEGA Network Taisen Mahjong MJ4 Evolution", "mj4-evo", "DVP-0081", "SBTA", "2008", "1024x768", WORKING, SEGA_TYPE_3, MAHJONG, 1024, 768, -1, 0, 0, 0, 0, 0, 1, YELLOW},
{MJ4_REVG, "SEGA Network Taisen Mahjong MJ4", "mj4-rev-g", "DVP-0049G", "SBPN", "2007", "1024x768", WORKING, SEGA_TYPE_3, MAHJONG, 1024, 768, -1, 0, 0, 0, 0, 0, 1, YELLOW},
{OUTRUN_2_SP_SDX, "Outrun 2 SP SDX", "outrun2", "DVP-0015", "SBMB", "2006", "800x480", WORKING, SEGA_TYPE_3, DRIVING, 800, 480, GROUP_OUTRUN, 0, 1, 1, 0, 0, 0, YELLOW},
{OUTRUN_2_SP_SDX_TEST, "Outrun 2 SP SDX", "outrun2", "DVP-0015", "SBMB", "2006", "800x480", WORKING, SEGA_TYPE_3, DRIVING, 800, 480, GROUP_OUTRUN_TEST, 0, 1, 1, 0, 0, 0, YELLOW},
{OUTRUN_2_SP_SDX_REVA, "Outrun 2 SP SDX Rev A", "outrun2-rev-a", "DVP-0015A", "SBMB", "2006", "800x480", WORKING, SEGA_TYPE_3, DRIVING, 800, 480, GROUP_OUTRUN, 0, 1, 1, 0, 0, 0, YELLOW},
{OUTRUN_2_SP_SDX_REVA_TEST, "Outrun 2 SP SDX Rev A", "outrun2-rev-a", "DVP-0015A", "SBMB", "2006", "800x480", WORKING, SEGA_TYPE_3, DRIVING, 800, 480, GROUP_OUTRUN_TEST, 0, 1, 1, 0, 0, 0, YELLOW},
{OUTRUN_2_SP_SDX_REVA_TEST2, "Outrun 2 SP SDX Rev A", "outrun2-rev-a", "DVP-0015A", "SBMB", "2006", "800x480", WORKING, SEGA_TYPE_3, DRIVING, 800, 480, GROUP_OUTRUN_TEST, 0, 1, 1, 0, 0, 0, YELLOW},
{PRIMEVAL_HUNT, "Primeval Hunt", "ph", "DVP-0048A", "SBPP", "2008", "640x480", WORKING, SEGA_TYPE_3, SHOOTING, 640, 480, -1, 0, 0, 0, 0, 0, 0, RED},
{QUIZ_AXA, "Network Taisen Quiz Answer x Answer (SBMS 1.30)", "axa", "DVP-0025H", "SBMS", "", "1024x768", WORKING, SEGA_TYPE_3, MAHJONG, 1024, 768, -1, 0, 0, 0, 0, 0, 1, YELLOW},
{QUIZ_AXA_LIVE, "Network Taisen Quiz Answer x Answer Live! (SBUR 3.530)", "axalive", "DVP-0087D", "SBUR", "", "1024x768", WORKING, SEGA_TYPE_3, MAHJONG, 1024, 768, -1, 0, 0, 0, 0, 0, 1, YELLOW},
{RAMBO, "Rambo", "rambo", "DVP-0069", "SBQL", "2008", "640x480, 1280x768", WORKING, SEGA_TYPE_3, SHOOTING, 1280, 768, GROUP_RAMBO, 0, 0, 0, 0, 0, 0, REDEX},
{RAMBO_CHINA, "Rambo", "rambo-cn", "DVP-0078", "SBSS", "2008", "640x480, 1280x768", WORKING, SEGA_TYPE_3, SHOOTING, 1280, 768, GROUP_RAMBO, 0, 0, 0, 0, 0, 0, REDEX},
{R_TUNED, "R-Tuned: Ultimate Street Racing", "r-tuned", "DVP-0060", "SBQW", "2008", "640x480", WORKING, SEGA_TYPE_3, DRIVING, 640, 480, -1, 0, 1, 0, 1, 0, 0, YELLOW},
{SEGABOOT_2_4, "Segaboot 2.4", "segaboot-24", "", "", "", "", WORKING, SEGA_TYPE_3, DIGITAL, 0, 0, -1, 0, 0, 0, 0, 0, 0, YELLOW},
{SEGABOOT_2_4_SYM, "Segaboot 2.4 with symbols", "segaboot-24-sym", "", "", "", "", WORKING, SEGA_TYPE_3, DIGITAL, 0, 0, -1, 0, 0, 0, 0, 0, 0, YELLOW},
{SEGA_RACE_TV, "SEGA Race TV", "srtv", "DVP-0044", "SBPF", "2008", "640x480", WORKING, SEGA_TYPE_3, DRIVING, 640, 480, -1, 0, 1, 0, 0, 0, 0, YELLOW},
{THE_HOUSE_OF_THE_DEAD_4_REVA, "The House of the Dead 4 Rev A", "hod4-rev-a", "DVP-0003A", "SBLC", "2005", "640x480, 1280x768", WORKING, SEGA_TYPE_3, SHOOTING, 1280, 768, GROUP_HOD4, 0, 0, 0, 0, 0, 0, YELLOW},
{THE_HOUSE_OF_THE_DEAD_4_REVA_TEST, "The House of the Dead 4 Rev A", "hod4-rev-a", "DVP-0003A", "SBLC", "2005", "640x480, 1280x768", WORKING, SEGA_TYPE_3, SHOOTING, 1280, 768, GROUP_HOD4_TEST, 0, 0, 0, 0, 0, 0, YELLOW},
{THE_HOUSE_OF_THE_DEAD_4_REVB, "The House of the Dead 4 Rev B", "hod4-rev-b", "DVP-0003B", "SBLC", "2005", "640x480, 1280x768", WORKING, SEGA_TYPE_3, SHOOTING, 1280, 768, GROUP_HOD4, 0, 0, 0, 0, 0, 0, YELLOW},
{THE_HOUSE_OF_THE_DEAD_4_REVB_TEST, "The House of the Dead 4 Rev B", "hod4-rev-b", "DVP-0003B", "SBLC", "2005", "640x480, 1280x768", WORKING, SEGA_TYPE_3, SHOOTING, 1280, 768, GROUP_HOD4_TEST, 0, 0, 0, 0, 0, 0, YELLOW},
{THE_HOUSE_OF_THE_DEAD_4_REVC, "The House of the Dead 4 Rev C", "hod4-rev-c", "DVP-0003C", "SBLC", "2005", "640x480, 1280x768", WORKING, SEGA_TYPE_3, SHOOTING, 1280, 768, GROUP_HOD4, 0, 0, 0, 0, 0, 0, YELLOW},
{THE_HOUSE_OF_THE_DEAD_4_REVC_TEST, "The House of the Dead 4 Rev C", "hod4-rev-c", "DVP-0003C", "SBLC", "2005", "640x480, 1280x768", WORKING, SEGA_TYPE_3, SHOOTING, 1280, 768, GROUP_HOD4_TEST, 0, 0, 0, 0, 0, 0, YELLOW},
{THE_HOUSE_OF_THE_DEAD_4_SPECIAL, "The House of the Dead 4 Special", "hod4-sp", "DVP-0010", "SBLS", "2006", "1024x768", WORKING, SEGA_TYPE_3, SHOOTING, 1024, 768, GROUP_HOD4_SP, 1, 0, 0, 0, 0, 0, YELLOW},
{THE_HOUSE_OF_THE_DEAD_4_SPECIAL_TEST, "The House of the Dead 4 Special", "hod4-sp", "DVP-0010", "SBLS", "2006", "1024x768", WORKING, SEGA_TYPE_3, SHOOTING, 1024, 768, GROUP_HOD4_SP_TEST, 1, 0, 0, 0, 0, 0, YELLOW},
{THE_HOUSE_OF_THE_DEAD_4_SPECIAL_REVB, "The House of the Dead 4 Special Rev B", "hod4-sp-rev-b", "DVP-0010B", "SBLS", "2006", "1024x768", WORKING, SEGA_TYPE_3, SHOOTING, 1024, 768, GROUP_HOD4_SP, 1, 0, 0, 0, 0, 0, YELLOW},
{THE_HOUSE_OF_THE_DEAD_4_SPECIAL_REVB_TEST, "The House of the Dead 4 Special Rev B", "hod4-sp-rev-b", "DVP-0010B", "SBLS", "2006", "1024x768", WORKING, SEGA_TYPE_3, SHOOTING, 1024, 768, GROUP_HOD4_SP_TEST, 1, 0, 0, 0, 0, 0, YELLOW},
{THE_HOUSE_OF_THE_DEAD_EX, "Ai Sareruyori Ai Shitai: The House of the Dead EX", "hod-ex", "DVP-0063", "SBRC", "2008", "640x480, 1280x768", WORKING, SEGA_TYPE_3, SHOOTING, 1360, 768, -1, 0, 0, 0, 0, 0, 0, YELLOW},
{THE_HOUSE_OF_THE_DEAD_EX_TEST, "Ai Sareruyori Ai Shitai: The House of the Dead EX", "hod-ex", "DVP-0063", "SBRC", "2008", "640x480, 1280x768", WORKING, SEGA_TYPE_3, SHOOTING, 1360, 768, -1, 0, 0, 0, 0, 0, 0, YELLOW},
{TOO_SPICY, "Too Spicy", "2spicy", "DVP-0027A", "SBMV", "2007", "640x480, 1280x768", WORKING, SEGA_TYPE_3, SHOOTING, 1280, 768, -1, 0, 0, 0, 0, 0, 0, RED},
{TOO_SPICY_TEST, "Too Spicy", "2spicy", "DVP-0027A", "SBMV", "2007", "640x480, 1280x768", WORKING, SEGA_TYPE_3, SHOOTING, 1280, 768, -1, 0, 0, 0, 0, 0, 0, RED},
{VIRTUA_FIGHTER_5, "Virtua Fighter 5", "vf5", "DVP-0008", "SBLM", "2005", "1280x768", WORKING, SEGA_TYPE_3, DIGITAL, 1280, 768, GROUP_VF5, 0, 0, 0, 0, 0, 0, YELLOW},
{VIRTUA_FIGHTER_5_EXPORT, "Virtua Fighter 5 Export", "vf5-exp", "DVP-0043", "SBLM", "2005", "1280x768", WORKING, SEGA_TYPE_3, DIGITAL, 1280, 768, GROUP_VF5, 0, 0, 0, 0, 0, 0, YELLOW},
{VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVA, "Virtua Fighter 5 Final Showdown REV A", "vf5-fs-rev-a", "DVP-5019A", "SBUV", "2010", "1280x768", WORKING, SEGA_TYPE_3, DIGITAL, 1280, 768, GROUP_VF5, 0, 0, 0, 0, 0, 0, YELLOW},
{VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB, "Virtua Fighter 5 Final Showdown REV B", "vf5-fs-rev-b", "DVP-5020", "SBXX", "2010", "1280x768", WORKING, SEGA_TYPE_3, DIGITAL, 1280, 768, GROUP_VF5, 0, 0, 0, 0, 0, 0, YELLOW},
{VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB_6000, "Virtua Fighter 5 Final Showdown REV B ver 6.0000", "vf5-fs-rev-b-6000", "DVP-5020", "SBXX", "2010", "1280x768", WORKING, SEGA_TYPE_3, DIGITAL, 1280, 768, GROUP_VF5, 0, 0, 0, 0, 0, 0, YELLOW},
{VIRTUA_FIGHTER_5_R, "Virtua Fighter 5 R", "vf5-r", "DVP-XXXX", "SBQU", "2008", "1280x768", WORKING, SEGA_TYPE_3, DIGITAL, 1280, 768, GROUP_VF5, 0, 0, 0, 0, 0, 0, YELLOW},
{VIRTUA_FIGHTER_5_R_REVD, "Virtua Fighter 5 R Rev D", "vf5-r-rev-d", "DVP-XXXX", "SBQU", "2008", "1280x768", WORKING, SEGA_TYPE_3, DIGITAL, 1280, 768, GROUP_VF5, 0, 0, 0, 0, 0, 0, YELLOW},
{VIRTUA_FIGHTER_5_R_REVG, "Virtua Fighter 5 R Rev G", "vf5-r-rev-g", "DVP-XXXX", "SBQU", "2008", "1280x768", WORKING, SEGA_TYPE_3, DIGITAL, 1280, 768, GROUP_VF5, 0, 0, 0, 0, 0, 0, YELLOW},
{VIRTUA_FIGHTER_5_REVA, "Virtua Fighter 5 Rev A", "vf5-rev-a", "DVP-0008A", "SBLM", "2005", "1280x768", WORKING, SEGA_TYPE_3, DIGITAL, 1280, 768, GROUP_VF5, 0, 0, 0, 0, 0, 0, YELLOW},
{VIRTUA_FIGHTER_5_REVB, "Virtua Fighter 5 Rev B", "vf5-rev-b", "DVP-0008B", "SBLM", "2005", "1280x768", WORKING, SEGA_TYPE_3, DIGITAL, 1280, 768, GROUP_VF5, 0, 0, 0, 0, 0, 0, YELLOW},
{VIRTUA_FIGHTER_5_REVE, "Virtua Fighter 5 Rev E (Public Version C)", "vf5-rev-e", "DVP-0008E", "SBLM", "2005", "1280x768", WORKING, SEGA_TYPE_3, DIGITAL, 1280, 768, GROUP_VF5, 0, 0, 0, 0, 0, 0, YELLOW},
{VIRTUA_TENNIS_3, "Virtua Tennis 3", "vt3", "DVP-0005", "SBKX", "2006", "640x480, 1360x768", WORKING, SEGA_TYPE_3, DIGITAL, 1360, 768, GROUP_VT3, 0, 0, 0, 1, 0, 0, YELLOW},
{VIRTUA_TENNIS_3_TEST, "Virtua Tennis 3", "vt3", "DVP-0005", "SBKX", "2006", "640x480, 1360x768", WORKING, SEGA_TYPE_3, DIGITAL, 1360, 768, GROUP_VT3_TEST, 0, 0, 0, 1, 0, 0, YELLOW},
{VIRTUA_TENNIS_3_REVA, "Virtua Tennis 3 Rev A", "vt3-rev-a", "DVP-0005A", "SBKX", "2006", "640x480, 1360x768", WORKING, SEGA_TYPE_3, DIGITAL, 1360, 768, GROUP_VT3, 0, 0, 0, 1, 0, 0, YELLOW},
{VIRTUA_TENNIS_3_REVA_TEST, "Virtua Tennis 3 Rev A", "vt3-rev-a", "DVP-0005A", "SBKX", "2006", "640x480, 1360x768", WORKING, SEGA_TYPE_3, DIGITAL, 1360, 768, GROUP_VT3_TEST, 0, 0, 0, 1, 0, 0, YELLOW},
{VIRTUA_TENNIS_3_REVB, "Virtua Tennis 3 Rev B", "vt3-rev-b", "DVP-0005B", "SBKX", "2006", "640x480, 1360x768", WORKING, SEGA_TYPE_3, DIGITAL, 1360, 768, GROUP_VT3, 0, 0, 0, 1, 0, 0, YELLOW},
{VIRTUA_TENNIS_3_REVB_TEST, "Virtua Tennis 3 Rev B", "vt3-rev-b", "DVP-0005B", "SBKX", "2006", "640x480, 1360x768", WORKING, SEGA_TYPE_3, DIGITAL, 1360, 768, GROUP_VT3_TEST, 0, 0, 0, 1, 0, 0, YELLOW},
{VIRTUA_TENNIS_3_REVC, "Virtua Tennis 3 Rev C", "vt3-rev-c", "DVP-0005C", "SBKX", "2006", "640x480, 1360x768", WORKING, SEGA_TYPE_3, DIGITAL, 1360, 768, GROUP_VT3, 0, 0, 0, 1, 0, 0, YELLOW},
{VIRTUA_TENNIS_3_REVC_TEST, "Virtua Tennis 3 Rev C", "vt3-rev-c", "DVP-0005C", "SBKX", "2006", "640x480, 1360x768", WORKING, SEGA_TYPE_3, DIGITAL, 1360, 768, GROUP_VT3_TEST, 0, 0, 0, 1, 0, 0, YELLOW},
};
const GameData *getGameData(uint32_t elf_crc)
{
for (size_t i = 0; i < sizeof(gameData) / sizeof(gameData[0]); ++i)
{
if (gameData[i].crc32 == elf_crc)
{
return &gameData[i];
}
}
return NULL;
}
+31
View File
@@ -0,0 +1,31 @@
#ifndef GAME_DATA_H
#define GAME_DATA_H
#include "config.h"
typedef struct GameData {
uint32_t crc32;
const char *gameTitle;
const char *gameShortTitle;
const char *gameDVP;
const char *gameID;
const char *gameReleaseYear;
const char *gameNativeResolutions;
GameStatus gameStatus;
JVSIOType jvsIOType;
GameType gameType;
int width;
int height;
GameGroup gameGroup;
int emulateRideboard;
int emulateDriveboard;
int emulateMotionboard;
int emulateHW210CardReader;
int emulateIDCardReader;
int emulateTouchscreen;
Colour gameLindberghColour;
} GameData;
const GameData *getGameData(uint32_t elf_crc);
#endif // GAME_DATA_H
+369
View File
@@ -0,0 +1,369 @@
#define GL_GLEXT_PROTOTYPES
#ifndef __i386__
#define __i386__
#endif
#undef __x86_64__
#include <GL/freeglut.h>
#include <GL/glx.h>
#include <SDL3/SDL.h>
#include <SDL3_ttf/SDL_ttf.h>
#include <stdbool.h>
#include "blitStretching.h"
#include "border.h"
#include "config.h"
#include "fpsLimiter.h"
#include "resolution.h"
#include "sdlCalls.h"
#include "touchScreen.h"
extern uint32_t gId;
extern int gGrp;
extern int gWidth;
extern int gHeight;
extern SDL_Window *sdlWindow;
extern Display *x11Display;
extern char sdlGameTitle[];
extern char current_text[256];
extern double local_fps;
bool winHidden = true;
void *displayFunc = NULL;
void *reshapeFunc = NULL;
void *visibilityFunc = NULL;
void *idleFunc = NULL;
extern int drawableW;
extern int drawableH;
extern SDL_Renderer *fontRenderer;
extern TTF_Font *font;
int penX = 0;
int penY = 0;
void FGAPIENTRY glutInit(int *argcp, char **argv)
{
void FGAPIENTRY (*_glutInit)(int *argcp, char **argv) = dlsym(RTLD_NEXT, "glutInit");
startSDL(argcp, argv);
}
void FGAPIENTRY glutMainLoop(void)
{
bool quit = false;
while (!quit)
{
pollEvents();
int w, h;
SDL_GetWindowSize(sdlWindow, &w, &h);
if (displayFunc != NULL)
(((void *(*)(void))displayFunc)());
if (reshapeFunc != NULL)
(((void *(*)(int, int))reshapeFunc)(w, h));
if (visibilityFunc != NULL)
(((void *(*)(int))visibilityFunc)(1));
if (idleFunc != NULL)
(((void *(*)(void))idleFunc)());
}
SDL_DestroyWindow(sdlWindow);
SDL_Quit();
}
void FGAPIENTRY glutMainLoopEvent(void)
{
return;
}
void FGAPIENTRY glutSwapBuffers(void)
{
EmulatorConfig *config = getConfig();
switch (gGrp)
{
case GROUP_OUTRUN:
case GROUP_OUTRUN_TEST:
{
pollEvents();
}
}
blitStretch();
if (config->borderEnabled)
drawGameBorder(drawableW, drawableH, config->whiteBorderPercentage, config->blackBorderPercentage);
SDL_GL_SwapWindow(sdlWindow);
if (config->fpsLimiter)
frameTiming();
char windowTitle[512];
sprintf(windowTitle, "%s - FPS: %.2f", sdlGameTitle, calculateFps());
SDL_SetWindowTitle(sdlWindow, windowTitle);
}
int FGAPIENTRY glutGet(GLenum type)
{
if (type == 0x66)
return gWidth;
if (type == 0x67)
return gHeight;
return 0;
}
void FGAPIENTRY glutInitWindowSize(int width, int height)
{
return;
}
void FGAPIENTRY glutInitWindowPosition(int x, int y)
{
return;
}
int FGAPIENTRY glutExtensionSupported(const char *extension)
{
return SDL_GL_ExtensionSupported(extension);
}
void FGAPIENTRY glutSetCursor(int glutCursor)
{
if (strcmp(getConfig()->customCursor, "") == 0 && strcmp(getConfig()->touchCursor, "") == 0)
{
SDL_Cursor *cursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_DEFAULT);
SDL_SetCursor(cursor);
}
}
void FGAPIENTRY glutDisplayFunc(void (*callback)(void))
{
displayFunc = callback;
}
void FGAPIENTRY glutReshapeFunc(void (*callback)(int, int))
{
return;
// reshapeFunc = callback;
}
void FGAPIENTRY glutVisibilityFunc(void (*callback)(int))
{
visibilityFunc = callback;
}
void FGAPIENTRY glutIdleFunc(void (*callback)(void))
{
idleFunc = callback;
}
void FGAPIENTRY glutInitDisplayMode(unsigned int mode)
{
return;
}
void FGAPIENTRY glutGameModeString(const char *string)
{
return;
}
int FGAPIENTRY glutEnterGameMode(void)
{
return 0;
}
int FGAPIENTRY glutCreateWindow(const char *title)
{
return 1;
}
void FGAPIENTRY glutJoystickFunc(void (*callback)(unsigned int, int, int, int), int pollInterval)
{
return;
}
void FGAPIENTRY glutPostRedisplay(void)
{
return;
}
void FGAPIENTRY glutKeyboardFunc(void (*callback)(unsigned char, int, int))
{
return;
}
void FGAPIENTRY glutKeyboardUpFunc(void (*callback)(unsigned char, int, int))
{
return;
}
void FGAPIENTRY glutMouseFunc(void (*callback)(int, int, int, int))
{
return;
}
void FGAPIENTRY glutMotionFunc(void (*callback)(int, int))
{
return;
}
void FGAPIENTRY glutSpecialFunc(void (*callback)(int, int, int))
{
return;
}
void FGAPIENTRY glutSpecialUpFunc(void (*callback)(int, int, int))
{
return;
}
void FGAPIENTRY glutPassiveMotionFunc(void (*callback)(int, int))
{
return;
}
void FGAPIENTRY glutEntryFunc(void (*callback)(int))
{
return;
}
void FGAPIENTRY glutLeaveGameMode()
{
return;
}
void FGAPIENTRY glutSolidTeapot(double size)
{
return;
}
void FGAPIENTRY glutWireTeapot(double size)
{
return;
}
void FGAPIENTRY glutSolidSphere(double radius, GLint slices, GLint stacks)
{
return;
}
void FGAPIENTRY glutWireSphere(double radius, GLint slices, GLint stacks)
{
return;
}
void FGAPIENTRY glutWireCone(double base, double height, GLint slices, GLint stacks)
{
return;
}
void FGAPIENTRY glutSolidCone(double base, double height, GLint slices, GLint stacks)
{
return;
}
void FGAPIENTRY glutWireCube(double dSize)
{
return;
}
void FGAPIENTRY glutSolidCube(double dSize)
{
return;
}
int FGAPIENTRY glutBitmapWidth(void *fontID, int character)
{
int width = 0;
if (fontID == GLUT_BITMAP_9_BY_15)
width = 9;
return width;
}
void convertSurfaceTo1Bit(SDL_Surface *surface, uint8_t *outBitmap, int pitch)
{
SDL_LockSurface(surface);
for (int y = 0; y < surface->h; ++y)
{
uint8_t byte = 0;
int bit = 0;
int sdlY = surface->h - 1 - y;
Uint8 *row = (Uint8 *)surface->pixels + sdlY * surface->pitch;
for (int x = 0; x < surface->w; ++x)
{
if (row[x])
byte |= (1 << (7 - bit));
bit++;
if (bit == 8 || x == surface->w - 1)
{
outBitmap[y * pitch + x / 8] = byte;
byte = 0;
bit = 0;
}
}
}
SDL_UnlockSurface(surface);
}
void glutBitmapCharacter(void *fontID, int character)
{
GLint glColor[4];
glGetIntegerv(GL_CURRENT_COLOR, glColor);
SDL_Color sdlColor;
sdlColor.r = (Uint8)(glColor[0] * 255);
sdlColor.g = (Uint8)(glColor[1] * 255);
sdlColor.b = (Uint8)(glColor[2] * 255);
sdlColor.a = (Uint8)(glColor[3] * 255);
GLint glPos[4];
glGetIntegerv(GL_CURRENT_RASTER_POSITION, glPos);
if (penX != glPos[0])
penX = glPos[0];
penY = glPos[1];
SDL_Surface *glyph = TTF_RenderGlyph_Solid(font, character, sdlColor);
if (!glyph)
{
printf("Failed to render glyph: %s\n", SDL_GetError());
return;
}
int pitch = (glyph->w + 7) / 8;
uint8_t *bitmap = malloc(pitch * glyph->h);
convertSurfaceTo1Bit(glyph, bitmap, pitch);
GLint swbytes, lsbfirst, rowlen, skiprows, skippix, align;
glGetIntegerv(GL_UNPACK_SWAP_BYTES, &swbytes);
glGetIntegerv(GL_UNPACK_LSB_FIRST, &lsbfirst);
glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rowlen);
glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skiprows);
glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skippix);
glGetIntegerv(GL_UNPACK_ALIGNMENT, &align);
glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glBitmap(glyph->w, glyph->h, 0, 0, (float)(glyph->w), 0.0, bitmap);
glGetIntegerv(GL_CURRENT_RASTER_POSITION, glPos);
glPixelStorei(GL_UNPACK_SWAP_BYTES, swbytes);
glPixelStorei(GL_UNPACK_LSB_FIRST, lsbfirst);
glPixelStorei(GL_UNPACK_ROW_LENGTH, rowlen);
glPixelStorei(GL_UNPACK_SKIP_ROWS, skiprows);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, skippix);
glPixelStorei(GL_UNPACK_ALIGNMENT, align);
free(bitmap);
SDL_DestroySurface(glyph);
}
-504
View File
@@ -1,504 +0,0 @@
#ifndef __i386__
#define __i386__
#endif
#undef __x86_64__
#include <GL/freeglut.h>
#include <GL/freeglut_std.h>
#include <GL/glx.h>
#include <time.h>
#include <SDL2/SDL.h>
#include <dlfcn.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <unistd.h>
#include "config.h"
#include "fps_limiter.h"
#include "sdlcalls.h"
#include "border.h"
#include "resolution.h"
extern uint32_t gId;
extern SDL_Window *SDLwindow;
extern char SDLgameTitle[];
extern fps_limit fpsLimit;
bool GLUTGame = false;
void *displayFunc = NULL;
void *reshapeFunc = NULL;
void *visibilityFunc = NULL;
void *idleFunc = NULL;
void FGAPIENTRY glutInit(int *argcp, char **argv)
{
void FGAPIENTRY (*_glutInit)(int *argcp, char **argv) = dlsym(RTLD_NEXT, "glutInit");
if (*argcp > 1 && gId == SEGA_RACE_TV)
{
if (isTestMode())
{
EmulatorConfig *config = getConfig();
config->noSDL = 0;
printf("Forced to use SDL to make Test mode render fine.\n");
}
}
if (getConfig()->noSDL)
{
_glutInit(argcp, argv);
return;
}
GLUTGame = true;
initSDL(argcp, argv);
}
void FGAPIENTRY glutMainLoop(void)
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutMainLoop)(void) = dlsym(RTLD_NEXT, "glutMainLoop");
_glutMainLoop();
return;
}
bool quit = false;
while (!quit)
{
pollEvents();
int w, h;
SDL_GetWindowSize(SDLwindow, &w, &h);
if (displayFunc != NULL)
(((void *(*)(void))displayFunc)());
if (reshapeFunc != NULL)
(((void *(*)(int, int))reshapeFunc)(w, h));
if (visibilityFunc != NULL)
(((void *(*)(int))visibilityFunc)(1));
if (idleFunc != NULL)
(((void *(*)(void))idleFunc)());
}
SDL_DestroyWindow(SDLwindow);
SDL_Quit();
}
void FGAPIENTRY glutMainLoopEvent(void)
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutMainLoopEvent)(void) = dlsym(RTLD_NEXT, "glutMainLoopEvent");
_glutMainLoopEvent();
}
return;
}
void FGAPIENTRY glutSwapBuffers(void)
{
EmulatorConfig *config = getConfig();
if (config->borderEnabled)
drawGameBorder(config->width, config->height, config->whiteBorderPercentage, config->blackBorderPercentage);
if (config->noSDL)
{
void FGAPIENTRY (*_glutSwapBuffers)(void) = dlsym(RTLD_NEXT, "glutSwapBuffers");
_glutSwapBuffers();
return;
}
switch (gId)
{
case OUTRUN_2_SP_SDX:
case OUTRUN_2_SP_SDX_REVA:
case OUTRUN_2_SP_SDX_REVA_TEST:
case OUTRUN_2_SP_SDX_REVA_TEST2:
case OUTRUN_2_SP_SDX_TEST:
pollEvents();
}
SDL_GL_SwapWindow(SDLwindow);
if (config->fpsLimiter)
{
fpsLimit.frameStart = Clock_now();
FpsLimiter(&fpsLimit);
fpsLimit.frameEnd = Clock_now();
}
char windowTitle[512];
sprintf(windowTitle, "%s - FPS: %.2f", SDLgameTitle, calculateFps());
SDL_SetWindowTitle(SDLwindow, windowTitle);
}
int FGAPIENTRY glutGet(GLenum type)
{
if (getConfig()->noSDL)
{
int FGAPIENTRY (*_glutGet)(GLenum type) = dlsym(RTLD_NEXT, "glutGet");
return _glutGet(type);
}
if (type == 0x66)
return getConfig()->width;
if (type == 0x67)
return getConfig()->height;
return 0;
}
void FGAPIENTRY glutInitWindowSize(int width, int height)
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutInitWindowSize)(int width, int height) = dlsym(RTLD_NEXT, "glutInitWindowSize");
_glutInitWindowSize(width, height);
return;
}
SDL_SetWindowSize(SDLwindow, getConfig()->width, getConfig()->height);
}
void FGAPIENTRY glutInitWindowPosition(int x, int y)
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutInitWindowPosition)(int width, int height) = dlsym(RTLD_NEXT, "glutInitWindowPosition");
_glutInitWindowPosition(x, y);
return;
}
SDL_SetWindowPosition(SDLwindow, x, y);
}
int FGAPIENTRY glutExtensionSupported(const char *extension)
{
if (getConfig()->noSDL)
{
int FGAPIENTRY (*_glutExtensionSupported)(const char *extension) = dlsym(RTLD_NEXT, "glutExtensionSupported");
return _glutExtensionSupported(extension);
}
return SDL_GL_ExtensionSupported(extension);
}
void FGAPIENTRY glutSetCursor(int glutCursor)
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutSetCursor)(int glutCursor) = dlsym(RTLD_NEXT, "glutSetCursor");
if(strcmp(getConfig()->customCursor, "") == 0)
_glutSetCursor(glutCursor);
return;
}
if (strcmp(getConfig()->customCursor, "") == 0)
{
SDL_Cursor *cursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
SDL_SetCursor(cursor);
}
}
void FGAPIENTRY glutDisplayFunc(void (*callback)(void))
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutDisplayFunc)(void (*callback)(void)) = dlsym(RTLD_NEXT, "glutDisplayFunc");
_glutDisplayFunc(callback);
return;
}
displayFunc = callback;
}
void FGAPIENTRY glutReshapeFunc(void (*callback)(int, int))
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutReshapeFunc)(void (*callback)(int, int)) = dlsym(RTLD_NEXT, "glutReshapeFunc");
_glutReshapeFunc(callback);
return;
}
reshapeFunc = callback;
}
void FGAPIENTRY glutVisibilityFunc(void (*callback)(int))
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutVisibilityFunc)(void (*callback)(int)) = dlsym(RTLD_NEXT, "glutVisibilityFunc");
_glutVisibilityFunc(callback);
return;
}
visibilityFunc = callback;
}
void FGAPIENTRY glutIdleFunc(void (*callback)(void))
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutIdleFunc)(void (*callback)(void)) = dlsym(RTLD_NEXT, "glutIdleFunc");
_glutIdleFunc(callback);
return;
}
idleFunc = callback;
}
void FGAPIENTRY glutInitDisplayMode(unsigned int mode)
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutInitDisplayMode)(unsigned int mode) = dlsym(RTLD_NEXT, "glutInitDisplayMode");
_glutInitDisplayMode(mode);
return;
}
return;
}
void FGAPIENTRY glutGameModeString(const char *string)
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutGameModeString)(const char *string) = dlsym(RTLD_NEXT, "glutGameModeString");
_glutGameModeString(string);
return;
}
return;
}
int FGAPIENTRY glutEnterGameMode(void)
{
if (getConfig()->noSDL)
{
int FGAPIENTRY (*_glutEnterGameMode)(void) = dlsym(RTLD_NEXT, "glutEnterGameMode");
char gameTitle[256] = {0};
strcat(gameTitle, getGameName());
glutCreateWindow(gameTitle);
return 1;
}
return 0;
}
int FGAPIENTRY glutCreateWindow(const char *title)
{
if (getConfig()->noSDL)
{
int FGAPIENTRY (*_glutCreateWindow)(const char *title) = dlsym(RTLD_NEXT, "glutCreateWindow");
return _glutCreateWindow(title);
}
return 1;
}
void FGAPIENTRY glutJoystickFunc(void (*callback)(unsigned int, int, int, int), int pollInterval)
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutJoystickFunc)(void (*callback)(unsigned int, int, int, int), int pollInterval) =
dlsym(RTLD_NEXT, "glutJoystickFunc");
_glutJoystickFunc(callback, pollInterval);
return;
}
return;
}
void FGAPIENTRY glutPostRedisplay(void)
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutPostRedisplay)(void) = dlsym(RTLD_NEXT, "glutPostRedisplay");
_glutPostRedisplay();
return;
}
return;
}
void FGAPIENTRY glutKeyboardFunc(void (*callback)(unsigned char, int, int))
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutKeyboardFunc)(void (*callback)(unsigned char, int, int)) =
dlsym(RTLD_NEXT, "glutKeyboardFunc");
_glutKeyboardFunc(callback);
return;
}
return;
}
void FGAPIENTRY glutKeyboardUpFunc(void (*callback)(unsigned char, int, int))
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutKeyboardUpFunc)(void (*callback)(unsigned char, int, int)) =
dlsym(RTLD_NEXT, "glutKeyboardUpFunc");
_glutKeyboardUpFunc(callback);
return;
}
return;
}
void FGAPIENTRY glutMouseFunc(void (*callback)(int, int, int, int))
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutMouseFunc)(void (*callback)(int, int, int, int)) = dlsym(RTLD_NEXT, "glutMouseFunc");
_glutMouseFunc(callback);
return;
}
return;
}
void FGAPIENTRY glutMotionFunc(void (*callback)(int, int))
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutMotionFunc)(void (*callback)(int, int)) = dlsym(RTLD_NEXT, "glutMotionFunc");
_glutMotionFunc(callback);
return;
}
return;
}
void FGAPIENTRY glutSpecialFunc(void (*callback)(int, int, int))
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutSpecialFunc)(void (*callback)(int, int, int)) = dlsym(RTLD_NEXT, "glutSpecialFunc");
_glutSpecialFunc(callback);
return;
}
return;
}
void FGAPIENTRY glutSpecialUpFunc(void (*callback)(int, int, int))
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutSpecialUpFunc)(void (*callback)(int, int, int)) = dlsym(RTLD_NEXT, "glutSpecialUpFunc");
_glutSpecialUpFunc(callback);
return;
}
return;
}
void FGAPIENTRY glutPassiveMotionFunc(void (*callback)(int, int))
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutPassiveMotionFunc)(void (*callback)(int, int)) =
dlsym(RTLD_NEXT, "glutPassiveMotionFunc");
_glutPassiveMotionFunc(callback);
return;
}
return;
}
void FGAPIENTRY glutEntryFunc(void (*callback)(int))
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutEntryFunc)(void (*callback)(int)) = dlsym(RTLD_NEXT, "glutEntryFunc");
_glutEntryFunc(callback);
return;
}
return;
}
void FGAPIENTRY glutLeaveGameMode()
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutLeaveGameMode)() = dlsym(RTLD_NEXT, "glutLeaveGameMode");
_glutLeaveGameMode();
return;
}
return;
}
void FGAPIENTRY glutSolidTeapot(double size)
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutSolidTeapot)(double size) = dlsym(RTLD_NEXT, "glutSolidTeapot");
_glutSolidTeapot(size);
return;
}
return;
}
void FGAPIENTRY glutWireTeapot(double size)
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutWireTeapot)(double size) = dlsym(RTLD_NEXT, "glutWireTeapot");
_glutWireTeapot(size);
return;
}
return;
}
void FGAPIENTRY glutSolidSphere(double radius, GLint slices, GLint stacks)
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutSolidSphere)(double radius, GLint slices, GLint stacks) =
dlsym(RTLD_NEXT, "glutSolidSphere");
_glutSolidSphere(radius, slices, stacks);
return;
}
return;
}
void FGAPIENTRY glutWireSphere(double radius, GLint slices, GLint stacks)
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutWireSphere)(double radius, GLint slices, GLint stacks) =
dlsym(RTLD_NEXT, "glutWireSphere");
_glutWireSphere(radius, slices, stacks);
return;
}
return;
}
void FGAPIENTRY glutWireCone(double base, double height, GLint slices, GLint stacks)
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutWireCone)(double base, double height, GLint slices, GLint stacks) =
dlsym(RTLD_NEXT, "glutWireCone");
_glutWireCone(base, height, slices, stacks);
return;
}
return;
}
void FGAPIENTRY glutSolidCone(double base, double height, GLint slices, GLint stacks)
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutSolidCone)(double base, double height, GLint slices, GLint stacks) =
dlsym(RTLD_NEXT, "glutSolidCone");
_glutSolidCone(base, height, slices, stacks);
return;
}
return;
}
void FGAPIENTRY glutWireCube(double dSize)
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutWireCube)(double dSize) = dlsym(RTLD_NEXT, "glutWireCube");
_glutWireCube(dSize);
return;
}
return;
}
void FGAPIENTRY glutSolidCube(double dSize)
{
if (getConfig()->noSDL)
{
void FGAPIENTRY (*_glutSolidCube)(double dSize) = dlsym(RTLD_NEXT, "glutSolidCube");
_glutSolidCube(dSize);
return;
}
return;
}
+171
View File
@@ -0,0 +1,171 @@
#ifndef __i386__
#define __i386__
#endif
#undef __x86_64__
#define GL_GLEXT_PROTOTYPES
#include <GL/glx.h>
#include <stdbool.h>
#include <dlfcn.h>
#include <SDL3/SDL.h>
#include <stdlib.h>
#include "blitStretching.h"
#include "border.h"
#include "config.h"
#include "flowControl.h"
#include "fpsLimiter.h"
#include "sdlCalls.h"
#include "touchScreen.h"
bool sdlGame = false;
extern uint32_t gId;
extern int gGrp;
extern SDL_Window *sdlWindow;
extern SDL_GLContext sdlContext;
extern Display *x11Display;
extern char sdlGameTitle[];
double local_fps = 0.0;
bool createContextCalled = false;
int ctxCnt = 0;
void glXSwapBuffers(Display *dpy, GLXDrawable drawable)
{
void (*_glXSwapBuffers)(Display *dpy, GLXDrawable drawable) = dlsym(RTLD_NEXT, "glXSwapBuffers");
EmulatorConfig *config = getConfig();
if (config->borderEnabled)
drawGameBorder(config->width, config->height, config->whiteBorderPercentage, config->blackBorderPercentage);
blitStretch();
pollEvents();
SDL_GL_SwapWindow(sdlWindow);
if (config->fpsLimiter)
frameTiming();
char windowTitle[512];
local_fps = calculateFps();
sprintf(windowTitle, "%s - FPS: %.2f", sdlGameTitle, local_fps);
SDL_SetWindowTitle(sdlWindow, windowTitle);
}
GLXContext glXCreateContext(Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct)
{
GLXContext (*_glXCreateContext)(Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct) =
dlsym(RTLD_NEXT, "glXCreateContext");
GLXContext ctx;
if (ctxCnt == 0)
ctx = (GLXContext)sdlContext;
else
ctx = _glXCreateContext(dpy, vis, shareList, direct);
ctxCnt++;
return ctx;
}
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");
char *__GLX_VENDOR_LIBRARY_NAME = getenv("__GLX_VENDOR_LIBRARY_NAME");
char *__NV_PRIME_RENDER_OFFLOAD = getenv("__NV_PRIME_RENDER_OFFLOAD");
if (__GLX_VENDOR_LIBRARY_NAME == NULL)
__GLX_VENDOR_LIBRARY_NAME = " ";
if (__NV_PRIME_RENDER_OFFLOAD == NULL)
__NV_PRIME_RENDER_OFFLOAD = " ";
if (gGrp == GROUP_HOD4 || gGrp == GROUP_HOD4_SP || gId == THE_HOUSE_OF_THE_DEAD_EX || gId == TOO_SPICY || gId == QUIZ_AXA || gId == QUIZ_AXA_LIVE)
{
if (strcmp(__GLX_VENDOR_LIBRARY_NAME, "nvidia") == 0 && strcmp(__NV_PRIME_RENDER_OFFLOAD, "1") == 0)
{
for (int i = 0; attrib_list[i] != None; i += 2)
{
if (attrib_list[i] == GLX_DOUBLEBUFFER || attrib_list[i] == GLX_DRAWABLE_TYPE)
{
int *ptr = (int *)&attrib_list[i + 1];
patchMemoryFromString((size_t)ptr, "01");
}
}
}
}
return _glXChooseFBConfig(dpy, screen, attrib_list, nelements);
}
GLXPbuffer glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list)
{
int pbufferAttribs[] = {
GLX_PBUFFER_WIDTH, width, GLX_PBUFFER_HEIGHT, height, GLX_PRESERVED_CONTENTS, true, GLX_LARGEST_PBUFFER, true, None};
return glXCreatePbuffer(dpy, config, pbufferAttribs);
}
void glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf)
{
glXDestroyPbuffer(dpy, pbuf);
}
GLXFBConfigSGIX *glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements)
{
int gId = getConfig()->crc32;
char *__GLX_VENDOR_LIBRARY_NAME = getenv("__GLX_VENDOR_LIBRARY_NAME");
char *__NV_PRIME_RENDER_OFFLOAD = getenv("__NV_PRIME_RENDER_OFFLOAD");
if (__GLX_VENDOR_LIBRARY_NAME == NULL)
__GLX_VENDOR_LIBRARY_NAME = " ";
if (__NV_PRIME_RENDER_OFFLOAD == NULL)
__NV_PRIME_RENDER_OFFLOAD = " ";
if (gGrp == GROUP_ID4_EXP || gGrp == GROUP_ID4_JAP)
{
if (strcmp(__GLX_VENDOR_LIBRARY_NAME, "nvidia") == 0 && strcmp(__NV_PRIME_RENDER_OFFLOAD, "1") == 0)
{
for (int i = 0; attrib_list[i] != None; i += 2)
{
if (attrib_list[i] == GLX_DOUBLEBUFFER)
{
int *ptr = (int *)&attrib_list[i + 1];
patchMemoryFromString((size_t)ptr, "01");
}
}
}
}
return glXChooseFBConfig(dpy, screen, attrib_list, nelements);
}
int glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value)
{
return glXGetFBConfigAttrib(dpy, config, attribute, value);
}
GLXContext glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct)
{
return glXCreateNewContext(dpy, config, render_type, share_list, direct);
}
Display *glXGetCurrentDisplay(void)
{
return x11Display;
}
int glXGetVideoSyncSGI(uint *count)
{
static unsigned int frameCount = 0;
*count = (frameCount++) / 2;
return 0;
}
int glXGetRefreshRateSGI(unsigned int *rate)
{
*rate = 60;
return 0;
}
int glXSwapIntervalSGI(int interval)
{
return 0;
}
-418
View File
@@ -1,418 +0,0 @@
#define GL_GLEXT_PROTOTYPES
#ifndef __i386__
#define __i386__
#include <GL/gl.h>
#include <SDL2/SDL_mutex.h>
#include <SDL2/SDL_video.h>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <stdint.h>
#include <time.h>
#endif
#undef __x86_64__
#include <GL/glx.h>
#include <GL/glxext.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <SDL2/SDL.h>
#include <sys/time.h>
#include <stdio.h>
#include "fps_limiter.h"
#include "sdlcalls.h"
#include "patch.h"
#include "config.h"
#include "border.h"
bool sdlGame = false;
extern uint32_t gId;
extern SDL_Window *SDLwindow;
extern SDL_GLContext SDLcontext;
extern char SDLgameTitle[];
extern fps_limit fpsLimit;
extern Window window;
void glXSwapBuffers(Display *dpy, GLXDrawable drawable)
{
void (*_glXSwapBuffers)(Display *dpy, GLXDrawable drawable) = dlsym(RTLD_NEXT, "glXSwapBuffers");
EmulatorConfig *config = getConfig();
if (config->borderEnabled)
drawGameBorder(config->width, config->height, config->whiteBorderPercentage, config->blackBorderPercentage);
if (getConfig()->noSDL)
{
switch (gId)
{
case OUTRUN_2_SP_SDX:
case OUTRUN_2_SP_SDX_REVA:
case OUTRUN_2_SP_SDX_REVA_TEST:
case OUTRUN_2_SP_SDX_REVA_TEST2:
case OUTRUN_2_SP_SDX_TEST:
{
XEvent event;
while (XPending(dpy))
{
XNextEvent(dpy, &event);
}
}
}
}
else
{
pollEvents();
}
if (getConfig()->noSDL)
{
_glXSwapBuffers(dpy, drawable);
}
else
{
SDL_GL_SwapWindow(SDLwindow);
}
if (getConfig()->fpsLimiter)
{
fpsLimit.frameStart = Clock_now();
FpsLimiter(&fpsLimit);
fpsLimit.frameEnd = Clock_now();
}
if (getConfig()->noSDL)
{
XStoreName(dpy, window, "");
return;
}
char windowTitle[512];
sprintf(windowTitle, "%s - FPS: %.2f", SDLgameTitle, calculateFps());
SDL_SetWindowTitle(SDLwindow, windowTitle);
}
int glxSDLmyCreateWindow(int *param1)
{
initSDL(0, 0);
char *buf = malloc(512);
memset(buf, '\0', 512);
// param1[0x17] = (intptr_t)(void *)buf; // window;
sdlGame = true;
return 1;
}
static int nVidiaAttribs[] = {GLX_RGBA,
GLX_DOUBLEBUFFER,
GLX_RED_SIZE,
8,
GLX_GREEN_SIZE,
8,
GLX_BLUE_SIZE,
8,
GLX_ALPHA_SIZE,
8,
GLX_DEPTH_SIZE,
16,
GLX_STENCIL_SIZE,
8,
None};
XVisualInfo *glXChooseVisual(Display *dpy, int screen, int *attribList)
{
XVisualInfo *(*_glXChooseVisual)(Display *dpy, int screen, int *attribList) = dlsym(RTLD_NEXT, "glXChooseVisual");
if (sdlGame)
return 0;
if (getConfig()->GPUVendor == NVIDIA_GPU)
{
return _glXChooseVisual(dpy, screen, nVidiaAttribs);
}
return _glXChooseVisual(dpy, screen, attribList);
}
void GLAPIENTRY openglDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
const GLchar *message, const void *userParam)
{
if (id == 1099)
return;
// Print the debug message details
printf("OpenGL Debug Message:\n");
printf("Source: 0x%x\n", source);
printf("Type: 0x%x\n", type);
printf("ID: %u\n", id);
printf("Severity: 0x%x\n", severity);
printf("Message: %s\n", message);
// You can filter based on severity or other attributes if needed
if (severity == GL_DEBUG_SEVERITY_HIGH)
{
printf("This is a high severity error!\n");
}
}
GLXContext glXCreateContext(Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct)
{
GLXContext (*_glXCreateContext)(Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct) =
dlsym(RTLD_NEXT, "glXCreateContext");
if (sdlGame)
{
return SDLcontext;
}
GLXContext ctx = _glXCreateContext(dpy, vis, shareList, direct);
if (getConfig()->showDebugMessages)
{
// Enable OpenGL debug output
glEnable(GL_DEBUG_OUTPUT);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); // Make the callback synchronous
glDebugMessageCallback(openglDebugCallback, NULL);
}
return ctx;
}
GLXContext glXGetCurrentContext()
{
GLXContext (*_glXGetCurrentContext)() = dlsym(RTLD_NEXT, "glXGetCurrentContext");
if (sdlGame)
return SDLcontext;
return _glXGetCurrentContext();
}
GLXPbuffer glXCreatePbuffer(Display *dpy, GLXFBConfig config, const int *attrib_list)
{
GLXPbuffer (*_glXCreatePbuffer)(Display *dpy, GLXFBConfig config, const int *attrib_list) =
dlsym(RTLD_NEXT, "glXCreatePbuffer");
if (sdlGame)
return 0;
return _glXCreatePbuffer(dpy, config, attrib_list);
}
void glXDestroyContext(Display *dpy, GLXContext ctx)
{
void (*_glXDestroyContext)(Display *dpy, GLXContext ctx) = dlsym(RTLD_NEXT, "glXDestroyContext");
if (sdlGame)
return;
_glXDestroyContext(dpy, ctx);
}
void glXDestroyPbuffer(Display *dpy, GLXPbuffer pbuf)
{
void (*_glXDestroyPbuffer)(Display *dpy, GLXPbuffer pbuf) = dlsym(RTLD_NEXT, "glXDestroyPbuffer");
if (sdlGame)
return;
_glXDestroyPbuffer(dpy, pbuf);
}
XVisualInfo *glXGetVisualFromFBConfig(Display *dpy, GLXFBConfig config)
{
XVisualInfo *(*_glXGetVisualFromFBConfig)(Display *dpy, GLXFBConfig config) =
dlsym(RTLD_NEXT, "glXGetVisualFromFBConfig");
if (sdlGame)
return 0;
return _glXGetVisualFromFBConfig(dpy, config);
}
Bool glXMakeCurrent(Display *dpy, GLXDrawable drawable, GLXContext ctx)
{
Bool (*_glXMakeCurrent)(Display *dpy, GLXDrawable drawable, GLXContext ctx) = dlsym(RTLD_NEXT, "glXMakeCurrent");
if (sdlGame)
{
SDL_GL_MakeCurrent(SDLwindow, SDLcontext);
return 1;
}
return _glXMakeCurrent(dpy, drawable, ctx);
}
Bool glXQueryExtension(Display *dpy, int *errorBase, int *eventBase)
{
Bool (*_glXQueryExtension)(Display *dpy, int *errorBase, int *eventBase) = dlsym(RTLD_NEXT, "glXQueryExtension");
if (sdlGame)
return 0;
return _glXQueryExtension(dpy, errorBase, eventBase);
}
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");
char *__GLX_VENDOR_LIBRARY_NAME = getenv("__GLX_VENDOR_LIBRARY_NAME");
char *__NV_PRIME_RENDER_OFFLOAD = getenv("__NV_PRIME_RENDER_OFFLOAD");
if (__GLX_VENDOR_LIBRARY_NAME == NULL)
__GLX_VENDOR_LIBRARY_NAME = " ";
if (__NV_PRIME_RENDER_OFFLOAD == NULL)
__NV_PRIME_RENDER_OFFLOAD = " ";
switch (gId)
{
case THE_HOUSE_OF_THE_DEAD_4_REVA:
case THE_HOUSE_OF_THE_DEAD_4_REVB:
case THE_HOUSE_OF_THE_DEAD_4_REVC:
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)
{
for (int i = 0; attrib_list[i] != None; i += 2)
{
if (attrib_list[i] == GLX_DOUBLEBUFFER)
{
int *ptr = (int *)&attrib_list[i + 1];
patchMemory((intptr_t)ptr, "01");
setVariable((intptr_t)ptr, GLX_DONT_CARE);
}
}
}
}
}
return _glXChooseFBConfig(dpy, screen, attrib_list, nelements);
}
GLXContext glXCreateNewContext(Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct)
{
GLXContext (*_glXCreateNewContext)(Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list,
Bool direct) = dlsym(RTLD_NEXT, "glXCreateNewContext");
GLXContext ctx = _glXCreateNewContext(dpy, config, render_type, share_list, direct);
if (getConfig()->showDebugMessages)
{
// Enable OpenGL debug output
glEnable(GL_DEBUG_OUTPUT);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
glDebugMessageCallback(openglDebugCallback, NULL);
}
return ctx;
}
GLXPbuffer glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height,
int *attrib_list)
{
if (sdlGame)
return 0;
int pbufferAttribs[] = {GLX_PBUFFER_WIDTH,
width,
GLX_PBUFFER_HEIGHT,
height,
GLX_PRESERVED_CONTENTS,
true,
GLX_LARGEST_PBUFFER,
true,
None};
return glXCreatePbuffer(dpy, config, pbufferAttribs);
}
void glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf)
{
if (sdlGame)
return;
glXDestroyPbuffer(dpy, pbuf);
}
GLXFBConfigSGIX *glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements)
{
if (sdlGame)
return 0;
int gId = getConfig()->crc32;
char *__GLX_VENDOR_LIBRARY_NAME = getenv("__GLX_VENDOR_LIBRARY_NAME");
char *__NV_PRIME_RENDER_OFFLOAD = getenv("__NV_PRIME_RENDER_OFFLOAD");
if (__GLX_VENDOR_LIBRARY_NAME == NULL)
__GLX_VENDOR_LIBRARY_NAME = " ";
if (__NV_PRIME_RENDER_OFFLOAD == NULL)
__NV_PRIME_RENDER_OFFLOAD = " ";
switch (gId)
{
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)
{
for (int i = 0; attrib_list[i] != None; i += 2)
{
if (attrib_list[i] == GLX_DOUBLEBUFFER)
{
int *ptr = (int *)&attrib_list[i + 1];
patchMemory((intptr_t)ptr, "01");
}
}
}
}
}
return glXChooseFBConfig(dpy, screen, attrib_list, nelements);
}
int glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value)
{
if (sdlGame)
return 0;
return glXGetFBConfigAttrib(dpy, config, attribute, value);
}
GLXContext glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list,
Bool direct)
{
if (sdlGame)
return 0;
return glXCreateNewContext(dpy, config, render_type, share_list, direct);
}
const char *glXGetClientString(Display *dpy, int name)
{
const char *(*_glXGetClientString)(Display *dpy, int name) = dlsym(RTLD_NEXT, "glXGetClientString");
if (sdlGame)
return "SDLGame";
return _glXGetClientString(dpy, name);
}
Display *glXGetCurrentDisplay(void)
{
Display *(*_glXGetCurrentDisplay)(void) = dlsym(RTLD_NEXT, "glXGetCurrentDisplay");
if (sdlGame)
return (Display *)SDLwindow;
return _glXGetCurrentDisplay();
}
const char *glXQueryExtensionsString(Display *dpy, int screen)
{
const char *(*_glXQueryExtensionsString)(Display *dpy, int screen) = dlsym(RTLD_NEXT, "glXQueryExtensionsString");
if (sdlGame)
return "";
return _glXQueryExtensionsString(dpy, screen);
}
const char *glXQueryServerString(Display *dpy, int screen, int name)
{
const char *(*_glXQueryServerString)(Display *dpy, int screen, int name) = dlsym(RTLD_NEXT, "glXQueryServerString");
if (sdlGame)
return "";
return _glXQueryServerString(dpy, screen, name);
}
int glXGetVideoSyncSGI(uint *count)
{
static unsigned int frameCount = 0;
*count = (frameCount++) / 2;
return 0;
}
int glXGetRefreshRateSGI(unsigned int *rate)
{
*rate = 60;
return 0;
}
int glXSwapIntervalSGI(int interval)
{
return 0;
}
@@ -3,8 +3,10 @@
#endif
#undef __x86_64__
#include <GL/gl.h>
#include <SDL2/SDL.h>
#include <SDL3/SDL.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "config.h"
@@ -15,7 +17,7 @@ int getGPUVendorID()
int vendorId;
EmulatorConfig *config = getConfig();
gettingGPUVendor = true;
if (SDL_Init(SDL_INIT_VIDEO) < 0)
if (!SDL_Init(SDL_INIT_VIDEO))
{
fprintf(stderr, "SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
exit(1);
@@ -23,11 +25,10 @@ int getGPUVendorID()
uint32_t windowFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN;
SDL_Window *window =
SDL_CreateWindow("OpenGL", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, windowFlags);
SDL_Window *window = SDL_CreateWindow("OpenGL", 640, 480, windowFlags);
if (!window)
{
fprintf(stderr, "Window could not be created! SDL_Error: %s\n", SDL_GetError());
fprintf(stderr, "Here Window could not be created! SDL_Error: %s\n", SDL_GetError());
exit(1);
}
+278 -387
View File
@@ -1,78 +1,50 @@
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#include <libgen.h>
#include <stdint.h>
#include <time.h>
#endif
#ifndef __i386__
#define __i386__
#endif
#undef __x86_64__
#include <arpa/inet.h>
#include <dlfcn.h>
#include <link.h>
#include <linux/sockios.h>
#include <math.h>
#include <netinet/in.h>
#include <semaphore.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <ucontext.h>
#include <unistd.h>
#include <signal.h>
#include <ifaddrs.h>
#include <ctype.h>
#include <dirent.h>
#include <link.h>
#include <math.h>
#include <net/if.h>
#include <signal.h>
#include <SDL3/SDL.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdint.h>
#include <sys/ioctl.h>
#include "baseboard.h"
#include "cardReader.h"
#include "baseBoard.h"
#include "config.h"
#include "driveboard.h"
#include "driveBoard.h"
#include "eeprom.h"
#include "gpuvendor.h"
#include "input.h"
#include "evdevInput.h"
#include "fpsLimiter.h"
#include "gpuVendor.h"
#include "hook.h"
#include "jvs.h"
#include "patch.h"
#include "pcidata.h"
#include "resolution.h"
#include "rideboard.h"
#include "securityboard.h"
#include "shader_patches.h"
#include "fps_limiter.h"
#include "evdevinput.h"
#include "card_reader.h"
#include "touchscreen.h"
#include "log.h"
#include "resources/font.h"
#include "patch.h"
#include "pciData.h"
#include "resolution.h"
#include "resources/logo.h"
#include "resources/font.h"
#include "rideBoard.h"
#include "sdlCalls.h"
#include "sdlInput.h"
#include "securityBoard.h"
#include "shaderCache.h"
#include "touchScreen.h"
#define HOOK_FILE_NAME "/dev/zero"
#define BASEBOARD 0
#define EEPROM 1
#define SERIAL0 2
#define SERIAL1 3
#define PCI_CARD_000 4
#define CPUINFO 0
#define OSRELEASE 1
#define PCI_CARD_1F0 2
#define FILE_RW1 3
#define FILE_RW2 4
#define FILE_HARLEY 5
#define FILE_FONT_ABC 6
#define FILE_FONT_TGA 7
#define FILE_LOGO_TGA 8
#define ROUTE 9
int hooks[5] = {-1, -1, -1, -1, -1};
DeviceType hooks[5] = {-1, -1, -1, -1, -1};
FILE *fileHooks[10] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
int fileRead[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
FileTypes fileRead[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
char envpath[100];
int fontABCidx = 0;
@@ -82,14 +54,21 @@ int logoTGAidx = 0;
uint32_t elf_crc = 0;
uint32_t gId = 0;
int gGrp = -1;
int gWidth;
int gHeight;
extern int hummerExtremeShaderFileIndex;
extern bool cachedShaderFilesLoaded;
extern char vf5StageNameAbbr[5];
bool phShowCursorInGame = false;
extern fps_limit fpsLimit;
extern FpsLimit fpsLimit;
Controllers controllers = {0};
extern SDLControllers sdlJoysticks;
char *configFolder = {0};
static int callback(struct dl_phdr_info *info, size_t size, void *data);
@@ -114,73 +93,92 @@ static void handleSegfault(int signal, siginfo_t *info, void *ptr)
// Get the address of the instruction causing the segfault
// uint8_t *code = (uint8_t *)ctx->uc_mcontext.gregs[REG_EIP];
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
uint8_t *code = (uint8_t *)(size_t)eip_value; // Use uintptr_t to ensure proper alignment
switch (*code)
{
case 0xED: // IN
case 0xED: // IN
{
// Get the port number from the EDX register
uint16_t port = ctx->uc_mcontext.gregs[REG_EDX] & 0xFFFF;
// The first port called is usually random, but everything after that
// is a constant offset, so this is a hack to fix that.
// When run as sudo it works fine!?
if (basePortAddress == 0xFFFF)
basePortAddress = port;
// Adjust the port number if necessary
if (port > 0x38)
port = port - basePortAddress;
// Call the security board input function with the port number and data
securityBoardIn(port, (uint32_t *)&(ctx->uc_mcontext.gregs[REG_EAX]));
ctx->uc_mcontext.gregs[REG_EIP]++;
return;
}
break;
case 0xE7: // OUT IMMEDIATE
{
// Increment the instruction pointer by two to skip over this instruction
ctx->uc_mcontext.gregs[REG_EIP] += 2;
return;
}
break;
case 0xE6: // OUT IMMEDIATE
{
// Increment the instruction pointer by two to skip over this instruction
ctx->uc_mcontext.gregs[REG_EIP] += 2;
return;
}
break;
case 0xEE: // OUT
{
uint16_t port = ctx->uc_mcontext.gregs[REG_EDX] & 0xFFFF;
uint8_t data = ctx->uc_mcontext.gregs[REG_EAX] & 0xFF;
ctx->uc_mcontext.gregs[REG_EIP]++;
return;
}
break;
case 0xEF: // OUT
{
uint16_t port = ctx->uc_mcontext.gregs[REG_EDX] & 0xFFFF;
ctx->uc_mcontext.gregs[REG_EIP]++;
return;
}
break;
default:
// repeat_printf("Skipping SEGFAULT %X\n", *code);
log_warn("Skipping SEGFAULT %X\n", *code);
ctx->uc_mcontext.gregs[REG_EIP]++;
// abort();
}
}
uint32_t getCrc32(const char *s, ssize_t n)
{
uint32_t crc = 0xFFFFFFFF;
for (size_t i = 0; i < n; i++)
{
// Get the port number from the EDX register
uint16_t port = ctx->uc_mcontext.gregs[REG_EDX] & 0xFFFF;
// The first port called is usually random, but everything after that
// is a constant offset, so this is a hack to fix that.
// When run as sudo it works fine!?
if (basePortAddress == 0xFFFF)
basePortAddress = port;
// Adjust the port number if necessary
if (port > 0x38)
port = port - basePortAddress;
// Call the security board input function with the port number and data
securityBoardIn(port, (uint32_t *)&(ctx->uc_mcontext.gregs[REG_EAX]));
ctx->uc_mcontext.gregs[REG_EIP]++;
return;
}
break;
case 0xE7: // OUT IMMEDIATE
{
// Increment the instruction pointer by two to skip over this instruction
ctx->uc_mcontext.gregs[REG_EIP] += 2;
return;
}
break;
case 0xE6: // OUT IMMEDIATE
{
// Increment the instruction pointer by two to skip over this instruction
ctx->uc_mcontext.gregs[REG_EIP] += 2;
return;
}
break;
case 0xEE: // OUT
{
uint16_t port = ctx->uc_mcontext.gregs[REG_EDX] & 0xFFFF;
uint8_t data = ctx->uc_mcontext.gregs[REG_EAX] & 0xFF;
ctx->uc_mcontext.gregs[REG_EIP]++;
return;
}
break;
case 0xEF: // OUT
{
uint16_t port = ctx->uc_mcontext.gregs[REG_EDX] & 0xFFFF;
ctx->uc_mcontext.gregs[REG_EIP]++;
return;
}
break;
default:
// repeat_printf("Skipping SEGFAULT %X\n", *code);
log_warn("Skipping SEGFAULT %X\n", *code);
ctx->uc_mcontext.gregs[REG_EIP]++;
// abort();
char ch = s[i];
for (size_t j = 0; j < 8; j++)
{
uint32_t b = (ch ^ crc) & 1;
crc >>= 1;
if (b)
crc = crc ^ 0xEDB88320;
ch >>= 1;
}
}
return ~crc;
}
/**
@@ -276,6 +274,9 @@ bool checkOS_ID()
*/
void __attribute__((constructor)) hook_init()
{
// We force x11 for SDL so the window do not scale in wayland.
setenv("SDL_VIDEODRIVER", "x11", 1);
// Get offsets of the Game's ELF and calculate CRC32.
dl_iterate_phdr(callback, NULL);
@@ -289,23 +290,25 @@ void __attribute__((constructor)) hook_init()
initConfig(envPath);
gId = getConfig()->crc32;
gGrp = getConfig()->gameGroup;
gWidth = getConfig()->width;
gHeight = getConfig()->height;
if (!checkOS_ID())
{
log_warn("Seems like you're not in debian-like system. There might be unexpected issues.");
}
if (getConfig()->fpsLimiter == 1)
{
fpsLimit.targetFrameTime = 1000000 / getConfig()->fpsTarget;
fpsLimit.frameEnd = Clock_now();
}
initFpsLimiter();
getGPUVendor();
if (initPatch() != 0)
exit(1);
if (initSDL() != 0)
exit(1);
if (initResolutionPatches() != 0)
exit(1);
@@ -333,24 +336,25 @@ void __attribute__((constructor)) hook_init()
exit(1);
}
if (getConfig()->emulateCardreader)
if (getConfig()->emulateHW210CardReader)
{
if (initCardReader() != 0)
exit(1);
}
if (initInput() != 0)
envPath = getenv("LINDBERGH_CONTROLS_PATH");
if (initSdlInput(envPath) != 0)
exit(1);
if (initControllers(&controllers) != 0)
if (initEvdevControllers(&controllers) != 0)
exit(1);
securityBoardSetDipResolution(getConfig()->width, getConfig()->height);
printf("\nSEGA Lindbergh Emulator\nBy the Lindbergh Development Team 2025\n\n");
printf(" GAME: %s\n", getGameName());
printf(" GAME ID: %s\n", getGameID());
printf(" DVP: %s\n", getDVPName());
printf(" GAME ID: %s\n", getGameId());
printf(" DVP: %s\n", getDvpName());
printf(" GPU VENDOR: %s\n", getConfig()->GPUVendorString);
for (int i = 0; i < controllers.count; i++)
@@ -362,25 +366,29 @@ void __attribute__((constructor)) hook_init()
}
printf("\n");
switch (gId)
for (int i = 0; i < MAX_JOYSTICKS; i++)
{
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)
SDL_Joystick *joy = NULL;
if (sdlJoysticks.controllers[i])
joy = SDL_GetGamepadJoystick(sdlJoysticks.controllers[i]);
else if (sdlJoysticks.joysticks[i])
joy = sdlJoysticks.joysticks[i];
if (joy != NULL)
printf(" SDL CONTROLLER %d: %s\n", i, SDL_GetJoystickName(joy));
}
printf("\n");
switch (gGrp)
{
case GROUP_LGJ:
case GROUP_ABC:
case GROUP_ID5:
{
printf("WARNING: Game %s is unsupported in AMD GPU with ATI driver\n", getGameName());
if (getConfig()->GPUVendor == ATI_GPU)
{
printf("WARNING: Game %s is unsupported in AMD GPU with ATI driver\n", getGameName());
}
}
}
}
@@ -396,33 +404,15 @@ DIR *opendir(const char *dirname)
{
DIR *(*_opendir)(const char *dirname) = dlsym(RTLD_NEXT, "opendir");
switch (gId)
if (strcmp(dirname, "/tmp/") == 0 && gGrp == GROUP_ID5)
{
case INITIALD_5_EXP:
case INITIALD_5_EXP_20:
case INITIALD_5_EXP_20A:
case INITIALD_5_JAP_REVA:
case INITIALD_5_JAP_REVF:
if (strcmp(dirname, "/tmp/") == 0)
{
return _opendir(dirname + 1);
}
return _opendir(dirname + 1);
}
// Fix for Outrun high scores
switch (gId)
if (strcmp(dirname, "/home/disk1/rankingdata") == 0 && (gGrp == GROUP_OUTRUN || gGrp == GROUP_OUTRUN_TEST))
{
case OUTRUN_2_SP_SDX:
case OUTRUN_2_SP_SDX_REVA:
case OUTRUN_2_SP_SDX_TEST:
case OUTRUN_2_SP_SDX_REVA_TEST:
case OUTRUN_2_SP_SDX_REVA_TEST2:
{
if (strcmp(dirname, "/home/disk1/rankingdata") == 0)
{
return _opendir("./rankingdata");
}
}
return _opendir("./rankingdata");
}
return _opendir(dirname);
}
@@ -438,19 +428,9 @@ int remove(const char *path)
{
int (*_remove)(const char *path) = dlsym(RTLD_NEXT, "remove");
switch (gId)
if (strcmp(path, "/home/disk1/rankingdata/%s") == 0 && (gGrp == GROUP_OUTRUN || gGrp == GROUP_OUTRUN_TEST))
{
case OUTRUN_2_SP_SDX:
case OUTRUN_2_SP_SDX_REVA:
case OUTRUN_2_SP_SDX_TEST:
case OUTRUN_2_SP_SDX_REVA_TEST:
case OUTRUN_2_SP_SDX_REVA_TEST2:
{
if (strcmp(path, "/home/disk1/rankingdata/%s") == 0)
{
return _remove("./rankingdata/%s");
}
}
return _remove("./rankingdata/%s");
}
return _remove(path);
}
@@ -466,19 +446,9 @@ int mkdir(const char *path, mode_t mode)
{
int (*_mkdir)(const char *path, mode_t mode) = dlsym(RTLD_NEXT, "mkdir");
switch (gId)
if (strcmp(path, "/home/disk1/rankingdata") == 0 && (gGrp == GROUP_OUTRUN || gGrp == GROUP_OUTRUN_TEST))
{
case OUTRUN_2_SP_SDX:
case OUTRUN_2_SP_SDX_REVA:
case OUTRUN_2_SP_SDX_TEST:
case OUTRUN_2_SP_SDX_REVA_TEST:
case OUTRUN_2_SP_SDX_REVA_TEST2:
{
if (strcmp(path, "/home/disk1/rankingdata") == 0)
{
return _mkdir("./rankingdata", mode);
}
}
return _mkdir("./rankingdata", mode);
}
return _mkdir(path, mode);
}
@@ -531,19 +501,19 @@ int open(const char *pathname, int flags, ...)
if (strcmp(pathname, "/dev/ttyS0") == 0 || strcmp(pathname, "/dev/tts/0") == 0)
{
if (getConfig()->emulateDriveboard == 0 && getConfig()->emulateRideboard == 0 && getConfig()->emulateCardreader == 0 &&
if (getConfig()->emulateDriveboard == 0 && getConfig()->emulateRideboard == 0 && getConfig()->emulateHW210CardReader == 0 &&
getConfig()->emulateTouchscreen == 0)
return _open(getConfig()->serial1Path, flags, mode);
if (hooks[SERIAL0] != -1 && getConfig()->emulateCardreader && gId != R_TUNED)
if (hooks[SERIAL0] != -1 && getConfig()->emulateHW210CardReader && gId != R_TUNED)
{
return hooks[SERIAL0];
}
hooks[SERIAL0] = _open(HOOK_FILE_NAME, flags, mode);
printf("Warning: SERIAL0 Opened %d\n", hooks[SERIAL0]);
log_warn("SERIAL0 Opened %d\n", hooks[SERIAL0]);
if (getConfig()->emulateCardreader == 1 && gId != R_TUNED)
if (getConfig()->emulateHW210CardReader == 1 && gId != R_TUNED)
cardReaderSetFd(0, hooks[SERIAL0], getConfig()->cardFile1);
return hooks[SERIAL0];
@@ -551,10 +521,11 @@ int open(const char *pathname, int flags, ...)
if (strcmp(pathname, "/dev/ttyS1") == 0 || strcmp(pathname, "/dev/tts/1") == 0)
{
if (getConfig()->emulateDriveboard == 0 && getConfig()->emulateMotionboard == 0 && getConfig()->emulateCardreader == 0)
if (getConfig()->emulateDriveboard == 0 && getConfig()->emulateMotionboard == 0 && getConfig()->emulateHW210CardReader == 0 &&
getConfig()->emulateTouchscreen == 0)
return _open(getConfig()->serial2Path, flags, mode);
if (hooks[SERIAL1] != -1 && getConfig()->emulateCardreader && gId != R_TUNED)
if (hooks[SERIAL1] != -1 && getConfig()->emulateHW210CardReader && gId != R_TUNED)
{
return hooks[SERIAL1];
}
@@ -562,7 +533,7 @@ int open(const char *pathname, int flags, ...)
hooks[SERIAL1] = _open(HOOK_FILE_NAME, flags, mode);
log_warn("SERIAL1 opened %d\n", hooks[SERIAL1]);
if (getConfig()->emulateCardreader == 1)
if (getConfig()->emulateHW210CardReader == 1)
cardReaderSetFd(1, hooks[SERIAL1], getConfig()->cardFile2);
return hooks[SERIAL1];
@@ -744,19 +715,9 @@ FILE *fopen(const char *restrict pathname, const char *restrict mode)
}
// Fix for Outrun high scores
switch (gId)
if ((newPathname = strstr(pathname, "/home/disk1")) != NULL && (gGrp == GROUP_OUTRUN || gGrp == GROUP_OUTRUN_TEST))
{
case OUTRUN_2_SP_SDX:
case OUTRUN_2_SP_SDX_REVA:
case OUTRUN_2_SP_SDX_TEST:
case OUTRUN_2_SP_SDX_REVA_TEST:
case OUTRUN_2_SP_SDX_REVA_TEST2:
{
if ((newPathname = strstr(pathname, "/home/disk1")) != NULL)
{
pathname = newPathname + 12;
}
}
pathname = newPathname + 12;
}
// This forces LGJ games and ID games to not use the pre-compiled shaders.
@@ -797,17 +758,9 @@ FILE *fopen(const char *restrict pathname, const char *restrict mode)
}
}
switch (gId)
if (strncmp(pathname, "/tmp/", 5) == 0 && gGrp == GROUP_ID5)
{
case INITIALD_5_EXP:
case INITIALD_5_EXP_20:
case INITIALD_5_EXP_20A:
case INITIALD_5_JAP_REVA:
case INITIALD_5_JAP_REVF:
if (strncmp(pathname, "/tmp/", 5) == 0)
{
return fopen(pathname + 1, mode);
}
return fopen(pathname + 1, mode);
}
if (gId == PRIMEVAL_HUNT)
@@ -825,9 +778,6 @@ FILE *fopen(const char *restrict pathname, const char *restrict mode)
else if (strstr(pathname, "/data/lua/stage/bonus_0") != NULL)
phShowCursorInGame = true;
}
// printf("Path= %s\n", pathname);
return _fopen(pathname, mode);
}
@@ -907,34 +857,33 @@ FILE *fopen64(const char *pathname, const char *mode)
}
int idx;
switch (gId)
if (gGrp == GROUP_HUMMER)
{
case HUMMER:
case HUMMER_SDLX:
case HUMMER_EXTREME:
case HUMMER_EXTREME_MDX:
if (shaderFileInList(pathname, &idx))
{
hummerExtremeShaderFileIndex = idx;
}
break;
case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVA:
case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB:
case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB_6000:
if (getConfig()->GPUVendor != NVIDIA_GPU && getConfig()->GPUVendor != ATI_GPU)
{
char *filename = basename((char *)pathname);
if (strstr(filename, "light_") || strstr(filename, "glow_"))
{
char *start = strchr(filename, '_') + 1;
char *end = strstr(filename, ".txt");
strncpy(vf5StageNameAbbr, start, end - start);
vf5StageNameAbbr[end - start] = '\0';
}
}
return _fopen64(pathname, mode);
}
// printf("fopen64 %s\n", pathname);
switch (gId)
{
case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVA:
case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB:
case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB_6000:
if (getConfig()->GPUVendor != NVIDIA_GPU && getConfig()->GPUVendor != ATI_GPU)
{
char *filename = basename((char *)pathname);
if (strstr(filename, "light_") || strstr(filename, "glow_"))
{
char *start = strchr(filename, '_') + 1;
char *end = strstr(filename, ".txt");
strncpy(vf5StageNameAbbr, start, end - start);
vf5StageNameAbbr[end - start] = '\0';
}
}
}
return _fopen64(pathname, mode);
}
@@ -979,8 +928,8 @@ int openat(int dirfd, const char *pathname, int flags, ...)
int (*_openat)(int dirfd, const char *pathname, int flags) = dlsym(RTLD_NEXT, "openat");
// printf("openat %s\n", pathname);
if (strcmp(pathname, "/dev/ttyS0") == 0 || strcmp(pathname, "/dev/ttyS1") == 0 ||
strcmp(pathname, "/dev/tts/0") == 0 || strcmp(pathname, "/dev/tts/1") == 0)
if (strcmp(pathname, "/dev/ttyS0") == 0 || strcmp(pathname, "/dev/ttyS1") == 0 || strcmp(pathname, "/dev/tts/0") == 0 ||
strcmp(pathname, "/dev/tts/1") == 0)
{
return open(pathname, flags);
}
@@ -1044,7 +993,6 @@ char *fgets(char *str, int n, FILE *stream)
if (getConfig()->lindberghColour == RED || getConfig()->lindberghColour == REDEX)
strcpy(contents[3], "model name : Intel(R) Celeron(R) CPU 2.80GHz");
if (fileRead[CPUINFO] == 4)
return NULL;
@@ -1065,7 +1013,7 @@ char *fgets(char *str, int n, FILE *stream)
ssize_t read(int fd, void *buf, size_t count)
{
int (*_read)(int fd, void *buf, size_t count) = dlsym(RTLD_NEXT, "read");
void *addr = __builtin_return_address(0);
if (fd == hooks[BASEBOARD])
{
return baseboardRead(fd, buf, count);
@@ -1081,7 +1029,7 @@ ssize_t read(int fd, void *buf, size_t count)
return driveboardRead(fd, buf, count);
}
if ((fd == hooks[SERIAL0] || fd == hooks[SERIAL1]) && getConfig()->emulateCardreader)
if ((fd == hooks[SERIAL0] || fd == hooks[SERIAL1]) && getConfig()->emulateHW210CardReader)
{
return cardReaderRead(fd, buf, count);
}
@@ -1202,14 +1150,14 @@ int fseek(FILE *stream, long int offset, int whence)
{
switch (whence)
{
case SEEK_CUR:
break;
case SEEK_SET:
fontABCidx = 0;
break;
case SEEK_END:
fontABCidx = fontABClen;
break;
case SEEK_CUR:
break;
case SEEK_SET:
fontABCidx = 0;
break;
case SEEK_END:
fontABCidx = fontABClen;
break;
}
return fontABCidx;
}
@@ -1247,7 +1195,7 @@ void rewind(FILE *stream)
ssize_t write(int fd, const void *buf, size_t count)
{
int (*_write)(int fd, const void *buf, size_t count) = dlsym(RTLD_NEXT, "write");
void *addr = __builtin_return_address(0);
if (fd == hooks[BASEBOARD])
{
return baseboardWrite(fd, buf, count);
@@ -1260,16 +1208,16 @@ ssize_t write(int fd, const void *buf, size_t count)
if (fd == hooks[SERIAL0] && getConfig()->emulateDriveboard)
{
// printf("Write addr: %p\n", addr);
return driveboardWrite(fd, buf, count);
}
if (fd == hooks[SERIAL1] && getConfig()->emulateDriveboard && gId != R_TUNED)
if (fd == hooks[SERIAL1] && getConfig()->emulateDriveboard)
{
return driveboardWrite(fd, buf, count);
if (gGrp != GROUP_OUTRUN && gGrp != GROUP_OUTRUN_TEST && gId != R_TUNED)
return driveboardWrite(fd, buf, count);
}
if ((fd == hooks[SERIAL0] || fd == hooks[SERIAL1]) && getConfig()->emulateCardreader)
if ((fd == hooks[SERIAL0] || fd == hooks[SERIAL1]) && getConfig()->emulateHW210CardReader)
{
return cardReaderWrite(fd, buf, count);
}
@@ -1284,33 +1232,46 @@ ssize_t write(int fd, const void *buf, size_t count)
* devices based on the file descriptor.
* @param fd The file descriptor to perform the ioctl on.
*/
int ioctl(int fd, unsigned int request, void *data)
int ioctl(int fd, unsigned long int request, ...)
{
va_list args;
va_start(args, request);
void *argp = va_arg(args, void *);
va_end(args);
int (*_ioctl)(int fd, int request, void *data) = dlsym(RTLD_NEXT, "ioctl");
if (fd == hooks[EEPROM])
{
if (request == 0xC04064A0)
return _ioctl(fd, request, data);
return eepromIoctl(fd, request, data);
return _ioctl(fd, request, argp);
return eepromIoctl(fd, request, argp);
}
if (fd == hooks[BASEBOARD])
{
return baseboardIoctl(fd, request, data);
return baseboardIoctl(fd, request, argp);
}
if (fd == hooks[SERIAL0] || fd == hooks[SERIAL1])
{
if (request == 0x541b && gId == R_TUNED && fd == hooks[SERIAL1])
if (request == 0x541b && (gId == R_TUNED) && fd == hooks[SERIAL1])
{
uint8_t d = 1;
memcpy(data, &d, sizeof(uint8_t));
memcpy(argp, &d, sizeof(uint8_t));
}
return 0;
}
return _ioctl(fd, request, data);
// Replace "eth0" with your interface name set in the config file.
if ((gGrp == GROUP_ID4_EXP || gId == INITIALD_5_EXP_20 || gId == INITIALD_5_EXP_20A ) &&
(request == SIOCGIFFLAGS || request == SIOCGIFADDR) && getConfig()->enableNetworkPatches && strcmp(getConfig()->nicName, "") != 0)
{
struct ifreq *ifr = (struct ifreq *)argp;
strncpy(ifr->ifr_name, getConfig()->nicName, IFNAMSIZ);
}
return _ioctl(fd, request, argp);
}
/**
@@ -1419,12 +1380,11 @@ int cfsetospeed(struct termios *termios_p, speed_t speed)
* @brief Hook for the select function.
*
* This function intercepts calls to select and redirects them to different
* devices based on the file descriptor.
* devices based on the file descriptor.c7 45 c8 65 74 68 30
* @param nfds The highest file descriptor number plus one.
* @param readfds The file descriptors to check for readability.
*/
int select(int nfds, fd_set *restrict readfds, fd_set *restrict writefds, fd_set *restrict exceptfds,
struct timeval *restrict timeout)
int select(int nfds, fd_set *restrict readfds, fd_set *restrict writefds, fd_set *restrict exceptfds, struct timeval *restrict timeout)
{
int (*_select)(int nfds, fd_set *restrict readfds, fd_set *restrict writefds, fd_set *restrict exceptfds,
struct timeval *restrict timeout) = dlsym(RTLD_NEXT, "select");
@@ -1439,7 +1399,8 @@ int select(int nfds, fd_set *restrict readfds, fd_set *restrict writefds, fd_set
return baseboardSelect(nfds, readfds, writefds, exceptfds, timeout);
}
if (getConfig()->emulateCardreader == 1 || getConfig()->emulateDriveboard == 1)
if ((getConfig()->emulateHW210CardReader == 1 || getConfig()->emulateDriveboard == 1) &&
(gGrp != GROUP_ID5 && gGrp != GROUP_ID4_EXP && gGrp != GROUP_ID4_JAP))
{
return 1;
}
@@ -1488,6 +1449,15 @@ int system(const char *command)
if (strstr(command, "check_ip.sh") != NULL)
return 0;
if (strcmp(command, "ifconfig eth0 10.0.0.1 netmask 255.255.255.0") == 0)
return 0;
if (strcmp(command, "ifconfig eth0 10.0.0.2 netmask 255.255.255.0") == 0)
return 0;
if (strcmp(command, "touch /tmp/segaboot/test") == 0)
command = "touch tmp/segaboot/test";
return _system(command);
}
@@ -1504,12 +1474,20 @@ char *strncpy(char *dest, const char *src, size_t n)
switch (gId)
{
case HARLEY_DAVIDSON:
case RAMBO:
case THE_HOUSE_OF_THE_DEAD_EX:
case TOO_SPICY:
if (getConfig()->GPUVendor != NVIDIA_GPU && (strstr(src, "../fs/compiledshader") != NULL || strstr(src, "../fs/compiled") != NULL))
return _strncpy(dest, "../fs/compiledmesa", n);
case HARLEY_DAVIDSON:
case RAMBO:
case RAMBO_CHINA:
case THE_HOUSE_OF_THE_DEAD_EX:
case TOO_SPICY:
if (getConfig()->GPUVendor != NVIDIA_GPU &&
(strstr(src, "../fs/compiledshader") != NULL || strstr(src, "../fs/compiled") != NULL))
return _strncpy(dest, "../fs/compiledmesa", n);
break;
case QUIZ_AXA:
case QUIZ_AXA_LIVE:
if (getConfig()->GPUVendor != NVIDIA_GPU && strstr(src, "../../data/compiledshader") != NULL)
return _strncpy(dest, "../../data/compiledmesa", n);
break;
}
return _strncpy(dest, src, n);
}
@@ -1547,92 +1525,6 @@ float powf(float base, float exponent)
return (float)pow((double)base, (double)exponent);
}
/*
int sem_wait(sem_t *sem)
{
int (*original_sem_wait)(sem_t * sem) = dlsym(RTLD_NEXT, "sem_wait");
return 0;
}
*/
/**
* @brief Gets the machine's IP address.
*
* This function retrieves the machine's IP address and stores it in the
* provided sockaddr_in structure.
* @param addr The sockaddr_in structure to store the IP address in.
*/
int get_machine_ip(struct sockaddr_in *addr)
{
struct ifaddrs *ifaddr, *ifa;
char ip_buffer[INET_ADDRSTRLEN];
if (getifaddrs(&ifaddr) == -1)
{
perror("getifaddrs");
return -1;
}
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
{
if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET)
{
if (inet_ntop(AF_INET, &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr, ip_buffer, sizeof(ip_buffer)))
{
if (strcmp(ifa->ifa_name, "lo") != 0)
{
addr->sin_addr.s_addr = inet_addr(ip_buffer);
freeifaddrs(ifaddr);
return 0;
}
}
}
}
freeifaddrs(ifaddr);
return -1;
}
/**
* Hook function used by Harley Davidson to change IPs to localhost
* Currently does nothing.
* @param sockfd
* @param addr
* @param addrlen
* @return
*/
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{
int (*_connect)(int sockfd, const struct sockaddr *addr, socklen_t addrlen) = dlsym(RTLD_NEXT, "connect");
struct sockaddr_in *in_pointer = (struct sockaddr_in *)addr;
// IP addresses to replace
const char *specific_ips[] = {"192.168.1.1", "192.168.1.5", "192.168.1.9"};
int num_specific_ips = sizeof(specific_ips) / sizeof(specific_ips[0]);
if (getConfig()->crc32 == HARLEY_DAVIDSON)
{
char *ip_address = inet_ntoa(in_pointer->sin_addr);
for (int i = 0; i < num_specific_ips; ++i)
{
if (strcmp(ip_address, specific_ips[i]) == 0)
{
// Change the IP to connect to 127.0.0.1
in_pointer->sin_addr.s_addr = inet_addr("127.0.0.1");
if (getConfig()->showDebugMessages)
{
char *some_addr = inet_ntoa(in_pointer->sin_addr);
printf("Connecting to %s\n", some_addr);
}
break;
}
}
}
return _connect(sockfd, addr, addrlen);
}
/**
* @brief Callback function for dl_iterate_phdr.
*
@@ -1644,7 +1536,7 @@ static int callback(struct dl_phdr_info *info, size_t size, void *data)
{
if ((info->dlpi_phnum >= 3) && (info->dlpi_phdr[2].p_type == PT_LOAD) && (info->dlpi_phdr[2].p_flags == 5))
{
elf_crc = get_crc32((void *)(size_t)(info->dlpi_addr + info->dlpi_phdr[2].p_vaddr + 10), 0x4000);
elf_crc = getCrc32((void *)(size_t)(info->dlpi_addr + info->dlpi_phdr[2].p_vaddr + 10), 0x4000);
}
return 1;
}
@@ -1680,18 +1572,7 @@ char *getenv(const char *name)
if (strcmp(name, "TEA_DIR") == 0)
{
switch (gId)
{
case VIRTUA_TENNIS_3:
case VIRTUA_TENNIS_3_TEST:
case VIRTUA_TENNIS_3_REVA:
case VIRTUA_TENNIS_3_REVA_TEST:
case VIRTUA_TENNIS_3_REVB:
case VIRTUA_TENNIS_3_REVB_TEST:
case VIRTUA_TENNIS_3_REVC:
case VIRTUA_TENNIS_3_REVC_TEST:
case RAMBO:
case TOO_SPICY:
if (gGrp == GROUP_VT3 || gGrp == GROUP_VT3_TEST || gId == RAMBO || gId == RAMBO_CHINA || gId == TOO_SPICY)
{
if (getcwd(envpath, 100) == NULL)
return "";
@@ -1701,14 +1582,12 @@ char *getenv(const char *name)
*ptr = '\0';
return envpath;
}
break;
default:
else
{
if (getcwd(envpath, 100) == NULL)
return "";
return envpath;
}
}
}
if (strcmp(name, "__GL_SYNC_TO_VBLANK") == 0)
@@ -1759,14 +1638,26 @@ char *__strdup(const char *string)
*/
struct tm *localtime_r(const time_t *timep, struct tm *result)
{
struct tm *(*_localtime_r)(const time_t *, struct tm *) =
(struct tm * (*)(const time_t *, struct tm *)) dlsym(RTLD_NEXT, "localtime_r");
struct tm *(*_gmtime_r)(const time_t *, struct tm *) = (struct tm * (*)(const time_t *, struct tm *)) dlsym(RTLD_NEXT, "gmtime_r");
if ((gId == MJ4_REVG || gId == MJ4_EVO) && getConfig()->mj4EnabledAtT == 1)
{
time_t target_time = 1735286445;
struct tm *res = _localtime_r(&target_time, result);
struct tm *res = _gmtime_r(&target_time, result);
return res;
}
return _localtime_r(timep, result);
return _gmtime_r(timep, result);
}
struct tm *gmtime_r(const time_t *timep, struct tm *result)
{
struct tm *(*_gmtime_r)(const time_t *, struct tm *) = (struct tm * (*)(const time_t *, struct tm *)) dlsym(RTLD_NEXT, "gmtime_r");
if ((gId == QUIZ_AXA || gId == QUIZ_AXA_LIVE) && getConfig()->mj4EnabledAtT == 1)
{
time_t target_time = 1735286445;
struct tm *res = _gmtime_r(&target_time, result);
return res;
}
return _gmtime_r(timep, result);
}
+24
View File
@@ -0,0 +1,24 @@
#pragma once
typedef enum
{
BASEBOARD = 0,
EEPROM = 1,
SERIAL0 = 2,
SERIAL1 = 3,
PCI_CARD_000 = 4
} DeviceType;
typedef enum
{
CPUINFO = 0,
OSRELEASE = 1,
PCI_CARD_1F0 = 2,
FILE_RW1 = 3,
FILE_RW2 = 4,
FILE_HARLEY = 5,
FILE_FONT_ABC = 6,
FILE_FONT_TGA = 7,
FILE_LOGO_TGA = 8,
ROUTE = 9
} FileTypes;
+228
View File
@@ -0,0 +1,228 @@
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include "iniParser.h"
#include "log.h"
/**
* @brief Trims leading and trailing whitespace from a string in-place.
* @param str The string to trim.
* @return A pointer to the beginning of the trimmed string.
*/
static char *trimString(char *str)
{
char *end;
while (isspace((unsigned char)*str))
str++;
if (*str == 0)
return str;
end = str + strlen(str) - 1;
while (end > str && isspace((unsigned char)*end))
end--;
end[1] = '\0';
return str;
}
/**
* @brief Loads and parses an INI file into an IniConfig structure.
* This function reads an INI file, parsing its sections and key-value pairs.
* It allocates memory for the configuration structure, which must be freed
* later by calling iniFree().
* @param filename The path to the INI file.
* @return A pointer to the newly created IniConfig structure, or NULL on failure.
*/
IniConfig *iniLoad(const char *filename)
{
FILE *file = fopen(filename, "r");
if (!file)
{
log_warn("Error opening INI file");
return NULL;
}
IniConfig *config = calloc(1, sizeof(IniConfig));
if (!config)
return NULL;
char line[1024];
IniSection *currentSection = NULL;
while (fgets(line, sizeof(line), file))
{
char *trimmedLine = trimString(line);
if (trimmedLine[0] == ';' || trimmedLine[0] == '#' || trimmedLine[0] == '\0')
continue;
if (trimmedLine[0] == '[' && trimmedLine[strlen(trimmedLine) - 1] == ']')
{
config->sections = realloc(config->sections, (config->numSections + 1) * sizeof(IniSection));
currentSection = &config->sections[config->numSections++];
currentSection->numPairs = 0;
currentSection->pairs = NULL;
char *sectionName = trimmedLine + 1;
sectionName[strlen(sectionName) - 1] = '\0';
currentSection->name = strdup(sectionName);
}
else if (currentSection && strchr(trimmedLine, '='))
{
char *key = trimmedLine;
char *value = strchr(trimmedLine, '=');
*value = '\0';
value++;
key = trimString(key);
value = trimString(value);
currentSection->pairs = realloc(currentSection->pairs, (currentSection->numPairs + 1) * sizeof(IniKeyValuePair));
IniKeyValuePair *pair = &currentSection->pairs[currentSection->numPairs++];
pair->key = strdup(key);
pair->value = strdup(value);
}
}
fclose(file);
return config;
}
/**
* @brief Retrieves a section from the INI configuration by its name.
* @param config Pointer to the INI configuration structure.
* @param section_name The name of the section to find.
* @return A pointer to the IniSection if found, otherwise NULL.
*/
IniSection *iniGetSection(const IniConfig *config, const char *sectionName)
{
if (!config)
return NULL;
for (int i = 0; i < config->numSections; i++)
{
if (strcmp(config->sections[i].name, sectionName) == 0)
return &config->sections[i];
}
return NULL;
}
/**
* @brief Frees all memory associated with an IniConfig structure.
* This includes all sections, key-value pairs, and their names.
* @param config Pointer to the INI configuration structure to free.
*/
void iniFree(IniConfig *config)
{
if (!config)
return;
for (int i = 0; i < config->numSections; i++)
{
for (int j = 0; j < config->sections[i].numPairs; j++)
{
free(config->sections[i].pairs[j].key);
free(config->sections[i].pairs[j].value);
}
free(config->sections[i].pairs);
free(config->sections[i].name);
}
free(config->sections);
free(config);
}
/**
* @brief Sets a key-value pair in a given section.
* If the section does not exist, it is created.
* If the key exists within the section, its value is updated.
* If the key does not exist, it is created.
* @param config Pointer to the INI configuration structure.
* @param section_name The name of the section.
* @param key The key to set.
* @param value The value to associate with the key.
*/
bool iniSetValue(IniConfig *config, const char *sectionName, const char *key, const char *value)
{
if (!config || !sectionName || !key || !value)
{
return false;
}
// Find the section, or create it if it doesn't exist.
IniSection *section = iniGetSection(config, sectionName);
if (!section)
{
config->sections = realloc(config->sections, (config->numSections + 1) * sizeof(IniSection));
section = &config->sections[config->numSections++];
section->name = strdup(sectionName);
section->pairs = NULL;
section->numPairs = 0;
}
// Find the key within the section.
for (int i = 0; i < section->numPairs; i++)
{
if (strcmp(section->pairs[i].key, key) == 0)
{
// Key found, update the value.
free(section->pairs[i].value);
section->pairs[i].value = strdup(value);
return true;
}
}
// Key not found, add a new key-value pair.
section->pairs = realloc(section->pairs, (section->numPairs + 1) * sizeof(IniKeyValuePair));
IniKeyValuePair *pair = &section->pairs[section->numPairs++];
pair->key = strdup(key);
pair->value = strdup(value);
return true;
}
/**
* @brief Saves the in-memory INI configuration to a file.
* NOTE: This will overwrite the existing file and will lose any comments
* or special formatting from the original.
* @param config Pointer to the INI configuration to save.
* @param filename The path of the file to save to.
* @return 0 on success, -1 on failure (e.g., cannot open file for writing).
*/
int iniSave(const IniConfig *config, const char *filename)
{
if (!config || !filename)
{
return -1;
}
FILE *file = fopen(filename, "w");
if (!file)
{
perror("Error saving INI file");
return -1;
}
// Write each section and its key-value pairs
for (int i = 0; i < config->numSections; i++)
{
IniSection *section = &config->sections[i];
fprintf(file, "[%s]\n", section->name);
for (int j = 0; j < section->numPairs; j++)
{
IniKeyValuePair *pair = &section->pairs[j];
fprintf(file, "%s = %s\n", pair->key, pair->value);
}
// Add a blank line between sections for readability
if (i < config->numSections - 1)
{
fprintf(file, "\n");
}
}
fclose(file);
return 0;
}
const char *iniGetValue(const IniConfig *config, const char *sectionName, const char *key)
{
IniSection *section = iniGetSection(config, sectionName);
if (!section)
return NULL;
for (int i = 0; i < section->numPairs; i++)
{
if (strcmp(section->pairs[i].key, key) == 0)
return section->pairs[i].value;
}
return NULL;
}
+29
View File
@@ -0,0 +1,29 @@
#pragma once
#include <stdbool.h>
typedef struct
{
char *key;
char *value;
} IniKeyValuePair;
typedef struct
{
char *name;
IniKeyValuePair *pairs;
int numPairs;
} IniSection;
typedef struct
{
IniSection *sections;
int numSections;
} IniConfig;
IniConfig *iniLoad(const char *filename);
void iniFree(IniConfig *config);
const char *iniGetValue(const IniConfig *config, const char *section, const char *key);
IniSection *iniGetSection(const IniConfig *config, const char *sectionName);
bool iniSetValue(IniConfig *config, const char *section, const char *key, const char *value);
int iniSave(const IniConfig *config, const char *filename);
-977
View File
@@ -1,977 +0,0 @@
#ifndef __i386__
#define __i386__
#include "customcursor.h"
#endif
#undef __x86_64__
#include <SDL2/SDL.h>
#include "jvs.h"
#include "config.h"
#include "customcursor.h"
#include "patch.h"
#include "touchscreen.h"
#include <GL/freeglut.h>
#include <GL/glx.h>
#include <SDL2/SDL.h>
#include <X11/Xatom.h>
#include <X11/extensions/xf86vmode.h>
#include <dlfcn.h>
#include <math.h>
#include <pthread.h>
#include <stdbool.h>
GameType gameType = SHOOTING;
int jvsAnalogueInBits = 10;
extern int phX, phY, phW, phH;
extern int phX2, phY2, phW2, phH2;
int phIsDragging = 0;
extern void *customCursor;
extern void *phTouchCursor;
extern bool phShowCursorInGame;
int initInput()
{
gameType = getConfig()->gameType;
jvsAnalogueInBits = getJVSIO()->capabilities.analogueInBits;
/* Center Steering wheel in racing games (need to add a check for when using real analog devices)*/
if (gameType == DRIVING)
{
setAnalogue(ANALOGUE_1, pow(2, jvsAnalogueInBits) * 0.5);
}
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
*/
int XNextEventDriving(Display *display, XEvent *event_return, int returnValue)
{
KeyMapping keymap = getConfig()->keymap;
switch (event_return->type)
{
case KeyPress:
case KeyRelease:
{
if (event_return->xkey.keycode == keymap.test)
setSwitch(SYSTEM, BUTTON_TEST, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player1.service)
setSwitch(PLAYER_1, BUTTON_SERVICE, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player1.coin)
incrementCoin(PLAYER_1, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player1.up)
setAnalogue(ANALOGUE_2, event_return->type == KeyPress ? pow(2, jvsAnalogueInBits) - 1 : 0);
else if (event_return->xkey.keycode == keymap.player1.down)
setAnalogue(ANALOGUE_3, event_return->type == KeyPress ? pow(2, jvsAnalogueInBits) - 1 : 0);
else if (event_return->xkey.keycode == keymap.player1.left)
setAnalogue(ANALOGUE_1, event_return->type == KeyPress ? pow(2, jvsAnalogueInBits) * 0.2
: pow(2, jvsAnalogueInBits) * 0.5);
else if (event_return->xkey.keycode == keymap.player1.right)
setAnalogue(ANALOGUE_1, event_return->type == KeyPress ? pow(2, jvsAnalogueInBits) * 0.8
: pow(2, jvsAnalogueInBits) * 0.5);
else if (event_return->xkey.keycode == keymap.player1.start)
setSwitch(PLAYER_1, BUTTON_START, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player1.button1)
setSwitch(PLAYER_1, BUTTON_1, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player1.button2)
setSwitch(PLAYER_1, BUTTON_2, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player1.button3)
setSwitch(PLAYER_1, BUTTON_3, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player1.button4)
setSwitch(PLAYER_1, BUTTON_4, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player1.button5)
setSwitch(PLAYER_1, BUTTON_DOWN, event_return->type == KeyPress); // Hummer - SegaTV view change
else if (event_return->xkey.keycode == keymap.player1.button6)
setSwitch(PLAYER_1, BUTTON_UP, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player1.button7)
setSwitch(PLAYER_1, BUTTON_LEFT, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player1.button8)
setSwitch(PLAYER_1, BUTTON_RIGHT, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player2.button1)
setSwitch(PLAYER_2, BUTTON_1, event_return->type == KeyPress); // SegaTV boost
else if (event_return->xkey.keycode == keymap.player2.down)
setSwitch(PLAYER_2, BUTTON_DOWN, event_return->type == KeyPress); // Hummer boost
else if (event_return->xkey.keycode == keymap.player2.up)
setSwitch(PLAYER_2, BUTTON_UP, event_return->type == KeyPress);
}
break;
default:
break;
}
return returnValue;
}
/**
* Button mapping used for Harley
*/
int XNextEventHarley(Display *display, XEvent *event_return, int returnValue)
{
KeyMapping keymap = getConfig()->keymap;
switch (event_return->type)
{
case KeyPress:
case KeyRelease:
{
if (event_return->xkey.keycode == keymap.test)
setSwitch(SYSTEM, BUTTON_TEST, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player1.service)
setSwitch(PLAYER_1, BUTTON_SERVICE, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player1.coin)
incrementCoin(PLAYER_1, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player1.up)
setAnalogue(ANALOGUE_1, event_return->type == KeyPress ? pow(2, jvsAnalogueInBits) - 1 : 0);
else if (event_return->xkey.keycode == keymap.player1.down)
setAnalogue(ANALOGUE_4, event_return->type == KeyPress ? pow(2, jvsAnalogueInBits) - 1 : 0);
else if (event_return->xkey.keycode == keymap.player1.left)
setAnalogue(ANALOGUE_2, event_return->type == KeyPress ? pow(2, jvsAnalogueInBits) * 0.2
: pow(2, jvsAnalogueInBits) * 0.5);
else if (event_return->xkey.keycode == keymap.player1.right)
setAnalogue(ANALOGUE_2, event_return->type == KeyPress ? pow(2, jvsAnalogueInBits) * 0.8
: pow(2, jvsAnalogueInBits) * 0.5);
else if (event_return->xkey.keycode == keymap.player1.start)
setSwitch(PLAYER_1, BUTTON_START, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player1.button1)
setSwitch(PLAYER_1, BUTTON_1, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player1.button2)
setSwitch(PLAYER_1, BUTTON_2, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player1.button3)
setSwitch(PLAYER_1, BUTTON_3, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player1.button4)
setSwitch(PLAYER_1, BUTTON_4, event_return->type == KeyPress);
}
break;
default:
break;
}
return returnValue;
}
/**
* Button mapping used for shooting games
*/
int XNextEventShooting(Display *display, XEvent *event_return, int returnValue)
{
KeyMapping keymap = getConfig()->keymap;
switch (event_return->type)
{
case KeyPress:
case KeyRelease:
{
if (event_return->xkey.keycode == keymap.test)
setSwitch(SYSTEM, BUTTON_TEST, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player1.service)
setSwitch(PLAYER_1, BUTTON_SERVICE, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player1.coin)
incrementCoin(PLAYER_1, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player1.start)
setSwitch(PLAYER_1, BUTTON_START, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player1.button1)
setSwitch(PLAYER_1, BUTTON_1, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player1.button2)
setSwitch(PLAYER_1, BUTTON_2, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player1.button3)
setSwitch(PLAYER_1, BUTTON_3, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player1.button4)
{
setSwitch(PLAYER_1, BUTTON_4, event_return->type == KeyPress);
// For The House of the Dead 4's Accelerometer
setAnalogue(ANALOGUE_5, 0);
setAnalogue(ANALOGUE_6, 0);
}
else if (event_return->xkey.keycode == keymap.player1.button5)
setSwitch(PLAYER_1, BUTTON_5, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player1.up)
setSwitch(PLAYER_1, BUTTON_UP, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player1.down)
setSwitch(PLAYER_1, BUTTON_DOWN, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player1.left)
setSwitch(PLAYER_1, BUTTON_LEFT, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player1.right)
setSwitch(PLAYER_1, BUTTON_RIGHT, event_return->type == KeyPress);
// Player 2 Controls
else if (event_return->xkey.keycode == keymap.player2.service)
setSwitch(PLAYER_2, BUTTON_SERVICE, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player2.coin)
incrementCoin(PLAYER_2, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player2.start)
setSwitch(PLAYER_2, BUTTON_START, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player2.button1)
setSwitch(PLAYER_2, BUTTON_1, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player2.button2)
setSwitch(PLAYER_2, BUTTON_2, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player2.button3)
setSwitch(PLAYER_2, BUTTON_3, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player2.button4)
setSwitch(PLAYER_2, BUTTON_4, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player2.button5)
setSwitch(PLAYER_2, BUTTON_5, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player2.up)
setSwitch(PLAYER_2, BUTTON_UP, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player2.down)
setSwitch(PLAYER_2, BUTTON_DOWN, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player2.left)
setSwitch(PLAYER_2, BUTTON_LEFT, event_return->type == KeyPress);
else if (event_return->xkey.keycode == keymap.player2.right)
setSwitch(PLAYER_2, BUTTON_RIGHT, event_return->type == KeyPress);
}
break;
case MotionNotify:
{
if (getConfig()->crc32 == LETS_GO_JUNGLE || getConfig()->crc32 == LETS_GO_JUNGLE_REVA)
{
setAnalogue(ANALOGUE_2, (1.0 - ((double)event_return->xmotion.x / (double)getConfig()->width)) *
pow(2, jvsAnalogueInBits));
setAnalogue(ANALOGUE_1, (1.0 - ((double)event_return->xmotion.y / (double)getConfig()->height)) *
pow(2, jvsAnalogueInBits));
}
else if (getConfig()->crc32 == PRIMEVAL_HUNT)
{
int mX = event_return->xmotion.x;
int mY = event_return->xmotion.y;
if (phIsDragging)
phTouchClick(mX, mY, event_return->type);
int motX = mX, motY = mY;
phTouchScreenCursor(mX, mY, &motX, &motY);
setAnalogue(ANALOGUE_1, ((double)(motX - phX) / (double)phW) * pow(2, jvsAnalogueInBits));
setAnalogue(ANALOGUE_2, ((double)(motY - phY) / (double)phH) * pow(2, jvsAnalogueInBits));
}
else
{
setAnalogue(ANALOGUE_1,
((double)event_return->xmotion.x / (double)getConfig()->width) * pow(2, jvsAnalogueInBits));
setAnalogue(ANALOGUE_2,
((double)event_return->xmotion.y / (double)getConfig()->height) * pow(2, jvsAnalogueInBits));
}
// For The House of the Dead 4's Accelerometer
static int lastMouseX = 0;
static int lastMouseY = 0;
static const int shakeThresholdPixels = 100; // Adjust as needed
int currentMouseX = event_return->xmotion.x;
int currentMouseY = event_return->xmotion.y;
// Calculate movement distance
int dx = currentMouseX - lastMouseX;
int dy = currentMouseY - lastMouseY;
// Update last position
lastMouseX = currentMouseX;
lastMouseY = currentMouseY;
// Check if mouse movement exceeds shake threshold
if (abs(dx) > shakeThresholdPixels || abs(dy) > shakeThresholdPixels)
{
setAnalogue(ANALOGUE_5, 0);
setAnalogue(ANALOGUE_6, 0);
}
else
{
setAnalogue(ANALOGUE_5, pow(2, jvsAnalogueInBits) / 2);
setAnalogue(ANALOGUE_6, pow(2, jvsAnalogueInBits) / 2);
}
}
break;
case ButtonPress:
case ButtonRelease:
{
if (event_return->xbutton.button == 1) // Trigger
{
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
{
if (getConfig()->crc32 == RAMBO || getConfig()->crc32 == TOO_SPICY)
{
setAnalogue(ANALOGUE_1, -1);
setAnalogue(ANALOGUE_2, -1);
}
setSwitch(PLAYER_1, BUTTON_2, event_return->type == ButtonPress);
}
else if (event_return->xbutton.button == 2) // Extra Gun Button
{
setSwitch(PLAYER_1, BUTTON_3, event_return->type == ButtonPress);
}
}
break;
default:
break;
}
return returnValue;
}
int XNextEvent(Display *display, XEvent *event_return)
{
int (*_XNextEvent)(Display *display, XEvent *event_return) = dlsym(RTLD_NEXT, "XNextEvent");
int returnValue = _XNextEvent(display, event_return);
// Return now if we're not emulating JVS or if EVDEV-only mode is enabled
if (!getConfig()->emulateJVS || getConfig()->inputMode == 2)
{
return returnValue;
}
// Select the appropriate input mapping depending on the game
switch (gameType)
{
case DRIVING:
return XNextEventDriving(display, event_return, returnValue);
break;
case HARLEY:
return XNextEventHarley(display, event_return, returnValue);
break;
case SHOOTING:
case FIGHTING:
default:
return XNextEventShooting(display, event_return, returnValue);
break;
}
return returnValue;
}
void sdlEventDriving(SDL_Event *event)
{
switch (event->type)
{
case SDL_KEYDOWN:
case SDL_KEYUP:
{
if (event->key.keysym.sym == SDLK_t)
setSwitch(SYSTEM, BUTTON_TEST, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_s)
setSwitch(PLAYER_1, BUTTON_SERVICE, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_5)
incrementCoin(PLAYER_1, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_1)
setSwitch(PLAYER_1, BUTTON_START, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_UP)
setAnalogue(ANALOGUE_2, event->type == SDL_KEYDOWN ? pow(2, jvsAnalogueInBits) - 1 : 0);
else if (event->key.keysym.sym == SDLK_DOWN)
setAnalogue(ANALOGUE_3, event->type == SDL_KEYDOWN ? pow(2, jvsAnalogueInBits) - 1 : 0);
else if (event->key.keysym.sym == SDLK_LEFT)
setAnalogue(ANALOGUE_1,
event->type == SDL_KEYDOWN ? pow(2, jvsAnalogueInBits) * 0.2 : pow(2, jvsAnalogueInBits) * 0.5);
else if (event->key.keysym.sym == SDLK_RIGHT)
setAnalogue(ANALOGUE_1,
event->type == SDL_KEYDOWN ? pow(2, jvsAnalogueInBits) * 0.8 : pow(2, jvsAnalogueInBits) * 0.5);
else if (event->key.keysym.sym == SDLK_q)
setSwitch(PLAYER_1, BUTTON_1, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_w)
setSwitch(PLAYER_1, BUTTON_2, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_e)
setSwitch(PLAYER_1, BUTTON_3, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_r)
setSwitch(PLAYER_1, BUTTON_4, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_z)
setSwitch(PLAYER_1, BUTTON_DOWN, event->type == SDL_KEYDOWN); // Hummer - SegaTV view change
else if (event->key.keysym.sym == SDLK_x)
setSwitch(PLAYER_1, BUTTON_UP, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_c)
setSwitch(PLAYER_1, BUTTON_LEFT, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_v)
setSwitch(PLAYER_1, BUTTON_RIGHT, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_a)
setSwitch(PLAYER_2, BUTTON_1, event->type == SDL_KEYDOWN); // SegaTV boost
else if (event->key.keysym.sym == SDLK_LCTRL)
setSwitch(PLAYER_2, BUTTON_DOWN, event->type == SDL_KEYDOWN); // Hummer boost
else if (event->key.keysym.sym == SDLK_SPACE)
setSwitch(PLAYER_2, BUTTON_UP, event->type == SDL_KEYDOWN);
}
break;
default:
break;
}
}
void sdlEventShooting(SDL_Event *event)
{
KeyMapping keymap = getConfig()->keymap;
switch (event->type)
{
case SDL_KEYDOWN:
case SDL_KEYUP:
{
if (event->key.keysym.sym == SDLK_t)
setSwitch(SYSTEM, BUTTON_TEST, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_s)
setSwitch(PLAYER_1, BUTTON_SERVICE, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_5)
incrementCoin(PLAYER_1, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_1)
setSwitch(PLAYER_1, BUTTON_START, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_q)
setSwitch(PLAYER_1, BUTTON_1, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_w)
setSwitch(PLAYER_1, BUTTON_2, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_e)
setSwitch(PLAYER_1, BUTTON_3, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_r)
{
setSwitch(PLAYER_1, BUTTON_4, event->type == SDL_KEYDOWN);
// For The House of the Dead 4's Accelerometer
setAnalogue(ANALOGUE_5, 0);
setAnalogue(ANALOGUE_6, 0);
}
else if (event->key.keysym.sym == SDLK_UP)
setSwitch(PLAYER_1, BUTTON_UP, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_DOWN)
setSwitch(PLAYER_1, BUTTON_DOWN, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_LEFT)
setSwitch(PLAYER_1, BUTTON_LEFT, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_RIGHT)
setSwitch(PLAYER_1, BUTTON_RIGHT, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_2)
setSwitch(PLAYER_2, BUTTON_START, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_z)
setSwitch(PLAYER_2, BUTTON_1, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_x)
setSwitch(PLAYER_2, BUTTON_2, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_c)
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)
setSwitch(PLAYER_2, BUTTON_UP, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_i)
setSwitch(PLAYER_2, BUTTON_DOWN, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_o)
setSwitch(PLAYER_2, BUTTON_LEFT, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_p)
setSwitch(PLAYER_2, BUTTON_RIGHT, event->type == SDL_KEYDOWN);
}
break;
case SDL_MOUSEMOTION:
{
if (getConfig()->crc32 == LETS_GO_JUNGLE || getConfig()->crc32 == LETS_GO_JUNGLE_REVA)
{
setAnalogue(ANALOGUE_2,
(1.0 - ((double)event->motion.x / (double)getConfig()->width)) * pow(2, jvsAnalogueInBits));
setAnalogue(ANALOGUE_1,
(1.0 - ((double)event->motion.y / (double)getConfig()->height)) * pow(2, jvsAnalogueInBits));
}
else if (getConfig()->crc32 == PRIMEVAL_HUNT)
{
int mX = event->motion.x;
int mY = event->motion.y;
if (phIsDragging)
phTouchClick(mX, mY, event->type);
int motX = mX, motY = mY;
phTouchScreenCursor(mX, mY, &motX, &motY);
setAnalogue(ANALOGUE_1, ((double)(motX - phX) / (double)phW) * pow(2, jvsAnalogueInBits));
setAnalogue(ANALOGUE_2, ((double)(motY - phY) / (double)phH) * pow(2, jvsAnalogueInBits));
}
else
{
setAnalogue(ANALOGUE_1, ((double)event->motion.x / (double)getConfig()->width) * pow(2, jvsAnalogueInBits));
setAnalogue(ANALOGUE_2,
((double)event->motion.y / (double)getConfig()->height) * pow(2, jvsAnalogueInBits));
}
// For The House of the Dead 4's Accelerometer
static int lastMouseX = 0;
static int lastMouseY = 0;
static const int shakeThresholdPixels = 100; // Adjust as needed
int currentMouseX = event->motion.x;
int currentMouseY = event->motion.y;
// Calculate movement distance
int dx = currentMouseX - lastMouseX;
int dy = currentMouseY - lastMouseY;
// Update last position
lastMouseX = currentMouseX;
lastMouseY = currentMouseY;
// Check if mouse movement exceeds shake threshold
if (abs(dx) > shakeThresholdPixels || abs(dy) > shakeThresholdPixels)
{
setAnalogue(ANALOGUE_5, 0);
setAnalogue(ANALOGUE_6, 0);
}
else
{
setAnalogue(ANALOGUE_5, pow(2, jvsAnalogueInBits) / 2);
setAnalogue(ANALOGUE_6, pow(2, jvsAnalogueInBits) / 2);
}
}
break;
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
{
if (event->button.button == SDL_BUTTON_LEFT) // Trigger
{
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
{
if (getConfig()->crc32 == RAMBO || getConfig()->crc32 == TOO_SPICY)
{
setAnalogue(ANALOGUE_1, -1);
setAnalogue(ANALOGUE_2, -1);
}
setSwitch(PLAYER_1, BUTTON_2, event->type == SDL_MOUSEBUTTONDOWN);
}
else if (event->button.button == SDL_BUTTON_MIDDLE) // Extra Gun Button
{
setSwitch(PLAYER_1, BUTTON_3, event->type == SDL_MOUSEBUTTONDOWN);
}
}
break;
default:
break;
}
}
void sdlEventABC(SDL_Event *event)
{
switch (event->type)
{
case SDL_KEYDOWN:
case SDL_KEYUP:
{
if (event->key.keysym.sym == SDLK_t)
setSwitch(SYSTEM, BUTTON_TEST, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_s)
setSwitch(PLAYER_1, BUTTON_SERVICE, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_5)
incrementCoin(PLAYER_1, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_1)
setSwitch(PLAYER_1, BUTTON_START, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_UP)
setAnalogue(ANALOGUE_2,
event->type == SDL_KEYDOWN ? pow(2, jvsAnalogueInBits) * 0.2 : pow(2, jvsAnalogueInBits) * 0.5);
else if (event->key.keysym.sym == SDLK_DOWN)
setAnalogue(ANALOGUE_2,
event->type == SDL_KEYDOWN ? pow(2, jvsAnalogueInBits) * 0.8 : pow(2, jvsAnalogueInBits) * 0.5);
else if (event->key.keysym.sym == SDLK_LEFT)
setAnalogue(ANALOGUE_1,
event->type == SDL_KEYDOWN ? pow(2, jvsAnalogueInBits) * 0.2 : pow(2, jvsAnalogueInBits) * 0.5);
else if (event->key.keysym.sym == SDLK_RIGHT)
setAnalogue(ANALOGUE_1,
event->type == SDL_KEYDOWN ? pow(2, jvsAnalogueInBits) * 0.8 : pow(2, jvsAnalogueInBits) * 0.5);
else if (event->key.keysym.sym == SDLK_q)
setSwitch(PLAYER_1, BUTTON_1, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_w)
setSwitch(PLAYER_1, BUTTON_2, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_e)
setSwitch(PLAYER_1, BUTTON_3, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_f)
setAnalogue(ANALOGUE_3, event->type == SDL_KEYDOWN ? pow(2, jvsAnalogueInBits) * 0.2 : pow(2, jvsAnalogueInBits) * 0.5);
else if (event->key.keysym.sym == SDLK_r)
setAnalogue(ANALOGUE_3, event->type == SDL_KEYDOWN ? pow(2, jvsAnalogueInBits) * 0.8 : pow(2, jvsAnalogueInBits) * 0.5);
else if (event->key.keysym.sym == SDLK_z)
setSwitch(PLAYER_1, BUTTON_DOWN, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_x)
setSwitch(PLAYER_1, BUTTON_UP, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_c)
setSwitch(PLAYER_1, BUTTON_LEFT, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_v)
setSwitch(PLAYER_1, BUTTON_RIGHT, event->type == SDL_KEYDOWN);
}
break;
default:
break;
}
}
void sdlEventHarley(SDL_Event *event)
{
switch (event->type)
{
case SDL_KEYDOWN:
case SDL_KEYUP:
{
if (event->key.keysym.sym == SDLK_t)
setSwitch(SYSTEM, BUTTON_TEST, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_s)
setSwitch(PLAYER_1, BUTTON_SERVICE, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_5)
incrementCoin(PLAYER_1, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_1)
setSwitch(PLAYER_1, BUTTON_START, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_UP)
setAnalogue(ANALOGUE_1, event->type == SDL_KEYDOWN ? pow(2, jvsAnalogueInBits) - 1 : 0);
else if (event->key.keysym.sym == SDLK_DOWN)
setAnalogue(ANALOGUE_4, event->type == SDL_KEYDOWN ? pow(2, jvsAnalogueInBits) - 1 : 0);
else if (event->key.keysym.sym == SDLK_LEFT)
setAnalogue(ANALOGUE_2, event->type == SDL_KEYDOWN ? pow(2, jvsAnalogueInBits) * 0.2 : pow(2, jvsAnalogueInBits) * 0.5);
else if (event->key.keysym.sym == SDLK_RIGHT)
setAnalogue(ANALOGUE_2, event->type == SDL_KEYDOWN ? pow(2, jvsAnalogueInBits) * 0.8 : pow(2, jvsAnalogueInBits) * 0.5);
else if (event->key.keysym.sym == SDLK_q)
setSwitch(PLAYER_1, BUTTON_1, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_w)
setSwitch(PLAYER_1, BUTTON_2, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_e)
setSwitch(PLAYER_1, BUTTON_3, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_r)
setSwitch(PLAYER_1, BUTTON_4, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_z)
setSwitch(PLAYER_1, BUTTON_DOWN, event->type == SDL_KEYDOWN); // Hummer - SegaTV view change
else if (event->key.keysym.sym == SDLK_x)
setSwitch(PLAYER_1, BUTTON_UP, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_c)
setSwitch(PLAYER_1, BUTTON_LEFT, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_v)
setSwitch(PLAYER_1, BUTTON_RIGHT, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_a)
setSwitch(PLAYER_2, BUTTON_1, event->type == SDL_KEYDOWN); // SegaTV boost
else if (event->key.keysym.sym == SDLK_LCTRL)
setSwitch(PLAYER_2, BUTTON_DOWN, event->type == SDL_KEYDOWN); // Hummer boost
else if (event->key.keysym.sym == SDLK_SPACE)
setSwitch(PLAYER_2, BUTTON_UP, event->type == SDL_KEYDOWN);
}
break;
default:
break;
}
}
void sdlEventMahjong(SDL_Event *event)
{
switch (event->type)
{
case SDL_KEYDOWN:
case SDL_KEYUP:
{
if (event->key.keysym.sym == SDLK_t)
setSwitch(SYSTEM, BUTTON_TEST, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_s)
setSwitch(PLAYER_1, BUTTON_SERVICE, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_5)
incrementCoin(PLAYER_1, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_1)
setSwitch(PLAYER_1, BUTTON_START, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_a)
setSwitch(PLAYER_1, BUTTON_RIGHT, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_b)
setSwitch(PLAYER_1, BUTTON_LEFT, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_c)
setSwitch(PLAYER_1, BUTTON_UP, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_d)
setSwitch(PLAYER_1, BUTTON_DOWN, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_e)
setSwitch(PLAYER_1, BUTTON_1, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_f)
setSwitch(PLAYER_1, BUTTON_2, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_g)
setSwitch(PLAYER_1, BUTTON_3, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_h)
setSwitch(PLAYER_1, BUTTON_4, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_i)
setSwitch(PLAYER_1, BUTTON_5, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_j)
setSwitch(PLAYER_1, BUTTON_6, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_k)
setSwitch(PLAYER_1, BUTTON_7, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_l)
setSwitch(PLAYER_2, BUTTON_RIGHT, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_m)
setSwitch(PLAYER_2, BUTTON_LEFT, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_n)
setSwitch(PLAYER_2, BUTTON_UP, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_o)
setSwitch(PLAYER_2, BUTTON_DOWN, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_p)
setSwitch(PLAYER_2, BUTTON_1, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_q)
setSwitch(PLAYER_2, BUTTON_2, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_r)
setSwitch(PLAYER_2, BUTTON_3, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_u)
setSwitch(PLAYER_2, BUTTON_4, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_v)
setSwitch(PLAYER_2, BUTTON_5, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_w)
setSwitch(PLAYER_2, BUTTON_6, event->type == SDL_KEYDOWN);
else if (event->key.keysym.sym == SDLK_x)
setSwitch(PLAYER_2, BUTTON_7, event->type == SDL_KEYDOWN);
}
break;
default:
break;
}
}
void handleSdlEvents(SDL_Event *event)
{
// Return now if we're not emulating JVS or if EVDEV-only mode is enabled
if (!getConfig()->emulateJVS || getConfig()->inputMode == 2)
{
return;
}
// Select the appropriate input mapping depending on the game
switch (gameType)
{
case DRIVING:
sdlEventDriving(event);
break;
case SHOOTING:
case FIGHTING:
sdlEventShooting(event);
break;
case ABC:
sdlEventABC(event);
break;
case HARLEY:
sdlEventHarley(event);
break;
case MAHJONG:
sdlEventMahjong(event);
break;
default:
// return XNextEventShooting(display, event_return, returnValue);
break;
}
}
-4
View File
@@ -1,4 +0,0 @@
#include <SDL2/SDL.h>
int initInput();
void handleSdlEvents(SDL_Event *event);
+3 -5
View File
@@ -1,11 +1,9 @@
#include "jvs.h"
#include "config.h"
#include <string.h>
#include <math.h>
#include <pthread.h> /* POSIX threads API to create and manage threads in the program */
#include "jvs.h"
#include "config.h"
/* The in and out packets used to read and write to and from*/
JVSPacket inputPacket, outputPacket;
+284 -47
View File
@@ -3,30 +3,39 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <libgen.h>
#include <sys/stat.h>
#include <limits.h>
#include "config.h"
#include "evdevinput.h"
#include "version.h"
#include "configIni.h"
#include "evdevInput.h"
#include "log.h"
#include "version.h"
#include "controlIniGen.h"
#include "sdlInput.h"
#define LD_LIBRARY_PATH "LD_LIBRARY_PATH"
#define LD_PRELOAD "LD_PRELOAD"
#define PRELOAD_FILE_NAME "lindbergh.so"
#define TEAM "bobbydilley, retrofan, dkeruza-neo, doozer, francesco, rolel, caviar-x"
#define PRELOAD_OPENAL "libopenal.so.0"
#define TEAM "bobbydilley, retrofan, dkeruza-neo, francesco"
#define COLLABORATORS "doozer, rolel, caviar-X"
#define SPECIAL_THANKS "Francesco"
#define LINDBERGH_CONFIG_PATH "LINDBERGH_CONFIG_PATH"
#define LINDBERGH_CONTROLS_PATH "LINDBERGH_CONTROLS_PATH"
#define LINDBERGH_CONTROLS_DB_PATH "LINDBERGH_CONTROLS_DB_PATH"
#define LINDBERGH_LOADER_CURRENT_DIR "LINDBERGH_LOADER_CURRENT_DIR"
#define MAX_PATH_LENGTH 1024
uint32_t elf_crc = 0;
// List of all lindbergh executables known, not including the test executables
char *games[] = {"a.elf", "abc", "apacheM.elf", "chopperM.elf", "drive.elf", "dsr",
"gsevo", "hod4M.elf", "hodexRI.elf", "hummer_Master.elf", "id4.elf", "id5.elf",
"Jennifer", "lgj_final", "lgjsp_app", "main.exe", "mj4", "ramboM.elf",
"vf5", "vsg", "vt3", "vt3_Lindbergh", "END"};
char *games[] = {"a.elf", "abc", "apacheM.elf", "chopperM.elf", "drive.elf",
"dsr", "gsevo", "hod4M.elf", "hodexRI.elf", "hummer_Master.elf",
"id4.elf", "id5.elf", "Jennifer", "lgj_final", "lgjsp_app",
"main.exe", "mj4", "q2satl_lind", "ramboM.elf", "vf5",
"vsg", "vt3", "vt3_Lindbergh", "END"};
/**
* An array containin clean games elf's CRC32
@@ -71,6 +80,7 @@ uint32_t cleanElfCRC32[] = {
0x2D2A18C1, // DVP-0019C | id4.elf
0x9BFD0D98, // DVP-0019D | id4.elf
0x9CF9BBCC, // DVP-0019G | id4.elf
0xDCAD8ABA, // DVP-0025H | q2satl_lind
0xFA0F6AB0, // DVP-0027A | apacheM.elf
0x5A7F315E, // DVP-0027A | apachetestM.elf
0x9D414D18, // DVP-0029A | vsg
@@ -91,13 +101,16 @@ uint32_t cleanElfCRC32[] = {
0x3A5EEC69, // DVP-0063 | hodextestR.elf
0x81E02850, // DVP-0069 | ramboM.elf
0xE4F202BB, // DVP-0070A | id5.elf
0x400C09CD, // DVP-0070C | id5.elf
0x2E6732A3, // DVP-0070F | id5.elf
0xF99A3CDB, // DVP-0075 | id5.elf
0xDCC1f8E7, // DVP-0078 | ramboM.elf
0x05647A8E, // DVP-0079 | hummer_Master.elf
0x0AD7CF0F, // DVP-0081 | mj4
0x4442EA15, // DVP-0083 | hummer_Master.elf
0x8DF6BBF9, // DVP-0084 | id5.elf
0x2AF8004E, // DVP-0084A | id5.elf
0xCB663DD0, // DVP-0087D | q2satl_lind
0xB95528F4, // DVP-5004 | vf5
0x012E4898, // DVP-5004D | vf5
0x74465F9F, // DVP-5004G | vf5
@@ -196,7 +209,6 @@ void isCleanElf(char *command)
return;
crc = crc ^ 0xFFFFFFFF;
if (!lookupCrcTable(crc))
{
printf("\033[1;31m");
@@ -232,7 +244,7 @@ void testModePath(char *program)
strcat(program, " -t");
}
char *findPreloadLibrary(const char *originalDir, const char *gameDir)
char *findPreloadLibrary(const char *originalDir, char *preloadFileName)
{
static char result[MAX_PATH_LENGTH];
char appImageLib[MAX_PATH_LENGTH];
@@ -240,17 +252,17 @@ char *findPreloadLibrary(const char *originalDir, const char *gameDir)
const char *folderCandidates[] = {"/app/lib32", appImageLib, originalDir, "/usr/lib/i386-linux-gnu", "/usr/lib/i686-linux-gnu",
"/usr/lib32", "/usr/lib", NULL};
if (fileExists(PRELOAD_FILE_NAME))
return PRELOAD_FILE_NAME;
for (int i = 0; i < sizeof(folderCandidates) / sizeof(folderCandidates[0]); i++)
{
snprintf(result, MAX_PATH_LENGTH, "%s/%s", folderCandidates[i], PRELOAD_FILE_NAME);
snprintf(result, MAX_PATH_LENGTH, "%s/%s", folderCandidates[i], preloadFileName);
if (fileExists(result))
return result;
}
return NULL;
if (fileExists(preloadFileName))
return preloadFileName;
return "";
}
int pathsDiffer(const char *p1, const char *p2)
@@ -270,9 +282,20 @@ bool hasSpaces(const char *path)
}
void setEnvironmentVariables(const char *ldLibPath, const char *originalDir, const char *gameDir, int zink, int nvidia,
const char *confFilePath)
const char *confFilePath, const char *contFilePath, const char *contDbFilePath, char *libOpenal)
{
setenv("LD_PRELOAD", ldLibPath, 1);
if (libOpenal != NULL)
{
char ldpreloadEnv[MAX_PATH_LENGTH];
snprintf(ldpreloadEnv, sizeof(ldpreloadEnv), "%s %s", ldLibPath, libOpenal);
setenv("LD_PRELOAD", ldpreloadEnv, 1);
}
else
{
setenv("LD_PRELOAD", ldLibPath, 1);
}
if (hasSpaces(ldLibPath))
{
log_error("The path \'%s\' where lindbergh.so is located cannot contain spaces.", ldLibPath);
@@ -317,11 +340,53 @@ void setEnvironmentVariables(const char *ldLibPath, const char *originalDir, con
if (hasSpaces(confFilePath))
{
log_error("The path \'%s\' for the config file cannot contain spaces.", confFilePath);
exit(EXIT_FAILURE);
log_error("The loader will use the default configuration.");
confFilePath = "";
}
else if(!fileExists(confFilePath))
{
log_error("The file \'%s\' does not exist, will be using default config.", confFilePath);
confFilePath = "";
}
setenv(LINDBERGH_CONFIG_PATH, confFilePath, 1);
}
if (strlen(contFilePath) > 0)
{
if (hasSpaces(contFilePath))
{
log_error("The path \'%s\' for the controls file cannot contain spaces.", contFilePath);
log_error("Controls will use the default controls config.");
contFilePath = "";
}
else if (!fileExists(contFilePath))
{
log_error("The file \'%s\' does not exist, will try to load controls.ini from the game folder or", contFilePath);
log_error("will be using the default controls config.");
contFilePath = "";
}
setenv(LINDBERGH_CONTROLS_PATH, contFilePath, 1);
}
if (strlen(contDbFilePath) > 0)
{
if (hasSpaces(contDbFilePath))
{
log_error("The path \'%s\' for the gamecontrollerdb.txt file cannot contain spaces.", contDbFilePath);
log_error("Additional game controller mappings will not be added.");
contDbFilePath = "";
}
else if (!fileExists(contDbFilePath))
{
log_error("The file \'%s\' does not exist, additional mapping db will be omitted.", contDbFilePath);
contDbFilePath = "";
}
setenv(LINDBERGH_CONTROLS_DB_PATH, contDbFilePath, 1);
}
if (zink && nvidia)
{
log_error("Cannot pass both, zink and nvidia options at the same time.");
@@ -348,33 +413,59 @@ void setEnvironmentVariables(const char *ldLibPath, const char *originalDir, con
}
}
void printUsage(char *argv[])
void printUsage(char *programName)
{
printf("%s [GAME_PATH] [OPTIONS]\n", argv[0]);
printf("%s [GAME_PATH] [OPTIONS]\n", basename(programName));
printf("Options:\n");
printf(" --test | -t Runs the test mode\n");
printf(" --segaboot | -s Runs segaboot\n");
printf(" --zink | -z Runs with Zink\n");
printf(" --nvidia | -n Runs with nVidia GPU when is as a secondary GPU in a laptop\n");
printf(" --gdb Runs with GDB\n");
printf(" --list-controllers Lists available controllers and inputs\n");
printf(" --version Displays the version of the loader and team's names\n");
printf(" --help Displays this usage text\n");
printf(" --config | -c Specifies configuration path\n");
printf(" --gamepath | -g Specifies game path without ELF name\n");
printf(" --test | -t Runs the test mode\n");
printf(" --segaboot | -s Runs segaboot\n");
printf(" --zink | -z Runs with Zink\n");
printf(" --nvidia | -n Runs with nVidia GPU when is as a secondary GPU in a laptop\n");
printf(" --gdb Runs with GDB\n");
printf(" --list-controllers | -l Lists available controllers and inputs for EVDEV.\n");
printf(" --list-guids | -lg Lists available SDL controllers GUIDs.\n");
printf(" --version | -v Displays the version of the loader and team's names\n");
printf(" --help | -h Displays this usage text\n");
printf(" --config | -c Specifies configuration ini file path\n");
printf(" --controls | -o Specifies controls ini file path\n");
printf(" --controlsdb | -d Specifies gamecontrollerdb.txt file path\n");
printf(" --gamepath | -g Specifies game path without ELF name\n");
printf(" --create | -C Creates a default config or controls file. Use '--create --help' for more info.\n");
}
void printCreateUsage(char *programName)
{
printf("Usage for the --create option:\n");
printf(" %s --create <sub-option> [output_path] [output_filename]\n\n", basename(programName));
printf("Arguments:\n");
printf(" sub-option The type of file to create. Can be one of:\n");
printf(" config (for lindbergh.ini)\n");
printf(" controls (for controls.ini)\n");
printf(" output_path (Optional) The directory where the file will be created.\n");
printf(" If not provided, the file is created in the current directory.\n");
printf(" output_filename (Optional) The name of the file to be created. Must end with .ini.\n");
printf(" If not provided, the default name will be used (lindbergh.ini or controls.ini).\n\n");
printf("Examples:\n");
printf(" %s --create config\n", basename(programName));
printf(" %s --create controls ./my_game_config\n", basename(programName));
printf(" %s --create config ./my_game_config myconfig.ini\n", basename(programName));
printf(" %s --create --help\n", basename(programName));
}
void printVersion()
{
printf("Lindbergh Loader v%d.%d\n", MAJOR_VERSION, MINOR_VERSION);
printf("Created by: %s\n", TEAM);
printf("Lindbergh Loader v%d.%d.%d\n", MAJOR_VERSION, MINOR_VERSION, UPDATE_VERSION);
printf("Lead Programming/Reversing: %s\n", TEAM);
printf("Collaborators: %s\n", COLLABORATORS);
printf("Special Thanks to: %s\n", SPECIAL_THANKS);
}
int listControllers()
int listEvDevControllers()
{
Controllers controllers;
ControllerStatus status = initControllers(&controllers);
ControllerStatus status = loadEvdevControllers(&controllers);
if (status != CONTROLLER_STATUS_SUCCESS)
{
log_error("Failed to list controllers\n");
@@ -395,28 +486,137 @@ int listControllers()
}
}
stopControllers(&controllers);
stopEvdevControllers(&controllers);
return EXIT_SUCCESS;
}
int main(int argc, char *argv[])
{
if (argc > 1 && strcmp(argv[1], "--version") == 0)
if (argc > 1 && (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-v") == 0))
{
printVersion();
return EXIT_SUCCESS;
}
if (argc > 1 && strcmp(argv[1], "--help") == 0)
if (argc > 1 && (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0))
{
printUsage(argv);
printUsage(argv[0]);
return EXIT_SUCCESS;
}
if (argc > 1 && strcmp(argv[1], "--list-controllers") == 0)
if (argc > 1 && (strcmp(argv[1], "--list-controllers") == 0 || strcmp(argv[1], "-l") == 0))
{
return listControllers();
return listEvDevControllers();
}
if (argc > 1 && (strcmp(argv[1], "--list-guids") == 0 || strcmp(argv[1], "-lg") == 0))
{
return listSdlControllers();
}
if (argc > 1 && (strcmp(argv[1], "--create") == 0 || strcmp(argv[1], "-C") == 0))
{
if (argc < 3)
{
log_error("Missing arguments for --create. See usage below.\n");
printCreateUsage(argv[0]);
return EXIT_FAILURE;
}
if (strcmp(argv[2], "--help") == 0)
{
printCreateUsage(argv[0]);
return EXIT_SUCCESS;
}
char *subOption = argv[2];
char *path = ".";
char *filename = NULL;
char *argCopyForDirname = NULL;
char *argCopyForBasename = NULL;
if (strcmp(subOption, "config") != 0 && strcmp(subOption, "controls") != 0)
{
log_error("Invalid sub-option for --create: '%s'. Must be 'config' or 'controls'.\n", subOption);
printCreateUsage(argv[0]);
return EXIT_FAILURE;
}
if (argc > 3)
{
if (argc > 4)
{
path = argv[3];
filename = argv[4];
}
else
{
char *arg = argv[3];
const char *dot = strrchr(arg, '.');
if (dot && strcmp(dot, ".ini") == 0)
{
argCopyForDirname = strdup(arg);
argCopyForBasename = strdup(arg);
path = dirname(argCopyForDirname);
filename = basename(argCopyForBasename);
}
// if arg is a path
else
{
path = arg;
}
}
}
if (filename)
{
const char *dot = strrchr(filename, '.');
if (!dot || strcmp(dot, ".ini") != 0)
{
log_error("Invalid filename: '%s'. Must have .ini extension.\n", filename);
if(argCopyForDirname) free(argCopyForDirname);
if(argCopyForBasename) free(argCopyForBasename);
return EXIT_FAILURE;
}
}
if (!dirExists(path))
{
log_error("Output directory does not exist: %s\n", path);
if(argCopyForDirname) free(argCopyForDirname);
if(argCopyForBasename) free(argCopyForBasename);
return EXIT_FAILURE;
}
char finalPath[MAX_PATH_LENGTH];
if (strcmp(subOption, "config") == 0)
{
if (!filename)
{
filename = "lindbergh.ini";
}
snprintf(finalPath, sizeof(finalPath), "%s/%s", path, filename);
createDefaultIni(finalPath);
log_info("Successfully created configuration file at %s\n", finalPath);
}
else if (strcmp(subOption, "controls") == 0)
{
if (!filename)
{
filename = "controls.ini";
}
snprintf(finalPath, sizeof(finalPath), "%s/%s", path, filename);
createDefaultControlsIni(finalPath);
log_info("Successfully created controls file at %s\n", finalPath);
}
if(argCopyForDirname) free(argCopyForDirname);
if(argCopyForBasename) free(argCopyForBasename);
return EXIT_SUCCESS;
}
char passedGamePath[MAX_PATH_LENGTH] = "";
@@ -424,6 +624,8 @@ int main(int argc, char *argv[])
char forcedGameDir[MAX_PATH_LENGTH] = "";
char gameELF[MAX_PATH_LENGTH] = "";
char extConfigPath[MAX_PATH_LENGTH] = "";
char extControlsPath[MAX_PATH_LENGTH] = "";
char extControlsDbPath[MAX_PATH_LENGTH] = "";
char originalDir[MAX_PATH_LENGTH] = "";
bool gdb = false;
bool testMode = false;
@@ -474,6 +676,28 @@ int main(int argc, char *argv[])
continue;
}
if (strcmp(argv[i], "-o") == 0 || strcmp(argv[i], "--controls") == 0)
{
if (i + 1 >= argc)
{
break;
}
strncpy(extControlsPath, argv[i + 1], MAX_PATH_LENGTH);
i += 1;
continue;
}
if (strcmp(argv[i], "-d") == 0 || strcmp(argv[i], "--controlsdb") == 0)
{
if (i + 1 >= argc)
{
break;
}
strncpy(extControlsDbPath, argv[i + 1], MAX_PATH_LENGTH);
i += 1;
continue;
}
if ((strcmp(argv[i], "-g") == 0 || strcmp(argv[i], "--gamepath") == 0) && i + 1 < argc)
{
strncpy(passedGamePath, argv[i + 1], MAX_PATH_LENGTH);
@@ -584,7 +808,7 @@ int main(int argc, char *argv[])
if (gameELF[0] == '\0')
{
log_error("No game ELF found in current directory.\n");
printUsage(argv);
printUsage(argv[0]);
return EXIT_FAILURE;
}
}
@@ -595,19 +819,29 @@ int main(int argc, char *argv[])
}
char *targetedGameDir = strlen(forcedGameDir) ? forcedGameDir : passedGamePath;
char *lib_path = findPreloadLibrary(originalDir, targetedGameDir);
if (!lib_path)
char *libPath = strdup(findPreloadLibrary(originalDir, PRELOAD_FILE_NAME));
if (strcmp(libPath, "") == 0)
{
log_error("Error: %s not found in known locations.\n", PRELOAD_FILE_NAME);
return 1;
}
setEnvironmentVariables(lib_path, originalDir, targetedGameDir, zink, nvidia, extConfigPath);
char *libOpenal = NULL;
if (strstr(gameELF, "q2satl_lind") != NULL)
{
libOpenal = strdup(findPreloadLibrary(originalDir, PRELOAD_OPENAL));
if (strcmp(libOpenal, "") == 0)
{
printf("You might not get sound because libopenal.so.0 was not found.\n");
}
}
setEnvironmentVariables(libPath, originalDir, targetedGameDir, zink, nvidia, extConfigPath, extControlsPath, extControlsDbPath,
libOpenal);
if (segaboot)
{
strcpy(gameELF, "segaboot -t");
// testMode = true;
}
// Final command
@@ -626,7 +860,10 @@ int main(int argc, char *argv[])
if (gdb)
{
char temp[128];
strcpy(temp, "gdb ");
if (testMode)
strcpy(temp, "gdb --args ");
else
strcpy(temp, "gdb ");
strcat(temp, command);
strcpy(command, temp);
}
@@ -1,4 +1,4 @@
#include "motionboard.h"
#include "motionBoard.h"
ssize_t motionboardRead(int fd, void *buf, size_t count) {
return 0;
+3129 -3062
View File
File diff suppressed because it is too large Load Diff
+2 -12
View File
@@ -1,14 +1,4 @@
#include <sys/types.h>
int initPatch();
void setVariable(size_t address, size_t value);
void patchMemory(size_t address, char *value);
void detourFunction(size_t address, void *function);
void replaceCallAtAddress(size_t address, void *function);
void stubReturn();
int stubRetOne();
int stubRetMinusOne();
char stubRetZeroChar();
int patchedPrintf(char *format,...);
int patchedPuts(char *s);
void callLoadCard();
void callEjectCard();
+217
View File
@@ -0,0 +1,217 @@
#include <dlfcn.h>
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <netdb.h>
#include "config.h"
#include "log.h"
#include "flowControl.h"
extern uint32_t gId;
char *rtunedIPs[4];
char *rtunedSortedIPs[4];
u_int8_t rtunedLinkId = 0;
uint8_t rtunedCabs = 0;
void hummerSetIPs(size_t firstAddress)
{
if (!getConfig()->enableNetworkPatches)
return;
if (strcmp(getConfig()->IpCab1, "") != 0)
setVariable(firstAddress, (size_t)(void *)getConfig()->IpCab1);
if (strcmp(getConfig()->IpCab2, "") != 0)
setVariable(firstAddress + 4, (size_t)(void *)getConfig()->IpCab2);
if (strcmp(getConfig()->IpCab3, "") != 0)
setVariable(firstAddress + 8, (size_t)(void *)getConfig()->IpCab3);
if (strcmp(getConfig()->IpCab4, "") != 0)
setVariable(firstAddress + 12, (size_t)(void *)getConfig()->IpCab4);
}
int rtunedGetCabs()
{
return rtunedCabs;
}
void rtunedGetLinkIdandCabs()
{
FILE *f = fopen(getConfig()->sramPath, "rb");
if (f == NULL)
return;
fseek(f, 0xc011, SEEK_SET);
fread(&rtunedLinkId, 1, 1, f);
fseek(f, 0xc019, SEEK_SET);
fread(&rtunedCabs, 1, 1, f);
fclose(f);
}
void rtunedRotateIps(char *ori[], char *dst[], int total, int pos)
{
for (int i = 0; i < total; i++)
{
dst[i] = ori[(pos + i) % total];
}
dst[total - 1] = ori[pos - 1];
}
void rtunedSetIPs()
{
if (!getConfig()->enableNetworkPatches)
return;
for (int x = 0; x < 4; x++)
{
rtunedIPs[x] = "0.0.0.0";
rtunedSortedIPs[x] = "0.0.0.0";
}
uint8_t setIps = 0;
if (strcmp(getConfig()->IpCab1, "") != 0)
{
rtunedIPs[0] = getConfig()->IpCab1;
setIps++;
}
if (strcmp(getConfig()->IpCab2, "") != 0)
{
rtunedIPs[1] = getConfig()->IpCab2;
setIps++;
}
if (strcmp(getConfig()->IpCab3, "") != 0)
{
rtunedIPs[2] = getConfig()->IpCab3;
setIps++;
}
if (strcmp(getConfig()->IpCab4, "") != 0)
{
rtunedIPs[3] = getConfig()->IpCab4;
setIps++;
}
if (setIps != rtunedCabs)
log_warn("Warning: You have %d IPs set in the config file and %d Cabinets set in the TestMenu.", setIps, rtunedCabs);
rtunedRotateIps(rtunedIPs, rtunedSortedIPs, rtunedCabs, rtunedLinkId);
}
int rtunedBind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{
if (rtunedCabs > 1)
{
int idx1 = 0;
int idx2 = 0;
for (int i = 0; i < rtunedCabs; i++)
{
setVariable(0x0851e890 + idx1, inet_addr(rtunedSortedIPs[i]));
setVariable(0x0851d7c0 + idx2, inet_addr(rtunedIPs[i]));
idx1 += 16;
idx2 += 4;
}
uint32_t ip = inet_addr(rtunedIPs[rtunedLinkId - 1]);
uint32_t invIp = ((ip & 0xFF) << 24) | ((ip & 0xFF00) << 8) | ((ip & 0xFF0000) >> 8) | ((ip & 0xFF000000) >> 24);
uint32_t invIpBcast = ((ip & 0xFF) << 24) | ((ip & 0xFF00) << 8) | ((ip & 0xFF0000) >> 8) | 0x000000FF;
setVariable(0x0851bf90, invIp);
setVariable(0x0851bf98, invIpBcast);
}
return bind(sockfd, addr, addrlen);
}
int inet_aton(const char *cp, struct in_addr *inp)
{
int (*_inet_aton)(const char *cp, struct in_addr *inp) = dlsym(RTLD_NEXT, "inet_aton");
if (gId == HARLEY_DAVIDSON)
{
if (getConfig()->enableNetworkPatches)
{
if ((strcmp(cp, "192.168.1.1") == 0 || strcmp(cp, "192.168.1.5") == 0 || strcmp(cp, "192.168.1.9") == 0))
{
if (strcmp(getConfig()->IpCab1, "") != 0)
return _inet_aton(getConfig()->IpCab1, inp);
else
return _inet_aton("127.0.0.1", inp);
}
if ((strcmp(cp, "192.168.1.2") == 0 || strcmp(cp, "192.168.1.7") == 0 || strcmp(cp, "192.168.1.10") == 0) &&
strcmp(getConfig()->IpCab2, "") != 0)
{
return _inet_aton(getConfig()->IpCab2, inp);
}
if ((strcmp(cp, "192.168.1.3") == 0 || strcmp(cp, "192.168.1.7") == 0 || strcmp(cp, "192.168.1.11") == 0) &&
strcmp(getConfig()->IpCab3, "") != 0)
{
return _inet_aton(getConfig()->IpCab4, inp);
}
if ((strcmp(cp, "192.168.1.4") == 0 || strcmp(cp, "192.168.1.8") == 0 || strcmp(cp, "192.168.1.12") == 0) &&
strcmp(getConfig()->IpCab4, "") != 0)
{
return _inet_aton(getConfig()->IpCab4, inp);
}
}
else
{
return _inet_aton("127.0.0.1", inp);
}
}
return _inet_aton(cp, inp);
}
in_addr_t inet_addr(const char *cp)
{
in_addr_t (*_inet_addr)(const char *cp) = dlsym(RTLD_NEXT, "inet_addr");
if (getConfig()->enableNetworkPatches)
{
if (gId == TOO_SPICY)
{
if (strcmp("10.0.0.1", cp) == 0 && strcmp(getConfig()->tooSpicyIpCab1, "") != 0)
{
cp = getConfig()->tooSpicyIpCab1;
}
else if (strcmp("10.0.0.2", cp) == 0 && strcmp(getConfig()->tooSpicyIpCab2, "") != 0)
{
cp = getConfig()->tooSpicyIpCab2;
}
}
else if (gId == SEGA_RACE_TV)
{
// Standalone = 4, Main = 0, 2-Sub = 1, 3-Sub = 2 and 4-Sub = 3
if (strcmp("192.168.49.1", cp) == 0 || strcmp("192.168.49.2", cp) == 0 || strcmp("192.168.49.3", cp) == 0 ||
strcmp("192.168.49.4", cp) == 0)
{
if (strcmp(getConfig()->srtvIP, "") != 0)
cp = getConfig()->srtvIP;
else
// Prevents the game to crash if the IP does not match the PC's IP.
cp = "127.0.0.1";
}
}
}
return _inet_addr(cp);
}
char *strstr(const char *haystack, const char *needle)
{
char *(*_strstr)(const char *__haystack, const char *__needle) = dlsym(RTLD_NEXT, "strstr");
if (strcmp(needle, "eth0") == 0 && getConfig()->enableNetworkPatches && strcmp(getConfig()->nicName, "") != 0)
{
return _strstr(haystack, getConfig()->nicName);
}
return _strstr(haystack, needle);
}
int gethostbyname_r(const char *name, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop)
{
int (*_gethostbyname_r)(const char *name, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop) =
dlsym(RTLD_NEXT, "gethostbyname_r");
void *addr = __builtin_return_address(0);
if (gId == QUIZ_AXA && addr == (void *)0x0832609d)
{
ret = 0;
buf[0] = '\0';
result = 0;
h_errnop = 0;
return -1;
}
return _gethostbyname_r(name, ret, buf, buflen, result, h_errnop);
}
+10
View File
@@ -0,0 +1,10 @@
#pragma once
#include <stdio.h>
#include <unistd.h>
void hummerSetIPs(size_t firstAddress);
int rtunedGetCabs();
void rtunedGetLinkIdandCabs();
void rtunedSetIPs();
int rtunedBind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
+2025 -2005
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,15 +1,4 @@
#include <stdio.h>
#include <sys/types.h>
#include <stdint.h>
#include <fcntl.h>
#include <linux/serial.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <unistd.h>
#include "rideboard.h"
#include "rideBoard.h"
RideState rideState = {0};
+316
View File
@@ -0,0 +1,316 @@
#ifndef __i386__
#define __i386__
#endif
#undef __x86_64__
#define GL_GLEXT_PROTOTYPES
#include <dlfcn.h>
// #include <fontconfig/fontconfig.h>
#include <GL/glx.h>
#include <GL/freeglut.h>
#include <SDL3/SDL.h>
#include <SDL3/SDL_error.h>
#include <SDL3_ttf/SDL_ttf.h>
#include <stdbool.h>
#include <unistd.h>
#include "blitStretching.h"
#include "config.h"
#include "customCursor.h"
#include "sdlInput.h"
#include "jvs.h"
#include "resources/LiberationMono-Regular.h"
#include "log.h"
#include "sdlCalls.h"
extern uint32_t gId;
extern int gGrp;
extern int gWidth;
extern int gHeight;
extern int drawableW;
extern int drawableH;
bool creatingWindow = false;
SDL_Window *sdlWindow = NULL;
SDL_GLContext sdlContext = NULL;
Display *x11Display = NULL;
Window x11Window;
char sdlGameTitle[256] = {0};
extern SDL_Cursor *customCursor;
extern SDL_Cursor *touchCursor;
int glutInitialized = 0;
bool isFullScreen = false;
bool sdlFontInit = false;
SDL_Renderer *fontRenderer;
TTF_Font *font;
void GLAPIENTRY openglDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message,
const void *userParam)
{
if (id == 1099)
return;
printf("OpenGL Debug Message:\n");
printf("Source: 0x%x\n", source);
printf("Type: 0x%x\n", type);
printf("ID: %u\n", id);
printf("Severity: 0x%x\n", severity);
printf("Message: %s\n", message);
if (severity == GL_DEBUG_SEVERITY_HIGH)
{
printf("This is a high severity error!\n");
}
}
int initSDL()
{
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMEPAD))
{
log_error("SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
return 1;
}
if (gGrp == GROUP_OUTRUN_TEST)
{
if (!TTF_Init())
{
log_error("SDL_ttf could not initialize! SDL_ttf Error: %s\n", SDL_GetError());
return 1;
}
SDL_IOStream *rw = SDL_IOFromConstMem(LiberationMonoRegular_ttf, LiberationMonoRegular_ttf_length);
float fontSize = 16.0;
if (gWidth > 640)
fontSize = fontSize * (((float)gWidth / 640.0f) + ((float)gHeight / 480.0f)) / 2.0f;
font = TTF_OpenFontIO(rw, 1, fontSize);
fontRenderer = SDL_CreateRenderer(sdlWindow, "");
}
return 0;
}
void startSDL(int *argcp, char **argv)
{
creatingWindow = true;
int numDisplays;
SDL_DisplayID *sdlDisplayId = SDL_GetDisplays(&numDisplays);
if (numDisplays > 1)
log_warn("More than 1 display detected, will use the first one.\n");
const SDL_DisplayMode *displayMode = SDL_GetCurrentDisplayMode(sdlDisplayId[0]);
if (displayMode == NULL)
{
log_error("SDL_GetCurrentDisplayMode Error: %s\n", SDL_GetError());
SDL_Quit();
exit(EXIT_FAILURE);
}
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); // Double buffering
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); // 24-bit depth buffer
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); // Set the alpha size to 8 bits
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32);
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
if (gGrp == GROUP_ABC || gGrp == GROUP_VF5 || gId == R_TUNED || gId == GHOST_SQUAD_EVOLUTION || gId == SEGA_RACE_TV ||
gId == MJ4_REVG || gId == MJ4_EVO)
{
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1);
}
uint32_t windowFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN;
strcat(sdlGameTitle, getGameName());
// Hacky way to make AxA games render the characters properly
if (gId == QUIZ_AXA || gId == QUIZ_AXA_LIVE)
sdlWindow = SDL_CreateWindow(sdlGameTitle, 1024, 768, windowFlags);
else
sdlWindow = SDL_CreateWindow(sdlGameTitle, gWidth, gHeight, windowFlags);
if (!sdlWindow)
{
SDL_Quit();
log_error("Window could not be created! SDL_Error: %s\n", SDL_GetError());
exit(EXIT_FAILURE);
}
if (gId == GHOST_SQUAD_EVOLUTION || gId == MJ4_EVO || gId == MJ4_REVG)
SDL_SetWindowSize(sdlWindow, gWidth, gHeight + 1);
x11Display = (Display *)SDL_GetPointerProperty(SDL_GetWindowProperties(sdlWindow), SDL_PROP_WINDOW_X11_DISPLAY_POINTER, NULL);
x11Window = (Window)SDL_GetNumberProperty(SDL_GetWindowProperties(sdlWindow), SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0);
if (!x11Display || !x11Window)
{
log_error("This program is not running on X11 or failed to get window/display.\n");
}
sdlContext = SDL_GL_CreateContext(sdlWindow);
if (!sdlContext)
{
SDL_DestroyWindow(sdlWindow);
SDL_Quit();
log_error("OpenGL context could not be created! SDL_Error: %s\n", SDL_GetError());
exit(EXIT_FAILURE);
}
if (getConfig()->showDebugMessages)
{
// Enable OpenGL debug output
glEnable(GL_DEBUG_OUTPUT);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
glDebugMessageCallback(openglDebugCallback, NULL);
}
// If games are any of the LGJ or Primeval Hunt, we prevent the window to resize.
if ((gGrp == GROUP_LGJ || gId == PRIMEVAL_HUNT) && !getConfig()->fullscreen)
SDL_SetWindowMaximumSize(sdlWindow, gWidth, gHeight);
else if (gGrp != GROUP_LGJ)
SDL_SetWindowMaximumSize(sdlWindow, displayMode->w, displayMode->h);
SDL_SetWindowMinimumSize(sdlWindow, gWidth, gHeight);
// Hacky way to make AxA games render the characters properly
if (gId == QUIZ_AXA || gId == QUIZ_AXA_LIVE)
SDL_SetWindowPosition(sdlWindow, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
if (getConfig()->fullscreen)
{
SDL_SetWindowFullscreenMode(sdlWindow, NULL);
SDL_SetWindowFullscreen(sdlWindow, true);
isFullScreen = true;
}
initBlitting();
SDL_ShowWindow(sdlWindow);
Uint64 startTime = SDL_GetTicks();
int running = 1;
// We clear the window background
while (running)
{
if (SDL_GetTicks() - startTime >= 1000)
running = 0;
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
SDL_GL_SwapWindow(sdlWindow);
}
if (gId != PRIMEVAL_HUNT)
SDL_SetWindowResizable(sdlWindow, true);
creatingWindow = false;
printf(" RESOLUTION: %dx%d\n", gWidth, gHeight);
loadCursors();
if (customCursor)
setCursor(customCursor);
if ((gId == MJ4_REVG || gId == MJ4_EVO || gId == QUIZ_AXA || gId == QUIZ_AXA_LIVE) && strcmp(getConfig()->touchCursor, "") != 0 &&
getConfig()->emulateTouchscreen)
setCursor(touchCursor);
else if (getConfig()->hideCursor)
SDL_HideCursor();
}
void sdlQuit()
{
setSwitch(SYSTEM, BUTTON_TEST, 1);
usleep(50000);
setSwitch(SYSTEM, BUTTON_TEST, 0);
usleep(50000);
SDL_DestroyWindow(sdlWindow);
SDL_Quit();
exit(0);
}
void pollEvents()
{
SDL_Event event;
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_EVENT_KEY_DOWN:
{
if (gGrp != GROUP_LGJ && gId != PRIMEVAL_HUNT)
{
SDL_Keymod mod = SDL_GetModState();
if ((event.key.key == SDLK_RETURN && (mod & SDL_KMOD_ALT)) || event.key.key == SDLK_F11)
{
if (isFullScreen)
{
if (!SDL_SetWindowFullscreen(sdlWindow, 0))
{
log_error("Error setting windowed mode: %s\n", SDL_GetError());
}
else
{
if ((long long)gWidth * 3 == (long long)gHeight * 4)
SDL_SetWindowSize(sdlWindow, gWidth + 1, gHeight);
else
SDL_SetWindowSize(sdlWindow, gWidth, gHeight + 1);
isFullScreen = false;
if (getConfig()->fullscreen)
SDL_SetWindowBordered(sdlWindow, true);
}
}
else
{
if (!SDL_SetWindowFullscreen(sdlWindow, true))
{
log_error("Error setting fullscreen mode: %s\n", SDL_GetError());
}
else
{
isFullScreen = true;
}
}
break;
}
}
}
case SDL_EVENT_KEY_UP:
case SDL_EVENT_MOUSE_BUTTON_DOWN:
case SDL_EVENT_MOUSE_BUTTON_UP:
case SDL_EVENT_MOUSE_MOTION:
case SDL_EVENT_GAMEPAD_BUTTON_DOWN:
case SDL_EVENT_GAMEPAD_BUTTON_UP:
case SDL_EVENT_GAMEPAD_AXIS_MOTION:
case SDL_EVENT_JOYSTICK_BUTTON_DOWN:
case SDL_EVENT_JOYSTICK_BUTTON_UP:
case SDL_EVENT_JOYSTICK_AXIS_MOTION:
case SDL_EVENT_JOYSTICK_HAT_MOTION:
processSdlEvent(&event);
break;
case SDL_EVENT_WINDOW_CLOSE_REQUESTED:
sdlQuit();
break;
case SDL_EVENT_WINDOW_RESTORED:
{
if (((long long)gWidth * 3 == (long long)gHeight * 4) || gGrp == GROUP_HUMMER)
SDL_SetWindowSize(sdlWindow, gWidth + 1, gHeight);
else
SDL_SetWindowSize(sdlWindow, gWidth, gHeight + 1);
}
break;
case SDL_EVENT_WINDOW_MOUSE_LEAVE:
case SDL_EVENT_WINDOW_MOUSE_ENTER:
processSdlEvent(&event);
default:
break;
}
}
if (gGrp == GROUP_HOD4 || gGrp == GROUP_HOD4_TEST)
updateGunShake();
updateCombinedAxes();
processChangedActions();
}
+7
View File
@@ -0,0 +1,7 @@
#pragma once
#include <GL/gl.h>
int initSDL();
void startSDL(int *argcp, char **argv);
void pollEvents();
File diff suppressed because it is too large Load Diff
+223
View File
@@ -0,0 +1,223 @@
#pragma once
#include <SDL3/SDL.h>
#include <stdbool.h>
#include "iniParser.h"
#include "jvs.h"
// --- CORE DATA STRUCTURES ---
#define MAX_PLAYERS 4
#define MAX_ENTITIES (MAX_PLAYERS + 1)
#define MAX_JOYSTICKS 8
#define MAX_JOY_BUTTONS 32
#define MAX_JOY_AXES 32
#define MAX_JOY_HATS 4
#define MAX_MOUSE_BUTTONS 16
typedef enum
{
LA_INVALID = -1,
LA_Test ,
LA_Coin,
LA_GearUp,
LA_GearDown,
LA_ViewChange,
LA_MusicChange,
LA_Boost,
LA_BoostRight,
LA_Start,
LA_Service,
LA_Up,
LA_Down,
LA_Left,
LA_Right,
LA_Button1,
LA_Button2,
LA_Button3,
LA_Button4,
LA_Button5,
LA_Button6,
LA_Button7,
LA_Button8,
LA_Button9,
LA_Button10,
LA_Trigger,
LA_OutOfScreen,
LA_Reload,
LA_GunButton,
LA_ActionButton,
LA_ChangeButton,
LA_PedalLeft,
LA_PedalRight,
LA_Steer,
LA_Gas,
LA_Brake,
LA_GunX,
LA_GunY,
LA_Steer_Left,
LA_Steer_Right,
LA_Gas_Digital,
LA_Brake_Digital,
LA_ABC_X,
LA_ABC_Left,
LA_ABC_Right,
LA_ABC_Y,
LA_ABC_Up,
LA_ABC_Down,
LA_Throttle,
LA_Throttle_Accelerate,
LA_Throttle_Slowdown,
LA_GunTrigger,
LA_MissileTrigger,
LA_ClimaxSwitch,
LA_CardInsert,
LA_Card1Insert,
LA_Card2Insert,
LA_A,
LA_B,
LA_C,
LA_D,
LA_E,
LA_F,
LA_G,
LA_H,
LA_I,
LA_J,
LA_K,
LA_L,
LA_M,
LA_N,
LA_Reach,
LA_Chi,
LA_Pon,
LA_Kan,
LA_Agari,
LA_Cancel,
NUM_LOGICAL_ACTIONS
} LogicalAction;
typedef enum
{
INPUT_TYPE_NONE,
INPUT_TYPE_KEY,
INPUT_TYPE_JOY_AXIS,
INPUT_TYPE_JOY_BUTTON,
INPUT_TYPE_JOY_HAT,
INPUT_TYPE_MOUSE_AXIS,
INPUT_TYPE_MOUSE_BUTTON,
INPUT_TYPE_GAMEPAD_AXIS,
INPUT_TYPE_GAMEPAD_BUTTON
} SDLInputType;
typedef enum
{
AXIS_MODE_FULL,
AXIS_MODE_POSITIVE_HALF,
AXIS_MODE_NEGATIVE_HALF,
AXIS_MODE_DIGITAL
} AxisMode;
typedef struct
{
SDLInputType type;
int deviceIndex;
int sdlId;
AxisMode axisMode;
int axisThreshold;
bool isInverted;
JVSPlayer player;
LogicalAction action;
} ControlBinding;
typedef struct
{
ControlBinding bindings[2];
} BindingPair;
typedef struct
{
ControlBinding up;
ControlBinding down;
ControlBinding left;
ControlBinding right;
} HatBinding;
typedef struct
{
bool isActive;
float analogValue;
float positiveContribution;
float negativeContribution;
} ActionState;
typedef struct
{
enum
{
JVS_CALL_SWITCH,
JVS_CALL_ANALOGUE,
JVS_CALL_COIN,
JVS_CALL_NONE
} call_type;
JVSInput jvsInput;
} JVSActionMapping;
typedef struct
{
JVSPlayer player;
LogicalAction action;
} ChangedAction;
typedef struct
{
bool isCentering;
bool isCombinedAxis;
int deadzone; // Added to store per-action deadzone
} LogicalActionProperties;
typedef struct
{
SDL_Joystick *joysticks[MAX_JOYSTICKS];
SDL_Gamepad *controllers[MAX_JOYSTICKS];
SDL_Haptic *haptics[MAX_JOYSTICKS];
int joysticksCount;
// int hapticsCount;
// int numButtons[MAX_JOYSTICKS];
// int numAxes[MAX_JOYSTICKS];
// int numHats[MAX_JOYSTICKS];
} SDLControllers;
// Ini Creation
#define MAX_INI_KEYS_PER_SECTION 100
#define MAX_INI_VALUE_LENGTH 256
typedef struct
{
char key[64];
char value[MAX_INI_VALUE_LENGTH];
} IniFileEntry;
typedef struct
{
const char *name;
IniFileEntry entries[MAX_INI_KEYS_PER_SECTION];
int num_entries;
} IniFileSection;
int initSdlInput(char *controlsPath);
int loadProfileFromIni(const IniSection *section);
void loadGlobalConfig(const IniConfig *ini);
void processChangedActions();
void processSdlEvent(const SDL_Event *e);
void initJvsMappings();
void setDefaultMappings();
void remapPerGame();
void initActionProperties();
void updateGunShake();
void updateCombinedAxes();
void detectCombinedAxes();
void getLogicalActionString(const ControlBinding *binding, char *out_str, size_t str_size, const char *name);
bool needsPlayer(LogicalAction action, const char *name);
int listSdlControllers(void);
-217
View File
@@ -1,217 +0,0 @@
#ifndef __i386__
#define __i386__
#endif
#undef __x86_64__
#define GL_GLEXT_PROTOTYPES
#include <GL/freeglut.h>
#include <stdbool.h>
#include <dlfcn.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_syswm.h>
#include <X11/Xlib.h>
#include "config.h"
#include "input.h"
#include "sdlcalls.h"
#include "fps_limiter.h"
#include "customcursor.h"
extern uint32_t gId;
bool SDLWindowCreated = false;
extern bool GLUTGame;
SDL_Window *SDLwindow;
SDL_GLContext SDLcontext;
Display *x11Display;
Window x11Window;
char SDLgameTitle[256] = {0};
extern fps_limit fpsLimit;
extern void *customCursor;
extern void *phTouchCursor;
int glutInitialized = 0;
void GLAPIENTRY openglDebugCallback2(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
const GLchar *message, const void *userParam)
{
if (id == 1099)
return;
// Print the debug message details
printf("OpenGL Debug Message:\n");
printf("Source: 0x%x\n", source);
printf("Type: 0x%x\n", type);
printf("ID: %u\n", id);
printf("Severity: 0x%x\n", severity);
printf("Message: %s\n", message);
// You can filter based on severity or other attributes if needed
if (severity == GL_DEBUG_SEVERITY_HIGH)
{
printf("This is a high severity error!\n");
}
}
void initSDL(int *argcp, char **argv)
{
void FGAPIENTRY (*_glutInit)(int *argcp, char **argv) = dlsym(RTLD_NEXT, "glutInit");
switch (gId)
{
case OUTRUN_2_SP_SDX_TEST:
case OUTRUN_2_SP_SDX_REVA_TEST:
case OUTRUN_2_SP_SDX_REVA_TEST2:
if (!glutInitialized)
{
glutInitialized = 1;
_glutInit(argcp, argv);
return;
}
}
switch (gId)
{
case AFTER_BURNER_CLIMAX:
case AFTER_BURNER_CLIMAX_REVA:
case AFTER_BURNER_CLIMAX_REVB:
case AFTER_BURNER_CLIMAX_SDX:
case AFTER_BURNER_CLIMAX_SDX_REVA:
case AFTER_BURNER_CLIMAX_SE:
case AFTER_BURNER_CLIMAX_SE_REVA:
setenv("SDL_VIDEODRIVER", "x11", 1);
}
SDLWindowCreated = true;
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
fprintf(stderr, "SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
exit(1);
}
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); // Double buffering
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 1); // 24-bit depth buffer
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); // Set the alpha size to 8 bits
switch (gId)
{
case AFTER_BURNER_CLIMAX:
case AFTER_BURNER_CLIMAX_REVA:
case AFTER_BURNER_CLIMAX_REVB:
case AFTER_BURNER_CLIMAX_SDX:
case AFTER_BURNER_CLIMAX_SDX_REVA:
case AFTER_BURNER_CLIMAX_SE:
case AFTER_BURNER_CLIMAX_SE_REVA:
case R_TUNED:
case VIRTUA_FIGHTER_5:
case VIRTUA_FIGHTER_5_REVA:
case VIRTUA_FIGHTER_5_REVB:
case VIRTUA_FIGHTER_5_REVE:
case VIRTUA_FIGHTER_5_EXPORT:
case VIRTUA_FIGHTER_5_R:
case VIRTUA_FIGHTER_5_R_REVD:
case VIRTUA_FIGHTER_5_R_REVG:
case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVA:
case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB:
case VIRTUA_FIGHTER_5_FINAL_SHOWDOWN_REVB_6000:
case GHOST_SQUAD_EVOLUTION:
case SEGA_RACE_TV:
case MJ4_REVG:
case MJ4_EVO:
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1);
}
uint32_t windowFlags = SDL_WINDOW_OPENGL;
strcat(SDLgameTitle, getGameName());
SDLwindow = SDL_CreateWindow(SDLgameTitle, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, getConfig()->width,
getConfig()->height, windowFlags);
if (!SDLwindow)
{
fprintf(stderr, "Window could not be created! SDL_Error: %s\n", SDL_GetError());
exit(1);
}
SDL_SysWMinfo info;
SDL_VERSION(&info.version);
if (SDL_GetWindowWMInfo(SDLwindow, &info))
{
if (info.subsystem == SDL_SYSWM_X11)
{
x11Display = info.info.x11.display;
x11Window = info.info.x11.window;
}
else
{
fprintf(stderr, "This program is not running on X11.\n");
}
}
else
{
fprintf(stderr, "SDL_GetWindowWMInfo Error: %s\n", SDL_GetError());
}
SDLcontext = SDL_GL_CreateContext(SDLwindow);
if (!SDLcontext)
{
fprintf(stderr, "OpenGL context could not be created! SDL_Error: %s\n", SDL_GetError());
exit(1);
}
glClearColor(0.1f, 0.1f, 0.1f, 1.0f); // Your bg color
// Force initial clear
glClear(GL_COLOR_BUFFER_BIT);
SDL_GL_SwapWindow(SDLwindow);
// Now show the window
SDL_ShowWindow(SDLwindow);
printf(" SDL RESOLUTION: %dx%d\n\n", getConfig()->width, getConfig()->height);
if (getConfig()->fullscreen)
{
SDL_SetWindowFullscreen(SDLwindow, SDL_WINDOW_FULLSCREEN);
}
loadCursors();
setCursor(customCursor);
if (getConfig()->hideCursor || gId == PRIMEVAL_HUNT)
SDL_ShowCursor(SDL_DISABLE);
}
void sdlQuit()
{
SDL_DestroyWindow(SDLwindow);
SDL_Quit();
exit(0);
}
void pollEvents()
{
SDL_Event event;
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
sdlQuit();
break;
case SDL_KEYDOWN:
case SDL_KEYUP:
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
case SDL_MOUSEMOTION:
handleSdlEvents(&event);
break;
case SDL_WINDOWEVENT:
if (event.window.event == SDL_WINDOWEVENT_CLOSE)
{
SDL_Quit();
}
break;
default:
break;
}
}
}
-2
View File
@@ -1,2 +0,0 @@
void initSDL(int *argcp, char **argv);
void pollEvents();
@@ -1,7 +1,7 @@
#include <stdio.h>
#include "config.h"
#include "securityboard.h"
#include "securityBoard.h"
#include "log.h"
#define SECURITY_BOARD_FRONT_PANEL 0x38
@@ -52,11 +52,11 @@ int securityBoardSetDipResolution(int width, int height)
setResolutionDips(1, 1, 0);
else if (width == 1360 && height == 768)
setResolutionDips(1, 1, 1);
else {
if(getConfig()->showDebugMessages)
else
{
if (getConfig()->showDebugMessages)
log_warn("Resolution not original, setting dips to 640 x 480.\n");
}
return 0;
}
@@ -81,15 +81,15 @@ int securityBoardSetSwitch(JVSInput switchNumber, int value)
{
switch (switchNumber)
{
case BUTTON_TEST:
securityBoard.testSwitch = value;
break;
case BUTTON_SERVICE:
securityBoard.serviceSwitch = value;
break;
default:
printf("Error: Attempted to set a security board switch incorrectly");
return -1;
case BUTTON_TEST:
securityBoard.testSwitch = value;
break;
case BUTTON_SERVICE:
securityBoard.serviceSwitch = value;
break;
default:
printf("Error: Attempted to set a security board switch incorrectly");
return -1;
}
return 0;
@@ -104,36 +104,36 @@ int securityBoardIn(uint16_t port, uint32_t *data)
{
switch (port)
{
case SECURITY_BOARD_FRONT_PANEL_NON_ROOT:
case SECURITY_BOARD_FRONT_PANEL:
{
uint32_t result = 0xFFFFFFFF;
if (securityBoard.dipSwitch[6]) // bit12
result &= ~0x800; // DIP 6
if (securityBoard.dipSwitch[5]) // bit11
result &= ~0x400; // DIP 5
if (securityBoard.dipSwitch[4]) // bit10
result &= ~0x200; // DIP 4
if (securityBoard.dipSwitch[3]) // bit9
result &= ~0x100; // DIP 3
if (securityBoard.dipSwitch[2]) // bit8
result &= ~0x80; // DIP 2
if (securityBoard.dipSwitch[1]) // bit7
result &= ~0x40; // DIP 1
if (securityBoard.dipSwitch[8]) // bit6
result &= ~0x20;
if (securityBoard.dipSwitch[7]) // bit5
result &= ~0x10;
if (securityBoard.serviceSwitch) // bit4
result &= ~0x08;
if (securityBoard.testSwitch) // bit3
result &= ~0x04;
*data = result;
}
break;
default:
case SECURITY_BOARD_FRONT_PANEL_NON_ROOT:
case SECURITY_BOARD_FRONT_PANEL:
{
uint32_t result = 0xFFFFFFFF;
if (securityBoard.dipSwitch[6]) // bit12
result &= ~0x800; // DIP 6
if (securityBoard.dipSwitch[5]) // bit11
result &= ~0x400; // DIP 5
if (securityBoard.dipSwitch[4]) // bit10
result &= ~0x200; // DIP 4
if (securityBoard.dipSwitch[3]) // bit9
result &= ~0x100; // DIP 3
if (securityBoard.dipSwitch[2]) // bit8
result &= ~0x80; // DIP 2
if (securityBoard.dipSwitch[1]) // bit7
result &= ~0x40; // DIP 1
if (securityBoard.dipSwitch[8]) // bit6
result &= ~0x20;
if (securityBoard.dipSwitch[7]) // bit5
result &= ~0x10;
if (securityBoard.serviceSwitch) // bit4
result &= ~0x08;
if (securityBoard.testSwitch) // bit3
result &= ~0x04;
*data = result;
}
break;
default:
break;
}
return 0;
+858
View File
@@ -0,0 +1,858 @@
#include <dlfcn.h>
#include <fcntl.h>
#include <libgen.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "../libxdiff/xdiff/xdiff.h"
#include "config.h"
#include "shaderPatches.h"
#include "shaderWork/common.h"
#include "shaderWork/2spicy.h"
#include "shaderWork/axa.h"
#include "shaderWork/gsevo.h"
#include "shaderWork/harley.h"
#include "shaderWork/hod4.h"
#include "shaderWork/hodex.h"
#include "shaderWork/hummer.h"
#include "shaderWork/id.h"
#include "shaderWork/lgj.h"
#include "shaderWork/primeval.h"
#include "shaderWork/rambo.h"
#include "shaderWork/vt3.h"
extern uint32_t gId;
extern int gGrp;
bool cachedShaderFilesLoaded = false;
bool fdHook = false;
int shaderIDX = 0;
SearchReplace attribsSet[] = {{"POSITION;", "ATTR0;"}, {"COLOR0;", "ATTR3;"}, {"COLOR;", "ATTR3;"}, {"BINORMAL;", "ATTR15;"},
{"NORMAL;", "ATTR2;"}, {"TEXCOORD0;", "ATTR8;"}, {"TEXCOORD1;", "ATTR9;"}, {"TEXCOORD2;", "ATTR10;"},
{"TEXCOORD3;", "ATTR11;"}, {"TANGENT;", "ATTR14;"}, {"BLENDWEIGHT;", "ATTR1;"}, {"BLENDINDICES;", "ATTR7;"}};
int attribsSetCount = sizeof(attribsSet) / sizeof(SearchReplace);
#define XDLT_STD_BLKSIZE (1024 * 8)
/**
* We check if the shader being loaded is one of the ones in the list of files
* we need to patch
*/
bool shaderFileInList(const char *pathname, int *idx)
{
char cwd[256];
int gpuVendor = getConfig()->GPUVendor;
if (gId == GHOST_SQUAD_EVOLUTION)
{
if (getConfig()->GPUVendor != NVIDIA_GPU)
{
for (int x = 0; x < gsevoShaderPatchesCount; x++)
{
if ((strcmp(gsevoMesaShaderPatches[x].fileName, pathname) == 0) && (gsevoMesaShaderPatches[x].shaderBufferSize != 0))
{
*idx = x;
return true;
}
}
return false;
}
else
{
for (int x = 0; x < gsevoShaderPatchesCount; x++)
{
if ((strcmp(gsevoNvidiaShaderPatches[x].fileName, pathname) == 0) && (gsevoNvidiaShaderPatches[x].shaderBufferSize != 0))
{
*idx = x;
return true;
}
}
return false;
}
}
else if (gId == RAMBO || gId == RAMBO_CHINA)
if (getConfig()->GPUVendor != NVIDIA_GPU)
{
for (int x = 0; x < ramboMesaShaderPatchesCount; x++)
{
if ((strcmp(ramboMesaShaderPatches[x].fileName, basename((char *)pathname)) == 0) &&
(ramboMesaShaderPatches[x].shaderBufferSize != 0))
{
*idx = x;
return true;
}
}
return false;
}
else
{
for (int x = 0; x < ramboNvidiaShaderPatchesCount; x++)
{
if ((strcmp(ramboNvidiaShaderPatches[x].fileName, basename((char *)pathname)) == 0) &&
(ramboNvidiaShaderPatches[x].shaderBufferSize != 0))
{
*idx = x;
return true;
}
}
return false;
}
else if (gGrp == GROUP_HOD4)
{
for (int x = 0; x < hod4ShaderPatchesCount; x++)
{
if ((strcmp(hod4ShaderPatches[x].fileName, basename((char *)pathname)) == 0) && (hod4ShaderPatches[x].shaderBufferSize != 0))
{
*idx = x;
return true;
}
}
return false;
}
else if (gGrp == GROUP_HOD4_SP)
{
for (int x = 0; x < hod4spShaderPatchesCount; x++)
{
if ((strcmp(hod4spShaderPatches[x].fileName, basename((char *)pathname)) == 0) &&
(hod4spShaderPatches[x].shaderBufferSize != 0))
{
*idx = x;
return true;
}
}
return false;
}
else if (gId == HARLEY_DAVIDSON)
{
for (int x = 0; x < harleyShaderPatchesCount; x++)
{
if ((strcmp(harleyShaderPatches[x].fileName, basename((char *)pathname)) == 0) &&
(harleyShaderPatches[x].shaderBufferSize != 0))
{
*idx = x;
return true;
}
}
return false;
}
else if (gId == PRIMEVAL_HUNT)
{
for (int x = 0; x < phShaderPatchesCount; x++)
{
if ((strcmp(basename((char *)phShaderPatches[x].fileName), basename((char *)pathname)) == 0) &&
(phShaderPatches[x].shaderBufferSize != 0))
{
*idx = x;
return true;
}
}
return false;
}
else if (gGrp == GROUP_HUMMER)
{
for (int x = 0; x < hummerFilesToModCount; x++)
{
if ((strcmp(basename((char *)hummerShaderFilesToMod[x].fileName), basename((char *)pathname)) == 0) &&
(hummerShaderFilesToMod[x].shaderBufferSize != 0))
{
*idx = x;
return true;
}
}
return false;
}
else if (gId == TOO_SPICY)
{
if (gpuVendor != NVIDIA_GPU)
{
for (int x = 0; x < tooSpicyShaderPatchesCount; x++)
{
if ((strcmp(tooSpicyShaderPatches[x].fileName, basename((char *)pathname)) == 0) &&
(tooSpicyShaderPatches[x].shaderBufferSize != 0))
{
*idx = x;
return true;
}
}
}
return false;
}
else if (gId == THE_HOUSE_OF_THE_DEAD_EX)
{
if (gpuVendor != NVIDIA_GPU)
{
for (int x = 0; x < hodexShaderPatchesCount; x++)
{
if ((strcmp(hodexShaderPatches[x].fileName, basename((char *)pathname)) == 0) &&
(hodexShaderPatches[x].shaderBufferSize != 0))
{
*idx = x;
return true;
}
}
}
return false;
}
else if(gId == QUIZ_AXA)
{
for (int x = 0; x < axaShaderPatchesCount; x++)
{
if ((strcmp(basename((char *)axaShaderPatches[x].fileName), basename((char *)pathname)) == 0) &&
(axaShaderPatches[x].shaderBufferSize != 0))
{
*idx = x;
return true;
}
}
return false;
}
else if (gId == QUIZ_AXA_LIVE)
{
for (int x = 0; x < axalShaderPatchesCount; x++)
{
if ((strcmp(basename((char *)axalShaderPatches[x].fileName), basename((char *)pathname)) == 0) &&
(axalShaderPatches[x].shaderBufferSize != 0))
{
*idx = x;
return true;
}
}
return false;
}
const char *fName = strrchr(pathname, '/');
char searchFileName[40];
char *searchFolder1;
char *searchFolder2;
char *format;
ShaderFilesToMod *filesToMod;
int filesToModCount;
if (gGrp == GROUP_LGJ)
{
if (gpuVendor == NVIDIA_GPU && getConfig()->lgjRenderWithMesa != 1)
return false;
filesToMod = lgjShaderFilesToMod;
filesToModCount = lgjFilesToModCount;
searchFolder1 = "/shader/Cg";
searchFolder2 = "/extraShader/Cg";
format = "%s/inc%s";
}
else if (gGrp == GROUP_ID4_EXP || gGrp == GROUP_ID4_JAP || gGrp == GROUP_ID5)
{
if (gpuVendor == NVIDIA_GPU)
return false;
// Set default values
filesToMod = idShaderFilesToMod;
filesToModCount = idFilesToModCount;
searchFolder1 = "/shader/Cg/inc";
searchFolder2 = "/data/Shader";
format = "%s%s";
if (gGrp == GROUP_ID4_JAP)
{
filesToMod = id4jShaderFilesToMod;
filesToModCount = id4FilesToModCount;
}
else if (gGrp == GROUP_ID5)
{
searchFolder2 = "/data/V5SHADER";
}
}
else if (gGrp == GROUP_VT3 || gGrp == GROUP_VT3_TEST)
{
if (gpuVendor == NVIDIA_GPU)
return false;
filesToMod = vt3ShaderFilesToMod;
filesToModCount = vt3FilesToModCount;
searchFolder1 = "/shader/Cg/inc";
searchFolder2 = "/shader";
format = "%s%s";
}
if (strstr(pathname, searchFolder1) != NULL)
{
sprintf((void *)searchFileName, format, searchFolder1, fName);
}
else if (strstr(pathname, searchFolder2) != NULL)
{
sprintf((void *)searchFileName, format, searchFolder2, fName);
}
else
{
return false;
}
for (int x = 0; x < filesToModCount; x++)
{
if (strcmp(filesToMod[x].fileName, searchFileName) == 0)
{
*idx = x;
return true;
}
}
return false;
}
/**
* We return the size of the shader we will use to replace the original
* tricking ftell.
*/
long int ftellGetShaderSize(int idx)
{
if (gId == GHOST_SQUAD_EVOLUTION)
{
return getConfig()->GPUVendor != NVIDIA_GPU ? gsevoMesaShaderPatches[idx].shaderBufferSize
: gsevoNvidiaShaderPatches[idx].shaderBufferSize;
}
else if (gGrp == GROUP_LGJ)
{
return lgjShaderFilesToMod[idx].shaderBufferSize;
}
else if (gGrp == GROUP_ID4_EXP || gGrp == GROUP_ID5)
{
return idShaderFilesToMod[idx].shaderBufferSize;
}
else if (gGrp == GROUP_ID4_JAP)
{
return id4jShaderFilesToMod[idx].shaderBufferSize;
}
else if (gGrp == GROUP_VT3 || gGrp == GROUP_VT3_TEST)
{
return vt3ShaderFilesToMod[idx].shaderBufferSize;
}
else if (gId == TOO_SPICY)
{
return tooSpicyShaderPatches[idx].shaderBufferSize;
}
else if (gId == RAMBO || gId == RAMBO_CHINA)
{
return getConfig()->GPUVendor != NVIDIA_GPU ? ramboMesaShaderPatches[idx].shaderBufferSize
: ramboNvidiaShaderPatches[idx].shaderBufferSize;
}
else if (gGrp == GROUP_HOD4)
{
return hod4ShaderPatches[idx].shaderBufferSize;
}
else if (gGrp == GROUP_HOD4_SP)
{
return hod4spShaderPatches[idx].shaderBufferSize;
}
else if (gId == THE_HOUSE_OF_THE_DEAD_EX)
{
return hodexShaderPatches[idx].shaderBufferSize;
}
else if (gGrp == GROUP_HUMMER)
{
return hummerShaderFilesToMod[idx].shaderBufferSize;
}
else if (gId == PRIMEVAL_HUNT)
{
return phShaderPatches[idx].shaderBufferSize;
}
else if (gId == HARLEY_DAVIDSON)
{
return harleyShaderPatches[idx].shaderBufferSize;
}
else if (gId == QUIZ_AXA)
{
return axaShaderPatches[idx].shaderBufferSize;
}
else if (gId == QUIZ_AXA_LIVE)
{
return axalShaderPatches[idx].shaderBufferSize;
}
return -1;
}
/**
* We replace the file being loaded by fread and insted, we fill the buffer
* with the data we want.
*/
size_t freadReplace(void *buf, size_t size, size_t count, int idx)
{
if (gId == GHOST_SQUAD_EVOLUTION)
{
if (getConfig()->GPUVendor != NVIDIA_GPU)
{
memcpy(buf, gsevoMesaShaderPatches[idx].shaderBuffer, gsevoMesaShaderPatches[idx].shaderBufferSize);
}
else
{
memcpy(buf, gsevoNvidiaShaderPatches[idx].shaderBuffer, gsevoNvidiaShaderPatches[idx].shaderBufferSize);
}
return 1;
}
else if (gGrp == GROUP_LGJ)
{
memcpy(buf, lgjShaderFilesToMod[idx].shaderBuffer, size);
return size;
}
else if (gGrp == GROUP_ID4_EXP || gGrp == GROUP_ID5)
{
memcpy(buf, idShaderFilesToMod[idx].shaderBuffer, size);
return size;
}
else if (gGrp == GROUP_ID4_JAP)
{
memcpy(buf, id4jShaderFilesToMod[idx].shaderBuffer, size);
return size;
}
else if (gGrp == GROUP_VT3 || gGrp == GROUP_VT3_TEST)
{
memcpy(buf, vt3ShaderFilesToMod[idx].shaderBuffer, size);
return size;
}
else if (gId == TOO_SPICY)
{
memcpy(buf, tooSpicyShaderPatches[idx].shaderBuffer, tooSpicyShaderPatches[idx].shaderBufferSize);
return tooSpicyShaderPatches[idx].shaderBufferSize;
}
else if (gId == RAMBO || gId == RAMBO_CHINA)
{
if (getConfig()->GPUVendor != NVIDIA_GPU)
{
memcpy(buf, ramboMesaShaderPatches[idx].shaderBuffer, ramboMesaShaderPatches[idx].shaderBufferSize);
return ramboMesaShaderPatches[idx].shaderBufferSize;
}
else
{
memcpy(buf, ramboNvidiaShaderPatches[idx].shaderBuffer, ramboNvidiaShaderPatches[idx].shaderBufferSize);
return ramboNvidiaShaderPatches[idx].shaderBufferSize;
}
}
else if (gGrp == GROUP_HOD4)
{
memcpy(buf, hod4ShaderPatches[idx].shaderBuffer, hod4ShaderPatches[idx].shaderBufferSize);
return hod4ShaderPatches[idx].shaderBufferSize;
}
else if (gGrp == GROUP_HOD4_SP)
{
memcpy(buf, hod4spShaderPatches[idx].shaderBuffer, hod4spShaderPatches[idx].shaderBufferSize);
return hod4spShaderPatches[idx].shaderBufferSize;
}
else if (gId == THE_HOUSE_OF_THE_DEAD_EX)
{
memcpy(buf, hodexShaderPatches[idx].shaderBuffer, hodexShaderPatches[idx].shaderBufferSize);
return hodexShaderPatches[idx].shaderBufferSize;
}
else if (gGrp == GROUP_HUMMER)
{
memcpy(buf, hummerShaderFilesToMod[idx].shaderBuffer, hummerShaderFilesToMod[idx].shaderBufferSize);
return hummerShaderFilesToMod[idx].shaderBufferSize;
}
else if (gId == PRIMEVAL_HUNT)
{
memcpy(buf, phShaderPatches[idx].shaderBuffer, phShaderPatches[idx].shaderBufferSize);
return phShaderPatches[idx].shaderBufferSize;
}
else if (gId == HARLEY_DAVIDSON)
{
memcpy(buf, harleyShaderPatches[idx].shaderBuffer, harleyShaderPatches[idx].shaderBufferSize);
return harleyShaderPatches[idx].shaderBufferSize;
}
else if (gId == QUIZ_AXA)
{
memcpy(buf, axaShaderPatches[idx].shaderBuffer, axaShaderPatches[idx].shaderBufferSize);
return axaShaderPatches[idx].shaderBufferSize;
}
else if (gId == QUIZ_AXA_LIVE)
{
memcpy(buf, axalShaderPatches[idx].shaderBuffer, axalShaderPatches[idx].shaderBufferSize);
return axalShaderPatches[idx].shaderBufferSize;
}
return -1;
}
int loadShader(char *path, char *buffer)
{
int fd = open(path, O_RDONLY);
if (fd == -1)
{
printf("Error opening %s.\n", path);
exit(1);
}
int s = lseek(fd, 0, SEEK_END);
lseek(fd, 0, SEEK_SET);
read(fd, buffer, s);
close(fd);
buffer[s] = '\0';
return s;
}
int xdlt_load_mmfile(char const *path, mmfile_t *mf)
{
int fd;
int pos = 0;
long size;
char *blk;
if (xdl_init_mmfile(mf, XDLT_STD_BLKSIZE, XDL_MMF_ATOMIC) < 0)
{
exit(1);
}
if ((fd = open(path, O_RDONLY)) == -1)
{
perror(path);
xdl_free_mmfile(mf);
exit(1);
}
size = lseek(fd, 0, SEEK_END);
lseek(fd, pos, SEEK_SET);
blk = (char *)xdl_mmfile_writeallocate(mf, size);
if (blk == NULL)
{
xdl_free_mmfile(mf);
close(fd);
exit(1);
}
if (read(fd, blk, (size_t)size) != (size_t)size)
{
perror(path);
xdl_free_mmfile(mf);
close(fd);
exit(1);
}
close(fd);
return 0;
}
/**
* Functions used by libxdiff for memory handling
*/
static void *wrap_malloc(void *priv, unsigned int size)
{
return malloc(size);
}
static void wrap_free(void *priv, void *ptr)
{
free(ptr);
}
static void *wrap_realloc(void *priv, void *ptr, unsigned int size)
{
return realloc(ptr, size);
}
int handle_patch(void *priv, mmbuffer_t *mb, int nbuf)
{
mmfile_t *patch = (mmfile_t *)priv;
xdl_writem_mmfile(patch, mb, nbuf);
return 0;
}
/**
* We load a few shader files from disk, we patch them and cache them in an
* array to later feed them to game intercepting fopen, ftell and fread.
*/
void cacheModedShaderFiles()
{
char cwd[256];
char fullPath[512];
char shaderBuffer[100000];
char *newProgram;
ShaderFilesToMod *shaderFilesToMod;
int filesToModCount;
memallocator_t malt;
malt.priv = NULL;
malt.malloc = wrap_malloc;
malt.free = wrap_free;
malt.realloc = wrap_realloc;
xdl_set_allocator(&malt);
mmfile_t patchedFile;
ShaderFilesToPatch *shaderFilesToPatch;
int shaderFilesToPatchCount;
char folderName[50];
sprintf(folderName, "/../fs/shader/");
if (gGrp == GROUP_LGJ)
{
for (int x = 0; x < lgjFilesToModCount; x++)
{
getcwd(cwd, sizeof(cwd));
sprintf(fullPath, "%s%s", cwd, lgjShaderFilesToMod[x].fileName);
loadShader(fullPath, shaderBuffer);
newProgram = replaceInBlock(shaderBuffer, attribsSet, attribsSetCount, "", "");
newProgram = replaceInBlock(newProgram, lgjShaderReplaceSet1, lgjShaderReplaceCount1, "", "");
// Dirty hack to fix just 1 shader
if (x == 3)
{
newProgram = replaceInBlock(newProgram, lgjShaderReplaceSet2, lgjShaderReplaceCount2, "", "");
}
lgjShaderFilesToMod[x].shaderBufferSize = strlen(newProgram);
lgjShaderFilesToMod[x].shaderBuffer = strndup(newProgram, strlen(newProgram));
free(newProgram);
}
}
else if (gGrp == GROUP_ID4_EXP || gGrp == GROUP_ID4_JAP || gGrp == GROUP_ID5)
{
if (gGrp == GROUP_ID4_JAP)
{
shaderFilesToMod = id4jShaderFilesToMod;
filesToModCount = id4FilesToModCount;
}
else
{
shaderFilesToMod = idShaderFilesToMod;
filesToModCount = idFilesToModCount;
}
for (int x = 0; x < filesToModCount; x++)
{
if (gGrp == GROUP_ID5)
{
char *fName = shaderFilesToMod[x].fileName;
shaderFilesToMod[x].fileName = replaceSubstring(fName, 0, strlen(fName), "Shader", "V5SHADER");
}
getcwd(cwd, sizeof(cwd));
sprintf(fullPath, "%s%s", cwd, shaderFilesToMod[x].fileName);
loadShader(fullPath, shaderBuffer);
if (strcmp(shaderFilesToMod[x].fileName, "/data/V5SHADER/effect_p.fx") == 0)
{
newProgram = replaceInBlock(shaderBuffer, id5ShaderReplaceSetForSmoke, id5ShaderReplaceSetForSmokeCount, "", "");
}
else if (strcmp(shaderFilesToMod[x].fileName, "/data/Shader/effect_p.fx") == 0)
{
newProgram = strndup(shaderBuffer, strlen(shaderBuffer));
}
else
{
newProgram = replaceInBlock(shaderBuffer, attribsSet, attribsSetCount, "struct\tVS_INPUT_P", "");
newProgram = replaceInBlock(newProgram, attribsSet, attribsSetCount, "struct VS_INPUT", "struct VS_OUTPUT");
newProgram = replaceInBlock(newProgram, idShaderReplaceSet, idShaderReplaceCount, "", "");
}
shaderFilesToMod[x].shaderBufferSize = strlen(newProgram);
shaderFilesToMod[x].shaderBuffer = strndup(newProgram, strlen(newProgram));
free(newProgram);
}
}
else if (gGrp == GROUP_VT3 || gGrp == GROUP_VT3_TEST)
{
for (int x = 0; x < vt3FilesToModCount; x++)
{
getcwd(cwd, sizeof(cwd));
sprintf(fullPath, "%s/..%s", cwd, vt3ShaderFilesToMod[x].fileName);
loadShader(fullPath, shaderBuffer);
newProgram = replaceInBlock(shaderBuffer, attribsSet, attribsSetCount, "struct\tVS_INPUT_P", "");
newProgram = replaceInBlock(newProgram, vt3ShaderReplaceSet2, vt3ShaderReplaceCount2, "Out main(", ")");
newProgram = replaceInBlock(newProgram, vt3ShaderReplaceSet1, vt3ShaderReplaceCount1, "", "");
vt3ShaderFilesToMod[x].shaderBufferSize = strlen(newProgram);
vt3ShaderFilesToMod[x].shaderBuffer = strndup(newProgram, strlen(newProgram));
free(newProgram);
}
}
else if (gGrp == GROUP_HUMMER)
{
for (int x = 0; x < hummerFilesToModCount; x++)
{
getcwd(cwd, sizeof(cwd));
sprintf(fullPath, "%s%s", cwd, hummerShaderFilesToMod[x].fileName);
loadShader(fullPath, shaderBuffer);
newProgram = replaceInBlock(shaderBuffer, hummerShaderReplaceSet1, hummerShaderReplaceSet1Count, "", "");
if (getConfig()->GPUVendor != NVIDIA_GPU)
{
newProgram = replaceInBlock(newProgram, hummerShaderReplaceMesa, hummerShaderReplaceMesaCount, "", "");
}
if (getConfig()->hummerFlickerFix)
{
newProgram = replaceInBlock(newProgram, hummerShaderReplaceFlicker, hummerShaderReplaceFlickerCount, "", "");
}
hummerShaderFilesToMod[x].shaderBufferSize = strlen(newProgram);
hummerShaderFilesToMod[x].shaderBuffer = strndup(newProgram, strlen(newProgram));
free(newProgram);
}
}
else
{
if (gId == TOO_SPICY)
{
shaderFilesToPatch = tooSpicyShaderPatches;
shaderFilesToPatchCount = tooSpicyShaderPatchesCount;
}
else if (gId == RAMBO || gId == RAMBO_CHINA)
{
if (getConfig()->GPUVendor != NVIDIA_GPU)
{
shaderFilesToPatch = ramboMesaShaderPatches;
shaderFilesToPatchCount = ramboMesaShaderPatchesCount;
}
else
{
shaderFilesToPatch = ramboNvidiaShaderPatches;
shaderFilesToPatchCount = ramboNvidiaShaderPatchesCount;
}
}
else if (gId == HARLEY_DAVIDSON)
{
shaderFilesToPatch = harleyShaderPatches;
shaderFilesToPatchCount = harleyShaderPatchesCount;
}
else if (gId == THE_HOUSE_OF_THE_DEAD_EX)
{
shaderFilesToPatch = hodexShaderPatches;
shaderFilesToPatchCount = hodexShaderPatchesCount;
}
else if (gGrp == GROUP_HOD4)
{
sprintf(folderName, "/../fs/dat/");
shaderFilesToPatchCount = hod4ShaderPatchesCount;
shaderFilesToPatch = hod4ShaderPatches;
}
else if (gGrp == GROUP_HOD4_SP)
{
sprintf(folderName, "/../fs/dat/");
shaderFilesToPatchCount = hod4spShaderPatchesCount;
shaderFilesToPatch = hod4spShaderPatches;
}
else if (gId == PRIMEVAL_HUNT)
{
sprintf(folderName, "/../data/nnstdshader/");
shaderFilesToPatchCount = phShaderPatchesCount;
shaderFilesToPatch = phShaderPatches;
}
else if (gId == GHOST_SQUAD_EVOLUTION)
{
shaderFilesToPatchCount = gsevoShaderPatchesCount;
sprintf(folderName, "/%s", "");
if (getConfig()->GPUVendor != NVIDIA_GPU)
{
shaderFilesToPatch = gsevoMesaShaderPatches;
}
else
{
shaderFilesToPatch = gsevoNvidiaShaderPatches;
}
}
else if (gId == QUIZ_AXA)
{
sprintf(folderName, "/../../data/shader/");
shaderFilesToPatchCount = axaShaderPatchesCount;
shaderFilesToPatch = axaShaderPatches;
}
else if (gId == QUIZ_AXA_LIVE)
{
sprintf(folderName, "/../../data/shader/");
shaderFilesToPatchCount = axalShaderPatchesCount;
shaderFilesToPatch = axalShaderPatches;
}
}
for (int x = 0; x < shaderFilesToPatchCount; x++)
{
mmfile_t oriFile, patch;
xdemitcb_t ecb, rjecb;
getcwd(cwd, sizeof(cwd));
sprintf(fullPath, "%s%s%s", cwd, folderName, shaderFilesToPatch[x].fileName);
if (xdlt_load_mmfile(fullPath, &oriFile) != 0)
{
printf("Error reading oriFile.\n");
exit(1);
return;
}
if (xdl_init_mmfile(&patchedFile, XDLT_STD_BLKSIZE, XDL_MMF_ATOMIC) < 0)
{
printf("Error Initializong patchedFile.\n");
exit(1);
return;
}
xdl_free_mmfile(&patchedFile);
if (xdl_init_mmfile(&patch, XDLT_STD_BLKSIZE, XDL_MMF_ATOMIC) < 0)
{
printf("Error Initializong patch.\n");
exit(1);
return;
}
xdl_free_mmfile(&patch);
xdl_write_mmfile(&patch, shaderFilesToPatch[x].patchBuffer, shaderFilesToPatch[x].patchBufferSize);
ecb.priv = &patchedFile;
ecb.outf = handle_patch;
if (xdl_bpatch(&oriFile, &patch, &ecb))
{
printf("Error patching shaders, are you sure your files are original?\n");
}
else
{
char *buff = malloc(patchedFile.fsize + 1);
xdl_seek_mmfile(&patchedFile, 0);
xdl_read_mmfile(&patchedFile, buff, patchedFile.fsize);
shaderFilesToPatch[x].shaderBufferSize = patchedFile.fsize;
shaderFilesToPatch[x].shaderBuffer = malloc(patchedFile.fsize);
memcpy((void *)shaderFilesToPatch[x].shaderBuffer, buff, patchedFile.fsize);
free(buff);
}
}
if (getConfig()->showDebugMessages)
{
printf("Modded Shaders cached.\n");
}
cachedShaderFilesLoaded = true;
}
void *vt3Open(void *fb, const char *s, int mode)
{
bool (*_vt3_open)(void *, const char *, int) = dlsym(RTLD_NEXT, "_ZNSt13basic_filebufIcSt11char_traitsIcEE4openEPKcSt13_Ios_Openmode");
if (shaderFileInList(s, &shaderIDX))
{
fdHook = true;
return (void *)_vt3_open((void *)fb, s, mode);
}
return (void *)_vt3_open((void *)fb, s, mode);
}
int vt3Close(void *fb)
{
bool (*_vt3_close)(void *) = dlsym(RTLD_NEXT, "_ZNSt13basic_filebufIcSt11char_traitsIcEE5closeEv");
if (fdHook)
{
fdHook = false;
shaderIDX = 0;
}
return _vt3_close((void *)fb);
}
u_int32_t *vt3Tellg(u_int32_t *size, void *is)
{
u_int32_t *(*_vt3_tellg)(void *, void *) = dlsym(RTLD_NEXT, "_ZNSi5tellgEv");
if (fdHook)
{
*(int *)(size) = ftellGetShaderSize(shaderIDX);
return size;
}
return _vt3_tellg(size, is);
}
void *vt3Read(void *is, char *s, long long n)
{
void *(*_vt3_read)(void *is, char *s, long long n) = dlsym(RTLD_NEXT, "_ZNSi4readEPci");
if (fdHook)
{
freadReplace(s, n, 1, shaderIDX);
return is;
}
return _vt3_read(is, s, n);
}
+12
View File
@@ -0,0 +1,12 @@
#pragma once
#include <stdbool.h>
#include <sys/types.h>
#include "shaderWork/common.h"
bool shaderFileInList(const char *pathname, int *idx);
size_t freadReplace(void *buf, size_t size, size_t count, int idx);
long int ftellGetShaderSize(int idx);
void *vt3Open(void *fb, const char *s, int mode);
int vt3Close(void *fb);
u_int32_t *vt3Tellg(u_int32_t *size, void *is);
void *vt3Read(void *is, char *s, long long n);
File diff suppressed because it is too large Load Diff
@@ -1,21 +1,20 @@
#pragma once
#include <GL/gl.h>
#include <GL/glext.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <sys/types.h>
typedef struct
{
const char *search;
const char *replacement;
} SearchReplace;
void gsEvoElfShaderPatcher();
void gl_ProgramStringARB(int vertex_prg, int program_fmt, int program_len, char *program);
void gl_ShaderSourceARB(u_int32_t shaderObj, int count, const char **const string, const int *length);
#ifdef __cplusplus
extern "C"
{
#endif
bool shaderFileInList(const char *pathname, int *idx);
size_t freadReplace(void *buf, size_t size, size_t count, int idx);
long int ftellGetShaderSize(int idx);
#ifdef __cplusplus
}
#endif
void *gl_XGetProcAddressARB(const unsigned char *procName);
void gl_MultiTexCoord2fARB(u_int32_t target, float s, float t);
void gl_Color4ub(u_char red, u_char green, u_char blue, u_char alpha);
@@ -27,26 +26,18 @@ void gl_ProgramParameters4fvNV(u_int32_t target, u_int32_t index, int32_t count,
void cacheModedShaderFiles();
void srtvElfShaderPatcher();
void gl_BindProgramNV(u_int32_t target, u_int32_t id);
void gl_LoadProgramNV(u_int32_t target, u_int32_t program, int len, const u_int8_t *string);
void gl_LoadProgramNV(GLenum target, GLuint program, GLsizei len, char *string);
void gl_DeleteProgramsNV(int n, const u_int32_t *programs);
void gl_EndOcclusionQueryNV(void);
void gl_BeginOcclusionQueryNV(u_int32_t id);
u_int32_t Gl_VertexShader_createFromAsmFile(char *filename);
u_int32_t Gl_FragmentShader_createShaderFromFile(char *filename);
void gl_TexImage2DOR(u_int32_t target, int level, int internalformat, int width, int height, int border,
u_int32_t format, u_int32_t type, const void *pixels);
void gl_InitWindowSizeOR(int width, int height);
void glut_GameModeStringOR(const char *string);
char *replaceSubstring(const char *buffer, int start, int end, const char *search, const char *replace);
int compileWithCGC(char *command);
void loadLibCg();
void cacheNnstdshader();
void *vt3_open(void *fb, const char *s, int mode);
int vt3_close(void *fb);
u_int32_t *vt3_tellg(u_int32_t *size, void *is);
void *vt3_read(void *is, char *s, long long n);
void vf5SetExposure(int var, float exposure);
void vf5SetIntensity(int var, float *intensity);
void vf5GetIdStart(void *iostream, int *idStart);
void vf5SetDiffuse(int var, float r, float g, float b, float a);
void hookVf5FSExposure(uint32_t expAddr, uint32_t intAddr, uint32_t idStartAddr, uint32_t difAddr);
void hookVf5FSExposure(uint32_t expAddr, uint32_t intAddr, uint32_t idStartAddr, uint32_t difAddr);
char *replaceInBlock(char *source, SearchReplace *searchReplace, int searchReplaceCount, char *startSearch, char *endSearch);
char *replaceSubstring(const char *buffer, int start, int end, const char *search, const char *replace);
+480
View File
@@ -0,0 +1,480 @@
#include "common.h"
// File: average.frag
const char toospicyFileName_0[] = "average.frag";
const size_t toospicyPatchSize_0 = 271;
const unsigned char toospicyPatchBuffer_0[] = {
0xe4, 0x97, 0xac, 0x3a, 0x18, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x01, 0x2b,
0x76, 0x65, 0x63, 0x34, 0x20, 0x56, 0x45, 0x52, 0x54, 0x45, 0x58, 0x5f, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x3b, 0x09,
0x0d, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x74, 0x65, 0x78, 0x43,
0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x02, 0x69, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x01, 0x14, 0x66, 0x6c, 0x6f,
0x61, 0x74, 0x20, 0x63, 0x20, 0x3d, 0x20, 0x30, 0x2e, 0x30, 0x3b, 0x0d, 0x0a, 0x09, 0x76, 0x65, 0x63, 0x02, 0xac,
0x00, 0x00, 0x00, 0x93, 0x00, 0x00, 0x00, 0x01, 0x02, 0x2f, 0x2f, 0x02, 0x3f, 0x01, 0x00, 0x00, 0x2d, 0x00, 0x00,
0x00, 0x01, 0x02, 0x2f, 0x2f, 0x02, 0x6c, 0x01, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x4f, 0x09, 0x09, 0x63,
0x72, 0x64, 0x2e, 0x78, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e, 0x78, 0x20, 0x2b,
0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x28, 0x64, 0x78, 0x29, 0x20, 0x2f, 0x20, 0x31, 0x32, 0x38, 0x2e, 0x30,
0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x63, 0x72, 0x64, 0x2e, 0x79, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 0x43,
0x6f, 0x6f, 0x72, 0x64, 0x2e, 0x79, 0x20, 0x2b, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x28, 0x64, 0x79, 0x29,
0x02, 0x8d, 0x01, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x01, 0x2a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x28, 0x53, 0x69,
0x7a, 0x65, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67,
0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x63, 0x29, 0x02, 0xeb, 0x01, 0x00,
0x00, 0x2d, 0x00, 0x00, 0x00};
// File: average.vert
const char toospicyFileName_1[] = "average.vert";
const size_t toospicyPatchSize_1 = 82;
const unsigned char toospicyPatchBuffer_1[] = {
0x07, 0x35, 0xa3, 0xe1, 0xa8, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00,
0x01, 0x15, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x74, 0x65, 0x78,
0x43, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x02, 0x1b, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x02,
0x2f, 0x2f, 0x02, 0x5b, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x01, 0x09, 0x74, 0x65, 0x78, 0x43,
0x6f, 0x6f, 0x72, 0x64, 0x3d, 0x02, 0x6d, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00};
// File: DoF.frag
const char toospicyFileName_2[] = "DoF.frag";
const size_t toospicyPatchSize_2 = 92;
const unsigned char toospicyPatchBuffer_2[] = {
0xf6, 0xbf, 0xe4, 0x98, 0xd4, 0x05, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x22, 0x02, 0x00, 0x00, 0x01, 0x06,
0x53, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x02, 0x22, 0x02, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, 0x01, 0x06, 0x66, 0x6c,
0x6f, 0x61, 0x74, 0x28, 0x02, 0xe3, 0x02, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x01, 0x03, 0x2e, 0x30, 0x29, 0x02,
0x05, 0x03, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x02, 0x6b, 0x03, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x02, 0xb9,
0x03, 0x00, 0x00, 0x28, 0x01, 0x00, 0x00, 0x02, 0xe2, 0x04, 0x00, 0x00, 0xf2, 0x00, 0x00, 0x00};
// File: GaussH.frag
const char toospicyFileName_3[] = "GaussH.frag";
const size_t toospicyPatchSize_3 = 241;
const unsigned char toospicyPatchBuffer_3[] = {
0xae, 0x80, 0x41, 0x90, 0xa9, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x61,
0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x57, 0x49, 0x44, 0x54, 0x48, 0x3b, 0x0d, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f,
0x72, 0x6d, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x48, 0x45, 0x49, 0x47, 0x48, 0x54, 0x3b, 0x0d, 0x0a, 0x75,
0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x57, 0x49, 0x44, 0x54, 0x48, 0x38,
0x3b, 0x0d, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x48, 0x45,
0x49, 0x47, 0x48, 0x54, 0x38, 0x3b, 0x0d, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x66, 0x6c, 0x6f,
0x61, 0x74, 0x02, 0x9c, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x01, 0x22, 0x76, 0x65, 0x63, 0x34, 0x20, 0x63,
0x6f, 0x6c, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x2c, 0x20,
0x30, 0x2e, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x29, 0x02, 0xd4, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x01,
0x01, 0x2e, 0x02, 0x71, 0x01, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x39, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x67,
0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x72, 0x67, 0x62, 0x3d, 0x63, 0x6f, 0x6c,
0x2e, 0x72, 0x67, 0x62, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f,
0x6c, 0x6f, 0x72, 0x2e, 0x61, 0x3d, 0x31, 0x2e, 0x30, 0x3b, 0x0d, 0x0a, 0x7d};
// File: GaussH.vert
const char toospicyFileName_4[] = "GaussH.vert";
const size_t toospicyPatchSize_4 = 53;
const unsigned char toospicyPatchBuffer_4[] = {
0xc1, 0x77, 0x6f, 0x38, 0x53, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x01, 0x00, 0x00, 0x01,
0x22, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x28, 0x69, 0x29, 0x2b, 0x30, 0x2e, 0x35, 0x29, 0x2a, 0x57, 0x49, 0x44,
0x54, 0x48, 0x2c, 0x30, 0x2e, 0x30, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x7d, 0x0d, 0x0a, 0x7d};
// File: GaussH_Depth.frag
const char toospicyFileName_5[] = "GaussH_Depth.frag";
const size_t toospicyPatchSize_5 = 495;
const unsigned char toospicyPatchBuffer_5[] = {
0x80, 0x58, 0x2b, 0x1c, 0x71, 0x04, 0x00, 0x00, 0x01, 0x52, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x68,
0x61, 0x6c, 0x66, 0x09, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x0d, 0x0a, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20,
0x68, 0x61, 0x6c, 0x66, 0x32, 0x09, 0x76, 0x65, 0x63, 0x32, 0x0d, 0x0a, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65,
0x20, 0x68, 0x61, 0x6c, 0x66, 0x33, 0x09, 0x76, 0x65, 0x63, 0x33, 0x0d, 0x0a, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e,
0x65, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x09, 0x76, 0x65, 0x63, 0x34, 0x0d, 0x0a, 0x0d, 0x0a, 0x02, 0x00, 0x00,
0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x01, 0xba, 0x53, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x20, 0x47, 0x61, 0x6d, 0x65,
0x44, 0x65, 0x70, 0x74, 0x68, 0x3b, 0x0d, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d,
0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x53, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x20, 0x52, 0x61, 0x79, 0x44, 0x65, 0x70,
0x74, 0x68, 0x3b, 0x0d, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x54,
0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x5b, 0x38, 0x5d, 0x3b, 0x0d, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72,
0x6d, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x57, 0x49, 0x44, 0x54, 0x48, 0x3b, 0x0d, 0x0a, 0x75, 0x6e, 0x69,
0x66, 0x6f, 0x72, 0x6d, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x48, 0x45, 0x49, 0x47, 0x48, 0x54, 0x3b, 0x0d,
0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x57, 0x49, 0x44, 0x54,
0x48, 0x38, 0x3b, 0x0d, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20,
0x48, 0x45, 0x49, 0x47, 0x48, 0x54, 0x38, 0x3b, 0x0d, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x66,
0x6c, 0x6f, 0x61, 0x74, 0x02, 0xd7, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x01, 0x19, 0x20, 0x76, 0x65, 0x63,
0x34, 0x28, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x30, 0x2e,
0x30, 0x29, 0x02, 0x0e, 0x01, 0x00, 0x00, 0xa9, 0x00, 0x00, 0x00, 0x02, 0xb8, 0x01, 0x00, 0x00, 0x27, 0x00, 0x00,
0x00, 0x01, 0x02, 0x2e, 0x30, 0x02, 0xdf, 0x01, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x02, 0x0b, 0x02, 0x00, 0x00,
0x27, 0x00, 0x00, 0x00, 0x01, 0x02, 0x2e, 0x30, 0x02, 0x32, 0x02, 0x00, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x01, 0x06,
0x66, 0x6c, 0x6f, 0x61, 0x74, 0x28, 0x02, 0x29, 0x01, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x03, 0x2e, 0x30,
0x29, 0x02, 0xf6, 0x02, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x01, 0x06, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x28, 0x02,
0x0c, 0x03, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x03, 0x2e, 0x30, 0x29, 0x02, 0x30, 0x03, 0x00, 0x00, 0xbc,
0x00, 0x00, 0x00, 0x01, 0x01, 0x2e, 0x02, 0xeb, 0x03, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x01, 0x18, 0x76, 0x65,
0x63, 0x34, 0x28, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x30,
0x2e, 0x30, 0x29, 0x02, 0x47, 0x04, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x06, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d,
0x0a};
// File: GaussH_Depth.vert
const char toospicyFileName_6[] = "GaussH_Depth.vert";
const size_t toospicyPatchSize_6 = 53;
const unsigned char toospicyPatchBuffer_6[] = {
0xc1, 0x77, 0x6f, 0x38, 0x53, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x01, 0x00, 0x00, 0x01,
0x22, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x28, 0x69, 0x29, 0x2b, 0x30, 0x2e, 0x35, 0x29, 0x2a, 0x57, 0x49, 0x44,
0x54, 0x48, 0x2c, 0x30, 0x2e, 0x30, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x7d, 0x0d, 0x0a, 0x7d};
// File: GaussV.frag
const char toospicyFileName_7[] = "GaussV.frag";
const size_t toospicyPatchSize_7 = 281;
const unsigned char toospicyPatchBuffer_7[] = {
0x47, 0x81, 0xa3, 0x96, 0xad, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x01, 0x6a,
0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x47, 0x61, 0x75, 0x73, 0x73, 0x46, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x5b, 0x38,
0x5d, 0x3b, 0x0d, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x48,
0x45, 0x49, 0x47, 0x48, 0x54, 0x38, 0x3b, 0x0d, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x66, 0x6c,
0x6f, 0x61, 0x74, 0x20, 0x48, 0x45, 0x49, 0x47, 0x48, 0x54, 0x3b, 0x0d, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72,
0x6d, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x57, 0x49, 0x44, 0x54, 0x48, 0x38, 0x3b, 0x0d, 0x0a, 0x75, 0x6e,
0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x02, 0xa7, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00,
0x00, 0x01, 0x22, 0x76, 0x65, 0x63, 0x34, 0x20, 0x63, 0x6f, 0x6c, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x30,
0x2e, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x29, 0x02,
0xd4, 0x00, 0x00, 0x00, 0x97, 0x00, 0x00, 0x00, 0x01, 0x64, 0x2e, 0x30, 0x2c, 0x48, 0x45, 0x49, 0x47, 0x48, 0x54,
0x38, 0x29, 0x29, 0x2a, 0x47, 0x61, 0x75, 0x73, 0x73, 0x46, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x5b, 0x37, 0x2d, 0x69,
0x5d, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x7d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x67,
0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x72, 0x67, 0x62, 0x3d, 0x63, 0x6f, 0x6c,
0x2e, 0x72, 0x67, 0x62, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f,
0x6c, 0x6f, 0x72, 0x2e, 0x61, 0x3d, 0x31, 0x2e, 0x30, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a};
// File: GaussV.vert
const char toospicyFileName_8[] = "GaussV.vert";
const size_t toospicyPatchSize_8 = 40;
const unsigned char toospicyPatchBuffer_8[] = {0x73, 0x83, 0x54, 0x8f, 0x81, 0x01, 0x00, 0x00, 0x02, 0x00,
0x00, 0x00, 0x00, 0x65, 0x01, 0x00, 0x00, 0x01, 0x0c, 0x2e,
0x30, 0x2c, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x28, 0x69,
0x29, 0x02, 0x68, 0x01, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00};
// File: GetBrightArea.frag
const char toospicyFileName_9[] = "GetBrightArea.frag";
const size_t toospicyPatchSize_9 = 63;
const unsigned char toospicyPatchBuffer_9[] = {
0x32, 0x1e, 0x86, 0xd8, 0x17, 0x04, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x01, 0x00,
0x00, 0x01, 0x02, 0x2f, 0x2f, 0x02, 0x5c, 0x01, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x02,
0x2f, 0x2f, 0x02, 0xd0, 0x01, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x01, 0x05, 0x66, 0x6c, 0x6f,
0x61, 0x74, 0x02, 0x1a, 0x02, 0x00, 0x00, 0xfd, 0x01, 0x00, 0x00, 0x01, 0x02, 0x0d, 0x0a};
// File: GlareCompose.frag
const char toospicyFileName_10[] = "GlareCompose.frag";
const size_t toospicyPatchSize_10 = 482;
const unsigned char toospicyPatchBuffer_10[] = {
0x3d, 0xef, 0xd1, 0x18, 0x06, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x01, 0x02,
0x2f, 0x2f, 0x02, 0x1a, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x6c, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65,
0x72, 0x32, 0x44, 0x20, 0x42, 0x61, 0x73, 0x65, 0x54, 0x6f, 0x6e, 0x65, 0x47, 0x6c, 0x61, 0x72, 0x65, 0x50, 0x69,
0x63, 0x3b, 0x0d, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x50,
0x6f, 0x77, 0x65, 0x72, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x76, 0x65,
0x63, 0x32, 0x20, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x5b, 0x35, 0x5d, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a,
0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x76, 0x6f, 0x69, 0x64, 0x29, 0x0d, 0x0a, 0x7b, 0x0d,
0x0a, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x02, 0x27, 0x01, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x02, 0x53, 0x01,
0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x03, 0x19, 0x01, 0x00, 0x00, 0x23, 0x69, 0x66, 0x20, 0x31, 0x20, 0x2f, 0x2f,
0x92, 0xc7, 0x89, 0xc1, 0x81, 0x40, 0x68, 0x61, 0x72, 0x61, 0x68, 0x0d, 0x0a, 0x09, 0x76, 0x65, 0x63, 0x34, 0x09,
0x42, 0x54, 0x47, 0x6c, 0x61, 0x72, 0x65, 0x43, 0x6f, 0x6c, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72,
0x65, 0x32, 0x44, 0x28, 0x42, 0x61, 0x73, 0x65, 0x54, 0x6f, 0x6e, 0x65, 0x47, 0x6c, 0x61, 0x72, 0x65, 0x50, 0x69,
0x63, 0x2c, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x5b, 0x30, 0x5d, 0x29, 0x2a, 0x31, 0x2e, 0x37, 0x35,
0x3b, 0x0d, 0x0a, 0x09, 0x76, 0x65, 0x63, 0x34, 0x09, 0x62, 0x6c, 0x65, 0x6e, 0x64, 0x6d, 0x69, 0x78, 0x3b, 0x0d,
0x0a, 0x09, 0x62, 0x6c, 0x65, 0x6e, 0x64, 0x6d, 0x69, 0x78, 0x2e, 0x72, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x78, 0x28,
0x63, 0x6f, 0x6c, 0x2e, 0x72, 0x2c, 0x42, 0x54, 0x47, 0x6c, 0x61, 0x72, 0x65, 0x43, 0x6f, 0x6c, 0x2e, 0x72, 0x29,
0x3b, 0x0d, 0x0a, 0x09, 0x62, 0x6c, 0x65, 0x6e, 0x64, 0x6d, 0x69, 0x78, 0x2e, 0x67, 0x20, 0x3d, 0x20, 0x6d, 0x61,
0x78, 0x28, 0x63, 0x6f, 0x6c, 0x2e, 0x67, 0x2c, 0x42, 0x54, 0x47, 0x6c, 0x61, 0x72, 0x65, 0x43, 0x6f, 0x6c, 0x2e,
0x67, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x62, 0x6c, 0x65, 0x6e, 0x64, 0x6d, 0x69, 0x78, 0x2e, 0x62, 0x20, 0x3d, 0x20,
0x6d, 0x61, 0x78, 0x28, 0x63, 0x6f, 0x6c, 0x2e, 0x62, 0x2c, 0x42, 0x54, 0x47, 0x6c, 0x61, 0x72, 0x65, 0x43, 0x6f,
0x6c, 0x2e, 0x62, 0x29, 0x3b, 0x0d, 0x0a, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x67,
0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x72, 0x67, 0x62, 0x20, 0x3d, 0x62, 0x6c,
0x65, 0x6e, 0x64, 0x6d, 0x69, 0x78, 0x2e, 0x72, 0x67, 0x62, 0x20, 0x2a, 0x20, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x3b,
0x0d, 0x0a, 0x23, 0x69, 0x66, 0x20, 0x30, 0x02, 0xca, 0x01, 0x00, 0x00, 0xab, 0x00, 0x00, 0x00, 0x01, 0x1b, 0x20,
0x20, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x61, 0x3d, 0x31, 0x2e,
0x30, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a};
// File: gradate.frag
const char toospicyFileName_11[] = "gradate.frag";
const size_t toospicyPatchSize_11 = 101;
const unsigned char toospicyPatchBuffer_11[] = {
0xa4, 0x99, 0x62, 0x6c, 0x21, 0x02, 0x00, 0x00, 0x01, 0x52, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65,
0x20, 0x68, 0x61, 0x6c, 0x66, 0x09, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x0d, 0x0a, 0x23, 0x64, 0x65, 0x66,
0x69, 0x6e, 0x65, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x32, 0x09, 0x76, 0x65, 0x63, 0x32, 0x0d, 0x0a, 0x23,
0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x33, 0x09, 0x76, 0x65, 0x63, 0x33,
0x0d, 0x0a, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x09, 0x76,
0x65, 0x63, 0x34, 0x0d, 0x0a, 0x0d, 0x0a, 0x02, 0x00, 0x00, 0x00, 0x00, 0x21, 0x02, 0x00, 0x00};
// File: intensitytest.frag
const char toospicyFileName_12[] = "intensitytest.frag";
const size_t toospicyPatchSize_12 = 47;
const unsigned char toospicyPatchBuffer_12[] = {0x2c, 0xe4, 0xe3, 0x09, 0x56, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x00, 0xfe, 0x01, 0x00, 0x00, 0x01, 0x05, 0x66, 0x6c, 0x6f, 0x61, 0x74,
0x02, 0x02, 0x02, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x01, 0x03, 0x76,
0x65, 0x63, 0x02, 0x35, 0x02, 0x00, 0x00, 0x21, 0x01, 0x00, 0x00};
// File: Laplacian.frag
const char toospicyFileName_13[] = "Laplacian.frag";
const size_t toospicyPatchSize_13 = 152;
const unsigned char toospicyPatchBuffer_13[] = {
0x27, 0xee, 0x97, 0x8c, 0x91, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x01, 0x00, 0x00, 0x01, 0x02,
0x2f, 0x2f, 0x02, 0x5c, 0x01, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x02, 0x2f, 0x2f, 0x02, 0xd0, 0x01, 0x00,
0x00, 0x65, 0x00, 0x00, 0x00, 0x01, 0x02, 0x2e, 0x30, 0x02, 0x35, 0x02, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x01,
0x02, 0x2e, 0x30, 0x02, 0xba, 0x02, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x76, 0x65, 0x63, 0x33, 0x28,
0x6c, 0x61, 0x70, 0x29, 0x2c, 0x76, 0x65, 0x63, 0x33, 0x02, 0xff, 0x02, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x01,
0x0e, 0x2e, 0x30, 0x2c, 0x30, 0x2e, 0x30, 0x2c, 0x30, 0x2e, 0x30, 0x2c, 0x31, 0x2e, 0x30, 0x02, 0x2f, 0x03, 0x00,
0x00, 0x21, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x2e, 0x30, 0x2c, 0x31, 0x2e, 0x30, 0x2c, 0x31, 0x2e, 0x30, 0x2c, 0x31,
0x2e, 0x30, 0x02, 0x56, 0x03, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x01, 0x06, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a};
// File: Monochrome.frag
const char toospicyFileName_14[] = "Monochrome.frag";
const size_t toospicyPatchSize_14 = 330;
const unsigned char toospicyPatchBuffer_14[] = {
0x60, 0xe0, 0xef, 0x32, 0x33, 0x03, 0x00, 0x00, 0x01, 0x66, 0x23, 0x69, 0x66, 0x6e, 0x64, 0x65, 0x66, 0x09, 0x4d,
0x4f, 0x44, 0x45, 0x0d, 0x0a, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x09, 0x4d, 0x4f, 0x44, 0x45, 0x09, 0x30,
0x0d, 0x0a, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x0d, 0x0a, 0x0d, 0x0a, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65,
0x09, 0x4d, 0x4f, 0x4e, 0x4f, 0x43, 0x48, 0x52, 0x4f, 0x4d, 0x45, 0x09, 0x09, 0x09, 0x28, 0x4d, 0x4f, 0x44, 0x45,
0x3d, 0x3d, 0x30, 0x29, 0x0d, 0x0a, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x09, 0x53, 0x45, 0x50, 0x49, 0x41,
0x09, 0x09, 0x09, 0x09, 0x28, 0x4d, 0x4f, 0x44, 0x45, 0x3d, 0x3d, 0x31, 0x29, 0x0d, 0x0a, 0x0d, 0x0a, 0x02, 0x00,
0x00, 0x00, 0x00, 0x5c, 0x01, 0x00, 0x00, 0x01, 0x02, 0x2f, 0x2f, 0x02, 0x5c, 0x01, 0x00, 0x00, 0x74, 0x00, 0x00,
0x00, 0x01, 0x02, 0x2f, 0x2f, 0x02, 0xd0, 0x01, 0x00, 0x00, 0x9d, 0x00, 0x00, 0x00, 0x01, 0x3f, 0x68, 0x61, 0x6c,
0x66, 0x34, 0x20, 0x6d, 0x6f, 0x6e, 0x6f, 0x63, 0x6f, 0x6c, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x30, 0x2e,
0x30, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x29, 0x3b, 0x0d,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x6e, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x72, 0x67, 0x62, 0x3d, 0x76, 0x65,
0x63, 0x33, 0x28, 0x02, 0x91, 0x02, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x01, 0x5d, 0x29, 0x3b, 0x0d, 0x0a, 0x23,
0x69, 0x66, 0x09, 0x53, 0x45, 0x50, 0x49, 0x41, 0x0d, 0x0a, 0x09, 0x6d, 0x6f, 0x6e, 0x6f, 0x63, 0x6f, 0x6c, 0x2e,
0x72, 0x67, 0x62, 0x2a, 0x3d, 0x68, 0x61, 0x6c, 0x66, 0x33, 0x28, 0x31, 0x2e, 0x30, 0x2c, 0x30, 0x2e, 0x36, 0x2c,
0x30, 0x2e, 0x33, 0x29, 0x3b, 0x0d, 0x0a, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x09, 0x2f, 0x2a, 0x09, 0x53, 0x45,
0x50, 0x49, 0x41, 0x09, 0x2a, 0x2f, 0x0d, 0x0a, 0x09, 0x6d, 0x6f, 0x6e, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x61, 0x3d,
0x31, 0x2e, 0x30, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x02, 0xed, 0x02, 0x00, 0x00, 0x29, 0x00,
0x00, 0x00, 0x01, 0x03, 0x7d, 0x0d, 0x0a};
// File: Monochrome.vert
const char toospicyFileName_15[] = "Monochrome.vert";
const size_t toospicyPatchSize_15 = 121;
const unsigned char toospicyPatchBuffer_15[] = {
0x78, 0x26, 0x8a, 0x51, 0x79, 0x00, 0x00, 0x00, 0x01, 0x66, 0x23, 0x69, 0x66, 0x6e, 0x64, 0x65, 0x66, 0x09,
0x4d, 0x4f, 0x44, 0x45, 0x0d, 0x0a, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x09, 0x4d, 0x4f, 0x44, 0x45,
0x09, 0x30, 0x0d, 0x0a, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x0d, 0x0a, 0x0d, 0x0a, 0x23, 0x64, 0x65, 0x66,
0x69, 0x6e, 0x65, 0x09, 0x4d, 0x4f, 0x4e, 0x4f, 0x43, 0x48, 0x52, 0x4f, 0x4d, 0x45, 0x09, 0x09, 0x09, 0x28,
0x4d, 0x4f, 0x44, 0x45, 0x3d, 0x3d, 0x30, 0x29, 0x0d, 0x0a, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x09,
0x53, 0x45, 0x50, 0x49, 0x41, 0x09, 0x09, 0x09, 0x09, 0x28, 0x4d, 0x4f, 0x44, 0x45, 0x3d, 0x3d, 0x31, 0x29,
0x0d, 0x0a, 0x0d, 0x0a, 0x02, 0x00, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00};
// File: nnstdshader.vert
const char toospicyFileName_16[] = "nnstdshader.vert";
const size_t toospicyPatchSize_16 = 652;
const unsigned char toospicyPatchBuffer_16[] = {
0x39, 0x15, 0xd4, 0xa8, 0x53, 0x16, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x01, 0x01, 0x00, 0x02, 0xaa,
0x01, 0x01, 0x00, 0x27, 0x00, 0x00, 0x00, 0x01, 0x04, 0x69, 0x66, 0x20, 0x28, 0x02, 0x4a, 0x36, 0x00, 0x00, 0x16,
0x00, 0x00, 0x00, 0x01, 0x39, 0x3e, 0x20, 0x30, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x09, 0x09,
0x6e, 0x6e, 0x67, 0x6c, 0x43, 0x61, 0x6c, 0x63, 0x50, 0x61, 0x72, 0x61, 0x6c, 0x65, 0x6c, 0x6c, 0x4c, 0x69, 0x67,
0x68, 0x74, 0x28, 0x30, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x09, 0x7d, 0x0d, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x09, 0x23, 0x69, 0x66, 0x02, 0xf2, 0x0d, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x20, 0x3e, 0x20,
0x31, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x09, 0x69, 0x66, 0x20, 0x28, 0x02, 0x4a, 0x36, 0x00, 0x00, 0x16, 0x00,
0x00, 0x00, 0x01, 0x39, 0x3e, 0x20, 0x31, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x09, 0x09, 0x6e,
0x6e, 0x67, 0x6c, 0x43, 0x61, 0x6c, 0x63, 0x50, 0x61, 0x72, 0x61, 0x6c, 0x65, 0x6c, 0x6c, 0x4c, 0x69, 0x67, 0x68,
0x74, 0x28, 0x31, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x09, 0x7d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
0x09, 0x23, 0x69, 0x66, 0x02, 0xf2, 0x0d, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x20, 0x3e, 0x20, 0x32,
0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x09, 0x69, 0x66, 0x20, 0x28, 0x02, 0x4a, 0x36, 0x00, 0x00, 0x16, 0x00, 0x00,
0x00, 0x01, 0x39, 0x3e, 0x20, 0x32, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x09, 0x09, 0x6e, 0x6e,
0x67, 0x6c, 0x43, 0x61, 0x6c, 0x63, 0x50, 0x61, 0x72, 0x61, 0x6c, 0x65, 0x6c, 0x6c, 0x4c, 0x69, 0x67, 0x68, 0x74,
0x28, 0x32, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x09, 0x7d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x09,
0x23, 0x69, 0x66, 0x02, 0xf2, 0x0d, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x20, 0x3e, 0x20, 0x33, 0x0d,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x09, 0x69, 0x66, 0x20, 0x28, 0x02, 0x4a, 0x36, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
0x01, 0x6c, 0x3e, 0x20, 0x33, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x09, 0x09, 0x6e, 0x6e, 0x67,
0x6c, 0x43, 0x61, 0x6c, 0x63, 0x50, 0x61, 0x72, 0x61, 0x6c, 0x65, 0x6c, 0x6c, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x28,
0x33, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x09, 0x7d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x09, 0x23,
0x65, 0x6e, 0x64, 0x69, 0x66, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x09, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x0d,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x09, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x09,
0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x09, 0x02, 0x3a, 0x37, 0x00,
0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x21, 0x20, 0x20, 0x20, 0x20, 0x09, 0x69, 0x66, 0x20, 0x28, 0x6e, 0x6e, 0x67,
0x6c, 0x75, 0x4e, 0x75, 0x6d, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x20, 0x3e, 0x20, 0x30,
0x29, 0x20, 0x02, 0xd2, 0x02, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x0a, 0x34, 0x29, 0x3b, 0x0d, 0x0a, 0x09,
0x7d, 0x0d, 0x0a, 0x09, 0x02, 0x3a, 0x37, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x01, 0x23, 0x20, 0x3e, 0x20, 0x31,
0x0d, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x28, 0x6e, 0x6e, 0x67, 0x6c, 0x75, 0x4e, 0x75, 0x6d, 0x50, 0x6f, 0x69, 0x6e,
0x74, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x20, 0x3e, 0x20, 0x31, 0x29, 0x20, 0x02, 0xd2, 0x02, 0x01, 0x00, 0x18, 0x00,
0x00, 0x00, 0x01, 0x09, 0x35, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a, 0x02, 0x54, 0xc9, 0x00, 0x00, 0x15,
0x00, 0x00, 0x00, 0x01, 0x03, 0x23, 0x69, 0x66, 0x02, 0xef, 0x38, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x01, 0x36,
0x0d, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x28, 0x6e, 0x6e, 0x67, 0x6c, 0x75, 0x4e, 0x75, 0x6d, 0x53, 0x70, 0x6f, 0x74,
0x4c, 0x69, 0x67, 0x68, 0x74, 0x20, 0x3e, 0x20, 0x30, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x6e, 0x6e, 0x67,
0x6c, 0x43, 0x61, 0x6c, 0x63, 0x53, 0x70, 0x6f, 0x74, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x28, 0x36, 0x02, 0xb0, 0x03,
0x01, 0x00, 0xa3, 0x12, 0x00, 0x00};
// File: Posterization.frag
const char toospicyFileName_17[] = "Posterization.frag";
const size_t toospicyPatchSize_17 = 59;
const unsigned char toospicyPatchBuffer_17[] = {0xc1, 0xb7, 0x73, 0x37, 0xa9, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x00, 0x5c, 0x01, 0x00, 0x00, 0x01, 0x02, 0x2f, 0x2f, 0x02, 0x5c, 0x01,
0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x02, 0x2f, 0x2f, 0x02, 0xd0,
0x01, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x01, 0x05, 0x66, 0x6c, 0x6f,
0x61, 0x74, 0x02, 0x1a, 0x02, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00};
// File: Sepia.frag
const char toospicyFileName_18[] = "Sepia.frag";
const size_t toospicyPatchSize_18 = 320;
const unsigned char toospicyPatchBuffer_18[] = {
0xe5, 0x2e, 0xad, 0xed, 0xa1, 0x04, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x01, 0x00, 0x00, 0x01, 0x02,
0x2f, 0x2f, 0x02, 0x5c, 0x01, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x22, 0x2f, 0x2f, 0x23, 0x65, 0x6e, 0x64,
0x69, 0x66, 0x0d, 0x0a, 0x0d, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20,
0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x02, 0xf2, 0x01, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x01,
0x0b, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x52, 0x61, 0x74, 0x65, 0x3b, 0x02, 0x44, 0x02, 0x00, 0x00, 0x18, 0x00,
0x00, 0x00, 0x01, 0xdd, 0x20, 0x20, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x63,
0x6f, 0x6c, 0x3d, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x44, 0x28, 0x4f, 0x72, 0x69, 0x67, 0x50, 0x69,
0x63, 0x2c, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x68,
0x61, 0x6c, 0x66, 0x34, 0x20, 0x73, 0x65, 0x70, 0x69, 0x61, 0x63, 0x6f, 0x6c, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x73, 0x65, 0x70, 0x69, 0x61, 0x63, 0x6f, 0x6c, 0x2e, 0x72, 0x67, 0x62, 0x3d, 0x64, 0x6f, 0x74, 0x28, 0x6f,
0x72, 0x69, 0x67, 0x63, 0x6f, 0x6c, 0x2e, 0x72, 0x67, 0x62, 0x2c, 0x68, 0x61, 0x6c, 0x66, 0x33, 0x28, 0x30, 0x2e,
0x32, 0x39, 0x39, 0x2c, 0x30, 0x2e, 0x35, 0x38, 0x37, 0x2c, 0x30, 0x2e, 0x31, 0x34, 0x34, 0x29, 0x29, 0x2a, 0x68,
0x61, 0x6c, 0x66, 0x33, 0x28, 0x31, 0x2e, 0x30, 0x2c, 0x30, 0x2e, 0x36, 0x2c, 0x30, 0x2e, 0x33, 0x29, 0x3b, 0x0d,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x65, 0x70, 0x69, 0x61, 0x63, 0x6f, 0x6c, 0x2e, 0x61, 0x3d, 0x31, 0x2e, 0x30,
0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c,
0x6f, 0x72, 0x3d, 0x6d, 0x69, 0x78, 0x28, 0x6f, 0x72, 0x69, 0x67, 0x63, 0x6f, 0x6c, 0x2c, 0x73, 0x65, 0x70, 0x69,
0x61, 0x63, 0x6f, 0x6c, 0x2c, 0x52, 0x61, 0x74, 0x65, 0x29, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a};
// File: Sepia.vert
const char toospicyFileName_19[] = "Sepia.vert";
const size_t toospicyPatchSize_19 = 68;
const unsigned char toospicyPatchBuffer_19[] = {
0xd1, 0x30, 0x7b, 0xf2, 0x9a, 0x00, 0x00, 0x00, 0x01, 0x31, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67,
0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0d, 0x0a,
0x0d, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x76, 0x6f, 0x69, 0x64, 0x29,
0x0d, 0x0a, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x02, 0x52, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00};
// File: Solarization.frag
const char toospicyFileName_20[] = "Solarization.frag";
const size_t toospicyPatchSize_20 = 98;
const unsigned char toospicyPatchBuffer_20[] = {
0x90, 0xdb, 0xc4, 0x2d, 0x22, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x01, 0x00, 0x00,
0x01, 0x02, 0x2f, 0x2f, 0x02, 0x5c, 0x01, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x02, 0x2f, 0x2f,
0x02, 0xd0, 0x01, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x01, 0x05, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x02,
0x1a, 0x02, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x01, 0x02, 0x2e, 0x30, 0x02, 0xa5, 0x02, 0x00, 0x00,
0x2c, 0x00, 0x00, 0x00, 0x01, 0x02, 0x2e, 0x30, 0x02, 0xd1, 0x02, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,
0x01, 0x02, 0x2e, 0x30, 0x02, 0xfd, 0x02, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00};
// File: Test0.frag
const char toospicyFileName_21[] = "Test0.frag";
const size_t toospicyPatchSize_21 = 907;
const unsigned char toospicyPatchBuffer_21[] = {
0x82, 0x87, 0xe9, 0xd6, 0x17, 0x05, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x01, 0x77,
0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x45, 0x64, 0x67, 0x65, 0x52, 0x3b, 0x0d, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f,
0x72, 0x6d, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x45, 0x64, 0x67, 0x65, 0x47, 0x3b, 0x0d, 0x0a, 0x75, 0x6e,
0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x45, 0x64, 0x67, 0x65, 0x42, 0x3b, 0x0d,
0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x54, 0x68, 0x72, 0x65,
0x73, 0x68, 0x6f, 0x6c, 0x64, 0x3b, 0x0d, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x66, 0x6c, 0x6f,
0x61, 0x74, 0x20, 0x57, 0x69, 0x64, 0x74, 0x68, 0x3b, 0x0d, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20,
0x66, 0x6c, 0x6f, 0x61, 0x74, 0x02, 0xd3, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x01, 0x5e, 0x66, 0x6c, 0x6f,
0x61, 0x74, 0x20, 0x44, 0x65, 0x70, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32,
0x44, 0x28, 0x47, 0x61, 0x6d, 0x65, 0x44, 0x65, 0x70, 0x74, 0x68, 0x2c, 0x76, 0x65, 0x63, 0x32, 0x28, 0x74, 0x65,
0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x29, 0x29, 0x2e, 0x72, 0x3b, 0x0d, 0x0a, 0x09, 0x67, 0x6c, 0x5f, 0x46, 0x72,
0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x72, 0x3d, 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x28, 0x44, 0x65, 0x70,
0x74, 0x68, 0x2a, 0x32, 0x35, 0x36, 0x2e, 0x30, 0x29, 0x2f, 0x32, 0x35, 0x36, 0x2e, 0x30, 0x02, 0x6d, 0x01, 0x00,
0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x53, 0x2e, 0x30, 0x3b, 0x0d, 0x0a, 0x09, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61,
0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x67, 0x3d, 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x28, 0x44, 0x65, 0x70, 0x74,
0x68, 0x2a, 0x32, 0x35, 0x36, 0x2e, 0x30, 0x29, 0x2f, 0x32, 0x35, 0x36, 0x2e, 0x30, 0x3b, 0x0d, 0x0a, 0x09, 0x44,
0x65, 0x70, 0x74, 0x68, 0x2d, 0x3d, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2e,
0x67, 0x3b, 0x44, 0x65, 0x70, 0x74, 0x68, 0x2a, 0x3d, 0x32, 0x35, 0x36, 0x2e, 0x30, 0x02, 0xdf, 0x01, 0x00, 0x00,
0x2f, 0x00, 0x00, 0x00, 0x01, 0x31, 0x3b, 0x0d, 0x0a, 0x23, 0x65, 0x6c, 0x73, 0x65, 0x0d, 0x0a, 0x09, 0x66, 0x6c,
0x6f, 0x61, 0x74, 0x20, 0x43, 0x44, 0x65, 0x70, 0x74, 0x68, 0x3b, 0x0d, 0x0a, 0x09, 0x66, 0x6c, 0x6f, 0x61, 0x74,
0x20, 0x44, 0x65, 0x70, 0x74, 0x68, 0x5b, 0x34, 0x5d, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x76, 0x65, 0x63, 0x02, 0x3f,
0x02, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x03, 0x4e, 0x01, 0x00, 0x00, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65,
0x32, 0x44, 0x28, 0x47, 0x61, 0x6d, 0x65, 0x44, 0x65, 0x70, 0x74, 0x68, 0x2c, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f,
0x72, 0x64, 0x29, 0x2e, 0x72, 0x3b, 0x0d, 0x0a, 0x09, 0x44, 0x65, 0x70, 0x74, 0x68, 0x5b, 0x30, 0x5d, 0x20, 0x3d,
0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x44, 0x28, 0x47, 0x61, 0x6d, 0x65, 0x44, 0x65, 0x70, 0x74,
0x68, 0x2c, 0x76, 0x65, 0x63, 0x32, 0x28, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e, 0x78, 0x2d, 0x32,
0x2e, 0x30, 0x2f, 0x57, 0x69, 0x64, 0x74, 0x68, 0x2c, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e, 0x79,
0x29, 0x29, 0x2e, 0x72, 0x3b, 0x0d, 0x0a, 0x09, 0x44, 0x65, 0x70, 0x74, 0x68, 0x5b, 0x31, 0x5d, 0x20, 0x3d, 0x20,
0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x44, 0x28, 0x47, 0x61, 0x6d, 0x65, 0x44, 0x65, 0x70, 0x74, 0x68,
0x2c, 0x76, 0x65, 0x63, 0x32, 0x28, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e, 0x78, 0x2b, 0x32, 0x2e,
0x30, 0x2f, 0x57, 0x69, 0x64, 0x74, 0x68, 0x2c, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e, 0x79, 0x29,
0x29, 0x2e, 0x72, 0x3b, 0x0d, 0x0a, 0x09, 0x44, 0x65, 0x70, 0x74, 0x68, 0x5b, 0x32, 0x5d, 0x20, 0x3d, 0x20, 0x74,
0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x44, 0x28, 0x47, 0x61, 0x6d, 0x65, 0x44, 0x65, 0x70, 0x74, 0x68, 0x2c,
0x76, 0x65, 0x63, 0x32, 0x28, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e, 0x78, 0x2c, 0x74, 0x65, 0x78,
0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e, 0x79, 0x2d, 0x32, 0x2e, 0x30, 0x2f, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x29,
0x29, 0x2e, 0x72, 0x3b, 0x0d, 0x0a, 0x09, 0x44, 0x65, 0x70, 0x74, 0x68, 0x5b, 0x33, 0x5d, 0x20, 0x3d, 0x20, 0x74,
0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x44, 0x28, 0x47, 0x61, 0x6d, 0x65, 0x44, 0x65, 0x70, 0x74, 0x68, 0x2c,
0x76, 0x65, 0x63, 0x32, 0x28, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e, 0x78, 0x2c, 0x74, 0x65, 0x78,
0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e, 0x79, 0x2b, 0x32, 0x2e, 0x30, 0x2f, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x29,
0x29, 0x2e, 0x72, 0x3b, 0x02, 0xd3, 0x03, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x01, 0x2e, 0x02, 0xf2, 0x03,
0x00, 0x00, 0x72, 0x00, 0x00, 0x00, 0x01, 0x6e, 0x20, 0x28, 0x65, 0x64, 0x67, 0x65, 0x20, 0x21, 0x3d, 0x20, 0x30,
0x29, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x72, 0x67, 0x62, 0x3d, 0x76,
0x65, 0x63, 0x33, 0x28, 0x45, 0x64, 0x67, 0x65, 0x52, 0x2c, 0x45, 0x64, 0x67, 0x65, 0x47, 0x2c, 0x45, 0x64, 0x67,
0x65, 0x42, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x61, 0x20, 0x3d,
0x20, 0x31, 0x2e, 0x30, 0x02, 0x9d, 0x04, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x01, 0x12, 0x3b, 0x0d, 0x0a, 0x09,
0x7d, 0x0d, 0x0a, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a};
// File: Test1.frag
const char toospicyFileName_22[] = "Test1.frag";
const size_t toospicyPatchSize_22 = 544;
const unsigned char toospicyPatchBuffer_22[] = {
0xde, 0x48, 0xcd, 0x78, 0x13, 0x08, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x01, 0x02,
0x2f, 0x2f, 0x02, 0x5a, 0x01, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x05, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x02,
0x8e, 0x01, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x01, 0x02, 0x2f, 0x2f, 0x02, 0xcf, 0x01, 0x00, 0x00, 0x82, 0x00,
0x00, 0x00, 0x01, 0x90, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x58, 0x3b, 0x0d, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f,
0x72, 0x6d, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x59, 0x3b, 0x0d, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72,
0x6d, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x52, 0x3b, 0x0d, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d,
0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x46, 0x6f, 0x63, 0x75, 0x73, 0x3b, 0x0d, 0x0a, 0x75, 0x6e, 0x69, 0x66,
0x6f, 0x72, 0x6d, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x52, 0x32, 0x3b, 0x0d, 0x0a, 0x75, 0x6e, 0x69, 0x66,
0x6f, 0x72, 0x6d, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x46, 0x6c, 0x61, 0x74, 0x3b, 0x0d, 0x0a, 0x75, 0x6e,
0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x46, 0x6f, 0x63, 0x75, 0x73, 0x32, 0x3b,
0x0d, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x02, 0xd9, 0x02, 0x00,
0x00, 0xce, 0x01, 0x00, 0x00, 0x01, 0x01, 0x2e, 0x02, 0xa6, 0x04, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x01, 0x4b,
0x68, 0x61, 0x6c, 0x66, 0x20, 0x6e, 0x65, 0x77, 0x46, 0x6f, 0x63, 0x75, 0x73, 0x3d, 0x30, 0x2e, 0x30, 0x3b, 0x0d,
0x0a, 0x09, 0x09, 0x69, 0x66, 0x28, 0x46, 0x6f, 0x63, 0x75, 0x73, 0x20, 0x3e, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x7b,
0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x6e, 0x2e, 0x78, 0x20, 0x2a, 0x3d, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x3b, 0x0d,
0x0a, 0x09, 0x09, 0x09, 0x6e, 0x65, 0x77, 0x46, 0x6f, 0x63, 0x75, 0x73, 0x20, 0x3d, 0x20, 0x32, 0x2e, 0x30, 0x02,
0x33, 0x05, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x01, 0x23, 0x2e, 0x30, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x65, 0x79,
0x65, 0x2e, 0x79, 0x20, 0x3d, 0x20, 0x30, 0x2e, 0x30, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x65, 0x79, 0x65, 0x2e, 0x7a,
0x20, 0x3d, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x02, 0x89, 0x05, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x01, 0x03, 0x6e,
0x65, 0x77, 0x02, 0xb0, 0x05, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x01, 0x25, 0x09, 0x76, 0x65, 0x63, 0x32, 0x20,
0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x54, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0d, 0x0a,
0x20, 0x20, 0x09, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x54, 0x02, 0x48, 0x06, 0x00, 0x00, 0x26, 0x00,
0x00, 0x00, 0x01, 0x09, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x54, 0x02, 0x6f, 0x06, 0x00, 0x00, 0x47,
0x00, 0x00, 0x00, 0x01, 0x09, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x54, 0x02, 0xb7, 0x06, 0x00, 0x00,
0xbf, 0x00, 0x00, 0x00, 0x01, 0x2d, 0x76, 0x65, 0x63, 0x32, 0x20, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64,
0x54, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x32, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x6d, 0x6f, 0x64, 0x69,
0x66, 0x69, 0x65, 0x64, 0x54, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x32, 0x02, 0x7f, 0x07, 0x00, 0x00, 0x1e,
0x00, 0x00, 0x00, 0x01, 0x11, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x54, 0x65, 0x78, 0x43, 0x6f, 0x6f,
0x72, 0x64, 0x32, 0x02, 0xa5, 0x07, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00};
// File: YUVCompose.frag
const char toospicyFileName_23[] = "YUVCompose.frag";
const size_t toospicyPatchSize_23 = 507;
const unsigned char toospicyPatchBuffer_23[] = {
0xee, 0x1d, 0x3d, 0x9c, 0x54, 0x04, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x01, 0x00, 0x00, 0x01, 0x02,
0x2f, 0x2f, 0x02, 0x5c, 0x01, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x49, 0x2f, 0x2f, 0x23, 0x65, 0x6e, 0x64,
0x69, 0x66, 0x0d, 0x0a, 0x0d, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20,
0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0d, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20,
0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 0x59, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x3b,
0x0d, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x02, 0x07, 0x02, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
0x01, 0x25, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44,
0x20, 0x43, 0x62, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x23, 0x69, 0x66, 0x09,
0x30, 0x02, 0x33, 0x02, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x01, 0x02, 0x2e, 0x30, 0x02, 0xba, 0x02, 0x00, 0x00,
0x70, 0x00, 0x00, 0x00, 0x01, 0x7a, 0x23, 0x65, 0x6c, 0x73, 0x65, 0x0d, 0x0a, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20,
0x6d, 0x61, 0x74, 0x33, 0x20, 0x59, 0x43, 0x62, 0x43, 0x72, 0x32, 0x52, 0x47, 0x42, 0x4d, 0x61, 0x74, 0x72, 0x69,
0x78, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x74, 0x33, 0x0d, 0x0a, 0x28, 0x20, 0x31, 0x2e, 0x31, 0x36, 0x34, 0x2c, 0x20,
0x31, 0x2e, 0x31, 0x36, 0x34, 0x2c, 0x31, 0x2e, 0x31, 0x36, 0x34, 0x2c, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x30,
0x2e, 0x30, 0x2c, 0x2d, 0x30, 0x2e, 0x33, 0x39, 0x32, 0x2c, 0x32, 0x2e, 0x30, 0x31, 0x37, 0x2c, 0x0d, 0x0a, 0x20,
0x20, 0x31, 0x2e, 0x35, 0x39, 0x36, 0x2c, 0x2d, 0x30, 0x2e, 0x38, 0x31, 0x33, 0x2c, 0x20, 0x20, 0x30, 0x2e, 0x30,
0x0d, 0x0a, 0x29, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x02, 0x28, 0x03, 0x00, 0x00,
0xde, 0x00, 0x00, 0x00, 0x01, 0x2e, 0x23, 0x69, 0x66, 0x09, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x59, 0x43, 0x62,
0x43, 0x72, 0x41, 0x2d, 0x3d, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x28, 0x31, 0x36, 0x2e, 0x30, 0x2f, 0x32, 0x35, 0x35,
0x2e, 0x30, 0x2c, 0x30, 0x2e, 0x35, 0x2c, 0x30, 0x2e, 0x35, 0x2c, 0x30, 0x29, 0x3b, 0x02, 0x2d, 0x04, 0x00, 0x00,
0x26, 0x00, 0x00, 0x00, 0x01, 0x8c, 0x23, 0x65, 0x6c, 0x73, 0x65, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x59, 0x43, 0x62,
0x43, 0x72, 0x41, 0x2e, 0x72, 0x67, 0x62, 0x2d, 0x3d, 0x68, 0x61, 0x6c, 0x66, 0x33, 0x28, 0x31, 0x36, 0x2e, 0x30,
0x2f, 0x32, 0x35, 0x35, 0x2e, 0x30, 0x2c, 0x30, 0x2e, 0x35, 0x2c, 0x30, 0x2e, 0x35, 0x29, 0x3b, 0x0d, 0x0a, 0x20,
0x20, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x72, 0x67, 0x62, 0x20,
0x3d, 0x20, 0x59, 0x43, 0x62, 0x43, 0x72, 0x32, 0x52, 0x47, 0x42, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x2a,
0x20, 0x59, 0x43, 0x62, 0x43, 0x72, 0x41, 0x2e, 0x72, 0x67, 0x62, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x67, 0x6c,
0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x61, 0x20, 0x3d, 0x20, 0x31, 0x2e, 0x30, 0x3b,
0x0d, 0x0a, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a};
ShaderFilesToPatch tooSpicyShaderPatches[] = {
{toospicyFileName_0, toospicyPatchSize_0, toospicyPatchBuffer_0, 0, ""},
{toospicyFileName_1, toospicyPatchSize_1, toospicyPatchBuffer_1, 0, ""},
{toospicyFileName_2, toospicyPatchSize_2, toospicyPatchBuffer_2, 0, ""},
{toospicyFileName_3, toospicyPatchSize_3, toospicyPatchBuffer_3, 0, ""},
{toospicyFileName_4, toospicyPatchSize_4, toospicyPatchBuffer_4, 0, ""},
{toospicyFileName_5, toospicyPatchSize_5, toospicyPatchBuffer_5, 0, ""},
{toospicyFileName_6, toospicyPatchSize_6, toospicyPatchBuffer_6, 0, ""},
{toospicyFileName_7, toospicyPatchSize_7, toospicyPatchBuffer_7, 0, ""},
{toospicyFileName_8, toospicyPatchSize_8, toospicyPatchBuffer_8, 0, ""},
{toospicyFileName_9, toospicyPatchSize_9, toospicyPatchBuffer_9, 0, ""},
{toospicyFileName_10, toospicyPatchSize_10, toospicyPatchBuffer_10, 0, ""},
{toospicyFileName_11, toospicyPatchSize_11, toospicyPatchBuffer_11, 0, ""},
{toospicyFileName_12, toospicyPatchSize_12, toospicyPatchBuffer_12, 0, ""},
{toospicyFileName_13, toospicyPatchSize_13, toospicyPatchBuffer_13, 0, ""},
{toospicyFileName_14, toospicyPatchSize_14, toospicyPatchBuffer_14, 0, ""},
{toospicyFileName_15, toospicyPatchSize_15, toospicyPatchBuffer_15, 0, ""},
{toospicyFileName_16, toospicyPatchSize_16, toospicyPatchBuffer_16, 0, ""},
{toospicyFileName_17, toospicyPatchSize_17, toospicyPatchBuffer_17, 0, ""},
{toospicyFileName_18, toospicyPatchSize_18, toospicyPatchBuffer_18, 0, ""},
{toospicyFileName_19, toospicyPatchSize_19, toospicyPatchBuffer_19, 0, ""},
{toospicyFileName_20, toospicyPatchSize_20, toospicyPatchBuffer_20, 0, ""},
{toospicyFileName_21, toospicyPatchSize_21, toospicyPatchBuffer_21, 0, ""},
{toospicyFileName_22, toospicyPatchSize_22, toospicyPatchBuffer_22, 0, ""},
{toospicyFileName_23, toospicyPatchSize_23, toospicyPatchBuffer_23, 0, ""}};
int tooSpicyShaderPatchesCount = sizeof(tooSpicyShaderPatches) / sizeof(ShaderFilesToPatch);
+5
View File
@@ -0,0 +1,5 @@
#include <sys/types.h>
#include "common.h"
extern ShaderFilesToPatch tooSpicyShaderPatches[];
extern int tooSpicyShaderPatchesCount;
+7
View File
@@ -0,0 +1,7 @@
#include "common.h"
extern SearchReplace abcFsMesa[];
extern int abcFsMesaCount;
extern SearchReplace abcVsMesa[];
extern int abcVsMesaCount;
+446
View File
@@ -0,0 +1,446 @@
#include "common.h"
// File: a.frag
const char axaFileName_0[] = "a.frag";
const size_t axaPatchSize_0 = 86;
const unsigned char axaPatchBuffer_0[] = {
0x27, 0xee, 0x11, 0x15, 0xac, 0x06, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x01, 0x00, 0x00, 0x01, 0x02, 0x2f, 0x2f, 0x02,
0x5c, 0x01, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x02, 0x2f, 0x2f, 0x02, 0xd0, 0x01, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x01,
0x06, 0x53, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x02, 0x1f, 0x02, 0x00, 0x00, 0x7d, 0x02, 0x00, 0x00, 0x01, 0x06, 0x66, 0x6c, 0x6f, 0x61,
0x74, 0x28, 0x02, 0x9c, 0x04, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x02, 0xbd, 0x04, 0x00, 0x00, 0xef, 0x01, 0x00, 0x00};
// File: average.frag
const char axaFileName_1[] = "average.frag";
const size_t axaPatchSize_1 = 122;
const unsigned char axaPatchBuffer_1[] = {
0xa5, 0x97, 0xab, 0xa7, 0x17, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x01, 0x01, 0x2e, 0x02,
0xa3, 0x00, 0x00, 0x00, 0xba, 0x00, 0x00, 0x00, 0x01, 0x09, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x28, 0x64, 0x78, 0x29, 0x02, 0x5f,
0x01, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x01, 0x09, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x28, 0x64, 0x79, 0x29, 0x02, 0x8c, 0x01,
0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x01, 0x2a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x28, 0x53, 0x69, 0x7a, 0x65, 0x50, 0x6f, 0x77,
0x65, 0x72, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d,
0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x63, 0x29, 0x02, 0xea, 0x01, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00};
// File: average.vert
const char axaFileName_2[] = "average.vert";
const size_t axaPatchSize_2 = 82;
const unsigned char axaPatchBuffer_2[] = {
0x07, 0x35, 0xa3, 0xe1, 0xa8, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x01, 0x15, 0x61, 0x72,
0x79, 0x69, 0x6e, 0x67, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x02, 0x1b,
0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x02, 0x2f, 0x2f, 0x02, 0x5b, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x01,
0x09, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x3d, 0x02, 0x6d, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00};
// File: DoF.frag
const char axaFileName_3[] = "DoF.frag";
const size_t axaPatchSize_3 = 87;
const unsigned char axaPatchBuffer_3[] = {
0xf6, 0xbf, 0xe4, 0x98, 0xd4, 0x05, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x22, 0x02, 0x00, 0x00, 0x01, 0x06, 0x53, 0x68, 0x61,
0x64, 0x6f, 0x77, 0x02, 0x22, 0x02, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, 0x01, 0x06, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x28, 0x02, 0xe3,
0x02, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x02, 0x05, 0x03, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x02, 0x6b, 0x03, 0x00, 0x00, 0x4d,
0x00, 0x00, 0x00, 0x02, 0xb9, 0x03, 0x00, 0x00, 0x28, 0x01, 0x00, 0x00, 0x02, 0xe2, 0x04, 0x00, 0x00, 0xf2, 0x00, 0x00, 0x00};
// File: GaussH.frag
const char axaFileName_4[] = "GaussH.frag";
const size_t axaPatchSize_4 = 71;
const unsigned char axaPatchBuffer_4[] = {0xbe, 0x8c, 0x26, 0xa2, 0xcf, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0xd7, 0x00,
0x00, 0x00, 0x01, 0x19, 0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x30, 0x2e, 0x30, 0x2c, 0x20,
0x30, 0x2e, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x29, 0x02,
0xd8, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x01, 0x01, 0x2e, 0x02, 0x75, 0x01, 0x00,
0x00, 0x55, 0x00, 0x00, 0x00, 0x01, 0x04, 0x3b, 0x0d, 0x0a, 0x7d};
// File: GaussH.vert
const char axaFileName_5[] = "GaussH.vert";
const size_t axaPatchSize_5 = 53;
const unsigned char axaPatchBuffer_5[] = {0xb9, 0x77, 0x17, 0x34, 0x53, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x3a,
0x01, 0x00, 0x00, 0x01, 0x22, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x28, 0x69, 0x29, 0x2b,
0x30, 0x2e, 0x35, 0x29, 0x2a, 0x57, 0x49, 0x44, 0x54, 0x48, 0x2c, 0x30, 0x2e, 0x30,
0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x7d, 0x0d, 0x0a, 0x7d};
// File: GaussV.frag
const char axaFileName_6[] = "GaussV.frag";
const size_t axaPatchSize_6 = 73;
const unsigned char axaPatchBuffer_6[] = {0x0e, 0x8d, 0x01, 0x4c, 0xd2, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0xd7, 0x00,
0x00, 0x00, 0x01, 0x19, 0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x30, 0x2e, 0x30, 0x2c, 0x20,
0x30, 0x2e, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x29, 0x02,
0xd8, 0x00, 0x00, 0x00, 0x97, 0x00, 0x00, 0x00, 0x01, 0x01, 0x2e, 0x02, 0x6e, 0x01, 0x00,
0x00, 0x5d, 0x00, 0x00, 0x00, 0x01, 0x06, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a};
// File: GaussV.vert
const char axaFileName_7[] = "GaussV.vert";
const size_t axaPatchSize_7 = 40;
const unsigned char axaPatchBuffer_7[] = {0x6b, 0x83, 0x38, 0x8a, 0x81, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x65,
0x01, 0x00, 0x00, 0x01, 0x0c, 0x2e, 0x30, 0x2c, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74,
0x28, 0x69, 0x29, 0x02, 0x68, 0x01, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00};
// File: GetBrightArea.frag
const char axaFileName_8[] = "GetBrightArea.frag";
const size_t axaPatchSize_8 = 58;
const unsigned char axaPatchBuffer_8[] = {0xad, 0x1e, 0xfd, 0x5a, 0x18, 0x04, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x01,
0x00, 0x00, 0x01, 0x02, 0x2f, 0x2f, 0x02, 0x5c, 0x01, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00,
0x01, 0x02, 0x2f, 0x2f, 0x02, 0xd0, 0x01, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x01, 0x04,
0x68, 0x61, 0x6c, 0x66, 0x02, 0x1b, 0x02, 0x00, 0x00, 0xfd, 0x01, 0x00, 0x00};
// File: GlareCompose.frag
const char axaFileName_9[] = "GlareCompose.frag";
const size_t axaPatchSize_9 = 25;
const unsigned char axaPatchBuffer_9[] = {0xc9, 0x8f, 0xdf, 0xaf, 0xdc, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
0xd5, 0x01, 0x00, 0x00, 0x01, 0x06, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a};
// File: Laplacian.frag
const char axaFileName_10[] = "Laplacian.frag";
const size_t axaPatchSize_10 = 152;
const unsigned char axaPatchBuffer_10[] = {
0x27, 0xee, 0x97, 0x8c, 0x91, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x01, 0x00, 0x00, 0x01, 0x02, 0x2f, 0x2f, 0x02,
0x5c, 0x01, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x02, 0x2f, 0x2f, 0x02, 0xd0, 0x01, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x01,
0x02, 0x2e, 0x30, 0x02, 0x35, 0x02, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x01, 0x02, 0x2e, 0x30, 0x02, 0xba, 0x02, 0x00, 0x00, 0x41,
0x00, 0x00, 0x00, 0x01, 0x0e, 0x76, 0x65, 0x63, 0x33, 0x28, 0x6c, 0x61, 0x70, 0x29, 0x2c, 0x76, 0x65, 0x63, 0x33, 0x02, 0xff, 0x02,
0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x2e, 0x30, 0x2c, 0x30, 0x2e, 0x30, 0x2c, 0x30, 0x2e, 0x30, 0x2c, 0x31, 0x2e, 0x30,
0x02, 0x2f, 0x03, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x2e, 0x30, 0x2c, 0x31, 0x2e, 0x30, 0x2c, 0x31, 0x2e, 0x30, 0x2c,
0x31, 0x2e, 0x30, 0x02, 0x56, 0x03, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x01, 0x06, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a};
// File: Laplacian.vert
const char axaFileName_11[] = "Laplacian.vert";
const size_t axaPatchSize_11 = 99;
const unsigned char axaPatchBuffer_11[] = {
0x7e, 0x77, 0x80, 0x69, 0x6e, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x01, 0x0b, 0x49,
0x44, 0x54, 0x48, 0x2c, 0x48, 0x45, 0x49, 0x47, 0x48, 0x54, 0x02, 0x35, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, 0x01,
0x04, 0x49, 0x44, 0x54, 0x48, 0x02, 0xc7, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x04, 0x49, 0x44, 0x54, 0x48,
0x02, 0xfb, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x01, 0x05, 0x45, 0x49, 0x47, 0x48, 0x54, 0x02, 0x32, 0x01, 0x00,
0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x45, 0x49, 0x47, 0x48, 0x54, 0x29, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a};
// File: Monochrome.frag
const char axaFileName_12[] = "Monochrome.frag";
const size_t axaPatchSize_12 = 113;
const unsigned char axaPatchBuffer_12[] = {
0x7b, 0xd1, 0x09, 0xaa, 0xff, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x01, 0x00, 0x00, 0x01, 0x02,
0x2f, 0x2f, 0x02, 0x5c, 0x01, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x02, 0x2f, 0x2f, 0x02, 0xd0, 0x01, 0x00,
0x00, 0xaa, 0x00, 0x00, 0x00, 0x01, 0x32, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x30, 0x2e, 0x30, 0x2c, 0x20,
0x30, 0x2e, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20,
0x20, 0x20, 0x6d, 0x6f, 0x6e, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x72, 0x67, 0x62, 0x3d, 0x76, 0x65, 0x63, 0x33, 0x28,
0x02, 0x8d, 0x02, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x02, 0xb4, 0x02, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00};
// File: Monochrome.vert
const char axaFileName_13[] = "Monochrome.vert";
const size_t axaPatchSize_13 = 121;
const unsigned char axaPatchBuffer_13[] = {
0x78, 0x26, 0x8a, 0x51, 0x79, 0x00, 0x00, 0x00, 0x01, 0x66, 0x23, 0x69, 0x66, 0x6e, 0x64, 0x65, 0x66, 0x09, 0x4d, 0x4f, 0x44,
0x45, 0x0d, 0x0a, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x09, 0x4d, 0x4f, 0x44, 0x45, 0x09, 0x30, 0x0d, 0x0a, 0x23, 0x65,
0x6e, 0x64, 0x69, 0x66, 0x0d, 0x0a, 0x0d, 0x0a, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x09, 0x4d, 0x4f, 0x4e, 0x4f, 0x43,
0x48, 0x52, 0x4f, 0x4d, 0x45, 0x09, 0x09, 0x09, 0x28, 0x4d, 0x4f, 0x44, 0x45, 0x3d, 0x3d, 0x30, 0x29, 0x0d, 0x0a, 0x23, 0x64,
0x65, 0x66, 0x69, 0x6e, 0x65, 0x09, 0x53, 0x45, 0x50, 0x49, 0x41, 0x09, 0x09, 0x09, 0x09, 0x28, 0x4d, 0x4f, 0x44, 0x45, 0x3d,
0x3d, 0x31, 0x29, 0x0d, 0x0a, 0x0d, 0x0a, 0x02, 0x00, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00};
// File: nnstdshader.vert
const char axaFileName_14[] = "nnstdshader.vert";
const size_t axaPatchSize_14 = 185;
const unsigned char axaPatchBuffer_14[] = {
0x72, 0x20, 0xc8, 0xf6, 0x8a, 0x1c, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x0b, 0x01, 0x00, 0x01, 0x1b, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x6d, 0x61, 0x78, 0x5f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x73,
0x75, 0x6d, 0x20, 0x3d, 0x02, 0xf5, 0x0b, 0x01, 0x00, 0x57, 0x00, 0x00, 0x00, 0x01, 0x77, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x6c, 0x6f, 0x6f, 0x70, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x20, 0x3d,
0x20, 0x28, 0x6d, 0x61, 0x78, 0x5f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x73, 0x75, 0x6d, 0x20, 0x3c, 0x20, 0x38, 0x29, 0x20,
0x3f, 0x20, 0x6d, 0x61, 0x78, 0x5f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x73, 0x75, 0x6d, 0x20, 0x3a, 0x20, 0x38, 0x3b, 0x0d,
0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x28, 0x20, 0x69, 0x6e, 0x74, 0x20,
0x6c, 0x69, 0x74, 0x6e, 0x6f, 0x20, 0x3d, 0x20, 0x30, 0x3b, 0x20, 0x6c, 0x69, 0x74, 0x6e, 0x6f, 0x20, 0x3c, 0x20, 0x6c, 0x6f,
0x6f, 0x70, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x02, 0x4e, 0x0c, 0x01, 0x00, 0x3c, 0x10, 0x00, 0x00};
// File: Posterization.frag
const char axaFileName_15[] = "Posterization.frag";
const size_t axaPatchSize_15 = 43;
const unsigned char axaPatchBuffer_15[] = {0x3c, 0xb8, 0x01, 0x0a, 0xaa, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x01,
0x00, 0x00, 0x01, 0x02, 0x2f, 0x2f, 0x02, 0x5c, 0x01, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00,
0x01, 0x02, 0x2f, 0x2f, 0x02, 0xd0, 0x01, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00};
// File: Sepia.frag
const char axaFileName_16[] = "Sepia.frag";
const size_t axaPatchSize_16 = 43;
const unsigned char axaPatchBuffer_16[] = {0x34, 0xd7, 0x76, 0x81, 0x16, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x01,
0x00, 0x00, 0x01, 0x02, 0x2f, 0x2f, 0x02, 0x5c, 0x01, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00,
0x01, 0x02, 0x2f, 0x2f, 0x02, 0xd0, 0x01, 0x00, 0x00, 0x46, 0x01, 0x00, 0x00};
// File: Solarization.frag
const char axaFileName_17[] = "Solarization.frag";
const size_t axaPatchSize_17 = 125;
const unsigned char axaPatchBuffer_17[] = {
0x0b, 0xdc, 0x75, 0x3a, 0x23, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x01, 0x00, 0x00, 0x01, 0x02, 0x2f, 0x2f,
0x02, 0x5c, 0x01, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x02, 0x2f, 0x2f, 0x02, 0xd0, 0x01, 0x00, 0x00, 0xb3, 0x00, 0x00,
0x00, 0x01, 0x24, 0x0d, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x28, 0x63, 0x6f, 0x6c, 0x2e, 0x72, 0x3e, 0x54, 0x68, 0x72, 0x65, 0x73,
0x68, 0x6f, 0x6c, 0x64, 0x52, 0x29, 0x0d, 0x0a, 0x09, 0x63, 0x6f, 0x6c, 0x2e, 0x72, 0x3d, 0x31, 0x2e, 0x30, 0x02, 0xa6, 0x02,
0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x02, 0x2e, 0x30, 0x02, 0xd2, 0x02, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x0b,
0x2e, 0x30, 0x2d, 0x63, 0x6f, 0x6c, 0x2e, 0x62, 0x3b, 0x0d, 0x0a, 0x02, 0x05, 0x03, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00};
// File: toon.frag
const char axaFileName_18[] = "toon.frag";
const size_t axaPatchSize_18 = 119;
const unsigned char axaPatchBuffer_18[] = {
0xc4, 0x90, 0xe7, 0x37, 0x52, 0x11, 0x00, 0x00, 0x01, 0x53, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x68, 0x61,
0x6c, 0x66, 0x09, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x0d, 0x0a, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x68, 0x61,
0x6c, 0x66, 0x32, 0x09, 0x76, 0x65, 0x63, 0x32, 0x0d, 0x0a, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x68, 0x61,
0x6c, 0x66, 0x33, 0x09, 0x76, 0x65, 0x63, 0x33, 0x0d, 0x0a, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x68, 0x61,
0x6c, 0x66, 0x34, 0x09, 0x76, 0x65, 0x63, 0x34, 0x0d, 0x0a, 0x09, 0x0d, 0x0a, 0x02, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00,
0x00, 0x00, 0x01, 0x06, 0x53, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x02, 0x45, 0x00, 0x00, 0x00, 0x0d, 0x11, 0x00, 0x00};
// File: YUVCompose.frag
const char axaFileName_19[] = "YUVCompose.frag";
const size_t axaPatchSize_19 = 507;
const unsigned char axaPatchBuffer_19[] = {
0xee, 0x1d, 0x3d, 0x9c, 0x54, 0x04, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x01, 0x00, 0x00, 0x01, 0x02, 0x2f, 0x2f, 0x02,
0x5c, 0x01, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x49, 0x2f, 0x2f, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x0d, 0x0a, 0x0d, 0x0a,
0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x3b,
0x0d, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 0x59, 0x54,
0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x3b, 0x0d, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x02, 0x07, 0x02, 0x00, 0x00,
0x16, 0x00, 0x00, 0x00, 0x01, 0x25, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32,
0x44, 0x20, 0x43, 0x62, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x23, 0x69, 0x66, 0x09, 0x30, 0x02,
0x33, 0x02, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x01, 0x02, 0x2e, 0x30, 0x02, 0xba, 0x02, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x01,
0x7a, 0x23, 0x65, 0x6c, 0x73, 0x65, 0x0d, 0x0a, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6d, 0x61, 0x74, 0x33, 0x20, 0x59, 0x43, 0x62,
0x43, 0x72, 0x32, 0x52, 0x47, 0x42, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x74, 0x33, 0x0d, 0x0a, 0x28,
0x20, 0x31, 0x2e, 0x31, 0x36, 0x34, 0x2c, 0x20, 0x31, 0x2e, 0x31, 0x36, 0x34, 0x2c, 0x31, 0x2e, 0x31, 0x36, 0x34, 0x2c, 0x0d, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x30, 0x2e, 0x30, 0x2c, 0x2d, 0x30, 0x2e, 0x33, 0x39, 0x32, 0x2c, 0x32, 0x2e, 0x30, 0x31, 0x37, 0x2c, 0x0d,
0x0a, 0x20, 0x20, 0x31, 0x2e, 0x35, 0x39, 0x36, 0x2c, 0x2d, 0x30, 0x2e, 0x38, 0x31, 0x33, 0x2c, 0x20, 0x20, 0x30, 0x2e, 0x30, 0x0d,
0x0a, 0x29, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x02, 0x28, 0x03, 0x00, 0x00, 0xde, 0x00, 0x00, 0x00,
0x01, 0x2e, 0x23, 0x69, 0x66, 0x09, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x59, 0x43, 0x62, 0x43, 0x72, 0x41, 0x2d, 0x3d, 0x68, 0x61,
0x6c, 0x66, 0x34, 0x28, 0x31, 0x36, 0x2e, 0x30, 0x2f, 0x32, 0x35, 0x35, 0x2e, 0x30, 0x2c, 0x30, 0x2e, 0x35, 0x2c, 0x30, 0x2e, 0x35,
0x2c, 0x30, 0x29, 0x3b, 0x02, 0x2d, 0x04, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x01, 0x8c, 0x23, 0x65, 0x6c, 0x73, 0x65, 0x0d, 0x0a,
0x20, 0x20, 0x20, 0x59, 0x43, 0x62, 0x43, 0x72, 0x41, 0x2e, 0x72, 0x67, 0x62, 0x2d, 0x3d, 0x68, 0x61, 0x6c, 0x66, 0x33, 0x28, 0x31,
0x36, 0x2e, 0x30, 0x2f, 0x32, 0x35, 0x35, 0x2e, 0x30, 0x2c, 0x30, 0x2e, 0x35, 0x2c, 0x30, 0x2e, 0x35, 0x29, 0x3b, 0x0d, 0x0a, 0x20,
0x20, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x72, 0x67, 0x62, 0x20, 0x3d, 0x20, 0x59,
0x43, 0x62, 0x43, 0x72, 0x32, 0x52, 0x47, 0x42, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x2a, 0x20, 0x59, 0x43, 0x62, 0x43, 0x72,
0x41, 0x2e, 0x72, 0x67, 0x62, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f,
0x72, 0x2e, 0x61, 0x20, 0x3d, 0x20, 0x31, 0x2e, 0x30, 0x3b, 0x0d, 0x0a, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x0d, 0x0a, 0x7d, 0x0d,
0x0a};
ShaderFilesToPatch axaShaderPatches[] = {
{axaFileName_0, axaPatchSize_0, axaPatchBuffer_0, 0, ""}, {axaFileName_1, axaPatchSize_1, axaPatchBuffer_1, 0, ""},
{axaFileName_2, axaPatchSize_2, axaPatchBuffer_2, 0, ""}, {axaFileName_3, axaPatchSize_3, axaPatchBuffer_3, 0, ""},
{axaFileName_4, axaPatchSize_4, axaPatchBuffer_4, 0, ""}, {axaFileName_5, axaPatchSize_5, axaPatchBuffer_5, 0, ""},
{axaFileName_6, axaPatchSize_6, axaPatchBuffer_6, 0, ""}, {axaFileName_7, axaPatchSize_7, axaPatchBuffer_7, 0, ""},
{axaFileName_8, axaPatchSize_8, axaPatchBuffer_8, 0, ""}, {axaFileName_9, axaPatchSize_9, axaPatchBuffer_9, 0, ""},
{axaFileName_10, axaPatchSize_10, axaPatchBuffer_10, 0, ""}, {axaFileName_11, axaPatchSize_11, axaPatchBuffer_11, 0, ""},
{axaFileName_12, axaPatchSize_12, axaPatchBuffer_12, 0, ""}, {axaFileName_13, axaPatchSize_13, axaPatchBuffer_13, 0, ""},
{axaFileName_14, axaPatchSize_14, axaPatchBuffer_14, 0, ""}, {axaFileName_15, axaPatchSize_15, axaPatchBuffer_15, 0, ""},
{axaFileName_16, axaPatchSize_16, axaPatchBuffer_16, 0, ""}, {axaFileName_17, axaPatchSize_17, axaPatchBuffer_17, 0, ""},
{axaFileName_18, axaPatchSize_18, axaPatchBuffer_18, 0, ""}, {axaFileName_19, axaPatchSize_19, axaPatchBuffer_19, 0, ""},
};
int axaShaderPatchesCount = sizeof(axaShaderPatches) / sizeof(ShaderFilesToPatch);
// File: a.frag
const char axalFileName_0[] = "a.frag";
const size_t axalPatchSize_0 = 69;
const unsigned char axalPatchBuffer_0[] = {0x8d, 0xf0, 0x28, 0x62, 0xb2, 0x06, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x5c,
0x01, 0x00, 0x00, 0x01, 0x02, 0x2f, 0x2f, 0x02, 0x5c, 0x01, 0x00, 0x00, 0x74, 0x00,
0x00, 0x00, 0x01, 0x02, 0x2f, 0x2f, 0x02, 0xd0, 0x01, 0x00, 0x00, 0xd2, 0x02, 0x00,
0x00, 0x01, 0x06, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x28, 0x02, 0x1f, 0x05, 0x00, 0x00,
0x22, 0x00, 0x00, 0x00, 0x02, 0xc3, 0x04, 0x00, 0x00, 0xef, 0x01, 0x00, 0x00};
// File: DoF.frag
const char axalFileName_1[] = "DoF.frag";
const size_t axalPatchSize_1 = 70;
const unsigned char axalPatchBuffer_1[] = {0x5c, 0xc2, 0xef, 0xdb, 0xda, 0x05, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0xe9,
0x02, 0x00, 0x00, 0x01, 0x06, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x28, 0x02, 0xe9, 0x02,
0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x02, 0x0b, 0x03, 0x00, 0x00, 0x65, 0x00, 0x00,
0x00, 0x02, 0x71, 0x03, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x02, 0xbf, 0x03, 0x00,
0x00, 0x28, 0x01, 0x00, 0x00, 0x02, 0xe8, 0x04, 0x00, 0x00, 0xf2, 0x00, 0x00, 0x00};
// File: Laplacian.frag
const char axalFileName_2[] = "Laplacian.frag";
const size_t axalPatchSize_2 = 205;
const unsigned char axalPatchBuffer_2[] = {
0x54, 0xf0, 0x85, 0x23, 0x99, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x01, 0x00, 0x00, 0x01, 0x02, 0x2f, 0x2f,
0x02, 0x5c, 0x01, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x02, 0x2f, 0x2f, 0x02, 0xd0, 0x01, 0x00, 0x00, 0x65, 0x00, 0x00,
0x00, 0x01, 0x02, 0x2e, 0x30, 0x02, 0x35, 0x02, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x01, 0x02, 0x2e, 0x30, 0x02, 0xba, 0x02,
0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x01, 0x75, 0x76, 0x65, 0x63, 0x33, 0x28, 0x6c, 0x61, 0x70, 0x29, 0x2c, 0x76, 0x65, 0x63,
0x33, 0x28, 0x30, 0x2e, 0x33, 0x2c, 0x30, 0x2e, 0x36, 0x2c, 0x30, 0x2e, 0x31, 0x29, 0x29, 0x3c, 0x30, 0x2e, 0x31, 0x35, 0x29,
0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x63, 0x6f, 0x6c, 0x3d, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x28,
0x30, 0x2e, 0x30, 0x2c, 0x30, 0x2e, 0x30, 0x2c, 0x30, 0x2e, 0x30, 0x2c, 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20,
0x20, 0x65, 0x6c, 0x73, 0x65, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x63, 0x6f, 0x6c, 0x3d, 0x68,
0x61, 0x6c, 0x66, 0x34, 0x28, 0x31, 0x2e, 0x30, 0x2c, 0x31, 0x2e, 0x30, 0x2c, 0x31, 0x2e, 0x30, 0x2c, 0x31, 0x2e, 0x30, 0x02,
0x5e, 0x03, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x01, 0x06, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a};
// File: toon.frag
const char axalFileName_3[] = "toon.frag";
const size_t axalPatchSize_3 = 1958;
const unsigned char axalPatchBuffer_3[] = {
0x7d, 0x45, 0x29, 0xe8, 0xfd, 0x0c, 0x00, 0x00, 0x01, 0x53, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x68, 0x61, 0x6c, 0x66,
0x09, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x0d, 0x0a, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x32, 0x09,
0x76, 0x65, 0x63, 0x32, 0x0d, 0x0a, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x33, 0x09, 0x76, 0x65,
0x63, 0x33, 0x0d, 0x0a, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x09, 0x76, 0x65, 0x63, 0x34,
0x0d, 0x0a, 0x09, 0x0d, 0x0a, 0x02, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x01, 0x01, 0x34, 0x02, 0x30, 0x00, 0x00, 0x00,
0x39, 0x00, 0x00, 0x00, 0x01, 0x09, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x4d, 0x61, 0x74, 0x02, 0x71, 0x00, 0x00, 0x00, 0x93, 0x01,
0x00, 0x00, 0x01, 0x5e, 0x4d, 0x41, 0x54, 0x45, 0x52, 0x49, 0x41, 0x4c, 0x5f, 0x43, 0x4d, 0x50, 0x09, 0x28, 0x46, 0x52, 0x41, 0x4d,
0x45, 0x4d, 0x4f, 0x44, 0x45, 0x26, 0x32, 0x29, 0x0d, 0x0a, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x09, 0x4e, 0x4f, 0x52, 0x4d,
0x41, 0x4c, 0x5f, 0x43, 0x4d, 0x50, 0x09, 0x09, 0x28, 0x46, 0x52, 0x41, 0x4d, 0x45, 0x4d, 0x4f, 0x44, 0x45, 0x26, 0x34, 0x29, 0x0d,
0x0a, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x09, 0x45, 0x58, 0x54, 0x52, 0x41, 0x5f, 0x43, 0x4d, 0x50, 0x09, 0x09, 0x28, 0x46,
0x52, 0x41, 0x4d, 0x45, 0x4d, 0x4f, 0x44, 0x45, 0x26, 0x38, 0x02, 0x1d, 0x02, 0x00, 0x00, 0x1b, 0x04, 0x00, 0x00, 0x01, 0x34, 0x76,
0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x76, 0x6f, 0x69, 0x64, 0x29, 0x0d, 0x0a, 0x7b, 0x0d, 0x0a, 0x09, 0x68, 0x61,
0x6c, 0x66, 0x34, 0x20, 0x66, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x28, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x30,
0x2c, 0x20, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x02, 0xdb, 0x06, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x01, 0x02, 0x7a, 0x77, 0x02, 0xd5,
0x07, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x01, 0x01, 0x2c, 0x02, 0x43, 0x07, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x01, 0x32,
0x02, 0x69, 0x07, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x01, 0x05, 0x33, 0x5d, 0x2e, 0x78, 0x79, 0x02, 0x09, 0x08, 0x00, 0x00, 0xfb,
0x00, 0x00, 0x00, 0x01, 0x05, 0x23, 0x69, 0x66, 0x20, 0x31, 0x02, 0x02, 0x09, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x01, 0x1f, 0x23,
0x65, 0x6c, 0x73, 0x65, 0x0d, 0x0a, 0x09, 0x09, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x44, 0x65, 0x70, 0x74, 0x68, 0x3d, 0x63, 0x76,
0x74, 0x5f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x28, 0x02, 0xf7, 0x06, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x02, 0x27, 0x09, 0x00, 0x00,
0x27, 0x00, 0x00, 0x00, 0x02, 0xe3, 0x07, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x01, 0x01, 0x30, 0x02, 0x05, 0x08, 0x00, 0x00, 0x0e,
0x00, 0x00, 0x00, 0x01, 0x10, 0x2c, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x63, 0x76, 0x74, 0x5f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x28, 0x02,
0xe3, 0x07, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x10, 0x2c, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x63, 0x76, 0x74, 0x5f, 0x64, 0x65,
0x70, 0x74, 0x68, 0x28, 0x02, 0xe3, 0x07, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x01, 0x01, 0x32, 0x02, 0x69, 0x07, 0x00, 0x00, 0x0d,
0x00, 0x00, 0x00, 0x01, 0x11, 0x29, 0x2c, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x63, 0x76, 0x74, 0x5f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x28,
0x02, 0xe3, 0x07, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x01, 0x01, 0x33, 0x02, 0x69, 0x07, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x01,
0x13, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x0d, 0x0a, 0x09, 0x09, 0x66, 0x2e, 0x78, 0x20, 0x02, 0xd1,
0x09, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x03, 0x2b, 0x05, 0x00, 0x00, 0x28, 0x4d, 0x41, 0x54, 0x45, 0x52, 0x49, 0x41, 0x4c, 0x5f,
0x43, 0x4d, 0x50, 0x20, 0x7c, 0x7c, 0x20, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x5f, 0x43, 0x4d, 0x50, 0x29, 0x0d, 0x0a, 0x09, 0x09,
0x68, 0x61, 0x6c, 0x66, 0x33, 0x20, 0x74, 0x6e, 0x6d, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x33, 0x28, 0x74, 0x65, 0x78, 0x74,
0x75, 0x72, 0x65, 0x32, 0x44, 0x28, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x4d, 0x61, 0x74, 0x49, 0x44, 0x50, 0x69, 0x63, 0x2c, 0x74,
0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x29, 0x2e, 0x72, 0x67, 0x62, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x68, 0x61, 0x6c, 0x66,
0x33, 0x20, 0x74, 0x6e, 0x6d, 0x73, 0x5b, 0x34, 0x5d, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x74, 0x6e, 0x6d, 0x73, 0x5b, 0x30, 0x5d, 0x20,
0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x33, 0x28, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x44, 0x28, 0x4e, 0x6f, 0x72, 0x6d,
0x61, 0x6c, 0x4d, 0x61, 0x74, 0x49, 0x44, 0x50, 0x69, 0x63, 0x2c, 0x20, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x77, 0x5b,
0x30, 0x5d, 0x2e, 0x7a, 0x77, 0x29, 0x2e, 0x72, 0x67, 0x62, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x74, 0x6e, 0x6d, 0x73, 0x5b, 0x31,
0x5d, 0x09, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x33, 0x28, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x44, 0x28, 0x4e, 0x6f,
0x72, 0x6d, 0x61, 0x6c, 0x4d, 0x61, 0x74, 0x49, 0x44, 0x50, 0x69, 0x63, 0x2c, 0x20, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64,
0x77, 0x5b, 0x31, 0x5d, 0x2e, 0x7a, 0x77, 0x29, 0x2e, 0x72, 0x67, 0x62, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x74, 0x6e, 0x6d, 0x73,
0x5b, 0x32, 0x5d, 0x09, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x33, 0x28, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x44, 0x28,
0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x4d, 0x61, 0x74, 0x49, 0x44, 0x50, 0x69, 0x63, 0x2c, 0x20, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f,
0x72, 0x64, 0x77, 0x5b, 0x32, 0x5d, 0x2e, 0x78, 0x79, 0x29, 0x2e, 0x72, 0x67, 0x62, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x74, 0x6e,
0x6d, 0x73, 0x5b, 0x33, 0x5d, 0x09, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x33, 0x28, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32,
0x44, 0x28, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x4d, 0x61, 0x74, 0x49, 0x44, 0x50, 0x69, 0x63, 0x2c, 0x20, 0x74, 0x65, 0x78, 0x43,
0x6f, 0x6f, 0x72, 0x64, 0x77, 0x5b, 0x33, 0x5d, 0x2e, 0x78, 0x79, 0x29, 0x2e, 0x72, 0x67, 0x62, 0x29, 0x3b, 0x0d, 0x0a, 0x23, 0x69,
0x66, 0x09, 0x09, 0x28, 0x4d, 0x41, 0x54, 0x45, 0x52, 0x49, 0x41, 0x4c, 0x5f, 0x43, 0x4d, 0x50, 0x20, 0x26, 0x26, 0x20, 0x4e, 0x4f,
0x52, 0x4d, 0x41, 0x4c, 0x5f, 0x43, 0x4d, 0x50, 0x29, 0x20, 0x26, 0x26, 0x20, 0x30, 0x09, 0x2f, 0x2a, 0x20, 0x4d, 0x41, 0x54, 0x45,
0x52, 0x49, 0x41, 0x4c, 0x20, 0x82, 0xc6, 0x20, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x20, 0x95, 0xca, 0x82, 0xe6, 0x82, 0xe8, 0x82,
0xe0, 0x92, 0x78, 0x82, 0xa2, 0x81, 0x42, 0x94, 0x70, 0x8e, 0x7e, 0x81, 0x42, 0x09, 0x2a, 0x2f, 0x0d, 0x0a, 0x09, 0x09, 0x68, 0x61,
0x6c, 0x66, 0x34, 0x20, 0x66, 0x79, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x68, 0x61, 0x6c, 0x66, 0x33, 0x20, 0x74, 0x68, 0x72, 0x65, 0x73,
0x68, 0x6f, 0x6c, 0x64, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x33, 0x28, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64,
0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x2c, 0x20, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x4e, 0x6f, 0x72, 0x6d, 0x61,
0x6c, 0x2c, 0x20, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x29, 0x3b, 0x0d,
0x0a, 0x09, 0x09, 0x66, 0x79, 0x2e, 0x78, 0x20, 0x3d, 0x20, 0x63, 0x6d, 0x70, 0x5f, 0x68, 0x61, 0x6c, 0x66, 0x33, 0x28, 0x74, 0x6e,
0x6d, 0x2c, 0x20, 0x74, 0x6e, 0x6d, 0x73, 0x5b, 0x30, 0x5d, 0x2c, 0x20, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x29,
0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x66, 0x79, 0x2e, 0x79, 0x20, 0x3d, 0x20, 0x63, 0x6d, 0x70, 0x5f, 0x68, 0x61, 0x6c, 0x66, 0x33, 0x28,
0x74, 0x6e, 0x6d, 0x2c, 0x20, 0x74, 0x6e, 0x6d, 0x73, 0x5b, 0x31, 0x5d, 0x2c, 0x20, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c,
0x64, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x66, 0x79, 0x2e, 0x7a, 0x20, 0x3d, 0x20, 0x63, 0x6d, 0x70, 0x5f, 0x68, 0x61, 0x6c, 0x66,
0x33, 0x28, 0x74, 0x6e, 0x6d, 0x2c, 0x20, 0x74, 0x6e, 0x6d, 0x73, 0x5b, 0x32, 0x5d, 0x2c, 0x20, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68,
0x6f, 0x6c, 0x64, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x66, 0x79, 0x2e, 0x77, 0x20, 0x3d, 0x20, 0x63, 0x6d, 0x70, 0x5f, 0x68, 0x61,
0x6c, 0x66, 0x33, 0x28, 0x74, 0x6e, 0x6d, 0x2c, 0x20, 0x74, 0x6e, 0x6d, 0x73, 0x5b, 0x33, 0x5d, 0x2c, 0x20, 0x74, 0x68, 0x72, 0x65,
0x73, 0x68, 0x6f, 0x6c, 0x64, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x66, 0x2e, 0x79, 0x20, 0x3d, 0x20, 0x64, 0x6f, 0x74, 0x28, 0x66,
0x79, 0x2c, 0x20, 0x66, 0x79, 0x29, 0x3b, 0x0d, 0x0a, 0x23, 0x65, 0x6c, 0x73, 0x65, 0x09, 0x2f, 0x2a, 0x09, 0x28, 0x4d, 0x41, 0x54,
0x45, 0x52, 0x49, 0x41, 0x4c, 0x5f, 0x43, 0x4d, 0x50, 0x20, 0x26, 0x26, 0x20, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x5f, 0x43, 0x4d,
0x50, 0x29, 0x09, 0x2a, 0x2f, 0x0d, 0x0a, 0x23, 0x69, 0x66, 0x09, 0x4d, 0x41, 0x54, 0x45, 0x52, 0x49, 0x41, 0x4c, 0x5f, 0x43, 0x4d,
0x50, 0x09, 0x2f, 0x2a, 0x20, 0x4d, 0x41, 0x54, 0x45, 0x52, 0x49, 0x41, 0x4c, 0x28, 0x55, 0x53, 0x45, 0x52, 0x50, 0x52, 0x4f, 0x46,
0x49, 0x4c, 0x45, 0x29, 0x09, 0x2a, 0x2f, 0x0d, 0x0a, 0x09, 0x09, 0x66, 0x2e, 0x79, 0x20, 0x3d, 0x20, 0x63, 0x6d, 0x70, 0x5f, 0x68,
0x61, 0x6c, 0x66, 0x34, 0x31, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x28, 0x74, 0x6e, 0x6d, 0x73, 0x5b, 0x30, 0x5d, 0x2e, 0x62, 0x2c,
0x20, 0x74, 0x6e, 0x6d, 0x73, 0x5b, 0x31, 0x5d, 0x2e, 0x62, 0x2c, 0x20, 0x74, 0x6e, 0x6d, 0x73, 0x5b, 0x32, 0x5d, 0x2e, 0x62, 0x2c,
0x20, 0x74, 0x6e, 0x6d, 0x73, 0x5b, 0x33, 0x5d, 0x2e, 0x62, 0x29, 0x2c, 0x20, 0x74, 0x6e, 0x6d, 0x2e, 0x62, 0x2c, 0x20, 0x54, 0x68,
0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x29, 0x3b, 0x0d, 0x0a, 0x23, 0x65, 0x6e, 0x64,
0x69, 0x66, 0x09, 0x2f, 0x2a, 0x09, 0x4d, 0x41, 0x54, 0x45, 0x52, 0x49, 0x41, 0x4c, 0x5f, 0x43, 0x4d, 0x50, 0x09, 0x2a, 0x2f, 0x0d,
0x0a, 0x23, 0x69, 0x66, 0x09, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x5f, 0x43, 0x4d, 0x50, 0x0d, 0x0a, 0x09, 0x09, 0x2f, 0x2a, 0x20,
0x20, 0x96, 0x40, 0x90, 0xfc, 0x82, 0xcd, 0x20, 0x58, 0x59, 0x20, 0x82, 0xcc, 0x82, 0xdd, 0x82, 0xc5, 0x94, 0xbb, 0x92, 0xe8, 0x20,
0x2a, 0x2f, 0x0d, 0x0a, 0x09, 0x09, 0x66, 0x2e, 0x7a, 0x20, 0x3d, 0x20, 0x63, 0x6d, 0x70, 0x5f, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x34,
0x28, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x28, 0x74, 0x6e, 0x6d, 0x2e, 0x72, 0x67, 0x2c, 0x20, 0x74, 0x6e, 0x6d, 0x2e, 0x72, 0x67, 0x29,
0x2c, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x28, 0x74, 0x6e, 0x6d, 0x73, 0x5b, 0x30, 0x5d, 0x2e, 0x72, 0x67, 0x2c, 0x20, 0x74, 0x6e,
0x6d, 0x73, 0x5b, 0x31, 0x5d, 0x2e, 0x72, 0x67, 0x29, 0x2c, 0x20, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x4e, 0x6f,
0x72, 0x6d, 0x61, 0x6c, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x66, 0x2e, 0x77, 0x20, 0x3d, 0x20, 0x63, 0x6d, 0x70, 0x5f, 0x68, 0x61,
0x6c, 0x66, 0x34, 0x34, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x28, 0x74, 0x6e, 0x6d, 0x2e, 0x72, 0x67, 0x2c, 0x20, 0x74, 0x6e, 0x6d,
0x2e, 0x72, 0x67, 0x29, 0x2c, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x28, 0x74, 0x6e, 0x6d, 0x73, 0x5b, 0x32, 0x5d, 0x2e, 0x72, 0x67,
0x2c, 0x20, 0x74, 0x6e, 0x6d, 0x73, 0x5b, 0x33, 0x5d, 0x2e, 0x72, 0x67, 0x29, 0x2c, 0x20, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f,
0x6c, 0x64, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x29, 0x3b, 0x0d, 0x0a, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x09, 0x2f, 0x2a, 0x20,
0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x5f, 0x43, 0x4d, 0x50, 0x09, 0x2a, 0x2f, 0x0d, 0x0a, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x09,
0x2f, 0x2a, 0x20, 0x28, 0x4d, 0x41, 0x54, 0x45, 0x52, 0x49, 0x41, 0x4c, 0x5f, 0x43, 0x4d, 0x50, 0x20, 0x26, 0x26, 0x20, 0x4e, 0x4f,
0x52, 0x4d, 0x41, 0x4c, 0x5f, 0x43, 0x4d, 0x50, 0x29, 0x09, 0x2a, 0x2f, 0x0d, 0x0a, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x09, 0x2f,
0x2a, 0x20, 0x28, 0x4d, 0x41, 0x54, 0x45, 0x52, 0x49, 0x41, 0x4c, 0x5f, 0x43, 0x4d, 0x50, 0x20, 0x7c, 0x7c, 0x20, 0x4e, 0x4f, 0x52,
0x4d, 0x41, 0x4c, 0x5f, 0x43, 0x4d, 0x50, 0x29, 0x09, 0x2a, 0x2f, 0x0d, 0x0a, 0x09, 0x7d, 0x02, 0x17, 0x0c, 0x00, 0x00, 0x4a, 0x00,
0x00, 0x00, 0x01, 0x16, 0x29, 0x20, 0x2a, 0x20, 0x6d, 0x69, 0x6e, 0x28, 0x64, 0x6f, 0x74, 0x28, 0x66, 0x2c, 0x20, 0x66, 0x29, 0x2c,
0x20, 0x31, 0x2e, 0x30, 0x02, 0x94, 0x0c, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x02, 0xb3, 0x0c, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00};
// File: toon.vert
const char axalFileName_4[] = "toon.vert";
const size_t axalPatchSize_4 = 1429;
const unsigned char axalPatchBuffer_4[] = {
0x5a, 0xb9, 0x67, 0xab, 0x46, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x01, 0x01, 0x34, 0x02, 0x30,
0x00, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x01, 0x05, 0x23, 0x69, 0x66, 0x20, 0x30, 0x02, 0xe8, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00,
0x00, 0x02, 0x40, 0x01, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x02, 0x10, 0x01, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x02, 0xfa, 0x00,
0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x02, 0x6e, 0x01, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x02, 0x10, 0x01, 0x00, 0x00, 0x2b, 0x00,
0x00, 0x00, 0x01, 0x01, 0x31, 0x02, 0x3c, 0x01, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x0d, 0x0a, 0x09, 0x74, 0x65, 0x78,
0x43, 0x6f, 0x6f, 0x72, 0x64, 0x77, 0x5b, 0x32, 0x02, 0x7e, 0x01, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x01, 0x01, 0x32, 0x02, 0x3c,
0x01, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x02, 0xda, 0x01, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x10, 0x09, 0x74, 0x65, 0x78,
0x43, 0x6f, 0x6f, 0x72, 0x64, 0x77, 0x5b, 0x33, 0x5d, 0x2e, 0x78, 0x79, 0x02, 0xc4, 0x01, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x01,
0x10, 0x09, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x77, 0x5b, 0x33, 0x5d, 0x2e, 0x7a, 0x77, 0x02, 0x82, 0x01, 0x00, 0x00,
0x21, 0x00, 0x00, 0x00, 0x02, 0xda, 0x01, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x17, 0x23, 0x65, 0x6c, 0x73, 0x65, 0x0d, 0x0a,
0x09, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x77, 0x5b, 0x30, 0x5d, 0x2e, 0x7a, 0x77, 0x02, 0xfa, 0x00, 0x00, 0x00, 0x41,
0x00, 0x00, 0x00, 0x01, 0x01, 0x31, 0x02, 0x3c, 0x01, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x01, 0x01, 0x32, 0x02, 0x7e, 0x01, 0x00,
0x00, 0x41, 0x00, 0x00, 0x00, 0x01, 0x05, 0x33, 0x5d, 0x2e, 0x78, 0x79, 0x02, 0xc4, 0x01, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x01,
0x13, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x0d, 0x0a, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x2f, 0x2f, 0x20, 0x20, 0x02, 0x00,
0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x04, 0x2f, 0x2f, 0x20, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
0x01, 0x2a, 0x77, 0x5b, 0x38, 0x5d, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x2f, 0x2f, 0x20, 0x20, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61,
0x69, 0x6e, 0x28, 0x76, 0x6f, 0x69, 0x64, 0x29, 0x0d, 0x0a, 0x2f, 0x2f, 0x20, 0x20, 0x7b, 0x0d, 0x0a, 0x2f, 0x2f, 0x20, 0x20, 0x09,
0x02, 0x87, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x04, 0x2f, 0x2f, 0x20, 0x20, 0x02, 0xc5, 0x00, 0x00, 0x00, 0x23, 0x00,
0x00, 0x00, 0x01, 0x11, 0x2f, 0x2f, 0x20, 0x20, 0x09, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x77, 0x5b, 0x30, 0x5d, 0x02,
0x40, 0x01, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, 0xba, 0x30, 0x2e, 0x30, 0x30, 0x30, 0x35, 0x2c, 0x20, 0x74, 0x65, 0x78, 0x43,
0x6f, 0x6f, 0x72, 0x64, 0x2e, 0x79, 0x20, 0x2d, 0x20, 0x30, 0x2e, 0x30, 0x30, 0x30, 0x37, 0x29, 0x3b, 0x0d, 0x0a, 0x2f, 0x2f, 0x20,
0x20, 0x09, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x77, 0x5b, 0x31, 0x5d, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x32, 0x28,
0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e, 0x78, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2c, 0x20, 0x74,
0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e, 0x79, 0x20, 0x2d, 0x20, 0x30, 0x2e, 0x30, 0x30, 0x30, 0x37, 0x29, 0x3b, 0x0d, 0x0a,
0x2f, 0x2f, 0x20, 0x20, 0x09, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x77, 0x5b, 0x32, 0x5d, 0x20, 0x3d, 0x20, 0x76, 0x65,
0x63, 0x32, 0x28, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e, 0x78, 0x20, 0x2b, 0x20, 0x30, 0x2e, 0x30, 0x30, 0x30, 0x35,
0x2c, 0x20, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e, 0x79, 0x20, 0x2d, 0x20, 0x30, 0x2e, 0x30, 0x30, 0x30, 0x37, 0x29,
0x3b, 0x0d, 0x0a, 0x2f, 0x2f, 0x20, 0x20, 0x09, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x77, 0x5b, 0x33, 0x5d, 0x02, 0x40,
0x01, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, 0x65, 0x30, 0x2e, 0x30, 0x30, 0x30, 0x35, 0x2c, 0x20, 0x74, 0x65, 0x78, 0x43, 0x6f,
0x6f, 0x72, 0x64, 0x2e, 0x79, 0x29, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x2f, 0x2f, 0x20, 0x20, 0x09, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f,
0x72, 0x64, 0x77, 0x5b, 0x34, 0x5d, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x32, 0x28, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64,
0x2e, 0x78, 0x20, 0x2b, 0x20, 0x30, 0x2e, 0x30, 0x30, 0x30, 0x35, 0x2c, 0x20, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e,
0x79, 0x29, 0x3b, 0x0d, 0x0a, 0x2f, 0x2f, 0x20, 0x20, 0x09, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x77, 0x5b, 0x35, 0x5d,
0x02, 0x40, 0x01, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x03, 0xa8, 0x02, 0x00, 0x00, 0x30, 0x2e, 0x30, 0x30, 0x30, 0x35, 0x2c, 0x20,
0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e, 0x79, 0x20, 0x2b, 0x20, 0x30, 0x2e, 0x30, 0x30, 0x30, 0x37, 0x29, 0x3b, 0x0d,
0x0a, 0x2f, 0x2f, 0x20, 0x20, 0x09, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x77, 0x5b, 0x36, 0x5d, 0x20, 0x3d, 0x20, 0x76,
0x65, 0x63, 0x32, 0x28, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e, 0x78, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x2c, 0x20, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e, 0x79, 0x20, 0x2b, 0x20, 0x30, 0x2e, 0x30, 0x30, 0x30, 0x37,
0x29, 0x3b, 0x0d, 0x0a, 0x2f, 0x2f, 0x20, 0x20, 0x09, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x77, 0x5b, 0x37, 0x5d, 0x20,
0x3d, 0x20, 0x76, 0x65, 0x63, 0x32, 0x28, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e, 0x78, 0x20, 0x2b, 0x20, 0x30, 0x2e,
0x30, 0x30, 0x30, 0x35, 0x2c, 0x20, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e, 0x79, 0x20, 0x2b, 0x20, 0x30, 0x2e, 0x30,
0x30, 0x30, 0x37, 0x29, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x2f, 0x2f, 0x20, 0x20, 0x09, 0x66, 0x6f, 0x72, 0x28, 0x69, 0x20, 0x3d, 0x20,
0x30, 0x3b, 0x20, 0x69, 0x20, 0x3c, 0x20, 0x38, 0x3b, 0x20, 0x69, 0x2b, 0x2b, 0x29, 0x7b, 0x0d, 0x0a, 0x2f, 0x2f, 0x20, 0x20, 0x09,
0x09, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x78, 0x3b, 0x0d, 0x0a, 0x2f, 0x2f, 0x20, 0x20, 0x09, 0x09, 0x66, 0x6c, 0x6f, 0x61, 0x74,
0x20, 0x79, 0x3b, 0x0d, 0x0a, 0x2f, 0x2f, 0x20, 0x20, 0x09, 0x09, 0x69, 0x66, 0x28, 0x69, 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x20, 0x7c,
0x7c, 0x20, 0x69, 0x20, 0x3d, 0x3d, 0x20, 0x33, 0x20, 0x7c, 0x7c, 0x20, 0x69, 0x20, 0x3d, 0x3d, 0x20, 0x35, 0x29, 0x7b, 0x0d, 0x0a,
0x2f, 0x2f, 0x20, 0x20, 0x09, 0x09, 0x09, 0x78, 0x20, 0x3d, 0x20, 0x2d, 0x30, 0x2e, 0x30, 0x30, 0x30, 0x35, 0x3b, 0x20, 0x2f, 0x2f,
0x20, 0x28, 0x31, 0x2e, 0x30, 0x20, 0x2f, 0x20, 0x31, 0x30, 0x32, 0x34, 0x2e, 0x30, 0x20, 0x29, 0x20, 0x2f, 0x20, 0x32, 0x2e, 0x30,
0x0d, 0x0a, 0x2f, 0x2f, 0x20, 0x20, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x2f, 0x2f, 0x20, 0x20, 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x20,
0x69, 0x66, 0x28, 0x69, 0x20, 0x3d, 0x3d, 0x20, 0x32, 0x20, 0x7c, 0x7c, 0x20, 0x69, 0x20, 0x3d, 0x3d, 0x20, 0x34, 0x20, 0x7c, 0x7c,
0x20, 0x69, 0x20, 0x3d, 0x3d, 0x20, 0x37, 0x29, 0x7b, 0x0d, 0x0a, 0x2f, 0x2f, 0x20, 0x20, 0x09, 0x09, 0x09, 0x78, 0x20, 0x3d, 0x20,
0x30, 0x2e, 0x30, 0x30, 0x30, 0x35, 0x3b, 0x0d, 0x0a, 0x2f, 0x2f, 0x20, 0x20, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x2f, 0x2f, 0x20, 0x20,
0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x0d, 0x0a, 0x2f, 0x2f, 0x20, 0x20, 0x09, 0x09, 0x09, 0x78, 0x20, 0x3d, 0x20, 0x30, 0x2e,
0x30, 0x3b, 0x0d, 0x0a, 0x2f, 0x2f, 0x20, 0x20, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x2f, 0x2f, 0x20, 0x20, 0x09, 0x09, 0x69, 0x66, 0x28,
0x69, 0x20, 0x3e, 0x3d, 0x20, 0x32, 0x29, 0x7b, 0x0d, 0x0a, 0x2f, 0x2f, 0x20, 0x20, 0x09, 0x09, 0x09, 0x79, 0x20, 0x3d, 0x20, 0x2d,
0x30, 0x2e, 0x30, 0x30, 0x30, 0x37, 0x3b, 0x20, 0x2f, 0x2f, 0x20, 0x28, 0x31, 0x2e, 0x30, 0x20, 0x2f, 0x20, 0x37, 0x36, 0x38, 0x2e,
0x30, 0x20, 0x29, 0x20, 0x2f, 0x20, 0x32, 0x2e, 0x30, 0x0d, 0x0a, 0x2f, 0x2f, 0x20, 0x20, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x2f, 0x2f,
0x20, 0x20, 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x69, 0x20, 0x3e, 0x3d, 0x20, 0x35, 0x29, 0x7b, 0x0d, 0x0a,
0x2f, 0x2f, 0x20, 0x20, 0x09, 0x09, 0x09, 0x79, 0x20, 0x3d, 0x20, 0x30, 0x2e, 0x30, 0x3b, 0x0d, 0x0a, 0x2f, 0x2f, 0x20, 0x20, 0x09,
0x09, 0x7d, 0x0d, 0x0a, 0x2f, 0x2f, 0x20, 0x20, 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x0d, 0x0a, 0x2f, 0x2f, 0x20, 0x20, 0x09,
0x09, 0x09, 0x79, 0x20, 0x3d, 0x20, 0x30, 0x2e, 0x30, 0x30, 0x30, 0x37, 0x3b, 0x0d, 0x0a, 0x2f, 0x2f, 0x20, 0x20, 0x09, 0x09, 0x7d,
0x0d, 0x0a, 0x2f, 0x2f, 0x20, 0x20, 0x09, 0x09, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x77, 0x5b, 0x69, 0x5d, 0x2e, 0x73,
0x74, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x32, 0x28, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e, 0x78, 0x20, 0x2b, 0x20,
0x78, 0x2c, 0x20, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e, 0x79, 0x20, 0x2b, 0x20, 0x79, 0x29, 0x3b, 0x0d, 0x0a, 0x2f,
0x2f, 0x20, 0x20, 0x09, 0x7d, 0x0d, 0x0a, 0x2f, 0x2f, 0x20, 0x20, 0x7d, 0x02, 0xfd, 0x01, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00};
ShaderFilesToPatch axalShaderPatches[] = {
{axalFileName_0, axalPatchSize_0, axalPatchBuffer_0, 0, ""}, // a.frag
{axaFileName_1, axaPatchSize_1, axaPatchBuffer_1, 0, ""}, // average.frag
{axaFileName_2, axaPatchSize_2, axaPatchBuffer_2, 0, ""}, // average.vert
{axalFileName_1, axalPatchSize_1, axalPatchBuffer_1, 0, ""}, // DOF.vert
{axaFileName_4, axaPatchSize_4, axaPatchBuffer_4, 0, ""}, // GaussH.frag
{axaFileName_5, axaPatchSize_5, axaPatchBuffer_5, 0, ""}, // GaussH.vert
{axaFileName_6, axaPatchSize_6, axaPatchBuffer_6, 0, ""}, // GaussV.frag
{axaFileName_7, axaPatchSize_7, axaPatchBuffer_7, 0, ""}, // GaussV.frag
{axaFileName_8, axaPatchSize_8, axaPatchBuffer_8, 0, ""}, // GetBrightArea.frag
{axaFileName_9, axaPatchSize_9, axaPatchBuffer_9, 0, ""}, // GlareCompare.frag
{axalFileName_2, axalPatchSize_2, axalPatchBuffer_2, 0, ""}, // Laplacian.frag
{axaFileName_11, axaPatchSize_11, axaPatchBuffer_11, 0, ""}, // Laplacian.vert
{axaFileName_12, axaPatchSize_12, axaPatchBuffer_12, 0, ""}, // Monochrome.frag
{axaFileName_13, axaPatchSize_13, axaPatchBuffer_13, 0, ""}, // Monochrome.vert
{axaFileName_15, axaPatchSize_15, axaPatchBuffer_15, 0, ""}, // Posterization.frag
{axaFileName_16, axaPatchSize_16, axaPatchBuffer_16, 0, ""}, // Sepia.frag
{axaFileName_17, axaPatchSize_17, axaPatchBuffer_17, 0, ""}, // Solarization.frag
{axalFileName_3, axalPatchSize_3, axalPatchBuffer_3, 0, ""}, // toon.frag
{axalFileName_4, axalPatchSize_4, axalPatchBuffer_4, 0, ""}, // toon.vert
{axaFileName_19, axaPatchSize_19, axaPatchBuffer_19, 0, ""}, // YUVCompose.frag
};
int axalShaderPatchesCount = sizeof(axalShaderPatches) / sizeof(ShaderFilesToPatch);
+8
View File
@@ -0,0 +1,8 @@
#include <sys/types.h>
#include "common.h"
extern ShaderFilesToPatch axaShaderPatches[];
extern int axaShaderPatchesCount;
extern ShaderFilesToPatch axalShaderPatches[];
extern int axalShaderPatchesCount;
+41
View File
@@ -0,0 +1,41 @@
#pragma once
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include "../shaderPatches.h"
typedef struct
{
uint32_t startOffset; // Offset inside the ELF
uint32_t totalSize; // Available size for the shader program
uint32_t sizeOfCode; // Size used by the original shader program
} ElfShaderOffsets;
typedef struct
{
char *fileName;
size_t shaderBufferSize;
char *shaderBuffer;
} ShaderFilesToMod;
typedef struct
{
const char *fileName;
size_t patchBufferSize;
const unsigned char *patchBuffer;
size_t shaderBufferSize;
const char *shaderBuffer;
} ShaderFilesToPatch;
typedef struct
{
const char *stageAbb;
const char *StageName;
bool patch;
} Vf5StagesList;
extern SearchReplace attribsSet[];
extern int attribsSetCount;
extern char *nnstdshader_vert;
extern char *nnstdshader_frag;
+14
View File
@@ -0,0 +1,14 @@
#pragma once
#include "common.h"
extern ElfShaderOffsets gsevoElfShaderOffsets[];
extern int gsevoShaderOffsetsCount;
extern SearchReplace gsevoElf[];
extern int gsevoElfCount;
extern SearchReplace gsevoElfMesa[];
extern int gsevoElfCountMesa;
extern SearchReplace gsevoSet1[];
extern int gsevoSetCount1;
extern ShaderFilesToPatch gsevoMesaShaderPatches[];
extern ShaderFilesToPatch gsevoNvidiaShaderPatches[];
extern int gsevoShaderPatchesCount;
+4
View File
@@ -0,0 +1,4 @@
#include "common.h"
extern ShaderFilesToPatch harleyShaderPatches[];
extern int harleyShaderPatchesCount;

Some files were not shown because too many files have changed in this diff Show More