diff --git a/.clang-format b/.clang-format index 0237ae7..2b56939 100644 --- a/.clang-format +++ b/.clang-format @@ -129,7 +129,7 @@ IncludeIsMainRegex: '(Test)?$' IncludeIsMainSourceRegex: '' IndentAccessModifiers: false IndentCaseBlocks: false -IndentCaseLabels: false +IndentCaseLabels: true IndentExternBlock: AfterExternBlock IndentGotoLabels: true IndentPPDirectives: None diff --git a/.github/workflows/appimage-build.yml b/.github/workflows/appimage-build.yml index a4b46a5..b8389b7 100644 --- a/.github/workflows/appimage-build.yml +++ b/.github/workflows/appimage-build.yml @@ -21,6 +21,12 @@ jobs: - name: Install Packages run: scripts/appimage/install-packages.sh + - name: Pack ID Libs + run: scripts/appimage/id-libs.sh + + - name: Install Kisak + run: scripts/appimage/install-kisak.sh + - name: Build Deps run: scripts/appimage/build-deps.sh @@ -42,7 +48,8 @@ jobs: - name: Upload SDL3 and FAudio uses: actions/upload-artifact@v4 with: - name: SDL3-FAudio + name: SDL3-FAudio-ID path: | libs/libs.tar libs/includes.tar + libs/lib32ID.tar diff --git a/.github/workflows/flatpak-build.yml b/.github/workflows/flatpak-build.yml index e2d4735..70b4795 100644 --- a/.github/workflows/flatpak-build.yml +++ b/.github/workflows/flatpak-build.yml @@ -26,7 +26,7 @@ jobs: - name: Download SDL3 libs uses: actions/download-artifact@v4 with: - name: SDL3-FAudio + name: SDL3-FAudio-ID path: libs/ # Work around container ownership issue diff --git a/.github/workflows/linux-build.yml b/.github/workflows/linux-build.yml index cfdbd47..eb9ff4a 100644 --- a/.github/workflows/linux-build.yml +++ b/.github/workflows/linux-build.yml @@ -20,7 +20,7 @@ jobs: - name: Download SDL3 libs uses: actions/download-artifact@v4 with: - name: SDL3-FAudio + name: SDL3-FAudio-ID path: libs/ # Set up Docker Buildx diff --git a/docs/changelog b/docs/changelog index 5ee2b90..228fe37 100644 --- a/docs/changelog +++ b/docs/changelog @@ -2,6 +2,22 @@ All notable changes to this project will be documented in this file. +## [2.1.1] +### Added + - Zink support in appimage (fixes Zink in the Steam Deck). + - Change the Mesa version on the fly to fix ID games rendering issues in the appimage. +### Fixed + - A typo in the command to load custom gamecontrollerdb (--controllerdb) to match the guide. + - Disable SDL input when EvDev is selected. + - A fix to make the Maximize window button show. +### Missing from las changelog + - Harley network link support (up to 4 players) + - R-Tuned network link support (up to 4 players) + - Hummer network link support (up to 4 players) + - 2 Spicy network link support (up to 2 players) + - Sega Race TV network link support (up to 4 players) + - ID4 and ID5 network link support (up to 2 players) + ## [2.1.0] ### Added - Rambo DVP-0078 (China version) support. diff --git a/libs/lib32ID.tar b/libs/lib32ID.tar new file mode 100644 index 0000000..483101a Binary files /dev/null and b/libs/lib32ID.tar differ diff --git a/scripts/appimage/id-libs.sh b/scripts/appimage/id-libs.sh new file mode 100755 index 0000000..9615b33 --- /dev/null +++ b/scripts/appimage/id-libs.sh @@ -0,0 +1,64 @@ +#!/bin/bash + +PACKAGES=( + "libdrm-amdgpu1:i386" + "libdrm-intel1:i386" + "libdrm-nouveau2:i386" + "libdrm-radeon1:i386" + "libgl1-mesa-dri:i386" + "libglx-mesa0:i386" +) + +COMPRESSION_TARGET_PATH="ext/usr/lib/i386-linux-gnu" + +cd libs + +rm -rf deb_files +mkdir -p deb_files +cd deb_files + +apt-get download "${PACKAGES[@]}" + +mkdir -p ext +for deb_file in *.deb; do + dpkg-deb -x "$deb_file" ext +done + +rm ext/usr/lib/i386-linux-gnu/dri/i915_dri.so +ln -s -f crocus_dri.so ext/usr/lib/i386-linux-gnu/dri/i915_dri.so +rm ext/usr/lib/i386-linux-gnu/dri/iris_dri.so +ln -s -f crocus_dri.so ext/usr/lib/i386-linux-gnu/dri/iris_dri.so +rm ext/usr/lib/i386-linux-gnu/dri/kms_swrast_dri.so +ln -s -f crocus_dri.so ext/usr/lib/i386-linux-gnu/dri/kms_swrast_dri.so +rm ext/usr/lib/i386-linux-gnu/dri/nouveau_dri.so +ln -s -f crocus_dri.so ext/usr/lib/i386-linux-gnu/dri/nouveau_dri.so +rm ext/usr/lib/i386-linux-gnu/dri/r300_dri.so +ln -s -f crocus_dri.so ext/usr/lib/i386-linux-gnu/dri/r300_dri.so +rm ext/usr/lib/i386-linux-gnu/dri/r600_dri.so +ln -s -f crocus_dri.so ext/usr/lib/i386-linux-gnu/dri/r600_dri.so +rm ext/usr/lib/i386-linux-gnu/dri/radeonsi_dri.so +ln -s -f crocus_dri.so ext/usr/lib/i386-linux-gnu/dri/radeonsi_dri.so +rm ext/usr/lib/i386-linux-gnu/dri/swrast_dri.so +ln -s -f crocus_dri.so ext/usr/lib/i386-linux-gnu/dri/swrast_dri.so +rm ext/usr/lib/i386-linux-gnu/dri/virtio_gpu_dri.so +ln -s -f crocus_dri.so ext/usr/lib/i386-linux-gnu/dri/virtio_gpu_dri.so +rm ext/usr/lib/i386-linux-gnu/dri/vmwgfx_dri.so +ln -s -f crocus_dri.so ext/usr/lib/i386-linux-gnu/dri/vmwgfx_dri.so +rm ext/usr/lib/i386-linux-gnu/dri/zink_dri.so +ln -s -f crocus_dri.so ext/usr/lib/i386-linux-gnu/dri/zink_dri.so + + + + +# cp -d /usr/lib/i386-linux-gnu/libedit.so* ext/usr/lib/i386-linux-gnu +# cp -d /usr/lib/i386-linux-gnu/libglapi.so* ext/usr/lib/i386-linux-gnu +# cp -d /usr/lib/i386-linux-gnu/libLLVM-15.so* ext/usr/lib/i386-linux-gnu +# cp -d /usr/lib/i386-linux-gnu/libsensors.so* ext/usr/lib/i386-linux-gnu + +tar -cf lib32ID.tar -C "$COMPRESSION_TARGET_PATH" . + +mv lib32ID.tar ../ + +cd .. + +rm -rf deb_files diff --git a/scripts/appimage/install-kisak.sh b/scripts/appimage/install-kisak.sh new file mode 100755 index 0000000..433682e --- /dev/null +++ b/scripts/appimage/install-kisak.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +sudo add-apt-repository ppa:kisak/turtle -y +sudo apt update -y && sudo apt upgrade -y \ No newline at end of file diff --git a/scripts/appimage/install-packages.sh b/scripts/appimage/install-packages.sh index e73b5b1..e48b83e 100755 --- a/scripts/appimage/install-packages.sh +++ b/scripts/appimage/install-packages.sh @@ -2,12 +2,10 @@ echo "Install Packages Running..." sudo dpkg --add-architecture i386 -sudo apt update +sudo apt update # && sudo apt upgrade -y sudo apt -y install --no-install-recommends \ 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/turtle -y -sudo apt update -y && sudo apt upgrade -y \ No newline at end of file + libudev-dev:i386 libxcursor-dev:i386 libxfixes-dev:i386 libxi-dev:i386 libxrandr-dev:i386 libxss-dev:i386 libxxf86vm-dev:i386 git libvulkan1:i386 \ + mesa-vulkan-drivers:i386 diff --git a/scripts/appimage/make-appimage.sh b/scripts/appimage/make-appimage.sh index dafa384..c5758e9 100755 --- a/scripts/appimage/make-appimage.sh +++ b/scripts/appimage/make-appimage.sh @@ -4,6 +4,7 @@ APPIMAGENAME=lindbergh-loader APPIMAGEDIRNAME=lindbergh-loader.AppDir declare -a ADDED_LIBS=( + "libasound.so.2" "libfreetype.so.6" "libOpenGL.so.0" "libGLdispatch.so.0" @@ -35,6 +36,15 @@ declare -a ADDED_LIBS=( "libstdc++.so.6" "libudev.so.1" "libsndio.so.7" + "libvulkan.so.1" + "libVkLayer_INTEL_nullhw.so" + "libVkLayer_MESA_device_select.so" + "libVkLayer_MESA_overlay.so" + "libvulkan_intel_hasvk.so" + "libvulkan_intel.so" + "libvulkan_lvp.so" + "libvulkan_radeon.so" + "libvulkan_virtio.so" ) set -e @@ -63,13 +73,18 @@ ADDED_LIBS_ARGS+=("--library=/usr/lib/i386-linux-gnu/pulseaudio/libpulsedsp.so") echo "Copying files into AppDir..." mkdir -p "$OUTPUT_FOLDER/usr/bin" mkdir -p "$OUTPUT_FOLDER/usr/lib" -mkdir -p "$OUTPUT_FOLDER/usr/lib32" +mkdir -p "$OUTPUT_FOLDER/usr/lib32/dri" +mkdir -p "$OUTPUT_FOLDER/usr/lib32ID" +mkdir -p "$OUTPUT_FOLDER/usr/share/vulkan/icd.d" + # We create the AppRun file cat > "$OUTPUT_FOLDER/AppRun" << 'EOF' #!/bin/bash APP_IMG_ROOT="$(dirname "$(readlink -f "$0")")" export APP_IMG_ROOT=$APP_IMG_ROOT +VK="/$APP_IMG_ROOT/usr/share/vulkan/icd.d" +export VK_ICD_FILENAMES="$VK/intel_hasvk_icd.i686.json:$VK/intel_icd.i686.json:$VK/lvp_icd.i686.json:$VK/radeon_icd.i686.json:$VK/virtio_icd.i686.json" export LD_LIBRARY_PATH="$APP_IMG_ROOT/usr/lib32:$LD_LIBRARY_PATH" exec "$APP_IMG_ROOT/usr/bin/lindbergh" "$@" EOF @@ -82,7 +97,11 @@ cp lindbergh.so $OUTPUT_FOLDER/usr/lib cp libposixtime.so $OUTPUT_FOLDER/usr/lib 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 +cp /usr/lib/i386-linux-gnu/dri/libdril_dri.so $OUTPUT_FOLDER/usr/lib/dri/libdril_dri.so +cp /usr/share/vulkan/icd.d/* $OUTPUT_FOLDER/usr/share/vulkan/icd.d +for file in $OUTPUT_FOLDER/usr/share/vulkan/icd.d/*; do + sed -i 's|/usr/lib/i386-linux-gnu/||' "$file" +done cd .. echo "Running linuxdeploy to create AppDir..." @@ -94,18 +113,33 @@ mv $OUTPUT_FOLDER/usr/lib/libkswapapi.so $OUTPUT_FOLDER/usr/lib32 mv $OUTPUT_FOLDER/usr/lib/libsegaapi.so $OUTPUT_FOLDER/usr/lib32 mv $OUTPUT_FOLDER/usr/lib/lindbergh.so $OUTPUT_FOLDER/usr/lib32 mv $OUTPUT_FOLDER/usr/lib/libposixtime.so $OUTPUT_FOLDER/usr/lib32 -mv $OUTPUT_FOLDER/usr/lib/dri $OUTPUT_FOLDER/usr/lib32 +mv $OUTPUT_FOLDER/usr/lib/dri $OUTPUT_FOLDER/usr/lib32/ +ln -s -f libdril_dri.so $OUTPUT_FOLDER/usr/lib32/dri/crocus_dri.so +ln -s -f libdril_dri.so $OUTPUT_FOLDER/usr/lib32/dri/i915_dri.so +ln -s -f libdril_dri.so $OUTPUT_FOLDER/usr/lib32/dri/iris_dri.so +ln -s -f libdril_dri.so $OUTPUT_FOLDER/usr/lib32/dri/kms_swrast_dri.so +ln -s -f libdril_dri.so $OUTPUT_FOLDER/usr/lib32/dri/nouveau_dri.so +ln -s -f libdril_dri.so $OUTPUT_FOLDER/usr/lib32/dri/r300_dri.so +ln -s -f libdril_dri.so $OUTPUT_FOLDER/usr/lib32/dri/r600_dri.so +ln -s -f libdril_dri.so $OUTPUT_FOLDER/usr/lib32/dri/radeonsi_dri.so +ln -s -f libdril_dri.so $OUTPUT_FOLDER/usr/lib32/dri/swrast_dri.so +ln -s -f libdril_dri.so $OUTPUT_FOLDER/usr/lib32/dri/virtio_gpu_dri.so +ln -s -f libdril_dri.so $OUTPUT_FOLDER/usr/lib32/dri/vmwgfx_dri.so +ln -s -f libdril_dri.so $OUTPUT_FOLDER/usr/lib32/dri/zink_dri.so + unzip libs/Cg-3.1.zip -d $OUTPUT_FOLDER/usr/lib32 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 +tar -xf libs/lib32ID.tar -C $OUTPUT_FOLDER/usr/lib32ID 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 +rm -rf $OUTPUT_FOLDER/usr/share/doc echo "Generating AppImage..." rm -f "$APPIMAGENAME.AppImage" diff --git a/scripts/flatpak/.gitignore b/scripts/flatpak/.gitignore index 60b1a16..32e56d7 100644 --- a/scripts/flatpak/.gitignore +++ b/scripts/flatpak/.gitignore @@ -1,4 +1,5 @@ .flatpak-builder/ build/ repo/ +assets/lib32ID *.flatpak diff --git a/scripts/flatpak/com.github.lindberghloader.yml b/scripts/flatpak/com.github.lindberghloader.yml index c35ea5a..89a3f83 100644 --- a/scripts/flatpak/com.github.lindberghloader.yml +++ b/scripts/flatpak/com.github.lindberghloader.yml @@ -37,19 +37,18 @@ add-extensions: org.freedesktop.Platform.Compat.i386: directory: lib/i386-linux-gnu version: *runtime-version - no-autodownload: true org.freedesktop.Platform.Compat.i386.Debug: directory: lib/debug/lib/i386-linux-gnu version: *runtime-version - no-autodownload: true + # no-autodownload: true org.freedesktop.Platform.GL32: directory: lib/i386-linux-gnu/GL version: *gl-version versions: *gl-versions subdirectories: true - no-autodownload: true + # no-autodownload: true autodelete: false add-ld-path: lib merge-dirs: *gl-merge-dirs @@ -61,8 +60,8 @@ add-extensions: directory: lib/debug/lib/i386-linux-gnu/GL version: *gl-version versions: *gl-versions - subdirectories: true - no-autodownload: true + # subdirectories: true + # no-autodownload: true merge-dirs: *gl-merge-dirs enable-if: active-gl-driver autoprune-unless: active-gl-driver @@ -77,7 +76,7 @@ modules: - type: file path: ./assets/libstdc++.so.5 - - name: SDL3-FAudio + - name: SDL3-FAudio-ID buildsystem: simple build-commands: - tar -xf libs/libs.tar -C /app/lib32 @@ -105,10 +104,11 @@ modules: config-opts: - -DCMAKE_BUILD_TYPE=Release - -DCMAKE_INSTALL_PREFIX=/app + - -DCMAKE_POLICY_VERSION_MINIMUM=3.5 sources: - - type: archive - url: https://downloads.sourceforge.net/freeglut/freeglut-3.2.2.tar.gz - sha256: c5944a082df0bba96b5756dddb1f75d0cd72ce27b5395c6c1dde85c2ff297a50 + - type: git + url: https://github.com/freeglut/freeglut.git + branch: master build-options: arch: x86_64: *i386-build-options @@ -151,11 +151,8 @@ modules: url: https://xorg.freedesktop.org/releases/individual/lib/libXmu-1.2.1.tar.gz sha256: bf0902583dd1123856c11e0a5085bd3c6e9886fbbd44954464975fd7d52eb599 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 + arch: + x86_64: *i386-build-options - name: libmd buildsystem: autotools @@ -181,25 +178,6 @@ modules: arch: x86_64: *i386-build-options - - name: ncurses - buildsystem: autotools - config-opts: - - --libdir=/app/lib32 - - --with-shared - - --without-debug - sources: - - type: archive - url: https://invisible-island.net/archives/ncurses/ncurses-5.9.tar.gz - sha256: 9046298fb440324c9d4135ecea7879ffed8546dd1b58e59430ea07a4633f563b - - type: patch - path: ./assets/ncurses-5.9.patch - build-options: - arch: - x86_64: *i386-build-options - env: - CPPFLAGS: "-P" - CXXFLAGS: "-std=c++14" - - name: nvidia-cg-toolkit buildsystem: simple build-commands: @@ -230,6 +208,24 @@ modules: url: https://pcsclite.apdu.fr/files/pcsc-lite-2.3.1.tar.xz sha256: a641d44d57affe1edd8365dd75307afc307e7eefb4e7ad839f6f146baa41ed56 + # Build 32-bit libFAudio (static) + - name: libFAudio-Static + buildsystem: cmake-ninja + config-opts: + - -DBUILD_SHARED_LIBS=off + - -DCMAKE_INSTALL_PREFIX=/app + - -DCMAKE_INSTALL_LIBDIR=/app/lib32 + build-options: + arch: + x86_64: *i386-build-options + env: + CFLAGS: "-m32 -mstackrealign" + CXXFLAGS: "-m32 -mstackrealign" + sources: + - type: git + url: https://github.com/FNA-XNA/FAudio.git + branch: master + - name: lindbergh-loader buildsystem: simple build-commands: @@ -251,6 +247,7 @@ modules: - 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 + - ln -s -f /usr/lib/i386-linux-gnu/libncurses.so /app/lib32/libncurses.so.5 build-options: arch: x86_64: *i386-build-options @@ -274,10 +271,6 @@ modules: - find /app/lib /app/lib32 -name '*.a' -type f -delete - find /app/lib /app/lib32 -name '*.la' -type f -delete - find /app/bin -mindepth 1 ! -name "lindbergh*" -exec rm -f {} \; - - rm -d /app/lib/terminfo - rm -rf /app/lib/pkgconfig /app/lib32/pkgconfig /app/share/pkgconfig /app/lib32/cmake /app/lib/debug /app/include /app/man /app/share - - rm /app/lib32/libmenu.* - - rm /app/lib32/libform.* - - rm /app/lib32/libpanel.* - rm /app/lib32/libXmuu.* - rm /app/lib32/libbsd.so diff --git a/src/lindbergh/baseBoard.c b/src/lindbergh/baseBoard.c index 8c58833..168774c 100644 --- a/src/lindbergh/baseBoard.c +++ b/src/lindbergh/baseBoard.c @@ -88,21 +88,24 @@ int initBaseboard() strcpy(serialString, SERIAL_STRING); - time_t t = time(NULL); // Get current time - struct tm *tm_info = localtime(&t); // Convert to local time structure + time_t t = time(NULL); // Get current time + struct tm *tm_info = localtime(&t); // Convert to local time structure int month = tm_info->tm_mon + 1; // tm_mon is 0-based (0 = Jan, 4 = May) int day = tm_info->tm_mday; // tm_mday is the day of the month - if (month == 1 && day == 18) { + if (month == 1 && day == 18) + { strcpy(serialString, "HAPPY BIRTHDAY!!"); } - if (month == 5 && day == 20) { + if (month == 5 && day == 20) + { strcpy(serialString, "HAPPY BIRTHDAY!!"); } - if (month == 5 && day == 21) { + if (month == 5 && day == 21) + { strcpy(serialString, "HAPPY BIRTHDAY!!"); } @@ -132,171 +135,171 @@ int baseboardIoctl(int fd, unsigned long request, void *data) switch (request) { - case BASEBOARD_GET_VERSION: - { - uint8_t versionData[4] = {0x00, 0x19, 0x20, 0x07}; - memcpy(data, versionData, 4); - return 0; - } - break; - - case BASEBOARD_INIT: - { - // selectReply = -1; Considering adding this in - return 0; - } - break; - - case BASEBOARD_READY: // Not sure if this is what it should be called - { - selectReply = 0; - return 0; - } - break; - - case BASEBOARD_SEEK_SHM: - { - sharedMemoryIndex = (size_t)data; - return 0; - } - break; - - case BASEBOARD_READ_SRAM: - { - readData_t *_data = data; - fseek(sram, _data->offset, SEEK_SET); - fread(_data->data, 1, _data->size, sram); - return 0; - } - break; - - case BASEBOARD_WRITE_SRAM: - { - writeData_t *_data = data; - fseek(sram, _data->offset, SEEK_SET); - fwrite(_data->data, 1, _data->size, sram); - return 0; - } - break; - - case BASEBOARD_REQUEST: - { - uint32_t *_data = data; - - switch (_data[0]) + case BASEBOARD_GET_VERSION: { - - case BASEBOARD_GET_SERIAL: // bcCmdSysInfoGetReq - { - serialCommand.destAddress = _data[1]; - serialCommand.destSize = _data[2]; + uint8_t versionData[4] = {0x00, 0x19, 0x20, 0x07}; + memcpy(data, versionData, 4); + return 0; } break; - case BASEBOARD_WRITE_FLASH: // bcCmdSysFlashWrite + case BASEBOARD_INIT: { - log_warn("The game attempted to write to the baseboard flash\n"); + // selectReply = -1; Considering adding this in + return 0; } break; - case BASEBOARD_PROCESS_JVS: + case BASEBOARD_READY: // Not sure if this is what it should be called { - jvsCommand.srcAddress = _data[1]; - jvsCommand.srcSize = _data[2]; - jvsCommand.destAddress = _data[3]; - jvsCommand.destSize = _data[4]; - memcpy(inputBuffer, &sharedMemory[jvsCommand.srcAddress], jvsCommand.srcSize); + selectReply = 0; + return 0; + } + break; - if (getConfig()->emulateJVS) + case BASEBOARD_SEEK_SHM: + { + sharedMemoryIndex = (size_t)data; + return 0; + } + break; + + case BASEBOARD_READ_SRAM: + { + readData_t *_data = data; + fseek(sram, _data->offset, SEEK_SET); + fread(_data->data, 1, _data->size, sram); + return 0; + } + break; + + case BASEBOARD_WRITE_SRAM: + { + writeData_t *_data = data; + fseek(sram, _data->offset, SEEK_SET); + fwrite(_data->data, 1, _data->size, sram); + return 0; + } + break; + + case BASEBOARD_REQUEST: + { + uint32_t *_data = data; + + switch (_data[0]) { - processPacket(&jvsPacketSize); - } - else if (jvsFileDescriptor >= 0) - { - for (int i = 0; i < jvsCommand.srcSize; i++) + + case BASEBOARD_GET_SERIAL: // bcCmdSysInfoGetReq { - write(jvsFileDescriptor, &inputBuffer[i], 1); - if (inputBuffer[i] == 0xF0) + serialCommand.destAddress = _data[1]; + serialCommand.destSize = _data[2]; + } + break; + + case BASEBOARD_WRITE_FLASH: // bcCmdSysFlashWrite + { + log_warn("The game attempted to write to the baseboard flash\n"); + } + break; + + case BASEBOARD_PROCESS_JVS: + { + jvsCommand.srcAddress = _data[1]; + jvsCommand.srcSize = _data[2]; + jvsCommand.destAddress = _data[3]; + jvsCommand.destSize = _data[4]; + memcpy(inputBuffer, &sharedMemory[jvsCommand.srcAddress], jvsCommand.srcSize); + + if (getConfig()->emulateJVS) { - setSenseLine(3); + processPacket(&jvsPacketSize); } - else if (inputBuffer[i] == 0xF1) + else if (jvsFileDescriptor >= 0) { - setSenseLine(1); + for (int i = 0; i < jvsCommand.srcSize; i++) + { + write(jvsFileDescriptor, &inputBuffer[i], 1); + if (inputBuffer[i] == 0xF0) + { + setSenseLine(3); + } + else if (inputBuffer[i] == 0xF1) + { + setSenseLine(1); + } + } } } + break; + + case BASEBOARD_GET_SENSE_LINE: + break; + + default: + printf("Error: Unknown baseboard command %X\n", _data[0]); } + + // Acknowledge the command + _data[0] |= 0xF0000000; + + return 0; } break; - case BASEBOARD_GET_SENSE_LINE: - break; - - default: - printf("Error: Unknown baseboard command %X\n", _data[0]); - } - - // Acknowledge the command - _data[0] |= 0xF0000000; - - return 0; - } - break; - - case BASEBOARD_RECEIVE: - { - uint32_t *_data = data; - - switch (_data[0] & 0xFFF) + case BASEBOARD_RECEIVE: { + uint32_t *_data = data; - case BASEBOARD_GET_SERIAL: - { - memcpy(&sharedMemory[serialCommand.destAddress + 96], serialString, strlen(serialString)); - _data[1] = 1; // Set the status to success - } - break; - - case BASEBOARD_GET_SENSE_LINE: - { - _data[2] = getSenseLine(); - _data[1] = 1; // Set the status to success - } - break; - - case BASEBOARD_PROCESS_JVS: - { - if (getConfig()->emulateJVS) + switch (_data[0] & 0xFFF) { - memcpy(&sharedMemory[jvsCommand.destAddress], outputBuffer, jvsPacketSize); - _data[2] = jvsCommand.destAddress; - _data[3] = jvsPacketSize; - _data[1] = 1; // Set the status to success - } - else if (jvsFileDescriptor >= 0) - { - JVSFrame frame = readJVSFrameFromThread(); - memcpy(&sharedMemory[jvsCommand.destAddress], frame.buffer, frame.size); - _data[2] = jvsCommand.destAddress; - _data[3] = frame.size; - _data[1] = frame.ready; + + case BASEBOARD_GET_SERIAL: + { + memcpy(&sharedMemory[serialCommand.destAddress + 96], serialString, strlen(serialString)); + _data[1] = 1; // Set the status to success + } + break; + + case BASEBOARD_GET_SENSE_LINE: + { + _data[2] = getSenseLine(); + _data[1] = 1; // Set the status to success + } + break; + + case BASEBOARD_PROCESS_JVS: + { + if (getConfig()->emulateJVS) + { + memcpy(&sharedMemory[jvsCommand.destAddress], outputBuffer, jvsPacketSize); + _data[2] = jvsCommand.destAddress; + _data[3] = jvsPacketSize; + _data[1] = 1; // Set the status to success + } + else if (jvsFileDescriptor >= 0) + { + JVSFrame frame = readJVSFrameFromThread(); + memcpy(&sharedMemory[jvsCommand.destAddress], frame.buffer, frame.size); + _data[2] = jvsCommand.destAddress; + _data[3] = frame.size; + _data[1] = frame.ready; + } + } + break; + + default: + printf("Error: Unknown baseboard receive command %X\n", _data[0] & 0xFFF); } + + // Acknowledge the command + _data[0] |= 0xF0000000; + + return 0; } break; default: - printf("Error: Unknown baseboard receive command %X\n", _data[0] & 0xFFF); - } - - // Acknowledge the command - _data[0] |= 0xF0000000; - - return 0; - } - break; - - default: - printf("Error: Unknown baseboard ioctl %lX\n", request); + printf("Error: Unknown baseboard ioctl %lX\n", request); } return 0; diff --git a/src/lindbergh/glutHooks.c b/src/lindbergh/glutHooks.c index 3194873..7a31f7c 100644 --- a/src/lindbergh/glutHooks.c +++ b/src/lindbergh/glutHooks.c @@ -26,7 +26,7 @@ extern SDL_Window *sdlWindow; extern Display *x11Display; extern char sdlGameTitle[]; extern char current_text[256]; -extern double local_fps; +extern double localFps; bool winHidden = true; void *displayFunc = NULL; diff --git a/src/lindbergh/glxHooks.c b/src/lindbergh/glxHooks.c index 416f6fe..63ce801 100644 --- a/src/lindbergh/glxHooks.c +++ b/src/lindbergh/glxHooks.c @@ -25,7 +25,7 @@ extern SDL_Window *sdlWindow; extern SDL_GLContext sdlContext; extern Display *x11Display; extern char sdlGameTitle[]; -double local_fps = 0.0; +double localFps = 0.0; bool createContextCalled = false; int ctxCnt = 0; @@ -49,8 +49,8 @@ void glXSwapBuffers(Display *dpy, GLXDrawable drawable) frameTiming(); char windowTitle[512]; - local_fps = calculateFps(); - sprintf(windowTitle, "%s - FPS: %.2f", sdlGameTitle, local_fps); + localFps = calculateFps(); + sprintf(windowTitle, "%s - FPS: %.2f", sdlGameTitle, localFps); SDL_SetWindowTitle(sdlWindow, windowTitle); } diff --git a/src/lindbergh/lindbergh.c b/src/lindbergh/lindbergh.c index 8c84f9d..9a1b1c5 100644 --- a/src/lindbergh/lindbergh.c +++ b/src/lindbergh/lindbergh.c @@ -8,6 +8,7 @@ #include #include +#include "config.h" #include "configIni.h" #include "evdevInput.h" #include "log.h" @@ -122,6 +123,34 @@ uint32_t cleanElfCRC32[] = { int cleanElfCRC32Count = sizeof(cleanElfCRC32) / sizeof(uint32_t); +bool isIDGame() +{ + switch (elf_crc) + { + case 0x22905D60: // DVP-0019A | id4.elf + case 0x43582D48: // DVP-0019B | id4.elf + case 0x2D2A18C1: // DVP-0019C | id4.elf + case 0x9BFD0D98: // DVP-0019D | id4.elf + case 0x9CF9BBCC: // DVP-0019G | id4.elf + case 0xC345E213: // DVP-0030B | id4.elf + case 0x98E6A516: // DVP-0030C | id4.elf + case 0xF67365C9: // DVP-0030D | id4.elf + case 0xE4F202BB: // DVP-0070A | id5.elf + case 0x400C09CD: // DVP-0070C | id5.elf + case 0x2E6732A3: // DVP-0070F | id5.elf + case 0xF99A3CDB: // DVP-0075 | id5.elf + case 0x8DF6BBF9: // DVP-0084 | id5.elf + case 0x2AF8004E: // DVP-0084A | id5.elf + { + return true; + } + default: + { + return false; + } + } +} + uint32_t calcCrc32(uint32_t crc, uint8_t data) { crc ^= data; @@ -204,12 +233,11 @@ void isCleanElf(char *command) exit(EXIT_FAILURE); } - uint32_t crc; - if (calculateCRC32inChunks(elfName, &crc) != 0) + if (calculateCRC32inChunks(elfName, &elf_crc) != 0) return; - crc = crc ^ 0xFFFFFFFF; - if (!lookupCrcTable(crc)) + elf_crc = elf_crc ^ 0xFFFFFFFF; + if (!lookupCrcTable(elf_crc)) { printf("\033[1;31m"); printf("Warning: The ELF you are running is not Clean and might cause unwanted behavior.\n"); @@ -305,11 +333,19 @@ void setEnvironmentVariables(const char *ldLibPath, const char *originalDir, con char *currentLibraryPath = getenv("LD_LIBRARY_PATH"); char newLdLibPath[MAX_PATH_LENGTH * 3] = ""; - if (currentLibraryPath && strlen(currentLibraryPath) > 0) - snprintf(newLdLibPath, sizeof(newLdLibPath), "%s:", currentLibraryPath); + char *appImgRoot = getenv("APP_IMG_ROOT"); + if (getenv("APP_IMG_ROOT") && isIDGame()) // If appimage and ID game. + { + strcat(newLdLibPath, appImgRoot); + strcat(newLdLibPath, "/usr/lib32ID:"); + strcat(newLdLibPath, currentLibraryPath); + } + else if (currentLibraryPath && strlen(currentLibraryPath) > 0) + { + snprintf(newLdLibPath, sizeof(newLdLibPath), "%s", currentLibraryPath); + } char *tmpLibPath = dirname(strdup(ldLibPath)); - if (strcmp(tmpLibPath, ".") != 0) { strcat(newLdLibPath, ":"); @@ -343,7 +379,7 @@ void setEnvironmentVariables(const char *ldLibPath, const char *originalDir, con log_error("The loader will use the default configuration."); confFilePath = ""; } - else if(!fileExists(confFilePath)) + else if (!fileExists(confFilePath)) { log_error("The file \'%s\' does not exist, will be using default config.", confFilePath); confFilePath = ""; @@ -395,6 +431,7 @@ void setEnvironmentVariables(const char *ldLibPath, const char *originalDir, con if (zink) { + setenv("LIBGL_KOPPER_DRI2", "1", 1); setenv("MESA_LOADER_DRIVER_OVERRIDE", "zink", 1); } @@ -404,13 +441,17 @@ void setEnvironmentVariables(const char *ldLibPath, const char *originalDir, con setenv("__NV_PRIME_RENDER_OFFLOAD", "1", 1); } - char *appImgRoot = getenv("APP_IMG_ROOT"); + char libglDriPath[MAX_PATH_LENGTH] = {0}; if (appImgRoot != NULL) { - char libglDriPath[MAX_PATH_LENGTH]; - sprintf(libglDriPath, "%s/usr/lib32/dri", appImgRoot); - setenv("LIBGL_DRIVERS_PATH", libglDriPath, 1); + if (isIDGame()) + snprintf(libglDriPath, sizeof(libglDriPath), "%s/usr/lib32ID/dri", appImgRoot); + else + snprintf(libglDriPath, sizeof(libglDriPath), "%s/usr/lib32/dri", appImgRoot); } + + if (libglDriPath[0] != '\0') + setenv("LIBGL_DRIVERS_PATH", libglDriPath, 1); } void printUsage(char *programName) @@ -428,7 +469,7 @@ void printUsage(char *programName) 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(" --controllerdb | -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"); } @@ -514,7 +555,7 @@ int main(int argc, char *argv[]) { return listSdlControllers(); } - + if (argc > 1 && (strcmp(argv[1], "--create") == 0 || strcmp(argv[1], "-C") == 0)) { if (argc < 3) @@ -536,7 +577,6 @@ int main(int argc, char *argv[]) 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); @@ -576,8 +616,10 @@ int main(int argc, char *argv[]) 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); + if (argCopyForDirname) + free(argCopyForDirname); + if (argCopyForBasename) + free(argCopyForBasename); return EXIT_FAILURE; } } @@ -585,8 +627,10 @@ int main(int argc, char *argv[]) if (!dirExists(path)) { log_error("Output directory does not exist: %s\n", path); - if(argCopyForDirname) free(argCopyForDirname); - if(argCopyForBasename) free(argCopyForBasename); + if (argCopyForDirname) + free(argCopyForDirname); + if (argCopyForBasename) + free(argCopyForBasename); return EXIT_FAILURE; } @@ -613,8 +657,10 @@ int main(int argc, char *argv[]) log_info("Successfully created controls file at %s\n", finalPath); } - if(argCopyForDirname) free(argCopyForDirname); - if(argCopyForBasename) free(argCopyForBasename); + if (argCopyForDirname) + free(argCopyForDirname); + if (argCopyForBasename) + free(argCopyForBasename); return EXIT_SUCCESS; } @@ -687,7 +733,7 @@ int main(int argc, char *argv[]) continue; } - if (strcmp(argv[i], "-d") == 0 || strcmp(argv[i], "--controlsdb") == 0) + if (strcmp(argv[i], "-d") == 0 || strcmp(argv[i], "--controllerdb") == 0) { if (i + 1 >= argc) { @@ -835,9 +881,6 @@ int main(int argc, char *argv[]) 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) { @@ -857,6 +900,9 @@ int main(int argc, char *argv[]) isCleanElf(command); + setEnvironmentVariables(libPath, originalDir, targetedGameDir, zink, nvidia, extConfigPath, extControlsPath, extControlsDbPath, + libOpenal); + if (gdb) { char temp[128]; diff --git a/src/lindbergh/passthrough.c b/src/lindbergh/passthrough.c index 28a8123..bac45b9 100644 --- a/src/lindbergh/passthrough.c +++ b/src/lindbergh/passthrough.c @@ -11,7 +11,7 @@ #include "passthrough.h" #define TIMEOUT_SELECT 200 -#define CTS_ON_RETRY 20 +#define CTS_ON_RETRY 100 // Used to read JVS frame in a non-blocking way JVSFrame jvsFrameBuffer; @@ -23,12 +23,14 @@ pthread_mutex_t jvsBuffer_lock = PTHREAD_MUTEX_INITIALIZER; * @param jvsPath The serial port path. Ex: "/dev/ttyS3" * @return A file descriptor */ -int openJVSSerial(char *jvsPath) { +int openJVSSerial(char *jvsPath) +{ int jvsFileDescriptor = -1; // TODO: check O_NOCTTY declaration jvsFileDescriptor = open(jvsPath, O_RDWR | O_NOCTTY); - if (jvsFileDescriptor < 0) { + if (jvsFileDescriptor < 0) + { printf("Failed to open '%s' for JVS.\n", jvsPath); } @@ -41,7 +43,8 @@ int openJVSSerial(char *jvsPath) { * @param fd * @return 0|1 */ -int initJVSSerial(int fd) { +int initJVSSerial(int fd) +{ struct termios options; int status; @@ -94,7 +97,7 @@ int initJVSSerial(int fd) { options.c_cc[VMIN] = 0; options.c_cc[VTIME] = 1; - + // options.c_cflag |= CREAD; // Turn on READ, let ctrl lines work tcsetattr(fd, TCSANOW, &options); /* No use ? Save it for later @@ -108,22 +111,26 @@ int initJVSSerial(int fd) { /** - * The DCD (Data Carrier Detect) status of a serial port indicates whether a carrier is present on the line, meaning that a connection has been established with another device. + * The DCD (Data Carrier Detect) status of a serial port indicates whether a carrier is present on the line, meaning that a connection has + * been established with another device. * @param fd File descriptor of JVS (serial) port * @return 0|1 According to control line status */ -int getDCD(int fd) { +int getDCD(int fd) +{ int status; ioctl(fd, TIOCMGET, &status); return (status & TIOCM_CAR) != 0; } /** - * The DSR (Data Set Ready) status of a serial port indicates whether the device at the other end of the connection is ready to receive data. + * The DSR (Data Set Ready) status of a serial port indicates whether the device at the other end of the connection is ready to receive + * data. * @param fd File descriptor of JVS (serial) port * @return 0|1 According to control line status */ -int getDSR(int fd) { +int getDSR(int fd) +{ int status; ioctl(fd, TIOCMGET, &status); return (status & TIOCM_DSR) != 0; @@ -134,7 +141,8 @@ int getDSR(int fd) { * @param fd File descriptor of JVS (serial) port * @return 0|1 According to control line status */ -int getCTS(int fd) { +int getCTS(int fd) +{ int status; ioctl(fd, TIOCMGET, &status); return (status & TIOCM_CTS) != 0; @@ -164,7 +172,7 @@ void *readJVSFrameThread(void * arg) // printf("SERIAL thread debug: trying to read byte.\n"); // Try to read a byte from serial, this call will be blocking if VMIN > 0 and VTIME = 0 bytesRead = read(fd, &localBuffer[byteCount], 1); - + // If nothing on serial and CTS is ON, we try to read "CTS_ON_RETRY" times ctsRetry = CTS_ON_RETRY; while (bytesRead < 1 && --ctsRetry > 0 && jvsFrameBuffer.ready == 0) { diff --git a/src/lindbergh/sdlCalls.c b/src/lindbergh/sdlCalls.c index e368f5b..dad6601 100644 --- a/src/lindbergh/sdlCalls.c +++ b/src/lindbergh/sdlCalls.c @@ -35,6 +35,7 @@ SDL_GLContext sdlContext = NULL; Display *x11Display = NULL; Window x11Window; char sdlGameTitle[256] = {0}; +bool sdlInputInitialized = false; extern SDL_Cursor *customCursor; extern SDL_Cursor *touchCursor; @@ -187,6 +188,9 @@ void startSDL(int *argcp, char **argv) initBlitting(); + if (gId != PRIMEVAL_HUNT) + SDL_SetWindowResizable(sdlWindow, true); + SDL_ShowWindow(sdlWindow); Uint64 startTime = SDL_GetTicks(); @@ -203,9 +207,6 @@ void startSDL(int *argcp, char **argv) SDL_GL_SwapWindow(sdlWindow); } - if (gId != PRIMEVAL_HUNT) - SDL_SetWindowResizable(sdlWindow, true); - creatingWindow = false; printf(" RESOLUTION: %dx%d\n", gWidth, gHeight); @@ -309,8 +310,11 @@ void pollEvents() break; } } - if (gGrp == GROUP_HOD4 || gGrp == GROUP_HOD4_TEST) - updateGunShake(); - updateCombinedAxes(); - processChangedActions(); + if (sdlInputInitialized) + { + if (gGrp == GROUP_HOD4 || gGrp == GROUP_HOD4_TEST) + updateGunShake(); + updateCombinedAxes(); + processChangedActions(); + } } diff --git a/src/lindbergh/sdlInput.c b/src/lindbergh/sdlInput.c index f287cd6..16b4734 100644 --- a/src/lindbergh/sdlInput.c +++ b/src/lindbergh/sdlInput.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -58,6 +59,7 @@ extern int gHeight; int widthOri; int heightOri; extern SDL_Window *sdlWindow; +extern bool sdlInputInitialized; extern Dest dest; @@ -201,7 +203,7 @@ int initSdlInput(char *controlsPath) if (envDbPath) { SDL_AddGamepadMappingsFromFile(envDbPath); - printf("%s, as a controller database.\n", envDbPath); + printf("%s loaded as a controller database.\n", basename(envDbPath)); } gameType = getConfig()->gameType; @@ -378,6 +380,7 @@ int initSdlInput(char *controlsPath) // Apply any final game-specific mapping overrides. remapPerGame(); + sdlInputInitialized = true; return 0; } @@ -1227,6 +1230,9 @@ void addActionToDirtyList(JVSPlayer player, LogicalAction action) */ void processSdlEvent(const SDL_Event *e) { + if (!sdlInputInitialized) + return; + switch (e->type) { case SDL_EVENT_KEY_DOWN: @@ -1522,9 +1528,9 @@ void processSdlEvent(const SDL_Event *e) break; case SDL_EVENT_MOUSE_MOTION: { - double mX = e->motion.x; - double mY = e->motion.y; - float posX, posY; + float mX = e->motion.x; + float mY = e->motion.y; + float posX = 0.0f, posY = 0.0f; if (gId == PRIMEVAL_HUNT) { @@ -1534,8 +1540,8 @@ void processSdlEvent(const SDL_Event *e) int motX = mX, motY = mY; phTouchScreenCursor(mX, mY, &motX, &motY); - posX = ((double)(motX - phX) / (double)phW); - posY = ((double)(motY - phY) / (double)phH); + posX = ((float)(motX - phX) / (float)phW); + posY = ((float)(motY - phY) / (float)phH); } else {