Compare commits

..

4 Commits

Author SHA1 Message Date
MelonSpeedruns 27274e7341 Merge remote-tracking branch 'origin/main' into feature/hyper-enemies
# Conflicts:
#	src/dusk/imgui/ImGuiMenuGame.cpp
#	src/dusk/settings.cpp
2026-05-03 17:23:54 -04:00
MelonSpeedruns ce0d89058a don't run hyper enemies while an event is running 2026-04-30 10:55:28 -04:00
MelonSpeedruns 36092f1fdb added setting 2026-04-27 18:29:14 -04:00
MelonSpeedruns 5eb3184174 Hyper Enemies (2x) 2026-04-27 16:55:43 -04:00
215 changed files with 6449 additions and 15314 deletions
+53 -57
View File
@@ -48,15 +48,13 @@ else ()
message(STATUS "Unable to find git, commit information will not be available") message(STATUS "Unable to find git, commit information will not be available")
endif () endif ()
if (DUSK_WC_DESCRIBE MATCHES "^v([0-9]+)\\.([0-9]+)\\.([0-9]+)([-+].*)?$") if (DUSK_WC_DESCRIBE MATCHES "^v([0-9]+)\\.([0-9]+)\\.([0-9]+)(-([0-9]+).*)?$")
set(DUSK_SHORT_VERSION_STRING "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}") set(DUSK_SHORT_VERSION_STRING "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}")
set(DUSK_VERSION_TWEAK "0") if (CMAKE_MATCH_5)
if (DUSK_WC_DESCRIBE MATCHES "^v[0-9]+\\.[0-9]+\\.[0-9]+-([0-9]+)(-dirty)?$") set(DUSK_VERSION_STRING "${DUSK_SHORT_VERSION_STRING}.${CMAKE_MATCH_5}")
set(DUSK_VERSION_TWEAK "${CMAKE_MATCH_1}") else ()
elseif (DUSK_WC_DESCRIBE MATCHES "^v[0-9]+\\.[0-9]+\\.[0-9]+-[0-9A-Za-z.-]+-([0-9]+)(-dirty)?$") set(DUSK_VERSION_STRING "${DUSK_SHORT_VERSION_STRING}.0")
set(DUSK_VERSION_TWEAK "${CMAKE_MATCH_1}")
endif () endif ()
set(DUSK_VERSION_STRING "${DUSK_SHORT_VERSION_STRING}.${DUSK_VERSION_TWEAK}")
else () else ()
set(DUSK_WC_DESCRIBE "UNKNOWN-VERSION") set(DUSK_WC_DESCRIBE "UNKNOWN-VERSION")
set(DUSK_VERSION_STRING "0.0.0.0") set(DUSK_VERSION_STRING "0.0.0.0")
@@ -71,7 +69,7 @@ message(STATUS "Dusk version set to ${DUSK_WC_DESCRIBE}")
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
project(dusk LANGUAGES C CXX VERSION ${DUSK_VERSION_STRING}) project(dusk LANGUAGES C CXX VERSION ${DUSK_VERSION_STRING})
if (APPLE) if (APPLE)
enable_language(OBJC OBJCXX) enable_language(OBJC)
endif () endif ()
if (APPLE AND NOT TVOS AND CMAKE_SYSTEM_NAME STREQUAL tvOS) if (APPLE AND NOT TVOS AND CMAKE_SYSTEM_NAME STREQUAL tvOS)
# ios.toolchain.cmake hack for SDL # ios.toolchain.cmake hack for SDL
@@ -104,17 +102,19 @@ set(AURORA_ENABLE_DVD ON CACHE BOOL "Enable DVD API support" FORCE)
set(AURORA_ENABLE_CARD ON CACHE BOOL "Enable CARD API support" FORCE) set(AURORA_ENABLE_CARD ON CACHE BOOL "Enable CARD API support" FORCE)
set(AURORA_ENABLE_RMLUI ON CACHE BOOL "Enable RmlUi UI support" FORCE) set(AURORA_ENABLE_RMLUI ON CACHE BOOL "Enable RmlUi UI support" FORCE)
add_subdirectory(extern/aurora EXCLUDE_FROM_ALL) add_subdirectory(extern/aurora EXCLUDE_FROM_ALL)
target_compile_definitions(aurora_mtx PRIVATE MTX_USE_PS=1)
add_subdirectory(libs/freeverb) add_subdirectory(libs/freeverb)
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)
if(ANDROID) if(ANDROID)
set(DUSK_MOVIE_SUPPORT OFF) set(DUSK_MOVIE_SUPPORT OFF)
set(NOD_COMPRESS_BZIP2 OFF CACHE BOOL "" FORCE)
set(NOD_COMPRESS_LZMA OFF CACHE BOOL "" FORCE)
set(NOD_COMPRESS_ZLIB OFF CACHE BOOL "" FORCE)
set(NOD_COMPRESS_ZSTD OFF CACHE BOOL "" FORCE)
endif () endif ()
option(DUSK_ENABLE_SENTRY_NATIVE "Enable sentry-native crash reporting support" OFF) option(DUSK_ENABLE_SENTRY_NATIVE "Enable sentry-native crash reporting support" OFF)
@@ -283,9 +283,9 @@ set(DUSK_PRODUCT_NAME "Dusk")
set(DUSK_COPYRIGHT "Copyright (C) Twilit Realm contributors") set(DUSK_COPYRIGHT "Copyright (C) Twilit Realm contributors")
source_group("dolzel" FILES ${DOLZEL_FILES} ${Z2AUDIOLIB_FILES} ${REL_FILES}) source_group("dolzel" FILES ${DOLZEL_FILES} ${Z2AUDIOLIB_FILES} ${REL_FILES})
source_group("dusk" FILES ${DUSK_FILES} ${DUSK_HTTP_BACKEND_FILES}) source_group("dusk" FILES ${DUSK_FILES})
set(GAME_COMPILE_DEFS TARGET_PC WIDESCREEN_SUPPORT=1 AVOID_UB=1 VERSION=0 MTX_USE_PS=1) set(GAME_COMPILE_DEFS TARGET_PC WIDESCREEN_SUPPORT=1 AVOID_UB=1 VERSION=0)
set(GAME_INCLUDE_DIRS set(GAME_INCLUDE_DIRS
include include
@@ -297,10 +297,8 @@ set(GAME_INCLUDE_DIRS
extern extern
${CMAKE_BINARY_DIR}) ${CMAKE_BINARY_DIR})
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)
list(APPEND GAME_LIBS libzstd_static) list(APPEND GAME_LIBS libzstd_static)
@@ -313,41 +311,6 @@ if (WIN32)
list(APPEND GAME_LIBS Ws2_32) list(APPEND GAME_LIBS Ws2_32)
endif () endif ()
set(DUSK_HTTP_BACKEND_SOURCE src/dusk/http/no_backend.cpp)
if (DUSK_ENABLE_UPDATE_CHECKER)
list(APPEND GAME_COMPILE_DEFS DUSK_ENABLE_UPDATE_CHECKER=1)
if (WIN32)
set(DUSK_HTTP_BACKEND_SOURCE src/dusk/http/winhttp.cpp)
list(APPEND GAME_LIBS winhttp)
list(APPEND GAME_COMPILE_DEFS DUSK_HTTP_BACKEND_WINHTTP=1)
message(STATUS "dusk: Enabled update checker (WinHTTP)")
elseif (ANDROID)
set(DUSK_HTTP_BACKEND_SOURCE src/dusk/http/android.cpp)
list(APPEND GAME_COMPILE_DEFS DUSK_HTTP_BACKEND_ANDROID=1)
message(STATUS "dusk: Enabled update checker (Android)")
elseif (APPLE)
find_library(FOUNDATION_FRAMEWORK Foundation REQUIRED)
set(DUSK_HTTP_BACKEND_SOURCE src/dusk/http/url_session.mm)
set_source_files_properties(src/dusk/http/url_session.mm PROPERTIES COMPILE_FLAGS -fobjc-arc)
list(APPEND GAME_LIBS ${FOUNDATION_FRAMEWORK})
list(APPEND GAME_COMPILE_DEFS DUSK_HTTP_BACKEND_URLSESSION=1)
message(STATUS "dusk: Enabled update checker (NSURLSession)")
elseif (CMAKE_SYSTEM_NAME STREQUAL Linux)
find_package(CURL QUIET OPTIONAL_COMPONENTS HTTPS SSL)
if (CURL_FOUND AND CURL_HTTPS_FOUND AND CURL_SSL_FOUND)
set(DUSK_HTTP_BACKEND_SOURCE src/dusk/http/curl.cpp)
list(APPEND GAME_LIBS CURL::libcurl)
list(APPEND GAME_COMPILE_DEFS DUSK_HTTP_BACKEND_LIBCURL=1)
message(STATUS "dusk: Enabled update checker (libcurl)")
else ()
message(STATUS "dusk: Disabled update checker (libcurl + HTTPS/SSL not found)")
endif ()
else ()
message(STATUS "dusk: Disabled update checker (unsupported platform)")
endif ()
endif ()
list(APPEND DUSK_FILES ${DUSK_HTTP_BACKEND_SOURCE})
if (DUSK_MOVIE_SUPPORT) if (DUSK_MOVIE_SUPPORT)
if (TARGET libjpeg-turbo::turbojpeg-static) if (TARGET libjpeg-turbo::turbojpeg-static)
list(APPEND GAME_LIBS libjpeg-turbo::turbojpeg-static) list(APPEND GAME_LIBS libjpeg-turbo::turbojpeg-static)
@@ -357,13 +320,46 @@ if (DUSK_MOVIE_SUPPORT)
list(APPEND GAME_COMPILE_DEFS MOVIE_SUPPORT=1) list(APPEND GAME_COMPILE_DEFS MOVIE_SUPPORT=1)
endif () endif ()
set(DUSK_ENABLE_DISCORD_DEFAULT ON) option(DUSK_ENABLE_DISCORD_RPC "Enable Discord Rich Presence support" ON)
if (DEFINED DUSK_ENABLE_DISCORD_RPC AND NOT DEFINED DUSK_ENABLE_DISCORD) if (DUSK_ENABLE_DISCORD_RPC AND NOT ANDROID AND NOT IOS AND NOT TVOS)
set(DUSK_ENABLE_DISCORD_DEFAULT ${DUSK_ENABLE_DISCORD_RPC})
endif () FetchContent_Populate(discord_rpc
option(DUSK_ENABLE_DISCORD "Enable Discord Rich Presence support" ${DUSK_ENABLE_DISCORD_DEFAULT}) URL https://github.com/discord/discord-rpc/archive/refs/tags/v3.4.0.tar.gz
if (DUSK_ENABLE_DISCORD AND NOT ANDROID AND NOT IOS AND NOT TVOS) URL_HASH SHA256=e13427019027acd187352dacba6c65953af66fdf3c35fcf38fc40b454a9d7855
list(APPEND GAME_COMPILE_DEFS DUSK_DISCORD=1) DOWNLOAD_EXTRACT_TIMESTAMP TRUE
)
# RapidJSON is a git submodule absent from the discord-rpc tarball; fetch separately.
FetchContent_Populate(rapidjson
URL https://github.com/Tencent/rapidjson/archive/refs/tags/v1.1.0.tar.gz
URL_HASH SHA256=bf7ced29704a1e696fbccf2a2b4ea068e7774fa37f6d7dd4039d0787f8bed98e
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
)
if (NOT TARGET discord-rpc)
set(_drpc ${discord_rpc_SOURCE_DIR}/src)
set(_drpc_src
${_drpc}/discord_rpc.cpp
${_drpc}/rpc_connection.cpp
${_drpc}/serialization.cpp
)
if (WIN32)
list(APPEND _drpc_src ${_drpc}/connection_win.cpp ${_drpc}/discord_register_win.cpp)
elseif (APPLE)
list(APPEND _drpc_src ${_drpc}/connection_unix.cpp ${_drpc}/discord_register_osx.m)
else ()
list(APPEND _drpc_src ${_drpc}/connection_unix.cpp ${_drpc}/discord_register_linux.cpp)
endif ()
add_library(discord-rpc STATIC ${_drpc_src})
target_include_directories(discord-rpc PUBLIC
${discord_rpc_SOURCE_DIR}/include
${rapidjson_SOURCE_DIR}/include
)
if (UNIX)
target_link_libraries(discord-rpc PUBLIC pthread)
endif ()
endif ()
list(APPEND GAME_LIBS discord-rpc)
list(APPEND GAME_COMPILE_DEFS DUSK_DISCORD_RPC=1)
endif () endif ()
# Edit & Continue # Edit & Continue
+1 -1
View File
@@ -30,7 +30,7 @@
"CMAKE_CXX_COMPILER_LAUNCHER": "sccache", "CMAKE_CXX_COMPILER_LAUNCHER": "sccache",
"DUSK_ENABLE_SENTRY_NATIVE": { "DUSK_ENABLE_SENTRY_NATIVE": {
"type": "BOOL", "type": "BOOL",
"value": false "value": true
}, },
"DUSK_SENTRY_DSN": "$env{SENTRY_DSN}", "DUSK_SENTRY_DSN": "$env{SENTRY_DSN}",
"DUSK_SENTRY_ENVIRONMENT": "production" "DUSK_SENTRY_ENVIRONMENT": "production"
+15 -44
View File
@@ -1,66 +1,37 @@
<div align="center"> ![DuskLogo](res/logo-mascot.png)
<img src="res/logo-mascot.png" alt="Logo" width="640">
<p align="center"> - ### **[Official Website](https://twilitrealm.dev)**
<a href="https://twilitrealm.dev">Official Website</a> - ### **[Discord](https://discord.gg/QACynxeyna)**
<a href="https://discord.gg/dusktp">Discord</a>
</p>
</div>
# Overview # Overview
Dusk is a reverse-engineered reimplementation of Twilight Princess. Dusk is a reverse-engineered reimplementation of Twilight Princess.
It aims to be as accurate as possible to the original while also providing new options, enhancements, and tools to customize your experience. It aims to be as accurate as possible to the original while also providing new options, enhancements, and tools to customize your experience.
# Setup # Setup
**⚠️ Dusk does NOT provide any copyrighted assets. You must provide your own copy of the game.**
> [!IMPORTANT] ### 1. Verify your ROM dump
> Dusk does *not* provide any copyrighted assets. You must provide your own copy of the original game. First make sure your dump of the game is clean and supported by Dusk. You can do this by checking the sha1 hash of your dump against this list of supported versions.
### 1. Verify your dump | Version | sha1 hash |
|--------------| ---------------------------------------- |
First, make sure your dump of the game is clean and supported by Dusk. You can do this by checking the SHA-1 hash of your dump against this list of supported versions: | GameCube USA | 75edd3ddff41f125d1b4ce1a40378f1b565519e7 |
| GameCube PAL | 2601822a488eeb86fb89db16ca8f29c2c953e1ca |
| Version | SHA-1 hash |
|--------------| ------------------------------------------ |
| GameCube USA | `75edd3ddff41f125d1b4ce1a40378f1b565519e7` |
| GameCube EUR | `2601822a488eeb86fb89db16ca8f29c2c953e1ca` |
*Support for other versions of the game is planned in the future.
### 2. Download [Dusk](https://github.com/TwilitRealm/dusk/releases) ### 2. Download [Dusk](https://github.com/TwilitRealm/dusk/releases)
### 3. Setup the game ### 3. Setup the game
**Windows / macOS / Linux** - Extract the zip folder
- Extract the .zip file
- Launch Dusk - Launch Dusk
- Press **Select Disc Image** and provide the path to your supported game dump - Select Options, then set the ISO Path to your supported game dump
- Press **Play**! - Press Start Game to play!
**iOS** ![Dusk options](assets/dusk_options.png)
- Follow the [iOS setup guide](docs/ios-install-altstore.md)
**Android**
- Install the Dusk apk
- Launch Dusk
- Press **Select Disc Image** and provide the path to your supported game dump
- Press **Play**!
# Building # Building
If you'd like to build Dusk from source, please read the [build instructions](docs/building.md). If you'd like to build Dusk from source, please read the [build instructions](docs/building.md).
Pull requests are welcomed! Note that we do not accept contributions that are primarily AI-generated and will close your PR if we suspect as much. Pull Requests are welcomed! Note that we do not accept contributions that are primarily AI generated and will close your PR if we suspect as much.
# Credits # Credits
Special thanks to the [TP decompilation](https://github.com/zeldaret/tp) team, the GC/Wii decompilation community, the [Aurora](https://github.com/encounter/aurora) developers, the [TP speedrunning community](https://zsrtp.link), and all [contributors](https://github.com/TwilitRealm/dusk/graphs/contributors). Special thanks to the [TP decompilation](https://github.com/zeldaret/tp) team, the GC/Wii decompilation community, the [Aurora](https://github.com/encounter/aurora) developers, the [TP speedrunning community](https://zsrtp.link), and all [contributors](https://github.com/TwilitRealm/dusk/graphs/contributors).
<br/>
<div align="center">
<a href="https://github.com/encounter/aurora">
<img src="assets/aurora-powered.png" alt="Powered by Aurora" width="800">
</a>
</div>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

-66
View File
@@ -1,66 +0,0 @@
<svg width="600" height="600" viewBox="0 0 300 300" xmlns="http://www.w3.org/2000/svg">
<circle cx="150" cy="150" r="105" fill="none" stroke="white" stroke-width="4"/>
<circle cx="150" cy="150" r="95" fill="none" stroke="white" stroke-width="4"/>
<circle cx="150" cy="150" r="60" fill="none" stroke="white" stroke-width="4"/>
<circle cx="150" cy="150" r="75" fill="none" stroke="white" stroke-width="4"/>
<defs>
<line id="ray" x1="150" y1="55" x2="150" y2="45"/>
<clipPath id="zigzag-clip">
<circle cx="150" cy="150" r="75"/>
</clipPath>
</defs>
<g stroke="white" stroke-width="3">
<use href="#ray"/>
<use href="#ray" transform="rotate(18 150 150)"/>
<use href="#ray" transform="rotate(36 150 150)"/>
<use href="#ray" transform="rotate(54 150 150)"/>
<use href="#ray" transform="rotate(72 150 150)"/>
<use href="#ray" transform="rotate(90 150 150)"/>
<use href="#ray" transform="rotate(108 150 150)"/>
<use href="#ray" transform="rotate(126 150 150)"/>
<use href="#ray" transform="rotate(144 150 150)"/>
<use href="#ray" transform="rotate(162 150 150)"/>
<use href="#ray" transform="rotate(180 150 150)"/>
<use href="#ray" transform="rotate(198 150 150)"/>
<use href="#ray" transform="rotate(216 150 150)"/>
<use href="#ray" transform="rotate(234 150 150)"/>
<use href="#ray" transform="rotate(252 150 150)"/>
<use href="#ray" transform="rotate(270 150 150)"/>
<use href="#ray" transform="rotate(288 150 150)"/>
<use href="#ray" transform="rotate(306 150 150)"/>
<use href="#ray" transform="rotate(324 150 150)"/>
<use href="#ray" transform="rotate(342 150 150)"/>
</g>
<polygon fill="none" stroke="white" stroke-width="4" opacity="1" clip-path="url(#zigzag-clip)"
points="
126.82,78.67
150,90
173.18,78.67
185.27,101.46
210.68,105.92
207.06,131.46
225,150
207.06,168.54
210.68,194.08
185.27,198.54
173.18,221.33
150,210
126.82,221.33
114.73,198.54
89.32,194.08
92.94,168.54
75,150
92.94,131.46
89.32,105.92
114.73,101.46
"/>
<g fill="none" stroke="white" stroke-width="4">
<polygon points="150,105 130,140 170,140"/>
<polygon points="130,140 110,175 150,175"/>
<polygon points="170,140 150,175 190,175"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

-46
View File
@@ -1,46 +0,0 @@
# Installing Dusk on iOS via AltStore
## Prerequisites
- Mac with Homebrew installed
- iPhone connected via USB
- Dusk IPA file (download the latest `Dusk-vX.X.X-ios-arm64.ipa` from the [releases page](https://github.com/TwilitRealm/dusk/releases))
- Game disc - `GZ2E01` (Gamecube USA) or `GZ2PE01` (Gamecube PAL)
## 1. Install AltServer
```sh
brew install altserver
open -a AltServer
```
AltServer will appear in your menu bar.
## 2. Enable Developer Mode (iOS 16+)
- On your iPhone, go to **Settings > Privacy & Security > Developer Mode**
- Toggle it on and restart when prompted
## 3. Install AltStore on Your iPhone
- Click AltServer in the menu bar
- Click **Install AltStore > [Your iPhone]**
- Enter your Apple ID credentials when prompted
- On your iPhone, go to **Settings > General > VPN & Device Management**
- Tap your Apple ID under "Developer App" and tap **Trust**
## 4. Copy Files to Your iPhone
Transfer the IPA and game disc to your iPhone so they're accessible in the Files app. A few ways to do this:
- **AirDrop** - Right-click the files on your Mac and choose Share > AirDrop
- **iCloud Drive** - Place files in iCloud Drive on your Mac and they'll sync to Files on your iPhone
- **USB transfer** - Connect your iPhone and drag files via Finder's sidebar
- **Cloud storage** - Upload to Google Drive, Dropbox, etc. and download on your iPhone
## 5. Install via AltStore
- Open **AltStore** on your iPhone
- Go to the **My Apps** tab
- Tap the **+** button (top left)
- Open the **Files** app and select the `.ipa` file
+1 -1
+11 -24
View File
@@ -1430,14 +1430,11 @@ set(DUSK_FILES
src/dusk/gyro.cpp src/dusk/gyro.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/io.cpp src/dusk/io.cpp
src/dusk/layout.cpp src/dusk/layout.cpp
src/dusk/logging.cpp src/dusk/logging.cpp
src/dusk/settings.cpp src/dusk/settings.cpp
src/dusk/stubs.cpp src/dusk/stubs.cpp
src/dusk/update_check.cpp
src/dusk/update_check.hpp
#src/dusk/m_Do_ext_dusk.cpp #src/dusk/m_Do_ext_dusk.cpp
src/dusk/imgui/ImGuiConfig.hpp src/dusk/imgui/ImGuiConfig.hpp
src/dusk/imgui/ImGuiConsole.hpp src/dusk/imgui/ImGuiConsole.hpp
@@ -1450,37 +1447,36 @@ set(DUSK_FILES
src/dusk/imgui/ImGuiBloomWindow.hpp src/dusk/imgui/ImGuiBloomWindow.hpp
src/dusk/imgui/ImGuiMenuTools.cpp src/dusk/imgui/ImGuiMenuTools.cpp
src/dusk/imgui/ImGuiMenuTools.hpp src/dusk/imgui/ImGuiMenuTools.hpp
src/dusk/imgui/ImGuiPreLaunchWindow.cpp
src/dusk/imgui/ImGuiPreLaunchWindow.hpp
src/dusk/imgui/ImGuiFirstRunPreset.hpp
src/dusk/imgui/ImGuiFirstRunPreset.cpp
src/dusk/imgui/ImGuiProcessOverlay.cpp src/dusk/imgui/ImGuiProcessOverlay.cpp
src/dusk/imgui/ImGuiCameraOverlay.cpp src/dusk/imgui/ImGuiCameraOverlay.cpp
src/dusk/imgui/ImGuiHeapOverlay.cpp src/dusk/imgui/ImGuiHeapOverlay.cpp
src/dusk/imgui/ImGuiDebugPad.cpp
src/dusk/imgui/ImGuiControllerOverlay.cpp src/dusk/imgui/ImGuiControllerOverlay.cpp
src/dusk/imgui/ImGuiStubLog.cpp src/dusk/imgui/ImGuiStubLog.cpp
src/dusk/imgui/ImGuiMapLoader.cpp src/dusk/imgui/ImGuiMapLoader.cpp
src/dusk/imgui/ImGuiSaveEditor.cpp src/dusk/imgui/ImGuiSaveEditor.cpp
src/dusk/imgui/ImGuiStateShare.hpp src/dusk/imgui/ImGuiStateShare.hpp
src/dusk/imgui/ImGuiStateShare.cpp src/dusk/imgui/ImGuiStateShare.cpp
src/dusk/ui/achievements.cpp src/dusk/imgui/ImGuiAchievements.hpp
src/dusk/ui/achievements.hpp src/dusk/imgui/ImGuiAchievements.cpp
src/dusk/ui/bool_button.cpp src/dusk/ui/bool_button.cpp
src/dusk/ui/bool_button.hpp src/dusk/ui/bool_button.hpp
src/dusk/ui/button.cpp src/dusk/ui/button.cpp
src/dusk/ui/button.hpp src/dusk/ui/button.hpp
src/dusk/ui/component.cpp src/dusk/ui/component.cpp
src/dusk/ui/component.hpp src/dusk/ui/component.hpp
src/dusk/ui/controller_config.cpp
src/dusk/ui/controller_config.hpp
src/dusk/ui/document.cpp src/dusk/ui/document.cpp
src/dusk/ui/document.hpp src/dusk/ui/document.hpp
src/dusk/ui/editor.cpp src/dusk/ui/editor.cpp
src/dusk/ui/editor.hpp src/dusk/ui/editor.hpp
src/dusk/ui/event.cpp src/dusk/ui/event.cpp
src/dusk/ui/event.hpp src/dusk/ui/event.hpp
src/dusk/ui/graphics_tuner.cpp
src/dusk/ui/graphics_tuner.hpp
src/dusk/ui/input.cpp src/dusk/ui/input.cpp
src/dusk/ui/input.hpp src/dusk/ui/input.hpp
src/dusk/ui/modal.cpp
src/dusk/ui/modal.hpp
src/dusk/ui/nav_types.hpp src/dusk/ui/nav_types.hpp
src/dusk/ui/number_button.cpp src/dusk/ui/number_button.cpp
src/dusk/ui/number_button.hpp src/dusk/ui/number_button.hpp
@@ -1488,12 +1484,12 @@ set(DUSK_FILES
src/dusk/ui/overlay.hpp src/dusk/ui/overlay.hpp
src/dusk/ui/pane.cpp src/dusk/ui/pane.cpp
src/dusk/ui/pane.hpp src/dusk/ui/pane.hpp
src/dusk/ui/menu_bar.cpp src/dusk/ui/popup.cpp
src/dusk/ui/menu_bar.hpp src/dusk/ui/popup.hpp
src/dusk/ui/prelaunch.cpp src/dusk/ui/prelaunch.cpp
src/dusk/ui/prelaunch.hpp src/dusk/ui/prelaunch.hpp
src/dusk/ui/preset.cpp src/dusk/ui/prelaunch_options.cpp
src/dusk/ui/preset.hpp src/dusk/ui/prelaunch_options.hpp
src/dusk/ui/select_button.cpp src/dusk/ui/select_button.cpp
src/dusk/ui/select_button.hpp src/dusk/ui/select_button.hpp
src/dusk/ui/settings.cpp src/dusk/ui/settings.cpp
@@ -1514,15 +1510,6 @@ set(DUSK_FILES
src/dusk/OSReport.cpp src/dusk/OSReport.cpp
src/dusk/OSThread.cpp src/dusk/OSThread.cpp
src/dusk/OSMutex.cpp src/dusk/OSMutex.cpp
src/dusk/discord.cpp
src/dusk/discord.hpp
src/dusk/discord_presence.cpp src/dusk/discord_presence.cpp
src/dusk/version.cpp src/dusk/version.cpp
) )
set(DUSK_HTTP_BACKEND_FILES
src/dusk/http/no_backend.cpp
src/dusk/http/curl.cpp
src/dusk/http/winhttp.cpp
src/dusk/http/url_session.mm
)
-12
View File
@@ -4552,18 +4552,6 @@ public:
void handleWolfHowl(); void handleWolfHowl();
void handleQuickTransform(); void handleQuickTransform();
bool checkGyroAimContext(); bool checkGyroAimContext();
void onIronBallChainInterpCallback();
static const int IRON_BALL_CHAIN_COUNT = 102;
cXyz mIBChainInterpPrevPos[IRON_BALL_CHAIN_COUNT];
cXyz mIBChainInterpCurrPos[IRON_BALL_CHAIN_COUNT];
csXyz mIBChainInterpPrevAngle[IRON_BALL_CHAIN_COUNT];
csXyz mIBChainInterpCurrAngle[IRON_BALL_CHAIN_COUNT];
cXyz mIBChainInterpPrevHandRoot;
cXyz mIBChainInterpCurrHandRoot;
bool mIBChainInterpPrevValid;
bool mIBChainInterpCurrValid;
#endif #endif
}; // Size: 0x385C }; // Size: 0x385C
-6
View File
@@ -80,12 +80,6 @@ public:
/* 0x125C */ u32 field_0x125c; /* 0x125C */ u32 field_0x125c;
/* 0x1260 */ u8 field_0x1260[0x126C - 0x1260]; /* 0x1260 */ u8 field_0x1260[0x126C - 0x1260];
/* 0x126C */ u8 HIOInit; /* 0x126C */ u8 HIOInit;
#if TARGET_PC
cXyz mStalkLineInterpPrev[12];
cXyz mStalkLineInterpCurr[12];
bool mStalkLineInterpPrevValid;
bool mStalkLineInterpCurrValid;
#endif
}; };
STATIC_ASSERT(sizeof(e_db_class) == 0x1270); STATIC_ASSERT(sizeof(e_db_class) == 0x1270);
-6
View File
@@ -73,12 +73,6 @@ public:
/* 0x124C */ f32 field_0x124c; /* 0x124C */ f32 field_0x124c;
/* 0x1250 */ u8 field_0x1250[0x1264 - 0x1250]; /* 0x1250 */ u8 field_0x1250[0x1264 - 0x1250];
/* 0x1264 */ u8 HIOInit; /* 0x1264 */ u8 HIOInit;
#if TARGET_PC
cXyz mStalkLineInterpPrev[12];
cXyz mStalkLineInterpCurr[12];
bool mStalkLineInterpPrevValid;
bool mStalkLineInterpCurrValid;
#endif
}; };
STATIC_ASSERT(sizeof(e_hb_class) == 0x1268); STATIC_ASSERT(sizeof(e_hb_class) == 0x1268);
-9
View File
@@ -81,15 +81,6 @@ public:
/* 0x306D */ u8 field_0x306D[0x307C - 0x306D]; /* 0x306D */ u8 field_0x306D[0x307C - 0x306D];
/* 0x307C */ u32 mBodyEffEmtrID; /* 0x307C */ u32 mBodyEffEmtrID;
/* 0x3080 */ u8 mInitHIO; /* 0x3080 */ u8 mInitHIO;
#if TARGET_PC
static const int HAIR_STRAND_COUNT = 22;
static const int HAIR_SEGMENT_COUNT = 16;
cXyz mHairInterpPrev[HAIR_STRAND_COUNT * HAIR_SEGMENT_COUNT];
cXyz mHairInterpCurr[HAIR_STRAND_COUNT * HAIR_SEGMENT_COUNT];
bool mHairInterpPrevValid;
bool mHairInterpCurrValid;
#endif
}; };
STATIC_ASSERT(sizeof(e_s1_class) == 0x3084); STATIC_ASSERT(sizeof(e_s1_class) == 0x3084);
-6
View File
@@ -74,12 +74,6 @@ public:
/* 0x1250 */ f32 field_0x1250; /* 0x1250 */ f32 field_0x1250;
/* 0x1254 */ u8 field_0x1254[0x1268 - 0x1254]; /* 0x1254 */ u8 field_0x1254[0x1268 - 0x1254];
/* 0x1268 */ u8 field_0x1268; /* 0x1268 */ u8 field_0x1268;
#if TARGET_PC
cXyz mLineMatInterpPrev[12];
cXyz mLineMatInterpCurr[12];
bool mLineMatInterpPrevValid;
bool mLineMatInterpCurrValid;
#endif
}; };
STATIC_ASSERT(sizeof(e_yd_class) == 0x126c); STATIC_ASSERT(sizeof(e_yd_class) == 0x126c);
-9
View File
@@ -63,15 +63,6 @@ public:
/* 0x0BB4 */ yg_ke_s mYgKes[13]; /* 0x0BB4 */ yg_ke_s mYgKes[13];
/* 0x1880 */ mDoExt_3DlineMat0_c mLineMat; /* 0x1880 */ mDoExt_3DlineMat0_c mLineMat;
/* 0x189C */ u8 mIsFirstSpawn; /* 0x189C */ u8 mIsFirstSpawn;
#if TARGET_PC
static const int TENTACLE_STRAND_COUNT = 13;
static const int TENTACLE_SEGMENT_COUNT = 10;
cXyz mTentacleInterpPrev[TENTACLE_STRAND_COUNT * TENTACLE_SEGMENT_COUNT];
cXyz mTentacleInterpCurr[TENTACLE_STRAND_COUNT * TENTACLE_SEGMENT_COUNT];
bool mTentacleInterpPrevValid;
bool mTentacleInterpCurrValid;
#endif
}; };
STATIC_ASSERT(sizeof(e_yg_class) == 0x18a0); STATIC_ASSERT(sizeof(e_yg_class) == 0x18a0);
-6
View File
@@ -77,12 +77,6 @@ public:
/* 0x1260 */ u32 field_0x1260; /* 0x1260 */ u32 field_0x1260;
/* 0x1260 */ u8 field_0x1264[0x1270 - 0x1264]; /* 0x1260 */ u8 field_0x1264[0x1270 - 0x1264];
/* 0x1270 */ bool mIsHIOOwner; /* 0x1270 */ bool mIsHIOOwner;
#if TARGET_PC
cXyz mLineInterpPrev[12];
cXyz mLineInterpCurr[12];
bool mLineInterpPrevValid;
bool mLineInterpCurrValid;
#endif
}; };
STATIC_ASSERT(sizeof(e_yh_class) == 0x1274); STATIC_ASSERT(sizeof(e_yh_class) == 0x1274);
-12
View File
@@ -31,10 +31,6 @@ public:
csXyz* getAngle() { return field_0x8a4; } csXyz* getAngle() { return field_0x8a4; }
J3DModelData* getModelData() { return mModelData; } J3DModelData* getModelData() { return mModelData; }
#if TARGET_PC
void onInterpCallback();
#endif
private: private:
/* 0x568 */ request_of_phase_process_class mPhase; /* 0x568 */ request_of_phase_process_class mPhase;
/* 0x570 */ J3DModelData* mModelData; /* 0x570 */ J3DModelData* mModelData;
@@ -46,14 +42,6 @@ private:
/* 0x694 */ cXyz field_0x694[22]; /* 0x694 */ cXyz field_0x694[22];
/* 0x79C */ cXyz field_0x79c[22]; /* 0x79C */ cXyz field_0x79c[22];
/* 0x8A4 */ csXyz field_0x8a4[22]; /* 0x8A4 */ csXyz field_0x8a4[22];
#if TARGET_PC
static const int CHAIN_COUNT = 22;
cXyz mChainInterpPrev[CHAIN_COUNT];
cXyz mChainInterpCurr[CHAIN_COUNT];
bool mChainInterpPrevValid;
bool mChainInterpCurrValid;
#endif
}; };
STATIC_ASSERT(sizeof(daObjFchain_c) == 0x928); STATIC_ASSERT(sizeof(daObjFchain_c) == 0x928);
-11
View File
@@ -25,10 +25,6 @@ public:
int Draw(); int Draw();
int Delete(); int Delete();
#if TARGET_PC
void onInterpCallback();
#endif
enum Param_e { enum Param_e {
LOCK_e = (1 << 6), NO_BASE_DISP = (1 << 7) LOCK_e = (1 << 6), NO_BASE_DISP = (1 << 7)
}; };
@@ -54,13 +50,6 @@ private:
/* 0x1020 */ dCcD_Cyl mCylinderCollider; /* 0x1020 */ dCcD_Cyl mCylinderCollider;
/* 0x115C */ s32 mStopSwingingFrames; /* 0x115C */ s32 mStopSwingingFrames;
#if TARGET_PC
cXyz mChainInterpPrev[64];
cXyz mChainInterpCurr[64];
bool mChainInterpPrevValid;
bool mChainInterpCurrValid;
#endif
// Number of chain models // Number of chain models
u32 getArg0() { u32 getArg0() {
return fopAcM_GetParamBit(this, 0, 6); return fopAcM_GetParamBit(this, 0, 6);
-18
View File
@@ -118,18 +118,6 @@ class camera_class;
class dCamera_c; class dCamera_c;
typedef bool (dCamera_c::*engine_fn)(s32); typedef bool (dCamera_c::*engine_fn)(s32);
#if TARGET_PC
struct DebugFlyCam {
bool initialized;
f32 pitch;
f32 yaw;
cXyz savedCenter;
cXyz savedEye;
f32 savedFovy;
cSAngle savedBank;
};
#endif
class dCamera_c { class dCamera_c {
public: public:
class dCamInfo_c { class dCamInfo_c {
@@ -1040,8 +1028,6 @@ public:
bool test2Camera(s32); bool test2Camera(s32);
#if TARGET_PC #if TARGET_PC
bool freeCamera(); bool freeCamera();
bool executeDebugFlyCam();
void deactivateDebugFlyCam();
#endif #endif
bool towerCamera(s32); bool towerCamera(s32);
bool hookshotCamera(s32); bool hookshotCamera(s32);
@@ -1390,10 +1376,6 @@ public:
/* 0x970 */ dCamSetup_c mCamSetup; /* 0x970 */ dCamSetup_c mCamSetup;
/* 0xAEC */ dCamParam_c mCamParam; /* 0xAEC */ dCamParam_c mCamParam;
/* 0xB0C */ u8 field_0xb0c; /* 0xB0C */ u8 field_0xb0c;
#if TARGET_PC
DebugFlyCam mDebugFlyCam;
#endif
}; // Size: 0xB10 }; // Size: 0xB10
dCamera_c* dCam_getBody(); dCamera_c* dCam_getBody();
-6
View File
@@ -1845,12 +1845,6 @@ inline void dComIfGs_addDeathCount() {
g_dComIfG_gameInfo.info.getPlayer().getPlayerInfo().addDeathCount(); g_dComIfG_gameInfo.info.getPlayer().getPlayerInfo().addDeathCount();
} }
#if TARGET_PC
inline u16 dComIfGs_getDeathCount() {
return g_dComIfG_gameInfo.info.getPlayer().getPlayerInfo().getDeathCount();
}
#endif
inline char* dComIfGs_getPlayerName() { inline char* dComIfGs_getPlayerName() {
return g_dComIfG_gameInfo.info.getPlayer().getPlayerInfo().getPlayerName(); return g_dComIfG_gameInfo.info.getPlayer().getPlayerInfo().getPlayerName();
} }
-6
View File
@@ -169,12 +169,6 @@ public:
void mapBlink() {} void mapBlink() {}
#if PLATFORM_WII || TARGET_PC
f32 getMirrorPosX(f32 param_0, f32 param_1) {
return (field_0x11dc * 2.0f - (param_0 + param_1)) - param_1;
}
#endif
// Unknown name // Unknown name
struct RegionTexData { struct RegionTexData {
/* 0x00 */ float mMinX; /* 0x00 */ float mMinX;
-10
View File
@@ -66,16 +66,6 @@ public:
_c90 = param_2; _c90 = param_2;
} }
#if PLATFORM_WII || TARGET_PC
f32 getMirrorCenterPosX(f32 param_0, f32 param_1) {
if (_c90) {
return (mCenterPosX * 2.0f - (param_0 + param_1)) - param_1;
}
return param_0;
}
#endif
struct Stage_c { struct Stage_c {
// Incomplete class // Incomplete class
-3
View File
@@ -486,9 +486,6 @@ public:
mDeathCount++; mDeathCount++;
} }
} }
#if TARGET_PC
u16 getDeathCount() const { return mDeathCount; }
#endif
char* getPlayerName() const { return const_cast<char*>(mPlayerName); } char* getPlayerName() const { return const_cast<char*>(mPlayerName); }
void setPlayerName(const char* i_name) { void setPlayerName(const char* i_name) {
#if AVOID_UB #if AVOID_UB
+5 -1
View File
@@ -12,8 +12,9 @@
namespace dusk { namespace dusk {
enum class AchievementCategory : uint8_t { enum class AchievementCategory : uint8_t {
Challenge, Story,
Collection, Collection,
Challenge,
Minigame, Minigame,
Misc, Misc,
Glitched Glitched
@@ -49,6 +50,8 @@ public:
bool hasSignal(const char* key) const; bool hasSignal(const char* key) const;
std::vector<Achievement> getAchievements() const; std::vector<Achievement> getAchievements() const;
bool hasPendingUnlock() const { return !m_pendingUnlocks.empty(); }
std::string consumePendingUnlock();
private: private:
struct Entry { struct Entry {
@@ -65,6 +68,7 @@ private:
std::unordered_set<std::string_view> m_signals; std::unordered_set<std::string_view> m_signals;
bool m_loaded = false; bool m_loaded = false;
bool m_dirty = false; bool m_dirty = false;
std::queue<std::string> m_pendingUnlocks;
}; };
} // namespace dusk } // namespace dusk
+12 -8
View File
@@ -1,14 +1,18 @@
#pragma once #pragma once
#ifdef DUSK_DISCORD #ifdef DUSK_DISCORD_RPC
namespace dusk::discord { namespace dusk {
namespace discord {
void initialize(); void Initialize();
void run_callbacks();
void update_presence();
void shutdown();
} // namespace dusk::discord void RunCallbacks();
#endif // DUSK_DISCORD void UpdatePresence();
void Shutdown();
}
}
#endif // DUSK_DISCORD_RPC
-1
View File
@@ -12,7 +12,6 @@ void rollgoalTableOffset(s16& out_ax, s16& out_az);
extern bool s_sensor_keep_alive; extern bool s_sensor_keep_alive;
bool get_sensor_keep_alive(); bool get_sensor_keep_alive();
void set_sensor_keep_alive(bool value); void set_sensor_keep_alive(bool value);
bool rollgoal_gyro_enabled();
} // namespace dusk::gyro } // namespace dusk::gyro
#endif #endif
+1 -14
View File
@@ -1,27 +1,14 @@
#ifndef DUSK_MAIN_H #ifndef DUSK_MAIN_H
#define DUSK_MAIN_H #define DUSK_MAIN_H
#if defined(__APPLE__)
#include <TargetConditionals.h>
#endif
#include <filesystem> #include <filesystem>
namespace dusk { namespace dusk {
extern bool IsRunning; extern bool IsRunning;
extern bool IsShuttingDown; extern bool IsShuttingDown;
extern bool IsGameLaunched; extern bool IsGameLaunched;
extern bool RestartRequested; extern bool IsFocusPaused;
extern std::filesystem::path ConfigPath; extern std::filesystem::path ConfigPath;
#if defined(__ANDROID__) || (defined(TARGET_OS_IOS) && TARGET_OS_IOS) || \
(defined(TARGET_OS_TV) && TARGET_OS_TV)
inline constexpr bool SupportsProcessRestart = false;
#else
inline constexpr bool SupportsProcessRestart = true;
#endif
void RequestRestart() noexcept;
} }
#endif // DUSK_MAIN_H #endif // DUSK_MAIN_H
-2
View File
@@ -1,7 +1,5 @@
#pragma once #pragma once
#include <array>
struct RoomEntry { struct RoomEntry {
u8 roomNo; u8 roomNo;
std::vector<s16> roomPoints = {}; std::vector<s16> roomPoints = {};
+137 -1
View File
@@ -2,6 +2,9 @@
#define _SRC_DUSK_MATH_H_ #define _SRC_DUSK_MATH_H_
#include <cmath> #include <cmath>
#include <array>
#include <limits>
#include <bit>
#ifndef M_PI #ifndef M_PI
#define M_PI 3.14159265358979323846f #define M_PI 3.14159265358979323846f
@@ -16,6 +19,139 @@ inline float i_cosf(float x) { return cos(x); }
inline float i_tanf(float x) { return tan(x); } inline float i_tanf(float x) { return tan(x); }
inline float i_acosf(float x) { return acos(x); } inline float i_acosf(float x) { return acos(x); }
#include <dolphin/ppc_math.h>
// frsqrte matching courtesy of Geotale, with reference to https://achurch.org/cpu-tests/ppc750cl.s
struct BaseAndDec32 {
uint32_t base;
int32_t dec;
};
struct BaseAndDec64 {
uint64_t base;
int64_t dec;
};
union c32 {
constexpr c32(const float p) {
f = p;
}
constexpr c32(const uint32_t p) {
u = p;
}
uint32_t u;
float f;
};
union c64 {
constexpr c64(const double p) {
f = p;
}
constexpr c64(const uint64_t p) {
u = p;
}
uint64_t u;
double f;
};
static constexpr uint64_t EXPONENT_SHIFT_F64 = 52;
static constexpr uint64_t MANTISSA_MASK_F64 = 0x000fffffffffffffULL;
static constexpr uint64_t EXPONENT_MASK_F64 = 0x7ff0000000000000ULL;
static constexpr uint64_t SIGN_MASK_F64 = 0x8000000000000000ULL;
static constexpr std::array<BaseAndDec64, 32> RSQRTE_TABLE = {{
{0x69fa000000000ULL, -0x15a0000000LL},
{0x5f2e000000000ULL, -0x13cc000000LL},
{0x554a000000000ULL, -0x1234000000LL},
{0x4c30000000000ULL, -0x10d4000000LL},
{0x43c8000000000ULL, -0x0f9c000000LL},
{0x3bfc000000000ULL, -0x0e88000000LL},
{0x34b8000000000ULL, -0x0d94000000LL},
{0x2df0000000000ULL, -0x0cb8000000LL},
{0x2794000000000ULL, -0x0bf0000000LL},
{0x219c000000000ULL, -0x0b40000000LL},
{0x1bfc000000000ULL, -0x0aa0000000LL},
{0x16ae000000000ULL, -0x0a0c000000LL},
{0x11a8000000000ULL, -0x0984000000LL},
{0x0ce6000000000ULL, -0x090c000000LL},
{0x0862000000000ULL, -0x0898000000LL},
{0x0416000000000ULL, -0x082c000000LL},
{0xffe8000000000ULL, -0x1e90000000LL},
{0xf0a4000000000ULL, -0x1c00000000LL},
{0xe2a8000000000ULL, -0x19c0000000LL},
{0xd5c8000000000ULL, -0x17c8000000LL},
{0xc9e4000000000ULL, -0x1610000000LL},
{0xbedc000000000ULL, -0x1490000000LL},
{0xb498000000000ULL, -0x1330000000LL},
{0xab00000000000ULL, -0x11f8000000LL},
{0xa204000000000ULL, -0x10e8000000LL},
{0x9994000000000ULL, -0x0fe8000000LL},
{0x91a0000000000ULL, -0x0f08000000LL},
{0x8a1c000000000ULL, -0x0e38000000LL},
{0x8304000000000ULL, -0x0d78000000LL},
{0x7c48000000000ULL, -0x0cc8000000LL},
{0x75e4000000000ULL, -0x0c28000000LL},
{0x6fd0000000000ULL, -0x0b98000000LL},
}};
[[nodiscard]] static inline double frsqrte(const double val) {
c64 bits(val);
uint64_t mantissa = bits.u & MANTISSA_MASK_F64;
int64_t exponent = bits.u & EXPONENT_MASK_F64;
bool sign = (bits.u & SIGN_MASK_F64) != 0;
// Handle 0 case
if (mantissa == 0 && exponent == 0) {
return std::copysign(std::numeric_limits<double>::infinity(), bits.f);
}
// Handle NaN-like
if (exponent == EXPONENT_MASK_F64) {
if (mantissa == 0) {
return sign ? std::numeric_limits<double>::quiet_NaN() : 0.0;
}
return val;
}
// Handle negative inputs
if (sign) {
return std::numeric_limits<double>::quiet_NaN();
}
if (exponent == 0) {
// Shift so one bit goes to where the exponent would be,
// then clear that bit to mimic a not-subnormal number!
// Aka, if there are 12 leading zeroes, shift left once
uint32_t shift = std::countl_zero(mantissa) - static_cast<uint32_t>(63 - EXPONENT_SHIFT_F64);
mantissa <<= shift;
mantissa &= MANTISSA_MASK_F64;
// The shift is subtracted by 1 because denormals by default
// are offset by 1 (exponent 0 doesn't have implied 1 bit)
exponent -= static_cast<int64_t>(shift - 1) << EXPONENT_SHIFT_F64;
}
// In reality this doesn't get the full exponent -- Only the least significant bit
// Only that's needed because square roots of higher exponent bits simply multiply the
// result by 2!!
uint32_t key = static_cast<uint32_t>((static_cast<uint64_t>(exponent) | mantissa) >> 37);
uint64_t new_exp =
(static_cast<uint64_t>((0xbfcLL << EXPONENT_SHIFT_F64) - exponent) >> 1) & EXPONENT_MASK_F64;
// Remove the bits relating to anything higher than the LSB of the exponent
const auto &entry = RSQRTE_TABLE[0x1f & (key >> 11)];
// The result is given by an estimate then an adjustment based on the original
// key that was computed
uint64_t new_mantissa = static_cast<uint64_t>(entry.base + entry.dec * static_cast<int64_t>(key & 0x7ff));
return c64(new_exp | new_mantissa).f;
}
#endif // _SRC_DUSK_MATH_H_ #endif // _SRC_DUSK_MATH_H_
+6 -37
View File
@@ -21,17 +21,6 @@ enum class GameLanguage : u8 {
Italian = OS_LANGUAGE_ITALIAN, Italian = OS_LANGUAGE_ITALIAN,
}; };
enum class DiscVerificationState : u8 {
Unknown = 0,
Success,
HashMismatch,
};
enum class GyroMode : u8 {
Sensor = 0,
Mouse = 1,
};
namespace config { namespace config {
template <> template <>
struct ConfigEnumRange<BloomMode> { struct ConfigEnumRange<BloomMode> {
@@ -44,18 +33,6 @@ struct ConfigEnumRange<GameLanguage> {
static constexpr auto min = GameLanguage::English; static constexpr auto min = GameLanguage::English;
static constexpr auto max = GameLanguage::Italian; static constexpr auto max = GameLanguage::Italian;
}; };
template <>
struct ConfigEnumRange<DiscVerificationState> {
static constexpr auto min = DiscVerificationState::Unknown;
static constexpr auto max = DiscVerificationState::HashMismatch;
};
template <>
struct ConfigEnumRange<GyroMode> {
static constexpr auto min = GyroMode::Sensor;
static constexpr auto max = GyroMode::Mouse;
};
} }
// Persistent user settings // Persistent user settings
@@ -68,8 +45,6 @@ struct UserSettings {
ConfigVar<bool> enableFullscreen; ConfigVar<bool> enableFullscreen;
ConfigVar<bool> enableVsync; ConfigVar<bool> enableVsync;
ConfigVar<bool> lockAspectRatio; ConfigVar<bool> lockAspectRatio;
ConfigVar<bool> enableFpsOverlay;
ConfigVar<int> fpsOverlayCorner;
} video; } video;
struct { struct {
@@ -81,7 +56,6 @@ struct UserSettings {
ConfigVar<int> fanfareVolume; ConfigVar<int> fanfareVolume;
ConfigVar<bool> enableReverb; ConfigVar<bool> enableReverb;
ConfigVar<bool> enableHrtf; ConfigVar<bool> enableHrtf;
ConfigVar<bool> menuSounds;
} audio; } audio;
// Game settings // Game settings
@@ -92,11 +66,13 @@ struct UserSettings {
// QoL // QoL
ConfigVar<bool> enableQuickTransform; ConfigVar<bool> enableQuickTransform;
ConfigVar<bool> hideTvSettingsScreen; ConfigVar<bool> hideTvSettingsScreen;
ConfigVar<bool> skipWarningScreen;
ConfigVar<bool> biggerWallets; ConfigVar<bool> biggerWallets;
ConfigVar<bool> noReturnRupees; ConfigVar<bool> noReturnRupees;
ConfigVar<bool> disableRupeeCutscenes; ConfigVar<bool> disableRupeeCutscenes;
ConfigVar<bool> noSwordRecoil; ConfigVar<bool> noSwordRecoil;
ConfigVar<int> damageMultiplier; ConfigVar<int> damageMultiplier;
ConfigVar<bool> hyperEnemies;
ConfigVar<bool> noHeartDrops; ConfigVar<bool> noHeartDrops;
ConfigVar<bool> instantDeath; ConfigVar<bool> instantDeath;
ConfigVar<bool> fastClimbing; ConfigVar<bool> fastClimbing;
@@ -110,11 +86,11 @@ struct UserSettings {
// Preferences // Preferences
ConfigVar<bool> enableMirrorMode; ConfigVar<bool> enableMirrorMode;
ConfigVar<bool> minimalHUD; ConfigVar<bool> disableMainHUD;
ConfigVar<bool> pauseOnFocusLost; ConfigVar<bool> pauseOnFocusLost;
ConfigVar<bool> enableLinkDollRotation; ConfigVar<bool> enableLinkDollRotation;
ConfigVar<bool> enableAchievementToasts; ConfigVar<bool> enableAchievementNotifications;
ConfigVar<bool> enableControllerToasts;
// Graphics // Graphics
ConfigVar<BloomMode> bloomMode; ConfigVar<BloomMode> bloomMode;
@@ -131,7 +107,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;
@@ -145,9 +120,6 @@ struct UserSettings {
ConfigVar<bool> invertCameraXAxis; ConfigVar<bool> invertCameraXAxis;
ConfigVar<bool> invertCameraYAxis; ConfigVar<bool> invertCameraYAxis;
ConfigVar<float> freeCameraSensitivity; ConfigVar<float> freeCameraSensitivity;
ConfigVar<bool> debugFlyCam;
ConfigVar<bool> debugFlyCamLockEvents;
ConfigVar<bool> allowBackgroundInput;
// Cheats // Cheats
ConfigVar<bool> infiniteHearts; ConfigVar<bool> infiniteHearts;
@@ -174,20 +146,17 @@ struct UserSettings {
// Tools // Tools
ConfigVar<bool> speedrunMode; ConfigVar<bool> speedrunMode;
ConfigVar<bool> liveSplitEnabled; ConfigVar<bool> liveSplitEnabled;
ConfigVar<bool> recordingMode;
} game; } game;
struct { struct {
ConfigVar<std::string> isoPath; ConfigVar<std::string> isoPath;
ConfigVar<DiscVerificationState> isoVerification;
ConfigVar<std::string> graphicsBackend; ConfigVar<std::string> graphicsBackend;
ConfigVar<bool> skipPreLaunchUI; ConfigVar<bool> skipPreLaunchUI;
ConfigVar<bool> showPipelineCompilation; ConfigVar<bool> showPipelineCompilation;
ConfigVar<bool> wasPresetChosen; ConfigVar<bool> wasPresetChosen;
ConfigVar<bool> enableCrashReporting; ConfigVar<bool> enableCrashReporting;
ConfigVar<bool> checkForUpdates; ConfigVar<bool> duskMenuOpen;
ConfigVar<int> cardFileType; ConfigVar<int> cardFileType;
ConfigVar<bool> enableAdvancedSettings;
} backend; } backend;
}; };
-13
View File
@@ -5,7 +5,6 @@
#include "Z2AudioLib/Z2EnvSeMgr.h" #include "Z2AudioLib/Z2EnvSeMgr.h"
#include "Z2AudioLib/Z2LinkMgr.h" #include "Z2AudioLib/Z2LinkMgr.h"
#include "dusk/audio.h" #include "dusk/audio.h"
#include "dusk/settings.h"
class mDoAud_zelAudio_c : public Z2AudioMgr { class mDoAud_zelAudio_c : public Z2AudioMgr {
public: public:
@@ -133,18 +132,6 @@ inline void mDoAud_seStart(u32 i_sfxID, const Vec* i_sePos, u32 param_2, s8 i_re
-1.0f, -1.0f, 0); -1.0f, -1.0f, 0);
} }
#if TARGET_PC
inline void mDoAud_seStartMenu(u32 i_sfxID) {
if (!mDoAud_zelAudio_c::isInitFlag()) {
return;
}
if (!dusk::getSettings().audio.menuSounds.getValue()) {
return;
}
mDoAud_seStart(i_sfxID, nullptr, 0, 0);
}
#endif
inline void mDoAud_seStartLevel(u32 i_sfxID, const Vec* i_sePos, u32 param_2, s8 i_reverb) { inline void mDoAud_seStartLevel(u32 i_sfxID, const Vec* i_sePos, u32 param_2, s8 i_reverb) {
DUSK_AUDIO_SKIP() DUSK_AUDIO_SKIP()
Z2AudioMgr::getInterface()->seStartLevel(i_sfxID, i_sePos, param_2, i_reverb, 1.0f, 1.0f, Z2AudioMgr::getInterface()->seStartLevel(i_sfxID, i_sePos, param_2, i_reverb, 1.0f, 1.0f,
@@ -1,9 +1,9 @@
#ifndef J3DSTRUCT_H #ifndef J3DSTRUCT_H
#define J3DSTRUCT_H #define J3DSTRUCT_H
#include <cstring>
#include <gx.h> #include <gx.h>
#include <mtx.h> #include <mtx.h>
#include <mtx.h>
#include "global.h" #include "global.h"
#include "JSystem/JMath/JMath.h" #include "JSystem/JMath/JMath.h"
@@ -556,8 +556,8 @@ void J3DModelLoader::readVertexData(const J3DVertexBlock& block, J3DVertexData&
if (attr == GX_VA_POS) { if (attr == GX_VA_POS) {
// can be a little off due to 0x20 alignment, account for that // can be a little off due to 0x20 alignment, account for that
// u32 expect = ((data.mVtxNum * vertStride) + 0x1F) & ~0x1F; u32 expect = ((data.mVtxNum * vertStride) + 0x1F) & ~0x1F;
// JUT_ASSERT(1234, expect == addrDiff); JUT_ASSERT(1234, expect == addrDiff);
} else if (attr == GX_VA_NRM) { } else if (attr == GX_VA_NRM) {
data.mNrmNum = num; data.mNrmNum = num;
} else if (attr == GX_VA_CLR0) { } else if (attr == GX_VA_CLR0) {
+3 -17
View File
@@ -8,10 +8,6 @@
#include "JSystem/JUtility/JUTFader.h" #include "JSystem/JUtility/JUTFader.h"
#include "JSystem/J2DGraph/J2DOrthoGraph.h" #include "JSystem/J2DGraph/J2DOrthoGraph.h"
#ifdef TARGET_PC
#include <algorithm>
#endif
JUTFader::JUTFader(int x, int y, int width, int height, JUtility::TColor pColor) JUTFader::JUTFader(int x, int y, int width, int height, JUtility::TColor pColor)
: mColor(pColor), mBox(x, y, x + width, y + height) { : mColor(pColor), mBox(x, y, x + width, y + height) {
mStatus = None; mStatus = None;
@@ -67,24 +63,14 @@ void JUTFader::advance() {
void JUTFader::control() { void JUTFader::control() {
advance(); advance();
#ifndef TARGET_PC
// FRAME INTERP NOTE: Draw is called by JFWDisplay when interpolation is active
draw(); draw();
#endif
} }
void JUTFader::draw() { void JUTFader::draw() {
if (mColor.a != 0) { if (mColor.a != 0) {
#ifdef TARGET_PC
if (dusk::frame_interp::is_enabled() && mDuration != 0) {
const auto step = dusk::frame_interp::get_interpolation_step();
const auto progress = static_cast<f32>(mTimer) / static_cast<f32>(mDuration);
const auto timer = mTimer - 1 + step + progress;
auto alpha = timer / mDuration;
if (mStatus == FadeIn) {
alpha = 1.0f - alpha;
}
alpha = std::clamp(alpha, 0.0f, 1.0f);
mColor.a = static_cast<u8>(alpha * 255.0f);
}
#endif
J2DOrthoGraph orthograph; J2DOrthoGraph orthograph;
orthograph.setColor(mColor); orthograph.setColor(mColor);
orthograph.fillBox(mBox); orthograph.fillBox(mBox);
+3 -2
View File
@@ -66,11 +66,12 @@ Output APK:
You can pass command-line args through the activity intent: You can pass command-line args through the activity intent:
```bash ```bash
adb shell am start -n dev.twilitrealm.dusk/.DuskActivity \ adb shell am start -n com.twilitrealm.dusk/.DuskActivity \
--es dusk_args "--backend vulkan" --es dusk_args "'/sdcard/Download/The Legend of Zelda: Twilight Princess (USA).iso'"
``` ```
Supported extras: Supported extras:
- `dusk_args`: single shell-like argument string - `dusk_args`: single shell-like argument string
- `dusk_argv`: string-array argv - `dusk_argv`: string-array argv
- `dusk_disc`: compatibility shortcut (single ISO path)
+3 -20
View File
@@ -2,22 +2,12 @@ plugins {
id 'com.android.application' id 'com.android.application'
} }
def duskRepoDir = rootProject.projectDir.parentFile.parentFile
def duskGeneratedAssetsDir = layout.buildDirectory.dir('generated/assets/dusk').get().asFile
def syncDuskAssets = tasks.register('syncDuskAssets', Sync) {
from(new File(duskRepoDir, 'res')) {
into 'res'
exclude '**/.DS_Store'
}
into duskGeneratedAssetsDir
}
android { android {
namespace 'dev.twilitrealm.dusk' namespace 'com.twilitrealm.dusk'
compileSdk 36 compileSdk 36
defaultConfig { defaultConfig {
applicationId 'dev.twilitrealm.dusk' applicationId 'com.twilitrealm.dusk'
minSdk 26 minSdk 26
targetSdk 36 targetSdk 36
versionCode 1 versionCode 1
@@ -37,7 +27,7 @@ android {
sourceSets { sourceSets {
main { main {
jniLibs.srcDirs = ['src/main/jniLibs'] jniLibs.srcDirs = ['src/main/jniLibs']
assets.srcDirs = [duskGeneratedAssetsDir] assets.srcDirs = ['../../assets']
} }
} }
@@ -58,10 +48,3 @@ android {
dependencies { dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar']) implementation fileTree(dir: 'libs', include: ['*.jar'])
} }
tasks.configureEach { task ->
if ((task.name.startsWith('merge') && task.name.endsWith('Assets')) ||
task.name.toLowerCase().contains('lint')) {
task.dependsOn(syncDuskAssets)
}
}
-2
View File
@@ -1,4 +1,2 @@
# Keep SDL activity and related JNI bridge methods. # Keep SDL activity and related JNI bridge methods.
-keep class org.libsdl.app.** { *; } -keep class org.libsdl.app.** { *; }
-keep class dev.twilitrealm.dusk.DuskHttpClient { *; }
-keep class dev.twilitrealm.dusk.DuskHttpClient$Response { *; }
@@ -10,7 +10,6 @@
<uses-feature android:name="android.hardware.type.pc" android:required="false" /> <uses-feature android:name="android.hardware.type.pc" android:required="false" />
<uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.INTERNET" />
<application <application
android:allowBackup="true" android:allowBackup="true"
@@ -25,7 +24,7 @@
android:resource="@xml/game_mode_config" /> android:resource="@xml/game_mode_config" />
<activity <activity
android:name="dev.twilitrealm.dusk.DuskActivity" android:name="com.twilitrealm.dusk.DuskActivity"
android:alwaysRetainTaskState="true" android:alwaysRetainTaskState="true"
android:configChanges="layoutDirection|locale|grammaticalGender|fontScale|fontWeightAdjustment|orientation|uiMode|screenLayout|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation" android:configChanges="layoutDirection|locale|grammaticalGender|fontScale|fontWeightAdjustment|orientation|uiMode|screenLayout|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation"
android:exported="true" android:exported="true"
@@ -1,28 +1,18 @@
package dev.twilitrealm.dusk; package com.twilitrealm.dusk;
import android.app.ActionBar; import android.app.ActionBar;
import android.content.ClipData;
import android.content.Intent; import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.provider.OpenableColumns;
import android.util.Log;
import android.view.View; import android.view.View;
import android.view.Window;
import android.view.WindowInsets; import android.view.WindowInsets;
import android.view.WindowInsetsController;
import org.libsdl.app.SDLActivity; import org.libsdl.app.SDLActivity;
import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class DuskActivity extends SDLActivity { public class DuskActivity extends SDLActivity {
private static final String TAG = "DuskActivity";
private static String[] splitArgs(String raw) { private static String[] splitArgs(String raw) {
List<String> out = new ArrayList<>(); List<String> out = new ArrayList<>();
StringBuilder current = new StringBuilder(); StringBuilder current = new StringBuilder();
@@ -71,46 +61,18 @@ public class DuskActivity extends SDLActivity {
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
hideSystemBars();
}
@Override
protected void onResume() {
super.onResume();
hideSystemBars();
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
hideSystemBars();
}
}
private void hideSystemBars() {
Window window = getWindow();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
window.setDecorFitsSystemWindows(false); getWindow().getDecorView().getWindowInsetsController().hide(WindowInsets.Type.systemBars());
WindowInsetsController ctrl = window.getDecorView().getWindowInsetsController(); }else {
if (ctrl != null) { View decorView = getWindow().getDecorView();
ctrl.setSystemBarsBehavior( // Hide the status bar.
WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE); int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
ctrl.hide(WindowInsets.Type.systemBars());
}
} else {
View decorView = window.getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN |
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY |
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
decorView.setSystemUiVisibility(uiOptions); decorView.setSystemUiVisibility(uiOptions);
// Remember that you should never show the action bar if the
// status bar is hidden, so hide that too if necessary.
ActionBar actionBar = getActionBar(); ActionBar actionBar = getActionBar();
if (actionBar != null) { actionBar.hide();
actionBar.hide();
}
} }
} }
@@ -138,96 +100,12 @@ public class DuskActivity extends SDLActivity {
return splitArgs(trimmed); return splitArgs(trimmed);
} }
} }
String discPath = intent.getStringExtra("dusk_disc");
if (discPath != null && !discPath.isEmpty()) {
return new String[] { discPath };
}
} }
return new String[0]; return new String[0];
} }
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
persistUriPermissions(data);
}
super.onActivityResult(requestCode, resultCode, data);
}
private void persistUriPermissions(Intent data) {
if (data == null) {
return;
}
int permissionFlags =
data.getFlags() & (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
if (permissionFlags == 0) {
return;
}
Uri uri = data.getData();
if (uri != null) {
persistUriPermission(uri, permissionFlags);
}
ClipData clipData = data.getClipData();
if (clipData == null) {
return;
}
for (int i = 0; i < clipData.getItemCount(); ++i) {
Uri itemUri = clipData.getItemAt(i).getUri();
if (itemUri != null) {
persistUriPermission(itemUri, permissionFlags);
}
}
}
private void persistUriPermission(Uri uri, int permissionFlags) {
if ((permissionFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
persistUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION, "read");
}
if ((permissionFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
persistUriPermission(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, "write");
}
}
private void persistUriPermission(Uri uri, int permissionFlag, String permissionName) {
try {
getContentResolver().takePersistableUriPermission(uri, permissionFlag);
} catch (SecurityException | IllegalArgumentException e) {
Log.w(TAG, "Unable to persist " + permissionName + " URI permission for " + uri, e);
}
}
public String getDisplayNameForUri(String uriString) {
if (uriString == null || uriString.isEmpty()) {
return "";
}
Uri uri = Uri.parse(uriString);
if ("content".equals(uri.getScheme())) {
try (Cursor cursor = getContentResolver().query(
uri, new String[] { OpenableColumns.DISPLAY_NAME }, null, null, null))
{
if (cursor != null && cursor.moveToFirst()) {
int displayNameColumn = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
if (displayNameColumn >= 0) {
String displayName = cursor.getString(displayNameColumn);
if (displayName != null && !displayName.isEmpty()) {
return displayName;
}
}
}
} catch (SecurityException | IllegalArgumentException e) {
Log.w(TAG, "Unable to query display name for " + uri, e);
}
} else if ("file".equals(uri.getScheme())) {
String path = uri.getPath();
if (path != null && !path.isEmpty()) {
String name = new File(path).getName();
if (!name.isEmpty()) {
return name;
}
}
}
String lastSegment = uri.getLastPathSegment();
return lastSegment != null ? lastSegment : "";
}
} }
@@ -1,237 +0,0 @@
package dev.twilitrealm.dusk;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.net.ssl.HttpsURLConnection;
public final class DuskHttpClient {
public static final int ERROR_NONE = 0;
public static final int ERROR_INVALID_URL = 1;
public static final int ERROR_UNSUPPORTED_SCHEME = 2;
public static final int ERROR_TIMEOUT = 3;
public static final int ERROR_TOO_LARGE = 4;
public static final int ERROR_NETWORK = 5;
private static final int MAX_REDIRECTS = 5;
public static final class Response {
public int error;
public String message;
public int statusCode;
public String[] headerNames;
public String[] headerValues;
public byte[] body;
Response(int error, String message, int statusCode, String[] headerNames,
String[] headerValues, byte[] body) {
this.error = error;
this.message = message;
this.statusCode = statusCode;
this.headerNames = headerNames != null ? headerNames : new String[0];
this.headerValues = headerValues != null ? headerValues : new String[0];
this.body = body != null ? body : new byte[0];
}
}
private DuskHttpClient() {
}
public static Response get(String url, String[] headerNames, String[] headerValues,
int timeoutMs, long maxBodyBytes) {
if (url == null || url.isEmpty()) {
return fail(ERROR_INVALID_URL, "URL is empty");
}
try {
URL currentUrl = new URL(url);
if (!isHttps(currentUrl)) {
return fail(ERROR_UNSUPPORTED_SCHEME, "Only https:// URLs are supported");
}
for (int redirect = 0; redirect <= MAX_REDIRECTS; ++redirect) {
HttpsURLConnection connection =
(HttpsURLConnection) currentUrl.openConnection();
try {
connection.setRequestMethod("GET");
connection.setConnectTimeout(timeoutMs);
connection.setReadTimeout(timeoutMs);
connection.setUseCaches(false);
connection.setInstanceFollowRedirects(false);
applyHeaders(connection, headerNames, headerValues);
int statusCode = connection.getResponseCode();
if (isRedirect(statusCode)) {
String location = connection.getHeaderField("Location");
if (location == null || location.isEmpty()) {
return fail(ERROR_NETWORK, "Redirect response did not include Location",
statusCode, connection, new byte[0]);
}
URL nextUrl = new URL(currentUrl, location);
if (!isHttps(nextUrl)) {
return fail(ERROR_UNSUPPORTED_SCHEME,
"Only https:// redirects are supported", statusCode,
connection, new byte[0]);
}
currentUrl = nextUrl;
continue;
}
byte[] body = readBody(connection, statusCode, maxBodyBytes);
return success(statusCode, connection, body);
} catch (ResponseTooLargeException e) {
return fail(ERROR_TOO_LARGE, "Response body exceeded the configured limit",
safeStatusCode(connection), connection, e.partialBody);
} finally {
connection.disconnect();
}
}
return fail(ERROR_NETWORK, "Too many redirects");
} catch (MalformedURLException e) {
return fail(ERROR_INVALID_URL, "Failed to parse URL");
} catch (SocketTimeoutException e) {
return fail(ERROR_TIMEOUT, "Request timed out");
} catch (IOException e) {
String message = e.getMessage();
return fail(ERROR_NETWORK, message != null ? message : e.toString());
} catch (ClassCastException e) {
return fail(ERROR_UNSUPPORTED_SCHEME, "Only https:// URLs are supported");
}
}
private static void applyHeaders(HttpsURLConnection connection, String[] names,
String[] values) {
if (names == null || values == null) {
return;
}
int count = Math.min(names.length, values.length);
for (int i = 0; i < count; ++i) {
if (names[i] != null && values[i] != null) {
connection.setRequestProperty(names[i], values[i]);
}
}
}
private static boolean isHttps(URL url) {
return "https".equalsIgnoreCase(url.getProtocol());
}
private static boolean isRedirect(int statusCode) {
return statusCode == HttpURLConnection.HTTP_MOVED_PERM ||
statusCode == HttpURLConnection.HTTP_MOVED_TEMP ||
statusCode == HttpURLConnection.HTTP_SEE_OTHER ||
statusCode == 307 ||
statusCode == 308;
}
private static byte[] readBody(HttpsURLConnection connection, int statusCode,
long maxBodyBytes) throws IOException,
ResponseTooLargeException {
InputStream stream = statusCode >= HttpURLConnection.HTTP_BAD_REQUEST ?
connection.getErrorStream() : connection.getInputStream();
if (stream == null) {
return new byte[0];
}
try (InputStream bodyStream = stream;
ByteArrayOutputStream out = new ByteArrayOutputStream()) {
byte[] buffer = new byte[8192];
long total = 0;
while (true) {
int read = bodyStream.read(buffer);
if (read < 0) {
return out.toByteArray();
}
if (read == 0) {
continue;
}
if (read > maxBodyBytes || total > maxBodyBytes - read) {
throw new ResponseTooLargeException(out.toByteArray());
}
out.write(buffer, 0, read);
total += read;
}
}
}
private static int safeStatusCode(HttpsURLConnection connection) {
try {
return connection.getResponseCode();
} catch (IOException e) {
return 0;
}
}
private static Response success(int statusCode, HttpsURLConnection connection, byte[] body) {
HeaderLists headers = readHeaders(connection);
return new Response(ERROR_NONE, "", statusCode, headers.names, headers.values, body);
}
private static Response fail(int error, String message) {
return new Response(error, message, 0, null, null, null);
}
private static Response fail(int error, String message, int statusCode,
HttpsURLConnection connection, byte[] body) {
HeaderLists headers = readHeaders(connection);
return new Response(error, message, statusCode, headers.names, headers.values, body);
}
private static HeaderLists readHeaders(HttpsURLConnection connection) {
List<String> names = new ArrayList<>();
List<String> values = new ArrayList<>();
Map<String, List<String>> headerFields = connection.getHeaderFields();
if (headerFields == null) {
return new HeaderLists(new String[0], new String[0]);
}
for (Map.Entry<String, List<String>> entry : headerFields.entrySet()) {
String name = entry.getKey();
if (name == null) {
continue;
}
List<String> entryValues = entry.getValue();
if (entryValues == null || entryValues.isEmpty()) {
names.add(name);
values.add("");
continue;
}
for (String value : entryValues) {
names.add(name);
values.add(value != null ? value : "");
}
}
return new HeaderLists(names.toArray(new String[0]), values.toArray(new String[0]));
}
private static final class HeaderLists {
final String[] names;
final String[] values;
HeaderLists(String[] names, String[] values) {
this.names = names;
this.values = values;
}
}
private static final class ResponseTooLargeException extends Exception {
final byte[] partialBody;
ResponseTooLargeException(byte[] partialBody) {
this.partialBody = partialBody;
}
}
}
@@ -256,7 +256,6 @@ public class HIDDeviceManager {
0x24c6, // PowerA 0x24c6, // PowerA
0x2c22, // Qanba 0x2c22, // Qanba
0x2dc8, // 8BitDo 0x2dc8, // 8BitDo
0x37d7, // Flydigi
0x9886, // ASTRO Gaming 0x9886, // ASTRO Gaming
}; };
@@ -61,7 +61,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
private static final String TAG = "SDL"; private static final String TAG = "SDL";
private static final int SDL_MAJOR_VERSION = 3; private static final int SDL_MAJOR_VERSION = 3;
private static final int SDL_MINOR_VERSION = 4; private static final int SDL_MINOR_VERSION = 4;
private static final int SDL_MICRO_VERSION = 4; private static final int SDL_MICRO_VERSION = 2;
/* /*
// Display InputType.SOURCE/CLASS of events and devices // Display InputType.SOURCE/CLASS of events and devices
// //
@@ -2032,7 +2032,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
try { try {
ParcelFileDescriptor pfd = mSingleton.getContentResolver().openFileDescriptor(Uri.parse(uri), mode); ParcelFileDescriptor pfd = mSingleton.getContentResolver().openFileDescriptor(Uri.parse(uri), mode);
return pfd != null ? pfd.detachFd() : -1; return pfd != null ? pfd.detachFd() : -1;
} catch (FileNotFoundException | SecurityException e) { } catch (FileNotFoundException e) {
e.printStackTrace(); e.printStackTrace();
return -1; return -1;
} }
@@ -2227,3 +2227,4 @@ class SDLClipboardHandler implements
SDLActivity.onNativeClipboardChanged(); SDLActivity.onNativeClipboardChanged();
} }
} }
@@ -65,15 +65,17 @@ class SDLInputConnection extends BaseInputConnection
@Override @Override
public boolean deleteSurroundingText(int beforeLength, int afterLength) { public boolean deleteSurroundingText(int beforeLength, int afterLength) {
// Workaround to capture backspace key. Ref: http://stackoverflow.com/questions>/14560344/android-backspace-in-webview-baseinputconnection if (Build.VERSION.SDK_INT <= 29 /* Android 10.0 (Q) */) {
// and https://bugzilla.libsdl.org/show_bug.cgi?id=2265 // Workaround to capture backspace key. Ref: http://stackoverflow.com/questions>/14560344/android-backspace-in-webview-baseinputconnection
if (beforeLength > 0 && afterLength == 0) { // and https://bugzilla.libsdl.org/show_bug.cgi?id=2265
// backspace(s) if (beforeLength > 0 && afterLength == 0) {
while (beforeLength-- > 0) { // backspace(s)
nativeGenerateScancodeForUnichar('\b'); while (beforeLength-- > 0) {
} nativeGenerateScancodeForUnichar('\b');
return true; }
} return true;
}
}
if (!super.deleteSurroundingText(beforeLength, afterLength)) { if (!super.deleteSurroundingText(beforeLength, afterLength)) {
return false; return false;
@@ -35,8 +35,6 @@ public class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
View.OnApplyWindowInsetsListener, View.OnKeyListener, View.OnTouchListener, View.OnApplyWindowInsetsListener, View.OnKeyListener, View.OnTouchListener,
SensorEventListener, ScaleGestureDetector.OnScaleGestureListener { SensorEventListener, ScaleGestureDetector.OnScaleGestureListener {
private static native void auroraNativeSetSurfaceReady(boolean ready);
// Sensors // Sensors
protected SensorManager mSensorManager; protected SensorManager mSensorManager;
protected Display mDisplay; protected Display mDisplay;
@@ -98,7 +96,6 @@ public class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
@Override @Override
public void surfaceCreated(SurfaceHolder holder) { public void surfaceCreated(SurfaceHolder holder) {
Log.v("SDL", "surfaceCreated()"); Log.v("SDL", "surfaceCreated()");
auroraNativeSetSurfaceReady(false);
SDLActivity.onNativeSurfaceCreated(); SDLActivity.onNativeSurfaceCreated();
} }
@@ -106,7 +103,6 @@ public class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
@Override @Override
public void surfaceDestroyed(SurfaceHolder holder) { public void surfaceDestroyed(SurfaceHolder holder) {
Log.v("SDL", "surfaceDestroyed()"); Log.v("SDL", "surfaceDestroyed()");
auroraNativeSetSurfaceReady(false);
// Transition to pause, if needed // Transition to pause, if needed
SDLActivity.mNextNativeState = SDLActivity.NativeState.PAUSED; SDLActivity.mNextNativeState = SDLActivity.NativeState.PAUSED;
@@ -196,7 +192,6 @@ public class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
/* Surface is ready */ /* Surface is ready */
mIsSurfaceReady = true; mIsSurfaceReady = true;
auroraNativeSetSurfaceReady(true);
SDLActivity.mNextNativeState = SDLActivity.NativeState.RESUMED; SDLActivity.mNextNativeState = SDLActivity.NativeState.RESUMED;
SDLActivity.handleNativeState(); SDLActivity.handleNativeState();
+16 -35
View File
@@ -14,22 +14,9 @@ if [[ -z "$ANDROID_NDK_VER" ]] && [[ -d "$ANDROID_HOME_DIR/ndk" ]]; then
fi fi
if [[ -n "$ANDROID_NDK_VER" ]]; then if [[ -n "$ANDROID_NDK_VER" ]]; then
case "$(uname -s)" in TOOLCHAIN_BIN="$ANDROID_HOME_DIR/ndk/$ANDROID_NDK_VER/toolchains/llvm/prebuilt/linux-x86_64/bin"
Darwin) HOST_TAG="darwin-x86_64" ;; if [[ -x "$TOOLCHAIN_BIN/llvm-strip" ]]; then
Linux) HOST_TAG="linux-x86_64" ;; STRIP_TOOL="$TOOLCHAIN_BIN/llvm-strip"
*) HOST_TAG="" ;;
esac
PREBUILT_DIR="$ANDROID_HOME_DIR/ndk/$ANDROID_NDK_VER/toolchains/llvm/prebuilt"
if [[ -n "$HOST_TAG" && -x "$PREBUILT_DIR/$HOST_TAG/bin/llvm-strip" ]]; then
STRIP_TOOL="$PREBUILT_DIR/$HOST_TAG/bin/llvm-strip"
else
for candidate in "$PREBUILT_DIR"/*/bin/llvm-strip; do
if [[ -x "$candidate" ]]; then
STRIP_TOOL="$candidate"
break
fi
done
fi fi
fi fi
@@ -38,35 +25,29 @@ copy_lib() {
local src="$2" local src="$2"
local dst_dir="$APP_DIR/$abi" local dst_dir="$APP_DIR/$abi"
local dst="$dst_dir/libmain.so" local dst="$dst_dir/libmain.so"
local tmp="$dst_dir/.libmain.so.$$"
if [[ ! -f "$src" ]]; then
echo "Missing native library for $abi: $src" >&2
exit 1
fi
mkdir -p "$dst_dir" mkdir -p "$dst_dir"
cp -f "$src" "$tmp" cp -f "$src" "$dst"
if [[ "$ANDROID_STAGE_STRIP" != "0" ]] && [[ -n "$STRIP_TOOL" ]]; then if [[ "$ANDROID_STAGE_STRIP" != "0" ]] && [[ -n "$STRIP_TOOL" ]]; then
"$STRIP_TOOL" --strip-unneeded "$tmp" "$STRIP_TOOL" --strip-debug "$dst"
mv -f "$tmp" "$dst" echo "Staged and stripped $src -> $dst"
echo "Stripped and staged $src -> $dst"
else else
mv -f "$tmp" "$dst"
echo "Staged $src -> $dst (strip disabled or strip tool unavailable)" echo "Staged $src -> $dst (strip disabled or strip tool unavailable)"
fi fi
} }
declare -A ABI_TO_LIB=(
["arm64-v8a"]="$ROOT_DIR/build/android-arm64/libmain.so"
["x86_64"]="$ROOT_DIR/build/android-x86_64/libmain.so"
)
# Drop any previously staged ABI directories to avoid stale APK contents. # Drop any previously staged ABI directories to avoid stale APK contents.
rm -rf "$APP_DIR/x86" "$APP_DIR/arm64-v8a" "$APP_DIR/x86_64" rm -rf "$APP_DIR/x86" "$APP_DIR/arm64-v8a" "$APP_DIR/x86_64"
for abi in $ANDROID_STAGE_ABIS; do for abi in $ANDROID_STAGE_ABIS; do
case "$abi" in src="${ABI_TO_LIB[$abi]:-}"
arm64-v8a) src="$ROOT_DIR/build/android-arm64/libmain.so" ;; if [[ -z "$src" ]]; then
x86_64) src="$ROOT_DIR/build/android-x86_64/libmain.so" ;; echo "Unsupported ABI '$abi'. Supported ABIs: arm64-v8a x86_64" >&2
*) exit 1
echo "Unsupported ABI '$abi'. Supported ABIs: arm64-v8a x86_64" >&2 fi
exit 1
;;
esac
copy_lib "$abi" "$src" copy_lib "$abi" "$src"
done done
Binary file not shown.

Before

Width:  |  Height:  |  Size: 928 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 306 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1014 B

After

Width:  |  Height:  |  Size: 79 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 761 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 99 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 279 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 179 B

+1 -1
View File
@@ -6,4 +6,4 @@ Exec=dusk
Icon=dusk Icon=dusk
Terminal=false Terminal=false
Type=Application Type=Application
Categories=Game; Categories=Graphics;3DGraphics;Game
Binary file not shown.
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 95 KiB

+98 -242
View File
@@ -8,284 +8,140 @@ body {
height: 100%; height: 100%;
margin: 0; margin: 0;
padding: 0; padding: 0;
font-family: "Fira Sans"; font-family: "Fira Sans Condensed";
font-weight: normal; font-size: 24dp;
font-size: 20dp; color: #FFFFFF;
color: #E0DBC8;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: flex-end; justify-content: flex-end;
align-items: stretch; align-items: stretch;
z-index: 1;
pointer-events: none;
} }
fps, .overlay-root {
toast { width: 100%;
position: absolute; min-height: 45%;
border: 1dp #92875B;
background-color: rgba(21, 22, 16, 80%);
}
toast {
top: 40dp;
right: 40dp;
display: flex; display: flex;
flex-flow: column; flex-direction: column;
border-radius: 14dp; justify-content: flex-end;
overflow: hidden; align-items: stretch;
backdrop-filter: blur(5dp); decorator: vertical-gradient(#00000000 #151610F2);
box-shadow: 0 0 15dp 3dp; padding: 48dp 0 40dp 0;
filter: opacity(0); filter: opacity(0);
transform: scale(0.9); transition: filter 0.2s linear-in-out;
transform-origin: center;
transition: filter transform 0.2s cubic-in-out;
padding: 18dp 24dp;
gap: 8dp;
} }
toast[open] { .overlay-root[open] {
filter: opacity(1); filter: opacity(1);
transform: scale(1);
} }
/*toast:hover { .overlay {
cursor: pointer;
background-color: rgba(61, 59, 36, 80%);
}
toast:active {
background-color: rgba(45, 43, 26, 80%);
}*/
toast heading {
display: flex;
gap: 18dp;
align-items: center;
font-family: "Fira Sans Condensed";
font-size: 18dp;
font-weight: bold;
text-transform: uppercase;
color: #92875B;
}
toast heading > span {
flex: 1 0 auto;
}
toast heading > row {
flex: 1 0 auto;
display: flex;
align-items: center;
gap: 4dp;
}
toast message {
display: flex;
flex-flow: column;
gap: 8dp;
}
toast message row {
display: flex;
}
toast message row.muted {
opacity: 0.5;
}
toast progress {
height: 4dp;
position: absolute;
left: 0;
bottom: 0;
width: 100%; width: 100%;
max-width: 1216dp;
margin-left: auto;
margin-right: auto;
display: flex;
flex-direction: column;
gap: 24dp;
padding: 0 32dp;
} }
toast progress fill { @media (max-height: 800dp) {
background-color: rgba(194, 164, 45, 80%); .overlay-root {
min-height: 38%;
padding: 32dp 0 28dp 0;
}
.overlay {
gap: 16dp;
padding: 0 24dp;
}
} }
toast.achievement { .header {
border: 1dp #C2A42D; display: flex;
} justify-content: space-between;
toast.achievement heading {
color: #C2A42D;
}
toast.controller-warning {
top: auto;
right: auto;
bottom: 40dp;
left: 50%;
width: 440dp;
max-width: 90%;
transform: translateX(-50%) scale(0.9);
}
toast.controller-warning[open] {
transform: translateX(-50%) scale(1);
}
toast.controller-warning heading {
color: #C2A42D;
}
toast.menu-notification {
top: 40dp;
right: auto;
bottom: auto;
left: 50%;
max-width: 90%;
transform: translateX(-50%) scale(0.9);
}
toast.menu-notification[open] {
transform: translateX(-50%) scale(1);
}
toast.menu-notification message {
align-items: center; align-items: center;
text-align: center; gap: 24dp;
} }
toast.menu-notification message row { .carousel-container {
align-items: center; flex: 1 1 auto;
gap: 6dp; display: flex;
justify-content: flex-end;
min-width: 0;
} }
icon { .description {
font-family: "Material Symbols Rounded";
font-weight: normal;
display: inline-block;
vertical-align: middle;
}
icon.arrow-forward {
width: 1.2em;
height: 1.2em;
font-size: 1.2em;
decorator: text("&#xe5c8;" center center);
}
icon.trophy {
width: 1.2em;
height: 1.2em;
font-size: 1.2em;
decorator: text("&#xe71a;" center center);
}
icon.controller {
width: 1.2em;
height: 1.2em;
font-size: 1.2em;
decorator: text("&#xf135;" center center);
}
icon.warning {
width: 1.2em;
height: 1.2em;
font-size: 1.2em;
decorator: text("&#xe002;" center center);
}
fps {
display: none;
z-index: 99;
font-size: 18dp; font-size: 18dp;
font-weight: bold; line-height: 22dp;
padding: 9dp 12dp; color: rgba(255, 255, 255, 50%);
border-radius: 7dp;
pointer-events: none;
white-space: nowrap;
} }
fps[open] { .divider {
margin: 1dp 0;
border-top: 1dp rgba(217, 217, 217, 50%);
}
.footer {
display: flex;
justify-content: space-between;
align-items: center;
gap: 24dp;
}
footer-button {
display: block; display: block;
}
fps[corner=tl] {
top: 12dp;
left: 12dp;
}
fps[corner=tr] {
top: 12dp;
right: 12dp;
}
fps[corner=bl] {
bottom: 12dp;
left: 12dp;
}
fps[corner=br] {
bottom: 12dp;
right: 12dp;
}
logo {
position: absolute;
width: 100dp;
height: 100dp;
bottom: 40dp;
left: 40dp;
opacity: 0;
transition: opacity 0.5s linear-in-out;
}
logo[open] {
opacity: 0.65;
}
logo img {
position: absolute;
top: 0;
left: 0;
width: 100%; width: 100%;
height: 100%; max-width: 220dp;
filter: drop-shadow(#0008 0 0 14dp); border: 0;
transform-origin: center; padding: 0;
background-color: transparent;
font-family: "Fira Sans Condensed";
font-weight: bold;
font-size: 20dp;
line-height: 24dp;
text-transform: uppercase;
color: #FFFFFF;
opacity: 1;
cursor: pointer;
} }
logo img.inner { footer-button.return {
animation: 24s linear-in-out infinite logo-inner-spin; text-align: left;
} }
logo img.outer { footer-button.reset {
animation: 8s linear-in-out infinite logo-outer-spin; text-align: right;
} }
@keyframes logo-inner-spin { .stepped-carousel {
from { display: flex;
transform: rotate(360deg); align-items: center;
} justify-content: center;
to { gap: 16dp;
transform: rotate(0deg); width: auto;
} min-width: 246dp;
padding: 0;
background-color: transparent;
font-family: "Fira Sans Condensed";
font-weight: bold;
} }
@keyframes logo-outer-spin { .stepped-carousel-value {
from { line-height: 29dp;
transform: rotate(0deg); min-width: 166dp;
} text-align: center;
to { white-space: nowrap;
transform: rotate(360deg); opacity: 0.9;
}
} }
@media (max-height: 640dp) { .stepped-carousel-arrow {
toast { width: 24dp;
top: 20dp; height: 24dp;
right: 20dp; min-width: 24dp;
} padding: 0;
border: 0;
toast.controller-warning { background-color: transparent;
bottom: 20dp; opacity: 1;
} cursor: pointer;
toast.menu-notification {
top: 20dp;
}
} }
+20 -330
View File
@@ -9,44 +9,16 @@ body {
font-weight: normal; font-weight: normal;
font-size: 20dp; font-size: 20dp;
color: #FFFFFF; color: #FFFFFF;
filter: opacity(0); background-color: #000000;
transition: filter 1s 0.2s linear-in-out;
z-index: -1;
}
.gradient {
position: absolute;
width: 100%;
height: 100%;
/* The color gradient from the Figma bands really badly. A fully black gradient does as well, but not as badly. */
decorator: horizontal-gradient(#000000FF #00000000);
}
body.mirrored .gradient {
decorator: horizontal-gradient(#00000000 #000000FF);
}
.background {
position: absolute;
width: 100%;
height: 100%;
decorator: image(../prelaunch-bg.png cover left center); decorator: image(../prelaunch-bg.png cover left center);
opacity: 0; filter: opacity(0);
transition: opacity 1s linear-in-out; transition: filter 1s 0.1s linear-in-out;
} }
body[open] { body[open] {
filter: opacity(1); filter: opacity(1);
} }
body[open] .background {
opacity: 1;
}
body.disc-ready .background {
opacity: 0;
}
content { content {
display: block; display: block;
width: 100%; width: 100%;
@@ -62,7 +34,6 @@ content[open] {
menu { menu {
position: absolute; position: absolute;
left: 96dp; left: 96dp;
right: auto;
top: 50%; top: 50%;
transform: translateY(-50%); transform: translateY(-50%);
/* Scale based on a reference screen width, 428/1216 */ /* Scale based on a reference screen width, 428/1216 */
@@ -75,11 +46,6 @@ menu {
gap: 48dp; gap: 48dp;
} }
body.mirrored menu {
left: auto;
right: 96dp;
}
hero { hero {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -88,10 +54,6 @@ hero {
gap: 8dp; gap: 8dp;
} }
body.mirrored hero {
align-items: flex-end;
}
hero img { hero img {
width: 100%; width: 100%;
} }
@@ -116,7 +78,6 @@ hero img {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 12dp; gap: 12dp;
align-items: flex-start;
} }
#menu-list button { #menu-list button {
@@ -124,7 +85,6 @@ hero img {
height: 54dp; height: 54dp;
padding: 8dp 16dp; padding: 8dp 16dp;
border-radius: 8dp; border-radius: 8dp;
text-align: left;
text-transform: uppercase; text-transform: uppercase;
font-family: "Fira Sans Condensed"; font-family: "Fira Sans Condensed";
font-size: 32dp; font-size: 32dp;
@@ -134,14 +94,8 @@ hero img {
decorator: horizontal-gradient(#00000000 #00000000); decorator: horizontal-gradient(#00000000 #00000000);
} }
#menu-list button:disabled {
opacity: 0.75;
cursor: default;
decorator: horizontal-gradient(#00000000 #00000000);
}
#menu-list button.anim-done { #menu-list button.anim-done {
transition: decorator color opacity 0.1s linear-in-out; transition: decorator color 0.1s linear-in-out;
} }
#menu-list button:hover, #menu-list button:hover,
@@ -150,183 +104,52 @@ hero img {
decorator: horizontal-gradient(#FEE685FF #FEE68500); decorator: horizontal-gradient(#FEE685FF #FEE68500);
} }
body.mirrored #menu-list { disk-status {
align-items: flex-end;
}
body.mirrored #menu-list button {
text-align: right;
}
body.mirrored #menu-list button:hover,
body.mirrored #menu-list button:focus-visible {
decorator: horizontal-gradient(#FEE68500 #FEE685FF);
}
disc-info {
position: absolute; position: absolute;
left: 96dp; left: 96dp;
right: auto;
bottom: 72dp; bottom: 72dp;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 12dp; gap: 8dp;
font-size: 24dp;
font-effect: glow(0dp 4dp 0dp 4dp black);
text-align: left;
}
body.mirrored disc-info {
left: auto;
right: 96dp;
text-align: right;
} }
version-info { version-info {
position: absolute; position: absolute;
right: 96dp; right: 96dp;
left: auto;
bottom: 72dp; bottom: 72dp;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 12dp;
text-align: right;
font-size: 24dp;
font-effect: glow(0dp 4dp 0dp 4dp black);
text-align: right;
}
body.mirrored version-info {
right: auto;
left: 96dp;
text-align: left;
}
#disc-status {
display: flex;
align-items: center;
gap: 8dp; gap: 8dp;
text-align: right;
} }
#disc-status[status=good] { .status,
.version {
font-size: 24dp;
}
.status,
.update {
color: #D8F999; color: #D8F999;
} }
#disc-status[status=bad] { .status[bad] {
color: #FFC9C9; color: #FFC9C9;
} }
#disc-status[status=verifying] { /* TODO: Hidden until an actual update checker is introduced */
color: #FFFFFF;
}
#disc-status[status=mismatch] {
color: #FFD6A7;
}
#disc-status[status=unknown] {
color: rgba(224, 219, 200, 65%);
}
#disc-status[status=pending] {
color: #FEE685;
}
#disc-status icon {
display: none;
width: 24dp;
height: 24dp;
font-family: "Material Symbols Rounded";
font-weight: normal;
font-size: 24dp;
}
#disc-status[status] icon {
display: block;
}
#disc-status[status=good] icon {
decorator: text("&#xe5ca;" center center);
}
#disc-status[status=bad] icon {
decorator: text("&#xe5cd;" center center);
}
#disc-status[status=verifying] icon {
decorator: text("&#xe8b5;" center center);
}
#disc-status[status=mismatch] icon {
decorator: text("&#xe002;" center center);
}
#disc-status[status=unknown] icon {
decorator: text("&#xe887;" center center);
}
#disc-status[status=pending] icon {
decorator: text("&#xe863;" center center);
}
#disc-version {
font-size: 20dp;
}
.update { .update {
display: none; display: none;
color: #A6A09B; font-size: 16dp;
align-items: center;
justify-content: flex-end;
gap: 8dp;
font-size: 20dp;
}
.update[state=checking],
.update[state=failed] {
display: block;
}
.update[state=available] {
display: flex;
}
#update-download {
display: none;
margin: 0dp;
padding: 0dp;
border-width: 0dp;
background-color: transparent;
color: #D8F999;
cursor: pointer;
text-transform: uppercase;
font-weight: bold; font-weight: bold;
decorator: horizontal-gradient(#00000000 #00000000); cursor: pointer;
} }
.update[state=available] #update-download { .detail,
display: flex; .update span {
align-items: center;
gap: 2dp;
}
#update-download icon {
display: block;
width: 18dp;
height: 18dp;
font-family: "Material Symbols Rounded";
font-weight: normal;
decorator: text("&#xe5c8;" center center);
}
.detail {
color: #A6A09B; color: #A6A09B;
} }
body.mirrored .update {
justify-content: flex-start;
}
/* Startup animation */ /* Startup animation */
.intro-item { .intro-item {
opacity: 0; opacity: 0;
@@ -362,136 +185,3 @@ body.animate-in .intro-item {
.delay-5 { .delay-5 {
transition: opacity transform 0.3s 0.6s cubic-in-out; transition: opacity transform 0.3s 0.6s cubic-in-out;
} }
/* Mobile layout */
@media (max-height: 640dp) {
.gradient {
decorator: horizontal-gradient(#00000000 #000000FF);
}
body.mirrored .gradient {
decorator: horizontal-gradient(#000000FF #00000000);
}
menu {
left: 32dp;
right: 32dp;
width: auto;
min-width: 0;
max-width: none;
flex-direction: row;
align-items: center;
justify-content: space-between;
gap: 16dp;
}
body.mirrored menu {
left: 32dp;
right: 32dp;
flex-direction: row-reverse;
}
hero {
flex: 1 1 0;
min-width: 0;
max-width: 48%;
margin-left: 32dp;
}
body.mirrored hero {
align-items: flex-end;
}
hero img {
width: 100%;
}
#menu-list {
flex: 1 1 0;
min-width: 0;
max-width: 52%;
align-items: flex-end;
}
#menu-list button {
width: 100%;
max-width: 100%;
text-align: right;
}
#menu-list button:hover,
#menu-list button:focus-visible {
decorator: horizontal-gradient(#FEE68500 #FEE685FF);
}
body.mirrored #menu-list {
align-items: flex-start;
}
body.mirrored #menu-list button {
text-align: left;
}
body.mirrored #menu-list button:hover,
body.mirrored #menu-list button:focus-visible {
decorator: horizontal-gradient(#FEE685FF #FEE68500);
}
.eyebrow {
display: none;
}
disc-info {
right: 32dp;
left: auto;
bottom: 32dp;
top: auto;
text-align: right;
font-size: 16dp;
}
#disc-status {
justify-content: flex-end;
}
#disc-status icon {
font-size: 20dp;
}
#disc-version {
font-size: 16dp;
}
version-info {
right: 32dp;
left: auto;
bottom: auto;
top: 32dp;
text-align: right;
font-size: 16dp;
}
.update {
font-size: 16dp;
}
body.mirrored disc-info {
right: auto;
left: 32dp;
bottom: 32dp;
top: auto;
text-align: left;
}
body.mirrored version-info {
right: auto;
left: 32dp;
bottom: auto;
top: 32dp;
text-align: left;
}
body.mirrored #disc-status {
justify-content: flex-start;
}
}
-48
View File
@@ -1,21 +1,10 @@
tab-bar { tab-bar {
display: flex; display: flex;
position: relative;
min-width: 0; min-width: 0;
overflow: auto hidden; overflow: auto hidden;
clip: always;
text-transform: uppercase; text-transform: uppercase;
} }
tab-bar scrollbarhorizontal,
tab-bar scrollbarhorizontal sliderarrowdec,
tab-bar scrollbarhorizontal sliderarrowinc,
tab-bar scrollbarhorizontal slidertrack,
tab-bar scrollbarhorizontal sliderbar {
width: 0;
height: 0;
}
tab-bar tab { tab-bar tab {
flex: 0 0 auto; flex: 0 0 auto;
padding: 0 24dp; padding: 0 24dp;
@@ -42,40 +31,3 @@ tab-bar tab:hover {
tab-bar tab:active { tab-bar tab:active {
decorator: vertical-gradient(#c2a42d10 #c2a42d40); decorator: vertical-gradient(#c2a42d10 #c2a42d40);
} }
tab-bar[closable] tab-end-spacer {
display: block;
flex: 0 0 64dp;
width: 64dp;
pointer-events: none;
}
tab-bar[closable] close {
display: block;
position: fixed;
top: 8dp;
right: 8dp;
z-index: 1;
width: 48dp;
height: 48dp;
font-family: "Material Symbols Rounded";
font-weight: normal;
font-size: 24dp;
color: rgba(224, 219, 200, 70%);
backdrop-filter: blur(2dp);
border-radius: 6dp;
decorator: text("&#xe5cd;" center center);
transition: color background-color 0.12s linear-in-out;
cursor: pointer;
}
tab-bar[closable] close:hover,
tab-bar[closable] close:focus-visible {
color: #fff;
background-color: rgba(194, 164, 45, 24%);
}
tab-bar[closable] close:active {
color: #fff;
background-color: rgba(194, 164, 45, 40%);
}
-147
View File
@@ -1,147 +0,0 @@
*, *:before, *:after {
box-sizing: border-box;
}
body {
overflow: visible;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
font-family: "Fira Sans Condensed";
font-size: 24dp;
color: #FFFFFF;
display: flex;
flex-direction: column;
justify-content: flex-end;
align-items: stretch;
}
.tuner-root {
width: 100%;
min-height: 45%;
display: flex;
flex-direction: column;
justify-content: flex-end;
align-items: stretch;
decorator: vertical-gradient(#00000000 #151610F2);
filter: opacity(0);
transition: filter 0.2s linear-in-out;
}
.tuner-root[open] {
filter: opacity(1);
}
.tuner {
width: 100%;
max-width: 1216dp;
margin-left: auto;
margin-right: auto;
display: flex;
flex-direction: column;
gap: 24dp;
padding: 48dp 64dp;
}
@media (max-height: 800dp) {
.tuner-root {
min-height: 38%;
}
.tuner {
gap: 16dp;
padding: 32dp 48dp;
}
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
gap: 24dp;
}
.carousel-container {
flex: 1 1 auto;
display: flex;
justify-content: flex-end;
min-width: 0;
}
.description {
font-size: 18dp;
line-height: 22dp;
color: rgba(255, 255, 255, 50%);
}
.divider {
margin: 1dp 0;
border-top: 1dp rgba(217, 217, 217, 50%);
}
.footer {
display: flex;
justify-content: space-between;
align-items: center;
gap: 24dp;
}
footer-button {
display: block;
width: 100%;
max-width: 220dp;
border: 0;
padding: 0;
background-color: transparent;
font-family: "Fira Sans Condensed";
font-weight: bold;
font-size: 20dp;
line-height: 24dp;
text-transform: uppercase;
color: #FFFFFF;
opacity: 1;
cursor: pointer;
}
footer-button.return {
text-align: left;
}
footer-button.reset {
text-align: right;
}
.stepped-carousel {
display: flex;
align-items: center;
justify-content: center;
gap: 16dp;
width: auto;
min-width: 246dp;
padding: 0;
background-color: transparent;
font-family: "Fira Sans Condensed";
font-weight: bold;
}
.stepped-carousel-value {
line-height: 29dp;
min-width: 166dp;
text-align: center;
white-space: nowrap;
opacity: 0.9;
}
.stepped-carousel-arrow {
width: 24dp;
height: 24dp;
min-width: 24dp;
padding: 0;
border: 0;
background-color: transparent;
opacity: 1;
cursor: pointer;
font-family: "Material Symbols Rounded";
font-weight: normal;
}
+4 -271
View File
@@ -3,7 +3,6 @@
} }
body { body {
display: flex;
width: 100%; width: 100%;
height: 100%; height: 100%;
padding: 64dp; padding: 64dp;
@@ -17,9 +16,7 @@ body {
window { window {
display: flex; display: flex;
flex-flow: column; flex-flow: column;
position: relative;
height: 100%; height: 100%;
width: 100%;
max-width: 1088dp; max-width: 1088dp;
max-height: 768dp; max-height: 768dp;
margin: auto; margin: auto;
@@ -35,15 +32,6 @@ window {
transition: filter transform 0.2s cubic-in-out; transition: filter transform 0.2s cubic-in-out;
} }
window.small {
height: auto;
width: auto;
}
window.modal {
max-width: 640dp;
}
window[open] { window[open] {
filter: opacity(1); filter: opacity(1);
transform: scale(1); transform: scale(1);
@@ -74,7 +62,7 @@ window tab-bar tab {
window content { window content {
display: flex; display: flex;
flex: 1 1 auto; flex: 1 1 0;
min-width: 0; min-width: 0;
min-height: 0; min-height: 0;
overflow: hidden; overflow: hidden;
@@ -84,6 +72,7 @@ window content pane {
display: flex; display: flex;
flex-flow: column; flex-flow: column;
flex: 1 1 0; flex: 1 1 0;
height: 100%;
min-width: 0; min-width: 0;
min-height: 0; min-height: 0;
padding: 24dp; padding: 24dp;
@@ -101,10 +90,6 @@ window content pane > * {
flex: 0 0 auto; flex: 0 0 auto;
} }
window content pane:last-of-type > div {
line-height: 1.625;
}
window content pane > spacer { window content pane > spacer {
display: block; display: block;
/* Completes the 24dp bottom inset after the pane's 8dp gap. */ /* Completes the 24dp bottom inset after the pane's 8dp gap. */
@@ -199,11 +184,6 @@ button:not(:disabled):active {
box-shadow: #C2A42D 0 0 0 2dp; box-shadow: #C2A42D 0 0 0 2dp;
} }
button.modal-btn {
flex: 1 1 0;
text-align: center;
}
select-button { select-button {
display: flex; display: flex;
align-items: center; align-items: center;
@@ -245,262 +225,15 @@ select-button key {
font-weight: bold; font-weight: bold;
font-size: 18dp; font-size: 18dp;
text-transform: uppercase; text-transform: uppercase;
flex: 0 1 auto; flex: 1 0 auto;
} }
select-button value { select-button value {
flex: 1 1 auto; margin-left: auto;
text-align: right;
font-size: 20dp; font-size: 20dp;
} }
select-button value.modified {
font-weight: bold;
}
select-button input { select-button input {
text-align: right; text-align: right;
font-size: 20dp; font-size: 20dp;
} }
icon {
width: 1em;
height: 1em;
font-family: "Material Symbols Rounded";
font-weight: normal;
display: inline-block;
vertical-align: middle;
}
icon.warning {
decorator: text("&#xe002;" center center);
}
icon.error {
decorator: text("&#xe000;" center center);
}
icon.verifying {
decorator: text("&#xe8b5;" center center);
}
icon.celebration {
decorator: text("&#xea65;" center center);
}
icon.question-mark {
decorator: text("&#xeb8b;" center center);
}
.achievement-total {
position: absolute;
top: 0;
right: 64dp;
height: 64dp;
line-height: 64dp;
font-family: "Fira Sans Condensed";
font-weight: bold;
font-size: 16dp;
color: rgba(224, 219, 200, 55%);
pointer-events: none;
}
.achievement-row {
display: flex;
align-items: flex-start;
gap: 10dp;
padding: 12dp 0;
border-bottom: 1dp rgba(146, 135, 91, 30%);
}
.achievement-info {
display: block;
flex: 1 1 0;
min-width: 0;
}
.achievement-header {
display: flex;
align-items: center;
}
.achievement-name {
flex: 1;
font-weight: bold;
}
.achievement-name.unlocked {
color: #ffa826;
}
.achievement-badge {
font-size: 14dp;
opacity: 0.7;
}
.achievement-badge.unlocked {
color: #44cc55;
opacity: 1;
}
.achievement-badge.locked {
color: #cc4444;
opacity: 1;
}
.achievement-desc {
display: block;
color: rgba(224, 219, 200, 55%);
font-size: 16dp;
margin: 4dp 0 0 0;
}
.achievement-progress {
display: block;
font-size: 13dp;
color: rgba(224, 219, 200, 45%);
}
progress {
display: block;
width: 100%;
height: 6dp;
border-radius: 3dp;
background-color: rgba(255, 255, 255, 10%);
margin: 6dp 0 2dp 0;
}
progress.progress-done fill {
background-color: #44aa22;
border-radius: 3dp;
}
progress.progress-ongoing fill {
background-color: #2255bb;
border-radius: 3dp;
}
button.achievement-clear {
flex: 0 0 auto;
align-self: center;
font-size: 14dp;
padding: 2dp 8dp;
opacity: 0.45;
}
.preset-grid {
display: flex;
flex-direction: row;
gap: 20dp;
flex: 0 1 auto;
align-items: flex-start;
width: 100%;
}
.preset-col {
display: flex;
flex-flow: column;
gap: 12dp;
flex: 1 1 0;
}
.preset-desc {
display: block;
font-size: 16dp;
text-align: center;
}
.modal-dialog {
display: flex;
flex-direction: column;
align-items: flex-start;
padding: 24dp;
gap: 20dp;
flex: 0 1 auto;
width: 100%;
text-align: left;
}
window.modal.danger {
border: 2dp #852221;
}
.modal-header {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
width: 100%;
flex: 0 0 auto;
gap: 16dp;
}
.modal-header icon {
font-size: 24dp;
color: #92875B;
}
.modal-title {
display: block;
font-family: "Fira Sans Condensed";
font-weight: bold;
text-transform: uppercase;
font-size: 18dp;
color: #92875B;
flex: 1 1 auto;
}
window.modal.danger .modal-title,
window.modal.danger .modal-header icon {
color: #B3261E;
}
.modal-body {
display: block;
width: 100%;
flex: 0 1 auto;
min-width: 0;
font-size: 20dp;
color: #FFFFFF;
font-weight: normal;
}
.modal-body span.tip {
font-size: 14dp;
color: #92875B;
}
.verification-progress {
display: flex;
flex-direction: column;
gap: 10dp;
width: 100%;
}
.verification-file {
display: block;
font-size: 17dp;
color: #FFFFFF;
}
progress.verification-progress-bar {
height: 8dp;
margin: 2dp 0 0 0;
}
.verification-detail {
display: block;
font-size: 14dp;
color: rgba(224, 219, 200, 65%);
}
.modal-actions {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: stretch;
gap: 12dp;
width: 100%;
flex: 0 0 auto;
padding-top: 4dp;
}
-6
View File
@@ -2,7 +2,6 @@
#include "Z2AudioLib/Z2SoundInfo.h" #include "Z2AudioLib/Z2SoundInfo.h"
#if TARGET_PC #if TARGET_PC
#include "dusk/audio/DuskDsp.hpp" #include "dusk/audio/DuskDsp.hpp"
#include "dusk/settings.h"
#include <cmath> #include <cmath>
#endif #endif
#include "Z2AudioLib/Z2Calc.h" #include "Z2AudioLib/Z2Calc.h"
@@ -706,11 +705,6 @@ f32 Z2Audience::calcRelPosVolume(const Vec& param_0, f32 param_1, int camID) {
f32 Z2Audience::calcRelPosPan(const Vec& param_0, int camID) { f32 Z2Audience::calcRelPosPan(const Vec& param_0, int camID) {
Vec local_54 = param_0; Vec local_54 = param_0;
local_54.y = 0.0f; local_54.y = 0.0f;
#if TARGET_PC
if (dusk::getSettings().game.enableMirrorMode) {
local_54.x = -local_54.x;
}
#endif
f32 dVar6 = VECMag(&local_54); f32 dVar6 = VECMag(&local_54);
if (dVar6 < 0.1f) { if (dVar6 < 0.1f) {
-26
View File
@@ -51,7 +51,6 @@
#include "d/actor/d_a_ni.h" #include "d/actor/d_a_ni.h"
#include "d/d_s_play.h" #include "d/d_s_play.h"
#include "dusk/frame_interpolation.h"
#include "dusk/settings.h" #include "dusk/settings.h"
#include "res/Object/Alink.h" #include "res/Object/Alink.h"
#include <cstring> #include <cstring>
@@ -14788,10 +14787,6 @@ void daAlink_c::deleteEquipItem(BOOL i_isPlaySound, BOOL i_isDeleteKantera) {
mIronBallChainPos = NULL; mIronBallChainPos = NULL;
mIronBallChainAngle = NULL; mIronBallChainAngle = NULL;
field_0x3848 = NULL; field_0x3848 = NULL;
#if TARGET_PC
mIBChainInterpPrevValid = false;
mIBChainInterpCurrValid = false;
#endif
field_0x0774 = NULL; field_0x0774 = NULL;
field_0x0778 = NULL; field_0x0778 = NULL;
mpHookshotLinChk = NULL; mpHookshotLinChk = NULL;
@@ -19722,27 +19717,6 @@ int daAlink_c::draw() {
) )
{ {
dComIfGd_getOpaListDark()->entryImm(mpHookChain, 0); dComIfGd_getOpaListDark()->entryImm(mpHookChain, 0);
#if TARGET_PC
if (dusk::getSettings().game.enableFrameInterpolation &&
mEquipItem == dItemNo_IRONBALL_e &&
mIronBallChainPos != NULL && mIronBallChainAngle != NULL)
{
if (mIBChainInterpCurrValid) {
memcpy(mIBChainInterpPrevPos, mIBChainInterpCurrPos, IRON_BALL_CHAIN_COUNT * sizeof(cXyz));
memcpy(mIBChainInterpPrevAngle, mIBChainInterpCurrAngle, IRON_BALL_CHAIN_COUNT * sizeof(csXyz));
mIBChainInterpPrevHandRoot = mIBChainInterpCurrHandRoot;
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);
}
#endif
} }
} }
-3
View File
@@ -205,9 +205,6 @@ int daAlink_c::setDamagePoint(int i_dmgAmount, BOOL i_checkZoraMag, BOOL i_setDm
dComIfGp_setItemLifeCount(-i_dmgAmount, 0); dComIfGp_setItemLifeCount(-i_dmgAmount, 0);
} }
#if TARGET_PC
dusk::AchievementSystem::get().signal("player_damaged");
#endif
onResetFlg1(RFLG1_DAMAGE_IMPACT); onResetFlg1(RFLG1_DAMAGE_IMPACT);
mSwordUpTimer = 0; mSwordUpTimer = 0;
+20 -16
View File
@@ -44,14 +44,16 @@ void daAlink_c::handleWolfHowl() {
bool canHowl = false; bool canHowl = false;
if (mLinkAcch.ChkGroundHit() && !checkModeFlg(MODE_PLAYER_FLY) && !checkMagneBootsOn()) { if (mLinkAcch.ChkGroundHit() && !checkModeFlg(MODE_PLAYER_FLY) && !checkMagneBootsOn()) {
if (checkMidnaRide()) { if (!checkForestOldCentury()) {
if ((checkWolf() && if (checkMidnaRide()) {
(checkModeFlg(MODE_UNK_1000) || dComIfGp_checkPlayerStatus0(0, 0x10))) || if ((checkWolf() &&
(!checkWolf() && (checkModeFlg(MODE_UNK_1000) || dComIfGp_checkPlayerStatus0(0, 0x10))) ||
(checkEventRun() || getMidnaActor()->checkMetamorphoseEnable()) && (!checkWolf() &&
(checkModeFlg(4) || dComIfGp_checkPlayerStatus0(0, 0x10)))) (checkEventRun() || getMidnaActor()->checkMetamorphoseEnable()) &&
{ (checkModeFlg(4) || dComIfGp_checkPlayerStatus0(0, 0x10))))
canHowl = true; {
canHowl = true;
}
} }
} }
} }
@@ -122,14 +124,16 @@ 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()) { if (!checkForestOldCentury()) {
if ((checkWolf() && if (checkMidnaRide()) {
(checkModeFlg(MODE_UNK_1000) || dComIfGp_checkPlayerStatus0(0, 0x10))) || if ((checkWolf() &&
(!checkWolf() && (checkModeFlg(MODE_UNK_1000) || dComIfGp_checkPlayerStatus0(0, 0x10))) ||
(checkEventRun() || getMidnaActor()->checkMetamorphoseEnable()) && (!checkWolf() &&
(checkModeFlg(4) || dComIfGp_checkPlayerStatus0(0, 0x10)))) (checkEventRun() || getMidnaActor()->checkMetamorphoseEnable()) &&
{ (checkModeFlg(4) || dComIfGp_checkPlayerStatus0(0, 0x10))))
canTransform = true; {
canTransform = true;
}
} }
} }
} }
+6 -48
View File
@@ -8,8 +8,6 @@
#include "d/actor/d_a_obj_swhang.h" #include "d/actor/d_a_obj_swhang.h"
#include "d/actor/d_a_obj_chandelier.h" #include "d/actor/d_a_obj_chandelier.h"
#include "JSystem/J3DGraphBase/J3DMaterial.h" #include "JSystem/J3DGraphBase/J3DMaterial.h"
#include "dusk/frame_interpolation.h"
#include "dusk/settings.h"
enum { enum {
HS_MODE_NONE_e, HS_MODE_NONE_e,
@@ -19,11 +17,11 @@ enum {
HS_MODE_RETURN_e = 6, HS_MODE_RETURN_e = 6,
}; };
#if TARGET_PC
static const int HS_CHAIN_MAX_LINKS = 600;
#endif
void daAlink_c::hsChainShape_c::draw() { void daAlink_c::hsChainShape_c::draw() {
if (dusk::getSettings().game.superClawshot) {
return;
}
static const int dummy = 0; static const int dummy = 0;
daAlink_c* alink = (daAlink_c*)getUserArea(); daAlink_c* alink = (daAlink_c*)getUserArea();
@@ -167,11 +165,7 @@ void daAlink_c::hsChainShape_c::draw() {
} }
(void)0; (void)0;
#if TARGET_PC while (maxDistanceF > var_f30) {
int chainLinks = 0;
#endif
while (maxDistanceF > var_f30 IF_DUSK(&&chainLinks < HS_CHAIN_MAX_LINKS)) {
temp_f27 = var_f28 * cM_fsin(sp34 * var_f30); temp_f27 = var_f28 * cM_fsin(sp34 * var_f30);
s16 spC = cM_atan2s(temp_f27 - var_f26, 5.0f); s16 spC = cM_atan2s(temp_f27 - var_f26, 5.0f);
sp64.x = sp6C.x + spC; sp64.x = sp6C.x + spC;
@@ -193,10 +187,6 @@ void daAlink_c::hsChainShape_c::draw() {
var_f26 = temp_f27; var_f26 = temp_f27;
var_f30 += fabsf(cM_scos(spC)) * 5.0f; var_f30 += fabsf(cM_scos(spC)) * 5.0f;
#if TARGET_PC
chainLinks++;
#endif
} }
} }
@@ -212,11 +202,7 @@ void daAlink_c::hsChainShape_c::draw() {
sp98 = subChainTopPos; sp98 = subChainTopPos;
sp6C.set(maxDistance.atan2sY_XZ(), maxDistance.atan2sX_Z(), 0); sp6C.set(maxDistance.atan2sY_XZ(), maxDistance.atan2sX_Z(), 0);
#if TARGET_PC while (maxDistanceF > var_f30) {
int subChainLinks = 0;
#endif
while (maxDistanceF > var_f30 IF_DUSK(&&subChainLinks < HS_CHAIN_MAX_LINKS)) {
mDoMtx_stack_c::copy(j3dSys.getViewMtx()); mDoMtx_stack_c::copy(j3dSys.getViewMtx());
mDoMtx_stack_c::transM(sp98); mDoMtx_stack_c::transM(sp98);
mDoMtx_stack_c::ZXYrotM(sp6C); mDoMtx_stack_c::ZXYrotM(sp6C);
@@ -229,39 +215,11 @@ void daAlink_c::hsChainShape_c::draw() {
sp98 += maxDistance * 5.0f; sp98 += maxDistance * 5.0f;
ANGLE_ADD_2(sp6C.z, 0x3000); ANGLE_ADD_2(sp6C.z, 0x3000);
var_f30 += 5.0f; var_f30 += 5.0f;
#if TARGET_PC
subChainLinks++;
#endif
} }
} }
} }
} }
#if TARGET_PC
static void ironBallChainInterpCallback(bool isSimFrame, void* pUserWork) {
static_cast<daAlink_c*>(pUserWork)->onIronBallChainInterpCallback();
}
void daAlink_c::onIronBallChainInterpCallback() {
if (!mIBChainInterpPrevValid || !mIBChainInterpCurrValid) {
return;
}
if (mIronBallChainPos == NULL || mIronBallChainAngle == NULL) {
return;
}
const f32 alpha = dusk::frame_interp::get_interpolation_step();
for (int i = 0; i < IRON_BALL_CHAIN_COUNT; i++) {
mIronBallChainPos[i] = mIBChainInterpPrevPos[i] + (mIBChainInterpCurrPos[i] - mIBChainInterpPrevPos[i]) * alpha;
mIronBallChainAngle[i].x = mIBChainInterpPrevAngle[i].x + (s16)((s16)(mIBChainInterpCurrAngle[i].x - mIBChainInterpPrevAngle[i].x) * alpha);
mIronBallChainAngle[i].y = mIBChainInterpPrevAngle[i].y + (s16)((s16)(mIBChainInterpCurrAngle[i].y - mIBChainInterpPrevAngle[i].y) * alpha);
mIronBallChainAngle[i].z = mIBChainInterpPrevAngle[i].z + (s16)((s16)(mIBChainInterpCurrAngle[i].z - mIBChainInterpPrevAngle[i].z) * alpha);
}
mHookshotTopPos = mIBChainInterpPrevHandRoot + (mIBChainInterpCurrHandRoot - mIBChainInterpPrevHandRoot) * alpha;
}
#endif
void daAlink_c::hookshotAtHitCallBack(dCcD_GObjInf* i_atObjInf, fopAc_ac_c* i_tgActor, void daAlink_c::hookshotAtHitCallBack(dCcD_GObjInf* i_atObjInf, fopAc_ac_c* i_tgActor,
dCcD_GObjInf* i_tgObjInf) { dCcD_GObjInf* i_tgObjInf) {
if (i_tgActor != NULL && fopAcM_IsActor(i_tgActor) && !i_tgObjInf->ChkTgHookshotThrough()) { if (i_tgActor != NULL && fopAcM_IsActor(i_tgActor) && !i_tgObjInf->ChkTgHookshotThrough()) {
+2 -2
View File
@@ -2721,7 +2721,7 @@ int daAlink_c::procHorseRun() {
} }
if (mProcVar2.field_0x300c == 0) { if (mProcVar2.field_0x300c == 0) {
set3DStatus(BUTTON_STATUS_HOLD_ON, IF_DUSK(dusk::getSettings().game.enableMirrorMode ? 1 :) 4); set3DStatus(BUTTON_STATUS_HOLD_ON, 4);
} }
} else { } else {
if (mProcVar3.field_0x300e != 0) { if (mProcVar3.field_0x300e != 0) {
@@ -2731,7 +2731,7 @@ int daAlink_c::procHorseRun() {
} }
if (mProcVar2.field_0x300c == 0) { if (mProcVar2.field_0x300c == 0) {
set3DStatus(BUTTON_STATUS_HOLD_ON, IF_DUSK(dusk::getSettings().game.enableMirrorMode ? 4 :) 1); set3DStatus(BUTTON_STATUS_HOLD_ON, 1);
} }
} }
+1 -1
View File
@@ -41,7 +41,7 @@ void daAlink_c::setOriginalHeap(JKRExpHeap** i_ppheap, u32 i_size) {
u32 var_r28 = 0x10; u32 var_r28 = 0x10;
u32 size = ROUND(i_size, 16); u32 size = ROUND(i_size, 16);
#if TARGET_PC #if TARGET_PC
size *= 20; // Increase Link's heap size to prevent mods from crashing with higher-quality models. size *= 2;
#endif #endif
JKRHeap* parent = mDoExt_getGameHeap(); JKRHeap* parent = mDoExt_getGameHeap();
+1 -9
View File
@@ -17,9 +17,6 @@
#include "d/actor/d_a_e_pz.h" #include "d/actor/d_a_e_pz.h"
#include "d/actor/d_a_horse.h" #include "d/actor/d_a_horse.h"
#include "d/actor/d_a_hozelda.h" #include "d/actor/d_a_hozelda.h"
#if TARGET_PC
#include "dusk/achievements.h"
#endif
int daArrow_c::createHeap() { int daArrow_c::createHeap() {
J3DModelData* model_data; J3DModelData* model_data;
@@ -95,12 +92,7 @@ void daArrow_c::atHitCallBack(dCcD_GObjInf* i_atObjInf, fopAc_ac_c* i_tgActor, d
if (dist_to_hitpos < field_0x998) { if (dist_to_hitpos < field_0x998) {
field_0x998 = dist_to_hitpos; field_0x998 = dist_to_hitpos;
mHitAcID = fopAcM_GetID(i_tgActor); mHitAcID = fopAcM_GetID(i_tgActor);
#if TARGET_PC
if (fopAcM_GetGroup(i_tgActor) == fopAc_ENEMY_e &&
current.pos.abs(mStartPos) > 10000.0f) {
dusk::AchievementSystem::get().signal("arrow_hit_100m");
}
#endif
if (mArrowType == 1) { if (mArrowType == 1) {
field_0x9a8 = *hit_pos_p; field_0x9a8 = *hit_pos_p;
} else if (i_tgObjInf->ChkTgShield()) { } else if (i_tgObjInf->ChkTgShield()) {
-6
View File
@@ -19,9 +19,6 @@
#include "dusk/frame_interpolation.h" #include "dusk/frame_interpolation.h"
#include "dusk/settings.h" #include "dusk/settings.h"
#if TARGET_PC
#include "dusk/achievements.h"
#endif
class daB_GND_HIO_c : public JORReflexible { class daB_GND_HIO_c : public JORReflexible {
public: public:
@@ -1292,9 +1289,6 @@ static void b_gnd_g_wait(b_gnd_class* i_this) {
if (i_this->mMoveMode < 5 && i_this->mPlayerDistXZ < 600.0f) { if (i_this->mMoveMode < 5 && i_this->mPlayerDistXZ < 600.0f) {
i_this->mMoveMode = 5; i_this->mMoveMode = 5;
i_this->field_0xc44[0] = 10; i_this->field_0xc44[0] = 10;
#if TARGET_PC
dusk::AchievementSystem::get().signal("ganondorf_fishing_rod");
#endif
} }
} else if (i_this->mMoveMode == 5) { } else if (i_this->mMoveMode == 5) {
i_this->mMoveMode = 6; i_this->mMoveMode = 6;
-4
View File
@@ -254,11 +254,7 @@ BOOL daBdoor_c::checkArea() {
if (fabsf(vec.z) > 100.0f) { if (fabsf(vec.z) > 100.0f) {
return false; return false;
} }
#ifdef TARGET_PC
return (s16)((s32)fabs(current.angle.y - 0x7fff - player->current.angle.y) & 0xffff) <= 0x4000 ? 1 : 0;
#else
return (s16)fabs((f64)(current.angle.y - 0x7fff - player->current.angle.y)) <= 0x4000 ? 1 : 0; return (s16)fabs((f64)(current.angle.y - 0x7fff - player->current.angle.y)) <= 0x4000 ? 1 : 0;
#endif
} }
BOOL daBdoor_c::checkFront() { BOOL daBdoor_c::checkFront() {
-4
View File
@@ -825,11 +825,7 @@ int daBdoorL1_c::checkArea() {
if (fabsf(local_48.z) > 100.0f) { if (fabsf(local_48.z) > 100.0f) {
return 0; return 0;
} }
#ifdef TARGET_PC
if ((s16)((s32)fabs(current.angle.y - 0x7fff - player->current.angle.y) & 0xffff) <= 0x4000) {
#else
if ((s16)fabs((f64)(current.angle.y - 0x7fff - player->current.angle.y)) <= 0x4000) { if ((s16)fabs((f64)(current.angle.y - 0x7fff - player->current.angle.y)) <= 0x4000) {
#endif
return 1; return 1;
} else { } else {
return 0; return 0;
-4
View File
@@ -348,11 +348,7 @@ int daBdoorL5_c::checkArea() {
if (fabsf(local_48.z) > 100.0f) { if (fabsf(local_48.z) > 100.0f) {
return 0; return 0;
} }
#ifdef TARGET_PC
if ((s16)((s32)fabs(current.angle.y - 0x7fff - player->current.angle.y) & 0xffff) <= 0x4000) {
#else
if ((s16)fabs((f64)(current.angle.y - 0x7fff - player->current.angle.y)) <= 0x4000) { if ((s16)fabs((f64)(current.angle.y - 0x7fff - player->current.angle.y)) <= 0x4000) {
#endif
return 1; return 1;
} else { } else {
return 0; return 0;
-4
View File
@@ -1318,11 +1318,7 @@ int daMBdoorL1_c::checkArea() {
return 0; return 0;
} }
#ifdef TARGET_PC
if ((s16)((s32)fabs(angle - 0x7fff - player->current.angle.y) & 0xffff) > 0x4000) {
#else
if ((s16)fabs((f64)(angle - 0x7fff - player->current.angle.y)) > 0x4000) { if ((s16)fabs((f64)(angle - 0x7fff - player->current.angle.y)) > 0x4000) {
#endif
return 0; return 0;
} else { } else {
return 1; return 1;
-31
View File
@@ -10,10 +10,6 @@
#include "f_op/f_op_kankyo_mng.h" #include "f_op/f_op_kankyo_mng.h"
#include "f_op/f_op_actor_enemy.h" #include "f_op/f_op_actor_enemy.h"
#if TARGET_PC
#include "dusk/frame_interpolation.h"
#endif
class daE_DB_HIO_c : public JORReflexible { class daE_DB_HIO_c : public JORReflexible {
public: public:
daE_DB_HIO_c(); daE_DB_HIO_c();
@@ -70,22 +66,6 @@ static BOOL leaf_anm_init(e_db_class* i_this, int i_anm, f32 i_morf, u8 i_mode,
return FALSE; return FALSE;
} }
#if TARGET_PC
static void daE_DB_interp_callback(bool isSimFrame, void* pUserWork) {
e_db_class* i_this = (e_db_class*)pUserWork;
if (!i_this->mStalkLineInterpPrevValid || !i_this->mStalkLineInterpCurrValid) {
return;
}
const f32 alpha = dusk::frame_interp::get_interpolation_step();
cXyz* dst = i_this->stalkLine.getPos(0);
for (int i = 0; i < 12; i++) {
const cXyz& p0 = i_this->mStalkLineInterpPrev[i];
const cXyz& p1 = i_this->mStalkLineInterpCurr[i];
dst[i] = p0 + (p1 - p0) * alpha;
}
}
#endif
static int daE_DB_Draw(e_db_class* i_this) { static int daE_DB_Draw(e_db_class* i_this) {
fopAc_ac_c* actor = &i_this->enemy; fopAc_ac_c* actor = &i_this->enemy;
@@ -115,17 +95,6 @@ static int daE_DB_Draw(e_db_class* i_this) {
static GXColor l_color = {0x14, 0x0F, 0x00, 0xFF}; static GXColor l_color = {0x14, 0x0F, 0x00, 0xFF};
i_this->stalkLine.update(12, l_color, &actor->tevStr); i_this->stalkLine.update(12, l_color, &actor->tevStr);
dComIfGd_set3DlineMat(&i_this->stalkLine); dComIfGd_set3DlineMat(&i_this->stalkLine);
#if TARGET_PC
if (dusk::getSettings().game.enableFrameInterpolation) {
if (i_this->mStalkLineInterpCurrValid) {
memcpy(i_this->mStalkLineInterpPrev, i_this->mStalkLineInterpCurr, sizeof(i_this->mStalkLineInterpCurr));
i_this->mStalkLineInterpPrevValid = true;
}
memcpy(i_this->mStalkLineInterpCurr, i_this->stalkLine.getPos(0), 12 * sizeof(cXyz));
i_this->mStalkLineInterpCurrValid = true;
dusk::frame_interp::add_interpolation_callback(&daE_DB_interp_callback, i_this);
}
#endif
for (int i = 1; i < 11; i++) { for (int i = 1; i < 11; i++) {
if (i_this->thornModel[i] != NULL) { if (i_this->thornModel[i] != NULL) {
-31
View File
@@ -9,10 +9,6 @@
#include "d/actor/d_a_e_hb_leaf.h" #include "d/actor/d_a_e_hb_leaf.h"
#include "f_op/f_op_actor_enemy.h" #include "f_op/f_op_actor_enemy.h"
#if TARGET_PC
#include "dusk/frame_interpolation.h"
#endif
enum daE_HB_ACTION { enum daE_HB_ACTION {
ACTION_STAY, ACTION_STAY,
ACTION_APPEAR, ACTION_APPEAR,
@@ -68,22 +64,6 @@ static BOOL leaf_anm_init(e_hb_class* i_this, int i_anm, f32 i_morf, u8 i_mode,
return FALSE; return FALSE;
} }
#if TARGET_PC
static void daE_HB_interp_callback(bool isSimFrame, void* pUserWork) {
e_hb_class* i_this = (e_hb_class*)pUserWork;
if (!i_this->mStalkLineInterpPrevValid || !i_this->mStalkLineInterpCurrValid) {
return;
}
const f32 alpha = dusk::frame_interp::get_interpolation_step();
cXyz* dst = i_this->stalkLine.getPos(0);
for (int i = 0; i < 12; i++) {
const cXyz& p0 = i_this->mStalkLineInterpPrev[i];
const cXyz& p1 = i_this->mStalkLineInterpCurr[i];
dst[i] = p0 + (p1 - p0) * alpha;
}
}
#endif
static int daE_HB_Draw(e_hb_class* i_this) { static int daE_HB_Draw(e_hb_class* i_this) {
fopAc_ac_c* actor = &i_this->enemy; fopAc_ac_c* actor = &i_this->enemy;
@@ -102,17 +82,6 @@ static int daE_HB_Draw(e_hb_class* i_this) {
static GXColor l_color = {0x14, 0x0F, 0x00, 0xFF}; static GXColor l_color = {0x14, 0x0F, 0x00, 0xFF};
i_this->stalkLine.update(12, l_color, &actor->tevStr); i_this->stalkLine.update(12, l_color, &actor->tevStr);
dComIfGd_set3DlineMat(&i_this->stalkLine); dComIfGd_set3DlineMat(&i_this->stalkLine);
#if TARGET_PC
if (dusk::getSettings().game.enableFrameInterpolation) {
if (i_this->mStalkLineInterpCurrValid) {
memcpy(i_this->mStalkLineInterpPrev, i_this->mStalkLineInterpCurr, sizeof(i_this->mStalkLineInterpCurr));
i_this->mStalkLineInterpPrevValid = true;
}
memcpy(i_this->mStalkLineInterpCurr, i_this->stalkLine.getPos(0), 12 * sizeof(cXyz));
i_this->mStalkLineInterpCurrValid = true;
dusk::frame_interp::add_interpolation_callback(&daE_HB_interp_callback, i_this);
}
#endif
for (int i = 1; i < 11; i++) { for (int i = 1; i < 11; i++) {
if (i_this->thornModel[i] != NULL) { if (i_this->thornModel[i] != NULL) {
-6
View File
@@ -517,12 +517,6 @@ void daE_OctBg_c::core_fish_attack() {
field_0xbaf = cM_rndFX(80.0f) + 100.0f; field_0xbaf = cM_rndFX(80.0f) + 100.0f;
} }
} }
#if AVOID_UB
else {
in_f31 = cM_rndF(400.0f) + 80.0f;
field_0xbaf = cM_rndFX(80.0f) + 100.0f;
}
#endif
} else if (current.pos.abs(cStack_5c) < 400.0f) { } else if (current.pos.abs(cStack_5c) < 400.0f) {
in_f31 = cM_rndF(50.0f) + 20.0f; in_f31 = cM_rndF(50.0f) + 20.0f;
field_0xbaf = cM_rndFX(20.0f) + 40.0f; field_0xbaf = cM_rndFX(20.0f) + 40.0f;
-42
View File
@@ -14,8 +14,6 @@
#include "d/d_s_play.h" #include "d/d_s_play.h"
#include "f_op/f_op_actor_enemy.h" #include "f_op/f_op_actor_enemy.h"
#include "f_op/f_op_camera_mng.h" #include "f_op/f_op_camera_mng.h"
#include "dusk/frame_interpolation.h"
#include "dusk/settings.h"
#include <cstring> #include <cstring>
class daE_S1_HIO_c { class daE_S1_HIO_c {
@@ -101,25 +99,6 @@ static void anm_init(e_s1_class* i_this, int i_resNo, f32 i_morf, u8 i_attr, f32
i_this->mAnm = i_resNo; i_this->mAnm = i_resNo;
} }
#if TARGET_PC
static void daE_S1_interp_callback(bool isSimFrame, void* pUserWork) {
e_s1_class* i_this = (e_s1_class*)pUserWork;
if (!i_this->mHairInterpPrevValid || !i_this->mHairInterpCurrValid) {
return;
}
const f32 alpha = dusk::frame_interp::get_interpolation_step();
for (int s = 0; s < e_s1_class::HAIR_STRAND_COUNT; s++) {
cXyz* dst = i_this->mLineMat.getPos(s);
for (int i = 0; i < e_s1_class::HAIR_SEGMENT_COUNT; i++) {
int idx = s * e_s1_class::HAIR_SEGMENT_COUNT + i;
const cXyz& p0 = i_this->mHairInterpPrev[idx];
const cXyz& p1 = i_this->mHairInterpCurr[idx];
dst[i] = p0 + (p1 - p0) * alpha;
}
}
}
#endif
static int daE_S1_Draw(e_s1_class* i_this) { static int daE_S1_Draw(e_s1_class* i_this) {
if (i_this->field_0x306c != 0) { if (i_this->field_0x306c != 0) {
return 1; return 1;
@@ -153,22 +132,6 @@ static int daE_S1_Draw(e_s1_class* i_this) {
i_this->mLineMat.update(16, line_color, &i_this->tevStr); i_this->mLineMat.update(16, line_color, &i_this->tevStr);
dComIfGd_set3DlineMatDark(&i_this->mLineMat); dComIfGd_set3DlineMatDark(&i_this->mLineMat);
#if TARGET_PC
if (dusk::getSettings().game.enableFrameInterpolation) {
if (i_this->mHairInterpCurrValid) {
memcpy(i_this->mHairInterpPrev, i_this->mHairInterpCurr, sizeof(i_this->mHairInterpCurr));
i_this->mHairInterpPrevValid = true;
}
for (int s = 0; s < e_s1_class::HAIR_STRAND_COUNT; s++) {
cXyz* src = i_this->mLineMat.getPos(s);
memcpy(&i_this->mHairInterpCurr[s * e_s1_class::HAIR_SEGMENT_COUNT], src,
e_s1_class::HAIR_SEGMENT_COUNT * sizeof(cXyz));
}
i_this->mHairInterpCurrValid = true;
dusk::frame_interp::add_interpolation_callback(&daE_S1_interp_callback, i_this);
}
#endif
dComIfGd_setList(); dComIfGd_setList();
return 1; return 1;
} }
@@ -2186,11 +2149,6 @@ static int daE_S1_Create(fopAc_ac_c* i_this) {
return cPhs_ERROR_e; return cPhs_ERROR_e;
} }
#if TARGET_PC
a_this->mHairInterpPrevValid = false;
a_this->mHairInterpCurrValid = false;
#endif
OS_REPORT("//////////////E_S1 SET 2 !!\n"); OS_REPORT("//////////////E_S1 SET 2 !!\n");
if (path_no != 0xFF) { if (path_no != 0xFF) {
-9
View File
@@ -12,9 +12,6 @@
#include "c/c_damagereaction.h" #include "c/c_damagereaction.h"
#include "f_op/f_op_actor_enemy.h" #include "f_op/f_op_actor_enemy.h"
#include "f_op/f_op_camera_mng.h" #include "f_op/f_op_camera_mng.h"
#if TARGET_PC
#include "dusk/achievements.h"
#endif
class daE_TH_HIO_c : public JORReflexible { class daE_TH_HIO_c : public JORReflexible {
public: public:
@@ -545,7 +542,6 @@ static void damage_check(e_th_class* i_this) {
if (i_this->field_0x6a4 == 0 && i_this->mAction != ACTION_SPIN) { if (i_this->field_0x6a4 == 0 && i_this->mAction != ACTION_SPIN) {
daPy_py_c* player = (daPy_py_c*)dComIfGp_getPlayer(0); daPy_py_c* player = (daPy_py_c*)dComIfGp_getPlayer(0);
OS_REPORT("E_th HP1 %d\n", i_this->health); OS_REPORT("E_th HP1 %d\n", i_this->health);
s16 prevHealth = i_this->health;
cc_at_check(i_this, &i_this->mAtInfo); cc_at_check(i_this, &i_this->mAtInfo);
OS_REPORT("E_th HP2 %d\n", i_this->health); OS_REPORT("E_th HP2 %d\n", i_this->health);
@@ -558,11 +554,6 @@ static void damage_check(e_th_class* i_this) {
dComIfGs_onOneZoneSwitch(3, -1); dComIfGs_onOneZoneSwitch(3, -1);
if (i_this->health <= 0) { if (i_this->health <= 0) {
#if TARGET_PC
if (prevHealth == i_this->field_0x560) {
dusk::AchievementSystem::get().signal("dark_hammer_one_hit");
}
#endif
i_this->mAction = ACTION_END; i_this->mAction = ACTION_END;
i_this->mMode = 0; i_this->mMode = 0;
i_this->field_0x68a |= 4; i_this->field_0x68a |= 4;
-2
View File
@@ -5852,8 +5852,6 @@ static int daE_WB_Create(fopAc_ac_c* actor) {
daE_WB_Execute(i_this); daE_WB_Execute(i_this);
c_start = 0; c_start = 0;
// Note: this flag makes king bulblin 1 instant die when set, as it only requires 2 laps
// for insta-kill to trigger.
if (dComIfGs_isEventBit(dSv_event_flag_c::saveBitLabels[88])) { if (dComIfGs_isEventBit(dSv_event_flag_c::saveBitLabels[88])) {
i_this->lap_num = 1; i_this->lap_num = 1;
} }
-31
View File
@@ -12,10 +12,6 @@
#include "d/d_cc_uty.h" #include "d/d_cc_uty.h"
#include "f_op/f_op_actor_enemy.h" #include "f_op/f_op_actor_enemy.h"
#if TARGET_PC
#include "dusk/frame_interpolation.h"
#endif
class daE_YD_HIO_c { class daE_YD_HIO_c {
public: public:
daE_YD_HIO_c(); daE_YD_HIO_c();
@@ -77,22 +73,6 @@ static s32 leaf_anm_init(e_yd_class* i_this, int param_1, f32 param_2, u8 param_
return false; return false;
} }
#if TARGET_PC
static void daE_YD_interp_callback(bool isSimFrame, void* pUserWork) {
e_yd_class* i_this = (e_yd_class*)pUserWork;
if (!i_this->mLineMatInterpPrevValid || !i_this->mLineMatInterpCurrValid) {
return;
}
const f32 alpha = dusk::frame_interp::get_interpolation_step();
cXyz* dst = i_this->mLineMat.getPos(0);
for (int i = 0; i < 12; i++) {
const cXyz& p0 = i_this->mLineMatInterpPrev[i];
const cXyz& p1 = i_this->mLineMatInterpCurr[i];
dst[i] = p0 + (p1 - p0) * alpha;
}
}
#endif
static s32 daE_YD_Draw(e_yd_class* i_this) { static s32 daE_YD_Draw(e_yd_class* i_this) {
static GXColor l_color = { 0x14, 0x0F, 0x00, 0xFF }; static GXColor l_color = { 0x14, 0x0F, 0x00, 0xFF };
@@ -106,17 +86,6 @@ static s32 daE_YD_Draw(e_yd_class* i_this) {
i_this->mpMorf->entryDL(); i_this->mpMorf->entryDL();
i_this->mLineMat.update(12, l_color, &i_this->actor.tevStr); i_this->mLineMat.update(12, l_color, &i_this->actor.tevStr);
dComIfGd_set3DlineMat(&i_this->mLineMat); dComIfGd_set3DlineMat(&i_this->mLineMat);
#if TARGET_PC
if (dusk::getSettings().game.enableFrameInterpolation) {
if (i_this->mLineMatInterpCurrValid) {
memcpy(i_this->mLineMatInterpPrev, i_this->mLineMatInterpCurr, sizeof(i_this->mLineMatInterpCurr));
i_this->mLineMatInterpPrevValid = true;
}
memcpy(i_this->mLineMatInterpCurr, i_this->mLineMat.getPos(0), 12 * sizeof(cXyz));
i_this->mLineMatInterpCurrValid = true;
dusk::frame_interp::add_interpolation_callback(&daE_YD_interp_callback, i_this);
}
#endif
for (s32 i = 1; i < 11; i++) { for (s32 i = 1; i < 11; i++) {
if (i_this->field_0x77c[i] != 0) { if (i_this->field_0x77c[i] != 0) {
g_env_light.setLightTevColorType_MAJI(i_this->field_0x77c[i], &i_this->actor.tevStr); g_env_light.setLightTevColorType_MAJI(i_this->field_0x77c[i], &i_this->actor.tevStr);
-43
View File
@@ -10,8 +10,6 @@
#include "f_op/f_op_kankyo_mng.h" #include "f_op/f_op_kankyo_mng.h"
#include "d/actor/d_a_obj_carry.h" #include "d/actor/d_a_obj_carry.h"
#include "Z2AudioLib/Z2Instances.h" #include "Z2AudioLib/Z2Instances.h"
#include "dusk/frame_interpolation.h"
#include "dusk/settings.h"
#include "f_op/f_op_actor_enemy.h" #include "f_op/f_op_actor_enemy.h"
enum E_yg_RES_File_ID { enum E_yg_RES_File_ID {
@@ -136,25 +134,6 @@ static BOOL pl_check(e_yg_class* i_this, f32 i_dist) {
return FALSE; return FALSE;
} }
#if TARGET_PC
static void daE_YG_interp_callback(bool isSimFrame, void* pUserWork) {
e_yg_class* i_this = (e_yg_class*)pUserWork;
if (!i_this->mTentacleInterpPrevValid || !i_this->mTentacleInterpCurrValid) {
return;
}
const f32 alpha = dusk::frame_interp::get_interpolation_step();
for (int s = 0; s < e_yg_class::TENTACLE_STRAND_COUNT; s++) {
cXyz* dst = i_this->mLineMat.getPos(s);
for (int i = 0; i < e_yg_class::TENTACLE_SEGMENT_COUNT; i++) {
int idx = s * e_yg_class::TENTACLE_SEGMENT_COUNT + i;
const cXyz& p0 = i_this->mTentacleInterpPrev[idx];
const cXyz& p1 = i_this->mTentacleInterpCurr[idx];
dst[i] = p0 + (p1 - p0) * alpha;
}
}
}
#endif
static int daE_YG_Draw(e_yg_class* i_this) { static int daE_YG_Draw(e_yg_class* i_this) {
if (i_this->mDispFlag) { if (i_this->mDispFlag) {
return 1; return 1;
@@ -181,23 +160,6 @@ static int daE_YG_Draw(e_yg_class* i_this) {
color.a = 0xFF; color.a = 0xFF;
i_this->mLineMat.update(10, color, &actor->tevStr); i_this->mLineMat.update(10, color, &actor->tevStr);
dComIfGd_set3DlineMatDark(&i_this->mLineMat); dComIfGd_set3DlineMatDark(&i_this->mLineMat);
#if TARGET_PC
if (dusk::getSettings().game.enableFrameInterpolation) {
if (i_this->mTentacleInterpCurrValid) {
memcpy(i_this->mTentacleInterpPrev, i_this->mTentacleInterpCurr, sizeof(i_this->mTentacleInterpCurr));
i_this->mTentacleInterpPrevValid = true;
}
for (int s = 0; s < e_yg_class::TENTACLE_STRAND_COUNT; s++) {
cXyz* src = i_this->mLineMat.getPos(s);
memcpy(&i_this->mTentacleInterpCurr[s * e_yg_class::TENTACLE_SEGMENT_COUNT], src,
e_yg_class::TENTACLE_SEGMENT_COUNT * sizeof(cXyz));
}
i_this->mTentacleInterpCurrValid = true;
dusk::frame_interp::add_interpolation_callback(&daE_YG_interp_callback, i_this);
}
#endif
dComIfGd_setList(); dComIfGd_setList();
return 1; return 1;
@@ -1416,11 +1378,6 @@ static cPhs_Step daE_YG_Create(fopAc_ac_c* actor) {
return cPhs_ERROR_e; return cPhs_ERROR_e;
} }
#if TARGET_PC
i_this->mTentacleInterpPrevValid = false;
i_this->mTentacleInterpCurrValid = false;
#endif
if (!hio_set) { if (!hio_set) {
i_this->mIsFirstSpawn = 1; i_this->mIsFirstSpawn = 1;
hio_set = true; hio_set = true;
-31
View File
@@ -12,10 +12,6 @@
#include "f_op/f_op_actor_enemy.h" #include "f_op/f_op_actor_enemy.h"
#include "f_op/f_op_kankyo_mng.h" #include "f_op/f_op_kankyo_mng.h"
#if TARGET_PC
#include "dusk/frame_interpolation.h"
#endif
class daE_YH_HIO_c : public JORReflexible { class daE_YH_HIO_c : public JORReflexible {
public: public:
daE_YH_HIO_c(); daE_YH_HIO_c();
@@ -89,22 +85,6 @@ static BOOL leaf_anm_init(e_yh_class* i_this, int param_2, f32 param_3, u8 param
return FALSE; return FALSE;
} }
#if TARGET_PC
static void daE_YH_interp_callback(bool isSimFrame, void* pUserWork) {
e_yh_class* i_this = (e_yh_class*)pUserWork;
if (!i_this->mLineInterpPrevValid || !i_this->mLineInterpCurrValid) {
return;
}
const f32 alpha = dusk::frame_interp::get_interpolation_step();
cXyz* dst = i_this->mLine.getPos(0);
for (int i = 0; i < 12; i++) {
const cXyz& p0 = i_this->mLineInterpPrev[i];
const cXyz& p1 = i_this->mLineInterpCurr[i];
dst[i] = p0 + (p1 - p0) * alpha;
}
}
#endif
static int daE_YH_Draw(e_yh_class* i_this) { static int daE_YH_Draw(e_yh_class* i_this) {
fopAc_ac_c* a_this = (fopAc_ac_c*)i_this; fopAc_ac_c* a_this = (fopAc_ac_c*)i_this;
@@ -134,17 +114,6 @@ static int daE_YH_Draw(e_yh_class* i_this) {
i_this->mLine.update(12, l_color, &a_this->tevStr); i_this->mLine.update(12, l_color, &a_this->tevStr);
dComIfGd_set3DlineMat(&i_this->mLine); dComIfGd_set3DlineMat(&i_this->mLine);
#if TARGET_PC
if (dusk::getSettings().game.enableFrameInterpolation) {
if (i_this->mLineInterpCurrValid) {
memcpy(i_this->mLineInterpPrev, i_this->mLineInterpCurr, sizeof(i_this->mLineInterpCurr));
i_this->mLineInterpPrevValid = true;
}
memcpy(i_this->mLineInterpCurr, i_this->mLine.getPos(0), 12 * sizeof(cXyz));
i_this->mLineInterpCurrValid = true;
dusk::frame_interp::add_interpolation_callback(&daE_YH_interp_callback, i_this);
}
#endif
for (int i = 1; i < 11; i++) { for (int i = 1; i < 11; i++) {
if (i_this->mModels[i] != NULL) { if (i_this->mModels[i] != NULL) {
-8
View File
@@ -3519,15 +3519,7 @@ void daKago_c::action() {
checkSizeBg(); checkSizeBg();
setFlyEffect(); setFlyEffect();
#if TARGET_PC
if (dusk::getSettings().game.enableMirrorMode) {
mStickX = -mDoCPd_c::getStickX3D(PAD_1);
} else {
mStickX = mDoCPd_c::getStickX3D(PAD_1);
}
#else
mStickX = mDoCPd_c::getStickX3D(PAD_1); mStickX = mDoCPd_c::getStickX3D(PAD_1);
#endif
mStickY = mDoCPd_c::getStickY(PAD_1); mStickY = mDoCPd_c::getStickY(PAD_1);
u8 prevIsWaterfall = mIsWaterfall; u8 prevIsWaterfall = mIsWaterfall;
+3 -5
View File
@@ -729,12 +729,10 @@ static void koro2_game(fshop_class* i_this) {
cLib_addCalcAngleS2(&i_this->field_0x4020.z, 0, 2, 0x200); cLib_addCalcAngleS2(&i_this->field_0x4020.z, 0, 2, 0x200);
case 2: case 2:
#if TARGET_PC #if TARGET_PC
if (dusk::gyro::rollgoal_gyro_enabled()) { if (dusk::getSettings().game.enableGyroRollgoal) {
if (!dusk::gyro::get_sensor_keep_alive()) { if (!dusk::gyro::get_sensor_keep_alive()) {
dusk::gyro::set_sensor_keep_alive(true); dusk::gyro::set_sensor_keep_alive(true);
} }
} else if (dusk::gyro::get_sensor_keep_alive()) {
dusk::gyro::set_sensor_keep_alive(false);
} }
#endif #endif
@@ -755,7 +753,7 @@ static void koro2_game(fshop_class* i_this) {
old_stick_x = mDoCPd_c::getSubStickX(PAD_1); old_stick_x = mDoCPd_c::getSubStickX(PAD_1);
cLib_addCalcAngleS2(&i_this->field_0x4060, i_this->field_0x4062, 4, 0x1000); cLib_addCalcAngleS2(&i_this->field_0x4060, i_this->field_0x4062, 4, 0x1000);
#if TARGET_PC #if TARGET_PC
if (dusk::gyro::rollgoal_gyro_enabled()) { if (dusk::getSettings().game.enableGyroRollgoal) {
dusk::gyro::rollgoalTick(true, i_this->field_0x4060); dusk::gyro::rollgoalTick(true, i_this->field_0x4060);
} }
#endif #endif
@@ -793,7 +791,7 @@ static void koro2_game(fshop_class* i_this) {
s16 gyro_ax = 0; s16 gyro_ax = 0;
s16 gyro_az = 0; s16 gyro_az = 0;
#if TARGET_PC #if TARGET_PC
if (dusk::gyro::rollgoal_gyro_enabled()) { if (dusk::getSettings().game.enableGyroRollgoal) {
dusk::gyro::rollgoalTableOffset(gyro_ax, gyro_az); dusk::gyro::rollgoalTableOffset(gyro_ax, gyro_az);
} }
#endif #endif
-36
View File
@@ -419,30 +419,9 @@ int daMidna_c::createHeap() {
return 0; return 0;
} }
#if TARGET_PC
if (mpDemoFCTongueBmd != NULL) {
if(!daAlink_c::initDemoBck(&mpDemoFCTmpBck, "demo00_Midna_cut00_FC_tmp.bck")) {
return 0;
}
// Update Midna's eye maxLOD to prevent the eyes from disappearing
J3DTexture* tex = mpDemoFCTongueBmd->getModelData()->getTexture();
JUTNameTab* nametable = mpDemoFCTongueBmd->getModelData()->getTextureName();
if (tex != nullptr && nametable != nullptr) {
for (u16 i = 0; i < tex->getNum(); i++) {
const char* tex_name = nametable->getName(i);
if (tex_name != NULL && strcmp(tex_name, "midona_eyeball") == 0) {
ResTIMG* timg = tex->getResTIMG(i);
timg->maxLOD = 0;
}
}
}
}
#else
if (mpDemoFCTongueBmd != NULL && !daAlink_c::initDemoBck(&mpDemoFCTmpBck, "demo00_Midna_cut00_FC_tmp.bck")) { if (mpDemoFCTongueBmd != NULL && !daAlink_c::initDemoBck(&mpDemoFCTmpBck, "demo00_Midna_cut00_FC_tmp.bck")) {
return 0; return 0;
} }
#endif
modelData = modelData =
(J3DModelData*)dComIfG_getObjectRes(dStage_roomControl_c::getDemoArcName(), "demo00_Midna_cut00_BD_tmp.bmd"); (J3DModelData*)dComIfG_getObjectRes(dStage_roomControl_c::getDemoArcName(), "demo00_Midna_cut00_BD_tmp.bmd");
@@ -454,21 +433,6 @@ int daMidna_c::createHeap() {
modelData->getMaterialNodePointer(2)->setMaterialAnm(mpEyeMatAnm[0]); modelData->getMaterialNodePointer(2)->setMaterialAnm(mpEyeMatAnm[0]);
modelData->getMaterialNodePointer(3)->setMaterialAnm(mpEyeMatAnm[1]); modelData->getMaterialNodePointer(3)->setMaterialAnm(mpEyeMatAnm[1]);
#if TARGET_PC
// Update Midna's eye maxLOD to prevent the eyes from disappearing
J3DTexture* tex = modelData->getTexture();
JUTNameTab* nametable = modelData->getTextureName();
if (tex != nullptr && nametable != nullptr) {
for (u16 i = 0; i < tex->getNum(); i++) {
const char* tex_name = nametable->getName(i);
if (tex_name != NULL && strcmp(tex_name, "midona_eyeball") == 0) {
ResTIMG* timg = tex->getResTIMG(i);
timg->maxLOD = 0;
}
}
}
#endif
} }
if (!initDemoModel(&mpDemoBDMaskBmd, "demo00_Midna_cut00_BD_mask.bmd", 0)) { if (!initDemoModel(&mpDemoBDMaskBmd, "demo00_Midna_cut00_BD_mask.bmd", 0)) {
-2
View File
@@ -14,7 +14,6 @@
#include "d/actor/d_a_obj_automata.h" #include "d/actor/d_a_obj_automata.h"
#include "d/d_msg_object.h" #include "d/d_msg_object.h"
#include "d/actor/d_a_obj_scannon.h" #include "d/actor/d_a_obj_scannon.h"
#include "dusk/frame_interpolation.h"
#include <cstring> #include <cstring>
const daNpc_Toby_HIOParam daNpc_Toby_Param_c::m = { const daNpc_Toby_HIOParam daNpc_Toby_Param_c::m = {
@@ -1399,7 +1398,6 @@ int daNpc_Toby_c::cutRepairSCannon(int arg0) {
old.pos = current.pos; old.pos = current.pos;
setAngle(cM_deg2s(5.0f * f32(mPath.getArg0()))); setAngle(cM_deg2s(5.0f * f32(mPath.getArg0())));
mEventTimer = mPath.getArg2(); mEventTimer = mPath.getArg2();
dusk::frame_interp::request_presentation_sync();
} }
} else if (!mHide) { } else if (!mHide) {
mHide = 1; mHide = 1;
-39
View File
@@ -10,8 +10,6 @@
#include "JSystem/J3DGraphBase/J3DDrawBuffer.h" #include "JSystem/J3DGraphBase/J3DDrawBuffer.h"
#include "SSystem/SComponent/c_math.h" #include "SSystem/SComponent/c_math.h"
#include "d/d_com_inf_game.h" #include "d/d_com_inf_game.h"
#include "dusk/frame_interpolation.h"
#include "dusk/settings.h"
#include <cstring> #include <cstring>
static char const l_arcName[] = "Fchain"; static char const l_arcName[] = "Fchain";
@@ -67,10 +65,6 @@ int daObjFchain_c::create() {
local_48++; local_48++;
} }
rv = cPhs_COMPLEATE_e; rv = cPhs_COMPLEATE_e;
#if TARGET_PC
mChainInterpPrevValid = false;
mChainInterpCurrValid = false;
#endif
break; break;
} }
return rv; return rv;
@@ -295,26 +289,6 @@ void daObjFchain_shape_c::draw() {
} }
} }
#if TARGET_PC
static void fchain_interp_callback(bool isSimFrame, void* pUserWork) {
static_cast<daObjFchain_c*>(pUserWork)->onInterpCallback();
}
void daObjFchain_c::onInterpCallback() {
if (!mChainInterpPrevValid || !mChainInterpCurrValid) {
return;
}
const f32 alpha = dusk::frame_interp::get_interpolation_step();
for (int i = 0; i < CHAIN_COUNT; i++) {
const cXyz& p0 = mChainInterpPrev[i];
const cXyz& p1 = mChainInterpCurr[i];
field_0x694[i] = p0 + (p1 - p0) * alpha;
}
}
#endif
int daObjFchain_c::draw() { int daObjFchain_c::draw() {
if (field_0x584 != 0) { if (field_0x584 != 0) {
g_env_light.settingTevStruct(0, &current.pos, &tevStr); g_env_light.settingTevStruct(0, &current.pos, &tevStr);
@@ -323,19 +297,6 @@ int daObjFchain_c::draw() {
return 1; return 1;
} }
dComIfGd_getOpaListDark()->entryImm(&mShape, 0); dComIfGd_getOpaListDark()->entryImm(&mShape, 0);
#if TARGET_PC
if (dusk::getSettings().game.enableFrameInterpolation) {
if (mChainInterpCurrValid) {
memcpy(mChainInterpPrev, mChainInterpCurr, sizeof(mChainInterpCurr));
mChainInterpPrevValid = true;
}
memcpy(mChainInterpCurr, field_0x694, sizeof(mChainInterpCurr));
mChainInterpCurrValid = true;
dusk::frame_interp::add_interpolation_callback(&fchain_interp_callback, this);
}
#endif
} }
return 1; return 1;
} }
-51
View File
@@ -11,8 +11,6 @@
#include "d/d_bg_w.h" #include "d/d_bg_w.h"
#include "d/d_cc_uty.h" #include "d/d_cc_uty.h"
#include "d/d_com_inf_game.h" #include "d/d_com_inf_game.h"
#include "dusk/frame_interpolation.h"
#include "dusk/settings.h"
struct daObjKLift00_HIO_c : public mDoHIO_entry_c { struct daObjKLift00_HIO_c : public mDoHIO_entry_c {
daObjKLift00_HIO_c(); daObjKLift00_HIO_c();
@@ -297,11 +295,6 @@ int daObjKLift00_c::Create() {
if(getLock()) if(getLock())
mStopSwingingFrames = 5; mStopSwingingFrames = 5;
#if TARGET_PC
mChainInterpPrevValid = false;
mChainInterpCurrValid = false;
#endif
return 1; return 1;
} }
@@ -443,34 +436,6 @@ int daObjKLift00_c::Execute(Mtx** i_mtx) {
return 1; return 1;
} }
#if TARGET_PC
static void klift00_interp_callback(bool isSimFrame, void* pUserWork) {
static_cast<daObjKLift00_c*>(pUserWork)->onInterpCallback();
}
void daObjKLift00_c::onInterpCallback() {
if (!mChainInterpPrevValid || !mChainInterpCurrValid) {
return;
}
const f32 alpha = dusk::frame_interp::get_interpolation_step();
cXyz savedPositions[64];
for (int i = 0; i < mNumChains; i++) {
savedPositions[i] = mChainPositions[i].mCurrentPos;
const cXyz& p0 = mChainInterpPrev[i];
const cXyz& p1 = mChainInterpCurr[i];
mChainPositions[i].mCurrentPos = p0 + (p1 - p0) * alpha;
}
setMtx();
for (int i = 0; i < mNumChains; i++) {
mChainPositions[i].mCurrentPos = savedPositions[i];
}
}
#endif
int daObjKLift00_c::Draw() { int daObjKLift00_c::Draw() {
g_env_light.settingTevStruct(16, &current.pos, &tevStr); g_env_light.settingTevStruct(16, &current.pos, &tevStr);
g_env_light.setLightTevColorType_MAJI(mpLiftPlatform, &tevStr); g_env_light.setLightTevColorType_MAJI(mpLiftPlatform, &tevStr);
@@ -492,22 +457,6 @@ int daObjKLift00_c::Draw() {
dComIfGd_setList(); dComIfGd_setList();
#if TARGET_PC
if (dusk::getSettings().game.enableFrameInterpolation) {
if (mChainInterpCurrValid) {
memcpy(mChainInterpPrev, mChainInterpCurr, mNumChains * sizeof(cXyz));
mChainInterpPrevValid = true;
}
for (int i = 0; i < mNumChains; i++) {
mChainInterpCurr[i] = mChainPositions[i].mCurrentPos;
}
mChainInterpCurrValid = true;
dusk::frame_interp::add_interpolation_callback(&klift00_interp_callback, this);
}
#endif
return 1; return 1;
} }
-9
View File
@@ -12,10 +12,6 @@
#include "SSystem/SComponent/c_counter.h" #include "SSystem/SComponent/c_counter.h"
#include <cstring> #include <cstring>
#if TARGET_PC
#include "dusk/settings.h"
#endif
#define DRAW_TYPE_YELLOW 0 #define DRAW_TYPE_YELLOW 0
#define DRAW_TYPE_RED 1 #define DRAW_TYPE_RED 1
@@ -1426,11 +1422,6 @@ int dAttention_c::Run() {
} }
void dAttention_c::Draw() { void dAttention_c::Draw() {
#if TARGET_PC
if (dusk::getSettings().game.recordingMode) {
return;
}
#endif
if (mAttParam.CheckFlag(dAttParam_c::EFlag_ARROW_OFF)) { if (mAttParam.CheckFlag(dAttParam_c::EFlag_ARROW_OFF)) {
draw[0].field_0x173 = 3; draw[0].field_0x173 = 3;
draw[1].field_0x173 = 3; draw[1].field_0x173 = 3;
+12 -205
View File
@@ -31,7 +31,6 @@
#if TARGET_PC #if TARGET_PC
#include "dusk/frame_interpolation.h" #include "dusk/frame_interpolation.h"
#include "dusk/logging.h" #include "dusk/logging.h"
#include "imgui.h"
#endif #endif
namespace { namespace {
@@ -1041,11 +1040,6 @@ void dCamera_c::debugDrawInit() {
bool dCamera_c::Run() { bool dCamera_c::Run() {
#if TARGET_PC #if TARGET_PC
ResetView(); ResetView();
if (executeDebugFlyCam()) {
mFrameCounter++;
mTicks++;
return true;
}
#endif #endif
daAlink_c* link = daAlink_getAlinkActorClass(); daAlink_c* link = daAlink_getAlinkActorClass();
@@ -7480,155 +7474,7 @@ bool dCamera_c::test2Camera(s32 param_0) {
return false; return false;
} }
static constexpr f32 FLYCAM_SPEED = 0.5f;
static constexpr f32 FLYCAM_FAST_SPEED = 4.0f;
static constexpr f32 FLYCAM_ROTATION_SPEED = 0.002f;
static constexpr f32 FLYCAM_TRIGGER_DEADZONE = 20.0f;
static constexpr s16 FLYCAM_ROLL_SPEED = 256;
static ImVec2 sFlyCamLastMousePos = {-1.f, -1.f};
#if TARGET_PC #if TARGET_PC
bool dCamera_c::executeDebugFlyCam() {
if (!dusk::getSettings().game.debugFlyCam) {
if (mDebugFlyCam.initialized) {
deactivateDebugFlyCam();
}
sFlyCamLastMousePos = {-1.f, -1.f};
return false;
}
dEvt_control_c* event = dComIfGp_getEvent();
if (event == nullptr) {
return false;
}
if (!mDebugFlyCam.initialized && (event->mEventStatus != 0 || dComIfGp_isPauseFlag())) {
dusk::getSettings().game.debugFlyCam.setValue(false);
return false;
}
if (!mDebugFlyCam.initialized) {
mDebugFlyCam.savedCenter = mCenter;
mDebugFlyCam.savedEye = mEye;
mDebugFlyCam.savedFovy = mFovy;
mDebugFlyCam.savedBank = mBank;
f32 dx = mCenter.x - mEye.x;
f32 dy = mCenter.y - mEye.y;
f32 dz = mCenter.z - mEye.z;
mDebugFlyCam.yaw = atan2f(dz, dx);
f32 horizontal = sqrtf(dx * dx + dz * dz);
mDebugFlyCam.pitch = atan2f(dy, horizontal);
mDebugFlyCam.initialized = true;
}
if (dusk::getSettings().game.debugFlyCamLockEvents) {
event->mEventStatus = 1;
dComIfGp_getEventManager().setCameraPlay(1);
} else {
if (event->mEventStatus != 0) {
event->mEventStatus = 0;
}
dComIfGp_getEventManager().setCameraPlay(0);
}
f32 stickY = 0.f;
f32 stickX = 0.f;
f32 cStickY = 0.f;
f32 cStickX = 0.f;
f32 trigL = 0.f;
f32 trigR = 0.f;
f32 rollInput = 0.f;
bool fast = false;
if (dusk::getSettings().game.debugFlyCamLockEvents) {
interface_of_controller_pad& pad = mDoCPd_c::getCpadInfo(0);
stickY = pad.mMainStickPosY * 72.0f;
stickX = pad.mMainStickPosX * 72.0f;
cStickY = pad.mCStickPosY * 59.0f;
cStickX = pad.mCStickPosX * 59.0f;
trigL = pad.mTriggerLeft * 150.0f;
trigR = pad.mTriggerRight * 150.0f;
fast = mDoCPd_c::getHoldZ(PAD_1);
if (mDoCPd_c::getHoldY(PAD_1)) rollInput -= 1.f;
if (mDoCPd_c::getHoldX(PAD_1)) rollInput += 1.f;
}
{
ImGuiIO& io = ImGui::GetIO();
if (!io.WantCaptureKeyboard) {
f32 kbX = 0.0f, kbY = 0.0f;
if (ImGui::IsKeyDown(ImGuiKey_W) || ImGui::IsKeyDown(ImGuiKey_UpArrow)) kbY += 1.f;
if (ImGui::IsKeyDown(ImGuiKey_S) || ImGui::IsKeyDown(ImGuiKey_DownArrow)) kbY -= 1.f;
if (ImGui::IsKeyDown(ImGuiKey_D) || ImGui::IsKeyDown(ImGuiKey_RightArrow)) kbX += 1.f;
if (ImGui::IsKeyDown(ImGuiKey_A) || ImGui::IsKeyDown(ImGuiKey_LeftArrow)) kbX -= 1.f;
f32 len = sqrtf(kbX * kbX + kbY * kbY);
if (len > 1.f) { kbX /= len; kbY /= len; }
stickX += kbX * 72.0f;
stickY += kbY * 72.0f;
if (ImGui::IsKeyDown(ImGuiKey_Space)) trigR += 150.0f;
if (ImGui::IsKeyDown(ImGuiKey_LeftCtrl)) trigL += 150.0f;
if (ImGui::IsKeyDown(ImGuiKey_LeftShift)) fast = true;
if (ImGui::IsKeyDown(ImGuiKey_Q)) rollInput -= 1.0f;
if (ImGui::IsKeyDown(ImGuiKey_E)) rollInput += 1.0f;
}
bool mouseValid = !io.WantCaptureMouse && io.MousePos.x >= 0.0f && io.MousePos.y >= 0.0f;
if (mouseValid && sFlyCamLastMousePos.x >= 0.0f) {
cStickX -= (io.MousePos.x - sFlyCamLastMousePos.x) * 2.0f;
cStickY -= (io.MousePos.y - sFlyCamLastMousePos.y) * 2.0f;
}
sFlyCamLastMousePos = mouseValid ? io.MousePos : ImVec2{-1.0f, -1.0f};
}
f32 verticalDisp = 0.0f;
if (trigR >= FLYCAM_TRIGGER_DEADZONE) {
verticalDisp += trigR;
}
if (trigL >= FLYCAM_TRIGGER_DEADZONE) {
verticalDisp -= trigL;
}
f32 moveDy = stickY * sinf(mDebugFlyCam.pitch) + verticalDisp;
f32 moveDx = stickY * cosf(mDebugFlyCam.yaw) * cosf(mDebugFlyCam.pitch) - stickX * sinf(mDebugFlyCam.yaw);
f32 moveDz = stickY * sinf(mDebugFlyCam.yaw) * cosf(mDebugFlyCam.pitch) + stickX * cosf(mDebugFlyCam.yaw);
f32 speed = fast ? FLYCAM_FAST_SPEED : FLYCAM_SPEED;
mEye.x += speed * moveDx;
mEye.y += speed * moveDy;
mEye.z += speed * moveDz;
static constexpr f32 FLYCAM_TARGET_DIST = 100.0f;
mCenter.x = mEye.x + cosf(mDebugFlyCam.yaw) * cosf(mDebugFlyCam.pitch) * FLYCAM_TARGET_DIST;
mCenter.z = mEye.z + sinf(mDebugFlyCam.yaw) * cosf(mDebugFlyCam.pitch) * FLYCAM_TARGET_DIST;
mCenter.y = mEye.y + sinf(mDebugFlyCam.pitch) * FLYCAM_TARGET_DIST;
mBank = mBank + static_cast<s16>(rollInput * FLYCAM_ROLL_SPEED * (fast ? FLYCAM_FAST_SPEED / FLYCAM_SPEED : 1.f));
Reset(mCenter, mEye);
f32 yawInput = dusk::getSettings().game.invertCameraXAxis ? cStickX : -cStickX;
mDebugFlyCam.yaw += yawInput * FLYCAM_ROTATION_SPEED;
mDebugFlyCam.yaw = fmodf(mDebugFlyCam.yaw + 2.0f * (f32)M_PI, 2.0f * (f32)M_PI);
f32 maxPitch = (f32)M_PI / 2.0f - 0.1f;
f32 minPitch = -(f32)M_PI / 2.0f + 0.1f;
mDebugFlyCam.pitch = std::clamp(mDebugFlyCam.pitch + cStickY * FLYCAM_ROTATION_SPEED, minPitch, maxPitch);
return true;
}
void dCamera_c::deactivateDebugFlyCam() {
Reset(mDebugFlyCam.savedCenter, mDebugFlyCam.savedEye, mDebugFlyCam.savedFovy, mDebugFlyCam.savedBank.Val());
dEvt_control_c* event = dComIfGp_getEvent();
if (event != nullptr && event->mEventStatus != 0) {
event->mEventStatus = 0;
}
dComIfGp_getEventManager().setCameraPlay(0);
mDebugFlyCam.initialized = false;
}
bool dCamera_c::freeCamera() { bool dCamera_c::freeCamera() {
if (dusk::getSettings().game.freeCamera && mGear == 1) { if (dusk::getSettings().game.freeCamera && mGear == 1) {
mGear = 0; mGear = 0;
@@ -11262,26 +11108,6 @@ static int camera_execute(camera_process_class* i_this) {
return 1; return 1;
} }
#ifdef TARGET_PC
void set_ar_corrected_trim(dDlst_window_c* window, float trim_height) {
const auto viewport = window->getViewPort();
if (mDoGph_gInf_c::isWideZoom()) {
const auto target_ar = FB_WIDTH / (FB_HEIGHT - trim_height * 2.0f);
const auto current_ar = mDoGph_gInf_c::m_safeWidthF / mDoGph_gInf_c::m_safeHeightF;
if (current_ar < target_ar) {
trim_height = FB_HEIGHT / 2.0f * (1.0f - current_ar / target_ar);
} else {
trim_height = 0.0f;
}
}
trim_height *= viewport->height / FB_HEIGHT;
window->setScissor(0.0f, trim_height, viewport->width, viewport->height - trim_height * 2.0f);
}
#endif
static int camera_draw(camera_process_class* i_this) { static int camera_draw(camera_process_class* i_this) {
camera_class* a_this = (camera_class*)i_this; camera_class* a_this = (camera_class*)i_this;
dCamera_c* body = &i_this->mCamera; dCamera_c* body = &i_this->mCamera;
@@ -11335,40 +11161,21 @@ static int camera_draw(camera_process_class* i_this) {
#endif #endif
#if TARGET_PC #if TARGET_PC
set_ar_corrected_trim(window, body->TrimHeight()); auto trim_height = body->TrimHeight();
if (dusk::getSettings().game.enableFrameInterpolation) { if (mDoGph_gInf_c::isWideZoom()) {
dusk::frame_interp::add_interpolation_callback([](bool _, void* pUserWork) { const auto target_ar = FB_WIDTH / (FB_HEIGHT - trim_height * 2.0f);
const auto i_this = static_cast<camera_process_class*>(pUserWork); const auto current_ar = mDoGph_gInf_c::m_safeWidthF / mDoGph_gInf_c::m_safeHeightF;
const auto camera = &i_this->mCamera;
const auto trim_size = camera->mTrimSize; if (current_ar < target_ar) {
trim_height = FB_HEIGHT / 2.0f * (1.0f - current_ar / target_ar);
if (camera->mCurState != 2 && trim_size >= 0 && trim_size <= 3) { } else {
// derive trim height at previous tick using current camera state trim_height = 0.0f;
f32 target; }
switch (trim_size) {
case 0:
target = 0.0f;
break;
case 1:
target = camera->mCamSetup.VistaTrimHeight();
break;
case 2:
case 3:
target = camera->mCamSetup.CinemaScopeTrimHeight();
break;
}
const auto step = dusk::frame_interp::get_interpolation_step();
const auto cur = camera->TrimHeight();
const auto prev = (4.0f * cur - target) / 3.0f;
const auto trim_height = prev + (cur - prev) * step;
set_ar_corrected_trim(get_window((camera_class*)i_this), trim_height);
}
}, i_this);
} }
trim_height *= viewport->height / FB_HEIGHT;
window->setScissor(0.0f, trim_height, viewport->width, viewport->height - trim_height * 2.0f);
#else #else
int trim_height = body->TrimHeight(); int trim_height = body->TrimHeight();
-8
View File
@@ -13,9 +13,6 @@
#include "d/d_s_play.h" #include "d/d_s_play.h"
#include "d/d_com_inf_game.h" #include "d/d_com_inf_game.h"
#include "f_op/f_op_actor_mng.h" #include "f_op/f_op_actor_mng.h"
#if TARGET_PC
#include "dusk/achievements.h"
#endif
static int plCutLRC[58] = { static int plCutLRC[58] = {
0, // 0, //
@@ -437,11 +434,6 @@ fopAc_ac_c* cc_at_check(fopAc_ac_c* i_enemy, dCcU_AtInfo* i_AtInfo) {
if (i_AtInfo->mAttackPower != 0 && i_enemy->health <= 0) { if (i_AtInfo->mAttackPower != 0 && i_enemy->health <= 0) {
i_AtInfo->mHitStatus = 2; i_AtInfo->mHitStatus = 2;
i_enemy->health = 0; i_enemy->health = 0;
#if TARGET_PC
if (fopAcM_GetGroup(i_enemy) == fopAc_ENEMY_e) {
dusk::AchievementSystem::get().signal("enemy_killed");
}
#endif
} }
int uvar8; int uvar8;
-73
View File
@@ -11,62 +11,6 @@
#include "JSystem/JGadget/define.h" #include "JSystem/JGadget/define.h"
#include <cstring> #include <cstring>
#include "dusk/logging.h"
#if TARGET_PC
#include "dusk/ui/ui.hpp"
namespace {
static int sJaiSkip = -1;
static JSUList<JAIStream>* get_stream_list() {
return Z2GetSoundMgr()->getStreamMgr()->getStreamList();
}
static int get_stream_count(JSUList<JAIStream>* list) {
int i = 0;
for (JSULink<JAIStream>* l = list != nullptr ? list->getFirst() : nullptr; l != nullptr;
l = l->getNext()) {
i++;
}
return i;
}
static void pause_stream(int skip_first, bool paused) {
int i = 0;
JSUList<JAIStream>* list = get_stream_list();
for (JSULink<JAIStream>* l = list->getFirst(); l != nullptr; l = l->getNext(), ++i) {
if (i >= skip_first) {
l->getObject()->pause(paused);
}
}
}
static void pause_streams(int skip_first) {
if (!dusk::ui::is_prelaunch_open()) {
return;
}
JSUList<JAIStream>* list = get_stream_list();
if (list == nullptr || get_stream_count(list) <= skip_first) {
return;
}
pause_stream(skip_first, true);
sJaiSkip = skip_first;
}
static void unpause_streams(bool require_prelaunch_hidden) {
if (sJaiSkip < 0) {
return;
}
if (require_prelaunch_hidden && dusk::ui::is_prelaunch_open()) {
return;
}
pause_stream(sJaiSkip, false);
sJaiSkip = -1;
}
} // namespace
#endif
s16 dDemo_c::m_branchId = -1; s16 dDemo_c::m_branchId = -1;
namespace { namespace {
@@ -1062,16 +1006,7 @@ int dDemo_c::start(u8 const* p_data, cXyz* p_translation, f32 rotationY) {
m_control->setSuspend(0); m_control->setSuspend(0);
} }
#if TARGET_PC
const int existing_streams = get_stream_count(get_stream_list());
#endif
m_control->forward(0); m_control->forward(0);
#if TARGET_PC
pause_streams(existing_streams);
#endif
m_translation = p_translation; m_translation = p_translation;
if (m_translation != NULL) { if (m_translation != NULL) {
@@ -1099,10 +1034,6 @@ static void dummyString2() {
void dDemo_c::end() { void dDemo_c::end() {
JUT_ASSERT(1956, m_system != NULL); JUT_ASSERT(1956, m_system != NULL);
#if TARGET_PC
unpause_streams(false);
#endif
m_control->destroyObject_all(); m_control->destroyObject_all();
m_object->remove(); m_object->remove();
m_data = NULL; m_data = NULL;
@@ -1123,10 +1054,6 @@ void dDemo_c::branch() {
int dDemo_c::update() { int dDemo_c::update() {
JUT_ASSERT(2064, m_system != NULL); JUT_ASSERT(2064, m_system != NULL);
#if TARGET_PC
unpause_streams(true);
#endif
if (m_data == NULL) { if (m_data == NULL) {
if (m_branchData == NULL) { if (m_branchData == NULL) {
return 0; return 0;
+4 -4
View File
@@ -1595,7 +1595,7 @@ void dMap_c::_move(f32 i_centerX, f32 i_centerZ, int i_roomNo, f32 param_3) {
calcMapCmPerTexel(field_0x80, &field_0x58); calcMapCmPerTexel(field_0x80, &field_0x58);
getPack(field_0x80, &mPackX, &mPackZ); getPack(field_0x80, &mPackX, &mPackZ);
mCenterX += IF_DUSK(dusk::getSettings().game.enableMirrorMode ? -mPackX :) mPackX; mCenterX += mPackX;
mCenterZ -= mPackZ; mCenterZ -= mPackZ;
mCenterX += field_0x64; mCenterX += field_0x64;
mCenterZ += mPackPlusZ; mCenterZ += mPackPlusZ;
@@ -1657,7 +1657,7 @@ void dMap_c::_move(f32 i_centerX, f32 i_centerZ, int i_roomNo, f32 param_3) {
calcMapCmPerTexel(field_0x80, &field_0x58); calcMapCmPerTexel(field_0x80, &field_0x58);
getPack(field_0x80, &mPackX, &mPackZ); getPack(field_0x80, &mPackX, &mPackZ);
mCenterX += IF_DUSK(dusk::getSettings().game.enableMirrorMode ? -mPackX :) mPackX; mCenterX += mPackX;
mCenterZ -= mPackZ; mCenterZ -= mPackZ;
} }
break; break;
@@ -1737,7 +1737,7 @@ void dMap_c::_move(f32 i_centerX, f32 i_centerZ, int i_roomNo, f32 param_3) {
calcMapCmPerTexel(field_0x80, &field_0x58); calcMapCmPerTexel(field_0x80, &field_0x58);
getPack(field_0x80, &mPackX, &mPackZ); getPack(field_0x80, &mPackX, &mPackZ);
mCenterX += IF_DUSK(dusk::getSettings().game.enableMirrorMode ? -mPackX :) mPackX; mCenterX += mPackX;
mCenterZ -= mPackZ; mCenterZ -= mPackZ;
field_0x8f = 4; field_0x8f = 4;
#if DEBUG #if DEBUG
@@ -1829,7 +1829,7 @@ void dMap_c::_move(f32 i_centerX, f32 i_centerZ, int i_roomNo, f32 param_3) {
sp14 += temp_f31_2 * (spC - sp14); sp14 += temp_f31_2 * (spC - sp14);
sp10 += temp_f31_2 * (sp8 - sp10); sp10 += temp_f31_2 * (sp8 - sp10);
mCenterX += IF_DUSK(dusk::getSettings().game.enableMirrorMode ? -sp14 :) sp14; mCenterX += sp14;
mCenterZ -= sp10; mCenterZ -= sp10;
break; break;
} }
+31 -121
View File
@@ -15,47 +15,13 @@
#include <cstring> #include <cstring>
#ifdef TARGET_PC #ifdef TARGET_PC
#include <span>
#include <numbers>
#include <array>
constexpr u16 kMapResolutionMultiplier = 4; constexpr u16 kMapResolutionMultiplier = 4;
constexpr u16 kMapImageSide = 16 * kMapResolutionMultiplier; constexpr u16 kMapCircleSize = 16 * kMapResolutionMultiplier;
constexpr u32 kMapImageTotalPixels = kMapImageSide * kMapImageSide;
typedef std::function<u8(size_t, size_t)> PaintI8Fn;
void paint_i8(std::span<u8> dst, size_t width, PaintI8Fn paint) {
const auto blocksAcross = width >> 3;
for (size_t i = 0; i < dst.size(); i++) {
// 8x4 block swizzling for I8
const auto blockIdx = i >> 5;
const auto localIdx = i & 31;
const auto blockY = blockIdx / blocksAcross;
const auto blockX = blockIdx % blocksAcross;
const auto localY = localIdx >> 3;
const auto localX = localIdx & 7;
const auto x = (blockX << 3) + localX;
const auto y = (blockY << 2) + localY;
dst[i] = paint(x, y);
}
}
#endif #endif
void dMpath_n::dTexObjAggregate_c::create() { void dMpath_n::dTexObjAggregate_c::create() {
static int const data[7] = { static int const data[7] = {
79, // 0: im_map_icon_square_4i.bti 79, 80, 77, 78, 76, 81, 82,
80, // 1: im_map_icon_tresurebox_4i.bti
77, // 2: im_map_icon_enter_4i.bti
78, // 3: im_map_icon_nijumaru_4i.bti
76, // 4: im_map_icon_circle_4i.bti
81, // 5: im_map_icon_try_force_4i.bti
82, // 6: map_icon_circle16x16_4i.bti
}; };
for (int lp1 = 0; lp1 < 7; lp1++) { for (int lp1 = 0; lp1 < 7; lp1++) {
@@ -69,101 +35,45 @@ void dMpath_n::dTexObjAggregate_c::create() {
} }
#if TARGET_PC #if TARGET_PC
static bool hqTexsDrawn = false; auto hqCircle = JKR_NEW TGXTexObj();
static u8 hqCircleData[kMapImageTotalPixels]; static bool hqCircleDrawn = false;
static u8 hqCircleAltData[kMapImageTotalPixels]; static u8 hqCircleData[kMapCircleSize * kMapCircleSize];
static u8 hqNijumaruData[kMapImageTotalPixels];
static u8 hqEnterData[kMapImageTotalPixels];
static u8 hqTryForceData[kMapImageTotalPixels];
if (!hqTexsDrawn) { if (!hqCircleDrawn) {
constexpr auto center = kMapImageSide / 2.0f; const auto center = kMapCircleSize / 2.0f;
constexpr auto radiusSq = center * center; const auto radiusSq = center * center;
const auto blocksAcross = kMapCircleSize >> 3;
const auto totalPixels = sizeof(hqCircleData);
// 6: map_icon_circle16x16_4i.bti - simple circle for (size_t i = 0; i < totalPixels; i++) {
paint_i8(std::span{hqCircleData}, kMapImageSide, [=](auto x, auto y) { // 8x4 block swizzling for I8
const auto dx = (x + 0.5f) - center; const auto blockIdx = i >> 5;
const auto dy = (y + 0.5f) - center; const auto localIdx = i & 31;
return (dx * dx + dy * dy < radiusSq) ? 0x11 : 0;
});
// 4: im_map_icon_circle_4i.bti - outlined circle const auto blockY = blockIdx / blocksAcross;
paint_i8(std::span{hqCircleAltData}, kMapImageSide, [=](auto x, auto y) { const auto blockX = blockIdx % blocksAcross;
constexpr auto innerRadius = kMapImageSide * 3.0f / 8.0f;
constexpr auto innerRadiusSq = innerRadius * innerRadius; const auto localY = localIdx >> 3;
const auto localX = localIdx & 7;
const auto x = (blockX << 3) + localX;
const auto y = (blockY << 2) + localY;
const auto dx = (x + 0.5f) - center; const auto dx = (x + 0.5f) - center;
const auto dy = (y + 0.5f) - center; const auto dy = (y + 0.5f) - center;
const auto dSq = dx * dx + dy * dy;
return dSq < radiusSq ? (dSq < innerRadiusSq ? 0x22 : 0x11) : 0; // the original texture is in I4 format and uses 1 to indicate if inside the circle
}); // so we scale to I8 range: 255 / 15 = 17
hqCircleData[i] = (dx * dx + dy * dy < radiusSq) ? 17 : 0;
// 3: im_map_icon_nijumaru_4i.bti - concentric rings }
paint_i8(std::span{hqNijumaruData}, kMapImageSide, [=](auto x, auto y) { hqCircleDrawn = true;
constexpr u8 nijumaruRings[] = {0x11, 0x22, 0x11, 0x11, 0x22, 0x22};
const auto dx = (x + 0.5f) - center;
const auto dy = (y + 0.5f) - center;
const auto dSq = dx * dx + dy * dy;
if (dSq < radiusSq) {
const auto ringIndex =
static_cast<size_t>(std::trunc(std::sqrt(dSq) / kMapImageSide * 12));
return nijumaruRings[ringIndex];
}
return u8{0};
});
// 2: im_map_icon_enter_4i.bti - outlined octagram
paint_i8(std::span{hqEnterData}, kMapImageSide, [=](auto x, auto y) {
constexpr auto outlineWidth = kMapImageSide / 6.0f;
const auto adx = std::abs((x + 0.5f) - center);
const auto ady = std::abs((y + 0.5f) - center);
const auto dist =
std::min(adx + ady, std::max(adx, ady) * std::numbers::sqrt2_v<float>) -
kMapImageSide / 2.0f;
return dist > 0.0f ? 0 : (dist > -outlineWidth ? 0x22 : 0x33);
});
// 5: im_map_icon_try_force_4i.bti - outlined circle with triangle
paint_i8(std::span{hqTryForceData}, kMapImageSide, [=](auto x, auto y) {
constexpr auto innerRadiusNorm = 5.0f / 12.0f;
constexpr auto innerRadius = kMapImageSide * innerRadiusNorm;
constexpr auto innerRadiusSq = innerRadius * innerRadius;
constexpr auto triRadius = kMapImageSide * innerRadiusNorm / 2.0f;
const auto dx = (x + 0.5f) - center;
const auto dy = (y + 0.5f) - center;
const auto dSq = dx * dx + dy * dy;
const auto triSideDist = (std::numbers::sqrt3_v<float> * std::abs(dx) - dy) * 0.5f;
const auto insideTri = std::max(dy, triSideDist) < triRadius;
return insideTri ? 0x22 : (dSq < radiusSq ? (dSq < innerRadiusSq ? 0x33 : 0x22) : 0);
});
hqTexsDrawn = true;
} }
constexpr auto replacements = std::to_array<std::pair<size_t, const u8*> >({ GXInitTexObj(hqCircle, hqCircleData, kMapCircleSize, kMapCircleSize, GX_TF_I8, GX_CLAMP,
{2, hqEnterData}, GX_CLAMP, GX_FALSE);
{3, hqNijumaruData}, GXInitTexObjLOD(hqCircle, GX_NEAR, GX_NEAR, 0.0f, 0.0f, 0.0f, GX_FALSE, GX_FALSE, GX_ANISO_1);
{4, hqCircleAltData}, mp_texObj[6] = hqCircle;
{5, hqTryForceData},
{6, hqCircleData},
});
for (const auto& [idx, data] : replacements) {
JKR_DELETE(mp_texObj[idx]);
const auto texobj = JKR_NEW TGXTexObj();
GXInitTexObj(
texobj, data, kMapImageSide, kMapImageSide, GX_TF_I8, GX_CLAMP, GX_CLAMP, GX_FALSE);
GXInitTexObjLOD(texobj, GX_NEAR, GX_NEAR, 0.0f, 0.0f, 0.0f, GX_FALSE, GX_FALSE, GX_ANISO_1);
mp_texObj[idx] = texobj;
}
#endif #endif
} }

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