Compare commits
319 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1c1a849095 | |||
| 89d393e57a | |||
| 2f27687d80 | |||
| 167a50c01d | |||
| 313f03f5e5 | |||
| 6cfdc3d8a3 | |||
| 9c24a0bc4b | |||
| b99ad920c4 | |||
| 912b18eca1 | |||
| 9e651a51db | |||
| c8b6e997a7 | |||
| 928e187524 | |||
| cf12d19860 | |||
| e3a3ac56fb | |||
| d15ed81cd5 | |||
| ff054f6f47 | |||
| 667cf70fa0 | |||
| 73eb401c93 | |||
| b11f3add06 | |||
| 92f888a152 | |||
| 78ed5cc716 | |||
| 3968b67c5d | |||
| 119830c979 | |||
| 647394c875 | |||
| c50d777309 | |||
| 4954685cca | |||
| 39d43a8d8f | |||
| b4761cc54e | |||
| 9aee2e9cfe | |||
| 7c7c8b228e | |||
| ca7714dafd | |||
| 1ad5ab8632 | |||
| c4e7838089 | |||
| 7313712263 | |||
| aa48d95f24 | |||
| c5baabbe9c | |||
| 1d2716139f | |||
| 742ad2c150 | |||
| 18eb0692f0 | |||
| b5f98f69db | |||
| 47593d0eb4 | |||
| 4404fce369 | |||
| 72c20f4dd0 | |||
| 3240885bfd | |||
| 7f0955f022 | |||
| c21bce0093 | |||
| 4e23472ed5 | |||
| cfe1f2304b | |||
| de6568d750 | |||
| 3aafe7fa16 | |||
| c1e65d19e7 | |||
| 5fdf954994 | |||
| 230868af3c | |||
| 66154d9de8 | |||
| 93ec3c7dbd | |||
| 945ce3e4bc | |||
| 782a8573e9 | |||
| 4e0ca51159 | |||
| 3cd160e1b2 | |||
| 93a236a9d2 | |||
| eaf3bc2f40 | |||
| 5ca0a2ba06 | |||
| ccd2bdbaac | |||
| 08321699cd | |||
| 7300c0e0f5 | |||
| 7e562824fe | |||
| ed8b5c96b9 | |||
| 14bccdffa6 | |||
| 39e465bcab | |||
| e53bb3a12d | |||
| 50fccd393f | |||
| 7993740ac8 | |||
| 8e5bb8ae59 | |||
| 8fefdd4114 | |||
| 64c8cee21b | |||
| 25fe686573 | |||
| 1c1ea98fdd | |||
| e098104f8f | |||
| 3c5ade5565 | |||
| b2ad75027e | |||
| fdfbf83b88 | |||
| 1b9ca0949e | |||
| 827037f0fa | |||
| d84c5790f5 | |||
| 49eb2282af | |||
| 741f9ecfab | |||
| 37b8122962 | |||
| 5f2cf68e80 | |||
| 74f2c58b29 | |||
| 208433047a | |||
| 2c01430035 | |||
| 5121437bcf | |||
| f61bd3e5ad | |||
| 835e409b32 | |||
| 010bdb7e25 | |||
| 7ba22b7714 | |||
| efcb19a3d0 | |||
| 55455bb1b5 | |||
| e49be12297 | |||
| 75f4940f5e | |||
| 8047330952 | |||
| 9105dcb078 | |||
| b8e38e03e2 | |||
| 331352878e | |||
| 62a88f1e9a | |||
| 43b603e70b | |||
| 95e6ac54cf | |||
| c4b2e2e501 | |||
| dccba23980 | |||
| bf27d10519 | |||
| 6c27011e32 | |||
| 6220990dc5 | |||
| 93e9767c9f | |||
| c774f53dad | |||
| 7fbfe5ad88 | |||
| ef02037990 | |||
| 23cc18ba0e | |||
| 924dbc7715 | |||
| 742f4938f2 | |||
| 02e0f586d3 | |||
| 5717aeef85 | |||
| da9b99f650 | |||
| 901ce2ee4c | |||
| dd2b993cd5 | |||
| 83577d3b82 | |||
| 1cb8b19520 | |||
| d109cd891e | |||
| 63c4002ca6 | |||
| 6954efcd15 | |||
| 78c2147771 | |||
| c938d5468e | |||
| 35590c5312 | |||
| e976b10e2a | |||
| 3949706b28 | |||
| ce55916845 | |||
| 9b252cbdd2 | |||
| 97fa09f6ee | |||
| 0e7a7cccb9 | |||
| 1c0cdcc176 | |||
| 280305c2ba | |||
| d1f1d579bc | |||
| eeeb3ffe25 | |||
| 1ee0f862e1 | |||
| 6b327c9f61 | |||
| f148e0ebc1 | |||
| 6f20f4d629 | |||
| 94670270d6 | |||
| 8e21247a97 | |||
| aa84004cb4 | |||
| e1c201f4bd | |||
| 425a1d15a0 | |||
| e3ad41792a | |||
| c1ba10fc8b | |||
| 1c5686f71b | |||
| b9e0f2b9ca | |||
| ede175f141 | |||
| a301874e30 | |||
| 9b4a9a6bd9 | |||
| 04274b1884 | |||
| ca783b8424 | |||
| 2e4c2b5b46 | |||
| 4c09d8b910 | |||
| fb1b260d09 | |||
| 98eb8f718e | |||
| 68b2e0ee2d | |||
| 81771a0522 | |||
| 93c8bcc210 | |||
| 176bf5f0c4 | |||
| 65a5945778 | |||
| 8f7b9cdfdd | |||
| acecba7ff7 | |||
| 507e0aadbc | |||
| 8406d9b192 | |||
| 6f3170cb56 | |||
| 835582224e | |||
| 52879f50f0 | |||
| 2b505f1be4 | |||
| f089f9024d | |||
| 43fb421a93 | |||
| f06d6b50a9 | |||
| 2c987b0211 | |||
| 3d860ad454 | |||
| b5bf19569b | |||
| 5a7f5cb4a7 | |||
| 1affefbbfc | |||
| e4ff38a712 | |||
| f2ac4d6f44 | |||
| 48b98a5432 | |||
| a4752154f7 | |||
| 0d973a497b | |||
| ab4eccf1df | |||
| e0c449f28e | |||
| ce9a5c06d5 | |||
| 2bbba1e4e8 | |||
| 39298f8d8f | |||
| 32b4c0567a | |||
| 7ff1b5332e | |||
| 5e77a60bd6 | |||
| 9629c000bd | |||
| 9dc5fed686 | |||
| 2cc9db77dd | |||
| 8aa08c9443 | |||
| dca3e2eba6 | |||
| 57061fba38 | |||
| cee6a24309 | |||
| 62edb3abc6 | |||
| 1c9e1c0a66 | |||
| a06aeb10c1 | |||
| b84b309e00 | |||
| 62eecb3ccd | |||
| ec07572ced | |||
| b45e2fa34d | |||
| 289a718446 | |||
| 292a2a6c34 | |||
| 2e8415b950 | |||
| dbf1f6e354 | |||
| 9a2fe9745d | |||
| b5ca343fac | |||
| 88c7ff63ff | |||
| 7a438ad30f | |||
| 89649de7c3 | |||
| a1960eaa33 | |||
| d6820c9233 | |||
| 5c4bb8d33d | |||
| e3ce1f01c9 | |||
| 9b6b344ecf | |||
| 3db85d5b44 | |||
| b5871d72d9 | |||
| b70a714f88 | |||
| cad5a8d1bc | |||
| 93f8a5fa8f | |||
| b0809ea78c | |||
| b0e9033736 | |||
| 1ac6df8de7 | |||
| 5899b2157a | |||
| 3185f578fb | |||
| 4fc09799b6 | |||
| fe0e3cad72 | |||
| 37d1aa7f40 | |||
| 4a12554bf4 | |||
| fecd1d5683 | |||
| bce9bf6fd9 | |||
| fbf63b075a | |||
| b86d6e90e2 | |||
| 6425b452e7 | |||
| 1657fe8083 | |||
| ecd74a4cbd | |||
| 36dc43c602 | |||
| d92515f0d4 | |||
| f147dcac0c | |||
| ee4c84f39b | |||
| b8a83c6f59 | |||
| 4462c0ef69 | |||
| c803bfb545 | |||
| 2623c44cab | |||
| 24dd02fc81 | |||
| a97602b6dc | |||
| e2943e90dc | |||
| 3cb7fbd030 | |||
| afe54f22ab | |||
| e15f5bcee9 | |||
| 1e372a856d | |||
| b26896cad5 | |||
| f75faf6b06 | |||
| b48d9aa052 | |||
| d899706208 | |||
| 3e05789b58 | |||
| 9a7b62cbc6 | |||
| 8e0f0e878e | |||
| 79344edf0d | |||
| e59bfd1a9c | |||
| 4d12cc8ea2 | |||
| 2ed2268579 | |||
| 94a99e8da0 | |||
| ddaf50c01d | |||
| 7566949b42 | |||
| bb6db3caea | |||
| 2dc494dc1c | |||
| 3c25633ee9 | |||
| d99ed2729b | |||
| 782455d48b | |||
| 47863b34c2 | |||
| 92391d5eb8 | |||
| 0d37cb4e54 | |||
| ea528ed9d9 | |||
| f7b880c5ea | |||
| ff78bc8d6c | |||
| 6503b4e7eb | |||
| 30b7087f30 | |||
| 0c1372f986 | |||
| 8fb4ba8924 | |||
| 5f675c6f2b | |||
| b3333241c5 | |||
| e39079c0f8 | |||
| c3317d9232 | |||
| a4777045fe | |||
| bbe8ea6aa6 | |||
| d662db69f0 | |||
| 9b259143be | |||
| 025cb58493 | |||
| b3dee825e8 | |||
| f6c5aac3c8 | |||
| 25e9064d09 | |||
| 3e1e8f1244 | |||
| eaae8b6137 | |||
| 0bf663141a | |||
| d7dced7ddf | |||
| 78b0563c0e | |||
| 871d18e294 | |||
| c157564da6 | |||
| ecc3b00c51 | |||
| 8afb1141ab | |||
| 8c5673d9b8 | |||
| 916dfcd9da | |||
| d9a0ef760f | |||
| 842210e539 | |||
| 39d951d0cb | |||
| a4be0841e5 | |||
| 95470b830f |
@@ -2,7 +2,7 @@
|
||||
Language: Cpp
|
||||
Standard: C++03
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignAfterOpenBracket: DontAlign
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignOperands: true
|
||||
|
||||
@@ -100,7 +100,9 @@ if (CMAKE_SYSTEM_NAME STREQUAL Linux)
|
||||
endif ()
|
||||
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_RMLUI ON CACHE BOOL "Enable RmlUi UI support" FORCE)
|
||||
add_subdirectory(extern/aurora EXCLUDE_FROM_ALL)
|
||||
target_compile_definitions(aurora_mtx PRIVATE MTX_USE_PS=1)
|
||||
|
||||
add_subdirectory(libs/freeverb)
|
||||
|
||||
@@ -284,7 +286,7 @@ set(DUSK_COPYRIGHT "Copyright (C) Twilit Realm contributors")
|
||||
source_group("dolzel" FILES ${DOLZEL_FILES} ${Z2AUDIOLIB_FILES} ${REL_FILES})
|
||||
source_group("dusk" FILES ${DUSK_FILES})
|
||||
|
||||
set(GAME_COMPILE_DEFS TARGET_PC WIDESCREEN_SUPPORT=1 AVOID_UB=1 VERSION=0)
|
||||
set(GAME_COMPILE_DEFS TARGET_PC WIDESCREEN_SUPPORT=1 AVOID_UB=1 VERSION=0 MTX_USE_PS=1)
|
||||
|
||||
set(GAME_INCLUDE_DIRS
|
||||
include
|
||||
@@ -296,8 +298,10 @@ set(GAME_INCLUDE_DIRS
|
||||
extern
|
||||
${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
|
||||
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)
|
||||
|
||||
@@ -319,46 +323,13 @@ if (DUSK_MOVIE_SUPPORT)
|
||||
list(APPEND GAME_COMPILE_DEFS MOVIE_SUPPORT=1)
|
||||
endif ()
|
||||
|
||||
option(DUSK_ENABLE_DISCORD_RPC "Enable Discord Rich Presence support" ON)
|
||||
if (DUSK_ENABLE_DISCORD_RPC AND NOT ANDROID AND NOT IOS AND NOT TVOS)
|
||||
|
||||
FetchContent_Populate(discord_rpc
|
||||
URL https://github.com/discord/discord-rpc/archive/refs/tags/v3.4.0.tar.gz
|
||||
URL_HASH SHA256=e13427019027acd187352dacba6c65953af66fdf3c35fcf38fc40b454a9d7855
|
||||
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)
|
||||
set(DUSK_ENABLE_DISCORD_DEFAULT ON)
|
||||
if (DEFINED DUSK_ENABLE_DISCORD_RPC AND NOT DEFINED DUSK_ENABLE_DISCORD)
|
||||
set(DUSK_ENABLE_DISCORD_DEFAULT ${DUSK_ENABLE_DISCORD_RPC})
|
||||
endif ()
|
||||
option(DUSK_ENABLE_DISCORD "Enable Discord Rich Presence support" ${DUSK_ENABLE_DISCORD_DEFAULT})
|
||||
if (DUSK_ENABLE_DISCORD AND NOT ANDROID AND NOT IOS AND NOT TVOS)
|
||||
list(APPEND GAME_COMPILE_DEFS DUSK_DISCORD=1)
|
||||
endif ()
|
||||
|
||||
# Edit & Continue
|
||||
|
||||
@@ -1,31 +1,55 @@
|
||||

|
||||
<div align="center">
|
||||
<img src="res/logo-mascot.png" alt="Logo" width="640">
|
||||
|
||||
- ### **[Official Website](https://twilitrealm.dev)**
|
||||
- ### **[Discord](https://discord.gg/QACynxeyna)**
|
||||
<p align="center">
|
||||
<a href="https://twilitrealm.dev">Official Website</a>
|
||||
•
|
||||
<a href="https://discord.gg/QACynxeyna">Discord</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
# Overview
|
||||
|
||||
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.
|
||||
|
||||
# Setup
|
||||
**⚠️ Dusk does NOT provide any copyrighted assets. You must provide your own copy of the game.**
|
||||
|
||||
### 1. Verify your ROM dump
|
||||
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.
|
||||
> [!IMPORTANT]
|
||||
> Dusk does *not* provide any copyrighted assets. You must provide your own copy of the original game.
|
||||
|
||||
| Version | sha1 hash |
|
||||
|--------------| ---------------------------------------- |
|
||||
| GameCube USA | 75edd3ddff41f125d1b4ce1a40378f1b565519e7 |
|
||||
| GameCube PAL | 2601822a488eeb86fb89db16ca8f29c2c953e1ca |
|
||||
### 1. Verify your dump
|
||||
|
||||
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:
|
||||
|
||||
| Version | SHA-1 hash |
|
||||
|--------------| ------------------------------------------ |
|
||||
| GameCube USA | `75edd3ddff41f125d1b4ce1a40378f1b565519e7` |
|
||||
| GameCube EUR | `2601822a488eeb86fb89db16ca8f29c2c953e1ca` |
|
||||
|
||||
### 2. Download [Dusk](https://github.com/TwilitRealm/dusk/releases)
|
||||
|
||||
### 3. Setup the game
|
||||
- Extract the zip folder
|
||||
- Launch Dusk
|
||||
- Select Options, then set the ISO Path to your supported game dump
|
||||
- Press Start Game to play!
|
||||
|
||||

|
||||
- Extract the .zip file
|
||||
- Launch Dusk
|
||||
- Press **Select Disc Image** and provide the path to your supported game dump.
|
||||
- Press **Play**!
|
||||
|
||||
# Building
|
||||
|
||||
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.
|
||||
|
||||
# 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).
|
||||
|
||||
<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>
|
||||
|
||||
|
After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 85 KiB |
@@ -0,0 +1,66 @@
|
||||
<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>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
@@ -1,7 +1,7 @@
|
||||
|
||||
set(DOLZEL_FILES
|
||||
src/m_Do/m_Do_main.cpp
|
||||
src/m_Do/m_Do_printf.cpp
|
||||
#src/m_Do/m_Do_printf.cpp
|
||||
src/m_Do/m_Do_audio.cpp
|
||||
src/m_Do/m_Do_controller_pad.cpp
|
||||
#src/m_Do/m_Re_controller_pad.cpp
|
||||
@@ -1429,6 +1429,7 @@ set(DUSK_FILES
|
||||
src/dusk/globals.cpp
|
||||
src/dusk/gyro.cpp
|
||||
src/dusk/gamepad_color.cpp
|
||||
src/dusk/autosave.cpp
|
||||
src/dusk/io.cpp
|
||||
src/dusk/layout.cpp
|
||||
src/dusk/logging.cpp
|
||||
@@ -1446,29 +1447,72 @@ set(DUSK_FILES
|
||||
src/dusk/imgui/ImGuiBloomWindow.hpp
|
||||
src/dusk/imgui/ImGuiMenuTools.cpp
|
||||
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/ImGuiCameraOverlay.cpp
|
||||
src/dusk/imgui/ImGuiHeapOverlay.cpp
|
||||
src/dusk/imgui/ImGuiDebugPad.cpp
|
||||
src/dusk/imgui/ImGuiControllerOverlay.cpp
|
||||
src/dusk/imgui/ImGuiStubLog.cpp
|
||||
src/dusk/imgui/ImGuiMapLoader.cpp
|
||||
src/dusk/imgui/ImGuiSaveEditor.cpp
|
||||
src/dusk/imgui/ImGuiStateShare.hpp
|
||||
src/dusk/imgui/ImGuiStateShare.cpp
|
||||
src/dusk/imgui/ImGuiAchievements.hpp
|
||||
src/dusk/imgui/ImGuiAchievements.cpp
|
||||
src/dusk/ui/achievements.cpp
|
||||
src/dusk/ui/achievements.hpp
|
||||
src/dusk/ui/bool_button.cpp
|
||||
src/dusk/ui/bool_button.hpp
|
||||
src/dusk/ui/button.cpp
|
||||
src/dusk/ui/button.hpp
|
||||
src/dusk/ui/component.cpp
|
||||
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.hpp
|
||||
src/dusk/ui/editor.cpp
|
||||
src/dusk/ui/editor.hpp
|
||||
src/dusk/ui/event.cpp
|
||||
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.hpp
|
||||
src/dusk/ui/modal.cpp
|
||||
src/dusk/ui/modal.hpp
|
||||
src/dusk/ui/nav_types.hpp
|
||||
src/dusk/ui/number_button.cpp
|
||||
src/dusk/ui/number_button.hpp
|
||||
src/dusk/ui/overlay.cpp
|
||||
src/dusk/ui/overlay.hpp
|
||||
src/dusk/ui/pane.cpp
|
||||
src/dusk/ui/pane.hpp
|
||||
src/dusk/ui/menu_bar.cpp
|
||||
src/dusk/ui/menu_bar.hpp
|
||||
src/dusk/ui/prelaunch.cpp
|
||||
src/dusk/ui/prelaunch.hpp
|
||||
src/dusk/ui/preset.cpp
|
||||
src/dusk/ui/preset.hpp
|
||||
src/dusk/ui/select_button.cpp
|
||||
src/dusk/ui/select_button.hpp
|
||||
src/dusk/ui/settings.cpp
|
||||
src/dusk/ui/settings.hpp
|
||||
src/dusk/ui/string_button.cpp
|
||||
src/dusk/ui/string_button.hpp
|
||||
src/dusk/ui/tab_bar.cpp
|
||||
src/dusk/ui/tab_bar.hpp
|
||||
src/dusk/ui/ui.cpp
|
||||
src/dusk/ui/ui.hpp
|
||||
src/dusk/ui/window.cpp
|
||||
src/dusk/ui/window.hpp
|
||||
src/dusk/achievements.cpp
|
||||
src/dusk/iso_validate.cpp
|
||||
src/dusk/livesplit.cpp
|
||||
src/dusk/offset_ptr.cpp
|
||||
src/dusk/OSContext.cpp
|
||||
src/dusk/OSReport.cpp
|
||||
src/dusk/OSThread.cpp
|
||||
src/dusk/OSMutex.cpp
|
||||
src/dusk/discord.cpp
|
||||
src/dusk/discord.hpp
|
||||
src/dusk/discord_presence.cpp
|
||||
src/dusk/version.cpp
|
||||
)
|
||||
|
||||
@@ -27,6 +27,7 @@ public:
|
||||
/* 0x17C */ cXyz mViewScale;
|
||||
#if TARGET_PC
|
||||
bool mbReset = false;
|
||||
bool mbHadEntry = false;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -25,6 +25,10 @@ public:
|
||||
int Draw();
|
||||
int Delete();
|
||||
|
||||
#if TARGET_PC
|
||||
void onInterpCallback();
|
||||
#endif
|
||||
|
||||
enum Param_e {
|
||||
LOCK_e = (1 << 6), NO_BASE_DISP = (1 << 7)
|
||||
};
|
||||
@@ -50,6 +54,13 @@ private:
|
||||
/* 0x1020 */ dCcD_Cyl mCylinderCollider;
|
||||
/* 0x115C */ s32 mStopSwingingFrames;
|
||||
|
||||
#if TARGET_PC
|
||||
cXyz mChainInterpPrev[64];
|
||||
cXyz mChainInterpCurr[64];
|
||||
bool mChainInterpPrevValid;
|
||||
bool mChainInterpCurrValid;
|
||||
#endif
|
||||
|
||||
// Number of chain models
|
||||
u32 getArg0() {
|
||||
return fopAcM_GetParamBit(this, 0, 6);
|
||||
|
||||
@@ -118,6 +118,18 @@ class camera_class;
|
||||
class dCamera_c;
|
||||
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 {
|
||||
public:
|
||||
class dCamInfo_c {
|
||||
@@ -1028,6 +1040,8 @@ public:
|
||||
bool test2Camera(s32);
|
||||
#if TARGET_PC
|
||||
bool freeCamera();
|
||||
bool executeDebugFlyCam();
|
||||
void deactivateDebugFlyCam();
|
||||
#endif
|
||||
bool towerCamera(s32);
|
||||
bool hookshotCamera(s32);
|
||||
@@ -1376,6 +1390,10 @@ public:
|
||||
/* 0x970 */ dCamSetup_c mCamSetup;
|
||||
/* 0xAEC */ dCamParam_c mCamParam;
|
||||
/* 0xB0C */ u8 field_0xb0c;
|
||||
|
||||
#if TARGET_PC
|
||||
DebugFlyCam mDebugFlyCam;
|
||||
#endif
|
||||
}; // Size: 0xB10
|
||||
|
||||
dCamera_c* dCam_getBody();
|
||||
|
||||
@@ -91,6 +91,10 @@ public:
|
||||
void calcCursor();
|
||||
void drawCursor();
|
||||
|
||||
#if TARGET_PC
|
||||
void dMapBgWide();
|
||||
#endif
|
||||
|
||||
void setDPDFloorSelCurPos(s8 i_pos) { field_0xdd6 = i_pos; }
|
||||
|
||||
f32 getMapWidth() { return mMapWidth; }
|
||||
|
||||
@@ -81,6 +81,10 @@ public:
|
||||
void calcDrawPriority();
|
||||
void setArrowPosAxis(f32, f32);
|
||||
|
||||
#if TARGET_PC
|
||||
void fMapBackWide();
|
||||
#endif
|
||||
|
||||
virtual void draw();
|
||||
virtual ~dMenu_Fmap2DBack_c();
|
||||
|
||||
@@ -165,6 +169,12 @@ public:
|
||||
|
||||
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
|
||||
struct RegionTexData {
|
||||
/* 0x00 */ float mMinX;
|
||||
@@ -330,6 +340,10 @@ public:
|
||||
void setHIO(bool);
|
||||
bool isWarpAccept();
|
||||
|
||||
#if TARGET_PC
|
||||
void fMapTopWide();
|
||||
#endif
|
||||
|
||||
virtual void draw();
|
||||
virtual ~dMenu_Fmap2DTop_c();
|
||||
|
||||
|
||||
@@ -66,6 +66,16 @@ public:
|
||||
_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 {
|
||||
// Incomplete class
|
||||
|
||||
|
||||
@@ -67,6 +67,9 @@ public:
|
||||
bool isStaffMessage();
|
||||
bool isSaveMessage();
|
||||
bool isTalkMessage();
|
||||
#if TARGET_PC
|
||||
bool isShopItemMessage();
|
||||
#endif
|
||||
const char* getSmellName();
|
||||
const char* getPortalName();
|
||||
const char* getBombName();
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include <functional>
|
||||
#include <queue>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
#include "nlohmann/json.hpp"
|
||||
|
||||
@@ -14,6 +16,7 @@ enum class AchievementCategory : uint8_t {
|
||||
Collection,
|
||||
Challenge,
|
||||
Minigame,
|
||||
Misc,
|
||||
Glitched
|
||||
};
|
||||
|
||||
@@ -40,10 +43,13 @@ public:
|
||||
void save();
|
||||
void tick();
|
||||
void clearAll();
|
||||
void clearOne(const char* key);
|
||||
|
||||
// Signals are visible to all achievement checks within the same tick, then cleared.
|
||||
void signal(const char* key);
|
||||
bool hasSignal(const char* key) const;
|
||||
|
||||
std::vector<Achievement> getAchievements() const;
|
||||
bool hasPendingUnlock() const { return !m_pendingUnlocks.empty(); }
|
||||
std::string consumePendingUnlock();
|
||||
|
||||
private:
|
||||
struct Entry {
|
||||
@@ -57,9 +63,9 @@ private:
|
||||
void processEntry(Entry& e);
|
||||
|
||||
std::vector<Entry> m_entries;
|
||||
std::unordered_set<std::string_view> m_signals;
|
||||
bool m_loaded = false;
|
||||
bool m_dirty = false;
|
||||
std::queue<std::string> m_pendingUnlocks;
|
||||
};
|
||||
|
||||
} // namespace dusk
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef AUTOSAVE_H
|
||||
#define AUTOSAVE_H
|
||||
|
||||
#include <m_Do/m_Do_MemCardRWmng.h>
|
||||
#include <m_Do/m_Do_MemCard.h>
|
||||
|
||||
void noAutoSave();
|
||||
void triggerAutoSave();
|
||||
void updateAutoSave();
|
||||
void enterAutoSave();
|
||||
void autoSaving();
|
||||
void waitingForWrite();
|
||||
void endAutoSave();
|
||||
|
||||
#endif
|
||||
@@ -1,18 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef DUSK_DISCORD_RPC
|
||||
#ifdef DUSK_DISCORD
|
||||
|
||||
namespace dusk {
|
||||
namespace discord {
|
||||
namespace dusk::discord {
|
||||
|
||||
void Initialize();
|
||||
void initialize();
|
||||
void run_callbacks();
|
||||
void update_presence();
|
||||
void shutdown();
|
||||
|
||||
void RunCallbacks();
|
||||
} // namespace dusk::discord
|
||||
|
||||
void UpdatePresence();
|
||||
|
||||
void Shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
#endif // DUSK_DISCORD_RPC
|
||||
#endif // DUSK_DISCORD
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
#ifndef DUSK_MAIN_H
|
||||
#define DUSK_MAIN_H
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <TargetConditionals.h>
|
||||
#endif
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
namespace dusk {
|
||||
@@ -8,7 +12,17 @@ namespace dusk {
|
||||
extern bool IsShuttingDown;
|
||||
extern bool IsGameLaunched;
|
||||
extern bool IsFocusPaused;
|
||||
extern bool RestartRequested;
|
||||
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
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
|
||||
struct RoomEntry {
|
||||
u8 roomNo;
|
||||
std::vector<s16> roomPoints = {};
|
||||
|
||||
@@ -2,9 +2,6 @@
|
||||
#define _SRC_DUSK_MATH_H_
|
||||
|
||||
#include <cmath>
|
||||
#include <array>
|
||||
#include <limits>
|
||||
#include <bit>
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846f
|
||||
@@ -19,139 +16,6 @@ inline float i_cosf(float x) { return cos(x); }
|
||||
inline float i_tanf(float x) { return tan(x); }
|
||||
inline float i_acosf(float x) { return acos(x); }
|
||||
|
||||
|
||||
// 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;
|
||||
}
|
||||
#include <dolphin/ppc_math.h>
|
||||
|
||||
#endif // _SRC_DUSK_MATH_H_
|
||||
|
||||
@@ -21,6 +21,12 @@ enum class GameLanguage : u8 {
|
||||
Italian = OS_LANGUAGE_ITALIAN,
|
||||
};
|
||||
|
||||
enum class DiscVerificationState : u8 {
|
||||
Unknown = 0,
|
||||
Success,
|
||||
HashMismatch,
|
||||
};
|
||||
|
||||
namespace config {
|
||||
template <>
|
||||
struct ConfigEnumRange<BloomMode> {
|
||||
@@ -33,6 +39,12 @@ struct ConfigEnumRange<GameLanguage> {
|
||||
static constexpr auto min = GameLanguage::English;
|
||||
static constexpr auto max = GameLanguage::Italian;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ConfigEnumRange<DiscVerificationState> {
|
||||
static constexpr auto min = DiscVerificationState::Unknown;
|
||||
static constexpr auto max = DiscVerificationState::HashMismatch;
|
||||
};
|
||||
}
|
||||
|
||||
// Persistent user settings
|
||||
@@ -45,6 +57,8 @@ struct UserSettings {
|
||||
ConfigVar<bool> enableFullscreen;
|
||||
ConfigVar<bool> enableVsync;
|
||||
ConfigVar<bool> lockAspectRatio;
|
||||
ConfigVar<bool> enableFpsOverlay;
|
||||
ConfigVar<int> fpsOverlayCorner;
|
||||
} video;
|
||||
|
||||
struct {
|
||||
@@ -55,6 +69,8 @@ struct UserSettings {
|
||||
ConfigVar<int> soundEffectsVolume;
|
||||
ConfigVar<int> fanfareVolume;
|
||||
ConfigVar<bool> enableReverb;
|
||||
ConfigVar<bool> enableHrtf;
|
||||
ConfigVar<bool> menuSounds;
|
||||
} audio;
|
||||
|
||||
// Game settings
|
||||
@@ -65,7 +81,6 @@ struct UserSettings {
|
||||
// QoL
|
||||
ConfigVar<bool> enableQuickTransform;
|
||||
ConfigVar<bool> hideTvSettingsScreen;
|
||||
ConfigVar<bool> skipWarningScreen;
|
||||
ConfigVar<bool> biggerWallets;
|
||||
ConfigVar<bool> noReturnRupees;
|
||||
ConfigVar<bool> disableRupeeCutscenes;
|
||||
@@ -76,13 +91,15 @@ struct UserSettings {
|
||||
ConfigVar<bool> fastClimbing;
|
||||
ConfigVar<bool> noMissClimbing;
|
||||
ConfigVar<bool> fastTears;
|
||||
ConfigVar<bool> no2ndFishForCat;
|
||||
ConfigVar<bool> instantSaves;
|
||||
ConfigVar<bool> instantText;
|
||||
ConfigVar<bool> sunsSong;
|
||||
ConfigVar<bool> autoSave;
|
||||
|
||||
// Preferences
|
||||
ConfigVar<bool> enableMirrorMode;
|
||||
ConfigVar<bool> disableMainHUD;
|
||||
ConfigVar<bool> minimalHUD;
|
||||
ConfigVar<bool> pauseOnFocusLost;
|
||||
ConfigVar<bool> enableLinkDollRotation;
|
||||
ConfigVar<bool> enableAchievementNotifications;
|
||||
@@ -116,6 +133,8 @@ struct UserSettings {
|
||||
ConfigVar<bool> invertCameraXAxis;
|
||||
ConfigVar<bool> invertCameraYAxis;
|
||||
ConfigVar<float> freeCameraSensitivity;
|
||||
ConfigVar<bool> debugFlyCam;
|
||||
ConfigVar<bool> debugFlyCamLockEvents;
|
||||
|
||||
// Cheats
|
||||
ConfigVar<bool> infiniteHearts;
|
||||
@@ -142,17 +161,19 @@ struct UserSettings {
|
||||
// Tools
|
||||
ConfigVar<bool> speedrunMode;
|
||||
ConfigVar<bool> liveSplitEnabled;
|
||||
ConfigVar<bool> recordingMode;
|
||||
} game;
|
||||
|
||||
struct {
|
||||
ConfigVar<std::string> isoPath;
|
||||
ConfigVar<DiscVerificationState> isoVerification;
|
||||
ConfigVar<std::string> graphicsBackend;
|
||||
ConfigVar<bool> skipPreLaunchUI;
|
||||
ConfigVar<bool> showPipelineCompilation;
|
||||
ConfigVar<bool> wasPresetChosen;
|
||||
ConfigVar<bool> enableCrashReporting;
|
||||
ConfigVar<bool> duskMenuOpen;
|
||||
ConfigVar<int> cardFileType;
|
||||
ConfigVar<bool> enableAdvancedSettings;
|
||||
} backend;
|
||||
};
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "Z2AudioLib/Z2EnvSeMgr.h"
|
||||
#include "Z2AudioLib/Z2LinkMgr.h"
|
||||
#include "dusk/audio.h"
|
||||
#include "dusk/settings.h"
|
||||
|
||||
class mDoAud_zelAudio_c : public Z2AudioMgr {
|
||||
public:
|
||||
@@ -132,6 +133,18 @@ inline void mDoAud_seStart(u32 i_sfxID, const Vec* i_sePos, u32 param_2, s8 i_re
|
||||
-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) {
|
||||
DUSK_AUDIO_SKIP()
|
||||
Z2AudioMgr::getInterface()->seStartLevel(i_sfxID, i_sePos, param_2, i_reverb, 1.0f, 1.0f,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#ifndef J3DSTRUCT_H
|
||||
#define J3DSTRUCT_H
|
||||
|
||||
#include <cstring>
|
||||
#include <gx.h>
|
||||
#include <mtx.h>
|
||||
#include <mtx.h>
|
||||
#include "global.h"
|
||||
#include "JSystem/JMath/JMath.h"
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-j3d
|
||||
*
|
||||
*
|
||||
*/
|
||||
struct J3DLightInfo {
|
||||
bool operator==(J3DLightInfo& other) const;
|
||||
@@ -28,7 +28,7 @@ struct J3DLightInfo {
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-j3d
|
||||
*
|
||||
*
|
||||
*/
|
||||
struct J3DTextureSRTInfo {
|
||||
// NOTE: Big endian when loaded from file!
|
||||
@@ -79,7 +79,7 @@ enum J3DTexMtxMode {
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-j3d
|
||||
*
|
||||
*
|
||||
*/
|
||||
struct J3DTexMtxInfo {
|
||||
bool operator==(J3DTexMtxInfo& other) const;
|
||||
@@ -97,7 +97,7 @@ struct J3DTexMtxInfo {
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-j3d
|
||||
*
|
||||
*
|
||||
*/
|
||||
struct J3DIndTexMtxInfo {
|
||||
J3DIndTexMtxInfo& operator=(J3DIndTexMtxInfo const&);
|
||||
@@ -107,7 +107,7 @@ struct J3DIndTexMtxInfo {
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-j3d
|
||||
*
|
||||
*
|
||||
*/
|
||||
struct J3DFogInfo {
|
||||
bool operator==(J3DFogInfo&) const;
|
||||
@@ -126,7 +126,7 @@ struct J3DFogInfo {
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-j3d
|
||||
*
|
||||
*
|
||||
*/
|
||||
struct J3DNBTScaleInfo {
|
||||
bool operator==(const J3DNBTScaleInfo& other) const;
|
||||
@@ -153,7 +153,7 @@ struct J3DIndTexOrderInfo {
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-j3d
|
||||
*
|
||||
*
|
||||
*/
|
||||
struct J3DTevSwapModeInfo {
|
||||
/* 0x0 */ u8 mRasSel;
|
||||
@@ -164,7 +164,7 @@ struct J3DTevSwapModeInfo {
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-j3d
|
||||
*
|
||||
*
|
||||
*/
|
||||
struct J3DTevSwapModeTableInfo {
|
||||
/* 0x0 */ u8 field_0x0;
|
||||
@@ -175,7 +175,7 @@ struct J3DTevSwapModeTableInfo {
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-j3d
|
||||
*
|
||||
*
|
||||
*/
|
||||
struct J3DTevStageInfo {
|
||||
/* 0x0 */ u8 field_0x0;
|
||||
@@ -202,7 +202,7 @@ struct J3DTevStageInfo {
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-j3d
|
||||
*
|
||||
*
|
||||
*/
|
||||
struct J3DIndTevStageInfo {
|
||||
/* 0x0 */ u8 mIndStage;
|
||||
@@ -219,7 +219,7 @@ struct J3DIndTevStageInfo {
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-j3d
|
||||
*
|
||||
*
|
||||
*/
|
||||
struct J3DTexCoordInfo {
|
||||
/* 0x0 */ u8 mTexGenType;
|
||||
@@ -265,7 +265,7 @@ struct J3DBlendInfo {
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-j3d
|
||||
*
|
||||
*
|
||||
*/
|
||||
struct J3DTevOrderInfo {
|
||||
void operator=(const J3DTevOrderInfo& other) {
|
||||
|
||||
@@ -59,6 +59,9 @@ public:
|
||||
bool isActive() const { return mSeqList.getNumLinks() != 0; }
|
||||
int getNumActiveSeqs() const { return mSeqList.getNumLinks(); }
|
||||
void pause(bool paused) { mActivity.field_0x0.flags.flag2 = paused; }
|
||||
#if TARGET_PC
|
||||
JSUList<JAISeq>* getSeqList() { return &mSeqList; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
/* 0x08 */ JAIAudience* mAudience;
|
||||
|
||||
@@ -207,4 +207,11 @@ void JPARegistAlphaEnv(JPAEmitterWorkData*, JPABaseParticle*);
|
||||
void JPARegistPrmAlpha(JPAEmitterWorkData*, JPABaseParticle*);
|
||||
void JPARegistPrmAlphaEnv(JPAEmitterWorkData*, JPABaseParticle*);
|
||||
|
||||
#if TARGET_PC
|
||||
void JPAInterpBillboard(JPAEmitterWorkData*, JPABaseParticle*);
|
||||
void JPAInterpRotBillboard(JPAEmitterWorkData*, JPABaseParticle*);
|
||||
void JPAInterpDirection(JPAEmitterWorkData*, JPABaseParticle*);
|
||||
void JPAInterpRotDirection(JPAEmitterWorkData*, JPABaseParticle*);
|
||||
#endif
|
||||
|
||||
#endif /* JPABASESHAPE_H */
|
||||
|
||||
@@ -24,6 +24,9 @@ public:
|
||||
void init_c(JPAEmitterWorkData*, JPABaseParticle*);
|
||||
bool calc_p(JPAEmitterWorkData*);
|
||||
bool calc_c(JPAEmitterWorkData*);
|
||||
#if TARGET_PC
|
||||
void interp(JPAEmitterWorkData*, void const* drawFunc);
|
||||
#endif
|
||||
bool canCreateChild(JPAEmitterWorkData*);
|
||||
f32 getWidth(JPABaseEmitter const*) const;
|
||||
f32 getHeight(JPABaseEmitter const*) const;
|
||||
|
||||
@@ -40,6 +40,9 @@ public:
|
||||
JUTTransparency getTransparency() const { return JUTTransparency(mTransparency); }
|
||||
u16 getNumColors() const { return mNumColors; }
|
||||
ResTLUT* getColorTable() const { return mColorTable; }
|
||||
#if TARGET_PC
|
||||
void dataUploaded();
|
||||
#endif
|
||||
|
||||
private:
|
||||
/* 0x00 */ GXTlutObj mTlutObj;
|
||||
|
||||
@@ -75,6 +75,7 @@ public:
|
||||
s32 getTransparency() const { return mTexInfo->alphaEnabled; }
|
||||
s32 getWidth() const { return mTexInfo->width; }
|
||||
s32 getHeight() const { return mTexInfo->height; }
|
||||
JUTPalette* getPalette() const { return mPalette; }
|
||||
void setCaptureFlag(bool flag) { mFlags &= 2 | flag; }
|
||||
bool getCaptureFlag() const { return mFlags & 1; }
|
||||
bool getEmbPaletteDelFlag() const { return mFlags & 2; }
|
||||
@@ -82,7 +83,7 @@ public:
|
||||
int getTlutName() const { return mTlutName; }
|
||||
bool operator==(const JUTTexture& other) {
|
||||
return mTexInfo == other.mTexInfo
|
||||
&& field_0x2c == other.field_0x2c
|
||||
&& mPalette == other.mPalette
|
||||
&& mWrapS == other.mWrapS
|
||||
&& mWrapT == other.mWrapT
|
||||
&& mMinFilter == other.mMinFilter
|
||||
@@ -100,7 +101,7 @@ private:
|
||||
/* 0x20 */ const ResTIMG* mTexInfo;
|
||||
/* 0x24 */ void* mTexData;
|
||||
/* 0x28 */ JUTPalette* mEmbPalette;
|
||||
/* 0x2C */ JUTPalette* field_0x2c;
|
||||
/* 0x2C */ JUTPalette* mPalette;
|
||||
/* 0x30 */ u8 mWrapS;
|
||||
/* 0x31 */ u8 mWrapT;
|
||||
/* 0x32 */ u8 mMinFilter;
|
||||
|
||||
@@ -556,8 +556,8 @@ void J3DModelLoader::readVertexData(const J3DVertexBlock& block, J3DVertexData&
|
||||
|
||||
if (attr == GX_VA_POS) {
|
||||
// can be a little off due to 0x20 alignment, account for that
|
||||
u32 expect = ((data.mVtxNum * vertStride) + 0x1F) & ~0x1F;
|
||||
JUT_ASSERT(1234, expect == addrDiff);
|
||||
// u32 expect = ((data.mVtxNum * vertStride) + 0x1F) & ~0x1F;
|
||||
// JUT_ASSERT(1234, expect == addrDiff);
|
||||
} else if (attr == GX_VA_NRM) {
|
||||
data.mNrmNum = num;
|
||||
} else if (attr == GX_VA_CLR0) {
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#include "JSystem/JSystem.h" // IWYU pragma: keep
|
||||
|
||||
#include "JSystem/JAudio2/JASChannel.h"
|
||||
#if TARGET_PC
|
||||
#include "dusk/audio/DuskDsp.hpp"
|
||||
#endif
|
||||
#include "JSystem/JAudio2/JASAiCtrl.h"
|
||||
#include "JSystem/JAudio2/JASCalc.h"
|
||||
#include "JSystem/JAudio2/JASDriverIF.h"
|
||||
@@ -170,7 +173,12 @@ void JASChannel::updateEffectorParam(JASDsp::TChannel* i_channel, u16* i_mixerVo
|
||||
|
||||
f32 pan = 0.5f;
|
||||
f32 dolby = 0.0f;
|
||||
switch (JASDriver::getOutputMode()) {
|
||||
#if TARGET_PC
|
||||
u32 effectiveOutputMode = dusk::audio::EnableHrtf ? JAS_OUTPUT_SURROUND : JASDriver::getOutputMode();
|
||||
#else
|
||||
u32 effectiveOutputMode = JASDriver::getOutputMode();
|
||||
#endif
|
||||
switch (effectiveOutputMode) {
|
||||
case JAS_OUTPUT_MONO:
|
||||
break;
|
||||
case JAS_OUTPUT_STEREO:
|
||||
|
||||
@@ -302,7 +302,6 @@ void JASKernel::setupRootHeap(JKRSolidHeap* heap, u32 size) {
|
||||
JKRHEAP_NAME(sSystemHeap, "JASKernel::sSystemHeap");
|
||||
JUT_ASSERT(787, sSystemHeap);
|
||||
sCommandHeap = JKR_NEW_ARGS (heap, 0) JASMemChunkPool<1024, JASThreadingModel::ObjectLevelLockable>;
|
||||
JKRHEAP_NAME(sSystemHeap, "JASKernel::sCommandHeap");
|
||||
JUT_ASSERT(790, sCommandHeap);
|
||||
JASDram = heap;
|
||||
}
|
||||
|
||||
@@ -442,6 +442,7 @@ static JAUSectionHeap* JAUNewSectionHeap(JKRSolidHeap* heap, bool param_1) {
|
||||
JAUSectionHeap* JAUNewSectionHeap(bool param_0) {
|
||||
s32 freeSize = JASDram->getFreeSize();
|
||||
JKRSolidHeap* sectionHeap = JKRCreateSolidHeap(freeSize, JASDram, true);
|
||||
JKRHEAP_NAME(sectionHeap, "sectionHeap");
|
||||
JUT_ASSERT(821, sectionHeap);
|
||||
return JAUNewSectionHeap(sectionHeap, param_0);
|
||||
}
|
||||
|
||||
@@ -222,16 +222,11 @@ void* JKRExpHeap::do_alloc(u32 size, int alignment) {
|
||||
OSReport_Error("Free block list as follows:\n");
|
||||
OSReport_Error("Start | End | Size \n");
|
||||
|
||||
int i = 0;
|
||||
for (const CMemBlock* block = mHeadFreeList; block; block = block->mNext) {
|
||||
if (block->mMagic) {
|
||||
// Allocated, ignore.
|
||||
continue;
|
||||
}
|
||||
if (i++ > 10) {
|
||||
OSReport_Error("<more>\n");
|
||||
break;
|
||||
}
|
||||
|
||||
auto blockStart = (uintptr_t)block - (uintptr_t)mStart;
|
||||
auto blockEnd = (uintptr_t)block + block->size - (uintptr_t)mStart;
|
||||
@@ -239,6 +234,14 @@ void* JKRExpHeap::do_alloc(u32 size, int alignment) {
|
||||
OSReport_Error("%08X | %08X | %08X\n", (u32) blockStart, (u32) blockEnd, (u32) blockSize);
|
||||
}
|
||||
|
||||
OSReport_Error("Child heaps as follows:\n");
|
||||
OSReport_Error("Start | End | Name \n");
|
||||
|
||||
const JSUTree<JKRHeap>& tree = getHeapTree();
|
||||
for (JSUTreeIterator iter(tree.getFirstChild()); iter != tree.getEndChild(); ++iter) {
|
||||
OSReport_Error("%08X | %08X | %s\n", iter->getStartAddr(), iter->getEndAddr(), iter->getName());
|
||||
}
|
||||
|
||||
CRASH("Aborting due to allocation failure!");
|
||||
}
|
||||
#else
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
#include <mtx.h>
|
||||
#include <gx.h>
|
||||
|
||||
#if TARGET_PC
|
||||
#include "dusk/frame_interpolation.h"
|
||||
#endif
|
||||
#include "tracy/Tracy.hpp"
|
||||
|
||||
void JPASetPointSize(JPAEmitterWorkData* work) {
|
||||
@@ -418,50 +421,95 @@ static projectionFunc p_prj[3] = {
|
||||
loadPrjAnm,
|
||||
};
|
||||
|
||||
void JPADrawBillboard(JPAEmitterWorkData* work, JPABaseParticle* param_1) {
|
||||
if (param_1->checkStatus(JPAPtclStts_Invisible)) {
|
||||
#if TARGET_PC
|
||||
void JPAInterpBillboard(JPAEmitterWorkData* work, JPABaseParticle* ptcl) {
|
||||
Mtx ptclPosMtx;
|
||||
MTXTrans(ptclPosMtx, ptcl->mPosition.x, ptcl->mPosition.y, ptcl->mPosition.z);
|
||||
dusk::frame_interp::record_final_mtx(ptclPosMtx, ptcl);
|
||||
}
|
||||
|
||||
void JPAInterpRotBillboard(JPAEmitterWorkData* work, JPABaseParticle* ptcl) {
|
||||
Mtx ptclPosMtx;
|
||||
f32 sinRot = JMASSin(ptcl->mRotateAngle);
|
||||
f32 cosRot = JMASCos(ptcl->mRotateAngle);
|
||||
MTXTrans(ptclPosMtx, ptcl->mPosition.x, ptcl->mPosition.y, ptcl->mPosition.z);
|
||||
ptclPosMtx[0][0] = cosRot;
|
||||
ptclPosMtx[0][1] = -sinRot;
|
||||
ptclPosMtx[1][0] = sinRot;
|
||||
ptclPosMtx[1][1] = cosRot;
|
||||
dusk::frame_interp::record_final_mtx(ptclPosMtx, ptcl);
|
||||
}
|
||||
#endif
|
||||
|
||||
void JPADrawBillboard(JPAEmitterWorkData* work, JPABaseParticle* ptcl) {
|
||||
if (ptcl->checkStatus(JPAPtclStts_Invisible)) {
|
||||
return;
|
||||
}
|
||||
|
||||
JGeometry::TVec3<f32> local_48;
|
||||
MTXMultVec(work->mPosCamMtx, ¶m_1->mPosition, &local_48);
|
||||
Mtx local_38;
|
||||
local_38[0][0] = work->mGlobalPtclScl.x * param_1->mParticleScaleX;
|
||||
local_38[0][3] = local_48.x;
|
||||
local_38[1][1] = work->mGlobalPtclScl.y * param_1->mParticleScaleY;
|
||||
local_38[1][3] = local_48.y;
|
||||
local_38[2][2] = 1.0f;
|
||||
local_38[2][3] = local_48.z;
|
||||
local_38[0][1] = local_38[0][2] = local_38[1][0] = local_38[1][2] = local_38[2][0] = local_38[2][1] = 0.0f;
|
||||
GXLoadPosMtxImm(local_38, 0);
|
||||
p_prj[work->mPrjType](work, local_38);
|
||||
JGeometry::TVec3<f32> pos;
|
||||
#if TARGET_PC
|
||||
Mtx ptclPosMtx;
|
||||
if (dusk::frame_interp::lookup_replacement(ptcl, ptclPosMtx)) {
|
||||
pos.set(ptclPosMtx[0][3], ptclPosMtx[1][3], ptclPosMtx[2][3]);
|
||||
MTXMultVec(work->mPosCamMtx, &pos, &pos);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
MTXMultVec(work->mPosCamMtx, &ptcl->mPosition, &pos);
|
||||
}
|
||||
Mtx posMtx;
|
||||
posMtx[0][0] = work->mGlobalPtclScl.x * ptcl->mParticleScaleX;
|
||||
posMtx[0][3] = pos.x;
|
||||
posMtx[1][1] = work->mGlobalPtclScl.y * ptcl->mParticleScaleY;
|
||||
posMtx[1][3] = pos.y;
|
||||
posMtx[2][2] = 1.0f;
|
||||
posMtx[2][3] = pos.z;
|
||||
posMtx[0][1] = posMtx[0][2] = posMtx[1][0] = posMtx[1][2] = posMtx[2][0] = posMtx[2][1] = 0.0f;
|
||||
GXLoadPosMtxImm(posMtx, GX_PNMTX0);
|
||||
p_prj[work->mPrjType](work, posMtx);
|
||||
GXCallDisplayList(jpa_dl, sizeof(jpa_dl));
|
||||
}
|
||||
|
||||
void JPADrawRotBillboard(JPAEmitterWorkData* work, JPABaseParticle* param_1) {
|
||||
if (param_1->checkStatus(JPAPtclStts_Invisible)) {
|
||||
void JPADrawRotBillboard(JPAEmitterWorkData* work, JPABaseParticle* ptcl) {
|
||||
if (ptcl->checkStatus(JPAPtclStts_Invisible)) {
|
||||
return;
|
||||
}
|
||||
|
||||
JGeometry::TVec3<f32> local_48;
|
||||
MTXMultVec(work->mPosCamMtx, ¶m_1->mPosition, &local_48);
|
||||
f32 sinRot = JMASSin(param_1->mRotateAngle);
|
||||
f32 cosRot = JMASCos(param_1->mRotateAngle);
|
||||
f32 particleX = work->mGlobalPtclScl.x * param_1->mParticleScaleX;
|
||||
f32 particleY = work->mGlobalPtclScl.y * param_1->mParticleScaleY;
|
||||
if (work->mpRes->getUsrIdx() == 0x89d7) {
|
||||
int a = 0;
|
||||
}
|
||||
|
||||
Mtx local_38;
|
||||
local_38[0][0] = cosRot * particleX;
|
||||
local_38[0][1] = -sinRot * particleY;
|
||||
local_38[0][3] = local_48.x;
|
||||
local_38[1][0] = sinRot * particleX;
|
||||
local_38[1][1] = cosRot * particleY;
|
||||
local_38[1][3] = local_48.y;
|
||||
local_38[2][2] = 1.0f;
|
||||
local_38[2][3] = local_48.z;
|
||||
local_38[0][2] = local_38[1][2] = local_38[2][0] = local_38[2][1] = 0.0f;
|
||||
GXLoadPosMtxImm(local_38, 0);
|
||||
p_prj[work->mPrjType](work, local_38);
|
||||
JGeometry::TVec3<f32> pos;
|
||||
f32 sinRot, cosRot;
|
||||
#if TARGET_PC
|
||||
Mtx ptclPosMtx;
|
||||
MTXTrans(ptclPosMtx, ptcl->mPosition.x, ptcl->mPosition.y, ptcl->mPosition.z);
|
||||
if (dusk::frame_interp::lookup_replacement(ptcl, ptclPosMtx)) {
|
||||
pos.set(ptclPosMtx[0][3], ptclPosMtx[1][3], ptclPosMtx[2][3]);
|
||||
sinRot = ptclPosMtx[1][0];
|
||||
cosRot = ptclPosMtx[0][0];
|
||||
MTXMultVec(work->mPosCamMtx, &pos, &pos);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
MTXMultVec(work->mPosCamMtx, &ptcl->mPosition, &pos);
|
||||
sinRot = JMASSin(ptcl->mRotateAngle);
|
||||
cosRot = JMASCos(ptcl->mRotateAngle);
|
||||
}
|
||||
f32 particleX = work->mGlobalPtclScl.x * ptcl->mParticleScaleX;
|
||||
f32 particleY = work->mGlobalPtclScl.y * ptcl->mParticleScaleY;
|
||||
Mtx posMtx;
|
||||
posMtx[0][0] = cosRot * particleX;
|
||||
posMtx[0][1] = -sinRot * particleY;
|
||||
posMtx[0][3] = pos.x;
|
||||
posMtx[1][0] = sinRot * particleX;
|
||||
posMtx[1][1] = cosRot * particleY;
|
||||
posMtx[1][3] = pos.y;
|
||||
posMtx[2][2] = 1.0f;
|
||||
posMtx[2][3] = pos.z;
|
||||
posMtx[0][2] = posMtx[1][2] = posMtx[2][0] = posMtx[2][1] = 0.0f;
|
||||
GXLoadPosMtxImm(posMtx, GX_PNMTX0);
|
||||
p_prj[work->mPrjType](work, posMtx);
|
||||
GXCallDisplayList(jpa_dl, sizeof(jpa_dl));
|
||||
}
|
||||
|
||||
@@ -484,7 +532,7 @@ void JPADrawYBillboard(JPAEmitterWorkData* work, JPABaseParticle* param_1) {
|
||||
local_38[2][2] = work->mYBBCamMtx[2][2];
|
||||
local_38[2][3] = local_48.z;
|
||||
local_38[0][1] = local_38[0][2] = local_38[1][0] = local_38[2][0] = 0.0f;
|
||||
GXLoadPosMtxImm(local_38, 0);
|
||||
GXLoadPosMtxImm(local_38, GX_PNMTX0);
|
||||
p_prj[work->mPrjType](work, local_38);
|
||||
GXCallDisplayList(jpa_dl, sizeof(jpa_dl));
|
||||
}
|
||||
@@ -517,7 +565,7 @@ void JPADrawRotYBillboard(JPAEmitterWorkData* work, JPABaseParticle* param_1) {
|
||||
local_38[2][1] = local_94 * fVar1;
|
||||
local_38[2][2] = local_90;
|
||||
local_38[2][3] = local_48.z;
|
||||
GXLoadPosMtxImm(local_38, 0);
|
||||
GXLoadPosMtxImm(local_38, GX_PNMTX0);
|
||||
p_prj[work->mPrjType](work, local_38);
|
||||
GXCallDisplayList(jpa_dl, sizeof(jpa_dl));
|
||||
}
|
||||
@@ -681,103 +729,197 @@ static u8* p_dl[2] = {
|
||||
jpa_dl_x,
|
||||
};
|
||||
|
||||
void JPADrawDirection(JPAEmitterWorkData* param_0, JPABaseParticle* param_1) {
|
||||
if (param_1->checkStatus(JPAPtclStts_Invisible)) {
|
||||
#if TARGET_PC
|
||||
void JPAInterpDirection(JPAEmitterWorkData* work, JPABaseParticle* ptcl) {
|
||||
JGeometry::TVec3<f32> axisY;
|
||||
JGeometry::TVec3<f32> axisZ;
|
||||
p_direction[work->mDirType](work, ptcl, &axisY);
|
||||
|
||||
if (axisY.isZero()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ZoneScoped;
|
||||
axisY.normalize();
|
||||
axisZ.cross(ptcl->mBaseAxis, axisY);
|
||||
|
||||
JGeometry::TVec3<f32> local_6c;
|
||||
JGeometry::TVec3<f32> local_78;
|
||||
p_direction[param_0->mDirType](param_0, param_1, &local_6c);
|
||||
|
||||
if (local_6c.isZero()) {
|
||||
if (axisZ.isZero()) {
|
||||
return;
|
||||
}
|
||||
|
||||
local_6c.normalize();
|
||||
local_78.cross(param_1->mBaseAxis, local_6c);
|
||||
|
||||
if (local_78.isZero()) {
|
||||
return;
|
||||
}
|
||||
|
||||
local_78.normalize();
|
||||
param_1->mBaseAxis.cross(local_6c, local_78);
|
||||
param_1->mBaseAxis.normalize();
|
||||
Mtx local_60;
|
||||
f32 fVar1 = param_0->mGlobalPtclScl.x * param_1->mParticleScaleX;
|
||||
f32 fVar2 = param_0->mGlobalPtclScl.y * param_1->mParticleScaleY;
|
||||
local_60[0][0] = param_1->mBaseAxis.x;
|
||||
local_60[0][1] = local_6c.x;
|
||||
local_60[0][2] = local_78.x;
|
||||
local_60[0][3] = param_1->mPosition.x;
|
||||
local_60[1][0] = param_1->mBaseAxis.y;
|
||||
local_60[1][1] = local_6c.y;
|
||||
local_60[1][2] = local_78.y;
|
||||
local_60[1][3] = param_1->mPosition.y;
|
||||
local_60[2][0] = param_1->mBaseAxis.z;
|
||||
local_60[2][1] = local_6c.z;
|
||||
local_60[2][2] = local_78.z;
|
||||
local_60[2][3] = param_1->mPosition.z;
|
||||
p_plane[param_0->mPlaneType](local_60, fVar1, fVar2);
|
||||
MTXConcat(param_0->mPosCamMtx, local_60, local_60);
|
||||
GXLoadPosMtxImm(local_60, 0);
|
||||
p_prj[param_0->mPrjType](param_0, local_60);
|
||||
GXCallDisplayList(p_dl[param_0->mDLType], sizeof(jpa_dl));
|
||||
axisZ.normalize();
|
||||
ptcl->mBaseAxis.cross(axisY, axisZ);
|
||||
ptcl->mBaseAxis.normalize();
|
||||
Mtx posMtx;
|
||||
f32 scaleX = work->mGlobalPtclScl.x * ptcl->mParticleScaleX;
|
||||
f32 scaleY = work->mGlobalPtclScl.y * ptcl->mParticleScaleY;
|
||||
posMtx[0][0] = ptcl->mBaseAxis.x;
|
||||
posMtx[0][1] = axisY.x;
|
||||
posMtx[0][2] = axisZ.x;
|
||||
posMtx[0][3] = ptcl->mPosition.x;
|
||||
posMtx[1][0] = ptcl->mBaseAxis.y;
|
||||
posMtx[1][1] = axisY.y;
|
||||
posMtx[1][2] = axisZ.y;
|
||||
posMtx[1][3] = ptcl->mPosition.y;
|
||||
posMtx[2][0] = ptcl->mBaseAxis.z;
|
||||
posMtx[2][1] = axisY.z;
|
||||
posMtx[2][2] = axisZ.z;
|
||||
posMtx[2][3] = ptcl->mPosition.z;
|
||||
p_plane[work->mPlaneType](posMtx, scaleX, scaleY);
|
||||
dusk::frame_interp::record_final_mtx(posMtx, ptcl);
|
||||
}
|
||||
|
||||
void JPADrawRotDirection(JPAEmitterWorkData* param_0, JPABaseParticle* param_1) {
|
||||
if (param_1->checkStatus(JPAPtclStts_Invisible)) {
|
||||
void JPAInterpRotDirection(JPAEmitterWorkData* work, JPABaseParticle* ptcl) {
|
||||
f32 sinRot = JMASSin(ptcl->mRotateAngle);
|
||||
f32 cosRot = JMASCos(ptcl->mRotateAngle);
|
||||
JGeometry::TVec3<f32> axisY;
|
||||
JGeometry::TVec3<f32> axisZ;
|
||||
p_direction[work->mDirType](work, ptcl, &axisY);
|
||||
|
||||
if (axisY.isZero()) {
|
||||
return;
|
||||
}
|
||||
|
||||
axisY.normalize();
|
||||
axisZ.cross(ptcl->mBaseAxis, axisY);
|
||||
|
||||
if (axisZ.isZero()) {
|
||||
return;
|
||||
}
|
||||
|
||||
axisZ.normalize();
|
||||
ptcl->mBaseAxis.cross(axisY, axisZ);
|
||||
ptcl->mBaseAxis.normalize();
|
||||
f32 scaleX = work->mGlobalPtclScl.x * ptcl->mParticleScaleX;
|
||||
f32 scaleY = work->mGlobalPtclScl.y * ptcl->mParticleScaleY;
|
||||
Mtx mtx1;
|
||||
Mtx mtx2;
|
||||
p_rot[work->mRotType](sinRot, cosRot, mtx1);
|
||||
p_plane[work->mPlaneType](mtx1, scaleX, scaleY);
|
||||
mtx2[0][0] = ptcl->mBaseAxis.x;
|
||||
mtx2[0][1] = axisY.x;
|
||||
mtx2[0][2] = axisZ.x;
|
||||
mtx2[0][3] = ptcl->mPosition.x;
|
||||
mtx2[1][0] = ptcl->mBaseAxis.y;
|
||||
mtx2[1][1] = axisY.y;
|
||||
mtx2[1][2] = axisZ.y;
|
||||
mtx2[1][3] = ptcl->mPosition.y;
|
||||
mtx2[2][0] = ptcl->mBaseAxis.z;
|
||||
mtx2[2][1] = axisY.z;
|
||||
mtx2[2][2] = axisZ.z;
|
||||
mtx2[2][3] = ptcl->mPosition.z;
|
||||
MTXConcat(mtx2, mtx1, mtx1);
|
||||
dusk::frame_interp::record_final_mtx(mtx1, ptcl);
|
||||
}
|
||||
#endif
|
||||
|
||||
void JPADrawDirection(JPAEmitterWorkData* work, JPABaseParticle* ptcl) {
|
||||
if (ptcl->checkStatus(JPAPtclStts_Invisible)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ZoneScoped;
|
||||
|
||||
f32 sinRot = JMASSin(param_1->mRotateAngle);
|
||||
f32 cosRot = JMASCos(param_1->mRotateAngle);
|
||||
JGeometry::TVec3<f32> local_6c;
|
||||
JGeometry::TVec3<f32> local_78;
|
||||
p_direction[param_0->mDirType](param_0, param_1, &local_6c);
|
||||
Mtx posMtx;
|
||||
#if TARGET_PC
|
||||
if (!dusk::frame_interp::lookup_replacement(ptcl, posMtx))
|
||||
#endif
|
||||
{
|
||||
JGeometry::TVec3<f32> axisY;
|
||||
JGeometry::TVec3<f32> axisZ;
|
||||
p_direction[work->mDirType](work, ptcl, &axisY);
|
||||
|
||||
if (local_6c.isZero()) {
|
||||
if (axisY.isZero()) {
|
||||
return;
|
||||
}
|
||||
|
||||
axisY.normalize();
|
||||
axisZ.cross(ptcl->mBaseAxis, axisY);
|
||||
|
||||
if (axisZ.isZero()) {
|
||||
return;
|
||||
}
|
||||
|
||||
axisZ.normalize();
|
||||
ptcl->mBaseAxis.cross(axisY, axisZ);
|
||||
ptcl->mBaseAxis.normalize();
|
||||
f32 scaleX = work->mGlobalPtclScl.x * ptcl->mParticleScaleX;
|
||||
f32 scaleY = work->mGlobalPtclScl.y * ptcl->mParticleScaleY;
|
||||
posMtx[0][0] = ptcl->mBaseAxis.x;
|
||||
posMtx[0][1] = axisY.x;
|
||||
posMtx[0][2] = axisZ.x;
|
||||
posMtx[0][3] = ptcl->mPosition.x;
|
||||
posMtx[1][0] = ptcl->mBaseAxis.y;
|
||||
posMtx[1][1] = axisY.y;
|
||||
posMtx[1][2] = axisZ.y;
|
||||
posMtx[1][3] = ptcl->mPosition.y;
|
||||
posMtx[2][0] = ptcl->mBaseAxis.z;
|
||||
posMtx[2][1] = axisY.z;
|
||||
posMtx[2][2] = axisZ.z;
|
||||
posMtx[2][3] = ptcl->mPosition.z;
|
||||
p_plane[work->mPlaneType](posMtx, scaleX, scaleY);
|
||||
}
|
||||
|
||||
MTXConcat(work->mPosCamMtx, posMtx, posMtx);
|
||||
GXLoadPosMtxImm(posMtx, GX_PNMTX0);
|
||||
p_prj[work->mPrjType](work, posMtx);
|
||||
GXCallDisplayList(p_dl[work->mDLType], sizeof(jpa_dl));
|
||||
}
|
||||
|
||||
void JPADrawRotDirection(JPAEmitterWorkData* work, JPABaseParticle* ptcl) {
|
||||
if (ptcl->checkStatus(JPAPtclStts_Invisible)) {
|
||||
return;
|
||||
}
|
||||
|
||||
local_6c.normalize();
|
||||
local_78.cross(param_1->mBaseAxis, local_6c);
|
||||
ZoneScoped;
|
||||
|
||||
if (local_78.isZero()) {
|
||||
return;
|
||||
Mtx mtx1;
|
||||
Mtx mtx2;
|
||||
#if TARGET_PC
|
||||
if (!dusk::frame_interp::lookup_replacement(ptcl, mtx1))
|
||||
#endif
|
||||
{
|
||||
f32 sinRot = JMASSin(ptcl->mRotateAngle);
|
||||
f32 cosRot = JMASCos(ptcl->mRotateAngle);
|
||||
JGeometry::TVec3<f32> axisY;
|
||||
JGeometry::TVec3<f32> axisZ;
|
||||
p_direction[work->mDirType](work, ptcl, &axisY);
|
||||
|
||||
if (axisY.isZero()) {
|
||||
return;
|
||||
}
|
||||
|
||||
axisY.normalize();
|
||||
axisZ.cross(ptcl->mBaseAxis, axisY);
|
||||
|
||||
if (axisZ.isZero()) {
|
||||
return;
|
||||
}
|
||||
|
||||
axisZ.normalize();
|
||||
ptcl->mBaseAxis.cross(axisY, axisZ);
|
||||
ptcl->mBaseAxis.normalize();
|
||||
f32 scaleX = work->mGlobalPtclScl.x * ptcl->mParticleScaleX;
|
||||
f32 scaleY = work->mGlobalPtclScl.y * ptcl->mParticleScaleY;
|
||||
p_rot[work->mRotType](sinRot, cosRot, mtx1);
|
||||
p_plane[work->mPlaneType](mtx1, scaleX, scaleY);
|
||||
mtx2[0][0] = ptcl->mBaseAxis.x;
|
||||
mtx2[0][1] = axisY.x;
|
||||
mtx2[0][2] = axisZ.x;
|
||||
mtx2[0][3] = ptcl->mPosition.x;
|
||||
mtx2[1][0] = ptcl->mBaseAxis.y;
|
||||
mtx2[1][1] = axisY.y;
|
||||
mtx2[1][2] = axisZ.y;
|
||||
mtx2[1][3] = ptcl->mPosition.y;
|
||||
mtx2[2][0] = ptcl->mBaseAxis.z;
|
||||
mtx2[2][1] = axisY.z;
|
||||
mtx2[2][2] = axisZ.z;
|
||||
mtx2[2][3] = ptcl->mPosition.z;
|
||||
MTXConcat(mtx2, mtx1, mtx1);
|
||||
}
|
||||
|
||||
local_78.normalize();
|
||||
param_1->mBaseAxis.cross(local_6c, local_78);
|
||||
param_1->mBaseAxis.normalize();
|
||||
f32 particleX = param_0->mGlobalPtclScl.x * param_1->mParticleScaleX;
|
||||
f32 particleY = param_0->mGlobalPtclScl.y * param_1->mParticleScaleY;
|
||||
Mtx auStack_80;
|
||||
Mtx local_60;
|
||||
p_rot[param_0->mRotType](sinRot, cosRot, auStack_80);
|
||||
p_plane[param_0->mPlaneType](auStack_80, particleX, particleY);
|
||||
local_60[0][0] = param_1->mBaseAxis.x;
|
||||
local_60[0][1] = local_6c.x;
|
||||
local_60[0][2] = local_78.x;
|
||||
local_60[0][3] = param_1->mPosition.x;
|
||||
local_60[1][0] = param_1->mBaseAxis.y;
|
||||
local_60[1][1] = local_6c.y;
|
||||
local_60[1][2] = local_78.y;
|
||||
local_60[1][3] = param_1->mPosition.y;
|
||||
local_60[2][0] = param_1->mBaseAxis.z;
|
||||
local_60[2][1] = local_6c.z;
|
||||
local_60[2][2] = local_78.z;
|
||||
local_60[2][3] = param_1->mPosition.z;
|
||||
MTXConcat(local_60, auStack_80, auStack_80);
|
||||
MTXConcat(param_0->mPosCamMtx, auStack_80, local_60);
|
||||
GXLoadPosMtxImm(local_60, 0);
|
||||
p_prj[param_0->mPrjType](param_0, local_60);
|
||||
GXCallDisplayList(p_dl[param_0->mDLType], sizeof(jpa_dl));
|
||||
MTXConcat(work->mPosCamMtx, mtx1, mtx2);
|
||||
GXLoadPosMtxImm(mtx2, GX_PNMTX0);
|
||||
p_prj[work->mPrjType](work, mtx2);
|
||||
GXCallDisplayList(p_dl[work->mDLType], sizeof(jpa_dl));
|
||||
}
|
||||
|
||||
void JPADrawDBillboard(JPAEmitterWorkData* param_0, JPABaseParticle* param_1) {
|
||||
|
||||
@@ -204,6 +204,28 @@ void JPABaseParticle::init_c(JPAEmitterWorkData* work, JPABaseParticle* parent)
|
||||
mTexAnmIdx = 0;
|
||||
}
|
||||
|
||||
#if TARGET_PC
|
||||
void JPABaseParticle::interp(JPAEmitterWorkData* work, void const* drawFunc) {
|
||||
static bool enable = false;
|
||||
if (!enable)
|
||||
return;
|
||||
|
||||
// don't interpolate the first frame
|
||||
if (mAge == 0)
|
||||
return;
|
||||
|
||||
if (drawFunc == JPADrawBillboard) {
|
||||
JPAInterpBillboard(work, this);
|
||||
} else if (drawFunc == JPADrawRotBillboard) {
|
||||
JPAInterpRotBillboard(work, this);
|
||||
} else if (drawFunc == JPADrawDirection) {
|
||||
JPAInterpDirection(work, this);
|
||||
} else if (drawFunc == JPADrawRotDirection) {
|
||||
JPAInterpRotDirection(work, this);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool JPABaseParticle::calc_p(JPAEmitterWorkData* work) {
|
||||
if (++mAge >= mLifeTime) {
|
||||
return true;
|
||||
@@ -247,6 +269,17 @@ bool JPABaseParticle::calc_p(JPAEmitterWorkData* work) {
|
||||
mOffsetPosition.y + mLocalPosition.y * work->mPublicScale.y,
|
||||
mOffsetPosition.z + mLocalPosition.z * work->mPublicScale.z);
|
||||
|
||||
#if TARGET_PC
|
||||
JPABaseShape* pBsp = work->mpRes->getBsp();
|
||||
work->mGlobalPtclScl.x = work->mpEmtr->mGlobalPScl.x * pBsp->getBaseSizeX();
|
||||
work->mGlobalPtclScl.y = work->mpEmtr->mGlobalPScl.y * pBsp->getBaseSizeY();
|
||||
work->mDirType = pBsp->getDirType();
|
||||
work->mRotType = pBsp->getRotType();
|
||||
work->mDLType = pBsp->getType() == 4 || pBsp->getType() == 8;
|
||||
work->mPlaneType = work->mDLType ? 2 : pBsp->getBasePlaneType();
|
||||
interp(work, (void const*)work->mpRes->mpDrawParticleFuncList[0]);
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -289,6 +322,23 @@ bool JPABaseParticle::calc_c(JPAEmitterWorkData* work) {
|
||||
mOffsetPosition.y + mLocalPosition.y * work->mPublicScale.y,
|
||||
mOffsetPosition.z + mLocalPosition.z * work->mPublicScale.z);
|
||||
|
||||
#if TARGET_PC
|
||||
JPABaseShape* pBsp = work->mpRes->getBsp();
|
||||
JPAChildShape* pCsp = work->mpRes->getCsp();
|
||||
if (pCsp->isScaleInherited()) {
|
||||
work->mGlobalPtclScl.x = work->mpEmtr->mGlobalPScl.x * pBsp->getBaseSizeX();
|
||||
work->mGlobalPtclScl.y = work->mpEmtr->mGlobalPScl.y * pBsp->getBaseSizeY();
|
||||
} else {
|
||||
work->mGlobalPtclScl.x = work->mpEmtr->mGlobalPScl.x * pCsp->getScaleX();
|
||||
work->mGlobalPtclScl.y = work->mpEmtr->mGlobalPScl.y * pCsp->getScaleY();
|
||||
}
|
||||
work->mDirType = pCsp->getDirType();
|
||||
work->mRotType = pCsp->getRotType();
|
||||
work->mDLType = pCsp->getType() == 4 || pCsp->getType() == 8;
|
||||
work->mPlaneType = work->mDLType ? 2 : pCsp->getBasePlaneType();
|
||||
interp(work, (void const*)work->mpRes->mpDrawParticleChildFuncList[0]);
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,3 +38,9 @@ bool JUTPalette::load() {
|
||||
|
||||
return check;
|
||||
}
|
||||
|
||||
#if TARGET_PC
|
||||
void JUTPalette::dataUploaded() {
|
||||
GXInitTlutObjData(&mTlutObj, (void*)mColorTable);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -27,7 +27,7 @@ void JUTTexture::storeTIMG(ResTIMG const* param_0, u8 param_1) {
|
||||
mTexData = (void*)((intptr_t)mTexInfo + 0x20);
|
||||
}
|
||||
|
||||
field_0x2c = NULL;
|
||||
mPalette = NULL;
|
||||
mTlutName = 0;
|
||||
mWrapS = mTexInfo->wrapS;
|
||||
mWrapT = mTexInfo->wrapT;
|
||||
@@ -95,7 +95,7 @@ void JUTTexture::storeTIMG(ResTIMG const* param_0, JUTPalette* param_1, GXTlut p
|
||||
}
|
||||
mEmbPalette = param_1;
|
||||
setEmbPaletteDelFlag(false);
|
||||
field_0x2c = NULL;
|
||||
mPalette = NULL;
|
||||
if (param_1 != NULL) {
|
||||
mTlutName = param_2;
|
||||
if (param_2 != param_1->getTlutName()) {
|
||||
@@ -120,11 +120,11 @@ void JUTTexture::storeTIMG(ResTIMG const* param_0, JUTPalette* param_1, GXTlut p
|
||||
void JUTTexture::attachPalette(JUTPalette* param_0) {
|
||||
if (mTexInfo->indexTexture) {
|
||||
if (param_0 == NULL && mEmbPalette != NULL) {
|
||||
field_0x2c = mEmbPalette;
|
||||
mPalette = mEmbPalette;
|
||||
} else {
|
||||
field_0x2c = param_0;
|
||||
mPalette = param_0;
|
||||
}
|
||||
initTexObj(field_0x2c->getTlutName());
|
||||
initTexObj(mPalette->getTlutName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,9 +133,9 @@ void JUTTexture::init() {
|
||||
initTexObj();
|
||||
} else {
|
||||
if (mEmbPalette != NULL) {
|
||||
field_0x2c = mEmbPalette;
|
||||
mPalette = mEmbPalette;
|
||||
|
||||
initTexObj(field_0x2c->getTlutName());
|
||||
initTexObj(mPalette->getTlutName());
|
||||
} else {
|
||||
OS_REPORT("This texture is CI-Format, but EmbPalette is NULL.\n");
|
||||
}
|
||||
@@ -179,8 +179,8 @@ void JUTTexture::initTexObj(GXTlut param_0) {
|
||||
}
|
||||
|
||||
void JUTTexture::load(GXTexMapID param_0) {
|
||||
if (field_0x2c) {
|
||||
field_0x2c->load();
|
||||
if (mPalette) {
|
||||
mPalette->load();
|
||||
}
|
||||
GXLoadTexObj(&mTexObj, param_0);
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 457 KiB |
|
Before Width: | Height: | Size: 188 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 1.3 MiB |
@@ -0,0 +1,276 @@
|
||||
*, *:before, *:after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
overflow: visible;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: "Fira Sans";
|
||||
font-weight: normal;
|
||||
font-size: 20dp;
|
||||
color: #E0DBC8;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
align-items: stretch;
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
fps,
|
||||
toast {
|
||||
position: absolute;
|
||||
border: 1dp #92875B;
|
||||
background-color: rgba(21, 22, 16, 80%);
|
||||
}
|
||||
|
||||
toast {
|
||||
top: 40dp;
|
||||
right: 40dp;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
border-radius: 14dp;
|
||||
overflow: hidden;
|
||||
backdrop-filter: blur(5dp);
|
||||
box-shadow: 0 0 15dp 3dp;
|
||||
filter: opacity(0);
|
||||
transform: scale(0.9);
|
||||
transform-origin: center;
|
||||
transition: filter transform 0.2s cubic-in-out;
|
||||
padding: 18dp 24dp;
|
||||
gap: 8dp;
|
||||
}
|
||||
|
||||
toast[open] {
|
||||
filter: opacity(1);
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
/*toast:hover {
|
||||
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%;
|
||||
}
|
||||
|
||||
toast progress fill {
|
||||
background-color: rgba(194, 164, 45, 80%);
|
||||
}
|
||||
|
||||
toast.achievement {
|
||||
border: 1dp #C2A42D;
|
||||
}
|
||||
|
||||
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;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
toast.menu-notification message row {
|
||||
align-items: center;
|
||||
gap: 6dp;
|
||||
}
|
||||
|
||||
icon {
|
||||
font-family: "Material Symbols Rounded";
|
||||
font-weight: normal;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
icon.arrow-forward {
|
||||
width: 24dp;
|
||||
height: 24dp;
|
||||
font-size: 24dp;
|
||||
decorator: text("" center center);
|
||||
}
|
||||
|
||||
icon.trophy {
|
||||
width: 24dp;
|
||||
height: 24dp;
|
||||
font-size: 24dp;
|
||||
decorator: text("" center center);
|
||||
}
|
||||
|
||||
icon.controller {
|
||||
width: 24dp;
|
||||
height: 24dp;
|
||||
font-size: 24dp;
|
||||
decorator: text("" center center);
|
||||
}
|
||||
|
||||
icon.warning {
|
||||
width: 24dp;
|
||||
height: 24dp;
|
||||
font-size: 24dp;
|
||||
decorator: text("" center center);
|
||||
}
|
||||
|
||||
fps {
|
||||
display: none;
|
||||
z-index: 99;
|
||||
font-size: 18dp;
|
||||
font-weight: bold;
|
||||
padding: 9dp 12dp;
|
||||
border-radius: 7dp;
|
||||
pointer-events: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
fps[open] {
|
||||
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%;
|
||||
height: 100%;
|
||||
filter: drop-shadow(#0008 0 0 14dp);
|
||||
transform-origin: center;
|
||||
}
|
||||
|
||||
logo img.inner {
|
||||
animation: 24s linear-in-out infinite logo-inner-spin;
|
||||
}
|
||||
|
||||
logo img.outer {
|
||||
animation: 8s linear-in-out infinite logo-outer-spin;
|
||||
}
|
||||
|
||||
@keyframes logo-inner-spin {
|
||||
from {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes logo-outer-spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
*, *:before, *:after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
overflow: visible;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: "Fira Sans Condensed";
|
||||
font-weight: bold;
|
||||
font-size: 18dp;
|
||||
color: #E0DBC8;
|
||||
}
|
||||
|
||||
button {
|
||||
cursor: pointer;
|
||||
focus: auto;
|
||||
}
|
||||
|
||||
popup {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
height: 64dp;
|
||||
background-color: rgba(21, 22, 16, 80%);
|
||||
border-bottom: 2dp #92875B;
|
||||
backdrop-filter: blur(5dp);
|
||||
transform: translateY(-64dp);
|
||||
transition: transform 0.2s cubic-in-out;
|
||||
}
|
||||
|
||||
popup[open] {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
popup tab-bar {
|
||||
flex: 1 1 0;
|
||||
}
|
||||
|
||||
popup tab-bar tab {
|
||||
opacity: 0.35;
|
||||
color: #E0DBC8;
|
||||
}
|
||||
@@ -0,0 +1,405 @@
|
||||
*, *:before, *:after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-family: "Fira Sans";
|
||||
font-weight: normal;
|
||||
font-size: 20dp;
|
||||
color: #FFFFFF;
|
||||
filter: opacity(0);
|
||||
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);
|
||||
opacity: 0;
|
||||
transition: opacity 1s linear-in-out;
|
||||
}
|
||||
|
||||
body[open] {
|
||||
filter: opacity(1);
|
||||
}
|
||||
|
||||
body[open] .background {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
body.disc-ready .background {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
content {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
filter: opacity(0);
|
||||
transition: filter 0.2s linear-in-out;
|
||||
}
|
||||
|
||||
content[open] {
|
||||
filter: opacity(1);
|
||||
}
|
||||
|
||||
menu {
|
||||
position: absolute;
|
||||
left: 96dp;
|
||||
right: auto;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
/* Scale based on a reference screen width, 428/1216 */
|
||||
width: 35.230264vw;
|
||||
min-width: 428dp;
|
||||
max-width: 856dp;
|
||||
height: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 48dp;
|
||||
}
|
||||
|
||||
body.mirrored menu {
|
||||
left: auto;
|
||||
right: 96dp;
|
||||
}
|
||||
|
||||
hero {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
gap: 8dp;
|
||||
}
|
||||
|
||||
body.mirrored hero {
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
hero img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.eyebrow {
|
||||
font-family: "Alegreya SC";
|
||||
font-size: 32dp;
|
||||
}
|
||||
|
||||
@media (min-width: 1216dp) {
|
||||
.eyebrow {
|
||||
/* Same logic as .menu, 32/1216 */
|
||||
font-size: 2.631579vw;
|
||||
}
|
||||
}
|
||||
|
||||
.eyebrow span {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#menu-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12dp;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
#menu-list button {
|
||||
width: 428dp;
|
||||
height: 54dp;
|
||||
padding: 8dp 16dp;
|
||||
border-radius: 8dp;
|
||||
text-align: left;
|
||||
text-transform: uppercase;
|
||||
font-family: "Fira Sans Condensed";
|
||||
font-size: 32dp;
|
||||
font-weight: normal;
|
||||
cursor: pointer;
|
||||
/* Define a fully transparent gradient as the default state, otherwise a white flash occurs */
|
||||
decorator: horizontal-gradient(#00000000 #00000000);
|
||||
}
|
||||
|
||||
#menu-list button:disabled {
|
||||
opacity: 0.75;
|
||||
cursor: default;
|
||||
decorator: horizontal-gradient(#00000000 #00000000);
|
||||
}
|
||||
|
||||
#menu-list button.anim-done {
|
||||
transition: decorator color opacity 0.1s linear-in-out;
|
||||
}
|
||||
|
||||
#menu-list button:hover,
|
||||
#menu-list button:focus-visible {
|
||||
color: black;
|
||||
decorator: horizontal-gradient(#FEE685FF #FEE68500);
|
||||
}
|
||||
|
||||
body.mirrored #menu-list {
|
||||
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;
|
||||
left: 96dp;
|
||||
right: auto;
|
||||
bottom: 72dp;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12dp;
|
||||
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 {
|
||||
position: absolute;
|
||||
right: 96dp;
|
||||
left: auto;
|
||||
bottom: 72dp;
|
||||
display: flex;
|
||||
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;
|
||||
}
|
||||
|
||||
#disc-status[status=good] {
|
||||
color: #D8F999;
|
||||
}
|
||||
|
||||
#disc-status[status=bad] {
|
||||
color: #FFC9C9;
|
||||
}
|
||||
|
||||
#disc-status[status=verifying] {
|
||||
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("" center center);
|
||||
}
|
||||
|
||||
#disc-status[status=bad] icon {
|
||||
decorator: text("" center center);
|
||||
}
|
||||
|
||||
#disc-status[status=verifying] icon {
|
||||
decorator: text("" center center);
|
||||
}
|
||||
|
||||
#disc-status[status=mismatch] icon {
|
||||
decorator: text("" center center);
|
||||
}
|
||||
|
||||
#disc-status[status=unknown] icon {
|
||||
decorator: text("" center center);
|
||||
}
|
||||
|
||||
#disc-status[status=pending] icon {
|
||||
decorator: text("" center center);
|
||||
}
|
||||
|
||||
#disc-version {
|
||||
font-size: 20dp;
|
||||
}
|
||||
|
||||
/* TODO: Hidden until an actual update checker is introduced */
|
||||
.update {
|
||||
display: none;
|
||||
font-size: 16dp;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
color: #D8F999;
|
||||
}
|
||||
|
||||
.detail,
|
||||
.update span {
|
||||
color: #A6A09B;
|
||||
}
|
||||
|
||||
/* Startup animation */
|
||||
.intro-item {
|
||||
opacity: 0;
|
||||
transform: translateY(10dp);
|
||||
transition: opacity transform 0.3s 0.1s cubic-in-out;
|
||||
}
|
||||
|
||||
body.animate-in .intro-item {
|
||||
opacity: 1;
|
||||
transform: translateY(0dp);
|
||||
}
|
||||
|
||||
.delay-0 {
|
||||
transition: opacity transform 0.3s 0.1s cubic-in-out;
|
||||
}
|
||||
|
||||
.delay-1 {
|
||||
transition: opacity transform 0.3s 0.2s cubic-in-out;
|
||||
}
|
||||
|
||||
.delay-2 {
|
||||
transition: opacity transform 0.3s 0.3s cubic-in-out;
|
||||
}
|
||||
|
||||
.delay-3 {
|
||||
transition: opacity transform 0.3s 0.4s cubic-in-out;
|
||||
}
|
||||
|
||||
.delay-4 {
|
||||
transition: opacity transform 0.3s 0.5s cubic-in-out;
|
||||
}
|
||||
|
||||
.delay-5 {
|
||||
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: 20dp;
|
||||
right: 20dp;
|
||||
width: auto;
|
||||
min-width: 0;
|
||||
max-width: none;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16dp;
|
||||
}
|
||||
|
||||
body.mirrored menu {
|
||||
left: 20dp;
|
||||
right: 20dp;
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
hero {
|
||||
flex: 1 1 0;
|
||||
min-width: 0;
|
||||
max-width: 48%;
|
||||
|
||||
}
|
||||
|
||||
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,
|
||||
disc-info,
|
||||
version-info {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
tab-bar {
|
||||
display: flex;
|
||||
position: relative;
|
||||
min-width: 0;
|
||||
overflow: auto hidden;
|
||||
clip: always;
|
||||
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 {
|
||||
flex: 0 0 auto;
|
||||
padding: 0 24dp;
|
||||
line-height: 64dp;
|
||||
white-space: nowrap;
|
||||
decorator: vertical-gradient(#c2a42d00 #c2a42d00);
|
||||
transition: decorator 0.1s linear-in-out, opacity 0.1s linear-in-out;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
tab-bar tab:selected {
|
||||
opacity: 1;
|
||||
border-bottom: 4dp #C2A42D;
|
||||
font-effect: glow(0dp 4dp 0dp 4dp black);
|
||||
}
|
||||
|
||||
tab-bar tab:focus-visible,
|
||||
tab-bar tab:hover {
|
||||
opacity: 1;
|
||||
font-effect: glow(0dp 4dp 0dp 4dp black);
|
||||
decorator: vertical-gradient(#c2a42d00 #c2a42d26);
|
||||
}
|
||||
|
||||
tab-bar tab:active {
|
||||
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("" 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%);
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
*, *: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;
|
||||
}
|
||||
@@ -0,0 +1,493 @@
|
||||
*, *:before, *:after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 64dp;
|
||||
font-family: "Fira Sans";
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-size: 15dp;
|
||||
color: #E0DBC8;
|
||||
}
|
||||
|
||||
window {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
max-width: 1088dp;
|
||||
max-height: 768dp;
|
||||
margin: auto;
|
||||
border-radius: 14dp;
|
||||
overflow: hidden;
|
||||
border: 2dp #92875B;
|
||||
backdrop-filter: blur(5dp);
|
||||
box-shadow: 0 0 25dp 5dp;
|
||||
background-color: rgba(21, 22, 16, 90%);
|
||||
filter: opacity(0);
|
||||
transform: scale(0.9);
|
||||
transform-origin: center;
|
||||
transition: filter transform 0.2s cubic-in-out;
|
||||
}
|
||||
|
||||
window.small {
|
||||
height: auto;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
window.modal {
|
||||
max-width: 640dp;
|
||||
}
|
||||
|
||||
window[open] {
|
||||
filter: opacity(1);
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
@media (max-height: 640dp) {
|
||||
body {
|
||||
padding: 16dp;
|
||||
}
|
||||
window {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
window tab-bar {
|
||||
flex: 0 0 64dp;
|
||||
height: 64dp;
|
||||
background-color: rgba(217, 217, 217, 10%);
|
||||
font-family: "Fira Sans Condensed";
|
||||
font-weight: bold;
|
||||
font-size: 18dp;
|
||||
border-bottom: 2dp #92875B;
|
||||
}
|
||||
|
||||
window tab-bar tab {
|
||||
opacity: 0.25;
|
||||
}
|
||||
|
||||
window content {
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
window content pane {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
flex: 1 1 0;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
padding: 24dp;
|
||||
padding-bottom: 0dp;
|
||||
gap: 8dp;
|
||||
overflow: hidden auto;
|
||||
font-size: 20dp;
|
||||
}
|
||||
|
||||
window content pane:not(:last-of-type) {
|
||||
border-right: 1dp #92875B;
|
||||
}
|
||||
|
||||
window content pane > * {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
window content pane:last-of-type > div {
|
||||
line-height: 1.625;
|
||||
}
|
||||
|
||||
window content pane > spacer {
|
||||
display: block;
|
||||
/* Completes the 24dp bottom inset after the pane's 8dp gap. */
|
||||
flex: 0 0 16dp;
|
||||
height: 16dp;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
scrollbarvertical {
|
||||
width: 8dp;
|
||||
margin: 4dp 4dp 4dp 0;
|
||||
}
|
||||
|
||||
scrollbarvertical sliderarrowdec,
|
||||
scrollbarvertical sliderarrowinc {
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
scrollbarvertical slidertrack {
|
||||
width: 8dp;
|
||||
}
|
||||
|
||||
scrollbarvertical sliderbar {
|
||||
width: 8dp;
|
||||
min-height: 24dp;
|
||||
background-color: rgba(224, 219, 200, 45%);
|
||||
border-radius: 2dp;
|
||||
transition: background-color 0.2s cubic-in-out;
|
||||
}
|
||||
|
||||
scrollbarvertical sliderbar:hover,
|
||||
scrollbarvertical sliderbar:active {
|
||||
background-color: rgba(194, 164, 45, 80%);
|
||||
}
|
||||
|
||||
scrollbarhorizontal {
|
||||
height: 0;
|
||||
}
|
||||
|
||||
scrollbarhorizontal sliderarrowdec,
|
||||
scrollbarhorizontal sliderarrowinc {
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
scrollbarhorizontal slidertrack,
|
||||
scrollbarhorizontal sliderbar {
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.section-heading {
|
||||
font-family: "Fira Sans Condensed";
|
||||
font-weight: bold;
|
||||
text-transform: uppercase;
|
||||
font-size: 22dp;
|
||||
opacity: 0.25;
|
||||
}
|
||||
|
||||
.section-heading:not(:first-of-type) {
|
||||
padding-top: 12dp;
|
||||
}
|
||||
|
||||
button {
|
||||
text-align: center;
|
||||
background-color: rgba(17, 16, 10, 20%);
|
||||
opacity: 0.9;
|
||||
padding: 8dp 16dp;
|
||||
border-radius: 14dp;
|
||||
box-shadow: rgba(146, 135, 91, 25%) 0 0 0 1dp;
|
||||
font-size: 20dp;
|
||||
transition: background-color 0.1s linear-in-out, opacity 0.1s linear-in-out;
|
||||
cursor: pointer;
|
||||
focus: auto;
|
||||
}
|
||||
|
||||
button:not(:disabled):hover,
|
||||
button:not(:disabled):focus-visible {
|
||||
background-color: rgba(204, 184, 119, 20%);
|
||||
box-shadow: #C2A42D 0 0 0 2dp;
|
||||
}
|
||||
|
||||
button:not(:disabled):selected {
|
||||
opacity: 1;
|
||||
background-color: rgba(204, 184, 119, 40%);
|
||||
}
|
||||
|
||||
button:not(:disabled):active {
|
||||
opacity: 1;
|
||||
background-color: rgba(204, 184, 119, 40%);
|
||||
box-shadow: #C2A42D 0 0 0 2dp;
|
||||
}
|
||||
|
||||
button.modal-btn {
|
||||
flex: 1 1 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
select-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8dp;
|
||||
background-color: rgba(17, 16, 10, 20%);
|
||||
opacity: 0.9;
|
||||
padding: 8dp 16dp;
|
||||
border-radius: 14dp;
|
||||
box-shadow: rgba(146, 135, 91, 25%) 0 0 0 1dp;
|
||||
transition: background-color 0.1s linear-in-out, opacity 0.1s linear-in-out;
|
||||
cursor: pointer;
|
||||
focus: auto;
|
||||
}
|
||||
|
||||
select-button:not(:disabled):hover,
|
||||
select-button:not(:disabled):focus-visible {
|
||||
background-color: rgba(204, 184, 119, 20%);
|
||||
box-shadow: #C2A42D 0 0 0 2dp;
|
||||
}
|
||||
|
||||
select-button:not(:disabled):selected {
|
||||
opacity: 1;
|
||||
background-color: rgba(204, 184, 119, 40%);
|
||||
}
|
||||
|
||||
select-button:not(:disabled):active {
|
||||
opacity: 1;
|
||||
background-color: rgba(204, 184, 119, 40%);
|
||||
box-shadow: #C2A42D 0 0 0 2dp;
|
||||
}
|
||||
|
||||
select-button:disabled {
|
||||
opacity: 0.35;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
select-button key {
|
||||
font-family: "Fira Sans Condensed";
|
||||
font-weight: bold;
|
||||
font-size: 18dp;
|
||||
text-transform: uppercase;
|
||||
flex: 0 1 auto;
|
||||
}
|
||||
|
||||
select-button value {
|
||||
flex: 1 1 auto;
|
||||
text-align: right;
|
||||
font-size: 20dp;
|
||||
}
|
||||
|
||||
select-button value.modified {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
select-button input {
|
||||
text-align: right;
|
||||
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("" center center);
|
||||
}
|
||||
|
||||
icon.error {
|
||||
decorator: text("" center center);
|
||||
}
|
||||
|
||||
icon.verifying {
|
||||
decorator: text("" center center);
|
||||
}
|
||||
|
||||
icon.celebration {
|
||||
decorator: text("" center center);
|
||||
}
|
||||
|
||||
icon.question-mark {
|
||||
decorator: text("" center center);
|
||||
}
|
||||
|
||||
.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;
|
||||
justify-content: stretch;
|
||||
align-items: stretch;
|
||||
gap: 12dp;
|
||||
width: 100%;
|
||||
flex: 0 0 auto;
|
||||
padding-top: 4dp;
|
||||
}
|
||||
@@ -1,5 +1,10 @@
|
||||
#include "Z2AudioLib/Z2Audience.h"
|
||||
#include "Z2AudioLib/Z2SoundInfo.h"
|
||||
#if TARGET_PC
|
||||
#include "dusk/audio/DuskDsp.hpp"
|
||||
#include "dusk/settings.h"
|
||||
#include <cmath>
|
||||
#endif
|
||||
#include "Z2AudioLib/Z2Calc.h"
|
||||
#include "Z2AudioLib/Z2Param.h"
|
||||
#include "JSystem/JAudio2/JAISound.h"
|
||||
@@ -701,6 +706,11 @@ f32 Z2Audience::calcRelPosVolume(const Vec& param_0, f32 param_1, int camID) {
|
||||
f32 Z2Audience::calcRelPosPan(const Vec& param_0, int camID) {
|
||||
Vec local_54 = param_0;
|
||||
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);
|
||||
if (dVar6 < 0.1f) {
|
||||
@@ -734,9 +744,22 @@ f32 Z2Audience::calcRelPosPan(const Vec& param_0, int camID) {
|
||||
|
||||
f32 Z2Audience::calcRelPosDolby(const Vec& param_0, int camID) {
|
||||
f32 fVar1 = param_0.z + mAudioCamera[camID].getDolbyCenterZ();
|
||||
#if TARGET_PC
|
||||
if (dusk::audio::EnableHrtf) {
|
||||
// Normalize the direction so result is purely front/back orientation,
|
||||
// independent of how far away the sound is
|
||||
f32 lenSq = param_0.x * param_0.x + param_0.y * param_0.y + param_0.z * param_0.z;
|
||||
if (lenSq < 0.0001f) {
|
||||
return 0.5f;
|
||||
}
|
||||
f32 zNorm = param_0.z / sqrtf(lenSq);
|
||||
f32 t = (zNorm + 1.0f) * 0.5f;
|
||||
return 0.5f - 0.5f * cosf(t * static_cast<f32>(M_PI));
|
||||
}
|
||||
#endif
|
||||
if (fVar1 > mSetting.field_0x48) {
|
||||
return 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
if (fVar1 < mSetting.field_0x44) {
|
||||
return 0.0f;
|
||||
|
||||
@@ -4962,13 +4962,16 @@ int daAlink_c::create() {
|
||||
|
||||
setArcName(checkWolf());
|
||||
setOriginalHeap(&mpArcHeap, 0xA2800);
|
||||
JKRHEAP_NAME(mpArcHeap, "Alink ArcHeap");
|
||||
if (dComIfG_resLoad(&mPhaseReq, mArcName, mpArcHeap) != cPhs_COMPLEATE_e) {
|
||||
return cPhs_INIT_e;
|
||||
}
|
||||
|
||||
setShieldArcName();
|
||||
setOriginalHeap(&mpShieldArcHeap, 0x7000);
|
||||
if (dComIfG_resLoad(&mShieldPhaseReq, mShieldArcName, mpShieldArcHeap) != cPhs_COMPLEATE_e) {
|
||||
JKRHEAP_NAME(mpShieldArcHeap, "Alink ShieldArcHeap");
|
||||
if (dComIfG_resLoad(&mShieldPhaseReq, mShieldArcName, mpShieldArcHeap) != cPhs_COMPLEATE_e)
|
||||
{
|
||||
return cPhs_INIT_e;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
#include "d/actor/d_a_horse.h"
|
||||
#include "d/actor/d_a_crod.h"
|
||||
#include "d/d_msg_object.h"
|
||||
#ifdef TARGET_PC
|
||||
#include "d/actor/d_a_obj_carry.h"
|
||||
#include "dusk/achievements.h"
|
||||
#endif
|
||||
|
||||
#if DEBUG
|
||||
#include "d/d_s_menu.h"
|
||||
@@ -677,6 +681,15 @@ BOOL daAlink_c::checkDamageAction() {
|
||||
}
|
||||
|
||||
setDamagePoint(dmg, at_mtrl == dCcD_MTRL_FIRE || at_mtrl == dCcD_MTRL_ICE, TRUE, 0);
|
||||
|
||||
#ifdef TARGET_PC
|
||||
if (tghit_ac_name == fpcNm_Obj_Carry_e) {
|
||||
auto* carry = static_cast<daObjCarry_c*>(tghit_ac);
|
||||
if (carry->prm_chk_type_ironball() && carry->checkCannon()) {
|
||||
dusk::AchievementSystem::get().signal("iron_ball_hit_player");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (armor_no_dmg && at_mtrl != dCcD_MTRL_ELECTRIC && at_mtrl != dCcD_MTRL_ICE) {
|
||||
setGuardSe(var_r29);
|
||||
|
||||
@@ -44,16 +44,14 @@ void daAlink_c::handleWolfHowl() {
|
||||
bool canHowl = false;
|
||||
|
||||
if (mLinkAcch.ChkGroundHit() && !checkModeFlg(MODE_PLAYER_FLY) && !checkMagneBootsOn()) {
|
||||
if (!checkForestOldCentury()) {
|
||||
if (checkMidnaRide()) {
|
||||
if ((checkWolf() &&
|
||||
(checkModeFlg(MODE_UNK_1000) || dComIfGp_checkPlayerStatus0(0, 0x10))) ||
|
||||
(!checkWolf() &&
|
||||
(checkEventRun() || getMidnaActor()->checkMetamorphoseEnable()) &&
|
||||
(checkModeFlg(4) || dComIfGp_checkPlayerStatus0(0, 0x10))))
|
||||
{
|
||||
canHowl = true;
|
||||
}
|
||||
if (checkMidnaRide()) {
|
||||
if ((checkWolf() &&
|
||||
(checkModeFlg(MODE_UNK_1000) || dComIfGp_checkPlayerStatus0(0, 0x10))) ||
|
||||
(!checkWolf() &&
|
||||
(checkEventRun() || getMidnaActor()->checkMetamorphoseEnable()) &&
|
||||
(checkModeFlg(4) || dComIfGp_checkPlayerStatus0(0, 0x10))))
|
||||
{
|
||||
canHowl = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -124,16 +122,14 @@ void daAlink_c::handleQuickTransform() {
|
||||
bool canTransform = false;
|
||||
|
||||
if (mLinkAcch.ChkGroundHit() && !checkModeFlg(MODE_PLAYER_FLY) && !checkMagneBootsOn()) {
|
||||
if (!checkForestOldCentury()) {
|
||||
if (checkMidnaRide()) {
|
||||
if ((checkWolf() &&
|
||||
(checkModeFlg(MODE_UNK_1000) || dComIfGp_checkPlayerStatus0(0, 0x10))) ||
|
||||
(!checkWolf() &&
|
||||
(checkEventRun() || getMidnaActor()->checkMetamorphoseEnable()) &&
|
||||
(checkModeFlg(4) || dComIfGp_checkPlayerStatus0(0, 0x10))))
|
||||
{
|
||||
canTransform = true;
|
||||
}
|
||||
if (checkMidnaRide()) {
|
||||
if ((checkWolf() &&
|
||||
(checkModeFlg(MODE_UNK_1000) || dComIfGp_checkPlayerStatus0(0, 0x10))) ||
|
||||
(!checkWolf() &&
|
||||
(checkEventRun() || getMidnaActor()->checkMetamorphoseEnable()) &&
|
||||
(checkModeFlg(4) || dComIfGp_checkPlayerStatus0(0, 0x10))))
|
||||
{
|
||||
canTransform = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,10 @@ enum {
|
||||
};
|
||||
|
||||
void daAlink_c::hsChainShape_c::draw() {
|
||||
if (dusk::getSettings().game.superClawshot) {
|
||||
return;
|
||||
}
|
||||
|
||||
static const int dummy = 0;
|
||||
|
||||
daAlink_c* alink = (daAlink_c*)getUserArea();
|
||||
|
||||
@@ -2721,7 +2721,7 @@ int daAlink_c::procHorseRun() {
|
||||
}
|
||||
|
||||
if (mProcVar2.field_0x300c == 0) {
|
||||
set3DStatus(BUTTON_STATUS_HOLD_ON, 4);
|
||||
set3DStatus(BUTTON_STATUS_HOLD_ON, IF_DUSK(dusk::getSettings().game.enableMirrorMode ? 1 :) 4);
|
||||
}
|
||||
} else {
|
||||
if (mProcVar3.field_0x300e != 0) {
|
||||
@@ -2731,7 +2731,7 @@ int daAlink_c::procHorseRun() {
|
||||
}
|
||||
|
||||
if (mProcVar2.field_0x300c == 0) {
|
||||
set3DStatus(BUTTON_STATUS_HOLD_ON, 1);
|
||||
set3DStatus(BUTTON_STATUS_HOLD_ON, IF_DUSK(dusk::getSettings().game.enableMirrorMode ? 4 :) 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,12 +41,11 @@ void daAlink_c::setOriginalHeap(JKRExpHeap** i_ppheap, u32 i_size) {
|
||||
u32 var_r28 = 0x10;
|
||||
u32 size = ROUND(i_size, 16);
|
||||
#if TARGET_PC
|
||||
size *= 2;
|
||||
size *= 20; // Increase Link's heap size to prevent mods from crashing with higher-quality models.
|
||||
#endif
|
||||
JKRHeap* parent = mDoExt_getGameHeap();
|
||||
|
||||
JKRExpHeap* heap = JKRExpHeap::create(size + (var_r29 + var_r28), parent, true);
|
||||
JKRHEAP_NAME(heap, "Alink original");
|
||||
*i_ppheap = heap;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,7 +254,11 @@ BOOL daBdoor_c::checkArea() {
|
||||
if (fabsf(vec.z) > 100.0f) {
|
||||
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;
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOL daBdoor_c::checkFront() {
|
||||
|
||||
@@ -825,7 +825,11 @@ int daBdoorL1_c::checkArea() {
|
||||
if (fabsf(local_48.z) > 100.0f) {
|
||||
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) {
|
||||
#endif
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
|
||||
@@ -348,7 +348,11 @@ int daBdoorL5_c::checkArea() {
|
||||
if (fabsf(local_48.z) > 100.0f) {
|
||||
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) {
|
||||
#endif
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
|
||||
@@ -1317,8 +1317,12 @@ int daMBdoorL1_c::checkArea() {
|
||||
if (fabsf(local_48.z) > 110.0f) {
|
||||
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) {
|
||||
#endif
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
#if TARGET_PC
|
||||
#include <f_ap/f_ap_game.h>
|
||||
#include <dusk/autosave.h>
|
||||
#endif
|
||||
|
||||
char* daDoor20_c::getStopBmdName() {
|
||||
switch (door_param2_c::getKind(this)) {
|
||||
case 3:
|
||||
@@ -196,6 +201,7 @@ void daDoor20_c::setEventPrm() {
|
||||
} else {
|
||||
roomNo = FRoomNo;
|
||||
}
|
||||
|
||||
if (dComIfGp_roomControl_checkStatusFlag(roomNo, 1)) {
|
||||
if (door_param2_c::getKind(this) == 9) {
|
||||
if (daPy_py_c::checkNowWolf()) {
|
||||
@@ -564,6 +570,11 @@ int daDoor20_c::openEnd(int param_1) {
|
||||
openEnd_1();
|
||||
break;
|
||||
}
|
||||
|
||||
#if TARGET_PC
|
||||
triggerAutoSave();
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -517,6 +517,12 @@ void daE_OctBg_c::core_fish_attack() {
|
||||
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) {
|
||||
in_f31 = cM_rndF(50.0f) + 20.0f;
|
||||
field_0xbaf = cM_rndFX(20.0f) + 40.0f;
|
||||
|
||||
@@ -282,6 +282,11 @@ static void e_th_spin_B(e_th_class* i_this) {
|
||||
i_this->current.pos += spC;
|
||||
|
||||
f32 speed_target;
|
||||
|
||||
#if AVOID_UB
|
||||
speed_target = 0;
|
||||
#endif
|
||||
|
||||
f32 anm_frame = i_this->mpModelMorf->getFrame();
|
||||
|
||||
switch (i_this->mMode) {
|
||||
|
||||
@@ -3519,7 +3519,15 @@ void daKago_c::action() {
|
||||
checkSizeBg();
|
||||
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);
|
||||
#endif
|
||||
mStickY = mDoCPd_c::getStickY(PAD_1);
|
||||
|
||||
u8 prevIsWaterfall = mIsWaterfall;
|
||||
|
||||
@@ -463,6 +463,23 @@ int daMidna_c::createHeap() {
|
||||
JKRReadIdxResource(mBckHeap[0].getBuffer(), mBckHeap[0].getBufferSize(), 0x1DC, dComIfGp_getAnmArchive());
|
||||
J3DAnmTransform* md_anm = (J3DAnmTransform*)J3DAnmLoaderDataBase::load(mBckHeap[0].getBuffer());
|
||||
modelData = (J3DModelData*)dComIfG_getObjectRes(l_arcName, 14);
|
||||
|
||||
#if TARGET_PC
|
||||
J3DTexture* tex = modelData->getTexture();
|
||||
JUTNameTab* nametable = modelData->getTextureName();
|
||||
if (tex != NULL && nametable != NULL) {
|
||||
for (u16 i = 0; i < tex->getNum(); i++) {
|
||||
const char* name = nametable->getName(i);
|
||||
if (name != NULL && strcmp(name, "midona_eye") == 0) {
|
||||
ResTIMG* timg = tex->getResTIMG(i);
|
||||
timg->mipmapEnabled = false;
|
||||
tex->loadGXTexObj(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
JUT_ASSERT(852, modelData != NULL);
|
||||
mpMorf = JKR_NEW mDoExt_McaMorfSO(modelData, &mMorfCB, NULL, md_anm, J3DFrameCtrl::EMode_LOOP, 1.0f, 0, -1, NULL, 0, 0x11000284);
|
||||
if (mpMorf == NULL || mpMorf->getModel() == NULL) {
|
||||
|
||||
@@ -40,6 +40,7 @@ dMirror_packet_c::dMirror_packet_c() {
|
||||
void dMirror_packet_c::reset() {
|
||||
#if TARGET_PC
|
||||
mbReset = true;
|
||||
mbHadEntry = false;
|
||||
#else
|
||||
mModelCount = 0;
|
||||
#endif
|
||||
@@ -84,11 +85,21 @@ void dMirror_packet_c::calcMinMax() {
|
||||
}
|
||||
|
||||
int dMirror_packet_c::entryModel(J3DModel* i_model) {
|
||||
#if TARGET_PC
|
||||
if (mbReset) {
|
||||
mModelCount = 0;
|
||||
mbReset = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mModelCount >= 0x40) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
mModels[mModelCount++] = i_model;
|
||||
#if TARGET_PC
|
||||
mbHadEntry = true;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -592,13 +603,6 @@ int daMirror_c::execute() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if TARGET_PC
|
||||
if (mPacket.mbReset) {
|
||||
mPacket.mModelCount = 0;
|
||||
mPacket.mbReset = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
daPy_py_c* player = daPy_getLinkPlayerActorClass();
|
||||
JUT_ASSERT(0, player != NULL);
|
||||
|
||||
@@ -624,6 +628,12 @@ int daMirror_c::draw() {
|
||||
mDoExt_modelUpdateDL(mpModel);
|
||||
}
|
||||
|
||||
#if TARGET_PC
|
||||
if (mPacket.mbReset && !mPacket.mbHadEntry) {
|
||||
mPacket.mModelCount = 0;
|
||||
}
|
||||
mPacket.mbHadEntry = true;
|
||||
#endif
|
||||
dComIfGd_getOpaListBG()->entryImm(&mPacket, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -956,7 +956,7 @@ static void npc_ne_tame(npc_ne_class* i_this) {
|
||||
i_this->mpMorf->setPlaySpeed(i_this->mAnmSpeed);
|
||||
|
||||
/* dSv_event_flag_c::F_0470 - Fishing Pond - Reserved for fishing */
|
||||
if (dComIfGs_isEventBit(dSv_event_flag_c::saveBitLabels[470])) {
|
||||
if (IF_DUSK(dusk::getSettings().game.no2ndFishForCat) || dComIfGs_isEventBit(dSv_event_flag_c::saveBitLabels[470])) {
|
||||
if (fpcEx_Search(s_fish_sub, _this) != NULL) {
|
||||
i_this->mAction = npc_ne_class::ACT_HOME;
|
||||
i_this->mMode = 10;
|
||||
@@ -2948,8 +2948,7 @@ static int daNpc_Ne_Execute(npc_ne_class* i_this) {
|
||||
|
||||
if (i_this->mWantsFish && (i_this->mCounter & 0xf) == 0) {
|
||||
/* dSv_event_flag_c::F_0470 - Fishing Pond - Reserved for fishing */
|
||||
if (dComIfGs_isEventBit(dSv_event_flag_c::saveBitLabels[470])
|
||||
&& i_this->mDistToTarget < 1500.0f) {
|
||||
if ((IF_DUSK(dusk::getSettings().game.no2ndFishForCat) || dComIfGs_isEventBit(dSv_event_flag_c::saveBitLabels[470])) && i_this->mDistToTarget < 1500.0f) {
|
||||
if (fopAcM_SearchByName(fpcNm_MG_ROD_e) != NULL) {
|
||||
i_this->mNoFollow = false;
|
||||
} else {
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "d/actor/d_a_obj_automata.h"
|
||||
#include "d/d_msg_object.h"
|
||||
#include "d/actor/d_a_obj_scannon.h"
|
||||
#include "dusk/frame_interpolation.h"
|
||||
#include <cstring>
|
||||
|
||||
const daNpc_Toby_HIOParam daNpc_Toby_Param_c::m = {
|
||||
@@ -1398,6 +1399,7 @@ int daNpc_Toby_c::cutRepairSCannon(int arg0) {
|
||||
old.pos = current.pos;
|
||||
setAngle(cM_deg2s(5.0f * f32(mPath.getArg0())));
|
||||
mEventTimer = mPath.getArg2();
|
||||
dusk::frame_interp::request_presentation_sync();
|
||||
}
|
||||
} else if (!mHide) {
|
||||
mHide = 1;
|
||||
|
||||
@@ -62,6 +62,16 @@ void daObj_Balloon_c::saveBestScore() {
|
||||
dComIfGp_setMessageCountNumber(m_balloon_score);
|
||||
}
|
||||
|
||||
#if TARGET_PC
|
||||
static void minigameReset() {
|
||||
// !@bug d_a_obj_balloon.rel unload used to zero these file-statics; with static linking they dangle across scenes.
|
||||
m_combo_type = 0xFFFFFFFF;
|
||||
m_combo_count = 0;
|
||||
m_combo_next_score = 0;
|
||||
m_balloon_score = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static u8 hio_set;
|
||||
|
||||
static daObj_Balloon_HIO_c l_HIO;
|
||||
@@ -205,13 +215,6 @@ int daObj_Balloon_c::_delete() {
|
||||
Z2GetAudioMgr()->seStop(Z2SE_OBJ_WATERMILL_ROUND, 0);
|
||||
if (mHIOInit) {
|
||||
hio_set = false;
|
||||
#ifdef TARGET_PC
|
||||
// !@bug d_a_obj_balloon.rel unload used to zero these file-statics; with static linking they dangle across scenes.
|
||||
m_combo_type = 0xFFFFFFFF;
|
||||
m_combo_count = 0;
|
||||
m_combo_next_score = 0;
|
||||
m_balloon_score = 0;
|
||||
#endif
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -253,6 +256,7 @@ int daObj_Balloon_c::create() {
|
||||
}
|
||||
|
||||
if (!hio_set) {
|
||||
IF_DUSK(minigameReset());
|
||||
mHIOInit = true;
|
||||
hio_set = true;
|
||||
l_HIO.field_0x04 = -1;
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include "d/d_bg_w.h"
|
||||
#include "d/d_cc_uty.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 {
|
||||
daObjKLift00_HIO_c();
|
||||
@@ -295,6 +297,11 @@ int daObjKLift00_c::Create() {
|
||||
if(getLock())
|
||||
mStopSwingingFrames = 5;
|
||||
|
||||
#if TARGET_PC
|
||||
mChainInterpPrevValid = false;
|
||||
mChainInterpCurrValid = false;
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -436,6 +443,34 @@ int daObjKLift00_c::Execute(Mtx** i_mtx) {
|
||||
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() {
|
||||
g_env_light.settingTevStruct(16, ¤t.pos, &tevStr);
|
||||
g_env_light.setLightTevColorType_MAJI(mpLiftPlatform, &tevStr);
|
||||
@@ -457,6 +492,22 @@ int daObjKLift00_c::Draw() {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
#include "SSystem/SComponent/c_counter.h"
|
||||
#include <cstring>
|
||||
|
||||
#if TARGET_PC
|
||||
#include "dusk/settings.h"
|
||||
#endif
|
||||
|
||||
#define DRAW_TYPE_YELLOW 0
|
||||
#define DRAW_TYPE_RED 1
|
||||
|
||||
@@ -1422,6 +1426,11 @@ int dAttention_c::Run() {
|
||||
}
|
||||
|
||||
void dAttention_c::Draw() {
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.recordingMode) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (mAttParam.CheckFlag(dAttParam_c::EFlag_ARROW_OFF)) {
|
||||
draw[0].field_0x173 = 3;
|
||||
draw[1].field_0x173 = 3;
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#if TARGET_PC
|
||||
#include "dusk/frame_interpolation.h"
|
||||
#include "dusk/logging.h"
|
||||
#include "imgui.h"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
@@ -794,16 +795,15 @@ void dCamera_c::updatePad() {
|
||||
|
||||
if (mTriggerLeftLast > mCamSetup.ManualEndVal()) {
|
||||
if (mLockLActive == 0) {
|
||||
#if TARGET_PC
|
||||
mCamParam.mManualMode = 0;
|
||||
#endif
|
||||
mLockLJustActivated = 1;
|
||||
} else {
|
||||
mLockLJustActivated = 0;
|
||||
}
|
||||
|
||||
mLockLActive = 1;
|
||||
|
||||
#if TARGET_PC
|
||||
mCamParam.mManualMode = 0;
|
||||
#endif
|
||||
} else {
|
||||
mLockLJustActivated = 0;
|
||||
mLockLActive = 0;
|
||||
@@ -1041,6 +1041,11 @@ void dCamera_c::debugDrawInit() {
|
||||
bool dCamera_c::Run() {
|
||||
#if TARGET_PC
|
||||
ResetView();
|
||||
if (executeDebugFlyCam()) {
|
||||
mFrameCounter++;
|
||||
mTicks++;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
daAlink_c* link = daAlink_getAlinkActorClass();
|
||||
@@ -1176,14 +1181,14 @@ bool dCamera_c::Run() {
|
||||
clrFlag(0x200000);
|
||||
}
|
||||
} else {
|
||||
sp0F = (this->*engine_tbl[mCamParam.Algorythmn(mCamStyle)])(mCamStyle);
|
||||
|
||||
#if TARGET_PC
|
||||
if (mCamParam.Algorythmn(mCamStyle) != 1) {
|
||||
mCamParam.mManualMode = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
sp0F = (this->*engine_tbl[mCamParam.Algorythmn(mCamStyle)])(mCamStyle);
|
||||
|
||||
field_0x170++;
|
||||
field_0x160++;
|
||||
mCurCamStyleTimer++;
|
||||
@@ -1488,7 +1493,7 @@ void dCamera_c::CalcTrimSize() {
|
||||
mTrimHeight += -mTrimHeight * 0.25f;
|
||||
break;
|
||||
case 2:
|
||||
#if WIDESCREEN_SUPPORT
|
||||
#if !TARGET_PC && WIDESCREEN_SUPPORT
|
||||
if (mDoGph_gInf_c::isWide() && mDoGph_gInf_c::isWideZoom()) {
|
||||
mTrimHeight += (16.0f - mTrimHeight) * 0.25f;
|
||||
break;
|
||||
@@ -3096,10 +3101,6 @@ bool dCamera_c::bumpCheck(u32 i_flags) {
|
||||
field_0x968 *= mMonitor.field_0xc / 5.0f;
|
||||
}
|
||||
|
||||
#if TARGET_PC
|
||||
if (!dusk::getSettings().game.freeCamera || !mCamParam.mManualMode) {
|
||||
#endif
|
||||
|
||||
f32 tmp = field_0x96c * (mIsWolf == 1 ? 30.0f : 30.0f);
|
||||
center += vec3.norm() * (tmp * globe.V().Sin());
|
||||
cSGlobe globe2(vec2 - center);
|
||||
@@ -3113,10 +3114,6 @@ bool dCamera_c::bumpCheck(u32 i_flags) {
|
||||
vec = lin_chk1.GetCross();
|
||||
}
|
||||
|
||||
#if TARGET_PC
|
||||
}
|
||||
#endif
|
||||
|
||||
#if DEBUG
|
||||
if (mCamSetup.CheckFlag(0x8000)) {
|
||||
dDbVw_Report(20, 235, " U");
|
||||
@@ -4208,6 +4205,11 @@ bool dCamera_c::chaseCamera(s32 param_0) {
|
||||
chase->field_0x8 -= chase->field_0xc;
|
||||
chase->field_0x8c = 0;
|
||||
chase->field_0x90 = false;
|
||||
|
||||
#if TARGET_PC
|
||||
freeCamera();
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -4631,10 +4633,6 @@ bool dCamera_c::chaseCamera(s32 param_0) {
|
||||
sp110 = mViewCache.mDirection.R();
|
||||
mViewCache.mDirection.R(mViewCache.mDirection.R() + (fVar55 - mViewCache.mDirection.R()) * chase->field_0x74);
|
||||
|
||||
#if TARGET_PC
|
||||
freeCamera();
|
||||
#endif
|
||||
|
||||
chase->field_0x64 = mViewCache.mCenter + mViewCache.mDirection.Xyz();
|
||||
mViewCache.mEye = chase->field_0x64;
|
||||
|
||||
@@ -4649,6 +4647,11 @@ bool dCamera_c::chaseCamera(s32 param_0) {
|
||||
if (chase->field_0x1c != 0) {
|
||||
chase->field_0x1c--;
|
||||
}
|
||||
|
||||
#if TARGET_PC
|
||||
freeCamera();
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -7096,10 +7099,12 @@ bool dCamera_c::subjectCamera(s32 param_0) {
|
||||
cXyz sp1E0(val0, val2, val1);
|
||||
|
||||
#if TARGET_PC
|
||||
f32 aspect = mDoGph_gInf_c::getAspect();
|
||||
f32 baseAspect = FB_WIDTH / FB_HEIGHT;
|
||||
if (aspect > baseAspect) {
|
||||
sp1E0.z += (aspect - baseAspect) * 4;
|
||||
if (sp13) {
|
||||
f32 aspect = mDoGph_gInf_c::getAspect();
|
||||
f32 baseAspect = FB_WIDTH / FB_HEIGHT;
|
||||
if (aspect > baseAspect) {
|
||||
sp1E0.z += (aspect - baseAspect) * 4;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -7475,37 +7480,198 @@ bool dCamera_c::test2Camera(s32 param_0) {
|
||||
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
|
||||
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() {
|
||||
if (!dusk::getSettings().game.freeCamera) {
|
||||
if (dusk::getSettings().game.freeCamera && mGear == 1) {
|
||||
mGear = 0;
|
||||
}
|
||||
|
||||
if (!dusk::getSettings().game.freeCamera || mCamStyle == 70)
|
||||
{
|
||||
mCamParam.mManualMode = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mCamParam.mManualMode) {
|
||||
mCamParam.freeXAngle = mViewCache.mDirection.mAzimuth.Degree();
|
||||
mCamParam.freeYAngle = mViewCache.mDirection.mInclination.Degree();
|
||||
}
|
||||
|
||||
cXyz camMovement = {mPadInfo.mCStick.mLastPosX, mPadInfo.mCStick.mLastPosY, 0.0f};
|
||||
f32 magnitude = sqrt(mPadInfo.mCStick.mLastPosX * mPadInfo.mCStick.mLastPosX + mPadInfo.mCStick.mLastPosY * mPadInfo.mCStick.mLastPosY);
|
||||
|
||||
if (mPadInfo.mCStick.mLastPosX != 0 || mPadInfo.mCStick.mLastPosY != 0) {
|
||||
if (!mCamParam.mManualMode) {
|
||||
mCamParam.mManualMode = 1;
|
||||
mCamParam.freeXAngle = mViewCache.mDirection.mAzimuth.Degree();
|
||||
mCamParam.freeYAngle = mViewCache.mDirection.mInclination.Degree();
|
||||
}
|
||||
|
||||
mCamParam.mManualMode = 1;
|
||||
camMovement = camMovement.normalize();
|
||||
camMovement.y *= dusk::getSettings().game.invertCameraYAxis ? 1.0f : -1.0f;
|
||||
mCamParam.freeXAngle += camMovement.x * magnitude * dusk::getSettings().game.freeCameraSensitivity * 4.0f;
|
||||
mCamParam.freeYAngle += camMovement.y * magnitude * dusk::getSettings().game.freeCameraSensitivity * 4.0f;
|
||||
mCamParam.freeXAngle += camMovement.x * magnitude * dusk::getSettings().game.freeCameraSensitivity * 5.0f;
|
||||
mCamParam.freeYAngle += camMovement.y * magnitude * dusk::getSettings().game.freeCameraSensitivity * 5.0f;
|
||||
}
|
||||
|
||||
if (mCamParam.mManualMode) {
|
||||
mCamParam.freeYAngle = std::clamp(mCamParam.freeYAngle, -35.0f, 60.0f);
|
||||
mViewCache.mDirection.mAzimuth = cSAngle(mCamParam.freeXAngle);
|
||||
mViewCache.mDirection.mInclination = cSAngle(mCamParam.freeYAngle);
|
||||
mViewCache.mDirection.mRadius = std::clamp((mCamParam.freeYAngle + 35.0f) * 10.0f, 300.0f, 10000.0f);
|
||||
fopAc_ac_c* player = dComIfGp_getPlayer(0);
|
||||
if (!mCamParam.mManualMode || player == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return mCamParam.mManualMode;
|
||||
f32 minYAngle = -30.0f;
|
||||
f32 maxAngle = 50.0f;
|
||||
|
||||
mCamParam.freeYAngle = std::clamp(mCamParam.freeYAngle, minYAngle, maxAngle);
|
||||
mViewCache.mDirection.mAzimuth = cSAngle(mCamParam.freeXAngle);
|
||||
mViewCache.mDirection.mInclination = cSAngle(mCamParam.freeYAngle);
|
||||
|
||||
cXyz finalEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
|
||||
mViewCache.mEye = finalEye;
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -11148,12 +11314,25 @@ static int camera_draw(camera_process_class* i_this) {
|
||||
}
|
||||
#endif
|
||||
|
||||
int trim_height = body->TrimHeight();
|
||||
|
||||
#if TARGET_PC
|
||||
auto trim_height = body->TrimHeight();
|
||||
|
||||
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);
|
||||
#else
|
||||
int trim_height = body->TrimHeight();
|
||||
|
||||
window->setScissor(0.0f, trim_height, FB_WIDTH, FB_HEIGHT - trim_height * 2.0f);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -11,6 +11,62 @@
|
||||
#include "JSystem/JGadget/define.h"
|
||||
#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;
|
||||
|
||||
namespace {
|
||||
@@ -1006,7 +1062,16 @@ int dDemo_c::start(u8 const* p_data, cXyz* p_translation, f32 rotationY) {
|
||||
m_control->setSuspend(0);
|
||||
}
|
||||
|
||||
#if TARGET_PC
|
||||
const int existing_streams = get_stream_count(get_stream_list());
|
||||
#endif
|
||||
|
||||
m_control->forward(0);
|
||||
|
||||
#if TARGET_PC
|
||||
pause_streams(existing_streams);
|
||||
#endif
|
||||
|
||||
m_translation = p_translation;
|
||||
|
||||
if (m_translation != NULL) {
|
||||
@@ -1034,6 +1099,10 @@ static void dummyString2() {
|
||||
void dDemo_c::end() {
|
||||
JUT_ASSERT(1956, m_system != NULL);
|
||||
|
||||
#if TARGET_PC
|
||||
unpause_streams(false);
|
||||
#endif
|
||||
|
||||
m_control->destroyObject_all();
|
||||
m_object->remove();
|
||||
m_data = NULL;
|
||||
@@ -1054,6 +1123,10 @@ void dDemo_c::branch() {
|
||||
int dDemo_c::update() {
|
||||
JUT_ASSERT(2064, m_system != NULL);
|
||||
|
||||
#if TARGET_PC
|
||||
unpause_streams(true);
|
||||
#endif
|
||||
|
||||
if (m_data == NULL) {
|
||||
if (m_branchData == NULL) {
|
||||
return 0;
|
||||
|
||||
@@ -22,6 +22,10 @@
|
||||
#include "dusk/frame_interpolation.h"
|
||||
#include "dusk/gx_helper.h"
|
||||
#include "dusk/logging.h"
|
||||
|
||||
static const void* getInterpKey(const void* base, int idx) {
|
||||
return reinterpret_cast<const void*>(reinterpret_cast<uintptr_t>(base) ^ idx);
|
||||
}
|
||||
#endif
|
||||
|
||||
class dDlst_2Dm_c {
|
||||
@@ -1062,7 +1066,15 @@ void dDlst_shadowReal_c::reset() {
|
||||
}
|
||||
|
||||
void dDlst_shadowReal_c::imageDraw(Mtx param_0) {
|
||||
GXSetProjection(mRenderProjMtx, GX_ORTHOGRAPHIC);
|
||||
#ifdef TARGET_PC
|
||||
Mtx render_proj_mtx;
|
||||
if (dusk::frame_interp::lookup_replacement(getInterpKey(mpModels[0], 2), render_proj_mtx)) {
|
||||
GXSetProjection(render_proj_mtx, GX_ORTHOGRAPHIC);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
GXSetProjection(mRenderProjMtx, GX_ORTHOGRAPHIC);
|
||||
}
|
||||
JUT_ASSERT(1916, mModelNum);
|
||||
J3DModelData* model_data;
|
||||
J3DModel** models = mpModels;
|
||||
@@ -1075,7 +1087,15 @@ void dDlst_shadowReal_c::imageDraw(Mtx param_0) {
|
||||
for (u16 j = 0; j < model_data->getShapeNum(); j++) {
|
||||
if (!model_data->getShapeNodePointer(j)->checkFlag(1)) {
|
||||
shape_pkt = (*models)->getShapePacket(j);
|
||||
shape_pkt->setBaseMtxPtr(&mViewMtx);
|
||||
#ifdef TARGET_PC
|
||||
Mtx view_mtx;
|
||||
if (dusk::frame_interp::lookup_replacement(getInterpKey(mpModels[0], 1), view_mtx)) {
|
||||
shape_pkt->setBaseMtxPtr(&view_mtx);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
shape_pkt->setBaseMtxPtr(&mViewMtx);
|
||||
}
|
||||
shape_pkt->drawFast();
|
||||
shape_pkt->setBaseMtxPtr((Mtx*)param_0);
|
||||
}
|
||||
@@ -1096,7 +1116,18 @@ void dDlst_shadowReal_c::draw() {
|
||||
GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
|
||||
GXSetCurrentMtx(GX_PNMTX0);
|
||||
GXLoadTexMtxImm(mReceiverProjMtx, GX_TEXMTX0, GX_MTX3x4);
|
||||
#ifdef TARGET_PC
|
||||
Mtx view_mtx, recv_proj_mtx;
|
||||
const auto have_view_mtx = dusk::frame_interp::lookup_replacement(getInterpKey(mpModels[0], 1), view_mtx);
|
||||
const auto have_recv_proj_mtx = dusk::frame_interp::lookup_replacement(getInterpKey(mpModels[0], 3), recv_proj_mtx);
|
||||
if (have_view_mtx && have_recv_proj_mtx) {
|
||||
cMtx_concat(recv_proj_mtx, view_mtx, recv_proj_mtx);
|
||||
GXLoadTexMtxImm(recv_proj_mtx, GX_TEXMTX0, GX_MTX3x4);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
GXLoadTexMtxImm(mReceiverProjMtx, GX_TEXMTX0, GX_MTX3x4);
|
||||
}
|
||||
mShadowRealPoly.draw();
|
||||
}
|
||||
|
||||
@@ -1253,6 +1284,13 @@ u8 dDlst_shadowReal_c::setShadowRealMtx(cXyz* param_0, cXyz* param_1, f32 param_
|
||||
cMtx_lookAt(mViewMtx, &local_64, param_1, 0);
|
||||
C_MTXOrtho(mRenderProjMtx, param_2, -param_2, -param_2, param_2, 1.0f, 10000.0f);
|
||||
C_MTXLightOrtho(mReceiverProjMtx, param_2, -param_2, -param_2, param_2, 0.5f, -0.5f, 0.5f, 0.5f);
|
||||
|
||||
#ifdef TARGET_PC
|
||||
const auto keybase = mpModels[0];
|
||||
dusk::frame_interp::record_final_mtx(mViewMtx, getInterpKey(keybase, 1));
|
||||
dusk::frame_interp::record_final_mtx(mRenderProjMtx, getInterpKey(keybase, 2));
|
||||
dusk::frame_interp::record_final_mtx(mReceiverProjMtx, getInterpKey(keybase, 3));
|
||||
#endif
|
||||
cMtx_concat(mReceiverProjMtx, mViewMtx, mReceiverProjMtx);
|
||||
return r29;
|
||||
}
|
||||
@@ -1277,6 +1315,10 @@ u32 dDlst_shadowReal_c::set(u32 i_key, J3DModel* i_model, cXyz* param_2, f32 par
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TARGET_PC
|
||||
// provide a stable key for interpolation
|
||||
mpModels[0] = i_model;
|
||||
#endif
|
||||
field_0x1 = setShadowRealMtx(&sp60, param_2, param_3, param_4, param_7, param_5);
|
||||
|
||||
if (!field_0x1) {
|
||||
@@ -1370,12 +1412,6 @@ void dDlst_shadowSimple_c::draw() {
|
||||
GXCallDisplayList(l_shadowVolumeDL, 0x40);
|
||||
}
|
||||
|
||||
#if TARGET_PC
|
||||
static const void* getInterpKey(const void* base, int idx) {
|
||||
return reinterpret_cast<const void*>(reinterpret_cast<uintptr_t>(base) ^ idx);
|
||||
}
|
||||
#endif
|
||||
|
||||
void dDlst_shadowSimple_c::set(cXyz* param_0, f32 param_1, f32 param_2, cXyz* param_3,
|
||||
s16 param_4, f32 param_5, TGXTexObj* param_6) {
|
||||
if (param_5 < 0.0f) {
|
||||
|
||||
@@ -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);
|
||||
getPack(field_0x80, &mPackX, &mPackZ);
|
||||
|
||||
mCenterX += mPackX;
|
||||
mCenterX += IF_DUSK(dusk::getSettings().game.enableMirrorMode ? -mPackX :) mPackX;
|
||||
mCenterZ -= mPackZ;
|
||||
mCenterX += field_0x64;
|
||||
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);
|
||||
getPack(field_0x80, &mPackX, &mPackZ);
|
||||
|
||||
mCenterX += mPackX;
|
||||
mCenterX += IF_DUSK(dusk::getSettings().game.enableMirrorMode ? -mPackX :) mPackX;
|
||||
mCenterZ -= mPackZ;
|
||||
}
|
||||
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);
|
||||
getPack(field_0x80, &mPackX, &mPackZ);
|
||||
|
||||
mCenterX += mPackX;
|
||||
mCenterX += IF_DUSK(dusk::getSettings().game.enableMirrorMode ? -mPackX :) mPackX;
|
||||
mCenterZ -= mPackZ;
|
||||
field_0x8f = 4;
|
||||
#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);
|
||||
sp10 += temp_f31_2 * (sp8 - sp10);
|
||||
mCenterX += sp14;
|
||||
mCenterX += IF_DUSK(dusk::getSettings().game.enableMirrorMode ? -sp14 :) sp14;
|
||||
mCenterZ -= sp10;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -15,12 +15,47 @@
|
||||
#include <cstring>
|
||||
|
||||
#ifdef TARGET_PC
|
||||
#include <span>
|
||||
#include <numbers>
|
||||
#include <array>
|
||||
|
||||
constexpr u16 kMapResolutionMultiplier = 4;
|
||||
constexpr u16 kMapImageSide = 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
|
||||
|
||||
void dMpath_n::dTexObjAggregate_c::create() {
|
||||
static int const data[7] = {
|
||||
79, 80, 77, 78, 76, 81, 82,
|
||||
79, // 0: im_map_icon_square_4i.bti
|
||||
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++) {
|
||||
@@ -32,6 +67,104 @@ void dMpath_n::dTexObjAggregate_c::create() {
|
||||
JUT_ASSERT(74, image->magFilter == GX_NEAR);
|
||||
mDoLib_setResTimgObj(image, mp_texObj[lp1], 0, NULL);
|
||||
}
|
||||
|
||||
#if TARGET_PC
|
||||
static bool hqTexsDrawn = false;
|
||||
|
||||
static u8 hqCircleData[kMapImageTotalPixels];
|
||||
static u8 hqCircleAltData[kMapImageTotalPixels];
|
||||
static u8 hqNijumaruData[kMapImageTotalPixels];
|
||||
static u8 hqEnterData[kMapImageTotalPixels];
|
||||
static u8 hqTryForceData[kMapImageTotalPixels];
|
||||
|
||||
if (!hqTexsDrawn) {
|
||||
constexpr auto center = kMapImageSide / 2.0f;
|
||||
constexpr auto radiusSq = center * center;
|
||||
|
||||
// 6: map_icon_circle16x16_4i.bti - simple circle
|
||||
paint_i8(std::span{hqCircleData}, kMapImageSide, [=](auto x, auto y) {
|
||||
const auto dx = (x + 0.5f) - center;
|
||||
const auto dy = (y + 0.5f) - center;
|
||||
return (dx * dx + dy * dy < radiusSq) ? 0x11 : 0;
|
||||
});
|
||||
|
||||
// 4: im_map_icon_circle_4i.bti - outlined circle
|
||||
paint_i8(std::span{hqCircleAltData}, kMapImageSide, [=](auto x, auto y) {
|
||||
constexpr auto innerRadius = kMapImageSide * 3.0f / 8.0f;
|
||||
constexpr auto innerRadiusSq = innerRadius * innerRadius;
|
||||
|
||||
const auto dx = (x + 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;
|
||||
});
|
||||
|
||||
// 3: im_map_icon_nijumaru_4i.bti - concentric rings
|
||||
paint_i8(std::span{hqNijumaruData}, kMapImageSide, [=](auto x, auto y) {
|
||||
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*> >({
|
||||
{2, hqEnterData},
|
||||
{3, hqNijumaruData},
|
||||
{4, hqCircleAltData},
|
||||
{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
|
||||
}
|
||||
|
||||
void dMpath_n::dTexObjAggregate_c::remove() {
|
||||
|
||||
@@ -856,7 +856,46 @@ void dMenu_DmapBg_c::decGoldFrameAlphaRate() {
|
||||
setGoldFrameAlphaRate(rate);
|
||||
}
|
||||
|
||||
void dMenu_DmapBg_c::dMapBgWide() {
|
||||
// Scale Base HUD
|
||||
mBaseScreen->scale(mDoGph_gInf_c::hudAspectScaleUp, 1.0f);
|
||||
mBaseScreen->translate(mDoGph_gInf_c::getSafeMinXF(), 0.0f);
|
||||
|
||||
// Boss Key, Compass & Map icons
|
||||
mBaseScreen->search(MULTI_CHAR('key_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
|
||||
mBaseScreen->search(MULTI_CHAR('con_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
|
||||
mBaseScreen->search(MULTI_CHAR('map_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
|
||||
|
||||
// Text Header
|
||||
mBaseScreen->search(MULTI_CHAR('t_t00'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
|
||||
mBaseScreen->search(MULTI_CHAR('f_t_00'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
|
||||
|
||||
// C Button
|
||||
mBaseScreen->search(MULTI_CHAR('c_btn2'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
|
||||
|
||||
// Scale Buttons HUD
|
||||
mButtonScreen->scale(mDoGph_gInf_c::hudAspectScaleUp, 1.0f);
|
||||
mButtonScreen->translate(mDoGph_gInf_c::getSafeMinXF(), 0.0f);
|
||||
|
||||
// Buttons
|
||||
mButtonScreen->search(MULTI_CHAR('cont_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
|
||||
|
||||
// C Button
|
||||
mButtonScreen->search(MULTI_CHAR('c_btn'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
|
||||
mButtonScreen->search(MULTI_CHAR('c_text_s'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
|
||||
mButtonScreen->search(MULTI_CHAR('c_text'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
|
||||
mButtonScreen->search(MULTI_CHAR('f_text_s'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
|
||||
mButtonScreen->search(MULTI_CHAR('f_text'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
|
||||
|
||||
// Decorations
|
||||
mButtonScreen->search(MULTI_CHAR('kazari_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
|
||||
}
|
||||
|
||||
void dMenu_DmapBg_c::draw() {
|
||||
#if TARGET_PC
|
||||
dMapBgWide();
|
||||
#endif
|
||||
|
||||
u32 scissor_left;
|
||||
u32 scissor_top;
|
||||
u32 scissor_width;
|
||||
@@ -903,7 +942,10 @@ void dMenu_DmapBg_c::draw() {
|
||||
f32 local_28c = mpBackTexture->getBounds().i.x;
|
||||
mpBackTexture->setBlackWhite(color_black, color_white);
|
||||
mpBackTexture->draw(local_28c, field_0xd94 + mpBackTexture->getBounds().i.y, mpBackTexture->getWidth(),
|
||||
mpBackTexture->getHeight(), false, false, false);
|
||||
mpBackTexture->getHeight(),
|
||||
IF_DUSK(dusk::getSettings().game.enableMirrorMode ? true :) false,
|
||||
false,
|
||||
false);
|
||||
|
||||
grafContext->scissor(field_0xd94 + mDoGph_gInf_c::getMinXF(),
|
||||
scissor_top, mDoGph_gInf_c::getWidthF(),
|
||||
|
||||
@@ -368,7 +368,7 @@ void dMenu_StageMapCtrl_c::initGetTreasureList(u8 param_0, s8 param_1) {
|
||||
}
|
||||
|
||||
inline static s16 rightModeCnvRot(s16 param_0) {
|
||||
return param_0;
|
||||
return IF_DUSK(dusk::getSettings().game.enableMirrorMode ? -param_0 :) param_0;
|
||||
}
|
||||
|
||||
bool dMenu_StageMapCtrl_c::getTreasureList(f32* o_posX, f32* o_posY, s8* param_2, u8* o_swbit,
|
||||
@@ -405,7 +405,7 @@ bool dMenu_StageMapCtrl_c::getTreasureList(f32* o_posX, f32* o_posY, s8* param_2
|
||||
}
|
||||
|
||||
inline static f32 rightModeCnvPos(f32 param_0) {
|
||||
return param_0;
|
||||
return IF_DUSK(dusk::getSettings().game.enableMirrorMode ? -param_0 :) param_0;
|
||||
}
|
||||
|
||||
void dMenu_StageMapCtrl_c::cnvPosTo2Dpos(f32 param_0, f32 param_1, f32* param_2,
|
||||
|
||||
@@ -919,9 +919,20 @@ void dMenu_Fmap_c::region_map_proc() {
|
||||
}
|
||||
mpDraw2DBack->regionMapMove(mpStick);
|
||||
int stage_no, room_no;
|
||||
|
||||
#if TARGET_PC
|
||||
f32 arrow_pos_x = mpDraw2DBack->getArrowPos2DX();
|
||||
if (dusk::getSettings().game.enableMirrorMode) {
|
||||
arrow_pos_x = mpDraw2DBack->getMirrorPosX(arrow_pos_x, 0.0f);
|
||||
}
|
||||
|
||||
f32 pos_x = arrow_pos_x - mDoGph_gInf_c::getMinXF() - mDoGph_gInf_c::getWidthF() * 0.5f;
|
||||
#else
|
||||
f32 pos_x = mpDraw2DBack->getArrowPos2DX() - mDoGph_gInf_c::getMinXF()
|
||||
- mDoGph_gInf_c::getWidthF() * 0.5f;
|
||||
#endif
|
||||
f32 pos_y = mpDraw2DBack->getArrowPos2DY() - mDoGph_gInf_c::getHeightF() * 0.5f;
|
||||
|
||||
mpMenuFmapMap->getPointStagePathInnerNo(getNowFmapRegionData(), pos_x, pos_y,
|
||||
mStayStageNo, &stage_no, &room_no);
|
||||
if (mStageCursor != stage_no || mRoomCursor != room_no || mResetAreaName) {
|
||||
@@ -2464,6 +2475,13 @@ void dMenu_Fmap_c::portalWarpMapMove(STControl* i_stick) {
|
||||
f32 arrow_y = mpDraw2DBack->getArrowPos2DY();
|
||||
u8 uVar6 = 0xff;
|
||||
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.enableMirrorMode) {
|
||||
arrow_x = mpDraw2DBack->getMirrorPosX(arrow_x, 0.0f);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
for (int i = 0; i < portal_dat->mCount; i++) {
|
||||
if (portals[i].mRegionNo == mpDraw2DBack->getRegionCursor() + 1
|
||||
&& checkDrawPortalIcon(portals[i].mStageNo, portals[i].mSwitchNo))
|
||||
|
||||
@@ -20,6 +20,15 @@
|
||||
#include "dusk/frame_interpolation.h"
|
||||
#include <cstring>
|
||||
|
||||
#if TARGET_PC
|
||||
void dMenu_Fmap2DBack_c::fMapBackWide() {
|
||||
mpBaseScreen->scale(mDoGph_gInf_c::hudAspectScaleUp, 1.0f);
|
||||
mpBaseScreen->translate(mDoGph_gInf_c::getSafeMinXF(), 0.0f);
|
||||
mpBackScreen->scale(mDoGph_gInf_c::hudAspectScaleUp, 1.0f);
|
||||
mpBackScreen->translate(mDoGph_gInf_c::getSafeMinXF(), 0.0f);
|
||||
}
|
||||
#endif
|
||||
|
||||
dMenu_Fmap2DBack_c::dMenu_Fmap2DBack_c() {
|
||||
dMeter2Info_setMapDrugFlag(0);
|
||||
|
||||
@@ -267,6 +276,10 @@ dMenu_Fmap2DBack_c::~dMenu_Fmap2DBack_c() {
|
||||
}
|
||||
|
||||
void dMenu_Fmap2DBack_c::draw() {
|
||||
#if TARGET_PC
|
||||
fMapBackWide();
|
||||
#endif
|
||||
|
||||
calcBlink();
|
||||
|
||||
J2DGrafContext* grafPort = dComIfGp_getCurrentGrafPort();
|
||||
@@ -1030,6 +1043,12 @@ void dMenu_Fmap2DBack_c::allmap_move2(STControl* param_0) {
|
||||
calcAllMapPos2D((mArrowPos3DX + control_xpos) - mStageTransX,
|
||||
(mArrowPos3DZ + control_ypos) - mStageTransZ, &sp14, &sp10);
|
||||
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.enableMirrorMode) {
|
||||
sp14 = getMirrorPosX(sp14, 0.0f);
|
||||
}
|
||||
#endif
|
||||
|
||||
mSelectRegion = 0xff;
|
||||
for (int i = 7; i >= 0; i--) {
|
||||
int val = field_0x1230[i];
|
||||
@@ -1199,7 +1218,7 @@ f32 dMenu_Fmap2DBack_c::getMapScissorAreaSizeX() {
|
||||
}
|
||||
|
||||
f32 dMenu_Fmap2DBack_c::getMapScissorAreaSizeRealX() {
|
||||
#if PLATFORM_GCN && !TARGET_PC
|
||||
#if PLATFORM_GCN
|
||||
return getMapScissorAreaSizeX();
|
||||
#else
|
||||
return getMapScissorAreaSizeX() * mDoGph_gInf_c::getScale();
|
||||
@@ -1384,6 +1403,15 @@ void dMenu_Fmap2DBack_c::regionTextureDraw() {
|
||||
if (uVar10 != uVar9) {
|
||||
bool b = 0;
|
||||
f32 v = mTransX + (dVar14 + (mRegionMinMapX[uVar10] + field_0xf0c[uVar10]));
|
||||
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.enableMirrorMode) {
|
||||
b = true;
|
||||
v = getMirrorPosX(mTransX + (dVar14 + (mRegionMinMapX[uVar10] + field_0xf0c[uVar10])),
|
||||
mRegionMapSizeX[uVar10] * mZoom * 0.5f);
|
||||
}
|
||||
#endif
|
||||
|
||||
mpAreaTex[uVar10]->draw(
|
||||
v, mTransZ + (dVar13 + (mRegionMinMapY[uVar10] + field_0xf2c[uVar10])),
|
||||
mRegionMapSizeX[uVar10] * mZoom, mRegionMapSizeY[uVar10] * mZoom, b, false,
|
||||
@@ -1391,6 +1419,15 @@ void dMenu_Fmap2DBack_c::regionTextureDraw() {
|
||||
} else {
|
||||
bool b = 0;
|
||||
f32 v = mTransX + (dVar14 + (mRegionMinMapX[uVar9] + field_0xf0c[uVar9]));
|
||||
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.enableMirrorMode) {
|
||||
b = true;
|
||||
v = getMirrorPosX(mTransX + (dVar14 + (mRegionMinMapX[uVar9] + field_0xf0c[uVar9])),
|
||||
mRegionMapSizeX[uVar9] * mZoom * 0.5f);
|
||||
}
|
||||
#endif
|
||||
|
||||
mpAreaTex[uVar9]->draw(
|
||||
v, mTransZ + (dVar13 + (mRegionMinMapY[uVar9] + field_0xf2c[uVar9])),
|
||||
mRegionMapSizeX[uVar9] * mZoom, mRegionMapSizeY[uVar9] * mZoom, b, false,
|
||||
@@ -1407,6 +1444,11 @@ void dMenu_Fmap2DBack_c::stageTextureDraw() {
|
||||
mpSpotTexture->setAlpha(mAlphaRate * 255.0f * field_0xfa8 * mSpotTextureFadeAlpha);
|
||||
}
|
||||
|
||||
#if TARGET_PC
|
||||
JUTPalette* pPalette = mpSpotTexture->getTexture(0)->getPalette();
|
||||
pPalette->dataUploaded();
|
||||
#endif
|
||||
|
||||
mpSpotTexture->draw(mTransX + getMapScissorAreaLX(), mTransZ + getMapScissorAreaLY(),
|
||||
getMapScissorAreaSizeRealX(), getMapScissorAreaSizeRealY(), false, false,
|
||||
false);
|
||||
@@ -2179,6 +2221,17 @@ void dMenu_Fmap2DBack_c::setArrowPosAxis(f32 i_posX, f32 i_posZ) {
|
||||
control_ypos = 0.0f;
|
||||
}
|
||||
|
||||
#if TARGET_PC
|
||||
void dMenu_Fmap2DTop_c::fMapTopWide() {
|
||||
mpTitleScreen->search(MULTI_CHAR('spot0_n'))->scale(mDoGph_gInf_c::hudAspectScaleUp, 1.0f);
|
||||
mpTitleScreen->search(MULTI_CHAR('spot2_n'))->scale(mDoGph_gInf_c::hudAspectScaleUp, 1.0f);
|
||||
mpTitleScreen->search(MULTI_CHAR('name_n'))->translate(mDoGph_gInf_c::ScaleHUDXLeft(-243.0f), -169.0f);
|
||||
mpTitleScreen->search(MULTI_CHAR('sub_n_n'))->translate(mDoGph_gInf_c::ScaleHUDXLeft(-80.0f), -154.0f);
|
||||
mpTitleScreen->search(MULTI_CHAR('btn_i_n'))->translate(mDoGph_gInf_c::ScaleHUDXLeft(-241.0f), 177.0f);
|
||||
mpTitleScreen->search(MULTI_CHAR('cont_n'))->translate(mDoGph_gInf_c::ScaleHUDXRight(515.0f), 83.0f);
|
||||
}
|
||||
#endif
|
||||
|
||||
dMenu_Fmap2DTop_c::dMenu_Fmap2DTop_c(JKRExpHeap* i_heap, STControl* i_stick) {
|
||||
mpHeap = i_heap;
|
||||
mTransX = 0.0f;
|
||||
@@ -2572,6 +2625,10 @@ void dMenu_Fmap2DTop_c::setAllAlphaRate(f32 i_rate, bool i_init) {
|
||||
}
|
||||
|
||||
void dMenu_Fmap2DTop_c::draw() {
|
||||
#if TARGET_PC
|
||||
fMapTopWide();
|
||||
#endif
|
||||
|
||||
u32 scissor_left, scissor_top, scissor_width, scissor_height;
|
||||
J2DOrthoGraph* ctx = static_cast<J2DOrthoGraph*>(dComIfGp_getCurrentGrafPort());
|
||||
ctx->setup2D();
|
||||
|
||||
@@ -17,6 +17,10 @@
|
||||
#include "d/d_msg_scrn_arrow.h"
|
||||
#include "d/d_lib.h"
|
||||
|
||||
#ifdef TARGET_PC
|
||||
#include "dusk/achievements.h"
|
||||
#endif
|
||||
|
||||
#if VERSION == VERSION_GCN_JPN
|
||||
#define D_MENU_LETTER_LINE_MAX 9
|
||||
#else
|
||||
@@ -514,6 +518,10 @@ void dMenu_Letter_c::read_open_init() {
|
||||
setAButtonString(0);
|
||||
setBButtonString(0);
|
||||
mpBlackTex->setAlpha(0);
|
||||
|
||||
#ifdef TARGET_PC
|
||||
dusk::AchievementSystem::get().signal("open_letter");
|
||||
#endif
|
||||
}
|
||||
|
||||
void dMenu_Letter_c::read_open_move() {
|
||||
|
||||
@@ -343,6 +343,11 @@ void dMenuMapCommon_c::drawIcon(f32 i_posX, f32 i_posY, f32 param_3, f32 param_4
|
||||
}
|
||||
|
||||
f32 pos_x = icon_pos_x + i_posX;
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.enableMirrorMode) {
|
||||
pos_x = getMirrorCenterPosX(pos_x, 0.0f);
|
||||
}
|
||||
#endif
|
||||
mpDrawCursor->setPos(pos_x, icon_pos_y + i_posY);
|
||||
mpDrawCursor->setScale(mIconInfo[info_idx].scale * g_fmapHIO.mMapIconHIO.mPortalCursorScale);
|
||||
mpDrawCursor->draw();
|
||||
@@ -364,6 +369,12 @@ void dMenuMapCommon_c::drawIcon(f32 i_posX, f32 i_posY, f32 param_3, f32 param_4
|
||||
}
|
||||
|
||||
f32 pos_x = (icon_pos_x + i_posX);
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.enableMirrorMode) {
|
||||
pos_x = getMirrorCenterPosX(pos_x, 0.0f);
|
||||
}
|
||||
#endif
|
||||
|
||||
mpPortalIcon->setPos(pos_x, icon_pos_y + i_posY);
|
||||
mpPortalIcon->setScale(mIconInfo[info_idx].scale * g_fmapHIO.mMapIconHIO.mPortalIconScale);
|
||||
mpPortalIcon->draw();
|
||||
@@ -399,6 +410,12 @@ void dMenuMapCommon_c::drawIcon(f32 i_posX, f32 i_posY, f32 param_3, f32 param_4
|
||||
}
|
||||
|
||||
f32 pos_x = i_posX + (icon_pos_x - (icon_size_x / 2));
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.enableMirrorMode) {
|
||||
pos_x = getMirrorCenterPosX(i_posX + (icon_pos_x - (icon_size_x / 2)), icon_size_x / 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
mPictures[mIconInfo[info_idx].icon_no]->draw(pos_x, (i_posY + (icon_pos_y - icon_size_y / 2)),
|
||||
icon_size_x, icon_size_y, false, false, false);
|
||||
|
||||
|
||||
@@ -24,9 +24,10 @@
|
||||
#include "d/actor/d_a_horse.h"
|
||||
#include <cstring>
|
||||
|
||||
#if TARGET_PC
|
||||
#include "dusk/memory.h"
|
||||
|
||||
#include "dusk/memory.h"
|
||||
#include "dusk/settings.h"
|
||||
#endif
|
||||
|
||||
int dMeter2_c::_create() {
|
||||
stage_stag_info_class* stag_info = dComIfGp_getStageStagInfo();
|
||||
@@ -316,6 +317,14 @@ int dMeter2_c::_execute() {
|
||||
}
|
||||
|
||||
int dMeter2_c::_draw() {
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.recordingMode || dusk::getSettings().game.minimalHUD ||
|
||||
dusk::getSettings().game.debugFlyCam)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mpMap != NULL) {
|
||||
mpMap->_draw();
|
||||
}
|
||||
@@ -424,12 +433,6 @@ void dMeter2_c::setLifeZero() {
|
||||
void dMeter2_c::checkStatus() {
|
||||
mStatus = 0;
|
||||
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.disableMainHUD) {
|
||||
mStatus |= 0xF0000000;
|
||||
}
|
||||
#endif
|
||||
|
||||
field_0x12c = field_0x128;
|
||||
|
||||
field_0x128 = daPy_py_c::checkNowWolf();
|
||||
|
||||
@@ -2306,6 +2306,10 @@ void dMeter_drawHIO_c::updateOnWide() {
|
||||
// River Canoe Minigame
|
||||
g_drawHIO.mMiniGame.mCounterPosX[1] = mDoGph_gInf_c::ScaleHUDXRight(g_drawHIO.mMiniGame.mCounterPosX[1]);
|
||||
g_drawHIO.mMiniGame.mIconPosX[1] = mDoGph_gInf_c::ScaleHUDXRight(g_drawHIO.mMiniGame.mIconPosX[1]);
|
||||
|
||||
// Bulblin Count in Hidden Village
|
||||
g_drawHIO.mMiniGame.mCounterPosX[2] = mDoGph_gInf_c::ScaleHUDXRight(g_drawHIO.mMiniGame.mCounterPosX[2]);
|
||||
g_drawHIO.mMiniGame.mIconPosX[2] = mDoGph_gInf_c::ScaleHUDXRight(g_drawHIO.mMiniGame.mIconPosX[2]);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -2066,7 +2066,7 @@ bool jmessage_tSequenceProcessor::do_isReady() {
|
||||
case 0:
|
||||
case 5:
|
||||
case 6:
|
||||
if (mDoCPd_c::getTrigA(PAD_1) || field_0xb2 != 0) {
|
||||
if (mDoCPd_c::getTrigA(PAD_1) || field_0xb2 != 0 IF_DUSK(|| (dusk::getSettings().game.instantText && mDoCPd_c::getHoldB(0)))) {
|
||||
field_0xa4 = 0;
|
||||
pReference->onBatchFlag();
|
||||
pReference->setCharCnt(D_MSG_CLASS_CHAR_CNT_MAX);
|
||||
|
||||
@@ -32,6 +32,9 @@
|
||||
|
||||
#if TARGET_PC
|
||||
#include "dusk/settings.h"
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#include <algorithm>
|
||||
#endif
|
||||
|
||||
static void dMsgObject_addFundRaising(s16 param_0);
|
||||
@@ -424,6 +427,16 @@ static void dummyStrings() {
|
||||
dMsgObject_HIO_c g_MsgObject_HIO_c;
|
||||
|
||||
int dMsgObject_c::_execute() {
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.enableMirrorMode) {
|
||||
// enable wii message index override
|
||||
g_MsgObject_HIO_c.mMessageDisplay = 1;
|
||||
} else if (!dusk::getSettings().game.enableMirrorMode && g_MsgObject_HIO_c.mMessageDisplay == 1) {
|
||||
g_MsgObject_HIO_c.mMessageDisplay = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
field_0x4c7 = 0;
|
||||
if (mpTalkHeap != NULL) {
|
||||
field_0x148 = mDoExt_setCurrentHeap(mpTalkHeap);
|
||||
@@ -1594,7 +1607,7 @@ u8 dMsgObject_c::isSend() {
|
||||
return 2;
|
||||
}
|
||||
} else {
|
||||
if (IF_DUSK((dusk::getSettings().game.instantText && mDoCPd_c::getHoldB(0)) ||)
|
||||
if (IF_DUSK((dusk::getSettings().game.instantText && mDoCPd_c::getHoldB(0) && !isShopItemMessage()) ||)
|
||||
mDoCPd_c::getTrigA(0) != 0 || mDoCPd_c::getTrigB(0) != 0) {
|
||||
return 2;
|
||||
}
|
||||
@@ -1866,6 +1879,39 @@ bool dMsgObject_c::isTalkMessage() {
|
||||
return true;
|
||||
}
|
||||
|
||||
#if TARGET_PC
|
||||
bool dMsgObject_c::isShopItemMessage() {
|
||||
|
||||
// Probably a better way to do this than just listing every message id, but this works for now
|
||||
// Note: Keep contents sorted so we can use binary search
|
||||
const auto shopMsgIds = std::to_array<std::vector<s16>>({
|
||||
{},
|
||||
// zel_01.bmg - Seras Shop
|
||||
{7001, 7003, 7004, 7005, 7006, 7007, 7008, 7009, 7010, 7013, 7014, 7022, 7023, 7028, 7029,
|
||||
7044, 7045, 7053},
|
||||
// zel_02.bmg - Kakariko Shops
|
||||
{5181, 5182, 5251, 5253, 5254, 5256, 5258, 5259, 5653, 5654, 5656, 5660, 5661, 5664, 5665,
|
||||
5697, 5698, 5699, 5803, 5804, 5806, 5810, 5811, 5812, 5814, 5821, 5823, 5824, 5987, 5988,
|
||||
5989, 5990, 5991, 5992, 5993, 5994, 5995, 5996, 5997, 5998, 5999},
|
||||
// zel_03.bmg - Death Mountain Shop
|
||||
{5303, 5304, 5306, 5310, 5311, 5314, 5315, 5322, 5323, 5324, 5496, 5497, 5498, 5499},
|
||||
// zel_04.bmg - Castle Town Shops
|
||||
{5407, 5408, 5409, 5410, 5411, 5412, 5413, 5414, 5415, 5416, 5417, 5418, 5419, 5420, 5431,
|
||||
5432, 5434, 5435, 5436, 5437, 5438, 5439, 5440, 5441, 5444, 5449, 5450, 5451, 5452, 5462},
|
||||
// zel_05.bmg - Oocca Shop
|
||||
{9428, 9429, 9430, 9431, 9432, 9437, 9443, 9448, 9449, 9451, 9459}
|
||||
});
|
||||
|
||||
u16 id = mMessageID;
|
||||
s16 group = dMsgObject_getGroupID();
|
||||
if (group < shopMsgIds.size()) {
|
||||
return std::ranges::binary_search(shopMsgIds[group], id);
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
const char* dMsgObject_c::getSmellName() {
|
||||
JMSMesgInfo_c* info_header_p = (JMSMesgInfo_c*)((char*)mpMsgRes + 0x20);
|
||||
char* data_ptr = (char*)info_header_p + info_header_p->header.size;
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
#include "d/d_com_inf_game.h"
|
||||
#include "d/d_pane_class.h"
|
||||
|
||||
#if TARGET_PC
|
||||
#include "dusk/settings.h"
|
||||
#endif
|
||||
|
||||
dMsgScrnArrow_c::dMsgScrnArrow_c() {
|
||||
mpScreen = JKR_NEW J2DScreen();
|
||||
JUT_ASSERT(0, mpScreen != NULL);
|
||||
@@ -65,6 +69,11 @@ dMsgScrnArrow_c::~dMsgScrnArrow_c() {
|
||||
}
|
||||
|
||||
void dMsgScrnArrow_c::draw() {
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.recordingMode) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
J2DGrafContext* graf_ctx = dComIfGp_getCurrentGrafPort();
|
||||
mpScreen->draw(0.0f, 0.0f, graf_ctx);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
#include "d/d_pane_class.h"
|
||||
#include <cstring>
|
||||
|
||||
#if TARGET_PC
|
||||
#include "dusk/settings.h"
|
||||
#endif
|
||||
|
||||
dMsgScrnBase_c::dMsgScrnBase_c() {
|
||||
init();
|
||||
}
|
||||
@@ -57,12 +61,22 @@ void dMsgScrnBase_c::init() {
|
||||
}
|
||||
|
||||
void dMsgScrnBase_c::multiDraw() {
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.recordingMode) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (field_0x48 != NULL) {
|
||||
dComIfGd_set2DOpa(field_0x48);
|
||||
}
|
||||
}
|
||||
|
||||
void dMsgScrnBase_c::draw() {
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.recordingMode) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
J2DGrafContext* ctx = dComIfGp_getCurrentGrafPort();
|
||||
|
||||
ctx->setup2D();
|
||||
@@ -72,10 +86,20 @@ void dMsgScrnBase_c::draw() {
|
||||
}
|
||||
|
||||
void dMsgScrnBase_c::drawSelf() {
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.recordingMode) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
drawOutFont(0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
void dMsgScrnBase_c::drawOutFont(f32 param_0, f32 param_1, f32 param_2) {
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.recordingMode) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
mpOutFont->draw(NULL, param_0, param_1, param_2);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
#include "d/d_msg_object.h"
|
||||
#include "d/d_pane_class.h"
|
||||
|
||||
#if TARGET_PC
|
||||
#include "dusk/settings.h"
|
||||
#endif
|
||||
|
||||
dMsgScrnBoss_c::dMsgScrnBoss_c() {
|
||||
static u64 t_tag[7] = {
|
||||
MULTI_CHAR('sfontb0'), MULTI_CHAR('sfontb1'), MULTI_CHAR('sfontb2'), MULTI_CHAR('sfontl0'), MULTI_CHAR('sfontl1'), MULTI_CHAR('sfontl2'), MULTI_CHAR('sfont00'),
|
||||
@@ -91,6 +95,11 @@ void dMsgScrnBoss_c::exec() {
|
||||
}
|
||||
|
||||
void dMsgScrnBoss_c::drawSelf() {
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.recordingMode) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
J2DGrafContext* ctx = dComIfGp_getCurrentGrafPort();
|
||||
ctx->setup2D();
|
||||
drawOutFont(0.0f, 0.0f, 1.0f);
|
||||
|
||||
@@ -13,6 +13,10 @@
|
||||
#include "d/d_msg_out_font.h"
|
||||
#include "d/d_pane_class.h"
|
||||
|
||||
#if TARGET_PC
|
||||
#include "dusk/settings.h"
|
||||
#endif
|
||||
|
||||
dMsgScrnKanban_c::dMsgScrnKanban_c(JKRExpHeap* param_0) {
|
||||
if (param_0 != NULL) {
|
||||
field_0xd4 = param_0;
|
||||
@@ -176,6 +180,11 @@ void dMsgScrnKanban_c::exec() {
|
||||
}
|
||||
|
||||
void dMsgScrnKanban_c::draw() {
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.recordingMode) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
J2DGrafContext* grafContext = dComIfGp_getCurrentGrafPort();
|
||||
grafContext->setup2D();
|
||||
mpScreen->draw(0.0f, 0.0f, grafContext);
|
||||
|
||||