mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-07-05 03:29:45 -04:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d204de47bf | |||
| 23dc0cdbf0 | |||
| 24b468f2a2 |
+7
-23
@@ -5,19 +5,8 @@ if (NOT CMAKE_BUILD_TYPE)
|
||||
"Build type options: Debug Release RelWithDebInfo MinSizeRel" FORCE)
|
||||
endif ()
|
||||
|
||||
set(DUSK_VERSION_OVERRIDE "" CACHE STRING "Override version string (skips git detection and format validation)")
|
||||
|
||||
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)
|
||||
# obtain revision info from git
|
||||
find_package(Git)
|
||||
if (GIT_FOUND)
|
||||
# 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
|
||||
@@ -74,8 +63,6 @@ else ()
|
||||
set(DUSK_SHORT_VERSION_STRING "0.0.0")
|
||||
endif ()
|
||||
|
||||
endif ()
|
||||
|
||||
# Add version information to CI environment variables
|
||||
if(DEFINED ENV{GITHUB_ENV})
|
||||
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_MOVIE_SUPPORT "If on, compile against libjpeg-turbo to enable THP file decoding" 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)
|
||||
set(DUSK_SENTRY_DSN "" CACHE STRING "Sentry DSN")
|
||||
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})
|
||||
endif ()
|
||||
set(_jpeg_passthrough_vars
|
||||
ANDROID_ABI
|
||||
ANDROID_PLATFORM
|
||||
CMAKE_BUILD_TYPE
|
||||
CMAKE_C_COMPILER
|
||||
CMAKE_C_COMPILER_LAUNCHER
|
||||
@@ -276,12 +266,6 @@ if (DUSK_ENABLE_SENTRY_NATIVE)
|
||||
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)
|
||||
set(PLATFORM_NAME win32)
|
||||
elseif (CMAKE_SYSTEM_NAME STREQUAL Darwin)
|
||||
|
||||
+25
-10
@@ -249,11 +249,22 @@
|
||||
"type": "BOOL",
|
||||
"value": false
|
||||
},
|
||||
"CMAKE_DISABLE_FIND_PACKAGE_PkgConfig": {
|
||||
"CMAKE_DISABLE_FIND_PACKAGE_BZip2": {
|
||||
"type": "BOOL",
|
||||
"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": {
|
||||
"microsoft.com/VisualStudioSettings/CMake/1.0": {
|
||||
@@ -318,11 +329,7 @@
|
||||
"cacheVariables": {
|
||||
"CMAKE_INSTALL_PREFIX": "${sourceDir}/build/install",
|
||||
"CMAKE_TOOLCHAIN_FILE": "$env{ANDROID_HOME}/ndk/$env{ANDROID_NDK_VERSION}/build/cmake/android.toolchain.cmake",
|
||||
"ANDROID_PLATFORM": "android-28",
|
||||
"BUILD_SHARED_LIBS": {
|
||||
"type": "BOOL",
|
||||
"value": false
|
||||
}
|
||||
"ANDROID_PLATFORM": "android-28"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -409,7 +416,7 @@
|
||||
},
|
||||
"CMAKE_OSX_DEPLOYMENT_TARGET": "11.0",
|
||||
"CMAKE_IGNORE_PREFIX_PATH": "/opt/homebrew",
|
||||
"BUILD_SHARED_LIBS": {
|
||||
"DUSK_MOVIE_SUPPORT": {
|
||||
"type": "BOOL",
|
||||
"value": false
|
||||
}
|
||||
@@ -442,7 +449,11 @@
|
||||
],
|
||||
"cacheVariables": {
|
||||
"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": {
|
||||
"CMAKE_C_COMPILER_LAUNCHER": "sccache",
|
||||
"CMAKE_CXX_COMPILER_LAUNCHER": "sccache"
|
||||
"CMAKE_CXX_COMPILER_LAUNCHER": "sccache",
|
||||
"DUSK_MOVIE_SUPPORT": {
|
||||
"type": "BOOL",
|
||||
"value": false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,40 +1,33 @@
|
||||
# Installing Dusklight on iOS via iloader
|
||||
# Installing Dusklight on iOS via AltStore
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- A Windows, Linux, or macOS device
|
||||
- iOS device connected to computer via USB
|
||||
- Mac with Homebrew installed
|
||||
- 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/dusk/releases))
|
||||
- Game disc - `GZ2E01` (Gamecube USA) or `GZ2PE01` (Gamecube PAL)
|
||||
|
||||
## 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.
|
||||
- Windows WILL require iTunes to be installed
|
||||
- Linux WILL require usbmuxd to be installed, this is installed by default in most distros though
|
||||
```sh
|
||||
brew install altserver
|
||||
open -a AltServer
|
||||
```
|
||||
|
||||
AltServer will appear in your menu bar.
|
||||
|
||||
## 2. Enable Developer Mode (iOS 16+)
|
||||
|
||||
- On your iPhone, go to **Settings > Privacy & Security > Developer Mode**
|
||||
- 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 and not stored by iloader)
|
||||
* You may be prompted to put in a code from your iOS device, do so
|
||||
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
|
||||
* You will need to hit `Refresh` after plugging it in at this stage so that it can be detected, it does not automatically refresh
|
||||
3. Leave settings unchanged (the Anisette server should stay Sidestore (.io))
|
||||
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 `Dusk-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 Dusk 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
|
||||
- Click AltServer in the menu bar
|
||||
- Click **Install AltStore > [Your iPhone]**
|
||||
- Enter your Apple ID credentials when prompted
|
||||
- On your iPhone, go to **Settings > General > VPN & Device Management**
|
||||
- Tap your Apple ID under "Developer App" and tap **Trust**
|
||||
|
||||
## 4. Copy Files to Your iPhone
|
||||
|
||||
@@ -45,4 +38,9 @@ Transfer the IPA and game disc to your iPhone so they're accessible in the Files
|
||||
- **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
|
||||
|
||||
You may now use Dusklight on iOS, 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
|
||||
Vendored
+1
-1
Submodule extern/aurora updated: 40913d532e...5703c68d46
+3
-2
@@ -1450,6 +1450,8 @@ set(DUSK_FILES
|
||||
src/dusk/imgui/ImGuiEngine.hpp
|
||||
src/dusk/imgui/ImGuiBloomWindow.cpp
|
||||
src/dusk/imgui/ImGuiBloomWindow.hpp
|
||||
src/dusk/imgui/ImGuiEnhancedLightingWindow.cpp
|
||||
src/dusk/imgui/ImGuiEnhancedLightingWindow.hpp
|
||||
src/dusk/imgui/ImGuiMenuTools.cpp
|
||||
src/dusk/imgui/ImGuiMenuTools.hpp
|
||||
src/dusk/imgui/ImGuiActorSpawner.cpp
|
||||
@@ -1458,6 +1460,7 @@ set(DUSK_FILES
|
||||
src/dusk/imgui/ImGuiHeapOverlay.cpp
|
||||
src/dusk/imgui/ImGuiControllerOverlay.cpp
|
||||
src/dusk/imgui/ImGuiStubLog.cpp
|
||||
src/dusk/imgui/ImGuiMapLoader.cpp
|
||||
src/dusk/imgui/ImGuiSaveEditor.cpp
|
||||
src/dusk/imgui/ImGuiStateShare.hpp
|
||||
src/dusk/imgui/ImGuiStateShare.cpp
|
||||
@@ -1508,8 +1511,6 @@ set(DUSK_FILES
|
||||
src/dusk/ui/tab_bar.hpp
|
||||
src/dusk/ui/ui.cpp
|
||||
src/dusk/ui/ui.hpp
|
||||
src/dusk/ui/warp.cpp
|
||||
src/dusk/ui/warp.hpp
|
||||
src/dusk/ui/window.cpp
|
||||
src/dusk/ui/window.hpp
|
||||
src/dusk/achievements.cpp
|
||||
|
||||
@@ -50,11 +50,7 @@
|
||||
|
||||
# Dusklight Actual (Linux x86_64 only — relies on prebuilt dawn/nod binaries)
|
||||
mkDusklight = pkgs:
|
||||
let srcs = buildSources pkgs;
|
||||
versionSuffix = if self ? shortRev && self.shortRev != null
|
||||
then "nix-${self.shortRev}"
|
||||
else "nix-dirty";
|
||||
in
|
||||
let srcs = buildSources pkgs; in
|
||||
pkgs.stdenv.mkDerivation {
|
||||
name = "dusklight";
|
||||
src = ./.;
|
||||
@@ -66,7 +62,6 @@
|
||||
'';
|
||||
# Remove last line to re-enable tests
|
||||
cmakeFlags = [
|
||||
"-DDUSK_VERSION_OVERRIDE=${versionSuffix}"
|
||||
"-DFETCHCONTENT_FULLY_DISCONNECTED=ON"
|
||||
"-DFETCHCONTENT_SOURCE_DIR_CXXOPTS=${pkgs.cxxopts.src}"
|
||||
"-DFETCHCONTENT_SOURCE_DIR_JSON=${pkgs.nlohmann_json.src}"
|
||||
@@ -88,14 +83,6 @@
|
||||
mkdir -p $out/bin
|
||||
cp dusklight $out/bin/dusklight
|
||||
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 = [
|
||||
pkgs.cmake
|
||||
@@ -225,4 +212,4 @@
|
||||
default = mkDevShell (pkgsFor system);
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <cmath>
|
||||
#include <dolphin/types.h>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
#include <m_Do/m_Do_MemCardRWmng.h>
|
||||
#include <m_Do/m_Do_MemCard.h>
|
||||
#include <d/actor/d_a_alink.h>
|
||||
|
||||
void noAutoSave();
|
||||
void triggerAutoSave();
|
||||
|
||||
@@ -175,7 +175,6 @@ class ConfigVar : public ConfigVarBase {
|
||||
T defaultValue;
|
||||
T value;
|
||||
T overrideValue;
|
||||
ConfigVarLayer priorLayer = ConfigVarLayer::Default;
|
||||
|
||||
public:
|
||||
/**
|
||||
@@ -266,7 +265,6 @@ public:
|
||||
void setSpeedrunValue(T newValue) {
|
||||
checkRegistered();
|
||||
if (layer != ConfigVarLayer::Override) {
|
||||
priorLayer = layer;
|
||||
overrideValue = std::move(newValue);
|
||||
layer = ConfigVarLayer::Speedrun;
|
||||
}
|
||||
@@ -284,20 +282,9 @@ public:
|
||||
checkRegistered();
|
||||
if (layer == ConfigVarLayer::Speedrun) {
|
||||
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>;
|
||||
|
||||
@@ -17,7 +17,6 @@ void ensure_initialized();
|
||||
void begin_record();
|
||||
void end_record();
|
||||
void begin_sim_tick();
|
||||
uint64_t sim_tick_seq();
|
||||
void begin_frame(bool enabled, bool is_sim_frame, float step);
|
||||
void interpolate();
|
||||
float get_interpolation_step();
|
||||
|
||||
@@ -14,6 +14,7 @@ constexpr const char* SHOW_DEBUG_OVERLAY = "F3";
|
||||
constexpr const char* SHOW_HEAP_VIEWER = "F4";
|
||||
constexpr const char* SHOW_PLAYER_INFO = "F5";
|
||||
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_DEBUG_CAMERA = "F9";
|
||||
constexpr const char* SHOW_AUDIO_DEBUG = "F10";
|
||||
|
||||
@@ -10,7 +10,6 @@ extern bool IsShuttingDown;
|
||||
extern bool IsGameLaunched;
|
||||
extern bool RestartRequested;
|
||||
extern std::filesystem::path ConfigPath;
|
||||
extern std::filesystem::path CachePath;
|
||||
|
||||
#if defined(__ANDROID__) || (defined(TARGET_OS_IOS) && TARGET_OS_IOS) || \
|
||||
(defined(TARGET_OS_TV) && TARGET_OS_TV)
|
||||
|
||||
@@ -120,6 +120,13 @@ struct UserSettings {
|
||||
ConfigVar<bool> enableDiscordPresence;
|
||||
|
||||
// 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<float> bloomMultiplier;
|
||||
ConfigVar<bool> disableWaterRefraction;
|
||||
@@ -158,7 +165,6 @@ struct UserSettings {
|
||||
// Cheats
|
||||
ConfigVar<bool> infiniteHearts;
|
||||
ConfigVar<bool> infiniteArrows;
|
||||
ConfigVar<bool> infiniteSeeds;
|
||||
ConfigVar<bool> infiniteBombs;
|
||||
ConfigVar<bool> infiniteOil;
|
||||
ConfigVar<bool> infiniteOxygen;
|
||||
@@ -172,7 +178,6 @@ struct UserSettings {
|
||||
ConfigVar<bool> fastRoll;
|
||||
ConfigVar<bool> fastSpinner;
|
||||
ConfigVar<bool> freeMagicArmor;
|
||||
ConfigVar<bool> invincibleEnemies;
|
||||
|
||||
// Technical
|
||||
ConfigVar<bool> restoreWiiGlitches;
|
||||
|
||||
@@ -108,7 +108,7 @@ struct fopAcM_search_prm {
|
||||
struct fOpAcm_HIO_entry_c : public mDoHIO_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.base); }
|
||||
void removeHIO(const fopEn_enemy_c& i_this) { removeHIO(i_this.base); }
|
||||
|
||||
@@ -28,9 +28,7 @@
|
||||
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
|
||||
<key>NSHighResolutionCapable</key>
|
||||
<true/>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.adventure-games</string>
|
||||
<key>LSSupportsGameMode</key>
|
||||
<true/>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -58,10 +58,6 @@ toast:active {
|
||||
background-color: rgba(45, 43, 26, 80%);
|
||||
}*/
|
||||
|
||||
b {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
toast heading {
|
||||
display: flex;
|
||||
gap: 18dp;
|
||||
|
||||
@@ -14,10 +14,6 @@ body {
|
||||
color: #E0DBC8;
|
||||
}
|
||||
|
||||
b {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
window {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
|
||||
@@ -7562,7 +7562,12 @@ void daAlink_c::setBlendMoveAnime(f32 i_morf) {
|
||||
f32 sp2C;
|
||||
f32 sp28 = mpHIO->mMove.m.mFootPositionRatio;
|
||||
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;
|
||||
|
||||
@@ -8075,7 +8080,7 @@ void daAlink_c::setBlendAtnBackMoveAnime(f32 i_morf) {
|
||||
daAlink_ANM var_r27;
|
||||
daAlink_ANM var_r29;
|
||||
|
||||
if (checkBootsMoveAnime(1) IF_DUSK(&& !dusk::getSettings().game.enableFastIronBoots)) {
|
||||
if (checkBootsMoveAnime(1)) {
|
||||
mMaxSpeed = mpHIO->mAtnMove.m.mMaxBackwardsSpeed;
|
||||
var_f27 = mpHIO->mAtnMove.m.mMinBackWalkFrame;
|
||||
var_f31 = mpHIO->mAtnMove.m.mBackWalkChangeRate;
|
||||
|
||||
@@ -77,12 +77,7 @@ int daAlink_c::loadModelDVD() {
|
||||
mpWlMidnaHairModel = NULL;
|
||||
|
||||
if (!checkNoResetFlg2(FLG2_UNK_280000)) {
|
||||
if (!dComIfG_resDelete(&mPhaseReq, mArcName)) {
|
||||
#if TARGET_PC
|
||||
// resDelete no-ops if load was in-progress; force-unregister before freeAll
|
||||
dComIfG_deleteObjectResMain(mArcName);
|
||||
#endif
|
||||
}
|
||||
dComIfG_resDelete(&mPhaseReq, mArcName);
|
||||
cPhs_Reset(&mPhaseReq);
|
||||
mpArcHeap->freeAll();
|
||||
|
||||
|
||||
@@ -8723,12 +8723,6 @@ int daAlink_c::procWolfCargoCarry() {
|
||||
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::transM(-9.0f, -7.0f, -30.0f);
|
||||
mDoMtx_stack_c::multVecZero(¤t.pos);
|
||||
|
||||
@@ -157,21 +157,6 @@ static void* s_h_sub(void* i_actor, void* i_data) {
|
||||
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) {
|
||||
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
|
||||
daPillar_c* pillar_p;
|
||||
@@ -185,9 +170,6 @@ static daPillar_c* search_hasira(e_mk_class* i_this) {
|
||||
|
||||
if (i_this->firstHasiraFlag == 0) {
|
||||
i_this->firstHasiraFlag++;
|
||||
#if TARGET_PC
|
||||
sort_target_info_by_id();
|
||||
#endif
|
||||
return (daPillar_c*)target_info[TREG_S(7) + 5];
|
||||
}
|
||||
|
||||
|
||||
@@ -7053,12 +7053,6 @@ static int daE_RD_IsDelete(e_rd_class*) {
|
||||
}
|
||||
|
||||
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;
|
||||
fopAcM_RegisterDeleteID(i_this, "E_RD");
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
#if TARGET_PC
|
||||
#include "dusk/dusk.h"
|
||||
#include "dusk/frame_interpolation.h"
|
||||
|
||||
namespace {
|
||||
// FRAME INTERP NOTE: Sim tick control point snapshots for interpolation
|
||||
@@ -33,7 +32,6 @@ int s_horseReinSimNumPrev;
|
||||
int s_horseReinSimNumCurr;
|
||||
bool s_horseReinSimPrevValid;
|
||||
bool s_horseReinSimCurrValid;
|
||||
uint64_t s_horseReinSimRolledSeq;
|
||||
} // namespace
|
||||
#endif
|
||||
|
||||
@@ -3035,14 +3033,10 @@ void daHorse_c::copyReinPos() {
|
||||
}
|
||||
#if TARGET_PC
|
||||
if (field_0x1204 > 0) {
|
||||
const uint64_t simSeq = dusk::frame_interp::sim_tick_seq();
|
||||
if (simSeq != s_horseReinSimRolledSeq) {
|
||||
s_horseReinSimRolledSeq = simSeq;
|
||||
if (s_horseReinSimCurrValid && s_horseReinSimNumCurr > 0) {
|
||||
memcpy(s_horseReinSimPrev, s_horseReinSimCurr, s_horseReinSimNumCurr * sizeof(cXyz));
|
||||
s_horseReinSimNumPrev = s_horseReinSimNumCurr;
|
||||
s_horseReinSimPrevValid = true;
|
||||
}
|
||||
if (s_horseReinSimCurrValid && s_horseReinSimNumCurr > 0) {
|
||||
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));
|
||||
s_horseReinSimNumCurr = field_0x1204;
|
||||
|
||||
@@ -1967,11 +1967,7 @@ static void demo_camera_shop(npc_henna_class* i_this) {
|
||||
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 */
|
||||
dComIfGs_onEventBit(dSv_event_flag_c::saveBitLabels[0x335]);
|
||||
#if TARGET_PC
|
||||
dComIfGp_setItemRupeeCount(dComIfGs_getRupeeMax());
|
||||
#else
|
||||
dComIfGp_setItemRupeeCount(1000);
|
||||
#endif
|
||||
} else if ((lbl_82_bss_91 & 0x38) == 0) {
|
||||
i_this->mMsgFlow.init(actor, 0x34f, 0, NULL);
|
||||
/* dSv_event_flag_c::F_0469 - Fishing Pond - Reserved for fishing */
|
||||
|
||||
@@ -299,8 +299,7 @@ int daObjDrop_c::modeParentWait() {
|
||||
|
||||
#if TARGET_PC
|
||||
static inline BOOL checkGetCargoRide() {
|
||||
if (daPy_getPlayerActorClass()->checkCargoCarry() &&
|
||||
strcmp(dComIfGp_getStartStageName(), "F_SP112") == 0 &&
|
||||
if ((daPy_getPlayerActorClass()->checkCargoCarry() && strcmp(dComIfGp_getStartStageName(), "F_SP112") == 0) ||
|
||||
dComIfGs_isLightDropGetFlag(dComIfGp_getStartStageDarkArea()))
|
||||
{
|
||||
return true;
|
||||
|
||||
+10
-10
@@ -13,7 +13,7 @@ const u16 l_J_Ohana00_64TEX__height = 63;
|
||||
#if TARGET_PC
|
||||
#include "dusk/dvd_asset.hpp"
|
||||
using GameVersion = dusk::version::GameVersion;
|
||||
static u8* l_J_Ohana00_64TEX_get() { static u8 buf[0x800]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x9060}, {GameVersion::GcnPal, 0x9060}, {GameVersion::GcnJpn, 0x9060}}, 0x800), true); return buf; }
|
||||
static u8* l_J_Ohana00_64TEX_get() { static u8 buf[0x800]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x9060}, {GameVersion::GcnPal, 0x9060}}, 0x800), true); return buf; }
|
||||
#define l_J_Ohana00_64TEX (l_J_Ohana00_64TEX_get())
|
||||
#else
|
||||
#include "assets/l_J_Ohana00_64TEX.h"
|
||||
@@ -111,10 +111,10 @@ static u8 l_flowerTexCoord[] = {
|
||||
#if TARGET_PC
|
||||
using GameVersion = dusk::version::GameVersion;
|
||||
|
||||
static u8* l_J_hana00DL_get() { static u8 buf[0x150]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x9D20}, {GameVersion::GcnPal, 0x9D20}, {GameVersion::GcnJpn, 0x9D20}}, 0x150), true); return buf; }
|
||||
static u8* l_J_hana00_cDL_get() { static u8 buf[0xDE]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x9E80}, {GameVersion::GcnPal, 0x9E80}, {GameVersion::GcnJpn, 0x9E80}}, 0xDE), true); return buf; }
|
||||
static u8* l_matDL_get() { static u8 buf[0x99]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x9F60}, {GameVersion::GcnPal, 0x9F60}, {GameVersion::GcnJpn, 0x9F60}}, 0x99), true); return buf; }
|
||||
static u8* l_matLight4DL_get() { static u8 buf[0x99]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0xA000}, {GameVersion::GcnPal, 0xA000}, {GameVersion::GcnJpn, 0xA000}}, 0x99), true); return buf; }
|
||||
static u8* l_J_hana00DL_get() { static u8 buf[0x150]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x9D20}, {GameVersion::GcnPal, 0x9D20}}, 0x150), true); return buf; }
|
||||
static u8* l_J_hana00_cDL_get() { static u8 buf[0xDE]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x9E80}, {GameVersion::GcnPal, 0x9E80}}, 0xDE), true); return buf; }
|
||||
static u8* l_matDL_get() { static u8 buf[0x99]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x9F60}, {GameVersion::GcnPal, 0x9F60}}, 0x99), true); return buf; }
|
||||
static u8* l_matLight4DL_get() { static u8 buf[0x99]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0xA000}, {GameVersion::GcnPal, 0xA000}}, 0x99), true); return buf; }
|
||||
#define l_J_hana00DL (l_J_hana00DL_get())
|
||||
#define l_J_hana00_cDL (l_J_hana00_cDL_get())
|
||||
#define l_matDL (l_matDL_get())
|
||||
@@ -270,11 +270,11 @@ static u8 l_flowerTexCoord2[] = {
|
||||
#if TARGET_PC
|
||||
using GameVersion = dusk::version::GameVersion;
|
||||
|
||||
static u8* l_J_hana01DL_get() { static u8 buf[0x138]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0xB7C0}, {GameVersion::GcnPal, 0xB7C0}, {GameVersion::GcnJpn, 0xB7C0}}, 0x138), true); return buf; }
|
||||
static u8* l_J_hana01_c_00DL_get() { static u8 buf[0xDE]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0xB900}, {GameVersion::GcnPal, 0xB900}, {GameVersion::GcnJpn, 0xB900}}, 0xDE), true); return buf; }
|
||||
static u8* l_J_hana01_c_01DL_get() { static u8 buf[0x128]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0xB9E0}, {GameVersion::GcnPal, 0xB9E0}, {GameVersion::GcnJpn, 0xB9E0}}, 0x128), true); return buf; }
|
||||
static u8* l_mat2DL_get() { static u8 buf[0x99]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0xBB20}, {GameVersion::GcnPal, 0xBB20}, {GameVersion::GcnJpn, 0xBB20}}, 0x99), true); return buf; }
|
||||
static u8* l_mat2Light4DL_get() { static u8 buf[0x99]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0xBBC0}, {GameVersion::GcnPal, 0xBBC0}, {GameVersion::GcnJpn, 0xBBC0}}, 0x99), true); return buf; }
|
||||
static u8* l_J_hana01DL_get() { static u8 buf[0x138]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0xB7C0}, {GameVersion::GcnPal, 0xB7C0}}, 0x138), true); return buf; }
|
||||
static u8* l_J_hana01_c_00DL_get() { static u8 buf[0xDE]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0xB900}, {GameVersion::GcnPal, 0xB900}}, 0xDE), true); return buf; }
|
||||
static u8* l_J_hana01_c_01DL_get() { static u8 buf[0x128]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0xB9E0}, {GameVersion::GcnPal, 0xB9E0}}, 0x128), true); return buf; }
|
||||
static u8* l_mat2DL_get() { static u8 buf[0x99]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0xBB20}, {GameVersion::GcnPal, 0xBB20}}, 0x99), true); return buf; }
|
||||
static u8* l_mat2Light4DL_get() { static u8 buf[0x99]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0xBBC0}, {GameVersion::GcnPal, 0xBBC0}}, 0x99), true); return buf; }
|
||||
#define l_J_hana01DL (l_J_hana01DL_get())
|
||||
#define l_J_hana01_c_00DL (l_J_hana01_c_00DL_get())
|
||||
#define l_J_hana01_c_01DL (l_J_hana01_c_01DL_get())
|
||||
|
||||
@@ -21,8 +21,8 @@ const u16 l_M_kusa05_RGBATEX__height = 31;
|
||||
#if TARGET_PC
|
||||
#include "dusk/dvd_asset.hpp"
|
||||
using GameVersion = dusk::version::GameVersion;
|
||||
static u8* l_M_kusa05_RGBATEX_get() { static u8 buf[0x800]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x7680}, {GameVersion::GcnPal, 0x7680}, {GameVersion::GcnJpn, 0x7680}}, 0x800), true); return buf; }
|
||||
static u8* l_M_Hijiki00TEX_get() { static u8 buf[0x800]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x7E80}, {GameVersion::GcnPal, 0x7E80}, {GameVersion::GcnJpn, 0x7E80}}, 0x800), true); return buf; }
|
||||
static u8* l_M_kusa05_RGBATEX_get() { static u8 buf[0x800]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x7680}, {GameVersion::GcnPal, 0x7680}}, 0x800), true); return buf; }
|
||||
static u8* l_M_Hijiki00TEX_get() { static u8 buf[0x800]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x7E80}, {GameVersion::GcnPal, 0x7E80}}, 0x800), true); return buf; }
|
||||
#define l_M_kusa05_RGBATEX (l_M_kusa05_RGBATEX_get())
|
||||
#define l_M_Hijiki00TEX (l_M_Hijiki00TEX_get())
|
||||
#else
|
||||
@@ -116,12 +116,12 @@ static u8 l_texCoord[160] = {
|
||||
#if TARGET_PC
|
||||
using GameVersion = dusk::version::GameVersion;
|
||||
|
||||
static u8* l_M_Kusa_9qDL_get() { static u8 buf[0xCB]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x8B00}, {GameVersion::GcnPal, 0x8B00}, {GameVersion::GcnJpn, 0x8B00}}, 0xCB), true); return buf; }
|
||||
static u8* l_M_Kusa_9q_cDL_get() { static u8 buf[0xCB]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x8BE0}, {GameVersion::GcnPal, 0x8BE0}, {GameVersion::GcnJpn, 0x8BE0}}, 0xCB), true); return buf; }
|
||||
static u8* l_M_TenGusaDL_get() { static u8 buf[0xD4]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x8CC0}, {GameVersion::GcnPal, 0x8CC0}, {GameVersion::GcnJpn, 0x8CC0}}, 0xD4), true); return buf; }
|
||||
static u8* l_Tengusa_matDL_get() { static u8 buf[0xA8]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x8DA0}, {GameVersion::GcnPal, 0x8DA0}, {GameVersion::GcnJpn, 0x8DA0}}, 0xA8), true); return buf; }
|
||||
static u8* l_kusa9q_matDL_get() { static u8 buf[0xA8]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x8E60}, {GameVersion::GcnPal, 0x8E60}, {GameVersion::GcnJpn, 0x8E60}}, 0xA8), true); return buf; }
|
||||
static u8* l_kusa9q_l4_matDL_get() { static u8 buf[0xA8]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x8F20}, {GameVersion::GcnPal, 0x8F20}, {GameVersion::GcnJpn, 0x8F20}}, 0xA8), true); return buf; }
|
||||
static u8* l_M_Kusa_9qDL_get() { static u8 buf[0xCB]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x8B00}, {GameVersion::GcnPal, 0x8B00}}, 0xCB), true); return buf; }
|
||||
static u8* l_M_Kusa_9q_cDL_get() { static u8 buf[0xCB]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x8BE0}, {GameVersion::GcnPal, 0x8BE0}}, 0xCB), true); return buf; }
|
||||
static u8* l_M_TenGusaDL_get() { static u8 buf[0xD4]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x8CC0}, {GameVersion::GcnPal, 0x8CC0}}, 0xD4), true); return buf; }
|
||||
static u8* l_Tengusa_matDL_get() { static u8 buf[0xA8]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x8DA0}, {GameVersion::GcnPal, 0x8DA0}}, 0xA8), true); return buf; }
|
||||
static u8* l_kusa9q_matDL_get() { static u8 buf[0xA8]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x8E60}, {GameVersion::GcnPal, 0x8E60}}, 0xA8), true); return buf; }
|
||||
static u8* l_kusa9q_l4_matDL_get() { static u8 buf[0xA8]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x8F20}, {GameVersion::GcnPal, 0x8F20}}, 0xA8), true); return buf; }
|
||||
#define l_M_Kusa_9qDL (l_M_Kusa_9qDL_get())
|
||||
#define l_M_Kusa_9q_cDL (l_M_Kusa_9q_cDL_get())
|
||||
#define l_M_TenGusaDL (l_M_TenGusaDL_get())
|
||||
|
||||
@@ -143,12 +143,13 @@ void dBrightCheck_c::modeMove() {
|
||||
if (mDoCPd_c::getTrigA(PAD_1) || mDoCPd_c::getTrigStart(PAD_1)) {
|
||||
mDoAud_seStart(Z2SE_ENTER_GAME, NULL, 0, 0);
|
||||
#ifdef TARGET_PC
|
||||
dusk::speedrun::start();
|
||||
|
||||
if (dusk::getSettings().game.speedrunMode && !dusk::getSettings().game.hideTvSettingsScreen) {
|
||||
// start a new run if a run isn't already in progress
|
||||
if (!dusk::m_speedrunInfo.m_isRunStarted) {
|
||||
dusk::resetForSpeedrunMode();
|
||||
dusk::m_speedrunInfo.startRun();
|
||||
dusk::speedrun::start();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#include "f_op/f_op_actor_mng.h"
|
||||
#if TARGET_PC
|
||||
#include "dusk/achievements.h"
|
||||
#include "dusk/settings.h"
|
||||
#endif
|
||||
|
||||
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) {
|
||||
i_enemy->health -= i_AtInfo->mAttackPower;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
#include "d/d_timer.h"
|
||||
#include "f_op/f_op_msg_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_controller_pad.h"
|
||||
#include "m_Do/m_Do_graphic.h"
|
||||
@@ -1239,13 +1238,6 @@ BOOL dComIfG_resetToOpening(scene_class* i_scene) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_PC
|
||||
if (!mDoMemCd_isCardCommNone()) {
|
||||
return 0;
|
||||
}
|
||||
g_mDoMemCd_control.SaveSync();
|
||||
#endif
|
||||
|
||||
dComIfG_changeOpeningScene(i_scene, fpcNm_OPENING_SCENE_e);
|
||||
mDoAud_bgmStop(30);
|
||||
mDoAud_resetProcess();
|
||||
|
||||
@@ -3882,11 +3882,7 @@ bool dCamera_c::hintTalkEvCamera() {
|
||||
|
||||
cSAngle acStack_1fc(20.0f);
|
||||
for (i = 0; i < 2; i++) {
|
||||
#if AVOID_UB
|
||||
for (j = 0; j < 10; j++) {
|
||||
#else
|
||||
for (j = 0; j < 12; j++) {
|
||||
#endif
|
||||
cSAngle acStack_200(local_b0[j] * fVar22);
|
||||
hintTalk->mDirection.U(acStack_1f8 + acStack_200);
|
||||
hintTalk->mDirection.V(((hintTalk->field_0x28.V() * acStack_200.Cos()) * 0.2f) + acStack_1fc);
|
||||
|
||||
@@ -26,10 +26,6 @@
|
||||
#include "f_op/f_op_overlap_mng.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 {
|
||||
public:
|
||||
virtual void draw() {
|
||||
@@ -1092,10 +1088,6 @@ void dMw_c::dMw_ring_create(u8 i_origin) {
|
||||
}
|
||||
|
||||
mpCapture->setCaptureFlag();
|
||||
|
||||
#ifdef TARGET_PC
|
||||
dusk::frame_interp::request_presentation_sync();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool dMw_c::dMw_ring_delete() {
|
||||
|
||||
+7
-67
@@ -17,62 +17,6 @@ static bool isPalOrJpn() {
|
||||
return dusk::version::isRegionPal() || dusk::version::isRegionJpn();
|
||||
}
|
||||
|
||||
#if TARGET_PC
|
||||
static const char* l_mojiHira[65] = {
|
||||
"\x82\xA0", "\x82\xA2", "\x82\xA4", "\x82\xA6", "\x82\xA8", "\x82\xA9", "\x82\xAB", "\x82\xAD", "\x82\xAF", "\x82\xB1", "\x82\xB3", "\x82\xB5", "\x82\xB7",
|
||||
"\x82\xB9", "\x82\xBB", "\x82\xBD", "\x82\xBF", "\x82\xC2", "\x82\xC4", "\x82\xC6", "\x82\xC8", "\x82\xC9", "\x82\xCA", "\x82\xCB", "\x82\xCC", "\x82\xCD",
|
||||
"\x82\xD0", "\x82\xD3", "\x82\xD6", "\x82\xD9", "\x82\xDC", "\x82\xDD", "\x82\xDE", "\x82\xDF", "\x82\xE0", "\x82\xE2", "\x81\x40", "\x82\xE4", "\x81\x40",
|
||||
"\x82\xE6", "\x82\xE7", "\x82\xE8", "\x82\xE9", "\x82\xEA", "\x82\xEB", "\x82\xED", "\x81\x40", "\x82\xF0", "\x81\x40", "\x82\xF1", "\x82\x9F", "\x82\xA1",
|
||||
"\x82\xA3", "\x82\xA5", "\x82\xA7", "\x82\xE1", "\x81\x40", "\x82\xE3", "\x81\x40", "\x82\xE5", "\x82\xC1", "\x81\x40", "\x81\x5B", "\x81\x4A", "\x81\x4B",
|
||||
};
|
||||
|
||||
static const char* l_mojiHira2[65] = {
|
||||
"\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x82\xAA", "\x82\xAC", "\x82\xAE", "\x82\xB0", "\x82\xB2", "\x82\xB4", "\x82\xB6", "\x82\xB8",
|
||||
"\x82\xBA", "\x82\xBC", "\x82\xBE", "\x82\xC0", "\x82\xC3", "\x82\xC5", "\x82\xC7", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x82\xCE",
|
||||
"\x82\xD1", "\x82\xD4", "\x82\xD7", "\x82\xDA", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F",
|
||||
"\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F",
|
||||
"\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F",
|
||||
};
|
||||
|
||||
static const char* l_mojiHira3[65] = {
|
||||
"\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F",
|
||||
"\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x82\xCF",
|
||||
"\x82\xD2", "\x82\xD5", "\x82\xD8", "\x82\xDB", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F",
|
||||
"\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F",
|
||||
"\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F",
|
||||
};
|
||||
|
||||
static const char* l_mojikata[65] = {
|
||||
"\x83\x41", "\x83\x43", "\x83\x45", "\x83\x47", "\x83\x49", "\x83\x4A", "\x83\x4C", "\x83\x4E", "\x83\x50", "\x83\x52", "\x83\x54", "\x83\x56", "\x83\x58",
|
||||
"\x83\x5A", "\x83\x5C", "\x83\x5E", "\x83\x60", "\x83\x63", "\x83\x65", "\x83\x67", "\x83\x69", "\x83\x6A", "\x83\x6B", "\x83\x6C", "\x83\x6D", "\x83\x6E",
|
||||
"\x83\x71", "\x83\x74", "\x83\x77", "\x83\x7A", "\x83\x7D", "\x83\x7E", "\x83\x80", "\x83\x81", "\x83\x82", "\x83\x84", "\x81\x40", "\x83\x86", "\x81\x40",
|
||||
"\x83\x88", "\x83\x89", "\x83\x8A", "\x83\x8B", "\x83\x8C", "\x83\x8D", "\x83\x8F", "\x81\x40", "\x83\x93", "\x81\x40", "\x83\x93", "\x83\x40", "\x83\x42"
|
||||
"\x83\x44", "\x83\x46", "\x83\x48", "\x83\x83", "\x81\x40", "\x83\x85", "\x81\x40", "\x83\x87", "\x83\x62", "\x81\x40", "\x81\x5B", "\x81\x4A", "\x81\x4B",
|
||||
};
|
||||
|
||||
static const char* l_mojikata2[65] = {
|
||||
"\x81\x8F", "\x81\x8F", "\x83\x94", "\x81\x8F", "\x81\x8F", "\x83\x4B", "\x83\x4D", "\x83\x4F", "\x83\x51", "\x83\x53", "\x83\x55", "\x83\x57", "\x83\x59",
|
||||
"\x83\x5B", "\x83\x5D", "\x83\x5F", "\x83\x61", "\x83\x64", "\x83\x66", "\x83\x68", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x83\x6F",
|
||||
"\x83\x72", "\x83\x75", "\x83\x78", "\x83\x7B", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F",
|
||||
"\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F",
|
||||
"\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F",
|
||||
};
|
||||
|
||||
static const char* l_mojikata3[65] = {
|
||||
"\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F",
|
||||
"\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x83\x70",
|
||||
"\x83\x73", "\x83\x76", "\x83\x79", "\x83\x7C", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F",
|
||||
"\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F",
|
||||
"\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F", "\x81\x8F",
|
||||
};
|
||||
|
||||
static const char* l_mojiEisu[65] = {
|
||||
"A", "N", "a", "n", "1", "B", "O", "b", "o", "2", "C", "P", "c", "p", "3", "D", "Q",
|
||||
"d", "q", "4", "E", "R", "e", "r", "5", "F", "S", "f", "s", "6", "G", "T", "g", "t",
|
||||
"7", "H", "U", "h", "u", "8", "I", "V", "i", "v", "9", "J", "W", "j", "w", "0", "K",
|
||||
"X", "k", "x", ",", "L", "Y", "l", "y", ".", "M", "Z", "m", "z", " ",
|
||||
};
|
||||
#else
|
||||
static const char* l_mojiHira[65] = {
|
||||
"あ", "い", "う", "え", "お", "か", "き", "く", "け", "こ", "さ", "し", "す",
|
||||
"せ", "そ", "た", "ち", "つ", "て", "と", "な", "に", "ぬ", "ね", "の", "は",
|
||||
@@ -127,23 +71,22 @@ static const char* l_mojiEisu[65] = {
|
||||
"7", "H", "U", "h", "u", "8", "I", "V", "i", "v", "9", "J", "W", "j", "w", "0", "K",
|
||||
"X", "k", "x", ",", "L", "Y", "l", "y", ".", "M", "Z", "m", "z", " ",
|
||||
};
|
||||
#endif
|
||||
|
||||
#if TARGET_PC
|
||||
// The game normally mutates this string list to fill in the real character codes.
|
||||
// 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] = {
|
||||
"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",
|
||||
"7", "H", "U", "\xC9", "\x8C", "8", "I", "V", "\xCA", "\xD9", "9", "J", "W", "\xCB", "\xDA", "0", "K",
|
||||
"X", "\xCC", "\xDB", ",", "L", "Y", "\xCD", "\xDC", ".", "M", "Z", "\xCE", "\x2D", " ",
|
||||
"\xC3", "\xD2", "4", "E", "R", "\xC4", "\xD3", "5", "F", "S", "\xC5", "\xD4", "6", "G", "T", "\xC6", "\xD5",
|
||||
"7", "H", "U", "\xC7", "\xD6", "8", "I", "V", "\xC8", "\xD7", "9", "J", "W", "\xC9", "\xD8", "0", "K",
|
||||
"X", "\xCA", "\xD9", ",", "L", "Y", "\xCB", "\xDA", ".", "M", "Z", "\xCC", "\xDB", " ",
|
||||
};
|
||||
|
||||
static const char* l_mojiEisuPal_2[65] = {
|
||||
"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",
|
||||
"\xF6", "7", "h", "u", "\xE9", "\x9C", "8", "i", "v", "\xEA", "\xF9", "9", "j", "w", "\xEB", "\xFA", "0",
|
||||
"k", "x", "\xEC", "\xFB", ",", "l", "y", "\xED", "\xFC", ".", "m", "z", "\xEE", "\xDF", " ",
|
||||
"\xE3", "\xF2", "4", "e", "r", "\xE4", "\xF3", "5", "f", "s", "\xE5", "\xF4", "6", "g", "t", "\xE6",
|
||||
"\xF5", "7", "h", "u", "\xE7", "\xF6", "8", "i", "v", "\xE8", "\xF7", "9", "j", "w", "\xE9", "\xF8", "0",
|
||||
"k", "x", "\xEA", "\xF9", ",", "l", "y", "\xEB", "\xFA", ".", "m", "z", "\xEC", "\xFB", " ",
|
||||
};
|
||||
#elif REGION_PAL
|
||||
static const char* l_mojiEisuPal_1[65] = {
|
||||
@@ -352,7 +295,6 @@ void dName_c::_move() {
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
#if !TARGET_PC
|
||||
if (mDoCPd_c::getTrigRight(PAD_1)) {
|
||||
// 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
|
||||
@@ -369,9 +311,7 @@ void dName_c::_move() {
|
||||
mCurPos--;
|
||||
nameCursorMove();
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
if (mDoCPd_c::getTrigB(PAD_1)) {
|
||||
} else if (mDoCPd_c::getTrigB(PAD_1)) {
|
||||
if (mCurPos == 0) {
|
||||
mDoAud_seStart(Z2SE_SY_MENU_BACK, 0, 0, 0);
|
||||
field_0x2ac = mSelProc;
|
||||
|
||||
+1
-8
@@ -907,14 +907,7 @@ dScnLogo_c::~dScnLogo_c() {
|
||||
mDoExt_getRubyFont();
|
||||
mDoExt_setAraCacheSize(free_size - aram_heap->getTotalFreeSize());
|
||||
|
||||
#if TARGET_PC
|
||||
if (getGameVersion() == GameVersion::GcnJpn) {
|
||||
if (dComIfGp_getFontArchive() != NULL) {
|
||||
dComIfGp_getFontArchive()->unmount();
|
||||
dComIfGp_setFontArchive(NULL);
|
||||
}
|
||||
}
|
||||
#elif VERSION == VERSION_GCN_JPN
|
||||
#if VERSION == VERSION_GCN_JPN
|
||||
if (dComIfGp_getFontArchive() != NULL) {
|
||||
dComIfGp_getFontArchive()->unmount();
|
||||
dComIfGp_setFontArchive(NULL);
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include "d/d_meter2_info.h"
|
||||
#include "d/d_s_name.h"
|
||||
#include "dusk/imgui/ImGuiConsole.hpp"
|
||||
#include "dusk/livesplit.h"
|
||||
#include "dusk/memory.h"
|
||||
#include "dusk/speedrun.h"
|
||||
#include "dusk/settings.h"
|
||||
@@ -423,7 +422,6 @@ void dScnName_c::changeGameScene() {
|
||||
if (!dusk::m_speedrunInfo.m_isRunStarted) {
|
||||
dusk::resetForSpeedrunMode();
|
||||
dusk::m_speedrunInfo.startRun();
|
||||
dusk::speedrun::start();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-3
@@ -30,9 +30,7 @@
|
||||
#if TARGET_PC
|
||||
#include "dusk/settings.h"
|
||||
#include <f_ap/f_ap_game.h>
|
||||
|
||||
#include "dusk/string.hpp"
|
||||
#define strcpy dusk::SafeStringCopy
|
||||
#include <dusk/autosave.h>
|
||||
#endif
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
#if TARGET_PC
|
||||
triggerAutoSave();
|
||||
#endif
|
||||
}
|
||||
|
||||
u8 dSv_player_item_c::getItem(int i_slotNo, bool i_checkCombo) const {
|
||||
|
||||
@@ -191,17 +191,13 @@ std::vector<AchievementSystem::Entry> AchievementSystem::makeEntries() {
|
||||
}
|
||||
|
||||
bool hasJewelRod = false;
|
||||
bool hasAncientDoc = false;
|
||||
for (int slot = 0; slot < 24; ++slot) {
|
||||
for (int slot = 0; slot < 24 && !hasJewelRod; ++slot) {
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -216,6 +212,7 @@ std::vector<AchievementSystem::Entry> AchievementSystem::makeEntries() {
|
||||
dItemNo_KANTERA_e,
|
||||
dItemNo_PACHINKO_e,
|
||||
dItemNo_HAWK_EYE_e,
|
||||
dItemNo_ANCIENT_DOCUMENT_e,
|
||||
dItemNo_HORSE_FLUTE_e,
|
||||
};
|
||||
for (u8 required : requiredWheelItems) {
|
||||
|
||||
+6
-26
@@ -14,23 +14,9 @@ static AutoSaveFuncs AutoSaveFuncsProc[] = {
|
||||
|
||||
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() {
|
||||
if (canAutoSave())
|
||||
if (dusk::getSettings().game.autoSave && shouldAutoSave && mAutoSaveProc == 0 &&
|
||||
strcmp(dComIfGp_getStartStageName(), "F_SP102") != 0)
|
||||
{
|
||||
mAutoSaveProc = 1;
|
||||
}
|
||||
@@ -40,12 +26,8 @@ void updateAutoSave() {
|
||||
(AutoSaveFuncsProc[mAutoSaveProc])();
|
||||
}
|
||||
|
||||
bool writeAutoSave() {
|
||||
stage_stag_info_class* stagInfo = dComIfGp_getStageStagInfo();
|
||||
if (stagInfo == nullptr) {
|
||||
return false;
|
||||
}
|
||||
int stageNo = dStage_stagInfo_GetSaveTbl(stagInfo);
|
||||
void writeAutoSave() {
|
||||
int stageNo = dStage_stagInfo_GetSaveTbl(dComIfGp_getStageStagInfo());
|
||||
|
||||
dComIfGs_putSave(stageNo);
|
||||
dComIfGs_setMemoryToCard(mSaveBuffer, dComIfGs_getDataNum());
|
||||
@@ -58,7 +40,6 @@ bool writeAutoSave() {
|
||||
}
|
||||
|
||||
g_mDoMemCd_control.save(mSaveBuffer, sizeof(mSaveBuffer), 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
void autoSaving() {
|
||||
@@ -67,9 +48,8 @@ void autoSaving() {
|
||||
if (cardState == 2) {
|
||||
mAutoSaveProc = 1;
|
||||
} else if (cardState == 1) {
|
||||
if (writeAutoSave()) {
|
||||
mAutoSaveProc = 3;
|
||||
}
|
||||
writeAutoSave();
|
||||
mAutoSaveProc = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-3
@@ -61,7 +61,7 @@ void ConfigImpl<T>::loadFromJson(ConfigVar<T>& cVar, const json& jsonValue) {
|
||||
|
||||
template<ConfigValue T>
|
||||
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>
|
||||
@@ -249,8 +249,7 @@ void dusk::config::Save() {
|
||||
json j;
|
||||
|
||||
for (const auto& pair : RegisteredConfigVars) {
|
||||
const auto layer = pair.second->getLayer();
|
||||
if (layer == ConfigVarLayer::Value || layer == ConfigVarLayer::Speedrun) {
|
||||
if (pair.second->getLayer() == ConfigVarLayer::Value) {
|
||||
j[pair.first] = pair.second->getImpl()->dumpToJson(*pair.second);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ std::string release_name() {
|
||||
}
|
||||
|
||||
std::filesystem::path sentry_database_path() {
|
||||
return dusk::CachePath / "sentry";
|
||||
return dusk::ConfigPath / "sentry";
|
||||
}
|
||||
|
||||
std::filesystem::path log_attachment_path() {
|
||||
|
||||
+93
-222
@@ -6,7 +6,6 @@
|
||||
#include "dusk/main.h"
|
||||
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
#include <filesystem>
|
||||
#include <optional>
|
||||
#include <ranges>
|
||||
@@ -31,21 +30,6 @@ constexpr auto kLocationDescriptorName = "data_location.json";
|
||||
constexpr auto kPipelineCacheName = "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 {
|
||||
Default,
|
||||
Portable,
|
||||
@@ -78,7 +62,6 @@ struct MigrationStats {
|
||||
|
||||
std::optional<std::filesystem::path> sConfiguredDataPath;
|
||||
std::optional<std::filesystem::path> sActiveDescriptorPath;
|
||||
std::optional<std::filesystem::path> sActivePrefPath;
|
||||
|
||||
std::filesystem::path path_from_utf8(std::string_view value) {
|
||||
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) {
|
||||
if (std::string_view{LegacyAppName}.empty() || prefPath.empty()) {
|
||||
std::filesystem::path get_legacy_path() {
|
||||
if (std::string_view{LegacyAppName}.empty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto normalizedPrefPath = prefPath;
|
||||
if (normalizedPrefPath.filename().empty()) {
|
||||
normalizedPrefPath = normalizedPrefPath.parent_path();
|
||||
char* prefPath = SDL_GetPrefPath(OrgName, LegacyAppName);
|
||||
if (!prefPath) {
|
||||
Log.fatal("Unable to get PrefPath: {}", SDL_GetError());
|
||||
}
|
||||
|
||||
const auto parentPath = normalizedPrefPath.parent_path();
|
||||
if (parentPath.empty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return parentPath / LegacyAppName;
|
||||
std::filesystem::path result{reinterpret_cast<const char8_t*>(prefPath)};
|
||||
SDL_free(prefPath);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::filesystem::path get_pref_path() {
|
||||
@@ -116,13 +96,6 @@ std::filesystem::path get_pref_path() {
|
||||
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) {
|
||||
const auto* basePath = SDL_GetBasePath();
|
||||
if (!basePath) {
|
||||
@@ -276,69 +249,6 @@ std::filesystem::path absolute_path(const std::filesystem::path& path) {
|
||||
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) {
|
||||
const auto normalizedRoot = normalized_path(root);
|
||||
const auto normalizedPath = normalized_path(path);
|
||||
@@ -373,46 +283,85 @@ bool should_skip_migration_path(const std::filesystem::path& path,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool matches_name(std::string_view name, const auto& names) {
|
||||
return std::ranges::find(names, name) != names.end();
|
||||
bool has_location_descriptor(const std::filesystem::path& path) {
|
||||
std::error_code ec;
|
||||
return std::filesystem::exists(path / kLocationDescriptorName, ec);
|
||||
}
|
||||
|
||||
bool should_migrate_user_data_path(
|
||||
const std::filesystem::path& sourcePath, const std::filesystem::path& from) {
|
||||
const auto relativePath = sourcePath.lexically_relative(from);
|
||||
if (relativePath.empty() || relativePath.is_absolute()) {
|
||||
bool remove_empty_destination_for_rename(const std::filesystem::path& path) {
|
||||
std::error_code ec;
|
||||
const bool exists = std::filesystem::exists(path, ec);
|
||||
if (ec) {
|
||||
Log.debug("Could not inspect migration destination '{}': {}", io::fs_path_to_string(path),
|
||||
ec.message());
|
||||
return false;
|
||||
}
|
||||
|
||||
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)) {
|
||||
if (!exists) {
|
||||
return true;
|
||||
}
|
||||
|
||||
++it;
|
||||
if (it != relativePath.end()) {
|
||||
const bool canRemove = std::filesystem::is_directory(path, ec) &&
|
||||
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;
|
||||
}
|
||||
|
||||
const auto filename = io::fs_path_to_string(relativePath.filename());
|
||||
if (matches_name(filename, kUserDataFiles)) {
|
||||
return true;
|
||||
std::filesystem::remove(path, ec);
|
||||
if (ec) {
|
||||
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" ||
|
||||
(filename.starts_with("MemoryCard") && filename.ends_with(".raw"));
|
||||
return true;
|
||||
}
|
||||
|
||||
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() {
|
||||
if (!ConfigPath.empty()) {
|
||||
return ConfigPath;
|
||||
}
|
||||
const auto prefPath = active_pref_path();
|
||||
const auto prefPath = get_pref_path();
|
||||
const auto descriptor = read_location_descriptor(prefPath);
|
||||
if (descriptor) {
|
||||
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);
|
||||
}
|
||||
|
||||
const auto prefPath = active_pref_path();
|
||||
const auto prefPath = get_pref_path();
|
||||
for (const auto& path : descriptor_write_paths(prefPath)) {
|
||||
if (write_descriptor_json(path, json)) {
|
||||
sActiveDescriptorPath = path;
|
||||
@@ -490,61 +439,6 @@ bool write_location_descriptor(LocationMode mode, const std::filesystem::path& t
|
||||
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::error_code ec;
|
||||
std::vector<std::filesystem::path> directories;
|
||||
@@ -753,6 +647,14 @@ void migrate_directory(const std::filesystem::path& from, const std::filesystem:
|
||||
return;
|
||||
}
|
||||
|
||||
if (try_rename_directory_migration(from, to)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (try_rename_directory_migration(from, to)) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::filesystem::create_directories(to, ec);
|
||||
if (ec) {
|
||||
++stats.failures;
|
||||
@@ -798,16 +700,6 @@ void migrate_directory(const std::filesystem::path& from, const std::filesystem:
|
||||
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);
|
||||
if (relativePath.empty() || relativePath.is_absolute()) {
|
||||
++stats.failures;
|
||||
@@ -869,6 +761,8 @@ void migrate_data(const std::filesystem::path& prefPath, const std::filesystem::
|
||||
const LocationDescriptor* descriptor) {
|
||||
if (descriptor && !descriptor->previousPath.empty()) {
|
||||
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
|
||||
}
|
||||
|
||||
bool set_custom_data_path(const std::filesystem::path& path, std::string* errorOut) {
|
||||
if (!validate_writable_data_path(path, errorOut)) {
|
||||
bool set_custom_data_path(const std::filesystem::path& path) {
|
||||
if (path.empty()) {
|
||||
Log.warn("Ignoring empty custom data path");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!write_location_descriptor(LocationMode::Custom, path)) {
|
||||
set_error(errorOut, fmt::format("{} could not save the data folder setting.", AppName));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return write_location_descriptor(LocationMode::Custom, path);
|
||||
}
|
||||
|
||||
bool set_custom_data_path(const char* path, std::string* errorOut) {
|
||||
if (path == nullptr) {
|
||||
set_error(errorOut, "Choose a folder.");
|
||||
return false;
|
||||
}
|
||||
return set_custom_data_path(path_from_utf8(path), errorOut);
|
||||
bool set_custom_data_path(const char* path) {
|
||||
return set_custom_data_path(path_from_utf8(path));
|
||||
}
|
||||
|
||||
bool set_portable_data_path() {
|
||||
@@ -1031,12 +917,12 @@ bool set_portable_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));
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -1045,7 +931,7 @@ std::filesystem::path configured_data_path() {
|
||||
return *sConfiguredDataPath;
|
||||
}
|
||||
|
||||
const auto prefPath = active_pref_path();
|
||||
const auto prefPath = get_pref_path();
|
||||
const auto descriptor = read_location_descriptor(prefPath);
|
||||
if (descriptor) {
|
||||
sActiveDescriptorPath = descriptor->path;
|
||||
@@ -1055,13 +941,6 @@ std::filesystem::path configured_data_path() {
|
||||
return *sConfiguredDataPath;
|
||||
}
|
||||
|
||||
std::filesystem::path cache_path() {
|
||||
if (!CachePath.empty()) {
|
||||
return CachePath;
|
||||
}
|
||||
return active_pref_path();
|
||||
}
|
||||
|
||||
bool is_data_path_restart_pending() {
|
||||
if (ConfigPath.empty()) {
|
||||
return false;
|
||||
@@ -1070,12 +949,8 @@ bool is_data_path_restart_pending() {
|
||||
return normalized_path(ConfigPath) != normalized_path(configured_data_path());
|
||||
}
|
||||
|
||||
Paths initialize_data() {
|
||||
const auto preferredPrefPath = get_pref_path();
|
||||
const auto prefPath =
|
||||
rename_legacy_pref_path(legacy_path_for_pref_path(preferredPrefPath), preferredPrefPath);
|
||||
sActivePrefPath = prefPath;
|
||||
|
||||
std::filesystem::path initialize_data() {
|
||||
const auto prefPath = get_pref_path();
|
||||
const auto descriptor = read_location_descriptor(prefPath);
|
||||
if (descriptor) {
|
||||
sActiveDescriptorPath = descriptor->path;
|
||||
@@ -1088,13 +963,9 @@ Paths initialize_data() {
|
||||
|
||||
migrate_data(prefPath, dataPath, descriptor ? &descriptor->descriptor : nullptr);
|
||||
ensure_data_directory(dataPath);
|
||||
ensure_data_directory(prefPath);
|
||||
ensure_initial_pipeline_cache(prefPath);
|
||||
ensure_initial_pipeline_cache(dataPath);
|
||||
|
||||
return Paths{
|
||||
.userPath = dataPath,
|
||||
.cachePath = prefPath,
|
||||
};
|
||||
return dataPath;
|
||||
}
|
||||
|
||||
} // namespace dusk::data
|
||||
|
||||
+4
-11
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <TargetConditionals.h>
|
||||
@@ -15,7 +14,7 @@
|
||||
#define DUSK_CAN_OPEN_DATA_FOLDER 0
|
||||
#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
|
||||
#else
|
||||
#define DUSK_CAN_CHANGE_DATA_FOLDER 1
|
||||
@@ -23,17 +22,11 @@
|
||||
|
||||
namespace dusk::data {
|
||||
|
||||
struct Paths {
|
||||
std::filesystem::path userPath;
|
||||
std::filesystem::path cachePath;
|
||||
};
|
||||
|
||||
Paths initialize_data();
|
||||
std::filesystem::path initialize_data();
|
||||
std::filesystem::path configured_data_path();
|
||||
std::filesystem::path cache_path();
|
||||
bool open_data_path();
|
||||
bool set_custom_data_path(const char* path, std::string* errorOut);
|
||||
bool set_custom_data_path(const std::filesystem::path& path, std::string* errorOut);
|
||||
bool set_custom_data_path(const char* path);
|
||||
bool set_custom_data_path(const std::filesystem::path& path);
|
||||
bool set_portable_data_path();
|
||||
bool reset_data_path();
|
||||
bool is_default_data_path();
|
||||
|
||||
@@ -21,7 +21,6 @@ bool g_sync_presentation = false;
|
||||
float g_step = 0.0f;
|
||||
bool g_is_sim_frame = false;
|
||||
bool g_ui_tick_pending = false;
|
||||
uint64_t g_sim_tick_seq = 0;
|
||||
|
||||
Recording g_current_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) {
|
||||
const float old_weight = 1.0f - step;
|
||||
for (size_t row = 0; row < 3; ++row) {
|
||||
for (size_t col = 0; col < 4; ++col) {
|
||||
const float l = lhs[row][col];
|
||||
out[row][col] = l + (rhs[row][col] - l) * step;
|
||||
out[row][col] = lhs[row][col] * old_weight + rhs[row][col] * step;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void lerp_xyz(cXyz* out, const cXyz& lhs, const cXyz& rhs, float step) {
|
||||
out->x = lhs.x + (rhs.x - lhs.x) * step;
|
||||
out->y = lhs.y + (rhs.y - lhs.y) * step;
|
||||
out->z = lhs.z + (rhs.z - lhs.z) * step;
|
||||
const float old_weight = 1.0f - step;
|
||||
out->x = lhs.x * old_weight + rhs.x * 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) {
|
||||
@@ -135,11 +135,6 @@ void begin_sim_tick() {
|
||||
|
||||
s_interpolationCallBackWork.clear();
|
||||
s_cam_prev = std::move(s_cam_curr);
|
||||
++g_sim_tick_seq;
|
||||
}
|
||||
|
||||
uint64_t sim_tick_seq() {
|
||||
return g_sim_tick_seq;
|
||||
}
|
||||
|
||||
void begin_frame(bool enabled, bool is_sim_frame, float step) {
|
||||
|
||||
@@ -263,7 +263,7 @@ namespace dusk {
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -322,8 +322,8 @@ namespace dusk {
|
||||
}
|
||||
ImGui::PushFont(ImGuiEngine::fontLarge);
|
||||
ImGuiTextCenter("Failed to initialize any graphics backend.");
|
||||
ImGuiTextCenter("\nDusklight requires Vulkan 1.1+, or Direct X 12.0.");
|
||||
ImGuiTextCenter("\nTry updating your Operating System and GPU drivers.");
|
||||
ImGuiTextCenter("\nYour system may be misconfigured, or your hardware may not support the required versions of any of the available backends.");
|
||||
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 retrySize = ImGui::CalcTextSize("Retry (Auto backend)");
|
||||
const auto quitSize = ImGui::CalcTextSize("Quit");
|
||||
@@ -368,7 +368,9 @@ namespace dusk {
|
||||
m_menuTools.ShowProcessManager();
|
||||
m_menuTools.ShowHeapOverlay();
|
||||
m_menuTools.ShowStubLog();
|
||||
m_menuTools.ShowMapLoader();
|
||||
m_menuTools.ShowBloomWindow();
|
||||
m_menuTools.ShowEnhancedLightingWindow();
|
||||
m_menuTools.ShowPlayerInfo();
|
||||
m_menuTools.ShowAudioDebug();
|
||||
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
|
||||
@@ -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
|
||||
@@ -1,11 +1,13 @@
|
||||
#include "fmt/format.h"
|
||||
#include "imgui.h"
|
||||
#include "aurora/gfx.h"
|
||||
#include <aurora/gfx.h>
|
||||
|
||||
#include "ImGuiConfig.hpp"
|
||||
#include "dusk/hotkeys.h"
|
||||
#include "dusk/settings.h"
|
||||
#include "ImGuiBloomWindow.hpp"
|
||||
#include "ImGuiConsole.hpp"
|
||||
#include "ImGuiEnhancedLightingWindow.hpp"
|
||||
#include "ImGuiMenuTools.hpp"
|
||||
|
||||
#include "ImGuiEngine.hpp"
|
||||
@@ -40,6 +42,7 @@ namespace dusk {
|
||||
ImGui::BeginDisabled(getSettings().game.speedrunMode);
|
||||
|
||||
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::EndDisabled();
|
||||
@@ -103,6 +106,7 @@ namespace dusk {
|
||||
ImGui::MenuItem("Debug Camera", hotkeys::SHOW_DEBUG_CAMERA, &m_showCameraOverlay);
|
||||
ImGui::MenuItem("Audio Debug", hotkeys::SHOW_AUDIO_DEBUG, &m_showAudioDebug);
|
||||
ImGui::MenuItem("Bloom", nullptr, &m_showBloomWindow);
|
||||
ImGui::MenuItem("Enhanced Lighting", nullptr, &m_showEnhancedLightingWindow);
|
||||
ImGui::MenuItem("Stub Log", nullptr, &m_showStubLog);
|
||||
ImGui::MenuItem("Actor Spawner", nullptr, &m_showActorSpawner);
|
||||
|
||||
|
||||
@@ -21,7 +21,9 @@ namespace dusk {
|
||||
void ShowProcessManager();
|
||||
void ShowHeapOverlay();
|
||||
void ShowStubLog();
|
||||
void ShowMapLoader();
|
||||
void ShowBloomWindow();
|
||||
void ShowEnhancedLightingWindow();
|
||||
void ShowPlayerInfo();
|
||||
void ShowAudioDebug();
|
||||
void ShowSaveEditor();
|
||||
@@ -42,9 +44,23 @@ namespace dusk {
|
||||
|
||||
bool m_showStubLog = false;
|
||||
|
||||
bool m_showMapLoader = false;
|
||||
|
||||
bool m_showBloomWindow = false;
|
||||
bool m_showEnhancedLightingWindow = 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;
|
||||
int m_playerInfoOverlayCorner = 1; // top-right
|
||||
|
||||
@@ -60,6 +60,18 @@ const char* verification_state_name(dusk::DiscVerificationState state) noexcept
|
||||
|
||||
namespace dusk::iso {
|
||||
|
||||
enum class Platform : u8 {
|
||||
GameCube,
|
||||
Wii,
|
||||
};
|
||||
|
||||
enum class Region : u8 {
|
||||
NorthAmerica,
|
||||
Europe,
|
||||
Japan,
|
||||
Korea,
|
||||
};
|
||||
|
||||
struct KnownDisc {
|
||||
std::string_view id;
|
||||
Platform platform;
|
||||
@@ -76,7 +88,7 @@ struct KnownDisc {
|
||||
|
||||
constexpr auto KNOWN_DISCS = std::to_array<KnownDisc>({
|
||||
{"GZ2E01", Platform::GameCube, Region::NorthAmerica, "14e886f08e548a000afde98a3195e788"},
|
||||
{"GZ2J01", Platform::GameCube, Region::Japan, "5967dc7a6a553652f4d2050aeef6f368"},
|
||||
{"GZ2J01", Platform::GameCube, Region::Japan},
|
||||
{"GZ2P01", Platform::GameCube, Region::Europe, "9ef597588b0035ca9e91b333fa9a8a7e"},
|
||||
{"RZDE01", Platform::Wii, Region::NorthAmerica},
|
||||
{"RZDJ01", Platform::Wii, Region::Japan},
|
||||
@@ -204,9 +216,7 @@ ValidationError validate(const char* path, VerificationStatus& status, DiscInfo&
|
||||
return ValidationError::WrongGame;
|
||||
}
|
||||
status.knownDisc = knownDisc;
|
||||
|
||||
info.platform = knownDisc->platform;
|
||||
info.region = knownDisc->region;
|
||||
info.isPal = knownDisc->region == Region::Europe;
|
||||
if (!knownDisc->supported) {
|
||||
return ValidationError::WrongVersion;
|
||||
}
|
||||
@@ -241,9 +251,7 @@ ValidationError inspect(const char* path, DiscInfo& info) {
|
||||
if (!knownDisc) {
|
||||
return ValidationError::WrongGame;
|
||||
}
|
||||
|
||||
info.platform = knownDisc->platform;
|
||||
info.region = knownDisc->region;
|
||||
info.isPal = knownDisc->region == Region::Europe;
|
||||
if (!knownDisc->supported) {
|
||||
return ValidationError::WrongVersion;
|
||||
}
|
||||
@@ -252,7 +260,7 @@ ValidationError inspect(const char* path, DiscInfo& info) {
|
||||
|
||||
bool isPal(const char* path) {
|
||||
DiscInfo info{};
|
||||
return inspect(path, info) == ValidationError::Success && info.region == Region::Europe;
|
||||
return inspect(path, info) == ValidationError::Success && info.isPal;
|
||||
}
|
||||
|
||||
void log_verification_state(std::string_view path, DiscVerificationState state) {
|
||||
|
||||
@@ -17,18 +17,6 @@ enum class ValidationError : u8 {
|
||||
Success
|
||||
};
|
||||
|
||||
enum class Platform : u8 {
|
||||
GameCube,
|
||||
Wii,
|
||||
};
|
||||
|
||||
enum class Region : u8 {
|
||||
NorthAmerica,
|
||||
Europe,
|
||||
Japan,
|
||||
Korea,
|
||||
};
|
||||
|
||||
struct VerificationStatus {
|
||||
std::atomic_size_t bytesRead = 0;
|
||||
std::atomic_size_t bytesTotal = 0;
|
||||
@@ -37,8 +25,7 @@ struct VerificationStatus {
|
||||
};
|
||||
|
||||
struct DiscInfo {
|
||||
Platform platform = Platform::GameCube;
|
||||
Region region = Region::NorthAmerica;
|
||||
bool isPal = false;
|
||||
};
|
||||
|
||||
ValidationError inspect(const char* path, DiscInfo& info);
|
||||
|
||||
+19
-5
@@ -13,7 +13,7 @@ UserSettings g_userSettings = {
|
||||
},
|
||||
|
||||
.audio = {
|
||||
.masterVolume {"audio.masterVolume", 60},
|
||||
.masterVolume {"audio.masterVolume", 80},
|
||||
.mainMusicVolume {"audio.mainMusicVolume", 100},
|
||||
.subMusicVolume {"audio.subMusicVolume", 100},
|
||||
.soundEffectsVolume {"audio.soundEffectsVolume", 100},
|
||||
@@ -55,6 +55,13 @@ UserSettings g_userSettings = {
|
||||
.enableDiscordPresence {"game.enableDiscordPresence", true},
|
||||
|
||||
// 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},
|
||||
.bloomMultiplier {"game.bloomMultiplier", 1.0f},
|
||||
.disableWaterRefraction {"game.disableWaterRefraction", false},
|
||||
@@ -93,7 +100,6 @@ UserSettings g_userSettings = {
|
||||
// Cheats
|
||||
.infiniteHearts {"game.infiniteHearts", false},
|
||||
.infiniteArrows {"game.infiniteArrows", false},
|
||||
.infiniteSeeds {"game.infiniteSeeds", false},
|
||||
.infiniteBombs {"game.infiniteBombs", false},
|
||||
.infiniteOil {"game.infiniteOil", false},
|
||||
.infiniteOxygen {"game.infiniteOxygen", false},
|
||||
@@ -107,7 +113,6 @@ UserSettings g_userSettings = {
|
||||
.fastRoll {"game.fastRoll", false},
|
||||
.fastSpinner {"game.fastSpinner", false},
|
||||
.freeMagicArmor {"game.freeMagicArmor", false},
|
||||
.invincibleEnemies {"game.invincibleEnemies", false},
|
||||
|
||||
// Technical
|
||||
.restoreWiiGlitches {"game.restoreWiiGlitches", false},
|
||||
@@ -215,6 +220,17 @@ void registerSettings() {
|
||||
Register(g_userSettings.game.minimalHUD);
|
||||
Register(g_userSettings.game.pauseOnFocusLost);
|
||||
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.bloomMultiplier);
|
||||
Register(g_userSettings.game.disableWaterRefraction);
|
||||
@@ -245,7 +261,6 @@ void registerSettings() {
|
||||
Register(g_userSettings.game.fastSpinner);
|
||||
Register(g_userSettings.game.infiniteHearts);
|
||||
Register(g_userSettings.game.infiniteArrows);
|
||||
Register(g_userSettings.game.infiniteSeeds);
|
||||
Register(g_userSettings.game.infiniteBombs);
|
||||
Register(g_userSettings.game.infiniteOil);
|
||||
Register(g_userSettings.game.infiniteOxygen);
|
||||
@@ -254,7 +269,6 @@ void registerSettings() {
|
||||
Register(g_userSettings.game.moonJump);
|
||||
Register(g_userSettings.game.superClawshot);
|
||||
Register(g_userSettings.game.alwaysGreatspin);
|
||||
Register(g_userSettings.game.invincibleEnemies);
|
||||
Register(g_userSettings.game.enableFrameInterpolation);
|
||||
Register(g_userSettings.game.gyroMode);
|
||||
Register(g_userSettings.game.enableGyroAim);
|
||||
|
||||
@@ -20,7 +20,6 @@ void resetForSpeedrunMode() {
|
||||
|
||||
getSettings().game.infiniteHearts.setSpeedrunValue(false);
|
||||
getSettings().game.infiniteArrows.setSpeedrunValue(false);
|
||||
getSettings().game.infiniteSeeds.setSpeedrunValue(false);
|
||||
getSettings().game.infiniteBombs.setSpeedrunValue(false);
|
||||
getSettings().game.infiniteOil.setSpeedrunValue(false);
|
||||
getSettings().game.infiniteOxygen.setSpeedrunValue(false);
|
||||
|
||||
+38
-37
@@ -26,43 +26,6 @@
|
||||
#include <vector>
|
||||
|
||||
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 {
|
||||
|
||||
bool has_save_data() {
|
||||
@@ -192,6 +155,44 @@ bool parse_vec3(const Rml::String& value, float& x, float& y, float& z) {
|
||||
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() {
|
||||
if (!has_save_data()) {
|
||||
return "";
|
||||
|
||||
@@ -1,19 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "window.hpp"
|
||||
|
||||
struct MapEntry;
|
||||
|
||||
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 {
|
||||
public:
|
||||
EditorWindow();
|
||||
|
||||
@@ -184,7 +184,7 @@ Rml::String format_graphics_setting_value(GraphicsOption option, int value) {
|
||||
case BloomMode::Classic:
|
||||
return "Classic";
|
||||
case BloomMode::Dusk:
|
||||
return "Dusklight";
|
||||
return "Dusk";
|
||||
}
|
||||
break;
|
||||
case GraphicsOption::BloomMultiplier:
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include "modal.hpp"
|
||||
#include "settings.hpp"
|
||||
#include "ui.hpp"
|
||||
#include "warp.hpp"
|
||||
#include "window.hpp"
|
||||
|
||||
#include <chrono>
|
||||
@@ -52,9 +51,11 @@ MenuBar::MenuBar() : Document(kDocumentSource), mRoot(mDocument->GetElementById(
|
||||
.autoSelect = false,
|
||||
});
|
||||
mTabBar->add_tab("Settings", [this] { push(std::make_unique<SettingsWindow>()); });
|
||||
// mTabBar->add_tab("Warp", [] {
|
||||
// // TODO
|
||||
// });
|
||||
|
||||
if (getSettings().backend.enableAdvancedSettings) {
|
||||
mTabBar->add_tab("Warp", [this] { push(std::make_unique<WarpWindow>()); });
|
||||
mTabBar->add_tab("Editor", [this] { push(std::make_unique<EditorWindow>()); });
|
||||
}
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@ Rml::String back_button_name() {
|
||||
#if defined(TARGET_ANDROID) || (defined(__APPLE__) && TARGET_OS_IOS && !TARGET_OS_MACCATALYST)
|
||||
constexpr auto kMenuNotificationPrefix = "3-finger tap or";
|
||||
#else
|
||||
constexpr auto kMenuNotificationPrefix = "Press <b>F1</b> or";
|
||||
constexpr auto kMenuNotificationPrefix = "Press F1 or";
|
||||
#endif
|
||||
|
||||
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);
|
||||
auto* icon = append(row, "icon");
|
||||
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");
|
||||
|
||||
return elem;
|
||||
@@ -354,9 +354,8 @@ void Overlay::update() {
|
||||
}
|
||||
}
|
||||
|
||||
u32 count = 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<WindowSmall*>(top_document()) == nullptr;
|
||||
if (showControllerWarning && mControllerWarning == nullptr) {
|
||||
|
||||
@@ -877,36 +877,8 @@ void Prelaunch::update() {
|
||||
if (mDiscDetail != nullptr) {
|
||||
if (activeDiscLoaded) {
|
||||
mDiscDetail->SetProperty(Rml::PropertyId::Display, Rml::Style::Display::Block);
|
||||
Rml::String innerRML = "";
|
||||
|
||||
switch (state.activeDiscInfo.platform) {
|
||||
case iso::Platform::GameCube:
|
||||
innerRML += "GameCube";
|
||||
break;
|
||||
case iso::Platform::Wii:
|
||||
innerRML += "Wii";
|
||||
break;
|
||||
}
|
||||
|
||||
innerRML += " • ";
|
||||
|
||||
switch (state.activeDiscInfo.region) {
|
||||
case iso::Region::Japan:
|
||||
innerRML += "JPN";
|
||||
break;
|
||||
case iso::Region::Europe:
|
||||
innerRML += "EUR";
|
||||
break;
|
||||
case iso::Region::NorthAmerica:
|
||||
innerRML += "USA";
|
||||
break;
|
||||
case iso::Region::Korea:
|
||||
innerRML += "KOR";
|
||||
break;
|
||||
default:
|
||||
innerRML += "Unknown";
|
||||
break;
|
||||
}
|
||||
Rml::String innerRML = "GameCube • ";
|
||||
innerRML += state.activeDiscInfo.isPal ? "EUR" : "USA";
|
||||
mDiscDetail->SetInnerRML(innerRML);
|
||||
} else {
|
||||
mDiscDetail->SetProperty(Rml::PropertyId::Display, Rml::Style::Display::None);
|
||||
|
||||
@@ -83,7 +83,7 @@ PresetWindow::PresetWindow() : WindowSmall("modal", "modal-dialog") {
|
||||
"Enhancements disabled to match the GameCube version. "
|
||||
"Good for speedrunning or simple nostalgia!",
|
||||
applyPresetClassic},
|
||||
{"Dusklight",
|
||||
{"Dusk",
|
||||
"Graphics & quality of life tweaks, including some from the Wii U version. "
|
||||
"Our recommended way to play!",
|
||||
applyPresetDusk},
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include "aurora/gfx.h"
|
||||
#include "bool_button.hpp"
|
||||
#include "controller_config.hpp"
|
||||
#include "dusk/app_info.hpp"
|
||||
#include "dusk/audio/DuskAudioSystem.h"
|
||||
#include "dusk/audio/DuskDsp.hpp"
|
||||
#include "dusk/config.hpp"
|
||||
@@ -18,7 +17,6 @@
|
||||
#include "graphics_tuner.hpp"
|
||||
#include "m_Do/m_Do_main.h"
|
||||
#include "menu_bar.hpp"
|
||||
#include "modal.hpp"
|
||||
#include "number_button.hpp"
|
||||
#include "menu_bar.hpp"
|
||||
#include "pane.hpp"
|
||||
@@ -27,7 +25,6 @@
|
||||
|
||||
#include <aurora/lib/window.hpp>
|
||||
#include <SDL3/SDL_filesystem.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
#if DUSK_ENABLE_SENTRY_NATIVE
|
||||
#include "dusk/crash_reporting.h"
|
||||
@@ -187,7 +184,6 @@ void reset_for_speedrun_mode() {
|
||||
|
||||
getSettings().game.infiniteHearts.setSpeedrunValue(false);
|
||||
getSettings().game.infiniteArrows.setSpeedrunValue(false);
|
||||
getSettings().game.infiniteSeeds.setSpeedrunValue(false);
|
||||
getSettings().game.infiniteBombs.setSpeedrunValue(false);
|
||||
getSettings().game.infiniteOil.setSpeedrunValue(false);
|
||||
getSettings().game.infiniteOxygen.setSpeedrunValue(false);
|
||||
@@ -201,7 +197,6 @@ void reset_for_speedrun_mode() {
|
||||
getSettings().game.fastRoll.setSpeedrunValue(false);
|
||||
getSettings().game.fastSpinner.setSpeedrunValue(false);
|
||||
getSettings().game.freeMagicArmor.setSpeedrunValue(false);
|
||||
getSettings().game.invincibleEnemies.setSpeedrunValue(false);
|
||||
|
||||
getSettings().game.pauseOnFocusLost.setSpeedrunValue(false);
|
||||
aurora_set_pause_on_focus_lost(false);
|
||||
@@ -300,49 +295,13 @@ private:
|
||||
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) {
|
||||
if (error != nullptr) {
|
||||
show_data_folder_error_modal(error);
|
||||
if (error != nullptr || path == nullptr) {
|
||||
return;
|
||||
}
|
||||
if (path == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string dataPathError;
|
||||
if (data::set_custom_data_path(path, &dataPathError)) {
|
||||
if (data::set_custom_data_path(path)) {
|
||||
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 =
|
||||
@@ -562,7 +521,7 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
|
||||
.getValue =
|
||||
[] {
|
||||
const auto& state = prelaunch_state();
|
||||
if (!state.configuredDiscCanLaunch || state.configuredDiscInfo.region != iso::Region::Europe) {
|
||||
if (!state.configuredDiscCanLaunch || !state.configuredDiscInfo.isPal) {
|
||||
return kLanguageNames[0];
|
||||
}
|
||||
const u8 idx = static_cast<u8>(getSettings().game.language.getValue());
|
||||
@@ -572,7 +531,7 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
|
||||
[] {
|
||||
const auto& state = prelaunch_state();
|
||||
return !state.configuredDiscCanLaunch ||
|
||||
state.configuredDiscInfo.region != iso::Region::Europe;
|
||||
!state.configuredDiscInfo.isPal;
|
||||
},
|
||||
.isModified =
|
||||
[] {
|
||||
@@ -953,7 +912,7 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
|
||||
[](int value) {
|
||||
getSettings().audio.masterVolume.setValue(value);
|
||||
config::Save();
|
||||
audio::SetMasterVolume(audio::MasterVolumeToLinear(value / 100.0f));
|
||||
audio::SetMasterVolume(value / 100.f);
|
||||
},
|
||||
.isModified =
|
||||
[] {
|
||||
@@ -1068,7 +1027,8 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
|
||||
addOption("Faster Tears of Light", getSettings().game.fastTears,
|
||||
"Tears of Light dropped by Shadow Insects pop out faster like the HD version.");
|
||||
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,
|
||||
"Skips the delay when writing to the Memory Card.");
|
||||
addOption("Hold B for Instant Text", getSettings().game.instantText,
|
||||
@@ -1147,7 +1107,6 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
|
||||
addCheat("Infinite Hearts", getSettings().game.infiniteHearts, "Keeps your health full.");
|
||||
addCheat(
|
||||
"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 Oil", getSettings().game.infiniteOil, "Keeps your lantern oil full.");
|
||||
addCheat("Infinite Oxygen", getSettings().game.infiniteOxygen,
|
||||
@@ -1165,7 +1124,7 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
|
||||
addCheat("Always Greatspin", getSettings().game.alwaysGreatspin,
|
||||
"Allows the Great Spin attack without requiring full health.");
|
||||
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,
|
||||
"Allows transforming even if NPCs are looking.");
|
||||
addCheat("Fast Roll", getSettings().game.fastRoll,
|
||||
@@ -1174,8 +1133,6 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
|
||||
"Speeds up Spinner movement while holding R.");
|
||||
addCheat("Free Magic Armor", getSettings().game.freeMagicArmor,
|
||||
"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) {
|
||||
@@ -1300,7 +1257,7 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
|
||||
config_bool_select(leftPane, rightPane, getSettings().game.enableDiscordPresence,
|
||||
{
|
||||
.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) {
|
||||
if (enabled) {
|
||||
dusk::discord::initialize();
|
||||
|
||||
@@ -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 ®ion->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
|
||||
@@ -1,12 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "window.hpp"
|
||||
|
||||
namespace dusk::ui {
|
||||
|
||||
class WarpWindow : public Window {
|
||||
public:
|
||||
WarpWindow();
|
||||
};
|
||||
|
||||
} // namespace dusk::ui
|
||||
@@ -28,8 +28,6 @@ void init() {
|
||||
gameVersion = GameVersion::GcnUsa;
|
||||
} else if (game == "GZ2P") {
|
||||
gameVersion = GameVersion::GcnPal;
|
||||
} else if (game == "GZ2J") {
|
||||
gameVersion = GameVersion::GcnJpn;
|
||||
} else {
|
||||
// TODO: Handle remaining valid versions.
|
||||
DuskLog.fatal("Unknown/unsupported game version in disc: {}", game);
|
||||
|
||||
@@ -792,10 +792,6 @@ static void duskExecute() {
|
||||
dComIfGs_setArrowNum(dComIfGs_getArrowMax());
|
||||
}
|
||||
|
||||
if (dusk::getSettings().game.infiniteSeeds) {
|
||||
dComIfGs_setPachinkoNum(dComIfGs_getPachinkoMax());
|
||||
}
|
||||
|
||||
if (dusk::getSettings().game.infiniteBombs) {
|
||||
dComIfGs_setBombNum(0, 99);
|
||||
dComIfGs_setBombNum(1, 99);
|
||||
@@ -807,7 +803,7 @@ static void duskExecute() {
|
||||
}
|
||||
|
||||
if (dusk::getSettings().game.infiniteRupees) {
|
||||
dComIfGs_setRupee(dComIfGs_getRupeeMax());
|
||||
dComIfGs_setRupee(9999);
|
||||
}
|
||||
|
||||
if (dusk::getSettings().game.infiniteOxygen) {
|
||||
|
||||
+1
-10
@@ -136,17 +136,8 @@ base_process_class* fpcBs_Create(s16 i_profname, fpc_ProcID i_procID, void* i_ap
|
||||
u32 size;
|
||||
|
||||
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={}",
|
||||
i_procID, procName ? procName : "(unknown)", i_profname, (void*)pprofile, pprofile->process_size, pprofile->unk_size);
|
||||
#endif
|
||||
i_procID, getProcName(i_profname), i_profname, (void*)pprofile, pprofile->process_size, pprofile->unk_size);
|
||||
size = pprofile->process_size + pprofile->unk_size;
|
||||
|
||||
pprocess = (base_process_class*)cMl::memalignB(-4, size);
|
||||
|
||||
+2
-17
@@ -26,7 +26,6 @@
|
||||
#include <cstring>
|
||||
#include "dusk/logging.h"
|
||||
#include "dusk/frame_interpolation.h"
|
||||
#include "dusk/version.hpp"
|
||||
|
||||
u8 mDoExt::CurrentHeapAdjustVerbose;
|
||||
u8 mDoExt::HeapAdjustVerbose;
|
||||
@@ -3702,15 +3701,7 @@ static ResFONT* mDoExt_resfont0;
|
||||
|
||||
static void mDoExt_initFont0() {
|
||||
static char const fontdata[] = "rodan_b_24_22.bfn";
|
||||
#if TARGET_PC
|
||||
if (dusk::version::getGameVersion() == dusk::version::GameVersion::GcnJpn) {
|
||||
mDoExt_initFontCommon(&mDoExt_font0, &mDoExt_resfont0, mDoExt_getZeldaHeap(),
|
||||
fontdata, dComIfGp_getFontArchive(), 0, 200, 512);
|
||||
} else {
|
||||
mDoExt_initFontCommon(&mDoExt_font0, &mDoExt_resfont0, mDoExt_getZeldaHeap(),
|
||||
fontdata, dComIfGp_getFontArchive(), 1, 0, 0);
|
||||
}
|
||||
#elif REGION_JPN
|
||||
#if REGION_JPN
|
||||
mDoExt_initFontCommon(&mDoExt_font0, &mDoExt_resfont0, mDoExt_getZeldaHeap(),
|
||||
fontdata, dComIfGp_getFontArchive(), 0, 200, 512);
|
||||
#else
|
||||
@@ -3737,13 +3728,7 @@ void mDoExt_removeMesgFont() {
|
||||
JKR_DELETE(mDoExt_font0);
|
||||
mDoExt_font0 = NULL;
|
||||
if (mDoExt_resfont0 != NULL) {
|
||||
#if TARGET_PC
|
||||
if (dusk::version::getGameVersion() == dusk::version::GameVersion::GcnJpn) {
|
||||
JKRFileLoader::removeResource(mDoExt_resfont0, NULL);
|
||||
} else {
|
||||
JKRFree(mDoExt_resfont0);
|
||||
}
|
||||
#elif REGION_JPN
|
||||
#if REGION_JPN
|
||||
JKRFileLoader::removeResource(mDoExt_resfont0, NULL);
|
||||
#else
|
||||
JKRFree(mDoExt_resfont0);
|
||||
|
||||
@@ -96,8 +96,8 @@ void mDoLib_project(Vec* src, Vec* dst) {
|
||||
xSize = FB_WIDTH;
|
||||
} else {
|
||||
#if TARGET_PC
|
||||
xOffset = mDoGph_gInf_c::getMinXF();
|
||||
xSize = mDoGph_gInf_c::getWidthF();
|
||||
xOffset = mDoGph_gInf_c::getSafeMinXF();
|
||||
xSize = viewPort->width * mDoGph_gInf_c::hudAspectScaleUp;
|
||||
#else
|
||||
xOffset = viewPort->x_orig;
|
||||
xSize = viewPort->width;
|
||||
|
||||
+18
-14
@@ -67,6 +67,7 @@
|
||||
|
||||
#include <aurora/aurora.h>
|
||||
#include <aurora/event.h>
|
||||
#include <aurora/gfx.h>
|
||||
#include <aurora/main.h>
|
||||
#include <aurora/dvd.h>
|
||||
#include <dolphin/dvd.h>
|
||||
@@ -80,7 +81,6 @@
|
||||
#include "dusk/audio/DuskAudioSystem.h"
|
||||
#include "dusk/audio/DuskDsp.hpp"
|
||||
#include "dusk/config.hpp"
|
||||
#include "dusk/speedrun.h"
|
||||
#include "dusk/settings.h"
|
||||
#include "dusk/io.hpp"
|
||||
#include "dusk/version.hpp"
|
||||
@@ -120,7 +120,6 @@ bool dusk::IsShuttingDown = false;
|
||||
bool dusk::IsGameLaunched = false;
|
||||
bool dusk::RestartRequested = false;
|
||||
std::filesystem::path dusk::ConfigPath;
|
||||
std::filesystem::path dusk::CachePath;
|
||||
#endif
|
||||
|
||||
void dusk::RequestRestart() noexcept {
|
||||
@@ -515,17 +514,12 @@ int game_main(int argc, char* argv[]) {
|
||||
|
||||
const auto startupLogLevel =
|
||||
static_cast<AuroraLogLevel>(parsed_arg_options["log-level"].as<uint8_t>());
|
||||
const auto dataPaths = dusk::data::initialize_data();
|
||||
dusk::ConfigPath = dataPaths.userPath;
|
||||
dusk::CachePath = dataPaths.cachePath;
|
||||
dusk::InitializeFileLogging(dusk::CachePath, startupLogLevel);
|
||||
dusk::ConfigPath = dusk::data::initialize_data();
|
||||
dusk::InitializeFileLogging(dusk::ConfigPath, startupLogLevel);
|
||||
|
||||
log_build_info();
|
||||
|
||||
dusk::config::LoadFromUserPreferences();
|
||||
if (dusk::getSettings().game.speedrunMode) {
|
||||
dusk::resetForSpeedrunMode();
|
||||
}
|
||||
ApplyCVarOverrides(parsed_arg_options["cvar"]);
|
||||
dusk::crash_reporting::initialize();
|
||||
// TODO: How to handle this?
|
||||
@@ -543,12 +537,10 @@ int game_main(int argc, char* argv[]) {
|
||||
SDL_SetAppMetadata("Dusklight", DUSK_VERSION_STRING, "dev.twilitrealm.dusk");
|
||||
|
||||
{
|
||||
const auto userPathString = dusk::ConfigPath.u8string();
|
||||
const auto cachePathString = dusk::CachePath.u8string();
|
||||
const auto configPathString = dusk::ConfigPath.u8string();
|
||||
AuroraConfig config{};
|
||||
config.appName = dusk::AppName;
|
||||
config.userPath = reinterpret_cast<const char*>(userPathString.c_str());
|
||||
config.cachePath = reinterpret_cast<const char*>(cachePathString.c_str());
|
||||
config.configPath = reinterpret_cast<const char*>(configPathString.c_str());
|
||||
config.vsync = dusk::getSettings().video.enableVsync;
|
||||
config.startFullscreen = dusk::getSettings().video.enableFullscreen;
|
||||
config.windowPosX = -1;
|
||||
@@ -566,6 +558,18 @@ int game_main(int argc, char* argv[]) {
|
||||
config.allowTextureReplacements = true;
|
||||
config.allowTextureDumps = false;
|
||||
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
|
||||
@@ -585,7 +589,7 @@ int game_main(int argc, char* argv[]) {
|
||||
}
|
||||
VISetFrameBufferScale(dusk::getSettings().game.internalResolutionScale.getValue());
|
||||
|
||||
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::EnableHrtf = dusk::getSettings().audio.enableHrtf;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user