Compare commits

..

34 Commits

Author SHA1 Message Date
Skyth 17d7b97dd6 Update version milestone to Beta 1. 2025-01-23 23:20:28 +03:00
Hyper 79b966586d version.cmake: don't show Git info or build type for Release 2025-01-23 20:00:48 +00:00
Hyper 686ef22c4d Implemented D-Pad support for the World Map, Gaia Colossus, Super Sonic and the Bobsleigh (#150)
* Implemented D-Pad support for World Map, Super Sonic (WIP) and Bobsleigh

* Implemented D-Pad support for Gaia Colossus and Super Sonic

* Improved touchpad sensitivity
2025-01-23 17:43:08 +00:00
Skyth (Asilkan) ca6b42e20e Interpolate barrels in Spagonia Night to fix softlock at high frame rates. (#153) 2025-01-23 19:41:15 +03:00
Skyth (Asilkan) 372c04fedd Implement ImGui additive rendering. (#152) 2025-01-23 16:25:31 +03:00
Skyth (Asilkan) b4de79720c Remove lzcnt instruction usage. (#151) 2025-01-23 15:18:19 +03:00
Hyper e10eb80e38 config: move Voice Language and Subtitles to System 2025-01-22 23:50:10 +00:00
Skyth (Asilkan) 4e149b0640 Implement proper post process scaling based on aspect ratio. (#148)
* Fix post process scaling for narrow aspect ratios.

* Compare width to pick gaussian blur quality for narrow aspect ratios.

* Account for world map disabling VERT+ for post process scaling.
2025-01-22 19:14:40 +03:00
Skyth (Asilkan) 85b5ebf9a7 Fix pause menu selection cast being visible while exiting options menu. (#139) 2025-01-22 19:13:53 +03:00
Skyth (Asilkan) bdbdd42bd0 Implement config option to toggle surround sound. (#144) 2025-01-22 18:51:51 +03:00
Skyth (Asilkan) fbc4bfa4d6 Fix save files not getting redirected without include directories. (#146) 2025-01-22 17:01:37 +03:00
Skyth 010c0a9fdf Use clamp texture addressing by default. 2025-01-22 15:49:30 +03:00
João Moura e6251bdbc3 Add GitHub Actions workflow files for Flatpak and Windows (#142)
Co-authored-by: SuperSonic16 <25761885+thesupersonic16@users.noreply.github.com>
Co-authored-by: Dario <dariosamo@gmail.com>
2025-01-22 14:29:02 +03:00
Skyth (Asilkan) fefd177b3a Replace indirect guest function calls with direct ones. (#141) 2025-01-20 18:18:20 +03:00
Skyth e8d36998a5 Fix gameplay UI scaling at narrow aspect ratios. 2025-01-20 02:08:43 +03:00
Skyth (Asilkan) 1efb4943b3 Replace uses of SWA with UnleashedRecomp & rebrand the recompilers. (#138) 2025-01-19 23:21:05 +03:00
Skyth (Asilkan) 312f913a92 Remove detail namespaces. (#137) 2025-01-19 21:09:47 +03:00
NextinHKRY d10f4bac3c Change Xbox Color Correction option to have 1 image (#136)
* Options: Color Correction with 1 thumbnail

* Update UnleashedRecompResources

* Update UnleashedRecompResources
2025-01-19 20:56:51 +03:00
Skyth (Asilkan) 535bca7d9f Move config implementations to a .cpp file. (#133) 2025-01-19 19:05:44 +03:00
Hyper 614106c868 input_patches: add missing hook functions 2025-01-19 15:58:02 +00:00
Hyper fde108178d CTitleStateIntro_patches: make g_quitMessageOpen not static 2025-01-19 15:42:05 +00:00
Hyper b56c0b8209 Implemented safer hooks for D-Pad movement (#129) 2025-01-19 15:01:11 +00:00
Hyper cdd801dcec Fix quit message not blocking advertise movie (#127) 2025-01-19 13:06:38 +00:00
Hyper e7919da1bd game_window: change window title to "Unleashed Recompiled" 2025-01-18 23:51:00 +00:00
Hyper 513a66657f xam: only print XamShowMessageBoxUI info on Win32 2025-01-18 22:51:49 +00:00
Hyper b9f0742ff9 CTitleStateIntro_patches: don't worry about it 2025-01-18 21:38:09 +00:00
Hyper 7c72146705 CTitleStateIntro_patches: fix save data validation hook 2025-01-18 21:34:20 +00:00
Skyth (Asilkan) 40a8bf557b Scale 2D coordinates to backbuffer resolution. (#124)
* Starting with backbuffer scaling refactor.

* CSD & primitive 2Ds refactored.

* More refactoring.

* Fix primitive 2D, and on screen 3D items.

* Fix right side offset scaling.

* Fix Inspire letterbox.

* Fix offset scaling in world map.

* Fix custom menus.

* Remove debugging code.
2025-01-18 23:56:47 +03:00
Hyper 1cf12fa97f installer_wizard: fix credits not fading out upon exit 2025-01-18 19:39:58 +00:00
Hyper aacb9d259c Added error message for corrupted save data, removed Win32 message box on XamShowMessageBoxUI (#122)
* xam: remove Win32 message box on XamShowMessageBoxUI

* CTitleStateIntro_patches: display error message on corrupted save data

TitleMenuRemoveContinueOnCorruptSaveMidAsmHook by @DeaTh-G

Co-Authored-By: DeaTh-G <55578911+DeaTh-G@users.noreply.github.com>

---------

Co-authored-by: DeaTh-G <55578911+DeaTh-G@users.noreply.github.com>
2025-01-18 22:32:37 +03:00
Skyth (Asilkan) c53df15578 Fix movie patches not accounting for half pixel properly. (#119) 2025-01-18 16:52:51 +03:00
SuperSonic16 53331d5760 Added scheme handler for Linux Flatpak (#118) 2025-01-18 15:09:37 +03:00
Skyth 0b675628ea Fix compilation error on Linux. 2025-01-18 13:42:59 +03:00
Skyth d3edee1945 Fix Vulkan dynamic depth bias validation error. 2025-01-18 12:58:02 +03:00
152 changed files with 2527 additions and 3461 deletions
+73
View File
@@ -0,0 +1,73 @@
name: Build Project (Flatpak)
on:
workflow_dispatch:
env:
FLATPAK_ID: io.github.hedge_dev.unleashedrecomp
FREEDESKTOP_VERSION: 23.08
LLVM_VERSION: 18
jobs:
build-flatpak:
name: Build Flatpak
runs-on: ubuntu-24.04
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: recursive
token: ${{ secrets.ORG_TOKEN }}
- name: Checkout private repository
uses: actions/checkout@v4
with:
repository: ${{ secrets.ASSET_REPO }}
token: ${{ secrets.ASSET_REPO_TOKEN }}
path: flatpak/private
- name: Install dependencies
run: |-
sudo apt update
sudo apt install -y flatpak-builder ccache
- name: Cache ccache directory
uses: actions/cache@v4
with:
path: /tmp/ccache
key: ccache-${{ runner.os }}
- name: Prepare Flatpak
run: |
flatpak --user remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
flatpak --user install -y flathub org.freedesktop.Sdk//${{ env.FREEDESKTOP_VERSION }}
flatpak --user install -y flathub org.freedesktop.Sdk.Extension.llvm${{ env.LLVM_VERSION }}//${{ env.FREEDESKTOP_VERSION }}
- name: Build Flatpak
run: |
echo "commit_message=$(git log -1 --pretty=%s)" >> $GITHUB_ENV
export CCACHE_DIR=/tmp/ccache
flatpak-builder --user --force-clean --install-deps-from=flathub --repo=repo --install --ccache builddir ./flatpak/${{ env.FLATPAK_ID }}.json
flatpak build-bundle repo ./${{ env.FLATPAK_ID }}.flatpak ${{ env.FLATPAK_ID }} --runtime-repo=https://flathub.org/repo/flathub.flatpakrepo
# Uploads the built flatpak bundle to GitHub
# - name: Upload artifact
# uses: actions/upload-artifact@v4
# with:
# name: UnleashedRecomp-flatpak
# path: ./${{ env.FLATPAK_ID }}.flatpak
- name: Upload artifact to Discord
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
if: ${{ env.DISCORD_WEBHOOK != '' }}
uses: tsickert/discord-webhook@v6.0.0
with:
webhook-url: ${{ env.DISCORD_WEBHOOK }}
content: |
OS: Linux
Summary: ${{ env.commit_message }}
Commit: ${{ github.sha }}
Branch: ${{ github.ref_name }}
filename: ./${{ env.FLATPAK_ID }}.flatpak
+94
View File
@@ -0,0 +1,94 @@
name: Build Project (Windows)
on:
workflow_dispatch:
env:
CMAKE_PRESET: x64-Clang-Release
jobs:
build:
name: Build Windows
runs-on: windows-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: recursive
token: ${{ secrets.ORG_TOKEN }}
- name: Checkout private repository
uses: actions/checkout@v4
with:
repository: ${{ secrets.ASSET_REPO }}
token: ${{ secrets.ASSET_REPO_TOKEN }}
path: .\private
- name: Setup ccache
uses: hendrikmuhs/ccache-action@v1.2
with:
key: ccache-${{ runner.os }}
- name: Cache vcpkg
uses: actions/cache@v4
with:
path: |
./thirdparty/vcpkg/downloads
./thirdparty/vcpkg/packages
key: vcpkg-${{ runner.os }}-${{ hashFiles('vcpkg.json') }}
restore-keys: |
vcpkg-${{ runner.os }}-
- name: Install dependencies
run: |
choco install ninja
Remove-Item -Path "C:\ProgramData\Chocolatey\bin\ccache.exe" -Force -ErrorAction SilentlyContinue
- name: Configure Developer Command Prompt
uses: ilammy/msvc-dev-cmd@v1
- name: Prepare Project
run: |
$commitMessage = git log -1 --pretty=%s
Add-Content -Path $env:GITHUB_ENV -Value "commit_message=$commitMessage"
copy .\private\* .\UnleashedRecompLib\private
- name: Configure Project
run: cmake . --preset ${{ env.CMAKE_PRESET }} -DSDL2MIXER_VORBIS=VORBISFILE -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER_LAUNCHER=ccache
- name: Build Project
run: cmake --build .\out\build\${{ env.CMAKE_PRESET }} --target UnleashedRecomp
- name: Pack Release
run: |
New-Item -ItemType Directory -Path .\release
New-Item -ItemType Directory -Path .\release\D3D12
Move-Item -Path ".\out\build\${{ env.CMAKE_PRESET }}\UnleashedRecomp\D3D12\D3D12Core.dll" -Destination ".\release\D3D12\D3D12Core.dll"
Move-Item -Path ".\out\build\${{ env.CMAKE_PRESET }}\UnleashedRecomp\dxcompiler.dll" -Destination ".\release\dxcompiler.dll"
Move-Item -Path ".\out\build\${{ env.CMAKE_PRESET }}\UnleashedRecomp\dxil.dll" -Destination ".\release\dxil.dll"
Move-Item -Path ".\out\build\${{ env.CMAKE_PRESET }}\UnleashedRecomp\UnleashedRecomp.exe" -Destination ".\release\UnleashedRecomp.exe"
Compress-Archive -Path .\release\* -DestinationPath .\UnleashedRecomp-Windows.zip
# Uploads the packed zip file to GitHub
# - name: Upload artifact
# uses: actions/upload-artifact@v4
# with:
# name: UnleashedRecomp-Windows
# path: .\UnleashedRecomp-Windows.zip
- name: Upload artifact to Discord
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
if: ${{ env.DISCORD_WEBHOOK != '' }}
uses: tsickert/discord-webhook@v6.0.0
with:
webhook-url: ${{ env.DISCORD_WEBHOOK }}
content: |
OS: Windows
Summary: ${{ env.commit_message }}
Commit: ${{ github.sha }}
Branch: ${{ github.ref_name }}
filename: .\UnleashedRecomp-Windows.zip
+6 -6
View File
@@ -1,12 +1,12 @@
[submodule "thirdparty/PowerRecomp"] [submodule "tools/XenonRecomp"]
path = tools/PowerRecomp path = tools/XenonRecomp
url = https://github.com/hedge-dev/PowerRecomp url = https://github.com/hedge-dev/XenonRecomp.git
[submodule "thirdparty/ddspp"] [submodule "thirdparty/ddspp"]
path = thirdparty/ddspp path = thirdparty/ddspp
url = https://github.com/redorav/ddspp.git url = https://github.com/redorav/ddspp.git
[submodule "thirdparty/ShaderRecomp"] [submodule "tools/XenosRecomp"]
path = tools/ShaderRecomp path = tools/XenosRecomp
url = https://github.com/hedge-dev/ShaderRecomp.git url = https://github.com/hedge-dev/XenosRecomp.git
[submodule "thirdparty/libmspack"] [submodule "thirdparty/libmspack"]
path = thirdparty/libmspack path = thirdparty/libmspack
url = https://github.com/kyz/libmspack url = https://github.com/kyz/libmspack
+9 -4
View File
@@ -5,8 +5,8 @@ if(NOT DEFINED ENV{VCPKG_ROOT})
endif() endif()
include($ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake) include($ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake)
set(SWA_THIRDPARTY_ROOT ${CMAKE_SOURCE_DIR}/thirdparty) set(UNLEASHED_RECOMP_THIRDPARTY_ROOT ${CMAKE_SOURCE_DIR}/thirdparty)
set(SWA_TOOLS_ROOT ${CMAKE_SOURCE_DIR}/tools) set(UNLEASHED_RECOMP_TOOLS_ROOT ${CMAKE_SOURCE_DIR}/tools)
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD 20)
set(BUILD_SHARED_LIBS OFF) set(BUILD_SHARED_LIBS OFF)
@@ -18,8 +18,13 @@ endif()
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>") set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
add_subdirectory(${SWA_THIRDPARTY_ROOT}) # Target Sandy Bridge for all projects
add_subdirectory(${SWA_TOOLS_ROOT}) add_compile_options(
-march=sandybridge
)
add_subdirectory(${UNLEASHED_RECOMP_THIRDPARTY_ROOT})
add_subdirectory(${UNLEASHED_RECOMP_TOOLS_ROOT})
project("UnleashedRecomp-ALL") project("UnleashedRecomp-ALL")
+1 -2
View File
@@ -23,8 +23,7 @@
"type": "equals", "type": "equals",
"lhs": "${hostSystemName}", "lhs": "${hostSystemName}",
"rhs": "Windows" "rhs": "Windows"
}, }
"toolset": "ClangCL"
}, },
{ {
"name": "x64-Clang-Debug", "name": "x64-Clang-Debug",
+83 -132
View File
@@ -1,16 +1,13 @@
project("UnleashedRecomp") project("UnleashedRecomp")
set(TARGET_NAME "SWA")
if (WIN32) if (WIN32)
option(SWA_D3D12 "Add D3D12 support for rendering" ON) option(UNLEASHED_RECOMP_D3D12 "Add D3D12 support for rendering" ON)
endif() endif()
if (CMAKE_SYSTEM_NAME MATCHES "Linux") if (CMAKE_SYSTEM_NAME MATCHES "Linux")
option(SWA_FLATPAK "Configure the build for Flatpak compatibility." OFF) option(UNLEASHED_RECOMP_FLATPAK "Configure the build for Flatpak compatibility." OFF)
endif() endif()
option(SWA_XAUDIO2 "Use XAudio2 for audio playback" OFF)
function(BIN2C) function(BIN2C)
cmake_parse_arguments(BIN2C_ARGS "" "TARGET_OBJ;SOURCE_FILE;DEST_FILE;ARRAY_NAME;COMPRESSION_TYPE" "" ${ARGN}) cmake_parse_arguments(BIN2C_ARGS "" "TARGET_OBJ;SOURCE_FILE;DEST_FILE;ARRAY_NAME;COMPRESSION_TYPE" "" ${ARGN})
@@ -42,9 +39,7 @@ function(BIN2C)
endfunction() endfunction()
add_compile_options( add_compile_options(
-march=sandybridge
-fno-strict-aliasing -fno-strict-aliasing
-Wno-switch -Wno-switch
-Wno-unused-function -Wno-unused-function
-Wno-unused-variable -Wno-unused-variable
@@ -64,16 +59,15 @@ else()
endif() endif()
add_compile_definitions( add_compile_definitions(
SWA_IMPL
SDL_MAIN_HANDLED SDL_MAIN_HANDLED
_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR # Microsoft wtf? _DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR # Microsoft wtf?
_CRT_SECURE_NO_WARNINGS) _CRT_SECURE_NO_WARNINGS)
set(SWA_PRECOMPILED_HEADERS set(UNLEASHED_RECOMP_PRECOMPILED_HEADERS
"stdafx.h" "stdafx.h"
) )
set(SWA_KERNEL_CXX_SOURCES set(UNLEASHED_RECOMP_KERNEL_CXX_SOURCES
"kernel/imports.cpp" "kernel/imports.cpp"
"kernel/xdm.cpp" "kernel/xdm.cpp"
"kernel/heap.cpp" "kernel/heap.cpp"
@@ -82,21 +76,13 @@ set(SWA_KERNEL_CXX_SOURCES
"kernel/io/file_system.cpp" "kernel/io/file_system.cpp"
) )
set(SWA_LOCALE_CXX_SOURCES set(UNLEASHED_RECOMP_LOCALE_CXX_SOURCES
"locale/config_locale.cpp" "locale/config_locale.cpp"
"locale/locale.cpp" "locale/locale.cpp"
) )
set(SWA_OS_CXX_SOURCES
"os/logger.cpp"
"os/media.cpp"
"os/process.cpp"
"os/user.cpp"
"os/version.cpp"
)
if (WIN32) if (WIN32)
list(APPEND SWA_OS_CXX_SOURCES set(UNLEASHED_RECOMP_OS_CXX_SOURCES
"os/win32/logger_win32.cpp" "os/win32/logger_win32.cpp"
"os/win32/media_win32.cpp" "os/win32/media_win32.cpp"
"os/win32/process_win32.cpp" "os/win32/process_win32.cpp"
@@ -104,7 +90,7 @@ if (WIN32)
"os/win32/version_win32.cpp" "os/win32/version_win32.cpp"
) )
elseif (CMAKE_SYSTEM_NAME MATCHES "Linux") elseif (CMAKE_SYSTEM_NAME MATCHES "Linux")
list(APPEND SWA_OS_CXX_SOURCES set(UNLEASHED_RECOMP_OS_CXX_SOURCES
"os/linux/logger_linux.cpp" "os/linux/logger_linux.cpp"
"os/linux/media_linux.cpp" "os/linux/media_linux.cpp"
"os/linux/process_linux.cpp" "os/linux/process_linux.cpp"
@@ -113,11 +99,11 @@ elseif (CMAKE_SYSTEM_NAME MATCHES "Linux")
) )
endif() endif()
set(SWA_CPU_CXX_SOURCES set(UNLEASHED_RECOMP_CPU_CXX_SOURCES
"cpu/guest_thread.cpp" "cpu/guest_thread.cpp"
) )
set(SWA_GPU_CXX_SOURCES set(UNLEASHED_RECOMP_GPU_CXX_SOURCES
"gpu/video.cpp" "gpu/video.cpp"
"gpu/imgui/imgui_common.cpp" "gpu/imgui/imgui_common.cpp"
"gpu/imgui/imgui_font_builder.cpp" "gpu/imgui/imgui_font_builder.cpp"
@@ -125,29 +111,24 @@ set(SWA_GPU_CXX_SOURCES
"gpu/rhi/plume_vulkan.cpp" "gpu/rhi/plume_vulkan.cpp"
) )
if (SWA_D3D12) if (UNLEASHED_RECOMP_D3D12)
list(APPEND SWA_GPU_CXX_SOURCES list(APPEND UNLEASHED_RECOMP_GPU_CXX_SOURCES
"gpu/rhi/plume_d3d12.cpp" "gpu/rhi/plume_d3d12.cpp"
) )
endif() endif()
set(SWA_APU_CXX_SOURCES set(UNLEASHED_RECOMP_APU_CXX_SOURCES
"apu/audio.cpp" "apu/audio.cpp"
"apu/embedded_player.cpp" "apu/embedded_player.cpp"
"apu/driver/sdl2_driver.cpp"
) )
if (SWA_XAUDIO2) set(UNLEASHED_RECOMP_HID_CXX_SOURCES
list(APPEND SWA_APU_CXX_SOURCES "apu/driver/xaudio_driver.cpp")
else()
list(APPEND SWA_APU_CXX_SOURCES "apu/driver/sdl2_driver.cpp")
endif()
set(SWA_HID_CXX_SOURCES
"hid/hid.cpp" "hid/hid.cpp"
"hid/driver/sdl_hid.cpp" "hid/driver/sdl_hid.cpp"
) )
set(SWA_PATCHES_CXX_SOURCES set(UNLEASHED_RECOMP_PATCHES_CXX_SOURCES
"patches/ui/CHudPause_patches.cpp" "patches/ui/CHudPause_patches.cpp"
"patches/ui/CTitleStateIntro_patches.cpp" "patches/ui/CTitleStateIntro_patches.cpp"
"patches/ui/CTitleStateMenu_patches.cpp" "patches/ui/CTitleStateMenu_patches.cpp"
@@ -155,8 +136,9 @@ set(SWA_PATCHES_CXX_SOURCES
"patches/aspect_ratio_patches.cpp" "patches/aspect_ratio_patches.cpp"
"patches/audio_patches.cpp" "patches/audio_patches.cpp"
"patches/camera_patches.cpp" "patches/camera_patches.cpp"
"patches/debug_patches.cpp" "patches/CGameModeStageTitle_patches.cpp"
"patches/fps_patches.cpp" "patches/fps_patches.cpp"
"patches/input_patches.cpp"
"patches/inspire_patches.cpp" "patches/inspire_patches.cpp"
"patches/misc_patches.cpp" "patches/misc_patches.cpp"
"patches/object_patches.cpp" "patches/object_patches.cpp"
@@ -165,16 +147,7 @@ set(SWA_PATCHES_CXX_SOURCES
"patches/video_patches.cpp" "patches/video_patches.cpp"
) )
set(SWA_UI_CXX_SOURCES set(UNLEASHED_RECOMP_UI_CXX_SOURCES
"ui/reddog/windows/counter_window.cpp"
"ui/reddog/windows/exports_window.cpp"
"ui/reddog/windows/view_window.cpp"
"ui/reddog/windows/welcome_window.cpp"
"ui/reddog/windows/window_list.cpp"
"ui/reddog/reddog_controls.cpp"
"ui/reddog/reddog_manager.cpp"
"ui/reddog/reddog_window.cpp"
"ui/reddog/debug_draw.cpp"
"ui/achievement_menu.cpp" "ui/achievement_menu.cpp"
"ui/achievement_overlay.cpp" "ui/achievement_overlay.cpp"
"ui/installer_wizard.cpp" "ui/installer_wizard.cpp"
@@ -187,7 +160,7 @@ set(SWA_UI_CXX_SOURCES
"ui/game_window.cpp" "ui/game_window.cpp"
) )
set(SWA_INSTALL_CXX_SOURCES set(UNLEASHED_RECOMP_INSTALL_CXX_SOURCES
"install/installer.cpp" "install/installer.cpp"
"install/iso_file_system.cpp" "install/iso_file_system.cpp"
"install/memory_mapped_file.cpp" "install/memory_mapped_file.cpp"
@@ -203,56 +176,56 @@ set(SWA_INSTALL_CXX_SOURCES
"install/hashes/update.cpp" "install/hashes/update.cpp"
) )
set(SWA_USER_CXX_SOURCES set(UNLEASHED_RECOMP_USER_CXX_SOURCES
"user/achievement_data.cpp" "user/achievement_data.cpp"
"user/config.cpp" "user/config.cpp"
) )
set(SWA_MOD_CXX_SOURCES set(UNLEASHED_RECOMP_MOD_CXX_SOURCES
"mod/mod_loader.cpp" "mod/mod_loader.cpp"
) )
set(SWA_THIRDPARTY_SOURCES set(UNLEASHED_RECOMP_THIRDPARTY_SOURCES
"${SWA_THIRDPARTY_ROOT}/imgui/backends/imgui_impl_sdl2.cpp" "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/imgui/backends/imgui_impl_sdl2.cpp"
"${SWA_THIRDPARTY_ROOT}/imgui/imgui.cpp" "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/imgui/imgui.cpp"
"${SWA_THIRDPARTY_ROOT}/imgui/imgui_demo.cpp" "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/imgui/imgui_demo.cpp"
"${SWA_THIRDPARTY_ROOT}/imgui/imgui_draw.cpp" "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/imgui/imgui_draw.cpp"
"${SWA_THIRDPARTY_ROOT}/imgui/imgui_tables.cpp" "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/imgui/imgui_tables.cpp"
"${SWA_THIRDPARTY_ROOT}/imgui/imgui_widgets.cpp" "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/imgui/imgui_widgets.cpp"
"${SWA_THIRDPARTY_ROOT}/implot/implot.cpp" "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/implot/implot.cpp"
"${SWA_THIRDPARTY_ROOT}/implot/implot_demo.cpp" "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/implot/implot_demo.cpp"
"${SWA_THIRDPARTY_ROOT}/implot/implot_items.cpp" "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/implot/implot_items.cpp"
"${SWA_THIRDPARTY_ROOT}/libmspack/libmspack/mspack/lzxd.c" "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/libmspack/libmspack/mspack/lzxd.c"
"${SWA_THIRDPARTY_ROOT}/tiny-AES-c/aes.c" "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/tiny-AES-c/aes.c"
"${SWA_TOOLS_ROOT}/ShaderRecomp/thirdparty/smol-v/source/smolv.cpp" "${UNLEASHED_RECOMP_TOOLS_ROOT}/XenosRecomp/thirdparty/smol-v/source/smolv.cpp"
) )
set(SWA_THIRDPARTY_INCLUDES set(UNLEASHED_RECOMP_THIRDPARTY_INCLUDES
"${SWA_THIRDPARTY_ROOT}/concurrentqueue" "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/concurrentqueue"
"${SWA_THIRDPARTY_ROOT}/ddspp" "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/ddspp"
"${SWA_THIRDPARTY_ROOT}/imgui" "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/imgui"
"${SWA_THIRDPARTY_ROOT}/implot" "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/implot"
"${SWA_THIRDPARTY_ROOT}/libmspack/libmspack/mspack" "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/libmspack/libmspack/mspack"
"${SWA_THIRDPARTY_ROOT}/magic_enum/include" "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/magic_enum/include"
"${SWA_THIRDPARTY_ROOT}/stb" "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/stb"
"${SWA_THIRDPARTY_ROOT}/tiny-AES-c" "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/tiny-AES-c"
"${SWA_THIRDPARTY_ROOT}/TinySHA1" "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/TinySHA1"
"${SWA_THIRDPARTY_ROOT}/unordered_dense/include" "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/unordered_dense/include"
"${SWA_THIRDPARTY_ROOT}/volk" "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/volk"
"${SWA_THIRDPARTY_ROOT}/Vulkan-Headers/include" "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/Vulkan-Headers/include"
"${SWA_THIRDPARTY_ROOT}/VulkanMemoryAllocator/include" "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/VulkanMemoryAllocator/include"
"${SWA_TOOLS_ROOT}/bc_diff" "${UNLEASHED_RECOMP_TOOLS_ROOT}/bc_diff"
"${SWA_TOOLS_ROOT}/ShaderRecomp/thirdparty/smol-v/source" "${UNLEASHED_RECOMP_TOOLS_ROOT}/XenosRecomp/thirdparty/smol-v/source"
) )
if (SWA_D3D12) if (UNLEASHED_RECOMP_D3D12)
list(APPEND SWA_THIRDPARTY_INCLUDES "${SWA_THIRDPARTY_ROOT}/D3D12MemoryAllocator/include") list(APPEND UNLEASHED_RECOMP_THIRDPARTY_INCLUDES "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/D3D12MemoryAllocator/include")
list(APPEND SWA_THIRDPARTY_SOURCES "${SWA_THIRDPARTY_ROOT}/D3D12MemoryAllocator/src/D3D12MemAlloc.cpp") list(APPEND UNLEASHED_RECOMP_THIRDPARTY_SOURCES "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/D3D12MemoryAllocator/src/D3D12MemAlloc.cpp")
endif() endif()
set_source_files_properties(${SWA_THIRDPARTY_SOURCES} PROPERTIES SKIP_PRECOMPILE_HEADERS ON) set_source_files_properties(${UNLEASHED_RECOMP_THIRDPARTY_SOURCES} PROPERTIES SKIP_PRECOMPILE_HEADERS ON)
set(SWA_CXX_SOURCES set(UNLEASHED_RECOMP_CXX_SOURCES
"app.cpp" "app.cpp"
"exports.cpp" "exports.cpp"
"main.cpp" "main.cpp"
@@ -260,40 +233,38 @@ set(SWA_CXX_SOURCES
"stdafx.cpp" "stdafx.cpp"
"version.cpp" "version.cpp"
${SWA_KERNEL_CXX_SOURCES} ${UNLEASHED_RECOMP_KERNEL_CXX_SOURCES}
${SWA_LOCALE_CXX_SOURCES} ${UNLEASHED_RECOMP_LOCALE_CXX_SOURCES}
${SWA_OS_CXX_SOURCES} ${UNLEASHED_RECOMP_OS_CXX_SOURCES}
${SWA_CPU_CXX_SOURCES} ${UNLEASHED_RECOMP_CPU_CXX_SOURCES}
${SWA_GPU_CXX_SOURCES} ${UNLEASHED_RECOMP_GPU_CXX_SOURCES}
${SWA_APU_CXX_SOURCES} ${UNLEASHED_RECOMP_APU_CXX_SOURCES}
${SWA_HID_CXX_SOURCES} ${UNLEASHED_RECOMP_HID_CXX_SOURCES}
${SWA_PATCHES_CXX_SOURCES} ${UNLEASHED_RECOMP_PATCHES_CXX_SOURCES}
${SWA_UI_CXX_SOURCES} ${UNLEASHED_RECOMP_UI_CXX_SOURCES}
${SWA_INSTALL_CXX_SOURCES} ${UNLEASHED_RECOMP_INSTALL_CXX_SOURCES}
${SWA_USER_CXX_SOURCES} ${UNLEASHED_RECOMP_USER_CXX_SOURCES}
${SWA_MOD_CXX_SOURCES} ${UNLEASHED_RECOMP_MOD_CXX_SOURCES}
${SWA_THIRDPARTY_SOURCES} ${UNLEASHED_RECOMP_THIRDPARTY_SOURCES}
) )
if (WIN32) if (WIN32)
# Set up Win32 resources for application icon. # Set up Win32 resources for application icon.
set(ICON_PATH "${PROJECT_SOURCE_DIR}/../UnleashedRecompResources/images/game_icon.ico") set(ICON_PATH "${PROJECT_SOURCE_DIR}/../UnleashedRecompResources/images/game_icon.ico")
configure_file("res/win32/res.rc.template" "${CMAKE_BINARY_DIR}/res.rc" @ONLY) configure_file("res/win32/res.rc.template" "${CMAKE_BINARY_DIR}/res.rc" @ONLY)
add_executable(UnleashedRecomp ${SWA_CXX_SOURCES} "${CMAKE_BINARY_DIR}/res.rc") add_executable(UnleashedRecomp ${UNLEASHED_RECOMP_CXX_SOURCES} "${CMAKE_BINARY_DIR}/res.rc")
else() else()
add_executable(UnleashedRecomp ${SWA_CXX_SOURCES}) add_executable(UnleashedRecomp ${UNLEASHED_RECOMP_CXX_SOURCES})
endif() endif()
set_target_properties(UnleashedRecomp PROPERTIES OUTPUT_NAME ${TARGET_NAME}) if (UNLEASHED_RECOMP_FLATPAK)
if (SWA_FLATPAK)
target_compile_definitions(UnleashedRecomp PRIVATE "GAME_INSTALL_DIRECTORY=\"/var/data\"") target_compile_definitions(UnleashedRecomp PRIVATE "GAME_INSTALL_DIRECTORY=\"/var/data\"")
endif() endif()
if (SWA_D3D12) if (UNLEASHED_RECOMP_D3D12)
find_package(directx-headers CONFIG REQUIRED) find_package(directx-headers CONFIG REQUIRED)
find_package(directx12-agility CONFIG REQUIRED) find_package(directx12-agility CONFIG REQUIRED)
target_compile_definitions(UnleashedRecomp PRIVATE SWA_D3D12) target_compile_definitions(UnleashedRecomp PRIVATE UNLEASHED_RECOMP_D3D12)
endif() endif()
if (CMAKE_SYSTEM_NAME MATCHES "Linux") if (CMAKE_SYSTEM_NAME MATCHES "Linux")
@@ -302,7 +273,7 @@ endif()
find_package(directx-dxc REQUIRED) find_package(directx-dxc REQUIRED)
if (SWA_D3D12) if (UNLEASHED_RECOMP_D3D12)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/D3D12) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/D3D12)
add_custom_command(TARGET UnleashedRecomp POST_BUILD add_custom_command(TARGET UnleashedRecomp POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_PROPERTY:Microsoft::DirectX12-Core,IMPORTED_LOCATION_RELEASE> ${CMAKE_CURRENT_BINARY_DIR}/D3D12 COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_PROPERTY:Microsoft::DirectX12-Core,IMPORTED_LOCATION_RELEASE> ${CMAKE_CURRENT_BINARY_DIR}/D3D12
@@ -340,7 +311,7 @@ target_link_libraries(UnleashedRecomp PRIVATE
msdf-atlas-gen::msdf-atlas-gen msdf-atlas-gen::msdf-atlas-gen
nfd::nfd nfd::nfd
o1heap o1heap
PowerUtils XenonUtils
SDL2::SDL2-static SDL2::SDL2-static
SDL2_mixer SDL2_mixer
tomlplusplus::tomlplusplus tomlplusplus::tomlplusplus
@@ -351,7 +322,7 @@ target_link_libraries(UnleashedRecomp PRIVATE
target_include_directories(UnleashedRecomp PRIVATE target_include_directories(UnleashedRecomp PRIVATE
${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
"${CMAKE_CURRENT_SOURCE_DIR}/api" "${CMAKE_CURRENT_SOURCE_DIR}/api"
${SWA_THIRDPARTY_INCLUDES} ${UNLEASHED_RECOMP_THIRDPARTY_INCLUDES}
) )
if (CMAKE_SYSTEM_NAME MATCHES "Linux") if (CMAKE_SYSTEM_NAME MATCHES "Linux")
@@ -360,12 +331,12 @@ if (CMAKE_SYSTEM_NAME MATCHES "Linux")
target_link_libraries(UnleashedRecomp PRIVATE ${X11_LIBRARIES}) target_link_libraries(UnleashedRecomp PRIVATE ${X11_LIBRARIES})
endif() endif()
target_precompile_headers(UnleashedRecomp PUBLIC ${SWA_PRECOMPILED_HEADERS}) target_precompile_headers(UnleashedRecomp PUBLIC ${UNLEASHED_RECOMP_PRECOMPILED_HEADERS})
function(compile_shader FILE_PATH TARGET_NAME) function(compile_shader FILE_PATH TARGET_NAME)
set(FILE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/gpu/shader/${FILE_PATH}.hlsl) set(FILE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/gpu/shader/${FILE_PATH}.hlsl)
cmake_path(GET FILE_PATH STEM VARIABLE_NAME) cmake_path(GET FILE_PATH STEM VARIABLE_NAME)
if (SWA_D3D12) if (UNLEASHED_RECOMP_D3D12)
add_custom_command( add_custom_command(
OUTPUT ${FILE_PATH}.dxil.h OUTPUT ${FILE_PATH}.dxil.h
COMMAND ${DIRECTX_DXC_TOOL} -T ${TARGET_NAME} -HV 2021 -all-resources-bound -Wno-ignored-attributes -Fh ${FILE_PATH}.dxil.h ${FILE_PATH} -Vn g_${VARIABLE_NAME}_dxil COMMAND ${DIRECTX_DXC_TOOL} -T ${TARGET_NAME} -HV 2021 -all-resources-bound -Wno-ignored-attributes -Fh ${FILE_PATH}.dxil.h ${FILE_PATH} -Vn g_${VARIABLE_NAME}_dxil
@@ -437,9 +408,9 @@ generate_aggregate_header(
) )
# Only show build type if not Release. # Only show build type if not Release.
set(IS_BUILD_TYPE_IN_VER_STRING 0) set(SHOW_GIT_INFO_AND_BUILD_TYPE 0)
if (NOT ${CMAKE_BUILD_TYPE} MATCHES "Release") if (NOT ${CMAKE_BUILD_TYPE} MATCHES "Release")
set(IS_BUILD_TYPE_IN_VER_STRING 1) set(SHOW_GIT_INFO_AND_BUILD_TYPE 1)
endif() endif()
include("version.cmake") include("version.cmake")
@@ -449,8 +420,8 @@ GenerateVersionSources(
H_TEMPLATE "${PROJECT_SOURCE_DIR}/res/version.h.template" H_TEMPLATE "${PROJECT_SOURCE_DIR}/res/version.h.template"
CXX_TEMPLATE "${PROJECT_SOURCE_DIR}/res/version.cpp.template" CXX_TEMPLATE "${PROJECT_SOURCE_DIR}/res/version.cpp.template"
BUILD_TYPE ${CMAKE_BUILD_TYPE} BUILD_TYPE ${CMAKE_BUILD_TYPE}
IS_BUILD_TYPE_IN_VER_STRING ${IS_BUILD_TYPE_IN_VER_STRING} SHOW_GIT_INFO ${SHOW_GIT_INFO_AND_BUILD_TYPE}
IS_GIT_REPO 1 SHOW_BUILD_TYPE ${SHOW_GIT_INFO_AND_BUILD_TYPE}
) )
set(RESOURCES_SOURCE_PATH "${PROJECT_SOURCE_DIR}/../UnleashedRecompResources") set(RESOURCES_SOURCE_PATH "${PROJECT_SOURCE_DIR}/../UnleashedRecompResources")
@@ -466,24 +437,6 @@ BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/co
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/kbm.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/kbm.dds" ARRAY_NAME "g_kbm" COMPRESSION_TYPE "zstd") BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/kbm.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/kbm.dds" ARRAY_NAME "g_kbm" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/select_fade.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/select_fade.dds" ARRAY_NAME "g_select_fade" COMPRESSION_TYPE "zstd") BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/select_fade.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/select_fade.dds" ARRAY_NAME "g_select_fade" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/select_fill.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/select_fill.dds" ARRAY_NAME "g_select_fill" COMPRESSION_TYPE "zstd") BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/select_fill.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/select_fill.dds" ARRAY_NAME "g_select_fill" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/button_close_1.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/button_close_1.dds" ARRAY_NAME "g_button_close_1")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/button_close_2.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/button_close_2.dds" ARRAY_NAME "g_button_close_2")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/button_minimum_1.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/button_minimum_1.dds" ARRAY_NAME "g_button_minimum_1")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/button_minimum_2.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/button_minimum_2.dds" ARRAY_NAME "g_button_minimum_2")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/button_pin_1.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/button_pin_1.dds" ARRAY_NAME "g_button_pin_1")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/button_pin_2.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/button_pin_2.dds" ARRAY_NAME "g_button_pin_2")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/checkbox_1.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/checkbox_1.dds" ARRAY_NAME "g_checkbox_1")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/checkbox_2.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/checkbox_2.dds" ARRAY_NAME "g_checkbox_2")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/common_button_1.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/common_button_1.dds" ARRAY_NAME "g_common_button_1")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/common_button_2.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/common_button_2.dds" ARRAY_NAME "g_common_button_2")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/common_icon.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/common_icon.dds" ARRAY_NAME "g_common_icon")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/debug_icon.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/debug_icon.dds" ARRAY_NAME "g_debug_icon")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/mouse_cursor.bmp" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/mouse_cursor.bmp" ARRAY_NAME "g_mouse_cursor")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/mouse_cursor_h.bmp" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/mouse_cursor_h.bmp" ARRAY_NAME "g_mouse_cursor_h")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/mouse_cursor_slant_l.bmp" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/mouse_cursor_slant_l.bmp" ARRAY_NAME "g_mouse_cursor_slant_l")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/mouse_cursor_slant_r.bmp" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/mouse_cursor_slant_r.bmp" ARRAY_NAME "g_mouse_cursor_slant_r")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/mouse_cursor_v.bmp" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/mouse_cursor_v.bmp" ARRAY_NAME "g_mouse_cursor_v")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/reddog/title_bar.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/reddog/title_bar.dds" ARRAY_NAME "g_title_bar")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/arrow_circle.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/arrow_circle.dds" ARRAY_NAME "g_arrow_circle" COMPRESSION_TYPE "zstd") BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/arrow_circle.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/arrow_circle.dds" ARRAY_NAME "g_arrow_circle" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_001.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_001.dds" ARRAY_NAME "g_install_001" COMPRESSION_TYPE "zstd") BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_001.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_001.dds" ARRAY_NAME "g_install_001" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_002.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_002.dds" ARRAY_NAME "g_install_002" COMPRESSION_TYPE "zstd") BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_002.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_002.dds" ARRAY_NAME "g_install_002" COMPRESSION_TYPE "zstd")
@@ -497,7 +450,6 @@ BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/in
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/pulse_install.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/pulse_install.dds" ARRAY_NAME "g_pulse_install" COMPRESSION_TYPE "zstd") BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/pulse_install.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/pulse_install.dds" ARRAY_NAME "g_pulse_install" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/achievement_notifications.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/achievement_notifications.dds" ARRAY_NAME "g_achievement_notifications" COMPRESSION_TYPE "zstd") BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/achievement_notifications.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/achievement_notifications.dds" ARRAY_NAME "g_achievement_notifications" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/allow_background_input.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/allow_background_input.dds" ARRAY_NAME "g_allow_background_input" COMPRESSION_TYPE "zstd") BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/allow_background_input.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/allow_background_input.dds" ARRAY_NAME "g_allow_background_input" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/allow_dpad_movement.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/allow_dpad_movement.dds" ARRAY_NAME "g_allow_dpad_movement" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/antialiasing.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/antialiasing.dds" ARRAY_NAME "g_antialiasing" COMPRESSION_TYPE "zstd") BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/antialiasing.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/antialiasing.dds" ARRAY_NAME "g_antialiasing" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/aspect_ratio.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/aspect_ratio.dds" ARRAY_NAME "g_aspect_ratio" COMPRESSION_TYPE "zstd") BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/aspect_ratio.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/aspect_ratio.dds" ARRAY_NAME "g_aspect_ratio" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/battle_theme.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/battle_theme.dds" ARRAY_NAME "g_battle_theme" COMPRESSION_TYPE "zstd") BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/battle_theme.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/battle_theme.dds" ARRAY_NAME "g_battle_theme" COMPRESSION_TYPE "zstd")
@@ -539,8 +491,7 @@ BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/op
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/vibration.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/vibration.dds" ARRAY_NAME "g_vibration" COMPRESSION_TYPE "zstd") BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/vibration.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/vibration.dds" ARRAY_NAME "g_vibration" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/vsync.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/vsync.dds" ARRAY_NAME "g_vsync" COMPRESSION_TYPE "zstd") BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/vsync.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/vsync.dds" ARRAY_NAME "g_vsync" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/window_size.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/window_size.dds" ARRAY_NAME "g_window_size" COMPRESSION_TYPE "zstd") BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/window_size.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/window_size.dds" ARRAY_NAME "g_window_size" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/xbox_color_correction_false.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/xbox_color_correction_false.dds" ARRAY_NAME "g_xbox_color_correction_false" COMPRESSION_TYPE "zstd") BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/xbox_color_correction.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/xbox_color_correction.dds" ARRAY_NAME "g_xbox_color_correction" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/xbox_color_correction_true.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/xbox_color_correction_true.dds" ARRAY_NAME "g_xbox_color_correction_true" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/miles_electric.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/miles_electric.dds" ARRAY_NAME "g_miles_electric" COMPRESSION_TYPE "zstd") BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/miles_electric.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/miles_electric.dds" ARRAY_NAME "g_miles_electric" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/game_icon.bmp" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/game_icon.bmp" ARRAY_NAME "g_game_icon") BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/game_icon.bmp" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/game_icon.bmp" ARRAY_NAME "g_game_icon")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/game_icon_night.bmp" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/game_icon_night.bmp" ARRAY_NAME "g_game_icon_night") BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/game_icon_night.bmp" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/game_icon_night.bmp" ARRAY_NAME "g_game_icon_night")
+8 -8
View File
@@ -9,41 +9,41 @@ namespace Chao::CSD
inline void CNode::SetText(const char* in_pText) inline void CNode::SetText(const char* in_pText)
{ {
GuestToHostFunction<int>(0x830BF640, this, in_pText); GuestToHostFunction<int>(sub_830BF640, this, in_pText);
} }
inline void CNode::SetText(const wchar_t* in_pText) inline void CNode::SetText(const wchar_t* in_pText)
{ {
GuestToHostFunction<int>(0x830BF640, this, in_pText); GuestToHostFunction<int>(sub_830BF640, this, in_pText);
} }
inline void CNode::GetPosition(Hedgehog::Math::CVector2& out_rResult) const inline void CNode::GetPosition(Hedgehog::Math::CVector2& out_rResult) const
{ {
GuestToHostFunction<void>(0x830BF008, &out_rResult, this); GuestToHostFunction<void>(sub_830BF008, &out_rResult, this);
} }
inline void CNode::SetPosition(float in_X, float in_Y) inline void CNode::SetPosition(float in_X, float in_Y)
{ {
GuestToHostFunction<int>(0x830BF078, this, in_X, in_Y); GuestToHostFunction<int>(sub_830BF078, this, in_X, in_Y);
} }
inline void CNode::SetHideFlag(uint32_t in_HideFlag) inline void CNode::SetHideFlag(uint32_t in_HideFlag)
{ {
GuestToHostFunction<int>(0x830BF080, this, in_HideFlag); GuestToHostFunction<int>(sub_830BF080, this, in_HideFlag);
} }
inline void CNode::SetRotation(float in_Rotation) inline void CNode::SetRotation(float in_Rotation)
{ {
GuestToHostFunction<int>(0x830BF088, this, in_Rotation); GuestToHostFunction<int>(sub_830BF088, this, in_Rotation);
} }
inline void CNode::SetScale(float in_X, float in_Y) inline void CNode::SetScale(float in_X, float in_Y)
{ {
GuestToHostFunction<int>(0x830BF090, this, in_X, in_Y); GuestToHostFunction<int>(sub_830BF090, this, in_X, in_Y);
} }
inline void CNode::SetPatternIndex(uint32_t in_PatternIndex) inline void CNode::SetPatternIndex(uint32_t in_PatternIndex)
{ {
GuestToHostFunction<int>(0x830BF300, this, in_PatternIndex); GuestToHostFunction<int>(sub_830BF300, this, in_PatternIndex);
} }
} }
@@ -5,20 +5,20 @@ namespace Chao::CSD
inline RCPtr<CScene> CProject::CreateScene(const char* in_pName) const inline RCPtr<CScene> CProject::CreateScene(const char* in_pName) const
{ {
RCPtr<CScene> rcScene; RCPtr<CScene> rcScene;
GuestToHostFunction<void>(0x830BEE00, this, rcScene, in_pName, nullptr); GuestToHostFunction<void>(sub_830BEE00, this, rcScene, in_pName, nullptr);
return rcScene; return rcScene;
} }
inline RCPtr<CScene> CProject::CreateScene(const char* in_pName, const char* in_pMotionName) const inline RCPtr<CScene> CProject::CreateScene(const char* in_pName, const char* in_pMotionName) const
{ {
RCPtr<CScene> rcScene; RCPtr<CScene> rcScene;
GuestToHostFunction<void>(0x830BECE0, this, rcScene, in_pName, in_pMotionName, nullptr); GuestToHostFunction<void>(sub_830BECE0, this, rcScene, in_pName, in_pMotionName, nullptr);
return rcScene; return rcScene;
} }
inline void CProject::DestroyScene(CScene* in_pScene) inline void CProject::DestroyScene(CScene* in_pScene)
{ {
GuestToHostFunction<void>(0x830BE298, this, in_pScene); GuestToHostFunction<void>(sub_830BE298, this, in_pScene);
} }
inline void CProject::DestroyScene(RCPtr<CScene>& inout_rcScene) inline void CProject::DestroyScene(RCPtr<CScene>& inout_rcScene)
@@ -30,6 +30,6 @@ namespace Chao::CSD
inline void RCPtrAbs::RCObject::Release() inline void RCPtrAbs::RCObject::Release()
{ {
GuestToHostFunction<void>(0x830BA068, this); GuestToHostFunction<void>(sub_830BA068, this);
} }
} }
@@ -27,12 +27,12 @@ namespace Chao::CSD
inline void RCPtrAbs::AttachAbs(void* in_pMemory) inline void RCPtrAbs::AttachAbs(void* in_pMemory)
{ {
GuestToHostFunction<void>(0x830BA298, this, in_pMemory); GuestToHostFunction<void>(sub_830BA298, this, in_pMemory);
} }
inline void RCPtrAbs::SetAbs(const RCPtrAbs& in_rPtr) inline void RCPtrAbs::SetAbs(const RCPtrAbs& in_rPtr)
{ {
GuestToHostFunction<void>(0x830BA328, this, in_rPtr); GuestToHostFunction<void>(sub_830BA328, this, in_rPtr);
} }
inline void* RCPtrAbs::operator*() const inline void* RCPtrAbs::operator*() const
@@ -22,7 +22,7 @@ namespace Chao::CSD
inline bool CScene::SetMotion(const char* in_pName) inline bool CScene::SetMotion(const char* in_pName)
{ {
return GuestToHostFunction<bool>(0x830BA760, this, in_pName); return GuestToHostFunction<bool>(sub_830BA760, this, in_pName);
} }
inline void CScene::SetMotionFrame(float in_MotionFrame) inline void CScene::SetMotionFrame(float in_MotionFrame)
@@ -33,21 +33,21 @@ namespace Chao::CSD
inline void CScene::SetPosition(float in_X, float in_Y) inline void CScene::SetPosition(float in_X, float in_Y)
{ {
GuestToHostFunction<void>(0x830BB550, this, in_X, in_Y); GuestToHostFunction<void>(sub_830BB550, this, in_X, in_Y);
} }
inline void CScene::SetHideFlag(uint32_t in_HideFlag) inline void CScene::SetHideFlag(uint32_t in_HideFlag)
{ {
GuestToHostFunction<void>(0x830BB378, this, in_HideFlag); GuestToHostFunction<void>(sub_830BB378, this, in_HideFlag);
} }
inline void CScene::SetRotation(float in_Angle) inline void CScene::SetRotation(float in_Angle)
{ {
GuestToHostFunction<void>(0x830BB5F8, this, in_Angle); GuestToHostFunction<void>(sub_830BB5F8, this, in_Angle);
} }
inline void CScene::SetScale(float in_X, float in_Y) inline void CScene::SetScale(float in_X, float in_Y)
{ {
GuestToHostFunction<void>(0x830BB650, this, in_X, in_Y); GuestToHostFunction<void>(sub_830BB650, this, in_X, in_Y);
} }
} }
-19
View File
@@ -1,19 +0,0 @@
#pragma once
#include <SWA.inl>
namespace Hedgehog::Math
{
class CAabb // Eigen::AlignedBox3f
{
public:
Hedgehog::Math::CVector min;
Hedgehog::Math::CVector max;
CVector Center() const;
};
SWA_ASSERT_SIZEOF(CAabb, 0x18);
}
#include "Aabb.inl"
@@ -1,12 +0,0 @@
namespace Hedgehog::Math
{
inline CVector Hedgehog::Math::CAabb::Center() const
{
// return (min + max) / 2;
Hedgehog::Math::CVector result;
result.X = (max.X + min.X) * 0.5f;
result.Y = (max.Y + min.Y) * 0.5f;
result.Z = 0.5f * (max.Z + min.Z);
return result;
}
}
@@ -1,21 +0,0 @@
#pragma once
#include <SWA.inl>
namespace Hedgehog::Math
{
class CMatrix
{
public:
be<float> data[16]; // Eigen::Affine3f
};
class CMatrix44
{
public:
be<float> data[16]; // Eigen::Matrix4f
};
SWA_ASSERT_SIZEOF(CMatrix, 0x40);
SWA_ASSERT_SIZEOF(CMatrix44, 0x40);
}
@@ -1,17 +0,0 @@
#pragma once
#include <SWA.inl>
namespace Hedgehog::Math
{
class CQuaternion //Eigen::Quaternionf;
{
public:
be<float> X;
be<float> Y;
be<float> Z;
be<float> W;
};
SWA_ASSERT_SIZEOF(CQuaternion, 0x10);
}
+1 -2
View File
@@ -17,6 +17,7 @@ namespace Hedgehog::Math
be<float> X; be<float> X;
be<float> Y; be<float> Y;
be<float> Z; be<float> Z;
be<float> W;
}; };
class CVector4 class CVector4
@@ -28,5 +29,3 @@ namespace Hedgehog::Math
be<float> W; be<float> W;
}; };
} }
#include "Vector.inl"
@@ -1,4 +0,0 @@
namespace Hedgehog::Math
{
}
@@ -1,18 +0,0 @@
#pragma once
#include <SWA.inl>
namespace Hedgehog::Mirage
{
class CCamera : Base::CObject
{
public:
Math::CMatrix m_View;
Math::CMatrix44 m_Projection;
Math::CVector m_Position;
Math::CVector m_Direction;
be<float> m_AspectRatio;
be<float> m_Near;
be<float> m_Far;
};
}
@@ -0,0 +1,32 @@
#pragma once
#include <SWA.inl>
#include <Hedgehog/Base/hhObject.h>
#include <Hedgehog/Universe/Engine/hhMessageProcess.h>
#include <Hedgehog/Universe/Engine/hhStateMachineMessageReceiver.h>
namespace Hedgehog::Universe
{
class CStateMachineBase : public IStateMachineMessageReceiver, public Base::CObject
{
public:
class CStateBase : public IMessageProcess
{
public:
SWA_INSERT_PADDING(0x08);
xpointer<void> m_pContext;
xpointer<CStateMachineBase> m_pStateMachine;
be<float> m_Time;
SWA_INSERT_PADDING(0x4C);
void* GetContextBase() const;
template<typename T>
T* GetContextBase() const;
};
SWA_INSERT_PADDING(0x60);
};
}
#include <Hedgehog/Universe/Engine/hhStateMachineBase.inl>
@@ -0,0 +1,13 @@
namespace Hedgehog::Universe
{
inline void* CStateMachineBase::CStateBase::GetContextBase() const
{
return m_pContext;
}
template<typename T>
inline T* CStateMachineBase::CStateBase::GetContextBase() const
{
return (T*)m_pContext.get();
}
}
@@ -0,0 +1,12 @@
#pragma once
#include <SWA.inl>
namespace Hedgehog::Universe
{
class IStateMachineMessageReceiver
{
public:
IStateMachineMessageReceiver(const swa_null_ctor&) {}
};
}
+10 -8
View File
@@ -27,11 +27,7 @@
#include "Hedgehog/Base/Type/hhSharedString.h" #include "Hedgehog/Base/Type/hhSharedString.h"
#include "Hedgehog/Base/hhObject.h" #include "Hedgehog/Base/hhObject.h"
#include "Hedgehog/Database/System/hhDatabaseData.h" #include "Hedgehog/Database/System/hhDatabaseData.h"
#include "Hedgehog/Math/Aabb.h"
#include "Hedgehog/Math/Matrix.h"
#include "Hedgehog/Math/Quaternion.h"
#include "Hedgehog/Math/Vector.h" #include "Hedgehog/Math/Vector.h"
#include "Hedgehog/MirageCore/Camera/hhCamera.h"
#include "Hedgehog/MirageCore/Misc/hhVertexDeclarationPtr.h" #include "Hedgehog/MirageCore/Misc/hhVertexDeclarationPtr.h"
#include "Hedgehog/MirageCore/RenderData/hhMaterialData.h" #include "Hedgehog/MirageCore/RenderData/hhMaterialData.h"
#include "Hedgehog/MirageCore/RenderData/hhMeshData.h" #include "Hedgehog/MirageCore/RenderData/hhMeshData.h"
@@ -51,6 +47,8 @@
#include "Hedgehog/Sparkle/hhParticleMaterial.h" #include "Hedgehog/Sparkle/hhParticleMaterial.h"
#include "Hedgehog/Universe/Engine/hhMessageActor.h" #include "Hedgehog/Universe/Engine/hhMessageActor.h"
#include "Hedgehog/Universe/Engine/hhMessageProcess.h" #include "Hedgehog/Universe/Engine/hhMessageProcess.h"
#include "Hedgehog/Universe/Engine/hhStateMachineBase.h"
#include "Hedgehog/Universe/Engine/hhStateMachineMessageReceiver.h"
#include "Hedgehog/Universe/Engine/hhUpdateInfo.h" #include "Hedgehog/Universe/Engine/hhUpdateInfo.h"
#include "Hedgehog/Universe/Engine/hhUpdateUnit.h" #include "Hedgehog/Universe/Engine/hhUpdateUnit.h"
#include "Hedgehog/Universe/Thread/hhParallelJob.h" #include "Hedgehog/Universe/Thread/hhParallelJob.h"
@@ -61,7 +59,8 @@
#include "SWA/CSD/CsdTexListMirage.h" #include "SWA/CSD/CsdTexListMirage.h"
#include "SWA/CSD/GameObjectCSD.h" #include "SWA/CSD/GameObjectCSD.h"
#include "SWA/Camera/Camera.h" #include "SWA/Camera/Camera.h"
#include "SWA/Globals.h" #include "SWA/Camera/CameraController.h"
#include "SWA/CharacterUtility/CharacterProxy.h"
#include "SWA/HUD/GeneralWindow/GeneralWindow.h" #include "SWA/HUD/GeneralWindow/GeneralWindow.h"
#include "SWA/HUD/Loading/Loading.h" #include "SWA/HUD/Loading/Loading.h"
#include "SWA/HUD/Pause/HudPause.h" #include "SWA/HUD/Pause/HudPause.h"
@@ -76,10 +75,9 @@
#include "SWA/Inspire/InspireTextureAnimationInfo.h" #include "SWA/Inspire/InspireTextureAnimationInfo.h"
#include "SWA/Inspire/InspireTextureOverlay.h" #include "SWA/Inspire/InspireTextureOverlay.h"
#include "SWA/Inspire/InspireTextureOverlayInfo.h" #include "SWA/Inspire/InspireTextureOverlayInfo.h"
#include "SWA/Menu/MenuWindowBase.h"
#include "SWA/Movie/MovieDisplayer.h" #include "SWA/Movie/MovieDisplayer.h"
#include "SWA/Movie/MovieManager.h" #include "SWA/Movie/MovieManager.h"
#include "SWA/Path/PathController.h"
#include "SWA/Path/Animation/PathAnimation.h"
#include "SWA/Player/Character/EvilSonic/EvilSonic.h" #include "SWA/Player/Character/EvilSonic/EvilSonic.h"
#include "SWA/Player/Character/EvilSonic/EvilSonicContext.h" #include "SWA/Player/Character/EvilSonic/EvilSonicContext.h"
#include "SWA/Player/Character/EvilSonic/Hud/EvilHudGuide.h" #include "SWA/Player/Character/EvilSonic/Hud/EvilHudGuide.h"
@@ -98,14 +96,18 @@
#include "SWA/System/GameMode/GameMode.h" #include "SWA/System/GameMode/GameMode.h"
#include "SWA/System/GameMode/GameModeStage.h" #include "SWA/System/GameMode/GameModeStage.h"
#include "SWA/System/GameMode/GameModeStageMovie.h" #include "SWA/System/GameMode/GameModeStageMovie.h"
#include "SWA/System/GameMode/GameModeStageTitle.h"
#include "SWA/System/GameMode/Title/TitleMenu.h" #include "SWA/System/GameMode/Title/TitleMenu.h"
#include "SWA/System/GameMode/Title/TitleStateBase.h" #include "SWA/System/GameMode/Title/TitleStateBase.h"
#include "SWA/System/GameMode/Title/TitleStateIntro.h"
#include "SWA/System/GameMode/Title/TitleStateWorldMap.h"
#include "SWA/System/GameMode/WorldMap/WorldMapCamera.h"
#include "SWA/System/GameMode/WorldMap/WorldMapCursor.h"
#include "SWA/System/GameObject.h" #include "SWA/System/GameObject.h"
#include "SWA/System/GameParameter.h" #include "SWA/System/GameParameter.h"
#include "SWA/System/GammaController.h" #include "SWA/System/GammaController.h"
#include "SWA/System/InputState.h" #include "SWA/System/InputState.h"
#include "SWA/System/PadState.h" #include "SWA/System/PadState.h"
#include "SWA/System/StageManager.h"
#include "SWA/System/World.h" #include "SWA/System/World.h"
#include "boost/smart_ptr/make_shared_object.h" #include "boost/smart_ptr/make_shared_object.h"
#include "boost/smart_ptr/shared_ptr.h" #include "boost/smart_ptr/shared_ptr.h"
@@ -3,7 +3,7 @@ namespace SWA
inline boost::shared_ptr<CCsdProject> CCsdDatabaseWrapper::GetCsdProject(const Hedgehog::Base::CSharedString& in_rName) inline boost::shared_ptr<CCsdProject> CCsdDatabaseWrapper::GetCsdProject(const Hedgehog::Base::CSharedString& in_rName)
{ {
boost::shared_ptr<CCsdProject> spCsdProject; boost::shared_ptr<CCsdProject> spCsdProject;
GuestToHostFunction<void>(0x825E2B40, &in_rName, this, &spCsdProject, 0); GuestToHostFunction<void>(sub_825E2B40, &in_rName, this, &spCsdProject, 0);
return spCsdProject; return spCsdProject;
} }
} }
-1
View File
@@ -9,7 +9,6 @@ namespace SWA
{ {
public: public:
xpointer<void> m_pVftable; xpointer<void> m_pVftable;
// SWA::CCamera::MyCamera
SWA_INSERT_PADDING(0xC4); SWA_INSERT_PADDING(0xC4);
be<float> m_VertAspectRatio; be<float> m_VertAspectRatio;
SWA_INSERT_PADDING(0x48); SWA_INSERT_PADDING(0x48);
@@ -0,0 +1,17 @@
#pragma once
#include <SWA.inl>
namespace SWA
{
class CCameraController : public Hedgehog::Universe::CStateMachineBase::CStateBase
{
public:
SWA_INSERT_PADDING(0x04);
be<float> m_FieldOfView;
SWA_INSERT_PADDING(0x68);
};
SWA_ASSERT_OFFSETOF(CCameraController, m_FieldOfView, 0x64);
SWA_ASSERT_SIZEOF(CCameraController, 0xD0);
}
@@ -0,0 +1,14 @@
#pragma once
#include <Hedgehog/Math/Vector.h>
namespace SWA
{
class CCharacterProxy
{
public:
SWA_INSERT_PADDING(0x120);
Hedgehog::Math::CVector m_Position;
Hedgehog::Math::CVector m_Velocity;
};
}
-69
View File
@@ -1,69 +0,0 @@
#pragma once
#include <SWA.inl>
namespace SWA
{
struct SGlobals
{
// ms_DrawLightFieldSamplingPoint: サンプリング点をデバッグ表示
static inline bool* ms_DrawLightFieldSamplingPoint;
// ms_IgnoreLightFieldData: データを無視する
static inline bool* ms_IgnoreLightFieldData;
// IsCollisionRender
static inline bool* ms_IsCollisionRender;
// N/A
static inline bool* ms_IsLoading;
// IsObjectCollisionRender
static inline bool* ms_IsObjectCollisionRender;
// ms_IsRenderDebugDraw: デバッグ描画
static inline bool* ms_IsRenderDebugDraw;
// ms_IsRenderDebugDrawText: デバッグ文字描画
static inline bool* ms_IsRenderDebugDrawText;
// ms_IsRenderDebugPositionDraw: デバッグ位置描画
static inline bool* ms_IsRenderDebugPositionDraw;
// ms_IsRenderGameMainHud: ゲームメインHUD 描画
static inline bool* ms_IsRenderGameMainHud;
// ms_IsRenderHud: 全 HUD 描画
static inline bool* ms_IsRenderHud;
// ms_IsRenderHudPause: ポーズメニュー 描画
static inline bool* ms_IsRenderHudPause;
// IsTriggerRender
static inline bool* ms_IsTriggerRender;
// ms_LightFieldDebug: 値をデバッグ表示
static inline bool* ms_LightFieldDebug;
// VisualizeLoadedLevel: ミップレベルを視覚化 赤=0, 緑=1, 青=2, 黄=未ロード
static inline bool* ms_VisualizeLoadedLevel;
static void Init()
{
ms_DrawLightFieldSamplingPoint = (bool*)MmGetHostAddress(0x83367BCE);
ms_IgnoreLightFieldData = (bool*)MmGetHostAddress(0x83367BCF);
ms_IsCollisionRender = (bool*)MmGetHostAddress(0x833678A6);
ms_IsLoading = (bool*)MmGetHostAddress(0x83367A4C);
ms_IsObjectCollisionRender = (bool*)MmGetHostAddress(0x83367905);
ms_IsRenderDebugDraw = (bool*)MmGetHostAddress(0x8328BB23);
ms_IsRenderDebugDrawText = (bool*)MmGetHostAddress(0x8328BB25);
ms_IsRenderDebugPositionDraw = (bool*)MmGetHostAddress(0x8328BB24);
ms_IsRenderGameMainHud = (bool*)MmGetHostAddress(0x8328BB27);
ms_IsRenderHud = (bool*)MmGetHostAddress(0x8328BB26);
ms_IsRenderHudPause = (bool*)MmGetHostAddress(0x8328BB28);
ms_IsTriggerRender = (bool*)MmGetHostAddress(0x83367904);
ms_LightFieldDebug = (bool*)MmGetHostAddress(0x83367BCD);
ms_VisualizeLoadedLevel = (bool*)MmGetHostAddress(0x833678C1);
}
};
}
@@ -0,0 +1,12 @@
#pragma once
#include <SWA.inl>
namespace SWA
{
class CMenuWindowBase
{
public:
SWA_INSERT_PADDING(0x10);
};
}
@@ -1,22 +0,0 @@
#pragma once
namespace SWA::PathAnimation
{
class Entity
{
public:
xpointer<void> m_pVftable;
SWA_INSERT_PADDING(0x18);
};
class Controller
{
public:
xpointer<void> m_pVftable;
SWA_INSERT_PADDING(0x1C);
be<float> m_DistanceAlongPath;
};
SWA_ASSERT_OFFSETOF(Controller, m_DistanceAlongPath, 0x20);
}
@@ -1,13 +0,0 @@
#pragma once
#include "Animation/PathAnimation.h"
namespace SWA
{
class CPathController
{
public:
be<uint32_t> m_Field000;
be<uint32_t> m_Field004;
boost::shared_ptr<PathAnimation::Controller> m_spPathAnimationController;
};
}
@@ -29,8 +29,7 @@ namespace SWA
SWA_INSERT_PADDING(0x10); SWA_INSERT_PADDING(0x10);
}; };
SWA_INSERT_PADDING(0x10); SWA_INSERT_PADDING(0x1C);
hh::map<Hedgehog::Base::CSharedString, boost::shared_ptr<SWA::CWorld>> m_Worlds;
boost::shared_ptr<Hedgehog::Database::CDatabase> m_spDatabase; boost::shared_ptr<Hedgehog::Database::CDatabase> m_spDatabase;
SWA_INSERT_PADDING(0x88); SWA_INSERT_PADDING(0x88);
Hedgehog::Base::CSharedString m_StageName; Hedgehog::Base::CSharedString m_StageName;
@@ -4,10 +4,9 @@
namespace SWA namespace SWA
{ {
class CGameMode // : Hedgehog::Universe::TStateMachine<SWA::CGame>::TState class CGameMode : public Hedgehog::Universe::CStateMachineBase::CStateBase
{ {
public: public:
SWA_INSERT_PADDING(0x60); // base
SWA_INSERT_PADDING(0x08); SWA_INSERT_PADDING(0x08);
}; };
} }
@@ -0,0 +1,14 @@
#pragma once
#include <SWA.inl>
namespace SWA
{
class CGameModeStageTitle : public CGameModeStage
{
public:
SWA_INSERT_PADDING(0x0E);
bool m_IsPlayingAdvertiseMovie;
be<float> m_AdvertiseMovieWaitTime;
};
}
@@ -4,19 +4,14 @@
namespace SWA namespace SWA
{ {
class CTitleStateBase // : Hedgehog::Universe::TStateMachine<SWA::CTitleManager>::TState class CTitleStateBase : public Hedgehog::Universe::CStateMachineBase::CStateBase
{ {
public: public:
class CMember class CTitleStateContext
{ {
public: public:
SWA_INSERT_PADDING(0x1E8); SWA_INSERT_PADDING(0x1E8);
xpointer<CTitleMenu> m_pTitleMenu; xpointer<CTitleMenu> m_pTitleMenu;
}; };
SWA_INSERT_PADDING(0x08);
xpointer<CMember> m_pMember;
SWA_INSERT_PADDING(0x5C);
be<uint32_t> m_State;
}; };
} }
@@ -0,0 +1,8 @@
#pragma once
#include <SWA.inl>
namespace SWA
{
class CTitleStateIntro : public CTitleStateBase {};
}
@@ -0,0 +1,14 @@
#pragma once
#include <SWA.inl>
#include <SWA/System/GameMode/WorldMap/WorldMapCursor.h>
namespace SWA
{
class CTitleStateWorldMap : public CTitleStateBase
{
public:
SWA_INSERT_PADDING(0x08);
xpointer<CWorldMapCursor> m_pWorldMapCursor;
};
}
@@ -0,0 +1,26 @@
#pragma once
#include <SWA.inl>
namespace SWA
{
class CWorldMapCamera : public CCameraController
{
public:
be<float> m_Pitch;
be<float> m_Yaw;
be<float> m_Distance;
be<float> m_RotationSpeed;
SWA_INSERT_PADDING(0x08);
bool m_CanMove;
SWA_INSERT_PADDING(0x34);
be<float> m_TiltToEarthTransitionSpeed;
};
SWA_ASSERT_OFFSETOF(CWorldMapCamera, m_Pitch, 0xD0);
SWA_ASSERT_OFFSETOF(CWorldMapCamera, m_Yaw, 0xD4);
SWA_ASSERT_OFFSETOF(CWorldMapCamera, m_Distance, 0xD8);
SWA_ASSERT_OFFSETOF(CWorldMapCamera, m_RotationSpeed, 0xDC);
SWA_ASSERT_OFFSETOF(CWorldMapCamera, m_CanMove, 0xE8);
SWA_ASSERT_OFFSETOF(CWorldMapCamera, m_TiltToEarthTransitionSpeed, 0x120);
}
@@ -0,0 +1,24 @@
#pragma once
#include <SWA.inl>
namespace SWA
{
class CWorldMapCursor : public CMenuWindowBase
{
public:
SWA_INSERT_PADDING(0x24);
be<float> m_LeftStickVertical;
be<float> m_LeftStickHorizontal;
bool m_IsCursorMoving;
SWA_INSERT_PADDING(0x07);
be<float> m_CursorY;
be<float> m_CursorX;
};
SWA_ASSERT_OFFSETOF(CWorldMapCursor, m_LeftStickVertical, 0x34);
SWA_ASSERT_OFFSETOF(CWorldMapCursor, m_LeftStickHorizontal, 0x38);
SWA_ASSERT_OFFSETOF(CWorldMapCursor, m_IsCursorMoving, 0x3C);
SWA_ASSERT_OFFSETOF(CWorldMapCursor, m_CursorY, 0x44);
SWA_ASSERT_OFFSETOF(CWorldMapCursor, m_CursorX, 0x48);
}
@@ -1,30 +0,0 @@
#pragma once
#include "SWA.inl"
#include "Hedgehog/Base/Thread/hhSynchronizedObject.h"
#include "Hedgehog/Universe/Engine/hhMessageActor.h"
#include "SWA/System/GameObject.h"
namespace SWA
{
class CStageManager //: public SWA::CGameObject, public Hedgehog::Base::CSynchronizedObject
{
public:
SWA_INSERT_PADDING(0xC4);
boost::shared_ptr<SWA::CPathController> m_spStageGuidePathController; //xpointer<SWA::CPathController> m_pStageGuidePathController;
SWA_INSERT_PADDING(0x4);
Hedgehog::Math::CVector m_PlayerPosition;
be<float> m_Field0DC; // Sonic's air distance from path??
SWA_INSERT_PADDING(0x3C);
be<float> m_StageGuidePathRatio; // Not updated in retail
be<float> m_StageGuidePathLength;
SWA_INSERT_PADDING(0x9C);
};
SWA_ASSERT_OFFSETOF(CStageManager, m_spStageGuidePathController, 0xC4);
SWA_ASSERT_OFFSETOF(CStageManager, m_PlayerPosition, 0xD0);
SWA_ASSERT_OFFSETOF(CStageManager, m_StageGuidePathRatio, 0x11C);
SWA_ASSERT_OFFSETOF(CStageManager, m_StageGuidePathLength, 0x120);
SWA_ASSERT_SIZEOF(CStageManager, 0x1C0);
}
+1 -13
View File
@@ -12,21 +12,9 @@ namespace SWA
class CMember class CMember
{ {
public: public:
//boost::shared_ptr<Hedgehog::Mirage::CRenderScene> m_spRenderScene; SWA_INSERT_PADDING(0x80);
//Hedgehog::Base::CSharedString m_Name;
SWA_INSERT_PADDING(0xC);
boost::shared_ptr<CCamera> m_spCamera;
boost::shared_ptr<CCamera> m_spOverrideCamera;
SWA_INSERT_PADDING(0x64);
}; };
xpointer<CMember> m_pMember; xpointer<CMember> m_pMember;
boost::shared_ptr<CCamera> GetCamera() const;
}; };
//SWA_ASSERT_OFFSETOF(CWorld::CMember, m_spCamera, 0xC);
//SWA_ASSERT_SIZEOF(CWorld::CMember, 0x80);
} }
#include "World.inl"
-7
View File
@@ -1,7 +0,0 @@
namespace SWA
{
inline boost::shared_ptr<CCamera> CWorld::GetCamera() const
{
return m_pMember->m_spOverrideCamera ? m_pMember->m_spOverrideCamera : m_pMember->m_spCamera;
}
}
+1 -3
View File
@@ -1,5 +1,4 @@
#include <app.h> #include <app.h>
#include <api/SWA.h>
#include <gpu/video.h> #include <gpu/video.h>
#include <install/installer.h> #include <install/installer.h>
#include <kernel/function.h> #include <kernel/function.h>
@@ -8,6 +7,7 @@
#include <patches/inspire_patches.h> #include <patches/inspire_patches.h>
#include <ui/game_window.h> #include <ui/game_window.h>
#include <user/config.h> #include <user/config.h>
#include <user/paths.h>
void App::Restart(std::vector<std::string> restartArgs) void App::Restart(std::vector<std::string> restartArgs)
{ {
@@ -34,8 +34,6 @@ PPC_FUNC(sub_824EB490)
App::s_isMissingDLC = !Installer::checkAllDLC(GetGamePath()); App::s_isMissingDLC = !Installer::checkAllDLC(GetGamePath());
App::s_language = Config::Language; App::s_language = Config::Language;
SWA::SGlobals::Init();
__imp__sub_824EB490(ctx, base); __imp__sub_824EB490(ctx, base);
} }
+1
View File
@@ -9,6 +9,7 @@ public:
static inline bool s_isMissingDLC; static inline bool s_isMissingDLC;
static inline bool s_isLoading; static inline bool s_isLoading;
static inline bool s_isWerehog; static inline bool s_isWerehog;
static inline bool s_isSaveDataCorrupt;
static inline ELanguage s_language; static inline ELanguage s_language;
+1 -2
View File
@@ -7,11 +7,10 @@
// Number of samples in a frame // Number of samples in a frame
#define XAUDIO_NUM_SAMPLES 256 #define XAUDIO_NUM_SAMPLES 256
#ifdef SWA_IMPL
void XAudioInitializeSystem(); void XAudioInitializeSystem();
void XAudioRegisterClient(PPCFunc* callback, uint32_t param); void XAudioRegisterClient(PPCFunc* callback, uint32_t param);
void XAudioSubmitFrame(void* samples); void XAudioSubmitFrame(void* samples);
#endif void XAudioConfigValueChangedCallback(class IConfigDef* configDef);
uint32_t XAudioRegisterRenderDriverClient(be<uint32_t>* callback, be<uint32_t>* driver); uint32_t XAudioRegisterRenderDriverClient(be<uint32_t>* callback, be<uint32_t>* driver);
uint32_t XAudioUnregisterRenderDriverClient(uint32_t driver); uint32_t XAudioUnregisterRenderDriverClient(uint32_t driver);
+44 -11
View File
@@ -1,26 +1,29 @@
#include "sdl2_driver.h" #include <apu/audio.h>
#include <cpu/guest_thread.h> #include <cpu/guest_thread.h>
#include <kernel/heap.h> #include <kernel/heap.h>
#include <user/config.h>
static PPCFunc* g_clientCallback{}; static PPCFunc* g_clientCallback{};
static uint32_t g_clientCallbackParam{}; // pointer in guest memory static uint32_t g_clientCallbackParam{}; // pointer in guest memory
static SDL_AudioDeviceID g_audioDevice{}; static SDL_AudioDeviceID g_audioDevice{};
static bool g_downMixToStereo; static bool g_downMixToStereo;
void XAudioInitializeSystem() static void CreateAudioDevice()
{ {
SDL_SetHint(SDL_HINT_AUDIO_CATEGORY, "playback"); if (g_audioDevice != NULL)
SDL_SetHint(SDL_HINT_AUDIO_DEVICE_APP_NAME, "Unleashed Recompiled"); SDL_CloseAudioDevice(g_audioDevice);
SDL_InitSubSystem(SDL_INIT_AUDIO);
bool surround = Config::ChannelConfiguration == EChannelConfiguration::Surround;
int allowedChanges = surround ? SDL_AUDIO_ALLOW_CHANNELS_CHANGE : 0;
SDL_AudioSpec desired{}, obtained{}; SDL_AudioSpec desired{}, obtained{};
desired.freq = XAUDIO_SAMPLES_HZ; desired.freq = XAUDIO_SAMPLES_HZ;
desired.format = AUDIO_F32SYS; desired.format = AUDIO_F32SYS;
desired.channels = XAUDIO_NUM_CHANNELS; desired.channels = surround ? XAUDIO_NUM_CHANNELS : 2;
desired.samples = XAUDIO_NUM_SAMPLES; desired.samples = XAUDIO_NUM_SAMPLES;
g_audioDevice = SDL_OpenAudioDevice(nullptr, 0, &desired, &obtained, SDL_AUDIO_ALLOW_CHANNELS_CHANGE); g_audioDevice = SDL_OpenAudioDevice(nullptr, 0, &desired, &obtained, allowedChanges);
if (obtained.channels != 2 && obtained.channels != XAUDIO_NUM_CHANNELS) if (obtained.channels != 2 && obtained.channels != XAUDIO_NUM_CHANNELS) // This check may fail only when surround sound is enabled.
{ {
SDL_CloseAudioDevice(g_audioDevice); SDL_CloseAudioDevice(g_audioDevice);
g_audioDevice = SDL_OpenAudioDevice(nullptr, 0, &desired, &obtained, 0); g_audioDevice = SDL_OpenAudioDevice(nullptr, 0, &desired, &obtained, 0);
@@ -29,7 +32,16 @@ void XAudioInitializeSystem()
g_downMixToStereo = (obtained.channels == 2); g_downMixToStereo = (obtained.channels == 2);
} }
void XAudioInitializeSystem()
{
SDL_SetHint(SDL_HINT_AUDIO_CATEGORY, "playback");
SDL_SetHint(SDL_HINT_AUDIO_DEVICE_APP_NAME, "Unleashed Recompiled");
SDL_InitSubSystem(SDL_INIT_AUDIO);
CreateAudioDevice();
}
static std::unique_ptr<std::thread> g_audioThread; static std::unique_ptr<std::thread> g_audioThread;
static volatile bool g_audioThreadShouldExit;
static void AudioThread() static void AudioThread()
{ {
@@ -39,7 +51,7 @@ static void AudioThread()
size_t channels = g_downMixToStereo ? 2 : XAUDIO_NUM_CHANNELS; size_t channels = g_downMixToStereo ? 2 : XAUDIO_NUM_CHANNELS;
while (true) while (!g_audioThreadShouldExit)
{ {
uint32_t queuedAudioSize = SDL_GetQueuedAudioSize(g_audioDevice); uint32_t queuedAudioSize = SDL_GetQueuedAudioSize(g_audioDevice);
constexpr size_t MAX_LATENCY = 10; constexpr size_t MAX_LATENCY = 10;
@@ -62,6 +74,13 @@ static void AudioThread()
} }
} }
static void CreateAudioThread()
{
SDL_PauseAudioDevice(g_audioDevice, 0);
g_audioThreadShouldExit = false;
g_audioThread = std::make_unique<std::thread>(AudioThread);
}
void XAudioRegisterClient(PPCFunc* callback, uint32_t param) void XAudioRegisterClient(PPCFunc* callback, uint32_t param)
{ {
auto* pClientParam = static_cast<uint32_t*>(g_userHeap.Alloc(sizeof(param))); auto* pClientParam = static_cast<uint32_t*>(g_userHeap.Alloc(sizeof(param)));
@@ -70,8 +89,7 @@ void XAudioRegisterClient(PPCFunc* callback, uint32_t param)
g_clientCallbackParam = g_memory.MapVirtual(pClientParam); g_clientCallbackParam = g_memory.MapVirtual(pClientParam);
g_clientCallback = callback; g_clientCallback = callback;
SDL_PauseAudioDevice(g_audioDevice, 0); CreateAudioThread();
g_audioThread = std::make_unique<std::thread>(AudioThread);
} }
void XAudioSubmitFrame(void* samples) void XAudioSubmitFrame(void* samples)
@@ -119,3 +137,18 @@ void XAudioSubmitFrame(void* samples)
SDL_QueueAudio(g_audioDevice, &audioFrames, sizeof(audioFrames)); SDL_QueueAudio(g_audioDevice, &audioFrames, sizeof(audioFrames));
} }
} }
void XAudioConfigValueChangedCallback(IConfigDef* configDef)
{
if (configDef == &Config::ChannelConfiguration)
{
if (g_audioThread->joinable())
{
g_audioThreadShouldExit = true;
g_audioThread->join();
}
CreateAudioDevice();
CreateAudioThread();
}
}
-3
View File
@@ -1,3 +0,0 @@
#pragma once
#include <apu/audio.h>
@@ -1,121 +0,0 @@
#include <stdafx.h>
#include "xaudio_driver.h"
#include <xaudio2.h>
#include <cpu/guest_thread.h>
#include <cpu/ppc_context.h>
#include <kernel/heap.h>
#define XAUDIO_DRIVER_KEY (uint32_t)('XAUD')
PPCFunc* volatile g_clientCallback{};
DWORD g_clientCallbackParam{}; // pointer in guest memory
DWORD g_driverThread{};
// TODO: Should use a counted ptr
IXAudio2* g_audio{};
IXAudio2MasteringVoice* g_masteringVoice{};
IXAudio2SourceVoice* g_sourceVoice{};
constexpr uint32_t g_semaphoreCount = 16;
constexpr uint32_t g_audioFrameSize = 256 * 6;
HANDLE g_audioSemaphore{ CreateSemaphoreA(nullptr, g_semaphoreCount, g_semaphoreCount, nullptr) };
uint32_t g_audioFrames[g_audioFrameSize * g_semaphoreCount];
uint32_t g_audioFrameIndex = 0;
class VoiceCallback : public IXAudio2VoiceCallback
{
STDMETHOD_(void, OnVoiceProcessingPassStart)(UINT32 BytesRequired) override {}
STDMETHOD_(void, OnVoiceProcessingPassEnd)() override {}
STDMETHOD_(void, OnBufferStart)(void* pBufferContext) override {}
STDMETHOD_(void, OnBufferEnd)(void* pBufferContext) override
{
ReleaseSemaphore(g_audioSemaphore, 1, nullptr);
}
STDMETHOD_(void, OnStreamEnd)() override {}
STDMETHOD_(void, OnLoopEnd)(void* pBufferContext) override {}
STDMETHOD_(void, OnVoiceError)(void* pBufferContext, HRESULT Error) override {}
} gVoiceCallback;
PPC_FUNC(DriverLoop)
{
GuestThread::SetThreadName(GetCurrentThreadId(), "Audio Driver");
while (true)
{
if (!g_clientCallback)
{
continue;
}
WaitForSingleObject(g_audioSemaphore, INFINITE);
ctx.r3.u64 = g_clientCallbackParam;
g_clientCallback(ctx, g_memory.base);
}
}
void XAudioInitializeSystem()
{
if (g_audio)
{
return;
}
//reinterpret_cast<decltype(&XAudio2Create)>(
// GetProcAddress(LoadLibraryA("XAudio2_8.dll"), "XAudio2Create"))(&gAudio, 0, 1);
XAudio2Create(&g_audio);
g_audio->CreateMasteringVoice(&g_masteringVoice);
WAVEFORMATIEEEFLOATEX format{};
format.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
format.Format.cbSize = sizeof(format) - sizeof(format.Format);
format.Format.nChannels = XAUDIO_NUM_CHANNELS;
format.Format.nSamplesPerSec = XAUDIO_SAMPLES_HZ;
format.Format.wBitsPerSample = XAUDIO_SAMPLE_BITS;
format.Format.nBlockAlign = (format.Format.nChannels * format.Format.wBitsPerSample) / 8;
format.Format.nAvgBytesPerSec = format.Format.nSamplesPerSec * format.Format.nBlockAlign;
format.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
format.Samples.wValidBitsPerSample = format.Format.wBitsPerSample;
format.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_CENTER | SPEAKER_FRONT_RIGHT |
SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT;
g_audio->CreateSourceVoice(&g_sourceVoice, &format.Format, 0, 1024, &gVoiceCallback);
g_sourceVoice->Start();
KeInsertHostFunction(XAUDIO_DRIVER_KEY, DriverLoop);
GuestThread::Start({ XAUDIO_DRIVER_KEY, 0, 0 }, nullptr);
}
void XAudioRegisterClient(PPCFunc* callback, uint32_t param)
{
auto* pClientParam = static_cast<uint32_t*>(g_userHeap.Alloc(sizeof(param)));
ByteSwapInplace(param);
*pClientParam = param;
g_clientCallbackParam = g_memory.MapVirtual(pClientParam);
g_clientCallback = callback;
}
void XAudioSubmitFrame(void* samples)
{
uint32_t* audioFrame = &g_audioFrames[g_audioFrameSize * g_audioFrameIndex];
g_audioFrameIndex = (g_audioFrameIndex + 1) % g_semaphoreCount;
for (size_t i = 0; i < XAUDIO_NUM_SAMPLES; i++)
{
for (size_t j = 0; j < 6; j++)
audioFrame[i * XAUDIO_NUM_CHANNELS + j] = ByteSwap(((uint32_t*)samples)[j * XAUDIO_NUM_SAMPLES + i]);
}
XAUDIO2_BUFFER buffer{};
buffer.pAudioData = (BYTE*)audioFrame;
buffer.AudioBytes = XAUDIO_NUM_SAMPLES * XAUDIO_NUM_CHANNELS * sizeof(float);
buffer.PlayLength = XAUDIO_NUM_SAMPLES;
g_sourceVoice->SubmitSourceBuffer(&buffer);
}
@@ -1,2 +0,0 @@
#pragma once
#include <apu/audio.h>
+6
View File
@@ -22,6 +22,7 @@ enum class ImGuiCallback : int32_t
SetOutline = -6, SetOutline = -6,
SetProceduralOrigin = -7, SetProceduralOrigin = -7,
// -8 is ImDrawCallback_ResetRenderState, don't use! // -8 is ImDrawCallback_ResetRenderState, don't use!
SetAdditive = -9
}; };
union ImGuiCallbackData union ImGuiCallbackData
@@ -64,6 +65,11 @@ union ImGuiCallbackData
{ {
float proceduralOrigin[2]; float proceduralOrigin[2];
} setProceduralOrigin; } setProceduralOrigin;
struct
{
bool enabled;
} setAdditive;
}; };
extern ImGuiCallbackData* AddImGuiCallback(ImGuiCallback callback); extern ImGuiCallbackData* AddImGuiCallback(ImGuiCallback callback);
@@ -1127,7 +1127,7 @@ namespace plume {
desc.srcBlend = RenderBlend::SRC_ALPHA; desc.srcBlend = RenderBlend::SRC_ALPHA;
desc.dstBlend = RenderBlend::INV_SRC_ALPHA; desc.dstBlend = RenderBlend::INV_SRC_ALPHA;
desc.blendOp = RenderBlendOperation::ADD; desc.blendOp = RenderBlendOperation::ADD;
desc.srcBlendAlpha = RenderBlend::ONE; desc.srcBlendAlpha = RenderBlend::SRC_ALPHA;
desc.dstBlendAlpha = RenderBlend::INV_SRC_ALPHA; desc.dstBlendAlpha = RenderBlend::INV_SRC_ALPHA;
desc.blendOpAlpha = RenderBlendOperation::ADD; desc.blendOpAlpha = RenderBlendOperation::ADD;
return desc; return desc;
@@ -1269,9 +1269,9 @@ namespace plume {
RenderFilter minFilter = RenderFilter::LINEAR; RenderFilter minFilter = RenderFilter::LINEAR;
RenderFilter magFilter = RenderFilter::LINEAR; RenderFilter magFilter = RenderFilter::LINEAR;
RenderMipmapMode mipmapMode = RenderMipmapMode::LINEAR; RenderMipmapMode mipmapMode = RenderMipmapMode::LINEAR;
RenderTextureAddressMode addressU = RenderTextureAddressMode::WRAP; RenderTextureAddressMode addressU = RenderTextureAddressMode::CLAMP;
RenderTextureAddressMode addressV = RenderTextureAddressMode::WRAP; RenderTextureAddressMode addressV = RenderTextureAddressMode::CLAMP;
RenderTextureAddressMode addressW = RenderTextureAddressMode::WRAP; RenderTextureAddressMode addressW = RenderTextureAddressMode::CLAMP;
float mipLODBias = 0.0f; float mipLODBias = 0.0f;
uint32_t maxAnisotropy = 16; uint32_t maxAnisotropy = 16;
bool anisotropyEnabled = false; bool anisotropyEnabled = false;
@@ -1,4 +1,4 @@
#include "../../../tools/ShaderRecomp/ShaderRecomp/shader_common.h" #include "../../../tools/XenosRecomp/XenosRecomp/shader_common.h"
#ifdef __spirv__ #ifdef __spirv__
@@ -1,4 +1,4 @@
#include "../../../tools/ShaderRecomp/ShaderRecomp/shader_common.h" #include "../../../tools/XenosRecomp/XenosRecomp/shader_common.h"
#ifdef __spirv__ #ifdef __spirv__
+1 -1
View File
@@ -1,4 +1,4 @@
#include "../../../tools/ShaderRecomp/ShaderRecomp/shader_common.h" #include "../../../tools/XenosRecomp/XenosRecomp/shader_common.h"
#ifdef __spirv__ #ifdef __spirv__
@@ -1,4 +1,4 @@
#include "../../../tools/ShaderRecomp/ShaderRecomp/shader_common.h" #include "../../../tools/XenosRecomp/XenosRecomp/shader_common.h"
#ifdef __spirv__ #ifdef __spirv__
@@ -1,4 +1,4 @@
#include "../../../tools/ShaderRecomp/ShaderRecomp/shader_common.h" #include "../../../tools/XenosRecomp/XenosRecomp/shader_common.h"
#ifdef __spirv__ #ifdef __spirv__
@@ -1,4 +1,4 @@
#include "../../../tools/ShaderRecomp/ShaderRecomp/shader_common.h" #include "../../../tools/XenosRecomp/XenosRecomp/shader_common.h"
#ifdef __spirv__ #ifdef __spirv__
@@ -1,6 +1,6 @@
#pragma once #pragma once
#include "../../../tools/ShaderRecomp/ShaderRecomp/shader_common.h" #include "../../../tools/XenosRecomp/XenosRecomp/shader_common.h"
#ifdef __spirv__ #ifdef __spirv__
+102 -97
View File
@@ -10,14 +10,13 @@
#include <decompressor.h> #include <decompressor.h>
#include <kernel/function.h> #include <kernel/function.h>
#include <kernel/heap.h> #include <kernel/heap.h>
#include <hid/hid_detail.h> #include <hid/hid.h>
#include <kernel/memory.h> #include <kernel/memory.h>
#include <kernel/xdbf.h> #include <kernel/xdbf.h>
#include <res/bc_diff/button_bc_diff.bin.h> #include <res/bc_diff/button_bc_diff.bin.h>
#include <res/font/im_font_atlas.dds.h> #include <res/font/im_font_atlas.dds.h>
#include <shader/shader_cache.h> #include <shader/shader_cache.h>
#include <SWA.h> #include <SWA.h>
#include <ui/reddog/reddog_manager.h>
#include <ui/achievement_menu.h> #include <ui/achievement_menu.h>
#include <ui/achievement_overlay.h> #include <ui/achievement_overlay.h>
#include <ui/button_guide.h> #include <ui/button_guide.h>
@@ -27,7 +26,6 @@
#include <ui/options_menu.h> #include <ui/options_menu.h>
#include <ui/sdl_listener.h> #include <ui/sdl_listener.h>
#include <ui/game_window.h> #include <ui/game_window.h>
#include <ui/imgui_utils.h>
#include <patches/aspect_ratio_patches.h> #include <patches/aspect_ratio_patches.h>
#include <user/config.h> #include <user/config.h>
#include <xxHashMap.h> #include <xxHashMap.h>
@@ -36,9 +34,9 @@
#include <magic_enum/magic_enum.hpp> #include <magic_enum/magic_enum.hpp>
#endif #endif
#include "../../tools/ShaderRecomp/ShaderRecomp/shader_common.h" #include "../../tools/XenosRecomp/XenosRecomp/shader_common.h"
#ifdef SWA_D3D12 #ifdef UNLEASHED_RECOMP_D3D12
#include "shader/copy_vs.hlsl.dxil.h" #include "shader/copy_vs.hlsl.dxil.h"
#include "shader/csd_filter_ps.hlsl.dxil.h" #include "shader/csd_filter_ps.hlsl.dxil.h"
#include "shader/csd_no_tex_vs.hlsl.dxil.h" #include "shader/csd_no_tex_vs.hlsl.dxil.h"
@@ -86,7 +84,7 @@ extern "C"
namespace plume namespace plume
{ {
#ifdef SWA_D3D12 #ifdef UNLEASHED_RECOMP_D3D12
extern std::unique_ptr<RenderInterface> CreateD3D12Interface(); extern std::unique_ptr<RenderInterface> CreateD3D12Interface();
#endif #endif
#ifdef SDL_VULKAN_ENABLED #ifdef SDL_VULKAN_ENABLED
@@ -200,7 +198,7 @@ static void SetDirtyValue(bool& dirtyState, T& dest, const T& src)
} }
} }
#ifdef SWA_D3D12 #ifdef UNLEASHED_RECOMP_D3D12
static bool g_vulkan = false; static bool g_vulkan = false;
#else #else
static constexpr bool g_vulkan = true; static constexpr bool g_vulkan = true;
@@ -621,7 +619,7 @@ static void LoadEmbeddedResources()
g_shaderCache = std::make_unique<uint8_t[]>(g_spirvCacheDecompressedSize); g_shaderCache = std::make_unique<uint8_t[]>(g_spirvCacheDecompressedSize);
ZSTD_decompress(g_shaderCache.get(), g_spirvCacheDecompressedSize, g_compressedSpirvCache, g_spirvCacheCompressedSize); ZSTD_decompress(g_shaderCache.get(), g_spirvCacheDecompressedSize, g_compressedSpirvCache, g_spirvCacheCompressedSize);
} }
#ifdef SWA_D3D12 #ifdef UNLEASHED_RECOMP_D3D12
else else
{ {
g_shaderCache = std::make_unique<uint8_t[]>(g_dxilCacheDecompressedSize); g_shaderCache = std::make_unique<uint8_t[]>(g_dxilCacheDecompressedSize);
@@ -1113,7 +1111,7 @@ static GuestShader* g_csdShader;
static std::unique_ptr<GuestShader> g_enhancedMotionBlurShader; static std::unique_ptr<GuestShader> g_enhancedMotionBlurShader;
#ifdef SWA_D3D12 #ifdef UNLEASHED_RECOMP_D3D12
#define CREATE_SHADER(NAME) \ #define CREATE_SHADER(NAME) \
g_device->createShader( \ g_device->createShader( \
@@ -1125,7 +1123,7 @@ static std::unique_ptr<GuestShader> g_enhancedMotionBlurShader;
#else #else
#define CREATE_SHADER(NAME) \ #define CREATE_SHADER(NAME) \
g_device->createShader(g_##NAME##_spirv, sizeof(g_##NAME##_spirv), "main", RenderShaderFormat::SPIRV); g_device->createShader(g_##NAME##_spirv, sizeof(g_##NAME##_spirv), "main", RenderShaderFormat::SPIRV)
#endif #endif
@@ -1143,6 +1141,7 @@ static constexpr size_t SAMPLER_DESCRIPTOR_SIZE = 1024;
static std::unique_ptr<GuestTexture> g_imFontTexture; static std::unique_ptr<GuestTexture> g_imFontTexture;
static std::unique_ptr<RenderPipelineLayout> g_imPipelineLayout; static std::unique_ptr<RenderPipelineLayout> g_imPipelineLayout;
static std::unique_ptr<RenderPipeline> g_imPipeline; static std::unique_ptr<RenderPipeline> g_imPipeline;
static std::unique_ptr<RenderPipeline> g_imAdditivePipeline;
template<typename T> template<typename T>
static void ExecuteCopyCommandList(const T& function) static void ExecuteCopyCommandList(const T& function)
@@ -1194,16 +1193,9 @@ static void CreateImGuiBackend()
AchievementMenu::Init(); AchievementMenu::Init();
AchievementOverlay::Init(); AchievementOverlay::Init();
ButtonGuide::Init(); ButtonGuide::Init();
InstallerWizard::Init();
MessageWindow::Init(); MessageWindow::Init();
OptionsMenu::Init(); OptionsMenu::Init();
InstallerWizard::Init();
#if !_DEBUG
if (Config::Debug)
#endif
{
Reddog::Manager::Init();
}
ImGui_ImplSDL2_InitForOther(GameWindow::s_pWindow); ImGui_ImplSDL2_InitForOther(GameWindow::s_pWindow);
@@ -1318,6 +1310,9 @@ static void CreateImGuiBackend()
pipelineDesc.inputSlotsCount = 1; pipelineDesc.inputSlotsCount = 1;
g_imPipeline = g_device->createGraphicsPipeline(pipelineDesc); g_imPipeline = g_device->createGraphicsPipeline(pipelineDesc);
pipelineDesc.renderTargetBlend[0].dstBlend = RenderBlend::ONE;
g_imAdditivePipeline = g_device->createGraphicsPipeline(pipelineDesc);
#ifndef ENABLE_IM_FONT_ATLAS_SNAPSHOT #ifndef ENABLE_IM_FONT_ATLAS_SNAPSHOT
ImFontAtlasSnapshot snapshot; ImFontAtlasSnapshot snapshot;
snapshot.Snap(); snapshot.Snap();
@@ -1364,16 +1359,8 @@ static void CheckSwapChain()
if (g_needsResize) if (g_needsResize)
Video::ComputeViewportDimensions(); Video::ComputeViewportDimensions();
if (g_aspectRatio >= NARROW_ASPECT_RATIO) g_backBuffer->width = Video::s_viewportWidth;
{ g_backBuffer->height = Video::s_viewportHeight;
g_backBuffer->width = Video::s_viewportWidth * 720 / Video::s_viewportHeight;
g_backBuffer->height = 720;
}
else
{
g_backBuffer->width = 960;
g_backBuffer->height = Video::s_viewportHeight * 960 / Video::s_viewportWidth;
}
} }
static void BeginCommandList() static void BeginCommandList()
@@ -1457,7 +1444,7 @@ void Video::CreateHostDevice(const char *sdlVideoDriver)
GameWindow::Init(sdlVideoDriver); GameWindow::Init(sdlVideoDriver);
#ifdef SWA_D3D12 #ifdef UNLEASHED_RECOMP_D3D12
g_vulkan = DetectWine() || Config::GraphicsAPI == EGraphicsAPI::Vulkan; g_vulkan = DetectWine() || Config::GraphicsAPI == EGraphicsAPI::Vulkan;
#endif #endif
@@ -1469,7 +1456,7 @@ void Video::CreateHostDevice(const char *sdlVideoDriver)
#else #else
g_interface = CreateVulkanInterface(); g_interface = CreateVulkanInterface();
#endif #endif
#ifdef SWA_D3D12 #ifdef UNLEASHED_RECOMP_D3D12
else else
g_interface = CreateD3D12Interface(); g_interface = CreateD3D12Interface();
#endif #endif
@@ -1974,7 +1961,27 @@ static double g_applicationValues[PROFILER_VALUE_COUNT];
static Profiler g_presentProfiler; static Profiler g_presentProfiler;
static Profiler g_renderDirectorProfiler; static Profiler g_renderDirectorProfiler;
void Video::DrawCounter() static bool g_profilerVisible;
static bool g_profilerWasToggled;
static void DrawProfiler()
{
bool toggleProfiler = SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_F1] != 0;
if (!g_profilerWasToggled && toggleProfiler)
g_profilerVisible = !g_profilerVisible;
g_profilerWasToggled = toggleProfiler;
if (!g_profilerVisible)
return;
ImFont* font = ImFontAtlasSnapshot::GetFont("FOT-SeuratPro-M.otf");
float defaultScale = font->Scale;
font->Scale = ImGui::GetDefaultFont()->FontSize / font->FontSize;
ImGui::PushFont(font);
if (ImGui::Begin("Profiler", &g_profilerVisible))
{ {
g_applicationValues[g_profilerValueIndex] = App::s_deltaTime * 1000.0; g_applicationValues[g_profilerValueIndex] = App::s_deltaTime * 1000.0;
@@ -2018,33 +2025,18 @@ void Video::DrawCounter()
ImGui::Text("Physical Heap Allocated: %d MB", int32_t(physicalDiagnostics.allocated / (1024 * 1024))); ImGui::Text("Physical Heap Allocated: %d MB", int32_t(physicalDiagnostics.allocated / (1024 * 1024)));
ImGui::NewLine(); ImGui::NewLine();
auto capabilities = g_device->getCapabilities(); ImGui::Text("Present Wait: %s", g_capabilities.presentWait ? "Supported" : "Unsupported");
ImGui::Text("Present Wait: %s", capabilities.presentWait ? "Supported" : "Unsupported"); ImGui::Text("Triangle Fan: %s", g_capabilities.triangleFan ? "Supported" : "Unsupported");
ImGui::Text("Triangle Fan: %s", capabilities.triangleFan ? "Supported" : "Unsupported");
ImGui::NewLine(); ImGui::NewLine();
const char* sdlVideoDriver = SDL_GetCurrentVideoDriver(); const char* sdlVideoDriver = SDL_GetCurrentVideoDriver();
if (sdlVideoDriver != nullptr) if (sdlVideoDriver != nullptr)
ImGui::Text("SDL Video Driver: %s", sdlVideoDriver); ImGui::Text("SDL Video Driver: %s", sdlVideoDriver);
} }
ImGui::End();
void Video::DrawFPS(ImFont* font) ImGui::PopFont();
{ font->Scale = defaultScale;
if (!Config::ShowFPS)
return;
auto drawList = ImGui::GetBackgroundDrawList();
auto fmt = fmt::format("FPS: {:.2f}", 1000.0 / g_presentProfiler.value.load());
auto fontSize = Scale(12.0f);
auto textSize = font->CalcTextSizeA(fontSize, FLT_MAX, 0, fmt.c_str());
ImVec2 min = { Scale(40), Scale(30) };
ImVec2 max = { min.x + std::max(Scale(75), textSize.x + Scale(10)), min.y + Scale(15) };
ImVec2 textPos = { min.x + Scale(2), CENTRE_TEXT_VERT(min, max, textSize) - Scale(0.5f) };
drawList->AddRectFilled(min, max, IM_COL32(0, 0, 0, 255));
drawList->AddText(font, fontSize, textPos, IM_COL32_WHITE, fmt.c_str());
} }
static void DrawImGui() static void DrawImGui()
@@ -2080,12 +2072,7 @@ static void DrawImGui()
ButtonGuide::Draw(); ButtonGuide::Draw();
Fader::Draw(); Fader::Draw();
#if !_DEBUG DrawProfiler();
if (Config::Debug)
#endif
{
Reddog::Manager::Draw();
}
ImGui::Render(); ImGui::Render();
@@ -2108,9 +2095,10 @@ static void ProcDrawImGui(const RenderCommand& cmd)
SetFramebuffer(g_backBuffer, nullptr, false); SetFramebuffer(g_backBuffer, nullptr, false);
auto& commandList = g_commandLists[g_frame]; auto& commandList = g_commandLists[g_frame];
auto pipeline = g_imPipeline.get();
commandList->setGraphicsPipelineLayout(g_imPipelineLayout.get()); commandList->setGraphicsPipelineLayout(g_imPipelineLayout.get());
commandList->setPipeline(g_imPipeline.get()); commandList->setPipeline(pipeline);
commandList->setGraphicsDescriptorSet(g_textureDescriptorSet.get(), 0); commandList->setGraphicsDescriptorSet(g_textureDescriptorSet.get(), 0);
commandList->setGraphicsDescriptorSet(g_samplerDescriptorSet.get(), 1); commandList->setGraphicsDescriptorSet(g_samplerDescriptorSet.get(), 1);
@@ -2184,6 +2172,16 @@ static void ProcDrawImGui(const RenderCommand& cmd)
case ImGuiCallback::SetProceduralOrigin: case ImGuiCallback::SetProceduralOrigin:
setPushConstants(&pushConstants.proceduralOrigin, &callbackData->setProceduralOrigin, sizeof(callbackData->setProceduralOrigin)); setPushConstants(&pushConstants.proceduralOrigin, &callbackData->setProceduralOrigin, sizeof(callbackData->setProceduralOrigin));
break; break;
case ImGuiCallback::SetAdditive:
{
auto pipelineToSet = callbackData->setAdditive.enabled ? g_imAdditivePipeline.get() : g_imPipeline.get();
if (pipeline != pipelineToSet)
{
commandList->setPipeline(pipelineToSet);
pipeline = pipelineToSet;
}
break;
}
default: default:
assert(false && "Unknown ImGui callback type."); assert(false && "Unknown ImGui callback type.");
break; break;
@@ -2465,11 +2463,6 @@ static GuestSurface* GetBackBuffer()
return g_backBuffer; return g_backBuffer;
} }
GuestSurface* Video::GetBackBuffer()
{
return g_backBuffer;
}
void Video::ComputeViewportDimensions() void Video::ComputeViewportDimensions()
{ {
uint32_t width = g_swapChain->getWidth(); uint32_t width = g_swapChain->getWidth();
@@ -2672,9 +2665,6 @@ static GuestSurface* CreateSurface(uint32_t width, uint32_t height, uint32_t for
static void FlushViewport() static void FlushViewport()
{ {
bool renderingToBackBuffer = g_renderTarget == g_backBuffer &&
g_backBuffer->texture != g_backBuffer->textureHolder.get();
auto& commandList = g_commandLists[g_frame]; auto& commandList = g_commandLists[g_frame];
if (g_dirtyStates.viewport) if (g_dirtyStates.viewport)
@@ -2686,17 +2676,6 @@ static void FlushViewport()
viewport.y += 0.5f; viewport.y += 0.5f;
} }
if (renderingToBackBuffer)
{
float width = Video::s_viewportWidth;
float height = Video::s_viewportHeight;
viewport.x *= width / g_backBuffer->width;
viewport.y *= height / g_backBuffer->height;
viewport.width *= width / g_backBuffer->width;
viewport.height *= height / g_backBuffer->height;
}
if (viewport.minDepth > viewport.maxDepth) if (viewport.minDepth > viewport.maxDepth)
std::swap(viewport.minDepth, viewport.maxDepth); std::swap(viewport.minDepth, viewport.maxDepth);
@@ -2713,17 +2692,6 @@ static void FlushViewport()
g_viewport.x + g_viewport.width, g_viewport.x + g_viewport.width,
g_viewport.y + g_viewport.height); g_viewport.y + g_viewport.height);
if (renderingToBackBuffer)
{
uint32_t width = Video::s_viewportWidth;
uint32_t height = Video::s_viewportHeight;
scissorRect.left = scissorRect.left * width / g_backBuffer->width;
scissorRect.top = scissorRect.top * height / g_backBuffer->height;
scissorRect.right = scissorRect.right * width / g_backBuffer->width;
scissorRect.bottom = scissorRect.bottom * height / g_backBuffer->height;
}
commandList->setScissors(scissorRect); commandList->setScissors(scissorRect);
g_dirtyStates.scissorRect = false; g_dirtyStates.scissorRect = false;
@@ -2827,7 +2795,10 @@ static void ProcStretchRect(const RenderCommand& cmd)
g_dirtyStates.pipelineState = true; g_dirtyStates.pipelineState = true;
if (g_vulkan) if (g_vulkan)
{
g_dirtyStates.depthBias = true; // Static depth bias in MSAA pipeline invalidates dynamic depth bias.
g_dirtyStates.vertexShaderConstants = true; g_dirtyStates.vertexShaderConstants = true;
}
SetHalfPixel(oldHalfPixel); SetHalfPixel(oldHalfPixel);
} }
@@ -3061,7 +3032,7 @@ static void SetTexture(GuestDevice* device, uint32_t index, GuestTexture* textur
auto isPlayStation = Config::ControllerIcons == EControllerIcons::PlayStation; auto isPlayStation = Config::ControllerIcons == EControllerIcons::PlayStation;
if (Config::ControllerIcons == EControllerIcons::Auto) if (Config::ControllerIcons == EControllerIcons::Auto)
isPlayStation = hid::detail::g_inputDeviceController == hid::detail::EInputDevice::PlayStation; isPlayStation = hid::g_inputDeviceController == hid::EInputDevice::PlayStation;
if (isPlayStation && texture != nullptr && texture->patchedTexture != nullptr) if (isPlayStation && texture != nullptr && texture->patchedTexture != nullptr)
texture = texture->patchedTexture.get(); texture = texture->patchedTexture.get();
@@ -3152,7 +3123,7 @@ static RenderShader* GetOrLinkShader(GuestShader* guestShader, uint32_t specCons
shader = guestShader->linkedShaders[specConstants].get(); shader = guestShader->linkedShaders[specConstants].get();
} }
#ifdef SWA_D3D12 #ifdef UNLEASHED_RECOMP_D3D12
if (shader == nullptr) if (shader == nullptr)
{ {
static Mutex g_compiledSpecConstantLibraryBlobMutex; static Mutex g_compiledSpecConstantLibraryBlobMutex;
@@ -3404,7 +3375,7 @@ static RenderPipeline* CreateGraphicsPipelineInRenderThread(PipelineState pipeli
pipeline = CreateGraphicsPipeline(pipelineState); pipeline = CreateGraphicsPipeline(pipelineState);
#ifdef ASYNC_PSO_DEBUG #ifdef ASYNC_PSO_DEBUG
bool loading = *SWA::SGlobals::ms_IsLoading; bool loading = *reinterpret_cast<bool*>(g_memory.Translate(0x83367A4C));
if (loading) if (loading)
++g_pipelinesCreatedAsynchronously; ++g_pipelinesCreatedAsynchronously;
@@ -4395,6 +4366,8 @@ static void ProcSetPixelShader(const RenderCommand& cmd)
break; break;
default: default:
{
if (g_aspectRatio >= WIDE_ASPECT_RATIO)
{ {
size_t height = round(Video::s_viewportHeight * Config::ResolutionScale); size_t height = round(Video::s_viewportHeight * Config::ResolutionScale);
@@ -4406,6 +4379,21 @@ static void ProcSetPixelShader(const RenderCommand& cmd)
shaderIndex = GAUSSIAN_BLUR_5X5; shaderIndex = GAUSSIAN_BLUR_5X5;
else else
shaderIndex = GAUSSIAN_BLUR_3X3; shaderIndex = GAUSSIAN_BLUR_3X3;
}
else
{
// Narrow aspect ratios should check for width to account for VERT+.
size_t width = round(Video::s_viewportWidth * Config::ResolutionScale);
if (width > 2560)
shaderIndex = GAUSSIAN_BLUR_9X9;
else if (width > 1920)
shaderIndex = GAUSSIAN_BLUR_7X7;
else if (width > 1280)
shaderIndex = GAUSSIAN_BLUR_5X5;
else
shaderIndex = GAUSSIAN_BLUR_3X3;
}
break; break;
} }
@@ -5133,23 +5121,40 @@ PPC_FUNC(sub_8258CAE0)
g_renderDirectorProfiler.End(); g_renderDirectorProfiler.End();
} }
// World map disables VERT+, so scaling by width does not work for it.
static uint32_t g_forceCheckHeightForPostProcessFix;
// SWA::CWorldMapCamera::CWorldMapCamera
PPC_FUNC_IMPL(__imp__sub_824860E0);
PPC_FUNC(sub_824860E0)
{
++g_forceCheckHeightForPostProcessFix;
__imp__sub_824860E0(ctx, base);
}
// SWA::CCameraController::~CCameraController
PPC_FUNC_IMPL(__imp__sub_824831D0);
PPC_FUNC(sub_824831D0)
{
if (PPC_LOAD_U32(ctx.r3.u32) == 0x8202BF1C) // SWA::CWorldMapCamera
--g_forceCheckHeightForPostProcessFix;
__imp__sub_824831D0(ctx, base);
}
void PostProcessResolutionFix(PPCRegister& r4, PPCRegister& f1, PPCRegister& f2) void PostProcessResolutionFix(PPCRegister& r4, PPCRegister& f1, PPCRegister& f2)
{ {
auto device = reinterpret_cast<be<uint32_t>*>(g_memory.Translate(r4.u32)); auto device = reinterpret_cast<be<uint32_t>*>(g_memory.Translate(r4.u32));
uint32_t width = device[46].get(); uint32_t width = device[46].get();
uint32_t height = device[47].get(); uint32_t height = device[47].get();
double aspectRatio = double(width) / double(height);
#if 0
// TODO: Figure out why this breaks for height > weight
double factor; double factor;
if (width > height) if ((aspectRatio >= WIDE_ASPECT_RATIO) || (g_forceCheckHeightForPostProcessFix != 0))
factor = 720.0 / double(height); factor = 720.0 / double(height);
else else
factor = 1280.0 / double(width); factor = 1280.0 / double(width);
#else
double factor = 720.0 / double(height);
#endif
f1.f64 *= factor; f1.f64 *= factor;
f2.f64 *= factor; f2.f64 *= factor;
+1 -4
View File
@@ -23,9 +23,6 @@ struct Video
static void Present(); static void Present();
static void StartPipelinePrecompilation(); static void StartPipelinePrecompilation();
static void WaitForGPU(); static void WaitForGPU();
static void DrawCounter();
static void DrawFPS(ImFont* font);
static struct GuestSurface* GetBackBuffer();
static void ComputeViewportDimensions(); static void ComputeViewportDimensions();
}; };
@@ -288,7 +285,7 @@ struct GuestShader : GuestResource
std::unique_ptr<RenderShader> shader; std::unique_ptr<RenderShader> shader;
struct ShaderCacheEntry* shaderCacheEntry = nullptr; struct ShaderCacheEntry* shaderCacheEntry = nullptr;
ankerl::unordered_dense::map<uint32_t, std::unique_ptr<RenderShader>> linkedShaders; ankerl::unordered_dense::map<uint32_t, std::unique_ptr<RenderShader>> linkedShaders;
#ifdef SWA_D3D12 #ifdef UNLEASHED_RECOMP_D3D12
std::vector<ComPtr<IDxcBlob>> shaderBlobs; std::vector<ComPtr<IDxcBlob>> shaderBlobs;
ComPtr<IDxcBlobEncoding> libraryBlob; ComPtr<IDxcBlobEncoding> libraryBlob;
#endif #endif
+23 -12
View File
@@ -1,7 +1,8 @@
#include <stdafx.h> #include <stdafx.h>
#include <SDL.h> #include <SDL.h>
#include <user/config.h> #include <user/config.h>
#include <hid/hid_detail.h> #include <hid/hid.h>
#include <os/logger.h>
#include <ui/game_window.h> #include <ui/game_window.h>
#include <kernel/xdm.h> #include <kernel/xdm.h>
#include <app.h> #include <app.h>
@@ -40,17 +41,17 @@ public:
return SDL_GameControllerTypeForIndex(index); return SDL_GameControllerTypeForIndex(index);
} }
hid::detail::EInputDevice GetInputDevice() const hid::EInputDevice GetInputDevice() const
{ {
switch (GetControllerType()) switch (GetControllerType())
{ {
case SDL_CONTROLLER_TYPE_PS3: case SDL_CONTROLLER_TYPE_PS3:
case SDL_CONTROLLER_TYPE_PS4: case SDL_CONTROLLER_TYPE_PS4:
case SDL_CONTROLLER_TYPE_PS5: case SDL_CONTROLLER_TYPE_PS5:
return hid::detail::EInputDevice::PlayStation; return hid::EInputDevice::PlayStation;
} }
return hid::detail::EInputDevice::Xbox; return hid::EInputDevice::Xbox;
} }
void Close() void Close()
@@ -168,8 +169,17 @@ static void SetControllerInputDevice(Controller* controller)
if (App::s_isLoading) if (App::s_isLoading)
return; return;
hid::detail::g_inputDevice = controller->GetInputDevice(); hid::g_inputDevice = controller->GetInputDevice();
hid::detail::g_inputDeviceController = hid::detail::g_inputDevice; hid::g_inputDeviceController = hid::g_inputDevice;
auto controllerType = (hid::EInputDeviceExplicit)controller->GetControllerType();
if (hid::g_inputDeviceExplicit != controllerType)
{
hid::g_inputDeviceExplicit = controllerType;
LOGFN("Detected controller: {}", hid::GetInputDeviceName());
}
} }
int HID_OnSDLEvent(void*, SDL_Event* event) int HID_OnSDLEvent(void*, SDL_Event* event)
@@ -199,6 +209,7 @@ int HID_OnSDLEvent(void*, SDL_Event* event)
case SDL_CONTROLLERBUTTONDOWN: case SDL_CONTROLLERBUTTONDOWN:
case SDL_CONTROLLERBUTTONUP: case SDL_CONTROLLERBUTTONUP:
case SDL_CONTROLLERAXISMOTION: case SDL_CONTROLLERAXISMOTION:
case SDL_CONTROLLERTOUCHPADDOWN:
{ {
auto* controller = FindController(event->cdevice.which); auto* controller = FindController(event->cdevice.which);
@@ -224,13 +235,13 @@ int HID_OnSDLEvent(void*, SDL_Event* event)
case SDL_KEYDOWN: case SDL_KEYDOWN:
case SDL_KEYUP: case SDL_KEYUP:
hid::detail::g_inputDevice = hid::detail::EInputDevice::Keyboard; hid::g_inputDevice = hid::EInputDevice::Keyboard;
break; break;
case SDL_MOUSEMOTION: case SDL_MOUSEMOTION:
case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP: case SDL_MOUSEBUTTONUP:
hid::detail::g_inputDevice = hid::detail::EInputDevice::Mouse; hid::g_inputDevice = hid::EInputDevice::Mouse;
break; break;
case SDL_WINDOWEVENT: case SDL_WINDOWEVENT:
@@ -266,7 +277,7 @@ int HID_OnSDLEvent(void*, SDL_Event* event)
return 0; return 0;
} }
void hid::detail::Init() void hid::Init()
{ {
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS3, "1"); SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS3, "1");
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS4, "1"); SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS4, "1");
@@ -282,7 +293,7 @@ void hid::detail::Init()
SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER); SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER);
} }
uint32_t hid::detail::GetState(uint32_t dwUserIndex, XAMINPUT_STATE* pState) uint32_t hid::GetState(uint32_t dwUserIndex, XAMINPUT_STATE* pState)
{ {
static uint32_t packet; static uint32_t packet;
@@ -301,7 +312,7 @@ uint32_t hid::detail::GetState(uint32_t dwUserIndex, XAMINPUT_STATE* pState)
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
uint32_t hid::detail::SetState(uint32_t dwUserIndex, XAMINPUT_VIBRATION* pVibration) uint32_t hid::SetState(uint32_t dwUserIndex, XAMINPUT_VIBRATION* pVibration)
{ {
if (!pVibration) if (!pVibration)
return ERROR_BAD_ARGUMENTS; return ERROR_BAD_ARGUMENTS;
@@ -314,7 +325,7 @@ uint32_t hid::detail::SetState(uint32_t dwUserIndex, XAMINPUT_VIBRATION* pVibrat
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
uint32_t hid::detail::GetCapabilities(uint32_t dwUserIndex, XAMINPUT_CAPABILITIES* pCaps) uint32_t hid::GetCapabilities(uint32_t dwUserIndex, XAMINPUT_CAPABILITIES* pCaps)
{ {
if (!pCaps) if (!pCaps)
return ERROR_BAD_ARGUMENTS; return ERROR_BAD_ARGUMENTS;
+56 -21
View File
@@ -1,39 +1,74 @@
#include <stdafx.h>
#include "hid.h" #include "hid.h"
#include "hid_detail.h"
hid::detail::EInputDevice hid::detail::g_inputDevice; hid::EInputDevice hid::g_inputDevice;
hid::detail::EInputDevice hid::detail::g_inputDeviceController; hid::EInputDevice hid::g_inputDeviceController;
hid::EInputDeviceExplicit hid::g_inputDeviceExplicit;
uint16_t hid::detail::g_prohibitedButtons; uint16_t hid::g_prohibitedButtons;
void hid::Init()
{
detail::Init();
}
void hid::SetProhibitedButtons(uint16_t wButtons) void hid::SetProhibitedButtons(uint16_t wButtons)
{ {
hid::detail::g_prohibitedButtons = wButtons; hid::g_prohibitedButtons = wButtons;
} }
uint32_t hid::GetState(uint32_t dwUserIndex, XAMINPUT_STATE* pState) bool hid::IsInputDeviceController()
{ {
return detail::GetState(dwUserIndex, pState); return hid::g_inputDevice != hid::EInputDevice::Keyboard &&
hid::g_inputDevice != hid::EInputDevice::Mouse;
} }
uint32_t hid::SetState(uint32_t dwUserIndex, XAMINPUT_VIBRATION* pVibration) std::string hid::GetInputDeviceName()
{ {
return detail::SetState(dwUserIndex, pVibration); switch (g_inputDevice)
{
case EInputDevice::Keyboard:
return "Keyboard";
case EInputDevice::Mouse:
return "Mouse";
} }
uint32_t hid::GetCapabilities(uint32_t dwUserIndex, XAMINPUT_CAPABILITIES* pCaps) switch (g_inputDeviceExplicit)
{ {
return detail::GetCapabilities(dwUserIndex, pCaps); case EInputDeviceExplicit::Xbox360:
return "Xbox 360";
case EInputDeviceExplicit::XboxOne:
return "Xbox One";
case EInputDeviceExplicit::DualShock3:
return "DualShock 3";
case EInputDeviceExplicit::DualShock4:
return "DualShock 4";
case EInputDeviceExplicit::SwitchPro:
return "Nintendo Switch Pro";
case EInputDeviceExplicit::Virtual:
return "Virtual";
case EInputDeviceExplicit::DualSense:
return "DualSense";
case EInputDeviceExplicit::Luna:
return "Amazon Luna";
case EInputDeviceExplicit::Stadia:
return "Google Stadia";
case EInputDeviceExplicit::NvShield:
return "NVIDIA Shield";
case EInputDeviceExplicit::SwitchJCLeft:
return "Nintendo Switch Joy-Con (Left)";
case EInputDeviceExplicit::SwitchJCRight:
return "Nintendo Switch Joy-Con (Right)";
case EInputDeviceExplicit::SwitchJCPair:
return "Nintendo Switch Joy-Con (Pair)";
} }
bool hid::detail::IsInputDeviceController() return "Unknown";
{
return hid::detail::g_inputDevice != hid::detail::EInputDevice::Keyboard &&
hid::detail::g_inputDevice != hid::detail::EInputDevice::Mouse;
} }
+35 -2
View File
@@ -1,13 +1,46 @@
#pragma once #pragma once
union SDL_Event;
namespace hid namespace hid
{ {
enum class EInputDevice
{
Keyboard,
Mouse,
Xbox,
PlayStation
};
enum class EInputDeviceExplicit
{
Unknown,
Xbox360,
XboxOne,
DualShock3,
DualShock4,
SwitchPro,
Virtual,
DualSense,
Luna,
Stadia,
NvShield,
SwitchJCLeft,
SwitchJCRight,
SwitchJCPair
};
extern EInputDevice g_inputDevice;
extern EInputDevice g_inputDeviceController;
extern EInputDeviceExplicit g_inputDeviceExplicit;
extern uint16_t g_prohibitedButtons;
void Init(); void Init();
void SetProhibitedButtons(uint16_t wButtons); void SetProhibitedButtons(uint16_t wButtons);
uint32_t GetState(uint32_t dwUserIndex, XAMINPUT_STATE* pState); uint32_t GetState(uint32_t dwUserIndex, XAMINPUT_STATE* pState);
uint32_t SetState(uint32_t dwUserIndex, XAMINPUT_VIBRATION* pVibration); uint32_t SetState(uint32_t dwUserIndex, XAMINPUT_VIBRATION* pVibration);
uint32_t GetCapabilities(uint32_t dwUserIndex, XAMINPUT_CAPABILITIES* pCaps); uint32_t GetCapabilities(uint32_t dwUserIndex, XAMINPUT_CAPABILITIES* pCaps);
bool IsInputDeviceController();
std::string GetInputDeviceName();
} }
-25
View File
@@ -1,25 +0,0 @@
#pragma once
namespace hid::detail
{
enum class EInputDevice
{
Keyboard,
Mouse,
Xbox,
PlayStation
};
extern EInputDevice g_inputDevice;
extern EInputDevice g_inputDeviceController;
extern uint16_t g_prohibitedButtons;
void Init();
uint32_t GetState(uint32_t dwUserIndex, XAMINPUT_STATE* pState);
uint32_t SetState(uint32_t dwUserIndex, XAMINPUT_VIBRATION* pVibration);
uint32_t GetCapabilities(uint32_t dwUserIndex, XAMINPUT_CAPABILITIES* pCaps);
bool IsInputDeviceController();
}
+25 -24
View File
@@ -2,7 +2,6 @@
#include "xam.h" #include "xam.h"
#include "xdm.h" #include "xdm.h"
#include <hid/hid.h> #include <hid/hid.h>
#include <hid/hid_detail.h>
#include <ui/game_window.h> #include <ui/game_window.h>
#include <cpu/guest_thread.h> #include <cpu/guest_thread.h>
#include <ranges> #include <ranges>
@@ -11,12 +10,6 @@
#include <user/paths.h> #include <user/paths.h>
#include <SDL.h> #include <SDL.h>
#ifdef _WIN32
#include <CommCtrl.h>
// Needed for commctrl
#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif
struct XamListener : KernelObject struct XamListener : KernelObject
{ {
uint32_t id{}; uint32_t id{};
@@ -208,11 +201,15 @@ bool XNotifyGetNext(uint32_t hNotification, uint32_t dwMsgFilter, be<uint32_t>*
uint32_t XamShowMessageBoxUI(uint32_t dwUserIndex, be<uint16_t>* wszTitle, be<uint16_t>* wszText, uint32_t cButtons, uint32_t XamShowMessageBoxUI(uint32_t dwUserIndex, be<uint16_t>* wszTitle, be<uint16_t>* wszText, uint32_t cButtons,
xpointer<be<uint16_t>>* pwszButtons, uint32_t dwFocusButton, uint32_t dwFlags, be<uint32_t>* pResult, XXOVERLAPPED* pOverlapped) xpointer<be<uint16_t>>* pwszButtons, uint32_t dwFocusButton, uint32_t dwFlags, be<uint32_t>* pResult, XXOVERLAPPED* pOverlapped)
{ {
int button{}; *pResult = cButtons ? cButtons - 1 : 0;
#ifdef _WIN32 #if _DEBUG
assert("XamShowMessageBoxUI encountered!" && false);
#elif _WIN32
// This code is Win32-only as it'll most likely crash, misbehave or
// cause corruption due to using a different type of memory than what
// wchar_t is on Linux. Windows uses 2 bytes while Linux uses 4 bytes.
std::vector<std::wstring> texts{}; std::vector<std::wstring> texts{};
std::vector<TASKDIALOG_BUTTON> buttons{};
texts.emplace_back(reinterpret_cast<wchar_t*>(wszTitle)); texts.emplace_back(reinterpret_cast<wchar_t*>(wszTitle));
texts.emplace_back(reinterpret_cast<wchar_t*>(wszText)); texts.emplace_back(reinterpret_cast<wchar_t*>(wszText));
@@ -226,23 +223,27 @@ uint32_t XamShowMessageBoxUI(uint32_t dwUserIndex, be<uint16_t>* wszTitle, be<ui
ByteSwapInplace(text[i]); ByteSwapInplace(text[i]);
} }
wprintf(L"[XamShowMessageBoxUI] !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
wprintf(L"[XamShowMessageBoxUI] If you are encountering this message and the game has ceased functioning,\n");
wprintf(L"[XamShowMessageBoxUI] please create an issue at https://github.com/hedge-dev/UnleashedRecomp/issues.\n");
wprintf(L"[XamShowMessageBoxUI] !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
wprintf(L"[XamShowMessageBoxUI] %ls\n", texts[0].c_str());
wprintf(L"[XamShowMessageBoxUI] %ls\n", texts[1].c_str());
wprintf(L"[XamShowMessageBoxUI] ");
for (size_t i = 0; i < cButtons; i++) for (size_t i = 0; i < cButtons; i++)
buttons.emplace_back(i, texts[2 + i].c_str()); {
wprintf(L"%ls", texts[2 + i].c_str());
XamNotifyEnqueueEvent(9, 1); if (i != cButtons - 1)
wprintf(L" | ");
}
TASKDIALOGCONFIG config{}; wprintf(L"\n");
config.cbSize = sizeof(config); wprintf(L"[XamShowMessageBoxUI] Defaulted to button: %d\n", pResult->get());
config.pszWindowTitle = texts[0].c_str(); wprintf(L"[XamShowMessageBoxUI] !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
config.pszContent = texts[1].c_str();
config.cButtons = cButtons;
config.pButtons = buttons.data();
TaskDialogIndirect(&config, &button, nullptr, nullptr);
#endif #endif
*pResult = button;
if (pOverlapped) if (pOverlapped)
{ {
pOverlapped->dwCompletionContext = GuestThread::GetCurrentThreadId(); pOverlapped->dwCompletionContext = GuestThread::GetCurrentThreadId();
@@ -453,7 +454,7 @@ uint32_t XamInputGetState(uint32_t userIndex, uint32_t flags, XAMINPUT_STATE* st
state->Gamepad.wButtons |= XAMINPUT_GAMEPAD_Y; state->Gamepad.wButtons |= XAMINPUT_GAMEPAD_Y;
} }
state->Gamepad.wButtons &= ~hid::detail::g_prohibitedButtons; state->Gamepad.wButtons &= ~hid::g_prohibitedButtons;
ByteSwapInplace(state->Gamepad.wButtons); ByteSwapInplace(state->Gamepad.wButtons);
ByteSwapInplace(state->Gamepad.sThumbLX); ByteSwapInplace(state->Gamepad.sThumbLX);
@@ -466,7 +467,7 @@ uint32_t XamInputGetState(uint32_t userIndex, uint32_t flags, XAMINPUT_STATE* st
uint32_t XamInputSetState(uint32_t userIndex, uint32_t flags, XAMINPUT_VIBRATION* vibration) uint32_t XamInputSetState(uint32_t userIndex, uint32_t flags, XAMINPUT_VIBRATION* vibration)
{ {
if (!hid::detail::IsInputDeviceController() || !Config::Vibration) if (!hid::IsInputDeviceController() || !Config::Vibration)
return ERROR_SUCCESS; return ERROR_SUCCESS;
ByteSwapInplace(vibration->wLeftMotorSpeed); ByteSwapInplace(vibration->wLeftMotorSpeed);
+18 -7
View File
@@ -19,10 +19,10 @@
*/ */
#define CONFIG_DEFINE_LOCALE(name) \ #define CONFIG_DEFINE_LOCALE(name) \
CONFIG_LOCALE Config::g_##name##_locale = CONFIG_LOCALE g_##name##_locale =
#define CONFIG_DEFINE_ENUM_LOCALE(type) \ #define CONFIG_DEFINE_ENUM_LOCALE(type) \
CONFIG_ENUM_LOCALE(type) Config::g_##type##_locale = CONFIG_ENUM_LOCALE(type) g_##type##_locale =
CONFIG_DEFINE_LOCALE(Language) CONFIG_DEFINE_LOCALE(Language)
{ {
@@ -117,11 +117,6 @@ CONFIG_DEFINE_LOCALE(AllowBackgroundInput)
{ ELanguage::English, { "Allow Background Input", "Allow controller input whilst the game window is unfocused." } } { ELanguage::English, { "Allow Background Input", "Allow controller input whilst the game window is unfocused." } }
}; };
CONFIG_DEFINE_LOCALE(AllowDPadMovement)
{
{ ELanguage::English, { "Allow D-Pad Movement", "Allow the player to also be controlled using the directional pad." } }
};
CONFIG_DEFINE_LOCALE(MasterVolume) CONFIG_DEFINE_LOCALE(MasterVolume)
{ {
{ ELanguage::English, { "Master Volume", "Adjust the overall volume." } } { ELanguage::English, { "Master Volume", "Adjust the overall volume." } }
@@ -142,6 +137,22 @@ CONFIG_DEFINE_LOCALE(MusicAttenuation)
{ ELanguage::English, { "Music Attenuation", "Fade out the game's music when external media is playing." } } { ELanguage::English, { "Music Attenuation", "Fade out the game's music when external media is playing." } }
}; };
CONFIG_DEFINE_LOCALE(ChannelConfiguration)
{
{ ELanguage::English, { "Channel Configuration", "" } }
};
CONFIG_DEFINE_ENUM_LOCALE(EChannelConfiguration)
{
{
ELanguage::English,
{
{ EChannelConfiguration::Stereo, { "STEREO", "" } },
{ EChannelConfiguration::Surround, { "SURROUND", "" } }
}
}
};
CONFIG_DEFINE_LOCALE(VoiceLanguage) CONFIG_DEFINE_LOCALE(VoiceLanguage)
{ {
{ ELanguage::English, { "Voice Language", "Change the language used for character voices." } } { ELanguage::English, { "Voice Language", "Change the language used for character voices." } }
+14
View File
@@ -342,6 +342,20 @@ std::unordered_map<std::string, std::unordered_map<ELanguage, std::string>> g_lo
{ ELanguage::Italian, "Sei sicuro di voler uscire?" } { ELanguage::Italian, "Sei sicuro di voler uscire?" }
} }
}, },
{
// Notes: message appears when the SYS-DATA is corrupted (mismatching file size).
// To make this occur, open the file in any editor and just remove a large chunk of data.
// Do not localise this unless absolutely necessary, these strings are from the XEX.
"Title_Message_SaveDataCorrupt",
{
{ ELanguage::English, "The save file appears to be\ncorrupted and cannot be loaded." },
{ ELanguage::Japanese, "ゲームデータの読み込みに失敗しました。\nこのまま続けるとゲームデータをセーブすることはできません" },
{ ELanguage::German, "Diese Speicherdatei ist beschädigt\nund kann nicht geladen werden." },
{ ELanguage::French, "Le fichier de sauvegarde semble être\nendommagé et ne peut être chargé." },
{ ELanguage::Spanish, "El archivo parece estar dañado\ny no se puede cargar." },
{ ELanguage::Italian, "I file di salvataggio sembrano danneggiati\ne non possono essere caricati." }
}
},
{ {
"Common_On", "Common_On",
{ {
+3 -3
View File
@@ -26,9 +26,6 @@ static std::vector<Mod> g_mods;
std::filesystem::path ModLoader::ResolvePath(std::string_view path) std::filesystem::path ModLoader::ResolvePath(std::string_view path)
{ {
if (g_mods.empty())
return {};
std::string_view root; std::string_view root;
size_t sepIndex = path.find(":\\"); size_t sepIndex = path.find(":\\");
@@ -51,6 +48,9 @@ std::filesystem::path ModLoader::ResolvePath(std::string_view path)
return {}; return {};
} }
if (g_mods.empty())
return {};
thread_local xxHashMap<std::filesystem::path> s_cache; thread_local xxHashMap<std::filesystem::path> s_cache;
XXH64_hash_t hash = XXH3_64bits(path.data(), path.size()); XXH64_hash_t hash = XXH3_64bits(path.data(), path.size());
+3 -3
View File
@@ -1,10 +1,10 @@
#include <os/logger_detail.h> #include <os/logger.h>
void os::logger::detail::Init() void os::logger::Init()
{ {
} }
void os::logger::detail::Log(const std::string_view str, detail::ELogType type, const char* func) void os::logger::Log(const std::string_view str, ELogType type, const char* func)
{ {
if (func) if (func)
{ {
+2 -2
View File
@@ -1,6 +1,6 @@
#include <os/media_detail.h> #include <os/media.h>
bool os::media::detail::IsExternalMediaPlaying() bool os::media::IsExternalMediaPlaying()
{ {
// This functionality is not supported in Linux. // This functionality is not supported in Linux.
return false; return false;
+4 -4
View File
@@ -1,8 +1,8 @@
#include <os/process_detail.h> #include <os/process.h>
#include <signal.h> #include <signal.h>
std::filesystem::path os::process::detail::GetExecutablePath() std::filesystem::path os::process::GetExecutablePath()
{ {
char exePath[PATH_MAX] = {}; char exePath[PATH_MAX] = {};
if (readlink("/proc/self/exe", exePath, PATH_MAX) > 0) if (readlink("/proc/self/exe", exePath, PATH_MAX) > 0)
@@ -15,7 +15,7 @@ std::filesystem::path os::process::detail::GetExecutablePath()
} }
} }
std::filesystem::path os::process::detail::GetWorkingDirectory() std::filesystem::path os::process::GetWorkingDirectory()
{ {
char cwd[PATH_MAX] = {}; char cwd[PATH_MAX] = {};
char *res = getcwd(cwd, sizeof(cwd)); char *res = getcwd(cwd, sizeof(cwd));
@@ -29,7 +29,7 @@ std::filesystem::path os::process::detail::GetWorkingDirectory()
} }
} }
bool os::process::detail::StartProcess(const std::filesystem::path path, const std::vector<std::string> args, std::filesystem::path work) bool os::process::StartProcess(const std::filesystem::path& path, const std::vector<std::string>& args, std::filesystem::path work)
{ {
pid_t pid = fork(); pid_t pid = fork();
if (pid < 0) if (pid < 0)
+2 -2
View File
@@ -1,6 +1,6 @@
#include <os/user_detail.h> #include <os/user.h>
bool os::user::detail::IsDarkTheme() bool os::user::IsDarkTheme()
{ {
return false; return false;
} }
+3 -3
View File
@@ -1,7 +1,7 @@
#include <os/version_detail.h> #include <os/version.h>
os::version::detail::OSVersion os::version::detail::GetOSVersion() os::version::OSVersion os::version::GetOSVersion()
{ {
assert(false && "Unimplemented."); assert(false && "Unimplemented.");
return os::version::detail::OSVersion(); return os::version::OSVersion();
} }
-12
View File
@@ -1,12 +0,0 @@
#include <os/logger.h>
#include <os/logger_detail.h>
void os::logger::Init()
{
detail::Init();
}
void os::logger::Log(const std::string_view str, detail::ELogType type, const char* func)
{
detail::Log(str, type, func);
}
+12 -4
View File
@@ -1,9 +1,9 @@
#pragma once #pragma once
#include <os/logger_detail.h> #include <source_location>
#define LOG_IMPL(type, func, str) os::logger::Log(str, os::logger::detail::ELogType::type, func) #define LOG_IMPL(type, func, str) os::logger::Log(str, os::logger::ELogType::type, func)
#define LOGF_IMPL(type, func, str, ...) os::logger::Log(fmt::format(str, __VA_ARGS__), os::logger::detail::ELogType::type, func) #define LOGF_IMPL(type, func, str, ...) os::logger::Log(fmt::format(str, __VA_ARGS__), os::logger::ELogType::type, func)
// Function-specific logging. // Function-specific logging.
@@ -51,6 +51,14 @@
namespace os::logger namespace os::logger
{ {
enum class ELogType
{
None,
Utility,
Warning,
Error
};
void Init(); void Init();
void Log(const std::string_view str, detail::ELogType type = detail::ELogType::None, const char* func = nullptr); void Log(const std::string_view str, ELogType type = ELogType::None, const char* func = nullptr);
} }
-17
View File
@@ -1,17 +0,0 @@
#pragma once
#include <source_location>
namespace os::logger::detail
{
enum class ELogType
{
None,
Utility,
Warning,
Error
};
void Init();
void Log(const std::string_view str, ELogType type = ELogType::None, const char* func = nullptr);
}
-7
View File
@@ -1,7 +0,0 @@
#include <os/media.h>
#include <os/media_detail.h>
bool os::media::IsExternalMediaPlaying()
{
return detail::IsExternalMediaPlaying();
}
-6
View File
@@ -1,6 +0,0 @@
#pragma once
namespace os::media::detail
{
bool IsExternalMediaPlaying();
}
-17
View File
@@ -1,17 +0,0 @@
#include <os/process.h>
#include <os/process_detail.h>
std::filesystem::path os::process::GetExecutablePath()
{
return detail::GetExecutablePath();
}
std::filesystem::path os::process::GetWorkingDirectory()
{
return detail::GetWorkingDirectory();
}
bool os::process::StartProcess(const std::filesystem::path path, const std::vector<std::string> args, std::filesystem::path work)
{
return detail::StartProcess(path, args, work);
}
+1 -1
View File
@@ -4,5 +4,5 @@ namespace os::process
{ {
std::filesystem::path GetExecutablePath(); std::filesystem::path GetExecutablePath();
std::filesystem::path GetWorkingDirectory(); std::filesystem::path GetWorkingDirectory();
bool StartProcess(const std::filesystem::path path, const std::vector<std::string> args, std::filesystem::path work = {}); bool StartProcess(const std::filesystem::path& path, const std::vector<std::string>& args, std::filesystem::path work = {});
} }
-8
View File
@@ -1,8 +0,0 @@
#pragma once
namespace os::process::detail
{
std::filesystem::path GetExecutablePath();
std::filesystem::path GetWorkingDirectory();
bool StartProcess(const std::filesystem::path path, const std::vector<std::string> args, std::filesystem::path work = {});
}
-7
View File
@@ -1,7 +0,0 @@
#include <os/user.h>
#include <os/user_detail.h>
bool os::user::IsDarkTheme()
{
return detail::IsDarkTheme();
}
-6
View File
@@ -1,6 +0,0 @@
#pragma once
namespace os::user::detail
{
bool IsDarkTheme();
}
-7
View File
@@ -1,7 +0,0 @@
#include <os/version.h>
#include <os/version_detail.h>
os::version::detail::OSVersion os::version::GetOSVersion()
{
return detail::GetOSVersion();
}
+8 -3
View File
@@ -1,8 +1,13 @@
#pragma once #pragma once
#include <os/version_detail.h>
namespace os::version namespace os::version
{ {
detail::OSVersion GetOSVersion(); struct OSVersion
{
uint32_t Major{};
uint32_t Minor{};
uint32_t Build{};
};
OSVersion GetOSVersion();
} }
-13
View File
@@ -1,13 +0,0 @@
#pragma once
namespace os::version::detail
{
struct OSVersion
{
uint32_t Major{};
uint32_t Minor{};
uint32_t Build{};
};
OSVersion GetOSVersion();
}
+3 -4
View File
@@ -1,17 +1,16 @@
#include <os/logger_detail.h> #include <os/logger.h>
#include <print>
#define FOREGROUND_WHITE (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE) #define FOREGROUND_WHITE (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE)
#define FOREGROUND_YELLOW (FOREGROUND_RED | FOREGROUND_GREEN) #define FOREGROUND_YELLOW (FOREGROUND_RED | FOREGROUND_GREEN)
HANDLE g_hStandardOutput; HANDLE g_hStandardOutput;
void os::logger::detail::Init() void os::logger::Init()
{ {
g_hStandardOutput = GetStdHandle(STD_OUTPUT_HANDLE); g_hStandardOutput = GetStdHandle(STD_OUTPUT_HANDLE);
} }
void os::logger::detail::Log(const std::string_view str, detail::ELogType type, const char* func) void os::logger::Log(const std::string_view str, ELogType type, const char* func)
{ {
switch (type) switch (type)
{ {
+2 -2
View File
@@ -1,4 +1,4 @@
#include <os/media_detail.h> #include <os/media.h>
#include <os/logger.h> #include <os/logger.h>
#include <winrt/Windows.Foundation.h> #include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Media.Control.h> #include <winrt/Windows.Media.Control.h>
@@ -62,7 +62,7 @@ static GlobalSystemMediaTransportControlsSessionPlaybackInfo GetPlaybackInfo()
} }
} }
bool os::media::detail::IsExternalMediaPlaying() bool os::media::IsExternalMediaPlaying()
{ {
auto playbackInfo = GetPlaybackInfo(); auto playbackInfo = GetPlaybackInfo();
+4 -4
View File
@@ -1,6 +1,6 @@
#include <os/process_detail.h> #include <os/process.h>
std::filesystem::path os::process::detail::GetExecutablePath() std::filesystem::path os::process::GetExecutablePath()
{ {
WCHAR exePath[MAX_PATH]; WCHAR exePath[MAX_PATH];
@@ -10,7 +10,7 @@ std::filesystem::path os::process::detail::GetExecutablePath()
return std::filesystem::path(exePath); return std::filesystem::path(exePath);
} }
std::filesystem::path os::process::detail::GetWorkingDirectory() std::filesystem::path os::process::GetWorkingDirectory()
{ {
WCHAR workPath[MAX_PATH]; WCHAR workPath[MAX_PATH];
@@ -20,7 +20,7 @@ std::filesystem::path os::process::detail::GetWorkingDirectory()
return std::filesystem::path(workPath); return std::filesystem::path(workPath);
} }
bool os::process::detail::StartProcess(const std::filesystem::path path, const std::vector<std::string> args, std::filesystem::path work) bool os::process::StartProcess(const std::filesystem::path& path, const std::vector<std::string>& args, std::filesystem::path work)
{ {
if (path.empty()) if (path.empty())
return false; return false;
+2 -2
View File
@@ -1,6 +1,6 @@
#include <os/user_detail.h> #include <os/user.h>
bool os::user::detail::IsDarkTheme() bool os::user::IsDarkTheme()
{ {
HKEY hKey; HKEY hKey;
+3 -3
View File
@@ -1,10 +1,10 @@
#include <os/version_detail.h> #include <os/version.h>
LIB_FUNCTION(LONG, "ntdll.dll", RtlGetVersion, PRTL_OSVERSIONINFOW); LIB_FUNCTION(LONG, "ntdll.dll", RtlGetVersion, PRTL_OSVERSIONINFOW);
os::version::detail::OSVersion os::version::detail::GetOSVersion() os::version::OSVersion os::version::GetOSVersion()
{ {
auto result = os::version::detail::OSVersion{}; auto result = os::version::OSVersion{};
OSVERSIONINFOEXW osvi = { 0 }; OSVERSIONINFOEXW osvi = { 0 };
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
@@ -0,0 +1,14 @@
#include <api/SWA.h>
#include <patches/ui/CTitleStateIntro_patches.h>
// SWA::CGameModeStageTitle::Update
PPC_FUNC_IMPL(__imp__sub_825518B8);
PPC_FUNC(sub_825518B8)
{
auto pGameModeStageTitle = (SWA::CGameModeStageTitle*)g_memory.Translate(ctx.r3.u32);
__imp__sub_825518B8(ctx, base);
if (g_quitMessageOpen)
pGameModeStageTitle->m_AdvertiseMovieWaitTime = 0;
}
@@ -185,13 +185,13 @@ void AspectRatioPatches::ComputeOffsets()
float height = Video::s_viewportHeight; float height = Video::s_viewportHeight;
g_aspectRatio = width / height; g_aspectRatio = width / height;
g_aspectRatioScale = 1.0f; g_aspectRatioGameplayScale = 1.0f;
if (g_aspectRatio >= NARROW_ASPECT_RATIO) if (g_aspectRatio >= NARROW_ASPECT_RATIO)
{ {
// height is locked to 720 in this case g_aspectRatioOffsetX = (width - height * WIDE_ASPECT_RATIO) / 2.0f;
g_aspectRatioOffsetX = 0.5f * (g_aspectRatio * 720.0f - 1280.0f);
g_aspectRatioOffsetY = 0.0f; g_aspectRatioOffsetY = 0.0f;
g_aspectRatioScale = height / 720.0f;
// keep same scale above Steam Deck aspect ratio // keep same scale above Steam Deck aspect ratio
if (g_aspectRatio < WIDE_ASPECT_RATIO) if (g_aspectRatio < WIDE_ASPECT_RATIO)
@@ -201,20 +201,29 @@ void AspectRatioPatches::ComputeOffsets()
float narrowScale = ComputeScale(NARROW_ASPECT_RATIO); float narrowScale = ComputeScale(NARROW_ASPECT_RATIO);
float lerpFactor = std::clamp((g_aspectRatio - NARROW_ASPECT_RATIO) / (STEAM_DECK_ASPECT_RATIO - NARROW_ASPECT_RATIO), 0.0f, 1.0f); float lerpFactor = std::clamp((g_aspectRatio - NARROW_ASPECT_RATIO) / (STEAM_DECK_ASPECT_RATIO - NARROW_ASPECT_RATIO), 0.0f, 1.0f);
g_aspectRatioScale = narrowScale + (steamDeckScale - narrowScale) * lerpFactor; g_aspectRatioGameplayScale = narrowScale + (steamDeckScale - narrowScale) * lerpFactor;
} }
} }
else else
{ {
// width is locked to 960 in this case to have 4:3 crop // 4:3 crop
g_aspectRatioOffsetX = 0.5f * (960.0f - 1280.0f); g_aspectRatioOffsetX = (width - width * NARROW_ASPECT_RATIO) / 2.0f;
g_aspectRatioOffsetY = 0.5f * (960.0f / g_aspectRatio - 720.0f); g_aspectRatioOffsetY = (height - width / NARROW_ASPECT_RATIO) / 2.0f;
g_aspectRatioScale = ComputeScale(NARROW_ASPECT_RATIO); g_aspectRatioScale = width / 960.0f;
g_aspectRatioGameplayScale = ComputeScale(NARROW_ASPECT_RATIO);
} }
g_narrowOffsetScale = std::clamp((g_aspectRatio - NARROW_ASPECT_RATIO) / (WIDE_ASPECT_RATIO - NARROW_ASPECT_RATIO), 0.0f, 1.0f); g_aspectRatioNarrowScale = std::clamp((g_aspectRatio - NARROW_ASPECT_RATIO) / (WIDE_ASPECT_RATIO - NARROW_ASPECT_RATIO), 0.0f, 1.0f);
} }
static void GetViewport(void* application, be<uint32_t>* width, be<uint32_t>* height)
{
*width = 1280;
*height = 720;
}
GUEST_FUNCTION_HOOK(sub_82E169B8, GetViewport);
// SWA::CGameDocument::ComputeScreenPosition // SWA::CGameDocument::ComputeScreenPosition
PPC_FUNC_IMPL(__imp__sub_8250FC70); PPC_FUNC_IMPL(__imp__sub_8250FC70);
PPC_FUNC(sub_8250FC70) PPC_FUNC(sub_8250FC70)
@@ -222,14 +231,15 @@ PPC_FUNC(sub_8250FC70)
__imp__sub_8250FC70(ctx, base); __imp__sub_8250FC70(ctx, base);
auto position = reinterpret_cast<be<float>*>(base + ctx.r3.u32); auto position = reinterpret_cast<be<float>*>(base + ctx.r3.u32);
position[0] = position[0] - g_aspectRatioOffsetX;
position[1] = position[1] - g_aspectRatioOffsetY; position[0] = (position[0] / 1280.0f * Video::s_viewportWidth - g_aspectRatioOffsetX) / g_aspectRatioScale;
position[1] = (position[1] / 720.0f * Video::s_viewportHeight - g_aspectRatioOffsetY) / g_aspectRatioScale;
} }
void ComputeScreenPositionMidAsmHook(PPCRegister& f1, PPCRegister& f2) void ComputeScreenPositionMidAsmHook(PPCRegister& f1, PPCRegister& f2)
{ {
f1.f64 -= g_aspectRatioOffsetX; f1.f64 = (f1.f64 / 1280.0 * Video::s_viewportWidth - g_aspectRatioOffsetX) / g_aspectRatioScale;
f2.f64 -= g_aspectRatioOffsetY; f2.f64 = (f2.f64 / 720.0 * Video::s_viewportHeight - g_aspectRatioOffsetY) / g_aspectRatioScale;
} }
void WorldMapInfoMidAsmHook(PPCRegister& r4) void WorldMapInfoMidAsmHook(PPCRegister& r4)
@@ -258,11 +268,11 @@ PPC_FUNC(sub_8258B558)
if (scene != NULL) if (scene != NULL)
{ {
ctx.r3.u32 = scene; ctx.r3.u32 = scene;
ctx.f1.f64 = offsetX + g_narrowOffsetScale * 140.0f; ctx.f1.f64 = offsetX + g_aspectRatioNarrowScale * 140.0f;
ctx.f2.f64 = offsetY; ctx.f2.f64 = offsetY;
if (Config::UIScaleMode == EUIScaleMode::Edge && g_narrowOffsetScale >= 1.0f) if (Config::UIScaleMode == EUIScaleMode::Edge && g_aspectRatioNarrowScale >= 1.0f)
ctx.f1.f64 += g_aspectRatioOffsetX; ctx.f1.f64 += g_aspectRatioOffsetX / g_aspectRatioScale;
sub_830BB3D0(ctx, base); sub_830BB3D0(ctx, base);
} }
@@ -282,9 +292,9 @@ PPC_FUNC(sub_8258B558)
uint32_t textBox = PPC_LOAD_U32(menuTextBox + 0x4); uint32_t textBox = PPC_LOAD_U32(menuTextBox + 0x4);
if (textBox != NULL) if (textBox != NULL)
{ {
float value = 708.0f + g_narrowOffsetScale * 140.0f; float value = 708.0f + g_aspectRatioNarrowScale * 140.0f;
if (Config::UIScaleMode == EUIScaleMode::Edge && g_narrowOffsetScale >= 1.0f) if (Config::UIScaleMode == EUIScaleMode::Edge && g_aspectRatioNarrowScale >= 1.0f)
value += g_aspectRatioOffsetX; value += g_aspectRatioOffsetX / g_aspectRatioScale;
PPC_STORE_U32(textBox + 0x38, reinterpret_cast<uint32_t&>(value)); PPC_STORE_U32(textBox + 0x38, reinterpret_cast<uint32_t&>(value));
} }
@@ -740,8 +750,6 @@ static void Draw(PPCContext& ctx, uint8_t* base, PPCFunc* original, uint32_t str
modifier.flags &= ~(ALIGN_LEFT | ALIGN_RIGHT); modifier.flags &= ~(ALIGN_LEFT | ALIGN_RIGHT);
} }
auto backBuffer = Video::GetBackBuffer();
uint32_t size = ctx.r5.u32 * stride; uint32_t size = ctx.r5.u32 * stride;
ctx.r1.u32 -= size; ctx.r1.u32 -= size;
@@ -755,10 +763,12 @@ static void Draw(PPCContext& ctx, uint8_t* base, PPCFunc* original, uint32_t str
if ((modifier.flags & STRETCH_HORIZONTAL) != 0) if ((modifier.flags & STRETCH_HORIZONTAL) != 0)
{ {
scaleX = backBuffer->width / 1280.0f; scaleX = Video::s_viewportWidth / 1280.0f;
} }
else else
{ {
scaleX = g_aspectRatioScale;
if ((modifier.flags & ALIGN_RIGHT) != 0) if ((modifier.flags & ALIGN_RIGHT) != 0)
offsetX = g_aspectRatioOffsetX * 2.0f; offsetX = g_aspectRatioOffsetX * 2.0f;
else if ((modifier.flags & ALIGN_LEFT) == 0) else if ((modifier.flags & ALIGN_LEFT) == 0)
@@ -766,27 +776,29 @@ static void Draw(PPCContext& ctx, uint8_t* base, PPCFunc* original, uint32_t str
if ((modifier.flags & SCALE) != 0) if ((modifier.flags & SCALE) != 0)
{ {
scaleX = g_aspectRatioScale; scaleX *= g_aspectRatioGameplayScale;
if ((modifier.flags & ALIGN_RIGHT) != 0) if ((modifier.flags & ALIGN_RIGHT) != 0)
offsetX += 1280.0f * (1.0f - scaleX); offsetX += 1280.0f * (1.0f - g_aspectRatioGameplayScale) * g_aspectRatioScale;
else if ((modifier.flags & ALIGN_LEFT) == 0) else if ((modifier.flags & ALIGN_LEFT) == 0)
offsetX += 640.0f * (1.0f - scaleX); offsetX += 640.0f * (1.0f - g_aspectRatioGameplayScale) * g_aspectRatioScale;
} }
if ((modifier.flags & WORLD_MAP) != 0) if ((modifier.flags & WORLD_MAP) != 0)
{ {
if ((modifier.flags & ALIGN_LEFT) != 0) if ((modifier.flags & ALIGN_LEFT) != 0)
offsetX += (1.0f - g_narrowOffsetScale) * -20.0f; offsetX += (1.0f - g_aspectRatioNarrowScale) * g_aspectRatioScale * -20.0f;
} }
} }
if ((modifier.flags & STRETCH_VERTICAL) != 0) if ((modifier.flags & STRETCH_VERTICAL) != 0)
{ {
scaleY = backBuffer->height / 720.0f; scaleY = Video::s_viewportHeight / 720.0f;
} }
else else
{ {
scaleY = g_aspectRatioScale;
if ((modifier.flags & ALIGN_BOTTOM) != 0) if ((modifier.flags & ALIGN_BOTTOM) != 0)
offsetY = g_aspectRatioOffsetY * 2.0f; offsetY = g_aspectRatioOffsetY * 2.0f;
else if ((modifier.flags & ALIGN_TOP) == 0) else if ((modifier.flags & ALIGN_TOP) == 0)
@@ -794,12 +806,12 @@ static void Draw(PPCContext& ctx, uint8_t* base, PPCFunc* original, uint32_t str
if ((modifier.flags & SCALE) != 0) if ((modifier.flags & SCALE) != 0)
{ {
scaleY = g_aspectRatioScale; scaleY *= g_aspectRatioGameplayScale;
if ((modifier.flags & ALIGN_BOTTOM) != 0) if ((modifier.flags & ALIGN_BOTTOM) != 0)
offsetY += 720.0f * (1.0f - scaleY); offsetY += 720.0f * (1.0f - g_aspectRatioGameplayScale) * g_aspectRatioScale;
else if ((modifier.flags & ALIGN_TOP) == 0) else if ((modifier.flags & ALIGN_TOP) == 0)
offsetY += 360.0f * (1.0f - scaleY); offsetY += 360.0f * (1.0f - g_aspectRatioGameplayScale) * g_aspectRatioScale;
} }
} }
@@ -836,7 +848,7 @@ static void Draw(PPCContext& ctx, uint8_t* base, PPCFunc* original, uint32_t str
if ((offsetScaleModifier.flags & OFFSET_SCALE_LEFT) != 0) if ((offsetScaleModifier.flags & OFFSET_SCALE_LEFT) != 0)
offsetX *= corner / offsetScaleModifier.cornerMax; offsetX *= corner / offsetScaleModifier.cornerMax;
else if ((offsetScaleModifier.flags & OFFSET_SCALE_RIGHT) != 0) else if ((offsetScaleModifier.flags & OFFSET_SCALE_RIGHT) != 0)
offsetX = 1280.0f - (1280.0f - offsetX) * (1280.0f - corner) / (1280.0f - offsetScaleModifier.cornerMax); offsetX = Video::s_viewportWidth - (Video::s_viewportWidth - offsetX) * (1280.0f - corner) / (1280.0f - offsetScaleModifier.cornerMax);
} }
for (size_t i = 0; i < ctx.r5.u32; i++) for (size_t i = 0; i < ctx.r5.u32; i++)
@@ -852,11 +864,11 @@ static void Draw(PPCContext& ctx, uint8_t* base, PPCFunc* original, uint32_t str
} }
else if ((modifier.flags & EXTEND_RIGHT) != 0 && (i == 2 || i == 3)) else if ((modifier.flags & EXTEND_RIGHT) != 0 && (i == 2 || i == 3))
{ {
x = std::max(x, float(backBuffer->width)); x = std::max(x, float(Video::s_viewportWidth));
} }
position[0] = round(x / backBuffer->width * Video::s_viewportWidth) / Video::s_viewportWidth * backBuffer->width; position[0] = round(x);
position[1] = round(y / backBuffer->height * Video::s_viewportHeight) / Video::s_viewportHeight * backBuffer->height; position[1] = round(y);
} }
ctx.r4.u32 = ctx.r1.u32; ctx.r4.u32 = ctx.r1.u32;
@@ -882,13 +894,12 @@ PPC_FUNC(sub_825E2E88)
PPC_FUNC_IMPL(__imp__sub_82E16C70); PPC_FUNC_IMPL(__imp__sub_82E16C70);
PPC_FUNC(sub_82E16C70) PPC_FUNC(sub_82E16C70)
{ {
auto backBuffer = Video::GetBackBuffer();
auto scissorRect = reinterpret_cast<GuestRect*>(base + ctx.r4.u32); auto scissorRect = reinterpret_cast<GuestRect*>(base + ctx.r4.u32);
scissorRect->left = scissorRect->left + g_aspectRatioOffsetX; scissorRect->left = scissorRect->left * g_aspectRatioScale + g_aspectRatioOffsetX;
scissorRect->top = scissorRect->top + g_aspectRatioOffsetY; scissorRect->top = scissorRect->top * g_aspectRatioScale + g_aspectRatioOffsetY;
scissorRect->right = scissorRect->right + g_aspectRatioOffsetX; scissorRect->right = scissorRect->right * g_aspectRatioScale + g_aspectRatioOffsetX;
scissorRect->bottom = scissorRect->bottom + g_aspectRatioOffsetY; scissorRect->bottom = scissorRect->bottom * g_aspectRatioScale + g_aspectRatioOffsetY;
__imp__sub_82E16C70(ctx, base); __imp__sub_82E16C70(ctx, base);
} }
@@ -926,10 +937,6 @@ PPC_FUNC(sub_830D1EF0)
__imp__sub_830D1EF0(ctx, base); __imp__sub_830D1EF0(ctx, base);
if (!PPC_LOAD_U8(r3.u32 + PRIMITIVE_2D_PADDING_OFFSET))
{
auto backBuffer = Video::GetBackBuffer();
struct Vertex struct Vertex
{ {
be<float> x; be<float> x;
@@ -945,8 +952,24 @@ PPC_FUNC(sub_830D1EF0)
for (size_t i = 0; i < 4; i++) for (size_t i = 0; i < 4; i++)
{ {
vertex[i].x = vertex[i].x * 1280.0f / backBuffer->width; float x = vertex[i].x * 640.0f + 640.0f;
vertex[i].y = vertex[i].y * 720.0f / backBuffer->height; float y = vertex[i].y * -360.0f + 360.0f;
if (PPC_LOAD_U8(r3.u32 + PRIMITIVE_2D_PADDING_OFFSET))
{
// Stretch
x = ((x + 0.5f) / 1280.0f) * Video::s_viewportWidth;
y = ((y + 0.5f) / 720.0f) * Video::s_viewportHeight;
}
else
{
// Center
x = g_aspectRatioOffsetX + (x + 0.5f) * g_aspectRatioScale;
y = g_aspectRatioOffsetY + (y + 0.5f) * g_aspectRatioScale;
}
vertex[i].x = ((x - 0.5f) / Video::s_viewportWidth) * 2.0f - 1.0f;
vertex[i].y = ((y - 0.5f) / Video::s_viewportHeight) * -2.0f + 1.0f;
} }
bool letterboxTop = PPC_LOAD_U8(r3.u32 + PRIMITIVE_2D_PADDING_OFFSET + 0x1); bool letterboxTop = PPC_LOAD_U8(r3.u32 + PRIMITIVE_2D_PADDING_OFFSET + 0x1);
@@ -954,8 +977,8 @@ PPC_FUNC(sub_830D1EF0)
if (letterboxTop || letterboxBottom) if (letterboxTop || letterboxBottom)
{ {
float halfPixelX = 1.0f / backBuffer->width; float halfPixelX = 1.0f / Video::s_viewportWidth;
float halfPixelY = 1.0f / backBuffer->height; float halfPixelY = 1.0f / Video::s_viewportHeight;
if (letterboxTop) if (letterboxTop)
{ {
@@ -987,7 +1010,6 @@ PPC_FUNC(sub_830D1EF0)
} }
} }
} }
}
// Objects are pushed forward by 1m, so the coordinates need to compensate for it. // Objects are pushed forward by 1m, so the coordinates need to compensate for it.
static const double OBJ_GET_ITEM_TANGENT = tan(M_PI / 8.0); static const double OBJ_GET_ITEM_TANGENT = tan(M_PI / 8.0);
@@ -1018,8 +1040,9 @@ static double ComputeObjGetItemX(uint32_t type)
x = 1058.0; x = 1058.0;
x *= g_aspectRatioScale; x *= g_aspectRatioScale;
x *= g_aspectRatioGameplayScale;
double scaleOffset = (1280.0 * (1.0 - g_aspectRatioScale)); double scaleOffset = (1280.0 * (1.0 - g_aspectRatioGameplayScale)) * g_aspectRatioScale;
if (Config::UIScaleMode == EUIScaleMode::Edge) if (Config::UIScaleMode == EUIScaleMode::Edge)
{ {
@@ -1031,8 +1054,7 @@ static double ComputeObjGetItemX(uint32_t type)
x += g_aspectRatioOffsetX + scaleOffset; x += g_aspectRatioOffsetX + scaleOffset;
} }
auto backBuffer = Video::GetBackBuffer(); return (x - (0.5 * Video::s_viewportWidth)) / (0.5 * Video::s_viewportHeight) * OBJ_GET_ITEM_TANGENT;
return (x - (0.5 * backBuffer->width)) / (0.5 * backBuffer->height) * OBJ_GET_ITEM_TANGENT;
} }
return 0.0; return 0.0;
@@ -1066,10 +1088,10 @@ static double ComputeObjGetItemY(uint32_t type)
y = 582.0; y = 582.0;
y *= g_aspectRatioScale; y *= g_aspectRatioScale;
y += g_aspectRatioOffsetY * 2.0 + 720.0 * (1.0 - g_aspectRatioScale); y *= g_aspectRatioGameplayScale;
y += g_aspectRatioOffsetY * 2.0 + 720.0 * (1.0 - g_aspectRatioGameplayScale) * g_aspectRatioScale;
auto backBuffer = Video::GetBackBuffer(); return ((0.5 * Video::s_viewportHeight) - y) / (0.5 * Video::s_viewportHeight) * OBJ_GET_ITEM_TANGENT;
return ((0.5 * backBuffer->height) - y) / (0.5 * backBuffer->height) * OBJ_GET_ITEM_TANGENT;
} }
return 0.25; return 0.25;
@@ -1133,12 +1155,12 @@ PPC_FUNC(sub_82B8AA40)
PPC_STORE_U8(ctx.r3.u32, shouldDrawLetterbox); PPC_STORE_U8(ctx.r3.u32, shouldDrawLetterbox);
if (shouldDrawLetterbox) if (shouldDrawLetterbox)
{ {
auto backBuffer = Video::GetBackBuffer(); float aspectRatio = std::max(NARROW_ASPECT_RATIO, g_aspectRatio);
uint32_t height = std::min(720u, backBuffer->height); uint32_t width = aspectRatio * 720;
PPC_STORE_U32(ctx.r3.u32 + 0xC, backBuffer->width); PPC_STORE_U32(ctx.r3.u32 + 0xC, width);
PPC_STORE_U32(ctx.r3.u32 + 0x10, height); PPC_STORE_U32(ctx.r3.u32 + 0x10, 720);
PPC_STORE_U32(ctx.r3.u32 + 0x14, (height - backBuffer->width * 9 / 16) / 2); PPC_STORE_U32(ctx.r3.u32 + 0x14, (720 - width * 9 / 16) / 2);
} }
__imp__sub_82B8AA40(ctx, base); __imp__sub_82B8AA40(ctx, base);
@@ -1161,5 +1183,5 @@ void InspireSubtitleMidAsmHook(PPCRegister& r3)
constexpr float NARROW_OFFSET = 485.0f; constexpr float NARROW_OFFSET = 485.0f;
constexpr float WIDE_OFFSET = 560.0f; constexpr float WIDE_OFFSET = 560.0f;
*reinterpret_cast<be<float>*>(g_memory.base + r3.u32 + 0x3C) = NARROW_OFFSET + (WIDE_OFFSET - NARROW_OFFSET) * g_narrowOffsetScale; *reinterpret_cast<be<float>*>(g_memory.base + r3.u32 + 0x3C) = NARROW_OFFSET + (WIDE_OFFSET - NARROW_OFFSET) * g_aspectRatioNarrowScale;
} }
@@ -8,7 +8,8 @@ inline float g_aspectRatio;
inline float g_aspectRatioOffsetX; inline float g_aspectRatioOffsetX;
inline float g_aspectRatioOffsetY; inline float g_aspectRatioOffsetY;
inline float g_aspectRatioScale; inline float g_aspectRatioScale;
inline float g_narrowOffsetScale; inline float g_aspectRatioGameplayScale;
inline float g_aspectRatioNarrowScale;
struct AspectRatioPatches struct AspectRatioPatches
{ {
-97
View File
@@ -1,97 +0,0 @@
#include <api/SWA.h>
#include <ui/game_window.h>
#include <user/config.h>
#include <ui/reddog/debug_draw.h>
#include <ui/imgui_utils.h>
#include <patches/aspect_ratio_patches.h>
// boost::~::SWA::CDebugDraw::CMember::SDrawLine
PPC_FUNC_IMPL(__imp__sub_822C9398);
PPC_FUNC(sub_822C9398)
{
auto a2 = (Hedgehog::Math::CVector*)g_memory.Translate(ctx.r4.u32);
auto a3 = (Hedgehog::Math::CVector*)g_memory.Translate(ctx.r5.u32);
auto a4 = (be<unsigned int>*)g_memory.Translate(ctx.r6.u32);
Reddog::Vector3 start(a2->X, a2->Y, a2->Z);
Reddog::Vector3 end(a3->X, a3->Y, a3->Z);
const Reddog::SDrawLine line{
start, end, a4->value
};
Reddog::DebugDraw::DrawLine(line);
__imp__sub_822C9398(ctx, base);
}
// SWA::CStageManager::UpdateParallel
//PPC_FUNC_IMPL(__imp__sub_82521C68);
//PPC_FUNC(sub_82521C68)
//{
// __imp__sub_82521C68(ctx, base);
//}
// SWA::CStageManager::UpdateSerial
PPC_FUNC_IMPL(__imp__sub_82522040);
PPC_FUNC(sub_82522040)
{
auto a1 = static_cast<SWA::CStageManager*>(g_memory.Translate(ctx.r3.u32));
__imp__sub_82522040(ctx, base);
// Draw player position
if (Reddog::DebugDraw::GetIsDrawPosition())
{
// TODO (RadiantDerg): Reimplement SWA::CStageManager ability to draw progress ratio
// NOTE: Currently does not work, is the API mapping horribly misaligned/misunderstood?
if (a1->m_spStageGuidePathController)
{
if (a1->m_spStageGuidePathController->m_spPathAnimationController)
{
auto PAC = a1->m_spStageGuidePathController->m_spPathAnimationController;
//Reddog::DebugDraw::DrawTextLog(fmt::format("m_DistanceAlongPath = {:.2f}", PAC->m_DistanceAlongPath.get()).c_str());
}
// Ratio
if (a1->m_StageGuidePathLength.get() > 0.0f)
{
//float distance = 0; // GetDistanceAlongPath(a1->m_StageGuidePathController)
//a1->m_StageGuidePathRatio = distance / a1->m_StageGuidePathLength;
const Reddog::SDrawText ratioText{
{Scale(g_aspectRatioOffsetX + 720), Scale(g_aspectRatioOffsetY + 36)},
fmt::format("{:.1f}m [{:.1f}/100.0]", a1->m_StageGuidePathLength.get(), a1->m_StageGuidePathRatio.get()),
0,
3.25f,
0xFFFFFFFF,
Reddog::eDrawTextFlags_NoShadow
};
Reddog::DebugDraw::DrawText2D(ratioText);
}
}
// Position
const Reddog::SDrawText positionText{
{Scale(g_aspectRatioOffsetX + 750), Scale(g_aspectRatioOffsetY + 120)},
fmt::format("( {:.2f}, {:.2f}, {:.2f} )", a1->m_PlayerPosition.X.get(), a1->m_PlayerPosition.Y.get(), a1->m_PlayerPosition.Z.get()),
0,
2.0f,
0xFFFFFFFF,
Reddog::eDrawTextFlags_NoShadow
};
Reddog::DebugDraw::DrawText2D(positionText);
}
}
// GetIsDebugRenderForGameObject()
//PPC_FUNC(sub_82512BF8)
//{
// ctx.r3.u8 = 1; // Always return true
//}
+3 -2
View File
@@ -94,7 +94,8 @@ bool LoadingUpdateMidAsmHook(PPCRegister& r31)
g_ppcContext->f1.f64 = deltaTime; g_ppcContext->f1.f64 = deltaTime;
g_memory.FindFunction(update)(*g_ppcContext, base); g_memory.FindFunction(update)(*g_ppcContext, base);
if (*SWA::SGlobals::ms_IsLoading) bool loading = PPC_LOAD_U8(0x83367A4C);
if (loading)
{ {
now = std::chrono::steady_clock::now(); now = std::chrono::steady_clock::now();
constexpr auto INTERVAL = 1000000000ns / 30; constexpr auto INTERVAL = 1000000000ns / 30;
@@ -103,7 +104,7 @@ bool LoadingUpdateMidAsmHook(PPCRegister& r31)
std::this_thread::sleep_until(next); std::this_thread::sleep_until(next);
} }
return *SWA::SGlobals::ms_IsLoading; return loading;
} }
// ADXM_WaitVsync // ADXM_WaitVsync
+348
View File
@@ -0,0 +1,348 @@
#include <api/SWA.h>
#include <hid/hid.h>
#include <ui/sdl_listener.h>
#include <app.h>
#include <exports.h>
class WorldMapTouchParams
{
public:
float CancelDeadzone{ 0.31f };
float Damping{ 0.99f };
float FlickAccelX{ 0.25f };
float FlickAccelY{ 0.1f };
float FlickTerminalVelocity{ 40.0f };
float FlickThreshold{ 2.25f };
float SensitivityX{};
float SensitivityY{};
float Smoothing{ 0.8f };
};
class WorldMapTouchParamsProspero : public WorldMapTouchParams
{
public:
WorldMapTouchParamsProspero()
{
SensitivityX = 1.15f;
SensitivityY = 1.05f;
}
}
g_worldMapTouchParamsProspero;
class WorldMapTouchParamsOrbis : public WorldMapTouchParams
{
public:
WorldMapTouchParamsOrbis()
{
SensitivityX = 0.95f;
SensitivityY = 1.0f;
}
}
g_worldMapTouchParamsOrbis;
WorldMapTouchParams g_worldMapTouchParams{};
static bool g_isTouchActive;
static float g_worldMapTouchVelocityX;
static float g_worldMapTouchVelocityY;
class SDLEventListenerForInputPatches : public SDLEventListener
{
static inline int ms_touchpadFingerCount;
static inline float ms_touchpadX;
static inline float ms_touchpadY;
static inline float ms_touchpadDeltaX;
static inline float ms_touchpadDeltaY;
static inline float ms_touchpadPrevX;
static inline float ms_touchpadPrevY;
public:
static void Update(float deltaTime)
{
/* NOTE (Hyper): this code was written at 144Hz and was
discovered later to be faulty at any other frame rate,
so this is here to account for that without changing
all the constants that I had tuned. */
constexpr auto referenceDeltaTime = 1.0f / 144.0f;
if (g_isTouchActive)
{
auto dxNorm = ms_touchpadDeltaX / referenceDeltaTime;
auto dyNorm = ms_touchpadDeltaY / referenceDeltaTime;
auto dxSens = dxNorm * g_worldMapTouchParams.SensitivityX;
auto dySens = dyNorm * g_worldMapTouchParams.SensitivityY;
auto smoothing = powf(g_worldMapTouchParams.Smoothing, deltaTime / referenceDeltaTime);
g_worldMapTouchVelocityX = smoothing * g_worldMapTouchVelocityX + (1.0f - smoothing) * dxSens;
g_worldMapTouchVelocityY = smoothing * g_worldMapTouchVelocityY + (1.0f - smoothing) * dySens;
auto flickThreshold = g_worldMapTouchParams.FlickThreshold;
if (fabs(dxSens) > flickThreshold || fabs(dySens) > flickThreshold)
{
g_worldMapTouchVelocityX += dxNorm * g_worldMapTouchParams.FlickAccelX * (deltaTime / referenceDeltaTime);
g_worldMapTouchVelocityY += dyNorm * g_worldMapTouchParams.FlickAccelY * (deltaTime / referenceDeltaTime);
}
auto terminalVelocity = g_worldMapTouchParams.FlickTerminalVelocity;
g_worldMapTouchVelocityX = std::clamp(g_worldMapTouchVelocityX, -terminalVelocity, terminalVelocity);
g_worldMapTouchVelocityY = std::clamp(g_worldMapTouchVelocityY, -terminalVelocity, terminalVelocity);
}
else
{
auto dampingFactor = powf(g_worldMapTouchParams.Damping, deltaTime / referenceDeltaTime);
g_worldMapTouchVelocityX *= dampingFactor;
g_worldMapTouchVelocityY *= dampingFactor;
}
}
void OnSDLEvent(SDL_Event* event) override
{
switch (event->type)
{
case SDL_CONTROLLERTOUCHPADMOTION:
{
g_isTouchActive = true;
if (ms_touchpadFingerCount > 1)
{
g_isTouchActive = false;
break;
}
ms_touchpadX = event->ctouchpad.x;
ms_touchpadY = event->ctouchpad.y;
ms_touchpadDeltaX = ms_touchpadX - ms_touchpadPrevX;
ms_touchpadDeltaY = ms_touchpadY - ms_touchpadPrevY;
ms_touchpadPrevX = ms_touchpadX;
ms_touchpadPrevY = ms_touchpadY;
break;
}
case SDL_CONTROLLERTOUCHPADDOWN:
{
g_worldMapTouchParams = hid::g_inputDeviceExplicit == hid::EInputDeviceExplicit::DualSense
? (WorldMapTouchParams)g_worldMapTouchParamsProspero
: (WorldMapTouchParams)g_worldMapTouchParamsOrbis;
ms_touchpadFingerCount++;
ms_touchpadPrevX = event->ctouchpad.x;
ms_touchpadPrevY = event->ctouchpad.y;
break;
}
case SDL_CONTROLLERTOUCHPADUP:
g_isTouchActive = false;
ms_touchpadFingerCount--;
break;
}
}
}
g_sdlEventListenerForInputPatches;
// -------------- COMMON --------------- //
static bool IsDPadActive(SWA::SPadState* pPadState)
{
return pPadState->IsDown(SWA::eKeyState_DpadUp) ||
pPadState->IsDown(SWA::eKeyState_DpadDown) ||
pPadState->IsDown(SWA::eKeyState_DpadLeft) ||
pPadState->IsDown(SWA::eKeyState_DpadRight);
}
static void SetDPadAnalogDirectionX(PPCRegister& pPadState, PPCRegister& x, bool invert, float max = 1.0f)
{
auto pGuestPadState = (SWA::SPadState*)g_memory.Translate(pPadState.u32);
if (pGuestPadState->IsDown(SWA::eKeyState_DpadLeft))
x.f64 = invert ? max : -max;
if (pGuestPadState->IsDown(SWA::eKeyState_DpadRight))
x.f64 = invert ? -max : max;
}
static void SetDPadAnalogDirectionY(PPCRegister& pPadState, PPCRegister& y, bool invert, float max = 1.0f)
{
auto pGuestPadState = (SWA::SPadState*)g_memory.Translate(pPadState.u32);
if (pGuestPadState->IsDown(SWA::eKeyState_DpadUp))
y.f64 = invert ? -max : max;
if (pGuestPadState->IsDown(SWA::eKeyState_DpadDown))
y.f64 = invert ? max : -max;
}
// -------------- PLAYER --------------- //
void PostureDPadSupportMidAsmHook(PPCRegister& pPadState, PPCRegister& x, PPCRegister& y)
{
SetDPadAnalogDirectionX(pPadState, x, false);
SetDPadAnalogDirectionY(pPadState, y, false);
}
void PostureDPadSupportInvertYMidAsmHook(PPCRegister& pPadState, PPCRegister& x, PPCRegister& y)
{
SetDPadAnalogDirectionX(pPadState, x, false);
SetDPadAnalogDirectionY(pPadState, y, true);
}
void PostureDPadSupportXMidAsmHook(PPCRegister& pPadState, PPCRegister& x)
{
SetDPadAnalogDirectionX(pPadState, x, false);
}
void PostureDPadSupportYMidAsmHook(PPCRegister& pPadState, PPCRegister& y)
{
SetDPadAnalogDirectionY(pPadState, y, false);
}
void PostureSpaceHurrierDPadSupportXMidAsmHook(PPCRegister& pPadState, PPCVRegister& vector)
{
auto pGuestPadState = (SWA::SPadState*)g_memory.Translate(pPadState.u32);
if (pGuestPadState->IsDown(SWA::eKeyState_DpadLeft))
vector.f32[3] = -1.0f;
if (pGuestPadState->IsDown(SWA::eKeyState_DpadRight))
vector.f32[3] = 1.0f;
}
void PostureSpaceHurrierDPadSupportYMidAsmHook(PPCRegister& pPadState, PPCVRegister& vector)
{
auto pGuestPadState = (SWA::SPadState*)g_memory.Translate(pPadState.u32);
if (pGuestPadState->IsDown(SWA::eKeyState_DpadUp))
vector.f32[3] = 1.0f;
if (pGuestPadState->IsDown(SWA::eKeyState_DpadDown))
vector.f32[3] = -1.0f;
}
// ------------- WORLD MAP ------------- //
bool WorldMapTouchSupportMidAsmHook()
{
SDLEventListenerForInputPatches::Update(App::s_deltaTime);
auto vxAbs = fabs(g_worldMapTouchVelocityX);
auto vyAbs = fabs(g_worldMapTouchVelocityY);
/* Reduce touch noise if the player has
their finger resting on the touchpad,
but allow much precise values without
touch for proper interpolation to zero. */
if (vxAbs < 0.05f || vyAbs < 0.05f)
return !g_isTouchActive;
return vxAbs > 0 || vyAbs > 0;
}
bool WorldMapTouchMagnetismSupportMidAsmHook(PPCRegister& f0)
{
return fabs(g_worldMapTouchVelocityX) > f0.f64 || fabs(g_worldMapTouchVelocityY) > f0.f64;
}
void TouchAndDPadSupportWorldMapXMidAsmHook(PPCRegister& pPadState, PPCRegister& x)
{
auto pGuestPadState = (SWA::SPadState*)g_memory.Translate(pPadState.u32);
if (fabs(pGuestPadState->LeftStickHorizontal) > g_worldMapTouchParams.CancelDeadzone ||
fabs(pGuestPadState->LeftStickVertical) > g_worldMapTouchParams.CancelDeadzone)
{
g_worldMapTouchVelocityX = 0;
}
if (IsDPadActive(pGuestPadState))
{
g_worldMapTouchVelocityX = 0;
SetDPadAnalogDirectionX(pPadState, x, false);
}
else
{
if (fabs(g_worldMapTouchVelocityX) > 0)
x.f64 = -g_worldMapTouchVelocityX;
}
}
void TouchAndDPadSupportWorldMapYMidAsmHook(PPCRegister& pPadState, PPCRegister& y)
{
auto pGuestPadState = (SWA::SPadState*)g_memory.Translate(pPadState.u32);
if (fabs(pGuestPadState->LeftStickHorizontal) > g_worldMapTouchParams.CancelDeadzone ||
fabs(pGuestPadState->LeftStickVertical) > g_worldMapTouchParams.CancelDeadzone)
{
g_worldMapTouchVelocityY = 0;
}
if (IsDPadActive(pGuestPadState))
{
g_worldMapTouchVelocityY = 0;
SetDPadAnalogDirectionY(pPadState, y, false);
}
else
{
if (fabs(g_worldMapTouchVelocityY) > 0)
y.f64 = g_worldMapTouchVelocityY;
}
}
// SWA::CWorldMapCamera::Update
PPC_FUNC_IMPL(__imp__sub_82486968);
PPC_FUNC(sub_82486968)
{
auto pWorldMapCamera = (SWA::CWorldMapCamera*)g_memory.Translate(ctx.r3.u32);
// Reset vertical velocity if maximum pitch reached.
if (fabs(pWorldMapCamera->m_Pitch) >= 80.0f)
g_worldMapTouchVelocityY = 0;
__imp__sub_82486968(ctx, base);
}
// World Map cursor move hook.
PPC_FUNC(sub_8256C938)
{
auto pWorldMapCursor = (SWA::CWorldMapCursor*)g_memory.Translate(ctx.r3.u32);
pWorldMapCursor->m_IsCursorMoving = g_isTouchActive;
if (ctx.r4.u8)
{
pWorldMapCursor->m_LeftStickVertical = 0;
pWorldMapCursor->m_LeftStickHorizontal = 0;
}
else if (auto pInputState = SWA::CInputState::GetInstance())
{
auto& rPadState = pInputState->GetPadState();
pWorldMapCursor->m_LeftStickVertical = rPadState.LeftStickVertical;
pWorldMapCursor->m_LeftStickHorizontal = rPadState.LeftStickHorizontal;
if (rPadState.IsDown(SWA::eKeyState_DpadUp))
pWorldMapCursor->m_LeftStickVertical = 1.0f;
if (rPadState.IsDown(SWA::eKeyState_DpadDown))
pWorldMapCursor->m_LeftStickVertical = -1.0f;
if (rPadState.IsDown(SWA::eKeyState_DpadLeft))
pWorldMapCursor->m_LeftStickHorizontal = -1.0f;
if (rPadState.IsDown(SWA::eKeyState_DpadRight))
pWorldMapCursor->m_LeftStickHorizontal = 1.0f;
if (sqrtf((pWorldMapCursor->m_LeftStickHorizontal * pWorldMapCursor->m_LeftStickHorizontal) +
(pWorldMapCursor->m_LeftStickVertical * pWorldMapCursor->m_LeftStickVertical)) > 0.7f)
{
pWorldMapCursor->m_IsCursorMoving = true;
}
}
}
-3
View File
@@ -1,5 +1,4 @@
#include <api/SWA.h> #include <api/SWA.h>
#include <ui/reddog/debug_draw.h>
#include <ui/game_window.h> #include <ui/game_window.h>
#include <user/achievement_data.h> #include <user/achievement_data.h>
#include <user/config.h> #include <user/config.h>
@@ -50,8 +49,6 @@ void WerehogBattleMusicMidAsmHook(PPCRegister& r11)
r11.u8 = 3; r11.u8 = 3;
} }
void StorageDevicePromptMidAsmHook() {}
/* Hook function that gets the game region /* Hook function that gets the game region
and force result to zero for Japanese and force result to zero for Japanese
to display the correct logos. */ to display the correct logos. */
@@ -1,3 +1,6 @@
#include <user/config.h>
#include <SWA/CharacterUtility/CharacterProxy.h>
// CObjFlame::CObjFlame // CObjFlame::CObjFlame
// A field is not zero initialized, // A field is not zero initialized,
// causing collisions to constantly get created // causing collisions to constantly get created
@@ -8,3 +11,59 @@ PPC_FUNC(sub_82608E60)
memset(base + ctx.r3.u32, 0, 0x154); memset(base + ctx.r3.u32, 0, 0x154);
__imp__sub_82608E60(ctx, base); __imp__sub_82608E60(ctx, base);
} }
// The barrel gets stuck at a slope at high frame rates and softlocks the player.
// We can update the character proxy at 30 FPS, and interpolate the visuals to work around this issue.
static constexpr size_t OBJ_BIG_BARREL_SIZE = 0x1A0;
struct ObjBigBarrelEx
{
float elapsedTime{};
bool interpolate{};
};
void ObjBigBarrelAllocMidAsmHook(PPCRegister& r3)
{
r3.u32 += sizeof(ObjBigBarrelEx);
}
// CObjBigBarrel::CObjBigBarrel
PPC_FUNC_IMPL(__imp__sub_8271AC08);
PPC_FUNC(sub_8271AC08)
{
new (base + ctx.r3.u32 + OBJ_BIG_BARREL_SIZE) ObjBigBarrelEx();
__imp__sub_8271AC08(ctx, base);
}
// CObjBigBarrel::Integrate
PPC_FUNC_IMPL(__imp__sub_8271AA30);
PPC_FUNC(sub_8271AA30)
{
auto objBigBarrelEx = reinterpret_cast<ObjBigBarrelEx*>(base + ctx.r3.u32 + OBJ_BIG_BARREL_SIZE);
objBigBarrelEx->interpolate = ctx.f1.f64 < (1.0 / 30.0);
objBigBarrelEx->elapsedTime += ctx.f1.f64;
if (!objBigBarrelEx->interpolate || objBigBarrelEx->elapsedTime >= (1.0f / 30.0f))
{
ctx.f1.f64 = objBigBarrelEx->elapsedTime;
__imp__sub_8271AA30(ctx, base);
objBigBarrelEx->elapsedTime = 0.0f;
}
}
void ObjBigBarrelSetPositionMidAsmHook(PPCRegister& r3, PPCRegister& r4)
{
uint8_t* base = g_memory.base;
auto objBigBarrelEx = reinterpret_cast<ObjBigBarrelEx*>(base + r3.u32 + OBJ_BIG_BARREL_SIZE);
if (objBigBarrelEx->interpolate)
{
auto characterProxy = reinterpret_cast<SWA::CCharacterProxy*>(base + PPC_LOAD_U32(r3.u32 + 0x100));
auto position = reinterpret_cast<Hedgehog::Math::CVector*>(base + r4.u32);
float factor = (1.0f / 30.0f) - objBigBarrelEx->elapsedTime;
position->X = position->X - characterProxy->m_Velocity.X * factor;
position->Y = position->Y - characterProxy->m_Velocity.Y * factor;
position->Z = position->Z - characterProxy->m_Velocity.Z * factor;
}
}
@@ -10,26 +10,6 @@ static uint32_t g_lastTrickScore;
static float g_lastDarkGaiaEnergy; static float g_lastDarkGaiaEnergy;
static bool g_isUnleashCancelled; static bool g_isUnleashCancelled;
void PostureDPadSupportMidAsmHook(PPCRegister& r3)
{
if (!Config::AllowDPadMovement)
return;
auto pPadState = (SWA::SPadState*)g_memory.Translate(r3.u32);
if (pPadState->IsDown(SWA::eKeyState_DpadUp))
pPadState->LeftStickVertical = 1.0f;
if (pPadState->IsDown(SWA::eKeyState_DpadDown))
pPadState->LeftStickVertical = -1.0f;
if (pPadState->IsDown(SWA::eKeyState_DpadLeft))
pPadState->LeftStickHorizontal = -1.0f;
if (pPadState->IsDown(SWA::eKeyState_DpadRight))
pPadState->LeftStickHorizontal = 1.0f;
}
/* Hook function for when checkpoints are activated /* Hook function for when checkpoints are activated
to preserve the current checkpoint score. */ to preserve the current checkpoint score. */
PPC_FUNC_IMPL(__imp__sub_82624308); PPC_FUNC_IMPL(__imp__sub_82624308);
+4 -2
View File
@@ -2,7 +2,7 @@
#include <user/config.h> #include <user/config.h>
#include <api/SWA.h> #include <api/SWA.h>
#include <os/logger.h> #include <os/logger.h>
#include <hid/hid_detail.h> #include <hid/hid.h>
#include <app.h> #include <app.h>
bool m_isSavedAchievementData = false; bool m_isSavedAchievementData = false;
@@ -69,6 +69,8 @@ PPC_FUNC(sub_824E5170)
if (pSaveIcon->m_IsVisible) if (pSaveIcon->m_IsVisible)
{ {
App::s_isSaveDataCorrupt = false;
if (!m_isSavedAchievementData) if (!m_isSavedAchievementData)
{ {
LOGN("Saving achievements..."); LOGN("Saving achievements...");
@@ -131,7 +133,7 @@ void LoadingScreenControllerMidAsmHook()
auto isPlayStation = Config::ControllerIcons == EControllerIcons::PlayStation; auto isPlayStation = Config::ControllerIcons == EControllerIcons::PlayStation;
if (Config::ControllerIcons == EControllerIcons::Auto) if (Config::ControllerIcons == EControllerIcons::Auto)
isPlayStation = hid::detail::g_inputDeviceController == hid::detail::EInputDevice::PlayStation; isPlayStation = hid::g_inputDeviceController == hid::EInputDevice::PlayStation;
const char* prefix = isPlayStation ? "ps3" : "360"; const char* prefix = isPlayStation ? "ps3" : "360";

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