Compare commits

..

3 Commits

Author SHA1 Message Date
madeline d204de47bf Merge branch 'main' of https://github.com/TakaRikka/dusk into phong 2026-05-12 20:37:35 -07:00
madeline 23dc0cdbf0 Merge branch 'main' into phong 2026-05-12 19:35:31 -07:00
madeline 24b468f2a2 phong 2026-04-26 01:08:58 -07:00
99 changed files with 822 additions and 1704 deletions
+7 -23
View File
@@ -5,19 +5,8 @@ if (NOT CMAKE_BUILD_TYPE)
"Build type options: Debug Release RelWithDebInfo MinSizeRel" FORCE) "Build type options: Debug Release RelWithDebInfo MinSizeRel" FORCE)
endif () endif ()
set(DUSK_VERSION_OVERRIDE "" CACHE STRING "Override version string (skips git detection and format validation)") # obtain revision info from git
find_package(Git)
if (DUSK_VERSION_OVERRIDE)
set(DUSK_WC_DESCRIBE "${DUSK_VERSION_OVERRIDE}")
set(DUSK_VERSION_STRING "0.0.0.0")
set(DUSK_SHORT_VERSION_STRING "0.0.0")
set(DUSK_WC_REVISION "")
set(DUSK_WC_BRANCH "")
set(DUSK_WC_DATE "")
message(STATUS "Dusklight version overridden to ${DUSK_WC_DESCRIBE}")
else ()
# obtain revision info from git
find_package(Git)
if (GIT_FOUND) if (GIT_FOUND)
# make sure version information gets re-run when the current Git HEAD changes # make sure version information gets re-run when the current Git HEAD changes
execute_process(WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND ${GIT_EXECUTABLE} rev-parse --git-path HEAD execute_process(WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND ${GIT_EXECUTABLE} rev-parse --git-path HEAD
@@ -74,8 +63,6 @@ else ()
set(DUSK_SHORT_VERSION_STRING "0.0.0") set(DUSK_SHORT_VERSION_STRING "0.0.0")
endif () endif ()
endif ()
# Add version information to CI environment variables # Add version information to CI environment variables
if(DEFINED ENV{GITHUB_ENV}) if(DEFINED ENV{GITHUB_ENV})
file(APPEND "$ENV{GITHUB_ENV}" "DUSK_VERSION=${DUSK_WC_DESCRIBE}\n") file(APPEND "$ENV{GITHUB_ENV}" "DUSK_VERSION=${DUSK_WC_DESCRIBE}\n")
@@ -125,6 +112,11 @@ option(DUSK_BUILD_WARNINGS "Enable compiler warnings (off by default)")
option(DUSK_SELECTED_OPT "If on, selected parts of the project will be compiled with optimizations on Debug, intending to make the game run at 30 FPS. Note for MSVC: you will need to remove '/RTC1' from your debug flags in CMake.") option(DUSK_SELECTED_OPT "If on, selected parts of the project will be compiled with optimizations on Debug, intending to make the game run at 30 FPS. Note for MSVC: you will need to remove '/RTC1' from your debug flags in CMake.")
option(DUSK_MOVIE_SUPPORT "If on, compile against libjpeg-turbo to enable THP file decoding" ON) option(DUSK_MOVIE_SUPPORT "If on, compile against libjpeg-turbo to enable THP file decoding" ON)
option(DUSK_ENABLE_UPDATE_CHECKER "Enable update checking support" ON) option(DUSK_ENABLE_UPDATE_CHECKER "Enable update checking support" ON)
if(ANDROID)
set(DUSK_MOVIE_SUPPORT OFF)
endif ()
option(DUSK_ENABLE_SENTRY_NATIVE "Enable sentry-native crash reporting support" OFF) option(DUSK_ENABLE_SENTRY_NATIVE "Enable sentry-native crash reporting support" OFF)
set(DUSK_SENTRY_DSN "" CACHE STRING "Sentry DSN") set(DUSK_SENTRY_DSN "" CACHE STRING "Sentry DSN")
set(DUSK_SENTRY_ENVIRONMENT "development" CACHE STRING "Sentry environment") set(DUSK_SENTRY_ENVIRONMENT "development" CACHE STRING "Sentry environment")
@@ -163,8 +155,6 @@ if (DUSK_MOVIE_SUPPORT)
list(APPEND _jpeg_cmake_args -DCMAKE_TOOLCHAIN_FILE=${_jpeg_toolchain_file}) list(APPEND _jpeg_cmake_args -DCMAKE_TOOLCHAIN_FILE=${_jpeg_toolchain_file})
endif () endif ()
set(_jpeg_passthrough_vars set(_jpeg_passthrough_vars
ANDROID_ABI
ANDROID_PLATFORM
CMAKE_BUILD_TYPE CMAKE_BUILD_TYPE
CMAKE_C_COMPILER CMAKE_C_COMPILER
CMAKE_C_COMPILER_LAUNCHER CMAKE_C_COMPILER_LAUNCHER
@@ -276,12 +266,6 @@ if (DUSK_ENABLE_SENTRY_NATIVE)
endif () endif ()
endif () endif ()
# Use signed char on ARM to match the original game (and x86)
string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" _arch)
if(_arch MATCHES "^(arm|aarch64)" AND CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU")
add_compile_options(-fsigned-char)
endif()
if (CMAKE_SYSTEM_NAME STREQUAL Windows) if (CMAKE_SYSTEM_NAME STREQUAL Windows)
set(PLATFORM_NAME win32) set(PLATFORM_NAME win32)
elseif (CMAKE_SYSTEM_NAME STREQUAL Darwin) elseif (CMAKE_SYSTEM_NAME STREQUAL Darwin)
+25 -10
View File
@@ -249,11 +249,22 @@
"type": "BOOL", "type": "BOOL",
"value": false "value": false
}, },
"CMAKE_DISABLE_FIND_PACKAGE_PkgConfig": { "CMAKE_DISABLE_FIND_PACKAGE_BZip2": {
"type": "BOOL", "type": "BOOL",
"value": true "value": true
}, },
"CMAKE_IGNORE_PREFIX_PATH": "/opt/homebrew" "CMAKE_DISABLE_FIND_PACKAGE_LibLZMA": {
"type": "BOOL",
"value": true
},
"CMAKE_DISABLE_FIND_PACKAGE_zstd": {
"type": "BOOL",
"value": true
},
"CMAKE_DISABLE_FIND_PACKAGE_Freetype": {
"type": "BOOL",
"value": true
}
}, },
"vendor": { "vendor": {
"microsoft.com/VisualStudioSettings/CMake/1.0": { "microsoft.com/VisualStudioSettings/CMake/1.0": {
@@ -318,11 +329,7 @@
"cacheVariables": { "cacheVariables": {
"CMAKE_INSTALL_PREFIX": "${sourceDir}/build/install", "CMAKE_INSTALL_PREFIX": "${sourceDir}/build/install",
"CMAKE_TOOLCHAIN_FILE": "$env{ANDROID_HOME}/ndk/$env{ANDROID_NDK_VERSION}/build/cmake/android.toolchain.cmake", "CMAKE_TOOLCHAIN_FILE": "$env{ANDROID_HOME}/ndk/$env{ANDROID_NDK_VERSION}/build/cmake/android.toolchain.cmake",
"ANDROID_PLATFORM": "android-28", "ANDROID_PLATFORM": "android-28"
"BUILD_SHARED_LIBS": {
"type": "BOOL",
"value": false
}
} }
}, },
{ {
@@ -409,7 +416,7 @@
}, },
"CMAKE_OSX_DEPLOYMENT_TARGET": "11.0", "CMAKE_OSX_DEPLOYMENT_TARGET": "11.0",
"CMAKE_IGNORE_PREFIX_PATH": "/opt/homebrew", "CMAKE_IGNORE_PREFIX_PATH": "/opt/homebrew",
"BUILD_SHARED_LIBS": { "DUSK_MOVIE_SUPPORT": {
"type": "BOOL", "type": "BOOL",
"value": false "value": false
} }
@@ -442,7 +449,11 @@
], ],
"cacheVariables": { "cacheVariables": {
"CMAKE_C_COMPILER_LAUNCHER": "sccache", "CMAKE_C_COMPILER_LAUNCHER": "sccache",
"CMAKE_CXX_COMPILER_LAUNCHER": "sccache" "CMAKE_CXX_COMPILER_LAUNCHER": "sccache",
"DUSK_MOVIE_SUPPORT": {
"type": "BOOL",
"value": false
}
} }
}, },
{ {
@@ -452,7 +463,11 @@
], ],
"cacheVariables": { "cacheVariables": {
"CMAKE_C_COMPILER_LAUNCHER": "sccache", "CMAKE_C_COMPILER_LAUNCHER": "sccache",
"CMAKE_CXX_COMPILER_LAUNCHER": "sccache" "CMAKE_CXX_COMPILER_LAUNCHER": "sccache",
"DUSK_MOVIE_SUPPORT": {
"type": "BOOL",
"value": false
}
} }
}, },
{ {
+51 -181
View File
@@ -1,165 +1,51 @@
# Building Dusklight ### Building
#### Prerequisites
## Dependencies
The following dependencies are required:
* [CMake 3.25+](https://cmake.org) * [CMake 3.25+](https://cmake.org)
* Windows: Install `CMake Tools` in Visual Studio
* macOS: `brew install cmake`
* [Python 3+](https://python.org) * [Python 3+](https://python.org)
* Windows: [Microsoft Store](https://go.microsoft.com/fwlink?linkID=2082640)
### Windows * Verify it's added to `%PATH%` by typing `python` in `cmd`.
* macOS: `brew install python@3`
* Install [CMake 3.25+](https://cmake.org) by searching `CMake Tools` in Visual Studio * **[Windows]** [Visual Studio 2026 Community](https://www.visualstudio.com/en-us/products/visual-studio-community-vs.aspx)
* Install Python 3 from the [Microsoft Store](https://go.microsoft.com/fwlink?linkID=2082640) and verify it's added to `%PATH%` by typing `python` in `cmd`. * Select `C++ Development` and verify the following packages are included:
* `Windows 11 SDK`
Recommended IDEs: * `CMake Tools`
* `C++ Clang Compiler`
* [Visual Studio 2026 Community](https://www.visualstudio.com/en-us/products/visual-studio-community-vs.aspx). During installation: * `C++ Clang-cl`
* Select `C++ Development` and verify the following packages are included: * **[macOS]** [Xcode 16.4+](https://developer.apple.com/xcode/download/)
* `Windows 11 SDK` * **[Linux]** Actively tested on Ubuntu 24.04, Arch Linux & derivatives.
* `CMake Tools` * Ubuntu 24.04+ packages
* `C++ Clang Compiler` ```
* `C++ Clang-cl` build-essential curl git ninja-build clang lld zlib1g-dev libcurl4-openssl-dev \
libglu1-mesa-dev libdbus-1-dev libvulkan-dev libxi-dev libxrandr-dev libasound2-dev libpulse-dev \
### macOS libudev-dev libpng-dev libncurses5-dev cmake libx11-xcb-dev python3 python-is-python3 \
libclang-dev libfreetype-dev libxinerama-dev libxcursor-dev python3-markupsafe libgtk-3-dev \
* Make sure [Homebrew](https://brew.sh) is installed libxss-dev libxtst-dev
* Install [CMake 3.25+](https://cmake.org) ```
* Arch Linux packages
```sh ```
brew install cmake base-devel cmake ninja llvm vulkan-headers python python-markupsafe clang lld alsa-lib libpulse libxrandr freetype2
``` ```
* Fedora packages
* Install Python 3 ```
cmake vulkan-headers ninja-build clang-devel llvm-devel libpng-devel
```sh ```
brew install python@3 * It's also important that you install the developer tools and libraries
``` ```
sudo dnf groupinstall "Development Tools" "Development Libraries"
Recommended IDEs: ```
#### Setup
* [Xcode 16.4 or later](https://developer.apple.com/xcode/) Clone and initialize the Dusklight repository
* [Visual Studio Code](https://code.visualstudio.com/download/)
* [CLion](https://www.jetbrains.com/clion/)
### Linux
Actively tested on Ubuntu 24.04, Arch Linux & derivatives.
**Ubuntu 24.04+ packages**
<details>
<summary>Click to expand</summary>
* Run the following command to install the required dependencies:
```sh
sudo apt update && sudo apt install -y \
build-essential \
clang \
cmake \
curl \
git \
libasound2-dev \
libclang-dev \
libcurl4-openssl-dev \
libdbus-1-dev \
libfreetype-dev \
libglu1-mesa-dev \
libgtk-3-dev \
libncurses5-dev \
libpng-dev \
libpulse-dev \
libudev-dev \
libvulkan-dev \
libx11-xcb-dev \
libxcursor-dev \
libxi-dev \
libxinerama-dev \
libxrandr-dev \
libxss-dev \
libxtst-dev \
lld \
ninja-build \
python-is-python3 \
python3 \
python3-markupsafe \
zlib1g-dev
```
</details>
<br>
**Arch Linux packages**
<details>
<summary>Click to expand</summary>
* Run the following command to install the required dependencies:
```sh
sudo pacman -S --needed \
alsa-lib \
base-devel \
clang \
cmake \
freetype2 \
libpulse \
libxrandr \
lld \
llvm \
ninja \
python \
python-markupsafe \
vulkan-headers
```
</details>
<br>
**Fedora packages**
<details>
<summary>Click to expand</summary>
* Run the following command to install the required dependencies:
```sh
sudo dnf install -y \
clang-devel \
cmake \
libpng-devel \
llvm-devel \
ninja-build \
vulkan-headers
```
* It's also important that you install the developer tools and libraries
```sh
sudo dnf groupinstall \
"Development Libraries" "Development Tools"
```
</details>
<br>
Recommended IDEs:
* [CLion](https://www.jetbrains.com/clion/)
* [Visual Studio Code](https://code.visualstudio.com/download/)
## Building
* Clone and initialize the Dusklight repository:
```sh ```sh
git clone --recursive https://github.com/TwilitRealm/dusklight.git git clone --recursive https://github.com/TwilitRealm/dusklight.git
git pull
cd dusklight cd dusklight
git pull
git submodule update --init --recursive git submodule update --init --recursive
``` ```
#### Building
**CLion (Windows / macOS / Linux)** **CLion (Windows / macOS / Linux)**
Open the project directory in CLion. Enable the appropriate presets for your platform: Open the project directory in CLion. Enable the appropriate presets for your platform:
@@ -178,8 +64,7 @@ cmake --build --preset macos-default-relwithdebinfo
``` ```
Alternate presets available: Alternate presets available:
- `macos-default-debug`: Clang, Debug
* `macos-default-debug`: Clang, Debug
**ninja (Linux)** **ninja (Linux)**
@@ -189,10 +74,9 @@ cmake --build --preset linux-default-relwithdebinfo
``` ```
Alternate presets available: Alternate presets available:
- `linux-default-debug`: GCC, Debug
* `linux-default-debug`: GCC, Debug - `linux-clang-relwithdebinfo`: Clang, RelWithDebInfo
* `linux-clang-relwithdebinfo`: Clang, RelWithDebInfo - `linux-clang-debug`: Clang, Debug
* `linux-clang-debug`: Clang, Debug
**ninja (Windows)** **ninja (Windows)**
@@ -202,27 +86,13 @@ cmake --build --preset windows-msvc-relwithdebinfo
``` ```
Alternate presets available: Alternate presets available:
- `windows-msvc-debug`: MSVC, Debug
- `windows-clang-relwithdebinfo`: Clang-cl, RelWithDebInfo
- `windows-clang-debug`: Clang-cl, Debug
* `windows-msvc-debug`: MSVC, Debug #### Running
* `windows-clang-relwithdebinfo`: Clang-cl, RelWithDebInfo Pass the disc image as a positional argument. Supported formats: ISO (GCM), RVZ, WIA, WBFS, CISO, GCZ
* `windows-clang-debug`: Clang-cl, Debug
## Running
**Windows / Linux**
* Pass the disc image as a positional argument using the `--dvd` flag. Supported formats are: ISO (GCM), RVZ, WIA, WBFS, CISO, GCZ
```sh ```sh
build/{preset}/dusklight --dvd /path/to/game.iso build/{preset}/dusklight/path/to/game.rvz
```
**macOS**
macOS builds an `.app` bundle which contains the executable and all necessary resources.
* Pass the disc image as a positional argument using the `--dvd` flag. Supported formats are: ISO (GCM), RVZ, WIA, WBFS, CISO, GCZ
```sh
build/{preset}/Dusklight.app/Contents/MacOS/Dusklight --dvd /path/to/game.iso
``` ```
If no path is specified, Dusklight defaults to `game.iso` in the current working directory.
+26 -28
View File
@@ -1,48 +1,46 @@
# Installing Dusklight on iOS via iloader # Installing Dusklight on iOS via AltStore
## Prerequisites ## Prerequisites
- A Windows, Linux, or macOS device - Mac with Homebrew installed
- iOS device connected to computer via USB - iPhone connected via USB
- Dusklight IPA file (download the latest `Dusklight-vX.X.X-ios-arm64.ipa` from the [releases page](https://github.com/TwilitRealm/dusklight/releases)) - Dusklight IPA file (download the latest `Dusklight-vX.X.X-ios-arm64.ipa` from the [releases page](https://github.com/TwilitRealm/dusk/releases))
- Legally acquired game disc - `GZ2E01` (Gamecube USA) or `GZ2PE01` (Gamecube PAL) - Game disc - `GZ2E01` (Gamecube USA) or `GZ2PE01` (Gamecube PAL)
## 1. Install iloader ## 1. Install AltServer
- Executable bundles can be installed from [iloader's main page](https://iloader.app/) or [their GitHub](https://github.com/nab138/iloader) for Windows, Linux, and macOS. ```sh
- Windows WILL require iTunes to be installed brew install altserver
- Linux WILL require usbmuxd to be installed, this is installed by default in most distros though open -a AltServer
```
AltServer will appear in your menu bar.
## 2. Enable Developer Mode (iOS 16+) ## 2. Enable Developer Mode (iOS 16+)
- On your iPhone, go to **Settings > Privacy & Security > Developer Mode** - On your iPhone, go to **Settings > Privacy & Security > Developer Mode**
- Toggle it on, put in your device passcode, and restart when prompted - Toggle it on and restart when prompted
## 3. Install Dusklight on Your iPhone ## 3. Install AltStore on Your iPhone
1. Sign into your Apple ID (this is required for registering app IDs, it is sent securely directly to Apple and not stored by iloader) - Click AltServer in the menu bar
* You may be prompted to put in a code from your iOS device if you have 2FA enabled, do so - Click **Install AltStore > [Your iPhone]**
2. Plug in your iOS device via USB into your PC. If you're missing a dependency, an error pop-up will tell you to install it - Enter your Apple ID credentials when prompted
* You will need to hit `Refresh` after plugging it in at this stage so that it can be detected, it does not automatically refresh - On your iPhone, go to **Settings > General > VPN & Device Management**
3. Leave settings unchanged (the Anisette server should stay Sidestore (.io)) - Tap your Apple ID under "Developer App" and tap **Trust**
3.(a) Installing SideStore directly is not required, but provides you a way to install Dusklight on your phone without being plugged into a computer later
4. Press `Import IPA` and choose your downloaded `Dusklight-v.X.X.X-ios-arm64.ipa`, it will begin installing on your device
**NOTE:** *At various stages, you may be prompted to trust your device, do so*
## 3. Getting Dusklight trusted
When installing sideloaded iOS applications, at first you will need to manually trust the app due to Apple's security policies
* Go to **Settings > General > VPN & Device Management**
* Tap the Apple ID you signed into iloader with under "Developer App" and tap **Trust**
* Tap **Allow** on the pop-up
## 4. Copy Files to Your iPhone ## 4. Copy Files to Your iPhone
Transfer the game disc (and optionally, the Dusklight IPA) to your iPhone so they are accessible in the Files app. A few ways to do this: Transfer the IPA and game disc to your iPhone so they're accessible in the Files app. A few ways to do this:
- **AirDrop** - Right-click the files on your Mac and choose Share > AirDrop - **AirDrop** - Right-click the files on your Mac and choose Share > AirDrop
- **iCloud Drive** - Place files in iCloud Drive on your Mac and they'll sync to Files on your iPhone - **iCloud Drive** - Place files in iCloud Drive on your Mac and they'll sync to Files on your iPhone
- **USB transfer** - Connect your iPhone and drag files via Finder's sidebar - **USB transfer** - Connect your iPhone and drag files via Finder's sidebar
- **Cloud storage** - Upload to Google Drive, Dropbox, etc. and download on your iPhone - **Cloud storage** - Upload to Google Drive, Dropbox, etc. and download on your iPhone
You may now use Dusklight on iOS and iPadOS! ## 5. Install via AltStore
- Open **AltStore** on your iPhone
- Go to the **My Apps** tab
- Tap the **+** button (top left)
- Open the **Files** app and select the `.ipa` file
+1 -1
+3 -2
View File
@@ -1450,6 +1450,8 @@ set(DUSK_FILES
src/dusk/imgui/ImGuiEngine.hpp src/dusk/imgui/ImGuiEngine.hpp
src/dusk/imgui/ImGuiBloomWindow.cpp src/dusk/imgui/ImGuiBloomWindow.cpp
src/dusk/imgui/ImGuiBloomWindow.hpp src/dusk/imgui/ImGuiBloomWindow.hpp
src/dusk/imgui/ImGuiEnhancedLightingWindow.cpp
src/dusk/imgui/ImGuiEnhancedLightingWindow.hpp
src/dusk/imgui/ImGuiMenuTools.cpp src/dusk/imgui/ImGuiMenuTools.cpp
src/dusk/imgui/ImGuiMenuTools.hpp src/dusk/imgui/ImGuiMenuTools.hpp
src/dusk/imgui/ImGuiActorSpawner.cpp src/dusk/imgui/ImGuiActorSpawner.cpp
@@ -1458,6 +1460,7 @@ set(DUSK_FILES
src/dusk/imgui/ImGuiHeapOverlay.cpp src/dusk/imgui/ImGuiHeapOverlay.cpp
src/dusk/imgui/ImGuiControllerOverlay.cpp src/dusk/imgui/ImGuiControllerOverlay.cpp
src/dusk/imgui/ImGuiStubLog.cpp src/dusk/imgui/ImGuiStubLog.cpp
src/dusk/imgui/ImGuiMapLoader.cpp
src/dusk/imgui/ImGuiSaveEditor.cpp src/dusk/imgui/ImGuiSaveEditor.cpp
src/dusk/imgui/ImGuiStateShare.hpp src/dusk/imgui/ImGuiStateShare.hpp
src/dusk/imgui/ImGuiStateShare.cpp src/dusk/imgui/ImGuiStateShare.cpp
@@ -1508,8 +1511,6 @@ set(DUSK_FILES
src/dusk/ui/tab_bar.hpp src/dusk/ui/tab_bar.hpp
src/dusk/ui/ui.cpp src/dusk/ui/ui.cpp
src/dusk/ui/ui.hpp src/dusk/ui/ui.hpp
src/dusk/ui/warp.cpp
src/dusk/ui/warp.hpp
src/dusk/ui/window.cpp src/dusk/ui/window.cpp
src/dusk/ui/window.hpp src/dusk/ui/window.hpp
src/dusk/achievements.cpp src/dusk/achievements.cpp
+10 -14
View File
@@ -15,6 +15,12 @@
# Dependencies that are not packaged in nixpkgs (used by the Linux package build): # Dependencies that are not packaged in nixpkgs (used by the Linux package build):
buildSources = pkgs: { buildSources = pkgs: {
aurora-src = pkgs.fetchFromGitHub {
owner = "encounter";
repo = "aurora";
rev = "63606a43265a3bc18dafd500ab4d7a2108f109e6";
hash = "sha256-xBvnAwGwNzav67Ac6oUz7RqDUwqgL2bsME3OOMn8Tqw=";
};
dawn-src = pkgs.fetchzip { dawn-src = pkgs.fetchzip {
url = "https://github.com/encounter/dawn-build/releases/download/v20260423.175430/dawn-linux-x86_64.tar.gz"; url = "https://github.com/encounter/dawn-build/releases/download/v20260423.175430/dawn-linux-x86_64.tar.gz";
hash = "sha256-HXfKTLHtMPwupnFnaflCARtXVPuS/0PoCePXidjE5xs="; hash = "sha256-HXfKTLHtMPwupnFnaflCARtXVPuS/0PoCePXidjE5xs=";
@@ -44,20 +50,18 @@
# Dusklight Actual (Linux x86_64 only — relies on prebuilt dawn/nod binaries) # Dusklight Actual (Linux x86_64 only — relies on prebuilt dawn/nod binaries)
mkDusklight = pkgs: mkDusklight = pkgs:
let srcs = buildSources pkgs; let srcs = buildSources pkgs; in
versionSuffix = if self ? shortRev && self.shortRev != null
then "nix-${self.shortRev}"
else "nix-dirty";
in
pkgs.stdenv.mkDerivation { pkgs.stdenv.mkDerivation {
name = "dusklight"; name = "dusklight";
src = ./.; src = ./.;
postUnpack = '' postUnpack = ''
mkdir -p $sourceRoot/extern/aurora
cp -r ${srcs.aurora-src}/. $sourceRoot/extern/aurora/
chmod -R u+w $sourceRoot/extern/aurora
sed -i '/add_subdirectory(tests)/d' $sourceRoot/extern/aurora/CMakeLists.txt sed -i '/add_subdirectory(tests)/d' $sourceRoot/extern/aurora/CMakeLists.txt
''; '';
# Remove last line to re-enable tests # Remove last line to re-enable tests
cmakeFlags = [ cmakeFlags = [
"-DDUSK_VERSION_OVERRIDE=${versionSuffix}"
"-DFETCHCONTENT_FULLY_DISCONNECTED=ON" "-DFETCHCONTENT_FULLY_DISCONNECTED=ON"
"-DFETCHCONTENT_SOURCE_DIR_CXXOPTS=${pkgs.cxxopts.src}" "-DFETCHCONTENT_SOURCE_DIR_CXXOPTS=${pkgs.cxxopts.src}"
"-DFETCHCONTENT_SOURCE_DIR_JSON=${pkgs.nlohmann_json.src}" "-DFETCHCONTENT_SOURCE_DIR_JSON=${pkgs.nlohmann_json.src}"
@@ -79,14 +83,6 @@
mkdir -p $out/bin mkdir -p $out/bin
cp dusklight $out/bin/dusklight cp dusklight $out/bin/dusklight
cp -r ./res $out/bin/res cp -r ./res $out/bin/res
mkdir -p $out/share/applications
cp $src/platforms/freedesktop/dusklight.desktop $out/share/applications/dusklight.desktop
for size in 16 32 48 64 128 256 512 1024; do
install -Dm644 $src/platforms/freedesktop/''${size}x''${size}/apps/dusklight.png \
$out/share/icons/hicolor/''${size}x''${size}/apps/dusklight.png
done
''; '';
nativeBuildInputs = [ nativeBuildInputs = [
pkgs.cmake pkgs.cmake
-11
View File
@@ -1,19 +1,8 @@
#pragma once #pragma once
#include <cmath>
#include <dolphin/types.h> #include <dolphin/types.h>
namespace dusk::audio { namespace dusk::audio {
// Converts a 0-1 volume to a linear amplitude multiplier.
// The curve is -4 dB per 10% step: 100% = 0 dB, 90% = -4 dB, ..., 0% = -inf dB
inline f32 MasterVolumeToLinear(f32 v) {
if (v <= 0.0f) {
return 0.0f;
}
return std::pow(10.0f, (v - 1.0f) * 2.0f);
}
/** /**
* Initialize the audio system and start playing audio. * Initialize the audio system and start playing audio.
*/ */
-1
View File
@@ -5,7 +5,6 @@
#include <m_Do/m_Do_MemCardRWmng.h> #include <m_Do/m_Do_MemCardRWmng.h>
#include <m_Do/m_Do_MemCard.h> #include <m_Do/m_Do_MemCard.h>
#include <d/actor/d_a_alink.h>
void noAutoSave(); void noAutoSave();
void triggerAutoSave(); void triggerAutoSave();
+1 -14
View File
@@ -175,7 +175,6 @@ class ConfigVar : public ConfigVarBase {
T defaultValue; T defaultValue;
T value; T value;
T overrideValue; T overrideValue;
ConfigVarLayer priorLayer = ConfigVarLayer::Default;
public: public:
/** /**
@@ -266,7 +265,6 @@ public:
void setSpeedrunValue(T newValue) { void setSpeedrunValue(T newValue) {
checkRegistered(); checkRegistered();
if (layer != ConfigVarLayer::Override) { if (layer != ConfigVarLayer::Override) {
priorLayer = layer;
overrideValue = std::move(newValue); overrideValue = std::move(newValue);
layer = ConfigVarLayer::Speedrun; layer = ConfigVarLayer::Speedrun;
} }
@@ -284,20 +282,9 @@ public:
checkRegistered(); checkRegistered();
if (layer == ConfigVarLayer::Speedrun) { if (layer == ConfigVarLayer::Speedrun) {
overrideValue = {}; overrideValue = {};
layer = priorLayer; layer = ConfigVarLayer::Value;
} }
} }
/**
* \brief Get the user-persisted value, ignoring any temporary overrides.
*
* Used by Save() to write the correct value even when a speedrun override is active.
*/
[[nodiscard]] constexpr const T& getValueForSave() const noexcept {
checkRegistered();
const ConfigVarLayer effectiveLayer = (layer == ConfigVarLayer::Speedrun) ? priorLayer : layer;
return effectiveLayer == ConfigVarLayer::Default ? defaultValue : value;
}
}; };
using ActionBindConfigVar = ConfigVar<int>; using ActionBindConfigVar = ConfigVar<int>;
-22
View File
@@ -227,28 +227,6 @@ struct BE<Mtx> {
} }
}; };
typedef f32 Mtx23[2][3];
template <>
struct BE<Mtx23> {
BE<f32> contents[2][3];
auto& operator[](int x) {
return contents[x];
}
auto& operator[](int x) const {
return contents[x];
}
void to_host(Mtx23& mtx) const {
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
mtx[i][j] = contents[i][j];
}
}
}
};
template<typename T> template<typename T>
void be_swap(T& val) { void be_swap(T& val) {
val = BE<T>::swap(val); val = BE<T>::swap(val);
+1 -3
View File
@@ -4,7 +4,6 @@
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include "settings.h"
class camera_process_class; class camera_process_class;
class view_class; class view_class;
@@ -18,8 +17,7 @@ void ensure_initialized();
void begin_record(); void begin_record();
void end_record(); void end_record();
void begin_sim_tick(); void begin_sim_tick();
uint64_t sim_tick_seq(); void begin_frame(bool enabled, bool is_sim_frame, float step);
void begin_frame(FrameInterpMode mode, bool is_sim_frame, float step);
void interpolate(); void interpolate();
float get_interpolation_step(); float get_interpolation_step();
+1
View File
@@ -14,6 +14,7 @@ constexpr const char* SHOW_DEBUG_OVERLAY = "F3";
constexpr const char* SHOW_HEAP_VIEWER = "F4"; constexpr const char* SHOW_HEAP_VIEWER = "F4";
constexpr const char* SHOW_PLAYER_INFO = "F5"; constexpr const char* SHOW_PLAYER_INFO = "F5";
constexpr const char* SHOW_SAVE_EDITOR = "F6"; constexpr const char* SHOW_SAVE_EDITOR = "F6";
constexpr const char* SHOW_MAP_LOADER = "F7";
constexpr const char* SHOW_STATE_SHARE = "F8"; constexpr const char* SHOW_STATE_SHARE = "F8";
constexpr const char* SHOW_DEBUG_CAMERA = "F9"; constexpr const char* SHOW_DEBUG_CAMERA = "F9";
constexpr const char* SHOW_AUDIO_DEBUG = "F10"; constexpr const char* SHOW_AUDIO_DEBUG = "F10";
-1
View File
@@ -10,7 +10,6 @@ extern bool IsShuttingDown;
extern bool IsGameLaunched; extern bool IsGameLaunched;
extern bool RestartRequested; extern bool RestartRequested;
extern std::filesystem::path ConfigPath; extern std::filesystem::path ConfigPath;
extern std::filesystem::path CachePath;
#if defined(__ANDROID__) || (defined(TARGET_OS_IOS) && TARGET_OS_IOS) || \ #if defined(__ANDROID__) || (defined(TARGET_OS_IOS) && TARGET_OS_IOS) || \
(defined(TARGET_OS_TV) && TARGET_OS_TV) (defined(TARGET_OS_TV) && TARGET_OS_TV)
+9 -30
View File
@@ -15,11 +15,6 @@ enum class BloomMode : int {
Dusk = 2, Dusk = 2,
}; };
enum class Resampler : int {
Bilinear = 0,
Area = 1,
};
enum class GameLanguage : u8 { enum class GameLanguage : u8 {
English = OS_LANGUAGE_ENGLISH, English = OS_LANGUAGE_ENGLISH,
German = OS_LANGUAGE_GERMAN, German = OS_LANGUAGE_GERMAN,
@@ -39,12 +34,6 @@ enum class GyroMode : u8 {
Mouse = 1, Mouse = 1,
}; };
enum class FrameInterpMode : u8 {
Off = 0,
Capped = 1,
Unlimited = 2,
};
namespace config { namespace config {
template <> template <>
struct ConfigEnumRange<BloomMode> { struct ConfigEnumRange<BloomMode> {
@@ -52,12 +41,6 @@ struct ConfigEnumRange<BloomMode> {
static constexpr auto max = BloomMode::Dusk; static constexpr auto max = BloomMode::Dusk;
}; };
template <>
struct ConfigEnumRange<Resampler> {
static constexpr auto min = Resampler::Bilinear;
static constexpr auto max = Resampler::Area;
};
template <> template <>
struct ConfigEnumRange<GameLanguage> { struct ConfigEnumRange<GameLanguage> {
static constexpr auto min = GameLanguage::English; static constexpr auto min = GameLanguage::English;
@@ -75,13 +58,7 @@ struct ConfigEnumRange<GyroMode> {
static constexpr auto min = GyroMode::Sensor; static constexpr auto min = GyroMode::Sensor;
static constexpr auto max = GyroMode::Mouse; static constexpr auto max = GyroMode::Mouse;
}; };
}
template <>
struct ConfigEnumRange<FrameInterpMode> {
static constexpr auto min = FrameInterpMode::Off;
static constexpr auto max = FrameInterpMode::Unlimited;
};
} // namespace config
// Persistent user settings // Persistent user settings
@@ -95,7 +72,6 @@ struct UserSettings {
ConfigVar<bool> lockAspectRatio; ConfigVar<bool> lockAspectRatio;
ConfigVar<bool> enableFpsOverlay; ConfigVar<bool> enableFpsOverlay;
ConfigVar<int> fpsOverlayCorner; ConfigVar<int> fpsOverlayCorner;
ConfigVar<int> maxFrameRate;
} video; } video;
struct { struct {
@@ -144,14 +120,19 @@ struct UserSettings {
ConfigVar<bool> enableDiscordPresence; ConfigVar<bool> enableDiscordPresence;
// Graphics // Graphics
ConfigVar<bool> enhancedLighting;
ConfigVar<bool> enableSpecularLighting;
ConfigVar<bool> enableRimLighting;
ConfigVar<float> specularIntensity;
ConfigVar<float> rimIntensity;
ConfigVar<float> ambientLightMultiplier;
ConfigVar<float> diffuseLightMultiplier;
ConfigVar<BloomMode> bloomMode; ConfigVar<BloomMode> bloomMode;
ConfigVar<float> bloomMultiplier; ConfigVar<float> bloomMultiplier;
ConfigVar<bool> disableWaterRefraction; ConfigVar<bool> disableWaterRefraction;
ConfigVar<bool> enableTextureReplacements; ConfigVar<bool> enableFrameInterpolation;
ConfigVar<FrameInterpMode> enableFrameInterpolation;
ConfigVar<int> internalResolutionScale; ConfigVar<int> internalResolutionScale;
ConfigVar<int> shadowResolutionMultiplier; ConfigVar<int> shadowResolutionMultiplier;
ConfigVar<Resampler> resampler;
ConfigVar<bool> enableDepthOfField; ConfigVar<bool> enableDepthOfField;
ConfigVar<bool> enableMapBackground; ConfigVar<bool> enableMapBackground;
ConfigVar<bool> disableCutscenePillarboxing; ConfigVar<bool> disableCutscenePillarboxing;
@@ -184,7 +165,6 @@ struct UserSettings {
// Cheats // Cheats
ConfigVar<bool> infiniteHearts; ConfigVar<bool> infiniteHearts;
ConfigVar<bool> infiniteArrows; ConfigVar<bool> infiniteArrows;
ConfigVar<bool> infiniteSeeds;
ConfigVar<bool> infiniteBombs; ConfigVar<bool> infiniteBombs;
ConfigVar<bool> infiniteOil; ConfigVar<bool> infiniteOil;
ConfigVar<bool> infiniteOxygen; ConfigVar<bool> infiniteOxygen;
@@ -198,7 +178,6 @@ struct UserSettings {
ConfigVar<bool> fastRoll; ConfigVar<bool> fastRoll;
ConfigVar<bool> fastSpinner; ConfigVar<bool> fastSpinner;
ConfigVar<bool> freeMagicArmor; ConfigVar<bool> freeMagicArmor;
ConfigVar<bool> invincibleEnemies;
// Technical // Technical
ConfigVar<bool> restoreWiiGlitches; ConfigVar<bool> restoreWiiGlitches;
+4 -40
View File
@@ -17,24 +17,16 @@
#include <shellapi.h> #include <shellapi.h>
#include <intrin.h> #include <intrin.h>
#endif #endif
#ifdef __APPLE__
#include <mach/mach_time.h>
#if defined(__x86_64__) || defined(__i386__)
#include <immintrin.h>
#endif
#endif
class Limiter { class Limiter {
public: public:
using duration_t = Uint64; using duration_t = Uint64;
void Reset() { void Reset() { m_oldTime = SDL_GetTicksNS(); }
m_oldTime = SDL_GetTicksNS();
}
duration_t Sleep(duration_t targetFrameTime) { void Sleep(duration_t targetFrameTime) {
if (targetFrameTime == 0) { if (targetFrameTime == 0) {
return 0; return;
} }
const Uint64 start = SDL_GetTicksNS(); const Uint64 start = SDL_GetTicksNS();
@@ -49,8 +41,6 @@ public:
} }
} }
Reset(); Reset();
return adjustedSleepTime;
} }
duration_t SleepTime(duration_t targetFrameTime) { duration_t SleepTime(duration_t targetFrameTime) {
@@ -84,6 +74,7 @@ private:
if (!initialized || numSleeps++ % 1000 == 0) { if (!initialized || numSleeps++ % 1000 == 0) {
LARGE_INTEGER freq; LARGE_INTEGER freq;
if (QueryPerformanceFrequency(&freq) == 0) { if (QueryPerformanceFrequency(&freq) == 0) {
DuskLog.warn("QueryPerformanceFrequency failed: {}", GetLastError());
return; return;
} }
countPerNs = static_cast<double>(freq.QuadPart) / 1e9; countPerNs = static_cast<double>(freq.QuadPart) / 1e9;
@@ -107,33 +98,6 @@ private:
#endif #endif
} while (current.QuadPart - start.QuadPart < ticksToWait); } while (current.QuadPart - start.QuadPart < ticksToWait);
} }
#elif defined (__APPLE__)
void NanoSleep(const duration_t duration) {
// Hybrid approach using Apple Mach
uint64_t start_mach = mach_absolute_time();
mach_timebase_info_data_t timebase_info;
mach_timebase_info(&timebase_info);
uint64_t total_mach_ticks = (duration * timebase_info.denom) / timebase_info.numer;
uint64_t target_mach = start_mach + total_mach_ticks;
uint64_t buffer_ns = 2'000'000ULL;
uint64_t buffer_mach_ticks = (buffer_ns * timebase_info.denom) / timebase_info.numer;
if (total_mach_ticks > buffer_mach_ticks) {
uint64_t sleep_until_mach = target_mach - buffer_mach_ticks;
mach_wait_until(sleep_until_mach);
}
while (mach_absolute_time() < target_mach) {
#if defined(__aarch64__) || defined(__arm__)
asm volatile("yield" ::: "memory"); // Hardware hint, not a scheduler hint.
#else
_mm_pause();
#endif
}
}
#else #else
void NanoSleep(const duration_t duration) { SDL_DelayPrecise(duration); } void NanoSleep(const duration_t duration) { SDL_DelayPrecise(duration); }
#endif #endif
+1 -1
View File
@@ -108,7 +108,7 @@ struct fopAcM_search_prm {
struct fOpAcm_HIO_entry_c : public mDoHIO_entry_c { struct fOpAcm_HIO_entry_c : public mDoHIO_entry_c {
virtual ~fOpAcm_HIO_entry_c() {} virtual ~fOpAcm_HIO_entry_c() {}
#if DEBUG && !TARGET_PC #if DEBUG
void removeHIO(const fopAc_ac_c* i_this) { removeHIO(*i_this); } void removeHIO(const fopAc_ac_c* i_this) { removeHIO(*i_this); }
void removeHIO(const fopAc_ac_c& i_this) { removeHIO(i_this.base); } void removeHIO(const fopAc_ac_c& i_this) { removeHIO(i_this.base); }
void removeHIO(const fopEn_enemy_c& i_this) { removeHIO(i_this.base); } void removeHIO(const fopEn_enemy_c& i_this) { removeHIO(i_this.base); }
@@ -116,7 +116,7 @@ private:
* *
*/ */
struct J2DIndTexMtxInfo { struct J2DIndTexMtxInfo {
/* 0x00 */ BE(Mtx23) mMtx; /* 0x00 */ Mtx23 mMtx;
/* 0x18 */ s8 mScaleExp; /* 0x18 */ s8 mScaleExp;
J2DIndTexMtxInfo& operator=(const J2DIndTexMtxInfo& other) { J2DIndTexMtxInfo& operator=(const J2DIndTexMtxInfo& other) {
@@ -287,28 +287,28 @@ template <typename T>
class JASPoolAllocObject { class JASPoolAllocObject {
public: public:
#if TARGET_PC #if TARGET_PC
static void* operator new(size_t n, JKRHeapToken) IF_DUSK(noexcept) { static void* operator new(size_t n, JKRHeapToken) {
return operator new(n); return operator new(n);
} }
#endif #endif
static void* operator new(size_t n) IF_DUSK(noexcept) { static void* operator new(size_t n) {
#if PLATFORM_GCN #if PLATFORM_GCN
JASMemPool<T>& memPool_ = getMemPool_(); JASMemPool<T>& memPool_ = getMemPool_();
#endif #endif
return memPool_.alloc(n); return memPool_.alloc(n);
} }
static void* operator new(size_t n, void* ptr) IF_DUSK(noexcept) { static void* operator new(size_t n, void* ptr) {
return ptr; return ptr;
} }
#if TARGET_PC #if TARGET_PC
static void operator delete(void* ptr, size_t n, JKRHeapToken) IF_DUSK(noexcept) { static void operator delete(void* ptr, size_t n, JKRHeapToken) {
operator delete(ptr, n); operator delete(ptr, n);
} }
#endif #endif
static void operator delete(void* ptr, size_t n) IF_DUSK(noexcept) { static void operator delete(void* ptr, size_t n) {
#if PLATFORM_GCN #if PLATFORM_GCN
JASMemPool<T>& memPool_ = getMemPool_(); JASMemPool<T>& memPool_ = getMemPool_();
#endif #endif
@@ -402,28 +402,28 @@ template <typename T>
class JASPoolAllocObject_MultiThreaded { class JASPoolAllocObject_MultiThreaded {
public: public:
#if TARGET_PC #if TARGET_PC
static void* operator new(size_t n, JKRHeapToken) IF_DUSK(noexcept) { static void* operator new(size_t n, JKRHeapToken) {
return operator new(n); return operator new(n);
} }
#endif #endif
static void* operator new(size_t n) IF_DUSK(noexcept) { static void* operator new(size_t n) {
#if PLATFORM_GCN #if PLATFORM_GCN
JASMemPool_MultiThreaded<T>& memPool_ = getMemPool(); JASMemPool_MultiThreaded<T>& memPool_ = getMemPool();
#endif #endif
return memPool_.alloc(n); return memPool_.alloc(n);
} }
static void* operator new(size_t n, void* ptr) IF_DUSK(noexcept) { static void* operator new(size_t n, void* ptr) {
return ptr; return ptr;
} }
#if TARGET_PC #if TARGET_PC
static void operator delete(void* ptr, size_t n, JKRHeapToken) IF_DUSK(noexcept) { static void operator delete(void* ptr, size_t n, JKRHeapToken) {
return operator delete(ptr, n); return operator delete(ptr, n);
} }
#endif #endif
static void operator delete(void* ptr, size_t n) IF_DUSK(noexcept) { static void operator delete(void* ptr, size_t n) {
#if PLATFORM_GCN #if PLATFORM_GCN
JASMemPool_MultiThreaded<T>& memPool_ = getMemPool(); JASMemPool_MultiThreaded<T>& memPool_ = getMemPool();
#endif #endif
+15 -19
View File
@@ -237,11 +237,11 @@ enum class JKRHeapToken {
Dummy Dummy
}; };
inline void* operator new(size_t, JKRHeapToken, void* where) noexcept { inline void* operator new(size_t, JKRHeapToken, void* where) {
return where; return where;
} }
inline void* operator new[](size_t, JKRHeapToken, void* where) noexcept { inline void* operator new[](size_t, JKRHeapToken, void* where) {
return where; return where;
} }
@@ -264,21 +264,21 @@ inline void* operator new[](size_t, JKRHeapToken, void* where) noexcept {
#define JKR_HEAP_TOKEN_PARAM #define JKR_HEAP_TOKEN_PARAM
#endif #endif
void* operator new(size_t size JKR_HEAP_TOKEN_PARAM) IF_DUSK(noexcept); void* operator new(size_t size JKR_HEAP_TOKEN_PARAM);
void* operator new(size_t size JKR_HEAP_TOKEN_PARAM, int alignment) IF_DUSK(noexcept); void* operator new(size_t size JKR_HEAP_TOKEN_PARAM, int alignment);
void* operator new(size_t size JKR_HEAP_TOKEN_PARAM, JKRHeap* heap, int alignment) IF_DUSK(noexcept); void* operator new(size_t size JKR_HEAP_TOKEN_PARAM, JKRHeap* heap, int alignment);
// On PC, these new[] overloads are only used to catch usages of JKR_NEW with []. // On PC, these new[] overloads are only used to catch usages of JKR_NEW with [].
void* operator new[](size_t size JKR_HEAP_TOKEN_PARAM) IF_DUSK(noexcept); void* operator new[](size_t size JKR_HEAP_TOKEN_PARAM);
void* operator new[](size_t size JKR_HEAP_TOKEN_PARAM, int alignment) IF_DUSK(noexcept); void* operator new[](size_t size JKR_HEAP_TOKEN_PARAM, int alignment);
void* operator new[](size_t size JKR_HEAP_TOKEN_PARAM, JKRHeap* heap, int alignment) IF_DUSK(noexcept); void* operator new[](size_t size JKR_HEAP_TOKEN_PARAM, JKRHeap* heap, int alignment);
void operator delete(void* ptr JKR_HEAP_TOKEN_PARAM) IF_DUSK(noexcept); void operator delete(void* ptr JKR_HEAP_TOKEN_PARAM);
void operator delete[](void* ptr JKR_HEAP_TOKEN_PARAM) IF_DUSK(noexcept); void operator delete[](void* ptr JKR_HEAP_TOKEN_PARAM);
#if TARGET_PC #if TARGET_PC
template<typename T> template<typename T>
void jkrDelete(T* ptr) IF_DUSK(noexcept) { void jkrDelete(T* ptr) {
if (ptr == nullptr) { if (ptr == nullptr) {
return; return;
} }
@@ -298,7 +298,7 @@ void jkrDelete(T* ptr) IF_DUSK(noexcept) {
} }
template<> template<>
inline void jkrDelete(void* ptr) IF_DUSK(noexcept) { inline void jkrDelete(void* ptr) {
if (ptr == nullptr) { if (ptr == nullptr) {
return; return;
} }
@@ -322,7 +322,7 @@ constexpr bool newArgsHasCustomAlignment() {
} }
template<typename T, typename... Args> template<typename T, typename... Args>
T* jkrNewArray(size_t count, std::in_place_type_t<T>, Args&&... args) IF_DUSK(noexcept) { T* jkrNewArray(size_t count, std::in_place_type_t<T>, Args&&... args) {
size_t allocSize = count * sizeof(T); size_t allocSize = count * sizeof(T);
if constexpr (!std::is_trivially_destructible<T>()) { if constexpr (!std::is_trivially_destructible<T>()) {
static_assert( static_assert(
@@ -333,10 +333,6 @@ T* jkrNewArray(size_t count, std::in_place_type_t<T>, Args&&... args) IF_DUSK(no
} }
void* ptr = operator new(allocSize, JKRHeapToken::Dummy, args...); void* ptr = operator new(allocSize, JKRHeapToken::Dummy, args...);
if (!ptr) {
return nullptr;
}
T* dataPtr; T* dataPtr;
if constexpr (!std::is_trivially_destructible<T>()) { if constexpr (!std::is_trivially_destructible<T>()) {
auto length = static_cast<size_t*>(ptr); auto length = static_cast<size_t*>(ptr);
@@ -356,7 +352,7 @@ T* jkrNewArray(size_t count, std::in_place_type_t<T>, Args&&... args) IF_DUSK(no
} }
template<typename T> template<typename T>
void jkrDeleteArray(T* pointer) IF_DUSK(noexcept) { void jkrDeleteArray(T* pointer) {
if (pointer == nullptr) { if (pointer == nullptr) {
return; return;
} }
@@ -376,7 +372,7 @@ void jkrDeleteArray(T* pointer) IF_DUSK(noexcept) {
} }
template<> template<>
inline void jkrDeleteArray(void* pointer) IF_DUSK(noexcept) { inline void jkrDeleteArray(void* pointer) {
if (pointer == nullptr) { if (pointer == nullptr) {
return; return;
} }
-6
View File
@@ -68,14 +68,8 @@ void J2DIndTevStage::load(u8 tevStage) {
} }
void J2DIndTexMtx::load(u8 indTexMtx) { void J2DIndTexMtx::load(u8 indTexMtx) {
#ifdef TARGET_PC
Mtx23 mtx;
mIndTexMtxInfo.mMtx.to_host(mtx);
GXSetIndTexMtx((GXIndTexMtxID)(GX_ITM_0 + indTexMtx), mtx, mIndTexMtxInfo.mScaleExp);
#else
GXSetIndTexMtx((GXIndTexMtxID)(GX_ITM_0 + indTexMtx), mIndTexMtxInfo.mMtx, GXSetIndTexMtx((GXIndTexMtxID)(GX_ITM_0 + indTexMtx), mIndTexMtxInfo.mMtx,
mIndTexMtxInfo.mScaleExp); mIndTexMtxInfo.mScaleExp);
#endif
} }
void J2DIndTexCoordScale::load(u8 indTexStage) { void J2DIndTexCoordScale::load(u8 indTexStage) {
+7 -7
View File
@@ -370,28 +370,28 @@ constexpr auto FRAME_PERIOD = std::chrono::duration_cast<std::chrono::nanosecond
constexpr auto RETRACE_PERIOD = FRAME_PERIOD / 2; constexpr auto RETRACE_PERIOD = FRAME_PERIOD / 2;
static void waitPrecise(Limiter& limiter, Limiter::duration_t targetNs) { static void waitPrecise(Limiter& limiter, Limiter::duration_t targetNs) {
const auto sleepTime = limiter.Sleep(targetNs); const auto sleepTime = limiter.SleepTime(targetNs);
dusk::frameUsagePct = dusk::frameUsagePct =
100.0f * (1.0f - static_cast<float>(sleepTime) / static_cast<float>(targetNs)); 100.0f * (1.0f - static_cast<float>(sleepTime) / static_cast<float>(targetNs));
limiter.Sleep(targetNs);
} }
#endif #endif
static void waitForTick(u32 p1, u16 p2) { static void waitForTick(u32 p1, u16 p2) {
#if TARGET_PC #if TARGET_PC
static Limiter limiter; if (dusk::getSettings().game.enableFrameInterpolation && !dusk::getTransientSettings().skipFrameRateLimit) {
dusk::frameUsagePct = 0.f;
if (dusk::frame_interp::is_enabled() && !dusk::getTransientSettings().skipFrameRateLimit) { return;
dusk::frameUsagePct = 0.f;
return;
} }
if (dusk::getTransientSettings().skipFrameRateLimit) { if (dusk::getTransientSettings().skipFrameRateLimit) {
p1 = OS_TIMER_CLOCK / 120; p1 = OS_TIMER_CLOCK / 120;
} }
#if TARGET_PC
if (fopOvlpM_IsPeek() && dusk::getTransientSettings().stateShareLoadActive) { if (fopOvlpM_IsPeek() && dusk::getTransientSettings().stateShareLoadActive) {
return; return;
} }
#endif
ZoneScopedC(tracy::Color::DimGray); ZoneScopedC(tracy::Color::DimGray);
#endif #endif
+8 -8
View File
@@ -559,7 +559,7 @@ void* operator new(size_t size) {
return JKRHeap::alloc(size, 4, NULL); return JKRHeap::alloc(size, 4, NULL);
} }
#else #else
void* operator new(size_t size JKR_HEAP_TOKEN_PARAM) noexcept { void* operator new(size_t size JKR_HEAP_TOKEN_PARAM) {
if (sCurrentHeap == NULL) { if (sCurrentHeap == NULL) {
return fallback_alloc(size, 0, false); return fallback_alloc(size, 0, false);
} }
@@ -576,7 +576,7 @@ void* operator new(size_t size, int alignment) {
return JKRHeap::alloc(size, alignment, NULL); return JKRHeap::alloc(size, alignment, NULL);
} }
#else #else
void* operator new(size_t size JKR_HEAP_TOKEN_PARAM, int alignment) noexcept { void* operator new(size_t size JKR_HEAP_TOKEN_PARAM, int alignment) {
void* mem = JKRHeap::alloc(size, alignment, nullptr); void* mem = JKRHeap::alloc(size, alignment, nullptr);
if (mem == nullptr) { if (mem == nullptr) {
return fallback_alloc(size, abs(alignment), true); return fallback_alloc(size, abs(alignment), true);
@@ -585,7 +585,7 @@ void* operator new(size_t size JKR_HEAP_TOKEN_PARAM, int alignment) noexcept {
} }
#endif #endif
void* operator new(size_t size JKR_HEAP_TOKEN_PARAM, JKRHeap* heap, int alignment) IF_DUSK(noexcept) { void* operator new(size_t size JKR_HEAP_TOKEN_PARAM, JKRHeap* heap, int alignment) {
void* mem = JKRHeap::alloc(size, alignment, heap); void* mem = JKRHeap::alloc(size, alignment, heap);
#if TARGET_PC #if TARGET_PC
if (mem == nullptr) { if (mem == nullptr) {
@@ -600,7 +600,7 @@ void* operator new[](size_t size) {
return JKRHeap::alloc(size, 4, NULL); return JKRHeap::alloc(size, 4, NULL);
} }
#else #else
void* operator new[](size_t JKR_HEAP_TOKEN_PARAM) IF_DUSK(noexcept) { void* operator new[](size_t JKR_HEAP_TOKEN_PARAM) {
OSPanic(__FILE__, __LINE__, "Allocation should go through JKR_NEW_ARRAY instead"); OSPanic(__FILE__, __LINE__, "Allocation should go through JKR_NEW_ARRAY instead");
} }
#endif #endif
@@ -610,12 +610,12 @@ void* operator new[](size_t size, int alignment) {
return JKRHeap::alloc(size, alignment, NULL); return JKRHeap::alloc(size, alignment, NULL);
} }
#else #else
void* operator new[](size_t JKR_HEAP_TOKEN_PARAM, int) IF_DUSK(noexcept) { void* operator new[](size_t JKR_HEAP_TOKEN_PARAM, int) {
OSPanic(__FILE__, __LINE__, "Allocation should go through JKR_NEW_ARRAY instead"); OSPanic(__FILE__, __LINE__, "Allocation should go through JKR_NEW_ARRAY instead");
} }
#endif #endif
void* operator new[](size_t JKR_HEAP_TOKEN_PARAM, JKRHeap*, int) IF_DUSK(noexcept) { void* operator new[](size_t JKR_HEAP_TOKEN_PARAM, JKRHeap*, int) {
OSPanic(__FILE__, __LINE__, "Allocation should go through JKR_NEW_ARRAY instead"); OSPanic(__FILE__, __LINE__, "Allocation should go through JKR_NEW_ARRAY instead");
} }
@@ -624,7 +624,7 @@ void operator delete(void* ptr) {
JKRHeap::free(ptr, NULL); JKRHeap::free(ptr, NULL);
} }
#else #else
void operator delete(void* ptr JKR_HEAP_TOKEN_PARAM) IF_DUSK(noexcept) { void operator delete(void* ptr JKR_HEAP_TOKEN_PARAM) {
if (ptr == NULL) if (ptr == NULL)
return; return;
JKRHeap* heap = JKRHeap::findFromRoot(ptr); JKRHeap* heap = JKRHeap::findFromRoot(ptr);
@@ -645,7 +645,7 @@ void operator delete[](void* ptr) {
JKRHeap::free(ptr, NULL); JKRHeap::free(ptr, NULL);
} }
#else #else
void operator delete[](void* ptr JKR_HEAP_TOKEN_PARAM) IF_DUSK(noexcept) { void operator delete[](void* ptr JKR_HEAP_TOKEN_PARAM) {
if (ptr == NULL) if (ptr == NULL)
return; return;
JKRHeap* heap = JKRHeap::findFromRoot(ptr); JKRHeap* heap = JKRHeap::findFromRoot(ptr);
@@ -655,7 +655,7 @@ value_or_fun:
value: value:
#if TARGET_PC #if TARGET_PC
if (dusk::frame_interp::is_enabled() && u <= 5 && if (dusk::getSettings().game.enableFrameInterpolation && u <= 5 &&
(operation == data::UNK_0x2 || operation == data::UNK_0x3 || operation == data::UNK_0x12)) (operation == data::UNK_0x2 || operation == data::UNK_0x3 || operation == data::UNK_0x12))
{ {
dusk::frame_interp::request_presentation_sync(); dusk::frame_interp::request_presentation_sync();
@@ -666,7 +666,7 @@ value:
value_n: value_n:
#if TARGET_PC #if TARGET_PC
if (dusk::frame_interp::is_enabled() && if (dusk::getSettings().game.enableFrameInterpolation &&
(pN == TAdaptor_camera::sauVariableValue_3_POSITION_XYZ || pN == TAdaptor_camera::sauVariableValue_3_TARGET_POSITION_XYZ) && (pN == TAdaptor_camera::sauVariableValue_3_POSITION_XYZ || pN == TAdaptor_camera::sauVariableValue_3_TARGET_POSITION_XYZ) &&
(operation == data::UNK_0x2 || operation == data::UNK_0x3 || operation == data::UNK_0x12)) (operation == data::UNK_0x2 || operation == data::UNK_0x3 || operation == data::UNK_0x12))
{ {
+1 -3
View File
@@ -28,9 +28,7 @@
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string> <string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
<key>NSHighResolutionCapable</key> <key>NSHighResolutionCapable</key>
<true/> <true/>
<key>LSApplicationCategoryType</key>
<string>public.app-category.adventure-games</string>
<key>LSSupportsGameMode</key> <key>LSSupportsGameMode</key>
<true/> <true/>
</dict> </dict>
</plist> </plist>
-4
View File
@@ -58,10 +58,6 @@ toast:active {
background-color: rgba(45, 43, 26, 80%); background-color: rgba(45, 43, 26, 80%);
}*/ }*/
b {
font-weight: bold;
}
toast heading { toast heading {
display: flex; display: flex;
gap: 18dp; gap: 18dp;
-4
View File
@@ -14,10 +14,6 @@ body {
color: #E0DBC8; color: #E0DBC8;
} }
b {
font-weight: bold;
}
window { window {
display: flex; display: flex;
flex-flow: column; flex-flow: column;
+9 -4
View File
@@ -5990,7 +5990,7 @@ void daAlink_c::setItemMatrix(int param_0) {
mDoMtx_stack_c::XrotS(-0x8000); mDoMtx_stack_c::XrotS(-0x8000);
#ifdef TARGET_PC #ifdef TARGET_PC
if (dusk::frame_interp::is_enabled()) { if (dusk::getSettings().game.enableFrameInterpolation) {
Mtx boot_mtx; Mtx boot_mtx;
mDoMtx_concat(mpLinkModel->getAnmMtx(0x18), mDoMtx_stack_c::get(), boot_mtx); mDoMtx_concat(mpLinkModel->getAnmMtx(0x18), mDoMtx_stack_c::get(), boot_mtx);
mpLinkBootModels[1]->setAnmMtx(1, boot_mtx); mpLinkBootModels[1]->setAnmMtx(1, boot_mtx);
@@ -7562,7 +7562,12 @@ void daAlink_c::setBlendMoveAnime(f32 i_morf) {
f32 sp2C; f32 sp2C;
f32 sp28 = mpHIO->mMove.m.mFootPositionRatio; f32 sp28 = mpHIO->mMove.m.mFootPositionRatio;
BOOL sp24 = checkEventRun(); BOOL sp24 = checkEventRun();
BOOL sp20 = checkBootsMoveAnime(1) IF_DUSK(&& !dusk::getSettings().game.enableFastIronBoots); BOOL sp20 = checkBootsMoveAnime(1);
#if TARGET_PC
if (dusk::getSettings().game.enableFastIronBoots) {
sp20 = FALSE;
}
#endif
f32 var_f29; f32 var_f29;
@@ -8075,7 +8080,7 @@ void daAlink_c::setBlendAtnBackMoveAnime(f32 i_morf) {
daAlink_ANM var_r27; daAlink_ANM var_r27;
daAlink_ANM var_r29; daAlink_ANM var_r29;
if (checkBootsMoveAnime(1) IF_DUSK(&& !dusk::getSettings().game.enableFastIronBoots)) { if (checkBootsMoveAnime(1)) {
mMaxSpeed = mpHIO->mAtnMove.m.mMaxBackwardsSpeed; mMaxSpeed = mpHIO->mAtnMove.m.mMaxBackwardsSpeed;
var_f27 = mpHIO->mAtnMove.m.mMinBackWalkFrame; var_f27 = mpHIO->mAtnMove.m.mMinBackWalkFrame;
var_f31 = mpHIO->mAtnMove.m.mBackWalkChangeRate; var_f31 = mpHIO->mAtnMove.m.mBackWalkChangeRate;
@@ -19767,7 +19772,7 @@ int daAlink_c::draw() {
dComIfGd_getOpaListDark()->entryImm(mpHookChain, 0); dComIfGd_getOpaListDark()->entryImm(mpHookChain, 0);
#if TARGET_PC #if TARGET_PC
if (dusk::frame_interp::is_enabled() && if (dusk::getSettings().game.enableFrameInterpolation &&
mEquipItem == dItemNo_IRONBALL_e && mEquipItem == dItemNo_IRONBALL_e &&
mIronBallChainPos != NULL && mIronBallChainAngle != NULL) mIronBallChainPos != NULL && mIronBallChainAngle != NULL)
{ {
+1 -6
View File
@@ -77,12 +77,7 @@ int daAlink_c::loadModelDVD() {
mpWlMidnaHairModel = NULL; mpWlMidnaHairModel = NULL;
if (!checkNoResetFlg2(FLG2_UNK_280000)) { if (!checkNoResetFlg2(FLG2_UNK_280000)) {
if (!dComIfG_resDelete(&mPhaseReq, mArcName)) { dComIfG_resDelete(&mPhaseReq, mArcName);
#if TARGET_PC
// resDelete no-ops if load was in-progress; force-unregister before freeAll
dComIfG_deleteObjectResMain(mArcName);
#endif
}
cPhs_Reset(&mPhaseReq); cPhs_Reset(&mPhaseReq);
mpArcHeap->freeAll(); mpArcHeap->freeAll();
-6
View File
@@ -8723,12 +8723,6 @@ int daAlink_c::procWolfCargoCarry() {
return checkNextActionWolf(0); return checkNextActionWolf(0);
} }
#if TARGET_PC
if (field_0x280c.getActor() == NULL) {
return checkNextActionWolf(0);
}
#endif
mDoMtx_stack_c::copy(((e_yc_class*)field_0x280c.getActor())->getLegR3Mtx()); mDoMtx_stack_c::copy(((e_yc_class*)field_0x280c.getActor())->getLegR3Mtx());
mDoMtx_stack_c::transM(-9.0f, -7.0f, -30.0f); mDoMtx_stack_c::transM(-9.0f, -7.0f, -30.0f);
mDoMtx_stack_c::multVecZero(&current.pos); mDoMtx_stack_c::multVecZero(&current.pos);
+1 -1
View File
@@ -397,7 +397,7 @@ static int daB_GND_Draw(b_gnd_class* i_this) {
i_this->field_0x21e8.update(2, l_color, &a_this->tevStr); i_this->field_0x21e8.update(2, l_color, &a_this->tevStr);
dComIfGd_set3DlineMat(&i_this->field_0x21e8); dComIfGd_set3DlineMat(&i_this->field_0x21e8);
#if TARGET_PC #if TARGET_PC
if (dusk::frame_interp::is_enabled()) { if (dusk::getSettings().game.enableFrameInterpolation) {
if (i_this->mReinsInterpCurrValid) { if (i_this->mReinsInterpCurrValid) {
memcpy(i_this->mReinsInterpPrev, i_this->mReinsInterpCurr, sizeof(i_this->mReinsInterpCurr)); memcpy(i_this->mReinsInterpPrev, i_this->mReinsInterpCurr, sizeof(i_this->mReinsInterpCurr));
memcpy(i_this->mReinsTexInterpPrev, i_this->mReinsTexInterpCurr, sizeof(i_this->mReinsTexInterpCurr)); memcpy(i_this->mReinsTexInterpPrev, i_this->mReinsTexInterpCurr, sizeof(i_this->mReinsTexInterpCurr));
-22
View File
@@ -674,29 +674,7 @@ static int daE_ARROW_Create(fopAc_ac_c* i_this) {
} }
int phase_state = dComIfG_resLoad(&a_this->mPhase, a_this->mResName); int phase_state = dComIfG_resLoad(&a_this->mPhase, a_this->mResName);
#if TARGET_PC
static int s_create_frames = 0;
static bool s_first_arrow = true;
static fpc_ProcID s_last_scene_id = 0;
s_create_frames++;
fpc_ProcID cur_scene_id = dStage_roomControl_c::getProcID();
if (cur_scene_id != s_last_scene_id) {
s_first_arrow = true;
s_last_scene_id = cur_scene_id;
}
if (phase_state == cPhs_COMPLEATE_e && s_first_arrow && s_create_frames < 4) {
return cPhs_INIT_e;
}
#endif
if (phase_state == cPhs_COMPLEATE_e) { if (phase_state == cPhs_COMPLEATE_e) {
#if TARGET_PC
s_create_frames = 0;
s_first_arrow = false;
#endif
a_this->mArrowType = fopAcM_GetParam(a_this) & 0xF; a_this->mArrowType = fopAcM_GetParam(a_this) & 0xF;
a_this->mFlags = fopAcM_GetParam(a_this) & 0xF0; a_this->mFlags = fopAcM_GetParam(a_this) & 0xF0;
+1 -1
View File
@@ -116,7 +116,7 @@ static int daE_DB_Draw(e_db_class* i_this) {
i_this->stalkLine.update(12, l_color, &actor->tevStr); i_this->stalkLine.update(12, l_color, &actor->tevStr);
dComIfGd_set3DlineMat(&i_this->stalkLine); dComIfGd_set3DlineMat(&i_this->stalkLine);
#if TARGET_PC #if TARGET_PC
if (dusk::frame_interp::is_enabled()) { if (dusk::getSettings().game.enableFrameInterpolation) {
if (i_this->mStalkLineInterpCurrValid) { if (i_this->mStalkLineInterpCurrValid) {
memcpy(i_this->mStalkLineInterpPrev, i_this->mStalkLineInterpCurr, sizeof(i_this->mStalkLineInterpCurr)); memcpy(i_this->mStalkLineInterpPrev, i_this->mStalkLineInterpCurr, sizeof(i_this->mStalkLineInterpCurr));
i_this->mStalkLineInterpPrevValid = true; i_this->mStalkLineInterpPrevValid = true;
+1 -1
View File
@@ -103,7 +103,7 @@ static int daE_HB_Draw(e_hb_class* i_this) {
i_this->stalkLine.update(12, l_color, &actor->tevStr); i_this->stalkLine.update(12, l_color, &actor->tevStr);
dComIfGd_set3DlineMat(&i_this->stalkLine); dComIfGd_set3DlineMat(&i_this->stalkLine);
#if TARGET_PC #if TARGET_PC
if (dusk::frame_interp::is_enabled()) { if (dusk::getSettings().game.enableFrameInterpolation) {
if (i_this->mStalkLineInterpCurrValid) { if (i_this->mStalkLineInterpCurrValid) {
memcpy(i_this->mStalkLineInterpPrev, i_this->mStalkLineInterpCurr, sizeof(i_this->mStalkLineInterpCurr)); memcpy(i_this->mStalkLineInterpPrev, i_this->mStalkLineInterpCurr, sizeof(i_this->mStalkLineInterpCurr));
i_this->mStalkLineInterpPrevValid = true; i_this->mStalkLineInterpPrevValid = true;
+1 -1
View File
@@ -105,7 +105,7 @@ static int daE_MB_Draw(e_mb_class* i_this) {
i_this->mRopeMat.update(16, l_color, &a_this->tevStr); i_this->mRopeMat.update(16, l_color, &a_this->tevStr);
dComIfGd_set3DlineMat(&i_this->mRopeMat); dComIfGd_set3DlineMat(&i_this->mRopeMat);
#if TARGET_PC #if TARGET_PC
if (dusk::frame_interp::is_enabled()) { if (dusk::getSettings().game.enableFrameInterpolation) {
if (i_this->mRopeInterpCurrValid) { if (i_this->mRopeInterpCurrValid) {
memcpy(i_this->mRopeInterpPrev, i_this->mRopeInterpCurr, sizeof(i_this->mRopeInterpCurr)); memcpy(i_this->mRopeInterpPrev, i_this->mRopeInterpCurr, sizeof(i_this->mRopeInterpCurr));
i_this->mRopeInterpPrevValid = true; i_this->mRopeInterpPrevValid = true;
-18
View File
@@ -157,21 +157,6 @@ static void* s_h_sub(void* i_actor, void* i_data) {
return NULL; return NULL;
} }
#if TARGET_PC
static void sort_target_info_by_id() {
for (int i = 1; i < target_info_count; i++) {
void* key = target_info[i];
fpc_ProcID key_id = fopAcM_GetID(key);
int j = i - 1;
while (j >= 0 && fopAcM_GetID(target_info[j]) > key_id) {
target_info[j + 1] = target_info[j];
j--;
}
target_info[j + 1] = key;
}
}
#endif
static daPillar_c* search_hasira(e_mk_class* i_this) { static daPillar_c* search_hasira(e_mk_class* i_this) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor; fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
daPillar_c* pillar_p; daPillar_c* pillar_p;
@@ -185,9 +170,6 @@ static daPillar_c* search_hasira(e_mk_class* i_this) {
if (i_this->firstHasiraFlag == 0) { if (i_this->firstHasiraFlag == 0) {
i_this->firstHasiraFlag++; i_this->firstHasiraFlag++;
#if TARGET_PC
sort_target_info_by_id();
#endif
return (daPillar_c*)target_info[TREG_S(7) + 5]; return (daPillar_c*)target_info[TREG_S(7) + 5];
} }
-6
View File
@@ -7053,12 +7053,6 @@ static int daE_RD_IsDelete(e_rd_class*) {
} }
static int daE_RD_Delete(e_rd_class* i_this) { static int daE_RD_Delete(e_rd_class* i_this) {
#if TARGET_PC
if (boss == i_this) {
boss = NULL;
}
#endif
fopEn_enemy_c* enemy = (fopEn_enemy_c*)&i_this->enemy; fopEn_enemy_c* enemy = (fopEn_enemy_c*)&i_this->enemy;
fopAcM_RegisterDeleteID(i_this, "E_RD"); fopAcM_RegisterDeleteID(i_this, "E_RD");
+1 -8
View File
@@ -117,13 +117,6 @@ static void daE_S1_interp_callback(bool isSimFrame, void* pUserWork) {
dst[i] = p0 + (p1 - p0) * alpha; dst[i] = p0 + (p1 - p0) * alpha;
} }
} }
GXColor line_color;
line_color.r = JREG_S(0) + 5;
line_color.g = JREG_S(1) + 10;
line_color.b = JREG_S(2) + 10;
line_color.a = 0xFF;
i_this->mLineMat.update(16, line_color, &i_this->tevStr);
} }
#endif #endif
@@ -161,7 +154,7 @@ static int daE_S1_Draw(e_s1_class* i_this) {
dComIfGd_set3DlineMatDark(&i_this->mLineMat); dComIfGd_set3DlineMatDark(&i_this->mLineMat);
#if TARGET_PC #if TARGET_PC
if (dusk::frame_interp::is_enabled()) { if (dusk::getSettings().game.enableFrameInterpolation) {
if (i_this->mHairInterpCurrValid) { if (i_this->mHairInterpCurrValid) {
memcpy(i_this->mHairInterpPrev, i_this->mHairInterpCurr, sizeof(i_this->mHairInterpCurr)); memcpy(i_this->mHairInterpPrev, i_this->mHairInterpCurr, sizeof(i_this->mHairInterpCurr));
i_this->mHairInterpPrevValid = true; i_this->mHairInterpPrevValid = true;
+1 -1
View File
@@ -535,7 +535,7 @@ static int daE_WB_Draw(e_wb_class* i_this) {
i_this->himo_tex.update(2, l_color, &actor->tevStr); i_this->himo_tex.update(2, l_color, &actor->tevStr);
dComIfGd_set3DlineMat(&i_this->himo_tex); dComIfGd_set3DlineMat(&i_this->himo_tex);
#if TARGET_PC #if TARGET_PC
if (dusk::frame_interp::is_enabled()) { if (dusk::getSettings().game.enableFrameInterpolation) {
if (i_this->himo_interp_curr_valid) { if (i_this->himo_interp_curr_valid) {
memcpy(i_this->himo_mat_interp_prev, i_this->himo_mat_interp_curr, sizeof(i_this->himo_mat_interp_curr)); memcpy(i_this->himo_mat_interp_prev, i_this->himo_mat_interp_curr, sizeof(i_this->himo_mat_interp_curr));
memcpy(i_this->himo_tex_interp_prev, i_this->himo_tex_interp_curr, sizeof(i_this->himo_tex_interp_curr)); memcpy(i_this->himo_tex_interp_prev, i_this->himo_tex_interp_curr, sizeof(i_this->himo_tex_interp_curr));
+1 -1
View File
@@ -107,7 +107,7 @@ static s32 daE_YD_Draw(e_yd_class* i_this) {
i_this->mLineMat.update(12, l_color, &i_this->actor.tevStr); i_this->mLineMat.update(12, l_color, &i_this->actor.tevStr);
dComIfGd_set3DlineMat(&i_this->mLineMat); dComIfGd_set3DlineMat(&i_this->mLineMat);
#if TARGET_PC #if TARGET_PC
if (dusk::frame_interp::is_enabled()) { if (dusk::getSettings().game.enableFrameInterpolation) {
if (i_this->mLineMatInterpCurrValid) { if (i_this->mLineMatInterpCurrValid) {
memcpy(i_this->mLineMatInterpPrev, i_this->mLineMatInterpCurr, sizeof(i_this->mLineMatInterpCurr)); memcpy(i_this->mLineMatInterpPrev, i_this->mLineMatInterpCurr, sizeof(i_this->mLineMatInterpCurr));
i_this->mLineMatInterpPrevValid = true; i_this->mLineMatInterpPrevValid = true;
+1 -9
View File
@@ -139,7 +139,6 @@ static BOOL pl_check(e_yg_class* i_this, f32 i_dist) {
#if TARGET_PC #if TARGET_PC
static void daE_YG_interp_callback(bool isSimFrame, void* pUserWork) { static void daE_YG_interp_callback(bool isSimFrame, void* pUserWork) {
e_yg_class* i_this = (e_yg_class*)pUserWork; e_yg_class* i_this = (e_yg_class*)pUserWork;
fopAc_ac_c* actor = (fopAc_ac_c*)&i_this->actor;
if (!i_this->mTentacleInterpPrevValid || !i_this->mTentacleInterpCurrValid) { if (!i_this->mTentacleInterpPrevValid || !i_this->mTentacleInterpCurrValid) {
return; return;
} }
@@ -153,13 +152,6 @@ static void daE_YG_interp_callback(bool isSimFrame, void* pUserWork) {
dst[i] = p0 + (p1 - p0) * alpha; dst[i] = p0 + (p1 - p0) * alpha;
} }
} }
GXColor color;
color.r = JREG_S(0) + 20;
color.g = JREG_S(1) + 20;
color.b = JREG_S(2) + 20;
color.a = 0xFF;
i_this->mLineMat.update(10, color, &actor->tevStr);
} }
#endif #endif
@@ -191,7 +183,7 @@ static int daE_YG_Draw(e_yg_class* i_this) {
dComIfGd_set3DlineMatDark(&i_this->mLineMat); dComIfGd_set3DlineMatDark(&i_this->mLineMat);
#if TARGET_PC #if TARGET_PC
if (dusk::frame_interp::is_enabled()) { if (dusk::getSettings().game.enableFrameInterpolation) {
if (i_this->mTentacleInterpCurrValid) { if (i_this->mTentacleInterpCurrValid) {
memcpy(i_this->mTentacleInterpPrev, i_this->mTentacleInterpCurr, sizeof(i_this->mTentacleInterpCurr)); memcpy(i_this->mTentacleInterpPrev, i_this->mTentacleInterpCurr, sizeof(i_this->mTentacleInterpCurr));
i_this->mTentacleInterpPrevValid = true; i_this->mTentacleInterpPrevValid = true;
+1 -1
View File
@@ -135,7 +135,7 @@ static int daE_YH_Draw(e_yh_class* i_this) {
i_this->mLine.update(12, l_color, &a_this->tevStr); i_this->mLine.update(12, l_color, &a_this->tevStr);
dComIfGd_set3DlineMat(&i_this->mLine); dComIfGd_set3DlineMat(&i_this->mLine);
#if TARGET_PC #if TARGET_PC
if (dusk::frame_interp::is_enabled()) { if (dusk::getSettings().game.enableFrameInterpolation) {
if (i_this->mLineInterpCurrValid) { if (i_this->mLineInterpCurrValid) {
memcpy(i_this->mLineInterpPrev, i_this->mLineInterpCurr, sizeof(i_this->mLineInterpCurr)); memcpy(i_this->mLineInterpPrev, i_this->mLineInterpCurr, sizeof(i_this->mLineInterpCurr));
i_this->mLineInterpPrevValid = true; i_this->mLineInterpPrevValid = true;
+5 -11
View File
@@ -22,7 +22,6 @@
#if TARGET_PC #if TARGET_PC
#include "dusk/dusk.h" #include "dusk/dusk.h"
#include "dusk/frame_interpolation.h"
namespace { namespace {
// FRAME INTERP NOTE: Sim tick control point snapshots for interpolation // FRAME INTERP NOTE: Sim tick control point snapshots for interpolation
@@ -33,7 +32,6 @@ int s_horseReinSimNumPrev;
int s_horseReinSimNumCurr; int s_horseReinSimNumCurr;
bool s_horseReinSimPrevValid; bool s_horseReinSimPrevValid;
bool s_horseReinSimCurrValid; bool s_horseReinSimCurrValid;
uint64_t s_horseReinSimRolledSeq;
} // namespace } // namespace
#endif #endif
@@ -3035,14 +3033,10 @@ void daHorse_c::copyReinPos() {
} }
#if TARGET_PC #if TARGET_PC
if (field_0x1204 > 0) { if (field_0x1204 > 0) {
const uint64_t simSeq = dusk::frame_interp::sim_tick_seq(); if (s_horseReinSimCurrValid && s_horseReinSimNumCurr > 0) {
if (simSeq != s_horseReinSimRolledSeq) { memcpy(s_horseReinSimPrev, s_horseReinSimCurr, s_horseReinSimNumCurr * sizeof(cXyz));
s_horseReinSimRolledSeq = simSeq; s_horseReinSimNumPrev = s_horseReinSimNumCurr;
if (s_horseReinSimCurrValid && s_horseReinSimNumCurr > 0) { s_horseReinSimPrevValid = true;
memcpy(s_horseReinSimPrev, s_horseReinSimCurr, s_horseReinSimNumCurr * sizeof(cXyz));
s_horseReinSimNumPrev = s_horseReinSimNumCurr;
s_horseReinSimPrevValid = true;
}
} }
memcpy(s_horseReinSimCurr, m_reinLine.getPos(0), field_0x1204 * sizeof(cXyz)); memcpy(s_horseReinSimCurr, m_reinLine.getPos(0), field_0x1204 * sizeof(cXyz));
s_horseReinSimNumCurr = field_0x1204; s_horseReinSimNumCurr = field_0x1204;
@@ -3165,7 +3159,7 @@ void daHorse_c::setReinPosNormalSubstance() {
#if TARGET_PC #if TARGET_PC
void daHorse_c::lerpControlPoints(f32 alpha) { void daHorse_c::lerpControlPoints(f32 alpha) {
// FRAME INTERP NOTE: Currently only lerping points for Epona's reins. Need a more global solution. // FRAME INTERP NOTE: Currently only lerping points for Epona's reins. Need a more global solution.
if (!dusk::frame_interp::is_enabled() || !s_horseReinSimPrevValid || !s_horseReinSimCurrValid) { if (!dusk::getSettings().game.enableFrameInterpolation || !s_horseReinSimPrevValid || !s_horseReinSimCurrValid) {
return; return;
} }
const int nCurr = s_horseReinSimNumCurr; const int nCurr = s_horseReinSimNumCurr;
-4
View File
@@ -1967,11 +1967,7 @@ static void demo_camera_shop(npc_henna_class* i_this) {
i_this->mMsgFlow.init(actor, 0x365, 0, NULL); i_this->mMsgFlow.init(actor, 0x365, 0, NULL);
/* dSv_event_flag_c::KORO2_ALLCLEAR - Fishing - After all stages (8-8) of roll goal game cleared */ /* dSv_event_flag_c::KORO2_ALLCLEAR - Fishing - After all stages (8-8) of roll goal game cleared */
dComIfGs_onEventBit(dSv_event_flag_c::saveBitLabels[0x335]); dComIfGs_onEventBit(dSv_event_flag_c::saveBitLabels[0x335]);
#if TARGET_PC
dComIfGp_setItemRupeeCount(dComIfGs_getRupeeMax());
#else
dComIfGp_setItemRupeeCount(1000); dComIfGp_setItemRupeeCount(1000);
#endif
} else if ((lbl_82_bss_91 & 0x38) == 0) { } else if ((lbl_82_bss_91 & 0x38) == 0) {
i_this->mMsgFlow.init(actor, 0x34f, 0, NULL); i_this->mMsgFlow.init(actor, 0x34f, 0, NULL);
/* dSv_event_flag_c::F_0469 - Fishing Pond - Reserved for fishing */ /* dSv_event_flag_c::F_0469 - Fishing Pond - Reserved for fishing */
+1 -2
View File
@@ -299,8 +299,7 @@ int daObjDrop_c::modeParentWait() {
#if TARGET_PC #if TARGET_PC
static inline BOOL checkGetCargoRide() { static inline BOOL checkGetCargoRide() {
if (daPy_getPlayerActorClass()->checkCargoCarry() && if ((daPy_getPlayerActorClass()->checkCargoCarry() && strcmp(dComIfGp_getStartStageName(), "F_SP112") == 0) ||
strcmp(dComIfGp_getStartStageName(), "F_SP112") == 0 &&
dComIfGs_isLightDropGetFlag(dComIfGp_getStartStageDarkArea())) dComIfGs_isLightDropGetFlag(dComIfGp_getStartStageDarkArea()))
{ {
return true; return true;
+1 -1
View File
@@ -325,7 +325,7 @@ int daObjFchain_c::draw() {
dComIfGd_getOpaListDark()->entryImm(&mShape, 0); dComIfGd_getOpaListDark()->entryImm(&mShape, 0);
#if TARGET_PC #if TARGET_PC
if (dusk::frame_interp::is_enabled()) { if (dusk::getSettings().game.enableFrameInterpolation) {
if (mChainInterpCurrValid) { if (mChainInterpCurrValid) {
memcpy(mChainInterpPrev, mChainInterpCurr, sizeof(mChainInterpCurr)); memcpy(mChainInterpPrev, mChainInterpCurr, sizeof(mChainInterpCurr));
mChainInterpPrevValid = true; mChainInterpPrevValid = true;
+1 -1
View File
@@ -493,7 +493,7 @@ int daObjKLift00_c::Draw() {
dComIfGd_setList(); dComIfGd_setList();
#if TARGET_PC #if TARGET_PC
if (dusk::frame_interp::is_enabled()) { if (dusk::getSettings().game.enableFrameInterpolation) {
if (mChainInterpCurrValid) { if (mChainInterpCurrValid) {
memcpy(mChainInterpPrev, mChainInterpCurr, mNumChains * sizeof(cXyz)); memcpy(mChainInterpPrev, mChainInterpCurr, mNumChains * sizeof(cXyz));
mChainInterpPrevValid = true; mChainInterpPrevValid = true;
+2 -2
View File
@@ -170,7 +170,7 @@ int daTitle_c::Execute() {
} }
#ifdef TARGET_PC #ifdef TARGET_PC
if (!dusk::frame_interp::is_enabled()) { if (!dusk::getSettings().game.enableFrameInterpolation) {
#endif #endif
dMenu_Collect3D_c::setViewPortOffsetY(0.0f); dMenu_Collect3D_c::setViewPortOffsetY(0.0f);
#ifdef TARGET_PC #ifdef TARGET_PC
@@ -354,7 +354,7 @@ void daTitle_c::fastLogoDispInit() {
mProcID = 5; mProcID = 5;
#ifdef TARGET_PC #ifdef TARGET_PC
if (dusk::frame_interp::is_enabled()) { if (dusk::getSettings().game.enableFrameInterpolation) {
dusk::frame_interp::request_presentation_sync(); dusk::frame_interp::request_presentation_sync();
} }
#endif #endif
+2 -1
View File
@@ -143,12 +143,13 @@ void dBrightCheck_c::modeMove() {
if (mDoCPd_c::getTrigA(PAD_1) || mDoCPd_c::getTrigStart(PAD_1)) { if (mDoCPd_c::getTrigA(PAD_1) || mDoCPd_c::getTrigStart(PAD_1)) {
mDoAud_seStart(Z2SE_ENTER_GAME, NULL, 0, 0); mDoAud_seStart(Z2SE_ENTER_GAME, NULL, 0, 0);
#ifdef TARGET_PC #ifdef TARGET_PC
dusk::speedrun::start();
if (dusk::getSettings().game.speedrunMode && !dusk::getSettings().game.hideTvSettingsScreen) { if (dusk::getSettings().game.speedrunMode && !dusk::getSettings().game.hideTvSettingsScreen) {
// start a new run if a run isn't already in progress // start a new run if a run isn't already in progress
if (!dusk::m_speedrunInfo.m_isRunStarted) { if (!dusk::m_speedrunInfo.m_isRunStarted) {
dusk::resetForSpeedrunMode(); dusk::resetForSpeedrunMode();
dusk::m_speedrunInfo.startRun(); dusk::m_speedrunInfo.startRun();
dusk::speedrun::start();
} }
} }
+2 -2
View File
@@ -10431,7 +10431,7 @@ bool dCamera_c::eventCamera(s32 param_0) {
#endif #endif
#if TARGET_PC #if TARGET_PC
if (dusk::frame_interp::is_enabled()) { if (dusk::getSettings().game.enableFrameInterpolation) {
switch (var_r29) { switch (var_r29) {
case 3: case 3:
case 4: case 4:
@@ -11322,7 +11322,7 @@ static int camera_execute(camera_process_class* i_this) {
#ifdef TARGET_PC #ifdef TARGET_PC
widezoom_correction(i_this, i_this->mCamera.TrimHeight()); widezoom_correction(i_this, i_this->mCamera.TrimHeight());
if (dusk::frame_interp::is_enabled()) { if (dusk::getSettings().game.enableFrameInterpolation) {
dusk::frame_interp::add_interpolation_callback([](bool _, void* pUserWork) { dusk::frame_interp::add_interpolation_callback([](bool _, void* pUserWork) {
const auto i_this = static_cast<camera_process_class*>(pUserWork); const auto i_this = static_cast<camera_process_class*>(pUserWork);
const auto camera = &i_this->mCamera; const auto camera = &i_this->mCamera;
-8
View File
@@ -15,7 +15,6 @@
#include "f_op/f_op_actor_mng.h" #include "f_op/f_op_actor_mng.h"
#if TARGET_PC #if TARGET_PC
#include "dusk/achievements.h" #include "dusk/achievements.h"
#include "dusk/settings.h"
#endif #endif
static int plCutLRC[58] = { static int plCutLRC[58] = {
@@ -430,13 +429,6 @@ fopAc_ac_c* cc_at_check(fopAc_ac_c* i_enemy, dCcU_AtInfo* i_AtInfo) {
} }
} }
#if TARGET_PC
if (dusk::getSettings().game.invincibleEnemies &&
fopAcM_GetGroup(i_enemy) == fopAc_ENEMY_e) {
i_AtInfo->mAttackPower = 0;
}
#endif
if (i_AtInfo->mAttackPower != 0) { if (i_AtInfo->mAttackPower != 0) {
i_enemy->health -= i_AtInfo->mAttackPower; i_enemy->health -= i_AtInfo->mAttackPower;
} }
-8
View File
@@ -19,7 +19,6 @@
#include "d/d_timer.h" #include "d/d_timer.h"
#include "f_op/f_op_msg_mng.h" #include "f_op/f_op_msg_mng.h"
#include "f_op/f_op_scene_mng.h" #include "f_op/f_op_scene_mng.h"
#include "m_Do/m_Do_MemCard.h"
#include "m_Do/m_Do_Reset.h" #include "m_Do/m_Do_Reset.h"
#include "m_Do/m_Do_controller_pad.h" #include "m_Do/m_Do_controller_pad.h"
#include "m_Do/m_Do_graphic.h" #include "m_Do/m_Do_graphic.h"
@@ -1239,13 +1238,6 @@ BOOL dComIfG_resetToOpening(scene_class* i_scene) {
} }
#endif #endif
#ifdef TARGET_PC
if (!mDoMemCd_isCardCommNone()) {
return 0;
}
g_mDoMemCd_control.SaveSync();
#endif
dComIfG_changeOpeningScene(i_scene, fpcNm_OPENING_SCENE_e); dComIfG_changeOpeningScene(i_scene, fpcNm_OPENING_SCENE_e);
mDoAud_bgmStop(30); mDoAud_bgmStop(30);
mDoAud_resetProcess(); mDoAud_resetProcess();
-4
View File
@@ -3882,11 +3882,7 @@ bool dCamera_c::hintTalkEvCamera() {
cSAngle acStack_1fc(20.0f); cSAngle acStack_1fc(20.0f);
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
#if AVOID_UB
for (j = 0; j < 10; j++) {
#else
for (j = 0; j < 12; j++) { for (j = 0; j < 12; j++) {
#endif
cSAngle acStack_200(local_b0[j] * fVar22); cSAngle acStack_200(local_b0[j] * fVar22);
hintTalk->mDirection.U(acStack_1f8 + acStack_200); hintTalk->mDirection.U(acStack_1f8 + acStack_200);
hintTalk->mDirection.V(((hintTalk->field_0x28.V() * acStack_200.Cos()) * 0.2f) + acStack_1fc); hintTalk->mDirection.V(((hintTalk->field_0x28.V() * acStack_200.Cos()) * 0.2f) + acStack_1fc);
+2 -2
View File
@@ -991,7 +991,7 @@ void dMenu_DmapBg_c::draw() {
-35.0f + (local_224.x - local_218.x), -35.0f + (local_224.x - local_218.x),
-35.0f + (local_224.y - local_218.y)); -35.0f + (local_224.y - local_218.y));
#if TARGET_PC #if TARGET_PC
if (!dusk::frame_interp::is_enabled()) { if (!dusk::getSettings().game.enableFrameInterpolation) {
field_0xdda = 0; field_0xdda = 0;
} }
#else #else
@@ -2624,7 +2624,7 @@ void dMenu_Dmap_c::zoomIn_proc() {
void dMenu_Dmap_c::zoomOut_init_proc() { void dMenu_Dmap_c::zoomOut_init_proc() {
#if TARGET_PC #if TARGET_PC
if (dusk::frame_interp::is_enabled()) { if (dusk::getSettings().game.enableFrameInterpolation) {
mpDrawBg->resetScrollArrowMask(); mpDrawBg->resetScrollArrowMask();
} }
#endif #endif
+1 -1
View File
@@ -1146,7 +1146,7 @@ void dMenu_Fmap_c::zoom_spot_to_region_init() {
field_0x1ec = 1.0f; field_0x1ec = 1.0f;
#if TARGET_PC #if TARGET_PC
// Frame interp note: field_0x122d used to be set every draw, causing flickering. Do it here instead. // Frame interp note: field_0x122d used to be set every draw, causing flickering. Do it here instead.
if (dusk::frame_interp::is_enabled()) { if (dusk::getSettings().game.enableFrameInterpolation) {
mpDraw2DBack->resetScrollArrowMask(); mpDraw2DBack->resetScrollArrowMask();
} }
#endif #endif
+1 -1
View File
@@ -437,7 +437,7 @@ void dMenu_Fmap2DBack_c::draw() {
if (field_0x122d) { if (field_0x122d) {
mpMeterHaihai->drawHaihai(field_0x122d); mpMeterHaihai->drawHaihai(field_0x122d);
#if TARGET_PC #if TARGET_PC
if (!dusk::frame_interp::is_enabled()) { if (!dusk::getSettings().game.enableFrameInterpolation) {
field_0x122d = 0; field_0x122d = 0;
} }
#else #else
-8
View File
@@ -26,10 +26,6 @@
#include "f_op/f_op_overlap_mng.h" #include "f_op/f_op_overlap_mng.h"
#include "m_Do/m_Do_controller_pad.h" #include "m_Do/m_Do_controller_pad.h"
#ifdef TARGET_PC
#include "dusk/frame_interpolation.h"
#endif
class dDlst_MENU_CAPTURE_c : public dDlst_base_c { class dDlst_MENU_CAPTURE_c : public dDlst_base_c {
public: public:
virtual void draw() { virtual void draw() {
@@ -1092,10 +1088,6 @@ void dMw_c::dMw_ring_create(u8 i_origin) {
} }
mpCapture->setCaptureFlag(); mpCapture->setCaptureFlag();
#ifdef TARGET_PC
dusk::frame_interp::request_presentation_sync();
#endif
} }
bool dMw_c::dMw_ring_delete() { bool dMw_c::dMw_ring_delete() {
-13
View File
@@ -18,9 +18,6 @@
#include "d/d_pane_class.h" #include "d/d_pane_class.h"
#include "dusk/frame_interpolation.h" #include "dusk/frame_interpolation.h"
#include <cstring> #include <cstring>
#if TARGET_PC
#include "dusk/string.hpp"
#endif
#if VERSION == VERSION_GCN_JPN #if VERSION == VERSION_GCN_JPN
#define STR_BUF_LEN 528 #define STR_BUF_LEN 528
@@ -2930,12 +2927,6 @@ bool dMeterButton_c::isClose() {
} }
void dMeterButton_c::setString(char* i_string, u8 i_button, u8 param_2, u8 param_3) { void dMeterButton_c::setString(char* i_string, u8 i_button, u8 param_2, u8 param_3) {
#if TARGET_PC
char* i_string_full = i_string;
char i_string_buf[sizeof(mButtonText[0])];
dusk::SafeStringCopyTruncate(i_string_buf, i_string);
i_string = i_string_buf;
#endif
if (strcmp(mButtonText[param_2], i_string) != 0 || field_0x4be[param_2] != i_button) { if (strcmp(mButtonText[param_2], i_string) != 0 || field_0x4be[param_2] != i_button) {
if (param_2 == 0 && strcmp(mButtonText[1], i_string) == 0 && if (param_2 == 0 && strcmp(mButtonText[1], i_string) == 0 &&
((i_button == BUTTON_A_e && field_0x4be[1] == BUTTON_A_e) || ((i_button == BUTTON_A_e && field_0x4be[1] == BUTTON_A_e) ||
@@ -3031,10 +3022,6 @@ void dMeterButton_c::setString(char* i_string, u8 i_button, u8 param_2, u8 param
strcpy(mButtonText[param_2], i_string); strcpy(mButtonText[param_2], i_string);
#if TARGET_PC
i_string = i_string_full;
#endif
if (param_2 == 0) { if (param_2 == 0) {
if (param_3 != 0) { if (param_3 != 0) {
field_0x4d9 = param_2; field_0x4d9 = param_2;
-8
View File
@@ -188,14 +188,6 @@ void dMsgScrnTree_c::exec() {
fukiAlpha(1.0f); fukiAlpha(1.0f);
} }
mpPmP_c->scale(g_MsgObject_HIO_c.mBoxWoodScaleX, g_MsgObject_HIO_c.mBoxWoodScaleY); mpPmP_c->scale(g_MsgObject_HIO_c.mBoxWoodScaleX, g_MsgObject_HIO_c.mBoxWoodScaleY);
#if TARGET_PC
const f32 hudScale = mDoGph_gInf_c::hudAspectScaleUp;
if (hudScale > 1.0f) {
field_0xc4->getPanePtr()->setBasePosition(J2DBasePosition_4);
field_0xc4->getPanePtr()->scale(hudScale, 1.0f);
}
#endif
} }
void dMsgScrnTree_c::draw() { void dMsgScrnTree_c::draw() {
+7 -10
View File
@@ -77,16 +77,16 @@ static const char* l_mojiEisu[65] = {
// That can't work on a modern platform, so instead I've filled them out ahead of time. // That can't work on a modern platform, so instead I've filled them out ahead of time.
static const char* l_mojiEisuPal_1[65] = { static const char* l_mojiEisuPal_1[65] = {
"A", "N", "\xC0", "\xCF", "1", "B", "O", "\xC1", "\xD0", "2", "C", "P", "\xC2", "\xD1", "3", "D", "Q", "A", "N", "\xC0", "\xCF", "1", "B", "O", "\xC1", "\xD0", "2", "C", "P", "\xC2", "\xD1", "3", "D", "Q",
"\xC4", "\xD2", "4", "E", "R", "\xC6", "\xD3", "5", "F", "S", "\xC7", "\xD4", "6", "G", "T", "\xC8", "\xD6", "\xC3", "\xD2", "4", "E", "R", "\xC4", "\xD3", "5", "F", "S", "\xC5", "\xD4", "6", "G", "T", "\xC6", "\xD5",
"7", "H", "U", "\xC9", "\x8C", "8", "I", "V", "\xCA", "\xD9", "9", "J", "W", "\xCB", "\xDA", "0", "K", "7", "H", "U", "\xC7", "\xD6", "8", "I", "V", "\xC8", "\xD7", "9", "J", "W", "\xC9", "\xD8", "0", "K",
"X", "\xCC", "\xDB", ",", "L", "Y", "\xCD", "\xDC", ".", "M", "Z", "\xCE", "\x2D", " ", "X", "\xCA", "\xD9", ",", "L", "Y", "\xCB", "\xDA", ".", "M", "Z", "\xCC", "\xDB", " ",
}; };
static const char* l_mojiEisuPal_2[65] = { static const char* l_mojiEisuPal_2[65] = {
"a", "n", "\xE0", "\xEF", "1", "b", "o", "\xE1", "\xF0", "2", "c", "p", "\xE2", "\xF1", "3", "d", "q", "a", "n", "\xE0", "\xEF", "1", "b", "o", "\xE1", "\xF0", "2", "c", "p", "\xE2", "\xF1", "3", "d", "q",
"\xE4", "\xF2", "4", "e", "r", "\xE6", "\xF3", "5", "f", "s", "\xE7", "\xF4", "6", "g", "t", "\xE8", "\xE3", "\xF2", "4", "e", "r", "\xE4", "\xF3", "5", "f", "s", "\xE5", "\xF4", "6", "g", "t", "\xE6",
"\xF6", "7", "h", "u", "\xE9", "\x9C", "8", "i", "v", "\xEA", "\xF9", "9", "j", "w", "\xEB", "\xFA", "0", "\xF5", "7", "h", "u", "\xE7", "\xF6", "8", "i", "v", "\xE8", "\xF7", "9", "j", "w", "\xE9", "\xF8", "0",
"k", "x", "\xEC", "\xFB", ",", "l", "y", "\xED", "\xFC", ".", "m", "z", "\xEE", "\xDF", " ", "k", "x", "\xEA", "\xF9", ",", "l", "y", "\xEB", "\xFA", ".", "m", "z", "\xEC", "\xFB", " ",
}; };
#elif REGION_PAL #elif REGION_PAL
static const char* l_mojiEisuPal_1[65] = { static const char* l_mojiEisuPal_1[65] = {
@@ -295,7 +295,6 @@ void dName_c::_move() {
} }
} else { } else {
#endif #endif
#if !TARGET_PC
if (mDoCPd_c::getTrigRight(PAD_1)) { if (mDoCPd_c::getTrigRight(PAD_1)) {
// BUG: this check only fails if the cursor is at exactly 7 // BUG: this check only fails if the cursor is at exactly 7
// setMoji allows the cursor to reach 8, which is out of bounds here // setMoji allows the cursor to reach 8, which is out of bounds here
@@ -312,9 +311,7 @@ void dName_c::_move() {
mCurPos--; mCurPos--;
nameCursorMove(); nameCursorMove();
} }
} else } else if (mDoCPd_c::getTrigB(PAD_1)) {
#endif
if (mDoCPd_c::getTrigB(PAD_1)) {
if (mCurPos == 0) { if (mCurPos == 0) {
mDoAud_seStart(Z2SE_SY_MENU_BACK, 0, 0, 0); mDoAud_seStart(Z2SE_SY_MENU_BACK, 0, 0, 0);
field_0x2ac = mSelProc; field_0x2ac = mSelProc;
-2
View File
@@ -10,7 +10,6 @@
#include "d/d_meter2_info.h" #include "d/d_meter2_info.h"
#include "d/d_s_name.h" #include "d/d_s_name.h"
#include "dusk/imgui/ImGuiConsole.hpp" #include "dusk/imgui/ImGuiConsole.hpp"
#include "dusk/livesplit.h"
#include "dusk/memory.h" #include "dusk/memory.h"
#include "dusk/speedrun.h" #include "dusk/speedrun.h"
#include "dusk/settings.h" #include "dusk/settings.h"
@@ -423,7 +422,6 @@ void dScnName_c::changeGameScene() {
if (!dusk::m_speedrunInfo.m_isRunStarted) { if (!dusk::m_speedrunInfo.m_isRunStarted) {
dusk::resetForSpeedrunMode(); dusk::resetForSpeedrunMode();
dusk::m_speedrunInfo.startRun(); dusk::m_speedrunInfo.startRun();
dusk::speedrun::start();
} }
} }
+5 -3
View File
@@ -30,9 +30,7 @@
#if TARGET_PC #if TARGET_PC
#include "dusk/settings.h" #include "dusk/settings.h"
#include <f_ap/f_ap_game.h> #include <f_ap/f_ap_game.h>
#include <dusk/autosave.h>
#include "dusk/string.hpp"
#define strcpy dusk::SafeStringCopy
#endif #endif
static u8 dSv_item_rename(u8 i_itemNo) { static u8 dSv_item_rename(u8 i_itemNo) {
@@ -351,6 +349,10 @@ void dSv_player_item_c::setItem(int i_slotNo, u8 i_itemNo) {
dComIfGp_setSelectItem(i); dComIfGp_setSelectItem(i);
} }
} }
#if TARGET_PC
triggerAutoSave();
#endif
} }
u8 dSv_player_item_c::getItem(int i_slotNo, bool i_checkCombo) const { u8 dSv_player_item_c::getItem(int i_slotNo, bool i_checkCombo) const {
+3 -6
View File
@@ -191,17 +191,13 @@ std::vector<AchievementSystem::Entry> AchievementSystem::makeEntries() {
} }
bool hasJewelRod = false; bool hasJewelRod = false;
bool hasAncientDoc = false; for (int slot = 0; slot < 24 && !hasJewelRod; ++slot) {
for (int slot = 0; slot < 24; ++slot) {
const u8 item = dComIfGs_getItem(slot, false); const u8 item = dComIfGs_getItem(slot, false);
if (item == dItemNo_JEWEL_ROD_e || item == dItemNo_JEWEL_BEE_ROD_e || item == dItemNo_JEWEL_WORM_ROD_e) { if (item == dItemNo_JEWEL_ROD_e || item == dItemNo_JEWEL_BEE_ROD_e || item == dItemNo_JEWEL_WORM_ROD_e) {
hasJewelRod = true; hasJewelRod = true;
} }
if (item == dItemNo_ANCIENT_DOCUMENT_e || item == dItemNo_ANCIENT_DOCUMENT2_e || item == dItemNo_AIR_LETTER_e) {
hasAncientDoc = true;
}
} }
if (!hasJewelRod || !hasAncientDoc) { if (!hasJewelRod) {
return; return;
} }
@@ -216,6 +212,7 @@ std::vector<AchievementSystem::Entry> AchievementSystem::makeEntries() {
dItemNo_KANTERA_e, dItemNo_KANTERA_e,
dItemNo_PACHINKO_e, dItemNo_PACHINKO_e,
dItemNo_HAWK_EYE_e, dItemNo_HAWK_EYE_e,
dItemNo_ANCIENT_DOCUMENT_e,
dItemNo_HORSE_FLUTE_e, dItemNo_HORSE_FLUTE_e,
}; };
for (u8 required : requiredWheelItems) { for (u8 required : requiredWheelItems) {
+6 -26
View File
@@ -14,23 +14,9 @@ static AutoSaveFuncs AutoSaveFuncsProc[] = {
void noAutoSave() {} void noAutoSave() {}
bool canAutoSave() {
daAlink_c* player = (daAlink_c*)daAlink_getAlinkActorClass();
if (player == nullptr) {
return false;
}
if (player->checkCargoCarry() || player->checkCanoeRide()) {
return false;
}
return dusk::getSettings().game.autoSave && shouldAutoSave && mAutoSaveProc == 0 &&
strcmp(dComIfGp_getStartStageName(), "F_SP102") != 0 &&
strcmp(dComIfGp_getStartStageName(), "F_SP112") != 0;
}
void triggerAutoSave() { void triggerAutoSave() {
if (canAutoSave()) if (dusk::getSettings().game.autoSave && shouldAutoSave && mAutoSaveProc == 0 &&
strcmp(dComIfGp_getStartStageName(), "F_SP102") != 0)
{ {
mAutoSaveProc = 1; mAutoSaveProc = 1;
} }
@@ -40,12 +26,8 @@ void updateAutoSave() {
(AutoSaveFuncsProc[mAutoSaveProc])(); (AutoSaveFuncsProc[mAutoSaveProc])();
} }
bool writeAutoSave() { void writeAutoSave() {
stage_stag_info_class* stagInfo = dComIfGp_getStageStagInfo(); int stageNo = dStage_stagInfo_GetSaveTbl(dComIfGp_getStageStagInfo());
if (stagInfo == nullptr) {
return false;
}
int stageNo = dStage_stagInfo_GetSaveTbl(stagInfo);
dComIfGs_putSave(stageNo); dComIfGs_putSave(stageNo);
dComIfGs_setMemoryToCard(mSaveBuffer, dComIfGs_getDataNum()); dComIfGs_setMemoryToCard(mSaveBuffer, dComIfGs_getDataNum());
@@ -58,7 +40,6 @@ bool writeAutoSave() {
} }
g_mDoMemCd_control.save(mSaveBuffer, sizeof(mSaveBuffer), 0); g_mDoMemCd_control.save(mSaveBuffer, sizeof(mSaveBuffer), 0);
return true;
} }
void autoSaving() { void autoSaving() {
@@ -67,9 +48,8 @@ void autoSaving() {
if (cardState == 2) { if (cardState == 2) {
mAutoSaveProc = 1; mAutoSaveProc = 1;
} else if (cardState == 1) { } else if (cardState == 1) {
if (writeAutoSave()) { writeAutoSave();
mAutoSaveProc = 3; mAutoSaveProc = 3;
}
} }
} }
} }
+2 -22
View File
@@ -56,29 +56,12 @@ static T sanitizeEnumValue(const ConfigVar<T>& cVar, T value) {
template<ConfigValue T> template<ConfigValue T>
void ConfigImpl<T>::loadFromJson(ConfigVar<T>& cVar, const json& jsonValue) { void ConfigImpl<T>::loadFromJson(ConfigVar<T>& cVar, const json& jsonValue) {
if constexpr (std::is_enum_v<T>) {
if (jsonValue.is_boolean()) {
using Underlying = std::underlying_type_t<T>;
const bool b = jsonValue.get<bool>();
Underlying raw;
if constexpr (std::is_same_v<T, dusk::FrameInterpMode>) {
raw = b ? static_cast<Underlying>(2) : static_cast<Underlying>(0);
} else {
raw = b ? static_cast<Underlying>(1) : static_cast<Underlying>(0);
}
cVar.setValue(sanitizeEnumValue(cVar, static_cast<T>(raw)), false);
return;
}
}
cVar.setValue(sanitizeEnumValue(cVar, jsonValue.get<T>()), false); cVar.setValue(sanitizeEnumValue(cVar, jsonValue.get<T>()), false);
} }
template<ConfigValue T> template<ConfigValue T>
nlohmann::json ConfigImpl<T>::dumpToJson(const ConfigVar<T>& cVar) { nlohmann::json ConfigImpl<T>::dumpToJson(const ConfigVar<T>& cVar) {
return cVar.getValueForSave(); return cVar.getValue();
} }
template<ConfigValue T> requires std::is_integral_v<T> && std::is_signed_v<T> template<ConfigValue T> requires std::is_integral_v<T> && std::is_signed_v<T>
@@ -175,8 +158,6 @@ namespace dusk::config {
template class ConfigImpl<dusk::DiscVerificationState>; template class ConfigImpl<dusk::DiscVerificationState>;
template class ConfigImpl<dusk::GameLanguage>; template class ConfigImpl<dusk::GameLanguage>;
template class ConfigImpl<dusk::GyroMode>; template class ConfigImpl<dusk::GyroMode>;
template class ConfigImpl<dusk::FrameInterpMode>;
template class ConfigImpl<dusk::Resampler>;
} }
void dusk::config::Register(ConfigVarBase& configVar) { void dusk::config::Register(ConfigVarBase& configVar) {
@@ -268,8 +249,7 @@ void dusk::config::Save() {
json j; json j;
for (const auto& pair : RegisteredConfigVars) { for (const auto& pair : RegisteredConfigVars) {
const auto layer = pair.second->getLayer(); if (pair.second->getLayer() == ConfigVarLayer::Value) {
if (layer == ConfigVarLayer::Value || layer == ConfigVarLayer::Speedrun) {
j[pair.first] = pair.second->getImpl()->dumpToJson(*pair.second); j[pair.first] = pair.second->getImpl()->dumpToJson(*pair.second);
} }
} }
+1 -1
View File
@@ -61,7 +61,7 @@ std::string release_name() {
} }
std::filesystem::path sentry_database_path() { std::filesystem::path sentry_database_path() {
return dusk::CachePath / "sentry"; return dusk::ConfigPath / "sentry";
} }
std::filesystem::path log_attachment_path() { std::filesystem::path log_attachment_path() {
+93 -222
View File
@@ -6,7 +6,6 @@
#include "dusk/main.h" #include "dusk/main.h"
#include <array> #include <array>
#include <chrono>
#include <filesystem> #include <filesystem>
#include <optional> #include <optional>
#include <ranges> #include <ranges>
@@ -31,21 +30,6 @@ constexpr auto kLocationDescriptorName = "data_location.json";
constexpr auto kPipelineCacheName = "pipeline_cache.db"; constexpr auto kPipelineCacheName = "pipeline_cache.db";
constexpr auto kInitialPipelineCacheName = "initial_pipeline_cache.db"; constexpr auto kInitialPipelineCacheName = "initial_pipeline_cache.db";
constexpr std::array<std::string_view, 4> kUserDataDirectories = {
"texture_replacements",
"USA",
"EUR",
"JAP",
};
constexpr std::array<std::string_view, 6> kUserDataFiles = {
"achievements.json",
"config.json",
"controller_ports.dat",
"imgui.ini",
"keyboard_bindings.dat",
"states.json",
};
enum class LocationMode { enum class LocationMode {
Default, Default,
Portable, Portable,
@@ -78,7 +62,6 @@ struct MigrationStats {
std::optional<std::filesystem::path> sConfiguredDataPath; std::optional<std::filesystem::path> sConfiguredDataPath;
std::optional<std::filesystem::path> sActiveDescriptorPath; std::optional<std::filesystem::path> sActiveDescriptorPath;
std::optional<std::filesystem::path> sActivePrefPath;
std::filesystem::path path_from_utf8(std::string_view value) { std::filesystem::path path_from_utf8(std::string_view value) {
return std::filesystem::path{ return std::filesystem::path{
@@ -87,22 +70,19 @@ std::filesystem::path path_from_utf8(std::string_view value) {
}; };
} }
std::filesystem::path legacy_path_for_pref_path(const std::filesystem::path& prefPath) { std::filesystem::path get_legacy_path() {
if (std::string_view{LegacyAppName}.empty() || prefPath.empty()) { if (std::string_view{LegacyAppName}.empty()) {
return {}; return {};
} }
auto normalizedPrefPath = prefPath; char* prefPath = SDL_GetPrefPath(OrgName, LegacyAppName);
if (normalizedPrefPath.filename().empty()) { if (!prefPath) {
normalizedPrefPath = normalizedPrefPath.parent_path(); Log.fatal("Unable to get PrefPath: {}", SDL_GetError());
} }
const auto parentPath = normalizedPrefPath.parent_path(); std::filesystem::path result{reinterpret_cast<const char8_t*>(prefPath)};
if (parentPath.empty()) { SDL_free(prefPath);
return {}; return result;
}
return parentPath / LegacyAppName;
} }
std::filesystem::path get_pref_path() { std::filesystem::path get_pref_path() {
@@ -116,13 +96,6 @@ std::filesystem::path get_pref_path() {
return result; return result;
} }
std::filesystem::path active_pref_path() {
if (sActivePrefPath) {
return *sActivePrefPath;
}
return get_pref_path();
}
std::filesystem::path base_path_relative(const std::filesystem::path& path) { std::filesystem::path base_path_relative(const std::filesystem::path& path) {
const auto* basePath = SDL_GetBasePath(); const auto* basePath = SDL_GetBasePath();
if (!basePath) { if (!basePath) {
@@ -276,69 +249,6 @@ std::filesystem::path absolute_path(const std::filesystem::path& path) {
return absolute.lexically_normal(); return absolute.lexically_normal();
} }
std::filesystem::path rename_legacy_pref_path(
const std::filesystem::path& legacyPath, const std::filesystem::path& prefPath) {
if (legacyPath.empty() || prefPath.empty() ||
normalized_path(legacyPath) == normalized_path(prefPath))
{
return prefPath;
}
std::error_code ec;
if (!std::filesystem::exists(legacyPath, ec)) {
if (ec) {
Log.warn("Failed to inspect legacy data directory '{}': {}",
io::fs_path_to_string(legacyPath), ec.message());
}
return prefPath;
}
const bool prefExists = std::filesystem::exists(prefPath, ec);
if (ec) {
Log.warn("Failed to inspect data directory '{}': {}", io::fs_path_to_string(prefPath),
ec.message());
return prefPath;
}
if (prefExists) {
if (!std::filesystem::is_directory(prefPath, ec) ||
!std::filesystem::is_empty(prefPath, ec))
{
if (ec) {
Log.warn("Failed to inspect data directory '{}': {}",
io::fs_path_to_string(prefPath), ec.message());
} else {
Log.info("Skipping legacy data directory rename because '{}' is not empty",
io::fs_path_to_string(prefPath));
}
return prefPath;
}
std::filesystem::remove(prefPath, ec);
if (ec) {
Log.warn("Failed to remove empty data directory '{}' before legacy rename: {}",
io::fs_path_to_string(prefPath), ec.message());
return prefPath;
}
}
std::filesystem::rename(legacyPath, prefPath, ec);
if (ec) {
Log.warn("Failed to rename legacy data directory '{}' to '{}': {}",
io::fs_path_to_string(legacyPath), io::fs_path_to_string(prefPath), ec.message());
ec.clear();
if (!std::filesystem::exists(prefPath, ec) && !ec) {
Log.info("Using legacy data directory '{}' because the new data directory is absent",
io::fs_path_to_string(legacyPath));
return legacyPath;
}
return prefPath;
}
Log.info("Renamed legacy data directory '{}' to '{}'", io::fs_path_to_string(legacyPath),
io::fs_path_to_string(prefPath));
return prefPath;
}
bool is_same_or_inside(const std::filesystem::path& root, const std::filesystem::path& path) { bool is_same_or_inside(const std::filesystem::path& root, const std::filesystem::path& path) {
const auto normalizedRoot = normalized_path(root); const auto normalizedRoot = normalized_path(root);
const auto normalizedPath = normalized_path(path); const auto normalizedPath = normalized_path(path);
@@ -373,46 +283,85 @@ bool should_skip_migration_path(const std::filesystem::path& path,
return false; return false;
} }
bool matches_name(std::string_view name, const auto& names) { bool has_location_descriptor(const std::filesystem::path& path) {
return std::ranges::find(names, name) != names.end(); std::error_code ec;
return std::filesystem::exists(path / kLocationDescriptorName, ec);
} }
bool should_migrate_user_data_path( bool remove_empty_destination_for_rename(const std::filesystem::path& path) {
const std::filesystem::path& sourcePath, const std::filesystem::path& from) { std::error_code ec;
const auto relativePath = sourcePath.lexically_relative(from); const bool exists = std::filesystem::exists(path, ec);
if (relativePath.empty() || relativePath.is_absolute()) { if (ec) {
Log.debug("Could not inspect migration destination '{}': {}", io::fs_path_to_string(path),
ec.message());
return false; return false;
} }
if (!exists) {
auto it = relativePath.begin();
if (it == relativePath.end() || *it == "..") {
return false;
}
const auto first = io::fs_path_to_string(*it);
if (matches_name(first, kUserDataDirectories)) {
return true; return true;
} }
++it; const bool canRemove = std::filesystem::is_directory(path, ec) &&
if (it != relativePath.end()) { std::filesystem::is_empty(path, ec) && !has_location_descriptor(path);
if (ec || !canRemove) {
if (ec) {
Log.debug("Could not inspect migration destination '{}': {}",
io::fs_path_to_string(path), ec.message());
}
return false; return false;
} }
const auto filename = io::fs_path_to_string(relativePath.filename()); std::filesystem::remove(path, ec);
if (matches_name(filename, kUserDataFiles)) { if (ec) {
return true; Log.debug("Could not remove empty migration destination '{}': {}",
io::fs_path_to_string(path), ec.message());
return false;
} }
return relativePath.extension() == ".controller" || relativePath.extension() == ".gci" || return true;
(filename.starts_with("MemoryCard") && filename.ends_with(".raw")); }
bool try_rename_directory_migration(
const std::filesystem::path& from, const std::filesystem::path& to) {
std::error_code ec;
if (!std::filesystem::is_directory(from, ec)) {
return false;
}
if (ec) {
Log.debug("Could not inspect migration source '{}': {}", io::fs_path_to_string(from),
ec.message());
return false;
}
if (has_location_descriptor(from)) {
return false;
}
if (!remove_empty_destination_for_rename(to)) {
return false;
}
std::filesystem::create_directories(to.parent_path(), ec);
if (ec) {
Log.debug("Could not create migration destination parent '{}': {}",
io::fs_path_to_string(to.parent_path()), ec.message());
return false;
}
std::filesystem::rename(from, to, ec);
if (ec) {
Log.debug("Could not rename data directory '{}' to '{}': {}", io::fs_path_to_string(from),
io::fs_path_to_string(to), ec.message());
return false;
}
Log.info("Renamed data directory '{}' to '{}'", io::fs_path_to_string(from),
io::fs_path_to_string(to));
return true;
} }
std::filesystem::path current_data_path() { std::filesystem::path current_data_path() {
if (!ConfigPath.empty()) { if (!ConfigPath.empty()) {
return ConfigPath; return ConfigPath;
} }
const auto prefPath = active_pref_path(); const auto prefPath = get_pref_path();
const auto descriptor = read_location_descriptor(prefPath); const auto descriptor = read_location_descriptor(prefPath);
if (descriptor) { if (descriptor) {
sActiveDescriptorPath = descriptor->path; sActiveDescriptorPath = descriptor->path;
@@ -478,7 +427,7 @@ bool write_location_descriptor(LocationMode mode, const std::filesystem::path& t
json["previousPath"] = io::fs_path_to_string(descriptor.previousPath); json["previousPath"] = io::fs_path_to_string(descriptor.previousPath);
} }
const auto prefPath = active_pref_path(); const auto prefPath = get_pref_path();
for (const auto& path : descriptor_write_paths(prefPath)) { for (const auto& path : descriptor_write_paths(prefPath)) {
if (write_descriptor_json(path, json)) { if (write_descriptor_json(path, json)) {
sActiveDescriptorPath = path; sActiveDescriptorPath = path;
@@ -490,61 +439,6 @@ bool write_location_descriptor(LocationMode mode, const std::filesystem::path& t
return false; return false;
} }
void set_error(std::string* errorOut, std::string error) {
if (errorOut != nullptr) {
*errorOut = std::move(error);
}
}
bool validate_writable_data_path(const std::filesystem::path& path, std::string* errorOut) {
if (path.empty()) {
set_error(errorOut, "Choose a folder.");
return false;
}
std::error_code ec;
std::filesystem::create_directories(path, ec);
if (ec) {
set_error(errorOut, fmt::format("{} could not create the selected folder.", AppName));
Log.warn("Failed to create custom data folder '{}': {}", io::fs_path_to_string(path),
ec.message());
return false;
}
if (!std::filesystem::is_directory(path, ec)) {
set_error(errorOut, "The selected path is not a folder.");
if (ec) {
Log.warn("Failed to inspect custom data folder '{}': {}", io::fs_path_to_string(path),
ec.message());
}
return false;
}
const auto probePath = path / fmt::format(".write-probe-{}.tmp",
std::chrono::steady_clock::now().time_since_epoch().count());
try {
io::FileStream::WriteAllText(probePath, "dusk");
} catch (const std::exception& e) {
set_error(errorOut, fmt::format("{} could not write to the selected folder.", AppName));
Log.warn("Failed write probe for custom data folder '{}': {}", io::fs_path_to_string(path),
e.what());
return false;
}
std::filesystem::remove(probePath, ec);
if (ec) {
set_error(
errorOut, fmt::format("{} could write to the selected folder, but could not remove "
"the test file it created.",
AppName));
Log.warn("Failed to remove custom data folder write probe '{}': {}",
io::fs_path_to_string(probePath), ec.message());
return false;
}
return true;
}
std::uintmax_t remove_empty_directories(const std::filesystem::path& root, bool includeRoot) { std::uintmax_t remove_empty_directories(const std::filesystem::path& root, bool includeRoot) {
std::error_code ec; std::error_code ec;
std::vector<std::filesystem::path> directories; std::vector<std::filesystem::path> directories;
@@ -753,6 +647,14 @@ void migrate_directory(const std::filesystem::path& from, const std::filesystem:
return; return;
} }
if (try_rename_directory_migration(from, to)) {
return;
}
if (try_rename_directory_migration(from, to)) {
return;
}
std::filesystem::create_directories(to, ec); std::filesystem::create_directories(to, ec);
if (ec) { if (ec) {
++stats.failures; ++stats.failures;
@@ -798,16 +700,6 @@ void migrate_directory(const std::filesystem::path& from, const std::filesystem:
continue; continue;
} }
if (!should_migrate_user_data_path(sourcePath, from)) {
++stats.skippedUnsupportedEntries;
if (std::filesystem::is_directory(status)) {
it.disable_recursion_pending();
}
ec.clear();
it.increment(ec);
continue;
}
const auto relativePath = sourcePath.lexically_relative(from); const auto relativePath = sourcePath.lexically_relative(from);
if (relativePath.empty() || relativePath.is_absolute()) { if (relativePath.empty() || relativePath.is_absolute()) {
++stats.failures; ++stats.failures;
@@ -869,6 +761,8 @@ void migrate_data(const std::filesystem::path& prefPath, const std::filesystem::
const LocationDescriptor* descriptor) { const LocationDescriptor* descriptor) {
if (descriptor && !descriptor->previousPath.empty()) { if (descriptor && !descriptor->previousPath.empty()) {
migrate_directory(descriptor->previousPath, dataPath, prefPath); migrate_directory(descriptor->previousPath, dataPath, prefPath);
} else if (const auto legacyPath = get_legacy_path(); !legacyPath.empty()) {
migrate_directory(legacyPath, dataPath, prefPath);
} }
} }
@@ -1005,25 +899,17 @@ bool open_data_path() {
#endif #endif
} }
bool set_custom_data_path(const std::filesystem::path& path, std::string* errorOut) { bool set_custom_data_path(const std::filesystem::path& path) {
if (!validate_writable_data_path(path, errorOut)) { if (path.empty()) {
Log.warn("Ignoring empty custom data path");
return false; return false;
} }
if (!write_location_descriptor(LocationMode::Custom, path)) { return write_location_descriptor(LocationMode::Custom, path);
set_error(errorOut, fmt::format("{} could not save the data folder setting.", AppName));
return false;
}
return true;
} }
bool set_custom_data_path(const char* path, std::string* errorOut) { bool set_custom_data_path(const char* path) {
if (path == nullptr) { return set_custom_data_path(path_from_utf8(path));
set_error(errorOut, "Choose a folder.");
return false;
}
return set_custom_data_path(path_from_utf8(path), errorOut);
} }
bool set_portable_data_path() { bool set_portable_data_path() {
@@ -1031,12 +917,12 @@ bool set_portable_data_path() {
} }
bool reset_data_path() { bool reset_data_path() {
const auto prefPath = active_pref_path(); const auto prefPath = get_pref_path();
return write_location_descriptor(LocationMode::Default, default_data_path(prefPath)); return write_location_descriptor(LocationMode::Default, default_data_path(prefPath));
} }
bool is_default_data_path() { bool is_default_data_path() {
const auto prefPath = active_pref_path(); const auto prefPath = get_pref_path();
return normalized_path(configured_data_path()) == normalized_path(default_data_path(prefPath)); return normalized_path(configured_data_path()) == normalized_path(default_data_path(prefPath));
} }
@@ -1045,7 +931,7 @@ std::filesystem::path configured_data_path() {
return *sConfiguredDataPath; return *sConfiguredDataPath;
} }
const auto prefPath = active_pref_path(); const auto prefPath = get_pref_path();
const auto descriptor = read_location_descriptor(prefPath); const auto descriptor = read_location_descriptor(prefPath);
if (descriptor) { if (descriptor) {
sActiveDescriptorPath = descriptor->path; sActiveDescriptorPath = descriptor->path;
@@ -1055,13 +941,6 @@ std::filesystem::path configured_data_path() {
return *sConfiguredDataPath; return *sConfiguredDataPath;
} }
std::filesystem::path cache_path() {
if (!CachePath.empty()) {
return CachePath;
}
return active_pref_path();
}
bool is_data_path_restart_pending() { bool is_data_path_restart_pending() {
if (ConfigPath.empty()) { if (ConfigPath.empty()) {
return false; return false;
@@ -1070,12 +949,8 @@ bool is_data_path_restart_pending() {
return normalized_path(ConfigPath) != normalized_path(configured_data_path()); return normalized_path(ConfigPath) != normalized_path(configured_data_path());
} }
Paths initialize_data() { std::filesystem::path initialize_data() {
const auto preferredPrefPath = get_pref_path(); const auto prefPath = get_pref_path();
const auto prefPath =
rename_legacy_pref_path(legacy_path_for_pref_path(preferredPrefPath), preferredPrefPath);
sActivePrefPath = prefPath;
const auto descriptor = read_location_descriptor(prefPath); const auto descriptor = read_location_descriptor(prefPath);
if (descriptor) { if (descriptor) {
sActiveDescriptorPath = descriptor->path; sActiveDescriptorPath = descriptor->path;
@@ -1088,13 +963,9 @@ Paths initialize_data() {
migrate_data(prefPath, dataPath, descriptor ? &descriptor->descriptor : nullptr); migrate_data(prefPath, dataPath, descriptor ? &descriptor->descriptor : nullptr);
ensure_data_directory(dataPath); ensure_data_directory(dataPath);
ensure_data_directory(prefPath); ensure_initial_pipeline_cache(dataPath);
ensure_initial_pipeline_cache(prefPath);
return Paths{ return dataPath;
.userPath = dataPath,
.cachePath = prefPath,
};
} }
} // namespace dusk::data } // namespace dusk::data
+4 -11
View File
@@ -1,7 +1,6 @@
#pragma once #pragma once
#include <filesystem> #include <filesystem>
#include <string>
#if defined(__APPLE__) #if defined(__APPLE__)
#include <TargetConditionals.h> #include <TargetConditionals.h>
@@ -15,7 +14,7 @@
#define DUSK_CAN_OPEN_DATA_FOLDER 0 #define DUSK_CAN_OPEN_DATA_FOLDER 0
#endif #endif
#if (defined(__APPLE__) && TARGET_OS_IOS && !TARGET_OS_MACCATALYST) || defined(__ANDROID__) #if defined(__APPLE__) && TARGET_OS_IOS && !TARGET_OS_MACCATALYST
#define DUSK_CAN_CHANGE_DATA_FOLDER 0 #define DUSK_CAN_CHANGE_DATA_FOLDER 0
#else #else
#define DUSK_CAN_CHANGE_DATA_FOLDER 1 #define DUSK_CAN_CHANGE_DATA_FOLDER 1
@@ -23,17 +22,11 @@
namespace dusk::data { namespace dusk::data {
struct Paths { std::filesystem::path initialize_data();
std::filesystem::path userPath;
std::filesystem::path cachePath;
};
Paths initialize_data();
std::filesystem::path configured_data_path(); std::filesystem::path configured_data_path();
std::filesystem::path cache_path();
bool open_data_path(); bool open_data_path();
bool set_custom_data_path(const char* path, std::string* errorOut); bool set_custom_data_path(const char* path);
bool set_custom_data_path(const std::filesystem::path& path, std::string* errorOut); bool set_custom_data_path(const std::filesystem::path& path);
bool set_portable_data_path(); bool set_portable_data_path();
bool reset_data_path(); bool reset_data_path();
bool is_default_data_path(); bool is_default_data_path();
+8 -13
View File
@@ -21,7 +21,6 @@ bool g_sync_presentation = false;
float g_step = 0.0f; float g_step = 0.0f;
bool g_is_sim_frame = false; bool g_is_sim_frame = false;
bool g_ui_tick_pending = false; bool g_ui_tick_pending = false;
uint64_t g_sim_tick_seq = 0;
Recording g_current_recording; Recording g_current_recording;
Recording g_previous_recording; Recording g_previous_recording;
@@ -67,18 +66,19 @@ void copy_view_to_snap(CameraSnapshot* dst, const view_class& v) {
} }
inline void lerp_matrix(Mtx out, const Mtx lhs, const Mtx rhs, float step) { inline void lerp_matrix(Mtx out, const Mtx lhs, const Mtx rhs, float step) {
const float old_weight = 1.0f - step;
for (size_t row = 0; row < 3; ++row) { for (size_t row = 0; row < 3; ++row) {
for (size_t col = 0; col < 4; ++col) { for (size_t col = 0; col < 4; ++col) {
const float l = lhs[row][col]; out[row][col] = lhs[row][col] * old_weight + rhs[row][col] * step;
out[row][col] = l + (rhs[row][col] - l) * step;
} }
} }
} }
inline void lerp_xyz(cXyz* out, const cXyz& lhs, const cXyz& rhs, float step) { inline void lerp_xyz(cXyz* out, const cXyz& lhs, const cXyz& rhs, float step) {
out->x = lhs.x + (rhs.x - lhs.x) * step; const float old_weight = 1.0f - step;
out->y = lhs.y + (rhs.y - lhs.y) * step; out->x = lhs.x * old_weight + rhs.x * step;
out->z = lhs.z + (rhs.z - lhs.z) * step; out->y = lhs.y * old_weight + rhs.y * step;
out->z = lhs.z * old_weight + rhs.z * step;
} }
static s16 lerp_bank(s16 a, s16 b, f32 t) { static s16 lerp_bank(s16 a, s16 b, f32 t) {
@@ -135,15 +135,10 @@ void begin_sim_tick() {
s_interpolationCallBackWork.clear(); s_interpolationCallBackWork.clear();
s_cam_prev = std::move(s_cam_curr); s_cam_prev = std::move(s_cam_curr);
++g_sim_tick_seq;
} }
uint64_t sim_tick_seq() { void begin_frame(bool enabled, bool is_sim_frame, float step) {
return g_sim_tick_seq; g_enabled = enabled;
}
void begin_frame(FrameInterpMode mode, bool is_sim_frame, float step) {
g_enabled = mode != FrameInterpMode::Off;
g_is_sim_frame = is_sim_frame; g_is_sim_frame = is_sim_frame;
g_step = std::clamp(step, 0.0f, 1.0f); g_step = std::clamp(step, 0.0f, 1.0f);
} }
+1 -3
View File
@@ -4,7 +4,6 @@
#include <chrono> #include <chrono>
#include <cmath> #include <cmath>
#include <unordered_map> #include <unordered_map>
#include <dusk/frame_interpolation.h>
namespace dusk::game_clock { namespace dusk::game_clock {
@@ -46,8 +45,7 @@ MainLoopPacer advance_main_loop() {
MainLoopPacer out{}; MainLoopPacer out{};
out.presentation_dt_seconds = presentation_dt; out.presentation_dt_seconds = presentation_dt;
const bool should_interpolate = dusk::getSettings().game.enableFrameInterpolation.getValue() != const bool should_interpolate = dusk::getSettings().game.enableFrameInterpolation &&
dusk::FrameInterpMode::Off &&
!dusk::getTransientSettings().skipFrameRateLimit; !dusk::getTransientSettings().skipFrameRateLimit;
out.is_interpolating = should_interpolate; out.is_interpolating = should_interpolate;
out.sim_pace = sim_pace(); out.sim_pace = sim_pace();
+5 -3
View File
@@ -263,7 +263,7 @@ namespace dusk {
} }
if (getSettings().game.enableResetKeybind && ImGui::GetIO().KeyCtrl && if (getSettings().game.enableResetKeybind && ImGui::GetIO().KeyCtrl &&
ImGui::IsKeyReleased(ImGuiKey_R) && !fpcM_SearchByName(fpcNm_LOGO_SCENE_e)) ImGui::IsKeyPressed(ImGuiKey_R) && !fpcM_SearchByName(fpcNm_LOGO_SCENE_e))
{ {
JUTGamePad::C3ButtonReset::sResetSwitchPushing = true; JUTGamePad::C3ButtonReset::sResetSwitchPushing = true;
} }
@@ -322,8 +322,8 @@ namespace dusk {
} }
ImGui::PushFont(ImGuiEngine::fontLarge); ImGui::PushFont(ImGuiEngine::fontLarge);
ImGuiTextCenter("Failed to initialize any graphics backend."); ImGuiTextCenter("Failed to initialize any graphics backend.");
ImGuiTextCenter("\nDusklight requires Vulkan 1.1+, or Direct X 12.0."); ImGuiTextCenter("\nYour system may be misconfigured, or your hardware may not support the required versions of any of the available backends.");
ImGuiTextCenter("\nTry updating your Operating System and GPU drivers."); ImGuiTextCenter("\nA clean reinstall of Dusklight may help. For further assistance, please visit #tech-support on the Twilit Realm Discord server.");
const auto& style = ImGui::GetStyle(); const auto& style = ImGui::GetStyle();
const auto retrySize = ImGui::CalcTextSize("Retry (Auto backend)"); const auto retrySize = ImGui::CalcTextSize("Retry (Auto backend)");
const auto quitSize = ImGui::CalcTextSize("Quit"); const auto quitSize = ImGui::CalcTextSize("Quit");
@@ -368,7 +368,9 @@ namespace dusk {
m_menuTools.ShowProcessManager(); m_menuTools.ShowProcessManager();
m_menuTools.ShowHeapOverlay(); m_menuTools.ShowHeapOverlay();
m_menuTools.ShowStubLog(); m_menuTools.ShowStubLog();
m_menuTools.ShowMapLoader();
m_menuTools.ShowBloomWindow(); m_menuTools.ShowBloomWindow();
m_menuTools.ShowEnhancedLightingWindow();
m_menuTools.ShowPlayerInfo(); m_menuTools.ShowPlayerInfo();
m_menuTools.ShowAudioDebug(); m_menuTools.ShowAudioDebug();
m_menuTools.ShowSaveEditor(); m_menuTools.ShowSaveEditor();
@@ -0,0 +1,103 @@
#include "imgui.h"
#include "ImGuiEnhancedLightingWindow.hpp"
#include "ImGuiMenuTools.hpp"
#include "dusk/config.hpp"
#include "dusk/settings.h"
#include <aurora/gfx.h>
namespace dusk {
static void ApplyFromSettings() {
const auto& g = getSettings().game;
aurora_set_enhanced_lighting_state({
g.enhancedLighting.getValue(),
g.enableSpecularLighting.getValue(),
g.enableRimLighting.getValue(),
g.specularIntensity.getValue(),
g.rimIntensity.getValue(),
g.ambientLightMultiplier.getValue(),
g.diffuseLightMultiplier.getValue(),
});
}
void DrawEnhancedLightingWindow(bool& open) {
if (!open) {
return;
}
if (!ImGui::Begin("Enhanced Lighting", &open)) {
ImGui::End();
return;
}
auto& g = getSettings().game;
bool changed = false;
bool enabled = g.enhancedLighting.getValue();
if (ImGui::Checkbox("Enhanced Lighting", &enabled)) {
g.enhancedLighting.setValue(enabled);
changed = true;
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Enables per-pixel lighting with Blinn-Phong shading.");
}
if (!enabled) {
ImGui::BeginDisabled();
}
bool enableSpecular = g.enableSpecularLighting.getValue();
if (ImGui::Checkbox("Specular Highlights", &enableSpecular)) {
g.enableSpecularLighting.setValue(enableSpecular);
changed = true;
}
bool enableRim = g.enableRimLighting.getValue();
if (ImGui::Checkbox("Rim Lighting", &enableRim)) {
g.enableRimLighting.setValue(enableRim);
changed = true;
}
float specularIntensity = g.specularIntensity.getValue();
if (ImGui::SliderFloat("Specular Intensity", &specularIntensity, 0.0f, 1.0f, "%.2f")) {
g.specularIntensity.setValue(specularIntensity);
changed = true;
}
float rimIntensity = g.rimIntensity.getValue();
if (ImGui::SliderFloat("Rim Intensity", &rimIntensity, 0.0f, 0.5f, "%.3f")) {
g.rimIntensity.setValue(rimIntensity);
changed = true;
}
float ambientMultiplier = g.ambientLightMultiplier.getValue();
if (ImGui::SliderFloat("Ambient Multiplier", &ambientMultiplier, 0.0f, 3.0f, "%.2f")) {
g.ambientLightMultiplier.setValue(ambientMultiplier);
changed = true;
}
float diffuseMultiplier = g.diffuseLightMultiplier.getValue();
if (ImGui::SliderFloat("Diffuse Multiplier", &diffuseMultiplier, 0.0f, 3.0f, "%.2f")) {
g.diffuseLightMultiplier.setValue(diffuseMultiplier);
changed = true;
}
if (!enabled) {
ImGui::EndDisabled();
}
if (changed) {
ApplyFromSettings();
config::Save();
}
ImGui::End();
}
void ImGuiMenuTools::ShowEnhancedLightingWindow() {
DrawEnhancedLightingWindow(m_showEnhancedLightingWindow);
}
} // namespace dusk
@@ -0,0 +1,5 @@
#pragma once
namespace dusk {
void DrawEnhancedLightingWindow(bool& open);
} // namespace dusk
+149
View File
@@ -0,0 +1,149 @@
#include "d/d_com_inf_game.h"
#include "imgui.h"
#include <imgui_internal.h>
#include "ImGuiConsole.hpp"
#include "ImGuiMenuTools.hpp"
#include "dusk/map_loader_definitions.h"
#include "fmt/format.h"
namespace dusk {
void ImGuiMenuTools::ShowMapLoader() {
if (!getSettings().backend.enableAdvancedSettings ||
!ImGuiConsole::CheckMenuViewToggle(ImGuiKey_F7, m_showMapLoader))
{
return;
}
ImGuiWindowFlags windowFlags = ImGuiWindowFlags_AlwaysAutoResize |
ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav;
// ImGui::SetNextWindowBgAlpha(0.65f);
if (!ImGui::Begin("Map Loader", &m_showMapLoader, windowFlags)) {
ImGui::End();
return;
}
ImGui::Checkbox("Show Internal Names", &m_mapLoaderInfo.showInternalNames);
const char* previewRegion = "None";
if (m_mapLoaderInfo.regionIdx != -1) {
previewRegion = gameRegions[m_mapLoaderInfo.regionIdx].regionName;
}
if (ImGui::BeginCombo("Select Region", previewRegion)) {
int idx = 0;
for (const auto& region : gameRegions) {
if (ImGui::Selectable(region.regionName)) {
if (m_mapLoaderInfo.regionIdx != idx) {
m_mapLoaderInfo.mapIdx = 0;
m_mapLoaderInfo.roomNoIdx = 0;
m_mapLoaderInfo.pointNoIdx = 0;
}
m_mapLoaderInfo.regionIdx = idx;
}
idx++;
}
ImGui::EndCombo();
}
if (m_mapLoaderInfo.regionIdx != -1) {
const auto& region = gameRegions[m_mapLoaderInfo.regionIdx];
std::string previewMap = "None";
if (m_mapLoaderInfo.mapIdx != -1) {
const auto& map = region.maps[m_mapLoaderInfo.mapIdx];
previewMap = m_mapLoaderInfo.showInternalNames ? fmt::format("{} ({})", map.mapName, map.mapFile) : map.mapName;
}
if (ImGui::BeginCombo("Select Map", previewMap.data())) {
int prevMapIdx = m_mapLoaderInfo.mapIdx;
for (int i = 0; i < region.maps.size(); ++i) {
const auto& map = region.maps[i];
std::string label = m_mapLoaderInfo.showInternalNames ? fmt::format("{} ({})", map.mapName, map.mapFile) : map.mapName;
if (ImGui::Selectable(label.data())) {
m_mapLoaderInfo.mapIdx = i;
}
}
ImGui::EndCombo();
if (m_mapLoaderInfo.mapIdx != prevMapIdx) {
m_mapLoaderInfo.roomNoIdx = 0;
m_mapLoaderInfo.pointNoIdx = 0;
}
}
} else {
ImGui::Text("No region selected.");
}
if (m_mapLoaderInfo.regionIdx != -1 && m_mapLoaderInfo.mapIdx != -1) {
const auto& region = gameRegions[m_mapLoaderInfo.regionIdx];
const auto& map = region.maps[m_mapLoaderInfo.mapIdx];
const auto& room = map.mapRooms[m_mapLoaderInfo.roomNoIdx];
if (map.mapRooms.size() > 1) {
ImGui::Text("Selected Room: %2d", room.roomNo);
ImGui::SameLine();
if (ImGui::Button("-###RoomNoIdxDec")) {
m_mapLoaderInfo.roomNoIdx--;
if (m_mapLoaderInfo.roomNoIdx < 0) {
m_mapLoaderInfo.roomNoIdx = map.mapRooms.size() - 1;
}
m_mapLoaderInfo.pointNoIdx = 0;
}
ImGui::SameLine();
if (ImGui::Button("+###RoomNoIdxInc")) {
m_mapLoaderInfo.roomNoIdx++;
if (m_mapLoaderInfo.roomNoIdx >= map.mapRooms.size()) {
m_mapLoaderInfo.roomNoIdx = 0;
}
m_mapLoaderInfo.pointNoIdx = 0;
}
}
constexpr int MAX_LAYER = 14;
ImGui::Text("Selected Layer: %3d", m_mapLoaderInfo.layer);
ImGui::SameLine();
if (ImGui::Button("-###layerDec")) {
m_mapLoaderInfo.layer--;
if (m_mapLoaderInfo.layer < -1) {
m_mapLoaderInfo.layer = MAX_LAYER;
}
}
ImGui::SameLine();
if (ImGui::Button("+###layerInc")) {
m_mapLoaderInfo.layer++;
if (m_mapLoaderInfo.layer > MAX_LAYER) {
m_mapLoaderInfo.layer = -1;
}
}
if (room.roomPoints.size() > 1) {
ImGui::Text("Selected Point: %3d", room.roomPoints[m_mapLoaderInfo.pointNoIdx]);
ImGui::SameLine();
if (ImGui::Button("-###PointNoIdxDec")) {
m_mapLoaderInfo.pointNoIdx--;
if (m_mapLoaderInfo.pointNoIdx < 0) {
m_mapLoaderInfo.pointNoIdx = room.roomPoints.size() - 1;
}
}
ImGui::SameLine();
if (ImGui::Button("+###PointNoIdxInc")) {
m_mapLoaderInfo.pointNoIdx++;
if (m_mapLoaderInfo.pointNoIdx >= room.roomPoints.size()) {
m_mapLoaderInfo.pointNoIdx = 0;
}
}
}
if (ImGui::Button("Warp")) {
dComIfGp_setNextStage(map.mapFile, room.roomPoints[m_mapLoaderInfo.pointNoIdx], room.roomNo, m_mapLoaderInfo.layer);
}
}
ImGui::End();
}
} // namespace dusk
+5 -1
View File
@@ -1,11 +1,13 @@
#include "fmt/format.h" #include "fmt/format.h"
#include "imgui.h" #include "imgui.h"
#include "aurora/gfx.h" #include <aurora/gfx.h>
#include "ImGuiConfig.hpp" #include "ImGuiConfig.hpp"
#include "dusk/hotkeys.h" #include "dusk/hotkeys.h"
#include "dusk/settings.h" #include "dusk/settings.h"
#include "ImGuiBloomWindow.hpp"
#include "ImGuiConsole.hpp" #include "ImGuiConsole.hpp"
#include "ImGuiEnhancedLightingWindow.hpp"
#include "ImGuiMenuTools.hpp" #include "ImGuiMenuTools.hpp"
#include "ImGuiEngine.hpp" #include "ImGuiEngine.hpp"
@@ -40,6 +42,7 @@ namespace dusk {
ImGui::BeginDisabled(getSettings().game.speedrunMode); ImGui::BeginDisabled(getSettings().game.speedrunMode);
ImGui::MenuItem("Save Editor", hotkeys::SHOW_SAVE_EDITOR, &m_showSaveEditor); ImGui::MenuItem("Save Editor", hotkeys::SHOW_SAVE_EDITOR, &m_showSaveEditor);
ImGui::MenuItem("Map Loader", hotkeys::SHOW_MAP_LOADER, &m_showMapLoader);
ImGui::MenuItem("State Share", hotkeys::SHOW_STATE_SHARE, &m_showStateShare); ImGui::MenuItem("State Share", hotkeys::SHOW_STATE_SHARE, &m_showStateShare);
ImGui::EndDisabled(); ImGui::EndDisabled();
@@ -103,6 +106,7 @@ namespace dusk {
ImGui::MenuItem("Debug Camera", hotkeys::SHOW_DEBUG_CAMERA, &m_showCameraOverlay); ImGui::MenuItem("Debug Camera", hotkeys::SHOW_DEBUG_CAMERA, &m_showCameraOverlay);
ImGui::MenuItem("Audio Debug", hotkeys::SHOW_AUDIO_DEBUG, &m_showAudioDebug); ImGui::MenuItem("Audio Debug", hotkeys::SHOW_AUDIO_DEBUG, &m_showAudioDebug);
ImGui::MenuItem("Bloom", nullptr, &m_showBloomWindow); ImGui::MenuItem("Bloom", nullptr, &m_showBloomWindow);
ImGui::MenuItem("Enhanced Lighting", nullptr, &m_showEnhancedLightingWindow);
ImGui::MenuItem("Stub Log", nullptr, &m_showStubLog); ImGui::MenuItem("Stub Log", nullptr, &m_showStubLog);
ImGui::MenuItem("Actor Spawner", nullptr, &m_showActorSpawner); ImGui::MenuItem("Actor Spawner", nullptr, &m_showActorSpawner);
+16
View File
@@ -21,7 +21,9 @@ namespace dusk {
void ShowProcessManager(); void ShowProcessManager();
void ShowHeapOverlay(); void ShowHeapOverlay();
void ShowStubLog(); void ShowStubLog();
void ShowMapLoader();
void ShowBloomWindow(); void ShowBloomWindow();
void ShowEnhancedLightingWindow();
void ShowPlayerInfo(); void ShowPlayerInfo();
void ShowAudioDebug(); void ShowAudioDebug();
void ShowSaveEditor(); void ShowSaveEditor();
@@ -42,9 +44,23 @@ namespace dusk {
bool m_showStubLog = false; bool m_showStubLog = false;
bool m_showMapLoader = false;
bool m_showBloomWindow = false; bool m_showBloomWindow = false;
bool m_showEnhancedLightingWindow = false;
bool m_showAudioDebug = false; bool m_showAudioDebug = false;
struct {
int mapIdx = -1;
int regionIdx = -1;
int roomNoIdx = 0;
int pointNoIdx = 0;
int roomNo = -1;
int pointNo = -1;
int spawnId = 0;
int layer = -1;
bool showInternalNames = false;
} m_mapLoaderInfo;
bool m_showPlayerInfo = false; bool m_showPlayerInfo = false;
int m_playerInfoOverlayCorner = 1; // top-right int m_playerInfoOverlayCorner = 1; // top-right
+1 -1
View File
@@ -713,7 +713,7 @@ namespace dusk {
transformLevel++; transformLevel++;
} }
} }
if (ImGui::SliderInt("Transform Level", &transformLevel, 0, 4)) { if (ImGui::SliderInt("Transform Level", &transformLevel, 0, 3)) {
u8 newFlags = 0; u8 newFlags = 0;
for (int i = 0; i < transformLevel; i++) { for (int i = 0; i < transformLevel; i++) {
newFlags |= (1 << i); newFlags |= (1 << i);
+20 -12
View File
@@ -10,11 +10,10 @@ UserSettings g_userSettings = {
.lockAspectRatio {"video.lockAspectRatio", false}, .lockAspectRatio {"video.lockAspectRatio", false},
.enableFpsOverlay {"game.enableFpsOverlay", false}, .enableFpsOverlay {"game.enableFpsOverlay", false},
.fpsOverlayCorner {"game.fpsOverlayCorner", 0}, .fpsOverlayCorner {"game.fpsOverlayCorner", 0},
.maxFrameRate {"video.maxFrameRate", 240},
}, },
.audio = { .audio = {
.masterVolume {"audio.masterVolume", 60}, .masterVolume {"audio.masterVolume", 80},
.mainMusicVolume {"audio.mainMusicVolume", 100}, .mainMusicVolume {"audio.mainMusicVolume", 100},
.subMusicVolume {"audio.subMusicVolume", 100}, .subMusicVolume {"audio.subMusicVolume", 100},
.soundEffectsVolume {"audio.soundEffectsVolume", 100}, .soundEffectsVolume {"audio.soundEffectsVolume", 100},
@@ -56,14 +55,19 @@ UserSettings g_userSettings = {
.enableDiscordPresence {"game.enableDiscordPresence", true}, .enableDiscordPresence {"game.enableDiscordPresence", true},
// Graphics // Graphics
.enhancedLighting {"game.enhancedLighting", false},
.enableSpecularLighting {"game.enableSpecularLighting", true},
.enableRimLighting {"game.enableRimLighting", true},
.specularIntensity {"game.specularIntensity", 0.2f},
.rimIntensity {"game.rimIntensity", 0.08f},
.ambientLightMultiplier {"game.ambientLightMultiplier", 1.0f},
.diffuseLightMultiplier {"game.diffuseLightMultiplier", 1.0f},
.bloomMode {"game.bloomMode", BloomMode::Dusk}, .bloomMode {"game.bloomMode", BloomMode::Dusk},
.bloomMultiplier {"game.bloomMultiplier", 1.0f}, .bloomMultiplier {"game.bloomMultiplier", 1.0f},
.disableWaterRefraction {"game.disableWaterRefraction", false}, .disableWaterRefraction {"game.disableWaterRefraction", false},
.enableTextureReplacements {"game.enableTextureReplacements", true}, .enableFrameInterpolation {"game.enableFrameInterpolation", false},
.enableFrameInterpolation {"game.enableFrameInterpolation", FrameInterpMode::Off},
.internalResolutionScale {"game.internalResolutionScale", 0}, .internalResolutionScale {"game.internalResolutionScale", 0},
.shadowResolutionMultiplier {"game.shadowResolutionMultiplier", 1}, .shadowResolutionMultiplier {"game.shadowResolutionMultiplier", 1},
.resampler {"game.resampler", Resampler::Bilinear},
.enableDepthOfField {"game.enableDepthOfField", true}, .enableDepthOfField {"game.enableDepthOfField", true},
.enableMapBackground {"game.enableMapBackground", true}, .enableMapBackground {"game.enableMapBackground", true},
.disableCutscenePillarboxing {"game.disableCutscenePillarboxing", false}, .disableCutscenePillarboxing {"game.disableCutscenePillarboxing", false},
@@ -96,7 +100,6 @@ UserSettings g_userSettings = {
// Cheats // Cheats
.infiniteHearts {"game.infiniteHearts", false}, .infiniteHearts {"game.infiniteHearts", false},
.infiniteArrows {"game.infiniteArrows", false}, .infiniteArrows {"game.infiniteArrows", false},
.infiniteSeeds {"game.infiniteSeeds", false},
.infiniteBombs {"game.infiniteBombs", false}, .infiniteBombs {"game.infiniteBombs", false},
.infiniteOil {"game.infiniteOil", false}, .infiniteOil {"game.infiniteOil", false},
.infiniteOxygen {"game.infiniteOxygen", false}, .infiniteOxygen {"game.infiniteOxygen", false},
@@ -110,7 +113,6 @@ UserSettings g_userSettings = {
.fastRoll {"game.fastRoll", false}, .fastRoll {"game.fastRoll", false},
.fastSpinner {"game.fastSpinner", false}, .fastSpinner {"game.fastSpinner", false},
.freeMagicArmor {"game.freeMagicArmor", false}, .freeMagicArmor {"game.freeMagicArmor", false},
.invincibleEnemies {"game.invincibleEnemies", false},
// Technical // Technical
.restoreWiiGlitches {"game.restoreWiiGlitches", false}, .restoreWiiGlitches {"game.restoreWiiGlitches", false},
@@ -180,7 +182,6 @@ void registerSettings() {
Register(g_userSettings.video.lockAspectRatio); Register(g_userSettings.video.lockAspectRatio);
Register(g_userSettings.video.enableFpsOverlay); Register(g_userSettings.video.enableFpsOverlay);
Register(g_userSettings.video.fpsOverlayCorner); Register(g_userSettings.video.fpsOverlayCorner);
Register(g_userSettings.video.maxFrameRate);
// Audio // Audio
Register(g_userSettings.audio.masterVolume); Register(g_userSettings.audio.masterVolume);
@@ -219,12 +220,21 @@ void registerSettings() {
Register(g_userSettings.game.minimalHUD); Register(g_userSettings.game.minimalHUD);
Register(g_userSettings.game.pauseOnFocusLost); Register(g_userSettings.game.pauseOnFocusLost);
Register(g_userSettings.game.enableDiscordPresence); Register(g_userSettings.game.enableDiscordPresence);
// Enhanced lighting
Register(g_userSettings.game.enhancedLighting);
Register(g_userSettings.game.enableSpecularLighting);
Register(g_userSettings.game.enableRimLighting);
Register(g_userSettings.game.specularIntensity);
Register(g_userSettings.game.rimIntensity);
Register(g_userSettings.game.ambientLightMultiplier);
Register(g_userSettings.game.diffuseLightMultiplier);
Register(g_userSettings.game.bloomMode); Register(g_userSettings.game.bloomMode);
Register(g_userSettings.game.bloomMultiplier); Register(g_userSettings.game.bloomMultiplier);
Register(g_userSettings.game.disableWaterRefraction); Register(g_userSettings.game.disableWaterRefraction);
Register(g_userSettings.game.enableTextureReplacements);
Register(g_userSettings.game.internalResolutionScale); Register(g_userSettings.game.internalResolutionScale);
Register(g_userSettings.game.resampler);
Register(g_userSettings.game.shadowResolutionMultiplier); Register(g_userSettings.game.shadowResolutionMultiplier);
Register(g_userSettings.game.enableDepthOfField); Register(g_userSettings.game.enableDepthOfField);
Register(g_userSettings.game.enableMapBackground); Register(g_userSettings.game.enableMapBackground);
@@ -251,7 +261,6 @@ void registerSettings() {
Register(g_userSettings.game.fastSpinner); Register(g_userSettings.game.fastSpinner);
Register(g_userSettings.game.infiniteHearts); Register(g_userSettings.game.infiniteHearts);
Register(g_userSettings.game.infiniteArrows); Register(g_userSettings.game.infiniteArrows);
Register(g_userSettings.game.infiniteSeeds);
Register(g_userSettings.game.infiniteBombs); Register(g_userSettings.game.infiniteBombs);
Register(g_userSettings.game.infiniteOil); Register(g_userSettings.game.infiniteOil);
Register(g_userSettings.game.infiniteOxygen); Register(g_userSettings.game.infiniteOxygen);
@@ -260,7 +269,6 @@ void registerSettings() {
Register(g_userSettings.game.moonJump); Register(g_userSettings.game.moonJump);
Register(g_userSettings.game.superClawshot); Register(g_userSettings.game.superClawshot);
Register(g_userSettings.game.alwaysGreatspin); Register(g_userSettings.game.alwaysGreatspin);
Register(g_userSettings.game.invincibleEnemies);
Register(g_userSettings.game.enableFrameInterpolation); Register(g_userSettings.game.enableFrameInterpolation);
Register(g_userSettings.game.gyroMode); Register(g_userSettings.game.gyroMode);
Register(g_userSettings.game.enableGyroAim); Register(g_userSettings.game.enableGyroAim);
-1
View File
@@ -20,7 +20,6 @@ void resetForSpeedrunMode() {
getSettings().game.infiniteHearts.setSpeedrunValue(false); getSettings().game.infiniteHearts.setSpeedrunValue(false);
getSettings().game.infiniteArrows.setSpeedrunValue(false); getSettings().game.infiniteArrows.setSpeedrunValue(false);
getSettings().game.infiniteSeeds.setSpeedrunValue(false);
getSettings().game.infiniteBombs.setSpeedrunValue(false); getSettings().game.infiniteBombs.setSpeedrunValue(false);
getSettings().game.infiniteOil.setSpeedrunValue(false); getSettings().game.infiniteOil.setSpeedrunValue(false);
getSettings().game.infiniteOxygen.setSpeedrunValue(false); getSettings().game.infiniteOxygen.setSpeedrunValue(false);
+48 -83
View File
@@ -37,7 +37,7 @@ Rml::String current_controller_name(int port) {
Rml::String controller_index_name(u32 index) { Rml::String controller_index_name(u32 index) {
const char* name = PADGetNameForControllerIndex(index); const char* name = PADGetNameForControllerIndex(index);
if (name == nullptr) { if (name == nullptr) {
return fmt::format("Device {}", index + 1); return fmt::format("Controller {}", index + 1);
} }
return name; return name;
} }
@@ -124,7 +124,7 @@ Rml::String native_axis_name(const PADAxisMapping& mapping, SDL_Gamepad* gamepad
return native_button_name(gamepad, static_cast<u32>(mapping.nativeButton)); return native_button_name(gamepad, static_cast<u32>(mapping.nativeButton));
} }
return "Not Bound"; return "Not bound";
} }
bool is_dpad_button(PADButton button) { bool is_dpad_button(PADButton button) {
@@ -162,7 +162,7 @@ bool keyboard_escape_pressed() {
Rml::String keyboard_key_name(s32 scancode) { Rml::String keyboard_key_name(s32 scancode) {
if (scancode == PAD_KEY_INVALID) { if (scancode == PAD_KEY_INVALID) {
return "Not Bound"; return "Not bound";
} }
switch (scancode) { switch (scancode) {
case PAD_KEY_MOUSE_LEFT: case PAD_KEY_MOUSE_LEFT:
@@ -303,7 +303,7 @@ void ControllerConfigWindow::build_port_tab(Rml::Element* content, int port) {
}); });
}; };
addPageButton(Page::Controller, "Device", [port] { return current_controller_name(port); }, [] { return false; }); addPageButton(Page::Controller, "Controller", [port] { return current_controller_name(port); }, [] { return false; });
addPageButton(Page::Buttons, "Buttons", [] { return Rml::String(">"); }, [] { return false; }); addPageButton(Page::Buttons, "Buttons", [] { return Rml::String(">"); }, [] { return false; });
addPageButton(Page::Triggers, "Triggers", [] { return Rml::String(">"); }, [] { return false; }); addPageButton(Page::Triggers, "Triggers", [] { return Rml::String(">"); }, [] { return false; });
addPageButton(Page::Sticks, "Sticks", [] { return Rml::String(">"); }, [] { return false; }); addPageButton(Page::Sticks, "Sticks", [] { return Rml::String(">"); }, [] { return false; });
@@ -349,14 +349,7 @@ void ControllerConfigWindow::build_port_tab(Rml::Element* content, int port) {
rightPane, [](Pane& pane) { rightPane, [](Pane& pane) {
pane.add_text("Treat analog trigger movement as digital L and R button input."); pane.add_text("Treat analog trigger movement as digital L and R button input.");
}); });
leftPane.register_control(leftPane.add_button("Restore Default Controls").on_pressed([this, port] {
mDoAud_seStartMenu(kSoundClick);
PADRestoreDefaultMapping(port);
}),
rightPane, [](Pane& pane) {
pane.clear();
pane.add_text("Restores all binding configurations for the currently selected device to their defaults.");
});
render_page(rightPane, port, mPage); render_page(rightPane, port, mPage);
} }
@@ -372,7 +365,7 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
[port] { return PADGetIndexForPort(port) < 0 && !keyboard_active(port); }, [port] { return PADGetIndexForPort(port) < 0 && !keyboard_active(port); },
}) })
.on_pressed([this, port] { .on_pressed([this, port] {
mDoAud_seStartMenu(kSoundClick); mDoAud_seStartMenu(kSoundItemChange);
cancel_pending_binding(); cancel_pending_binding();
PADClearPort(port); PADClearPort(port);
PADSetKeyboardActive(static_cast<u32>(port), FALSE); PADSetKeyboardActive(static_cast<u32>(port), FALSE);
@@ -385,7 +378,7 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
.isSelected = [port] { return keyboard_active(port); }, .isSelected = [port] { return keyboard_active(port); },
}) })
.on_pressed([this, port] { .on_pressed([this, port] {
mDoAud_seStartMenu(kSoundClick); mDoAud_seStartMenu(kSoundItemChange);
cancel_pending_binding(); cancel_pending_binding();
PADClearPort(port); PADClearPort(port);
PADSetKeyboardActive(static_cast<u32>(port), TRUE); PADSetKeyboardActive(static_cast<u32>(port), TRUE);
@@ -395,7 +388,7 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
const u32 controllerCount = PADCount(); const u32 controllerCount = PADCount();
if (controllerCount == 0) { if (controllerCount == 0) {
pane.add_text("No Device Detected"); pane.add_text("No controllers detected");
break; break;
} }
@@ -407,7 +400,7 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
[port, i] { return PADGetIndexForPort(port) == static_cast<s32>(i); }, [port, i] { return PADGetIndexForPort(port) == static_cast<s32>(i); },
}) })
.on_pressed([this, port, i] { .on_pressed([this, port, i] {
mDoAud_seStartMenu(kSoundClick); mDoAud_seStartMenu(kSoundItemChange);
cancel_pending_binding(); cancel_pending_binding();
PADSetKeyboardActive(static_cast<u32>(port), FALSE); PADSetKeyboardActive(static_cast<u32>(port), FALSE);
PADSetPortForIndex(i, port); PADSetPortForIndex(i, port);
@@ -432,18 +425,17 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
PADKeyButtonBinding* bindings = PADKeyButtonBinding* bindings =
PADGetKeyButtonBindings(static_cast<u32>(port), &count); PADGetKeyButtonBindings(static_cast<u32>(port), &count);
if (bindings == nullptr) { if (bindings == nullptr) {
return Rml::String("Not Bound"); return Rml::String("Not bound");
} }
for (u32 i = 0; i < PAD_BUTTON_COUNT; ++i) { for (u32 i = 0; i < PAD_BUTTON_COUNT; ++i) {
if (bindings[i].padButton == button) { if (bindings[i].padButton == button) {
return keyboard_key_name(bindings[i].scancode); return keyboard_key_name(bindings[i].scancode);
} }
} }
return Rml::String("Not Bound"); return Rml::String("Not bound");
}, },
}) })
.on_pressed([this, port, button] { .on_pressed([this, port, button] {
mDoAud_seStartMenu(kSoundClick);
cancel_pending_binding(); cancel_pending_binding();
mPendingPort = port; mPendingPort = port;
mPendingBindingArmed = false; mPendingBindingArmed = false;
@@ -470,7 +462,7 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
u32 buttonCount = 0; u32 buttonCount = 0;
PADButtonMapping* mappings = PADGetButtonMappings(port, &buttonCount); PADButtonMapping* mappings = PADGetButtonMappings(port, &buttonCount);
if (mappings == nullptr) { if (mappings == nullptr) {
pane.add_text("No Device Selected"); pane.add_text("No controller selected");
break; break;
} }
@@ -494,7 +486,6 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
}, },
}) })
.on_pressed([this, port, &mapping] { .on_pressed([this, port, &mapping] {
mDoAud_seStartMenu(kSoundClick);
cancel_pending_binding(); cancel_pending_binding();
mPendingPort = port; mPendingPort = port;
mPendingBindingArmed = false; mPendingBindingArmed = false;
@@ -521,7 +512,6 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
}, },
}) })
.on_pressed([this, port, &mapping] { .on_pressed([this, port, &mapping] {
mDoAud_seStartMenu(kSoundClick);
cancel_pending_binding(); cancel_pending_binding();
mPendingPort = port; mPendingPort = port;
mPendingBindingArmed = false; mPendingBindingArmed = false;
@@ -545,18 +535,17 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
PADKeyButtonBinding* bindings = PADKeyButtonBinding* bindings =
PADGetKeyButtonBindings(static_cast<u32>(port), &count); PADGetKeyButtonBindings(static_cast<u32>(port), &count);
if (bindings == nullptr) { if (bindings == nullptr) {
return Rml::String("Not Bound"); return Rml::String("Not bound");
} }
for (u32 i = 0; i < PAD_BUTTON_COUNT; ++i) { for (u32 i = 0; i < PAD_BUTTON_COUNT; ++i) {
if (bindings[i].padButton == button) { if (bindings[i].padButton == button) {
return keyboard_key_name(bindings[i].scancode); return keyboard_key_name(bindings[i].scancode);
} }
} }
return Rml::String("Not Bound"); return Rml::String("Not bound");
}, },
}) })
.on_pressed([this, port, button] { .on_pressed([this, port, button] {
mDoAud_seStartMenu(kSoundClick);
cancel_pending_binding(); cancel_pending_binding();
mPendingPort = port; mPendingPort = port;
mPendingBindingArmed = false; mPendingBindingArmed = false;
@@ -577,18 +566,17 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
PADKeyAxisBinding* bindings = PADKeyAxisBinding* bindings =
PADGetKeyAxisBindings(static_cast<u32>(port), &count); PADGetKeyAxisBindings(static_cast<u32>(port), &count);
if (bindings == nullptr) { if (bindings == nullptr) {
return Rml::String("Not Bound"); return Rml::String("Not bound");
} }
for (u32 i = 0; i < PAD_AXIS_COUNT; ++i) { for (u32 i = 0; i < PAD_AXIS_COUNT; ++i) {
if (bindings[i].padAxis == axis) { if (bindings[i].padAxis == axis) {
return keyboard_key_name(bindings[i].scancode); return keyboard_key_name(bindings[i].scancode);
} }
} }
return Rml::String("Not Bound"); return Rml::String("Not bound");
}, },
}) })
.on_pressed([this, port, axis] { .on_pressed([this, port, axis] {
mDoAud_seStartMenu(kSoundClick);
cancel_pending_binding(); cancel_pending_binding();
mPendingPort = port; mPendingPort = port;
mPendingBindingArmed = false; mPendingBindingArmed = false;
@@ -611,7 +599,7 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
u32 buttonCount = 0; u32 buttonCount = 0;
PADButtonMapping* buttons = PADGetButtonMappings(port, &buttonCount); PADButtonMapping* buttons = PADGetButtonMappings(port, &buttonCount);
if (axes == nullptr && buttons == nullptr) { if (axes == nullptr && buttons == nullptr) {
pane.add_text("No Device Selected"); pane.add_text("No controller selected");
break; break;
} }
@@ -635,7 +623,6 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
}, },
}) })
.on_pressed([this, port, &mapping] { .on_pressed([this, port, &mapping] {
mDoAud_seStartMenu(kSoundClick);
cancel_pending_binding(); cancel_pending_binding();
mPendingPort = port; mPendingPort = port;
mPendingBindingArmed = false; mPendingBindingArmed = false;
@@ -644,33 +631,30 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
} }
} }
if (getSettings().backend.enableAdvancedSettings) { pane.add_section("Digital");
pane.add_section("Digital"); if (buttons != nullptr) {
if (buttons != nullptr) { for (u32 i = 0; i < buttonCount; ++i) {
for (u32 i = 0; i < buttonCount; ++i) { PADButtonMapping& mapping = buttons[i];
PADButtonMapping& mapping = buttons[i]; if (mapping.padButton != PAD_TRIGGER_L && mapping.padButton != PAD_TRIGGER_R) {
if (mapping.padButton != PAD_TRIGGER_L && mapping.padButton != PAD_TRIGGER_R) { continue;
continue;
}
pane.add_select_button({
.key = PADGetButtonName(mapping.padButton),
.getValue =
[this, &mapping, gamepad] {
if (mPendingButtonMapping == &mapping) {
return pending_button_label();
}
return native_button_name(
gamepad, mapping.nativeButton);
},
})
.on_pressed([this, port, &mapping] {
mDoAud_seStartMenu(kSoundClick);
cancel_pending_binding();
mPendingPort = port;
mPendingBindingArmed = false;
mPendingButtonMapping = &mapping;
});
} }
pane.add_select_button({
.key = PADGetButtonName(mapping.padButton),
.getValue =
[this, &mapping, gamepad] {
if (mPendingButtonMapping == &mapping) {
return pending_button_label();
}
return native_button_name(
gamepad, mapping.nativeButton);
},
})
.on_pressed([this, port, &mapping] {
cancel_pending_binding();
mPendingPort = port;
mPendingBindingArmed = false;
mPendingButtonMapping = &mapping;
});
} }
} }
@@ -722,18 +706,17 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
PADKeyAxisBinding* bindings = PADKeyAxisBinding* bindings =
PADGetKeyAxisBindings(static_cast<u32>(port), &count); PADGetKeyAxisBindings(static_cast<u32>(port), &count);
if (bindings == nullptr) { if (bindings == nullptr) {
return Rml::String("Not Bound"); return Rml::String("Not bound");
} }
for (u32 i = 0; i < PAD_AXIS_COUNT; ++i) { for (u32 i = 0; i < PAD_AXIS_COUNT; ++i) {
if (bindings[i].padAxis == axis) { if (bindings[i].padAxis == axis) {
return keyboard_key_name(bindings[i].scancode); return keyboard_key_name(bindings[i].scancode);
} }
} }
return Rml::String("Not Bound"); return Rml::String("Not bound");
}, },
}) })
.on_pressed([this, port, axis] { .on_pressed([this, port, axis] {
mDoAud_seStartMenu(kSoundClick);
cancel_pending_binding(); cancel_pending_binding();
mPendingPort = port; mPendingPort = port;
mPendingBindingArmed = false; mPendingBindingArmed = false;
@@ -758,7 +741,7 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
u32 axisCount = 0; u32 axisCount = 0;
PADAxisMapping* axes = PADGetAxisMappings(port, &axisCount); PADAxisMapping* axes = PADGetAxisMappings(port, &axisCount);
if (axes == nullptr) { if (axes == nullptr) {
pane.add_text("No Device Selected"); pane.add_text("No controller selected");
break; break;
} }
@@ -779,7 +762,6 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
}, },
}) })
.on_pressed([this, port, &mapping] { .on_pressed([this, port, &mapping] {
mDoAud_seStartMenu(kSoundClick);
cancel_pending_binding(); cancel_pending_binding();
mPendingPort = port; mPendingPort = port;
mPendingBindingArmed = false; mPendingBindingArmed = false;
@@ -925,7 +907,6 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
}, },
}) })
.on_pressed([this, port, actionBind] { .on_pressed([this, port, actionBind] {
mDoAud_seStartMenu(kSoundClick);
cancel_pending_binding(); cancel_pending_binding();
mPendingPort = port; mPendingPort = port;
mPendingBindingArmed = false; mPendingBindingArmed = false;
@@ -945,7 +926,7 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
u32 buttonCount = 0; u32 buttonCount = 0;
PADButtonMapping* mappings = PADGetButtonMappings(port, &buttonCount); PADButtonMapping* mappings = PADGetButtonMappings(port, &buttonCount);
if (mappings == nullptr) { if (mappings == nullptr) {
pane.add_text("No Device Selected"); pane.add_text("No controller selected");
break; break;
} }
@@ -969,7 +950,6 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
}, },
}) })
.on_pressed([this, port, actionBind] { .on_pressed([this, port, actionBind] {
mDoAud_seStartMenu(kSoundClick);
cancel_pending_binding(); cancel_pending_binding();
mPendingPort = port; mPendingPort = port;
mPendingBindingArmed = false; mPendingBindingArmed = false;
@@ -1033,12 +1013,6 @@ void ControllerConfigWindow::poll_pending_binding() {
const s32 nativeButton = PADGetNativeButtonPressed(mPendingPort); const s32 nativeButton = PADGetNativeButtonPressed(mPendingPort);
if (nativeButton != -1) { if (nativeButton != -1) {
const int completedPort = mPendingPort; const int completedPort = mPendingPort;
if (mPendingButtonMapping->nativeButton == static_cast<u32>(nativeButton) &&
(mPendingButtonMapping->padButton != PAD_BUTTON_A &&
mPendingButtonMapping->padButton != PAD_BUTTON_B)) {
unmap_pending_binding();
return;
}
mPendingButtonMapping->nativeButton = static_cast<u32>(nativeButton); mPendingButtonMapping->nativeButton = static_cast<u32>(nativeButton);
finish_pending_binding(completedPort); finish_pending_binding(completedPort);
} }
@@ -1049,10 +1023,6 @@ void ControllerConfigWindow::poll_pending_binding() {
const PADSignedNativeAxis nativeAxis = PADGetNativeAxisPulled(mPendingPort); const PADSignedNativeAxis nativeAxis = PADGetNativeAxisPulled(mPendingPort);
if (nativeAxis.nativeAxis != -1) { if (nativeAxis.nativeAxis != -1) {
const int completedPort = mPendingPort; const int completedPort = mPendingPort;
if (mPendingAxisMapping->nativeAxis.nativeAxis == nativeAxis.nativeAxis) {
unmap_pending_binding();
return;
}
mPendingAxisMapping->nativeAxis = nativeAxis; mPendingAxisMapping->nativeAxis = nativeAxis;
mPendingAxisMapping->nativeButton = -1; mPendingAxisMapping->nativeButton = -1;
finish_pending_binding(completedPort); finish_pending_binding(completedPort);
@@ -1079,10 +1049,6 @@ void ControllerConfigWindow::poll_pending_binding() {
if (button != -1) { if (button != -1) {
const int completedPort = mPendingPort; const int completedPort = mPendingPort;
if (mPendingActionBinding->getValue() == button) {
unmap_pending_binding();
return;
}
mPendingActionBinding->setValue(button); mPendingActionBinding->setValue(button);
config::Save(); config::Save();
finish_pending_binding(completedPort); finish_pending_binding(completedPort);
@@ -1092,7 +1058,6 @@ void ControllerConfigWindow::poll_pending_binding() {
} }
void ControllerConfigWindow::finish_pending_binding(int completedPort) { void ControllerConfigWindow::finish_pending_binding(int completedPort) {
mDoAud_seStartMenu(kSoundBindingChanged);
mPendingButtonMapping = nullptr; mPendingButtonMapping = nullptr;
mPendingAxisMapping = nullptr; mPendingAxisMapping = nullptr;
mPendingActionBinding = nullptr; mPendingActionBinding = nullptr;
@@ -1145,11 +1110,11 @@ bool ControllerConfigWindow::pending_input_neutral() const {
} }
Rml::String ControllerConfigWindow::pending_button_label() const { Rml::String ControllerConfigWindow::pending_button_label() const {
return mPendingBindingArmed ? "Press a Key or Button..." : "Waiting..."; return mPendingBindingArmed ? "Press a button..." : "Waiting...";
} }
Rml::String ControllerConfigWindow::pending_axis_label() const { Rml::String ControllerConfigWindow::pending_axis_label() const {
return mPendingBindingArmed ? "Move Axis or press a Key or Button..." : "Waiting..."; return mPendingBindingArmed ? "Move axis or press a button..." : "Waiting...";
} }
void ControllerConfigWindow::cancel_pending_binding() { void ControllerConfigWindow::cancel_pending_binding() {
@@ -1178,7 +1143,7 @@ void ControllerConfigWindow::finish_pending_key_binding() {
} }
Rml::String ControllerConfigWindow::pending_key_label() const { Rml::String ControllerConfigWindow::pending_key_label() const {
return mPendingBindingArmed ? "Press a Key or Mouse Button..." : "Waiting..."; return mPendingBindingArmed ? "Press a key or mouse button..." : "Waiting...";
} }
void ControllerConfigWindow::stop_rumble_test() { void ControllerConfigWindow::stop_rumble_test() {
@@ -1194,7 +1159,7 @@ void ControllerConfigWindow::stop_rumble_test() {
Rml::String native_button_name(SDL_Gamepad* gamepad, u32 buttonUntyped) { Rml::String native_button_name(SDL_Gamepad* gamepad, u32 buttonUntyped) {
if (buttonUntyped == PAD_NATIVE_BUTTON_INVALID) { if (buttonUntyped == PAD_NATIVE_BUTTON_INVALID) {
return "Not Bound"; return "Not bound";
} }
auto button = static_cast<SDL_GamepadButton>(buttonUntyped); auto button = static_cast<SDL_GamepadButton>(buttonUntyped);
+40 -39
View File
@@ -26,43 +26,6 @@
#include <vector> #include <vector>
namespace dusk::ui { namespace dusk::ui {
Rml::String stage_option_label(const MapEntry& map, bool showInternalNames) {
return showInternalNames ? fmt::format("{} ({})", map.mapName, map.mapFile) : map.mapName;
}
Rml::String stage_label_for_file(const Rml::String& stageFile, bool showInternalNames) {
for (const auto& region : gameRegions) {
for (const auto& map : region.maps) {
if (stageFile == map.mapFile) {
return stage_option_label(map, showInternalNames);
}
}
}
return stageFile;
}
void populate_stage_picker(Pane& pane, std::function<Rml::String()> getStageFile,
std::function<void(const char*)> setStageFile, bool showInternalNames) {
pane.clear();
for (const auto& region : gameRegions) {
pane.add_section(region.regionName);
for (const auto& map : region.maps) {
pane.add_button({
.text = stage_option_label(map, showInternalNames),
.isSelected =
[getStageFile, stageFile = map.mapFile] {
return getStageFile() == stageFile;
},
})
.on_pressed([setStageFile, stageFile = map.mapFile] {
mDoAud_seStartMenu(kSoundItemChange);
setStageFile(stageFile);
});
}
}
}
namespace { namespace {
bool has_save_data() { bool has_save_data() {
@@ -192,6 +155,44 @@ bool parse_vec3(const Rml::String& value, float& x, float& y, float& z) {
return *cursor == '\0'; return *cursor == '\0';
} }
Rml::String stage_option_label(const MapEntry& map) {
// TODO: option to show internal name?
// return fmt::format("{} ({})", map.mapName, map.mapFile);
return map.mapName;
}
Rml::String stage_label_for_file(const Rml::String& stageFile) {
for (const auto& region : gameRegions) {
for (const auto& map : region.maps) {
if (stageFile == map.mapFile) {
return stage_option_label(map);
}
}
}
return stageFile;
}
void populate_stage_picker(Pane& pane, std::function<Rml::String()> getStageFile,
std::function<void(const char*)> setStageFile) {
pane.clear();
for (const auto& region : gameRegions) {
pane.add_section(region.regionName);
for (const auto& map : region.maps) {
pane.add_button({
.text = stage_option_label(map),
.isSelected =
[getStageFile, stageFile = map.mapFile] {
return getStageFile() == stageFile;
},
})
.on_pressed([setStageFile, stageFile = map.mapFile] {
mDoAud_seStartMenu(kSoundItemChange);
setStageFile(stageFile);
});
}
}
}
Rml::String get_player_name() { Rml::String get_player_name() {
if (!has_save_data()) { if (!has_save_data()) {
return ""; return "";
@@ -1501,14 +1502,14 @@ EditorWindow::EditorWindow() {
.getValue = .getValue =
[] { [] {
return std::popcount(static_cast<unsigned>( return std::popcount(static_cast<unsigned>(
get_player_status_b()->mTransformLevelFlag & 0xF)); get_player_status_b()->mTransformLevelFlag & 0x7));
}, },
.setValue = .setValue =
[](int value) { [](int value) {
get_player_status_b()->mTransformLevelFlag = get_player_status_b()->mTransformLevelFlag =
static_cast<u8>((1u << value) - 1u); static_cast<u8>((1u << value) - 1u);
}, },
.max = 4, .max = 3,
}), }),
rightPane, {}); rightPane, {});
leftPane.register_control( leftPane.register_control(
-11
View File
@@ -1,19 +1,8 @@
#pragma once #pragma once
#include "window.hpp" #include "window.hpp"
struct MapEntry;
namespace dusk::ui { namespace dusk::ui {
class Pane;
Rml::String stage_option_label(const MapEntry& map, bool showInternalNames = false);
Rml::String stage_label_for_file(const Rml::String& stageFile, bool showInternalNames = false);
void populate_stage_picker(Pane& pane, std::function<Rml::String()> getStageFile,
std::function<void(const char*)> setStageFile,
bool showInternalNames = false);
class EditorWindow : public Window { class EditorWindow : public Window {
public: public:
EditorWindow(); EditorWindow();
+2 -29
View File
@@ -3,7 +3,6 @@
#include "Z2AudioLib/Z2SeMgr.h" #include "Z2AudioLib/Z2SeMgr.h"
#include "m_Do/m_Do_audio.h" #include "m_Do/m_Do_audio.h"
#include <aurora/aurora.h>
#include <dolphin/gx/GXAurora.h> #include <dolphin/gx/GXAurora.h>
#include <dolphin/vi.h> #include <dolphin/vi.h>
#include <fmt/format.h> #include <fmt/format.h>
@@ -44,8 +43,6 @@ int get_value(GraphicsOption option) {
return getSettings().game.internalResolutionScale.getValue(); return getSettings().game.internalResolutionScale.getValue();
case GraphicsOption::ShadowResolution: case GraphicsOption::ShadowResolution:
return getSettings().game.shadowResolutionMultiplier.getValue(); return getSettings().game.shadowResolutionMultiplier.getValue();
case GraphicsOption::Resampler:
return static_cast<int>(getSettings().game.resampler.getValue());
case GraphicsOption::BloomMode: case GraphicsOption::BloomMode:
return static_cast<int>(getSettings().game.bloomMode.getValue()); return static_cast<int>(getSettings().game.bloomMode.getValue());
case GraphicsOption::BloomMultiplier: case GraphicsOption::BloomMultiplier:
@@ -65,22 +62,6 @@ void set_value(GraphicsOption option, int value) {
case GraphicsOption::ShadowResolution: case GraphicsOption::ShadowResolution:
getSettings().game.shadowResolutionMultiplier.setValue(value); getSettings().game.shadowResolutionMultiplier.setValue(value);
break; break;
case GraphicsOption::Resampler: {
const auto sampler = static_cast<Resampler>(std::clamp(value,
static_cast<int>(Resampler::Bilinear),
static_cast<int>(Resampler::Area)));
getSettings().game.resampler.setValue(sampler);
switch (sampler) {
case Resampler::Area:
aurora_set_resampler(SAMPLER_AREA);
break;
case Resampler::Bilinear:
default:
aurora_set_resampler(SAMPLER_BILINEAR);
break;
}
break;
}
case GraphicsOption::BloomMode: case GraphicsOption::BloomMode:
getSettings().game.bloomMode.setValue(static_cast<BloomMode>(std::clamp( getSettings().game.bloomMode.setValue(static_cast<BloomMode>(std::clamp(
value, static_cast<int>(BloomMode::Off), static_cast<int>(BloomMode::Dusk)))); value, static_cast<int>(BloomMode::Off), static_cast<int>(BloomMode::Dusk))));
@@ -196,14 +177,6 @@ Rml::String format_graphics_setting_value(GraphicsOption option, int value) {
} }
case GraphicsOption::ShadowResolution: case GraphicsOption::ShadowResolution:
return fmt::format("{}×", value); return fmt::format("{}×", value);
case GraphicsOption::Resampler:
switch (static_cast<Resampler>(value)) {
case Resampler::Bilinear:
return "Bilinear";
case Resampler::Area:
return "Area";
}
break;
case GraphicsOption::BloomMode: case GraphicsOption::BloomMode:
switch (static_cast<BloomMode>(value)) { switch (static_cast<BloomMode>(value)) {
case BloomMode::Off: case BloomMode::Off:
@@ -211,7 +184,7 @@ Rml::String format_graphics_setting_value(GraphicsOption option, int value) {
case BloomMode::Classic: case BloomMode::Classic:
return "Classic"; return "Classic";
case BloomMode::Dusk: case BloomMode::Dusk:
return "Dusklight"; return "Dusk";
} }
break; break;
case GraphicsOption::BloomMultiplier: case GraphicsOption::BloomMultiplier:
@@ -238,7 +211,7 @@ GraphicsTuner::GraphicsTuner(GraphicsTunerProps props, bool prelaunch)
SteppedCarousel::Props{ SteppedCarousel::Props{
.min = mValueMin, .min = mValueMin,
.max = mValueMax, .max = mValueMax,
.step = props.step, .step = 1,
.getValue = [this] { return get_value(mOption); }, .getValue = [this] { return get_value(mOption); },
.onChange = [this](int value) { set_value(mOption, value); }, .onChange = [this](int value) { set_value(mOption, value); },
.formatValue = .formatValue =
-2
View File
@@ -42,7 +42,6 @@ private:
enum class GraphicsOption { enum class GraphicsOption {
InternalResolution, InternalResolution,
ShadowResolution, ShadowResolution,
Resampler,
BloomMode, BloomMode,
BloomMultiplier, BloomMultiplier,
}; };
@@ -56,7 +55,6 @@ struct GraphicsTunerProps {
int valueMin = 0; int valueMin = 0;
int valueMax = 0; int valueMax = 0;
int defaultValue = 0; int defaultValue = 0;
int step = 1;
}; };
class GraphicsTuner : public Document { class GraphicsTuner : public Document {
+11 -20
View File
@@ -454,18 +454,10 @@ bool touch_moved_too_far(
return delta.SquaredMagnitude() > threshold * threshold; return delta.SquaredMagnitude() > threshold * threshold;
} }
void emit_key_press(Rml::Context& context, Rml::Input::KeyIdentifier key) noexcept {
context.ProcessMouseLeave();
context.ProcessKeyDown(key, 0);
}
void emit_key_tap(Rml::Context& context, Rml::Input::KeyIdentifier key) noexcept {
emit_key_press(context, key);
context.ProcessKeyUp(key, 0);
}
void dispatch_menu_key(Rml::Context& context) noexcept { void dispatch_menu_key(Rml::Context& context) noexcept {
emit_key_tap(context, Rml::Input::KI_F1); context.ProcessMouseLeave();
context.ProcessKeyDown(Rml::Input::KI_F1, 0);
context.ProcessKeyUp(Rml::Input::KI_F1, 0);
} }
bool handle_touch_menu_tap(Rml::Context& context, const SDL_Event& event) noexcept { bool handle_touch_menu_tap(Rml::Context& context, const SDL_Event& event) noexcept {
@@ -635,9 +627,7 @@ void process_axis_direction(
if (repeat->held) { if (repeat->held) {
if (released) { if (released) {
if (repeat->pending) { if (!repeat->pending) {
emit_key_tap(context, repeat->key);
} else {
context.ProcessKeyUp(repeat->key, 0); context.ProcessKeyUp(repeat->key, 0);
} }
set_pad_button_held(port, heldPadButton, false); set_pad_button_held(port, heldPadButton, false);
@@ -668,7 +658,8 @@ void process_axis_direction(
} }
begin_gamepad_key(*repeat, key); begin_gamepad_key(*repeat, key);
emit_key_press(context, key); context.ProcessMouseLeave();
context.ProcessKeyDown(key, 0);
} }
} // namespace } // namespace
@@ -756,7 +747,8 @@ void handle_event(const SDL_Event& event) noexcept {
} }
} }
if (!deferred) { if (!deferred) {
emit_key_press(*context, key); context->ProcessMouseLeave();
context->ProcessKeyDown(key, 0);
} }
} }
} else { } else {
@@ -768,9 +760,7 @@ void handle_event(const SDL_Event& event) noexcept {
if (repeat != nullptr) { if (repeat != nullptr) {
*repeat = {}; *repeat = {};
} }
if (wasPending) { if (!wasPending) {
emit_key_tap(*context, key);
} else {
context->ProcessKeyUp(key, 0); context->ProcessKeyUp(key, 0);
} }
} }
@@ -797,7 +787,8 @@ void update_input() noexcept {
repeat.pressedAt = now; repeat.pressedAt = now;
repeat.nextRepeatAt = repeat.nextRepeatAt =
repeat.repeatable ? now + kGamepadRepeatInitialDelay : 0.0; repeat.repeatable ? now + kGamepadRepeatInitialDelay : 0.0;
emit_key_press(*context, repeat.key); context->ProcessMouseLeave();
context->ProcessKeyDown(repeat.key, 0);
continue; continue;
} }
+3 -2
View File
@@ -18,7 +18,6 @@
#include "modal.hpp" #include "modal.hpp"
#include "settings.hpp" #include "settings.hpp"
#include "ui.hpp" #include "ui.hpp"
#include "warp.hpp"
#include "window.hpp" #include "window.hpp"
#include <chrono> #include <chrono>
@@ -52,9 +51,11 @@ MenuBar::MenuBar() : Document(kDocumentSource), mRoot(mDocument->GetElementById(
.autoSelect = false, .autoSelect = false,
}); });
mTabBar->add_tab("Settings", [this] { push(std::make_unique<SettingsWindow>()); }); mTabBar->add_tab("Settings", [this] { push(std::make_unique<SettingsWindow>()); });
// mTabBar->add_tab("Warp", [] {
// // TODO
// });
if (getSettings().backend.enableAdvancedSettings) { if (getSettings().backend.enableAdvancedSettings) {
mTabBar->add_tab("Warp", [this] { push(std::make_unique<WarpWindow>()); });
mTabBar->add_tab("Editor", [this] { push(std::make_unique<EditorWindow>()); }); mTabBar->add_tab("Editor", [this] { push(std::make_unique<EditorWindow>()); });
} }
+5 -6
View File
@@ -103,13 +103,13 @@ Rml::Element* create_controller_warning(Rml::Element* parent) {
auto* heading = append(elem, "heading"); auto* heading = append(elem, "heading");
auto* title = append(heading, "span"); auto* title = append(heading, "span");
title->SetInnerRML("No Device Assigned"); title->SetInnerRML("No controller assigned");
auto* icon = append(heading, "icon"); auto* icon = append(heading, "icon");
icon->SetClass("warning", true); icon->SetClass("warning", true);
auto* message = append(elem, "message"); auto* message = append(elem, "message");
auto* content = append(message, "span"); auto* content = append(message, "span");
content->SetInnerRML("Configure <b>Port 1</b> in Settings."); content->SetInnerRML("Configure controller port 1 in Settings.");
return elem; return elem;
} }
@@ -147,7 +147,7 @@ Rml::String back_button_name() {
#if defined(TARGET_ANDROID) || (defined(__APPLE__) && TARGET_OS_IOS && !TARGET_OS_MACCATALYST) #if defined(TARGET_ANDROID) || (defined(__APPLE__) && TARGET_OS_IOS && !TARGET_OS_MACCATALYST)
constexpr auto kMenuNotificationPrefix = "3-finger tap or"; constexpr auto kMenuNotificationPrefix = "3-finger tap or";
#else #else
constexpr auto kMenuNotificationPrefix = "Press <b>F1</b> or"; constexpr auto kMenuNotificationPrefix = "Press F1 or";
#endif #endif
Rml::Element* create_menu_notification(Rml::Element* parent) { Rml::Element* create_menu_notification(Rml::Element* parent) {
@@ -169,7 +169,7 @@ Rml::Element* create_menu_notification(Rml::Element* parent) {
append(row, "span")->SetInnerRML(kMenuNotificationPrefix); append(row, "span")->SetInnerRML(kMenuNotificationPrefix);
auto* icon = append(row, "icon"); auto* icon = append(row, "icon");
icon->SetClass("controller", true); icon->SetClass("controller", true);
append(row, "span")->SetInnerRML("<b>" + escape(padButton) + "</b>"); append(row, "span")->SetInnerRML(escape(padButton));
append(row, "span")->SetInnerRML("to open menu"); append(row, "span")->SetInnerRML("to open menu");
return elem; return elem;
@@ -354,9 +354,8 @@ void Overlay::update() {
} }
} }
u32 count = 0;
const bool showControllerWarning = PADGetIndexForPort(PAD_CHAN0) < 0 && const bool showControllerWarning = PADGetIndexForPort(PAD_CHAN0) < 0 &&
PADGetKeyButtonBindings(PAD_CHAN0, &count) == nullptr && PADGetKeyButtonBindings(PAD_CHAN0, nullptr) == nullptr &&
dynamic_cast<Window*>(top_document()) == nullptr && dynamic_cast<Window*>(top_document()) == nullptr &&
dynamic_cast<WindowSmall*>(top_document()) == nullptr; dynamic_cast<WindowSmall*>(top_document()) == nullptr;
if (showControllerWarning && mControllerWarning == nullptr) { if (showControllerWarning && mControllerWarning == nullptr) {
+2 -2
View File
@@ -40,7 +40,7 @@ void applyPresetDusk() {
s.game.enableQuickTransform.setValue(true); s.game.enableQuickTransform.setValue(true);
s.game.instantSaves.setValue(true); s.game.instantSaves.setValue(true);
s.game.midnasLamentNonStop.setValue(true); s.game.midnasLamentNonStop.setValue(true);
s.game.enableFrameInterpolation.setValue(FrameInterpMode::Unlimited); s.game.enableFrameInterpolation.setValue(true);
s.game.sunsSong.setValue(true); s.game.sunsSong.setValue(true);
s.game.bloomMode.setValue(BloomMode::Dusk); s.game.bloomMode.setValue(BloomMode::Dusk);
s.game.internalResolutionScale.setValue(0); s.game.internalResolutionScale.setValue(0);
@@ -83,7 +83,7 @@ PresetWindow::PresetWindow() : WindowSmall("modal", "modal-dialog") {
"Enhancements disabled to match the GameCube version. " "Enhancements disabled to match the GameCube version. "
"Good for speedrunning or simple nostalgia!", "Good for speedrunning or simple nostalgia!",
applyPresetClassic}, applyPresetClassic},
{"Dusklight", {"Dusk",
"Graphics & quality of life tweaks, including some from the Wii U version. " "Graphics & quality of life tweaks, including some from the Wii U version. "
"Our recommended way to play!", "Our recommended way to play!",
applyPresetDusk}, applyPresetDusk},
+18 -138
View File
@@ -3,7 +3,6 @@
#include "aurora/gfx.h" #include "aurora/gfx.h"
#include "bool_button.hpp" #include "bool_button.hpp"
#include "controller_config.hpp" #include "controller_config.hpp"
#include "dusk/app_info.hpp"
#include "dusk/audio/DuskAudioSystem.h" #include "dusk/audio/DuskAudioSystem.h"
#include "dusk/audio/DuskDsp.hpp" #include "dusk/audio/DuskDsp.hpp"
#include "dusk/config.hpp" #include "dusk/config.hpp"
@@ -18,7 +17,6 @@
#include "graphics_tuner.hpp" #include "graphics_tuner.hpp"
#include "m_Do/m_Do_main.h" #include "m_Do/m_Do_main.h"
#include "menu_bar.hpp" #include "menu_bar.hpp"
#include "modal.hpp"
#include "number_button.hpp" #include "number_button.hpp"
#include "menu_bar.hpp" #include "menu_bar.hpp"
#include "pane.hpp" #include "pane.hpp"
@@ -27,7 +25,6 @@
#include <aurora/lib/window.hpp> #include <aurora/lib/window.hpp>
#include <SDL3/SDL_filesystem.h> #include <SDL3/SDL_filesystem.h>
#include <fmt/format.h>
#if DUSK_ENABLE_SENTRY_NATIVE #if DUSK_ENABLE_SENTRY_NATIVE
#include "dusk/crash_reporting.h" #include "dusk/crash_reporting.h"
@@ -59,12 +56,6 @@ constexpr std::array kFpsOverlayCornerNames = {
"Bottom Right", "Bottom Right",
}; };
constexpr std::array kInterpolationModes = {
"Off",
"Capped",
"Unlimited",
};
constexpr std::array kGyroInputModeLabels = { constexpr std::array kGyroInputModeLabels = {
"Sensor", "Sensor",
"Mouse", "Mouse",
@@ -163,8 +154,8 @@ std::vector<AuroraBackend> available_backends() {
size_t backendCount = 0; size_t backendCount = 0;
const AuroraBackend* raw = aurora_get_available_backends(&backendCount); const AuroraBackend* raw = aurora_get_available_backends(&backendCount);
for (size_t i = 0; i < backendCount; ++i) { for (size_t i = 0; i < backendCount; ++i) {
// Do not expose NULL // Do not expose NULL or D3D11
if (raw[i] != BACKEND_NULL) { if (raw[i] != BACKEND_NULL && raw[i] != BACKEND_D3D11) {
backends.emplace_back(raw[i]); backends.emplace_back(raw[i]);
} }
} }
@@ -193,7 +184,6 @@ void reset_for_speedrun_mode() {
getSettings().game.infiniteHearts.setSpeedrunValue(false); getSettings().game.infiniteHearts.setSpeedrunValue(false);
getSettings().game.infiniteArrows.setSpeedrunValue(false); getSettings().game.infiniteArrows.setSpeedrunValue(false);
getSettings().game.infiniteSeeds.setSpeedrunValue(false);
getSettings().game.infiniteBombs.setSpeedrunValue(false); getSettings().game.infiniteBombs.setSpeedrunValue(false);
getSettings().game.infiniteOil.setSpeedrunValue(false); getSettings().game.infiniteOil.setSpeedrunValue(false);
getSettings().game.infiniteOxygen.setSpeedrunValue(false); getSettings().game.infiniteOxygen.setSpeedrunValue(false);
@@ -207,7 +197,6 @@ void reset_for_speedrun_mode() {
getSettings().game.fastRoll.setSpeedrunValue(false); getSettings().game.fastRoll.setSpeedrunValue(false);
getSettings().game.fastSpinner.setSpeedrunValue(false); getSettings().game.fastSpinner.setSpeedrunValue(false);
getSettings().game.freeMagicArmor.setSpeedrunValue(false); getSettings().game.freeMagicArmor.setSpeedrunValue(false);
getSettings().game.invincibleEnemies.setSpeedrunValue(false);
getSettings().game.pauseOnFocusLost.setSpeedrunValue(false); getSettings().game.pauseOnFocusLost.setSpeedrunValue(false);
aurora_set_pause_on_focus_lost(false); aurora_set_pause_on_focus_lost(false);
@@ -306,49 +295,13 @@ private:
Rml::String mCurrentRml; Rml::String mCurrentRml;
}; };
void show_data_folder_error_modal(std::string_view message) {
auto dismiss = [](Modal& modal) {
mDoAud_seStartMenu(kSoundWindowClose);
modal.pop();
};
push_document(std::make_unique<Modal>(Modal::Props{
.title = "Data Folder Not Changed",
.bodyRml = escape(message),
.actions =
{
ModalAction{
.label = "OK",
.onPressed = dismiss,
},
},
.onDismiss = dismiss,
.icon = "warning",
}));
if (auto* doc = top_document()) {
doc->focus();
}
}
void data_folder_dialog_callback(void*, const char* path, const char* error) { void data_folder_dialog_callback(void*, const char* path, const char* error) {
if (error != nullptr) { if (error != nullptr || path == nullptr) {
show_data_folder_error_modal(error);
return; return;
} }
if (path == nullptr) { if (data::set_custom_data_path(path)) {
return;
}
std::string dataPathError;
if (data::set_custom_data_path(path, &dataPathError)) {
mDoAud_seStartMenu(kSoundItemChange); mDoAud_seStartMenu(kSoundItemChange);
return;
} }
if (dataPathError.empty()) {
dataPathError =
fmt::format("{} could not use the selected folder as its data folder.", AppName);
}
show_data_folder_error_modal(dataPathError);
} }
const Rml::String kInternalResolutionHelpText = const Rml::String kInternalResolutionHelpText =
@@ -357,15 +310,13 @@ const Rml::String kInternalResolutionHelpText =
const Rml::String kShadowResolutionHelpText = const Rml::String kShadowResolutionHelpText =
"Configure the shadow-map resolution. Higher values improve shadow quality but increase GPU " "Configure the shadow-map resolution. Higher values improve shadow quality but increase GPU "
"and memory usage."; "and memory usage.";
const Rml::String kResamplerHelpText =
"Configure the sampling method used when scaling the internal resolution for final presentation.";
const Rml::String kBloomHelpText = const Rml::String kBloomHelpText =
"Configure the post-processing bloom effect. Classic uses the original bloom pass; Dusklight uses " "Configure the post-processing bloom effect. Classic uses the original bloom pass; Dusklight uses "
"a higher-quality bloom pass."; "a higher-quality bloom pass.";
const Rml::String kBloomBrightnessHelpText = const Rml::String kBloomBrightnessHelpText =
"Configure bloom intensity. Higher values make bright areas glow more strongly."; "Configure bloom intensity. Higher values make bright areas glow more strongly.";
const Rml::String kUnlockFramerateHelpText = const Rml::String kUnlockFramerateHelpText =
"<br/>Uses inter-frame interpolation to enable higher frame rates.<br/><br/>May introduce minor " "Uses inter-frame interpolation to enable higher frame rates.<br/><br/>May introduce minor "
"visual artifacts or animation glitches."; "visual artifacts or animation glitches.";
int float_setting_percent(ConfigVar<float>& var) { int float_setting_percent(ConfigVar<float>& var) {
@@ -448,31 +399,6 @@ SelectButton& config_percent_select(Pane& leftPane, Pane& rightPane, ConfigVar<f
return button; return button;
} }
SelectButton& config_int_select(Pane& leftPane, Pane& rightPane, ConfigVar<int>& var,
Rml::String key, Rml::String helpText, int min, int max, int step = 5,
std::function<bool()> isDisabled = {}, std::string suffix = "") {
auto& button = leftPane.add_child<NumberButton>(NumberButton::Props{
.key = std::move(key),
.getValue = [&var] { return var; },
.setValue =
[&var, min, max](int value) {
var.setValue(std::clamp(value, min, max));
config::Save();
},
.isDisabled = std::move(isDisabled),
.isModified = [&var] { return var.getValue() != var.getDefaultValue(); },
.min = min,
.max = max,
.step = step,
.suffix = suffix,
});
leftPane.register_control(button, rightPane, [helpText = std::move(helpText)](Pane& pane) {
pane.clear();
pane.add_text(helpText);
});
return button;
}
template <typename T> template <typename T>
void graphics_tuner_control(Window& window, Pane& leftPane, Pane& rightPane, ConfigVar<T>& var, void graphics_tuner_control(Window& window, Pane& leftPane, Pane& rightPane, ConfigVar<T>& var,
const GraphicsTunerProps& props, bool prelaunch) { const GraphicsTunerProps& props, bool prelaunch) {
@@ -807,15 +733,6 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
.valueMax = 8, .valueMax = 8,
.defaultValue = 1, .defaultValue = 1,
}, mPrelaunch); }, mPrelaunch);
graphics_tuner_control(*this, leftPane, rightPane, getSettings().game.resampler,
GraphicsTunerProps{
.option = GraphicsOption::Resampler,
.title = "Output Resampling",
.helpText = kResamplerHelpText,
.valueMin = static_cast<int>(Resampler::Bilinear),
.valueMax = static_cast<int>(Resampler::Area),
.defaultValue = static_cast<int>(Resampler::Bilinear),
}, mPrelaunch);
leftPane.add_section("Post-Processing"); leftPane.add_section("Post-Processing");
graphics_tuner_control(*this, leftPane, rightPane, getSettings().game.bloomMode, graphics_tuner_control(*this, leftPane, rightPane, getSettings().game.bloomMode,
@@ -835,49 +752,14 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
.valueMin = 0, .valueMin = 0,
.valueMax = 100, .valueMax = 100,
.defaultValue = 100, .defaultValue = 100,
.step = 10,
}, mPrelaunch); }, mPrelaunch);
leftPane.add_section("Rendering"); leftPane.add_section("Rendering");
config_bool_select(leftPane, rightPane, getSettings().game.enableTextureReplacements, config_bool_select(leftPane, rightPane, getSettings().game.enableFrameInterpolation,
{ {
.key = "Use Texture Pack",
.helpText = "Enable installed texture replacements.",
.onChange = [](bool value) { aurora_set_texture_replacements_enabled(value); },
});
leftPane.register_control(
leftPane.add_select_button({
.key = "Unlock Framerate", .key = "Unlock Framerate",
.getValue = .helpText = kUnlockFramerateHelpText,
[] {
return kInterpolationModes[static_cast<u8>(getSettings().game.enableFrameInterpolation.getValue())];
},
.isModified =
[] {
return getSettings().game.enableFrameInterpolation.getValue() !=
getSettings().game.enableFrameInterpolation.getDefaultValue();
},
}),
rightPane, [](Pane& pane) {
for (int i = 0; i < kInterpolationModes.size(); i++) {
pane.add_button({
.text = kInterpolationModes[i],
.isSelected =
[i] {
return getSettings().game.enableFrameInterpolation.getValue() == static_cast<FrameInterpMode>(i);
},
})
.on_pressed([i] {
mDoAud_seStartMenu(kSoundItemChange);
getSettings().game.enableFrameInterpolation.setValue(static_cast<FrameInterpMode>(i));
config::Save();
});
}
pane.add_rml(kUnlockFramerateHelpText);
}); });
config_int_select(leftPane, rightPane, getSettings().video.maxFrameRate,
"Framerate Cap", "Limit the framerate to the specified value.", 30, 540, 1,
[] { return getSettings().game.enableFrameInterpolation.getValue() != FrameInterpMode::Capped; });
config_bool_select(leftPane, rightPane, getSettings().game.enableDepthOfField, config_bool_select(leftPane, rightPane, getSettings().game.enableDepthOfField,
{ {
.key = "Enable Depth of Field", .key = "Enable Depth of Field",
@@ -906,18 +788,18 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
}); });
}; };
leftPane.add_section("Inputs"); leftPane.add_section("Controller");
leftPane.register_control(leftPane.add_button("Configure Inputs").on_pressed([this] { leftPane.register_control(leftPane.add_button("Configure Controller").on_pressed([this] {
push(std::make_unique<ControllerConfigWindow>(mPrelaunch)); push(std::make_unique<ControllerConfigWindow>(mPrelaunch));
}), }),
rightPane, [](Pane& pane) { rightPane, [](Pane& pane) {
pane.clear(); pane.clear();
pane.add_text("Open input binding configuration."); pane.add_text("Open controller binding configuration.");
}); });
config_bool_select(leftPane, rightPane, getSettings().game.allowBackgroundInput, config_bool_select(leftPane, rightPane, getSettings().game.allowBackgroundInput,
{ {
.key = "Allow Background Inputs", .key = "Allow Background Input",
.helpText = "Allow inputs even when the game window is not focused.", .helpText = "Allow controller input even when the game window is not focused.",
.onChange = [](bool value) { aurora_set_background_input(value); }, .onChange = [](bool value) { aurora_set_background_input(value); },
}); });
@@ -1030,7 +912,7 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
[](int value) { [](int value) {
getSettings().audio.masterVolume.setValue(value); getSettings().audio.masterVolume.setValue(value);
config::Save(); config::Save();
audio::SetMasterVolume(audio::MasterVolumeToLinear(value / 100.0f)); audio::SetMasterVolume(value / 100.f);
}, },
.isModified = .isModified =
[] { [] {
@@ -1145,7 +1027,8 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
addOption("Faster Tears of Light", getSettings().game.fastTears, addOption("Faster Tears of Light", getSettings().game.fastTears,
"Tears of Light dropped by Shadow Insects pop out faster like the HD version."); "Tears of Light dropped by Shadow Insects pop out faster like the HD version.");
addSpeedrunDisabledOption("Autosave", getSettings().game.autoSave, addSpeedrunDisabledOption("Autosave", getSettings().game.autoSave,
"Autosaves the game when going to a new area or opening a dungeon door."); "Autosaves the game when going to a new area, opening a dungeon door, "
"or getting a new item.");
addOption("Instant Saves", getSettings().game.instantSaves, addOption("Instant Saves", getSettings().game.instantSaves,
"Skips the delay when writing to the Memory Card."); "Skips the delay when writing to the Memory Card.");
addOption("Hold B for Instant Text", getSettings().game.instantText, addOption("Hold B for Instant Text", getSettings().game.instantText,
@@ -1224,7 +1107,6 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
addCheat("Infinite Hearts", getSettings().game.infiniteHearts, "Keeps your health full."); addCheat("Infinite Hearts", getSettings().game.infiniteHearts, "Keeps your health full.");
addCheat( addCheat(
"Infinite Arrows", getSettings().game.infiniteArrows, "Keeps your arrow count full."); "Infinite Arrows", getSettings().game.infiniteArrows, "Keeps your arrow count full.");
addCheat("Infinite Seeds", getSettings().game.infiniteSeeds, "Keeps your slingshot pellets (seeds) full.");
addCheat("Infinite Bombs", getSettings().game.infiniteBombs, "Keeps all bomb bags full."); addCheat("Infinite Bombs", getSettings().game.infiniteBombs, "Keeps all bomb bags full.");
addCheat("Infinite Oil", getSettings().game.infiniteOil, "Keeps your lantern oil full."); addCheat("Infinite Oil", getSettings().game.infiniteOil, "Keeps your lantern oil full.");
addCheat("Infinite Oxygen", getSettings().game.infiniteOxygen, addCheat("Infinite Oxygen", getSettings().game.infiniteOxygen,
@@ -1242,7 +1124,7 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
addCheat("Always Greatspin", getSettings().game.alwaysGreatspin, addCheat("Always Greatspin", getSettings().game.alwaysGreatspin,
"Allows the Great Spin attack without requiring full health."); "Allows the Great Spin attack without requiring full health.");
addCheat("Fast Iron Boots", getSettings().game.enableFastIronBoots, addCheat("Fast Iron Boots", getSettings().game.enableFastIronBoots,
"Speeds up movement while heavy, including wearing the Iron Boots, holding the Ball and Chain, wearing Magic Armor without rupees, etc."); "Speeds up movement while wearing the Iron Boots.");
addCheat("Can Transform Anywhere", getSettings().game.canTransformAnywhere, addCheat("Can Transform Anywhere", getSettings().game.canTransformAnywhere,
"Allows transforming even if NPCs are looking."); "Allows transforming even if NPCs are looking.");
addCheat("Fast Roll", getSettings().game.fastRoll, addCheat("Fast Roll", getSettings().game.fastRoll,
@@ -1251,8 +1133,6 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
"Speeds up Spinner movement while holding R."); "Speeds up Spinner movement while holding R.");
addCheat("Free Magic Armor", getSettings().game.freeMagicArmor, addCheat("Free Magic Armor", getSettings().game.freeMagicArmor,
"Lets the magic armor work without consuming rupees."); "Lets the magic armor work without consuming rupees.");
addCheat("Invincible Enemies", getSettings().game.invincibleEnemies,
"Prevents enemies from taking damage.");
}); });
add_tab("Interface", [this](Rml::Element* content) { add_tab("Interface", [this](Rml::Element* content) {
@@ -1324,7 +1204,7 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
}); });
pane.add_button( pane.add_button(
{ {
.text = "Missing Device", .text = "Controller",
.isSelected = .isSelected =
[] { return getSettings().game.enableControllerToasts.getValue(); }, [] { return getSettings().game.enableControllerToasts.getValue(); },
}) })
@@ -1377,7 +1257,7 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
config_bool_select(leftPane, rightPane, getSettings().game.enableDiscordPresence, config_bool_select(leftPane, rightPane, getSettings().game.enableDiscordPresence,
{ {
.key = "Enable Discord Rich Presence", .key = "Enable Discord Rich Presence",
.helpText = "Enable Dusklight to integrate with Discord Rich Presence. This allows Discord to show your status in-game.", .helpText = "Enable Dusk to integrate with Discord Rich Presence. This allows Discord to show your status in-game.",
.onChange = [](bool enabled) { .onChange = [](bool enabled) {
if (enabled) { if (enabled) {
dusk::discord::initialize(); dusk::discord::initialize();
+2 -2
View File
@@ -130,7 +130,7 @@ void handle_event(const SDL_Event& event) noexcept {
if (getSettings().game.enableControllerToasts) { if (getSettings().game.enableControllerToasts) {
const char* name = SDL_GetGamepadName(gamepad); const char* name = SDL_GetGamepadName(gamepad);
Rml::String content = fmt::format("<span>{}</span>", name ? name : "[Unknown]"); Rml::String content = fmt::format("<span>{}</span>", name ? name : "[Unknown]");
Rml::String title = "Device Connected"; Rml::String title = "Controller connected";
if (const char* icon = connection_state_icon(SDL_GetGamepadConnectionState(gamepad))) { if (const char* icon = connection_state_icon(SDL_GetGamepadConnectionState(gamepad))) {
title = fmt::format( title = fmt::format(
"<row><span>{}</span> <icon class=\"connection\">&#x{};</icon></row>", title, "<row><span>{}</span> <icon class=\"connection\">&#x{};</icon></row>", title,
@@ -163,7 +163,7 @@ void handle_event(const SDL_Event& event) noexcept {
const char* name = SDL_GetGamepadNameForID(event.gdevice.which); const char* name = SDL_GetGamepadNameForID(event.gdevice.which);
push_toast({ push_toast({
.type = "controller", .type = "controller",
.title = "Device Disconnected", .title = "Controller disconnected",
.content = name ? name : "[Unknown]", .content = name ? name : "[Unknown]",
.duration = std::chrono::seconds(4), .duration = std::chrono::seconds(4),
}); });
-4
View File
@@ -26,8 +26,6 @@ struct Toast {
constexpr u32 kSoundClick = Z2SE_SY_CURSOR_OK; constexpr u32 kSoundClick = Z2SE_SY_CURSOR_OK;
// "Play" button clicked/pressed // "Play" button clicked/pressed
constexpr u32 kSoundPlay = Z2SE_SY_ITEM_COMBINE_ON; constexpr u32 kSoundPlay = Z2SE_SY_ITEM_COMBINE_ON;
// Input binding changed
constexpr u32 kSoundBindingChanged = Z2SE_SY_ITEM_SET_X;
// Menu button pressed (open/close menu bar or hide/show the active window) // Menu button pressed (open/close menu bar or hide/show the active window)
constexpr u32 kSoundMenuOpen = Z2SE_SY_MENU_SUB_IN; constexpr u32 kSoundMenuOpen = Z2SE_SY_MENU_SUB_IN;
@@ -51,8 +49,6 @@ constexpr u32 kSoundItemDisable = Z2SE_SUBJ_VIEW_OUT;
// Achievement unlocked // Achievement unlocked
constexpr u32 kSoundAchievementUnlock = Z2SE_NAVI_FLY; constexpr u32 kSoundAchievementUnlock = Z2SE_NAVI_FLY;
// Warning prompt
constexpr u32 kSoundWarning = Z2SE_SY_COW_GET_IN;
struct Insets { struct Insets {
float top = 0.0f; float top = 0.0f;
-334
View File
@@ -1,334 +0,0 @@
#include "warp.hpp"
#include "editor.hpp"
#include "pane.hpp"
#include "dusk/map_loader_definitions.h"
#include "fmt/format.h"
namespace dusk::ui {
namespace {
constexpr int kMinLayer = -1;
constexpr int kMaxLayer = 14;
struct WarpSelectionState {
int regionIdx = 0;
int mapIdx = 0;
int roomIdx = 0;
int pointIdx = 0;
int layer = -1;
bool showInternalNames = false;
};
WarpSelectionState& selection_state() {
static WarpSelectionState state;
return state;
}
const RegionEntry* selected_region(const WarpSelectionState& state) {
if (state.regionIdx < 0 || state.regionIdx >= static_cast<int>(gameRegions.size())) {
return nullptr;
}
return &gameRegions[state.regionIdx];
}
const MapEntry* selected_map(const WarpSelectionState& state) {
const auto* region = selected_region(state);
if (region == nullptr || state.mapIdx < 0 || state.mapIdx >= static_cast<int>(region->maps.size())) {
return nullptr;
}
return &region->maps[state.mapIdx];
}
const RoomEntry* selected_room(const WarpSelectionState& state) {
const auto* map = selected_map(state);
if (map == nullptr || state.roomIdx < 0 || state.roomIdx >= static_cast<int>(map->mapRooms.size())) {
return nullptr;
}
return &map->mapRooms[state.roomIdx];
}
const s16* selected_point(const WarpSelectionState& state) {
const auto* room = selected_room(state);
if (room == nullptr || state.pointIdx < 0 ||
state.pointIdx >= static_cast<int>(room->roomPoints.size()))
{
return nullptr;
}
return &room->roomPoints[state.pointIdx];
}
void clamp_indices(WarpSelectionState& state) {
if (gameRegions.empty()) {
state.regionIdx = -1;
state.mapIdx = -1;
state.roomIdx = -1;
state.pointIdx = -1;
state.layer = std::clamp(state.layer, kMinLayer, kMaxLayer);
return;
}
state.regionIdx = std::clamp(state.regionIdx, 0, static_cast<int>(gameRegions.size()) - 1);
const auto& region = gameRegions[state.regionIdx];
if (region.maps.empty()) {
state.mapIdx = -1;
state.roomIdx = -1;
state.pointIdx = -1;
state.layer = std::clamp(state.layer, kMinLayer, kMaxLayer);
return;
}
state.mapIdx = std::clamp(state.mapIdx, 0, static_cast<int>(region.maps.size()) - 1);
const auto& map = region.maps[state.mapIdx];
if (map.mapRooms.empty()) {
state.roomIdx = -1;
state.pointIdx = -1;
state.layer = std::clamp(state.layer, kMinLayer, kMaxLayer);
return;
}
state.roomIdx = std::clamp(state.roomIdx, 0, static_cast<int>(map.mapRooms.size()) - 1);
const auto& room = map.mapRooms[state.roomIdx];
if (room.roomPoints.empty()) {
state.pointIdx = -1;
} else {
state.pointIdx = std::clamp(state.pointIdx, 0, static_cast<int>(room.roomPoints.size()) - 1);
}
state.layer = std::clamp(state.layer, kMinLayer, kMaxLayer);
}
bool can_warp(const WarpSelectionState& state) {
return selected_point(state) != nullptr;
}
void reset_selection(WarpSelectionState& state) {
state.roomIdx = 0;
state.pointIdx = 0;
state.layer = kMinLayer;
clamp_indices(state);
}
void populate_map_picker(Pane& pane, WarpSelectionState& state) {
pane.clear();
clamp_indices(state);
if (state.regionIdx < 0 || state.regionIdx >= static_cast<int>(gameRegions.size())) {
return;
}
pane.add_button({
.text = "Show Internal Names",
.isSelected = [&state] { return state.showInternalNames; },
})
.on_pressed([&pane, &state] {
mDoAud_seStartMenu(kSoundItemChange);
state.showInternalNames = !state.showInternalNames;
populate_map_picker(pane, state);
});
pane.add_section("Maps");
const auto& region = gameRegions[state.regionIdx];
for (int i = 0; i < static_cast<int>(region.maps.size()); ++i) {
pane.add_button({
.text = stage_option_label(region.maps[i], state.showInternalNames),
.isSelected = [i, &state] { return state.mapIdx == i; },
})
.on_pressed([i, &state] {
mDoAud_seStartMenu(kSoundItemChange);
if (state.mapIdx != i) {
state.mapIdx = i;
reset_selection(state);
}
});
}
}
} // namespace
WarpWindow::WarpWindow() {
add_tab("Warp", [this](Rml::Element* content) {
auto& leftPane = add_child<Pane>(content, Pane::Type::Controlled);
auto& rightPane = add_child<Pane>(content, Pane::Type::Uncontrolled);
auto& state = selection_state();
clamp_indices(state);
leftPane.add_section("Destination");
leftPane.register_control(
leftPane.add_select_button({
.key = "Region",
.getValue =
[&state] {
clamp_indices(state);
const auto* region = selected_region(state);
return region == nullptr ? Rml::String{"None"} :
Rml::String{region->regionName};
},
}),
rightPane, [&state](Pane& pane) {
pane.clear();
for (int i = 0; i < static_cast<int>(gameRegions.size()); ++i) {
pane.add_button({
.text = gameRegions[i].regionName,
.isSelected = [i, &state] { return state.regionIdx == i; },
})
.on_pressed([i, &state] {
mDoAud_seStartMenu(kSoundItemChange);
if (state.regionIdx != i) {
state.regionIdx = i;
state.mapIdx = 0;
reset_selection(state);
}
});
}
});
leftPane.register_control(
leftPane.add_select_button({
.key = "Map",
.getValue =
[&state] {
clamp_indices(state);
const auto* map = selected_map(state);
return map == nullptr ? Rml::String{"None"} :
stage_option_label(*map, state.showInternalNames);
},
}),
rightPane, [&state](Pane& pane) { populate_map_picker(pane, state); });
leftPane.register_control(
leftPane.add_select_button({
.key = "Room",
.getValue = [&state] {
clamp_indices(state);
const auto* room = selected_room(state);
return room == nullptr ? Rml::String{"None"} :
fmt::format("{}", room->roomNo);
},
.isDisabled = [&state] {
clamp_indices(state);
const auto* map = selected_map(state);
return map == nullptr || map->mapRooms.size() <= 1;
},
}),
rightPane, [&state](Pane& pane) {
pane.clear();
clamp_indices(state);
if (state.regionIdx < 0 || state.regionIdx >= static_cast<int>(gameRegions.size())) {
return;
}
const auto& region = gameRegions[state.regionIdx];
if (state.mapIdx < 0 || state.mapIdx >= static_cast<int>(region.maps.size())) {
return;
}
const auto& map = region.maps[state.mapIdx];
for (int i = 0; i < static_cast<int>(map.mapRooms.size()); ++i) {
pane.add_button({
.text = fmt::format("{}", map.mapRooms[i].roomNo),
.isSelected = [i, &state] { return state.roomIdx == i; },
})
.on_pressed([i, &state] {
mDoAud_seStartMenu(kSoundItemChange);
if (state.roomIdx != i) {
state.roomIdx = i;
state.pointIdx = 0;
clamp_indices(state);
}
});
}
});
leftPane.register_control(
leftPane.add_select_button({
.key = "Point",
.getValue = [&state] {
clamp_indices(state);
const auto* point = selected_point(state);
return point == nullptr ? Rml::String{"None"} : fmt::format("{}", *point);
},
.isDisabled = [&state] {
clamp_indices(state);
const auto* room = selected_room(state);
return room == nullptr || room->roomPoints.size() <= 1;
},
}),
rightPane, [&state](Pane& pane) {
pane.clear();
clamp_indices(state);
if (state.regionIdx < 0 || state.regionIdx >= static_cast<int>(gameRegions.size())) {
return;
}
const auto& region = gameRegions[state.regionIdx];
if (state.mapIdx < 0 || state.mapIdx >= static_cast<int>(region.maps.size())) {
return;
}
const auto& map = region.maps[state.mapIdx];
if (state.roomIdx < 0 || state.roomIdx >= static_cast<int>(map.mapRooms.size())) {
return;
}
const auto& room = map.mapRooms[state.roomIdx];
for (int i = 0; i < static_cast<int>(room.roomPoints.size()); ++i) {
pane.add_button({
.text = fmt::format("{}", room.roomPoints[i]),
.isSelected = [i, &state] { return state.pointIdx == i; },
})
.on_pressed([i, &state] {
if (state.pointIdx != i) {
mDoAud_seStartMenu(kSoundItemChange);
state.pointIdx = i;
clamp_indices(state);
}
});
}
});
leftPane.register_control(
leftPane.add_select_button({
.key = "Layer",
.getValue = [&state] { return fmt::format("{}", state.layer); },
}),
rightPane, [&state](Pane& pane) {
pane.clear();
for (int layer = kMinLayer; layer <= kMaxLayer; ++layer) {
pane.add_button({
.text = fmt::format("{}", layer),
.isSelected = [layer, &state] { return state.layer == layer; },
})
.on_pressed([layer, &state] {
if (state.layer != layer) {
mDoAud_seStartMenu(kSoundItemChange);
state.layer = layer;
}
});
}
});
leftPane.add_section("Action");
leftPane.register_control(
leftPane.add_button({
.text = "Warp",
.isDisabled = [&state] {
clamp_indices(state);
return !can_warp(state);
},
})
.on_pressed([&state] {
clamp_indices(state);
if (!can_warp(state)) {
return;
}
mDoAud_seStartMenu(kSoundClick);
const auto& region = gameRegions[state.regionIdx];
const auto& map = region.maps[state.mapIdx];
const auto& room = map.mapRooms[state.roomIdx];
dComIfGp_setNextStage( map.mapFile, room.roomPoints[state.pointIdx], room.roomNo, state.layer);
}),
rightPane, [](Pane& pane) {
pane.clear();
pane.add_text("Warp to the selected destination.");
});
});
}
} // namespace dusk::ui
-12
View File
@@ -1,12 +0,0 @@
#pragma once
#include "window.hpp"
namespace dusk::ui {
class WarpWindow : public Window {
public:
WarpWindow();
};
} // namespace dusk::ui
+1 -5
View File
@@ -792,10 +792,6 @@ static void duskExecute() {
dComIfGs_setArrowNum(dComIfGs_getArrowMax()); dComIfGs_setArrowNum(dComIfGs_getArrowMax());
} }
if (dusk::getSettings().game.infiniteSeeds) {
dComIfGs_setPachinkoNum(dComIfGs_getPachinkoMax());
}
if (dusk::getSettings().game.infiniteBombs) { if (dusk::getSettings().game.infiniteBombs) {
dComIfGs_setBombNum(0, 99); dComIfGs_setBombNum(0, 99);
dComIfGs_setBombNum(1, 99); dComIfGs_setBombNum(1, 99);
@@ -807,7 +803,7 @@ static void duskExecute() {
} }
if (dusk::getSettings().game.infiniteRupees) { if (dusk::getSettings().game.infiniteRupees) {
dComIfGs_setRupee(dComIfGs_getRupeeMax()); dComIfGs_setRupee(9999);
} }
if (dusk::getSettings().game.infiniteOxygen) { if (dusk::getSettings().game.infiniteOxygen) {
+1 -10
View File
@@ -136,17 +136,8 @@ base_process_class* fpcBs_Create(s16 i_profname, fpc_ProcID i_procID, void* i_ap
u32 size; u32 size;
pprofile = (process_profile_definition*)fpcPf_Get(i_profname); pprofile = (process_profile_definition*)fpcPf_Get(i_profname);
if (pprofile == NULL) {
#if TARGET_PC
DuskLog.debug("fpcBs_Create: profile not found for profname={}", i_profname);
#endif
return NULL;
}
#if TARGET_PC
const char* procName = getProcName(i_profname);
DuskLog.debug("fpcBs_Create: pid={} profname={} ({}) profile={} procSize={} unkSize={}", DuskLog.debug("fpcBs_Create: pid={} profname={} ({}) profile={} procSize={} unkSize={}",
i_procID, procName ? procName : "(unknown)", i_profname, (void*)pprofile, pprofile->process_size, pprofile->unk_size); i_procID, getProcName(i_profname), i_profname, (void*)pprofile, pprofile->process_size, pprofile->unk_size);
#endif
size = pprofile->process_size + pprofile->unk_size; size = pprofile->process_size + pprofile->unk_size;
pprocess = (base_process_class*)cMl::memalignB(-4, size); pprocess = (base_process_class*)cMl::memalignB(-4, size);
+6 -6
View File
@@ -2410,7 +2410,7 @@ void mDoExt_3DlineMat0_c::draw() {
} }
#if TARGET_PC #if TARGET_PC
if (!dusk::frame_interp::is_enabled()) if (!dusk::getSettings().game.enableFrameInterpolation)
#endif #endif
{ {
field_0x16 ^= (u8)1; field_0x16 ^= (u8)1;
@@ -2740,7 +2740,7 @@ void mDoExt_3DlineMat1_c::draw() {
} }
GXSetTexCoordScaleManually(GX_TEXCOORD0, 0, 0, 0); GXSetTexCoordScaleManually(GX_TEXCOORD0, 0, 0, 0);
#if TARGET_PC #if TARGET_PC
if (!dusk::frame_interp::is_enabled()) if (!dusk::getSettings().game.enableFrameInterpolation)
#endif #endif
{ {
mIsDrawn ^= (u8)1; mIsDrawn ^= (u8)1;
@@ -2822,7 +2822,7 @@ void mDoExt_3DlineMat1_c::update(int param_0, f32 param_1, GXColor& param_2, u16
} }
#if TARGET_PC #if TARGET_PC
const cXyz& lineEye = (presentationEye != nullptr && dusk::frame_interp::is_enabled()) ? *presentationEye : sp_3c->lookat.eye; const cXyz& lineEye = (presentationEye != nullptr && dusk::getSettings().game.enableFrameInterpolation) ? *presentationEye : sp_3c->lookat.eye;
sp_13c = *local_r27 - lineEye; sp_13c = *local_r27 - lineEye;
#else #else
sp_13c = *local_r27 - sp_3c->lookat.eye; sp_13c = *local_r27 - sp_3c->lookat.eye;
@@ -2982,7 +2982,7 @@ void mDoExt_3DlineMat1_c::update(int param_0, GXColor& param_2, dKy_tevstr_c* pa
local_r27 = sp_38[0].field_0x0; local_r27 = sp_38[0].field_0x0;
size_p = sp_38->field_0x4; size_p = sp_38->field_0x4;
#if TARGET_PC #if TARGET_PC
if (presentationEye != nullptr && dusk::frame_interp::is_enabled() && size_p == NULL) { if (presentationEye != nullptr && dusk::getSettings().game.enableFrameInterpolation && size_p == NULL) {
sp_38 += 1; sp_38 += 1;
continue; continue;
} }
@@ -3001,7 +3001,7 @@ void mDoExt_3DlineMat1_c::update(int param_0, GXColor& param_2, dKy_tevstr_c* pa
local_f30 = sp_130.abs(); local_f30 = sp_130.abs();
local_f31 += local_f30 * 0.1f; local_f31 += local_f30 * 0.1f;
#if TARGET_PC #if TARGET_PC
const cXyz& lineEye = (presentationEye != nullptr && dusk::frame_interp::is_enabled()) ? *presentationEye : stack_3c->lookat.eye; const cXyz& lineEye = (presentationEye != nullptr && dusk::getSettings().game.enableFrameInterpolation) ? *presentationEye : stack_3c->lookat.eye;
sp_13c = local_r27[0] - lineEye; sp_13c = local_r27[0] - lineEye;
#else #else
sp_13c = local_r27[0] - stack_3c->lookat.eye; sp_13c = local_r27[0] - stack_3c->lookat.eye;
@@ -3077,7 +3077,7 @@ void mDoExt_3DlineMat1_c::update(int param_0, GXColor& param_2, dKy_tevstr_c* pa
#if TARGET_PC #if TARGET_PC
void mDoExt_3DlineMat1_c::refreshGeometryForPresentationEye(const cXyz& eye) { void mDoExt_3DlineMat1_c::refreshGeometryForPresentationEye(const cXyz& eye) {
if (!dusk::frame_interp::is_enabled()) { if (!dusk::getSettings().game.enableFrameInterpolation) {
return; return;
} }
if (mInterpLineKind == 1) { if (mInterpLineKind == 1) {
+3 -3
View File
@@ -2063,7 +2063,7 @@ static void captureScreenPerspDrawInfo(JPADrawInfo& info) {
static void drawItem3D() { static void drawItem3D() {
ZoneScoped; ZoneScoped;
#ifdef TARGET_PC #ifdef TARGET_PC
if (dusk::frame_interp::is_enabled()) { if (dusk::getSettings().game.enableFrameInterpolation) {
// FRAME INTERP NOTE: Title screen needs 0.0f while everything else that runs through this is -100.0f. // FRAME INTERP NOTE: Title screen needs 0.0f while everything else that runs through this is -100.0f.
if (fopAcM_SearchByName(fpcNm_TITLE_e) != nullptr) { if (fopAcM_SearchByName(fpcNm_TITLE_e) != nullptr) {
dMenu_Collect3D_c::setViewPortOffsetY(0.0f); dMenu_Collect3D_c::setViewPortOffsetY(0.0f);
@@ -2241,7 +2241,7 @@ int mDoGph_Painter() {
#endif #endif
dKy_setLight(); dKy_setLight();
#if TARGET_PC #if TARGET_PC
if (dusk::frame_interp::is_enabled()) { if (dusk::getSettings().game.enableFrameInterpolation) {
dKy_setLight_again(); dKy_setLight_again();
} }
#endif #endif
@@ -2296,7 +2296,7 @@ int mDoGph_Painter() {
} }
#if TARGET_PC #if TARGET_PC
if (dusk::frame_interp::is_enabled()) { if (dusk::getSettings().game.enableFrameInterpolation) {
// FRAME INTERP NOTE: Currently only recalculating points for Epona's reins. Need a more global solution. // FRAME INTERP NOTE: Currently only recalculating points for Epona's reins. Need a more global solution.
if (daHorse_c* horse = dComIfGp_getHorseActor()) { if (daHorse_c* horse = dComIfGp_getHorseActor()) {
horse->lerpControlPoints(dusk::frame_interp::get_interpolation_step()); horse->lerpControlPoints(dusk::frame_interp::get_interpolation_step());
+2 -2
View File
@@ -96,8 +96,8 @@ void mDoLib_project(Vec* src, Vec* dst) {
xSize = FB_WIDTH; xSize = FB_WIDTH;
} else { } else {
#if TARGET_PC #if TARGET_PC
xOffset = mDoGph_gInf_c::getMinXF(); xOffset = mDoGph_gInf_c::getSafeMinXF();
xSize = mDoGph_gInf_c::getWidthF(); xSize = viewPort->width * mDoGph_gInf_c::hudAspectScaleUp;
#else #else
xOffset = viewPort->x_orig; xOffset = viewPort->x_orig;
xSize = viewPort->width; xSize = viewPort->width;
+23 -48
View File
@@ -28,7 +28,6 @@
#include "d/d_s_logo.h" #include "d/d_s_logo.h"
#include "d/d_s_menu.h" #include "d/d_s_menu.h"
#include "d/d_s_play.h" #include "d/d_s_play.h"
#include "dusk/time.h"
#include "f_ap/f_ap_game.h" #include "f_ap/f_ap_game.h"
#include "f_op/f_op_msg.h" #include "f_op/f_op_msg.h"
#include "m_Do/m_Do_MemCard.h" #include "m_Do/m_Do_MemCard.h"
@@ -68,6 +67,7 @@
#include <aurora/aurora.h> #include <aurora/aurora.h>
#include <aurora/event.h> #include <aurora/event.h>
#include <aurora/gfx.h>
#include <aurora/main.h> #include <aurora/main.h>
#include <aurora/dvd.h> #include <aurora/dvd.h>
#include <dolphin/dvd.h> #include <dolphin/dvd.h>
@@ -81,7 +81,6 @@
#include "dusk/audio/DuskAudioSystem.h" #include "dusk/audio/DuskAudioSystem.h"
#include "dusk/audio/DuskDsp.hpp" #include "dusk/audio/DuskDsp.hpp"
#include "dusk/config.hpp" #include "dusk/config.hpp"
#include "dusk/speedrun.h"
#include "dusk/settings.h" #include "dusk/settings.h"
#include "dusk/io.hpp" #include "dusk/io.hpp"
#include "dusk/version.hpp" #include "dusk/version.hpp"
@@ -121,7 +120,6 @@ bool dusk::IsShuttingDown = false;
bool dusk::IsGameLaunched = false; bool dusk::IsGameLaunched = false;
bool dusk::RestartRequested = false; bool dusk::RestartRequested = false;
std::filesystem::path dusk::ConfigPath; std::filesystem::path dusk::ConfigPath;
std::filesystem::path dusk::CachePath;
#endif #endif
void dusk::RequestRestart() noexcept { void dusk::RequestRestart() noexcept {
@@ -280,9 +278,8 @@ void main01(void) {
const auto pacing = dusk::game_clock::advance_main_loop(); const auto pacing = dusk::game_clock::advance_main_loop();
if (pacing.is_interpolating) { if (pacing.is_interpolating) {
if (pacing.sim_ticks_to_run > 0) { if (pacing.sim_ticks_to_run > 0) {
dusk::frame_interp::begin_frame(dusk::getSettings().game.enableFrameInterpolation, true, 0.0f); dusk::frame_interp::begin_frame(true, true, 0.0f);
dusk::frame_interp::set_ui_tick_pending(true); dusk::frame_interp::set_ui_tick_pending(true);
for (int sim_tick = 0; sim_tick < pacing.sim_ticks_to_run; ++sim_tick) { for (int sim_tick = 0; sim_tick < pacing.sim_ticks_to_run; ++sim_tick) {
dusk::frame_interp::begin_sim_tick(); dusk::frame_interp::begin_sim_tick();
mDoCPd_c::read(); mDoCPd_c::read();
@@ -293,7 +290,7 @@ void main01(void) {
} }
} }
dusk::frame_interp::begin_frame(dusk::getSettings().game.enableFrameInterpolation, false, dusk::frame_interp::begin_frame(true, false,
dusk::game_clock::sample_interpolation_step()); dusk::game_clock::sample_interpolation_step());
dusk::frame_interp::interpolate(); dusk::frame_interp::interpolate();
dusk::frame_interp::begin_presentation_camera(); dusk::frame_interp::begin_presentation_camera();
@@ -303,7 +300,7 @@ void main01(void) {
dusk::frame_interp::end_presentation_camera(); dusk::frame_interp::end_presentation_camera();
dusk::frame_interp::set_ui_tick_pending(false); dusk::frame_interp::set_ui_tick_pending(false);
} else { } else {
dusk::frame_interp::begin_frame(dusk::FrameInterpMode::Off, true, 0.0f); dusk::frame_interp::begin_frame(false, true, 0.0f);
dusk::frame_interp::set_ui_tick_pending(true); dusk::frame_interp::set_ui_tick_pending(true);
// Game Inputs // Game Inputs
@@ -317,26 +314,8 @@ void main01(void) {
mDoAud_Execute(); mDoAud_Execute();
} }
static Limiter main_loop_limiter;
static double last_fps_setting = 0.0;
static Limiter::duration_t target_ns = 0;
if (dusk::getSettings().game.enableFrameInterpolation.getValue() == dusk::FrameInterpMode::Capped && !dusk::getTransientSettings().skipFrameRateLimit) {
double current_fps = dusk::getSettings().video.maxFrameRate.getValue();
if (current_fps != last_fps_setting) {
last_fps_setting = current_fps;
target_ns = static_cast<Limiter::duration_t>(1'000'000'000.0 / current_fps);
}
Limiter::duration_t sleepTime = main_loop_limiter.Sleep(target_ns);
dusk::frameUsagePct = 100.0f * (1.0f - static_cast<float>(sleepTime) / static_cast<float>(target_ns));
} else {
main_loop_limiter.Reset();
}
aurora_end_frame(); aurora_end_frame();
FrameMark; FrameMark;
#ifdef DUSK_DISCORD #ifdef DUSK_DISCORD
@@ -513,7 +492,7 @@ int game_main(int argc, char* argv[]) {
("h,help", "Print usage") ("h,help", "Print usage")
("console", "Show the Windows console window for logs", cxxopts::value<bool>()->default_value("false")->implicit_value("true")) ("console", "Show the Windows console window for logs", cxxopts::value<bool>()->default_value("false")->implicit_value("true"))
("dvd", "Path to DVD image file", cxxopts::value<std::string>()) ("dvd", "Path to DVD image file", cxxopts::value<std::string>())
("backend", "Graphics API backend to use (auto, d3d12, d3d11, metal, vulkan, null)", cxxopts::value<std::string>()) ("backend", "Graphics API backend to use (auto, d3d12, metal, vulkan, null)", cxxopts::value<std::string>())
("cvar", "Override configuration variables without modifying config", cxxopts::value<std::vector<std::string>>()); ("cvar", "Override configuration variables without modifying config", cxxopts::value<std::vector<std::string>>());
arg_options.parse_positional({"dvd"}); arg_options.parse_positional({"dvd"});
@@ -535,17 +514,12 @@ int game_main(int argc, char* argv[]) {
const auto startupLogLevel = const auto startupLogLevel =
static_cast<AuroraLogLevel>(parsed_arg_options["log-level"].as<uint8_t>()); static_cast<AuroraLogLevel>(parsed_arg_options["log-level"].as<uint8_t>());
const auto dataPaths = dusk::data::initialize_data(); dusk::ConfigPath = dusk::data::initialize_data();
dusk::ConfigPath = dataPaths.userPath; dusk::InitializeFileLogging(dusk::ConfigPath, startupLogLevel);
dusk::CachePath = dataPaths.cachePath;
dusk::InitializeFileLogging(dusk::CachePath, startupLogLevel);
log_build_info(); log_build_info();
dusk::config::LoadFromUserPreferences(); dusk::config::LoadFromUserPreferences();
if (dusk::getSettings().game.speedrunMode) {
dusk::resetForSpeedrunMode();
}
ApplyCVarOverrides(parsed_arg_options["cvar"]); ApplyCVarOverrides(parsed_arg_options["cvar"]);
dusk::crash_reporting::initialize(); dusk::crash_reporting::initialize();
// TODO: How to handle this? // TODO: How to handle this?
@@ -563,12 +537,10 @@ int game_main(int argc, char* argv[]) {
SDL_SetAppMetadata("Dusklight", DUSK_VERSION_STRING, "dev.twilitrealm.dusk"); SDL_SetAppMetadata("Dusklight", DUSK_VERSION_STRING, "dev.twilitrealm.dusk");
{ {
const auto userPathString = dusk::ConfigPath.u8string(); const auto configPathString = dusk::ConfigPath.u8string();
const auto cachePathString = dusk::CachePath.u8string();
AuroraConfig config{}; AuroraConfig config{};
config.appName = dusk::AppName; config.appName = dusk::AppName;
config.userPath = reinterpret_cast<const char*>(userPathString.c_str()); config.configPath = reinterpret_cast<const char*>(configPathString.c_str());
config.cachePath = reinterpret_cast<const char*>(cachePathString.c_str());
config.vsync = dusk::getSettings().video.enableVsync; config.vsync = dusk::getSettings().video.enableVsync;
config.startFullscreen = dusk::getSettings().video.enableFullscreen; config.startFullscreen = dusk::getSettings().video.enableFullscreen;
config.windowPosX = -1; config.windowPosX = -1;
@@ -583,9 +555,21 @@ int game_main(int argc, char* argv[]) {
config.allowJoystickBackgroundEvents = dusk::getSettings().game.allowBackgroundInput; config.allowJoystickBackgroundEvents = dusk::getSettings().game.allowBackgroundInput;
config.pauseOnFocusLost = dusk::getSettings().game.pauseOnFocusLost; config.pauseOnFocusLost = dusk::getSettings().game.pauseOnFocusLost;
config.imGuiInitCallback = &aurora_imgui_init_callback; config.imGuiInitCallback = &aurora_imgui_init_callback;
config.allowTextureReplacements = dusk::getSettings().game.enableTextureReplacements; config.allowTextureReplacements = true;
config.allowTextureDumps = false; config.allowTextureDumps = false;
auroraInfo = aurora_initialize(argc, argv, &config); auroraInfo = aurora_initialize(argc, argv, &config);
{
const auto& g = dusk::getSettings().game;
aurora_set_enhanced_lighting_state({
g.enhancedLighting.getValue(),
g.enableSpecularLighting.getValue(),
g.enableRimLighting.getValue(),
g.specularIntensity.getValue(),
g.rimIntensity.getValue(),
g.ambientLightMultiplier.getValue(),
g.diffuseLightMultiplier.getValue(),
});
}
} }
#ifdef DUSK_DISCORD #ifdef DUSK_DISCORD
@@ -604,17 +588,8 @@ int game_main(int argc, char* argv[]) {
AuroraSetViewportPolicy(AURORA_VIEWPORT_STRETCH); AuroraSetViewportPolicy(AURORA_VIEWPORT_STRETCH);
} }
VISetFrameBufferScale(dusk::getSettings().game.internalResolutionScale.getValue()); VISetFrameBufferScale(dusk::getSettings().game.internalResolutionScale.getValue());
switch (dusk::getSettings().game.resampler.getValue()) {
case dusk::Resampler::Area:
aurora_set_resampler(SAMPLER_AREA);
break;
case dusk::Resampler::Bilinear:
default:
aurora_set_resampler(SAMPLER_BILINEAR);
break;
}
dusk::audio::SetMasterVolume(dusk::audio::MasterVolumeToLinear(dusk::getSettings().audio.masterVolume / 100.0f)); dusk::audio::SetMasterVolume(dusk::getSettings().audio.masterVolume / 100.0f);
dusk::audio::SetEnableReverb(dusk::getSettings().audio.enableReverb); dusk::audio::SetEnableReverb(dusk::getSettings().audio.enableReverb);
dusk::audio::EnableHrtf = dusk::getSettings().audio.enableHrtf; dusk::audio::EnableHrtf = dusk::getSettings().audio.enableHrtf;