Compare commits

..

156 Commits

Author SHA1 Message Date
madeline c6d65de5af first person cam proof of concept 2026-04-06 22:52:20 -07:00
madeline f489cc2786 Merge branch 'main' of https://github.com/TakaRikka/dusk 2026-04-06 20:36:01 -07:00
madeline 4e12f7bb95 fix basically all known audio bugs fixes #148 fixes #146 fixes #130 2026-04-06 20:35:54 -07:00
Luke Street 8fac510140 Update aurora & fixes for OS header changes 2026-04-06 21:25:50 -06:00
TakaRikka bdf648008d Merge pull request #255 from TwilitRealm/fast-spinner
fast spinner cheat impl
2026-04-06 19:35:53 -07:00
TakaRikka f2c46f8498 Merge pull request #241 from TwilitRealm/double-heaps
Double heap sizes for various heaps (Midna eye)
2026-04-06 19:31:56 -07:00
CraftyBoss e4de461e7a fast spinner cheat impl
just makes it so holding R while on the spinner increases its speed to 60 units
2026-04-06 18:26:33 -07:00
CraftyBoss 287cd21f71 update aurora 2026-04-06 17:43:23 -07:00
Jeffrey Crowell 2dbcf13c09 use "Cmd" instead of "Ctrl" for hotkeys on Apple (#239) 2026-04-07 02:33:27 +02:00
TakaRikka 8e4889cc5c Merge pull request #250 from TwilitRealm/faster-saving
Accelerate saving, copying & erasing save files
2026-04-06 16:18:55 -07:00
MelonSpeedruns 185c70bd10 Accelerate saving, copying & erasing save files 2026-04-06 19:08:10 -04:00
TakaRikka 839c9b8875 Merge pull request #237 from TwilitRealm/feature/dynamic-aspect-ratio
Feature/dynamic aspect ratio
2026-04-06 15:52:19 -07:00
PJB3005 5c247bcb15 Fix cCcS layout being interpreted inconsistently across TUs
Fixes #245

Might be the cause of #176 too but I wasn't able to repro that in either case, so can't confirm.
2026-04-06 23:15:56 +02:00
Lurs 3d66c127ab Use HEAP_SIZE() 2026-04-06 23:08:34 +02:00
Lurs 168d819254 Fix "[ERROR] memory free error!!" message while leaving options menu 2026-04-06 22:09:50 +02:00
Lurs 83a9df4016 Fix "[NEW] JKRHeap (d_a_bg Anms) FULL! Fallback to malloc for size XXX" errors/warnings 2026-04-06 21:18:29 +02:00
Lurs 4f28c4ed10 double heaps to fix Midna's eye (#106) and various other error messages I got.
Also updating aurora.
2026-04-06 21:18:28 +02:00
MelonSpeedruns af6a1ff004 fix building 2026-04-06 13:21:04 -04:00
MelonSpeedruns c0024b28b1 Merge remote-tracking branch 'origin/main' into feature/dynamic-aspect-ratio 2026-04-06 13:16:38 -04:00
madeline c41ec46c71 reorganize menus a bit 2026-04-06 00:48:10 -07:00
TakaRikka c7e2892357 Merge pull request #221 from TwilitRealm/26-04-04-config
Config system v1
2026-04-05 19:45:55 -07:00
madeline 0b5dcfc7ad fix every viewport projection issue fixes #123 fixes #115 2026-04-05 16:31:57 -07:00
madeline 77fbc2b7d1 Merge branch 'main' of https://github.com/TakaRikka/dusk 2026-04-05 15:05:41 -07:00
madeline e7dc10aefb fix cloud, sun, moon, rain, fog, lens flare, etc, culling 2026-04-05 15:05:38 -07:00
Max Roncace b098577ab9 Reapply settings changes on top of #209 2026-04-05 23:49:31 +02:00
PJB3005 3eb843cc80 Explanation at top of config.hpp
(config_var.hpp already had one)
2026-04-05 23:13:33 +02:00
PJB3005 1da0655ec6 Un-duplicate togglefullscreen code again 2026-04-05 23:09:51 +02:00
PJB3005 6c6b2c3567 Merge branch 'main' into 26-04-04-config 2026-04-05 23:08:03 +02:00
madeline aa54aba07c update aurora sm 2026-04-05 17:05:34 -04:00
bdamja 1430f690e0 button to restore default window size and position (#234) 2026-04-05 17:04:40 -04:00
MelonSpeedruns 9a27718808 Almost all menus scaled 2026-04-05 17:04:39 -04:00
MelonSpeedruns dd11e5a39f Modified Map Name to work with aspect ratios 2026-04-05 17:04:39 -04:00
CraftyBoss 6ca9017e12 update HUD positions in updateOnWide instead of when drawing
this change makes it so positions will properly update when resizing the window, instead of only updating on room load
2026-04-05 17:04:39 -04:00
PJB3005 6e6f55f1e4 Fix compile by giving WIDESCREEN_SUPPORT a value 2026-04-05 17:03:24 -04:00
MelonSpeedruns 47a8881406 fix full map rendering with multiple ratios, cursor still glitched 2026-04-05 16:56:35 -04:00
MelonSpeedruns 0ae4f5a78c Fix Wolf Senses vignette on widescreen 2026-04-05 16:56:35 -04:00
MelonSpeedruns ba965ae32d Fix black screen effect when turning into Wolf Link 2026-04-05 16:56:35 -04:00
MelonSpeedruns fe02fb8e61 Fix underwater effect + Fading to work at any aspect ratio 2026-04-05 16:56:35 -04:00
MelonSpeedruns 769eba2e21 fix building 2026-04-05 16:56:33 -04:00
Lurs ae1018318a Fix arrows for dungeon map 2026-04-05 16:55:52 -04:00
MelonSpeedruns 49ad699eb3 fix reticles for good 2026-04-05 16:55:52 -04:00
MelonSpeedruns 483b7eaecc nvm im dumb 2026-04-05 16:55:52 -04:00
MelonSpeedruns 9d61f300c1 fix reticle position 2026-04-05 16:55:52 -04:00
MelonSpeedruns 74d0c0b282 scale bloom depending on the window size 2026-04-05 16:55:52 -04:00
Irastris bbe205d3bf Fix fmap cursor and options screen 2026-04-05 16:55:52 -04:00
MelonSpeedruns 3414cec13c initial commit with working 3D view at all times 2026-04-05 16:55:48 -04:00
Max Roncace bfbf524be2 Build "game" as a static library (#236)
* Build "game" as a static library

This effectively renames the "game" lib to game_base, builds it and
game_debug as object libraries, and links both into a single static
library. There is also some refactoring done to remove the game_base's
dependencies on game_debug's compile-time parameters which have now
been moved into shared buildscript variables.

* Fix build

---------

Co-authored-by: PJB3005 <pieterjan.briers+git@gmail.com>
2026-04-05 22:48:44 +02:00
madeline c006baaf63 Merge branch 'main' of https://github.com/TakaRikka/dusk 2026-04-05 11:48:20 -07:00
madeline 3d5f2474bf turbo keybind tool 2026-04-05 11:47:49 -07:00
Irastris 13f24a585d Use int for audio sliders, show current value (#235) 2026-04-05 12:31:45 -06:00
MelonSpeedruns adf22e69c1 Resize ImGui windows automatically + Move "Tools" menu after "Enhancements" (#232)
* Resize ImGui windows automatically + Move "Tools" menu after "Enhancements"

* Oops, forgot one of those

* Always resize Tools menu

* Moved hotkeys to allow fullscreen & reset to be done without the menu open
2026-04-05 12:30:48 -06:00
Jeffrey Crowell 7920a6144a force scale of 1.0 (#230)
combine with https://github.com/encounter/aurora/pull/54
to have aurora actually handle the scaling properly instead of doing it
hackily in dusk.
2026-04-05 12:30:03 -06:00
Max Roncace 2aad522298 Revert "Get rid of separate game dylib"
This reverts commit 9b44afa5b2.
2026-04-05 14:21:14 -04:00
madeline 791e2400de Merge branch 'main' of https://github.com/TakaRikka/dusk 2026-04-05 11:05:38 -07:00
madeline 1ffeb900ae fix trimming issue closes #201 2026-04-05 11:05:31 -07:00
PJB3005 9b44afa5b2 Get rid of separate game dylib
Just link that shit into the exe. Means we can turn off CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS and save file size.
2026-04-05 19:32:04 +02:00
PJB3005 1cccef54d5 Remove and tighten down on some unused stubs 2026-04-05 19:29:06 +02:00
PJB3005 49412fae51 appname.hpp -> app_info.hpp 2026-04-05 19:20:10 +02:00
PJB3005 92fe1e7702 Fix destructible bridges by removing a STUB_RET
Fixes #127
2026-04-05 19:15:45 +02:00
PJB3005 0af2ad69e0 Fix bad snprintf in ImGuiHeapOverlay.cpp 2026-04-05 19:10:42 +02:00
PJB3005 b82a623810 DUSK_SELECTED_OPT applies to freeverb
Fixes audio stuttering on debug builds
2026-04-05 19:09:33 +02:00
PJB3005 f732eccf6c Set Aurora config path 2026-04-05 19:03:26 +02:00
PJB3005 98b5166413 Merge remote-tracking branch 'origin/main' into 26-04-04-config 2026-04-05 15:13:04 +02:00
TakaRikka b5f9b9d7d3 Merge pull request #228 from TwilitRealm/fix-sand
Find proper distance initialization for particles (fix for #207)
2026-04-04 23:43:07 -07:00
Irastris 574d980b23 Fix enhancements menu v3_reallyforreal_final_v02 2026-04-05 02:23:55 -04:00
madeline 1d98db6d13 make the reverb sound slightly more accurate 2026-04-04 23:04:08 -07:00
Lurs a8e136c2c9 Fixes #207 (A bug I brought myself in :( ) 2026-04-05 07:46:28 +02:00
madeline de038222ac no longer needed 2026-04-04 22:45:35 -07:00
madeline bdae7b3e42 Merge branch 'main' of https://github.com/TakaRikka/dusk 2026-04-04 22:45:05 -07:00
madeline 05b1b29cb9 fix clangd for vscode and remove win platform variants since thats done through environment on windows 2026-04-04 22:45:00 -07:00
Irastris a52dffe9a8 I hate you VS 2026-04-05 01:24:20 -04:00
madeline 78e7c3ced9 a 2026-04-04 22:22:34 -07:00
madeline 6857c54695 fix .clangd on vscode 2026-04-04 22:22:18 -07:00
Irastris cf30230501 Fix building again & minor reformatting 2026-04-05 01:19:53 -04:00
TakaRikka 67bd14bfd8 Merge pull request #215 from TwilitRealm/reverb-wip
Audio FX reverb proof of concept
2026-04-04 21:38:01 -07:00
TakaRikka 8926512e02 Merge pull request #219 from TakaRikka/feature/no-low-hp-sound
No Low HP Sound Enhancement
2026-04-04 19:02:32 -07:00
MelonSpeedruns ce979a3328 Merge branch 'main' into feature/no-low-hp-sound 2026-04-04 21:50:00 -04:00
madeline 29ea44fc1d dump audio and bigger room size 2026-04-04 17:14:09 -07:00
madeline 37ab09ec1d h 2026-04-04 16:07:36 -07:00
madeline ebc37b934d better reverb 2026-04-04 15:59:18 -07:00
TakaRikka 8377cf618a Merge pull request #218 from TakaRikka/feature/transform-anywhere
Can transform Anywhere + Refactored checks to see if you can Quick Transform
2026-04-04 15:59:12 -07:00
TakaRikka 1ffb5a8c7f Merge pull request #217 from TakaRikka/feature/no-miss-animation
No Climbing Miss Animation toggle, similar to TPHD
2026-04-04 15:54:57 -07:00
TakaRikka 1946a7230c Merge pull request #216 from TakaRikka/feature/MDH-no-cut
Non-Stop Midna's Lament Audio Enhancement
2026-04-04 15:54:01 -07:00
PJB3005 0bb9ff5ef3 Merge remote-tracking branch 'origin/main' into 26-04-04-config 2026-04-05 00:12:17 +02:00
PJB3005 14026397e9 Implicit conversion operator is probably a good idea tbh. 2026-04-04 23:00:33 +02:00
PJB3005 e55537f23e I realize that's an important comment for C++ 2026-04-04 22:49:51 +02:00
PJB3005 824263fa6e Config system v1
Roughly inspired by what I've learned from my work on Space Station 14, without some of the unnecessary cruft and complexity.

Implementation is relatively simple once I figured out all the template order shenanigans.
2026-04-04 22:47:48 +02:00
MelonSpeedruns 3dca79e375 No Low HP Sound Enhancement 2026-04-04 14:47:39 -04:00
MelonSpeedruns d0afac0fba removed period in description 2026-04-04 14:31:40 -04:00
MelonSpeedruns 35337d5569 removed period in description 2026-04-04 14:31:16 -04:00
MelonSpeedruns dca35f8b91 Can transform anywhere + Refactored checks to see if you can Quick Transform 2026-04-04 14:30:42 -04:00
MelonSpeedruns 0ccf5e8771 No Climbing Miss Animation toggle, similar to TPHD 2026-04-04 11:59:08 -04:00
MelonSpeedruns 6f76a52545 oops, forgot to check the box 2026-04-04 11:57:42 -04:00
MelonSpeedruns 1862e3a0e4 Non-Stop Midna's Lament Audio Enhancement 2026-04-04 11:36:15 -04:00
TakaRikka 015e7aceab hd faster tears toggle 2026-04-04 06:02:23 -07:00
TakaRikka b45af18374 quick climbing qol, difficulty options 2026-04-04 03:52:28 -07:00
TakaRikka 0d1e680ddd no sword recoil enhancement 2026-04-04 02:59:53 -07:00
TakaRikka 7d41421702 couple of hd qol toggles 2026-04-04 02:37:59 -07:00
madeline f5ce58ca7f reverb proof of concept 2026-04-04 01:38:28 -07:00
TakaRikka ec66b4c9f4 Merge pull request #98 from TakaRikka/feature/disable-tv-settings
Add tweak to enable/disable TV settings screen
2026-04-03 23:27:04 -07:00
Irastris c94976cd41 Remove AuroraConfig configPath 2026-04-04 01:52:48 -04:00
Max Roncace 932123bedb Fix compile error in J3DMaterialFactory_v21 2026-04-04 01:41:04 -04:00
Max Roncace 479d444066 Fix a couple more BE issues in J3DMaterialFactory_v21 2026-04-04 01:36:16 -04:00
madeline c869320471 Merge branch 'main' of https://github.com/TakaRikka/dusk 2026-04-03 22:33:41 -07:00
madeline 350e99e8ab fix getDopplerPower fixes #213 2026-04-03 22:33:38 -07:00
Max Roncace 5bb36dfb20 Fix crashes when entering Henna's shop 2026-04-04 01:30:24 -04:00
madeline 882c61e101 Merge branch 'main' of https://github.com/TakaRikka/dusk 2026-04-03 21:51:08 -07:00
madeline 889129cacf do resampling manually 2026-04-03 21:51:04 -07:00
Max Roncace 970664d7f9 Add tweak to enable/disable TV settings screen 2026-04-04 00:32:17 -04:00
TakaRikka 4d3330acf5 Merge pull request #209 from TakaRikka/feature/tweaks-refactor
Refactor Dusk settings out to common interface used by game and UI code
2026-04-03 21:23:53 -07:00
Max Roncace 45137f4838 Move hotkey bindings to separate header 2026-04-04 00:16:44 -04:00
Max Roncace b9e16d33df Refactor Dusk settings out to common interface used by game and UI code 2026-04-04 00:16:44 -04:00
madeline 495536bc18 Merge branch 'main' of https://github.com/TakaRikka/dusk 2026-04-03 19:55:00 -07:00
madeline f3465b7506 better gitignore 2026-04-03 19:54:57 -07:00
Irastris e04cd69851 Fix Windows builds 2026-04-03 21:53:39 -04:00
TakaRikka 12631c3ee8 Merge pull request #212 from TakaRikka/imgui-overhaul
Copy more imgui stuff from Metaforce
2026-04-03 16:48:48 -07:00
Luke Street d7644a294d Add pipeline progress overlay 2026-04-03 17:28:32 -06:00
Luke Street 5f0f3628ce Rescale imgui on display scale change 2026-04-03 17:09:29 -06:00
Luke Street b8f53c55a5 Copy more imgui stuff from Metaforce 2026-04-03 17:04:22 -06:00
TakaRikka 97ab7313d4 Merge pull request #210 from TakaRikka/offscreen
Update aurora & use new frame buffer API
2026-04-02 22:20:00 -07:00
Luke Street cdcb352084 Update aurora & use new frame buffer API 2026-04-02 23:08:00 -06:00
TakaRikka 806bef466c Merge branch 'main' of https://github.com/TakaRikka/dusk 2026-04-02 21:11:03 -07:00
TakaRikka 5e5e72ca1b fix plumm balloon score proj 2026-04-02 21:10:57 -07:00
Max Roncace 507ba41a26 Fix crash when first talking to Fyrus
The animation metadata passed into playExpression is invalid and
causes a junk pointer to be read, triggering a segfault.
2026-04-02 23:08:01 -04:00
TakaRikka 776cd0b344 fix 2026-04-02 19:15:41 -07:00
TakaRikka 3222d18e3c add mirror mode toggle 2026-04-02 19:08:30 -07:00
TakaRikka 67402d092e Merge pull request #193 from TakaRikka/26-04-01-quick-transform
Implement Quick Transform from Rando
2026-04-02 14:48:15 -07:00
PJB3005 ea6a357887 Rename d_a_alink_quicktransform.cpp to d_a_alink_dusk.cpp 2026-04-02 23:45:35 +02:00
PJB3005 c6eb705950 Just use mDoCPd_c for the input check 2026-04-02 23:45:22 +02:00
PJB3005 2edbcd6c65 Merge branch 'main' into 26-04-01-quick-transform 2026-04-02 20:35:49 +02:00
TakaRikka f04a0d2119 add enhancements menu tab 2026-04-02 03:11:58 -07:00
TakaRikka b3196db113 Merge pull request #206 from TakaRikka/ira/title-reload
Reset title screen instead of softlocking when movies are unsupported
2026-04-01 22:59:51 -07:00
Luke Street e9b96bdd21 Add JKRThread::Run return value 2026-04-01 21:01:59 -06:00
TakaRikka bf4aa16185 Merge pull request #205 from TakaRikka/shutdown
Allow threads to gracefully shutdown
2026-04-01 18:32:31 -07:00
TakaRikka d5cd60cd0d Merge pull request #196 from TakaRikka/feature/camera-invert-option
Added camera invert X option to Tweaks menu
2026-04-01 18:30:35 -07:00
Irastris f93180bb54 Reset instead of softlocking when movies are unsupported 2026-04-01 20:57:49 -04:00
Luke Street 7642d72a52 Allow threads to gracefully shutdown 2026-04-01 18:30:12 -06:00
PJB3005 c4bedd6684 BE d_msg_unit.cpp
Fixes fish lengths and probably more stuff

Fixes #194
2026-04-02 01:23:53 +02:00
Irastris 0818add160 Update Aurora 2026-04-01 18:09:40 -04:00
PJB3005 2c82fcb255 How did this compile on my branch but not here... (fix d_a_movie_player.h) 2026-04-01 23:48:45 +02:00
PJB3005 cb77b629e6 Fix bad merge in #139 2026-04-01 23:43:26 +02:00
TakaRikka e7e363f9a4 Merge pull request #139 from TakaRikka/26-03-28-movie-player
Make the movie player work
2026-04-01 13:49:55 -07:00
PJB3005 7480cd3c34 Implement Quick Transform from Rando 2026-04-01 18:11:49 +02:00
Pieter-Jan Briers 6730d0c952 Merge branch 'main' into 26-03-28-movie-player 2026-04-01 15:15:08 +02:00
MelonSpeedruns 5fae2be850 Added camera invert X option to Tweaks menu 2026-03-31 17:33:28 -04:00
PJB3005 95d6d24d31 Fix build without movie support 2026-03-29 03:50:37 +02:00
PJB3005 e18e8cc5dd Forgot to remove this 2026-03-29 03:31:36 +02:00
PJB3005 e827f19554 Give up on fetching libjpeg-turbo ourselves, rely on find_package and user providing it at build time 2026-03-29 03:29:51 +02:00
PJB3005 9738917a91 Clang compile fixes 2026-03-29 03:29:30 +02:00
PJB3005 2686c8dc81 Merge remote-tracking branch 'origin/main' into 26-03-28-movie-player 2026-03-29 03:16:24 +02:00
PJB3005 b09da82912 Allow movie support to be compiled out
(and therefore remove the libjpeg-turbo dependency)
2026-03-29 03:07:03 +02:00
PJB3005 23c6b78bc9 Properly clean up movie player threads
Pain and suffering.
2026-03-29 01:56:41 +01:00
PJB3005 70a5bb08a4 Comment 2026-03-29 01:54:49 +01:00
PJB3005 98da847bf5 OSThread fixes
OSCancelThread and OSDetachThread stubbed out cuz they're probably both broken

Code cleanup, unnecessary code copied from decomp removed, copy-paste reduced.

Don't immediately detach threads when creating them (what's the point??)

Fix OSJoinThread
2026-03-29 01:54:45 +01:00
PJB3005 b17b5fe405 Works a lot better now 2026-03-29 00:19:56 +01:00
PJB3005 bb92f955c8 Make the movie player work somewhat.
THPs are *almost* just a bunch of JPEGs so the TL;DR is BE fixes and replacing the decoding with libjpeg-turbo.

Needs changes to thp.h which should be removed from Aurora, will do that later.

Also audio not implemented yet.
2026-03-28 18:29:58 +01:00
173 changed files with 4912 additions and 805 deletions
+4
View File
@@ -43,3 +43,7 @@ compile_commands.json
# ISOs
*.iso
*.ini
*.controller
pipeline_cache.bin
+7 -3
View File
@@ -1,5 +1,10 @@
{
"cmake.buildDirectory": "${workspaceFolder}/build/dusk/${buildType}/${variant:platform}/${variant:tp_version}",
"cmake.buildDirectory": "${workspaceFolder}/build/dusk/${buildType}/${variant:tp_version}",
"cmake.generator": "Ninja",
"cmake.configureSettings": {
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
},
"cmake.copyCompileCommands": "${workspaceFolder}/compile_commands.json",
"[c]": {
"files.encoding": "utf8",
"editor.defaultFormatter": "llvm-vs-code-extensions.vscode-clangd"
@@ -44,8 +49,7 @@
"build.ninja": true,
".ninja_*": true,
"objdiff.json": true,
".cache/**": true,
"compile_commands.json": true,
".cache/**": true
},
"clangd.arguments": [
"--function-arg-placeholders=0",
+78 -22
View File
@@ -17,8 +17,18 @@ set(AURORA_ENABLE_DVD ON CACHE BOOL "Enable DVD API support" FORCE)
set(AURORA_ENABLE_CARD ON CACHE BOOL "Enable CARD API support" FORCE)
add_subdirectory(extern/aurora EXCLUDE_FROM_ALL)
add_subdirectory(libs/freeverb)
option(DUSK_BUILD_WARNINGS "If off, compiler warnings will be suppressed")
option(DUSK_SELECTED_OPT "If on, selected parts of the project will be compiled with optimizations on Debug, intending to make the game run at 30 FPS. Note for MSVC: you will need to remove '/RTC1' from your debug flags in CMake.")
option(DUSK_MOVIE_SUPPORT "If on, compile against libjpeg-turbo to enable THP file decoding" ON)
find_package(libjpeg-turbo)
set(DUSK_MOVIE_SUPPORT_REAL ${DUSK_MOVIE_SUPPORT})
if (DUSK_MOVIE_SUPPORT AND NOT libjpeg-turbo_FOUND)
message(WARNING "libjpeg-turbo not found but DUSK_MOVIE_SUPPORT set, movie playback will not be available!")
set(DUSK_MOVIE_SUPPORT_REAL OFF)
endif ()
if (CMAKE_SYSTEM_NAME STREQUAL Linux)
# -Wno-multichar: Multi-character constants ('ABCD') are implementation-defined but all compilers
@@ -61,6 +71,12 @@ FetchContent_Declare(
)
FetchContent_MakeAvailable(cxxopts)
FetchContent_Declare(json
URL https://github.com/nlohmann/json/releases/download/v3.12.0/json.tar.xz
URL_HASH SHA256=42f6e95cad6ec532fd372391373363b62a14af6d771056dbfc86160e6dfff7aa
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
)
FetchContent_MakeAvailable(json)
include(files.cmake)
@@ -78,9 +94,37 @@ message(STATUS "dusk: TP Version: ${DUSK_TP_VERSION}")
source_group("dolzel" FILES ${DOLZEL_FILES} ${Z2AUDIOLIB_FILES} ${JSYSTEM_FILES} ${JSYSTEM_DEBUG_FILES} ${REL_FILES})
source_group("dusk" FILES ${DUSK_FILES})
set(GAME_COMPILE_DEFS TARGET_PC WIDESCREEN_SUPPORT=1 AVOID_UB=1 VERSION=0
DUSK_TP_VERSION="${DUSK_TP_VERSION}" DUSK_GAME_NAME="${DUSK_GAME_NAME}" DUSK_GAME_VERSION="${DUSK_GAME_VERSION}")
set(GAME_INCLUDE_DIRS
include
src
assets/${DUSK_TP_VERSION}
libs/JSystem/include
libs
extern/aurora/include/dolphin
extern
${CMAKE_SOURCE_DIR}/build/${DUSK_TP_VERSION}/include
build/${DUSK_TP_VERSION}/include)
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)
if (DUSK_MOVIE_SUPPORT_REAL)
if (TARGET libjpeg-turbo::turbojpeg-static)
message(STATUS "dusk: Linking against libjpeg-turbo static library")
list(APPEND GAME_LIBS "libjpeg-turbo::turbojpeg-static")
else ()
message(STATUS "dusk: Linking against libjpeg-turbo shared library")
list(APPEND GAME_LIBS "libjpeg-turbo::turbojpeg")
endif ()
list(APPEND GAME_COMPILE_DEFS MOVIE_SUPPORT=1)
endif ()
# game_debug is for game code files that we know work when compiled with DEBUG=1
# Of course, if building a release build, this distinction is irrelevant
add_library(game_debug STATIC ${JSYSTEM_DEBUG_FILES} ${SSYSTEM_FILES}
add_library(game_debug OBJECT ${JSYSTEM_DEBUG_FILES} ${SSYSTEM_FILES}
src/dusk/audio/DuskAudioSystem.cpp
src/dusk/audio/JASCriticalSection.cpp
src/dusk/audio/DuskDsp.hpp
@@ -88,36 +132,47 @@ add_library(game_debug STATIC ${JSYSTEM_DEBUG_FILES} ${SSYSTEM_FILES}
src/dusk/audio/Adpcm.cpp
src/dusk/audio/Adpcm.hpp
src/dusk/audio/DspStub.cpp)
target_compile_definitions(game_debug PRIVATE TARGET_PC AVOID_UB=1 VERSION=0 $<$<CONFIG:Debug>:DEBUG=1>)
# Make these properties PUBLIC so that the regular game target also sees them.
target_include_directories(game_debug PUBLIC
include
src
assets/${DUSK_TP_VERSION}
libs/JSystem/include
extern/aurora/include/dolphin
extern
${CMAKE_SOURCE_DIR}/build/${DUSK_TP_VERSION}/include
build/${DUSK_TP_VERSION}/include)
target_link_libraries(game_debug PUBLIC aurora::core aurora::gx aurora::gd aurora::si aurora::vi aurora::pad aurora::mtx aurora::os aurora::dvd aurora::card)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
add_library(game SHARED ${DOLZEL_FILES} ${Z2AUDIOLIB_FILES} ${SSYSTEM_FILES} ${JSYSTEM_FILES} ${REL_FILES} ${DUSK_FILES} ${DOLPHIN_FILES}
# game_base is for all other game code files
add_library(game_base OBJECT ${DOLZEL_FILES} ${Z2AUDIOLIB_FILES} ${JSYSTEM_FILES} ${REL_FILES} ${DUSK_FILES}
${DOLPHIN_FILES}
src/dusk/imgui/ImGuiStubLog.cpp
src/dusk/imgui/ImGuiAudio.cpp)
target_link_libraries(game PRIVATE game_debug cxxopts::cxxopts absl::flat_hash_map)
target_compile_definitions(game PRIVATE TARGET_PC AVOID_UB=1 VERSION=0 NDEBUG=1 NDEBUG_DEFINED=1 DEBUG_DEFINED=0
DUSK_TP_VERSION="${DUSK_TP_VERSION}" DUSK_GAME_NAME="${DUSK_GAME_NAME}" DUSK_GAME_VERSION="${DUSK_GAME_VERSION}")
target_precompile_headers(game PRIVATE "$<$<COMPILE_LANGUAGE:CXX>:${CMAKE_SOURCE_DIR}/include/dusk_pch.hpp>")
target_compile_definitions(game_debug PRIVATE ${GAME_COMPILE_DEFS} $<$<CONFIG:Debug>:DEBUG=1>)
target_compile_definitions(game_base PRIVATE ${GAME_COMPILE_DEFS} NDEBUG=1 NDEBUG_DEFINED=1 DEBUG_DEFINED=0)
# only apply PCH to game_base since not all headers are necessarily validated with DEBUG=1
target_precompile_headers(game_base PRIVATE "$<$<COMPILE_LANGUAGE:CXX>:${CMAKE_SOURCE_DIR}/include/dusk_pch.hpp>")
target_include_directories(game_debug PRIVATE ${GAME_INCLUDE_DIRS})
target_include_directories(game_base PRIVATE ${GAME_INCLUDE_DIRS})
# This implicitly pulls in the library include directories even though no
# linking actually takes place for object libraries
target_link_libraries(game_debug PRIVATE ${GAME_LIBS})
target_link_libraries(game_base PRIVATE ${GAME_LIBS})
# Combined game library
add_library(game STATIC
$<TARGET_OBJECTS:game_base>
$<TARGET_OBJECTS:game_debug>)
target_link_libraries(game PUBLIC ${GAME_LIBS})
add_executable(dusk src/dusk/main.cpp)
target_compile_definitions(dusk PRIVATE TARGET_PC AVOID_UB=1 VERSION=0)
target_include_directories(dusk PRIVATE include)
target_link_libraries(dusk PRIVATE game aurora::main)
target_link_libraries(dusk PRIVATE game aurora::main freeverb)
add_custom_command(TARGET dusk POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
"${CMAKE_SOURCE_DIR}/res"
"$<TARGET_FILE_DIR:dusk>/res"
COMMENT "Copying resources"
)
include(extern/aurora/cmake/AuroraCopyRuntimeDLLs.cmake)
aurora_copy_runtime_dlls(dusk game)
aurora_copy_runtime_dlls(dusk)
if (DUSK_SELECTED_OPT)
if (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
@@ -128,4 +183,5 @@ if (DUSK_SELECTED_OPT)
target_compile_options(xxhash PRIVATE ${_opt_flags})
target_compile_options(aurora_gx PRIVATE ${_opt_flags})
target_compile_options(freeverb PRIVATE ${_opt_flags})
endif ()
-16
View File
@@ -14,22 +14,6 @@ buildType:
long: Optimized, with debug symbols
buildType: RelWithDebInfo
platform:
default: win64
description: Target platform
choices:
win32:
short: Win32
long: Windows 32-bit (MSVC)
settings:
CMAKE_GENERATOR_PLATFORM: Win32
win64:
short: Win64
long: Windows 64-bit (MSVC)
settings:
CMAKE_GENERATOR_PLATFORM: x64
tp_version:
default: GZ2E01
description: TP Version
+1 -1
+12
View File
@@ -1332,20 +1332,32 @@ set(DOLPHIN_FILES
set(DUSK_FILES
include/dusk/endian_gx.hpp
include/dusk/config.hpp
src/d/actor/d_a_alink_dusk.cpp
src/dusk/asserts.cpp
src/dusk/config.cpp
src/dusk/settings.cpp
src/dusk/logging.cpp
src/dusk/layout.cpp
src/dusk/stubs.cpp
src/dusk/endian.cpp
src/dusk/extras.c
src/dusk/extras.cpp
src/dusk/io.cpp
src/dusk/globals.cpp
src/dusk/settings.cpp
#src/dusk/m_Do_ext_dusk.cpp
src/dusk/imgui/ImGuiConfig.hpp
src/dusk/imgui/ImGuiConsole.hpp
src/dusk/imgui/ImGuiConsole.cpp
src/dusk/imgui/ImGuiEngine.cpp
src/dusk/imgui/ImGuiEngine.hpp
src/dusk/imgui/ImGuiMenuGame.cpp
src/dusk/imgui/ImGuiMenuGame.hpp
src/dusk/imgui/ImGuiMenuTools.cpp
src/dusk/imgui/ImGuiMenuTools.hpp
src/dusk/imgui/ImGuiMenuEnhancements.cpp
src/dusk/imgui/ImGuiMenuEnhancements.hpp
src/dusk/imgui/ImGuiProcessOverlay.cpp
src/dusk/imgui/ImGuiCameraOverlay.cpp
src/dusk/imgui/ImGuiHeapOverlay.cpp
+1 -1
View File
@@ -15,7 +15,7 @@ public:
/* 0x0400 */ cCcD_Obj* mpObjTg[0x300];
/* 0x1000 */ cCcD_Obj* mpObjCo[0x100];
/* 0x1400 */ cCcD_Obj* mpObj[0x500];
#if DEBUG
#if TARGET_PC || DEBUG
/* 0x2800 */ u32 m_debug_code;
#endif
/* 0x2800 */ u16 mObjAtCount;
+4 -6
View File
@@ -4547,6 +4547,10 @@ public:
/* 0x03848 */ cXyz* field_0x3848;
/* 0x0384C */ cXyz* field_0x384c;
/* 0x03850 */ daAlink_procFunc mpProcFunc;
#if TARGET_PC
void handleQuickTransform();
#endif
}; // Size: 0x385C
class daAlinkHIO_data_c : public JORReflexible {
@@ -8425,10 +8429,4 @@ inline daAlink_c* daAlink_getAlinkActorClass() {
return (daAlink_c*)dComIfGp_getLinkPlayer();
}
#if TARGET_PC
namespace dusk::tweaks {
extern bool FastIronBoots;
}
#endif
#endif /* D_A_D_A_ALINK_H */
+87
View File
@@ -1,7 +1,11 @@
#ifndef D_A_MOVIE_PLAYER_H
#define D_A_MOVIE_PLAYER_H
#if !TARGET_PC
#include <thp.h>
#else
#include <atomic>
#endif
#include "f_op/f_op_actor.h"
#include "d/d_drawlist.h"
@@ -11,6 +15,85 @@ struct daMP_THPReadBuffer {
BOOL isValid;
};
#if TARGET_PC
// Copying here because thp.h is probably erroneous in the dolphin lib,
// and it's kind of a problem being there (Aurora owns the headers).
// TODO: Move this stuff in decomp?
typedef struct THPAudioRecordHeader {
BE(u32) offsetNextChannel;
BE(u32) sampleSize;
BE(s16) lCoef[8][2];
BE(s16) rCoef[8][2];
BE(s16) lYn1;
BE(s16) lYn2;
BE(s16) rYn1;
BE(s16) rYn2;
} THPAudioRecordHeader;
typedef struct THPAudioDecodeInfo {
u8* encodeData;
u32 offsetNibbles;
u8 predictor;
u8 scale;
s16 yn1;
s16 yn2;
} THPAudioDecodeInfo;
typedef struct THPTextureSet {
u8* ytexture;
u8* utexture;
u8* vtexture;
s32 frameNumber;
} THPTextureSet;
typedef struct THPAudioBuffer {
s16* buffer;
s16* curPtr;
u32 validSample;
} THPAudioBuffer;
typedef struct THPVideoInfo {
BE(u32) xSize;
BE(u32) ySize;
BE(u32) videoType;
} THPVideoInfo;
typedef struct THPAudioInfo {
BE(u32) sndChannels;
BE(u32) sndFrequency;
BE(u32) sndNumSamples;
BE(u32) sndNumTracks;
} THPAudioInfo;
typedef struct THPFrameCompInfo {
BE(u32) numComponents;
u8 frameComp[16];
} THPFrameCompInfo;
typedef struct THPHeader {
/* 0x00 */ char magic[4];
/* 0x04 */ BE(u32) version;
/* 0x08 */ BE(u32) bufsize;
/* 0x0C */ BE(u32) audioMaxSamples;
/* 0x10 */ BE(f32) frameRate;
/* 0x14 */ BE(u32) numFrames;
/* 0x18 */ BE(u32) firstFrameSize;
/* 0x1C */ BE(u32) movieDataSize;
/* 0x20 */ BE(u32) compInfoDataOffsets;
/* 0x24 */ BE(u32) offsetDataOffsets;
/* 0x28 */ BE(u32) movieDataOffsets;
/* 0x2C */ BE(u32) finalFrameDataOffsets;
} THPHeader;
static u32 THPAudioDecode(s16* audioBuffer, u8* audioFrame, s32 flag);
static s32 __THPAudioGetNewSample(THPAudioDecodeInfo* info);
static void __THPAudioInitialize(THPAudioDecodeInfo* info, u8* ptr);
#define THP_AUDIO_BUFFER_COUNT 3
#define THP_READ_BUFFER_COUNT 10
#define THP_TEXTURE_SET_COUNT 3
#endif
struct daMP_THPPlayer {
/* 0x000 */ DVDFileInfo fileInfo;
/* 0x03C */ THPHeader header;
@@ -34,7 +117,11 @@ struct daMP_THPPlayer {
/* 0x0C8 */ s64 retaceCount;
/* 0x0D0 */ s32 prevCount;
/* 0x0D4 */ s32 curCount;
#if TARGET_PC
/* 0x0D8 */ std::atomic<s32> videoDecodeCount;
#else
/* 0x0D8 */ s32 videoDecodeCount;
#endif
/* 0x0DC */ f32 curVolume;
/* 0x0E0 */ f32 targetVolume;
/* 0x0E4 */ f32 deltaVolume;
+3
View File
@@ -29,6 +29,9 @@ public:
void _move();
void modeWait();
void modeMove();
#if TARGET_PC
void brightCheckWide();
#endif
void _draw();
void draw() {
+3
View File
@@ -367,6 +367,9 @@ public:
void menuCursorShow();
void yesnoWakuAlpahAnmInit(u8, u8, u8, u8);
bool yesnoWakuAlpahAnm(u8);
#if TARGET_PC
void fileSelectWide();
#endif
void _draw();
void errorMoveAnmInitSet(int, int);
bool errorMoveAnm();
+5
View File
@@ -29,6 +29,11 @@ public:
class dMenu_Collect2D_c : public dDlst_base_c {
public:
dMenu_Collect2D_c(JKRExpHeap*, STControl*, CSTControl*);
#if TARGET_PC
void menuCollectWide();
#endif
void _create();
void _delete();
void initialize();
+5
View File
@@ -263,6 +263,11 @@ public:
void setSaveData();
void setInitSaveData();
void _draw();
#if TARGET_PC
void menuSaveWide();
#endif
void _draw2();
virtual ~dMenu_save_c() {}
+6
View File
@@ -148,6 +148,12 @@ public:
void setEmphasisB(u8 param_0) { field_0x762 = param_0; }
u8 getInsideObjCheck() { return field_0x772; }
#if TARGET_PC
constexpr f32 getButtonZAlpha() const {
return mButtonZAlpha;
}
#endif
private:
/* 0x004 */ item_params mItemParams[4];
/* 0x074 */ JKRExpHeap* heap;
+5
View File
@@ -110,6 +110,11 @@ public:
void menuCursorMove();
void menuCursorMove2();
void selectCursorPosSet(int);
#if TARGET_PC
void nameWide();
#endif
void _draw();
void screenSet();
void displayInit();
+4
View File
@@ -48,6 +48,7 @@ public:
void FileSelectClose();
void brightCheckOpen();
void brightCheck();
void doPreLoadSetup();
void changeGameScene();
#if VERSION == VERSION_GCN_PAL
@@ -70,6 +71,9 @@ private:
/* 0x41E */ u8 mWaitTimer;
/* 0x41F */ u8 field_0x41f;
/* 0x420 */ u8 field_0x420;
#if TARGET_PC
bool mShowTvSettingsScreen;
#endif
};
#endif /* D_S_D_S_NAME_H */
+20
View File
@@ -0,0 +1,20 @@
#ifndef DUSK_APPNAME_HPP
#define DUSK_APPNAME_HPP
namespace dusk {
/**
* \brief The internal application name for the game.
*
* This gets used for file paths and such, and cannot be changed!
*/
constexpr auto AppName = "Dusk";
/**
* \brief The internal organization name for the game.
*
* This gets used for file paths and such, and cannot be changed!
*/
constexpr auto OrgName = "TwilitRealm";
}
#endif // DUSK_APPNAME_HPP
+122
View File
@@ -0,0 +1,122 @@
#ifndef DUSK_CONFIG_HPP
#define DUSK_CONFIG_HPP
#include <stdexcept>
#include "nlohmann/json.hpp"
#include "config_var.hpp"
namespace dusk::config {
/*
* config.hpp is a heavier "full" header for the configuration system.
* For a basic overview and the basic types (sufficient for accessing settings),
* look at config_var.hpp.
*
* Avoid including this header in the entire game, it's heavier than I'd like!
*/
/**
* \brief Base class containing virtual functions used for save/load of CVars.
*/
class ConfigImplBase {
protected:
virtual ~ConfigImplBase() = default;
public:
/**
* \brief Load a JSON value into a CVar at the Value layer.
*/
virtual void loadFromJson(ConfigVarBase& cVar, const nlohmann::json& jsonValue) const = 0;
/**
* \brief Load a simple launch argument into the CVar at the Override layer.
*/
virtual void loadFromArg(ConfigVarBase& cVar, std::string_view stringValue) const = 0;
/**
* \brief Dump the value contained in the CVar to JSON.
*/
[[nodiscard]] virtual nlohmann::json dumpToJson(const ConfigVarBase& cVar) const = 0;
};
template<ConfigValue T>
class ConfigImpl : public ConfigImplBase {
// Just downcasting the references...
void loadFromJson(ConfigVarBase& cVar, const nlohmann::json& jsonValue) const final {
assert(typeid(cVar) == typeid(ConfigVar<T>));
loadFromJson(dynamic_cast<ConfigVar<T>&>(cVar), jsonValue);
}
void loadFromArg(ConfigVarBase& cVar, std::string_view stringValue) const final {
assert(typeid(cVar) == typeid(ConfigVar<T>));
loadFromArg(dynamic_cast<ConfigVar<T>&>(cVar), stringValue);
}
[[nodiscard]] nlohmann::json dumpToJson(const ConfigVarBase& cVar) const final {
assert(typeid(cVar) == typeid(ConfigVar<T>));
return dumpToJson(dynamic_cast<const ConfigVar<T>&>(cVar));
}
/**
* \brief Load a JSON value into a CVar at the Value layer.
*/
static void loadFromJson(ConfigVar<T>& cVar, const nlohmann::json& jsonValue);
/**
* \brief Load a simple launch argument into the CVar at the Override layer.
*/
static void loadFromArg(ConfigVar<T>& cVar, std::string_view stringValue);
/**
* \brief Dump the value contained in the CVar to JSON.
*/
[[nodiscard]] static nlohmann::json dumpToJson(const ConfigVar<T>& cVar);
};
/**
* \brief Thrown by config loading functions if the value provided is invalid for the CVar.
*/
class InvalidConfigError : public std::runtime_error {
public:
explicit InvalidConfigError(const char* what) : runtime_error(what) {}
};
/**
* \brief Register a CVar to make the config system aware of it.
*
* This must be done on startup *before* config has been loaded.
*/
void Register(ConfigVarBase& configVar);
/**
* \brief Indicate that all registrations have happened and everything should lock in.
*/
void FinishRegistration();
/**
* \brief Load config from the standard user preferences location.
*/
void LoadFromUserPreferences();
void LoadFromFileName(const char* path);
/**
* \brief Save the config to file.
*/
void Save();
/**
* \brief Get a registered CVar by name.
*
* @return null if the CVar does not exist.
*/
ConfigVarBase* GetConfigVar(std::string_view name);
template <ConfigValue T>
const ConfigImplBase* GetConfigImpl() {
static ConfigImpl<T> config;
return &config;
}
} // namespace dusk::config
#endif
+235
View File
@@ -0,0 +1,235 @@
#ifndef DUSK_CONFIG_VAR_HPP
#define DUSK_CONFIG_VAR_HPP
#include "dolphin/types.h"
#include <type_traits>
#include <cstdlib>
#include <string>
/**
* The configuration system.
*
* Configuration works via "configuration variables" aka "CVars". Each stores a single value that
* may be individually written to/from a configuration file.
*
* CVars, like ogres, have layers. Higher layers (e.g. a set value) override lower layers
* (e.g. the default value).
*
* To define a CVar, simply make a global variable of type ConfigVar<T>,
* and make sure Register() is called on it during program startup.
*
* config_var.hpp contains the simplest "just the configuration vars themselves".
* This should be safe to include for files that need to *access* configuration,
* without blowing up compile times on implementation details.
*
* config.hpp on the other hand contains far more calls for mutating, loading, and defining CVars.
*/
namespace dusk::config {
/**
* \brief Layers that a configuration variable can currently be at.
*
* A configuration variable can be on one of multiple *layers*, which determines where
* the current value is coming from.
*/
enum class ConfigVarLayer : u8 {
/**
* The CVar is at the default value defined by the application code.
*/
Default,
/**
* The CVar has been modified by the user and may be saved to config.
*/
Value,
/**
* The CVar is modified by launch argument, overruling the normal config value.
* Will not get saved to config.
*/
Override,
};
class ConfigImplBase;
/**
* Base class that all CVars inherit from.
* You want the templated ConfigVar instead for actual usage.
*/
class ConfigVarBase {
protected:
/**
* The name of this CVar, used in the configuration file.
*/
const char* name;
/**
* Whether this CVar has been registered with the global managing logic.
* If this is not done, it is not functional.
*/
bool registered;
/**
* The layer this CVar is at.
*/
ConfigVarLayer layer;
/**
* Pointer to an implementation struct for various load/save calls.
*/
const ConfigImplBase* impl;
ConfigVarBase(const char* name, const ConfigImplBase* impl);
virtual ~ConfigVarBase() = default;
/**
* Check that the CVar is registered, aborting if this is not the case.
*/
void checkRegistered() const {
if (!registered)
abort();
}
public:
/**
* Get the name of this CVar, used in the configuration file.
*/
[[nodiscard]] const char* getName() const noexcept;
/**
* Get the pointer to the implementation struct.
*/
[[nodiscard]] const ConfigImplBase* getImpl() const noexcept;
/**
* Get the layer this CVar is currently at.
*/
[[nodiscard]] constexpr ConfigVarLayer getLayer() const noexcept {
return layer;
}
/**
* Mark this CVar as being registered with the central save/load logic.
* This is necessary to make it legal to access.
*/
void markRegistered();
};
template <typename T>
concept ConfigValueInteger =
std::is_same_v<T, s8>
|| std::is_same_v<T, u8>
|| std::is_same_v<T, s16>
|| std::is_same_v<T, u16>
|| std::is_same_v<T, s32>
|| std::is_same_v<T, u32>
|| std::is_same_v<T, s64>
|| std::is_same_v<T, u64>;
/**
* \brief Concept that defines the legal set of types that can be used for CVar values.
*
* Valid types cannot be cv-qualified and must be basic primitive types (int, float, bool),
* strings, or enums of the basic primitives.
*/
template <typename T>
concept ConfigValue =
!std::is_const_v<T>
&& !std::is_volatile_v<T>
&& (std::is_same_v<T, bool>
|| ConfigValueInteger<T>
|| std::is_same_v<T, f32>
|| std::is_same_v<T, f64>
|| std::is_same_v<T, std::string>
|| (std::is_enum_v<T> && ConfigValueInteger<std::underlying_type_t<T>>));
template <ConfigValue T>
const ConfigImplBase* GetConfigImpl();
/**
* \brief A CVar storing values.
*
* @tparam T The type of value stored in the CVar.
*/
template <ConfigValue T>
class ConfigVar : public ConfigVarBase {
T defaultValue;
T value;
T overrideValue;
public:
/**
* \brief Construct a CVar.
*
* @param name The name of this CVar. Must be unique.
* @param arg Arguments to forward to construct the default value.
*/
template <typename... Args>
explicit ConfigVar(const char* name, Args&&... arg)
: ConfigVarBase(name, GetConfigImpl<T>()), defaultValue(std::forward<Args>(arg)...),
value(), overrideValue() {}
/**
* \brief Get the current value of the CVar.
*
* This reference is not guaranteed to remain up-to-date after modification of the CVar.
* It will, however, remain sound to access.
*/
[[nodiscard]] constexpr const T& getValue() const noexcept {
checkRegistered();
switch (layer) {
case ConfigVarLayer::Default:
return defaultValue;
case ConfigVarLayer::Value:
return value;
case ConfigVarLayer::Override:
return overrideValue;
default:
abort();
}
}
/**
* \brief Change the value of a CVar.
*
* The new value is always stored at the Value layer.
*
* @param newValue The new value the CVar will get.
* @param replaceOverride If true, clear an existing override layer if there is one.
* If this is false and there is an override layer,
* the result of getValue() will not change immediately.
*/
void setValue(T newValue, bool replaceOverride = true) {
checkRegistered();
value = std::move(newValue);
if (replaceOverride) {
overrideValue = {};
layer = ConfigVarLayer::Value;
} else if (layer != ConfigVarLayer::Override) {
layer = ConfigVarLayer::Value;
}
}
operator const T&() {
return getValue();
}
/**
* \brief Give a CVar an override value.
*
* This overrides (but does not replace) the apparent set value of this CVar.
* The overriden value will not get saved to config.
*
* @param newValue The new value the CVar will get.
*/
void setOverrideValue(T newValue) {
checkRegistered();
overrideValue = std::move(newValue);
layer = ConfigVarLayer::Override;
}
};
}
#endif // DUSK_CONFIG_VAR_HPP
+1
View File
@@ -4,5 +4,6 @@
#include <aurora/aurora.h>
extern AuroraInfo auroraInfo;
extern const char* configPath;
#endif // DUSK_DUSK_H
+25
View File
@@ -0,0 +1,25 @@
#ifndef DUSK_HOTKEYS_H
#define DUSK_HOTKEYS_H
namespace dusk::hotkeys {
#if __APPLE__
constexpr const char* DO_RESET = "Cmd+R";
#else
constexpr const char* DO_RESET = "Ctrl+R";
#endif
constexpr const char* TOGGLE_FULLSCREEN = "F11";
constexpr const char* SHOW_PROCESS_MANAGEMENT = "F2";
constexpr const char* SHOW_DEBUG_OVERLAY = "F3";
constexpr const char* SHOW_HEAP_VIEWER = "F4";
constexpr const char* SHOW_STUB_LOG = "F5";
constexpr const char* SHOW_CAMERA_DEBUG = "F6";
constexpr const char* SHOW_AUDIO_DEBUG = "F7";
constexpr const char* TURBO = "Tab";
}
#endif // DUSK_HOTKEYS_H
+75
View File
@@ -0,0 +1,75 @@
#ifndef DUSK_IO_HPP
#define DUSK_IO_HPP
#include <vector>
// I can't believe it's 2026 and neither SDL (no error codes) nor
// C++ (no error codes) have a file system API functional enough for me to use.
// Here you go, this one's inspired by C#. I only wrote the functions I need.
namespace dusk::io {
/**
* \brief A simple file stream wrapping cstdio FILE*.
*
* Methods on this class throw appropriate C++ exceptions when an error occurs.
*/
class FileStream {
void* file;
public:
FileStream() noexcept;
/**
* \brief Take ownership of a FILE* handle.
*/
explicit FileStream(void* file);
FileStream(const FileStream& other) = delete;
FileStream(FileStream&& other) noexcept;
~FileStream();
/**
* \brief Open a file for reading at the given path.
*/
static FileStream OpenRead(const char* utf8Path);
/**
* \brief Create a file for writing.
*
* If there is an existing file, its contents are demolished.
*/
static FileStream Create(const char* utf8Path);
/**
* \brief Read the byte contents of a file directly into a vector.
*/
static std::vector<u8> ReadAllBytes(const char* utf8Path);
/**
* \brief Read the byte contents of a file directly into a vector.
*/
static void WriteAllText(const char* utf8Path, std::string_view text);
/**
* \brief Read the remaining contents of the file directly into a vector.
*/
std::vector<u8> ReadFull();
/**
* Get direct access to the underlying FILE* handle.
*/
[[nodiscard]] void* GetFileHandle() const noexcept {
return file;
}
/**
* Write data to the file.
*/
void Write(const char* data, size_t dataLen);
};
}
#endif // DUSK_IO_HPP
+37
View File
@@ -0,0 +1,37 @@
#ifndef DUSK_LAYOUT_H
#define DUSK_LAYOUT_H
#include "dolphin/types.h"
namespace dusk {
/**
* Helper struct for laying things out on the screen. Represents a rectangle via two corner
* positions.
*/
struct LayoutRect {
f32 PosX;
f32 PosY;
f32 PosX2;
f32 PosY2;
[[nodiscard]] constexpr f32 Width() const {
return PosX2 - PosX;
}
[[nodiscard]] constexpr f32 Height() const {
return PosY2 - PosY;
}
/**
* Calculates the position to render one rectangle inside another, centered and maintaining aspect ratio.
*/
[[nodiscard]] static LayoutRect FitRectInRect(
f32 widthOuter,
f32 heightOuter,
f32 widthInner,
f32 heightInner);
};
}
#endif // DUSK_LAYOUT_H
+3
View File
@@ -617,5 +617,8 @@ static const auto gameRegions = std::to_array({
MapEntry("Cutscene: Hyrule Castle Throne Room", "R_SP301", {
{0, {0, 20, 100}},
}),
MapEntry("Title screen movie map", "S_MV000", {
{0, {0, 1}},
}),
})
});
+100
View File
@@ -0,0 +1,100 @@
#ifndef DUSK_CONFIG_H
#define DUSK_CONFIG_H
#include "dusk/config_var.hpp"
namespace dusk {
using namespace config;
// Persistent user settings
struct UserSettings {
// Program settings
struct {
// Video
ConfigVar<bool> enableFullscreen;
} video;
struct {
// Audio
ConfigVar<int> masterVolume;
ConfigVar<int> mainMusicVolume;
ConfigVar<int> subMusicVolume;
ConfigVar<int> soundEffectsVolume;
ConfigVar<int> fanfareVolume;
ConfigVar<bool> enableReverb;
} audio;
// Game settings
struct {
// QoL
ConfigVar<bool> enableQuickTransform;
ConfigVar<bool> hideTvSettingsScreen;
ConfigVar<bool> biggerWallets;
ConfigVar<bool> noReturnRupees;
ConfigVar<bool> disableRupeeCutscenes;
ConfigVar<bool> noSwordRecoil;
ConfigVar<int> damageMultiplier;
ConfigVar<bool> instantDeath;
ConfigVar<bool> fastClimbing;
ConfigVar<bool> noMissClimbing;
ConfigVar<bool> fastTears;
// Preferences
ConfigVar<bool> enableMirrorMode;
ConfigVar<bool> invertCameraXAxis;
// Graphics
ConfigVar<bool> enableBloom;
ConfigVar<bool> useWaterProjectionOffset;
// Audio
ConfigVar<bool> noLowHpSound;
ConfigVar<bool> midnasLamentNonStop;
// Cheats
ConfigVar<bool> enableFastIronBoots;
ConfigVar<bool> canTransformAnywhere;
ConfigVar<bool> fastSpinner;
// Technical
ConfigVar<bool> restoreWiiGlitches;
// Controls
ConfigVar<bool> enableTurboKeybind;
// VR
ConfigVar<bool> vrCamera;
} game;
};
UserSettings& getSettings();
void registerSettings();
// Transient settings
struct CollisionViewSettings {
bool enableTerrainView;
bool enableWireframe;
bool enableAtView;
bool enableTgView;
bool enableCoView;
float terrainViewOpacity;
float colliderViewOpacity;
float drawRange;
};
struct TransientSettings {
CollisionViewSettings collisionView;
bool skipFrameRateLimit;
};
TransientSettings& getTransientSettings();
}
#endif // DUSK_CONFIG_H
+26 -2
View File
@@ -3,6 +3,7 @@
#include "JSystem/JUtility/JUTGamePad.h"
#include "SSystem/SComponent/c_API_controller_pad.h"
#include "dusk/settings.h"
// Controller Ports 1 - 4
enum { PAD_1, PAD_2, PAD_3, PAD_4 };
@@ -52,8 +53,31 @@ public:
static f32 getStickX3D(u32 pad) { return getCpadInfo(pad).mMainStickPosX; }
static f32 getStickValue(u32 pad) { return getCpadInfo(pad).mMainStickValue; }
static s16 getStickAngle(u32 pad) { return getCpadInfo(pad).mMainStickAngle; }
static s16 getStickAngle3D(u32 pad) { return getCpadInfo(pad).mMainStickAngle; }
static f32 getSubStickX3D(u32 pad) { return getCpadInfo(pad).mCStickPosX; }
static s16 getStickAngle3D(u32 pad) {
#if TARGET_PC
if (dusk::getSettings().game.enableMirrorMode) {
return -getCpadInfo(pad).mMainStickAngle;
} else {
return getCpadInfo(pad).mMainStickAngle;
}
#else
return getCpadInfo(pad).mMainStickAngle;
#endif
}
static f32 getSubStickX3D(u32 pad) {
#if TARGET_PC
if (dusk::getSettings().game.enableMirrorMode) {
return -getCpadInfo(pad).mCStickPosX;
} else {
return getCpadInfo(pad).mCStickPosX;
}
#else
return getCpadInfo(pad).mCStickPosX;
#endif
}
static f32 getSubStickX(u32 pad) { return getCpadInfo(pad).mCStickPosX; }
static f32 getSubStickY(u32 pad) { return getCpadInfo(pad).mCStickPosY; }
static f32 getSubStickValue(u32 pad) { return getCpadInfo(pad).mCStickValue; }
+19 -4
View File
@@ -8,7 +8,7 @@
#include <aurora/aurora.h>
#endif
#if WIDESCREEN_SUPPORT
#if WIDESCREEN_SUPPORT && !TARGET_PC
#define FB_WIDTH (640)
#define FB_HEIGHT (456)
#else
@@ -117,6 +117,13 @@ public:
static void setTickRate(u32 rate) { JFWDisplay::getManager()->setTickRate(rate); }
static void waitBlanking(int wait) { JFWDisplay::getManager()->waitBlanking(wait); }
#if TARGET_PC
static f32 hudAspectScaleDown;
static f32 hudAspectScaleUp;
static f32 ScaleHUDXLeft(f32 baseX) { return getMinXF() + baseX; }
static f32 ScaleHUDXRight(f32 baseX) { return -getMinXF() + baseX; }
#endif
static void setBlureMtx(const Mtx m) {
cMtx_copy(m, mBlureMtx);
}
@@ -266,7 +273,12 @@ public:
#if WIDESCREEN_SUPPORT
static void setTvSize();
#if TARGET_PC
static void onWide(f32 width, f32 height);
#else
static void onWide();
#endif
static void offWide();
static u8 isWide();
@@ -312,6 +324,12 @@ public:
static JKRHeap* m_heap;
#endif
#if PLATFORM_WII || PLATFORM_SHIELD || TARGET_PC
static ResTIMG* m_fullFrameBufferTimg;
static void* m_fullFrameBufferTex;
static TGXTexObj m_fullFrameBufferTexObj;
#endif
#if PLATFORM_WII || PLATFORM_SHIELD
static void resetDimming();
@@ -326,9 +344,6 @@ public:
#if WIDESCREEN_SUPPORT
static u8 mWide;
static u8 mWideZoom;
static ResTIMG* m_fullFrameBufferTimg;
static void* m_fullFrameBufferTex;
static TGXTexObj m_fullFrameBufferTexObj;
static f32 m_aspect;
static f32 m_scale;
@@ -82,7 +82,7 @@ public:
/* 0x00 */ u16 mMaterialNum;
/* 0x04 */ J3DMaterialInitData_v21* mpMaterialInitData;
/* 0x08 */ u16* mpMaterialID;
/* 0x08 */ BE(u16)* mpMaterialID;
/* 0x0C */ GXColor* mpMatColor;
/* 0x10 */ u8* mpColorChanNum;
/* 0x14 */ J3DColorChanInfo* mpColorChanInfo;
@@ -91,10 +91,10 @@ public:
/* 0x20 */ J3DTexCoord2Info* mpTexCoord2Info;
/* 0x24 */ J3DTexMtxInfo* mpTexMtxInfo;
/* 0x28 */ J3DTexMtxInfo* field_0x28;
/* 0x2C */ u16* mpTexNo;
/* 0x30 */ GXCullMode* mpCullMode;
/* 0x2C */ BE(u16)* mpTexNo;
/* 0x30 */ BE(GXCullMode)* mpCullMode;
/* 0x34 */ J3DTevOrderInfo* mpTevOrderInfo;
/* 0x38 */ GXColorS10* mpTevColor;
/* 0x38 */ BE(GXColorS10)* mpTevColor;
/* 0x3C */ GXColor* mpTevKColor;
/* 0x40 */ u8* mpTevStageNum;
/* 0x44 */ J3DTevStageInfo* mpTevStageInfo;
@@ -10,7 +10,7 @@
*/
struct JAUAudibleParam {
f32 getDopplerPower() const {
return (u32)((*(u8*)&field_0x0.raw >> 4) & 0xf) * (1.0f / 15.0f);
return field_0x0.bytes.b0_0 * (1.0f / 15.0f);
}
union {
@@ -101,11 +101,22 @@ public:
}
return message;
}
#ifdef TARGET_PC
OSMessage waitMessageBlock(BOOL* received) {
OSMessage message;
BOOL rv = OSReceiveMessage(&mMessageQueue, &message, OS_MESSAGE_BLOCK);
if (received) {
*received = rv;
}
return message;
}
#else
OSMessage waitMessageBlock() {
OSMessage message;
OSReceiveMessage(&mMessageQueue, &message, OS_MESSAGE_BLOCK);
return message;
}
#endif
void jamMessageBlock(OSMessage message) {
OSJamMessage(&mMessageQueue, message, OS_MESSAGE_BLOCK);
}
@@ -10,8 +10,8 @@
J3DMaterialFactory_v21::J3DMaterialFactory_v21(J3DMaterialBlock_v21 const& i_block) {
mMaterialNum = i_block.mMaterialNum;
mpMaterialInitData = JSUConvertOffsetToPtr<J3DMaterialInitData_v21>(&i_block, i_block.mpMaterialInitData);
mpMaterialID = JSUConvertOffsetToPtr<u16>(&i_block, i_block.mpMaterialID);
mpCullMode = JSUConvertOffsetToPtr<GXCullMode>(&i_block, i_block.mpCullMode);
mpMaterialID = JSUConvertOffsetToPtr<BE(u16)>(&i_block, i_block.mpMaterialID);
mpCullMode = JSUConvertOffsetToPtr<BE(GXCullMode)>(&i_block, i_block.mpCullMode);
mpMatColor = JSUConvertOffsetToPtr<GXColor>(&i_block, i_block.mpMatColor);
mpColorChanNum = JSUConvertOffsetToPtr<u8>(&i_block, i_block.mpColorChanNum);
mpColorChanInfo = JSUConvertOffsetToPtr<J3DColorChanInfo>(&i_block, i_block.mpColorChanInfo);
@@ -20,9 +20,9 @@ J3DMaterialFactory_v21::J3DMaterialFactory_v21(J3DMaterialBlock_v21 const& i_blo
mpTexCoord2Info = JSUConvertOffsetToPtr<J3DTexCoord2Info>(&i_block, i_block.mpTexCoord2Info);
mpTexMtxInfo = JSUConvertOffsetToPtr<J3DTexMtxInfo>(&i_block, i_block.mpTexMtxInfo);
field_0x28 = JSUConvertOffsetToPtr<J3DTexMtxInfo>(&i_block, i_block.field_0x38);
mpTexNo = JSUConvertOffsetToPtr<u16>(&i_block, i_block.mpTexNo);
mpTexNo = JSUConvertOffsetToPtr<BE(u16)>(&i_block, i_block.mpTexNo);
mpTevOrderInfo = JSUConvertOffsetToPtr<J3DTevOrderInfo>(&i_block, i_block.mpTevOrderInfo);
mpTevColor = JSUConvertOffsetToPtr<GXColorS10>(&i_block, i_block.mpTevColor);
mpTevColor = JSUConvertOffsetToPtr<BE(GXColorS10)>(&i_block, i_block.mpTevColor);
mpTevKColor = JSUConvertOffsetToPtr<GXColor>(&i_block, i_block.mpTevKColor);
mpTevStageNum = JSUConvertOffsetToPtr<u8>(&i_block, i_block.mpTevStageNum);
mpTevStageInfo = JSUConvertOffsetToPtr<J3DTevStageInfo>(&i_block, i_block.mpTevStageInfo);
@@ -260,7 +260,7 @@ J3DGXColorS10 J3DMaterialFactory_v21::newTevColor(int i_idx, int i_no) const {
J3DGXColorS10 dflt = defaultTevColor;
J3DMaterialInitData_v21* mtl_init_data = &mpMaterialInitData[mpMaterialID[i_idx]];
if (mtl_init_data->mTevColorIdx[i_no] != 0xffff) {
return mpTevColor[mtl_init_data->mTevColorIdx[i_no]];
return (GXColorS10)mpTevColor[mtl_init_data->mTevColorIdx[i_no]];
} else {
return dflt;
}
@@ -242,7 +242,7 @@ void J3DModelLoader::setupBBoardInfo() {
J3DMaterial* mesh = mpModelData->getJointNodePointer(i)->getMesh();
if (mesh != NULL) {
u32 shape_index = mesh->getShape()->getIndex();
u16* index_table = JSUConvertOffsetToPtr<u16>(mpShapeBlock,
BE(u16)* index_table = JSUConvertOffsetToPtr<BE(u16)>(mpShapeBlock,
(uintptr_t)mpShapeBlock->mpIndexTable);
J3DShapeInitData* shape_init_data =
JSUConvertOffsetToPtr<J3DShapeInitData>(mpShapeBlock,
+4
View File
@@ -260,6 +260,10 @@ void JASDriver::finishDSPFrame() {
}
void JASDriver::registerMixCallback(MixCallback param_0, JASMixMode param_1) {
#if TARGET_PC
JASCriticalSection section;
#endif
extMixCallback = param_0;
sMixMode = param_1;
}
+14 -1
View File
@@ -884,6 +884,19 @@ s32 JASSeqParser::cmdPrintf(JASTrack* param_0, u32* param_1) {
s32 JASSeqParser::execNoteOnGate(JASTrack* param_0, u32 param_1, u32 param_2, u32 param_3,
u32 param_4) {
JASSeqCtrl* seqCtrl = param_0->getSeqCtrl();
int r31 = 0;
#if TARGET_PC
// CodeWarrior on PPC allocates MSB-first for bit fields i think, which is stupid
// so in reality these are stored in bit 6 and 7 not but 0 and 1, do this to get around it
if (param_4 & 0x40) {
r31 |= 2;
}
if (param_4 & 0x80) {
r31 |= 1;
}
#else
// likely fake match, this may use some actual union defined somewhere else
union {
u8 val;
@@ -893,13 +906,13 @@ s32 JASSeqParser::execNoteOnGate(JASTrack* param_0, u32 param_1, u32 param_2, u3
} bits;
} tmp;
tmp.val = param_4;
int r31 = 0;
if (tmp.bits.bit1) {
r31 |= 2;
}
if (tmp.bits.bit0) {
r31 |= 1;
}
#endif
if (param_3 == 0) {
r31 |= 4;
}
@@ -85,7 +85,15 @@ void* JASTaskThread::run() {
JASThreadCallStack* callstack;
OSInitFastCast();
do {
#ifdef TARGET_PC
BOOL received = FALSE;
callstack = static_cast<JASThreadCallStack*>(waitMessageBlock(&received));
if (!received) {
break;
}
#else
callstack = static_cast<JASThreadCallStack*>(waitMessageBlock());
#endif
if (field_0x84) {
OSSleepThread(&threadQueue_);
}
@@ -98,6 +106,9 @@ void* JASTaskThread::run() {
JASKernel::getCommandHeap()->free(callstack);
} while (true);
#ifdef TARGET_PC
return NULL;
#endif
}
void JASTaskThread::pause(bool param_0) {
+6 -1
View File
@@ -15,6 +15,7 @@
#include "aurora/aurora.h"
#include "dusk/gx_helper.h"
#include "dusk/logging.h"
#include "dusk/settings.h"
#include "global.h"
void JFWDisplay::ctor_subroutine(bool enableAlpha) {
@@ -347,7 +348,11 @@ void JFWDisplay::waitBlanking(int param_0) {
}
static void waitForTick(u32 p1, u16 p2) {
#if TARGET_PC
if (dusk::getTransientSettings().skipFrameRateLimit) {
p1 = OS_TIMER_CLOCK / 120;
}
#endif
if (p1 != 0)
{
@@ -79,11 +79,15 @@ void JFWSystem::init() {
JUTGamePad::init();
#ifndef TARGET_PC
JUTDirectPrint* dbPrint = JUTDirectPrint::start();
#endif
JUTAssertion::create();
#ifndef TARGET_PC
JUTException::create(dbPrint);
#endif
systemFont = JKR_NEW JUTResFont(CSetUpParam::systemFontRes, NULL);
+9
View File
@@ -94,7 +94,13 @@ void* JKRAram::run(void) {
OSInitMessageQueue(&sMessageQueue, sMessageBuffer, 4);
do {
OSMessage msg;
#ifdef TARGET_PC
if (!OSReceiveMessage(&sMessageQueue, &msg, OS_MESSAGE_BLOCK)) {
break;
}
#else
OSReceiveMessage(&sMessageQueue, &msg, OS_MESSAGE_BLOCK);
#endif
JKRAramCommand* message = (JKRAramCommand*)msg;
int result = message->field_0x00;
JKRAMCommand* command = (JKRAMCommand*)message->command;
@@ -106,6 +112,9 @@ void* JKRAram::run(void) {
break;
}
} while (true);
#ifdef TARGET_PC
return NULL;
#endif
}
void JKRAram::checkOkAddress(u8* addr, u32 size, JKRAramBlock* block, u32 param_4) {
@@ -43,7 +43,13 @@ void* JKRAramStream::run() {
for (;;) {
OSMessage message;
#ifdef TARGET_PC
if (!OSReceiveMessage(&sMessageQueue, &message, OS_MESSAGE_BLOCK)) {
break;
}
#else
OSReceiveMessage(&sMessageQueue, &message, OS_MESSAGE_BLOCK);
#endif
JKRAramStreamCommand* command = (JKRAramStreamCommand*)message;
switch (command->mType) {
@@ -55,6 +61,9 @@ void* JKRAramStream::run() {
break;
}
}
#ifdef TARGET_PC
return NULL;
#endif
}
s32 JKRAramStream::readFromAram() {
+9
View File
@@ -34,7 +34,13 @@ void* JKRDecomp::run() {
OSInitMessageQueue(&sMessageQueue, sMessageBuffer, 8);
for (;;) {
OSMessage message;
#ifdef TARGET_PC
if (!OSReceiveMessage(&sMessageQueue, &message, OS_MESSAGE_BLOCK)) {
break;
}
#else
OSReceiveMessage(&sMessageQueue, &message, OS_MESSAGE_BLOCK);
#endif
JKRDecompCommand* command = (JKRDecompCommand*)message;
decode(command->mSrcBuffer, command->mDstBuffer, command->mSrcLength, command->mDstLength);
@@ -57,6 +63,9 @@ void* JKRDecomp::run() {
OSSendMessage(&command->mMessageQueue, (OSMessage)1, OS_MESSAGE_NOBLOCK);
}
}
#ifdef TARGET_PC
return NULL;
#endif
}
JKRDecompCommand* JKRDecomp::prepareCommand(u8* srcBuffer, u8* dstBuffer, u32 srcLength,
+11
View File
@@ -309,7 +309,15 @@ void* JKRTask::run() {
};
OSInitFastCast();
while (true) {
#ifdef TARGET_PC
BOOL received = FALSE;
TaskMessage* msg = (TaskMessage*)waitMessageBlock(&received);
if (!received) {
break;
}
#else
TaskMessage* msg = (TaskMessage*)waitMessageBlock();
#endif
if (msg->field_0x0) {
msg->field_0x0(msg->field_0x4);
check();
@@ -319,6 +327,9 @@ void* JKRTask::run() {
}
msg->field_0x0 = NULL;
}
#ifdef TARGET_PC
return NULL;
#endif
}
int JKRTask::check() {
@@ -101,6 +101,9 @@ JUTException* JUTException::create(JUTDirectPrint* directPrint) {
OSMessage JUTException::sMessageBuffer[1] = {0};
void* JUTException::run() {
#ifdef TARGET_PC
return NULL;
#else
u32 msr = PPCMfmsr();
msr &= ~0x0900;
PPCMtmsr(msr);
@@ -132,6 +135,7 @@ void* JUTException::run() {
sErrorManager->mDirectPrint->changeFrameBuffer(mFrameMemory);
sErrorManager->printContext(error, context, r24, r23);
}
#endif
}
void* JUTException::sConsoleBuffer;
@@ -145,6 +149,7 @@ u32 JUTException::msr;
u32 JUTException::fpscr;
void JUTException::errorHandler(OSError error, OSContext* context, u32 param_3, u32 param_4) {
#ifndef TARGET_PC
msr = PPCMfmsr();
fpscr = context->fpscr;
OSFillFPUContext(context);
@@ -165,6 +170,7 @@ void JUTException::errorHandler(OSError error, OSContext* context, u32 param_3,
OSSendMessage(&sMessageQueue, &exCallbackObject, OS_MESSAGE_BLOCK);
OSEnableScheduler();
OSYieldThread();
#endif
}
void JUTException::panic_f_va(char const* file, int line, char const* format, va_list args) {
@@ -234,6 +240,7 @@ void JUTException::showFloatSub(int index, f32 value) {
}
void JUTException::showFloat(OSContext* context) {
#ifndef TARGET_PC
if (!sConsole) {
return;
}
@@ -251,6 +258,7 @@ void JUTException::showFloat(OSContext* context) {
sConsole->print(" ");
showFloatSub(21, context->fpr[21]);
sConsole->print("\n");
#endif
}
bool JUTException::searchPartialModule(u32 address, u32* module_id, u32* section_id,
@@ -333,6 +341,7 @@ void JUTException::showStack(OSContext* context) {
}
void JUTException::showMainInfo(u16 error, OSContext* context, u32 dsisr, u32 dar) {
#ifndef TARGET_PC
if (!sConsole) {
return;
}
@@ -391,9 +400,11 @@ void JUTException::showMainInfo(u16 error, OSContext* context, u32 dsisr, u32 da
}
sConsole->print_f("SRR0: %08XH SRR1:%08XH\n", context->srr0, context->srr1);
sConsole->print_f("DSISR: %08XH DAR: %08XH\n", dsisr, dar);
#endif
}
void JUTException::showGPR(OSContext* context) {
#ifndef TARGET_PC
if (!sConsole) {
return;
}
@@ -404,6 +415,7 @@ void JUTException::showGPR(OSContext* context) {
context->gpr[i + 11], i + 22, context->gpr[i + 22]);
}
sConsole->print_f("R%02d:%08XH R%02d:%08XH\n", 10, context->gpr[10], 21, context->gpr[21]);
#endif
}
bool JUTException::showMapInfo_subroutine(u32 address, bool begin_with_newline) {
@@ -454,6 +466,7 @@ bool JUTException::showMapInfo_subroutine(u32 address, bool begin_with_newline)
}
void JUTException::showGPRMap(OSContext* context) {
#ifndef TARGET_PC
if (!sConsole) {
return;
}
@@ -480,9 +493,11 @@ void JUTException::showGPRMap(OSContext* context) {
if (!found_address_register) {
sConsole->print(" no register which seem to address.\n");
}
#endif
}
void JUTException::showSRR0Map(OSContext* context) {
#ifndef TARGET_PC
if (!sConsole) {
return;
}
@@ -497,6 +512,7 @@ void JUTException::showSRR0Map(OSContext* context) {
}
JUTConsoleManager::getManager()->drawDirect(true);
}
#endif
}
void JUTException::printDebugInfo(JUTException::EInfoPage page, OSError error, OSContext* context,
+2
View File
@@ -81,12 +81,14 @@ void JUTVideo::preRetraceProc(u32 retrace_count) {
static void* frameBuffer = NULL;
#ifndef TARGET_PC
if (frameBuffer) {
const GXRenderModeObj* renderMode = JUTGetVideoManager()->getRenderMode();
u16 width = renderMode->fbWidth;
u16 height = renderMode->efbHeight;
JUTDirectPrint::getManager()->changeFrameBuffer(frameBuffer, width, height);
}
#endif
if (getManager()->mSetBlack == 1) {
s32 frame_count = getManager()->mSetBlackFrameCount;
+9
View File
@@ -0,0 +1,9 @@
cmake_minimum_required(VERSION 3.10)
project(freeverb LANGUAGES CXX)
add_library(freeverb
comb.cpp
allpass.cpp
revmodel.cpp
)
+36
View File
@@ -0,0 +1,36 @@
// Allpass filter implementation
//
// Written by Jezar at Dreampoint, June 2000
// http://www.dreampoint.co.uk
// This code is public domain
#include "allpass.hpp"
allpass::allpass()
{
bufidx = 0;
}
void allpass::setbuffer(float *buf, int size)
{
buffer = buf;
bufsize = size;
}
void allpass::mute()
{
for (int i=0; i<bufsize; i++)
buffer[i]=0;
}
void allpass::setfeedback(float val)
{
feedback = val;
}
float allpass::getfeedback()
{
return feedback;
}
//ends
+48
View File
@@ -0,0 +1,48 @@
// Allpass filter declaration
//
// Written by Jezar at Dreampoint, June 2000
// http://www.dreampoint.co.uk
// This code is public domain
#ifndef _allpass_
#define _allpass_
#include "denormals.h"
class allpass
{
public:
allpass();
void setbuffer(float *buf, int size);
inline float process(float inp);
void mute();
void setfeedback(float val);
float getfeedback();
// private:
float feedback;
float *buffer;
int bufsize;
int bufidx;
};
// Big to inline - but crucial for speed
inline float allpass::process(float input)
{
float output;
float bufout;
bufout = buffer[bufidx];
undenormalise(bufout);
output = -input + bufout;
buffer[bufidx] = input + (bufout*feedback);
if(++bufidx>=bufsize) bufidx = 0;
return output;
}
#endif//_allpass
//ends
+48
View File
@@ -0,0 +1,48 @@
// Comb filter implementation
//
// Written by Jezar at Dreampoint, June 2000
// http://www.dreampoint.co.uk
// This code is public domain
#include "comb.hpp"
comb::comb()
{
filterstore = 0;
bufidx = 0;
}
void comb::setbuffer(float *buf, int size)
{
buffer = buf;
bufsize = size;
}
void comb::mute()
{
for (int i=0; i<bufsize; i++)
buffer[i]=0;
}
void comb::setdamp(float val)
{
damp1 = val;
damp2 = 1-val;
}
float comb::getdamp()
{
return damp1;
}
void comb::setfeedback(float val)
{
feedback = val;
}
float comb::getfeedback()
{
return feedback;
}
// ends
+55
View File
@@ -0,0 +1,55 @@
// Comb filter class declaration
//
// Written by Jezar at Dreampoint, June 2000
// http://www.dreampoint.co.uk
// This code is public domain
#ifndef _comb_
#define _comb_
#include "denormals.h"
class comb
{
public:
comb();
void setbuffer(float *buf, int size);
inline float process(float inp);
void mute();
void setdamp(float val);
float getdamp();
void setfeedback(float val);
float getfeedback();
private:
float feedback;
float filterstore;
float damp1;
float damp2;
float *buffer;
int bufsize;
int bufidx;
};
// Big to inline - but crucial for speed
inline float comb::process(float input)
{
float output;
output = buffer[bufidx];
undenormalise(output);
filterstore = (output*damp2) + (filterstore*damp1);
undenormalise(filterstore);
buffer[bufidx] = input + (filterstore*feedback);
if(++bufidx>=bufsize) bufidx = 0;
return output;
}
#endif //_comb_
//ends
+15
View File
@@ -0,0 +1,15 @@
// Macro for killing denormalled numbers
//
// Written by Jezar at Dreampoint, June 2000
// http://www.dreampoint.co.uk
// Based on IS_DENORMAL macro by Jon Watte
// This code is public domain
#ifndef _denormals_
#define _denormals_
#define undenormalise(sample) if(((*(unsigned int*)&sample)&0x7f800000)==0) sample=0.0f
#endif//_denormals_
//ends
+252
View File
@@ -0,0 +1,252 @@
// Reverb model implementation
//
// Written by Jezar at Dreampoint, June 2000
// http://www.dreampoint.co.uk
// This code is public domain
#include "revmodel.hpp"
revmodel::revmodel()
{
// Tie the components to their buffers
combL[0].setbuffer(bufcombL1,combtuningL1);
combR[0].setbuffer(bufcombR1,combtuningR1);
combL[1].setbuffer(bufcombL2,combtuningL2);
combR[1].setbuffer(bufcombR2,combtuningR2);
combL[2].setbuffer(bufcombL3,combtuningL3);
combR[2].setbuffer(bufcombR3,combtuningR3);
combL[3].setbuffer(bufcombL4,combtuningL4);
combR[3].setbuffer(bufcombR4,combtuningR4);
combL[4].setbuffer(bufcombL5,combtuningL5);
combR[4].setbuffer(bufcombR5,combtuningR5);
combL[5].setbuffer(bufcombL6,combtuningL6);
combR[5].setbuffer(bufcombR6,combtuningR6);
combL[6].setbuffer(bufcombL7,combtuningL7);
combR[6].setbuffer(bufcombR7,combtuningR7);
combL[7].setbuffer(bufcombL8,combtuningL8);
combR[7].setbuffer(bufcombR8,combtuningR8);
allpassL[0].setbuffer(bufallpassL1,allpasstuningL1);
allpassR[0].setbuffer(bufallpassR1,allpasstuningR1);
allpassL[1].setbuffer(bufallpassL2,allpasstuningL2);
allpassR[1].setbuffer(bufallpassR2,allpasstuningR2);
allpassL[2].setbuffer(bufallpassL3,allpasstuningL3);
allpassR[2].setbuffer(bufallpassR3,allpasstuningR3);
allpassL[3].setbuffer(bufallpassL4,allpasstuningL4);
allpassR[3].setbuffer(bufallpassR4,allpasstuningR4);
// Set default values
allpassL[0].setfeedback(0.5f);
allpassR[0].setfeedback(0.5f);
allpassL[1].setfeedback(0.5f);
allpassR[1].setfeedback(0.5f);
allpassL[2].setfeedback(0.5f);
allpassR[2].setfeedback(0.5f);
allpassL[3].setfeedback(0.5f);
allpassR[3].setfeedback(0.5f);
setwet(initialwet);
setroomsize(initialroom);
setdry(initialdry);
setdamp(initialdamp);
setwidth(initialwidth);
setmode(initialmode);
// Buffer will be full of rubbish - so we MUST mute them
mute();
}
void revmodel::mute()
{
if (getmode() >= freezemode)
return;
for (int i=0;i<numcombs;i++)
{
combL[i].mute();
combR[i].mute();
}
for (int i=0;i<numallpasses;i++)
{
allpassL[i].mute();
allpassR[i].mute();
}
}
void revmodel::processreplace(float *inputL, float *inputR, float *outputL, float *outputR, long numsamples, int skip)
{
float outL,outR,input;
while(numsamples-- > 0)
{
outL = outR = 0;
input = (*inputL + *inputR) * gain;
// Accumulate comb filters in parallel
for(int i=0; i<numcombs; i++)
{
outL += combL[i].process(input);
outR += combR[i].process(input);
}
// Feed through allpasses in series
for(int i=0; i<numallpasses; i++)
{
outL = allpassL[i].process(outL);
outR = allpassR[i].process(outR);
}
// Calculate output REPLACING anything already there
*outputL = outL*wet1 + outR*wet2 + *inputL*dry;
*outputR = outR*wet1 + outL*wet2 + *inputR*dry;
// Increment sample pointers, allowing for interleave (if any)
inputL += skip;
inputR += skip;
outputL += skip;
outputR += skip;
}
}
void revmodel::processmix(float *inputL, float *inputR, float *outputL, float *outputR, long numsamples, int skip)
{
float outL,outR,input;
while(numsamples-- > 0)
{
outL = outR = 0;
input = (*inputL + *inputR) * gain;
// Accumulate comb filters in parallel
for(int i=0; i<numcombs; i++)
{
outL += combL[i].process(input);
outR += combR[i].process(input);
}
// Feed through allpasses in series
for(int i=0; i<numallpasses; i++)
{
outL = allpassL[i].process(outL);
outR = allpassR[i].process(outR);
}
// Calculate output MIXING with anything already there
*outputL += outL*wet1 + outR*wet2 + *inputL*dry;
*outputR += outR*wet1 + outL*wet2 + *inputR*dry;
// Increment sample pointers, allowing for interleave (if any)
inputL += skip;
inputR += skip;
outputL += skip;
outputR += skip;
}
}
void revmodel::update()
{
// Recalculate internal values after parameter change
int i;
wet1 = wet*(width/2 + 0.5f);
wet2 = wet*((1-width)/2);
if (mode >= freezemode)
{
roomsize1 = 1;
damp1 = 0;
gain = muted;
}
else
{
roomsize1 = roomsize;
damp1 = damp;
gain = fixedgain;
}
for(i=0; i<numcombs; i++)
{
combL[i].setfeedback(roomsize1);
combR[i].setfeedback(roomsize1);
}
for(i=0; i<numcombs; i++)
{
combL[i].setdamp(damp1);
combR[i].setdamp(damp1);
}
}
// The following get/set functions are not inlined, because
// speed is never an issue when calling them, and also
// because as you develop the reverb model, you may
// wish to take dynamic action when they are called.
void revmodel::setroomsize(float value)
{
roomsize = (value*scaleroom) + offsetroom;
update();
}
float revmodel::getroomsize()
{
return (roomsize-offsetroom)/scaleroom;
}
void revmodel::setdamp(float value)
{
damp = value*scaledamp;
update();
}
float revmodel::getdamp()
{
return damp/scaledamp;
}
void revmodel::setwet(float value)
{
wet = value*scalewet;
update();
}
float revmodel::getwet()
{
return wet/scalewet;
}
void revmodel::setdry(float value)
{
dry = value*scaledry;
}
float revmodel::getdry()
{
return dry/scaledry;
}
void revmodel::setwidth(float value)
{
width = value;
update();
}
float revmodel::getwidth()
{
return width;
}
void revmodel::setmode(float value)
{
mode = value;
update();
}
float revmodel::getmode()
{
if (mode >= freezemode)
return 1;
else
return 0;
}
//ends
+87
View File
@@ -0,0 +1,87 @@
// Reverb model declaration
//
// Written by Jezar at Dreampoint, June 2000
// http://www.dreampoint.co.uk
// This code is public domain
#ifndef _revmodel_
#define _revmodel_
#include "comb.hpp"
#include "allpass.hpp"
#include "tuning.h"
class revmodel
{
public:
revmodel();
void mute();
void processmix(float *inputL, float *inputR, float *outputL, float *outputR, long numsamples, int skip);
void processreplace(float *inputL, float *inputR, float *outputL, float *outputR, long numsamples, int skip);
void setroomsize(float value);
float getroomsize();
void setdamp(float value);
float getdamp();
void setwet(float value);
float getwet();
void setdry(float value);
float getdry();
void setwidth(float value);
float getwidth();
void setmode(float value);
float getmode();
private:
void update();
private:
float gain;
float roomsize,roomsize1;
float damp,damp1;
float wet,wet1,wet2;
float dry;
float width;
float mode;
// The following are all declared inline
// to remove the need for dynamic allocation
// with its subsequent error-checking messiness
// Comb filters
comb combL[numcombs];
comb combR[numcombs];
// Allpass filters
allpass allpassL[numallpasses];
allpass allpassR[numallpasses];
// Buffers for the combs
float bufcombL1[combtuningL1];
float bufcombR1[combtuningR1];
float bufcombL2[combtuningL2];
float bufcombR2[combtuningR2];
float bufcombL3[combtuningL3];
float bufcombR3[combtuningR3];
float bufcombL4[combtuningL4];
float bufcombR4[combtuningR4];
float bufcombL5[combtuningL5];
float bufcombR5[combtuningR5];
float bufcombL6[combtuningL6];
float bufcombR6[combtuningR6];
float bufcombL7[combtuningL7];
float bufcombR7[combtuningR7];
float bufcombL8[combtuningL8];
float bufcombR8[combtuningR8];
// Buffers for the allpasses
float bufallpassL1[allpasstuningL1];
float bufallpassR1[allpasstuningR1];
float bufallpassL2[allpasstuningL2];
float bufallpassR2[allpasstuningR2];
float bufallpassL3[allpasstuningL3];
float bufallpassR3[allpasstuningR3];
float bufallpassL4[allpasstuningL4];
float bufallpassR4[allpasstuningR4];
};
#endif//_revmodel_
//ends
+60
View File
@@ -0,0 +1,60 @@
// Reverb model tuning values
//
// Written by Jezar at Dreampoint, June 2000
// http://www.dreampoint.co.uk
// This code is public domain
#ifndef _tuning_
#define _tuning_
const int numcombs = 8;
const int numallpasses = 4;
const float muted = 0;
const float fixedgain = 0.015f;
const float scalewet = 3;
const float scaledry = 2;
const float scaledamp = 0.4f;
const float scaleroom = 0.28f;
const float offsetroom = 0.7f;
const float initialroom = 0.5f;
const float initialdamp = 0.5f;
const float initialwet = 1/scalewet;
const float initialdry = 0;
const float initialwidth = 1;
const float initialmode = 0;
const float freezemode = 0.5f;
const int stereospread = 23;
// These values assume 44.1KHz sample rate
// they will probably be OK for 48KHz sample rate
// but would need scaling for 96KHz (or other) sample rates.
// The values were obtained by listening tests.
const int combtuningL1 = 1116;
const int combtuningR1 = 1116+stereospread;
const int combtuningL2 = 1188;
const int combtuningR2 = 1188+stereospread;
const int combtuningL3 = 1277;
const int combtuningR3 = 1277+stereospread;
const int combtuningL4 = 1356;
const int combtuningR4 = 1356+stereospread;
const int combtuningL5 = 1422;
const int combtuningR5 = 1422+stereospread;
const int combtuningL6 = 1491;
const int combtuningR6 = 1491+stereospread;
const int combtuningL7 = 1557;
const int combtuningR7 = 1557+stereospread;
const int combtuningL8 = 1617;
const int combtuningR8 = 1617+stereospread;
const int allpasstuningL1 = 556;
const int allpasstuningR1 = 556+stereospread;
const int allpasstuningL2 = 441;
const int allpasstuningR2 = 441+stereospread;
const int allpasstuningL3 = 341;
const int allpasstuningR3 = 341+stereospread;
const int allpasstuningL4 = 225;
const int allpasstuningR4 = 225+stereospread;
#endif//_tuning_
//ends
Binary file not shown.
+1 -1
View File
@@ -802,7 +802,7 @@ f32 Z2Audience::calcFxMix_(f32 param_0, int distVolBit) const {
f32 Z2Audience::calcPitch_(Z2AudibleChannel* channel, const Z2Audible* audible, const Z2AudioCamera* camera) const {
JAUAudibleParam audParam = *audible->getAudibleParam();
if ((*(u8*)&audParam.field_0x0.raw >> 4) & 0xf) {
if (audParam.field_0x0.bytes.b0_0) {
JGeometry::TVec3<f32> aTStack_4c;
aTStack_4c.normalize(channel->field_0x14.field_0x00);
JAUAudibleParam audParam = *audible->getAudibleParam();
+7
View File
@@ -155,7 +155,14 @@ void Z2AudioMgr::zeldaGFrameWork() {
mSpeechMgr.framework();
processSeFramework();
processBgmFramework();
#if TARGET_PC
if (!dusk::getSettings().game.noLowHpSound) {
processHeartGaugeSound();
}
#else
processHeartGaugeSound();
#endif
#if DEBUG
mDebugSys.debugframework();
+9
View File
@@ -107,6 +107,15 @@ static Z2EnemyInfo mEnemyInfo[64] = {
void Z2SoundObjMgr::searchEnemy() {
twilightBattle_ = 0;
#if TARGET_PC
if (Z2GetSeqMgr()->checkBgmIDPlaying(Z2BGM_MIDNA_SOS) &&
dusk::getSettings().game.midnasLamentNonStop)
{
Z2GetSeqMgr()->changeSubBgmStatus(0);
return;
}
#endif
if (!Z2GetLink()) {
Z2GetSeqMgr()->stopBattleBgm(1, 1);
return;
+3 -7
View File
@@ -54,10 +54,6 @@
#include "res/Object/Alink.h"
#include <cstring>
#if TARGET_PC
bool dusk::tweaks::FastIronBoots = false;
#endif
static int daAlink_Create(fopAc_ac_c* i_this);
static int daAlink_Delete(daAlink_c* i_this);
static int daAlink_Execute(daAlink_c* i_this);
@@ -7514,7 +7510,7 @@ void daAlink_c::setBlendMoveAnime(f32 i_morf) {
BOOL sp24 = checkEventRun();
BOOL sp20 = checkBootsMoveAnime(1);
#if TARGET_PC
if (dusk::tweaks::FastIronBoots) {
if (dusk::getSettings().game.enableFastIronBoots) {
sp20 = FALSE;
}
#endif
@@ -9479,7 +9475,7 @@ void daAlink_c::setStickData() {
mHeavySpeedMultiplier = mpHIO->mItem.mIronBoots.m.mInputFactor;
}
#if TARGET_PC
if (dusk::tweaks::FastIronBoots) {
if (dusk::getSettings().game.enableFastIronBoots) {
mHeavySpeedMultiplier = 1.0f;
}
#endif
@@ -9491,7 +9487,7 @@ void daAlink_c::setStickData() {
mHeavySpeedMultiplier = mpHIO->mItem.mIronBoots.m.mWaterInputFactor;
}
#if TARGET_PC
if (dusk::tweaks::FastIronBoots) {
if (dusk::getSettings().game.enableFastIronBoots) {
mHeavySpeedMultiplier = 1.0f;
}
#endif
+8
View File
@@ -7,6 +7,8 @@
#include "d/actor/d_a_b_gnd.h"
#include "SSystem/SComponent/c_math.h"
#include "dusk/settings.h"
enum daAlink_CutNmParamType {
CUT_NM_PARAM_VERTICAL,
CUT_NM_PARAM_LEFT,
@@ -369,6 +371,12 @@ BOOL daAlink_c::changeCutReverseProc(daAlink_c::daAlink_ANM i_anmID) {
return procCutReverseInit(i_anmID);
}
#if TARGET_PC
if (dusk::getSettings().game.noSwordRecoil) {
return FALSE;
}
#endif
if (checkNoResetFlg0(FLG0_CUT_AT_FLG) || mEquipItem == dItemNo_COPY_ROD_e) {
cXyz sp28;
Vec sp1C;
+7
View File
@@ -152,6 +152,13 @@ f32 daAlink_c::damageMagnification(BOOL i_checkZoraMag, int param_1) {
base_mag = 1.0f;
}
#if TARGET_PC
base_mag *= dusk::getSettings().game.damageMultiplier;
if (dusk::getSettings().game.instantDeath) {
base_mag = 9999.0f;
}
#endif
if (checkWolf() && !checkCargoCarry() && param_1 == 0) {
return 2.0f * base_mag;
}
+15 -3
View File
@@ -23,6 +23,8 @@
#include "d/actor/d_a_npc_tkc.h"
#include <cstring>
#include "dusk/settings.h"
BOOL daAlink_c::checkEventRun() const {
return dComIfGp_event_runCheck() || checkPlayerDemoMode();
}
@@ -2230,6 +2232,12 @@ void daAlink_c::setGetSubBgm(int i_itemNo) {
}
BOOL daAlink_c::checkTreasureRupeeReturn(int i_itemNo) const {
#if TARGET_PC
if (dusk::getSettings().game.noReturnRupees) {
return FALSE;
}
#endif
static const int dummy = 0;
if (i_itemNo == dItemNo_LINKS_SAVINGS_e) {
@@ -4290,7 +4298,7 @@ static fopAc_ac_c* daAlink_searchPortal(fopAc_ac_c* i_actor, void* i_data) {
}
bool daAlink_c::checkAcceptWarp() {
#if VERSION != VERSION_WII_USA_R0
#if TARGET_PC || VERSION != VERSION_WII_USA_R0
cM3dGPla plane;
#endif
@@ -4298,7 +4306,9 @@ bool daAlink_c::checkAcceptWarp() {
* Fixed in versions above Wii USA Rev 0 by checking FLG0_WATER_IN_MOVE
*/
if (mLinkAcch.ChkGroundHit() && !checkModeFlg(MODE_PLAYER_FLY)
#if VERSION != VERSION_WII_USA_R0
#if TARGET_PC
&& (dusk::getSettings().game.restoreWiiGlitches || !checkNoResetFlg0(FLG0_WATER_IN_MOVE))
#elif VERSION != VERSION_WII_USA_R0
&& !checkNoResetFlg0(FLG0_WATER_IN_MOVE)
#endif
)
@@ -4307,7 +4317,9 @@ bool daAlink_c::checkAcceptWarp() {
* Fixed in versions above Wii USA Rev 0 by checking getSlidePolygon
*/
if (
#if VERSION != VERSION_WII_USA_R0
#if TARGET_PC
(dusk::getSettings().game.restoreWiiGlitches || !getSlidePolygon(&plane)) &&
#elif VERSION != VERSION_WII_USA_R0
!getSlidePolygon(&plane) &&
#endif
!checkForestOldCentury()
+78
View File
@@ -0,0 +1,78 @@
#include "d/actor/d_a_alink.h"
#include "d/actor/d_a_midna.h"
#include "d/d_meter2.h"
#include "d/d_meter2_draw.h"
#include "d/d_meter2_info.h"
void daAlink_c::handleQuickTransform() {
if (!dusk::getSettings().game.enableQuickTransform) {
return;
}
// Ensure that link is not in a cutscene.
if (checkEventRun()) {
return;
}
// Check to see if Link has the ability to transform.
if (!dComIfGs_isEventBit(dSv_event_flag_c::M_077)) {
return;
}
// Ensure there is a proper pointer to the mMeterClass and mpMeterDraw structs in g_meter2_info.
const auto meterClassPtr = g_meter2_info.getMeterClass();
if (!meterClassPtr) {
return;
}
const auto meterDrawPtr = meterClassPtr->getMeterDrawPtr();
if (!meterDrawPtr) {
return;
}
mDoCPd_c::getCpadInfo(PAD_1).mPressedButtonFlags = 0;
// Ensure that the Z Button is not dimmed
if (meterDrawPtr->getButtonZAlpha() != 1.f) {
Z2GetAudioMgr()->seStart(Z2SE_SYS_ERROR, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0);
return;
}
// The game will crash if trying to quick transform while holding the Ball and Chain
if (mEquipItem == dItemNo_IRONBALL_e) {
Z2GetAudioMgr()->seStart(Z2SE_SYS_ERROR, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0);
return;
}
// Use the game's default checks for if the player can currently transform
if (!m_midnaActor->checkMetamorphoseEnableBase()) {
Z2GetAudioMgr()->seStart(Z2SE_SYS_ERROR, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0);
return;
}
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 (!canTransform)
{
Z2GetAudioMgr()->seStart(Z2SE_SYS_ERROR, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0);
return;
}
OSReport("Running quick transform!");
procCoMetamorphoseInit();
}
+5
View File
@@ -1562,6 +1562,11 @@ void daAlink_c::setMetamorphoseEffectStartLink() {
emitter->setGlobalParticleScale(effScale);
}
#endif
#if TARGET_PC
static const Vec effWideScale = {mDoGph_gInf_c::getAspect(), 1.0f, 1.0f};
emitter->setGlobalParticleScale(effWideScale);
#endif
}
void daAlink_c::setMetamorphoseEffect() {
+69 -11
View File
@@ -13,8 +13,15 @@
#include "d/actor/d_a_obj_swhang.h"
f32 daAlink_c::getHangMoveAnmSpeed() {
#if TARGET_PC
return getAnmSpeedStickRate(
dusk::getSettings().game.fastClimbing ? 2.0f : mpHIO->mWallHang.mWallMove.m.mMinAnmSpeed,
dusk::getSettings().game.fastClimbing ? 2.0f : mpHIO->mWallHang.mWallMove.m.mMaxAnmSpeed
);
#else
return getAnmSpeedStickRate(mpHIO->mWallHang.mWallMove.m.mMinAnmSpeed,
mpHIO->mWallHang.mWallMove.m.mMaxAnmSpeed);
#endif
}
int daAlink_c::getHangDirectionFromAngle() {
@@ -278,7 +285,11 @@ int daAlink_c::procHangStartInit() {
offNoResetFlg2(FLG2_UNK_2000);
if (checkHangFootWall()) {
#if TARGET_PC
if (!is_prev_hangReady && cM_rnd() < 0.7f && !dusk::getSettings().game.noMissClimbing) {
#else
if (!is_prev_hangReady && cM_rnd() < 0.7f) {
#endif
setSingleAnimeParam(ANM_CLIMB_HANG_MISS, &mpHIO->mLadder.m.mWallAttachMissAnm);
field_0x3478 = mpHIO->mLadder.m.mWallAttachMissAnm.mCancelFrame;
voiceStart(Z2SE_AL_V_FOOT_MISS);
@@ -1209,7 +1220,12 @@ void daAlink_c::setLadderPos(int param_0) {
f32 daAlink_c::getLadderMoveAnmSpeed() {
return getAnmSpeedStickRate(mpHIO->mLadder.m.mMoveMinASpeed,
mpHIO->mLadder.m.mMoveMaxSpeed);
#if TARGET_PC
dusk::getSettings().game.fastClimbing ? 1.575f : mpHIO->mLadder.m.mMoveMaxSpeed
#else
mpHIO->mLadder.m.mMoveMaxSpeed
#endif
);
}
int daAlink_c::changeLadderMoveProc(int param_0) {
@@ -1304,8 +1320,14 @@ int daAlink_c::procLadderUpStartInit() {
mNormalSpeed = 0.0f;
speedF = 0.0f;
setSingleAnimeBaseSpeed(ANM_LADDER_UP_START, mpHIO->mLadder.m.mClimbUpStartASpeed,
mpHIO->mLadder.m.mClimbUpStartInterp);
setSingleAnimeBaseSpeed(ANM_LADDER_UP_START,
#if TARGET_PC
dusk::getSettings().game.fastClimbing ? 1.8f : mpHIO->mLadder.m.mClimbUpStartASpeed,
#else
mpHIO->mLadder.m.mClimbUpStartASpeed,
#endif
mpHIO->mLadder.m.mClimbUpStartInterp);
field_0x2f99 = 0x10;
field_0x3588 = l_waitBaseAnime;
dComIfGp_setPlayerStatus0(0, 0x2000000);
@@ -1354,8 +1376,14 @@ int daAlink_c::procLadderUpEndInit(BOOL param_0) {
anm_id = ANM_LADDER_UP_END_RIGHT;
}
setSingleAnimeBaseSpeed(anm_id, mpHIO->mLadder.m.mClimbUpEndASpeed,
mpHIO->mLadder.m.mClimbUpEndInterp);
setSingleAnimeBaseSpeed(anm_id,
#if TARGET_PC
dusk::getSettings().game.fastClimbing ? 1.765f : mpHIO->mLadder.m.mClimbUpEndASpeed,
#else
mpHIO->mLadder.m.mClimbUpEndASpeed,
#endif
mpHIO->mLadder.m.mClimbUpEndInterp);
field_0x2f99 = 14;
setSpecialGravity(0.0f, maxFallSpeed, 0);
@@ -1413,8 +1441,14 @@ int daAlink_c::procLadderDownStartInit() {
shape_angle.y = field_0x306e + 0x8000;
current.angle.y = field_0x306e;
setSingleAnimeBaseSpeed(ANM_LADDER_DOWN_START, mpHIO->mLadder.m.mClimbDownStartASpeed,
mpHIO->mLadder.m.mClimbDownStartInterp);
setSingleAnimeBaseSpeed(ANM_LADDER_DOWN_START,
#if TARGET_PC
dusk::getSettings().game.fastClimbing ? 1.8f : mpHIO->mLadder.m.mClimbDownStartASpeed,
#else
mpHIO->mLadder.m.mClimbDownStartASpeed,
#endif
mpHIO->mLadder.m.mClimbDownStartInterp);
field_0x2f99 = 0x10;
field_0x3588 = l_waitBaseAnime;
dComIfGp_setPlayerStatus0(0, 0x2000000);
@@ -1469,8 +1503,14 @@ int daAlink_c::procLadderDownEndInit(BOOL param_0) {
anm_id = ANM_LADDER_DOWN_END_RIGHT;
}
setSingleAnimeBaseSpeed(anm_id, mpHIO->mLadder.m.mClimbDownEndASpeed,
mpHIO->mLadder.m.mClimbDownEndInterp);
setSingleAnimeBaseSpeed(anm_id,
#if TARGET_PC
dusk::getSettings().game.fastClimbing ? 1.8f : mpHIO->mLadder.m.mClimbDownEndASpeed,
#else
mpHIO->mLadder.m.mClimbDownEndASpeed,
#endif
mpHIO->mLadder.m.mClimbDownEndInterp);
field_0x2f99 = 14;
setSpecialGravity(0.0f, maxFallSpeed, 0);
@@ -1602,12 +1642,22 @@ int daAlink_c::procLadderMove() {
f32 daAlink_c::getClimbMoveUpDownAnmSpeed() {
return getAnmSpeedStickRate(mpHIO->mLadder.m.mWallVerticalMinAnmSpeed,
mpHIO->mLadder.m.mWallVerticalMaxAnmSpeed);
#if TARGET_PC
dusk::getSettings().game.fastClimbing ? 1.875f : mpHIO->mLadder.m.mWallVerticalMaxAnmSpeed
#else
mpHIO->mLadder.m.mWallVerticalMaxAnmSpeed
#endif
);
}
f32 daAlink_c::getClimbMoveSideAnmSpeed() {
return getAnmSpeedStickRate(mpHIO->mLadder.m.mWallHorizontalMinAnmSpeed,
mpHIO->mLadder.m.mWallHorizontalMaxAnmSpeed);
#if TARGET_PC
dusk::getSettings().game.fastClimbing ? 2.0f : mpHIO->mLadder.m.mWallHorizontalMaxAnmSpeed
#else
mpHIO->mLadder.m.mWallHorizontalMaxAnmSpeed
#endif
);
}
BOOL daAlink_c::checkClimbCode(cBgS_PolyInfo& i_polyinfo) {
@@ -2038,7 +2088,11 @@ int daAlink_c::procClimbUpStartInit(int param_0) {
speed.y = 0.0f;
mNormalSpeed = 0.0f;
#if TARGET_PC
if (param_0 || var_r29 || cM_rnd() < 0.3f || dusk::getSettings().game.noMissClimbing) {
#else
if (param_0 || var_r29 || cM_rnd() < 0.3f) {
#endif
setSingleAnimeParam(ANM_CLIMB_HANG, &mpHIO->mLadder.m.mWallAttachAnm);
field_0x3478 = mpHIO->mLadder.m.mWallAttachAnm.mCancelFrame;
voiceStart(Z2SE_AL_V_JUMP_HANG);
@@ -2115,7 +2169,11 @@ int daAlink_c::procClimbDownStartInit(s16 param_0) {
deleteEquipItem(TRUE, FALSE);
#if TARGET_PC
if (cM_rnd() < 0.7f || dusk::getSettings().game.noMissClimbing) {
#else
if (cM_rnd() < 0.7f) {
#endif
setSingleAnimeParam(ANM_CLIMB_HANG, &mpHIO->mLadder.m.mWallAttachAnm);
field_0x3478 = mpHIO->mLadder.m.mWallAttachAnm.mCancelFrame;
mProcVar0.field_0x3008 = 0;
+3 -1
View File
@@ -348,7 +348,9 @@ int daAlink_c::procMagneBootsFly() {
* Fixed in GCN and Wii KOR versions by adding a checkEquipHeavyBoots check
*/
if (dComIfG_Bgsp().ChkPolySafe(mPolyInfo2)
#if PLATFORM_GCN || VERSION == VERSION_WII_KOR
#if TARGET_PC
&& (dusk::getSettings().game.restoreWiiGlitches || checkEquipHeavyBoots())
#elif PLATFORM_GCN || VERSION == VERSION_WII_KOR
&& checkEquipHeavyBoots()
#endif
)
+5
View File
@@ -180,7 +180,12 @@ void daAlink_c::preKandelaarDraw() {
mat_p->setTevColor(2, &color);
cXyz proj;
#if TARGET_PC
mDoLib_project(&mKandelaarFlamePos, &proj, {0, 0, FB_WIDTH, FB_HEIGHT});
#else
mDoLib_project(&mKandelaarFlamePos, &proj);
#endif
camera_process_class* camera_p = dComIfGp_getCamera(0);
f32 trimHeight;
+3
View File
@@ -40,6 +40,9 @@ void daAlink_c::setOriginalHeap(JKRExpHeap** i_ppheap, u32 i_size) {
u32 var_r29 = 0x90;
u32 var_r28 = 0x10;
u32 size = ROUND(i_size, 16);
#if TARGET_PC
size *= 2;
#endif
JKRHeap* parent = mDoExt_getGameHeap();
JKRExpHeap* heap = JKRExpHeap::create(size + (var_r29 + var_r28), parent, true);
+4
View File
@@ -304,7 +304,11 @@ void daBalloon2D_c::addScoreCount(cXyz* param_1, u32 param_2, u8 param_3) {
field_0x5f8[current].field_0xf = field_0x5f8[prev].field_0xf;
}
cXyz acStack_2c;
#if TARGET_PC
mDoLib_project(param_1, &acStack_2c, { 0, 0, FB_WIDTH, FB_HEIGHT });
#else
mDoLib_project(param_1, &acStack_2c);
#endif
field_0x5f8[0].field_0x0.set(acStack_2c);
field_0x5f8[0].field_0xc = param_2;
field_0x5f8[0].field_0xe = 60;
+11
View File
@@ -1096,8 +1096,14 @@ inline int daDemo00_c::execute() {
case 2: {
u16 sp0A = sp0E & 0x3FFF;
if ((sp0E & 0xC000) == 0) {
#if !MOVIE_SUPPORT
// If movie support isn't available, automatically reset.
// TPHD-esque. Maybe not the best solution, but it works.
dComIfGp_event_reset();
#else
fopAcM_create(fpcNm_MOVIE_PLAYER_e, sp0A, NULL, fopAcM_GetRoomNo(this), NULL, NULL, 0xFF);
mDoGph_gInf_c::fadeOut(1.0f);
#endif
} else {
switch (sp0A) {
case 0:
@@ -1652,7 +1658,12 @@ int daDemo00_c::draw() {
MTXCopy(mModel.field_0x5d4->getAnmMtx(0), mDoMtx_stack_c::get());
spb0.set(0.0f, 0.0f, 0.0f);
mDoMtx_stack_c::multVec(&spb0, &sp98);
#if TARGET_PC
mDoLib_project(&sp98, &spa4, {0, 0, FB_WIDTH, FB_HEIGHT});
#else
mDoLib_project(&sp98, &spa4);
#endif
if (spa4.x >= -700.0f && spa4.x < 1600.0f && spa4.y >= -200.0f && spa4.y < 600.0f) {
if (mModel.mID.field_0x18 == 0 || mModel.mID.field_0x18 == 1) {
+6
View File
@@ -429,7 +429,13 @@ void daE_FK_c::DamageAction() {
bool daE_FK_c::checkViewArea() {
Vec proj;
#if TARGET_PC
mDoLib_project(&current.pos, &proj, {0, 0, FB_WIDTH, FB_HEIGHT});
#else
mDoLib_project(&current.pos, &proj);
#endif
return (proj.x >= 0.0f && proj.x <= FB_WIDTH) && (proj.y >= 0.0f && proj.y <= FB_HEIGHT);
}
+6
View File
@@ -463,7 +463,13 @@ static void damage_check(e_fs_class* i_this) {
static bool checkViewArea(cXyz* i_pos) {
Vec proj;
#if TARGET_PC
mDoLib_project(i_pos, &proj, {0, 0, FB_WIDTH, FB_HEIGHT});
#else
mDoLib_project(i_pos, &proj);
#endif
bool ret = false;
if (proj.x >= 0.0f && proj.x <= FB_WIDTH && proj.y >= 0.0f && proj.y <= FB_HEIGHT) {
ret = true;
+6
View File
@@ -1362,7 +1362,13 @@ void daE_SM_c::E_SM_C_Hook() {
bool daE_SM_c::CheckViewArea() {
Vec vec;
#if TARGET_PC
mDoLib_project(&current.pos, &vec, {0, 0, FB_WIDTH, FB_HEIGHT});
#else
mDoLib_project(&current.pos, &vec);
#endif
bool rv = false;
if (vec.x >= 0.0f && vec.x <= FB_WIDTH && vec.y >= 0.0f && vec.y <= FB_HEIGHT) {
+16 -1
View File
@@ -16,6 +16,8 @@
#include "f_op/f_op_camera_mng.h"
#include <cstring>
#include "dusk/settings.h"
class daE_YM_HIO_c: public JORReflexible {
public:
daE_YM_HIO_c();
@@ -1066,7 +1068,11 @@ void daE_YM_c::executeDown() {
}
if (mAcch.ChkGroundHit()) {
if (mFlyType != 1) {
#if TARGET_PC
bckSet(6, 0, 0.0f, dusk::getSettings().game.fastTears && dComIfGp_event_getMode() == 0 ? 2.0f : 1.0f);
#else
bckSet(6, 0, 0.0f, 1.0f);
#endif
}
if (mMode == 1) {
mSound.startCreatureSound(Z2SE_EN_YM_LAND, 0, -1);
@@ -1086,7 +1092,11 @@ void daE_YM_c::executeDown() {
if (current.pos.y < gnd_cross) {
mSound.startCreatureSound(Z2SE_CM_BODYFALL_WATER_M, 0, -1);
mSound.startCreatureSound(Z2SE_EN_YM_MOGAKU, 0, -1);
#if TARGET_PC
bckSet(6, 0, 0.0f, dusk::getSettings().game.fastTears && dComIfGp_event_getMode() == 0 ? 2.0f : 1.0f);
#else
bckSet(6, 0, 0.0f, 1.0f);
#endif
speedF = 0.0f;
speed.y = gravity = 0.0f;
current.pos.y = gnd_cross;
@@ -1102,8 +1112,13 @@ void daE_YM_c::executeDown() {
f32 gnd_cross_2 = dComIfG_Bgsp().GroundCross(&gnd_chk);
if (gnd_cross_2 == -G_CM3D_F_INF || std::abs(gnd_cross_2 - current.pos.y) > 1000.0f
|| dComIfG_Bgsp().GetGroundCode(gnd_chk) == 4 || dComIfG_Bgsp().GetGroundCode(gnd_chk) == 10
|| dComIfG_Bgsp().GetGroundCode(gnd_chk) == 5) {
|| dComIfG_Bgsp().GetGroundCode(gnd_chk) == 5)
{
#if TARGET_PC
bckSet(6, 0, 0.0f, dusk::getSettings().game.fastTears && dComIfGp_event_getMode() == 0 ? 2.0f : 1.0f);
#else
bckSet(6, 0, 0.0f, 1.0f);
#endif
mMode = 3;
speedF = 0.0f;
shape_angle.x = -0x8000;
+8 -3
View File
@@ -3046,12 +3046,17 @@ void daMidna_c::setMidnaNoDrawFlg() {
BOOL daMidna_c::checkMetamorphoseEnableBase() {
BOOL tmp;
if (
!daAlink_getAlinkActorClass()->checkMidnaRide() || (g_env_light.mEvilInitialized & 0x80) ||
if (!daAlink_getAlinkActorClass()->checkMidnaRide() || (g_env_light.mEvilInitialized & 0x80) ||
/* dSv_event_flag_c::M_077 - Main Event - Get shadow crystal (can now transform) */
!dComIfGs_isEventBit(0xD04) ||
#if TARGET_PC
(fopAcIt_Judge((fopAcIt_JudgeFunc)daMidna_searchNpc, &tmp) &&
!dusk::getSettings().game.canTransformAnywhere)
#else
fopAcIt_Judge((fopAcIt_JudgeFunc)daMidna_searchNpc, &tmp)
) {
#endif
)
{
return FALSE;
}
return TRUE;
+381 -24
View File
@@ -14,21 +14,41 @@
#pragma optimization_level 4
#pragma optimize_for_size off
#include "JSystem/JKernel/JKRExpHeap.h"
#include <cstring>
#include <span>
#include "JSystem/JAudio2/JASAiCtrl.h"
#include "JSystem/JAudio2/JASDriverIF.h"
#include "d/actor/d_a_movie_player.h"
#include "JSystem/JKernel/JKRExpHeap.h"
#include "Z2AudioLib/Z2Instances.h"
#include "d/actor/d_a_movie_player.h"
#include <cassert>
#include "f_op/f_op_overlap_mng.h"
#include <cstring>
#include "dusk/gx_helper.h"
#include "dusk/os.h"
#include "dusk/layout.hpp"
#include "JSystem/JAudio2/JASCriticalSection.h"
#if MOVIE_SUPPORT
#include "turbojpeg.h"
#endif
inline s32 daMP_NEXT_READ_SIZE(daMP_THPReadBuffer* readBuf) {
return *(s32*)readBuf->ptr;
return *(BE(s32)*)readBuf->ptr;
}
#ifdef __cplusplus
#if TARGET_PC
// idk what OS_THREAD_ATTR_DETACH does, and it stops OSThreadJoin()
// probably the difference doesn't matter since we are using OS threads anyways.
#define OS_THREAD_ATTR 0
#else
#define OS_THREAD_ATTR OS_THREAD_ATTR_DETACH
#endif
#if defined(__cplusplus) && !TARGET_PC
extern "C" {
#endif
@@ -196,6 +216,7 @@ static void __THPAudioInitialize(THPAudioDecodeInfo* info, u8* ptr) {
info->encodeData++;
}
#if !TARGET_PC
static u8 THPStatistics[1120] ATTRIBUTE_ALIGN(32);
static THPHuffmanTab* Ydchuff ATTRIBUTE_ALIGN(32);
@@ -2562,8 +2583,109 @@ static void __THPHuffDecodeDCTCompV(__REGISTER THPFileInfo* info, THPCoeff* bloc
}
}
}
#else // !TARGET_PC
static daMP_THPPlayer daMP_ActivePlayer;
#if MOVIE_SUPPORT
static std::vector<u8> FixedJpegData;
static tjhandle JpegDecompressHandle;
static const std::vector<u8>& FixJpeg(const std::span<u8> data) {
FixedJpegData.resize(0);
FixedJpegData.reserve(data.size());
size_t startOfScanLocation = 0;
for (; startOfScanLocation < data.size() - 1; startOfScanLocation++) {
if (data[startOfScanLocation] == 0xFF && data[startOfScanLocation + 1] == 0xDA) {
goto sosFound;
}
}
CRASH("Unable to find SOS marker!");
sosFound:
startOfScanLocation += 2; // TODO: Skip entire SOS header?
size_t endOfImage = data.size() - 1;
for (; endOfImage > startOfScanLocation; endOfImage--) {
if (data[endOfImage] == 0xFF && data[endOfImage + 1] == 0xD9) {
goto eoiFound;
}
}
CRASH("Unable to find EOI marker!");
eoiFound:
// Copy data before SOS
for (size_t i = 0; i < startOfScanLocation; i++) {
FixedJpegData.push_back(data[i]);
}
// Copy data inside SOS, fixing up lacking of "byte shuffling"
for (size_t i = startOfScanLocation; i < endOfImage; i++) {
u8 value = data[i];
FixedJpegData.push_back(value);
if (value == 0xFF) {
FixedJpegData.push_back(0x00);
}
}
// Copy data after SOS.
for (size_t i = endOfImage; i < data.size(); i++) {
FixedJpegData.push_back(data[i]);
}
return FixedJpegData;
}
static s32 THPVideoDecode(void* file, size_t fileSize, void* tileY, void* tileU, void* tileV, void*) {
assert(JpegDecompressHandle);
const auto handle = JpegDecompressHandle;
const auto fixedData = FixJpeg(std::span(static_cast<u8*>(file), fileSize));
auto ret = tj3DecompressHeader(handle, fixedData.data(), fixedData.size());
if (ret == -1) {
OSReport_Error("Parsing JPEG header failed: %s", tj3GetErrorStr(handle));
return 1;
}
if (tj3Get(handle, TJPARAM_JPEGWIDTH) != daMP_ActivePlayer.videoInfo.xSize) {
OSReport_Error("Invalid width in video frame!");
return 1;
}
if (tj3Get(handle, TJPARAM_JPEGHEIGHT) != daMP_ActivePlayer.videoInfo.ySize) {
OSReport_Error("Invalid height in video frame!");
return 1;
}
ret = tj3Set(handle, TJPARAM_SUBSAMP, TJSAMP_420);
if (ret != 0) {
OSReport_Error("Failed to set subsampling mode: %s", tj3GetErrorStr(handle));
return 1;
}
u8* planes[3] = {static_cast<u8*>(tileY), static_cast<u8*>(tileU), static_cast<u8*>(tileV)};
ret = tj3DecompressToYUVPlanes8(handle, fixedData.data(), fixedData.size(), planes, nullptr);
if (ret != 0) {
OSReport_Error("Image decompression failed: %s", tj3GetErrorStr(handle));
return 1;
}
return 0;
}
#else // MOVIE_SUPPORT
static s32 THPVideoDecode(void*, size_t, void*, void*, void*, void*) {
return 1; // Immediate error.
}
#endif
#endif
static BOOL THPInit() {
#if !TARGET_PC
u8* base;
base = (u8*)(0xE000 << 16);
@@ -2585,15 +2707,21 @@ static BOOL THPInit() {
OSInitFastCast();
__THPInitFlag = TRUE;
#endif
return TRUE;
}
#ifdef __cplusplus
#if defined(__cplusplus) && !TARGET_PC
}
#endif
#if !TARGET_PC // Defined earlier in file.
static daMP_THPPlayer daMP_ActivePlayer;
#endif
#if TARGET_PC
static BOOL ReadThreadCancelled;
#endif
static BOOL daMP_ReadThreadCreated;
static OSMessageQueue daMP_FreeReadBufferQueue;
@@ -2648,12 +2776,23 @@ void daMP_ReadThreadStart() {
void daMP_ReadThreadCancel() {
if (daMP_ReadThreadCreated) {
#if TARGET_PC
ReadThreadCancelled = TRUE;
OSReceiveMessage(&daMP_ReadedBufferQueue, nullptr, OS_MESSAGE_NOBLOCK);
OSSendMessage(&daMP_FreeReadBufferQueue, nullptr, OS_MESSAGE_NOBLOCK);
OSJoinThread(&daMP_ReadThread, nullptr);
#else
OSCancelThread(&daMP_ReadThread);
#endif
daMP_ReadThreadCreated = FALSE;
}
}
void* daMP_Reader(void*) {
#if TARGET_PC
OSSetCurrentThreadName("movie player reader");
#endif
daMP_THPReadBuffer* buf;
s32 curFrame;
s32 status;
@@ -2664,8 +2803,17 @@ void* daMP_Reader(void*) {
offset = daMP_ActivePlayer.initOffset;
initReadSize = daMP_ActivePlayer.initReadSize;
#if TARGET_PC
while (!ReadThreadCancelled) {
#else
while (TRUE) {
#endif
buf = (daMP_THPReadBuffer*)daMP_PopFreeReadBuffer();
#if TARGET_PC
if (!buf) {
return nullptr;
}
#endif
status = DVDReadPrio(&daMP_ActivePlayer.fileInfo, buf->ptr, initReadSize, offset, 2);
if (status != initReadSize) {
if (status == -1)
@@ -2673,7 +2821,11 @@ void* daMP_Reader(void*) {
if (frame == 0)
daMP_PrepareReady(FALSE);
#if TARGET_PC
return nullptr;
#else
OSSuspendThread(&daMP_ReadThread);
#endif
}
buf->frameNumber = frame;
@@ -2686,20 +2838,35 @@ void* daMP_Reader(void*) {
if (curFrame == daMP_ActivePlayer.header.numFrames - 1) {
if (daMP_ActivePlayer.playFlag & 1)
offset = daMP_ActivePlayer.header.movieDataOffsets;
else
OSSuspendThread(&daMP_ReadThread);
else {
#if TARGET_PC
return nullptr;
#else
OSSuspendThread(&daMP_ReadThread);
#endif
}
}
frame++;
}
#if TARGET_PC
return nullptr;
#endif
}
static u8 daMP_ReadThreadStack[0x2000];
#if TARGET_PC
static BOOL VideoThreadCancelled;
#endif
static BOOL daMP_VideoDecodeThreadCreated;
static BOOL daMP_CreateReadThread(s32 param_0) {
if (!OSCreateThread(&daMP_ReadThread, daMP_Reader, 0, daMP_ReadThreadStack + sizeof(daMP_ReadThreadStack), sizeof(daMP_ReadThreadStack), param_0, 1)) {
#if TARGET_PC
ReadThreadCancelled = FALSE;
#endif
if (!OSCreateThread(&daMP_ReadThread, daMP_Reader, 0, daMP_ReadThreadStack + sizeof(daMP_ReadThreadStack), sizeof(daMP_ReadThreadStack), param_0, OS_THREAD_ATTR)) {
OSReport("Can't create read thread\n");
return FALSE;
}
@@ -2751,19 +2918,30 @@ static BOOL daMP_First;
static void daMP_VideoDecode(daMP_THPReadBuffer* readBuffer) {
THPTextureSet* textureSet;
s32 i;
u32* tileOffsets;
BE(u32)* tileOffsets;
u8* tile;
tileOffsets = (u32*)(readBuffer->ptr + 8);
tileOffsets = (BE(u32)*)(readBuffer->ptr + 8);
tile = &readBuffer->ptr[daMP_ActivePlayer.compInfo.numComponents * 4] + 8;
textureSet = (THPTextureSet*)daMP_PopFreeTextureSet();
#if TARGET_PC
if (textureSet == nullptr) {
return;
}
#endif
for (i = 0; i < daMP_ActivePlayer.compInfo.numComponents; i++) {
switch (daMP_ActivePlayer.compInfo.frameComp[i]) {
case 0: {
if ((daMP_ActivePlayer.videoError = THPVideoDecode(
tile, textureSet->ytexture, textureSet->utexture,
textureSet->vtexture, daMP_ActivePlayer.thpWork))) {
tile,
#if TARGET_PC
*tileOffsets,
#endif
textureSet->ytexture, textureSet->utexture,
textureSet->vtexture,
daMP_ActivePlayer.thpWork))) {
if (daMP_First) {
daMP_PrepareReady(FALSE);
daMP_First = FALSE;
@@ -2789,12 +2967,24 @@ static void daMP_VideoDecode(daMP_THPReadBuffer* readBuffer) {
}
static void* daMP_VideoDecoder(void* param_0) {
daMP_THPReadBuffer* thpBuffer;
#if TARGET_PC
OSSetCurrentThreadName("movie video decoder");
#endif
daMP_THPReadBuffer* thpBuffer;
#if TARGET_PC
while (!VideoThreadCancelled) {
#else
while (TRUE) {
#endif
if (daMP_ActivePlayer.audioExist) {
for (; daMP_ActivePlayer.videoDecodeCount < 0;) {
thpBuffer = (daMP_THPReadBuffer*)daMP_PopReadedBuffer2();
#if TARGET_PC
if (thpBuffer == nullptr) {
goto exit;
}
#endif
s32 remaining
= ((thpBuffer->frameNumber + daMP_ActivePlayer.initReadFrame)
% daMP_ActivePlayer.header.numFrames);
@@ -2814,12 +3004,26 @@ static void* daMP_VideoDecoder(void* param_0) {
else
thpBuffer = (daMP_THPReadBuffer*)daMP_PopReadedBuffer();
#if TARGET_PC
if (thpBuffer == nullptr) {
goto exit;
}
#endif
daMP_VideoDecode(thpBuffer);
daMP_PushFreeReadBuffer(thpBuffer);
}
#if TARGET_PC
exit:;
return nullptr;
#endif
}
static void* daMP_VideoDecoderForOnMemory(void* param_0) {
#if TARGET_PC
OSSetCurrentThreadName("movie video decoder");
#endif
daMP_THPReadBuffer readBuffer;
s32 readSize;
s32 frame;
@@ -2876,13 +3080,17 @@ static void* daMP_VideoDecoderForOnMemory(void* param_0) {
}
static BOOL daMP_CreateVideoDecodeThread(OSPriority prio, u8* param_1) {
#if TARGET_PC
VideoThreadCancelled = FALSE;
#endif
if (param_1 != NULL) {
if (!OSCreateThread(&daMP_VideoDecodeThread, daMP_VideoDecoderForOnMemory, param_1, daMP_VideoDecodeThreadStack + sizeof(daMP_VideoDecodeThreadStack), sizeof(daMP_VideoDecodeThreadStack), prio, 1)) {
if (!OSCreateThread(&daMP_VideoDecodeThread, daMP_VideoDecoderForOnMemory, param_1, daMP_VideoDecodeThreadStack + sizeof(daMP_VideoDecodeThreadStack), sizeof(daMP_VideoDecodeThreadStack), prio, OS_THREAD_ATTR)) {
OSReport("Can't create video decode thread\n");
return FALSE;
}
} else {
if (!OSCreateThread(&daMP_VideoDecodeThread, daMP_VideoDecoder, NULL, daMP_VideoDecodeThreadStack + sizeof(daMP_VideoDecodeThreadStack), sizeof(daMP_VideoDecodeThreadStack), prio, 1)) {
if (!OSCreateThread(&daMP_VideoDecodeThread, daMP_VideoDecoder, NULL, daMP_VideoDecodeThreadStack + sizeof(daMP_VideoDecodeThreadStack), sizeof(daMP_VideoDecodeThreadStack), prio, OS_THREAD_ATTR)) {
OSReport("Can't create video decode thread\n");
return FALSE;
}
@@ -2903,12 +3111,24 @@ static void daMP_VideoDecodeThreadStart() {
void daMP_VideoDecodeThreadCancel() {
if (daMP_VideoDecodeThreadCreated) {
#if TARGET_PC
VideoThreadCancelled = TRUE;
// Push junk into the queues so the thread unblocks and can exit cleanly.
daMP_PushFreeTextureSet(nullptr);
daMP_PushReadedBuffer(nullptr);
daMP_PushReadedBuffer2(nullptr);
OSJoinThread(&daMP_VideoDecodeThread, nullptr);
#else
OSCancelThread(&daMP_VideoDecodeThread);
#endif
daMP_VideoDecodeThreadCreated = FALSE;
}
}
static BOOL daMP_AudioDecodeThreadCreated;
#if TARGET_PC
static BOOL AudioThreadCancelled;
#endif
static OSThread daMP_AudioDecodeThread;
@@ -2944,12 +3164,17 @@ static void daMP_PushDecodedAudioBuffer(void* buffer) {
static void daMP_AudioDecode(daMP_THPReadBuffer* readBuffer) {
THPAudioBuffer* audioBuf;
s32 i;
u32* offsets;
BE(u32)* offsets;
u8* audioData;
offsets = (u32*)(readBuffer->ptr + 8);
offsets = (BE(u32)*)(readBuffer->ptr + 8);
audioData = &readBuffer->ptr[daMP_ActivePlayer.compInfo.numComponents * 4] + 8;
audioBuf = (THPAudioBuffer*)daMP_PopFreeAudioBuffer();
#if TARGET_PC
if (!audioBuf) {
return;
}
#endif
for (i = 0; i < daMP_ActivePlayer.compInfo.numComponents; i++) {
switch (daMP_ActivePlayer.compInfo.frameComp[i]) {
@@ -2969,16 +3194,34 @@ static void daMP_AudioDecode(daMP_THPReadBuffer* readBuffer) {
}
static void* daMP_AudioDecoder(void* param_0) {
#if TARGET_PC
OSSetCurrentThreadName("movie audio decoder");
#endif
daMP_THPReadBuffer* buf;
#if TARGET_PC
while (!AudioThreadCancelled) {
#else
while (TRUE) {
#endif
buf = (daMP_THPReadBuffer*)daMP_PopReadedBuffer();
#if TARGET_PC
if (!buf) {
return nullptr;
}
#endif
daMP_AudioDecode(buf);
daMP_PushReadedBuffer2(buf);
}
return nullptr;
}
static void* daMP_AudioDecoderForOnMemory(void* param_0) {
#if TARGET_PC
OSSetCurrentThreadName("movie audio decoder");
#endif
s32 size;
s32 readSize;
daMP_THPReadBuffer readBuffer;
@@ -2989,7 +3232,11 @@ static void* daMP_AudioDecoderForOnMemory(void* param_0) {
readBuffer.ptr = (u8*)param_0;
frame = 0;
#if TARGET_PC
while (!AudioThreadCancelled) {
#else
while (TRUE) {
#endif
readBuffer.frameNumber = frame;
daMP_AudioDecode(&readBuffer);
@@ -2999,7 +3246,11 @@ static void* daMP_AudioDecoderForOnMemory(void* param_0) {
readSize = *(s32*)readBuffer.ptr;
readBuffer.ptr = daMP_ActivePlayer.movieData;
} else {
#if TARGET_PC
return nullptr;
#else
OSSuspendThread(&daMP_AudioDecodeThread);
#endif
}
} else {
size = *(s32*)readBuffer.ptr;
@@ -3008,6 +3259,7 @@ static void* daMP_AudioDecoderForOnMemory(void* param_0) {
}
frame++;
}
return nullptr;
}
static OSMessage daMP_FreeAudioBufferMessage[3];
@@ -3015,13 +3267,16 @@ static OSMessage daMP_FreeAudioBufferMessage[3];
static OSMessage daMP_DecodedAudioBufferMessage[3];
static BOOL daMP_CreateAudioDecodeThread(OSPriority prio, u8* param_1) {
#if TARGET_PC
AudioThreadCancelled = FALSE;
#endif
if (param_1 != NULL) {
if (!OSCreateThread(&daMP_AudioDecodeThread, daMP_AudioDecoderForOnMemory, param_1, daMP_AudioDecodeThreadStack + sizeof(daMP_AudioDecodeThreadStack), sizeof(daMP_AudioDecodeThreadStack), prio, 1)) {
if (!OSCreateThread(&daMP_AudioDecodeThread, daMP_AudioDecoderForOnMemory, param_1, daMP_AudioDecodeThreadStack + sizeof(daMP_AudioDecodeThreadStack), sizeof(daMP_AudioDecodeThreadStack), prio, OS_THREAD_ATTR)) {
OS_REPORT("Can't create audio decode thread\n");
return FALSE;
}
} else {
if (!OSCreateThread(&daMP_AudioDecodeThread, daMP_AudioDecoder, NULL, daMP_AudioDecodeThreadStack + sizeof(daMP_AudioDecodeThreadStack), sizeof(daMP_AudioDecodeThreadStack), prio, 1)) {
if (!OSCreateThread(&daMP_AudioDecodeThread, daMP_AudioDecoder, NULL, daMP_AudioDecodeThreadStack + sizeof(daMP_AudioDecodeThreadStack), sizeof(daMP_AudioDecodeThreadStack), prio, OS_THREAD_ATTR)) {
OSReport("Can't create audio decode thread\n");
return FALSE;
}
@@ -3042,7 +3297,17 @@ void daMP_AudioDecodeThreadStart() {
void daMP_AudioDecodeThreadCancel() {
if (daMP_AudioDecodeThreadCreated) {
#if TARGET_PC
AudioThreadCancelled = TRUE;
// Push junk into the queues so the thread unblocks and can exit cleanly.
OSSendMessage(&daMP_ReadedBufferQueue, nullptr, OS_MESSAGE_NOBLOCK);
daMP_PushFreeAudioBuffer(nullptr);
OSReceiveMessage(&daMP_ReadedBufferQueue2, nullptr, OS_MESSAGE_NOBLOCK);
OSReceiveMessage(&daMP_DecodedAudioBufferQueue, nullptr, OS_MESSAGE_NOBLOCK);
OSJoinThread(&daMP_AudioDecodeThread, nullptr);
#else
OSCancelThread(&daMP_AudioDecodeThread);
#endif
daMP_AudioDecodeThreadCreated = FALSE;
}
}
@@ -3077,8 +3342,13 @@ static void daMP_THPGXYuv2RgbSetup(const GXRenderModeObj* rmode) {
Mtx44 m;
Mtx e_m;
#if TARGET_PC
w = JUTVideo::getManager()->getFbWidth();
h = JUTVideo::getManager()->getEfbHeight();
#else
w = rmode->fbWidth;
h = rmode->efbHeight;
#endif
var_f31 = 0.0f;
#if WIDESCREEN_SUPPORT
@@ -3168,19 +3438,26 @@ static void daMP_THPGXYuv2RgbDraw(u8* y_data, u8* u_data, u8* v_data, s16 x,
TGXTexObj tobj0;
TGXTexObj tobj1;
TGXTexObj tobj2;
#if TARGET_PC
#define FMT (GXTexFmt)GX_TF_R8_PC
#else
#define FMT GX_TF_I8
#endif
GXInitTexObj(&tobj0, y_data, textureWidth, textureHeight, GX_TF_I8, GX_CLAMP, GX_CLAMP, GX_FALSE);
GXInitTexObj(&tobj0, y_data, textureWidth, textureHeight, FMT, GX_CLAMP, GX_CLAMP, GX_FALSE);
GXInitTexObjLOD(&tobj0, GX_NEAR, GX_NEAR, 0.0f, 0.0f, 0.0f, 0, 0, GX_ANISO_1);
GXLoadTexObj(&tobj0, GX_TEXMAP0);
GXInitTexObj(&tobj1, u_data, textureWidth >> 1, textureHeight >> 1, GX_TF_I8, GX_CLAMP, GX_CLAMP, GX_FALSE);
GXInitTexObj(&tobj1, u_data, textureWidth >> 1, textureHeight >> 1, FMT, GX_CLAMP, GX_CLAMP, GX_FALSE);
GXInitTexObjLOD(&tobj1, GX_NEAR, GX_NEAR, 0.0f, 0.0f, 0.0f, 0, 0, GX_ANISO_1);
GXLoadTexObj(&tobj1, GX_TEXMAP1);
GXInitTexObj(&tobj2, v_data, textureWidth >> 1, textureHeight >> 1, GX_TF_I8, GX_CLAMP, GX_CLAMP, GX_FALSE);
GXInitTexObj(&tobj2, v_data, textureWidth >> 1, textureHeight >> 1, FMT, GX_CLAMP, GX_CLAMP, GX_FALSE);
GXInitTexObjLOD(&tobj2, GX_NEAR, GX_NEAR, 0.0f, 0.0f, 0.0f, 0, 0, GX_ANISO_1);
GXLoadTexObj(&tobj2, GX_TEXMAP2);
#undef FMT
GXBegin(GX_QUADS, GX_VTXFMT7, 4);
GXPosition3s16(x, y, 0);
GXTexCoord2u16(0, 0);
@@ -3191,6 +3468,12 @@ static void daMP_THPGXYuv2RgbDraw(u8* y_data, u8* u_data, u8* v_data, s16 x,
GXPosition3s16(x, y + polygonHeight, 0);
GXTexCoord2u16(0, 1);
GXEnd();
#if TARGET_PC
GXDestroyTexObj(&tobj0);
GXDestroyTexObj(&tobj1);
GXDestroyTexObj(&tobj2);
#endif
}
static u16 daMP_VolumeTable[] = {
@@ -3495,6 +3778,13 @@ static BOOL daMP_THPPlayerOpen(char const* filename, BOOL onMemory) {
}
static BOOL daMP_THPPlayerClose() {
#if TARGET_PC && MOVIE_SUPPORT
tj3Destroy(JpegDecompressHandle);
JpegDecompressHandle = nullptr;
FixedJpegData.clear();
#endif
if (daMP_ActivePlayer.open && daMP_ActivePlayer.state == 0) {
daMP_ActivePlayer.open = 0;
DVDClose(&daMP_ActivePlayer.fileInfo);
@@ -3546,6 +3836,11 @@ static BOOL daMP_THPPlayerSetBuffer(u8* buffer) {
ysize = ALIGN_NEXT(daMP_ActivePlayer.videoInfo.xSize * daMP_ActivePlayer.videoInfo.ySize, 32);
uvsize = ALIGN_NEXT(daMP_ActivePlayer.videoInfo.xSize * daMP_ActivePlayer.videoInfo.ySize / 4, 32);
#if TARGET_PC
assert(ysize >= tj3YUVPlaneSize(0, daMP_ActivePlayer.videoInfo.xSize, 0, daMP_ActivePlayer.videoInfo.ySize, TJSAMP_420));
assert(uvsize >= tj3YUVPlaneSize(1, daMP_ActivePlayer.videoInfo.xSize, 0, daMP_ActivePlayer.videoInfo.ySize, TJSAMP_420));
assert(uvsize >= tj3YUVPlaneSize(2, daMP_ActivePlayer.videoInfo.xSize, 0, daMP_ActivePlayer.videoInfo.ySize, TJSAMP_420));
#endif
for (i = 0; i < ARRAY_SIZE(daMP_ActivePlayer.textureSet); i++) {
daMP_ActivePlayer.textureSet[i].ytexture = ptr;
@@ -3623,6 +3918,12 @@ static BOOL daMP_ProperTimingForGettingNextFrame() {
}
} else {
s32 frameRate = daMP_ActivePlayer.header.frameRate * 100.0f;
#if TARGET_PC
// DUSK HACK: We only fire retrace callbacks *half* as often as the game expects,
// because we only run them once per frame, and normally there should be two scans
// per game frame.
frameRate *= 2;
#endif
if (VIGetTvFormat() == VI_PAL) {
daMP_ActivePlayer.curCount = daMP_ActivePlayer.retaceCount * frameRate / 5000;
} else {
@@ -3951,6 +4252,9 @@ static BOOL daMP_THPPlayerSetVolume(s32 vol, s32 duration) {
if (duration < 0)
duration = 0;
#if TARGET_PC
JASCriticalSection section;
#endif
interrupt = OSDisableInterrupts();
daMP_ActivePlayer.targetVolume = vol;
@@ -3994,11 +4298,14 @@ static BOOL daMP_ActivePlayer_Init(char const* moviePath) {
daMP_THPPlayerGetVideoInfo(&daMP_videoInfo);
daMP_THPPlayerGetAudioInfo(&daMP_audioInfo);
#if !TARGET_PC
// Window can be resized during playback, update this during draw.
u16 width = JUTVideo::getManager()->getRenderMode()->fbWidth;
u16 height = JUTVideo::getManager()->getRenderMode()->efbHeight;
daMP_DrawPosX = (width - daMP_videoInfo.xSize) >> 1;
daMP_DrawPosY = (height - daMP_videoInfo.ySize) >> 1;
#endif
// "The memory needed for this THP movie is %d bytes\n"
OS_REPORT("このTHPムービーが必要なメモリは%dバイトです\n", daMP_THPPlayerCalcNeedMemory());
@@ -4015,6 +4322,15 @@ static BOOL daMP_ActivePlayer_Init(char const* moviePath) {
daMP_THPPlayerSetBuffer((u8*)daMP_buffer);
#if TARGET_PC && MOVIE_SUPPORT
assert(JpegDecompressHandle == nullptr);
JpegDecompressHandle = tj3Init(TJINIT_DECOMPRESS);
if (JpegDecompressHandle == nullptr) {
OSReport_Error("Failed to create turbojpeg handle: %s", tj3GetErrorStr(nullptr));
return 0;
}
#endif
if (!daMP_THPPlayerPrepare(0, 0, daMP_audioInfo.sndNumTracks != 1 ? OSGetTick() % daMP_audioInfo.sndNumTracks : 0)) {
OSReport("Fail to prepare\n");
#if DEBUG
@@ -4050,14 +4366,55 @@ static void daMP_ActivePlayer_Main() {
}
}
#if TARGET_PC && 0
#include "imgui.h"
#endif
static void daMP_ActivePlayer_Draw() {
int frame = daMP_THPPlayerDrawCurrentFrame(JUTVideo::getManager()->getRenderMode(), daMP_DrawPosX, daMP_DrawPosY, daMP_videoInfo.xSize, daMP_videoInfo.ySize);
#if TARGET_PC
u16 width = JUTVideo::getManager()->getFbWidth();
u16 height = JUTVideo::getManager()->getEfbHeight();
const auto rect = dusk::LayoutRect::FitRectInRect(
width,
height,
static_cast<f32>(daMP_videoInfo.xSize),
static_cast<f32>(daMP_videoInfo.ySize));
daMP_DrawPosX = static_cast<u32>(rect.PosX);
daMP_DrawPosY = static_cast<u32>(rect.PosY);
#endif
int frame = daMP_THPPlayerDrawCurrentFrame(
JUTVideo::getManager()->getRenderMode(),
daMP_DrawPosX, daMP_DrawPosY,
#if TARGET_PC
static_cast<u32>(rect.Width()),
static_cast<u32>(rect.Height()));
#else
daMP_videoInfo.xSize,
daMP_videoInfo.ySize);
#endif
daMP_THPPlayerDrawDone();
if (!fopOvlpM_IsPeek() && frame > 0 && (cAPICPad_ANY_BUTTON(0) || !daMP_c::daMP_c_Get_MovieRestFrame())) {
dComIfGp_event_reset();
daMP_c::daMP_c_Set_PercentMovieVolume(0.0f);
}
#if TARGET_PC && 0
if (ImGui::Begin("Movie player")) {
ImGui::Text("daMP_ReadedBufferQueue: %d", daMP_ReadedBufferQueue.usedCount);
ImGui::Text("daMP_ReadedBufferQueue2: %d", daMP_ReadedBufferQueue2.usedCount);
ImGui::Text("daMP_FreeReadBufferQueue: %d", daMP_FreeReadBufferQueue.usedCount);
ImGui::Text("daMP_DecodedTextureSetQueue: %d", daMP_DecodedTextureSetQueue.usedCount);
ImGui::Text("daMP_FreeTextureSetQueue: %d", daMP_FreeTextureSetQueue.usedCount);
ImGui::Text("daMP_DecodedAudioBufferQueue: %d", daMP_DecodedAudioBufferQueue.usedCount);
ImGui::Text("daMP_FreeAudioBufferQueue: %d", daMP_FreeAudioBufferQueue.usedCount);
}
ImGui::End();
#endif
}
static BOOL daMP_Fail_alloc;
+5 -6
View File
@@ -2694,16 +2694,15 @@ BOOL daNpcT_chkActorInScreen(fopAc_ac_c* i_ActorP, f32 param_1, f32 param_2, f32
}
for (int i = 0; i < 8; i++) {
#if TARGET_PC
mDoLib_project(&pos_array[i], &proj, {0, 0, FB_WIDTH, FB_HEIGHT});
#else
mDoLib_project(&pos_array[i], &proj);
#if TARGET_PC
if (0.0f < proj.x && proj.x < mDoGph_gInf_c::getWidth() && 0.0f < proj.y && proj.y < mDoGph_gInf_c::getHeight()) {
continue;
}
#else
#endif
if (0.0f < proj.x && proj.x < FB_WIDTH && 0.0f < proj.y && proj.y < FB_HEIGHT) {
continue;
}
#endif
return false;
}
+9 -1
View File
@@ -1363,7 +1363,15 @@ void daNpc_Grz_c::playExpression() {
daNpcF_anmPlayData dat7 = {ANM_LIEDOWN, mpHIO->m.common.morf_frame, 0};
daNpcF_anmPlayData* pDat7[1] = {&dat7};
daNpcF_anmPlayData dat8 = {ANM_GETUP, mpHIO->m.common.morf_frame, 1};
daNpcF_anmPlayData* pDat8[1] = {&dat8};
#if TARGET_PC
// BUG: If mNumLoops is non-zero, the data array MUST be null-terminated to prevent
// playExpression from reading junk when it increments the index.
// For some reason this doesn't crash on hardware, but it triggers a segfault on PC
// when first talking to Fyrus after defating him.
daNpcF_anmPlayData* pDat8[2] = {&dat8, NULL};
#else
daNpcF_anmPlayData* pDat8[2] = {&dat8};
#endif
daNpcF_anmPlayData dat9 = {ANM_F_WEAK_WAIT, mpHIO->m.common.morf_frame, 0};
daNpcF_anmPlayData* pDat9[1] = {&dat9};
daNpcF_anmPlayData dat10 = {ANM_NONE, mpHIO->m.common.morf_frame, 0};
+8
View File
@@ -2709,6 +2709,14 @@ static int daNpc_Henna_Create(fopAc_ac_c* i_this) {
}
i_this->attention_info.flags = (fopAc_AttnFlag_SPEAK_e | fopAc_AttnFlag_TALK_e);
a_this->action = 0;
#if AVOID_UB
a_this->field_0x654 = 0;
a_this->field_0x658 = 0;
a_this->field_0x662 = 0;
a_this->field_0x664 = 0;
#endif
fopAcM_SetMtx(i_this, a_this->mpMorf->getModel()->getBaseTRMtx());
lbl_82_bss_90 = 0;
if (a_this->arg0 == 1) {
+5 -3
View File
@@ -824,9 +824,11 @@ void daNpcTks_c::playMotion() {
daNpcF_anmPlayData dat4b = {ANM_FLY, 0.0f, 0};
daNpcF_anmPlayData* pDat4[2] = {&dat4a, &dat4b};
#if TARGET_PC
// Note: this fixes a crash in the cutscene after entering city and likely needs to be revisited as its
// unclear why this was 1 in the first place and unclear why this fixes it
#if TARGET_PC
// BUG: If mNumLoops is non-zero, the data array MUST be null-terminated to prevent
// playExpression from reading junk when it increments the index.
// For some reason this doesn't crash on hardware, but it triggers a segfault on PC
// in the cutscene after entering city.
daNpcF_anmPlayData dat5 = {ANM_JUMP_E, 0.0f, 0};
#else
daNpcF_anmPlayData dat5 = {ANM_JUMP_E, 0.0f, 1};
+6
View File
@@ -499,7 +499,13 @@ void daObjARI_c::Z_BufferChk() {
cXyz vec2, vec1;
vec1 = current.pos;
vec1.y += 20.0f;
#if TARGET_PC
mDoLib_project(&vec1, &vec2, {0, 0, FB_WIDTH, FB_HEIGHT});
#else
mDoLib_project(&vec1, &vec2);
#endif
f32 trim_height;
camera_process_class* camera = dComIfGp_getCamera(0);
if (camera != NULL) {
+6
View File
@@ -285,7 +285,13 @@ bool Hahen_c::CheckCull() {
bool Hahen_c::checkViewArea() {
Vec proj;
#if TARGET_PC
mDoLib_project(&pos, &proj, {0, 0, FB_WIDTH, FB_HEIGHT});
#else
mDoLib_project(&pos, &proj);
#endif
return (proj.x >= -50.0f && proj.x <= 658.0f) && (proj.y >= -50.0f && proj.y <= 498.0f);
}
-2
View File
@@ -590,8 +590,6 @@ static void cut_control2(obj_brg_class* i_this, br_s* i_part) {
}
static void himo_cut_control1(obj_brg_class* i_this, cXyz* param_1, f32 param_2) {
STUB_RET();
cXyz sp74 = {};
cXyz sp80 = {};
cXyz sp8C = {};
+6
View File
@@ -289,7 +289,13 @@ void daObjCHO_c::Z_BufferChk() {
cXyz vec2, vec1;
vec1 = current.pos;
vec1.y += 20.0f;
#if TARGET_PC
mDoLib_project(&vec1, &vec2, {0, 0, FB_WIDTH, FB_HEIGHT});
#else
mDoLib_project(&vec1, &vec2);
#endif
f32 trim_height;
camera_process_class* camera = dComIfGp_getCamera(0);
if (camera != NULL) {
+6
View File
@@ -224,7 +224,13 @@ void daObjCRVFENCE_c::NormalAction() {
bool daObjCRVFENCE_c::checkViewArea(cXyz* param_1) {
Vec sp24;
#if TARGET_PC
mDoLib_project(param_1, &sp24, {0, 0, FB_WIDTH, FB_HEIGHT});
#else
mDoLib_project(param_1, &sp24);
#endif
bool rv = false;
bool bVar1 = false;
+5
View File
@@ -137,7 +137,12 @@ void daObjCRVHAHEN_c::CheckCull() {
bool daObjCRVHAHEN_c::checkViewArea(cXyz* i_this) {
Vec proj;
#if TARGET_PC
mDoLib_project(i_this, &proj, {0, 0, FB_WIDTH, FB_HEIGHT});
#else
mDoLib_project(i_this, &proj);
#endif
bool ret = false;
+6
View File
@@ -267,7 +267,13 @@ void daObjDAN_c::Z_BufferChk() {
cXyz vec2, vec1;
vec1 = current.pos;
vec1.y += 20.0f;
#if TARGET_PC
mDoLib_project(&vec1, &vec2, {0, 0, FB_WIDTH, FB_HEIGHT});
#else
mDoLib_project(&vec1, &vec2);
#endif
f32 trim_height;
camera_process_class* camera = dComIfGp_getCamera(0);
if (camera != NULL) {
+53
View File
@@ -20,6 +20,8 @@
#include "d/actor/d_a_e_ymb.h"
#include "f_op/f_op_camera_mng.h"
#include "dusk/settings.h"
#if DEBUG
daObjDrop_HIO_c l_HIO;
#endif
@@ -261,8 +263,18 @@ int daObjDrop_c::modeParentWait() {
}
mModeAction = 1;
#if TARGET_PC
mModeTimer = dusk::getSettings().game.fastTears && dComIfGp_event_getMode() == 0 ? 20 : 40;
if (dusk::getSettings().game.fastTears && dComIfGp_event_getMode() == 0) {
current.pos.y += 100.0f;
} else {
current.pos.y += 300.0f;
}
#else
mModeTimer = 40;
current.pos.y += 300.0f;
#endif
mSound.startSound(Z2SE_OBJ_LIGHTDROP_APPEAR, 0, -1);
break;
case 1:
@@ -272,7 +284,11 @@ int daObjDrop_c::modeParentWait() {
break;
case 2:
createBodyEffect();
#if TARGET_PC
mModeTimer = dusk::getSettings().game.fastTears && dComIfGp_event_getMode() == 0 ? 5 : 45;
#else
mModeTimer = 45;
#endif
mModeAction = 0;
setMode(MODE_WAIT_e);
break;
@@ -281,6 +297,18 @@ int daObjDrop_c::modeParentWait() {
return 1;
}
#if TARGET_PC
static inline BOOL checkGetCargoRide() {
if ((daPy_getPlayerActorClass()->checkCargoCarry() && strcmp(dComIfGp_getStartStageName(), "F_SP112") == 0) ||
dComIfGs_isLightDropGetFlag(dComIfGp_getStartStageDarkArea()))
{
return true;
}
return false;
}
#endif
int daObjDrop_c::modeWait() {
daPy_py_c* pplayer = daPy_getPlayerActorClass();
@@ -302,7 +330,32 @@ int daObjDrop_c::modeWait() {
case 1:
case 2:
case 50:
#if TARGET_PC
if (dusk::getSettings().game.fastTears && dComIfGp_event_getMode() == 0) {
f32 player_dist = current.pos.abs(daPy_getPlayerActorClass()->current.pos);
f32 home_dist = current.pos.abs(home.pos);
if (checkGetCargoRide() && player_dist < 1000.0f) {
mTargetPos = pplayer->current.pos;
mTargetPos.y += 100.0f;
f32 temp = 3000.0f - home_dist;
if (temp < 0.0f) {
temp = 0.0f;
}
cLib_chaseF(&speedF, (temp / 3000.0f) * 10.0f * (temp / 3000.0f), 1.0f);
} else {
mTargetPos = home.pos;
cLib_chaseF(&speedF, 2.0f, 0.5f);
}
} else {
cLib_chaseF(&speedF, 7.5f, 0.4f);
}
#else
cLib_chaseF(&speedF, 7.5f, 0.4f);
#endif
if (mModeAction == 1) {
cLib_chasePos(&current.pos, mTargetPos, speedF);
}
+6
View File
@@ -201,7 +201,13 @@ void daObjGOMIKABE_c::CheckCull() {
bool daObjGOMIKABE_c::checkViewArea(cXyz param_1) {
Vec local_24;
#if TARGET_PC
mDoLib_project(&param_1, &local_24, {0, 0, FB_WIDTH, FB_HEIGHT});
#else
mDoLib_project(&param_1, &local_24);
#endif
bool rv = false;
if (local_24.x >= 0.0f && local_24.x <= FB_WIDTH && local_24.y >= 0.0f && local_24.y <= FB_HEIGHT) {
rv = true;
+6
View File
@@ -214,7 +214,13 @@ void daObjHHASHI_c::CheckCull() {
bool daObjHHASHI_c::checkViewArea(int param_1) {
Vec local_20;
#if TARGET_PC
mDoLib_project(&field_0x5b0[param_1], &local_20, {0, 0, FB_WIDTH, FB_HEIGHT});
#else
mDoLib_project(&field_0x5b0[param_1], &local_20);
#endif
bool rv = false;
if (local_20.x >= 0.0f && local_20.x <= FB_WIDTH && local_20.y >= 0.0f && local_20.y <= FB_HEIGHT) {
rv = true;
+6
View File
@@ -517,7 +517,13 @@ void daObjKAM_c::Z_BufferChk() {
cXyz currentOffset;
currentOffset = current.pos;
currentOffset.y += 20.0f;
#if TARGET_PC
mDoLib_project(&currentOffset, &currentProj, {0, 0, FB_WIDTH, FB_HEIGHT});
#else
mDoLib_project(&currentOffset, &currentProj);
#endif
camera_process_class* camera = dComIfGp_getCamera(0);
f32 cameraHeight;
if (camera != NULL) {
+5
View File
@@ -611,7 +611,12 @@ void daObjKAT_c::Z_BufferChk() {
cXyz curWithOff;
curWithOff = current.pos;
curWithOff.y += 20.0f;
#if TARGET_PC
mDoLib_project(&curWithOff, &projected, {0, 0, FB_WIDTH, FB_HEIGHT});
#else
mDoLib_project(&curWithOff, &projected);
#endif
camera_process_class* camera = dComIfGp_getCamera(0);
f32 unkFloat1;
+5
View File
@@ -528,7 +528,12 @@ void daObjKUW_c::Z_BufferChk() {
cStack_68 = current.pos;
cStack_68.y += 20.0f;
#if TARGET_PC
mDoLib_project(&cStack_68, &local_5c, {0, 0, FB_WIDTH, FB_HEIGHT});
#else
mDoLib_project(&cStack_68, &local_5c);
#endif
camera_process_class* cc = dComIfGp_getCamera(0);
f32 trimHeight;
+6
View File
@@ -593,7 +593,13 @@ void daObjTEN_c::Z_BufferChk() {
cXyz cStack_68;
cStack_68 = current.pos;
cStack_68.y += 20.0f;
#if TARGET_PC
mDoLib_project(&cStack_68, &local_5c, {0, 0, FB_WIDTH, FB_HEIGHT});
#else
mDoLib_project(&cStack_68, &local_5c);
#endif
camera_process_class* camera = dComIfGp_getCamera(0);
f32 trimHeight;
if (camera != NULL) {
+6
View File
@@ -504,7 +504,13 @@ void daObjTOMBO_c::Z_BufferChk() {
cXyz cStack_68;
cStack_68 = current.pos;
cStack_68.y += 20.0f;
#if TARGET_PC
mDoLib_project(&cStack_68, &local_5c, {0, 0, FB_WIDTH, FB_HEIGHT});
#else
mDoLib_project(&cStack_68, &local_5c);
#endif
camera_process_class* pCamera = dComIfGp_getCamera(0);
f32 trimHeight;
if (pCamera != NULL) {
+5
View File
@@ -38,7 +38,12 @@ BOOL daZraFreeze_c::chkActorInScreen() {
mDoMtx_stack_c::transM(0.0f, 0.0f, 0.0f);
PSMTXMultVecArray(mDoMtx_stack_c::get(), vec, vec, 8);
for (int i = 0; i < 8; i++) {
#if TARGET_PC
mDoLib_project(&vec[i], &proj, {0, 0, FB_WIDTH, FB_HEIGHT});
#else
mDoLib_project(&vec[i], &proj);
#endif
if (0.0f < proj.x && proj.x < FB_WIDTH && 0.0f < proj.y && proj.y < FB_HEIGHT) {
continue;
}
+3 -4
View File
@@ -237,11 +237,7 @@ void* daPy_anmHeap_c::mallocBuffer() {
return mBuffer;
}
#if TARGET_PC
void daPy_anmHeap_c::createHeap(daPy_anmHeap_c::daAlinkHEAP_TYPE i_heapType, const char* name) {
#else
void daPy_anmHeap_c::createHeap(daPy_anmHeap_c::daAlinkHEAP_TYPE i_heapType, const char* name) {
#endif
u32 size;
if (i_heapType == 4) {
@@ -255,6 +251,9 @@ void daPy_anmHeap_c::createHeap(daPy_anmHeap_c::daAlinkHEAP_TYPE i_heapType, con
} else {
size = 0xA0;
}
#if TARGET_PC
size *= 2;
#endif
char* tmpWork;
mDoExt_transAnmBas* tmpTransBas;
+11 -10
View File
@@ -10,12 +10,14 @@
#include "d/d_bg_w.h"
#include "d/d_com_inf_game.h"
#include "f_op/f_op_actor_mng.h"
#include "dusk/offset_ptr.h"
#include "d/d_debug_viewer.h"
#include "d/d_bg_s_capt_poly.h"
#include "dusk/imgui/ImGuiConsole.hpp"
#if TARGET_PC
#include "dusk/offset_ptr.h"
#include "dusk/settings.h"
#endif
#if DEBUG
int g_ground_counter;
@@ -619,8 +621,8 @@ static int poly_draw(dBgS_CaptPoly* capt, cBgD_Vtx_t* vtxList, int v0, int v1, i
GXColor wall_color = {0, 0xFF, 0, 0xFF};
#if TARGET_PC
dusk::ImGuiMenuTools::CollisionViewSettings collisionViewSettings = dusk::g_imguiConsole.getCollisionViewSettings();
f32 view_opacity = 255 * (collisionViewSettings.m_terrainViewOpacity / 100.0f);
const auto& collisionViewSettings = dusk::getTransientSettings().collisionView;
f32 view_opacity = 255 * (collisionViewSettings.terrainViewOpacity / 100.0f);
ground_color.a = view_opacity;
roof_color.a = view_opacity;
wall_color.a = view_opacity;
@@ -658,16 +660,16 @@ void dBgS::Draw() {
cBgS::Draw();
#if TARGET_PC
#define IMGUI_TOGGLE_HIO_FLAG(status, flag) \
#define DUSK_TOGGLE_HIO_FLAG(status, flag) \
if (status) { \
s_InsideHio.m_flags |= flag; \
} else { \
s_InsideHio.m_flags &= ~flag; \
}
dusk::ImGuiMenuTools::CollisionViewSettings collisionViewSettings = dusk::g_imguiConsole.getCollisionViewSettings();
IMGUI_TOGGLE_HIO_FLAG(collisionViewSettings.m_enableTerrainView, dBgS_InsideHIO::FLAG_DISP_POLY_e);
IMGUI_TOGGLE_HIO_FLAG(collisionViewSettings.m_enableWireframe, dBgS_InsideHIO::FLAG_WHITE_WIRE_e);
const auto& collisionViewSettings = dusk::getTransientSettings().collisionView;
DUSK_TOGGLE_HIO_FLAG(collisionViewSettings.enableTerrainView, dBgS_InsideHIO::FLAG_DISP_POLY_e);
DUSK_TOGGLE_HIO_FLAG(collisionViewSettings.enableWireframe, dBgS_InsideHIO::FLAG_WHITE_WIRE_e);
#endif
if (s_InsideHio.ChkDispPoly()) {
@@ -680,8 +682,7 @@ void dBgS::Draw() {
f32 var_f31 = fabsf(s_InsideHio.m_p0.x);
#if TARGET_PC
dusk::ImGuiMenuTools::CollisionViewSettings collisionViewSettings = dusk::g_imguiConsole.getCollisionViewSettings();
var_f31 = collisionViewSettings.m_drawRange;
var_f31 = collisionViewSettings.drawRange;
#endif
min.x = player->current.pos.x - var_f31;
+49
View File
@@ -143,7 +143,56 @@ void dBrightCheck_c::modeMove() {
}
}
#if TARGET_PC
void dBrightCheck_c::brightCheckWide() {
// Main Canvas
mBrightCheck.Scr->scale(mDoGph_gInf_c::hudAspectScaleUp, 1.0f);
mBrightCheck.Scr->translate(mDoGph_gInf_c::getMinXF(), 0.0f);
// Right Square
mBrightCheck.Scr->search(MULTI_CHAR('fuchi_1'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
mBrightCheck.Scr->search(MULTI_CHAR('big_squa'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
// Middle Square
mBrightCheck.Scr->search(MULTI_CHAR('fuchi_3'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
mBrightCheck.Scr->search(MULTI_CHAR('big_squ1'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
// Left Square
mBrightCheck.Scr->search(MULTI_CHAR('fuchi_4'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
mBrightCheck.Scr->search(MULTI_CHAR('big_squ2'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
// Gray Squares
mBrightCheck.Scr->search(MULTI_CHAR('gray_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
mBrightCheck.Scr->search(MULTI_CHAR('fuchi_2'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
// Confirm A Button
mBrightCheck.Scr->search(MULTI_CHAR('abtn_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
mBrightCheck.Scr->search(MULTI_CHAR('gcabtn_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
// Text
mBrightCheck.Scr->search(MULTI_CHAR('menu_6n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
mBrightCheck.Scr->search(MULTI_CHAR('menu_9n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
mBrightCheck.Scr->search(MULTI_CHAR('menu_10n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
mBrightCheck.Scr->search(MULTI_CHAR('menu_7n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
mBrightCheck.Scr->search(MULTI_CHAR('menu_8n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
mBrightCheck.Scr->search(MULTI_CHAR('fmenu_8n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
mBrightCheck.Scr->search(MULTI_CHAR('fmenu_7n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
mBrightCheck.Scr->search(MULTI_CHAR('fmenu_10'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
mBrightCheck.Scr->search(MULTI_CHAR('fmenu_6n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
mBrightCheck.Scr->search(MULTI_CHAR('fmenu_9n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
mBrightCheck.Scr->search(MULTI_CHAR('t_t00'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
mBrightCheck.Scr->search(MULTI_CHAR('f_t00'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
// Spirals
mBrightCheck.Scr->search(MULTI_CHAR('t_mo_l_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
mBrightCheck.Scr->search(MULTI_CHAR('t_mo_r_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
}
#endif
void dBrightCheck_c::_draw() {
#if TARGET_PC
brightCheckWide();
#endif
dComIfGd_set2DOpa(&mBrightCheck);
}
+27 -2
View File
@@ -23,6 +23,10 @@
#include <cmath>
#include <cstring>
#if TARGET_PC
#include "dusk/settings.h"
#endif
#if DEBUG
#include "d/d_debug_pad.h"
#include "d/d_debug_camera.h"
@@ -762,6 +766,13 @@ void dCamera_c::updatePad() {
var_f29 = 0.0f;
} else {
var_f31 = mDoCPd_c::getSubStickX3D(mPadID);
#if TARGET_PC
if (dusk::getSettings().game.invertCameraXAxis) {
var_f31 *= -1.0f;
}
#endif
var_f30 = mDoCPd_c::getSubStickY(mPadID);
var_f29 = mDoCPd_c::getSubStickValue(mPadID);
}
@@ -1348,6 +1359,20 @@ bool dCamera_c::Run() {
clrFlag(0x1000);
mTagCamTool.Clr();
field_0x89c.Clr();
#if TARGET_PC
if (dusk::getSettings().game.vrCamera && link != nullptr) {
MtxP headMtx = link->getHeadMtx();
cXyz headForward(headMtx[0][0], headMtx[1][0], headMtx[2][0]);
// place eye slightly in front of Link's eye position, looking forward
static constexpr f32 EYE_FORWARD_OFFSET = 20.0f;
static constexpr f32 CENTER_DISTANCE = 200.0f;
mEye = mViewCache.mEye = link->eyePos + headForward * EYE_FORWARD_OFFSET;
mCenter = mViewCache.mCenter = mEye + headForward * CENTER_DISTANCE;
}
#endif
return sp0F;
}
@@ -10149,9 +10174,9 @@ bool dCamera_c::eventCamera(s32 param_0) {
mEye = mCenter + mDirection.Xyz();
}
int* sp90_i;
BE(int)* sp90_i;
if (getEvStringData(sp90, "Trim", "DEFAULT") != false) {
sp90_i = (int*)sp90;
sp90_i = (BE(int)*)sp90;
if (*sp90_i == 'STAN') {
mEventData.field_0x1c = 0;
} else if (*sp90_i == 'VIST') {
+9 -8
View File
@@ -9,8 +9,9 @@
#include "d/d_com_inf_game.h"
#include "d/d_jnt_col.h"
#include "f_op/f_op_actor_mng.h"
#include "dusk/imgui/ImGuiConsole.hpp"
#if TARGET_PC
#include "dusk/settings.h"
#endif
class dCcS_HIO : public JORReflexible {
public:
@@ -770,19 +771,19 @@ void dCcS::Draw() {
#endif
#if TARGET_PC
#define IMGUI_TOGGLE_HIO_FLAG(status, flag) \
#define DUSK_TOGGLE_HIO_FLAG(status, flag) \
if (status) { \
s_Hio.m_flags |= flag; \
} else { \
s_Hio.m_flags &= ~flag; \
}
dusk::ImGuiMenuTools::CollisionViewSettings collisionViewSettings = dusk::g_imguiConsole.getCollisionViewSettings();
IMGUI_TOGGLE_HIO_FLAG(collisionViewSettings.m_enableAtView, dCcS_HIO::FLAG_AT_ON_e);
IMGUI_TOGGLE_HIO_FLAG(collisionViewSettings.m_enableTgView, dCcS_HIO::FLAG_TG_ON_e);
IMGUI_TOGGLE_HIO_FLAG(collisionViewSettings.m_enableCoView, dCcS_HIO::FLAG_CO_ON_e);
const auto& collisionViewSettings = dusk::getTransientSettings().collisionView;
DUSK_TOGGLE_HIO_FLAG(collisionViewSettings.enableAtView, dCcS_HIO::FLAG_AT_ON_e);
DUSK_TOGGLE_HIO_FLAG(collisionViewSettings.enableTgView, dCcS_HIO::FLAG_TG_ON_e);
DUSK_TOGGLE_HIO_FLAG(collisionViewSettings.enableCoView, dCcS_HIO::FLAG_CO_ON_e);
f32 view_opacity = 255 * (collisionViewSettings.m_colliderViewOpacity / 100.0f);
f32 view_opacity = 255 * (collisionViewSettings.colliderViewOpacity / 100.0f);
#endif
if (s_Hio.CheckAtOn()) {
+17
View File
@@ -1398,7 +1398,12 @@ void dDlst_shadowSimple_c::set(cXyz* param_0, f32 param_1, f32 param_2, cXyz* pa
}
void dDlst_shadowControl_c::init() {
#if TARGET_PC
// Increase shadow map resolution
static u16 l_realImageSize[2] = {1024, 512};
#else
static u16 l_realImageSize[2] = {192, 64};
#endif
for (int i = 0; i < 2; i++) {
u16 size = l_realImageSize[i];
@@ -1471,11 +1476,18 @@ void dDlst_shadowControl_c::imageDraw(Mtx param_0) {
int tex = 0;
u16 r27;
u16 r26;
#ifdef TARGET_PC
bool needsRestore = false;
#endif
for (; shadowReal; shadowReal = shadowReal->getZsortNext()) {
if (shadowReal->isUse()) {
if (r29 == 0) {
r27 = GXGetTexObjWidth(field_0x15eb0 + tex);
r26 = r27 * 2;
#ifdef TARGET_PC
GXCreateFrameBuffer(r26, r26);
needsRestore = true;
#endif
GXSetViewport(0.0f, 0.0f, r26, r26, 0.0f, 1.0f);
GXSetScissor(0, 0, r26, r26);
}
@@ -1503,6 +1515,11 @@ void dDlst_shadowControl_c::imageDraw(Mtx param_0) {
GXPixModeSync();
GXSetAlphaUpdate(GX_DISABLE);
}
#ifdef TARGET_PC
if (needsRestore) {
GXRestoreFrameBuffer();
}
#endif
GXSetClipMode(GX_CLIP_ENABLE);
GXSetDither(GX_TRUE);
}

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