Compare commits

...

53 Commits

Author SHA1 Message Date
Luke Street b247eaa5d3 (Temp) Disable map scale 2026-06-08 22:49:58 -06:00
Luke Street a58f64ed80 Update aurora 2026-06-08 22:49:28 -06:00
Luke Street 28a37f6b4f Check for sNoUseDrawMtxPtr in J3DModel::entry 2026-06-08 22:14:34 -06:00
Luke Street 285691cd19 Add -debug-asan presets with AddressSanitizer 2026-06-08 22:14:10 -06:00
Luke Street 93e33ecf1a Cap map resolution multiplier
Resolves #1058
Resolves #1422
Resolves #1668
2026-06-08 00:08:00 -06:00
Reilly Brogan e26fab71d6 Add DUSK_PACKAGE_INSTALL (#1966)
Signed-off-by: Reilly Brogan <reilly@reillybrogan.com>
2026-06-07 23:33:49 -06:00
Luke Street 824389f871 Remove embedded gamecontrollerdb.txt (#2018)
But still load from the data dir if
it exists there (for user overrides)
2026-06-07 22:30:07 -06:00
Luke Street aa42265041 Fix Impaz expression animation OOB read (#2017)
Resolves #1152
2026-06-07 22:29:52 -06:00
BoLThompson 8b7ed4b5da Interpolation fixes (fishing rod, key door chains, hookshot chain) (#2008)
* fishing rod line (item and minigame) interpolated

* small key, big key door chains interpolated

* hookshot chain interpolated
2026-06-08 00:28:48 -04:00
SuperDude88 f33746f373 Alternate Config Variable Migration Method (#1577)
* Use Explicit Template Specialization

- Move migration of FrameInterpMode to use a unique specialization of loadFromJson

This avoids coding special cases into the main template, which I think is more sustainable in the long-run if we need to migrate other settings ever

* Error for Default Migration

- Add error message in the config log for default migration

Not a fatal, just a clear signal that you should handle your enum cases explicitly to make sure they're right
2026-06-07 21:39:02 -06:00
Nathan Mena 18c1d11335 Fix mirror mode sign arrows (#1704)
* Manually defined specific Wii messages to be returned when mirror mode is enabled

* Fixed random hanging on some messages
2026-06-07 21:18:58 -06:00
SuperDude88 710f252d53 Fix Respawning in Final Zant Phase (#2013)
Zant was trying to get the player's position before the player was even created

Based on the fix for camera/peahat load order
2026-06-07 21:18:45 -06:00
SuperDude88 2a92a67b87 Fix Mirror Mode Poe Counter (#1997)
Fixes #1817
2026-06-07 21:18:33 -06:00
SuperDude88 0d05f9b75b More Magic Armor Options (#1691)
* More Magic Armor Options

- Add a 3rd option to lose rupees only on damage

* More Choices

- Add cosmetic and double defense options

These both have been requested a couple times

* Shorten Description

The description was very, very long before

* Web Editor Got Me

Fix my syntax
2026-06-07 21:18:23 -06:00
ZipoLabs e27cce0e3c Add Green Chu merging functionality to "Restore Wii 1.0 Glitches" setting (#2000) 2026-06-07 21:18:10 -06:00
SuperDude88 511721f4d5 Fix Ganondorf's Cape Texture (#2016)
* Cape Texture Fix

- Load pos/norm/texcoord data directly from the REL

Before the hardcoded array was LE but being treated as BE, now we load it directly from the REL so treating it as BE is the correct behavior

* Fix Cape Tearing

- Update the cached textures when the cape is torn, reset the texture when creating the actor
2026-06-07 21:14:10 -06:00
Luke Street 08e0f4a2ee Update aurora & remove old pipeline cache handling 2026-06-06 09:41:07 -06:00
doop 7a900471bf Clamp flycam FOV (#1996) 2026-06-05 17:05:54 -04:00
MelonSpeedruns d9d9966f8f Time Freezing Camera (#1787)
Thanks to @bkd89 for the idea!

Co-authored-by: MelonSpeedruns <melonspeedruns@stratobox.net>
2026-06-05 00:17:06 -06:00
Kevin Lema 8705e75b9d Add HUD scale setting (#1387)
* Add HUD scale setting

Adds a "HUD Scale" preference (50%–200%) that scales the gameplay HUD
(hearts, magic/lantern meter, light drops, rupees/keys, action buttons
and the mini-map) without affecting dialog boxes or menus.

Each HUD group is scaled around its own pane origin and nudged toward
its anchor corner (via dApplyHudCorner) so it stays put against the
screen edge instead of drifting toward the centre when shrunk. The
mini-map is scaled and shifted in d_meter_map so its bottom-left corner
stays anchored. The setting is clamped to a safe range and is a no-op on
non-PC targets. It is disabled in the menu while Minimal HUD is enabled.

Signed-off-by: kevin Lema <kevin.soesto@gmail.com>

* Scale remaining gameplay HUD elements with HUD scale

Extends the HUD Scale setting to the item ammo counters, the lantern oil
  gauge and the small-key counter, and gives the oil/magic meter a reduced
  horizontal anchor pull so it stays on-screen at small scales.

Signed-off-by: kevin Lema <kevin.soesto@gmail.com>

* Update settings.cpp

Signed-off-by: kevin Lema <kevin.soesto@gmail.com>

---------

Signed-off-by: kevin Lema <kevin.soesto@gmail.com>
2026-06-05 00:14:09 -06:00
Luke Street 1b42c4ecac ci: Build Android w/ release & LTO 2026-06-05 00:12:59 -06:00
SuperDude88 24ca190029 Adjust Total Achievement Count (#1924)
- Don't count the glitched achievements towards the total so that they appear over 100%
2026-06-05 00:05:47 -06:00
doop eefa69b53d Re-enable JParticle interpolation and fix emitter direction issue (#1968)
* Re-enable JParticle interpolation

* Ensure emitter direction is valid for JPA interp

Fixes #618.

* Don't `calcWorkData` if we don't need to
2026-06-05 00:05:20 -06:00
Luke Street da3ac9f546 ci: Build with shared vcruntime 2026-06-05 00:03:43 -06:00
Luke Street 7f306fe1ec Update aurora 2026-06-05 00:03:29 -06:00
Luke Street 358de64570 ci: Use mold linker on Linux 2026-06-04 23:30:30 -06:00
Luke Street e484a10018 tvOS fixes 2026-06-04 23:28:44 -06:00
Luke Street 0936115483 Optimize display lists in J3DShapeDraw
This is a stop-gap until DL optimization
is upstreamed to Aurora.
2026-06-04 23:27:30 -06:00
Luke Street b00b7f8f1b More texture caching 2026-06-04 23:21:13 -06:00
Luke Street 08c4442fdf Update aurora 2026-06-03 21:01:39 -06:00
Pieter-Jan Briers 74f20c38e0 Don't send debug groups to Aurora if not enabled (#1984)
Intended together with https://github.com/encounter/aurora/pull/221
2026-06-03 20:58:35 -06:00
Pieter-Jan Briers b7d32918bd Fix a warning (#1985)
Lol
2026-06-03 20:29:54 -06:00
Joshua Trees e99b604dd2 Fix flake.nix for systems where nod must build from source (#1987)
This should actually be fixed upstream, but until then...

See here for more details:

https://github.com/NixOS/nixpkgs/issues/144170

Co-authored-by: Joshua Trees <gh@jtrees.io>
2026-06-03 20:29:41 -06:00
MelonSpeedruns 2376e0102e TPHD Button Fishing (#1949)
Co-authored-by: MelonSpeedruns <melonspeedruns@stratobox.net>
2026-06-03 13:35:51 -04:00
Luke Street 5a9bd6f8dc Update aurora 2026-06-03 02:17:58 -06:00
Luke Street 62a26a639d Bump CMAKE_OSX_DEPLOYMENT_TARGET to 12.0 2026-06-03 02:17:54 -06:00
Luke Street 1a247c2977 Pass CMAKE_OSX_* to libjpeg-turbo build 2026-06-03 02:17:46 -06:00
Luke Street ef122efccd Update aurora 2026-06-03 00:56:44 -06:00
Luke Street deadde352c Update aurora 2026-06-03 00:02:47 -06:00
Luke Street 460b96c709 More Tracy zones 2026-06-03 00:01:34 -06:00
Pieter-Jan Briers f8ba14ea8f Optimize some special kankyo draw packets (housi, snow, odour) (#1970)
* Slight dKankyo_housi_Packet documentation

* Optimize dKyr_drawHousi (twilight squares)

Now a single draw call rather than like 300

* Optimize dKyr_drawSnow

Snowpeak stonks rising

* Optimize dKyr_odour_draw
2026-06-02 23:47:34 -06:00
Irastris bd9b81f700 Add mouse input option for the third-person camera (#1011)
* Untie existing mouse logic from gyro

* A bit more mouse cleanup before I start building off it

* Rebase and last bit of cleanup

* Fix rebase mistake, don't apply invertFirstPerson to gyro or mouse input

* Remove the deprecated ImGui toast system

* Add Mouse Camera option in preparation for its use

* WIP, add mouse controls for the third-person camera

* Various helpText revisions

* Enable free camera on horseback

* Untie mouse camera and free camera options
Either being enabled now allows the underlying freecam logic to run

* Allow simultaneous C-stick and mouse input

* Combine mouse sensitivities for both aim and camera

* Add option for inverting mouse Y

* Refactor cursor visibility handling

* Tighten aim capture condition and constrain cursor to window region

* Tidying my trash

* Last bit of housekeeping so I'm satisfied

* Don't write code while sleep deprived

* Fix my sloppy merge and a few helpText updates

* Disable control stick aim when mouse aim is active

* Use same conditions for cursor grabbing as for capture
2026-06-01 23:37:53 -06:00
Reilly Brogan b531936a1f linux: Add metainfo file (#1860)
* linux: Add metainfo file

Split from https://github.com/TwilitRealm/dusklight/pull/1191 and adjusted for the correct appId and to remove any trademarks.

Credit to @Gabantax

Signed-off-by: Reilly Brogan <reilly@reillybrogan.com>

* Update metainfo per suggestions

Signed-off-by: Reilly Brogan <reilly@reillybrogan.com>

---------

Signed-off-by: Reilly Brogan <reilly@reillybrogan.com>
2026-06-01 20:24:02 -06:00
Pieter-Jan Briers 21692d5a78 Fix portable mode Unicode (#1893)
* Fix portable mode Unicode

Fixes https://github.com/TwilitRealm/dusklight/issues/1839

* Use path_from_utf8 instead

Huh yeah sure we have that apparently
2026-06-01 20:23:28 -06:00
Reilly Brogan 7af51e53bd Update aurora and adapt for libzstd changes (#1950)
* Update aurora and adapt for libzstd changes

Signed-off-by: Reilly Brogan <reilly@reillybrogan.com>

* Fix android build failure with zstd

Signed-off-by: Reilly Brogan <reilly@reillybrogan.com>

* Another attempt at fixing Android

Signed-off-by: Reilly Brogan <reilly@reillybrogan.com>

---------

Signed-off-by: Reilly Brogan <reilly@reillybrogan.com>
2026-06-01 20:23:13 -06:00
qubitnano bd90c3fc69 flake.nix: devendor aurora, add BUILD_SHARED_LIBS=OFF (#1956)
* flake.nix: devendor aurora

* flake.nix: nixfmt

* flake.nix: add BUILD_SHARED_LIBS=OFF
2026-06-01 20:22:45 -06:00
Luke Street 37abcaf616 Use BUILD_SHARED_LIBS=OFF on base linux/macos presets 2026-05-31 21:30:25 -06:00
Luke Street b26f3f7f51 Update aurora & fix rebuilding on iOS reconfigure 2026-05-31 17:18:11 -06:00
Pieter-Jan Briers 81caa89e12 Update Aurora & use new texture replacements API (#1935)
Cherry picked from TPHD branch

Co-authored-by: Luke Street <luke@street.dev>
2026-05-30 19:57:17 -06:00
Luke Street bc3cdcc955 Revert "Adds a new cheat that let you transform from the start of the game. (…" (#1927)
This reverts commit 62c19c0f64.
2026-05-29 21:20:15 -06:00
tomlube bf0dc85468 Revert "Added Sword and Shield skip Achievement" (#1917) 2026-05-29 15:14:05 -04:00
tomlube 656346a900 Merge pull request #1909 from 5upern1ce/sword-and-shield-skip
Added Sword and Shield skip Achievement
2026-05-29 15:11:46 -04:00
Supern_Ice 5269eadfaf Added Sword and Shield skip Achievement 2026-05-29 15:26:26 +01:00
88 changed files with 2288 additions and 3127 deletions
+1 -1
View File
@@ -52,7 +52,7 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: | run: |
sudo apt-get update sudo apt-get update
sudo apt-get -y install ninja-build clang lld openssl libcurl4-openssl-dev \ sudo apt-get -y install ninja-build clang lld mold openssl libcurl4-openssl-dev \
zlib1g-dev libglu1-mesa-dev libdbus-1-dev libvulkan-dev libxi-dev libxrandr-dev libasound2-dev \ zlib1g-dev libglu1-mesa-dev libdbus-1-dev libvulkan-dev libxi-dev libxrandr-dev libasound2-dev \
libpulse-dev libudev-dev libpng-dev libncurses5-dev libx11-xcb-dev libfreetype-dev \ libpulse-dev libudev-dev libpng-dev libncurses5-dev libx11-xcb-dev libfreetype-dev \
libxinerama-dev libxcursor-dev python3-markupsafe libgtk-3-dev libssl-dev \ libxinerama-dev libxcursor-dev python3-markupsafe libgtk-3-dev libssl-dev \
+62 -7
View File
@@ -126,6 +126,33 @@ set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
set_property(GLOBAL PROPERTY USE_FOLDERS ON) set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER "_cmake") set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER "_cmake")
option(ENABLE_ASAN "Enable AddressSanitizer" OFF)
if (ENABLE_ASAN)
if (CMAKE_C_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC" AND
CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/fsanitize=address>)
add_link_options(/fsanitize=address /INCREMENTAL:NO)
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "ProgramDatabase")
foreach (_lang C CXX)
foreach (_rtc_flag /RTC1 /RTCc /RTCs /RTCu)
string(REPLACE "${_rtc_flag}" "" CMAKE_${_lang}_FLAGS_DEBUG "${CMAKE_${_lang}_FLAGS_DEBUG}")
endforeach ()
endforeach ()
elseif (CMAKE_C_COMPILER_FRONTEND_VARIANT STREQUAL "GNU" AND
CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU")
add_compile_options(
$<$<COMPILE_LANGUAGE:C,CXX,OBJC,OBJCXX>:-fsanitize=address>
$<$<COMPILE_LANGUAGE:C,CXX,OBJC,OBJCXX>:-fno-omit-frame-pointer>
)
add_link_options(-fsanitize=address)
else ()
message(FATAL_ERROR "ENABLE_ASAN requires GNU-like or MSVC-like C/C++ compiler frontends")
endif ()
add_compile_definitions(NDEBUG_SANITIZER) # Avoids absl issue with SwissTable debug code
message(STATUS "dusklight: Enabled AddressSanitizer")
endif ()
if (CMAKE_SYSTEM_NAME STREQUAL Linux) if (CMAKE_SYSTEM_NAME STREQUAL Linux)
set(DAWN_USE_WAYLAND ON CACHE BOOL "Enable support for Wayland surface" FORCE) set(DAWN_USE_WAYLAND ON CACHE BOOL "Enable support for Wayland surface" FORCE)
endif () endif ()
@@ -137,11 +164,19 @@ target_compile_definitions(aurora_mtx PRIVATE MTX_USE_PS=1)
add_subdirectory(libs/freeverb) add_subdirectory(libs/freeverb)
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
set(DUSK_GFX_DEBUG_GROUPS_DEFAULT ON)
else ()
set(DUSK_GFX_DEBUG_GROUPS_DEFAULT OFF)
endif ()
option(DUSK_BUILD_WARNINGS "Enable compiler warnings (off by default)") option(DUSK_BUILD_WARNINGS "Enable compiler warnings (off by default)")
option(DUSK_SELECTED_OPT "If on, selected parts of the project will be compiled with optimizations on Debug, intending to make the game run at 30 FPS. Note for MSVC: you will need to remove '/RTC1' from your debug flags in CMake.") option(DUSK_SELECTED_OPT "If on, selected parts of the project will be compiled with optimizations on Debug, intending to make the game run at 30 FPS. Note for MSVC: you will need to remove '/RTC1' from your debug flags in CMake.")
option(DUSK_MOVIE_SUPPORT "If on, compile against libjpeg-turbo to enable THP file decoding" ON) option(DUSK_MOVIE_SUPPORT "If on, compile against libjpeg-turbo to enable THP file decoding" ON)
option(DUSK_ENABLE_UPDATE_CHECKER "Enable update checking support" ON) option(DUSK_ENABLE_UPDATE_CHECKER "Enable update checking support" ON)
option(DUSK_ENABLE_SENTRY_NATIVE "Enable sentry-native crash reporting support" OFF) option(DUSK_ENABLE_SENTRY_NATIVE "Enable sentry-native crash reporting support" OFF)
option(DUSK_PACKAGE_INSTALL "Install Dusklight with a Linux-native file structure" OFF)
option(DUSK_GFX_DEBUG_GROUPS "Report debug groups to the native graphics API" ${DUSK_GFX_DEBUG_GROUPS_DEFAULT})
set(DUSK_SENTRY_DSN "" CACHE STRING "Sentry DSN") set(DUSK_SENTRY_DSN "" CACHE STRING "Sentry DSN")
set(DUSK_SENTRY_ENVIRONMENT "development" CACHE STRING "Sentry environment") set(DUSK_SENTRY_ENVIRONMENT "development" CACHE STRING "Sentry environment")
@@ -189,6 +224,8 @@ if (DUSK_MOVIE_SUPPORT)
CMAKE_MSVC_RUNTIME_LIBRARY CMAKE_MSVC_RUNTIME_LIBRARY
CMAKE_MSVC_DEBUG_INFORMATION_FORMAT CMAKE_MSVC_DEBUG_INFORMATION_FORMAT
CMAKE_OSX_ARCHITECTURES CMAKE_OSX_ARCHITECTURES
CMAKE_OSX_DEPLOYMENT_TARGET
CMAKE_OSX_SYSROOT
DEPLOYMENT_TARGET DEPLOYMENT_TARGET
ENABLE_ARC ENABLE_ARC
ENABLE_BITCODE ENABLE_BITCODE
@@ -247,7 +284,6 @@ elseif (MSVC)
add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/utf-8>) add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/utf-8>)
endif () endif ()
include(FetchContent) include(FetchContent)
# Declare all dependencies first so CMake can download them in parallel # Declare all dependencies first so CMake can download them in parallel
@@ -342,9 +378,7 @@ set(GAME_INCLUDE_DIRS
find_package(Threads REQUIRED) find_package(Threads REQUIRED)
set(GAME_LIBS aurora::core aurora::gx aurora::gd aurora::si aurora::vi aurora::pad aurora::mtx aurora::os aurora::dvd set(GAME_LIBS aurora::core aurora::gx aurora::gd aurora::si aurora::vi aurora::pad aurora::mtx aurora::os aurora::dvd
aurora::card freeverb cxxopts::cxxopts absl::flat_hash_map nlohmann_json::nlohmann_json TracyClient fmt::fmt aurora::card freeverb cxxopts::cxxopts absl::flat_hash_map nlohmann_json::nlohmann_json TracyClient fmt::fmt
Threads::Threads) Threads::Threads zstd::libzstd)
list(APPEND GAME_LIBS libzstd_static)
if (DUSK_ENABLE_SENTRY_NATIVE) if (DUSK_ENABLE_SENTRY_NATIVE)
list(APPEND GAME_LIBS sentry) list(APPEND GAME_LIBS sentry)
@@ -416,6 +450,16 @@ if(ANDROID)
list(APPEND GAME_COMPILE_DEFS TARGET_ANDROID=1) list(APPEND GAME_COMPILE_DEFS TARGET_ANDROID=1)
endif () endif ()
if (DUSK_PACKAGE_INSTALL)
include(GNUInstallDirs)
list(APPEND GAME_COMPILE_DEFS DUSK_ASSET_DIR="${CMAKE_INSTALL_FULL_DATADIR}/dusklight/")
endif ()
if (DUSK_GFX_DEBUG_GROUPS)
list(APPEND GAME_COMPILE_DEFS DUSK_GFX_DEBUG_GROUPS=1)
target_compile_definitions(aurora_gx PRIVATE AURORA_GFX_DEBUG_GROUPS)
endif ()
# game_debug is for game code files that we know work when compiled with DEBUG=1 # game_debug is for game code files that we know work when compiled with DEBUG=1
# Of course, if building a release build, this distinction is irrelevant # Of course, if building a release build, this distinction is irrelevant
set(GAME_DEBUG_FILES set(GAME_DEBUG_FILES
@@ -472,6 +516,9 @@ if(ANDROID)
else () else ()
add_executable(dusklight ${DUSK_FILES}) add_executable(dusklight ${DUSK_FILES})
endif () endif ()
if (ENABLE_ASAN)
target_sources(dusklight PRIVATE src/dusk/asan_options.c)
endif ()
target_compile_definitions(dusklight PRIVATE ${GAME_COMPILE_DEFS}) target_compile_definitions(dusklight PRIVATE ${GAME_COMPILE_DEFS})
target_include_directories(dusklight PRIVATE ${GAME_INCLUDE_DIRS}) target_include_directories(dusklight PRIVATE ${GAME_INCLUDE_DIRS})
@@ -634,12 +681,20 @@ set(EXTRA_TARGETS "")
if (TARGET crashpad_handler) if (TARGET crashpad_handler)
list(APPEND EXTRA_TARGETS crashpad_handler) list(APPEND EXTRA_TARGETS crashpad_handler)
endif () endif ()
install(TARGETS ${BINARY_TARGETS} ${EXTRA_TARGETS} DESTINATION ${CMAKE_INSTALL_PREFIX}) if (DUSK_PACKAGE_INSTALL)
install(TARGETS ${BINARY_TARGETS} ${EXTRA_TARGETS} DESTINATION ${CMAKE_INSTALL_BINDIR})
else()
install(TARGETS ${BINARY_TARGETS} ${EXTRA_TARGETS} DESTINATION ${CMAKE_INSTALL_PREFIX})
endif()
aurora_install_runtime_dlls(dusklight ${CMAKE_INSTALL_PREFIX}) aurora_install_runtime_dlls(dusklight ${CMAKE_INSTALL_PREFIX})
if (NOT APPLE) if (NOT APPLE)
install(DIRECTORY ${CMAKE_SOURCE_DIR}/res DESTINATION ${CMAKE_INSTALL_PREFIX}) if (DUSK_PACKAGE_INSTALL)
install(DIRECTORY ${CMAKE_SOURCE_DIR}/res DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/dusklight)
else()
install(DIRECTORY ${CMAKE_SOURCE_DIR}/res DESTINATION ${CMAKE_INSTALL_PREFIX})
endif()
endif () endif ()
if (CMAKE_BUILD_TYPE STREQUAL Debug OR CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo) if (CMAKE_BUILD_TYPE STREQUAL Debug OR CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo AND NOT DUSK_PACKAGE_INSTALL)
set(DEBUG_FILES_LIST "") set(DEBUG_FILES_LIST "")
foreach (target IN LISTS BINARY_TARGETS EXTRA_TARGETS) foreach (target IN LISTS BINARY_TARGETS EXTRA_TARGETS)
get_target_output_name(${target} output_name) get_target_output_name(${target} output_name)
+111 -20
View File
@@ -19,7 +19,19 @@
"hidden": true, "hidden": true,
"cacheVariables": { "cacheVariables": {
"CMAKE_BUILD_TYPE": "RelWithDebInfo", "CMAKE_BUILD_TYPE": "RelWithDebInfo",
"CMAKE_MSVC_RUNTIME_LIBRARY": "MultiThreaded" "CMAKE_MSVC_RUNTIME_LIBRARY": "MultiThreadedDLL"
}
},
{
"name": "release",
"hidden": true,
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"CMAKE_MSVC_RUNTIME_LIBRARY": "MultiThreadedDLL",
"CMAKE_INTERPROCEDURAL_OPTIMIZATION": {
"type": "BOOL",
"value": true
}
} }
}, },
{ {
@@ -40,12 +52,26 @@
} }
} }
}, },
{
"name": "asan",
"hidden": true,
"cacheVariables": {
"ENABLE_ASAN": {
"type": "BOOL",
"value": true
}
}
},
{ {
"name": "linux-default", "name": "linux-default",
"displayName": "Linux (default)", "displayName": "Linux (default)",
"generator": "Ninja", "generator": "Ninja",
"binaryDir": "${sourceDir}/build/${presetName}", "binaryDir": "${sourceDir}/build/${presetName}",
"cacheVariables": { "cacheVariables": {
"BUILD_SHARED_LIBS": {
"type": "BOOL",
"value": false
},
"CMAKE_INSTALL_PREFIX": "${sourceDir}/build/install" "CMAKE_INSTALL_PREFIX": "${sourceDir}/build/install"
}, },
"vendor": { "vendor": {
@@ -67,6 +93,15 @@
"linux-default" "linux-default"
] ]
}, },
{
"name": "linux-default-debug-asan",
"displayName": "Linux (default) Debug ASan",
"inherits": [
"debug",
"linux-default",
"asan"
]
},
{ {
"name": "linux-default-relwithdebinfo", "name": "linux-default-relwithdebinfo",
"displayName": "Linux (default) RelWithDebInfo", "displayName": "Linux (default) RelWithDebInfo",
@@ -94,6 +129,15 @@
"linux-clang" "linux-clang"
] ]
}, },
{
"name": "linux-clang-debug-asan",
"displayName": "Linux (Clang) Debug ASan",
"inherits": [
"debug",
"linux-clang",
"asan"
]
},
{ {
"name": "linux-clang-relwithdebinfo", "name": "linux-clang-relwithdebinfo",
"displayName": "Linux (Clang) RelWithDebInfo", "displayName": "Linux (Clang) RelWithDebInfo",
@@ -132,6 +176,15 @@
"windows-msvc" "windows-msvc"
] ]
}, },
{
"name": "windows-msvc-debug-asan",
"displayName": "Windows (MSVC) Debug ASan",
"inherits": [
"debug",
"windows-msvc",
"asan"
]
},
{ {
"name": "windows-msvc-relwithdebinfo", "name": "windows-msvc-relwithdebinfo",
"displayName": "Windows (MSVC) RelWithDebInfo", "displayName": "Windows (MSVC) RelWithDebInfo",
@@ -201,6 +254,10 @@
"generator": "Ninja", "generator": "Ninja",
"binaryDir": "${sourceDir}/build/${presetName}", "binaryDir": "${sourceDir}/build/${presetName}",
"cacheVariables": { "cacheVariables": {
"BUILD_SHARED_LIBS": {
"type": "BOOL",
"value": false
},
"CMAKE_INSTALL_PREFIX": "${sourceDir}/build/install" "CMAKE_INSTALL_PREFIX": "${sourceDir}/build/install"
}, },
"vendor": { "vendor": {
@@ -219,6 +276,15 @@
"macos-default" "macos-default"
] ]
}, },
{
"name": "macos-default-debug-asan",
"displayName": "macOS (default) Debug ASan",
"inherits": [
"debug",
"macos-default",
"asan"
]
},
{ {
"name": "macos-default-relwithdebinfo", "name": "macos-default-relwithdebinfo",
"displayName": "macOS (default) RelWithDebInfo", "displayName": "macOS (default) RelWithDebInfo",
@@ -284,24 +350,21 @@
"type": "BOOL", "type": "BOOL",
"value": false "value": false
}, },
"ENABLE_ARC": {
"type": "BOOL",
"value": false
},
"Rust_CARGO_TARGET": "aarch64-apple-tvos", "Rust_CARGO_TARGET": "aarch64-apple-tvos",
"Rust_TOOLCHAIN": "nightly", "Rust_TOOLCHAIN": "nightly",
"BUILD_SHARED_LIBS": { "BUILD_SHARED_LIBS": {
"type": "BOOL", "type": "BOOL",
"value": false "value": false
}, },
"CMAKE_DISABLE_FIND_PACKAGE_BZip2": { "CMAKE_DISABLE_FIND_PACKAGE_PkgConfig": {
"type": "BOOL", "type": "BOOL",
"value": true "value": true
}, },
"CMAKE_DISABLE_FIND_PACKAGE_LibLZMA": { "CMAKE_IGNORE_PREFIX_PATH": "/opt/homebrew"
"type": "BOOL",
"value": true
},
"CMAKE_DISABLE_FIND_PACKAGE_zstd": {
"type": "BOOL",
"value": true
}
}, },
"vendor": { "vendor": {
"microsoft.com/VisualStudioSettings/CMake/1.0": { "microsoft.com/VisualStudioSettings/CMake/1.0": {
@@ -327,8 +390,14 @@
"type": "BOOL", "type": "BOOL",
"value": false "value": false
}, },
"AURORA_SDL3_VERSION": "3.4.8", "CMAKE_DISABLE_FIND_PACKAGE_PkgConfig": {
"AURORA_SDL3_REF": "refs/tags/release-3.4.8" "type": "BOOL",
"value": true
},
"CMAKE_DISABLE_FIND_PACKAGE_zstd": {
"type": "BOOL",
"value": true
}
} }
}, },
{ {
@@ -356,7 +425,8 @@
"hidden": true, "hidden": true,
"inherits": [ "inherits": [
"android-base", "android-base",
"ci" "ci",
"release"
], ],
"cacheVariables": { "cacheVariables": {
"DUSK_ENABLE_SENTRY_NATIVE": { "DUSK_ENABLE_SENTRY_NATIVE": {
@@ -384,7 +454,8 @@
"ci" "ci"
], ],
"cacheVariables": { "cacheVariables": {
"AURORA_SDL3_PROVIDER": "vendor" "AURORA_SDL3_PROVIDER": "vendor",
"CMAKE_LINKER_TYPE": "MOLD"
} }
}, },
{ {
@@ -413,12 +484,8 @@
"type": "BOOL", "type": "BOOL",
"value": true "value": true
}, },
"CMAKE_OSX_DEPLOYMENT_TARGET": "11.0", "CMAKE_OSX_DEPLOYMENT_TARGET": "12.0",
"CMAKE_IGNORE_PREFIX_PATH": "/opt/homebrew", "CMAKE_IGNORE_PREFIX_PATH": "/opt/homebrew"
"BUILD_SHARED_LIBS": {
"type": "BOOL",
"value": false
}
} }
}, },
{ {
@@ -508,6 +575,12 @@
"description": "Linux (default) debug build", "description": "Linux (default) debug build",
"displayName": "Linux (default) Debug" "displayName": "Linux (default) Debug"
}, },
{
"name": "linux-default-debug-asan",
"configurePreset": "linux-default-debug-asan",
"description": "Linux (default) debug build with AddressSanitizer",
"displayName": "Linux (default) Debug ASan"
},
{ {
"name": "linux-default-relwithdebinfo", "name": "linux-default-relwithdebinfo",
"configurePreset": "linux-default-relwithdebinfo", "configurePreset": "linux-default-relwithdebinfo",
@@ -520,6 +593,12 @@
"description": "Linux (Clang) debug build", "description": "Linux (Clang) debug build",
"displayName": "Linux (Clang) Debug" "displayName": "Linux (Clang) Debug"
}, },
{
"name": "linux-clang-debug-asan",
"configurePreset": "linux-clang-debug-asan",
"description": "Linux (Clang) debug build with AddressSanitizer",
"displayName": "Linux (Clang) Debug ASan"
},
{ {
"name": "linux-clang-relwithdebinfo", "name": "linux-clang-relwithdebinfo",
"configurePreset": "linux-clang-relwithdebinfo", "configurePreset": "linux-clang-relwithdebinfo",
@@ -532,6 +611,12 @@
"description": "macOS debug build", "description": "macOS debug build",
"displayName": "macOS Debug" "displayName": "macOS Debug"
}, },
{
"name": "macos-default-debug-asan",
"configurePreset": "macos-default-debug-asan",
"description": "macOS debug build with AddressSanitizer",
"displayName": "macOS Debug ASan"
},
{ {
"name": "macos-default-relwithdebinfo", "name": "macos-default-relwithdebinfo",
"configurePreset": "macos-default-relwithdebinfo", "configurePreset": "macos-default-relwithdebinfo",
@@ -589,6 +674,12 @@
"description": "Windows (MSVC) debug build", "description": "Windows (MSVC) debug build",
"displayName": "Windows (MSVC) Debug" "displayName": "Windows (MSVC) Debug"
}, },
{
"name": "windows-msvc-debug-asan",
"configurePreset": "windows-msvc-debug-asan",
"description": "Windows (MSVC) debug build with AddressSanitizer",
"displayName": "Windows (MSVC) Debug ASan"
},
{ {
"name": "windows-msvc-relwithdebinfo", "name": "windows-msvc-relwithdebinfo",
"configurePreset": "windows-msvc-relwithdebinfo", "configurePreset": "windows-msvc-relwithdebinfo",
+4
View File
@@ -180,6 +180,7 @@ cmake --build --preset macos-default-relwithdebinfo
Alternate presets available: Alternate presets available:
* `macos-default-debug`: Clang, Debug * `macos-default-debug`: Clang, Debug
* `macos-default-debug-asan`: Clang, Debug, AddressSanitizer
**ninja (Linux)** **ninja (Linux)**
@@ -191,8 +192,10 @@ cmake --build --preset linux-default-relwithdebinfo
Alternate presets available: Alternate presets available:
* `linux-default-debug`: GCC, Debug * `linux-default-debug`: GCC, Debug
* `linux-default-debug-asan`: GCC, Debug, AddressSanitizer
* `linux-clang-relwithdebinfo`: Clang, RelWithDebInfo * `linux-clang-relwithdebinfo`: Clang, RelWithDebInfo
* `linux-clang-debug`: Clang, Debug * `linux-clang-debug`: Clang, Debug
* `linux-clang-debug-asan`: Clang, Debug, AddressSanitizer
**ninja (Windows)** **ninja (Windows)**
@@ -204,6 +207,7 @@ cmake --build --preset windows-msvc-relwithdebinfo
Alternate presets available: Alternate presets available:
* `windows-msvc-debug`: MSVC, Debug * `windows-msvc-debug`: MSVC, Debug
* `windows-msvc-debug-asan`: MSVC, Debug, AddressSanitizer
* `windows-clang-relwithdebinfo`: Clang-cl, RelWithDebInfo * `windows-clang-relwithdebinfo`: Clang-cl, RelWithDebInfo
* `windows-clang-debug`: Clang-cl, Debug * `windows-clang-debug`: Clang-cl, Debug
+1 -1
+3
View File
@@ -1432,6 +1432,7 @@ set(DUSK_FILES
src/dusk/game_clock.cpp src/dusk/game_clock.cpp
src/dusk/globals.cpp src/dusk/globals.cpp
src/dusk/gyro.cpp src/dusk/gyro.cpp
src/dusk/mouse.cpp
src/dusk/gamepad_color.cpp src/dusk/gamepad_color.cpp
src/dusk/autosave.cpp src/dusk/autosave.cpp
src/dusk/http/http.hpp src/dusk/http/http.hpp
@@ -1442,6 +1443,8 @@ set(DUSK_FILES
src/dusk/speedrun.cpp src/dusk/speedrun.cpp
src/dusk/string.cpp src/dusk/string.cpp
src/dusk/stubs.cpp src/dusk/stubs.cpp
include/dusk/texture_replacements.hpp
src/dusk/texture_replacements.cpp
src/dusk/update_check.cpp src/dusk/update_check.cpp
src/dusk/update_check.hpp src/dusk/update_check.hpp
#src/dusk/m_Do_ext_dusk.cpp #src/dusk/m_Do_ext_dusk.cpp
+32
View File
@@ -0,0 +1,32 @@
From f69d29614644f9963f5cb3f828b58575d60a1c5a Mon Sep 17 00:00:00 2001
From: Joshua Trees <gh@jtrees.io>
Date: Thu, 4 Jun 2026 01:04:04 +0100
Subject: [PATCH] fix cmake paths
---
cmake/nodConfig.cmake.in | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/cmake/nodConfig.cmake.in b/cmake/nodConfig.cmake.in
index 0969382..2a24a88 100644
--- a/cmake/nodConfig.cmake.in
+++ b/cmake/nodConfig.cmake.in
@@ -1,12 +1,12 @@
@PACKAGE_INIT@
-set(_nod_libdir "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_LIBDIR@")
-set(_nod_incdir "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_INCLUDEDIR@")
+set(_nod_libdir "@CMAKE_INSTALL_FULL_LIBDIR@")
+set(_nod_incdir "@CMAKE_INSTALL_FULL_INCLUDEDIR@")
if (NOT TARGET nod::nod_shared AND NOT TARGET nod::nod_static)
# Shared library
if (WIN32)
- set(_nod_dll "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_BINDIR@/${CMAKE_SHARED_LIBRARY_PREFIX}nod${CMAKE_SHARED_LIBRARY_SUFFIX}")
+ set(_nod_dll "@CMAKE_INSTALL_FULL_BINDIR@/${CMAKE_SHARED_LIBRARY_PREFIX}nod${CMAKE_SHARED_LIBRARY_SUFFIX}")
set(_nod_implib "${_nod_libdir}/${CMAKE_IMPORT_LIBRARY_PREFIX}nod${CMAKE_IMPORT_LIBRARY_SUFFIX}")
if (EXISTS "${_nod_dll}")
add_library(nod::nod_shared SHARED IMPORTED)
--
2.53.0
+127 -115
View File
@@ -57,12 +57,22 @@
inherit (pkgs.stdenv.hostPlatform) isDarwin; inherit (pkgs.stdenv.hostPlatform) isDarwin;
hasNodPrebuilt = nodPrebuiltInfo ? ${system}; hasNodPrebuilt = nodPrebuiltInfo ? ${system};
aurora = pkgs.fetchFromGitHub { aurora = builtins.pathExists "${self}/extern/aurora/CMakeLists.txt";
owner = "encounter"; needSubmodules = ''
repo = "aurora"; dusklight: The aurora submodule is not vendored. Add submodules=1 to build.
rev = "10006618ee493f248b8597e4dfa1d2871d76a1d9";
hash = "sha256-lY2xuVyB7aPJ9+2wwLRB3F5U/BuPSxdSpegdG+qNd9o="; As a flake input:
};
dusklight.url = "git+https://github.com/TwilitRealm/dusklight?ref=main&submodules=1";
nix command:
nix run 'git+https://github.com/TwilitRealm/dusklight?submodules=1'
Local checkout:
nix run '.?submodules=1#dusklight'
'';
dawn = pkgs.fetchzip { dawn = pkgs.fetchzip {
url = "https://github.com/encounter/dawn-build/releases/download/${dawnVersion}/dawn-${dawnInfo.${system}.triple}.tar.gz"; url = "https://github.com/encounter/dawn-build/releases/download/${dawnVersion}/dawn-${dawnInfo.${system}.triple}.tar.gz";
@@ -86,6 +96,7 @@
rev = nodVersion; rev = nodVersion;
hash = "sha256-+zrtVzjo0+X/6uMcNUn1+FaSR+jOhrcQSDNBFjw0NDs="; hash = "sha256-+zrtVzjo0+X/6uMcNUn1+FaSR+jOhrcQSDNBFjw0NDs=";
}; };
patches = [ ./fix-cmake-paths.patch ];
cargoDeps = pkgs.rustPlatform.importCargoLock { cargoDeps = pkgs.rustPlatform.importCargoLock {
lockFile = "${finalAttrs.src}/Cargo.lock"; lockFile = "${finalAttrs.src}/Cargo.lock";
}; };
@@ -153,119 +164,120 @@
}; };
}; };
dusklight = pkgs.stdenv.mkDerivation { dusklight =
pname = "dusklight"; if !aurora then
version = versionSuffix; throw needSubmodules
src = ./.; else
pkgs.stdenv.mkDerivation {
pname = "dusklight";
version = versionSuffix;
src = ./.;
postUnpack = '' postUnpack = ''
chmod -R u+w "$sourceRoot" chmod -R u+w "$sourceRoot"
rm -rf "$sourceRoot/extern/aurora" substituteInPlace "$sourceRoot/extern/aurora/CMakeLists.txt" \
mkdir -p "$sourceRoot/extern" --replace-warn "add_subdirectory(tests)" ""
cp -r ${aurora} "$sourceRoot/extern/aurora"
chmod -R u+w "$sourceRoot/extern/aurora"
substituteInPlace "$sourceRoot/extern/aurora/CMakeLists.txt" \
--replace-warn "add_subdirectory(tests)" ""
'';
nativeBuildInputs = [
pkgs.cmake
pkgs.ninja
pkgs.pkg-config
pkgs.python3
pkgs.python3Packages.markupsafe
]
++ lib.optionals (!isDarwin) [ pkgs.autoPatchelfHook ];
buildInputs = [
pkgs.sdl3
pkgs.freetype
pkgs.zstd
pkgs.cxxopts
pkgs.nlohmann_json
pkgs.xxHash
pkgs.abseil-cpp
pkgs.zlib
pkgs.libpng
pkgs.libjpeg_turbo
pkgs.curl
pkgs.openssl
]
++ lib.optionals isDarwin [
pkgs.apple-sdk_15
pkgs.libiconv
]
++ lib.optionals (!isDarwin) [
pkgs.libGL
pkgs.libGLU
pkgs.libglvnd
pkgs.vulkan-loader
pkgs.libX11
pkgs.libxcb
pkgs.libXcursor
pkgs.libxi
pkgs.libxrandr
pkgs.libxscrnsaver
pkgs.libxtst
pkgs.libxinerama
pkgs.libxkbcommon
pkgs.wayland
pkgs.libdecor
pkgs.alsa-lib
pkgs.libpulseaudio
pkgs.pipewire
pkgs.dbus
pkgs.udev
pkgs.libusb1
pkgs.libunwind
pkgs.gtk3
];
cmakeBuildType = "RelWithDebInfo";
ninjaFlags = [ "dusklight" ];
cmakeFlags = [
"-DDUSK_VERSION_OVERRIDE=${versionSuffix}"
"-DFETCHCONTENT_FULLY_DISCONNECTED=ON"
"-DAURORA_DAWN_PROVIDER=package"
"-DAURORA_DAWN_LINKAGE=static"
"-DAURORA_NOD_PROVIDER=package"
"-DAURORA_NOD_LINKAGE=static"
"-DAURORA_SDL3_PROVIDER=system"
]
++ lib.mapAttrsToList (key: src: "-DFETCHCONTENT_SOURCE_DIR_${key}=${src}") fetchContentDirs;
installPhase =
if isDarwin then
''
runHook preInstall
mkdir -p "$out/Applications"
cp -r Dusklight.app "$out/Applications/Dusklight.app"
runHook postInstall
''
else
''
runHook preInstall
install -Dm755 dusklight "$out/bin/dusklight"
cp -r "$src/res" "$out/bin/res"
install -Dm644 "$src/platforms/freedesktop/dev.twilitrealm.dusk.desktop" \
"$out/share/applications/dev.twilitrealm.dusk.desktop"
for size in 16 32 48 64 128 256 512 1024; do
install -Dm644 "$src/platforms/freedesktop/''${size}x''${size}/apps/dev.twilitrealm.dusk.png" \
"$out/share/icons/hicolor/''${size}x''${size}/apps/dev.twilitrealm.dusk.png"
done
runHook postInstall
''; '';
dontStrip = true; nativeBuildInputs = [
pkgs.cmake
pkgs.ninja
pkgs.pkg-config
pkgs.python3
pkgs.python3Packages.markupsafe
]
++ lib.optionals (!isDarwin) [ pkgs.autoPatchelfHook ];
meta = { buildInputs = [
description = "Dusklight native PC port of the Twilight Princess decompilation"; pkgs.sdl3
homepage = "https://github.com/zeldaret/tp"; pkgs.freetype
platforms = supportedSystems; pkgs.zstd
mainProgram = "dusklight"; pkgs.cxxopts
}; pkgs.nlohmann_json
}; pkgs.xxHash
pkgs.abseil-cpp
pkgs.zlib
pkgs.libpng
pkgs.libjpeg_turbo
pkgs.curl
pkgs.openssl
]
++ lib.optionals isDarwin [
pkgs.apple-sdk_15
pkgs.libiconv
]
++ lib.optionals (!isDarwin) [
pkgs.libGL
pkgs.libGLU
pkgs.libglvnd
pkgs.vulkan-loader
pkgs.libX11
pkgs.libxcb
pkgs.libXcursor
pkgs.libxi
pkgs.libxrandr
pkgs.libxscrnsaver
pkgs.libxtst
pkgs.libxinerama
pkgs.libxkbcommon
pkgs.wayland
pkgs.libdecor
pkgs.alsa-lib
pkgs.libpulseaudio
pkgs.pipewire
pkgs.dbus
pkgs.udev
pkgs.libusb1
pkgs.libunwind
pkgs.gtk3
nod
];
cmakeBuildType = "RelWithDebInfo";
ninjaFlags = [ "dusklight" ];
cmakeFlags = [
"-DDUSK_VERSION_OVERRIDE=${versionSuffix}"
"-DFETCHCONTENT_FULLY_DISCONNECTED=ON"
"-DAURORA_DAWN_PROVIDER=package"
"-DAURORA_DAWN_LINKAGE=static"
"-DAURORA_NOD_PROVIDER=system"
"-DAURORA_SDL3_PROVIDER=system"
"-DBUILD_SHARED_LIBS=OFF"
]
++ lib.mapAttrsToList (key: src: "-DFETCHCONTENT_SOURCE_DIR_${key}=${src}") fetchContentDirs;
installPhase =
if isDarwin then
''
runHook preInstall
mkdir -p "$out/Applications"
cp -r Dusklight.app "$out/Applications/Dusklight.app"
runHook postInstall
''
else
''
runHook preInstall
install -Dm755 dusklight "$out/bin/dusklight"
cp -r "$src/res" "$out/bin/res"
install -Dm644 "$src/platforms/freedesktop/dev.twilitrealm.dusk.desktop" \
"$out/share/applications/dev.twilitrealm.dusk.desktop"
for size in 16 32 48 64 128 256 512 1024; do
install -Dm644 "$src/platforms/freedesktop/''${size}x''${size}/apps/dev.twilitrealm.dusk.png" \
"$out/share/icons/hicolor/''${size}x''${size}/apps/dev.twilitrealm.dusk.png"
done
runHook postInstall
'';
dontStrip = true;
meta = {
description = "Dusklight native PC port of the Twilight Princess decompilation";
homepage = "https://github.com/zeldaret/tp";
platforms = supportedSystems;
mainProgram = "dusklight";
};
};
# Tooling common to every supported host (Linux and macOS). # Tooling common to every supported host (Linux and macOS).
commonDevTools = [ commonDevTools = [
+17 -1
View File
@@ -88,6 +88,10 @@ public:
/* 0x02C */ cXyz field_0x2c; /* 0x02C */ cXyz field_0x2c;
/* 0x038 */ cXyz field_0x38[60]; /* 0x038 */ cXyz field_0x38[60];
/* 0x308 */ cXyz field_0x308[60]; /* 0x308 */ cXyz field_0x308[60];
#if TARGET_PC
TGXTexObj mBlurTexObj;
ResTIMG* mpCachedBlurTex = nullptr;
#endif
}; // Size = 0x5D8 }; // Size = 0x5D8
class dAlink_bottleWaterPcallBack_c : public JPAParticleCallBack { class dAlink_bottleWaterPcallBack_c : public JPAParticleCallBack {
@@ -4551,7 +4555,7 @@ public:
#if TARGET_PC #if TARGET_PC
void handleWolfHowl(); void handleWolfHowl();
void handleQuickTransform(); void handleQuickTransform();
bool checkGyroAimContext(); bool checkAimContext();
void onIronBallChainInterpCallback(); void onIronBallChainInterpCallback();
@@ -4564,6 +4568,18 @@ public:
cXyz mIBChainInterpCurrHandRoot; cXyz mIBChainInterpCurrHandRoot;
bool mIBChainInterpPrevValid; bool mIBChainInterpPrevValid;
bool mIBChainInterpCurrValid; bool mIBChainInterpCurrValid;
cXyz mHsChainInterpPrevTop;
cXyz mHsChainInterpCurrTop;
cXyz mHsChainInterpPrevRoot;
cXyz mHsChainInterpCurrRoot;
cXyz mHsChainInterpPrevSubRoot;
cXyz mHsChainInterpCurrSubRoot;
cXyz mHsChainInterpPrevSubTop;
cXyz mHsChainInterpCurrSubTop;
bool mHsChainInterpPrevValid;
bool mHsChainInterpCurrValid;
bool mIsRollstab = false; bool mIsRollstab = false;
#endif #endif
}; // Size: 0x385C }; // Size: 0x385C
+7 -2
View File
@@ -299,8 +299,13 @@ public:
/* 0x168C */ u8 field_0x168c; /* 0x168C */ u8 field_0x168c;
/* 0x168D */ u8 field_0x168d; /* 0x168D */ u8 field_0x168d;
/* 0x168E */ u8 HIOInit; /* 0x168E */ u8 HIOInit;
#if TARGET_PC
cXyz mLineInterpPrev[MG_ROD_LURE_LINE_LEN];
cXyz mLineInterpCurr[MG_ROD_LURE_LINE_LEN];
bool mLineInterpPrevValid;
bool mLineInterpCurrValid;
#endif
}; };
STATIC_ASSERT(sizeof(dmg_rod_class) == 0x1690);
#endif /* D_A_MG_ROD_H */ #endif /* D_A_MG_ROD_H */
+9
View File
@@ -66,9 +66,18 @@ public:
/* 0x2CA7 */ s8 hide_lock; /* 0x2CA7 */ s8 hide_lock;
/* 0x2CA8 */ cXyz field_0x2ca8; /* 0x2CA8 */ cXyz field_0x2ca8;
/* 0x2CB4 */ u8 field_0x2cb4; /* 0x2CB4 */ u8 field_0x2cb4;
#if TARGET_PC
Mtx mChainInterpPrev[6][16];
Mtx mChainInterpCurr[6][16];
bool mChainInterpPrevValid;
bool mChainInterpCurrValid;
#endif
}; };
#if !TARGET_PC
STATIC_ASSERT(sizeof(obj_keyhole_class) == 0x2CB8); STATIC_ASSERT(sizeof(obj_keyhole_class) == 0x2CB8);
#endif
class daObj_Keyhole_HIO_c : public JORReflexible { class daObj_Keyhole_HIO_c : public JORReflexible {
public: public:
+4
View File
@@ -50,6 +50,10 @@ public:
/* 0x14 */ Mtx mProjMtx; /* 0x14 */ Mtx mProjMtx;
/* 0x44 */ ResTIMG* mpImg; /* 0x44 */ ResTIMG* mpImg;
/* 0x48 */ u8* mpData; /* 0x48 */ u8* mpData;
#if TARGET_PC
TGXTexObj mTexObj;
ResTIMG* mpCachedImg = nullptr;
#endif
}; };
class daPy_boomerangMove_c { class daPy_boomerangMove_c {
+1
View File
@@ -1037,6 +1037,7 @@ public:
bool test1Camera(s32); bool test1Camera(s32);
bool test2Camera(s32); bool test2Camera(s32);
#if TARGET_PC #if TARGET_PC
static bool canUseFreeCam();
bool freeCamera(); bool freeCamera();
bool executeDebugFlyCam(); bool executeDebugFlyCam();
void deactivateDebugFlyCam(); void deactivateDebugFlyCam();
+2 -1
View File
@@ -198,6 +198,7 @@ struct HOUSI_EFF {
/* 0x4C */ u16 field_0x4c; /* 0x4C */ u16 field_0x4c;
}; // Size: 0x50 }; // Size: 0x50
// Housi is the rising square particles in Twilight
class dKankyo_housi_Packet : public J3DPacket { class dKankyo_housi_Packet : public J3DPacket {
public: public:
virtual void draw(); virtual void draw();
@@ -208,7 +209,7 @@ public:
/* 0x0020 */ HOUSI_EFF mHousiEff[300]; /* 0x0020 */ HOUSI_EFF mHousiEff[300];
/* 0x5DE0 */ u8 field_0x5de0[8]; /* 0x5DE0 */ u8 field_0x5de0[8];
/* 0x5DE8 */ f32 field_0x5de8; /* 0x5DE8 */ f32 field_0x5de8;
/* 0x5DEC */ s16 field_0x5dec; /* 0x5DEC */ s16 mHousiCount;
}; // Size: 0x5DF0 }; // Size: 0x5DF0
struct CLOUD_EFF { struct CLOUD_EFF {
+25
View File
@@ -7,12 +7,16 @@
#include <dolphin/gx/GXExtra.h> #include <dolphin/gx/GXExtra.h>
#include "tracy/Tracy.hpp" #include "tracy/Tracy.hpp"
#if DUSK_GFX_DEBUG_GROUPS
#define GX_DEBUG_GROUP(name, ...) \ #define GX_DEBUG_GROUP(name, ...) \
do { \ do { \
GXPushDebugGroup(#name); \ GXPushDebugGroup(#name); \
name(__VA_ARGS__); \ name(__VA_ARGS__); \
GXPopDebugGroup(); \ GXPopDebugGroup(); \
} while (0) } while (0)
#else
#define GX_DEBUG_GROUP(name, ...) name(__VA_ARGS__)
#endif
#ifdef TARGET_PC #ifdef TARGET_PC
class GXTexObjRAII : public GXTexObj { class GXTexObjRAII : public GXTexObj {
@@ -39,16 +43,37 @@ public:
static_assert(sizeof(GXTexObjRAII) == sizeof(GXTexObj), static_assert(sizeof(GXTexObjRAII) == sizeof(GXTexObj),
"GXTexObjRAII should have the same size as GXTexObj"); "GXTexObjRAII should have the same size as GXTexObj");
typedef GXTexObjRAII TGXTexObj; typedef GXTexObjRAII TGXTexObj;
class GXTlutObjRAII : public GXTlutObj {
public:
GXTlutObjRAII() : GXTlutObj() {}
~GXTlutObjRAII() { GXDestroyTlutObj(this); }
void reset() { GXDestroyTlutObj(this); }
GXTlutObjRAII(const GXTlutObjRAII&) = delete;
GXTlutObjRAII& operator=(const GXTlutObjRAII&) = delete;
GXTlutObjRAII(GXTlutObjRAII&&) = delete;
GXTlutObjRAII& operator=(GXTlutObjRAII&&) = delete;
};
static_assert(sizeof(GXTlutObjRAII) == sizeof(GXTlutObj),
"GXTlutObjRAII should have the same size as GXTlutObj");
typedef GXTlutObjRAII TGXTlutObj;
#else #else
typedef GXTexObj TGXTexObj; typedef GXTexObj TGXTexObj;
typedef GXTlutObj TGXTlutObj;
#endif #endif
struct GXScopedDebugGroup { struct GXScopedDebugGroup {
explicit GXScopedDebugGroup(const char* text) { explicit GXScopedDebugGroup(const char* text) {
#if DUSK_GFX_DEBUG_GROUPS
GXPushDebugGroup(text); GXPushDebugGroup(text);
#endif
} }
~GXScopedDebugGroup() { ~GXScopedDebugGroup() {
#if DUSK_GFX_DEBUG_GROUPS
GXPopDebugGroup(); GXPopDebugGroup();
#endif
} }
}; };
+1 -4
View File
@@ -1,5 +1,4 @@
#ifndef DUSK_GYRO_H #pragma once
#define DUSK_GYRO_H
namespace dusk::gyro { namespace dusk::gyro {
void read(float dt); void read(float dt);
@@ -14,5 +13,3 @@ bool get_sensor_keep_alive();
void set_sensor_keep_alive(bool value); void set_sensor_keep_alive(bool value);
bool rollgoal_gyro_enabled(); bool rollgoal_gyro_enabled();
} // namespace dusk::gyro } // namespace dusk::gyro
#endif
+12
View File
@@ -0,0 +1,12 @@
#pragma once
#include <SDL3/SDL_events.h>
namespace dusk::mouse {
void read();
void getAimDeltas(float& out_yaw, float& out_pitch);
void getCameraDeltas(float& out_yaw, float& out_pitch);
void handle_event(const SDL_Event& event) noexcept;
void onFocusLost();
void onFocusGained();
} // namespace dusk::mouse
+22 -3
View File
@@ -57,6 +57,14 @@ enum class MenuScaling : u8 {
Dusklight = 2, Dusklight = 2,
}; };
enum class MagicArmorMode : u8 {
NORMAL = 0,
ON_DAMAGE = 1,
DOUBLE_DEFENSE = 2,
INVINCIBLE = 3,
COSMETIC = 4,
};
namespace config { namespace config {
template <> template <>
struct ConfigEnumRange<BloomMode> { struct ConfigEnumRange<BloomMode> {
@@ -105,6 +113,12 @@ struct ConfigEnumRange<MenuScaling> {
static constexpr auto min = MenuScaling::GameCube; static constexpr auto min = MenuScaling::GameCube;
static constexpr auto max = MenuScaling::Dusklight; static constexpr auto max = MenuScaling::Dusklight;
}; };
template <>
struct ConfigEnumRange<MagicArmorMode> {
static constexpr auto min = MagicArmorMode::NORMAL;
static constexpr auto max = MagicArmorMode::COSMETIC;
};
} // namespace config } // namespace config
// Persistent user settings // Persistent user settings
@@ -153,6 +167,7 @@ struct UserSettings {
ConfigVar<bool> noMissClimbing; ConfigVar<bool> noMissClimbing;
ConfigVar<bool> fastTears; ConfigVar<bool> fastTears;
ConfigVar<bool> no2ndFishForCat; ConfigVar<bool> no2ndFishForCat;
ConfigVar<bool> buttonFishing;
ConfigVar<bool> instantSaves; ConfigVar<bool> instantSaves;
ConfigVar<bool> instantText; ConfigVar<bool> instantText;
ConfigVar<bool> sunsSong; ConfigVar<bool> sunsSong;
@@ -162,6 +177,7 @@ struct UserSettings {
// Preferences // Preferences
ConfigVar<bool> enableMirrorMode; ConfigVar<bool> enableMirrorMode;
ConfigVar<bool> minimalHUD; ConfigVar<bool> minimalHUD;
ConfigVar<float> hudScale;
ConfigVar<bool> pauseOnFocusLost; ConfigVar<bool> pauseOnFocusLost;
ConfigVar<bool> enableLinkDollRotation; ConfigVar<bool> enableLinkDollRotation;
ConfigVar<bool> enableAchievementToasts; ConfigVar<bool> enableAchievementToasts;
@@ -187,7 +203,6 @@ struct UserSettings {
ConfigVar<bool> midnasLamentNonStop; ConfigVar<bool> midnasLamentNonStop;
// Input // Input
ConfigVar<GyroMode> gyroMode;
ConfigVar<bool> enableGyroAim; ConfigVar<bool> enableGyroAim;
ConfigVar<bool> enableGyroRollgoal; ConfigVar<bool> enableGyroRollgoal;
ConfigVar<float> gyroSensitivityX; ConfigVar<float> gyroSensitivityX;
@@ -197,6 +212,11 @@ struct UserSettings {
ConfigVar<float> gyroDeadband; ConfigVar<float> gyroDeadband;
ConfigVar<bool> gyroInvertPitch; ConfigVar<bool> gyroInvertPitch;
ConfigVar<bool> gyroInvertYaw; ConfigVar<bool> gyroInvertYaw;
ConfigVar<bool> enableMouseCamera;
ConfigVar<bool> enableMouseAim;
ConfigVar<float> mouseAimSensitivity;
ConfigVar<float> mouseCameraSensitivity;
ConfigVar<bool> invertMouseY;
ConfigVar<bool> freeCamera; ConfigVar<bool> freeCamera;
ConfigVar<bool> invertCameraXAxis; ConfigVar<bool> invertCameraXAxis;
ConfigVar<bool> invertCameraYAxis; ConfigVar<bool> invertCameraYAxis;
@@ -228,9 +248,8 @@ struct UserSettings {
ConfigVar<bool> canTransformAnywhere; ConfigVar<bool> canTransformAnywhere;
ConfigVar<bool> fastRoll; ConfigVar<bool> fastRoll;
ConfigVar<bool> fastSpinner; ConfigVar<bool> fastSpinner;
ConfigVar<bool> freeMagicArmor; ConfigVar<MagicArmorMode> armorRupeeDrain;
ConfigVar<bool> invincibleEnemies; ConfigVar<bool> invincibleEnemies;
ConfigVar<bool> transformWithoutShadowCrystal;
// Technical // Technical
ConfigVar<bool> restoreWiiGlitches; ConfigVar<bool> restoreWiiGlitches;
+12
View File
@@ -0,0 +1,12 @@
#ifndef DUSK_TEXTURE_REPLACEMENTS_HPP
#define DUSK_TEXTURE_REPLACEMENTS_HPP
namespace dusk::texture_replacements {
void reload();
void set_enabled(bool enabled);
void shutdown();
}
#endif
+1 -1
View File
@@ -44,7 +44,7 @@ struct mDoLib_clipper {
void mDoLib_project(Vec* src, Vec* dst); void mDoLib_project(Vec* src, Vec* dst);
u32 mDoLib_setResTimgObj(ResTIMG const* res, TGXTexObj* o_texObj, u32 tlut_name, u32 mDoLib_setResTimgObj(ResTIMG const* res, TGXTexObj* o_texObj, u32 tlut_name,
GXTlutObj* o_tlutObj); TGXTlutObj* o_tlutObj);
void mDoLib_pos2camera(Vec* src, Vec* dst); void mDoLib_pos2camera(Vec* src, Vec* dst);
#if PLATFORM_WII #if PLATFORM_WII
+41 -16
View File
@@ -952,45 +952,70 @@ if(DEFINED APPLE_TARGET_TRIPLE)
set(APPLE_TARGET_TRIPLE_FLAG "-target ${APPLE_TARGET_TRIPLE}") set(APPLE_TARGET_TRIPLE_FLAG "-target ${APPLE_TARGET_TRIPLE}")
endif() endif()
function(ios_toolchain_set_cached_flags variable description)
set(clean_flags "${${variable}}")
foreach(toolchain_flag IN LISTS ARGN)
if(NOT "${toolchain_flag}" STREQUAL "")
string(REPLACE "${toolchain_flag}" "" clean_flags "${clean_flags}")
endif()
endforeach()
string(REGEX REPLACE "[ \t]+" " " clean_flags "${clean_flags}")
string(STRIP "${clean_flags}" clean_flags)
set(final_flags "")
foreach(toolchain_flag IN LISTS ARGN)
if(NOT "${toolchain_flag}" STREQUAL "")
string(APPEND final_flags " ${toolchain_flag}")
endif()
endforeach()
if(NOT "${clean_flags}" STREQUAL "")
string(APPEND final_flags " ${clean_flags}")
endif()
string(REGEX REPLACE "[ \t]+" " " final_flags "${final_flags}")
string(STRIP "${final_flags}" final_flags)
set(${variable} "${final_flags}" CACHE INTERNAL "${description}")
endfunction()
#Check if Xcode generator is used since that will handle these flags automagically #Check if Xcode generator is used since that will handle these flags automagically
if(CMAKE_GENERATOR MATCHES "Xcode") if(CMAKE_GENERATOR MATCHES "Xcode")
message(STATUS "Not setting any manual command-line buildflags, since Xcode is selected as the generator. Modifying the Xcode build-settings directly instead.") message(STATUS "Not setting any manual command-line buildflags, since Xcode is selected as the generator. Modifying the Xcode build-settings directly instead.")
else() else()
set(CMAKE_C_FLAGS "${C_TARGET_FLAGS} ${APPLE_TARGET_TRIPLE_FLAG} ${SDK_NAME_VERSION_FLAGS} ${OBJC_LEGACY_VARS} ${BITCODE} ${VISIBILITY} ${CMAKE_C_FLAGS}" CACHE INTERNAL ios_toolchain_set_cached_flags(CMAKE_C_FLAGS "Flags used by the compiler during all C build types."
"Flags used by the compiler during all C build types.") "${C_TARGET_FLAGS}" "${APPLE_TARGET_TRIPLE_FLAG}" "${SDK_NAME_VERSION_FLAGS}" "${OBJC_LEGACY_VARS}" "${BITCODE}" "${VISIBILITY}")
set(CMAKE_C_FLAGS_DEBUG "-O0 -g ${CMAKE_C_FLAGS_DEBUG}") set(CMAKE_C_FLAGS_DEBUG "-O0 -g ${CMAKE_C_FLAGS_DEBUG}")
set(CMAKE_C_FLAGS_MINSIZEREL "-DNDEBUG -Os ${CMAKE_C_FLAGS_MINSIZEREL}") set(CMAKE_C_FLAGS_MINSIZEREL "-DNDEBUG -Os ${CMAKE_C_FLAGS_MINSIZEREL}")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-DNDEBUG -O2 -g ${CMAKE_C_FLAGS_RELWITHDEBINFO}") set(CMAKE_C_FLAGS_RELWITHDEBINFO "-DNDEBUG -O2 -g ${CMAKE_C_FLAGS_RELWITHDEBINFO}")
set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG -O3 ${CMAKE_C_FLAGS_RELEASE}") set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG -O3 ${CMAKE_C_FLAGS_RELEASE}")
set(CMAKE_CXX_FLAGS "${C_TARGET_FLAGS} ${APPLE_TARGET_TRIPLE_FLAG} ${SDK_NAME_VERSION_FLAGS} ${OBJC_LEGACY_VARS} ${BITCODE} ${VISIBILITY} ${CMAKE_CXX_FLAGS}" CACHE INTERNAL ios_toolchain_set_cached_flags(CMAKE_CXX_FLAGS "Flags used by the compiler during all CXX build types."
"Flags used by the compiler during all CXX build types.") "${C_TARGET_FLAGS}" "${APPLE_TARGET_TRIPLE_FLAG}" "${SDK_NAME_VERSION_FLAGS}" "${OBJC_LEGACY_VARS}" "${BITCODE}" "${VISIBILITY}")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g ${CMAKE_CXX_FLAGS_DEBUG}") set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g ${CMAKE_CXX_FLAGS_DEBUG}")
set(CMAKE_CXX_FLAGS_MINSIZEREL "-DNDEBUG -Os ${CMAKE_CXX_FLAGS_MINSIZEREL}") set(CMAKE_CXX_FLAGS_MINSIZEREL "-DNDEBUG -Os ${CMAKE_CXX_FLAGS_MINSIZEREL}")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-DNDEBUG -O2 -g ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-DNDEBUG -O2 -g ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -O3 ${CMAKE_CXX_FLAGS_RELEASE}") set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -O3 ${CMAKE_CXX_FLAGS_RELEASE}")
if(NAMED_LANGUAGE_SUPPORT_INT) if(NAMED_LANGUAGE_SUPPORT_INT)
set(CMAKE_OBJC_FLAGS "${C_TARGET_FLAGS} ${APPLE_TARGET_TRIPLE_FLAG} ${SDK_NAME_VERSION_FLAGS} ${BITCODE} ${VISIBILITY} ${FOBJC_ARC} ${OBJC_VARS} ${CMAKE_OBJC_FLAGS}" CACHE INTERNAL ios_toolchain_set_cached_flags(CMAKE_OBJC_FLAGS "Flags used by the compiler during all OBJC build types."
"Flags used by the compiler during all OBJC build types.") "${C_TARGET_FLAGS}" "${APPLE_TARGET_TRIPLE_FLAG}" "${SDK_NAME_VERSION_FLAGS}" "${BITCODE}" "${VISIBILITY}" "${FOBJC_ARC}" "${OBJC_VARS}")
set(CMAKE_OBJC_FLAGS_DEBUG "-O0 -g ${CMAKE_OBJC_FLAGS_DEBUG}") set(CMAKE_OBJC_FLAGS_DEBUG "-O0 -g ${CMAKE_OBJC_FLAGS_DEBUG}")
set(CMAKE_OBJC_FLAGS_MINSIZEREL "-DNDEBUG -Os ${CMAKE_OBJC_FLAGS_MINSIZEREL}") set(CMAKE_OBJC_FLAGS_MINSIZEREL "-DNDEBUG -Os ${CMAKE_OBJC_FLAGS_MINSIZEREL}")
set(CMAKE_OBJC_FLAGS_RELWITHDEBINFO "-DNDEBUG -O2 -g ${CMAKE_OBJC_FLAGS_RELWITHDEBINFO}") set(CMAKE_OBJC_FLAGS_RELWITHDEBINFO "-DNDEBUG -O2 -g ${CMAKE_OBJC_FLAGS_RELWITHDEBINFO}")
set(CMAKE_OBJC_FLAGS_RELEASE "-DNDEBUG -O3 ${CMAKE_OBJC_FLAGS_RELEASE}") set(CMAKE_OBJC_FLAGS_RELEASE "-DNDEBUG -O3 ${CMAKE_OBJC_FLAGS_RELEASE}")
set(CMAKE_OBJCXX_FLAGS "${C_TARGET_FLAGS} ${APPLE_TARGET_TRIPLE_FLAG} ${SDK_NAME_VERSION_FLAGS} ${BITCODE} ${VISIBILITY} ${FOBJC_ARC} ${OBJC_VARS} ${CMAKE_OBJCXX_FLAGS}" CACHE INTERNAL ios_toolchain_set_cached_flags(CMAKE_OBJCXX_FLAGS "Flags used by the compiler during all OBJCXX build types."
"Flags used by the compiler during all OBJCXX build types.") "${C_TARGET_FLAGS}" "${APPLE_TARGET_TRIPLE_FLAG}" "${SDK_NAME_VERSION_FLAGS}" "${BITCODE}" "${VISIBILITY}" "${FOBJC_ARC}" "${OBJC_VARS}")
set(CMAKE_OBJCXX_FLAGS_DEBUG "-O0 -g ${CMAKE_OBJCXX_FLAGS_DEBUG}") set(CMAKE_OBJCXX_FLAGS_DEBUG "-O0 -g ${CMAKE_OBJCXX_FLAGS_DEBUG}")
set(CMAKE_OBJCXX_FLAGS_MINSIZEREL "-DNDEBUG -Os ${CMAKE_OBJCXX_FLAGS_MINSIZEREL}") set(CMAKE_OBJCXX_FLAGS_MINSIZEREL "-DNDEBUG -Os ${CMAKE_OBJCXX_FLAGS_MINSIZEREL}")
set(CMAKE_OBJCXX_FLAGS_RELWITHDEBINFO "-DNDEBUG -O2 -g ${CMAKE_OBJCXX_FLAGS_RELWITHDEBINFO}") set(CMAKE_OBJCXX_FLAGS_RELWITHDEBINFO "-DNDEBUG -O2 -g ${CMAKE_OBJCXX_FLAGS_RELWITHDEBINFO}")
set(CMAKE_OBJCXX_FLAGS_RELEASE "-DNDEBUG -O3 ${CMAKE_OBJCXX_FLAGS_RELEASE}") set(CMAKE_OBJCXX_FLAGS_RELEASE "-DNDEBUG -O3 ${CMAKE_OBJCXX_FLAGS_RELEASE}")
endif() endif()
set(CMAKE_C_LINK_FLAGS "${C_TARGET_FLAGS} ${SDK_NAME_VERSION_FLAGS} -Wl,-search_paths_first ${CMAKE_C_LINK_FLAGS}" CACHE INTERNAL ios_toolchain_set_cached_flags(CMAKE_C_LINK_FLAGS "Flags used by the compiler for all C link types."
"Flags used by the compiler for all C link types.") "${C_TARGET_FLAGS}" "${SDK_NAME_VERSION_FLAGS}" "-Wl,-search_paths_first")
set(CMAKE_CXX_LINK_FLAGS "${C_TARGET_FLAGS} ${SDK_NAME_VERSION_FLAGS} -Wl,-search_paths_first ${CMAKE_CXX_LINK_FLAGS}" CACHE INTERNAL ios_toolchain_set_cached_flags(CMAKE_CXX_LINK_FLAGS "Flags used by the compiler for all CXX link types."
"Flags used by the compiler for all CXX link types.") "${C_TARGET_FLAGS}" "${SDK_NAME_VERSION_FLAGS}" "-Wl,-search_paths_first")
if(NAMED_LANGUAGE_SUPPORT_INT) if(NAMED_LANGUAGE_SUPPORT_INT)
set(CMAKE_OBJC_LINK_FLAGS "${C_TARGET_FLAGS} ${SDK_NAME_VERSION_FLAGS} -Wl,-search_paths_first ${CMAKE_OBJC_LINK_FLAGS}" CACHE INTERNAL ios_toolchain_set_cached_flags(CMAKE_OBJC_LINK_FLAGS "Flags used by the compiler for all OBJC link types."
"Flags used by the compiler for all OBJC link types.") "${C_TARGET_FLAGS}" "${SDK_NAME_VERSION_FLAGS}" "-Wl,-search_paths_first")
set(CMAKE_OBJCXX_LINK_FLAGS "${C_TARGET_FLAGS} ${SDK_NAME_VERSION_FLAGS} -Wl,-search_paths_first ${CMAKE_OBJCXX_LINK_FLAGS}" CACHE INTERNAL ios_toolchain_set_cached_flags(CMAKE_OBJCXX_LINK_FLAGS "Flags used by the compiler for all OBJCXX link types."
"Flags used by the compiler for all OBJCXX link types.") "${C_TARGET_FLAGS}" "${SDK_NAME_VERSION_FLAGS}" "-Wl,-search_paths_first")
endif() endif()
set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS} -x assembler-with-cpp" CACHE INTERNAL set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS} -x assembler-with-cpp" CACHE INTERNAL
"Flags used by the compiler for all ASM build types.") "Flags used by the compiler for all ASM build types.")
@@ -1,6 +1,7 @@
#ifndef J3DSHAPEDRAW_H #ifndef J3DSHAPEDRAW_H
#define J3DSHAPEDRAW_H #define J3DSHAPEDRAW_H
#include <gx.h>
#include <types.h> #include <types.h>
/** /**
@@ -12,6 +13,9 @@ public:
u32 countVertex(u32); u32 countVertex(u32);
void addTexMtxIndexInDL(u32, u32, u32); void addTexMtxIndexInDL(u32, u32, u32);
J3DShapeDraw(u8 const*, u32); J3DShapeDraw(u8 const*, u32);
#if TARGET_PC
J3DShapeDraw(u8 const*, u32, const GXVtxDescList*);
#endif
void draw() const; void draw() const;
virtual ~J3DShapeDraw(); virtual ~J3DShapeDraw();
@@ -3,6 +3,8 @@
#include "JSystem/J2DGraph/J2DGrafContext.h" #include "JSystem/J2DGraph/J2DGrafContext.h"
#include <gx.h> #include <gx.h>
#include <tracy/Tracy.hpp>
J2DGrafContext::J2DGrafContext(f32 x, f32 y, f32 width, f32 height) J2DGrafContext::J2DGrafContext(f32 x, f32 y, f32 width, f32 height)
: mBounds(x, y, x + width, y + height), mScissorBounds(x, y, x + width, y + height) { : mBounds(x, y, x + width, y + height), mScissorBounds(x, y, x + width, y + height) {
if (x < 0.0f || y < 0.0f) { if (x < 0.0f || y < 0.0f) {
@@ -137,6 +139,7 @@ void J2DGrafContext::setLineWidth(u8 lineWidth) {
} }
void J2DGrafContext::fillBox(JGeometry::TBox2<f32> const& box) { void J2DGrafContext::fillBox(JGeometry::TBox2<f32> const& box) {
ZoneScoped;
GXSetBlendMode((GXBlendMode)mBoxPart.mType, (GXBlendFactor)mBoxPart.mSrcFactor, GXSetBlendMode((GXBlendMode)mBoxPart.mType, (GXBlendFactor)mBoxPart.mSrcFactor,
(GXBlendFactor)mBoxPart.mDstFactor, GX_LO_SET); (GXBlendFactor)mBoxPart.mDstFactor, GX_LO_SET);
GXLoadPosMtxImm(mPosMtx, 0); GXLoadPosMtxImm(mPosMtx, 0);
@@ -155,6 +158,7 @@ void J2DGrafContext::fillBox(JGeometry::TBox2<f32> const& box) {
} }
void J2DGrafContext::drawFrame(JGeometry::TBox2<f32> const& box) { void J2DGrafContext::drawFrame(JGeometry::TBox2<f32> const& box) {
ZoneScoped;
GXSetBlendMode((GXBlendMode)mBoxPart.mType, (GXBlendFactor)mBoxPart.mSrcFactor, GXSetBlendMode((GXBlendMode)mBoxPart.mType, (GXBlendFactor)mBoxPart.mSrcFactor,
(GXBlendFactor)mBoxPart.mDstFactor, GX_LO_SET); (GXBlendFactor)mBoxPart.mDstFactor, GX_LO_SET);
GXLoadPosMtxImm(mPosMtx, 0); GXLoadPosMtxImm(mPosMtx, 0);
@@ -175,6 +179,7 @@ void J2DGrafContext::drawFrame(JGeometry::TBox2<f32> const& box) {
} }
void J2DGrafContext::line(JGeometry::TVec2<f32> start, JGeometry::TVec2<f32> end) { void J2DGrafContext::line(JGeometry::TVec2<f32> start, JGeometry::TVec2<f32> end) {
ZoneScoped;
GXSetBlendMode((GXBlendMode)mLinePart.mType, (GXBlendFactor)mLinePart.mSrcFactor, GXSetBlendMode((GXBlendMode)mLinePart.mType, (GXBlendFactor)mLinePart.mSrcFactor,
(GXBlendFactor)mLinePart.mDstFactor, GX_LO_SET); (GXBlendFactor)mLinePart.mDstFactor, GX_LO_SET);
GXLoadPosMtxImm(mPosMtx, 0); GXLoadPosMtxImm(mPosMtx, 0);
@@ -542,8 +542,11 @@ void J3DModel::viewCalc() {
} }
#ifdef TARGET_PC #ifdef TARGET_PC
for (u16 i = 0; i < mModelData->getDrawMtxNum(); ++i) { Mtx* drawMtx = getDrawMtxPtr();
dusk::frame_interp::record_final_mtx(getDrawMtxPtr()[i]); if (drawMtx != J3DMtxBuffer::sNoUseDrawMtxPtr) {
for (u16 i = 0; i < mModelData->getDrawMtxNum(); ++i) {
dusk::frame_interp::record_final_mtx(drawMtx[i]);
}
} }
#endif #endif
+339 -4
View File
@@ -1,15 +1,310 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep #include "JSystem/JSystem.h" // IWYU pragma: keep
#include <cstring>
#include <gx.h>
#include <stdint.h>
#include "JSystem/J3DGraphBase/J3DShapeDraw.h" #include "JSystem/J3DGraphBase/J3DShapeDraw.h"
#include "JSystem/JKernel/JKRHeap.h" #include "JSystem/JKernel/JKRHeap.h"
#include <cstring>
#include <stdint.h> #if TARGET_PC
#include <gx.h> #include <algorithm>
#include <tracy/Tracy.hpp>
#include <vector>
#include "dusk/logging.h"
namespace {
u16 read_be16(const u8* data) {
return (u16(data[0]) << 8) | data[1];
}
void append_be16(std::vector<u8>& out, u16 value) {
out.push_back(value >> 8);
out.push_back(value & 0xFF);
}
void append_bytes(std::vector<u8>& out, const u8* data, u32 size) {
out.insert(out.end(), data, data + size);
}
bool is_matrix_idx_attr(GXAttr attr) {
return attr >= GX_VA_PNMTXIDX && attr <= GX_VA_TEX7MTXIDX;
}
bool is_draw_opcode(u8 opcode) {
return opcode == GX_QUADS || opcode == GX_TRIANGLES || opcode == GX_TRIANGLESTRIP ||
opcode == GX_TRIANGLEFAN || opcode == GX_LINES || opcode == GX_LINESTRIP ||
opcode == GX_POINTS;
}
bool is_mergeable_draw_opcode(u8 opcode) {
return opcode == GX_QUADS || opcode == GX_TRIANGLES || opcode == GX_TRIANGLESTRIP ||
opcode == GX_TRIANGLEFAN;
}
bool calc_vtx_stride(const GXVtxDescList* vtxDesc, u32& stride) {
stride = 0;
for (; vtxDesc->attr != GX_VA_NULL; vtxDesc++) {
switch (vtxDesc->type) {
case GX_NONE:
break;
case GX_DIRECT:
if (!is_matrix_idx_attr(vtxDesc->attr)) {
return false;
}
stride += 1;
break;
case GX_INDEX8:
stride += 1;
break;
case GX_INDEX16:
stride += 2;
break;
default:
return false;
}
}
return stride != 0;
}
bool get_command_size(const u8* dlStart, u32 dlSize, u32 offset, u32 stride, u32& cmdSize) {
if (offset >= dlSize) {
return false;
}
const u8 cmd = dlStart[offset];
const u8 opcode = cmd & GX_OPCODE_MASK;
switch (opcode) {
case GX_NOP:
case GX_CMD_INVL_VC:
cmdSize = 1;
return true;
case (GX_LOAD_BP_REG & GX_OPCODE_MASK):
cmdSize = 5;
return offset + cmdSize <= dlSize;
case GX_LOAD_CP_REG:
cmdSize = 6;
return offset + cmdSize <= dlSize;
case GX_LOAD_XF_REG: {
if (offset + 5 > dlSize) {
return false;
}
const u16 count = read_be16(dlStart + offset + 1) + 1;
cmdSize = 5 + count * 4;
return offset + cmdSize <= dlSize;
}
case GX_LOAD_INDX_A:
case GX_LOAD_INDX_B:
case GX_LOAD_INDX_C:
case GX_LOAD_INDX_D:
cmdSize = 5;
return offset + cmdSize <= dlSize;
case GX_CMD_CALL_DL:
cmdSize = 9;
return offset + cmdSize <= dlSize;
default:
if (is_draw_opcode(opcode)) {
if (offset + 3 > dlSize) {
return false;
}
const u16 vtxCount = read_be16(dlStart + offset + 1);
cmdSize = 3 + vtxCount * stride;
return offset + cmdSize <= dlSize;
}
return false;
}
}
struct MergeRun {
u8 cmd = 0;
u16 vtxCount = 0;
std::vector<u8> vertices;
};
void flush_merge_run(std::vector<u8>& out, MergeRun& run) {
if (run.vtxCount == 0) {
return;
}
out.push_back(run.cmd);
append_be16(out, run.vtxCount);
append_bytes(out, run.vertices.data(), run.vertices.size());
run.vertices.clear();
run.vtxCount = 0;
}
void append_vertex(std::vector<u8>& out, const u8* vertices, u32 stride, u16 idx) {
append_bytes(out, vertices + idx * stride, stride);
}
bool triangulate_draw(
std::vector<u8>& out, u8 opcode, const u8* vertices, u32 stride, u16 vtxCount) {
switch (opcode) {
case GX_TRIANGLES:
append_bytes(out, vertices, vtxCount * stride);
return true;
case GX_TRIANGLEFAN:
if (vtxCount < 3) {
return false;
}
for (u16 v = 2; v < vtxCount; v++) {
append_vertex(out, vertices, stride, 0);
append_vertex(out, vertices, stride, v - 1);
append_vertex(out, vertices, stride, v);
}
return true;
case GX_TRIANGLESTRIP:
if (vtxCount < 3) {
return false;
}
for (u16 v = 2; v < vtxCount; v++) {
if ((v & 1) == 0) {
append_vertex(out, vertices, stride, v - 2);
append_vertex(out, vertices, stride, v - 1);
} else {
append_vertex(out, vertices, stride, v - 1);
append_vertex(out, vertices, stride, v - 2);
}
append_vertex(out, vertices, stride, v);
}
return true;
case GX_QUADS:
if ((vtxCount & 3) != 0) {
return false;
}
for (u16 v = 0; v < vtxCount; v += 4) {
append_vertex(out, vertices, stride, v);
append_vertex(out, vertices, stride, v + 1);
append_vertex(out, vertices, stride, v + 2);
append_vertex(out, vertices, stride, v + 2);
append_vertex(out, vertices, stride, v + 3);
append_vertex(out, vertices, stride, v);
}
return true;
default:
return false;
}
}
void append_triangles_to_run(
std::vector<u8>& out, MergeRun& run, u8 cmd, const std::vector<u8>& vertices, u32 stride) {
u32 offset = 0;
u32 remaining = vertices.size() / stride;
while (remaining != 0) {
if (run.vtxCount != 0 && run.cmd != cmd) {
flush_merge_run(out, run);
}
if (run.vtxCount == 0) {
run.cmd = cmd;
}
u32 available = 0xFFFF - run.vtxCount;
if (available == 0) {
flush_merge_run(out, run);
continue;
}
u32 toCopy = std::min(remaining, available);
append_bytes(run.vertices, vertices.data() + offset * stride, toCopy * stride);
run.vtxCount += toCopy;
offset += toCopy;
remaining -= toCopy;
if (run.vtxCount == 0xFFFF) {
flush_merge_run(out, run);
}
}
}
bool optimize_display_list(const u8* dlStart, u32 dlSize, u32 stride, std::vector<u8>& out) {
MergeRun run;
out.reserve(dlSize);
for (u32 offset = 0; offset < dlSize;) {
u32 cmdSize = 0;
if (!get_command_size(dlStart, dlSize, offset, stride, cmdSize)) {
return false;
}
const u8 cmd = dlStart[offset];
const u8 opcode = cmd & GX_OPCODE_MASK;
if (opcode == GX_NOP) {
offset += cmdSize;
continue;
}
if (!is_draw_opcode(opcode)) {
flush_merge_run(out, run);
append_bytes(out, dlStart + offset, cmdSize);
offset += cmdSize;
continue;
}
if (!is_mergeable_draw_opcode(opcode)) {
flush_merge_run(out, run);
append_bytes(out, dlStart + offset, cmdSize);
offset += cmdSize;
continue;
}
const u16 vtxCount = read_be16(dlStart + offset + 1);
const u8* vertices = dlStart + offset + 3;
std::vector<u8> triangles;
if (!triangulate_draw(triangles, opcode, vertices, stride, vtxCount)) {
flush_merge_run(out, run);
append_bytes(out, dlStart + offset, cmdSize);
offset += cmdSize;
continue;
}
append_triangles_to_run(out, run, (GX_TRIANGLES | (cmd & GX_VAT_MASK)), triangles, stride);
offset += cmdSize;
}
flush_merge_run(out, run);
return true;
}
void set_display_list_copy(void*& displayList, u32& displayListSize, const u8* data, u32 size) {
const u32 alignedSize = ALIGN_NEXT(size, 0x20);
u8* newDL = JKR_NEW_ARRAY_ARGS(u8, alignedSize, 0x20);
if (size != 0) {
std::memcpy(newDL, data, size);
}
for (u32 i = size; i < alignedSize; i++) {
newDL[i] = 0;
}
displayList = newDL;
displayListSize = alignedSize;
DCStoreRange(newDL, displayListSize);
}
} // namespace
#endif
u32 J3DShapeDraw::countVertex(u32 stride) { u32 J3DShapeDraw::countVertex(u32 stride) {
u32 count = 0; u32 count = 0;
u8* dlStart = (u8*)getDisplayList(); u8* dlStart = (u8*)getDisplayList();
#if TARGET_PC
for (u32 offset = 0; offset < getDisplayListSize();) {
u8 cmd = dlStart[offset];
u8 opcode = cmd & GX_OPCODE_MASK;
u32 cmdSize = 0;
if (!get_command_size(dlStart, getDisplayListSize(), offset, stride, cmdSize)) {
break;
}
if (!is_draw_opcode(opcode)) {
offset += cmdSize;
continue;
}
int vtxNum = be16(*reinterpret_cast<u16*>(dlStart + offset + 1));
count += vtxNum;
offset += 3 + stride * vtxNum;
}
#else
for (u8* dl = dlStart; (dl - dlStart) < getDisplayListSize();) { for (u8* dl = dlStart; (dl - dlStart) < getDisplayListSize();) {
u8 cmd = *(u8*)dl; u8 cmd = *(u8*)dl;
dl++; dl++;
@@ -20,6 +315,7 @@ u32 J3DShapeDraw::countVertex(u32 stride) {
count += vtxNum; count += vtxNum;
dl = (u8*)dl + stride * vtxNum; dl = (u8*)dl + stride * vtxNum;
} }
#endif
return count; return count;
} }
@@ -34,13 +330,32 @@ void J3DShapeDraw::addTexMtxIndexInDL(u32 stride, u32 attrOffs, u32 valueBase) {
u8* newDL = newDLStart; u8* newDL = newDLStart;
for (; (oldDL - oldDLStart) < mDisplayListSize;) { for (; (oldDL - oldDLStart) < mDisplayListSize;) {
#if TARGET_PC
u32 oldOffset = oldDL - oldDLStart;
u32 cmdSize = 0;
if (!get_command_size(oldDLStart, mDisplayListSize, oldOffset, stride, cmdSize)) {
memcpy(newDL, oldDL, mDisplayListSize - oldOffset);
newDL += mDisplayListSize - oldOffset;
break;
}
#endif
// Copy command // Copy command
u8 cmd = *(u8*)oldDL; u8 cmd = *(u8*)oldDL;
oldDL++; oldDL++;
*newDL++ = cmd; *newDL++ = cmd;
#if TARGET_PC
u8 opcode = cmd & GX_OPCODE_MASK;
if (!is_draw_opcode(opcode)) {
memcpy(newDL, oldDL, cmdSize - 1);
oldDL += cmdSize - 1;
newDL += cmdSize - 1;
continue;
}
#else
if (cmd != GX_TRIANGLEFAN && cmd != GX_TRIANGLESTRIP) if (cmd != GX_TRIANGLEFAN && cmd != GX_TRIANGLESTRIP)
break; break;
#endif
// Copy count // Copy count
int vtxNum = *(u16*)oldDL; int vtxNum = *(u16*)oldDL;
@@ -71,11 +386,31 @@ void J3DShapeDraw::addTexMtxIndexInDL(u32 stride, u32 attrOffs, u32 valueBase) {
} }
J3DShapeDraw::J3DShapeDraw(const u8* displayList, u32 displayListSize) { J3DShapeDraw::J3DShapeDraw(const u8* displayList, u32 displayListSize) {
#if TARGET_PC
set_display_list_copy(mDisplayList, mDisplayListSize, displayList, displayListSize);
#else
mDisplayList = (void*)displayList; mDisplayList = (void*)displayList;
mDisplayListSize = displayListSize; mDisplayListSize = displayListSize;
#endif
} }
#if TARGET_PC
J3DShapeDraw::J3DShapeDraw(
const u8* displayList, u32 displayListSize, const GXVtxDescList* vtxDesc) {
u32 stride = 0;
std::vector<u8> optimized;
if (calc_vtx_stride(vtxDesc, stride) &&
optimize_display_list(displayList, displayListSize, stride, optimized))
{
set_display_list_copy(mDisplayList, mDisplayListSize, optimized.data(), optimized.size());
} else {
set_display_list_copy(mDisplayList, mDisplayListSize, displayList, displayListSize);
}
}
#endif
void J3DShapeDraw::draw() const { void J3DShapeDraw::draw() const {
ZoneScoped;
GXCallDisplayList(mDisplayList, mDisplayListSize); GXCallDisplayList(mDisplayList, mDisplayListSize);
} }
@@ -132,7 +132,12 @@ J3DShapeDraw* J3DShapeFactory::newShapeDraw(int shapeNo, int mtxGroupNo) const {
const J3DShapeInitData& shapeInitData = mShapeInitData[mIndexTable[shapeNo]]; const J3DShapeInitData& shapeInitData = mShapeInitData[mIndexTable[shapeNo]];
const J3DShapeDrawInitData& drawInitData = const J3DShapeDrawInitData& drawInitData =
(&mDrawInitData[shapeInitData.mDrawInitDataIndex])[mtxGroupNo]; (&mDrawInitData[shapeInitData.mDrawInitDataIndex])[mtxGroupNo];
#if TARGET_PC
shapeDraw = JKR_NEW J3DShapeDraw(&mDisplayListData[drawInitData.mDisplayListIndex], drawInitData.mDisplayListSize,
getVtxDescList(shapeNo));
#else
shapeDraw = JKR_NEW J3DShapeDraw(&mDisplayListData[drawInitData.mDisplayListIndex], drawInitData.mDisplayListSize); shapeDraw = JKR_NEW J3DShapeDraw(&mDisplayListData[drawInitData.mDisplayListIndex], drawInitData.mDisplayListSize);
#endif
J3D_ASSERT_ALLOCMEM(193, shapeDraw); J3D_ASSERT_ALLOCMEM(193, shapeDraw);
return shapeDraw; return shapeDraw;
} }
@@ -154,7 +159,7 @@ s32 J3DShapeFactory::calcSize(int shapeNo, u32 flag) {
for (u32 i = 0; i < mtxGroupNo; i++) { for (u32 i = 0; i < mtxGroupNo; i++) {
size += calcSizeShapeMtx(flag, shapeNo, i); size += calcSizeShapeMtx(flag, shapeNo, i);
size += 0x0C; size += sizeof(J3DShapeDraw);
} }
return size; return size;
+1 -2
View File
@@ -206,8 +206,7 @@ void JPABaseParticle::init_c(JPAEmitterWorkData* work, JPABaseParticle* parent)
#if TARGET_PC #if TARGET_PC
void JPABaseParticle::interp(JPAEmitterWorkData* work, void const* drawFunc) { void JPABaseParticle::interp(JPAEmitterWorkData* work, void const* drawFunc) {
static bool enable = false; if (!dusk::frame_interp::is_enabled())
if (!enable)
return; return;
// don't interpolate the first frame // don't interpolate the first frame
@@ -761,6 +761,15 @@ bool JPAResource::calc(JPAEmitterWorkData* work, JPABaseEmitter* emtr) {
} }
} }
#ifdef TARGET_PC
if (((pBsp && pBsp->getDirType() == 3) || (pCsp && pCsp->getDirType() == 3)) &&
dusk::frame_interp::is_enabled())
{
// ensure mGlobalEmtrDir is valid
calcWorkData_d(work);
}
#endif
JPANode<JPABaseParticle>* next = NULL; JPANode<JPABaseParticle>* next = NULL;
for (JPANode<JPABaseParticle>* node = emtr->mAlivePtclBase.getFirst(); node != emtr->mAlivePtclBase.getEnd(); node = next) { for (JPANode<JPABaseParticle>* node = emtr->mAlivePtclBase.getFirst(); node != emtr->mAlivePtclBase.getEnd(); node = next) {
next = node->getNext(); next = node->getNext();
+1
View File
@@ -249,6 +249,7 @@ f32 JUTResFont::drawChar_scale(f32 pos_x, f32 pos_y, f32 scale_x, f32 scale_y, i
f32 x2; f32 x2;
f32 y1; f32 y1;
ZoneScoped;
JUT_ASSERT(378, mValid); JUT_ASSERT(378, mValid);
JUTFont::TWidth width; JUTFont::TWidth width;
loadFont(str_int, GX_TEXMAP0, &width FONT_DRAW_CTX_ARG); loadFont(str_int, GX_TEXMAP0, &width FONT_DRAW_CTX_ARG);
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop-application">
<id>dev.twilitrealm.dusk</id>
<launchable type="desktop-id">dev.twilitrealm.dusk.desktop</launchable>
<name>Dusklight</name>
<summary>Native port of a classic adventure game</summary>
<developer id="dev.twilitrealm">
<name>Twilit Realm</name>
</developer>
<url type="homepage">https://twilitrealm.dev</url>
<url type="bugtracker">https://github.com/TwilitRealm/dusklight/issues</url>
<metadata_license>CC0-1.0</metadata_license>
<project_license>CC0-1.0</project_license>
<content_rating type="oars-1.0"/>
<supports>
<control>console</control>
<control>gamepad</control>
</supports>
<description>
<p>
Dusklight is a reverse-engineered reimplementation of a classic adventure game.
It aims to be as accurate as possible to the original while also providing new options, enhancements, and tools to customize your experience.
</p>
</description>
<provides>
<binary>dusklight</binary>
<id>dev.twilitrealm.dusk.desktop</id>
</provides>
<releases>
<release version="UNRELEASED" date="2026-12-31">
<description>
<p>Initial Flatpak release.</p>
</description>
</release>
</releases>
</component>
File diff suppressed because it is too large Load Diff
+46 -18
View File
@@ -12734,7 +12734,19 @@ void daAlink_c::setMagicArmorBrk(int i_status) {
BOOL daAlink_c::checkMagicArmorHeavy() const { BOOL daAlink_c::checkMagicArmorHeavy() const {
#if TARGET_PC #if TARGET_PC
return checkMagicArmorWearAbility() && (dComIfGs_getRupee() == 0 && !dusk::getSettings().game.freeMagicArmor); if(!checkMagicArmorWearAbility()) {
return false;
}
switch(dusk::getSettings().game.armorRupeeDrain) {
case dusk::MagicArmorMode::NORMAL:
return dComIfGs_getRupee() == 0;
case dusk::MagicArmorMode::ON_DAMAGE:
case dusk::MagicArmorMode::DOUBLE_DEFENSE:
case dusk::MagicArmorMode::INVINCIBLE:
case dusk::MagicArmorMode::COSMETIC:
return false;
}
#else #else
return checkMagicArmorWearAbility() && dComIfGs_getRupee() == 0; return checkMagicArmorWearAbility() && dComIfGs_getRupee() == 0;
#endif #endif
@@ -14796,6 +14808,8 @@ void daAlink_c::deleteEquipItem(BOOL i_isPlaySound, BOOL i_isDeleteKantera) {
#if TARGET_PC #if TARGET_PC
mIBChainInterpPrevValid = false; mIBChainInterpPrevValid = false;
mIBChainInterpCurrValid = false; mIBChainInterpCurrValid = false;
mHsChainInterpPrevValid = false;
mHsChainInterpCurrValid = false;
#endif #endif
field_0x0774 = NULL; field_0x0774 = NULL;
field_0x0778 = NULL; field_0x0778 = NULL;
@@ -18707,7 +18721,7 @@ int daAlink_c::execute() {
#if TARGET_PC #if TARGET_PC
// This handles rupee drain and transitions between rupees/no rupees // This handles rupee drain and transitions between rupees/no rupees
// We can skip all of that if the magic armor doesn't use rupees // We can skip all of that if the magic armor doesn't use rupees
if (!dusk::getSettings().game.freeMagicArmor && checkMagicArmorWearAbility() && mClothesChangeWaitTimer == 0) { if (dusk::getSettings().game.armorRupeeDrain.getValue() == dusk::MagicArmorMode::NORMAL && checkMagicArmorWearAbility() && mClothesChangeWaitTimer == 0) {
#else #else
if (checkMagicArmorWearAbility() && mClothesChangeWaitTimer == 0) { if (checkMagicArmorWearAbility() && mClothesChangeWaitTimer == 0) {
#endif #endif
@@ -19768,23 +19782,37 @@ int daAlink_c::draw() {
dComIfGd_getOpaListDark()->entryImm(mpHookChain, 0); dComIfGd_getOpaListDark()->entryImm(mpHookChain, 0);
#if TARGET_PC #if TARGET_PC
if (dusk::frame_interp::is_enabled() && if (dusk::frame_interp::is_enabled()) {
mEquipItem == dItemNo_IRONBALL_e && if (mEquipItem == dItemNo_IRONBALL_e &&
mIronBallChainPos != NULL && mIronBallChainAngle != NULL) mIronBallChainPos != NULL && mIronBallChainAngle != NULL)
{ {
if (mIBChainInterpCurrValid) { if (mIBChainInterpCurrValid) {
memcpy(mIBChainInterpPrevPos, mIBChainInterpCurrPos, IRON_BALL_CHAIN_COUNT * sizeof(cXyz)); memcpy(mIBChainInterpPrevPos, mIBChainInterpCurrPos, IRON_BALL_CHAIN_COUNT * sizeof(cXyz));
memcpy(mIBChainInterpPrevAngle, mIBChainInterpCurrAngle, IRON_BALL_CHAIN_COUNT * sizeof(csXyz)); memcpy(mIBChainInterpPrevAngle, mIBChainInterpCurrAngle, IRON_BALL_CHAIN_COUNT * sizeof(csXyz));
mIBChainInterpPrevHandRoot = mIBChainInterpCurrHandRoot; mIBChainInterpPrevHandRoot = mIBChainInterpCurrHandRoot;
mIBChainInterpPrevValid = true; mIBChainInterpPrevValid = true;
}
memcpy(mIBChainInterpCurrPos, mIronBallChainPos, IRON_BALL_CHAIN_COUNT * sizeof(cXyz));
memcpy(mIBChainInterpCurrAngle, mIronBallChainAngle, IRON_BALL_CHAIN_COUNT * sizeof(csXyz));
mIBChainInterpCurrHandRoot = mHookshotTopPos;
mIBChainInterpCurrValid = true;
dusk::frame_interp::add_interpolation_callback(&ironBallChainInterpCallback, this);
} else {
if (mHsChainInterpCurrValid) {
mHsChainInterpPrevTop = mHsChainInterpCurrTop;
mHsChainInterpPrevRoot = mHsChainInterpCurrRoot;
mHsChainInterpPrevSubRoot = mHsChainInterpCurrSubRoot;
mHsChainInterpPrevSubTop = mHsChainInterpCurrSubTop;
mHsChainInterpPrevValid = true;
}
mHsChainInterpCurrTop = mHookshotTopPos;
mHsChainInterpCurrRoot = mHeldItemRootPos;
mHsChainInterpCurrSubRoot = field_0x3810;
mHsChainInterpCurrSubTop = mIronBallBgChkPos;
mHsChainInterpCurrValid = true;
} }
memcpy(mIBChainInterpCurrPos, mIronBallChainPos, IRON_BALL_CHAIN_COUNT * sizeof(cXyz));
memcpy(mIBChainInterpCurrAngle, mIronBallChainAngle, IRON_BALL_CHAIN_COUNT * sizeof(csXyz));
mIBChainInterpCurrHandRoot = mHookshotTopPos;
mIBChainInterpCurrValid = true;
dusk::frame_interp::add_interpolation_callback(&ironBallChainInterpCallback, this);
} }
#endif #endif
} }
+25 -1
View File
@@ -192,7 +192,7 @@ int daAlink_c::setDamagePoint(int i_dmgAmount, BOOL i_checkZoraMag, BOOL i_setDm
if (checkMagicArmorNoDamage()) { if (checkMagicArmorNoDamage()) {
#if TARGET_PC #if TARGET_PC
if(dusk::getSettings().game.freeMagicArmor) { if(dusk::getSettings().game.armorRupeeDrain.getValue() == dusk::MagicArmorMode::INVINCIBLE) {
i_dmgAmount = 0; i_dmgAmount = 0;
} }
#endif #endif
@@ -202,6 +202,11 @@ int daAlink_c::setDamagePoint(int i_dmgAmount, BOOL i_checkZoraMag, BOOL i_setDm
if (!mpHIO->mDamage.m.mInvincible && g_debugHpMode == 0) if (!mpHIO->mDamage.m.mInvincible && g_debugHpMode == 0)
#endif #endif
{ {
#if TARGET_PC
if(checkMagicArmorWearAbility() && dusk::getSettings().game.armorRupeeDrain.getValue() == dusk::MagicArmorMode::DOUBLE_DEFENSE) {
i_dmgAmount /= 2;
}
#endif
dComIfGp_setItemLifeCount(-i_dmgAmount, 0); dComIfGp_setItemLifeCount(-i_dmgAmount, 0);
} }
@@ -281,7 +286,26 @@ BOOL daAlink_c::checkIcePolygonDamage(cBgS_PolyInfo* i_poly) {
} }
BOOL daAlink_c::checkMagicArmorNoDamage() { BOOL daAlink_c::checkMagicArmorNoDamage() {
#ifdef TARGET_PC
if (!checkMagicArmorWearAbility()) {
return false;
}
switch(dusk::getSettings().game.armorRupeeDrain) {
case dusk::MagicArmorMode::NORMAL:
return !checkMagicArmorHeavy();
case dusk::MagicArmorMode::ON_DAMAGE:
return dComIfGs_getRupee() != 0;
case dusk::MagicArmorMode::DOUBLE_DEFENSE:
return false;
case dusk::MagicArmorMode::INVINCIBLE:
return true;
case dusk::MagicArmorMode::COSMETIC:
return false;
}
#else
return checkMagicArmorWearAbility() && !checkMagicArmorHeavy(); return checkMagicArmorWearAbility() && !checkMagicArmorHeavy();
#endif
} }
int daAlink_c::checkPolyDamage() { int daAlink_c::checkPolyDamage() {
+4 -4
View File
@@ -72,7 +72,7 @@ void daAlink_c::handleQuickTransform() {
} }
// Check to see if Link has the ability to transform. // Check to see if Link has the ability to transform.
if (!dComIfGs_isEventBit(dSv_event_flag_c::M_077) && !dusk::getSettings().game.transformWithoutShadowCrystal) { if (!dComIfGs_isEventBit(dSv_event_flag_c::M_077)) {
return; return;
} }
@@ -102,7 +102,7 @@ void daAlink_c::handleQuickTransform() {
} }
// Ensure that the Z Button is not dimmed // Ensure that the Z Button is not dimmed
if (meterDrawPtr->getButtonZAlpha() != 1.f && !dusk::getSettings().game.transformWithoutShadowCrystal) { if (meterDrawPtr->getButtonZAlpha() != 1.f) {
Z2GetAudioMgr()->seStart(Z2SE_SYS_ERROR, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0); Z2GetAudioMgr()->seStart(Z2SE_SYS_ERROR, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0);
return; return;
} }
@@ -122,7 +122,7 @@ void daAlink_c::handleQuickTransform() {
bool canTransform = false; bool canTransform = false;
if (mLinkAcch.ChkGroundHit() && !checkModeFlg(MODE_PLAYER_FLY) && !checkMagneBootsOn()) { if (mLinkAcch.ChkGroundHit() && !checkModeFlg(MODE_PLAYER_FLY) && !checkMagneBootsOn()) {
if (checkMidnaRide() || dusk::getSettings().game.transformWithoutShadowCrystal) { if (checkMidnaRide()) {
if ((checkWolf() && if ((checkWolf() &&
(checkModeFlg(MODE_UNK_1000) || dComIfGp_checkPlayerStatus0(0, 0x10))) || (checkModeFlg(MODE_UNK_1000) || dComIfGp_checkPlayerStatus0(0, 0x10))) ||
(!checkWolf() && (!checkWolf() &&
@@ -144,7 +144,7 @@ void daAlink_c::handleQuickTransform() {
procCoMetamorphoseInit(); procCoMetamorphoseInit();
} }
bool daAlink_c::checkGyroAimContext() { bool daAlink_c::checkAimContext() {
switch (mProcID) { switch (mProcID) {
case PROC_SUBJECTIVITY: case PROC_SUBJECTIVITY:
case PROC_SWIM_SUBJECTIVITY: case PROC_SWIM_SUBJECTIVITY:
+16 -3
View File
@@ -2028,11 +2028,10 @@ void daAlink_blur_c::traceBlur(cXyz const* param_0, cXyz const* param_1, s16 par
} }
void daAlink_blur_c::draw() { void daAlink_blur_c::draw() {
ZoneScoped;
j3dSys.reinitGX(); j3dSys.reinitGX();
#ifdef TARGET_PC #if !TARGET_PC
TGXTexObj texObj;
#else
static TGXTexObj texObj; static TGXTexObj texObj;
#endif #endif
static GXColor nColor0 = {0xFF, 0xFF, 0xFF, 0x14}; static GXColor nColor0 = {0xFF, 0xFF, 0xFF, 0x14};
@@ -2040,11 +2039,25 @@ void daAlink_blur_c::draw() {
GXSetNumIndStages(0); GXSetNumIndStages(0);
nColor0.a = field_0x20; nColor0.a = field_0x20;
#if TARGET_PC
if (mpCachedBlurTex != m_blurTex) {
mBlurTexObj.reset();
GXInitTexObj(&mBlurTexObj,
reinterpret_cast<void*>(
reinterpret_cast<uintptr_t>(m_blurTex) + m_blurTex->imageOffset),
16, 4, GX_TF_I4, GX_CLAMP, GX_CLAMP, GX_FALSE);
GXInitTexObjLOD(
&mBlurTexObj, GX_LINEAR, GX_LINEAR, 0.0f, 0.0f, 0.0f, GX_FALSE, GX_FALSE, GX_ANISO_1);
mpCachedBlurTex = m_blurTex;
}
GXLoadTexObj(&mBlurTexObj, GX_TEXMAP0);
#else
GXInitTexObj(&texObj, (void*)((uintptr_t)m_blurTex + m_blurTex->imageOffset), 16, 4, GX_TF_I4, GXInitTexObj(&texObj, (void*)((uintptr_t)m_blurTex + m_blurTex->imageOffset), 16, 4, GX_TF_I4,
GX_CLAMP, GX_CLAMP, GX_FALSE); GX_CLAMP, GX_CLAMP, GX_FALSE);
GXInitTexObjLOD(&texObj, GX_LINEAR, GX_LINEAR, 0.0f, 0.0f, 0.0f, GX_FALSE, GX_FALSE, GXInitTexObjLOD(&texObj, GX_LINEAR, GX_LINEAR, 0.0f, 0.0f, 0.0f, GX_FALSE, GX_FALSE,
GX_ANISO_1); GX_ANISO_1);
GXLoadTexObj(&texObj, GX_TEXMAP0); GXLoadTexObj(&texObj, GX_TEXMAP0);
#endif
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGBA, GX_F32, 0); GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGBA, GX_F32, 0);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_CLR_RGBA, GX_RGBA4, 8); GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_CLR_RGBA, GX_RGBA4, 8);
GXClearVtxDesc(); GXClearVtxDesc();
+23
View File
@@ -136,8 +136,26 @@ void daAlink_c::hsChainShape_c::draw() {
} }
} }
} else { } else {
#if TARGET_PC
cXyz hsInterpTop, hsInterpRoot, hsInterpSubRoot, hsInterpSubTop;
if (dusk::frame_interp::is_enabled() && alink->mHsChainInterpPrevValid && alink->mHsChainInterpCurrValid) {
const f32 alpha = dusk::frame_interp::get_interpolation_step();
hsInterpTop = alink->mHsChainInterpPrevTop + (alink->mHsChainInterpCurrTop - alink->mHsChainInterpPrevTop) * alpha;
hsInterpRoot = alink->mHsChainInterpPrevRoot + (alink->mHsChainInterpCurrRoot - alink->mHsChainInterpPrevRoot) * alpha;
hsInterpSubRoot = alink->mHsChainInterpPrevSubRoot + (alink->mHsChainInterpCurrSubRoot - alink->mHsChainInterpPrevSubRoot) * alpha;
hsInterpSubTop = alink->mHsChainInterpPrevSubTop + (alink->mHsChainInterpCurrSubTop - alink->mHsChainInterpPrevSubTop) * alpha;
} else {
hsInterpTop = alink->getHsChainTopPos();
hsInterpRoot = alink->getHsChainRootPos();
hsInterpSubRoot = alink->getHsSubChainRootPos();
hsInterpSubTop = alink->getHsSubChainTopPos();
}
const cXyz& chainRootPos = hsInterpRoot;
const cXyz& chainTopPos = hsInterpTop;
#else
const cXyz& chainRootPos = alink->getHsChainRootPos(); const cXyz& chainRootPos = alink->getHsChainRootPos();
const cXyz& chainTopPos = alink->getHsChainTopPos(); const cXyz& chainTopPos = alink->getHsChainTopPos();
#endif
cXyz maxDistance = chainRootPos - chainTopPos; cXyz maxDistance = chainRootPos - chainTopPos;
f32 maxDistanceF = maxDistance.abs(); f32 maxDistanceF = maxDistance.abs();
@@ -200,8 +218,13 @@ void daAlink_c::hsChainShape_c::draw() {
} }
} }
#if TARGET_PC
const cXyz& subChainRootPos = hsInterpSubRoot;
const cXyz& subChainTopPos = hsInterpSubTop;
#else
const cXyz& subChainRootPos = alink->getHsSubChainRootPos(); const cXyz& subChainRootPos = alink->getHsSubChainRootPos();
const cXyz& subChainTopPos = alink->getHsSubChainTopPos(); const cXyz& subChainTopPos = alink->getHsSubChainTopPos();
#endif
maxDistance = subChainRootPos - subChainTopPos; maxDistance = subChainRootPos - subChainTopPos;
maxDistanceF = maxDistance.abs(); maxDistanceF = maxDistance.abs();
+31 -11
View File
@@ -11,8 +11,9 @@
#include "d/actor/d_a_tag_mhint.h" #include "d/actor/d_a_tag_mhint.h"
#if TARGET_PC #if TARGET_PC
#include "dusk/gyro.h"
#include "dusk/action_bindings.h" #include "dusk/action_bindings.h"
#include "dusk/gyro.h"
#include "dusk/mouse.h"
#endif #endif
bool daAlink_c::checkNoSubjectModeCamera() { bool daAlink_c::checkNoSubjectModeCamera() {
@@ -120,18 +121,28 @@ BOOL daAlink_c::setBodyAngleToCamera() {
var_f31 /= dComIfGp_getCameraZoomScale(field_0x317c); var_f31 /= dComIfGp_getCameraZoomScale(field_0x317c);
} }
shape_angle.y = shape_angle.y + (var_f31 * cM_ssin(mStickAngle) IF_DUSK(* (dusk::getSettings().game.invertFirstPersonXAxis ? -1.0f : 1.0f))); #if TARGET_PC
sp8 = mBodyAngle.x + (var_f31 * cM_scos(mStickAngle) IF_DUSK(* (dusk::getSettings().game.invertFirstPersonYAxis ? -1.0f : 1.0f))); if (dusk::getSettings().game.enableMouseAim && checkAimContext()) {
if (checkNotItemSinkLimit() && sp8 > 0 && sp8 > mBodyAngle.x) {
sp8 = mBodyAngle.x; sp8 = mBodyAngle.x;
} else
#endif
{
shape_angle.y = shape_angle.y + (var_f31 * cM_ssin(mStickAngle) IF_DUSK(* (dusk::getSettings().game.invertFirstPersonXAxis ? -1.0f : 1.0f)));
sp8 = mBodyAngle.x + (var_f31 * cM_scos(mStickAngle) IF_DUSK(* (dusk::getSettings().game.invertFirstPersonYAxis ? -1.0f : 1.0f)));
if (checkNotItemSinkLimit() && sp8 > 0 && sp8 > mBodyAngle.x) {
sp8 = mBodyAngle.x;
}
} }
} else { } else {
sp8 = mBodyAngle.x; sp8 = mBodyAngle.x;
} }
#if TARGET_PC #if TARGET_PC
if (dusk::getSettings().game.enableGyroAim && checkGyroAimContext()) { if ((dusk::getSettings().game.enableGyroAim ||
dusk::getSettings().game.enableMouseAim) &&
checkAimContext())
{
f32 gyro_scale = 1.0f; f32 gyro_scale = 1.0f;
if (checkWolfEyeUp()) { if (checkWolfEyeUp()) {
gyro_scale *= 0.6f; gyro_scale *= 0.6f;
@@ -141,12 +152,21 @@ BOOL daAlink_c::setBodyAngleToCamera() {
gyro_scale /= dComIfGp_getCameraZoomScale(field_0x317c); gyro_scale /= dComIfGp_getCameraZoomScale(field_0x317c);
} }
f32 gy_yaw = 0.f; f32 final_yaw = 0.f;
f32 gy_pitch = 0.f; f32 final_pitch = 0.f;
dusk::gyro::getAimDeltas(gy_yaw, gy_pitch); if (dusk::getSettings().game.enableMouseAim) {
dusk::mouse::getAimDeltas(final_yaw, final_pitch);
}
if (dusk::getSettings().game.enableGyroAim) {
f32 gyro_yaw = 0.f;
f32 gyro_pitch = 0.f;
dusk::gyro::getAimDeltas(gyro_yaw, gyro_pitch);
final_yaw += gyro_yaw;
final_pitch += gyro_pitch;
}
shape_angle.y = shape_angle.y + cM_rad2s(gy_yaw * gyro_scale); shape_angle.y = shape_angle.y + cM_rad2s(final_yaw * gyro_scale);
sp8 = sp8 + cM_rad2s(gy_pitch * gyro_scale); sp8 = sp8 + cM_rad2s(final_pitch * gyro_scale);
if (checkNotItemSinkLimit() && sp8 > 0 && sp8 > mBodyAngle.x) { if (checkNotItemSinkLimit() && sp8 > 0 && sp8 > mBodyAngle.x) {
sp8 = mBodyAngle.x; sp8 = mBodyAngle.x;
+2 -2
View File
@@ -348,7 +348,7 @@ void daAlink_c::changeLink(int param_0) {
initModel(static_cast<J3DModelData*>(dComIfG_getObjectRes(l_mArcName, "al_hands.bmd")), 0); initModel(static_cast<J3DModelData*>(dComIfG_getObjectRes(l_mArcName, "al_hands.bmd")), 0);
#if TARGET_PC #if TARGET_PC
if (dComIfGs_getRupee() != 0 || dusk::getSettings().game.freeMagicArmor) if (dComIfGs_getRupee() != 0 || dusk::getSettings().game.armorRupeeDrain.getValue() != dusk::MagicArmorMode::NORMAL)
#else #else
if (dComIfGs_getRupee() != 0) if (dComIfGs_getRupee() != 0)
#endif #endif
@@ -458,7 +458,7 @@ void daAlink_c::changeLink(int param_0) {
field_0x06f0 = field_0x064C->getMaterialNodePointer(2)->getShape(); field_0x06f0 = field_0x064C->getMaterialNodePointer(2)->getShape();
#if TARGET_PC #if TARGET_PC
if (dComIfGs_getRupee() != 0 || dusk::getSettings().game.freeMagicArmor) { if (dComIfGs_getRupee() != 0 || dusk::getSettings().game.armorRupeeDrain.getValue() != dusk::MagicArmorMode::NORMAL) {
#else #else
if (dComIfGs_getRupee() != 0) { if (dComIfGs_getRupee() != 0) {
#endif #endif
+9
View File
@@ -5472,6 +5472,15 @@ int daB_ZANT_c::create() {
fopAcM_ct(this, daB_ZANT_c); fopAcM_ct(this, daB_ZANT_c);
OS_REPORT("B_ZANT PARAM %x\n", fopAcM_GetParam(this)); OS_REPORT("B_ZANT PARAM %x\n", fopAcM_GetParam(this));
#if TARGET_PC
// Due to our loads being so much faster, Zant can initialize *before* the player
// This breaks respawning in the final phase of the fight when it tries
// to load the player's position
if (daPy_getPlayerActorClass() == NULL) {
return cPhs_INIT_e;
}
#endif
mSwbit = fopAcM_GetParam(this); mSwbit = fopAcM_GetParam(this);
if (mSwbit != 0xFF) { if (mSwbit != 0xFF) {
if (dComIfGs_isSwitch(mSwbit, fopAcM_GetRoomNo(this))) { if (dComIfGs_isSwitch(mSwbit, fopAcM_GetRoomNo(this))) {
+8
View File
@@ -923,6 +923,14 @@ static void damage_check(e_sm2_class* i_this) {
sm_hit_actor->mode = 10; sm_hit_actor->mode = 10;
u8 new_color_type = new_col_d[(sm_hit_actor->type * 7) + i_this->type]; u8 new_color_type = new_col_d[(sm_hit_actor->type * 7) + i_this->type];
#if TARGET_PC
if (dusk::getSettings().game.restoreWiiGlitches &&
((sm_hit_actor->type == TYPE_BLUE && i_this->type == TYPE_YELLOW) ||
(sm_hit_actor->type == TYPE_YELLOW && i_this->type == TYPE_BLUE)))
{
new_color_type = TYPE_GREEN;
}
#endif
i_this->type = new_color_type; i_this->type = new_color_type;
sm_hit_actor->type = new_color_type; sm_hit_actor->type = new_color_type;
+60 -231
View File
@@ -16,12 +16,30 @@
using GameVersion = dusk::version::GameVersion; using GameVersion = dusk::version::GameVersion;
static u8* l_Egnd_mantTEX_get() { alignas(32) static u8 buf[0x4000]; static bool _ = (dusk::LoadRelAsset(buf, "/rel/Final/Release/d_a_mant.rel", {{GameVersion::GcnUsa, 0x1C00}, {GameVersion::GcnPal, 0x1C00}}, 0x4000), true); return buf; } // keep the original version of the cape texture const so we don't need to reload the file
static u8 const * l_Egnd_mantTEX_get() { alignas(32) static u8 buf[0x4000]; static bool _ = (dusk::LoadRelAsset(buf, "/rel/Final/Release/d_a_mant.rel", {{GameVersion::GcnUsa, 0x1C00}, {GameVersion::GcnPal, 0x1C00}}, 0x4000), true); return buf; }
static u8* l_Egnd_mantTEX_U_get() { alignas(32) static u8 buf[0x4000]; static bool _ = (dusk::LoadRelAsset(buf, "/rel/Final/Release/d_a_mant.rel", {{GameVersion::GcnUsa, 0x5C00}, {GameVersion::GcnPal, 0x5C00}}, 0x4000), true); return buf; } static u8* l_Egnd_mantTEX_U_get() { alignas(32) static u8 buf[0x4000]; static bool _ = (dusk::LoadRelAsset(buf, "/rel/Final/Release/d_a_mant.rel", {{GameVersion::GcnUsa, 0x5C00}, {GameVersion::GcnPal, 0x5C00}}, 0x4000), true); return buf; }
static u8* l_Egnd_mantPAL_get() { alignas(32) static u8 buf[0x60]; static bool _ = (dusk::LoadRelAsset(buf, "/rel/Final/Release/d_a_mant.rel", {{GameVersion::GcnUsa, 0x9C00}, {GameVersion::GcnPal, 0x9C00}}, 0x60), true); return buf; } static u8* l_Egnd_mantPAL_get() { alignas(32) static u8 buf[0x60]; static bool _ = (dusk::LoadRelAsset(buf, "/rel/Final/Release/d_a_mant.rel", {{GameVersion::GcnUsa, 0x9C00}, {GameVersion::GcnPal, 0x9C00}}, 0x60), true); return buf; }
#define l_Egnd_mantTEX (l_Egnd_mantTEX_get()) #define l_Egnd_mantTEX (l_Egnd_mantTEX_get())
#define l_Egnd_mantTEX_U (l_Egnd_mantTEX_U_get()) #define l_Egnd_mantTEX_U (l_Egnd_mantTEX_U_get())
#define l_Egnd_mantPAL (l_Egnd_mantPAL_get()) #define l_Egnd_mantPAL (l_Egnd_mantPAL_get())
// make a copy of the cape texture that can be overwritten with the tears
static u8 l_Egnd_mantTEX_copy[0x4000];
// keep our cached texture objects out here so that we can update them from multiple places
static bool textureObjsInitialized = false;
static TGXTlutObj tlutObj;
static TGXTexObj mainTexObj;
static TGXTexObj undersideTexObj;
// l_pos is unused
//static f32* l_pos_get() { alignas(32) static f32 buf[507]; static bool _ = (dusk::LoadRelAsset(buf, "/rel/Final/Release/d_a_mant.rel", {{GameVersion::GcnUsa, 0xA44C}, {GameVersion::GcnPal, 0xA44C}}, sizeof(buf)), true); return buf; }
static f32* l_normal_get() { alignas(32) static f32 buf[3]; static bool _ = (dusk::LoadRelAsset(buf, "/rel/Final/Release/d_a_mant.rel", {{GameVersion::GcnUsa, 0x9C60}, {GameVersion::GcnPal, 0x9C60}}, sizeof(buf)), true); return buf; }
static f32* l_texCoord_get() { alignas(32) static f32 buf[338]; static bool _ = (dusk::LoadRelAsset(buf, "/rel/Final/Release/d_a_mant.rel", {{GameVersion::GcnUsa, 0xA458}, {GameVersion::GcnPal, 0xA458}}, sizeof(buf)), true); return buf; }
//#define l_pos (l_pos_get())
#define l_normal (l_normal_get())
#define l_texCoord (l_texCoord_get())
#else #else
#include "assets/l_Egnd_mantTEX.h" #include "assets/l_Egnd_mantTEX.h"
@@ -31,228 +49,6 @@ static u8* l_Egnd_mantPAL_get() { alignas(32) static u8 buf[0x60]; static bo
#endif #endif
#include "d/d_s_play.h" #include "d/d_s_play.h"
static u32 l_pos[507] = {
0x42480000, 0x3F5CFC93, 0xC365BD9C, 0x4226AAAA,
0x3F5CFC93, 0xC365BD9C, 0x42055556, 0x3F5CFC93,
0xC365BD9C, 0x41C80000, 0x3F5CFC93, 0xC365BD9C,
0x41855556, 0x3F5CFC93, 0xC365BD9C, 0x41055556,
0x3F5CFC93, 0xC365BD9C, 0x358637BD, 0x3F5CFC93,
0xC365BD9C, 0xC1055554, 0x3F5CFC93, 0xC365BD9C,
0xC1855554, 0x3F5CFC93, 0xC365BD9C, 0xC1C7FFFF,
0x3F5CFC93, 0xC365BD9C, 0xC2055554, 0x3F5CFC93,
0xC365BD9C, 0xC226AAAA, 0x3F5CFC93, 0xC365BD9C,
0xC2480000, 0x3F5CFC93, 0xC365BD9C, 0x42480000,
0x3F5CFC93, 0xC35292F0, 0x4226AAAA, 0x3F5CFC93,
0xC35292F0, 0x42055556, 0x3F5CFC93, 0xC35292F0,
0x41C80000, 0x3F5CFC93, 0xC35292F0, 0x41855556,
0x3F5CFC93, 0xC35292F0, 0x41055556, 0x3F5CFC93,
0xC35292F0, 0x358637BD, 0x3F5CFC93, 0xC35292F0,
0xC1055554, 0x3F5CFC93, 0xC35292F0, 0xC1855554,
0x3F5CFC93, 0xC35292F0, 0xC1C7FFFF, 0x3F5CFC93,
0xC35292F0, 0xC2055554, 0x3F5CFC93, 0xC35292F0,
0xC226AAAA, 0x3F5CFC93, 0xC35292F0, 0xC2480000,
0x3F5CFC93, 0xC35292F0, 0x42480000, 0x3F5CFC93,
0xC33F6846, 0x4226AAAA, 0x3F5CFC93, 0xC33F6846,
0x42055556, 0x3F5CFC93, 0xC33F6846, 0x41C80000,
0x3F5CFC93, 0xC33F6846, 0x41855556, 0x3F5CFC93,
0xC33F6846, 0x41055556, 0x3F5CFC93, 0xC33F6846,
0x358637BD, 0x3F5CFC93, 0xC33F6846, 0xC1055554,
0x3F5CFC93, 0xC33F6846, 0xC1855554, 0x3F5CFC93,
0xC33F6846, 0xC1C7FFFF, 0x3F5CFC93, 0xC33F6846,
0xC2055554, 0x3F5CFC93, 0xC33F6846, 0xC226AAAA,
0x3F5CFC93, 0xC33F6846, 0xC2480000, 0x3F5CFC93,
0xC33F6846, 0x42480000, 0x3F5CFC93, 0xC32C3D9C,
0x4226AAAA, 0x3F5CFC93, 0xC32C3D9C, 0x42055556,
0x3F5CFC93, 0xC32C3D9C, 0x41C80000, 0x3F5CFC93,
0xC32C3D9C, 0x41855556, 0x3F5CFC93, 0xC32C3D9C,
0x41055556, 0x3F5CFC93, 0xC32C3D9C, 0x358637BD,
0x3F5CFC93, 0xC32C3D9C, 0xC1055554, 0x3F5CFC93,
0xC32C3D9C, 0xC1855554, 0x3F5CFC93, 0xC32C3D9C,
0xC1C7FFFF, 0x3F5CFC93, 0xC32C3D9C, 0xC2055554,
0x3F5CFC93, 0xC32C3D9C, 0xC226AAAA, 0x3F5CFC93,
0xC32C3D9C, 0xC2480000, 0x3F5CFC93, 0xC32C3D9C,
0x42480000, 0x3F5CFC93, 0xC31912F1, 0x4226AAAA,
0x3F5CFC93, 0xC31912F1, 0x42055556, 0x3F5CFC93,
0xC31912F1, 0x41C80000, 0x3F5CFC93, 0xC31912F1,
0x41855556, 0x3F5CFC93, 0xC31912F1, 0x41055556,
0x3F5CFC93, 0xC31912F1, 0x358637BD, 0x3F5CFC93,
0xC31912F1, 0xC1055554, 0x3F5CFC93, 0xC31912F1,
0xC1855554, 0x3F5CFC93, 0xC31912F1, 0xC1C7FFFF,
0x3F5CFC93, 0xC31912F1, 0xC2055554, 0x3F5CFC93,
0xC31912F1, 0xC226AAAA, 0x3F5CFC93, 0xC31912F1,
0xC2480000, 0x3F5CFC93, 0xC31912F1, 0x42480000,
0x3F5CFC93, 0xC305E846, 0x4226AAAA, 0x3F5CFC93,
0xC305E846, 0x42055556, 0x3F5CFC93, 0xC305E846,
0x41C80000, 0x3F5CFC93, 0xC305E846, 0x41855556,
0x3F5CFC93, 0xC305E846, 0x41055556, 0x3F5CFC93,
0xC305E846, 0x358637BD, 0x3F5CFC93, 0xC305E846,
0xC1055554, 0x3F5CFC93, 0xC305E846, 0xC1855554,
0x3F5CFC93, 0xC305E846, 0xC1C7FFFF, 0x3F5CFC93,
0xC305E846, 0xC2055554, 0x3F5CFC93, 0xC305E846,
0xC226AAAA, 0x3F5CFC93, 0xC305E846, 0xC2480000,
0x3F5CFC93, 0xC305E846, 0x42480000, 0x3F5CFC93,
0xC2E57B38, 0x4226AAAA, 0x3F5CFC93, 0xC2E57B38,
0x42055556, 0x3F5CFC93, 0xC2E57B38, 0x41C80000,
0x3F5CFC93, 0xC2E57B38, 0x41855556, 0x3F5CFC93,
0xC2E57B38, 0x41055556, 0x3F5CFC93, 0xC2E57B38,
0x358637BD, 0x3F5CFC93, 0xC2E57B38, 0xC1055554,
0x3F5CFC93, 0xC2E57B38, 0xC1855554, 0x3F5CFC93,
0xC2E57B38, 0xC1C7FFFF, 0x3F5CFC93, 0xC2E57B38,
0xC2055554, 0x3F5CFC93, 0xC2E57B38, 0xC226AAAA,
0x3F5CFC93, 0xC2E57B38, 0xC2480000, 0x3F5CFC93,
0xC2E57B38, 0x42480000, 0x3F5CFC93, 0xC2BF25E2,
0x4226AAAA, 0x3F5CFC93, 0xC2BF25E2, 0x42055556,
0x3F5CFC93, 0xC2BF25E2, 0x41C80000, 0x3F5CFC93,
0xC2BF25E2, 0x41855556, 0x3F5CFC93, 0xC2BF25E2,
0x41055556, 0x3F5CFC93, 0xC2BF25E2, 0x358637BD,
0x3F5CFC93, 0xC2BF25E2, 0xC1055554, 0x3F5CFC93,
0xC2BF25E2, 0xC1855554, 0x3F5CFC93, 0xC2BF25E2,
0xC1C7FFFF, 0x3F5CFC93, 0xC2BF25E2, 0xC2055554,
0x3F5CFC93, 0xC2BF25E2, 0xC226AAAA, 0x3F5CFC93,
0xC2BF25E2, 0xC2480000, 0x3F5CFC93, 0xC2BF25E2,
0x42480000, 0x3F5CFC93, 0xC298D08D, 0x4226AAAA,
0x3F5CFC93, 0xC298D08D, 0x42055556, 0x3F5CFC93,
0xC298D08D, 0x41C80000, 0x3F5CFC93, 0xC298D08D,
0x41855556, 0x3F5CFC93, 0xC298D08D, 0x41055556,
0x3F5CFC93, 0xC298D08D, 0x358637BD, 0x3F5CFC93,
0xC298D08D, 0xC1055554, 0x3F5CFC93, 0xC298D08D,
0xC1855554, 0x3F5CFC93, 0xC298D08D, 0xC1C7FFFF,
0x3F5CFC93, 0xC298D08D, 0xC2055554, 0x3F5CFC93,
0xC298D08D, 0xC226AAAA, 0x3F5CFC93, 0xC298D08D,
0xC2480000, 0x3F5CFC93, 0xC298D08D, 0x42480000,
0x3F5CFC93, 0xC264F66F, 0x4226AAAA, 0x3F5CFC93,
0xC264F66F, 0x42055556, 0x3F5CFC93, 0xC264F66F,
0x41C80000, 0x3F5CFC93, 0xC264F66F, 0x41855556,
0x3F5CFC93, 0xC264F66F, 0x41055556, 0x3F5CFC93,
0xC264F66F, 0x358637BD, 0x3F5CFC93, 0xC264F66F,
0xC1055554, 0x3F5CFC93, 0xC264F66F, 0xC1855554,
0x3F5CFC93, 0xC264F66F, 0xC1C7FFFF, 0x3F5CFC93,
0xC264F66F, 0xC2055554, 0x3F5CFC93, 0xC264F66F,
0xC226AAAA, 0x3F5CFC93, 0xC264F66F, 0xC2480000,
0x3F5CFC93, 0xC264F66F, 0x42480000, 0x3F5CFC93,
0xC2184BC4, 0x4226AAAA, 0x3F5CFC93, 0xC2184BC4,
0x42055556, 0x3F5CFC93, 0xC2184BC4, 0x41C80000,
0x3F5CFC93, 0xC2184BC4, 0x41855556, 0x3F5CFC93,
0xC2184BC4, 0x41055556, 0x3F5CFC93, 0xC2184BC4,
0x358637BD, 0x3F5CFC93, 0xC2184BC4, 0xC1055554,
0x3F5CFC93, 0xC2184BC4, 0xC1855554, 0x3F5CFC93,
0xC2184BC4, 0xC1C7FFFF, 0x3F5CFC93, 0xC2184BC4,
0xC2055554, 0x3F5CFC93, 0xC2184BC4, 0xC226AAAA,
0x3F5CFC93, 0xC2184BC4, 0xC2480000, 0x3F5CFC93,
0xC2184BC4, 0x42480000, 0x3F5CFC93, 0xC1974231,
0x4226AAAA, 0x3F5CFC93, 0xC1974231, 0x42055556,
0x3F5CFC93, 0xC1974231, 0x41C80000, 0x3F5CFC93,
0xC1974231, 0x41855556, 0x3F5CFC93, 0xC1974231,
0x41055556, 0x3F5CFC93, 0xC1974231, 0x358637BD,
0x3F5CFC93, 0xC1974231, 0xC1055554, 0x3F5CFC93,
0xC1974231, 0xC1855554, 0x3F5CFC93, 0xC1974231,
0xC1C7FFFF, 0x3F5CFC93, 0xC1974231, 0xC2055554,
0x3F5CFC93, 0xC1974231, 0xC226AAAA, 0x3F5CFC93,
0xC1974231, 0xC2480000, 0x3F5CFC93, 0xC1974231,
0x42480000, 0x3F5CFC93, 0x3E84C964, 0x4226AAAA,
0x3F5CFC93, 0x3E84C964, 0x42055556, 0x3F5CFC93,
0x3E84C964, 0x41C80000, 0x3F5CFC93, 0x3E84C964,
0x41855556, 0x3F5CFC93, 0x3E84C964, 0x41055556,
0x3F5CFC93, 0x3E84C964, 0x358637BD, 0x3F5CFC93,
0x3E84C964, 0xC1055554, 0x3F5CFC93, 0x3E84C964,
0xC1855554, 0x3F5CFC93, 0x3E84C964, 0xC1C7FFFF,
0x3F5CFC93, 0x3E84C964, 0xC2055554, 0x3F5CFC93,
0x3E84C964, 0xC226AAAA, 0x3F5CFC93, 0x3E84C964,
0xC2480000, 0x3F5CFC93, 0x3E84C964,
};
static u32 l_normal[3] = {
0x00000000, 0x3F800000, 0x00000000,
};
static u32 l_texCoord[338] = {
0x00000000, 0x3F6AAAB0, 0x3DAAAA7E, 0x3F6AAAB0,
0x3DAAAA7E, 0x3F800000, 0x00000000, 0x3F800000,
0x3E2AAAC1, 0x3F6AAAB0, 0x3E2AAAC1, 0x3F800000,
0x3E800000, 0x3F6AAAB0, 0x3E800000, 0x3F800000,
0x3EAAAA9F, 0x3F6AAAB0, 0x3EAAAA9F, 0x3F800000,
0x3ED55561, 0x3F6AAAB0, 0x3ED55561, 0x3F800000,
0x3F000000, 0x3F6AAAB0, 0x3F000000, 0x3F800000,
0x3F155550, 0x3F6AAAB0, 0x3F155550, 0x3F800000,
0x3F2AAAB0, 0x3F6AAAB0, 0x3F2AAAB0, 0x3F800000,
0x3F400000, 0x3F6AAAB0, 0x3F400000, 0x3F800000,
0x3F555550, 0x3F6AAAB0, 0x3F555550, 0x3F800000,
0x3F6AAAB0, 0x3F6AAAB0, 0x3F6AAAB0, 0x3F800000,
0x3F800000, 0x3F6AAAB0, 0x3F800000, 0x3F800000,
0x00000000, 0x3F555550, 0x3DAAAA7E, 0x3F555550,
0x3E2AAAC1, 0x3F555550, 0x3E800000, 0x3F555550,
0x3EAAAA9F, 0x3F555550, 0x3ED55561, 0x3F555550,
0x3F000000, 0x3F555550, 0x3F155550, 0x3F555550,
0x3F2AAAB0, 0x3F555550, 0x3F400000, 0x3F555550,
0x3F555550, 0x3F555550, 0x3F6AAAB0, 0x3F555550,
0x3F800000, 0x3F555550, 0x00000000, 0x3F400000,
0x3DAAAA7E, 0x3F400000, 0x3E2AAAC1, 0x3F400000,
0x3E800000, 0x3F400000, 0x3EAAAA9F, 0x3F400000,
0x3ED55561, 0x3F400000, 0x3F000000, 0x3F400000,
0x3F155550, 0x3F400000, 0x3F2AAAB0, 0x3F400000,
0x3F400000, 0x3F400000, 0x3F555550, 0x3F400000,
0x3F6AAAB0, 0x3F400000, 0x3F800000, 0x3F400000,
0x00000000, 0x3F2AAAB0, 0x3DAAAA7E, 0x3F2AAAB0,
0x3E2AAAC1, 0x3F2AAAB0, 0x3E800000, 0x3F2AAAB0,
0x3EAAAA9F, 0x3F2AAAB0, 0x3ED55561, 0x3F2AAAB0,
0x3F000000, 0x3F2AAAB0, 0x3F155550, 0x3F2AAAB0,
0x3F2AAAB0, 0x3F2AAAB0, 0x3F400000, 0x3F2AAAB0,
0x3F555550, 0x3F2AAAB0, 0x3F6AAAB0, 0x3F2AAAB0,
0x3F800000, 0x3F2AAAB0, 0x00000000, 0x3F155550,
0x3DAAAA7E, 0x3F155550, 0x3E2AAAC1, 0x3F155550,
0x3E800000, 0x3F155550, 0x3EAAAA9F, 0x3F155550,
0x3ED55561, 0x3F155550, 0x3F000000, 0x3F155550,
0x3F155550, 0x3F155550, 0x3F2AAAB0, 0x3F155550,
0x3F400000, 0x3F155550, 0x3F555550, 0x3F155550,
0x3F6AAAB0, 0x3F155550, 0x3F800000, 0x3F155550,
0x00000000, 0x3F000000, 0x3DAAAA7E, 0x3F000000,
0x3E2AAAC1, 0x3F000000, 0x3E800000, 0x3F000000,
0x3EAAAA9F, 0x3F000000, 0x3ED55561, 0x3F000000,
0x3F000000, 0x3F000000, 0x3F155550, 0x3F000000,
0x3F2AAAB0, 0x3F000000, 0x3F400000, 0x3F000000,
0x3F555550, 0x3F000000, 0x3F6AAAB0, 0x3F000000,
0x3F800000, 0x3F000000, 0x00000000, 0x3ED55561,
0x3DAAAA7E, 0x3ED55561, 0x3E2AAAC1, 0x3ED55561,
0x3E800000, 0x3ED55561, 0x3EAAAA9F, 0x3ED55561,
0x3ED55561, 0x3ED55561, 0x3F000000, 0x3ED55561,
0x3F155550, 0x3ED55561, 0x3F2AAAB0, 0x3ED55561,
0x3F400000, 0x3ED55561, 0x3F555550, 0x3ED55561,
0x3F6AAAB0, 0x3ED55561, 0x3F800000, 0x3ED55561,
0x00000000, 0x3EAAAA9F, 0x3DAAAA7E, 0x3EAAAA9F,
0x3E2AAAC1, 0x3EAAAA9F, 0x3E800000, 0x3EAAAA9F,
0x3EAAAA9F, 0x3EAAAA9F, 0x3ED55561, 0x3EAAAA9F,
0x3F000000, 0x3EAAAA9F, 0x3F155550, 0x3EAAAA9F,
0x3F2AAAB0, 0x3EAAAA9F, 0x3F400000, 0x3EAAAA9F,
0x3F555550, 0x3EAAAA9F, 0x3F6AAAB0, 0x3EAAAA9F,
0x3F800000, 0x3EAAAA9F, 0x00000000, 0x3E800000,
0x3DAAAA7E, 0x3E800000, 0x3E2AAAC1, 0x3E800000,
0x3E800000, 0x3E800000, 0x3EAAAA9F, 0x3E800000,
0x3ED55561, 0x3E800000, 0x3F000000, 0x3E800000,
0x3F155550, 0x3E800000, 0x3F2AAAB0, 0x3E800000,
0x3F400000, 0x3E800000, 0x3F555550, 0x3E800000,
0x3F6AAAB0, 0x3E800000, 0x3F800000, 0x3E800000,
0x00000000, 0x3E2AAAC1, 0x3DAAAA7E, 0x3E2AAAC1,
0x3E2AAAC1, 0x3E2AAAC1, 0x3E800000, 0x3E2AAAC1,
0x3EAAAA9F, 0x3E2AAAC1, 0x3ED55561, 0x3E2AAAC1,
0x3F000000, 0x3E2AAAC1, 0x3F155550, 0x3E2AAAC1,
0x3F2AAAB0, 0x3E2AAAC1, 0x3F400000, 0x3E2AAAC1,
0x3F555550, 0x3E2AAAC1, 0x3F6AAAB0, 0x3E2AAAC1,
0x3F800000, 0x3E2AAAC1, 0x00000000, 0x3DAAAA7E,
0x3DAAAA7E, 0x3DAAAA7E, 0x3E2AAAC1, 0x3DAAAA7E,
0x3E800000, 0x3DAAAA7E, 0x3EAAAA9F, 0x3DAAAA7E,
0x3ED55561, 0x3DAAAA7E, 0x3F000000, 0x3DAAAA7E,
0x3F155550, 0x3DAAAA7E, 0x3F2AAAB0, 0x3DAAAA7E,
0x3F400000, 0x3DAAAA7E, 0x3F555550, 0x3DAAAA7E,
0x3F6AAAB0, 0x3DAAAA7E, 0x3F800000, 0x3DAAAA7E,
0x00000000, 0x00000000, 0x3DAAAA7E, 0x00000000,
0x3E2AAAC1, 0x00000000, 0x3E800000, 0x00000000,
0x3EAAAA9F, 0x00000000, 0x3ED55561, 0x00000000,
0x3F000000, 0x00000000, 0x3F155550, 0x00000000,
0x3F2AAAB0, 0x00000000, 0x3F400000, 0x00000000,
0x3F555550, 0x00000000, 0x3F6AAAB0, 0x00000000,
0x3F800000, 0x00000000,
};
#if TARGET_PC #if TARGET_PC
using GameVersion = dusk::version::GameVersion; using GameVersion = dusk::version::GameVersion;
@@ -305,8 +101,9 @@ static void mant_build_anchor_frame(const cXyz& anchor_a, const cXyz& anchor_b,
#endif #endif
void daMant_packet_c::draw() { void daMant_packet_c::draw() {
ZoneScoped;
#if TARGET_PC #if TARGET_PC
void* image = l_Egnd_mantTEX; void* image = l_Egnd_mantTEX_copy;
void* lut = l_Egnd_mantPAL; void* lut = l_Egnd_mantPAL;
#else #else
void* image = tex_d[0]; void* image = tex_d[0];
@@ -388,12 +185,12 @@ void daMant_packet_c::draw() {
} }
} }
GXSETARRAY(GX_VA_POS, draw_pos, sizeof(mNrm[0]), 12, true); GXSETARRAY(GX_VA_POS, draw_pos, sizeof(mNrm[0]), 12, true);
GXSETARRAY(GX_VA_NRM, &l_normal, sizeof(l_normal), 12, false); GXSETARRAY(GX_VA_NRM, l_normal, sizeof(f32) * 3, 12, false);
#else #else
GXSETARRAY(GX_VA_POS, this->getPos(), sizeof(mPos[0]), 12, true); GXSETARRAY(GX_VA_POS, this->getPos(), sizeof(mPos[0]), 12, true);
GXSETARRAY(GX_VA_NRM, this->getNrm(), sizeof(mNrm[0]), 12, true); GXSETARRAY(GX_VA_NRM, this->getNrm(), sizeof(mNrm[0]), 12, true);
#endif #endif
GXSETARRAY(GX_VA_TEX0, &l_texCoord, sizeof(l_texCoord), 8, false); // TODO: set to true when converted to float literals GXSETARRAY(GX_VA_TEX0, l_texCoord, sizeof(f32) * 338, 8, false);
GXSetZCompLoc(0); GXSetZCompLoc(0);
GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_ENABLE); GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_ENABLE);
@@ -418,15 +215,32 @@ void daMant_packet_c::draw() {
GXSetTevKAlphaSel(GX_TEVSTAGE0, GX_TEV_KASEL_K3_A); GXSetTevKAlphaSel(GX_TEVSTAGE0, GX_TEV_KASEL_K3_A);
GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_OR, GX_GREATER, 0); GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_OR, GX_GREATER, 0);
#if TARGET_PC
if (!textureObjsInitialized) {
GXInitTlutObj(&tlutObj, lut, GX_TL_RGB5A3, 0x100);
GXInitTexObjCI(&mainTexObj, image, 0x80, 0x80, GX_TF_C8, GX_CLAMP, GX_CLAMP, 0, 0);
GXInitTexObjLOD(&mainTexObj, GX_LINEAR, GX_LINEAR, 0.0, 0.0, 0.0, 0, 0, GX_ANISO_1);
GXInitTexObjCI(
&undersideTexObj, l_Egnd_mantTEX_U, 0x80, 0x80, GX_TF_C8, GX_CLAMP, GX_CLAMP, 0, 0);
GXInitTexObjLOD(&undersideTexObj, GX_LINEAR, GX_LINEAR, 0.0, 0.0, 0.0, 0, 0, GX_ANISO_1);
textureObjsInitialized = true;
}
#else
GXTlutObj GStack_80; GXTlutObj GStack_80;
GXInitTlutObj(&GStack_80, lut, GX_TL_RGB5A3, 0x100); GXInitTlutObj(&GStack_80, lut, GX_TL_RGB5A3, 0x100);
TGXTexObj GStack_74; TGXTexObj GStack_74;
GXInitTexObjCI(&GStack_74, image, 0x80, 0x80, GX_TF_C8, GX_CLAMP, GX_CLAMP, 0, 0); GXInitTexObjCI(&GStack_74, image, 0x80, 0x80, GX_TF_C8, GX_CLAMP, GX_CLAMP, 0, 0);
GXInitTexObjLOD(&GStack_74, GX_LINEAR, GX_LINEAR, 0.0, 0.0, 0.0, 0, 0, GX_ANISO_1); GXInitTexObjLOD(&GStack_74, GX_LINEAR, GX_LINEAR, 0.0, 0.0, 0.0, 0, 0, GX_ANISO_1);
#endif
GXLoadTlut(&GStack_80, 0); #if TARGET_PC
GXLoadTlut(&tlutObj, GX_TLUT0);
GXLoadTexObj(&mainTexObj, GX_TEXMAP0);
#else
GXLoadTlut(&GStack_80, GX_TLUT0);
GXLoadTexObj(&GStack_74, GX_TEXMAP0); GXLoadTexObj(&GStack_74, GX_TEXMAP0);
#endif
GXSetCullMode(GX_CULL_BACK); GXSetCullMode(GX_CULL_BACK);
@@ -442,12 +256,13 @@ void daMant_packet_c::draw() {
GXLoadNrmMtxImm(MStack_54, GX_PNMTX0); GXLoadNrmMtxImm(MStack_54, GX_PNMTX0);
GXCallDisplayList(l_Egnd_mantDL, 0x3e0); GXCallDisplayList(l_Egnd_mantDL, 0x3e0);
#ifdef TARGET_PC #if TARGET_PC
GStack_74.reset(); GXLoadTexObj(&undersideTexObj, GX_TEXMAP0);
#endif #else
GXInitTexObjCI(&GStack_74, l_Egnd_mantTEX_U, 0x80, 0x80, GX_TF_C8, GX_CLAMP, GX_CLAMP, 0, 0); GXInitTexObjCI(&GStack_74, l_Egnd_mantTEX_U, 0x80, 0x80, GX_TF_C8, GX_CLAMP, GX_CLAMP, 0, 0);
GXInitTexObjLOD(&GStack_74, GX_LINEAR, GX_LINEAR, 0.0, 0.0, 0.0, 0, 0, GX_ANISO_1); GXInitTexObjLOD(&GStack_74, GX_LINEAR, GX_LINEAR, 0.0, 0.0, 0.0, 0, 0, GX_ANISO_1);
GXLoadTexObj(&GStack_74, GX_TEXMAP0); GXLoadTexObj(&GStack_74, GX_TEXMAP0);
#endif
GXSetTevColor(GX_TEVREG0, COMPOUND_LITERAL(GXColor){0, 0, 0, 0}); GXSetTevColor(GX_TEVREG0, COMPOUND_LITERAL(GXColor){0, 0, 0, 0});
GXSetTevKColor(GX_KCOLOR0, COMPOUND_LITERAL(GXColor){0, 0, 0, 0}); GXSetTevKColor(GX_KCOLOR0, COMPOUND_LITERAL(GXColor){0, 0, 0, 0});
@@ -894,8 +709,14 @@ static int daMant_Execute(mant_class* i_this) {
if (0 <= uVar1 && uVar1 < 0x4000) { if (0 <= uVar1 && uVar1 < 0x4000) {
int iVar5 = (uVar1 & 7) + (uVar1 & 0x78) * 4 + (uVar1 >> 4 & 0x18) + (uVar1 & 0x3e00); int iVar5 = (uVar1 & 7) + (uVar1 & 0x78) * 4 + (uVar1 >> 4 & 0x18) + (uVar1 & 0x3e00);
l_Egnd_mantTEX[iVar5] = l_Egnd_mantTEX_U[iVar5] = 0; DUSK_IF_ELSE(l_Egnd_mantTEX_copy[iVar5], l_Egnd_mantTEX[iVar5]) = l_Egnd_mantTEX_U[iVar5] = 0;
} }
#if TARGET_PC
if(textureObjsInitialized) {
GXInitTlutObjData(&tlutObj, l_Egnd_mantPAL); // make sure the cached textures are updated
}
#endif
} }
} }
@@ -933,6 +754,14 @@ static int daMant_Create(fopAc_ac_c* i_this) {
l_Egnd_mantTEX_U[i] = 6; l_Egnd_mantTEX_U[i] = 6;
} }
#if TARGET_PC
memcpy(l_Egnd_mantTEX_copy, l_Egnd_mantTEX, sizeof(l_Egnd_mantTEX_copy));
if(textureObjsInitialized) {
GXInitTlutObjData(&tlutObj, l_Egnd_mantPAL); // make sure the cached textures are updated
}
#endif
lbl_277_bss_0 = 0; lbl_277_bss_0 = 0;
daMant_Execute(m_this); daMant_Execute(m_this);
return 4; return 4;
+66
View File
@@ -26,6 +26,7 @@
#include <cstring> #include <cstring>
#if TARGET_PC #if TARGET_PC
#include "dusk/frame_interpolation.h"
#include "dusk/settings.h" #include "dusk/settings.h"
#include "dusk/version.hpp" #include "dusk/version.hpp"
#endif #endif
@@ -180,6 +181,25 @@ static int Worm_nodeCallBack(J3DJoint* i_joint, int param_1) {
return 1; return 1;
} }
#if TARGET_PC
static void dmg_rod_interp_callback(bool isSimFrame, void* pUserWork) {
dmg_rod_class* i_this = (dmg_rod_class*)pUserWork;
if (!i_this->mLineInterpPrevValid || !i_this->mLineInterpCurrValid) {
return;
}
const f32 alpha = dusk::frame_interp::get_interpolation_step();
const int count = i_this->kind == MG_ROD_KIND_LURE ? MG_ROD_LURE_LINE_LEN : MG_ROD_UKI_LINE_LEN;
cXyz* dst = i_this->linemat.getPos(0);
for (int i = 0; i < count; i++) {
const cXyz& p0 = i_this->mLineInterpPrev[i];
const cXyz& p1 = i_this->mLineInterpCurr[i];
dst[i] = p0 + (p1 - p0) * alpha;
}
static GXColor l_color = {0xFF, 0xFF, 0x96, 0xFF};
i_this->linemat.update(count, l_color, &i_this->actor.tevStr);
}
#endif
static int dmg_rod_Draw(dmg_rod_class* i_this) { static int dmg_rod_Draw(dmg_rod_class* i_this) {
int unused; int unused;
fopAc_ac_c* actor = &i_this->actor; fopAc_ac_c* actor = &i_this->actor;
@@ -220,6 +240,18 @@ static int dmg_rod_Draw(dmg_rod_class* i_this) {
i_this->linemat.update(MG_ROD_LURE_LINE_LEN, l_color, &i_this->actor.tevStr); i_this->linemat.update(MG_ROD_LURE_LINE_LEN, l_color, &i_this->actor.tevStr);
dComIfGd_set3DlineMat(&i_this->linemat); dComIfGd_set3DlineMat(&i_this->linemat);
#if TARGET_PC
if (dusk::frame_interp::is_enabled()) {
if (i_this->mLineInterpCurrValid) {
memcpy(i_this->mLineInterpPrev, i_this->mLineInterpCurr, MG_ROD_LURE_LINE_LEN * sizeof(cXyz));
i_this->mLineInterpPrevValid = true;
}
memcpy(i_this->mLineInterpCurr, i_this->linemat.getPos(0), MG_ROD_LURE_LINE_LEN * sizeof(cXyz));
i_this->mLineInterpCurrValid = true;
dusk::frame_interp::add_interpolation_callback(&dmg_rod_interp_callback, i_this);
}
#endif
model = i_this->rod_modelMorf->getModel(); model = i_this->rod_modelMorf->getModel();
g_env_light.setLightTevColorType_MAJI(model, &i_this->actor.tevStr); g_env_light.setLightTevColorType_MAJI(model, &i_this->actor.tevStr);
i_this->rod_modelMorf->entryDL(); i_this->rod_modelMorf->entryDL();
@@ -244,6 +276,18 @@ static int dmg_rod_Draw(dmg_rod_class* i_this) {
i_this->linemat.update(MG_ROD_UKI_LINE_LEN, l_color, &i_this->actor.tevStr); i_this->linemat.update(MG_ROD_UKI_LINE_LEN, l_color, &i_this->actor.tevStr);
dComIfGd_set3DlineMat(&i_this->linemat); dComIfGd_set3DlineMat(&i_this->linemat);
#if TARGET_PC
if (dusk::frame_interp::is_enabled()) {
if (i_this->mLineInterpCurrValid) {
memcpy(i_this->mLineInterpPrev, i_this->mLineInterpCurr, MG_ROD_UKI_LINE_LEN * sizeof(cXyz));
i_this->mLineInterpPrevValid = true;
}
memcpy(i_this->mLineInterpCurr, i_this->linemat.getPos(0), MG_ROD_UKI_LINE_LEN * sizeof(cXyz));
i_this->mLineInterpCurrValid = true;
dusk::frame_interp::add_interpolation_callback(&dmg_rod_interp_callback, i_this);
}
#endif
for (int i = 0; i < 15; i++) { for (int i = 0; i < 15; i++) {
g_env_light.setLightTevColorType_MAJI(i_this->rod_uki_model[i], &actor->tevStr); g_env_light.setLightTevColorType_MAJI(i_this->rod_uki_model[i], &actor->tevStr);
mDoExt_modelUpdateDL(i_this->rod_uki_model[i]); mDoExt_modelUpdateDL(i_this->rod_uki_model[i]);
@@ -5755,6 +5799,12 @@ static void play_camera_u(dmg_rod_class* i_this) {
} }
} }
#if TARGET_PC
BOOL item_any_fishing_rod(int itemId) {
return itemId == dItemNo_FISHING_ROD_1_e || (itemId >= dItemNo_BEE_ROD_e && itemId <= dItemNo_JEWEL_WORM_ROD_e);
}
#endif
static int dmg_rod_Execute(dmg_rod_class* i_this) { static int dmg_rod_Execute(dmg_rod_class* i_this) {
fopAc_ac_c* actor = &i_this->actor; fopAc_ac_c* actor = &i_this->actor;
@@ -5821,6 +5871,17 @@ static int dmg_rod_Execute(dmg_rod_class* i_this) {
i_this->prev_rod_substick_y = i_this->rod_substick_y; i_this->prev_rod_substick_y = i_this->rod_substick_y;
i_this->rod_substick_y = mDoCPd_c::getSubStickY(PAD_1); i_this->rod_substick_y = mDoCPd_c::getSubStickY(PAD_1);
#if TARGET_PC
if (dusk::getSettings().game.buttonFishing) {
if ((item_any_fishing_rod(dComIfGp_getSelectItem(0)) && mDoCPd_c::getHoldX(PAD_1)) ||
(item_any_fishing_rod(dComIfGp_getSelectItem(1)) && mDoCPd_c::getHoldY(PAD_1)))
{
i_this->rod_stick_y = -1.0f;
i_this->rod_substick_y = -1.0f;
}
}
#endif
i_this->reel_speed = 5.0f; i_this->reel_speed = 5.0f;
i_this->reel_btn_flags = mDoCPd_c::getHoldB(PAD_1) | mDoCPd_c::getHoldDown(PAD_1); i_this->reel_btn_flags = mDoCPd_c::getHoldB(PAD_1) | mDoCPd_c::getHoldDown(PAD_1);
if (mDoCPd_c::getHoldDown(PAD_1)) { if (mDoCPd_c::getHoldDown(PAD_1)) {
@@ -6388,6 +6449,11 @@ static int dmg_rod_Create(fopAc_ac_c* i_this) {
return cPhs_ERROR_e; return cPhs_ERROR_e;
} }
#if TARGET_PC
rod->mLineInterpPrevValid = false;
rod->mLineInterpCurrValid = false;
#endif
OS_REPORT("//////////////MG_ROD SET 2 !!\n"); OS_REPORT("//////////////MG_ROD SET 2 !!\n");
if (!hio_set) { if (!hio_set) {
rod->HIOInit = TRUE; rod->HIOInit = TRUE;
+6 -10
View File
@@ -3106,18 +3106,14 @@ void daMidna_c::setMidnaNoDrawFlg() {
BOOL daMidna_c::checkMetamorphoseEnableBase() { BOOL daMidna_c::checkMetamorphoseEnableBase() {
BOOL tmp; BOOL tmp;
if (!daAlink_getAlinkActorClass()->checkMidnaRide() || (g_env_light.mEvilInitialized & 0x80) ||
/* dSv_event_flag_c::M_077 - Main Event - Get shadow crystal (can now transform) */
!dComIfGs_isEventBit(0xD04) ||
#if TARGET_PC #if TARGET_PC
if (((!daAlink_getAlinkActorClass()->checkMidnaRide() || (g_env_light.mEvilInitialized & 0x80) || (fopAcIt_Judge((fopAcIt_JudgeFunc)daMidna_searchNpc, &tmp) &&
/* dSv_event_flag_c::M_077 - Main Event - Get shadow crystal (can now transform) */ !dusk::getSettings().game.canTransformAnywhere)
!dComIfGs_isEventBit(0xD04)) &&
!dusk::getSettings().game.transformWithoutShadowCrystal) ||
(fopAcIt_Judge((fopAcIt_JudgeFunc)daMidna_searchNpc, &tmp) &&
!dusk::getSettings().game.canTransformAnywhere)
#else #else
if (!daAlink_getAlinkActorClass()->checkMidnaRide() || (g_env_light.mEvilInitialized & 0x80) || fopAcIt_Judge((fopAcIt_JudgeFunc)daMidna_searchNpc, &tmp)
/* dSv_event_flag_c::M_077 - Main Event - Get shadow crystal (can now transform) */
!dComIfGs_isEventBit(0xD04) ||
fopAcIt_Judge((fopAcIt_JudgeFunc)daMidna_searchNpc, &tmp)
#endif #endif
) )
{ {
+2
View File
@@ -105,6 +105,7 @@ int dMirror_packet_c::entryModel(J3DModel* i_model) {
void dMirror_packet_c::mirrorZdraw(f32* param_0, f32* param_1, f32 param_2, f32 param_3, void dMirror_packet_c::mirrorZdraw(f32* param_0, f32* param_1, f32 param_2, f32 param_3,
f32 param_4, f32 param_5, f32 param_6, f32 param_7) { f32 param_4, f32 param_5, f32 param_6, f32 param_7) {
ZoneScoped;
GXSetNumChans(1); GXSetNumChans(1);
GXSetChanCtrl(GX_COLOR0, GX_FALSE, GX_SRC_REG, GX_SRC_REG, 0, GX_DF_NONE, GX_AF_NONE); GXSetChanCtrl(GX_COLOR0, GX_FALSE, GX_SRC_REG, GX_SRC_REG, 0, GX_DF_NONE, GX_AF_NONE);
GXSetNumTexGens(0); GXSetNumTexGens(0);
@@ -265,6 +266,7 @@ void dMirror_packet_c::modelDraw(J3DModel* i_model, Mtx param_1) {
} }
void dMirror_packet_c::mainDraw() { void dMirror_packet_c::mainDraw() {
ZoneScoped;
j3dSys.reinitGX(); j3dSys.reinitGX();
cXyz sp19C[5]; cXyz sp19C[5];
+4 -4
View File
@@ -328,13 +328,13 @@ int daNpcImpal_c::step(s16 i_angle, int i_animate) {
} }
void daNpcImpal_c::playExpression() { void daNpcImpal_c::playExpression() {
daNpcF_anmPlayData dat0 = {ANM_1, mpHIO->m.common.morf_frame, 1}; daNpcF_anmPlayData dat0 = {ANM_1, mpHIO->m.common.morf_frame, DUSK_IF_ELSE(0, 1)};
daNpcF_anmPlayData* pDat0[1] = {&dat0}; daNpcF_anmPlayData* pDat0[1] = {&dat0};
daNpcF_anmPlayData dat1 = {ANM_5, mpHIO->m.common.morf_frame, 1}; daNpcF_anmPlayData dat1 = {ANM_5, mpHIO->m.common.morf_frame, DUSK_IF_ELSE(0, 1)};
daNpcF_anmPlayData* pDat1[1] = {&dat1}; daNpcF_anmPlayData* pDat1[1] = {&dat1};
daNpcF_anmPlayData dat2 = {ANM_4, mpHIO->m.common.morf_frame, 1}; daNpcF_anmPlayData dat2 = {ANM_4, mpHIO->m.common.morf_frame, DUSK_IF_ELSE(0, 1)};
daNpcF_anmPlayData* pDat2[1] = {&dat2}; daNpcF_anmPlayData* pDat2[1] = {&dat2};
daNpcF_anmPlayData dat3 = {ANM_6, mpHIO->m.common.morf_frame, 1}; daNpcF_anmPlayData dat3 = {ANM_6, mpHIO->m.common.morf_frame, DUSK_IF_ELSE(0, 1)};
daNpcF_anmPlayData* pDat3[1] = {&dat3}; daNpcF_anmPlayData* pDat3[1] = {&dat3};
daNpcF_anmPlayData dat4 = {ANM_8, mpHIO->m.common.morf_frame, 0}; daNpcF_anmPlayData dat4 = {ANM_8, mpHIO->m.common.morf_frame, 0};
daNpcF_anmPlayData* pDat4[1] = {&dat4}; daNpcF_anmPlayData* pDat4[1] = {&dat4};
+1 -1
View File
@@ -178,7 +178,7 @@ static void anm_init(npc_ks_class* i_this, int param_2, f32 i_morf, u8 i_attr, f
param_2 = 42; param_2 = 42;
} else { } else {
// bug: developers meant to set equal to 44? // bug: developers meant to set equal to 44?
param_2 == 44; IF_NOT_DUSK(param_2 == 44);
dComIfGs_shake_kandelaar(); dComIfGs_shake_kandelaar();
} }
} }
+1
View File
@@ -261,6 +261,7 @@ void FlagCloth_c::execute() {
} }
void FlagCloth_c::draw() { void FlagCloth_c::draw() {
ZoneScoped;
j3dSys.reinitGX(); j3dSys.reinitGX();
GXSetNumIndStages(0); GXSetNumIndStages(0);
dKy_setLight_again(); dKy_setLight_again();
+1
View File
@@ -220,6 +220,7 @@ void FlagCloth2_c::initCcSphere(fopAc_ac_c*) {
} }
inline void FlagCloth2_c::draw() { inline void FlagCloth2_c::draw() {
ZoneScoped;
j3dSys.reinitGX(); j3dSys.reinitGX();
GXSetNumIndStages(0); GXSetNumIndStages(0);
dKy_setLight_again(); dKy_setLight_again();
+38
View File
@@ -10,6 +10,9 @@
#include "d/d_s_play.h" #include "d/d_s_play.h"
#include "d/actor/d_a_player.h" #include "d/actor/d_a_player.h"
#include "Z2AudioLib/Z2Instances.h" #include "Z2AudioLib/Z2Instances.h"
#if TARGET_PC
#include "dusk/frame_interpolation.h"
#endif
daObj_Keyhole_HIO_c::daObj_Keyhole_HIO_c() { daObj_Keyhole_HIO_c::daObj_Keyhole_HIO_c() {
id = -1; id = -1;
@@ -53,6 +56,21 @@ static int daObj_Keyhole_Draw(obj_keyhole_class* i_this) {
for (int i = 0; i < 6; i++) { for (int i = 0; i < 6; i++) {
kh_chain_s* chain_s = &i_this->chain_s[i]; kh_chain_s* chain_s = &i_this->chain_s[i];
for (int j = 0; j < i_this->chain_num; j++) { for (int j = 0; j < i_this->chain_num; j++) {
#if TARGET_PC
if (dusk::frame_interp::is_enabled() && i_this->mChainInterpPrevValid && i_this->mChainInterpCurrValid) {
const f32 alpha = dusk::frame_interp::get_interpolation_step();
Mtx mtx;
const f32* p0 = (const f32*)i_this->mChainInterpPrev[i][j];
const f32* p1 = (const f32*)i_this->mChainInterpCurr[i][j];
f32* dst = (f32*)mtx;
for (int k = 0; k < 12; k++) {
dst[k] = p0[k] + (p1[k] - p0[k]) * alpha;
}
chain_s->model[j]->setBaseTRMtx(mtx);
g_env_light.setLightTevColorType_MAJI(chain_s->model[j], &actor->tevStr);
mDoExt_modelUpdateDL(chain_s->model[j]);
} else
#endif
dComIfGp_entrySimpleModel(chain_s->model[j], fopAcM_GetRoomNo(actor)); dComIfGp_entrySimpleModel(chain_s->model[j], fopAcM_GetRoomNo(actor));
} }
} }
@@ -370,6 +388,21 @@ static void chain_move(obj_keyhole_class* i_this) {
ANGLE_ADD(sp8, TREG_S(0) + 0x3D00); ANGLE_ADD(sp8, TREG_S(0) + 0x3D00);
} }
} }
#if TARGET_PC
if (dusk::frame_interp::is_enabled()) {
if (i_this->mChainInterpCurrValid) {
memcpy(i_this->mChainInterpPrev, i_this->mChainInterpCurr, sizeof(i_this->mChainInterpCurr));
i_this->mChainInterpPrevValid = true;
}
for (int i = 0; i < 6; i++) {
for (int j = 0; j < i_this->chain_num; j++) {
MTXCopy(i_this->chain_s[i].model[j]->getBaseTRMtx(), i_this->mChainInterpCurr[i][j]);
}
}
i_this->mChainInterpCurrValid = true;
}
#endif
} }
static void open(obj_keyhole_class* i_this) { static void open(obj_keyhole_class* i_this) {
@@ -750,6 +783,11 @@ static int daObj_Keyhole_Create(fopAc_ac_c* a_this) {
return cPhs_ERROR_e; return cPhs_ERROR_e;
} }
#if TARGET_PC
i_this->mChainInterpPrevValid = false;
i_this->mChainInterpCurrValid = false;
#endif
OS_REPORT("//////////////OBJ_KEYHOLE SET 2 !!\n"); OS_REPORT("//////////////OBJ_KEYHOLE SET 2 !!\n");
if (i_this->arg0 == 3) { if (i_this->arg0 == 3) {
+17
View File
@@ -392,7 +392,10 @@ static const u8* l_sightDL_get() {
#endif #endif
void daPy_sightPacket_c::draw() { void daPy_sightPacket_c::draw() {
ZoneScoped;
#if !TARGET_PC
TGXTexObj texObj; TGXTexObj texObj;
#endif
j3dSys.reinitGX(); j3dSys.reinitGX();
GXSetNumIndStages(0); GXSetNumIndStages(0);
@@ -407,10 +410,24 @@ void daPy_sightPacket_c::draw() {
GXSetTevColor(GX_TEVREG0, reg0); GXSetTevColor(GX_TEVREG0, reg0);
GXSetTevColor(GX_TEVREG1, reg1); GXSetTevColor(GX_TEVREG1, reg1);
#if TARGET_PC
if (mpCachedImg != mpImg) {
mTexObj.reset();
GXInitTexObj(&mTexObj, mpData, mpImg->width, mpImg->height,
static_cast<GXTexFmt>(mpImg->format), static_cast<GXTexWrapMode>(mpImg->wrapS),
static_cast<GXTexWrapMode>(mpImg->wrapT),
mpImg->mipmapCount > 1 ? GX_ENABLE : GX_DISABLE);
GXInitTexObjLOD(
&mTexObj, GX_LINEAR, GX_LINEAR, 0.0, 0.0, 0.0, GX_FALSE, GX_FALSE, GX_ANISO_1);
mpCachedImg = mpImg;
}
GXLoadTexObj(&mTexObj, GX_TEXMAP0);
#else
GXInitTexObj(&texObj, mpData, mpImg->width, mpImg->height, (GXTexFmt)mpImg->format, GXInitTexObj(&texObj, mpData, mpImg->width, mpImg->height, (GXTexFmt)mpImg->format,
(GXTexWrapMode)mpImg->wrapS, (GXTexWrapMode)mpImg->wrapT, mpImg->mipmapCount > 1 ? GX_ENABLE : GX_DISABLE); (GXTexWrapMode)mpImg->wrapS, (GXTexWrapMode)mpImg->wrapT, mpImg->mipmapCount > 1 ? GX_ENABLE : GX_DISABLE);
GXInitTexObjLOD(&texObj, GX_LINEAR, GX_LINEAR, 0.0, 0.0, 0.0, GX_FALSE, GX_FALSE, GX_ANISO_1); GXInitTexObjLOD(&texObj, GX_LINEAR, GX_LINEAR, 0.0, 0.0, 0.0, GX_FALSE, GX_FALSE, GX_ANISO_1);
GXLoadTexObj(&texObj, GX_TEXMAP0); GXLoadTexObj(&texObj, GX_TEXMAP0);
#endif
GXLoadPosMtxImm(mProjMtx, GX_PNMTX0); GXLoadPosMtxImm(mProjMtx, GX_PNMTX0);
GXSetCurrentMtx(0); GXSetCurrentMtx(0);
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL); GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
+1
View File
@@ -598,6 +598,7 @@ dFlower_packet_c::dFlower_packet_c() {
} }
void dFlower_packet_c::draw() { void dFlower_packet_c::draw() {
ZoneScoped;
dScnKy_env_light_c* kankyo = dKy_getEnvlight(); dScnKy_env_light_c* kankyo = dKy_getEnvlight();
j3dSys.reinitGX(); j3dSys.reinitGX();
+1
View File
@@ -518,6 +518,7 @@ dGrass_packet_c::dGrass_packet_c() {
} }
void dGrass_packet_c::draw() { void dGrass_packet_c::draw() {
ZoneScoped;
dScnKy_env_light_c* kankyo = dKy_getEnvlight(); dScnKy_env_light_c* kankyo = dKy_getEnvlight();
cXyz spB4; cXyz spB4;
cXyz spA8; cXyz spA8;
+27 -2
View File
@@ -32,6 +32,8 @@
#include "dusk/frame_interpolation.h" #include "dusk/frame_interpolation.h"
#include "dusk/logging.h" #include "dusk/logging.h"
#include "dusk/action_bindings.h" #include "dusk/action_bindings.h"
#include "dusk/mouse.h"
#include "dusk/settings.h"
#include "imgui.h" #include "imgui.h"
#endif #endif
@@ -7638,12 +7640,16 @@ void dCamera_c::deactivateDebugFlyCam() {
mDebugFlyCam.initialized = false; mDebugFlyCam.initialized = false;
} }
bool dCamera_c::canUseFreeCam() {
return dusk::getSettings().game.freeCamera || dusk::getSettings().game.enableMouseCamera;
}
bool dCamera_c::freeCamera() { bool dCamera_c::freeCamera() {
if (dusk::getSettings().game.freeCamera && mGear == 1) { if (canUseFreeCam() && mGear == 1) {
mGear = 0; mGear = 0;
} }
if (!dusk::getSettings().game.freeCamera || mCamStyle == 70) if (!canUseFreeCam() || mCamStyle == 70)
{ {
mCamParam.mManualMode = 0; mCamParam.mManualMode = 0;
return false; return false;
@@ -7669,6 +7675,17 @@ bool dCamera_c::freeCamera() {
mCamParam.freeYAngle += camMovement.y * magnitude * dusk::getSettings().game.freeCameraYSensitivity * 5.0f; mCamParam.freeYAngle += camMovement.y * magnitude * dusk::getSettings().game.freeCameraYSensitivity * 5.0f;
} }
f32 yaw_rad = 0.0f;
f32 pitch_rad = 0.0f;
dusk::mouse::getCameraDeltas(yaw_rad, pitch_rad);
if (dusk::getSettings().game.enableMouseCamera && (yaw_rad != 0.0f || pitch_rad != 0.0f) &&
!dComIfGp_checkCameraAttentionStatus(dComIfGp_getPlayerCameraID(0), 0x8))
{
mCamParam.mManualMode = 1;
mCamParam.freeXAngle += MTXRadToDeg(yaw_rad);
mCamParam.freeYAngle += -MTXRadToDeg(pitch_rad);
}
fopAc_ac_c* player = dComIfGp_getPlayer(0); fopAc_ac_c* player = dComIfGp_getPlayer(0);
if (!mCamParam.mManualMode || player == nullptr) { if (!mCamParam.mManualMode || player == nullptr) {
return false; return false;
@@ -9350,6 +9367,10 @@ bool dCamera_c::rideCamera(s32 param_0) {
mStyleSettle.mFinished = true; mStyleSettle.mFinished = true;
} }
#if TARGET_PC
freeCamera();
#endif
return true; return true;
} }
@@ -9479,6 +9500,10 @@ bool dCamera_c::rideCamera(s32 param_0) {
setFlag(0x400); setFlag(0x400);
} }
#if TARGET_PC
freeCamera();
#endif
return true; return true;
} }
+1 -5
View File
@@ -2843,11 +2843,7 @@ BOOL dComIfGs_Wolf_Change_Check() {
BOOL is_wolf = false; BOOL is_wolf = false;
// Transforming Unlocked // Transforming Unlocked
if (dComIfGs_isEventBit(0x0D04) if (dComIfGs_isEventBit(0x0D04)) {
#if TARGET_PC
|| dusk::getSettings().game.transformWithoutShadowCrystal
#endif
) {
is_wolf = dComIfGs_getTransformStatus(); is_wolf = dComIfGs_getTransformStatus();
} else if (dComIfGs_isTransformLV(0) && !dComIfGs_isDarkClearLV(0)) { } else if (dComIfGs_isTransformLV(0) && !dComIfGs_isDarkClearLV(0)) {
is_wolf = true; is_wolf = true;
+17 -6
View File
@@ -41,12 +41,12 @@ public:
/* 0x14 */ GXColor field_0x14; /* 0x14 */ GXColor field_0x14;
/* 0x18 */ GXColor field_0x18; /* 0x18 */ GXColor field_0x18;
/* 0x1C */ TGXTexObj field_0x1c; /* 0x1C */ TGXTexObj field_0x1c;
/* 0x3C */ GXTlutObj field_0x3c; /* 0x3C */ TGXTlutObj field_0x3c;
/* 0x48 */ s16 field_0x48; /* 0x48 */ s16 field_0x48;
/* 0x4A */ s16 field_0x4a; /* 0x4A */ s16 field_0x4a;
/* 0x4C */ u8 field_0x4c; /* 0x4C */ u8 field_0x4c;
/* 0x50 */ TGXTexObj field_0x50; /* 0x50 */ TGXTexObj field_0x50;
/* 0x70 */ GXTlutObj field_0x70; /* 0x70 */ TGXTlutObj field_0x70;
/* 0x7C */ s16 field_0x7c; /* 0x7C */ s16 field_0x7c;
/* 0x7E */ s16 field_0x7e; /* 0x7E */ s16 field_0x7e;
/* 0x80 */ u8 field_0x80; /* 0x80 */ u8 field_0x80;
@@ -100,7 +100,7 @@ public:
u8 check() { return field_0x0; } u8 check() { return field_0x0; }
int getCI() { return mCI; } int getCI() { return mCI; }
TGXTexObj* getTexObj() { return &mTexObj; } TGXTexObj* getTexObj() { return &mTexObj; }
GXTlutObj* getTlutObj() { return &mTlutObj; } TGXTlutObj* getTlutObj() { return &mTlutObj; }
GXColor* getColor() { return &mColor; } GXColor* getColor() { return &mColor; }
f32 getS() { return mS; } f32 getS() { return mS; }
f32 getT() { return mT; } f32 getT() { return mT; }
@@ -110,7 +110,7 @@ public:
/* 0x00 */ u8 field_0x0; /* 0x00 */ u8 field_0x0;
/* 0x01 */ u8 mCI; /* 0x01 */ u8 mCI;
/* 0x04 */ TGXTexObj mTexObj; /* 0x04 */ TGXTexObj mTexObj;
/* 0x24 */ GXTlutObj mTlutObj; /* 0x24 */ TGXTlutObj mTlutObj;
/* 0x30 */ GXColor mColor; /* 0x30 */ GXColor mColor;
/* 0x34 */ f32 mS; /* 0x34 */ f32 mS;
/* 0x38 */ f32 mT; /* 0x38 */ f32 mT;
@@ -188,6 +188,7 @@ void dDlst_window_c::setScissor(f32 xOrig, f32 yOrig, f32 width, f32 height) {
} }
void dDlst_2DTri_c::draw() { void dDlst_2DTri_c::draw() {
ZoneScoped;
f32 f4; f32 f4;
f32 f5; f32 f5;
f32 f2 = cM_scos(field_0xc); f32 f2 = cM_scos(field_0xc);
@@ -224,6 +225,7 @@ void dDlst_2DTri_c::draw() {
} }
void dDlst_2DQuad_c::draw() { void dDlst_2DQuad_c::draw() {
ZoneScoped;
GXClearVtxDesc(); GXClearVtxDesc();
GXSetVtxDesc(GX_VA_POS, GX_DIRECT); GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0); GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0);
@@ -247,6 +249,7 @@ void dDlst_2DQuad_c::draw() {
} }
void dDlst_2DPoint_c::draw() { void dDlst_2DPoint_c::draw() {
ZoneScoped;
GXClearVtxDesc(); GXClearVtxDesc();
GXSetVtxDesc(GX_VA_POS, GX_DIRECT); GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0); GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0);
@@ -268,6 +271,7 @@ void dDlst_2DPoint_c::draw() {
} }
void dDlst_2DT_c::draw() { void dDlst_2DT_c::draw() {
ZoneScoped;
static GXColor l_color = {0xFF, 0xFF, 0xFF, 0xE0}; static GXColor l_color = {0xFF, 0xFF, 0xFF, 0xE0};
f32 var5 = field_0xe; f32 var5 = field_0xe;
f32 var6 = field_0x10; f32 var6 = field_0x10;
@@ -326,6 +330,7 @@ void dDlst_2DT_c::draw() {
} }
void dDlst_2DT2_c::draw() { void dDlst_2DT2_c::draw() {
ZoneScoped;
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_F32, 0); GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_F32, 0);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_CLR_RGBA, GX_RGBA6, 0); GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_CLR_RGBA, GX_RGBA6, 0);
GXClearVtxDesc(); GXClearVtxDesc();
@@ -665,6 +670,7 @@ void dDlst_2DT2_c::init(ResTIMG* i_timg, f32 param_1, f32 param_2, f32 param_3,
} }
void dDlst_2DM_c::draw() { void dDlst_2DM_c::draw() {
ZoneScoped;
s16 r31 = field_0x22; s16 r31 = field_0x22;
s16 r30 = field_0x24; s16 r30 = field_0x24;
int r29 = field_0x22 + 256.0f; int r29 = field_0x22 + 256.0f;
@@ -728,6 +734,7 @@ void dDlst_2DM_c::draw() {
void dDlst_2Dm_c::draw() { void dDlst_2Dm_c::draw() {
ZoneScoped;
s16 r31 = field_0x48; s16 r31 = field_0x48;
s16 r30 = field_0x4a; s16 r30 = field_0x4a;
int r29 = field_0x48 + 256.0f; int r29 = field_0x48 + 256.0f;
@@ -794,6 +801,7 @@ void dDlst_2Dm_c::draw() {
void dDlst_2DMt_c::draw() { void dDlst_2DMt_c::draw() {
ZoneScoped;
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0); GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0);
GXClearVtxDesc(); GXClearVtxDesc();
GXSetVtxDesc(GX_VA_POS, GX_DIRECT); GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
@@ -933,6 +941,7 @@ f32 cM_rnd_c::getValue(f32 param_0, f32 param_1) {
} }
void dDlst_effectLine_c::draw() { void dDlst_effectLine_c::draw() {
ZoneScoped;
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
GXClearVtxDesc(); GXClearVtxDesc();
GXSetVtxDesc(GX_VA_POS, GX_DIRECT); GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
@@ -1034,6 +1043,7 @@ void dDlst_shadowPoly_c::draw() {
return; return;
#endif #endif
ZoneScoped;
dDlst_shadowTri_c* tri = getTri(); dDlst_shadowTri_c* tri = getTri();
GXBegin(GX_TRIANGLES, GX_VTXFMT0, mCount * 3); GXBegin(GX_TRIANGLES, GX_VTXFMT0, mCount * 3);
@@ -1610,6 +1620,7 @@ void dDlst_shadowControl_c::imageDraw(Mtx param_0) {
} }
void dDlst_shadowControl_c::draw(Mtx param_0) { void dDlst_shadowControl_c::draw(Mtx param_0) {
ZoneScoped;
static GXTevColorChan l_tevColorChan[4] = { static GXTevColorChan l_tevColorChan[4] = {
GX_CH_RED, GX_CH_RED,
GX_CH_GREEN, GX_CH_GREEN,
@@ -1985,7 +1996,7 @@ int dDlst_list_c::set(dDlst_base_c**& p_start, dDlst_base_c**& p_end, dDlst_base
return 1; return 1;
} }
#if TARGET_PC && (TRACY_ENABLE || PARTIAL_DEBUG) #if DUSK_GFX_DEBUG_GROUPS
static absl::flat_hash_map<std::type_index, const char*> typeDrawNames; static absl::flat_hash_map<std::type_index, const char*> typeDrawNames;
static const char* getTypeDrawName(dDlst_base_c* dlst) { static const char* getTypeDrawName(dDlst_base_c* dlst) {
@@ -2008,7 +2019,7 @@ void dDlst_list_c::draw(dDlst_base_c** p_start, dDlst_base_c** p_end) {
for (; p_start < p_end; p_start++) { for (; p_start < p_end; p_start++) {
dDlst_base_c* dlst = *p_start; dDlst_base_c* dlst = *p_start;
#if TARGET_PC && (TRACY_ENABLE || PARTIAL_DEBUG) #if DUSK_GFX_DEBUG_GROUPS
const auto name = getTypeDrawName(dlst); const auto name = getTypeDrawName(dlst);
GXScopedDebugGroup scope(name); GXScopedDebugGroup scope(name);
#endif #endif
+246 -31
View File
@@ -94,6 +94,39 @@ static void dKyr_set_btitex(TGXTexObj* i_obj, ResTIMG* i_img) {
dKyr_set_btitex_common(i_obj, i_img, GX_TEXMAP0); dKyr_set_btitex_common(i_obj, i_img, GX_TEXMAP0);
} }
#if TARGET_PC
template <int N>
struct CachedTexObjs {
TGXTexObj texObj[N];
ResTIMG* timg[N] = {};
};
template <int N>
static GXTexObj* load_cached_tex(CachedTexObjs<N>& cache, ResTIMG* img, GXTexMapID mapID) {
for (int i = 0; i < N; i++) {
if (img != nullptr && cache.timg[i] == img) {
GXLoadTexObj(&cache.texObj[i], mapID);
return &cache.texObj[i];
}
}
int slot = 0;
for (int i = 0; i < N; i++) {
if (cache.timg[i] == nullptr) {
slot = i;
break;
}
}
if (cache.timg[slot] != nullptr) {
cache.texObj[slot].reset();
}
cache.timg[slot] = img;
dKyr_set_btitex_common(&cache.texObj[slot], img, mapID);
return &cache.texObj[slot];
}
#endif
void dKyr_lenzflare_move() { void dKyr_lenzflare_move() {
dKankyo_sun_Packet* sun_packet = g_env_light.mpSunPacket; dKankyo_sun_Packet* sun_packet = g_env_light.mpSunPacket;
dKankyo_sunlenz_Packet* lenz_packet = g_env_light.mpSunLenzPacket; dKankyo_sunlenz_Packet* lenz_packet = g_env_light.mpSunLenzPacket;
@@ -929,7 +962,7 @@ void dKyr_housi_move() {
if (g_env_light.mHousiCount != 0 || if (g_env_light.mHousiCount != 0 ||
(g_env_light.mHousiCount == 0 && housi_packet->field_0x5de8 <= 0.0f)) (g_env_light.mHousiCount == 0 && housi_packet->field_0x5de8 <= 0.0f))
{ {
housi_packet->field_0x5dec = g_env_light.mHousiCount; housi_packet->mHousiCount = g_env_light.mHousiCount;
} }
if (g_env_light.mHousiCount != 0) { if (g_env_light.mHousiCount != 0) {
@@ -938,7 +971,7 @@ void dKyr_housi_move() {
cLib_addCalc(&housi_packet->field_0x5de8, 0.0f, 0.2f, 0.05f, 0.01f); cLib_addCalc(&housi_packet->field_0x5de8, 0.0f, 0.2f, 0.05f, 0.01f);
} }
if (housi_packet->field_0x5dec == 0) { if (housi_packet->mHousiCount == 0) {
return; return;
} }
@@ -977,7 +1010,7 @@ void dKyr_housi_move() {
} }
} }
for (int i = housi_packet->field_0x5dec - 1; i >= 0; i--) { for (int i = housi_packet->mHousiCount - 1; i >= 0; i--) {
f32 var_f26 = 0.4f * housi_packet->field_0x5de8; f32 var_f26 = 0.4f * housi_packet->field_0x5de8;
effect = &housi_packet->mHousiEff[i]; effect = &housi_packet->mHousiEff[i];
@@ -2025,16 +2058,27 @@ void vrkumo_move() {
} }
} }
static void dKr_cullVtx_Set() { static void dKr_cullVtx_Set(IF_DUSK(bool const vtxColor = false)) {
GXSetCullMode(GX_CULL_NONE); GXSetCullMode(GX_CULL_NONE);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGBA, GX_F32, 0); GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGBA, GX_F32, 0);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_CLR_RGBA, GX_RGBA4, 8); GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_CLR_RGBA, GX_RGBA4, 8);
#if TARGET_PC
if (vtxColor) {
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
}
#endif
GXClearVtxDesc(); GXClearVtxDesc();
GXSetVtxDesc(GX_VA_POS, GX_DIRECT); GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
#if TARGET_PC
if (vtxColor) {
GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT);
}
#endif
} }
static void dKyr_draw_rev_moon(Mtx drawMtx, u8** tex) { static void dKyr_draw_rev_moon(Mtx drawMtx, u8** tex) {
ZoneScoped;
dKankyo_sun_Packet* sun_packet = g_env_light.mpSunPacket; dKankyo_sun_Packet* sun_packet = g_env_light.mpSunPacket;
dKankyo_sunlenz_Packet* lenz_packet = g_env_light.mpSunLenzPacket; dKankyo_sunlenz_Packet* lenz_packet = g_env_light.mpSunLenzPacket;
camera_class* camera = (camera_class*)dComIfGp_getCamera(0); camera_class* camera = (camera_class*)dComIfGp_getCamera(0);
@@ -2122,10 +2166,17 @@ static void dKyr_draw_rev_moon(Mtx drawMtx, u8** tex) {
return; return;
} }
#if TARGET_PC
static CachedTexObjs<8> texobj;
load_cached_tex(texobj, (ResTIMG*)tex[0], GX_TEXMAP0);
load_cached_tex(texobj, (ResTIMG*)tex[1], GX_TEXMAP1);
load_cached_tex(texobj, (ResTIMG*)tex[texidx + 2], GX_TEXMAP2);
#else
TGXTexObj texobj; TGXTexObj texobj;
dKyr_set_btitex_common(&texobj, (ResTIMG*)tex[0], GX_TEXMAP0); dKyr_set_btitex_common(&texobj, (ResTIMG*)tex[0], GX_TEXMAP0);
dKyr_set_btitex_common(&texobj, (ResTIMG*)tex[1], GX_TEXMAP1); dKyr_set_btitex_common(&texobj, (ResTIMG*)tex[1], GX_TEXMAP1);
dKyr_set_btitex_common(&texobj, (ResTIMG*)tex[texidx + 2], GX_TEXMAP2); dKyr_set_btitex_common(&texobj, (ResTIMG*)tex[texidx + 2], GX_TEXMAP2);
#endif
GXSetNumChans(0); GXSetNumChans(0);
GXSetTevColor(GX_TEVREG0, color_reg0); GXSetTevColor(GX_TEVREG0, color_reg0);
@@ -2205,7 +2256,11 @@ static void dKyr_draw_rev_moon(Mtx drawMtx, u8** tex) {
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
if (i == 1) { if (i == 1) {
#if TARGET_PC
load_cached_tex(texobj, (ResTIMG*)lenz_packet->mpResBall, GX_TEXMAP0);
#else
dKyr_set_btitex(&texobj, (ResTIMG*)lenz_packet->mpResBall); dKyr_set_btitex(&texobj, (ResTIMG*)lenz_packet->mpResBall);
#endif
GXClearVtxDesc(); GXClearVtxDesc();
GXSetVtxDesc(GX_VA_POS, GX_DIRECT); GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
@@ -2470,10 +2525,17 @@ void dKyr_drawSun(Mtx drawMtx, cXyz* ppos, GXColor& unused, u8** tex) {
return; return;
} }
#if TARGET_PC
static CachedTexObjs<8> texobj;
load_cached_tex(texobj, (ResTIMG*)tex[0], GX_TEXMAP0);
load_cached_tex(texobj, (ResTIMG*)tex[1], GX_TEXMAP1);
load_cached_tex(texobj, (ResTIMG*)tex[texidx + 2], GX_TEXMAP2);
#else
TGXTexObj texobj; TGXTexObj texobj;
dKyr_set_btitex_common(&texobj, (ResTIMG*)tex[0], GX_TEXMAP0); dKyr_set_btitex_common(&texobj, (ResTIMG*)tex[0], GX_TEXMAP0);
dKyr_set_btitex_common(&texobj, (ResTIMG*)tex[1], GX_TEXMAP1); dKyr_set_btitex_common(&texobj, (ResTIMG*)tex[1], GX_TEXMAP1);
dKyr_set_btitex_common(&texobj, (ResTIMG*)tex[texidx + 2], GX_TEXMAP2); dKyr_set_btitex_common(&texobj, (ResTIMG*)tex[texidx + 2], GX_TEXMAP2);
#endif
GXSetNumChans(0); GXSetNumChans(0);
GXSetTevColor(GX_TEVREG0, color_reg0); GXSetTevColor(GX_TEVREG0, color_reg0);
@@ -2567,7 +2629,11 @@ void dKyr_drawSun(Mtx drawMtx, cXyz* ppos, GXColor& unused, u8** tex) {
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
if (i == 1) { if (i == 1) {
#if TARGET_PC
load_cached_tex(texobj, (ResTIMG*)lenz_packet->mpResBall, GX_TEXMAP0);
#else
dKyr_set_btitex(&texobj, (ResTIMG*)lenz_packet->mpResBall); dKyr_set_btitex(&texobj, (ResTIMG*)lenz_packet->mpResBall);
#endif
GXClearVtxDesc(); GXClearVtxDesc();
GXSetVtxDesc(GX_VA_POS, GX_DIRECT); GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
@@ -2680,6 +2746,7 @@ void dKyr_drawSun(Mtx drawMtx, cXyz* ppos, GXColor& unused, u8** tex) {
} }
void dKyr_drawLenzflare(Mtx drawMtx, cXyz* ppos, GXColor& param_2, u8** tex) { void dKyr_drawLenzflare(Mtx drawMtx, cXyz* ppos, GXColor& param_2, u8** tex) {
ZoneScoped;
dKankyo_sunlenz_Packet* lenz_packet = g_env_light.mpSunLenzPacket; dKankyo_sunlenz_Packet* lenz_packet = g_env_light.mpSunLenzPacket;
dKankyo_sun_Packet* sun_packet = g_env_light.mpSunPacket; dKankyo_sun_Packet* sun_packet = g_env_light.mpSunPacket;
camera_class* camera = (camera_class*)dComIfGp_getCamera(0); camera_class* camera = (camera_class*)dComIfGp_getCamera(0);
@@ -2730,8 +2797,13 @@ void dKyr_drawLenzflare(Mtx drawMtx, cXyz* ppos, GXColor& param_2, u8** tex) {
j3dSys.reinitGX(); j3dSys.reinitGX();
#if TARGET_PC
static CachedTexObjs<3> texobj;
load_cached_tex(texobj, (ResTIMG*)tex[0], GX_TEXMAP0);
#else
TGXTexObj texobj; TGXTexObj texobj;
dKyr_set_btitex(&texobj, (ResTIMG*)tex[0]); dKyr_set_btitex(&texobj, (ResTIMG*)tex[0]);
#endif
GXSetNumChans(0); GXSetNumChans(0);
GXSetTevColor(GX_TEVREG0, color_reg0); GXSetTevColor(GX_TEVREG0, color_reg0);
GXSetTevColor(GX_TEVREG1, color_reg1); GXSetTevColor(GX_TEVREG1, color_reg1);
@@ -3036,11 +3108,23 @@ void dKyr_drawLenzflare(Mtx drawMtx, cXyz* ppos, GXColor& param_2, u8** tex) {
} }
if (i == 1) { if (i == 1) {
#if TARGET_PC
load_cached_tex(texobj, (ResTIMG*)tex[2], GX_TEXMAP0);
#else
dKyr_set_btitex(&texobj, (ResTIMG*)tex[2]); dKyr_set_btitex(&texobj, (ResTIMG*)tex[2]);
#endif
} else if (i == 2) { } else if (i == 2) {
#if TARGET_PC
load_cached_tex(texobj, (ResTIMG*)tex[3], GX_TEXMAP0);
#else
dKyr_set_btitex(&texobj, (ResTIMG*)tex[3]); dKyr_set_btitex(&texobj, (ResTIMG*)tex[3]);
#endif
} else { } else {
#if TARGET_PC
load_cached_tex(texobj, (ResTIMG*)tex[0], GX_TEXMAP0);
#else
dKyr_set_btitex(&texobj, (ResTIMG*)tex[0]); dKyr_set_btitex(&texobj, (ResTIMG*)tex[0]);
#endif
} }
spE4.x = -var_f31; spE4.x = -var_f31;
@@ -3131,8 +3215,13 @@ void dKyr_drawRain(Mtx drawMtx, u8** tex) {
return; return;
} }
#if TARGET_PC
static CachedTexObjs<1> texobj;
load_cached_tex(texobj, (ResTIMG*)tex[0], GX_TEXMAP0);
#else
TGXTexObj texobj; TGXTexObj texobj;
dKyr_set_btitex(&texobj, (ResTIMG*)tex[0]); dKyr_set_btitex(&texobj, (ResTIMG*)tex[0]);
#endif
GXSetNumChans(0); GXSetNumChans(0);
GXSetTevColor(GX_TEVREG0, color_reg0); GXSetTevColor(GX_TEVREG0, color_reg0);
GXSetNumTexGens(1); GXSetNumTexGens(1);
@@ -3296,8 +3385,13 @@ void dKyr_drawSibuki(Mtx drawMtx, u8** tex) {
color.b = 0xC8; color.b = 0xC8;
color.a = rain_packet->mSibukiAlpha * alphaFade; color.a = rain_packet->mSibukiAlpha * alphaFade;
#if TARGET_PC
static CachedTexObjs<1> texobj;
load_cached_tex(texobj, (ResTIMG*)tex[1], GX_TEXMAP0);
#else
TGXTexObj texobj; TGXTexObj texobj;
dKyr_set_btitex(&texobj, (ResTIMG*)tex[1]); dKyr_set_btitex(&texobj, (ResTIMG*)tex[1]);
#endif
GXSetNumChans(0); GXSetNumChans(0);
GXSetTevColor(GX_TEVREG0, color); GXSetTevColor(GX_TEVREG0, color);
GXSetTevColor(GX_TEVREG1, color); GXSetTevColor(GX_TEVREG1, color);
@@ -3378,21 +3472,26 @@ void dKyr_drawSibuki(Mtx drawMtx, u8** tex) {
} }
void dKyr_drawHousi(Mtx drawMtx, u8** tex) { void dKyr_drawHousi(Mtx drawMtx, u8** tex) {
ZoneScoped;
dKankyo_housi_Packet* housi_packet = g_env_light.mpHousiPacket; dKankyo_housi_Packet* housi_packet = g_env_light.mpHousiPacket;
static f32 rot = 0.0f; static f32 rot = 0.0f;
Mtx camMtx; Mtx camMtx;
Mtx rotMtx; Mtx rotMtx;
cXyz pos[4]; cXyz pos[4];
#if TARGET_PC
static CachedTexObjs<1> texobj;
#else
TGXTexObj spDC; TGXTexObj spDC;
#endif
cXyz spD0; cXyz spD0;
Vec spC4; Vec spC4;
Vec spB8; Vec spB8;
bool var_r28 = 0; bool isPalaceOfTwilight = 0;
if (housi_packet->field_0x5dec != 0) { if (housi_packet->mHousiCount != 0) {
if (strcmp(dComIfGp_getStartStageName(), "D_MN08") == 0) { if (strcmp(dComIfGp_getStartStageName(), "D_MN08") == 0) {
var_r28 = 1; isPalaceOfTwilight = 1;
} }
if (strcmp(dComIfGp_getStartStageName(), "D_MN08") != 0 || if (strcmp(dComIfGp_getStartStageName(), "D_MN08") != 0 ||
@@ -3419,7 +3518,7 @@ void dKyr_drawHousi(Mtx drawMtx, u8** tex) {
color_reg1.b = 0xCA; color_reg1.b = 0xCA;
color_reg1.a = 0xFF; color_reg1.a = 0xFF;
if (dKy_darkworld_check() == 1 || var_r28 == 1) { if (dKy_darkworld_check() == 1 || isPalaceOfTwilight == 1) {
color_reg0.r = 0; color_reg0.r = 0;
color_reg0.g = 0; color_reg0.g = 0;
color_reg0.b = 0; color_reg0.b = 0;
@@ -3471,18 +3570,27 @@ void dKyr_drawHousi(Mtx drawMtx, u8** tex) {
f32 temp_f24 = 6.5f; f32 temp_f24 = 6.5f;
for (int i = 0; i < 1; i++) { for (int i = 0; i < 1; i++) {
dKyr_set_btitex(&spDC, (ResTIMG*)*tex); #if TARGET_PC
load_cached_tex(texobj, (ResTIMG*)*tex, GX_TEXMAP0);
#else
dKyr_set_btitex(&texobj, (ResTIMG*)*tex);
#endif
#if TARGET_PC
GXSetNumChans(1);
GXSetChanCtrl(GX_COLOR0, GX_DISABLE, GX_SRC_REG, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_CLAMP, GX_AF_NONE);
#else
GXSetNumChans(0); GXSetNumChans(0);
GXSetTevColor(GX_TEVREG0, color_reg0); GXSetTevColor(GX_TEVREG0, color_reg0);
#endif
GXSetTevColor(GX_TEVREG1, color_reg1); GXSetTevColor(GX_TEVREG1, color_reg1);
GXSetNumTexGens(1); GXSetNumTexGens(1);
GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY); GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
GXSetNumTevStages(1); GXSetNumTevStages(1);
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL); GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, DUSK_IF_ELSE(GX_COLOR0A0, GX_COLOR_NULL));
GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_C1, GX_CC_C0, GX_CC_TEXC, GX_CC_ZERO); GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_C1, DUSK_IF_ELSE(GX_CC_RASC, GX_CC_C0), GX_CC_TEXC, GX_CC_ZERO);
GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE,
GX_TEVPREV); GX_TEVPREV);
GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_A0, GX_CA_TEXA, GX_CA_ZERO); GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, DUSK_IF_ELSE(GX_CA_RASA, GX_CA_CA), GX_CA_TEXA, GX_CA_ZERO);
GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE,
GX_TEVPREV); GX_TEVPREV);
@@ -3505,7 +3613,7 @@ void dKyr_drawHousi(Mtx drawMtx, u8** tex) {
GXSetClipMode(GX_CLIP_DISABLE); GXSetClipMode(GX_CLIP_DISABLE);
GXSetNumIndStages(0); GXSetNumIndStages(0);
dKr_cullVtx_Set(); dKr_cullVtx_Set(IF_DUSK(true));
rot += 1.2f; rot += 1.2f;
MTXRotRad(rotMtx, 'Z', DEG_TO_RAD(rot)); MTXRotRad(rotMtx, 'Z', DEG_TO_RAD(rot));
@@ -3514,7 +3622,13 @@ void dKyr_drawHousi(Mtx drawMtx, u8** tex) {
GXLoadPosMtxImm(drawMtx, GX_PNMTX0); GXLoadPosMtxImm(drawMtx, GX_PNMTX0);
GXSetCurrentMtx(GX_PNMTX0); GXSetCurrentMtx(GX_PNMTX0);
for (int j = 0; j < housi_packet->field_0x5dec; j++) { #if TARGET_PC
// Dusklight optimization: we submit a single large draw call, rather than hundreds.
u32 vertCount = 4 * housi_packet->mHousiCount;
GXBegin(GX_QUADS, GX_VTXFMT0, vertCount);
#endif
for (int j = 0; j < housi_packet->mHousiCount; j++) {
fopAc_ac_c* player = dComIfGp_getPlayer(0); fopAc_ac_c* player = dComIfGp_getPlayer(0);
spD0.x = spD0.x =
@@ -3525,6 +3639,10 @@ void dKyr_drawHousi(Mtx drawMtx, u8** tex) {
housi_packet->mHousiEff[j].mBasePos.z + housi_packet->mHousiEff[j].mPosition.z; housi_packet->mHousiEff[j].mBasePos.z + housi_packet->mHousiEff[j].mPosition.z;
if (i == 1 && j == 0) { if (i == 1 && j == 0) {
#if TARGET_PC
// Never gets hit I think?
abort();
#endif
color_reg0.r = 0; color_reg0.r = 0;
color_reg0.g = 0; color_reg0.g = 0;
color_reg0.b = 0; color_reg0.b = 0;
@@ -3553,8 +3671,10 @@ void dKyr_drawHousi(Mtx drawMtx, u8** tex) {
color_reg0.a = housi_packet->mHousiEff[j].mAlpha * var_f25; color_reg0.a = housi_packet->mHousiEff[j].mAlpha * var_f25;
block_14: block_14:
GXLoadTexObj(&spDC, GX_TEXMAP0); #if !TARGET_PC // GXLoadTextObj does nothing, TEV colors replaced with vertex colors
GXLoadTexObj(&texobj, GX_TEXMAP0);
GXSetTevColor(GX_TEVREG0, color_reg0); GXSetTevColor(GX_TEVREG0, color_reg0);
#endif
f32 var_f27 = housi_packet->mHousiEff[j].field_0x48 * 9.0f; f32 var_f27 = housi_packet->mHousiEff[j].field_0x48 * 9.0f;
if (g_env_light.field_0xea9 == 1) { if (g_env_light.field_0xea9 == 1) {
@@ -3566,7 +3686,7 @@ void dKyr_drawHousi(Mtx drawMtx, u8** tex) {
f32 temp_f30 = f32 temp_f30 =
(var_f27 * 0.2f) * cM_fcos(housi_packet->mHousiEff[j].mScale.y * 6.0f); (var_f27 * 0.2f) * cM_fcos(housi_packet->mHousiEff[j].mScale.y * 6.0f);
if (dKy_darkworld_check() == 1 || var_r28 == 1) { if (dKy_darkworld_check() == 1 || isPalaceOfTwilight == 1) {
cXyz sp7C[] = { cXyz sp7C[] = {
cXyz(-1.0f, -0.5f, 0.0f), cXyz(-1.0f, -0.5f, 0.0f),
cXyz(-1.0f, 1.5f, 0.0f), cXyz(-1.0f, 1.5f, 0.0f),
@@ -3711,24 +3831,34 @@ void dKyr_drawHousi(Mtx drawMtx, u8** tex) {
pos[3].z = spD0.z + spB8.z; pos[3].z = spD0.z + spB8.z;
} }
GXBegin(GX_QUADS, GX_VTXFMT0, 4); IF_NOT_DUSK(GXBegin(GX_QUADS, GX_VTXFMT0, 4));
s16 var_r17 = 0x1FF; s16 var_r17 = 0x1FF;
if (dKy_darkworld_check() == true || var_r28 == 1) { if (dKy_darkworld_check() == true || isPalaceOfTwilight == 1) {
var_r17 = 0xFA; var_r17 = 0xFA;
} }
GXPosition3f32(pos[0].x, pos[0].y, pos[0].z); GXPosition3f32(pos[0].x, pos[0].y, pos[0].z);
IF_DUSK(GXColor4u8(color_reg0.r, color_reg0.g, color_reg0.b, color_reg0.a));
GXTexCoord2s16(0, 0); GXTexCoord2s16(0, 0);
GXPosition3f32(pos[1].x, pos[1].y, pos[1].z); GXPosition3f32(pos[1].x, pos[1].y, pos[1].z);
IF_DUSK(GXColor4u8(color_reg0.r, color_reg0.g, color_reg0.b, color_reg0.a));
GXTexCoord2s16(var_r17, 0); GXTexCoord2s16(var_r17, 0);
GXPosition3f32(pos[2].x, pos[2].y, pos[2].z); GXPosition3f32(pos[2].x, pos[2].y, pos[2].z);
IF_DUSK(GXColor4u8(color_reg0.r, color_reg0.g, color_reg0.b, color_reg0.a));
GXTexCoord2s16(var_r17, var_r17); GXTexCoord2s16(var_r17, var_r17);
GXPosition3f32(pos[3].x, pos[3].y, pos[3].z); GXPosition3f32(pos[3].x, pos[3].y, pos[3].z);
IF_DUSK(GXColor4u8(color_reg0.r, color_reg0.g, color_reg0.b, color_reg0.a));
GXTexCoord2s16(0, var_r17); GXTexCoord2s16(0, var_r17);
GXEnd();
IF_NOT_DUSK(GXEnd());
} }
} }
#if TARGET_PC
GXEnd();
#endif
} }
GXSetClipMode(GX_CLIP_ENABLE); GXSetClipMode(GX_CLIP_ENABLE);
@@ -3738,6 +3868,7 @@ void dKyr_drawHousi(Mtx drawMtx, u8** tex) {
} }
void dKyr_drawSnow(Mtx drawMtx, u8** tex) { void dKyr_drawSnow(Mtx drawMtx, u8** tex) {
ZoneScoped;
camera_class* camera = (camera_class*)dComIfGp_getCamera(0); camera_class* camera = (camera_class*)dComIfGp_getCamera(0);
dKankyo_snow_Packet* snow_packet = g_env_light.mpSnowPacket; dKankyo_snow_Packet* snow_packet = g_env_light.mpSnowPacket;
@@ -3801,25 +3932,37 @@ void dKyr_drawSnow(Mtx drawMtx, u8** tex) {
} }
if (tex[0] != NULL) { if (tex[0] != NULL) {
TGXTexObj spA0; #if TARGET_PC
dKyr_set_btitex(&spA0, (ResTIMG*)tex[0]); static CachedTexObjs<1> texobj;
load_cached_tex(texobj, (ResTIMG*)tex[0], GX_TEXMAP0);
#else
TGXTexObj texobj;
dKyr_set_btitex(&texobj, (ResTIMG*)tex[0]);
#endif
#if TARGET_PC
// Dusklight optimization: enable draw call merging
// by using vertex color instead of GX_TEVREG0
GXSetNumChans(1);
GXSetChanCtrl(GX_COLOR0, GX_DISABLE, GX_SRC_REG, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_CLAMP, GX_AF_NONE);
#else
GXSetNumChans(0); GXSetNumChans(0);
GXSetTevColor(GX_TEVREG0, color_reg0); GXSetTevColor(GX_TEVREG0, color_reg0);
#endif
GXSetTevColor(GX_TEVREG1, color_reg1); GXSetTevColor(GX_TEVREG1, color_reg1);
GXSetNumTexGens(1); GXSetNumTexGens(1);
GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY); GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
GXSetNumTevStages(1); GXSetNumTevStages(1);
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL); GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, DUSK_IF_ELSE(GX_COLOR0A0, GX_COLOR_NULL));
GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_C1, GX_CC_C0, GX_CC_TEXC, GX_CC_ZERO); GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_C1, DUSK_IF_ELSE(GX_CC_RASC, GX_CC_C0), GX_CC_TEXC, GX_CC_ZERO);
GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_A0, GX_CA_TEXA, GX_CA_ZERO); GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, DUSK_IF_ELSE(GX_CA_RASA, GX_CA_CA), GX_CA_TEXA, GX_CA_ZERO);
GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_ONE, GX_LO_COPY); GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_ONE, GX_LO_COPY);
GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_OR, GX_GREATER, 0); GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_OR, GX_GREATER, 0);
GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_DISABLE); GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_DISABLE);
GXSetClipMode(GX_CLIP_DISABLE); GXSetClipMode(GX_CLIP_DISABLE);
GXSetNumIndStages(0); GXSetNumIndStages(0);
dKr_cullVtx_Set(); dKr_cullVtx_Set(IF_DUSK(true));
Mtx rotMtx; Mtx rotMtx;
MTXRotRad(rotMtx, 'Z', DEG_TO_RAD(rot)); MTXRotRad(rotMtx, 'Z', DEG_TO_RAD(rot));
@@ -3896,7 +4039,7 @@ void dKyr_drawSnow(Mtx drawMtx, u8** tex) {
} }
} }
GXSetTevColor(GX_TEVREG0, color_reg0); IF_NOT_DUSK(GXSetTevColor(GX_TEVREG0, color_reg0));
f32 sp38 = 2.0f * (i / 500.0f) * snow_packet->field_0x6d80; f32 sp38 = 2.0f * (i / 500.0f) * snow_packet->field_0x6d80;
f32 sp68 = sp50 * (camera->view.lookat.eye.abs(sp7C) / 1000.0f); f32 sp68 = sp50 * (camera->view.lookat.eye.abs(sp7C) / 1000.0f);
if (sp68 > 1.0f) { if (sp68 > 1.0f) {
@@ -3944,19 +4087,23 @@ void dKyr_drawSnow(Mtx drawMtx, u8** tex) {
for (int k = 0; k < spC; k++) { for (int k = 0; k < spC; k++) {
GXBegin(GX_QUADS, GX_VTXFMT0, 4); GXBegin(GX_QUADS, GX_VTXFMT0, 4);
GXPosition3f32(pos[0].x + (temp_f31 * add_table[k].x), pos[0].y + (temp_f31 * add_table[k].y), pos[0].z + (temp_f31 * add_table[k].z)); GXPosition3f32(pos[0].x + (temp_f31 * add_table[k].x), pos[0].y + (temp_f31 * add_table[k].y), pos[0].z + (temp_f31 * add_table[k].z));
IF_DUSK(GXColor4u8(color_reg0.r, color_reg0.g, color_reg0.b, color_reg0.a));
GXTexCoord2s16(0, 0); GXTexCoord2s16(0, 0);
GXPosition3f32(pos[1].x + (temp_f31 * add_table[k].x), pos[1].y + (temp_f31 * add_table[k].y), pos[1].z + (temp_f31 * add_table[k].z)); GXPosition3f32(pos[1].x + (temp_f31 * add_table[k].x), pos[1].y + (temp_f31 * add_table[k].y), pos[1].z + (temp_f31 * add_table[k].z));
IF_DUSK(GXColor4u8(color_reg0.r, color_reg0.g, color_reg0.b, color_reg0.a));
GXTexCoord2s16(0xFF, 0); GXTexCoord2s16(0xFF, 0);
GXPosition3f32(pos[2].x + (temp_f31 * add_table[k].x), pos[2].y + (temp_f31 * add_table[k].y), pos[2].z + (temp_f31 * add_table[k].z)); GXPosition3f32(pos[2].x + (temp_f31 * add_table[k].x), pos[2].y + (temp_f31 * add_table[k].y), pos[2].z + (temp_f31 * add_table[k].z));
IF_DUSK(GXColor4u8(color_reg0.r, color_reg0.g, color_reg0.b, color_reg0.a));
GXTexCoord2s16(0xFF, 0xFF); GXTexCoord2s16(0xFF, 0xFF);
GXPosition3f32(pos[3].x + (temp_f31 * add_table[k].x), pos[3].y + (temp_f31 * add_table[k].y), pos[3].z + (temp_f31 * add_table[k].z)); GXPosition3f32(pos[3].x + (temp_f31 * add_table[k].x), pos[3].y + (temp_f31 * add_table[k].y), pos[3].z + (temp_f31 * add_table[k].z));
IF_DUSK(GXColor4u8(color_reg0.r, color_reg0.g, color_reg0.b, color_reg0.a));
GXTexCoord2s16(0, 0xFF); GXTexCoord2s16(0, 0xFF);
GXEnd(); GXEnd();
} }
if ((g_env_light.field_0xe90 != 0 && dComIfGp_roomControl_getStayNo() == 0 && sp7C.z < 3000.0f) || dComIfGp_roomControl_getStayNo() == 3 || dComIfGp_roomControl_getStayNo() == 6 || dComIfGp_roomControl_getStayNo() == 9 || dComIfGp_roomControl_getStayNo() == 13) { if ((g_env_light.field_0xe90 != 0 && dComIfGp_roomControl_getStayNo() == 0 && sp7C.z < 3000.0f) || dComIfGp_roomControl_getStayNo() == 3 || dComIfGp_roomControl_getStayNo() == 6 || dComIfGp_roomControl_getStayNo() == 9 || dComIfGp_roomControl_getStayNo() == 13) {
color_reg0.a = 255.0f * ((0.4f * snow_packet->mSnowEff[i].field_0x30) + temp_f29); color_reg0.a = 255.0f * ((0.4f * snow_packet->mSnowEff[i].field_0x30) + temp_f29);
GXSetTevColor(GX_TEVREG0, color_reg0); IF_NOT_DUSK(GXSetTevColor(GX_TEVREG0, color_reg0));
f32 sp34; f32 sp34;
f32 sp30; f32 sp30;
@@ -4012,12 +4159,16 @@ void dKyr_drawSnow(Mtx drawMtx, u8** tex) {
GXBegin(GX_QUADS, GX_VTXFMT0, 4); GXBegin(GX_QUADS, GX_VTXFMT0, 4);
int var_r27 = 0; int var_r27 = 0;
GXPosition3f32(pos[0].x + (temp_f31 * add_table[var_r27].x), pos[0].y + (temp_f31 * add_table[var_r27].y), pos[0].z + (temp_f31 * add_table[var_r27].z)); GXPosition3f32(pos[0].x + (temp_f31 * add_table[var_r27].x), pos[0].y + (temp_f31 * add_table[var_r27].y), pos[0].z + (temp_f31 * add_table[var_r27].z));
IF_DUSK(GXColor4u8(color_reg0.r, color_reg0.g, color_reg0.b, color_reg0.a));
GXTexCoord2s16(0, 0); GXTexCoord2s16(0, 0);
GXPosition3f32(pos[1].x + (temp_f31 * add_table[var_r27].x), pos[1].y + (temp_f31 * add_table[var_r27].y), pos[1].z + (temp_f31 * add_table[var_r27].z)); GXPosition3f32(pos[1].x + (temp_f31 * add_table[var_r27].x), pos[1].y + (temp_f31 * add_table[var_r27].y), pos[1].z + (temp_f31 * add_table[var_r27].z));
IF_DUSK(GXColor4u8(color_reg0.r, color_reg0.g, color_reg0.b, color_reg0.a));
GXTexCoord2s16(0xFF, 0); GXTexCoord2s16(0xFF, 0);
GXPosition3f32(pos[2].x + (temp_f31 * add_table[var_r27].x), pos[2].y + (temp_f31 * add_table[var_r27].y), pos[2].z + (temp_f31 * add_table[var_r27].z)); GXPosition3f32(pos[2].x + (temp_f31 * add_table[var_r27].x), pos[2].y + (temp_f31 * add_table[var_r27].y), pos[2].z + (temp_f31 * add_table[var_r27].z));
IF_DUSK(GXColor4u8(color_reg0.r, color_reg0.g, color_reg0.b, color_reg0.a));
GXTexCoord2s16(0xFF, 0xFF); GXTexCoord2s16(0xFF, 0xFF);
GXPosition3f32(pos[3].x + (temp_f31 * add_table[var_r27].x), pos[3].y + (temp_f31 * add_table[var_r27].y), pos[3].z + (temp_f31 * add_table[var_r27].z)); GXPosition3f32(pos[3].x + (temp_f31 * add_table[var_r27].x), pos[3].y + (temp_f31 * add_table[var_r27].y), pos[3].z + (temp_f31 * add_table[var_r27].z));
IF_DUSK(GXColor4u8(color_reg0.r, color_reg0.g, color_reg0.b, color_reg0.a));
GXTexCoord2s16(0, 0xFF); GXTexCoord2s16(0, 0xFF);
GXEnd(); GXEnd();
} }
@@ -4353,6 +4504,7 @@ void dKyr_drawStar(Mtx drawMtx, u8** tex) {
} }
void drawCloudShadow(Mtx drawMtx, u8** tex) { void drawCloudShadow(Mtx drawMtx, u8** tex) {
ZoneScoped;
dScnKy_env_light_c* envlight = dKy_getEnvlight(); dScnKy_env_light_c* envlight = dKy_getEnvlight();
dKankyo_cloud_Packet* cloud_packet = g_env_light.mpCloudPacket; dKankyo_cloud_Packet* cloud_packet = g_env_light.mpCloudPacket;
camera_class* camera = (camera_class*)dComIfGp_getCamera(0); camera_class* camera = (camera_class*)dComIfGp_getCamera(0);
@@ -4388,7 +4540,12 @@ void drawCloudShadow(Mtx drawMtx, u8** tex) {
GXSetClipMode(GX_CLIP_DISABLE); GXSetClipMode(GX_CLIP_DISABLE);
#if TARGET_PC
static CachedTexObjs<1> texobj;
TGXTexObj fb_texobj;
#else
TGXTexObj texobj, fb_texobj; TGXTexObj texobj, fb_texobj;
#endif
if (g_env_light.mMoyaMode < 50) { if (g_env_light.mMoyaMode < 50) {
dKy_ParticleColor_get_bg(&camera->view.lookat.eye, NULL, &sp48, &sp44, &sp40, &sp3C, 0.0f); dKy_ParticleColor_get_bg(&camera->view.lookat.eye, NULL, &sp48, &sp44, &sp40, &sp3C, 0.0f);
f32 temp_f30 = 0.4f; f32 temp_f30 = 0.4f;
@@ -4401,7 +4558,11 @@ void drawCloudShadow(Mtx drawMtx, u8** tex) {
color_reg1.g = (0.45f * sp38.g) + (0.55f * sp44.g); color_reg1.g = (0.45f * sp38.g) + (0.55f * sp44.g);
color_reg1.b = (0.45f * sp38.b) + (0.55f * sp44.b); color_reg1.b = (0.45f * sp38.b) + (0.55f * sp44.b);
#if TARGET_PC
load_cached_tex(texobj, (ResTIMG*)tex[0], GX_TEXMAP0);
#else
dKyr_set_btitex(&texobj, (ResTIMG*)tex[0]); dKyr_set_btitex(&texobj, (ResTIMG*)tex[0]);
#endif
GXSetNumChans(0); GXSetNumChans(0);
GXSetTevColor(GX_TEVREG0, color_reg0); GXSetTevColor(GX_TEVREG0, color_reg0);
GXSetTevColor(GX_TEVREG1, color_reg1); GXSetTevColor(GX_TEVREG1, color_reg1);
@@ -4446,7 +4607,11 @@ void drawCloudShadow(Mtx drawMtx, u8** tex) {
color_reg1.b = 0; color_reg1.b = 0;
color_reg1.a = 0xFF; color_reg1.a = 0xFF;
#if TARGET_PC
load_cached_tex(texobj, (ResTIMG*)tex[0], GX_TEXMAP1);
#else
dKyr_set_btitex_common(&texobj, (ResTIMG*)tex[0], GX_TEXMAP1); dKyr_set_btitex_common(&texobj, (ResTIMG*)tex[0], GX_TEXMAP1);
#endif
ResTIMG* fb_timg = mDoGph_gInf_c::getFrameBufferTimg(); ResTIMG* fb_timg = mDoGph_gInf_c::getFrameBufferTimg();
dDlst_window_c* window = dComIfGp_getWindow(0); dDlst_window_c* window = dComIfGp_getWindow(0);
@@ -4593,7 +4758,11 @@ void drawVrkumo(Mtx drawMtx, GXColor& color, u8** tex) {
Mtx camMtx; Mtx camMtx;
Mtx rotMtx; Mtx rotMtx;
#if TARGET_PC
static CachedTexObjs<3> texobj;
#else
TGXTexObj texobj; TGXTexObj texobj;
#endif
cXyz proj; cXyz proj;
f32 rot; f32 rot;
@@ -4703,7 +4872,11 @@ void drawVrkumo(Mtx drawMtx, GXColor& color, u8** tex) {
color_reg1.r = 0; color_reg1.r = 0;
color_reg1.g = 0; color_reg1.g = 0;
color_reg1.b = 0; color_reg1.b = 0;
#if TARGET_PC
auto* loaded_texobj = load_cached_tex(texobj, (ResTIMG*)tex[j], GX_TEXMAP0);
#else
dKyr_set_btitex(&texobj, (ResTIMG*)tex[j]); dKyr_set_btitex(&texobj, (ResTIMG*)tex[j]);
#endif
GXSetNumChans(0); GXSetNumChans(0);
GXSetTevColor(GX_TEVREG0, color); GXSetTevColor(GX_TEVREG0, color);
@@ -4808,7 +4981,11 @@ void drawVrkumo(Mtx drawMtx, GXColor& color, u8** tex) {
} }
if (!(vrkumo_packet->mVrkumoEff[k].mAlpha <= 0.000001f)) { if (!(vrkumo_packet->mVrkumoEff[k].mAlpha <= 0.000001f)) {
#if TARGET_PC
GXLoadTexObj(loaded_texobj, GX_TEXMAP0);
#else
GXLoadTexObj(&texobj, GX_TEXMAP0); GXLoadTexObj(&texobj, GX_TEXMAP0);
#endif
GXSetTevColor(GX_TEVREG0, color); GXSetTevColor(GX_TEVREG0, color);
sp60 = sp68 * (0.2f + (0.2f * (k / 100.0f))); sp60 = sp68 * (0.2f + (0.2f * (k / 100.0f)));
@@ -5341,6 +5518,7 @@ void dKyr_odour_move() {
} }
void dKyr_odour_draw(Mtx drawMtx, u8** tex) { void dKyr_odour_draw(Mtx drawMtx, u8** tex) {
ZoneScoped;
dScnKy_env_light_c* envlight = dKy_getEnvlight(); dScnKy_env_light_c* envlight = dKy_getEnvlight();
dKankyo_odour_Packet* odour_packet = envlight->mOdourData.mpOdourPacket; dKankyo_odour_Packet* odour_packet = envlight->mOdourData.mpOdourPacket;
camera_class* camera = (camera_class*)dComIfGp_getCamera(0); camera_class* camera = (camera_class*)dComIfGp_getCamera(0);
@@ -5429,8 +5607,14 @@ void dKyr_odour_draw(Mtx drawMtx, u8** tex) {
break; break;
} }
#if TARGET_PC
static CachedTexObjs<1> texobj;
TGXTexObj fb_texobj;
load_cached_tex(texobj, (ResTIMG*)tex[0], GX_TEXMAP1);
#else
TGXTexObj texobj, fb_texobj; TGXTexObj texobj, fb_texobj;
dKyr_set_btitex_common(&texobj, (ResTIMG*)tex[0], GX_TEXMAP1); dKyr_set_btitex_common(&texobj, (ResTIMG*)tex[0], GX_TEXMAP1);
#endif
ResTIMG* fb_timg = mDoGph_gInf_c::getFrameBufferTimg(); ResTIMG* fb_timg = mDoGph_gInf_c::getFrameBufferTimg();
dDlst_window_c* window = dComIfGp_getWindow(0); dDlst_window_c* window = dComIfGp_getWindow(0);
@@ -5445,18 +5629,23 @@ void dKyr_odour_draw(Mtx drawMtx, u8** tex) {
MTXRotRad(rotMtx, 'Z', DEG_TO_RAD(rot)); MTXRotRad(rotMtx, 'Z', DEG_TO_RAD(rot));
MTXConcat(camMtx, rotMtx, camMtx); MTXConcat(camMtx, rotMtx, camMtx);
// Dusklight opt: enable draw call merging
// by using vertex color instead of GX_TEVREG0
GXLoadPosMtxImm(drawMtx, GX_PNMTX0); GXLoadPosMtxImm(drawMtx, GX_PNMTX0);
GXSetCurrentMtx(GX_PNMTX0); GXSetCurrentMtx(GX_PNMTX0);
GXLoadTexMtxImm(spF0, GX_TEXMTX0, GX_MTX3x4); GXLoadTexMtxImm(spF0, GX_TEXMTX0, GX_MTX3x4);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGBA, GX_F32, 0); GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGBA, GX_F32, 0);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_CLR_RGBA, GX_RGBA4, 8); GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_CLR_RGBA, GX_RGBA4, 8);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX1, GX_CLR_RGBA, GX_RGBA4, 8); GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX1, GX_CLR_RGBA, GX_RGBA4, 8);
IF_DUSK(GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0));
GXClearVtxDesc(); GXClearVtxDesc();
GXSetVtxDesc(GX_VA_POS, GX_DIRECT); GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
GXSetVtxDesc(GX_VA_TEX1, GX_DIRECT); GXSetVtxDesc(GX_VA_TEX1, GX_DIRECT);
IF_DUSK(GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT));
GXSetNumChans(1); GXSetNumChans(1);
GXSetChanCtrl(GX_COLOR0, GX_DISABLE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_CLAMP, GX_AF_NONE); GXSetChanCtrl(GX_COLOR0, GX_DISABLE, GX_SRC_REG, DUSK_IF_ELSE(GX_SRC_VTX, GX_SRC_REG), GX_LIGHT_NULL, GX_DF_CLAMP, GX_AF_NONE);
GXSetTevColor(GX_TEVREG0, color_reg0); GXSetTevColor(GX_TEVREG0, color_reg0);
GXSetTevColor(GX_TEVREG1, color_reg1); GXSetTevColor(GX_TEVREG1, color_reg1);
GXSetNumTexGens(2); GXSetNumTexGens(2);
@@ -5464,14 +5653,14 @@ void dKyr_odour_draw(Mtx drawMtx, u8** tex) {
GXSetTexCoordGen(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX1, GX_IDENTITY); GXSetTexCoordGen(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX1, GX_IDENTITY);
GXSetNumTevStages(2); GXSetNumTevStages(2);
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_TEXC, GX_CC_C0, GX_CC_C1); GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_TEXC, DUSK_IF_ELSE(GX_CC_RASC, GX_CC_C0), GX_CC_C1);
GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_TEXA, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO); GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_TEXA, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO);
GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD1, GX_TEXMAP1, GX_COLOR0A0); GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD1, GX_TEXMAP1, GX_COLOR0A0);
GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_CPREV, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO); GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_CPREV, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO);
GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_FALSE, GX_TEVPREV); GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_FALSE, GX_TEVPREV);
GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_A0, GX_CA_TEXA, GX_CA_ZERO); GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, DUSK_IF_ELSE(GX_CA_RASA, GX_CA_A0), GX_CA_TEXA, GX_CA_ZERO);
GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_FALSE, GX_TEVPREV); GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_FALSE, GX_TEVPREV);
GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_COPY); GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_COPY);
GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_OR, GX_ALWAYS, 0); GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_OR, GX_ALWAYS, 0);
@@ -5513,7 +5702,7 @@ void dKyr_odour_draw(Mtx drawMtx, u8** tex) {
if (effect->mStatus != 0) { if (effect->mStatus != 0) {
if (!(temp_f29 <= 0.000001f)) { if (!(temp_f29 <= 0.000001f)) {
color_reg0.a = 255.0f * temp_f29; color_reg0.a = 255.0f * temp_f29;
GXSetTevColor(GX_TEVREG0, color_reg0); IF_NOT_DUSK(GXSetTevColor(GX_TEVREG0, color_reg0));
sp70 = sp4C; sp70 = sp4C;
@@ -5551,15 +5740,19 @@ void dKyr_odour_draw(Mtx drawMtx, u8** tex) {
GXBegin(GX_QUADS, GX_VTXFMT0, 4); GXBegin(GX_QUADS, GX_VTXFMT0, 4);
GXPosition3f32(pos[0].x, pos[0].y, pos[0].z); GXPosition3f32(pos[0].x, pos[0].y, pos[0].z);
IF_DUSK(GXColor4u8(color_reg0.r, color_reg0.g, color_reg0.b, color_reg0.a));
GXTexCoord2s16(0, 0); GXTexCoord2s16(0, 0);
GXTexCoord2s16(0, 0); GXTexCoord2s16(0, 0);
GXPosition3f32(pos[1].x, pos[1].y, pos[1].z); GXPosition3f32(pos[1].x, pos[1].y, pos[1].z);
IF_DUSK(GXColor4u8(color_reg0.r, color_reg0.g, color_reg0.b, color_reg0.a));
GXTexCoord2s16(0xFF, 0); GXTexCoord2s16(0xFF, 0);
GXTexCoord2s16(0xFF, 0); GXTexCoord2s16(0xFF, 0);
GXPosition3f32(pos[2].x, pos[2].y, pos[2].z); GXPosition3f32(pos[2].x, pos[2].y, pos[2].z);
IF_DUSK(GXColor4u8(color_reg0.r, color_reg0.g, color_reg0.b, color_reg0.a));
GXTexCoord2s16(0xFF, 0xFF); GXTexCoord2s16(0xFF, 0xFF);
GXTexCoord2s16(0xFF, 0xFF); GXTexCoord2s16(0xFF, 0xFF);
GXPosition3f32(pos[3].x, pos[3].y, pos[3].z); GXPosition3f32(pos[3].x, pos[3].y, pos[3].z);
IF_DUSK(GXColor4u8(color_reg0.r, color_reg0.g, color_reg0.b, color_reg0.a));
GXTexCoord2s16(0, 0xFF); GXTexCoord2s16(0, 0xFF);
GXTexCoord2s16(0, 0xFF); GXTexCoord2s16(0, 0xFF);
GXEnd(); GXEnd();
@@ -5730,6 +5923,7 @@ void dKyr_mud_move() {
} }
void dKyr_mud_draw(Mtx drawMtx, u8** tex) { void dKyr_mud_draw(Mtx drawMtx, u8** tex) {
ZoneScoped;
dKankyo_mud_Packet* mud_packet = g_env_light.mpMudPacket; dKankyo_mud_Packet* mud_packet = g_env_light.mpMudPacket;
dKankyo_sun_Packet* sun_packet = g_env_light.mpSunPacket; dKankyo_sun_Packet* sun_packet = g_env_light.mpSunPacket;
@@ -5823,8 +6017,13 @@ void dKyr_mud_draw(Mtx drawMtx, u8** tex) {
if (g_env_light.camera_water_in_status == 0) { if (g_env_light.camera_water_in_status == 0) {
for (int i = 0; i < 1; i++) { for (int i = 0; i < 1; i++) {
#if TARGET_PC
static CachedTexObjs<1> texobj_cache;
auto* texobj = load_cached_tex(texobj_cache, (ResTIMG*)tex[0], GX_TEXMAP0);
#else
TGXTexObj texobj; TGXTexObj texobj;
dKyr_set_btitex(&texobj, (ResTIMG*)tex[0]); dKyr_set_btitex(&texobj, (ResTIMG*)tex[0]);
#endif
GXSetNumChans(0); GXSetNumChans(0);
GXSetTevColor(GX_TEVREG0, color_reg0); GXSetTevColor(GX_TEVREG0, color_reg0);
@@ -5864,7 +6063,11 @@ void dKyr_mud_draw(Mtx drawMtx, u8** tex) {
color_reg0.a = mud_packet->mEffect[j].field_0x38 * var_f31; color_reg0.a = mud_packet->mEffect[j].field_0x38 * var_f31;
#if TARGET_PC
GXLoadTexObj(texobj, GX_TEXMAP0);
#else
GXLoadTexObj(&texobj, GX_TEXMAP0); GXLoadTexObj(&texobj, GX_TEXMAP0);
#endif
GXSetTevColor(GX_TEVREG0, color_reg0); GXSetTevColor(GX_TEVREG0, color_reg0);
f32 sp30 = 1.0f; f32 sp30 = 1.0f;
@@ -5949,6 +6152,7 @@ void dKyr_evil_move() {
} }
static void dKyr_evil_draw2(Mtx drawMtx, u8** tex) { static void dKyr_evil_draw2(Mtx drawMtx, u8** tex) {
ZoneScoped;
dScnKy_env_light_c* envlight = dKy_getEnvlight(); dScnKy_env_light_c* envlight = dKy_getEnvlight();
dKankyo_evil_Packet* evil_packet = envlight->mpEvilPacket; dKankyo_evil_Packet* evil_packet = envlight->mpEvilPacket;
camera_class* camera = (camera_class*)dComIfGp_getCamera(0); camera_class* camera = (camera_class*)dComIfGp_getCamera(0);
@@ -5985,8 +6189,13 @@ static void dKyr_evil_draw2(Mtx drawMtx, u8** tex) {
color_reg0.b = 0x87; color_reg0.b = 0x87;
color_reg0.a = 0xFF; color_reg0.a = 0xFF;
#if TARGET_PC
static CachedTexObjs<1> texobj;
load_cached_tex(texobj, (ResTIMG*)tex[1], GX_TEXMAP0);
#else
TGXTexObj texobj; TGXTexObj texobj;
dKyr_set_btitex(&texobj, (ResTIMG*)tex[1]); dKyr_set_btitex(&texobj, (ResTIMG*)tex[1]);
#endif
#if TARGET_PC #if TARGET_PC
if (dusk::frame_interp::get_ui_tick_pending()) if (dusk::frame_interp::get_ui_tick_pending())
@@ -6187,6 +6396,7 @@ static f32 dKyr_near_bosslight_check(cXyz pos) {
} }
void dKyr_evil_draw(Mtx drawMtx, u8** tex) { void dKyr_evil_draw(Mtx drawMtx, u8** tex) {
ZoneScoped;
dScnKy_env_light_c* envlight = dKy_getEnvlight(); dScnKy_env_light_c* envlight = dKy_getEnvlight();
dKankyo_evil_Packet* evil_packet = envlight->mpEvilPacket; dKankyo_evil_Packet* evil_packet = envlight->mpEvilPacket;
camera_class* camera = (camera_class*)dComIfGp_getCamera(0); camera_class* camera = (camera_class*)dComIfGp_getCamera(0);
@@ -6223,8 +6433,13 @@ void dKyr_evil_draw(Mtx drawMtx, u8** tex) {
color_reg1.b = 10; color_reg1.b = 10;
color_reg1.a = 255; color_reg1.a = 255;
#if TARGET_PC
static CachedTexObjs<1> texobj;
load_cached_tex(texobj, (ResTIMG*)tex[0], GX_TEXMAP0);
#else
TGXTexObj texobj; TGXTexObj texobj;
dKyr_set_btitex(&texobj, (ResTIMG*)tex[0]); dKyr_set_btitex(&texobj, (ResTIMG*)tex[0]);
#endif
#if TARGET_PC #if TARGET_PC
if (dusk::frame_interp::get_ui_tick_pending()) if (dusk::frame_interp::get_ui_tick_pending())
+3 -3
View File
@@ -79,7 +79,7 @@ SNOW_EFF::~SNOW_EFF() {}
SNOW_EFF::SNOW_EFF() {} SNOW_EFF::SNOW_EFF() {}
void dKankyo_snow_Packet::draw() { void dKankyo_snow_Packet::draw() {
dKyr_drawSnow(j3dSys.getViewMtx(), &mpTex); GX_DEBUG_GROUP(dKyr_drawSnow, j3dSys.getViewMtx(), &mpTex);
} }
STAR_EFF::~STAR_EFF() {} STAR_EFF::~STAR_EFF() {}
@@ -103,7 +103,7 @@ HOUSI_EFF::~HOUSI_EFF() {}
HOUSI_EFF::HOUSI_EFF() {} HOUSI_EFF::HOUSI_EFF() {}
void dKankyo_housi_Packet::draw() { void dKankyo_housi_Packet::draw() {
dKyr_drawHousi(j3dSys.getViewMtx(), &mpResTex); GX_DEBUG_GROUP(dKyr_drawHousi, j3dSys.getViewMtx(), &mpResTex);
} }
VRKUMO_EFF::~VRKUMO_EFF() {} VRKUMO_EFF::~VRKUMO_EFF() {}
@@ -119,7 +119,7 @@ EF_ODOUR_EFF::~EF_ODOUR_EFF() {}
EF_ODOUR_EFF::EF_ODOUR_EFF() {} EF_ODOUR_EFF::EF_ODOUR_EFF() {}
void dKankyo_odour_Packet::draw() { void dKankyo_odour_Packet::draw() {
dKyr_odour_draw(j3dSys.getViewMtx(), &mpResTex); GX_DEBUG_GROUP(dKyr_odour_draw, j3dSys.getViewMtx(), &mpResTex);
} }
EF_MUD_EFF::~EF_MUD_EFF() {} EF_MUD_EFF::~EF_MUD_EFF() {}
+29 -11
View File
@@ -19,12 +19,30 @@
#include <numbers> #include <numbers>
#include <array> #include <array>
constexpr u16 kMapResolutionMultiplier = 4; constexpr u16 kPreferredMapResolutionMultiplier = 1;
constexpr u16 kMapImageSide = 16 * kMapResolutionMultiplier; constexpr u32 kMaxMapRenderPixels = 2048 * 2048;
constexpr u16 kMapImageSide = 16 * kPreferredMapResolutionMultiplier;
constexpr u32 kMapImageTotalPixels = kMapImageSide * kMapImageSide; constexpr u32 kMapImageTotalPixels = kMapImageSide * kMapImageSide;
typedef std::function<u8(size_t, size_t)> PaintI8Fn; typedef std::function<u8(size_t, size_t)> PaintI8Fn;
u16 map_resolution_multiplier(u16 width, u16 height) {
const u32 basePixels = static_cast<u32>(width) * height;
if (basePixels == 0) {
return 1;
}
u16 scale = kPreferredMapResolutionMultiplier;
while (scale > 1) {
const u32 scalePixels = static_cast<u32>(scale) * scale;
if (basePixels <= kMaxMapRenderPixels / scalePixels) {
break;
}
scale--;
}
return scale;
}
void paint_i8(std::span<u8> dst, size_t width, PaintI8Fn paint) { void paint_i8(std::span<u8> dst, size_t width, PaintI8Fn paint) {
const auto blocksAcross = width >> 3; const auto blocksAcross = width >> 3;
@@ -478,9 +496,9 @@ void dRenderingMap_c::makeResTIMG(ResTIMG* p_image, u16 width, u16 height, u8* p
p_image->format = GX_TF_C8; p_image->format = GX_TF_C8;
p_image->alphaEnabled = 2; p_image->alphaEnabled = 2;
#ifdef TARGET_PC #ifdef TARGET_PC
// Increase map render resolution const u16 scale = map_resolution_multiplier(width, height);
p_image->width = width * kMapResolutionMultiplier; p_image->width = width * scale;
p_image->height = height * kMapResolutionMultiplier; p_image->height = height * scale;
#else #else
p_image->width = width; p_image->width = width;
p_image->height = height; p_image->height = height;
@@ -563,9 +581,9 @@ void dRenderingFDAmap_c::drawBack() const {
void dRenderingFDAmap_c::preRenderingMap() { void dRenderingFDAmap_c::preRenderingMap() {
#ifdef TARGET_PC #ifdef TARGET_PC
// Increase map render resolution const u16 scale = map_resolution_multiplier(mTexWidth, mTexHeight);
const u16 w = mTexWidth * kMapResolutionMultiplier; const u16 w = mTexWidth * scale;
const u16 h = mTexHeight * kMapResolutionMultiplier; const u16 h = mTexHeight * scale;
GXCreateFrameBuffer(w, h); GXCreateFrameBuffer(w, h);
// Set logical viewport dimensions // Set logical viewport dimensions
GXSetViewport(0.0f, 0.0f, mTexWidth, mTexHeight, 0.0f, 1.0f); GXSetViewport(0.0f, 0.0f, mTexWidth, mTexHeight, 0.0f, 1.0f);
@@ -610,9 +628,9 @@ void dRenderingFDAmap_c::preRenderingMap() {
void dRenderingFDAmap_c::postRenderingMap() { void dRenderingFDAmap_c::postRenderingMap() {
GXSetCopyFilter(GX_FALSE, NULL, GX_FALSE, NULL); GXSetCopyFilter(GX_FALSE, NULL, GX_FALSE, NULL);
#ifdef TARGET_PC #ifdef TARGET_PC
// Increase map render resolution const u16 scale = map_resolution_multiplier(mTexWidth, mTexHeight);
const u16 w = mTexWidth * kMapResolutionMultiplier; const u16 w = mTexWidth * scale;
const u16 h = mTexHeight * kMapResolutionMultiplier; const u16 h = mTexHeight * scale;
GXSetTexCopySrc(0, 0, w, h); GXSetTexCopySrc(0, 0, w, h);
GXSetTexCopyDst(w, h, GX_CTF_R8, GX_FALSE); GXSetTexCopyDst(w, h, GX_CTF_R8, GX_FALSE);
GXCopyTex(field_0x4, GX_TRUE); GXCopyTex(field_0x4, GX_TRUE);
+6
View File
@@ -1943,6 +1943,12 @@ void dMenu_Fmap2DBack_c::regionMapMove(STControl* i_stick) {
calcAllMapPos2D(mArrowPos3DX + control_xpos - mStageTransX, calcAllMapPos2D(mArrowPos3DX + control_xpos - mStageTransX,
mArrowPos3DZ + control_ypos - mStageTransZ, &pos_x, &pos_y); mArrowPos3DZ + control_ypos - mStageTransZ, &pos_x, &pos_y);
#if TARGET_PC
if (dusk::getSettings().game.enableMirrorMode) {
pos_x = getMirrorPosX(pos_x, 0.0f);
}
#endif
mSelectRegion = 0xff; mSelectRegion = 0xff;
int region = mRegionCursor; int region = mRegionCursor;
if (region != 0xff && region != 7) { if (region != 0xff && region != 7) {
+161
View File
@@ -23,6 +23,39 @@
#include "dusk/frame_interpolation.h" #include "dusk/frame_interpolation.h"
#include <cstring> #include <cstring>
#if TARGET_PC
#include "dusk/settings.h"
#include <algorithm>
namespace {
// Reads the user HUD scale setting, clamped to a safe range.
f32 dGetUserHudScale() {
return std::clamp(dusk::getSettings().game.hudScale.getValue(), 0.5f, 2.0f);
}
// The screen corner each HUD group is anchored to. A pane scales around its own origin,
// so without correction it drifts away from the screen edge; this names the corner that
// must stay put.
enum class HudCorner { TopLeft, TopRight, BottomLeft, BottomRight };
// Adds the paneTrans offset that keeps i_corner pinned in place while the user HUD scale
// grows or shrinks the pane. The shift is half the change in size pushed toward the
// anchor corner, so it depends only on the pane's size (not its on-screen position) and
// works whether the HUD is scaled down or up. i_pull < 1 applies a partial horizontal
// push for a pane whose content sits inset from its box edge (the heart row).
void dAnchorHudScale(CPaneMgr* i_pane, HudCorner i_corner, f32* io_x, f32* io_y, f32 i_pull = 1.0f) {
const f32 half = (1.0f - dGetUserHudScale()) * 0.5f;
const f32 dirX =
(i_corner == HudCorner::TopRight || i_corner == HudCorner::BottomRight) ? 1.0f : -1.0f;
const f32 dirY =
(i_corner == HudCorner::BottomLeft || i_corner == HudCorner::BottomRight) ? 1.0f : -1.0f;
*io_x += dirX * i_pane->getInitSizeX() * half * i_pull;
*io_y += dirY * i_pane->getInitSizeY() * half;
}
} // namespace
#endif
dMeter2Draw_c::dMeter2Draw_c(JKRExpHeap* mp_heap) { dMeter2Draw_c::dMeter2Draw_c(JKRExpHeap* mp_heap) {
OS_REPORT("enter dMeter2Draw_c::dMeter2Draw_c(JKRExpHeap *mp_heap)\n"); OS_REPORT("enter dMeter2Draw_c::dMeter2Draw_c(JKRExpHeap *mp_heap)\n");
@@ -536,6 +569,12 @@ void dMeter2Draw_c::init() {
} }
void dMeter2Draw_c::exec(u32 i_status) { void dMeter2Draw_c::exec(u32 i_status) {
#if TARGET_PC
// n_all keeps the vanilla scale. Scaling the root pane shrinks every child toward
// its centred origin; per-child scaling in each drawXxx() path keeps each HUD group
// anchored to its own pane origin and also pulls it toward the screen corner.
const f32 userHudScale = dGetUserHudScale();
#endif
if (mParentScale != g_drawHIO.mParentScale) { if (mParentScale != g_drawHIO.mParentScale) {
mParentScale = g_drawHIO.mParentScale; mParentScale = g_drawHIO.mParentScale;
mpParent->scale(g_drawHIO.mParentScale, g_drawHIO.mParentScale); mpParent->scale(g_drawHIO.mParentScale, g_drawHIO.mParentScale);
@@ -546,6 +585,39 @@ void dMeter2Draw_c::exec(u32 i_status) {
mpParent->setAlphaRate(g_drawHIO.mParentAlpha); mpParent->setAlphaRate(g_drawHIO.mParentAlpha);
} }
#if TARGET_PC
if (i_status & 0x1000000) {
f32 ringPosX = g_drawHIO.mRingHUDButtonsPosX;
f32 ringPosY = g_drawHIO.mRingHUDButtonsPosY;
dAnchorHudScale(mpButtonParent, HudCorner::TopRight, &ringPosX, &ringPosY);
if (mButtonsPosX != ringPosX || mButtonsPosY != ringPosY) {
mButtonsPosX = ringPosX;
mButtonsPosY = ringPosY;
mpButtonParent->paneTrans(ringPosX, ringPosY);
}
const f32 ringButtonsScale = g_drawHIO.mRingHUDButtonsScale * userHudScale;
if (mButtonsScale != ringButtonsScale) {
mButtonsScale = ringButtonsScale;
mpButtonParent->scale(ringButtonsScale, ringButtonsScale);
}
} else {
f32 mainPosX = g_drawHIO.mMainHUDButtonsPosX;
f32 mainPosY = g_drawHIO.mMainHUDButtonsPosY;
dAnchorHudScale(mpButtonParent, HudCorner::TopRight, &mainPosX, &mainPosY);
if (mButtonsPosX != mainPosX || mButtonsPosY != mainPosY) {
mButtonsPosX = mainPosX;
mButtonsPosY = mainPosY;
mpButtonParent->paneTrans(mainPosX, mainPosY);
}
const f32 mainButtonsScale = g_drawHIO.mMainHUDButtonsScale * userHudScale;
if (mButtonsScale != mainButtonsScale) {
mButtonsScale = mainButtonsScale;
mpButtonParent->scale(mainButtonsScale, mainButtonsScale);
}
}
#else
if (i_status & 0x1000000) { if (i_status & 0x1000000) {
if (mButtonsPosX != g_drawHIO.mRingHUDButtonsPosX || if (mButtonsPosX != g_drawHIO.mRingHUDButtonsPosX ||
mButtonsPosY != g_drawHIO.mRingHUDButtonsPosY) mButtonsPosY != g_drawHIO.mRingHUDButtonsPosY)
@@ -574,6 +646,7 @@ void dMeter2Draw_c::exec(u32 i_status) {
mpButtonParent->scale(g_drawHIO.mMainHUDButtonsScale, g_drawHIO.mMainHUDButtonsScale); mpButtonParent->scale(g_drawHIO.mMainHUDButtonsScale, g_drawHIO.mMainHUDButtonsScale);
} }
} }
#endif
} }
void dMeter2Draw_c::draw() { void dMeter2Draw_c::draw() {
@@ -588,6 +661,9 @@ void dMeter2Draw_c::draw() {
if (mpItemXY[i] != NULL) { if (mpItemXY[i] != NULL) {
for (int j = 0; j < 3; j++) { for (int j = 0; j < 3; j++) {
f32 temp_f30 = mItemParams[i].num_scale * 16.0f; f32 temp_f30 = mItemParams[i].num_scale * 16.0f;
#if TARGET_PC
temp_f30 *= dGetUserHudScale();
#endif
Vec vtx0 = mpItemXY[i]->getPanePtr()->getGlbVtx(0); Vec vtx0 = mpItemXY[i]->getPanePtr()->getGlbVtx(0);
Vec vtx3 = mpItemXY[i]->getPanePtr()->getGlbVtx(3); Vec vtx3 = mpItemXY[i]->getPanePtr()->getGlbVtx(3);
@@ -1478,7 +1554,12 @@ void dMeter2Draw_c::drawLife(s16 i_maxLife, s16 i_life, f32 i_posX, f32 i_posY)
} }
} }
#if TARGET_PC
const f32 lifeParentScale = g_drawHIO.mLifeParentScale * dGetUserHudScale();
mpLifeParent->scale(lifeParentScale, lifeParentScale);
#else
mpLifeParent->scale(g_drawHIO.mLifeParentScale, g_drawHIO.mLifeParentScale); mpLifeParent->scale(g_drawHIO.mLifeParentScale, g_drawHIO.mLifeParentScale);
#endif
for (int i = 0; i < 20; i++) { for (int i = 0; i < 20; i++) {
mpHeartMark[i]->scale(g_drawHIO.mHeartMarkScale, g_drawHIO.mHeartMarkScale); mpHeartMark[i]->scale(g_drawHIO.mHeartMarkScale, g_drawHIO.mHeartMarkScale);
@@ -1488,7 +1569,16 @@ void dMeter2Draw_c::drawLife(s16 i_maxLife, s16 i_life, f32 i_posX, f32 i_posY)
mpBigHeart->scale(g_drawHIO.mBigHeartScale, g_drawHIO.mBigHeartScale); mpBigHeart->scale(g_drawHIO.mBigHeartScale, g_drawHIO.mBigHeartScale);
} }
#if TARGET_PC
f32 lifePosX = i_posX;
f32 lifePosY = i_posY;
// The heart row sits inset from its box's left edge, so use a partial horizontal pull
// to keep it from jamming against the screen edge.
dAnchorHudScale(mpLifeParent, HudCorner::TopLeft, &lifePosX, &lifePosY, 0.6f);
mpLifeParent->paneTrans(lifePosX, lifePosY);
#else
mpLifeParent->paneTrans(i_posX, i_posY); mpLifeParent->paneTrans(i_posX, i_posY);
#endif
} }
void dMeter2Draw_c::setAlphaLifeChange(bool param_0) { void dMeter2Draw_c::setAlphaLifeChange(bool param_0) {
@@ -1601,9 +1691,22 @@ void dMeter2Draw_c::drawKanteraScreen(u8 i_meterType) {
mpMagicMeter->resize(field_0x584[i_meterType], field_0x590[i_meterType]); mpMagicMeter->resize(field_0x584[i_meterType], field_0x590[i_meterType]);
mpMagicFrameR->move(field_0x59c[i_meterType], field_0x5a8[i_meterType]); mpMagicFrameR->move(field_0x59c[i_meterType], field_0x5a8[i_meterType]);
mpMagicBase->resize(field_0x5b4[i_meterType], field_0x5c0[i_meterType]); mpMagicBase->resize(field_0x5b4[i_meterType], field_0x5c0[i_meterType]);
#if TARGET_PC
const f32 magicUserScale = dGetUserHudScale();
mpMagicParent->scale(field_0x5cc[i_meterType] * magicUserScale,
field_0x5d8[i_meterType] * magicUserScale);
f32 magicPosX = field_0x5e4[i_meterType];
f32 magicPosY = field_0x5f0[i_meterType];
// The oil/magic bar sits inset within its pane box, so use a reduced horizontal pull
// (like the heart row) to keep it from overshooting off the left edge when shrunk.
dAnchorHudScale(mpMagicParent, HudCorner::TopLeft, &magicPosX, &magicPosY, 0.3f);
mpMagicParent->paneTrans(magicPosX, magicPosY);
#else
mpMagicParent->scale(field_0x5cc[i_meterType], field_0x5d8[i_meterType]); mpMagicParent->scale(field_0x5cc[i_meterType], field_0x5d8[i_meterType]);
mpMagicParent->paneTrans(field_0x5e4[i_meterType], field_0x5f0[i_meterType]); mpMagicParent->paneTrans(field_0x5e4[i_meterType], field_0x5f0[i_meterType]);
#endif
mpKanteraScreen->draw(0.0f, 0.0f, graf_ctx); mpKanteraScreen->draw(0.0f, 0.0f, graf_ctx);
} }
@@ -1867,10 +1970,21 @@ void dMeter2Draw_c::drawLightDrop(u8 i_num, u8 i_needNum, f32 i_posX, f32 i_posY
field_0x6fc = param_5; field_0x6fc = param_5;
mLightDropVesselScale = i_vesselScale; mLightDropVesselScale = i_vesselScale;
#if TARGET_PC
const f32 lightDropUserScale = dGetUserHudScale();
const f32 lightDropScale = mLightDropVesselScale * field_0x6f8 * lightDropUserScale;
mpLightDropParent->scale(lightDropScale, lightDropScale);
f32 lightDropPosX = i_posX;
f32 lightDropPosY = i_posY;
dAnchorHudScale(mpLightDropParent, HudCorner::TopRight, &lightDropPosX, &lightDropPosY);
mpLightDropParent->paneTrans(lightDropPosX, lightDropPosY);
#else
mpLightDropParent->scale(mLightDropVesselScale * field_0x6f8, mpLightDropParent->scale(mLightDropVesselScale * field_0x6f8,
mLightDropVesselScale * field_0x6f8); mLightDropVesselScale * field_0x6f8);
mpLightDropParent->paneTrans(i_posX, i_posY); mpLightDropParent->paneTrans(i_posX, i_posY);
#endif
} }
void dMeter2Draw_c::setAlphaLightDropChange(bool unused) {} void dMeter2Draw_c::setAlphaLightDropChange(bool unused) {}
@@ -1943,8 +2057,13 @@ void dMeter2Draw_c::setAlphaLightDropAnimeMax() {
field_0x6f8 = 1.0f; field_0x6f8 = 1.0f;
} }
#if TARGET_PC
const f32 dropAnimScale = mLightDropVesselScale * field_0x6f8 * dGetUserHudScale();
mpLightDropParent->scale(dropAnimScale, dropAnimScale);
#else
mpLightDropParent->scale(mLightDropVesselScale * field_0x6f8, mpLightDropParent->scale(mLightDropVesselScale * field_0x6f8,
mLightDropVesselScale * field_0x6f8); mLightDropVesselScale * field_0x6f8);
#endif
if (g_drawHIO.mLightDrop.mDropGetScaleAnimFrameNum == mpLightDropParent->getAlphaTimer()) { if (g_drawHIO.mLightDrop.mDropGetScaleAnimFrameNum == mpLightDropParent->getAlphaTimer()) {
dMeter2Info_setLightDropGetFlag(dComIfGp_getStartStageDarkArea(), 0xFF); dMeter2Info_setLightDropGetFlag(dComIfGp_getStartStageDarkArea(), 0xFF);
@@ -2015,10 +2134,22 @@ void dMeter2Draw_c::drawRupee(s16 i_rupeeNum) {
static_cast<J2DPicture*>(mpRupeeTexture[0][0]->getPanePtr())->changeTexture(timg, 0); static_cast<J2DPicture*>(mpRupeeTexture[0][0]->getPanePtr())->changeTexture(timg, 0);
static_cast<J2DPicture*>(mpRupeeTexture[0][1]->getPanePtr())->changeTexture(timg, 0); static_cast<J2DPicture*>(mpRupeeTexture[0][1]->getPanePtr())->changeTexture(timg, 0);
#if TARGET_PC
const f32 rupeeKeyUserScale = dGetUserHudScale();
const f32 rupeeKeyScale = g_drawHIO.mRupeeKeyScale * field_0x718 * rupeeKeyUserScale;
mpRupeeKeyParent->scale(rupeeKeyScale, rupeeKeyScale);
f32 rupeeKeyPosX = g_drawHIO.mRupeeKeyPosX;
f32 rupeeKeyPosY = g_drawHIO.mRupeeKeyPosY;
// Rupees/keys read better anchored to the bottom-right corner than the top-right.
dAnchorHudScale(mpRupeeKeyParent, HudCorner::BottomRight, &rupeeKeyPosX, &rupeeKeyPosY);
mpRupeeKeyParent->paneTrans(rupeeKeyPosX, rupeeKeyPosY);
#else
mpRupeeKeyParent->scale(g_drawHIO.mRupeeKeyScale * field_0x718, mpRupeeKeyParent->scale(g_drawHIO.mRupeeKeyScale * field_0x718,
g_drawHIO.mRupeeKeyScale * field_0x718); g_drawHIO.mRupeeKeyScale * field_0x718);
mpRupeeKeyParent->paneTrans(g_drawHIO.mRupeeKeyPosX, g_drawHIO.mRupeeKeyPosY); mpRupeeKeyParent->paneTrans(g_drawHIO.mRupeeKeyPosX, g_drawHIO.mRupeeKeyPosY);
#endif
mpRupeeParent[0]->scale(g_drawHIO.mRupeeScale, g_drawHIO.mRupeeScale); mpRupeeParent[0]->scale(g_drawHIO.mRupeeScale, g_drawHIO.mRupeeScale);
mpRupeeParent[0]->paneTrans(g_drawHIO.mRupeePosX, g_drawHIO.mRupeePosY); mpRupeeParent[0]->paneTrans(g_drawHIO.mRupeePosX, g_drawHIO.mRupeePosY);
@@ -2137,8 +2268,18 @@ void dMeter2Draw_c::drawKey(s16 i_keyNum) {
} }
} }
#if TARGET_PC
const f32 keyScale = g_drawHIO.mKeyScale * dGetUserHudScale();
mpKeyParent->scale(keyScale, keyScale);
f32 keyPosX = g_drawHIO.mKeyPosX;
f32 keyPosY = g_drawHIO.mKeyPosY;
dAnchorHudScale(mpKeyParent, HudCorner::BottomRight, &keyPosX, &keyPosY);
mpKeyParent->paneTrans(keyPosX, keyPosY);
#else
mpKeyParent->scale(g_drawHIO.mKeyScale, g_drawHIO.mKeyScale); mpKeyParent->scale(g_drawHIO.mKeyScale, g_drawHIO.mKeyScale);
mpKeyParent->paneTrans(g_drawHIO.mKeyPosX, g_drawHIO.mKeyPosY); mpKeyParent->paneTrans(g_drawHIO.mKeyPosX, g_drawHIO.mKeyPosY);
#endif
} }
void dMeter2Draw_c::setAlphaKeyChange(bool param_0) { void dMeter2Draw_c::setAlphaKeyChange(bool param_0) {
@@ -2596,11 +2737,24 @@ f32 dMeter2Draw_c::getButtonCrossParentInitTransY() {
} }
void dMeter2Draw_c::drawButtonCross(f32 i_posX, f32 i_posY) { void dMeter2Draw_c::drawButtonCross(f32 i_posX, f32 i_posY) {
#if TARGET_PC
const f32 buttonCrossUserScale = dGetUserHudScale();
const f32 buttonCrossScale = g_drawHIO.mButtonCrossScale * buttonCrossUserScale;
mpButtonCrossParent->scale(buttonCrossScale, buttonCrossScale);
#else
mpButtonCrossParent->scale(g_drawHIO.mButtonCrossScale, g_drawHIO.mButtonCrossScale); mpButtonCrossParent->scale(g_drawHIO.mButtonCrossScale, g_drawHIO.mButtonCrossScale);
#endif
mpTextI->scale(g_drawHIO.mButtonCrossTextScale, g_drawHIO.mButtonCrossTextScale); mpTextI->scale(g_drawHIO.mButtonCrossTextScale, g_drawHIO.mButtonCrossTextScale);
mpTextM->scale(g_drawHIO.mButtonCrossTextScale, g_drawHIO.mButtonCrossTextScale); mpTextM->scale(g_drawHIO.mButtonCrossTextScale, g_drawHIO.mButtonCrossTextScale);
#if TARGET_PC
f32 buttonCrossPosX = i_posX;
f32 buttonCrossPosY = i_posY;
dAnchorHudScale(mpButtonCrossParent, HudCorner::TopLeft, &buttonCrossPosX, &buttonCrossPosY);
mpButtonCrossParent->paneTrans(buttonCrossPosX, buttonCrossPosY);
#else
mpButtonCrossParent->paneTrans(i_posX, i_posY); mpButtonCrossParent->paneTrans(i_posX, i_posY);
#endif
} }
void dMeter2Draw_c::setAlphaButtonCrossAnimeMin() { void dMeter2Draw_c::setAlphaButtonCrossAnimeMin() {
@@ -3505,9 +3659,16 @@ void dMeter2Draw_c::drawKanteraMeter(u8 i_button, f32 i_alphaRate) {
Vec vtx0 = pane->getPanePtr()->getGlbVtx(0); Vec vtx0 = pane->getPanePtr()->getGlbVtx(0);
Vec vtx3 = pane->getPanePtr()->getGlbVtx(3); Vec vtx3 = pane->getPanePtr()->getGlbVtx(3);
#if TARGET_PC
const f32 oilUserScale = dGetUserHudScale();
mpKanteraMeter[i_button]->setPos(((vtx0.x + vtx3.x) * 0.5f) + 9.0f * oilUserScale + sp10[i_button],
vtx3.y + sp8[i_button]);
mpKanteraMeter[i_button]->setScale(0.6f * oilUserScale, 0.6f * oilUserScale);
#else
mpKanteraMeter[i_button]->setPos(((vtx0.x + vtx3.x) * 0.5f) + 9.0f + sp10[i_button], mpKanteraMeter[i_button]->setPos(((vtx0.x + vtx3.x) * 0.5f) + 9.0f + sp10[i_button],
vtx3.y + sp8[i_button]); vtx3.y + sp8[i_button]);
mpKanteraMeter[i_button]->setScale(0.6f, 0.6f); mpKanteraMeter[i_button]->setScale(0.6f, 0.6f);
#endif
mpKanteraMeter[i_button]->setNowGauge(dComIfGs_getMaxOil(), dComIfGs_getOil()); mpKanteraMeter[i_button]->setNowGauge(dComIfGs_getMaxOil(), dComIfGs_getOil());
mpKanteraMeter[i_button]->setAlphaRate(i_alphaRate); mpKanteraMeter[i_button]->setAlphaRate(i_alphaRate);
} }
+14 -2
View File
@@ -16,6 +16,10 @@
#include "f_op/f_op_overlap_mng.h" #include "f_op/f_op_overlap_mng.h"
#include "m_Do/m_Do_controller_pad.h" #include "m_Do/m_Do_controller_pad.h"
#include "d/d_camera.h" #include "d/d_camera.h"
#if TARGET_PC
#include "dusk/settings.h"
#include <algorithm>
#endif
#include <cstring> #include <cstring>
#if (PLATFORM_WII || PLATFORM_SHIELD) #if (PLATFORM_WII || PLATFORM_SHIELD)
@@ -621,8 +625,16 @@ void dMeterMap_c::draw() {
mMapJ2DPicture->setAlpha(alpha); mMapJ2DPicture->setAlpha(alpha);
#if TARGET_PC #if TARGET_PC
mMapJ2DPicture->draw(mDoGph_gInf_c::ScaleHUDXLeft(drawPosX), drawPosY, sizeX, sizeY, false, // Scale the minimap with the user HUD scale and shift down so its bottom-left
false, false); // corner stays anchored to the same screen position as at scale 1.0.
const f32 userHudScale =
std::clamp(dusk::getSettings().game.hudScale.getValue(), 0.5f, 2.0f);
const f32 scaledSizeX = sizeX * userHudScale;
const f32 scaledSizeY = sizeY * userHudScale;
const f32 mapBottomShift = sizeY - scaledSizeY;
mMapJ2DPicture->draw(mDoGph_gInf_c::ScaleHUDXLeft(drawPosX),
drawPosY + mapBottomShift, scaledSizeX, scaledSizeY,
false, false, false);
#else #else
mMapJ2DPicture->draw(drawPosX, drawPosY, sizeX, sizeY, false, false, false); mMapJ2DPicture->draw(drawPosX, drawPosY, sizeX, sizeY, false, false, false);
#endif #endif
+72 -3
View File
@@ -604,6 +604,70 @@ int dMsgObject_c::_delete() {
return 1; return 1;
} }
#if TARGET_PC
struct MirrorMsgOverride {
u32 gcMsgId;
u32 wiiMsgId;
};
static const MirrorMsgOverride mirrorMsgOverrides[] = {
{0x153a, 0x3c4a},
{0x1553, 0x3c63},
{0x1558, 0x3c68},
{0x155c, 0x3c6c},
{0x1569, 0x3c79},
{0x156f, 0x3c7f},
{0x1f81, 0x4691},
{0x232a, 0x4a3a},
{0x13f2, 0x3b02},
{0x1416, 0x3b26},
{0x1417, 0x3b27},
{0x1419, 0x3b29},
{0x1521, 0x3c31},
{0x1614, 0x3d24},
{0x1626, 0x3d36},
{0x1628, 0x3d38},
{0x16aa, 0x3dba},
{0x16b8, 0x3dc8},
{0x16b9, 0x3dc9},
{0x1904, 0x4014},
{0x1919, 0x4029},
{0x19cd, 0x40dd},
{0x19d3, 0x40e3},
{0x19d6, 0x40e6},
{0x19e6, 0x40f6},
{0x19eb, 0x40fb},
{0x14b6, 0x3bc6},
{0x151a, 0x3c2a},
{0x1530, 0x3c40},
{0x1532, 0x3c42},
{0x2726, 0x4e36},
{0x2736, 0x4e46},
{0x2739, 0x4e49},
{0x274c, 0x4e5c},
{0x24da, 0x4bea},
{0x24db, 0x4beb},
{0x13d8, 0x3ae8},
{0x13dc, 0x3aec},
{0x13eb, 0x3afb},
{0x17df, 0x3eef},
{0x17e2, 0x3ef2},
{0x1dae, 0x44be},
{0x14ca, 0x3bda},
{0x470, 0x493},
{0x473, 0x492},
};
static u32 getMirrorMsgOverride(u32 msgId) {
for (size_t i = 0; i < sizeof(mirrorMsgOverrides) / sizeof(mirrorMsgOverrides[0]); i++) {
if (mirrorMsgOverrides[i].gcMsgId == msgId) {
return mirrorMsgOverrides[i].wiiMsgId;
}
}
return msgId;
}
#endif
void dMsgObject_c::setMessageIndex(u32 revoIndex, u32 param_2, bool param_3) { void dMsgObject_c::setMessageIndex(u32 revoIndex, u32 param_2, bool param_3) {
field_0x158 = revoIndex; field_0x158 = revoIndex;
revoIndex = getRevoMessageIndex(revoIndex); revoIndex = getRevoMessageIndex(revoIndex);
@@ -692,9 +756,14 @@ u32 dMsgObject_c::getMessageIndex(u32 param_0) {
} }
u32 dMsgObject_c::getRevoMessageIndex(u32 param_1) { u32 dMsgObject_c::getRevoMessageIndex(u32 param_1) {
if (!g_MsgObject_HIO_c.mMessageDisplay) { #if TARGET_PC
return param_1; if (!dusk::getSettings().game.enableMirrorMode) {
} if (!g_MsgObject_HIO_c.mMessageDisplay) { return param_1; } }
if (param_1 == getMirrorMsgOverride(param_1)) { return param_1; }
#else
if (!g_MsgObject_HIO_c.mMessageDisplay) { return param_1; }
#endif
u32 msgIndexCount; u32 msgIndexCount;
JMSMesgInfo_c* pMsg; JMSMesgInfo_c* pMsg;
int i = 0; int i = 0;
+4
View File
@@ -1359,6 +1359,7 @@ void dPa_control_c::calcMenu() {
} }
void dPa_control_c::draw(JPADrawInfo* param_0, u8 param_1) { void dPa_control_c::draw(JPADrawInfo* param_0, u8 param_1) {
ZoneScoped;
if (mEmitterMng != NULL) { if (mEmitterMng != NULL) {
j3dSys.reinitGX(); j3dSys.reinitGX();
dKy_setLight_again(); dKy_setLight_again();
@@ -1957,6 +1958,7 @@ void dPa_gen_d_light8PcallBack::execute(JPABaseEmitter* i_emitter, JPABasePartic
} }
void dPa_light8PcallBack::draw(JPABaseEmitter* param_1, JPABaseParticle* param_2) { void dPa_light8PcallBack::draw(JPABaseEmitter* param_1, JPABaseParticle* param_2) {
ZoneScoped;
Mtx local_60; Mtx local_60;
Mtx auStack_90; Mtx auStack_90;
Mtx auStack_c0; Mtx auStack_c0;
@@ -2084,6 +2086,7 @@ void dPa_light8PcallBack::draw(JPABaseEmitter* param_1, JPABaseParticle* param_2
} }
void dPa_gen_b_light8PcallBack::draw(JPABaseEmitter* param_1, JPABaseParticle* param_2) { void dPa_gen_b_light8PcallBack::draw(JPABaseEmitter* param_1, JPABaseParticle* param_2) {
ZoneScoped;
Mtx local_80; Mtx local_80;
JGeometry::TVec3<f32> local_8c; JGeometry::TVec3<f32> local_8c;
JGeometry::TVec3<f32> aTStack_98; JGeometry::TVec3<f32> aTStack_98;
@@ -2172,6 +2175,7 @@ void dPa_gen_b_light8PcallBack::draw(JPABaseEmitter* param_1, JPABaseParticle* p
} }
void dPa_gen_d_light8PcallBack::draw(JPABaseEmitter* param_1, JPABaseParticle* param_2) { void dPa_gen_d_light8PcallBack::draw(JPABaseEmitter* param_1, JPABaseParticle* param_2) {
ZoneScoped;
Mtx local_60; Mtx local_60;
Mtx auStack_90; Mtx auStack_90;
Mtx auStack_c0; Mtx auStack_c0;
+3
View File
@@ -0,0 +1,3 @@
const char* __asan_default_options(void) {
return "abort_on_error=1:symbolize=1:intercept_memcmp=0:detect_leaks=0";
}
+17 -6
View File
@@ -76,15 +76,12 @@ template<ConfigValue T>
void ConfigImpl<T>::loadFromJson(ConfigVar<T>& cVar, const json& jsonValue) { void ConfigImpl<T>::loadFromJson(ConfigVar<T>& cVar, const json& jsonValue) {
if constexpr (std::is_enum_v<T>) { if constexpr (std::is_enum_v<T>) {
if (jsonValue.is_boolean()) { if (jsonValue.is_boolean()) {
DuskConfigLog.error("Doing default migration of CVar {} from bool, enum values may not be what is expected!", cVar.getName());
using Underlying = std::underlying_type_t<T>; using Underlying = std::underlying_type_t<T>;
const bool b = jsonValue.get<bool>(); const bool b = jsonValue.get<bool>();
Underlying raw; const Underlying raw = b ? static_cast<Underlying>(1) : static_cast<Underlying>(0);
if constexpr (std::is_same_v<T, dusk::FrameInterpMode>) {
raw = b ? static_cast<Underlying>(2) : static_cast<Underlying>(0);
} else {
raw = b ? static_cast<Underlying>(1) : static_cast<Underlying>(0);
}
cVar.setValue(sanitizeEnumValue(cVar, static_cast<T>(raw)), false); cVar.setValue(sanitizeEnumValue(cVar, static_cast<T>(raw)), false);
return; return;
@@ -194,9 +191,23 @@ namespace dusk::config {
template class ConfigImpl<dusk::DiscVerificationState>; template class ConfigImpl<dusk::DiscVerificationState>;
template class ConfigImpl<dusk::GameLanguage>; template class ConfigImpl<dusk::GameLanguage>;
template class ConfigImpl<dusk::GyroMode>; template class ConfigImpl<dusk::GyroMode>;
template<> void ConfigImpl<FrameInterpMode>::loadFromJson(ConfigVar<FrameInterpMode>& cVar, const json& jsonValue) {
if (jsonValue.is_boolean()) {
const bool b = jsonValue.get<bool>();
const FrameInterpMode mode = b ? FrameInterpMode::Unlimited : FrameInterpMode::Off;
cVar.setValue(sanitizeEnumValue(cVar, mode), false);
return;
}
cVar.setValue(sanitizeEnumValue(cVar, jsonValue.get<FrameInterpMode>()), false);
}
template class ConfigImpl<dusk::FrameInterpMode>; template class ConfigImpl<dusk::FrameInterpMode>;
template class ConfigImpl<dusk::MenuScaling>; template class ConfigImpl<dusk::MenuScaling>;
template class ConfigImpl<dusk::Resampler>; template class ConfigImpl<dusk::Resampler>;
template class ConfigImpl<dusk::MagicArmorMode>;
} }
void dusk::config::Register(ConfigVarBase& configVar) { void dusk::config::Register(ConfigVarBase& configVar) {
+2 -1
View File
@@ -34,6 +34,7 @@
#if defined(__APPLE__) #if defined(__APPLE__)
#include <mach-o/dyld.h> #include <mach-o/dyld.h>
#include <mach-o/loader.h> #include <mach-o/loader.h>
#include <TargetConditionals.h>
#else #else
#include <elf.h> #include <elf.h>
#include <link.h> #include <link.h>
@@ -929,7 +930,7 @@ void install() {
SymInitialize(GetCurrentProcess(), nullptr, TRUE); SymInitialize(GetCurrentProcess(), nullptr, TRUE);
#endif #endif
g_prevFilter = SetUnhandledExceptionFilter(&windowsHandler); g_prevFilter = SetUnhandledExceptionFilter(&windowsHandler);
#else #elif !defined(__APPLE__) || !TARGET_OS_TV
Dl_info moduleInfo; Dl_info moduleInfo;
if (dladdr(reinterpret_cast<void*>(&install), &moduleInfo) != 0) { if (dladdr(reinterpret_cast<void*>(&install), &moduleInfo) != 0) {
g_ctx.moduleBase = reinterpret_cast<uintptr_t>(moduleInfo.dli_fbase); g_ctx.moduleBase = reinterpret_cast<uintptr_t>(moduleInfo.dli_fbase);
+4 -103
View File
@@ -16,7 +16,6 @@
#include <vector> #include <vector>
#include <SDL3/SDL_filesystem.h> #include <SDL3/SDL_filesystem.h>
#include <SDL3/SDL_iostream.h>
#include <SDL3/SDL_misc.h> #include <SDL3/SDL_misc.h>
#include <SDL3/SDL_stdinc.h> #include <SDL3/SDL_stdinc.h>
@@ -28,8 +27,6 @@ namespace {
aurora::Module Log{"dusk::data"}; aurora::Module Log{"dusk::data"};
constexpr auto kLocationDescriptorName = "data_location.json"; 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 = { constexpr std::array<std::string_view, 4> kUserDataDirectories = {
"texture_replacements", "texture_replacements",
@@ -37,10 +34,11 @@ constexpr std::array<std::string_view, 4> kUserDataDirectories = {
"EUR", "EUR",
"JAP", "JAP",
}; };
constexpr std::array<std::string_view, 6> kUserDataFiles = { constexpr std::array<std::string_view, 7> kUserDataFiles = {
"achievements.json", "achievements.json",
"config.json", "config.json",
"controller_ports.dat", "controller_ports.dat",
"gamecontrollerdb.txt",
"imgui.ini", "imgui.ini",
"keyboard_bindings.dat", "keyboard_bindings.dat",
"states.json", "states.json",
@@ -111,7 +109,7 @@ std::filesystem::path get_pref_path() {
Log.fatal("Unable to get PrefPath: {}", SDL_GetError()); Log.fatal("Unable to get PrefPath: {}", SDL_GetError());
} }
std::filesystem::path result{reinterpret_cast<const char8_t*>(prefPath)}; std::filesystem::path result = path_from_utf8(prefPath);
SDL_free(prefPath); SDL_free(prefPath);
return result; return result;
} }
@@ -128,7 +126,7 @@ std::filesystem::path base_path_relative(const std::filesystem::path& path) {
if (!basePath) { if (!basePath) {
return path; return path;
} }
return std::filesystem::path{basePath} / path; return path_from_utf8(basePath) / path;
} }
std::filesystem::path default_data_path(const std::filesystem::path& prefPath) { std::filesystem::path default_data_path(const std::filesystem::path& prefPath) {
@@ -888,102 +886,6 @@ void ensure_data_directory(const std::filesystem::path& dataPath) {
} }
} }
SDL_IOStream* open_initial_pipeline_cache_source(std::string& sourcePathString) {
const auto basePath = base_path_relative(kInitialPipelineCacheName);
sourcePathString = io::fs_path_to_string(basePath);
auto* source = SDL_IOFromFile(sourcePathString.c_str(), "rb");
if (source != nullptr) {
return source;
}
sourcePathString = std::string{kInitialPipelineCacheName};
return SDL_IOFromFile(sourcePathString.c_str(), "rb");
}
void ensure_initial_pipeline_cache(const std::filesystem::path& configDir) {
if (configDir.empty()) {
return;
}
std::error_code ec;
std::filesystem::create_directories(configDir, ec);
if (ec) {
Log.warn("Failed to create config directory '{}' for pipeline cache: {}",
io::fs_path_to_string(configDir), ec.message());
return;
}
const auto pipelineCachePath = configDir / kPipelineCacheName;
if (std::filesystem::exists(pipelineCachePath, ec)) {
return;
}
std::string sourcePathString;
SDL_IOStream* source = open_initial_pipeline_cache_source(sourcePathString);
if (source == nullptr) {
Log.info("No bundled initial pipeline cache found");
return;
}
const auto pipelineCacheString = io::fs_path_to_string(pipelineCachePath);
SDL_IOStream* destination = SDL_IOFromFile(pipelineCacheString.c_str(), "wb");
if (destination == nullptr) {
Log.warn("Failed to open '{}' for seeded pipeline cache: {}", pipelineCacheString,
SDL_GetError());
SDL_CloseIO(source);
return;
}
bool copied = true;
std::array<char, 64 * 1024> buffer{};
while (true) {
const size_t bytesRead = SDL_ReadIO(source, buffer.data(), buffer.size());
if (bytesRead > 0) {
size_t bytesWritten = 0;
while (bytesWritten < bytesRead) {
const size_t written = SDL_WriteIO(
destination, buffer.data() + bytesWritten, bytesRead - bytesWritten);
if (written == 0) {
Log.warn("Failed to write seeded pipeline cache '{}': {}", pipelineCacheString,
SDL_GetError());
copied = false;
break;
}
bytesWritten += written;
}
}
if (!copied) {
break;
}
if (bytesRead < buffer.size()) {
if (SDL_GetIOStatus(source) == SDL_IO_STATUS_EOF) {
break;
}
Log.warn(
"Failed to read bundled pipeline cache '{}': {}", sourcePathString, SDL_GetError());
copied = false;
break;
}
}
if (!SDL_CloseIO(destination)) {
Log.warn(
"Failed to close seeded pipeline cache '{}': {}", pipelineCacheString, SDL_GetError());
copied = false;
}
SDL_CloseIO(source);
if (!copied) {
std::filesystem::remove(pipelineCachePath, ec);
return;
}
Log.info("Seeded pipeline cache from '{}'", sourcePathString);
}
} // namespace } // namespace
bool open_data_path() { bool open_data_path() {
@@ -1096,7 +998,6 @@ Paths initialize_data() {
migrate_data(prefPath, dataPath, descriptor ? &descriptor->descriptor : nullptr); migrate_data(prefPath, dataPath, descriptor ? &descriptor->descriptor : nullptr);
ensure_data_directory(dataPath); ensure_data_directory(dataPath);
ensure_data_directory(prefPath); ensure_data_directory(prefPath);
ensure_initial_pipeline_cache(prefPath);
return Paths{ return Paths{
.userPath = dataPath, .userPath = dataPath,
+2 -53
View File
@@ -2,8 +2,6 @@
#include "dusk/ui/ui.hpp" #include "dusk/ui/ui.hpp"
#include "d/actor/d_a_alink.h" #include "d/actor/d_a_alink.h"
#include <aurora/lib/window.hpp>
#include <SDL3/SDL_mouse.h>
#include <cmath> #include <cmath>
namespace dusk::gyro { namespace dusk::gyro {
@@ -16,14 +14,11 @@ constexpr float kGravityEmaAlpha = 0.1f;
constexpr float kMinGravityProjection = 0.2f; constexpr float kMinGravityProjection = 0.2f;
// Let roll contribute more strongly as the pad approaches an upright posture. // Let roll contribute more strongly as the pad approaches an upright posture.
constexpr float kRollAimBoostMax = 2.0f; constexpr float kRollAimBoostMax = 2.0f;
constexpr float kMousePixelToRad = 0.0025f;
bool s_sensor_enabled = false; bool s_sensor_enabled = false;
bool s_accel_enabled = false; bool s_accel_enabled = false;
bool s_was_aiming = false; bool s_was_aiming = false;
bool s_have_gravity_baseline = false; bool s_have_gravity_baseline = false;
bool s_mouse_enabled = false;
bool s_mouse_relative = false;
float s_smooth_gx = 0.0f; float s_smooth_gx = 0.0f;
float s_smooth_gy = 0.0f; float s_smooth_gy = 0.0f;
float s_smooth_gz = 0.0f; float s_smooth_gz = 0.0f;
@@ -43,7 +38,6 @@ void reset_filter_state() {
s_baseline_gravity_y = s_baseline_gravity_z = 0.0f; s_baseline_gravity_y = s_baseline_gravity_z = 0.0f;
s_was_aiming = false; s_was_aiming = false;
s_have_gravity_baseline = false; s_have_gravity_baseline = false;
s_mouse_enabled = false;
s_yaw_rad = s_pitch_rad = s_roll_rad = 0.0f; s_yaw_rad = s_pitch_rad = s_roll_rad = 0.0f;
s_rollgoal_ax = s_rollgoal_az = 0; s_rollgoal_ax = s_rollgoal_az = 0;
} }
@@ -72,7 +66,7 @@ bool get_sensor_keep_alive() { return s_sensor_keep_alive; }
void set_sensor_keep_alive(bool value) { s_sensor_keep_alive = value; } void set_sensor_keep_alive(bool value) { s_sensor_keep_alive = value; }
bool rollgoal_gyro_enabled() { bool rollgoal_gyro_enabled() {
return getSettings().game.enableGyroRollgoal && getSettings().game.gyroMode.getValue() != GyroMode::Mouse; return getSettings().game.enableGyroRollgoal;
} }
bool queryGyroAimContext() { bool queryGyroAimContext() {
@@ -85,7 +79,7 @@ bool queryGyroAimContext() {
return false; return false;
} }
return link->checkGyroAimContext() && dComIfGp_checkCameraAttentionStatus(link->field_0x317c, 0x10); return link->checkAimContext() && dComIfGp_checkCameraAttentionStatus(link->field_0x317c, 0x10);
} }
void read(float dt) { void read(float dt) {
@@ -94,26 +88,6 @@ void read(float dt) {
const bool aim_just_ended = !aim_active && s_was_aiming; const bool aim_just_ended = !aim_active && s_was_aiming;
s_was_aiming = aim_active; s_was_aiming = aim_active;
const bool mouse_mode = getSettings().game.gyroMode.getValue() == GyroMode::Mouse;
const bool mouse_gyro_active = !ui::any_document_visible() && mouse_mode && (aim_active || s_sensor_keep_alive);
SDL_Window* window = aurora::window::get_sdl_window();
if (window != nullptr && mouse_gyro_active != s_mouse_relative &&
SDL_SetWindowRelativeMouseMode(window, mouse_gyro_active))
{
s_mouse_relative = mouse_gyro_active;
}
if (mouse_gyro_active && !s_mouse_enabled && window != nullptr) {
const AuroraWindowSize sz = aurora::window::get_window_size();
const float cx = static_cast<float>(sz.width) * 0.5f;
const float cy = static_cast<float>(sz.height) * 0.5f;
SDL_WarpMouseInWindow(window, cx, cy);
float discard_x = 0.0f;
float discard_y = 0.0f;
SDL_GetRelativeMouseState(&discard_x, &discard_y);
}
s_mouse_enabled = mouse_gyro_active;
if (!s_sensor_keep_alive && !aim_active) { if (!s_sensor_keep_alive && !aim_active) {
disable_pad_sensors(); disable_pad_sensors();
reset_filter_state(); reset_filter_state();
@@ -126,31 +100,6 @@ void read(float dt) {
s_have_gravity_baseline = false; s_have_gravity_baseline = false;
} }
if (mouse_mode && !mouse_gyro_active) {
s_pitch_rad = 0.0f;
s_yaw_rad = 0.0f;
s_roll_rad = 0.0f;
return;
}
if (mouse_mode) {
disable_pad_sensors();
float mx_rel = 0.0f;
float my_rel = 0.0f;
SDL_GetRelativeMouseState(&mx_rel, &my_rel);
// Convert pixels to radians
s_pitch_rad = my_rel * kMousePixelToRad * getSettings().game.gyroSensitivityY;
s_yaw_rad = -mx_rel * kMousePixelToRad * getSettings().game.gyroSensitivityX;
s_roll_rad = 0.0f;
s_pitch_rad = getSettings().game.gyroInvertPitch ? -s_pitch_rad : s_pitch_rad;
s_yaw_rad = getSettings().game.gyroInvertYaw ? -s_yaw_rad : s_yaw_rad;
s_yaw_rad = getSettings().game.enableMirrorMode ? -s_yaw_rad : s_yaw_rad;
return;
}
if (!s_sensor_enabled) { if (!s_sensor_enabled) {
if (!PADHasSensor(PAD_CHAN0, PAD_SENSOR_GYRO)) { if (!PADHasSensor(PAD_CHAN0, PAD_SENSOR_GYRO)) {
return; return;
+5 -3
View File
@@ -49,7 +49,9 @@ namespace dusk {
dCam->Reset(center, eye); dCam->Reset(center, eye);
} }
ImGui::InputFloat("Camera FOV", &dCam->mFovy); if (ImGui::InputFloat("Camera FOV", &dCam->mFovy)) {
dCam->mFovy = std::clamp(dCam->mFovy, 0.1f, 179.9f);
}
ImGui::SeparatorText("Options"); ImGui::SeparatorText("Options");
@@ -75,12 +77,12 @@ namespace dusk {
if (!getSettings().game.debugFlyCam) { if (!getSettings().game.debugFlyCam) {
ImGui::BeginDisabled(); ImGui::BeginDisabled();
} }
config::ImGuiCheckbox("Lock Events", getSettings().game.debugFlyCamLockEvents); config::ImGuiCheckbox("Freeze Time", getSettings().game.debugFlyCamLockEvents);
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) { if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
if (!getSettings().game.debugFlyCam) { if (!getSettings().game.debugFlyCam) {
ImGui::SetTooltip("Enable Fly Mode first."); ImGui::SetTooltip("Enable Fly Mode first.");
} else { } else {
ImGui::SetTooltip("Freeze game events while flying."); ImGui::SetTooltip("Freezes the game while flying.");
} }
} }
if (!getSettings().game.debugFlyCam) { if (!getSettings().game.debugFlyCam) {
-65
View File
@@ -12,7 +12,6 @@
#include "ImGuiConsole.hpp" #include "ImGuiConsole.hpp"
#include "ImGuiEngine.hpp" #include "ImGuiEngine.hpp"
#include "JSystem/JUtility/JUTGamePad.h" #include "JSystem/JUtility/JUTGamePad.h"
#include "SDL3/SDL_mouse.h"
#include "dusk/action_bindings.h" #include "dusk/action_bindings.h"
#include "dusk/audio/DuskAudioSystem.h" #include "dusk/audio/DuskAudioSystem.h"
#include "dusk/config.hpp" #include "dusk/config.hpp"
@@ -61,10 +60,6 @@ namespace dusk {
ImGui::TextUnformatted(text.data(), text.data() + text.size()); ImGui::TextUnformatted(text.data(), text.data() + text.size());
} }
void DuskToast(std::string_view message, float duration) {
g_imguiConsole.AddToast(message, duration);
}
void ImGuiTextCenter(std::string_view text) { void ImGuiTextCenter(std::string_view text) {
ImGui::NewLine(); ImGui::NewLine();
float fontSize = ImGui::CalcTextSize( float fontSize = ImGui::CalcTextSize(
@@ -376,22 +371,6 @@ namespace dusk {
m_menuTools.ShowActorSpawner(); m_menuTools.ShowActorSpawner();
} }
// Hide mouse cursor if the F1 menu is not open and the cursor is idle for 3 seconds.
if (dusk::getSettings().game.gyroMode.getValue() != GyroMode::Mouse)
{
ImGuiIO& io = ImGui::GetIO();
if (io.MouseDelta.x != 0.0f || io.MouseDelta.y != 0.0f) {
mouseHideTimer = 0.0f;
ImGui::GetIO().ConfigFlags &= ~ImGuiConfigFlags_NoMouseCursorChange; // Imgui will re-show cursor.
} else if (mouseHideTimer <= 3.0f) {
mouseHideTimer += ImGui::GetIO().DeltaTime;
} else {
ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange;
SDL_HideCursor();
}
}
ShowToasts();
} }
void ImGuiConsole::PostDraw() { void ImGuiConsole::PostDraw() {
@@ -545,50 +524,6 @@ namespace dusk {
return false; return false;
} }
void ImGuiConsole::AddToast(std::string_view message, float duration) {
m_toasts.emplace_back(std::string(message), duration);
}
void ImGuiConsole::ShowToasts() {
if (m_toasts.empty()) {
return;
}
auto& toast = m_toasts.front();
const float dt = ImGui::GetIO().DeltaTime;
toast.remain -= dt;
toast.current += dt;
const ImGuiViewport* viewport = ImGui::GetMainViewport();
const ImVec2 workPos = viewport->WorkPos;
const ImVec2 workSize = viewport->WorkSize;
constexpr float padding = 10.0f;
const ImVec2 windowPos{workPos.x + workSize.x / 2, workPos.y + workSize.y - padding};
ImGui::SetNextWindowPos(windowPos, ImGuiCond_Always, ImVec2{0.5f, 1.f});
const float alpha = std::min({toast.remain, toast.current, 1.f});
ImGui::SetNextWindowBgAlpha(alpha * 0.65f);
ImVec4 textColor = ImGui::GetStyleColorVec4(ImGuiCol_Text);
textColor.w *= alpha;
ImVec4 borderColor = ImGui::GetStyleColorVec4(ImGuiCol_Border);
borderColor.w *= alpha;
ImGui::PushStyleColor(ImGuiCol_Text, textColor);
ImGui::PushStyleColor(ImGuiCol_Border, borderColor);
if (ImGui::Begin("Toast", nullptr,
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_AlwaysAutoResize |
ImGuiWindowFlags_NoSavedSettings |
ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav |
ImGuiWindowFlags_NoMove))
{
ImGuiStringViewText(toast.message);
}
ImGui::End();
ImGui::PopStyleColor(2);
if (toast.remain <= 0.f) {
m_toasts.pop_front();
}
}
void ImGuiConsole::ShowPipelineProgress() { void ImGuiConsole::ShowPipelineProgress() {
const auto* stats = aurora_get_stats(); const auto* stats = aurora_get_stats();
const u32 queuedPipelines = stats->queuedPipelines; const u32 queuedPipelines = stats->queuedPipelines;
-13
View File
@@ -24,29 +24,17 @@ public:
void PostDraw(); void PostDraw();
static bool CheckMenuViewToggle(ImGuiKey key, bool& active); static bool CheckMenuViewToggle(ImGuiKey key, bool& active);
void AddToast(std::string_view message, float duration = 3.f);
private: private:
struct Toast {
std::string message;
float remain;
float current = 0.f;
Toast(std::string message, float duration) noexcept : message(std::move(message)),
remain(duration) {}
};
float mouseHideTimer = 0.0f;
bool m_isHidden = true; bool m_isHidden = true;
bool m_isLaunchInitialized = false; bool m_isLaunchInitialized = false;
ImGuiWindow* m_dragScrollWindow = nullptr; ImGuiWindow* m_dragScrollWindow = nullptr;
ImVec2 m_dragScrollLastMousePos = {}; ImVec2 m_dragScrollLastMousePos = {};
std::deque<Toast> m_toasts;
// Keep always last // Keep always last
ImGuiMenuTools m_menuTools; ImGuiMenuTools m_menuTools;
void ShowToasts();
void ShowPipelineProgress(); void ShowPipelineProgress();
void UpdateDragScroll(); void UpdateDragScroll();
}; };
@@ -60,7 +48,6 @@ std::string BytesToString(size_t bytes);
void SetOverlayWindowLocation(int corner); void SetOverlayWindowLocation(int corner);
bool ShowCornerContextMenu(int& corner, int avoidCorner); bool ShowCornerContextMenu(int& corner, int avoidCorner);
void ImGuiStringViewText(std::string_view text); void ImGuiStringViewText(std::string_view text);
void DuskToast(std::string_view message, float duration = 3.f);
void ImGuiBeginGroupPanel(const char* name, const ImVec2& size); void ImGuiBeginGroupPanel(const char* name, const ImVec2& size);
void ImGuiEndGroupPanel(); void ImGuiEndGroupPanel();
void ImGuiTextCenter(std::string_view text); void ImGuiTextCenter(std::string_view text);
+4
View File
@@ -20,7 +20,11 @@
namespace dusk { namespace dusk {
namespace { namespace {
std::string GetAssetPath(const char* assetName) { std::string GetAssetPath(const char* assetName) {
#ifdef DUSK_ASSET_DIR
const char* basePath = DUSK_ASSET_DIR;
#else
const char* basePath = SDL_GetBasePath(); const char* basePath = SDL_GetBasePath();
#endif
if (basePath != nullptr && basePath[0] != '\0') { if (basePath != nullptr && basePath[0] != '\0') {
return std::string(basePath) + "res/" + assetName; return std::string(basePath) + "res/" + assetName;
} }
+211
View File
@@ -0,0 +1,211 @@
#include "dusk/mouse.h"
#include "dusk/settings.h"
#include "dusk/ui/ui.hpp"
#include "d/actor/d_a_alink.h"
#include "d/d_com_inf_game.h"
#include <aurora/lib/window.hpp>
#include <imgui.h>
#include <SDL3/SDL_mouse.h>
#include <SDL3/SDL_video.h>
namespace dusk::mouse {
namespace {
constexpr float kMousePixelToRad = 0.0025f;
constexpr int kIdleHideFrames = 99; // Approx. 3 seconds with 33ms ticks
float s_aim_yaw_rad = 0.0f;
float s_aim_pitch_rad = 0.0f;
float s_camera_yaw_rad = 0.0f;
float s_camera_pitch_rad = 0.0f;
int s_idle_frames = 0;
void reset_deltas() {
s_aim_yaw_rad = s_aim_pitch_rad = 0.0f;
s_camera_yaw_rad = s_camera_pitch_rad = 0.0f;
}
bool queryMouseAimContext() {
if (!getSettings().game.enableMouseAim) {
return false;
}
daAlink_c* link = daAlink_getAlinkActorClass();
if (link == nullptr) {
return false;
}
return link->checkAimContext() && dComIfGp_checkCameraAttentionStatus(link->field_0x317c, 0x10);
}
bool wantMouseCapture() {
return getSettings().game.enableMouseCamera.getValue() || queryMouseAimContext();
}
bool isWindowFocused(SDL_Window* window) {
if (window == nullptr) {
return false;
}
return (SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS) != 0;
}
bool shouldCaptureMouse(SDL_Window* window) {
if (window == nullptr || ui::any_document_visible()) {
return false;
}
return wantMouseCapture() && isWindowFocused(window);
}
bool syncCaptureState(SDL_Window* window, bool should_capture) {
if (window == nullptr) {
reset_deltas();
return false;
}
const bool was_captured = SDL_GetWindowRelativeMouseMode(window);
if (was_captured != should_capture) {
SDL_SetWindowMouseGrab(window, should_capture);
SDL_SetWindowRelativeMouseMode(window, should_capture);
}
const bool is_captured = SDL_GetWindowRelativeMouseMode(window);
if (is_captured && !was_captured) {
const AuroraWindowSize sz = aurora::window::get_window_size();
const float cx = static_cast<float>(sz.width) * 0.5f;
const float cy = static_cast<float>(sz.height) * 0.5f;
SDL_WarpMouseInWindow(window, cx, cy);
float discard_x = 0.0f;
float discard_y = 0.0f;
SDL_GetRelativeMouseState(&discard_x, &discard_y);
}
if (!is_captured) {
reset_deltas();
}
return is_captured;
}
void accumulateDeltas(float mx_rel, float my_rel, bool camera_active, bool aim_active) {
const auto& game = getSettings().game;
const bool mirror_mode = game.enableMirrorMode.getValue();
const bool invert_y = game.invertMouseY.getValue();
if (aim_active) {
const float aimSens = game.mouseAimSensitivity.getValue();
s_aim_yaw_rad = -mx_rel * kMousePixelToRad * aimSens;
s_aim_pitch_rad = my_rel * kMousePixelToRad * aimSens;
s_aim_yaw_rad = mirror_mode ? -s_aim_yaw_rad : s_aim_yaw_rad;
s_aim_pitch_rad = invert_y ? -s_aim_pitch_rad : s_aim_pitch_rad;
} else {
s_aim_yaw_rad = s_aim_pitch_rad = 0.0f;
}
if (camera_active) {
const float camSens = game.mouseCameraSensitivity.getValue();
s_camera_yaw_rad = -mx_rel * kMousePixelToRad * camSens;
s_camera_pitch_rad = -my_rel * kMousePixelToRad * camSens;
s_camera_yaw_rad = mirror_mode ? -s_camera_yaw_rad : s_camera_yaw_rad;
s_camera_pitch_rad = invert_y ? -s_camera_pitch_rad : s_camera_pitch_rad;
} else {
s_camera_yaw_rad = s_camera_pitch_rad = 0.0f;
}
}
void set_cursor_visible(bool visible) {
if (visible) {
ImGui::GetIO().ConfigFlags &= ~ImGuiConfigFlags_NoMouseCursorChange;
SDL_ShowCursor();
} else {
ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange;
SDL_HideCursor();
}
}
void update_cursor_visibility(SDL_Window* window, bool captured) {
if (window == nullptr || !isWindowFocused(window)) {
return;
}
if (captured) {
s_idle_frames = 0;
set_cursor_visible(false);
return;
}
const ImGuiIO& io = ImGui::GetIO();
if (io.MouseDelta.x != 0.0f || io.MouseDelta.y != 0.0f) {
s_idle_frames = 0;
set_cursor_visible(true);
return;
}
if (s_idle_frames < kIdleHideFrames) {
++s_idle_frames;
set_cursor_visible(true);
} else {
set_cursor_visible(false);
}
}
} // namespace
void read() {
SDL_Window* window = aurora::window::get_sdl_window();
const bool capture_active = syncCaptureState(window, shouldCaptureMouse(window));
update_cursor_visibility(window, capture_active);
if (!capture_active) {
return;
}
const bool aim_active = capture_active && queryMouseAimContext();
const bool camera_active = capture_active && getSettings().game.enableMouseCamera;
float mx_rel = 0.0f;
float my_rel = 0.0f;
SDL_GetRelativeMouseState(&mx_rel, &my_rel);
accumulateDeltas(mx_rel, my_rel, camera_active, aim_active);
}
void getAimDeltas(float& out_yaw, float& out_pitch) {
out_yaw = s_aim_yaw_rad;
out_pitch = s_aim_pitch_rad;
}
void getCameraDeltas(float& out_yaw, float& out_pitch) {
out_yaw = 0.0f;
out_pitch = 0.0f;
if (!getSettings().game.enableMouseCamera) {
return;
}
out_yaw = s_camera_yaw_rad;
out_pitch = s_camera_pitch_rad;
}
void handle_event(const SDL_Event& event) noexcept {
switch (event.type) {
case SDL_EVENT_WINDOW_FOCUS_LOST:
onFocusLost();
break;
case SDL_EVENT_WINDOW_FOCUS_GAINED:
onFocusGained();
break;
}
}
void onFocusLost() {
SDL_Window* window = aurora::window::get_sdl_window();
if (window != nullptr) {
syncCaptureState(window, false);
}
s_idle_frames = 0;
set_cursor_visible(true);
}
void onFocusGained() {
SDL_Window* window = aurora::window::get_sdl_window();
syncCaptureState(window, shouldCaptureMouse(window));
}
} // namespace dusk::mouse
+16 -6
View File
@@ -41,6 +41,7 @@ UserSettings g_userSettings = {
.noMissClimbing {"game.noMissClimbing", false}, .noMissClimbing {"game.noMissClimbing", false},
.fastTears {"game.fastTears", false}, .fastTears {"game.fastTears", false},
.no2ndFishForCat {"game.no2ndFishForCat", false}, .no2ndFishForCat {"game.no2ndFishForCat", false},
.buttonFishing {"game.buttonFishing", false},
.instantSaves {"game.instantSaves", false}, .instantSaves {"game.instantSaves", false},
.instantText {"game.instantText", false}, .instantText {"game.instantText", false},
.sunsSong {"game.sunsSong", false}, .sunsSong {"game.sunsSong", false},
@@ -50,6 +51,7 @@ UserSettings g_userSettings = {
// Preferences // Preferences
.enableMirrorMode {"game.enableMirrorMode", false}, .enableMirrorMode {"game.enableMirrorMode", false},
.minimalHUD {"game.minimalHUD", false}, .minimalHUD {"game.minimalHUD", false},
.hudScale {"game.hudScale", 1.0f},
.pauseOnFocusLost {"game.pauseOnFocusLost", false}, .pauseOnFocusLost {"game.pauseOnFocusLost", false},
.enableLinkDollRotation {"game.enableLinkDollRotation", false}, .enableLinkDollRotation {"game.enableLinkDollRotation", false},
.enableAchievementToasts {"game.enableAchievementToasts", true}, .enableAchievementToasts {"game.enableAchievementToasts", true},
@@ -75,7 +77,6 @@ UserSettings g_userSettings = {
.midnasLamentNonStop {"game.midnasLamentNonStop", false}, .midnasLamentNonStop {"game.midnasLamentNonStop", false},
// Input // Input
.gyroMode {"game.gyroMode", GyroMode::Sensor},
.enableGyroAim {"game.enableGyroAim", false}, .enableGyroAim {"game.enableGyroAim", false},
.enableGyroRollgoal {"game.enableGyroRollgoal", false}, .enableGyroRollgoal {"game.enableGyroRollgoal", false},
.gyroSensitivityX {"game.gyroSensitivityX", 1.0f}, .gyroSensitivityX {"game.gyroSensitivityX", 1.0f},
@@ -85,6 +86,11 @@ UserSettings g_userSettings = {
.gyroDeadband {"game.gyroDeadband", 0.04f}, .gyroDeadband {"game.gyroDeadband", 0.04f},
.gyroInvertPitch {"game.gyroInvertPitch", false}, .gyroInvertPitch {"game.gyroInvertPitch", false},
.gyroInvertYaw {"game.gyroInvertYaw", false}, .gyroInvertYaw {"game.gyroInvertYaw", false},
.enableMouseCamera {"game.enableMouseCamera", false},
.enableMouseAim {"game.enableMouseAim", false},
.mouseAimSensitivity {"game.mouseAimSensitivity", 1.0f},
.mouseCameraSensitivity {"game.mouseCameraSensitivity", 1.0f},
.invertMouseY {"game.invertMouseY", false},
.freeCamera {"game.freeCamera", false}, .freeCamera {"game.freeCamera", false},
.invertCameraXAxis {"game.invertCameraXAxis", false}, .invertCameraXAxis {"game.invertCameraXAxis", false},
.invertCameraYAxis {"game.invertCameraYAxis", false}, .invertCameraYAxis {"game.invertCameraYAxis", false},
@@ -121,9 +127,8 @@ UserSettings g_userSettings = {
.canTransformAnywhere {"game.canTransformAnywhere", false}, .canTransformAnywhere {"game.canTransformAnywhere", false},
.fastRoll {"game.fastRoll", false}, .fastRoll {"game.fastRoll", false},
.fastSpinner {"game.fastSpinner", false}, .fastSpinner {"game.fastSpinner", false},
.freeMagicArmor {"game.freeMagicArmor", false}, .armorRupeeDrain {"game.armorRupeeDrain", MagicArmorMode::NORMAL},
.invincibleEnemies {"game.invincibleEnemies", false}, .invincibleEnemies {"game.invincibleEnemies", false},
.transformWithoutShadowCrystal {"game.transformWithoutShadowCrystal", false},
// Technical // Technical
.restoreWiiGlitches {"game.restoreWiiGlitches", false}, .restoreWiiGlitches {"game.restoreWiiGlitches", false},
@@ -209,7 +214,6 @@ void registerSettings() {
// Game // Game
Register(g_userSettings.game.language); Register(g_userSettings.game.language);
Register(g_userSettings.game.enableQuickTransform); Register(g_userSettings.game.enableQuickTransform);
Register(g_userSettings.game.transformWithoutShadowCrystal);
Register(g_userSettings.game.hideTvSettingsScreen); Register(g_userSettings.game.hideTvSettingsScreen);
Register(g_userSettings.game.biggerWallets); Register(g_userSettings.game.biggerWallets);
Register(g_userSettings.game.noReturnRupees); Register(g_userSettings.game.noReturnRupees);
@@ -221,6 +225,7 @@ void registerSettings() {
Register(g_userSettings.game.fastClimbing); Register(g_userSettings.game.fastClimbing);
Register(g_userSettings.game.fastTears); Register(g_userSettings.game.fastTears);
Register(g_userSettings.game.no2ndFishForCat); Register(g_userSettings.game.no2ndFishForCat);
Register(g_userSettings.game.buttonFishing);
Register(g_userSettings.game.instantSaves); Register(g_userSettings.game.instantSaves);
Register(g_userSettings.game.instantText); Register(g_userSettings.game.instantText);
Register(g_userSettings.game.sunsSong); Register(g_userSettings.game.sunsSong);
@@ -236,6 +241,7 @@ void registerSettings() {
Register(g_userSettings.game.freeCameraXSensitivity); Register(g_userSettings.game.freeCameraXSensitivity);
Register(g_userSettings.game.freeCameraYSensitivity); Register(g_userSettings.game.freeCameraYSensitivity);
Register(g_userSettings.game.minimalHUD); Register(g_userSettings.game.minimalHUD);
Register(g_userSettings.game.hudScale);
Register(g_userSettings.game.pauseOnFocusLost); Register(g_userSettings.game.pauseOnFocusLost);
Register(g_userSettings.game.enableDiscordPresence); Register(g_userSettings.game.enableDiscordPresence);
Register(g_userSettings.game.bloomMode); Register(g_userSettings.game.bloomMode);
@@ -251,7 +257,7 @@ void registerSettings() {
Register(g_userSettings.game.enableFastIronBoots); Register(g_userSettings.game.enableFastIronBoots);
Register(g_userSettings.game.canTransformAnywhere); Register(g_userSettings.game.canTransformAnywhere);
Register(g_userSettings.game.fastRoll); Register(g_userSettings.game.fastRoll);
Register(g_userSettings.game.freeMagicArmor); Register(g_userSettings.game.armorRupeeDrain);
Register(g_userSettings.game.restoreWiiGlitches); Register(g_userSettings.game.restoreWiiGlitches);
Register(g_userSettings.game.enableLinkDollRotation); Register(g_userSettings.game.enableLinkDollRotation);
Register(g_userSettings.game.enableAchievementToasts); Register(g_userSettings.game.enableAchievementToasts);
@@ -283,7 +289,6 @@ void registerSettings() {
Register(g_userSettings.game.alwaysGreatspin); Register(g_userSettings.game.alwaysGreatspin);
Register(g_userSettings.game.invincibleEnemies); Register(g_userSettings.game.invincibleEnemies);
Register(g_userSettings.game.enableFrameInterpolation); Register(g_userSettings.game.enableFrameInterpolation);
Register(g_userSettings.game.gyroMode);
Register(g_userSettings.game.enableGyroAim); Register(g_userSettings.game.enableGyroAim);
Register(g_userSettings.game.enableGyroRollgoal); Register(g_userSettings.game.enableGyroRollgoal);
Register(g_userSettings.game.gyroSensitivityX); Register(g_userSettings.game.gyroSensitivityX);
@@ -293,6 +298,11 @@ void registerSettings() {
Register(g_userSettings.game.gyroSmoothing); Register(g_userSettings.game.gyroSmoothing);
Register(g_userSettings.game.gyroInvertPitch); Register(g_userSettings.game.gyroInvertPitch);
Register(g_userSettings.game.gyroInvertYaw); Register(g_userSettings.game.gyroInvertYaw);
Register(g_userSettings.game.enableMouseCamera);
Register(g_userSettings.game.enableMouseAim);
Register(g_userSettings.game.mouseAimSensitivity);
Register(g_userSettings.game.mouseCameraSensitivity);
Register(g_userSettings.game.invertMouseY);
Register(g_userSettings.game.freeCamera); Register(g_userSettings.game.freeCamera);
Register(g_userSettings.game.debugFlyCam); Register(g_userSettings.game.debugFlyCam);
Register(g_userSettings.game.debugFlyCamLockEvents); Register(g_userSettings.game.debugFlyCamLockEvents);
+1 -1
View File
@@ -33,7 +33,7 @@ void resetForSpeedrunMode() {
getSettings().game.canTransformAnywhere.setSpeedrunValue(false); getSettings().game.canTransformAnywhere.setSpeedrunValue(false);
getSettings().game.fastRoll.setSpeedrunValue(false); getSettings().game.fastRoll.setSpeedrunValue(false);
getSettings().game.fastSpinner.setSpeedrunValue(false); getSettings().game.fastSpinner.setSpeedrunValue(false);
getSettings().game.freeMagicArmor.setSpeedrunValue(false); getSettings().game.armorRupeeDrain.setSpeedrunValue(MagicArmorMode::NORMAL);
getSettings().game.pauseOnFocusLost.setSpeedrunValue(false); getSettings().game.pauseOnFocusLost.setSpeedrunValue(false);
aurora_set_pause_on_focus_lost(false); aurora_set_pause_on_focus_lost(false);
+38
View File
@@ -0,0 +1,38 @@
#include "dusk/texture_replacements.hpp"
#include <aurora/texture.hpp>
#include "dusk/logging.h"
#include "dusk/main.h"
#include "dusk/settings.h"
namespace dusk::texture_replacements {
namespace {
aurora::texture::ReplacementGroup s_directoryGroup;
}
void reload() {
aurora::texture::unregister_replacements(s_directoryGroup);
s_directoryGroup.registrations.clear();
if (!getSettings().game.enableTextureReplacements) {
return;
}
const auto root = ConfigPath / "texture_replacements";
s_directoryGroup = aurora::texture::load_replacement_directory(root);
DuskLog.info("Texture replacement directory loaded: {} registration(s)",
s_directoryGroup.registrations.size());
}
void set_enabled(bool enabled) {
getSettings().game.enableTextureReplacements.setValue(enabled);
reload();
}
void shutdown() {
aurora::texture::unregister_replacements(s_directoryGroup);
s_directoryGroup.registrations.clear();
}
}
+1 -1
View File
@@ -217,7 +217,7 @@ void AchievementsWindow::updateTotal() {
return; return;
} }
const auto all = AchievementSystem::get().getAchievements(); const auto all = AchievementSystem::get().getAchievements();
int total = static_cast<int>(all.size()); const int total = std::count_if(all.begin(), all.end(), [](const Achievement& achievement){ return achievement.category != AchievementCategory::Glitched;});
int unlocked = 0; int unlocked = 0;
for (const auto& a : all) { for (const auto& a : all) {
if (a.unlocked) { if (a.unlocked) {
-15
View File
@@ -5,7 +5,6 @@
#include "Z2AudioLib/Z2SeMgr.h" #include "Z2AudioLib/Z2SeMgr.h"
#include "m_Do/m_Do_audio.h" #include "m_Do/m_Do_audio.h"
#include <imgui.h>
namespace dusk::ui { namespace dusk::ui {
namespace { namespace {
@@ -107,7 +106,6 @@ bool Document::visible() const {
bool Document::handle_nav_command(Rml::Event& event, NavCommand cmd) { bool Document::handle_nav_command(Rml::Event& event, NavCommand cmd) {
if (cmd == NavCommand::Menu) { if (cmd == NavCommand::Menu) {
toggle_cursor_if_gyro(!visible());
mDoAud_seStartMenu(visible() ? kSoundMenuClose : kSoundMenuOpen); mDoAud_seStartMenu(visible() ? kSoundMenuClose : kSoundMenuOpen);
toggle(); toggle();
return true; return true;
@@ -115,17 +113,4 @@ bool Document::handle_nav_command(Rml::Event& event, NavCommand cmd) {
return false; return false;
} }
void Document::toggle_cursor_if_gyro(bool cursor_enabled) {
if (dusk::getSettings().game.gyroMode.getValue() == GyroMode::Mouse)
{
if (cursor_enabled) {
ImGui::GetIO().ConfigFlags &= ~ImGuiConfigFlags_NoMouseCursorChange;
SDL_ShowCursor();
} else {
ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange;
SDL_HideCursor();
}
}
}
} // namespace dusk::ui } // namespace dusk::ui
-2
View File
@@ -43,8 +43,6 @@ public:
bool pending_close() const { return mPendingClose; } bool pending_close() const { return mPendingClose; }
bool closed() const { return mClosed; } bool closed() const { return mClosed; }
void toggle_cursor_if_gyro(bool);
protected: protected:
virtual bool handle_nav_command(Rml::Event& event, NavCommand cmd); virtual bool handle_nav_command(Rml::Event& event, NavCommand cmd);
+2 -2
View File
@@ -11,6 +11,7 @@
#include "dusk/config.hpp" #include "dusk/config.hpp"
#include "dusk/settings.h" #include "dusk/settings.h"
#include "dusk/texture_replacements.hpp"
#include <algorithm> #include <algorithm>
#include <string> #include <string>
@@ -98,8 +99,7 @@ void set_value(GraphicsOption option, int value) {
getSettings().game.bloomMultiplier.setValue(std::clamp(value, 0, 100) / 100.0f); getSettings().game.bloomMultiplier.setValue(std::clamp(value, 0, 100) / 100.0f);
break; break;
case GraphicsOption::TextureReplacements: case GraphicsOption::TextureReplacements:
getSettings().game.enableTextureReplacements.setValue(static_cast<bool>(value)); texture_replacements::set_enabled(static_cast<bool>(value));
aurora_set_texture_replacements_enabled(static_cast<bool>(value));
break; break;
} }
} }
-2
View File
@@ -45,7 +45,6 @@ MenuBar::MenuBar() : Document(kDocumentSource), mRoot(mDocument->GetElementById(
mTabBar = std::make_unique<TabBar>(mRoot, TabBar::Props{ mTabBar = std::make_unique<TabBar>(mRoot, TabBar::Props{
.onClose = .onClose =
[this] { [this] {
toggle_cursor_if_gyro(false);
mDoAud_seStartMenu(kSoundMenuClose); mDoAud_seStartMenu(kSoundMenuClose);
hide(false); hide(false);
}, },
@@ -219,7 +218,6 @@ bool MenuBar::handle_nav_command(Rml::Event& event, NavCommand cmd) {
return true; return true;
} }
if (cmd == NavCommand::Cancel && visible()) { if (cmd == NavCommand::Cancel && visible()) {
toggle_cursor_if_gyro(false);
mDoAud_seStartMenu(kSoundMenuClose); mDoAud_seStartMenu(kSoundMenuClose);
hide(false); hide(false);
return true; return true;
-2
View File
@@ -699,8 +699,6 @@ Prelaunch::Prelaunch() : Document(kDocumentSource), mRoot(mDocument->GetElementB
return; return;
} }
toggle_cursor_if_gyro(false);
mDoAud_seStartMenu(kSoundPlay); mDoAud_seStartMenu(kSoundPlay);
show_menu_notification(); show_menu_notification();
+1
View File
@@ -37,6 +37,7 @@ void applyPresetDusk() {
s.game.invertCameraXAxis.setValue(true); s.game.invertCameraXAxis.setValue(true);
s.game.invertFirstPersonYAxis.setValue(true); s.game.invertFirstPersonYAxis.setValue(true);
s.game.no2ndFishForCat.setValue(true); s.game.no2ndFishForCat.setValue(true);
s.game.buttonFishing.setValue(true);
s.game.enableAchievementToasts.setValue(true); s.game.enableAchievementToasts.setValue(true);
s.game.enableControllerToasts.setValue(true); s.game.enableControllerToasts.setValue(true);
s.game.enableQuickTransform.setValue(true); s.game.enableQuickTransform.setValue(true);
+87 -69
View File
@@ -75,6 +75,14 @@ constexpr std::array kMenuScalingModeLabels = {
"Dusklight", "Dusklight",
}; };
constexpr std::array kMagicArmorModes = {
"Normal",
"On Damage",
"Double Defense",
"Invincible",
"Cosmetic",
};
bool try_parse_backend(std::string_view backend, AuroraBackend& outBackend) { bool try_parse_backend(std::string_view backend, AuroraBackend& outBackend) {
if (backend == "auto") { if (backend == "auto") {
outBackend = BACKEND_AUTO; outBackend = BACKEND_AUTO;
@@ -211,7 +219,7 @@ void reset_for_speedrun_mode() {
getSettings().game.canTransformAnywhere.setSpeedrunValue(false); getSettings().game.canTransformAnywhere.setSpeedrunValue(false);
getSettings().game.fastRoll.setSpeedrunValue(false); getSettings().game.fastRoll.setSpeedrunValue(false);
getSettings().game.fastSpinner.setSpeedrunValue(false); getSettings().game.fastSpinner.setSpeedrunValue(false);
getSettings().game.freeMagicArmor.setSpeedrunValue(false); getSettings().game.armorRupeeDrain.setSpeedrunValue(MagicArmorMode::NORMAL);
getSettings().game.invincibleEnemies.setSpeedrunValue(false); getSettings().game.invincibleEnemies.setSpeedrunValue(false);
getSettings().game.pauseOnFocusLost.setSpeedrunValue(false); getSettings().game.pauseOnFocusLost.setSpeedrunValue(false);
@@ -383,9 +391,7 @@ int float_setting_percent(ConfigVar<float>& var) {
} }
bool gyro_enabled() { bool gyro_enabled() {
return getSettings().game.enableGyroAim || return getSettings().game.enableGyroAim || getSettings().game.enableGyroRollgoal;
(getSettings().game.enableGyroRollgoal &&
getSettings().game.gyroMode.getValue() != GyroMode::Mouse);
} }
struct ConfigBoolProps { struct ConfigBoolProps {
@@ -453,7 +459,7 @@ SelectButton& config_percent_select(Pane& leftPane, Pane& rightPane, ConfigVar<f
}); });
leftPane.register_control(button, rightPane, [helpText = std::move(helpText)](Pane& pane) { leftPane.register_control(button, rightPane, [helpText = std::move(helpText)](Pane& pane) {
pane.clear(); pane.clear();
pane.add_text(helpText); pane.add_rml(helpText);
}); });
return button; return button;
} }
@@ -949,73 +955,32 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
leftPane.add_section("Camera"); leftPane.add_section("Camera");
addOption("Free Camera", getSettings().game.freeCamera, addOption("Free Camera", getSettings().game.freeCamera,
"Enables twin-stick camera control, letting the C-Stick move the camera vertically as " "Enables free camera control, letting you control the camera fully with the C-Stick.");
"well as horizontally.");
addOption("Invert Camera X Axis", getSettings().game.invertCameraXAxis,
"Invert horizontal camera movement.");
addOption("Invert Camera Y Axis", getSettings().game.invertCameraYAxis,
"Invert vertical camera movement when Free Camera is enabled.",
[] { return !getSettings().game.freeCamera; });
config_percent_select(leftPane, rightPane, getSettings().game.freeCameraXSensitivity, config_percent_select(leftPane, rightPane, getSettings().game.freeCameraXSensitivity,
"Free Camera X Sensitivity", "Adjusts twin-stick camera X axis sensitivity.", 50, 200, 5, "Free Camera X Sensitivity",
[] { return !getSettings().game.freeCamera; }); "Adjusts horizontal free camera sensitivity.<br/><br/>Applies to the control stick only.",
50, 200, 5, [] { return !getSettings().game.freeCamera; });
config_percent_select(leftPane, rightPane, getSettings().game.freeCameraYSensitivity, config_percent_select(leftPane, rightPane, getSettings().game.freeCameraYSensitivity,
"Free Camera Y Sensitivity", "Adjusts twin-stick camera Y axis sensitivity.", 50, 200, 5, "Free Camera Y Sensitivity",
"Adjusts vertical free camera sensitivity.<br/><br/>Applies to the control stick only.",
50, 200, 5, [] { return !getSettings().game.freeCamera; });
addOption("Invert Camera X Axis", getSettings().game.invertCameraXAxis,
"Invert horizontal camera movement.<br/><br/>Applies to the control stick only.");
addOption("Invert Camera Y Axis", getSettings().game.invertCameraYAxis,
"Invert vertical camera movement.<br/><br/>Applies to the control stick only.",
[] { return !getSettings().game.freeCamera; }); [] { return !getSettings().game.freeCamera; });
addOption("Invert First Person X Axis", getSettings().game.invertFirstPersonXAxis, addOption("Invert First Person X Axis", getSettings().game.invertFirstPersonXAxis,
"Invert horizontal movement while aiming with items or first person camera. Applies only to the control stick (the gyroscope can be inverted in Input settings)."); "Invert horizontal movement while aiming with items or first person camera.<br/><br/>Applies to the control stick only.");
addOption("Invert First Person Y Axis", getSettings().game.invertFirstPersonYAxis, addOption("Invert First Person Y Axis", getSettings().game.invertFirstPersonYAxis,
"Invert vertical movement while aiming with items or first person camera. Applies only to the control stick (the gyroscope can be inverted in Input settings)."); "Invert vertical movement while aiming with items or first person camera.<br/><br/>Applies to the control stick only.");
addOption("Invert Air/Swim X Axis", getSettings().game.invertAirSwimX,
"Invert horizontal movement while flying or swimming.");
addOption("Invert Air/Swim Y Axis", getSettings().game.invertAirSwimY,
"Invert vertical movement while flying or swimming.");
leftPane.add_section("Gyro"); leftPane.add_section("Gyro");
leftPane.register_control(
leftPane.add_select_button({
.key = "Gyro Input Method",
.getValue =
[] {
const auto mode = getSettings().game.gyroMode.getValue();
const auto idx = static_cast<size_t>(mode);
return Rml::String{kGyroInputModeLabels[idx]};
},
.isModified =
[] {
return getSettings().game.gyroMode.getValue() !=
getSettings().game.gyroMode.getDefaultValue();
},
}),
rightPane, [](Pane& pane) {
for (size_t i = 0; i < kGyroInputModeLabels.size(); i++) {
pane
.add_button({
.text = Rml::String{kGyroInputModeLabels[i]},
.isSelected =
[i] {
return getSettings().game.gyroMode.getValue() == static_cast<GyroMode>(i);
},
})
.on_pressed([i] {
mDoAud_seStartMenu(kSoundItemChange);
const GyroMode mode = static_cast<GyroMode>(i);
getSettings().game.gyroMode.setValue(mode);
config::Save();
});
}
pane.add_rml(
"<br/><b>Sensor</b> reads motion directly from a supported controller's gyro via SDL.<br/>"
"<br/><b>Mouse</b> treats mouse input as gyro, intended for use with the Steam Deck.<br/>"
"<br/>Mouse input cannot currently be used with Gyro Rollgoal.");
});
addOption("Gyro Aim", getSettings().game.enableGyroAim, addOption("Gyro Aim", getSettings().game.enableGyroAim,
"Enables gyro controls while in look mode, aiming a hawk, and aiming " "Enables gyro controls while in look mode, aiming a hawk, and aiming "
"supported items.<br/><br/>Supported items include the Slingshot, Gale Boomerang, " "supported items.<br/><br/>Supported items include the Slingshot, Gale Boomerang, "
"Hero's Bow, Clawshot(s), Ball and Chain, and Dominion Rod."); "Hero's Bow, Clawshot(s), Ball and Chain, and Dominion Rod.");
addOption("Gyro Rollgoal", getSettings().game.enableGyroRollgoal, addOption("Gyro Rollgoal", getSettings().game.enableGyroRollgoal,
"Enables gyro controls for Rollgoal in Hena's Cabin.", "Enables gyro controls for Rollgoal in Hena's Cabin.");
[] { return getSettings().game.gyroMode.getValue() == GyroMode::Mouse; });
config_percent_select(leftPane, rightPane, getSettings().game.gyroSensitivityY, config_percent_select(leftPane, rightPane, getSettings().game.gyroSensitivityY,
"Gyro Pitch Sensitivity", "Controls vertical gyro aiming sensitivity.", 25, 400, 5, "Gyro Pitch Sensitivity", "Controls vertical gyro aiming sensitivity.", 25, 400, 5,
[] { return !gyro_enabled(); }); [] { return !gyro_enabled(); });
@@ -1025,10 +990,7 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
config_percent_select(leftPane, rightPane, getSettings().game.gyroSensitivityRollgoal, config_percent_select(leftPane, rightPane, getSettings().game.gyroSensitivityRollgoal,
"Rollgoal Sensitivity", "Controls how strongly gyro input tilts the Rollgoal table.", "Rollgoal Sensitivity", "Controls how strongly gyro input tilts the Rollgoal table.",
25, 400, 5, 25, 400, 5,
[] { [] { return !getSettings().game.enableGyroRollgoal; });
return !getSettings().game.enableGyroRollgoal ||
getSettings().game.gyroMode.getValue() == GyroMode::Mouse;
});
config_percent_select(leftPane, rightPane, getSettings().game.gyroDeadband, "Gyro Deadband", config_percent_select(leftPane, rightPane, getSettings().game.gyroDeadband, "Gyro Deadband",
"Ignores small gyro movement to reduce drift and jitter.", 0, 50, 1, "Ignores small gyro movement to reduce drift and jitter.", 0, 50, 1,
[] { return !gyro_enabled(); }); [] { return !gyro_enabled(); });
@@ -1039,8 +1001,29 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
"Invert vertical gyro aiming.", [] { return !gyro_enabled(); }); "Invert vertical gyro aiming.", [] { return !gyro_enabled(); });
addOption("Invert Gyro Yaw", getSettings().game.gyroInvertYaw, addOption("Invert Gyro Yaw", getSettings().game.gyroInvertYaw,
"Invert horizontal gyro aiming.", [] { return !gyro_enabled(); }); "Invert horizontal gyro aiming.", [] { return !gyro_enabled(); });
leftPane.add_section("Mouse");
addOption("Mouse Aim", getSettings().game.enableMouseAim,
"Enables mouse input while in look mode, aiming a hawk, and aiming "
"supported items.<br/><br/>Supported items include the Slingshot, Gale Boomerang, "
"Hero's Bow, Clawshot(s), Ball and Chain, and Dominion Rod.");
addOption("Mouse Camera", getSettings().game.enableMouseCamera,
"Enables mouse input for controlling the third-person camera.");
config_percent_select(leftPane, rightPane, getSettings().game.mouseAimSensitivity,
"Mouse Aim Sensitivity", "Controls mouse aim sensitivity.", 25, 400, 5,
[] { return !getSettings().game.enableMouseAim; });
config_percent_select(leftPane, rightPane, getSettings().game.mouseCameraSensitivity,
"Mouse Camera Sensitivity", "Controls mouse camera sensitivity.", 25, 400, 5,
[] { return !getSettings().game.enableMouseCamera; });
addOption("Invert Mouse Y", getSettings().game.invertMouseY,
"Invert vertical mouse control for both aiming and camera.",
[] { return !getSettings().game.enableMouseAim || !getSettings().game.enableMouseCamera; });
leftPane.add_section("Gameplay"); leftPane.add_section("Gameplay");
addOption("Invert Air/Swim X Axis", getSettings().game.invertAirSwimX,
"Invert horizontal movement while flying or swimming.");
addOption("Invert Air/Swim Y Axis", getSettings().game.invertAirSwimY,
"Invert vertical movement while flying or swimming.");
addOption("Swap Direct Select Input", getSettings().game.swapDirectSelect, addOption("Swap Direct Select Input", getSettings().game.swapDirectSelect,
"Swap the controls for using Direct Select on the item wheel, making Direct Select the default and holding L to scroll the wheel."); "Swap the controls for using Direct Select on the item wheel, making Direct Select the default and holding L to scroll the wheel.");
@@ -1138,6 +1121,11 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
addOption("Minimal HUD", getSettings().game.minimalHUD, addOption("Minimal HUD", getSettings().game.minimalHUD,
"Disables the elements of the main HUD of the game.<br/>Useful for a more immersive " "Disables the elements of the main HUD of the game.<br/>Useful for a more immersive "
"experience."); "experience.");
config_percent_select(leftPane, rightPane, getSettings().game.hudScale,
"HUD Scale",
"Scales the size of the gameplay HUD (hearts, buttons, mini-map, etc.). Does not affect dialog boxes or menus.",
50, 200, 5,
[] { return getSettings().game.minimalHUD.getValue(); });
addOption("Restore Wii 1.0 Glitches", getSettings().game.restoreWiiGlitches, addOption("Restore Wii 1.0 Glitches", getSettings().game.restoreWiiGlitches,
"Restores patched glitches from Wii USA 1.0, the first released version."); "Restores patched glitches from Wii USA 1.0, the first released version.");
addOption("Enable Rotating Link Doll", getSettings().game.enableLinkDollRotation, addOption("Enable Rotating Link Doll", getSettings().game.enableLinkDollRotation,
@@ -1198,6 +1186,8 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
"Link will not recoil when his sword hits walls."); "Link will not recoil when his sword hits walls.");
addOption("No 2nd Fish for Cat", getSettings().game.no2ndFishForCat, addOption("No 2nd Fish for Cat", getSettings().game.no2ndFishForCat,
"Skip needing to catch a second fish for Sera's cat."); "Skip needing to catch a second fish for Sera's cat.");
addOption("Button Fishing", getSettings().game.buttonFishing,
"Allow fishing with the Fishing Rod using the button the item is assigned to.");
addOption("Show Poe Count on Map", getSettings().game.enhancedMapMenus, addOption("Show Poe Count on Map", getSettings().game.enhancedMapMenus,
"Displays collected/total number of Poe Souls for a region on the map."); "Displays collected/total number of Poe Souls for a region on the map.");
addSpeedrunDisabledOption("Sun's Song (R+X)", getSettings().game.sunsSong, addSpeedrunDisabledOption("Sun's Song (R+X)", getSettings().game.sunsSong,
@@ -1290,12 +1280,40 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
"Makes Link's roll animation and movement twice as fast."); "Makes Link's roll animation and movement twice as fast.");
addCheat("Fast Spinner", getSettings().game.fastSpinner, addCheat("Fast Spinner", getSettings().game.fastSpinner,
"Speeds up Spinner movement while holding R."); "Speeds up Spinner movement while holding R.");
addCheat("Free Magic Armor", getSettings().game.freeMagicArmor, leftPane.register_control(
"Lets the magic armor work without consuming rupees."); leftPane.add_select_button({
.key = "Magic Armor Behavior",
.getValue =
[] {
return kMagicArmorModes[static_cast<u8>(getSettings().game.armorRupeeDrain.getValue())];
},
.isDisabled = [] { return getSettings().game.speedrunMode; },
.isModified =
[] {
return getSettings().game.armorRupeeDrain.getValue() !=
getSettings().game.armorRupeeDrain.getDefaultValue();
},
}),
rightPane, [](Pane& pane) {
for (int i = 0; i < kMagicArmorModes.size(); i++) {
pane.add_button({
.text = kMagicArmorModes[i],
.isSelected =
[i] {
return getSettings().game.armorRupeeDrain.getValue() == static_cast<MagicArmorMode>(i);
},
})
.on_pressed([i] {
mDoAud_seStartMenu(kSoundItemChange);
getSettings().game.armorRupeeDrain.setValue(static_cast<MagicArmorMode>(i));
config::Save();
});
}
pane.add_rml(
"<br/>Control the behavior of the Magic Armor.");
});
addCheat("Invincible Enemies", getSettings().game.invincibleEnemies, addCheat("Invincible Enemies", getSettings().game.invincibleEnemies,
"Prevents enemies from taking damage."); "Prevents enemies from taking damage.");
addCheat("Transform without Shadow Crystal", getSettings().game.transformWithoutShadowCrystal,
"Allows Link to transform without the Shadow Crystal (Only using Quick Transform.)");
}); });
add_tab("Interface", [this](Rml::Element* content) { add_tab("Interface", [this](Rml::Element* content) {
+11
View File
@@ -36,9 +36,20 @@ static int fopCam_Execute(camera_class* i_this) {
fapGm_HIO_c::startCpuTimer(); fapGm_HIO_c::startCpuTimer();
#endif #endif
#if TARGET_PC
if (dusk::getSettings().game.debugFlyCam && dusk::getSettings().game.debugFlyCamLockEvents) {
dScnPly_c::setPauseTimer(1);
ret = fpcMtd_Execute((process_method_class*)i_this->submethod, i_this);
} else {
if (!dComIfGp_isPauseFlag() && !dScnPly_c::isPause()) {
ret = fpcMtd_Execute((process_method_class*)i_this->submethod, i_this);
}
}
#else
if (!dComIfGp_isPauseFlag() && !dScnPly_c::isPause()) { if (!dComIfGp_isPauseFlag() && !dScnPly_c::isPause()) {
ret = fpcMtd_Execute((process_method_class*)i_this->submethod, i_this); ret = fpcMtd_Execute((process_method_class*)i_this->submethod, i_this);
} }
#endif
#if DEBUG #if DEBUG
fapGm_HIO_c::stopCpuTimer("カメラ(計算処理)"); // Camera (computational processing) fapGm_HIO_c::stopCpuTimer("カメラ(計算処理)"); // Camera (computational processing)
+10
View File
@@ -2369,6 +2369,7 @@ static u8 l_matDL[132] ATTRIBUTE_ALIGN(32) = {
}; };
void mDoExt_3DlineMat0_c::setMaterial() { void mDoExt_3DlineMat0_c::setMaterial() {
ZoneScoped;
j3dSys.reinitGX(); j3dSys.reinitGX();
GXSetNumIndStages(0); GXSetNumIndStages(0);
dKy_setLight_again(); dKy_setLight_again();
@@ -2384,6 +2385,7 @@ void mDoExt_3DlineMat0_c::setMaterial() {
} }
void mDoExt_3DlineMat0_c::draw() { void mDoExt_3DlineMat0_c::draw() {
ZoneScoped;
GXSetTevColor(GX_TEVREG2, field_0x8); GXSetTevColor(GX_TEVREG2, field_0x8);
if (field_0xc != NULL) { if (field_0xc != NULL) {
@@ -2692,6 +2694,7 @@ static u8 l_mat1DL[141] ATTRIBUTE_ALIGN(32) = {
}; };
void mDoExt_3DlineMat1_c::setMaterial() { void mDoExt_3DlineMat1_c::setMaterial() {
ZoneScoped;
j3dSys.reinitGX(); j3dSys.reinitGX();
GXSetNumIndStages(0); GXSetNumIndStages(0);
dKy_setLight_again(); dKy_setLight_again();
@@ -2709,6 +2712,7 @@ void mDoExt_3DlineMat1_c::setMaterial() {
} }
void mDoExt_3DlineMat1_c::draw() { void mDoExt_3DlineMat1_c::draw() {
ZoneScoped;
GXLoadTexObj(&mTextureObject, GX_TEXMAP0); GXLoadTexObj(&mTextureObject, GX_TEXMAP0);
GXSetTexCoordScaleManually(GX_TEXCOORD0, 1, GXGetTexObjWidth(&mTextureObject), GXGetTexObjHeight(&mTextureObject)); GXSetTexCoordScaleManually(GX_TEXCOORD0, 1, GXGetTexObjWidth(&mTextureObject), GXGetTexObjHeight(&mTextureObject));
GXSetTevColor(GX_TEVREG2, mColor); GXSetTevColor(GX_TEVREG2, mColor);
@@ -2922,6 +2926,7 @@ void mDoExt_3DlineMat1_c::update(int param_0, f32 param_1, GXColor& param_2, u16
#endif #endif
void mDoExt_3DlineMat2_c::setMaterial() { void mDoExt_3DlineMat2_c::setMaterial() {
ZoneScoped;
j3dSys.reinitGX(); j3dSys.reinitGX();
GXSetNumIndStages(0); GXSetNumIndStages(0);
GXClearVtxDesc(); GXClearVtxDesc();
@@ -3119,6 +3124,7 @@ mDoExt_cube8pPacket::mDoExt_cube8pPacket(cXyz* i_points, const GXColor& i_color)
} }
void drawCube(MtxP mtx, cXyz* pos, const GXColor& color) { void drawCube(MtxP mtx, cXyz* pos, const GXColor& color) {
ZoneScoped;
GXSETARRAY(GX_VA_POS, pos, sizeof(cXyz) * 8, sizeof(cXyz), true); GXSETARRAY(GX_VA_POS, pos, sizeof(cXyz) * 8, sizeof(cXyz), true);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
GXClearVtxDesc(); GXClearVtxDesc();
@@ -3198,6 +3204,7 @@ mDoExt_quadPacket::mDoExt_quadPacket(cXyz* i_points, const GXColor& i_color, u8
} }
void mDoExt_quadPacket::draw() { void mDoExt_quadPacket::draw() {
ZoneScoped;
GXSETARRAY(GX_VA_POS, mPoints, sizeof(mPoints), sizeof(cXyz), true); GXSETARRAY(GX_VA_POS, mPoints, sizeof(mPoints), sizeof(cXyz), true);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
GXClearVtxDesc(); GXClearVtxDesc();
@@ -3248,6 +3255,7 @@ mDoExt_trianglePacket::mDoExt_trianglePacket(cXyz* i_points, const GXColor& i_co
} }
void mDoExt_trianglePacket::draw() { void mDoExt_trianglePacket::draw() {
ZoneScoped;
j3dSys.reinitGX(); j3dSys.reinitGX();
GXSETARRAY(GX_VA_POS, mPoints, sizeof(mPoints), sizeof(cXyz), true); GXSETARRAY(GX_VA_POS, mPoints, sizeof(mPoints), sizeof(cXyz), true);
@@ -3301,6 +3309,7 @@ mDoExt_linePacket::mDoExt_linePacket(cXyz& i_start, cXyz& i_end, const GXColor&
} }
void mDoExt_linePacket::draw() { void mDoExt_linePacket::draw() {
ZoneScoped;
j3dSys.reinitGX(); j3dSys.reinitGX();
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
@@ -3418,6 +3427,7 @@ mDoExt_pointPacket::mDoExt_pointPacket(cXyz& i_position, const GXColor& i_color,
} }
void mDoExt_pointPacket::draw() { void mDoExt_pointPacket::draw() {
ZoneScoped;
j3dSys.reinitGX(); j3dSys.reinitGX();
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
+4 -1
View File
@@ -11,12 +11,15 @@
#include <types.h> #include <types.h>
u32 mDoLib_setResTimgObj(ResTIMG const* i_img, TGXTexObj* o_texObj, u32 tlut_name, u32 mDoLib_setResTimgObj(ResTIMG const* i_img, TGXTexObj* o_texObj, u32 tlut_name,
GXTlutObj* o_tlutObj) { TGXTlutObj* o_tlutObj) {
#ifdef TARGET_PC #ifdef TARGET_PC
o_texObj->reset(); o_texObj->reset();
#endif #endif
if (i_img->indexTexture) { if (i_img->indexTexture) {
JUT_ASSERT(44, o_tlutObj != NULL); JUT_ASSERT(44, o_tlutObj != NULL);
#ifdef TARGET_PC
o_tlutObj->reset();
#endif
GXInitTlutObj(o_tlutObj, (void*)((u8*)i_img + i_img->paletteOffset), GXInitTlutObj(o_tlutObj, (void*)((u8*)i_img + i_img->paletteOffset),
(GXTlutFmt)i_img->colorFormat, (u16)i_img->numColors); (GXTlutFmt)i_img->colorFormat, (u16)i_img->numColors);
GXInitTexObjCI(o_texObj, (void*)((u8*)i_img + i_img->imageOffset), i_img->width, i_img->height, GXInitTexObjCI(o_texObj, (void*)((u8*)i_img + i_img->imageOffset), i_img->width, i_img->height,
+24 -14
View File
@@ -55,6 +55,7 @@
#include "dusk/frame_interpolation.h" #include "dusk/frame_interpolation.h"
#include "dusk/game_clock.h" #include "dusk/game_clock.h"
#include "dusk/gyro.h" #include "dusk/gyro.h"
#include "dusk/mouse.h"
#include "dusk/imgui/ImGuiConsole.hpp" #include "dusk/imgui/ImGuiConsole.hpp"
#include "dusk/imgui/ImGuiEngine.hpp" #include "dusk/imgui/ImGuiEngine.hpp"
#include "dusk/iso_validate.hpp" #include "dusk/iso_validate.hpp"
@@ -74,7 +75,6 @@
#include <dolphin/dvd.h> #include <dolphin/dvd.h>
#include "SDL3/SDL_init.h" #include "SDL3/SDL_init.h"
#include "SDL3/SDL_filesystem.h"
#include "SDL3/SDL_iostream.h" #include "SDL3/SDL_iostream.h"
#include "SDL3/SDL_misc.h" #include "SDL3/SDL_misc.h"
#include "cxxopts.hpp" #include "cxxopts.hpp"
@@ -84,6 +84,7 @@
#include "dusk/config.hpp" #include "dusk/config.hpp"
#include "dusk/speedrun.h" #include "dusk/speedrun.h"
#include "dusk/settings.h" #include "dusk/settings.h"
#include "dusk/texture_replacements.hpp"
#include "dusk/io.hpp" #include "dusk/io.hpp"
#include "dusk/version.hpp" #include "dusk/version.hpp"
#include "dusk/discord_presence.hpp" #include "dusk/discord_presence.hpp"
@@ -167,6 +168,7 @@ bool launchUILoop() {
while (event != nullptr && event->type != AURORA_NONE) { while (event != nullptr && event->type != AURORA_NONE) {
switch (event->type) { switch (event->type) {
case AURORA_SDL_EVENT: case AURORA_SDL_EVENT:
dusk::mouse::handle_event(event->sdl);
dusk::ui::handle_event(event->sdl); dusk::ui::handle_event(event->sdl);
dusk::g_imguiConsole.HandleSDLEvent(event->sdl); dusk::g_imguiConsole.HandleSDLEvent(event->sdl);
break; break;
@@ -245,12 +247,15 @@ void main01(void) {
goto eventsDone; goto eventsDone;
case AURORA_PAUSED: case AURORA_PAUSED:
dusk::audio::SetPaused(true); dusk::audio::SetPaused(true);
dusk::mouse::onFocusLost();
break; break;
case AURORA_UNPAUSED: case AURORA_UNPAUSED:
dusk::audio::SetPaused(false); dusk::audio::SetPaused(false);
dusk::game_clock::reset_frame_timer(); dusk::game_clock::reset_frame_timer();
dusk::mouse::onFocusGained();
break; break;
case AURORA_SDL_EVENT: case AURORA_SDL_EVENT:
dusk::mouse::handle_event(event->sdl);
dusk::ui::handle_event(event->sdl); dusk::ui::handle_event(event->sdl);
dusk::g_imguiConsole.HandleSDLEvent(event->sdl); dusk::g_imguiConsole.HandleSDLEvent(event->sdl);
break; break;
@@ -287,6 +292,7 @@ void main01(void) {
for (int sim_tick = 0; sim_tick < pacing.sim_ticks_to_run; ++sim_tick) { for (int sim_tick = 0; sim_tick < pacing.sim_ticks_to_run; ++sim_tick) {
dusk::frame_interp::begin_sim_tick(); dusk::frame_interp::begin_sim_tick();
mDoCPd_c::read(); mDoCPd_c::read();
dusk::mouse::read();
dusk::gyro::read(pacing.sim_pace); dusk::gyro::read(pacing.sim_pace);
fapGm_Execute(); fapGm_Execute();
mDoAud_Execute(); mDoAud_Execute();
@@ -309,6 +315,7 @@ void main01(void) {
// Game Inputs // Game Inputs
mDoCPd_c::read(); mDoCPd_c::read();
dusk::mouse::read();
dusk::gyro::read(pacing.presentation_dt_seconds); dusk::gyro::read(pacing.presentation_dt_seconds);
// EXECUTE GAME LOGIC & RENDER // EXECUTE GAME LOGIC & RENDER
@@ -477,14 +484,6 @@ static void LanguageInit() {
selectedLanguage = static_cast<u8>(dusk::getSettings().game.language.getValue()); selectedLanguage = static_cast<u8>(dusk::getSettings().game.language.getValue());
} }
static std::string asset_path(const char* assetName) {
const char* basePath = SDL_GetBasePath();
if (basePath != nullptr && basePath[0] != '\0') {
return std::string(basePath) + "res/" + assetName;
}
return std::string("res/") + assetName;
}
static void log_build_info() { static void log_build_info() {
DuskLog.info("Build: {} (rev {}, built {}, type {})", DUSK_WC_DESCRIBE, DUSK_WC_REVISION, DUSK_WC_DATE, DUSK_BUILD_TYPE); DuskLog.info("Build: {} (rev {}, built {}, type {})", DUSK_WC_DESCRIBE, DUSK_WC_REVISION, DUSK_WC_DATE, DUSK_BUILD_TYPE);
DuskLog.info("Platform: {}", DUSK_PLATFORM_NAME); DuskLog.info("Platform: {}", DUSK_PLATFORM_NAME);
@@ -554,10 +553,17 @@ int game_main(int argc, char* argv[]) {
// PADSetDefaultMapping(&defaultPadMapping, PAD_TYPE_STANDARD); // PADSetDefaultMapping(&defaultPadMapping, PAD_TYPE_STANDARD);
{ {
// Load mappings from https://github.com/mdqinc/SDL_GameControllerDB const auto mappingsPath = dusk::ConfigPath / "gamecontrollerdb.txt";
const auto mappingsPath = asset_path("gamecontrollerdb.txt"); std::error_code ec;
if (SDL_AddGamepadMappingsFromFile(mappingsPath.c_str()) < 0) { if (std::filesystem::exists(mappingsPath, ec)) {
DuskLog.warn("Failed to load gamecontrollerdb.txt: {}", SDL_GetError()); const auto mappingsPathString = dusk::io::fs_path_to_string(mappingsPath);
if (SDL_AddGamepadMappingsFromFile(mappingsPathString.c_str()) < 0) {
DuskLog.warn("Failed to load gamecontrollerdb.txt from '{}': {}",
mappingsPathString, SDL_GetError());
}
} else if (ec) {
DuskLog.warn("Failed to inspect gamecontrollerdb.txt in data folder '{}': {}",
dusk::io::fs_path_to_string(mappingsPath), ec.message());
} }
} }
@@ -571,6 +577,9 @@ int game_main(int argc, char* argv[]) {
config.appName = dusk::AppName; config.appName = dusk::AppName;
config.userPath = reinterpret_cast<const char*>(userPathString.c_str()); config.userPath = reinterpret_cast<const char*>(userPathString.c_str());
config.cachePath = reinterpret_cast<const char*>(cachePathString.c_str()); config.cachePath = reinterpret_cast<const char*>(cachePathString.c_str());
#ifdef DUSK_ASSET_DIR
config.resourcesPath = DUSK_ASSET_DIR;
#endif
config.vsync = dusk::getSettings().video.enableVsync; config.vsync = dusk::getSettings().video.enableVsync;
config.startFullscreen = dusk::getSettings().video.enableFullscreen; config.startFullscreen = dusk::getSettings().video.enableFullscreen;
config.windowPosX = -1; config.windowPosX = -1;
@@ -585,7 +594,6 @@ int game_main(int argc, char* argv[]) {
config.allowJoystickBackgroundEvents = dusk::getSettings().game.allowBackgroundInput; config.allowJoystickBackgroundEvents = dusk::getSettings().game.allowBackgroundInput;
config.pauseOnFocusLost = dusk::getSettings().game.pauseOnFocusLost; config.pauseOnFocusLost = dusk::getSettings().game.pauseOnFocusLost;
config.imGuiInitCallback = &aurora_imgui_init_callback; config.imGuiInitCallback = &aurora_imgui_init_callback;
config.allowTextureReplacements = dusk::getSettings().game.enableTextureReplacements;
config.allowTextureDumps = false; config.allowTextureDumps = false;
auroraInfo = aurora_initialize(argc, argv, &config); auroraInfo = aurora_initialize(argc, argv, &config);
} }
@@ -635,6 +643,7 @@ int game_main(int argc, char* argv[]) {
return 0; return 0;
} }
dusk::texture_replacements::reload();
dusk::ui::initialize(); dusk::ui::initialize();
dusk::ui::push_document(std::make_unique<dusk::ui::Overlay>(), true, true); dusk::ui::push_document(std::make_unique<dusk::ui::Overlay>(), true, true);
dusk::ui::push_document(std::make_unique<dusk::ui::MenuBar>(), false); dusk::ui::push_document(std::make_unique<dusk::ui::MenuBar>(), false);
@@ -783,6 +792,7 @@ int game_main(int argc, char* argv[]) {
dusk::discord::shutdown(); dusk::discord::shutdown();
#endif #endif
dusk::ui::shutdown(); dusk::ui::shutdown();
dusk::texture_replacements::shutdown();
aurora_shutdown(); aurora_shutdown();
return 0; return 0;