Compare commits

..

319 Commits

Author SHA1 Message Date
MelonSpeedruns 1c1a849095 Recording Mode & Enable Autosave in Dusk preset (#685)
* branch for recording without a HUD

* no more black bars thanks maddie

* Backslash hotkey

* mute music

* dont check for null twice

* renamed option to recording mode, and added it to the rmlui menu

* Move recording mode to Interface

* re-added & renamed minimal hud option

* Mute all BGM if recording mode is on

* Update Interface section

* Un-experimentalize Autosave & enable in Dusk preset

---------

Co-authored-by: MelonSpeedruns <melonspeedruns@stratobox.net>
Co-authored-by: Irastris <irastris15@gmail.com>
Co-authored-by: Luke Street <luke@street.dev>
2026-05-07 23:26:22 -06:00
Phillip Stephens 89d393e57a Add missing climits include 2026-05-07 22:24:31 -07:00
Phillip Stephens 2f27687d80 Fix OSReport strings corruption with non-trivial format (#709)
* Fix OSReport strings corruption with non-trivial format

* Limit format attempts to 3
2026-05-07 23:10:23 -06:00
SuperDude88 167a50c01d Deselect Sub-Menu On Focus Change (#710)
- Unselect any previous items when focusing a new one

This might be way over-inclusive so it should be scrutinized harshly (but fixes #672)
2026-05-07 23:09:25 -06:00
SuperDude88 313f03f5e5 Dim Carousel Arrows
- Dim carousel arrows if there are no further options in that direction (closes #708)

This sets the color property constantly, not sure if that is a concern for perf (would imagine not since it already sets the rml to mValueElem every frame also?)
2026-05-07 23:05:08 -06:00
Howard Luck 6cfdc3d8a3 add keyboard controls + roll support to fly cam (#705) 2026-05-07 23:04:29 -06:00
Luke Street 9c24a0bc4b Disable Development Mode & move Input Viewer
Resolves #712
2026-05-07 23:03:26 -06:00
TakaRikka b99ad920c4 Merge pull request #704 from TwilitRealm/ira/rmlui-confirmation
Add confirmations modals to Reset and Quit
2026-05-07 13:57:03 -07:00
TakaRikka 912b18eca1 Merge pull request #703 from TwilitRealm/ui/advanced-settings
Advanced Settings
2026-05-07 13:55:13 -07:00
TakaRikka 9e651a51db Merge pull request #700 from TwilitRealm/ira/rmlui-fps
Add FPS counter to RmlUi
2026-05-07 13:51:51 -07:00
TakaRikka c8b6e997a7 Merge pull request #702 from TwilitRealm/ira/rmlui-inputconfig
Add remaining controller config options to RmlUi
2026-05-07 13:45:35 -07:00
Irastris 928e187524 Add mobile layout for prelaunch 2026-05-07 15:57:52 -04:00
Irastris cf12d19860 Resolve RmlUi deprecation warning, add L1/R1 tabbing to MenuBar 2026-05-07 13:48:12 -04:00
Irastris e3a3ac56fb Add confirmations modals to Reset and Quit 2026-05-07 13:32:59 -04:00
MelonSpeedruns d15ed81cd5 Only show Editor if Advanced Settings is enabled 2026-05-07 12:39:37 -04:00
TakaRikka ff054f6f47 update aurora and enable MTX_USE_PS 2026-05-07 09:36:32 -07:00
MelonSpeedruns 667cf70fa0 Add Advanced Settings option & Disable debug hotkeys if it's off 2026-05-07 12:01:32 -04:00
Irastris 73eb401c93 Add remaining controller config options, remove ImGui config 2026-05-07 12:00:35 -04:00
Irastris b11f3add06 Don't immediately dismiss prelaunch if skip config is toggled
Prevents a situation where memcard is not init until restarting after the deferral change
2026-05-07 09:26:41 -04:00
Irastris 92f888a152 Remove blur and shadow from counter, consolidate options 2026-05-07 03:28:30 -04:00
Irastris 78ed5cc716 Add FPS counter 2026-05-07 03:13:08 -04:00
Luke Street 3968b67c5d Disc verification cleanup 2026-05-07 00:35:00 -06:00
Luke Street 119830c979 Merge pull request #695 from TwilitRealm/hash-verif
Hash verification for disc images
2026-05-06 23:41:57 -06:00
Luke Street 647394c875 Don't hash on startup & cleanup 2026-05-06 23:33:55 -06:00
Luke Street c50d777309 Progress modal & persist validation state 2026-05-06 23:21:43 -06:00
Luke Street 4954685cca Merge branch 'main' into hash-verif 2026-05-06 22:09:20 -06:00
qwertyquerty 39d43a8d8f Keyboard mouse binding controls (#682)
* kbm controls

* submodule

* files.cmake

* a

* Fixes

* include <cstring> in J3DStruct.h

---------

Co-authored-by: Luke Street <luke@street.dev>
2026-05-06 22:07:28 -06:00
TakaRikka b4761cc54e fix build 2026-05-06 20:36:21 -07:00
qwertyquerty 9aee2e9cfe PS math accuracy (#654)
* math accuracy

* submodule

* Update aurora

---------

Co-authored-by: Luke Street <luke@street.dev>
2026-05-06 21:22:59 -06:00
Luke Street 7c7c8b228e Crafty's crafty Dungeon door hack 2026-05-06 19:53:18 -06:00
doop ca7714dafd Merge pull request #697 from TwilitRealm/include-numbers
Try to fix Windows/macOS build errors
2026-05-06 21:09:53 -04:00
doop 1ad5ab8632 Try to fix Windows/macOS build errors 2026-05-07 01:02:43 +00:00
Irastris c4e7838089 Swap shield labels in RmlUi editor 2026-05-06 21:02:15 -04:00
roeming 7313712263 update area flags to precalculate correct offsets/masks (#694)
Co-authored-by: roeming <roeming@users.noreply.github.com>
2026-05-06 18:40:10 -06:00
doop aa48d95f24 Procedurally-generate HQ minimap textures (#692)
* Procedurally-generate HQ minimap textures

* Don't leak old minimap textures
2026-05-06 18:40:04 -06:00
Thomas c5baabbe9c assets: Remove objdiff screenshot (#691)
Leftover from the decomp.
2026-05-06 18:38:01 -06:00
Irastris 1d2716139f Redesign PresetWindow 2026-05-06 19:49:57 -04:00
MelonSpeedruns 742ad2c150 Increase Link's heap size for mods 2026-05-06 19:48:43 -04:00
Luke Street 18eb0692f0 UI: "No controller" & menu notifications
Resolves #629
Resolves #678
2026-05-06 17:34:08 -06:00
Irastris b5f98f69db Redesign Modal 2026-05-06 19:19:38 -04:00
Irastris 47593d0eb4 Allow hash-mismatched discs to be loaded with user confirmation 2026-05-06 19:19:38 -04:00
Irastris 4404fce369 Do hash-based verification of disc images 2026-05-06 19:19:38 -04:00
Irastris 72c20f4dd0 Add stylesheet rules 2026-05-06 19:19:38 -04:00
doop 3240885bfd Preserved doop work
* Disc verification

* Add platform and region info to known discs map

* Use array over map

* Use std::to_array
2026-05-06 19:19:38 -04:00
Luke Street 7f0955f022 Add ImGui screen for Aurora Null backend
Resolves #628
2026-05-06 16:39:28 -06:00
Luke Street c21bce0093 UI: Adjust battery icon thresholds 2026-05-06 11:49:24 -06:00
Luke Street 4e23472ed5 UI: Controller connect/disconnect toasts 2026-05-06 11:14:12 -06:00
doop cfe1f2304b Increase line-height for right pane descriptions 2026-05-06 13:15:30 +00:00
TakaRikka de6568d750 allow suns song / quick transform in ToT past 2026-05-06 04:25:42 -07:00
TakaRikka 3aafe7fa16 more mirror mode map fixes 2026-05-06 04:19:00 -07:00
Luke Street c1e65d19e7 Autosave: Rotate inner ring too 2026-05-05 23:57:20 -06:00
Luke Street 5fdf954994 Reduce autosave spinner opacity 2026-05-05 23:25:06 -06:00
Luke Street 230868af3c Add autosave spinner & make RmlUi respect 4:3
Resolves #627
2026-05-05 23:18:11 -06:00
doop 66154d9de8 Remove post-trim scissor (#684)
* Remove post-trim scissor

Fixes #679

* Add comment
2026-05-05 19:41:59 -06:00
Luke Street 93ec3c7dbd New UI: Achievement toasts (#690)
* Rename Overlay -> GraphicsTuner, Popup -> MenuBar

* Update GraphicsTuner CSS

* WIP Overlay document & toasts

* Achievement toasts

* Cleanup
2026-05-05 19:29:42 -06:00
MelonSpeedruns 945ce3e4bc Alternate RMLUI Menu Sounds (#686)
* Alternate RMLUI Menu Sounds

Those fit more the game I feel like.

* swapped tab sounds

* pressing A on tab button plays the OK sound

* Fix tab sound + Added menu sounds to prelaunch menu

* Centralize UI sound definitions

* Improvements

* Add "Play" button sound

* Use kSoundItemFocus in prelaunch

* Oops

* Update play/enable/disable sounds

---------

Co-authored-by: MelonSpeedruns <melonspeedruns@stratobox.net>
Co-authored-by: Luke Street <luke@street.dev>
2026-05-05 16:44:11 -06:00
TakaRikka 782a8573e9 Merge pull request #570 from TwilitRealm/mapmirror
fix main map for mirror mode
2026-05-05 14:22:25 -07:00
Irastris 4e0ca51159 Remove restart notice from cardFileType's rightPane 2026-05-05 17:03:04 -04:00
Irastris 3cd160e1b2 Defer mDoMemCd_ThdInit if necessary, removing restart requirement
Thanks, Melon
2026-05-05 16:56:41 -04:00
Luke Street 93a236a9d2 Prelaunch settings: actually save config 2026-05-05 14:47:53 -06:00
Irastris eaf3bc2f40 Remove skipWarningScreen config option, always skip logos 2026-05-05 16:27:41 -04:00
Luke Street 5ca0a2ba06 UI: Fix focus reconciliation for context root 2026-05-05 14:17:57 -06:00
Luke Street ccd2bdbaac Add full Settings window to prelaunch 2026-05-05 14:12:53 -06:00
Irastris 08321699cd Display the real title screen behind the prelaunch menu (#638)
* Start game execution as soon as a disk image is available

* Do not update dDemo_c if prelaunch document is visible

* Prevent intro music until prelaunch has popped

* Replace "Start Game" references with "Play"

* Make prelaunch layout respect mirror mode

* Add drop shadow to prelaunch disk-status and version-info

* Remove ImGui prelaunch

* Add "Change Disk Image" button to prelaunch options

* Actually validate discs and make prelaunch very betterer :)

* Check your build before pushing dumbass, and go to sleep

* "Disc" consistency, adjust restart notice logic

* Better LanguageSelect logic

* Add restart notice to SaveTypeSelect

* Added wind sounds to the pre-launch menu

* Add Modal document, use it for disc verification

* Consolidate Modal and PresetWindow

* Squash various bugs, rearrange document flow

* Allow Window inheritors to opt-out of being toggleable

* Tweak focus behavior/syntax

* Implement "Restart Now" option

* Tweaks

* Remove a bunch of dynamic_cast

* Update README.md

---------

Co-authored-by: Luke Street <luke@street.dev>
2026-05-05 12:18:25 -06:00
Luke Street 7300c0e0f5 Update aurora 2026-05-05 12:15:01 -06:00
Luke Street 7e562824fe Add a <br> 2026-05-05 11:30:49 -06:00
Luke Street ed8b5c96b9 Update aurora & add logo to README.md 2026-05-05 11:28:05 -06:00
TakaRikka 14bccdffa6 fix mirror map portal selection 2026-05-05 06:25:46 -07:00
TakaRikka 39e465bcab fix mirror map region selection 2026-05-05 06:22:49 -07:00
TakaRikka e53bb3a12d Merge branch 'main' of github.com:TwilitRealm/dusk into mapmirror 2026-05-05 04:59:25 -07:00
TakaRikka 50fccd393f fix mirror mode text / rodeo direction 2026-05-05 04:44:14 -07:00
TakaRikka 7993740ac8 fix kargorok mirror mode controls 2026-05-05 01:16:01 -07:00
TakaRikka 8e5bb8ae59 Merge pull request #676 from TwilitRealm/instant-text-tweaks
Instant text tweaks
2026-05-04 23:43:43 -07:00
TakaRikka 8fefdd4114 Merge pull request #669 from TwilitRealm/remove-discord-rpc
Remove discord-rpc/rapidjson; roll our own
2026-05-04 23:43:24 -07:00
gymnast86 64c8cee21b revert to checking for Hold B at the start of do_isReady 2026-05-04 23:08:01 -07:00
gymnast86 25fe686573 add message ids for not being able to buy bombs from barnes 2026-05-04 23:07:23 -07:00
Luke Street 1c1ea98fdd Update aurora 2026-05-04 23:35:21 -06:00
TakaRikka e098104f8f Merge pull request #642 from TwilitRealm/debug-fly-cam
Add fly mode option to debug cam
2026-05-04 19:25:19 -07:00
Pheenoh 3c5ade5565 don't allow activation if paused or in event 2026-05-04 20:15:02 -06:00
Pheenoh b2ad75027e Merge branch 'main' into debug-fly-cam 2026-05-04 19:26:31 -06:00
TakaRikka fdfbf83b88 Merge pull request #660 from TwilitRealm/fix/fix-ub
Fix a UB in Morpheel
2026-05-04 18:24:16 -07:00
SuperDude88 1b9ca0949e Clear Description on More Hovers (#673)
- Properly clear the previous option description when you hover over "toggle fullscreen" or "restore default window size"

Fixes #671
2026-05-04 19:17:39 -06:00
Luke Street 827037f0fa Update aurora for RmlUi base path fix 2026-05-04 18:27:50 -06:00
Luke Street d84c5790f5 NOMINMAX 2026-05-04 16:27:12 -06:00
Luke Street 49eb2282af Forgor to add 2026-05-04 16:20:30 -06:00
Luke Street 741f9ecfab Remove discord-rpc/rapidjson; roll our own 2026-05-04 16:14:57 -06:00
Luke Street 37b8122962 UI: Refactor pane control to allow hover for help text 2026-05-04 14:16:35 -06:00
doop 5f2cf68e80 Minor UI nits 2026-05-04 19:38:11 +00:00
Luke Street 74f2c58b29 UI: Preset tweaks 2026-05-04 13:08:20 -06:00
madeline 208433047a Merge branch 'main' of https://github.com/TakaRikka/dusk 2026-05-04 12:06:28 -07:00
madeline 2c01430035 fix stereo audio with mirror mode fixes #666 2026-05-04 12:06:24 -07:00
Luke Street 5121437bcf UI: Avoid looping at end of window content 2026-05-04 11:49:12 -06:00
Luke Street f61bd3e5ad UI: Reorder settings tabs 2026-05-04 11:31:09 -06:00
Luke Street 835e409b32 UI: Fix prelaunch options close anim 2026-05-04 11:27:31 -06:00
Luke Street 010bdb7e25 UI: Fix left/right nav from content to change tabs 2026-05-04 11:17:48 -06:00
Luke Street 7ba22b7714 UI: Refocus top document automatically 2026-05-04 11:14:40 -06:00
Luke Street efcb19a3d0 Revert hide change to popup menu 2026-05-04 10:49:57 -06:00
Luke Street 55455bb1b5 Adjust presets & default settings 2026-05-04 10:43:42 -06:00
qwertyquerty e49be12297 RmlUi improvements (#663)
* rmlui audio

* fix menu select sound

* Fixes #662

* fix reset logic and fix popup getting stuck closed

* fix X button on menu popup

* rmlui achievements, and fix open/close bug

* presets, achievements css, and menu sounds toggle

* forgor

* fix b button causing audio when menu not visible
2026-05-04 10:25:13 -06:00
MelonSpeedruns 75f4940f5e set field_0xbaf variable like all the other conditions 2026-05-04 11:29:29 -04:00
MelonSpeedruns 8047330952 oops i suck 2026-05-04 09:55:01 -04:00
MelonSpeedruns 9105dcb078 remove empty line 2026-05-04 09:54:24 -04:00
MelonSpeedruns b8e38e03e2 Apply PJB request 2026-05-04 09:54:00 -04:00
MelonSpeedruns 331352878e Fix a UB in morpheel 2026-05-04 08:41:19 -04:00
Luke Street 62a88f1e9a UI: Add warning icons to experimental settings 2026-05-03 23:44:38 -06:00
Luke Street 43b603e70b UI: 3-finger tap to toggle menu on mobile 2026-05-03 22:39:31 -06:00
doop 95e6ac54cf Random UI and README tweaks (#653) 2026-05-03 22:02:09 -06:00
Luke Street c4b2e2e501 Make prelaunch fade out smoother 2026-05-03 22:01:02 -06:00
Luke Street dccba23980 Update aurora 2026-05-03 20:47:14 -06:00
Luke Street bf27d10519 Revert "Convert UI fonts to WOFF2 (#647)" (#648)
This reverts commit 6c27011e32.
2026-05-03 20:41:24 -06:00
doop 6c27011e32 Convert UI fonts to WOFF2 (#647)
* Convert UI fonts to WOFF2

* ...except for the ones we use for ImGui
2026-05-03 20:36:55 -06:00
Luke Street 6220990dc5 UI: Use decorator: text for close button 2026-05-03 19:01:44 -06:00
Phillip Stephens 93e9767c9f Fix OSReport crash on linux, harden FormatToString against malformed strings (#640)
* Fix OSReport crash on linux, harden FormatToString against malformed strings

* Move size increment to after error check

* Update aurora and impl OSPanic

---------

Co-authored-by: Luke Street <luke@street.dev>
2026-05-03 18:50:49 -06:00
Luke Street c774f53dad UI: Fix L/R to switch tabs
Resolves #645
2026-05-03 18:36:06 -06:00
Luke Street 7fbfe5ad88 UI: Add close button to tab bar 2026-05-03 18:29:08 -06:00
Luke Street ef02037990 Remove ESC to exit fullscreen 2026-05-03 17:26:17 -06:00
Luke Street 23cc18ba0e UI: Press ESC to unbind a button
Resolves #562
2026-05-03 17:26:17 -06:00
Luke Street 924dbc7715 UI: Implement controller config
Resolves #622
2026-05-03 17:26:17 -06:00
TakaRikka 742f4938f2 Merge pull request #641 from TwilitRealm/fix/klift00
Frame Interp: Fix obj_klift00 chains
2026-05-03 15:32:35 -07:00
TakaRikka 02e0f586d3 Merge pull request #639 from TwilitRealm/fix/fyer_cs
Frame Interp: Fix Fyer canon repair cutscene
2026-05-03 15:31:09 -07:00
Luke Street 5717aeef85 UI: Bold modified settings values 2026-05-03 16:01:33 -06:00
Luke Street da9b99f650 Update aurora 2026-05-03 15:28:03 -06:00
Pheenoh 901ce2ee4c add debug fly cam option 2026-05-03 15:23:59 -06:00
Pheenoh dd2b993cd5 frame interp: fix obj_klift00 chains 2026-05-03 09:58:31 -06:00
Pheenoh 83577d3b82 frame interp: fix fyer canon repair cs 2026-05-03 09:20:41 -06:00
TakaRikka 1cb8b19520 Merge pull request #612 from TwilitRealm/26-05-01-gameheap-size
Increase gameHeap size by an order of magnitude
2026-05-03 00:18:37 -07:00
TakaRikka d109cd891e add note 2026-05-03 00:07:37 -07:00
doop 63c4002ca6 Fix prelaunch nav cycling 2026-05-03 05:49:53 +00:00
Lurs 6954efcd15 Should fix #636 2026-05-03 06:46:49 +02:00
Jasper St. Pierre 78c2147771 midna eye lod fix 2026-05-02 15:36:00 -07:00
Irastris c938d5468e Add Interface tab to RmlUi, remove ImGui interface menu 2026-05-02 18:16:42 -04:00
Irastris 35590c5312 Increase font size for pane text 2026-05-02 17:24:10 -04:00
Luke Street e976b10e2a UI: Avoid overlapping ImGui menu bar 2026-05-02 15:22:24 -06:00
Irastris 3949706b28 Revise gyro aim help text, remove ImGui input menu 2026-05-02 17:19:41 -04:00
Irastris ce55916845 Add Autosave to RmlUi, remove ImGui gameplay menu, formatting consistency 2026-05-02 17:01:30 -04:00
Irastris 9b252cbdd2 Remove ImGui cheats menu 2026-05-02 16:33:50 -04:00
Irastris 97fa09f6ee Add spatial sound option to RmlUi, remove ImGui audio menu 2026-05-02 16:05:57 -04:00
TakaRikka 0e7a7cccb9 Merge pull request #458 from TwilitRealm/feature/autosave
Autosave Feature
2026-05-02 13:03:29 -07:00
Irastris 1c0cdcc176 Typo 2: Electric Boogaloo 2026-05-02 15:54:42 -04:00
Irastris 280305c2ba Typo 2026-05-02 15:33:44 -04:00
Luke Street d1f1d579bc Prevent macOS crash on shutdown by tracking logging dtor (#626) 2026-05-02 13:22:28 -06:00
Irastris eeeb3ffe25 Remove ImGui graphics menu 2026-05-02 14:45:34 -04:00
Jasper St. Pierre 1ee0f862e1 map highlight fix 2026-05-02 11:45:01 -07:00
Jasper St. Pierre 6b327c9f61 disable jpa interp for now
closes #618
2026-05-02 11:44:21 -07:00
Luke Street f148e0ebc1 UI: Rework Document close handling again 2026-05-02 12:39:07 -06:00
Jasper St. Pierre 6f20f4d629 compile fix 2026-05-02 10:54:45 -07:00
Irastris 94670270d6 Fix prelaunch menu transition post-startup 2026-05-02 13:52:20 -04:00
Luke Street 8e21247a97 UI: Prelaunch fade + BG persistence 2026-05-02 11:32:59 -06:00
Luke Street aa84004cb4 Merge branch 'rmlui-integration' 2026-05-02 10:50:18 -06:00
Luke Street e1c201f4bd Make prelaunch sticky & kill ImGui prelaunch 2026-05-02 10:44:59 -06:00
MelonSpeedruns 425a1d15a0 Merge remote-tracking branch 'origin/main' into feature/autosave 2026-05-02 10:56:36 -04:00
MelonSpeedruns e3ad41792a fix respawn stageinfo when autosaving 2026-05-02 10:42:20 -04:00
MelonSpeedruns c1ba10fc8b fix mistake 2026-05-02 10:29:23 -04:00
TakaRikka 1c5686f71b Merge pull request #616 from TwilitRealm/HRTF
Emulate Surround option
2026-05-01 22:51:25 -07:00
TakaRikka b9e0f2b9ca Merge pull request #611 from TwilitRealm/26-05-01-heap-crash-log
Improve heap crash logging
2026-05-01 22:19:33 -07:00
TakaRikka ede175f141 Merge pull request #600 from TwilitRealm/fix/fix-bow-aiming
Fix bow aiming in first person
2026-05-01 22:18:14 -07:00
TakaRikka a301874e30 Merge pull request #592 from TwilitRealm/fix/free-cam-fix
Freecam Fixes
2026-05-01 22:17:21 -07:00
Irastris 9b4a9a6bd9 Initial attempt at the prelaunch document 2026-05-02 00:10:11 -04:00
Luke Street 04274b1884 Make RmlUi F1, ImGui Shift+F1 2026-05-01 21:53:48 -06:00
Luke Street ca783b8424 Merge branch 'main' into rmlui-integration
# Conflicts:
#	extern/aurora
2026-05-01 21:24:24 -06:00
Luke Street 2e4c2b5b46 UI: Add controller input 2026-05-01 21:24:12 -06:00
Luke Street 4c09d8b910 Fix restoring scroll position on pop 2026-05-01 17:40:38 -06:00
Luke Street fb1b260d09 Add Input tab to settings 2026-05-01 16:52:08 -06:00
Luke Street 98eb8f718e Add Bloom settings 2026-05-01 16:32:04 -06:00
Luke Street 68b2e0ee2d Rework Settings components 2026-05-01 16:14:20 -06:00
Luke Street 81771a0522 Editor Collection, Minigame, Config tabs 2026-05-01 14:12:12 -06:00
madeline 93c8bcc210 hrtf 2026-05-01 13:04:08 -07:00
Luke Street 176bf5f0c4 Editor inventory tab 2026-05-01 13:11:43 -06:00
Luke Street 65a5945778 Location tab in editor 2026-05-01 12:37:40 -06:00
Luke Street 8f7b9cdfdd Dual pane navigation & more player editor 2026-05-01 12:06:05 -06:00
MelonSpeedruns acecba7ff7 Reset camera zoom to 0 if freecam is enabled mid-game 2026-05-01 12:54:40 -04:00
MelonSpeedruns 507e0aadbc Merge remote-tracking branch 'origin/main' into fix/free-cam-fix 2026-05-01 12:54:12 -04:00
Jasper St. Pierre 8406d9b192 Merge pull request #613 from TwilitRealm/widescreen/wide-hidden-village
Wide Bulblin count in Hidden Village
2026-05-01 09:04:23 -07:00
Jasper St. Pierre 6f3170cb56 Merge pull request #604 from TwilitRealm/widescreen/dmap-menu
Widescreen Dungeon Map
2026-05-01 09:04:08 -07:00
Jasper St. Pierre 835582224e Merge pull request #601 from TwilitRealm/fix/fmap-widescreen
Widescreen Field Map
2026-05-01 09:04:00 -07:00
MelonSpeedruns 52879f50f0 Wide Bulblin count in Hidden Village 2026-05-01 11:47:18 -04:00
Irastris 2b505f1be4 Revise floating scrollbar margin 2026-05-01 11:19:51 -04:00
Irastris f089f9024d Centralize tab styling and other tidying 2026-05-01 11:13:14 -04:00
roeming 43fb421a93 Merge pull request #608 from TwilitRealm/location-flags-ui
Area flags UI
2026-05-01 07:26:23 -04:00
PJB3005 f06d6b50a9 Fix Plumm game score reset
Fixes #609
2026-05-01 09:27:45 +02:00
Jasper St. Pierre 2c987b0211 build fix 2026-05-01 00:17:51 -07:00
Jasper St. Pierre 3d860ad454 jpa interp start 2026-05-01 00:12:26 -07:00
Luke Street b5bf19569b Button: Selected but not active style 2026-05-01 01:01:38 -06:00
PJB3005 5a7f5cb4a7 Increase gameHeap size by an order of magnitude
Why not?
2026-05-01 08:57:37 +02:00
Luke Street 1affefbbfc Pane: Focus selected child first 2026-05-01 00:56:53 -06:00
PJB3005 e4ff38a712 Disable spammy mDoGph_Painter log line
What was this even debugging? Who knows.
2026-05-01 08:54:32 +02:00
PJB3005 f2ac4d6f44 Leave OSReport enabled. 2026-05-01 08:52:41 +02:00
PJB3005 48b98a5432 Make JKRExpHeap OOM logging more verbose 2026-05-01 08:50:55 +02:00
PJB3005 a4752154f7 Nicely plumb OSReport error/warning/etc through Aurora's logger
This makes a new implementation in the dusk src folder, and makes the existing file containing these functions not compiled anymore.

A ton of dead code is now gone.
2026-05-01 08:50:42 +02:00
Luke Street 0d973a497b Editor: Add get_item_name 2026-05-01 00:40:57 -06:00
Luke Street ab4eccf1df Some more dual pane select work 2026-05-01 00:26:04 -06:00
Luke Street e0c449f28e Improve add_child and Button APIs 2026-04-30 23:36:30 -06:00
Jasper St. Pierre ce9a5c06d5 heap name 2026-04-30 22:19:19 -07:00
Jasper St. Pierre 2bbba1e4e8 couple small fixes 2026-04-30 21:37:28 -07:00
Luke Street 39298f8d8f Preserve focused element on pop 2026-04-30 22:31:24 -06:00
Luke Street 32b4c0567a Animate overlay open/close 2026-04-30 22:17:48 -06:00
Jasper St. Pierre 7ff1b5332e Merge pull request #606 from dooplecks/trim-correction
Correct trim height for arbitrary aspect ratios
2026-04-30 20:38:03 -07:00
Jasper St. Pierre 5e77a60bd6 Merge pull request #610 from dooplecks/shadow-interp
Interpolate shadow camera
2026-04-30 20:36:53 -07:00
doop 9629c000bd Interpolate shadow camera
Fixes #454.
2026-05-01 03:25:07 +00:00
Luke Street 9dc5fed686 Fix overlay CSS 2026-04-30 21:12:25 -06:00
Luke Street 2cc9db77dd Fix overlay 2026-04-30 21:10:48 -06:00
Luke Street 8aa08c9443 Window animations & tags instead of classes 2026-04-30 20:55:21 -06:00
Irastris dca3e2eba6 Overlay: I forgot about pop_document()
This in turn fixes a bug that I was about to bother encounter about, smh
2026-04-30 21:54:52 -04:00
Irastris 57061fba38 Initial attempt at the overlay document 2026-04-30 21:39:39 -04:00
Luke Street cee6a24309 UI: Defer document destruction 2026-04-30 17:46:36 -06:00
Luke Street 62edb3abc6 UI: Implement initial document stack logic 2026-04-30 17:21:55 -06:00
Luke Street 1c9e1c0a66 Minor clean 2026-04-30 16:15:27 -06:00
Luke Street a06aeb10c1 Extract TabBar component 2026-04-30 16:13:08 -06:00
roeming b84b309e00 compilation fix attempt 3 2026-04-30 17:51:52 -04:00
roeming 62eecb3ccd compilation fix attempt 2 2026-04-30 17:48:39 -04:00
roeming ec07572ced compilation fix attempt 2026-04-30 17:45:53 -04:00
roeming b45e2fa34d swap array for named variables 2026-04-30 17:25:24 -04:00
roeming 289a718446 fix comment wording 2026-04-30 17:10:33 -04:00
roeming 292a2a6c34 fix wrong formatting, fix duplicate ui object, fix wrong flags getting set 2026-04-30 17:03:47 -04:00
Luke Street 2e8415b950 Update aurora 2026-04-30 14:43:44 -06:00
roeming dbf1f6e354 implement multibyte area flags in UI 2026-04-30 16:25:56 -04:00
roeming 9a2fe9745d Draw area flags as table 2026-04-30 15:55:59 -04:00
Irastris b5ca343fac Fix apostrophes in strings 2026-04-30 15:50:01 -04:00
doop 88c7ff63ff Fix preprocessor conditional 2026-04-30 19:48:03 +00:00
Luke Street 7a438ad30f UI: Extract a Document class 2026-04-30 13:44:33 -06:00
doop 89649de7c3 Correct trim height for arbitrary aspect ratios
Fixes #543.
2026-04-30 19:39:36 +00:00
Irastris a1960eaa33 Initial attempt at the popup menu 2026-04-30 15:30:14 -04:00
MelonSpeedruns d6820c9233 fix toast call 2026-04-30 14:53:15 -04:00
MelonSpeedruns 5c4bb8d33d Merge remote-tracking branch 'origin/main' into feature/autosave
# Conflicts:
#	src/dusk/imgui/ImGuiConsole.cpp
2026-04-30 14:51:17 -04:00
MelonSpeedruns e3ce1f01c9 Widescreen Dungeon Map 2026-04-30 14:38:24 -04:00
Luke Street 9b6b344ecf Revert "mirror clip fix"
This reverts commit 1ac6df8de7.
2026-04-30 12:09:18 -06:00
Luke Street 3db85d5b44 Merge branch 'main' into rmlui-integration
# Conflicts:
#	extern/aurora
2026-04-30 12:04:21 -06:00
roeming b5871d72d9 fix build 2026-04-30 11:47:22 -04:00
roeming b70a714f88 Remove missed randomizer flag 2026-04-30 11:45:16 -04:00
roeming cad5a8d1bc Add multibyte flags to Area iterators 2026-04-30 11:43:57 -04:00
roeming 93f8a5fa8f Move area multi flag bits to combined flags, at most 2 2026-04-30 11:11:08 -04:00
roeming b0809ea78c Add area flags 2026-04-30 11:02:18 -04:00
MelonSpeedruns b0e9033736 Widescreen Field Map 2026-04-30 10:55:53 -04:00
Jasper St. Pierre 1ac6df8de7 mirror clip fix
closes #581
2026-04-30 07:52:44 -07:00
MelonSpeedruns 5899b2157a fix bow aiming in first person 2026-04-30 09:29:42 -04:00
Luke Street 3185f578fb Update aurora 2026-04-30 01:45:54 -06:00
Luke Street 4fc09799b6 UI: Fix section heading font 2026-04-30 01:45:25 -06:00
Irastris fe0e3cad72 Remove unused editor functions 2026-04-30 03:27:48 -04:00
Luke Street 37d1aa7f40 UI: Run builder before moving it 2026-04-30 01:07:11 -06:00
Luke Street 4a12554bf4 UI: Mobile keyboard fixes, safe area padding, & more 2026-04-30 00:06:27 -06:00
Phillip Stephens fecd1d5683 Update aurora 2026-04-29 22:33:02 -07:00
doop bce9bf6fd9 Merge pull request #597 from dooplecks/haze-fix
Correct JPADrawInfo proj matrix on widescreen
2026-04-30 00:55:32 -04:00
doop fbf63b075a Correct JPADrawInfo proj matrix on widescreen
Fixes #337.
2026-04-30 04:28:47 +00:00
Luke Street b86d6e90e2 Add Gameplay settings & make Panes scrollable 2026-04-29 21:52:33 -06:00
Luke Street 6425b452e7 Make PgUp/PgDown change tabs 2026-04-29 20:25:59 -06:00
Luke Street 1657fe8083 Split out string/number components 2026-04-29 20:19:27 -06:00
Luke Street ecd74a4cbd More settings/editor components 2026-04-29 19:54:37 -06:00
MelonSpeedruns 36dc43c602 Fix changing tunics crash while on top of mirror (#596)
* Fix changing tunics while reflection is active

* Revert "Fix changing tunics while reflection is active"

This reverts commit 89927dc7a6.

* Really fix changing tunics while reflection is active

* Fix transforming on ice again

---------

Co-authored-by: MelonSpeedruns <melonspeedruns@stratobox.net>
Co-authored-by: Irastris <irastris15@gmail.com>
2026-04-29 18:13:07 -06:00
Luke Street d92515f0d4 Begin scaffolding keyboard nav 2026-04-29 15:19:15 -06:00
MelonSpeedruns f147dcac0c Fix camera while crawling & disable freecam properly when not chasecam 2026-04-29 15:29:00 -04:00
MelonSpeedruns ee4c84f39b Fix slight spazz when changing cam type 2026-04-29 15:21:48 -04:00
MelonSpeedruns b8a83c6f59 disable freecam if not chasecamera 2026-04-29 14:37:32 -04:00
MelonSpeedruns 4462c0ef69 more optimizations to freecam code 2026-04-29 14:28:18 -04:00
Phillip Stephens c803bfb545 Update aurora 2026-04-29 09:14:51 -07:00
qwertyquerty 2623c44cab Merge pull request #583 from TheLastPocket/achievement/email-me
Email me and Heavy Hitter Achievements
2026-04-29 05:29:50 -07:00
madeline 24dd02fc81 better back in time condition 2026-04-29 05:28:28 -07:00
TakaRikka a97602b6dc Merge pull request #589 from TwilitRealm/instant-text-shop-fix
Fix instant text clearing some shop dialogue too quickly
2026-04-29 00:37:51 -07:00
TakaRikka e2943e90dc Merge pull request #590 from dooplecks/map-outline
Improve map outline rendering
2026-04-29 00:37:04 -07:00
Luke Street 3cb7fbd030 Create new component system & initial settings window 2026-04-29 00:38:26 -06:00
doop afe54f22ab Write circle pixels linearly 2026-04-29 04:16:24 +00:00
doop e15f5bcee9 Improve map outline rendering 2026-04-29 03:51:14 +00:00
Irastris 1e372a856d Attempted to start making the save editor functional 2026-04-28 22:54:47 -04:00
gymnast86 b26896cad5 includes 2026-04-28 18:05:40 -07:00
gymnast86 f75faf6b06 fix instant text clearing shop messages too early 2026-04-28 18:03:06 -07:00
Irastris b48d9aa052 Split window document and styles out to files for readability 2026-04-28 19:09:47 -04:00
Luke Street d899706208 Start UI over from scratch and add demo window 2026-04-28 16:20:45 -06:00
TakaRikka 3e05789b58 Merge pull request #586 from TwilitRealm/fix/fix-super-clawshot
Fix draw crash with Super Clawshot enabled
2026-04-28 13:34:24 -07:00
MelonSpeedruns 9a7b62cbc6 disable freecam if an event cam happens 2026-04-28 16:25:42 -04:00
MelonSpeedruns 8e0f0e878e optimize some code 2026-04-28 16:13:49 -04:00
MelonSpeedruns 79344edf0d maybe fix number 2 2026-04-28 15:19:32 -04:00
MelonSpeedruns e59bfd1a9c potential fix for freecam flashing 2026-04-28 15:01:57 -04:00
MelonSpeedruns 4d12cc8ea2 Fix draw crash with Super Clawshot enabled 2026-04-28 11:05:29 -04:00
Julian Maynes 2ed2268579 fix newline 2026-04-28 07:19:18 -07:00
Julian Maynes 94a99e8da0 Add iron boots achievement 2026-04-28 07:12:29 -07:00
madeline ddaf50c01d long jump attack achievement 2026-04-28 06:53:20 -07:00
madeline 7566949b42 fix friendly fire achievement 2026-04-28 06:21:41 -07:00
Julian Maynes bb6db3caea remove newlines 2026-04-28 06:18:40 -07:00
Julian Maynes 2dc494dc1c Finish achievement 2026-04-28 06:14:56 -07:00
madeline 3c25633ee9 speed_target avoid ub 2026-04-28 06:08:04 -07:00
madeline d99ed2729b fix achievements window sizing 2026-04-28 05:57:58 -07:00
madeline 782455d48b Merge branch 'main' of https://github.com/TakaRikka/dusk 2026-04-28 05:54:12 -07:00
madeline 47863b34c2 achievement signal system 2026-04-28 05:54:09 -07:00
TakaRikka 92391d5eb8 add overview and ai notice to readme 2026-04-28 04:06:29 -07:00
madeline 0d37cb4e54 thank you berry much achievement 2026-04-28 04:01:22 -07:00
madeline ea528ed9d9 clear single achievement and fix achievement tab moving around 2026-04-28 03:41:04 -07:00
Luke Street f7b880c5ea Small tweak to rml_string 2026-04-28 00:27:18 -06:00
Luke Street ff78bc8d6c Start using Rml::PropertyId/Property instead of strings 2026-04-28 00:18:52 -06:00
Luke Street 6503b4e7eb Add blur and shadow to window component 2026-04-27 23:44:58 -06:00
TakaRikka 30b7087f30 add option for only fishing once for sera's cat 2026-04-27 22:04:42 -07:00
Luke Street 0c1372f986 Revert "Kinda crappy initial controller support"
This reverts commit 23a91a37be.
2026-04-27 21:55:57 -06:00
Irastris 8fb4ba8924 Remove "Enable" from various options, and move DoF under post-processing 2026-04-27 22:51:56 -04:00
Irastris 5f675c6f2b Start deprecating ImGui 2026-04-27 22:44:26 -04:00
Irastris b3333241c5 Add right-pane for item descriptions 2026-04-27 22:44:26 -04:00
Irastris e39079c0f8 Initial game menu implementation 2026-04-27 22:44:26 -04:00
Irastris c3317d9232 Initial window class programming 2026-04-27 22:43:04 -04:00
TakaRikka a4777045fe Merge pull request #578 from TwilitRealm/fix/fix-disable-hud
Fix bugs with Disable Main HUD
2026-04-27 15:29:02 -07:00
TakaRikka bbe8ea6aa6 Merge pull request #577 from TwilitRealm/better-freecam-code
Better Freecam code + Allow Freecam in Target mode
2026-04-27 15:28:39 -07:00
MelonSpeedruns d662db69f0 Fix bugs with Disable Main HUD 2026-04-27 17:04:42 -04:00
MelonSpeedruns 9b259143be Better Freecam code + Allow Freecam in Target mode 2026-04-27 12:05:26 -04:00
Luke Street 025cb58493 Forgor to commit 2026-04-27 01:15:19 -06:00
Luke Street b3dee825e8 Improve button/option style 2026-04-27 00:44:01 -06:00
Luke Street f6c5aac3c8 Improve disc selector 2026-04-27 00:36:56 -06:00
Luke Street 25e9064d09 Revamped prelaunch experiment w/ RmlUi 2026-04-27 00:18:31 -06:00
Luke Street 3e1e8f1244 Enable RmlUi 2026-04-26 21:53:39 -06:00
TakaRikka eaae8b6137 Merge branch 'main' of github.com:TwilitRealm/dusk into mapmirror 2026-04-26 17:37:30 -07:00
roeming 0bf663141a change filter to avoid allocations 2026-04-25 14:39:47 -04:00
MelonSpeedruns d7dced7ddf don't autosave if playing a cutscene 2026-04-25 08:25:50 -04:00
MelonSpeedruns 78b0563c0e Merge remote-tracking branch 'origin/main' into feature/autosave
# Conflicts:
#	src/dusk/imgui/ImGuiMenuEnhancements.cpp
#	src/dusk/settings.cpp
#	src/f_ap/f_ap_game.cpp
2026-04-24 12:54:40 -04:00
MelonSpeedruns 871d18e294 added experimental setting for autosave 2026-04-20 13:15:37 -04:00
MelonSpeedruns c157564da6 dungeon doors now autosave 2026-04-20 13:02:25 -04:00
MelonSpeedruns ecc3b00c51 Merge remote-tracking branch 'origin/main' into feature/autosave
# Conflicts:
#	src/f_ap/f_ap_game.cpp
2026-04-20 12:55:17 -04:00
MelonSpeedruns 8afb1141ab Autosave when changing rooms 2026-04-17 13:41:56 -04:00
MelonSpeedruns 8c5673d9b8 autosave when loading scene 2026-04-17 13:12:20 -04:00
MelonSpeedruns 916dfcd9da Merge remote-tracking branch 'origin/main' into feature/autosave
# Conflicts:
#	src/dusk/imgui/ImGuiConsole.cpp
2026-04-17 12:10:24 -04:00
TakaRikka d9a0ef760f fix icon positions 2026-04-16 19:46:02 -07:00
MelonSpeedruns 842210e539 remove scene autosave cause that's buggy atm 2026-04-16 19:56:04 -04:00
MelonSpeedruns 39d951d0cb scene saving now works 2026-04-16 19:50:20 -04:00
MelonSpeedruns a4be0841e5 autosave WIP 2026-04-16 19:30:37 -04:00
TakaRikka 95470b830f wip map mirror 2026-04-16 05:55:46 -07:00
195 changed files with 18234 additions and 2972 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
Language: Cpp
Standard: C++03
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignAfterOpenBracket: DontAlign
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignOperands: true
+13 -42
View File
@@ -100,7 +100,9 @@ if (CMAKE_SYSTEM_NAME STREQUAL Linux)
endif ()
set(AURORA_ENABLE_DVD ON CACHE BOOL "Enable DVD API support" FORCE)
set(AURORA_ENABLE_CARD ON CACHE BOOL "Enable CARD API support" FORCE)
set(AURORA_ENABLE_RMLUI ON CACHE BOOL "Enable RmlUi UI support" FORCE)
add_subdirectory(extern/aurora EXCLUDE_FROM_ALL)
target_compile_definitions(aurora_mtx PRIVATE MTX_USE_PS=1)
add_subdirectory(libs/freeverb)
@@ -284,7 +286,7 @@ set(DUSK_COPYRIGHT "Copyright (C) Twilit Realm contributors")
source_group("dolzel" FILES ${DOLZEL_FILES} ${Z2AUDIOLIB_FILES} ${REL_FILES})
source_group("dusk" FILES ${DUSK_FILES})
set(GAME_COMPILE_DEFS TARGET_PC WIDESCREEN_SUPPORT=1 AVOID_UB=1 VERSION=0)
set(GAME_COMPILE_DEFS TARGET_PC WIDESCREEN_SUPPORT=1 AVOID_UB=1 VERSION=0 MTX_USE_PS=1)
set(GAME_INCLUDE_DIRS
include
@@ -296,8 +298,10 @@ set(GAME_INCLUDE_DIRS
extern
${CMAKE_BINARY_DIR})
find_package(Threads REQUIRED)
set(GAME_LIBS aurora::core aurora::gx aurora::gd aurora::si aurora::vi aurora::pad aurora::mtx aurora::os aurora::dvd
aurora::card freeverb cxxopts::cxxopts absl::flat_hash_map nlohmann_json::nlohmann_json TracyClient fmt::fmt)
aurora::card freeverb cxxopts::cxxopts absl::flat_hash_map nlohmann_json::nlohmann_json TracyClient fmt::fmt
Threads::Threads)
list(APPEND GAME_LIBS libzstd_static)
@@ -319,46 +323,13 @@ if (DUSK_MOVIE_SUPPORT)
list(APPEND GAME_COMPILE_DEFS MOVIE_SUPPORT=1)
endif ()
option(DUSK_ENABLE_DISCORD_RPC "Enable Discord Rich Presence support" ON)
if (DUSK_ENABLE_DISCORD_RPC AND NOT ANDROID AND NOT IOS AND NOT TVOS)
FetchContent_Populate(discord_rpc
URL https://github.com/discord/discord-rpc/archive/refs/tags/v3.4.0.tar.gz
URL_HASH SHA256=e13427019027acd187352dacba6c65953af66fdf3c35fcf38fc40b454a9d7855
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
)
# RapidJSON is a git submodule absent from the discord-rpc tarball; fetch separately.
FetchContent_Populate(rapidjson
URL https://github.com/Tencent/rapidjson/archive/refs/tags/v1.1.0.tar.gz
URL_HASH SHA256=bf7ced29704a1e696fbccf2a2b4ea068e7774fa37f6d7dd4039d0787f8bed98e
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
)
if (NOT TARGET discord-rpc)
set(_drpc ${discord_rpc_SOURCE_DIR}/src)
set(_drpc_src
${_drpc}/discord_rpc.cpp
${_drpc}/rpc_connection.cpp
${_drpc}/serialization.cpp
)
if (WIN32)
list(APPEND _drpc_src ${_drpc}/connection_win.cpp ${_drpc}/discord_register_win.cpp)
elseif (APPLE)
list(APPEND _drpc_src ${_drpc}/connection_unix.cpp ${_drpc}/discord_register_osx.m)
else ()
list(APPEND _drpc_src ${_drpc}/connection_unix.cpp ${_drpc}/discord_register_linux.cpp)
endif ()
add_library(discord-rpc STATIC ${_drpc_src})
target_include_directories(discord-rpc PUBLIC
${discord_rpc_SOURCE_DIR}/include
${rapidjson_SOURCE_DIR}/include
)
if (UNIX)
target_link_libraries(discord-rpc PUBLIC pthread)
endif ()
endif ()
list(APPEND GAME_LIBS discord-rpc)
list(APPEND GAME_COMPILE_DEFS DUSK_DISCORD_RPC=1)
set(DUSK_ENABLE_DISCORD_DEFAULT ON)
if (DEFINED DUSK_ENABLE_DISCORD_RPC AND NOT DEFINED DUSK_ENABLE_DISCORD)
set(DUSK_ENABLE_DISCORD_DEFAULT ${DUSK_ENABLE_DISCORD_RPC})
endif ()
option(DUSK_ENABLE_DISCORD "Enable Discord Rich Presence support" ${DUSK_ENABLE_DISCORD_DEFAULT})
if (DUSK_ENABLE_DISCORD AND NOT ANDROID AND NOT IOS AND NOT TVOS)
list(APPEND GAME_COMPILE_DEFS DUSK_DISCORD=1)
endif ()
# Edit & Continue
+39 -15
View File
@@ -1,31 +1,55 @@
![DuskLogo](res/logo-mascot.webp)
<div align="center">
<img src="res/logo-mascot.png" alt="Logo" width="640">
- ### **[Official Website](https://twilitrealm.dev)**
- ### **[Discord](https://discord.gg/QACynxeyna)**
<p align="center">
<a href="https://twilitrealm.dev">Official Website</a>
<a href="https://discord.gg/QACynxeyna">Discord</a>
</p>
</div>
# Overview
Dusk is a reverse-engineered reimplementation of Twilight Princess.
It aims to be as accurate as possible to the original while also providing new options, enhancements, and tools to customize your experience.
# Setup
**⚠️ Dusk does NOT provide any copyrighted assets. You must provide your own copy of the game.**
### 1. Verify your ROM dump
First make sure your dump of the game is clean and supported by Dusk. You can do this by checking the sha1 hash of your dump against this list of supported versions.
> [!IMPORTANT]
> Dusk does *not* provide any copyrighted assets. You must provide your own copy of the original game.
| Version | sha1 hash |
|--------------| ---------------------------------------- |
| GameCube USA | 75edd3ddff41f125d1b4ce1a40378f1b565519e7 |
| GameCube PAL | 2601822a488eeb86fb89db16ca8f29c2c953e1ca |
### 1. Verify your dump
First, make sure your dump of the game is clean and supported by Dusk. You can do this by checking the SHA-1 hash of your dump against this list of supported versions:
| Version | SHA-1 hash |
|--------------| ------------------------------------------ |
| GameCube USA | `75edd3ddff41f125d1b4ce1a40378f1b565519e7` |
| GameCube EUR | `2601822a488eeb86fb89db16ca8f29c2c953e1ca` |
### 2. Download [Dusk](https://github.com/TwilitRealm/dusk/releases)
### 3. Setup the game
- Extract the zip folder
- Launch Dusk
- Select Options, then set the ISO Path to your supported game dump
- Press Start Game to play!
![Dusk options](assets/dusk_options.png)
- Extract the .zip file
- Launch Dusk
- Press **Select Disc Image** and provide the path to your supported game dump.
- Press **Play**!
# Building
If you'd like to build Dusk from source, please read the [build instructions](docs/building.md).
Pull requests are welcomed! Note that we do not accept contributions that are primarily AI-generated and will close your PR if we suspect as much.
# Credits
Special thanks to the [TP decompilation](https://github.com/zeldaret/tp) team, the GC/Wii decompilation community, the [Aurora](https://github.com/encounter/aurora) developers, the [TP speedrunning community](https://zsrtp.link), and all [contributors](https://github.com/TwilitRealm/dusk/graphs/contributors).
<br/>
<div align="center">
<a href="https://github.com/encounter/aurora">
<img src="assets/aurora-powered.png" alt="Powered by Aurora" width="800">
</a>
</div>
Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

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

After

Width:  |  Height:  |  Size: 2.3 KiB

+1 -1
+52 -8
View File
@@ -1,7 +1,7 @@
set(DOLZEL_FILES
src/m_Do/m_Do_main.cpp
src/m_Do/m_Do_printf.cpp
#src/m_Do/m_Do_printf.cpp
src/m_Do/m_Do_audio.cpp
src/m_Do/m_Do_controller_pad.cpp
#src/m_Do/m_Re_controller_pad.cpp
@@ -1429,6 +1429,7 @@ set(DUSK_FILES
src/dusk/globals.cpp
src/dusk/gyro.cpp
src/dusk/gamepad_color.cpp
src/dusk/autosave.cpp
src/dusk/io.cpp
src/dusk/layout.cpp
src/dusk/logging.cpp
@@ -1446,29 +1447,72 @@ set(DUSK_FILES
src/dusk/imgui/ImGuiBloomWindow.hpp
src/dusk/imgui/ImGuiMenuTools.cpp
src/dusk/imgui/ImGuiMenuTools.hpp
src/dusk/imgui/ImGuiPreLaunchWindow.cpp
src/dusk/imgui/ImGuiPreLaunchWindow.hpp
src/dusk/imgui/ImGuiFirstRunPreset.hpp
src/dusk/imgui/ImGuiFirstRunPreset.cpp
src/dusk/imgui/ImGuiProcessOverlay.cpp
src/dusk/imgui/ImGuiCameraOverlay.cpp
src/dusk/imgui/ImGuiHeapOverlay.cpp
src/dusk/imgui/ImGuiDebugPad.cpp
src/dusk/imgui/ImGuiControllerOverlay.cpp
src/dusk/imgui/ImGuiStubLog.cpp
src/dusk/imgui/ImGuiMapLoader.cpp
src/dusk/imgui/ImGuiSaveEditor.cpp
src/dusk/imgui/ImGuiStateShare.hpp
src/dusk/imgui/ImGuiStateShare.cpp
src/dusk/imgui/ImGuiAchievements.hpp
src/dusk/imgui/ImGuiAchievements.cpp
src/dusk/ui/achievements.cpp
src/dusk/ui/achievements.hpp
src/dusk/ui/bool_button.cpp
src/dusk/ui/bool_button.hpp
src/dusk/ui/button.cpp
src/dusk/ui/button.hpp
src/dusk/ui/component.cpp
src/dusk/ui/component.hpp
src/dusk/ui/controller_config.cpp
src/dusk/ui/controller_config.hpp
src/dusk/ui/document.cpp
src/dusk/ui/document.hpp
src/dusk/ui/editor.cpp
src/dusk/ui/editor.hpp
src/dusk/ui/event.cpp
src/dusk/ui/event.hpp
src/dusk/ui/graphics_tuner.cpp
src/dusk/ui/graphics_tuner.hpp
src/dusk/ui/input.cpp
src/dusk/ui/input.hpp
src/dusk/ui/modal.cpp
src/dusk/ui/modal.hpp
src/dusk/ui/nav_types.hpp
src/dusk/ui/number_button.cpp
src/dusk/ui/number_button.hpp
src/dusk/ui/overlay.cpp
src/dusk/ui/overlay.hpp
src/dusk/ui/pane.cpp
src/dusk/ui/pane.hpp
src/dusk/ui/menu_bar.cpp
src/dusk/ui/menu_bar.hpp
src/dusk/ui/prelaunch.cpp
src/dusk/ui/prelaunch.hpp
src/dusk/ui/preset.cpp
src/dusk/ui/preset.hpp
src/dusk/ui/select_button.cpp
src/dusk/ui/select_button.hpp
src/dusk/ui/settings.cpp
src/dusk/ui/settings.hpp
src/dusk/ui/string_button.cpp
src/dusk/ui/string_button.hpp
src/dusk/ui/tab_bar.cpp
src/dusk/ui/tab_bar.hpp
src/dusk/ui/ui.cpp
src/dusk/ui/ui.hpp
src/dusk/ui/window.cpp
src/dusk/ui/window.hpp
src/dusk/achievements.cpp
src/dusk/iso_validate.cpp
src/dusk/livesplit.cpp
src/dusk/offset_ptr.cpp
src/dusk/OSContext.cpp
src/dusk/OSReport.cpp
src/dusk/OSThread.cpp
src/dusk/OSMutex.cpp
src/dusk/discord.cpp
src/dusk/discord.hpp
src/dusk/discord_presence.cpp
src/dusk/version.cpp
)
+1
View File
@@ -27,6 +27,7 @@ public:
/* 0x17C */ cXyz mViewScale;
#if TARGET_PC
bool mbReset = false;
bool mbHadEntry = false;
#endif
};
+11
View File
@@ -25,6 +25,10 @@ public:
int Draw();
int Delete();
#if TARGET_PC
void onInterpCallback();
#endif
enum Param_e {
LOCK_e = (1 << 6), NO_BASE_DISP = (1 << 7)
};
@@ -50,6 +54,13 @@ private:
/* 0x1020 */ dCcD_Cyl mCylinderCollider;
/* 0x115C */ s32 mStopSwingingFrames;
#if TARGET_PC
cXyz mChainInterpPrev[64];
cXyz mChainInterpCurr[64];
bool mChainInterpPrevValid;
bool mChainInterpCurrValid;
#endif
// Number of chain models
u32 getArg0() {
return fopAcM_GetParamBit(this, 0, 6);
+18
View File
@@ -118,6 +118,18 @@ class camera_class;
class dCamera_c;
typedef bool (dCamera_c::*engine_fn)(s32);
#if TARGET_PC
struct DebugFlyCam {
bool initialized;
f32 pitch;
f32 yaw;
cXyz savedCenter;
cXyz savedEye;
f32 savedFovy;
cSAngle savedBank;
};
#endif
class dCamera_c {
public:
class dCamInfo_c {
@@ -1028,6 +1040,8 @@ public:
bool test2Camera(s32);
#if TARGET_PC
bool freeCamera();
bool executeDebugFlyCam();
void deactivateDebugFlyCam();
#endif
bool towerCamera(s32);
bool hookshotCamera(s32);
@@ -1376,6 +1390,10 @@ public:
/* 0x970 */ dCamSetup_c mCamSetup;
/* 0xAEC */ dCamParam_c mCamParam;
/* 0xB0C */ u8 field_0xb0c;
#if TARGET_PC
DebugFlyCam mDebugFlyCam;
#endif
}; // Size: 0xB10
dCamera_c* dCam_getBody();
+4
View File
@@ -91,6 +91,10 @@ public:
void calcCursor();
void drawCursor();
#if TARGET_PC
void dMapBgWide();
#endif
void setDPDFloorSelCurPos(s8 i_pos) { field_0xdd6 = i_pos; }
f32 getMapWidth() { return mMapWidth; }
+14
View File
@@ -81,6 +81,10 @@ public:
void calcDrawPriority();
void setArrowPosAxis(f32, f32);
#if TARGET_PC
void fMapBackWide();
#endif
virtual void draw();
virtual ~dMenu_Fmap2DBack_c();
@@ -165,6 +169,12 @@ public:
void mapBlink() {}
#if PLATFORM_WII || TARGET_PC
f32 getMirrorPosX(f32 param_0, f32 param_1) {
return (field_0x11dc * 2.0f - (param_0 + param_1)) - param_1;
}
#endif
// Unknown name
struct RegionTexData {
/* 0x00 */ float mMinX;
@@ -330,6 +340,10 @@ public:
void setHIO(bool);
bool isWarpAccept();
#if TARGET_PC
void fMapTopWide();
#endif
virtual void draw();
virtual ~dMenu_Fmap2DTop_c();
+10
View File
@@ -66,6 +66,16 @@ public:
_c90 = param_2;
}
#if PLATFORM_WII || TARGET_PC
f32 getMirrorCenterPosX(f32 param_0, f32 param_1) {
if (_c90) {
return (mCenterPosX * 2.0f - (param_0 + param_1)) - param_1;
}
return param_0;
}
#endif
struct Stage_c {
// Incomplete class
+3
View File
@@ -67,6 +67,9 @@ public:
bool isStaffMessage();
bool isSaveMessage();
bool isTalkMessage();
#if TARGET_PC
bool isShopItemMessage();
#endif
const char* getSmellName();
const char* getPortalName();
const char* getBombName();
+9 -3
View File
@@ -4,6 +4,8 @@
#include <functional>
#include <queue>
#include <string>
#include <string_view>
#include <unordered_set>
#include <vector>
#include "nlohmann/json.hpp"
@@ -14,6 +16,7 @@ enum class AchievementCategory : uint8_t {
Collection,
Challenge,
Minigame,
Misc,
Glitched
};
@@ -40,10 +43,13 @@ public:
void save();
void tick();
void clearAll();
void clearOne(const char* key);
// Signals are visible to all achievement checks within the same tick, then cleared.
void signal(const char* key);
bool hasSignal(const char* key) const;
std::vector<Achievement> getAchievements() const;
bool hasPendingUnlock() const { return !m_pendingUnlocks.empty(); }
std::string consumePendingUnlock();
private:
struct Entry {
@@ -57,9 +63,9 @@ private:
void processEntry(Entry& e);
std::vector<Entry> m_entries;
std::unordered_set<std::string_view> m_signals;
bool m_loaded = false;
bool m_dirty = false;
std::queue<std::string> m_pendingUnlocks;
};
} // namespace dusk
+17
View File
@@ -0,0 +1,17 @@
#pragma once
#ifndef AUTOSAVE_H
#define AUTOSAVE_H
#include <m_Do/m_Do_MemCardRWmng.h>
#include <m_Do/m_Do_MemCard.h>
void noAutoSave();
void triggerAutoSave();
void updateAutoSave();
void enterAutoSave();
void autoSaving();
void waitingForWrite();
void endAutoSave();
#endif
+8 -12
View File
@@ -1,18 +1,14 @@
#pragma once
#ifdef DUSK_DISCORD_RPC
#ifdef DUSK_DISCORD
namespace dusk {
namespace discord {
namespace dusk::discord {
void Initialize();
void initialize();
void run_callbacks();
void update_presence();
void shutdown();
void RunCallbacks();
} // namespace dusk::discord
void UpdatePresence();
void Shutdown();
}
}
#endif // DUSK_DISCORD_RPC
#endif // DUSK_DISCORD
+14
View File
@@ -1,6 +1,10 @@
#ifndef DUSK_MAIN_H
#define DUSK_MAIN_H
#if defined(__APPLE__)
#include <TargetConditionals.h>
#endif
#include <filesystem>
namespace dusk {
@@ -8,7 +12,17 @@ namespace dusk {
extern bool IsShuttingDown;
extern bool IsGameLaunched;
extern bool IsFocusPaused;
extern bool RestartRequested;
extern std::filesystem::path ConfigPath;
#if defined(__ANDROID__) || (defined(TARGET_OS_IOS) && TARGET_OS_IOS) || \
(defined(TARGET_OS_TV) && TARGET_OS_TV)
inline constexpr bool SupportsProcessRestart = false;
#else
inline constexpr bool SupportsProcessRestart = true;
#endif
void RequestRestart() noexcept;
}
#endif // DUSK_MAIN_H
+2
View File
@@ -1,5 +1,7 @@
#pragma once
#include <array>
struct RoomEntry {
u8 roomNo;
std::vector<s16> roomPoints = {};
+1 -137
View File
@@ -2,9 +2,6 @@
#define _SRC_DUSK_MATH_H_
#include <cmath>
#include <array>
#include <limits>
#include <bit>
#ifndef M_PI
#define M_PI 3.14159265358979323846f
@@ -19,139 +16,6 @@ inline float i_cosf(float x) { return cos(x); }
inline float i_tanf(float x) { return tan(x); }
inline float i_acosf(float x) { return acos(x); }
// frsqrte matching courtesy of Geotale, with reference to https://achurch.org/cpu-tests/ppc750cl.s
struct BaseAndDec32 {
uint32_t base;
int32_t dec;
};
struct BaseAndDec64 {
uint64_t base;
int64_t dec;
};
union c32 {
constexpr c32(const float p) {
f = p;
}
constexpr c32(const uint32_t p) {
u = p;
}
uint32_t u;
float f;
};
union c64 {
constexpr c64(const double p) {
f = p;
}
constexpr c64(const uint64_t p) {
u = p;
}
uint64_t u;
double f;
};
static constexpr uint64_t EXPONENT_SHIFT_F64 = 52;
static constexpr uint64_t MANTISSA_MASK_F64 = 0x000fffffffffffffULL;
static constexpr uint64_t EXPONENT_MASK_F64 = 0x7ff0000000000000ULL;
static constexpr uint64_t SIGN_MASK_F64 = 0x8000000000000000ULL;
static constexpr std::array<BaseAndDec64, 32> RSQRTE_TABLE = {{
{0x69fa000000000ULL, -0x15a0000000LL},
{0x5f2e000000000ULL, -0x13cc000000LL},
{0x554a000000000ULL, -0x1234000000LL},
{0x4c30000000000ULL, -0x10d4000000LL},
{0x43c8000000000ULL, -0x0f9c000000LL},
{0x3bfc000000000ULL, -0x0e88000000LL},
{0x34b8000000000ULL, -0x0d94000000LL},
{0x2df0000000000ULL, -0x0cb8000000LL},
{0x2794000000000ULL, -0x0bf0000000LL},
{0x219c000000000ULL, -0x0b40000000LL},
{0x1bfc000000000ULL, -0x0aa0000000LL},
{0x16ae000000000ULL, -0x0a0c000000LL},
{0x11a8000000000ULL, -0x0984000000LL},
{0x0ce6000000000ULL, -0x090c000000LL},
{0x0862000000000ULL, -0x0898000000LL},
{0x0416000000000ULL, -0x082c000000LL},
{0xffe8000000000ULL, -0x1e90000000LL},
{0xf0a4000000000ULL, -0x1c00000000LL},
{0xe2a8000000000ULL, -0x19c0000000LL},
{0xd5c8000000000ULL, -0x17c8000000LL},
{0xc9e4000000000ULL, -0x1610000000LL},
{0xbedc000000000ULL, -0x1490000000LL},
{0xb498000000000ULL, -0x1330000000LL},
{0xab00000000000ULL, -0x11f8000000LL},
{0xa204000000000ULL, -0x10e8000000LL},
{0x9994000000000ULL, -0x0fe8000000LL},
{0x91a0000000000ULL, -0x0f08000000LL},
{0x8a1c000000000ULL, -0x0e38000000LL},
{0x8304000000000ULL, -0x0d78000000LL},
{0x7c48000000000ULL, -0x0cc8000000LL},
{0x75e4000000000ULL, -0x0c28000000LL},
{0x6fd0000000000ULL, -0x0b98000000LL},
}};
[[nodiscard]] static inline double frsqrte(const double val) {
c64 bits(val);
uint64_t mantissa = bits.u & MANTISSA_MASK_F64;
int64_t exponent = bits.u & EXPONENT_MASK_F64;
bool sign = (bits.u & SIGN_MASK_F64) != 0;
// Handle 0 case
if (mantissa == 0 && exponent == 0) {
return std::copysign(std::numeric_limits<double>::infinity(), bits.f);
}
// Handle NaN-like
if (exponent == EXPONENT_MASK_F64) {
if (mantissa == 0) {
return sign ? std::numeric_limits<double>::quiet_NaN() : 0.0;
}
return val;
}
// Handle negative inputs
if (sign) {
return std::numeric_limits<double>::quiet_NaN();
}
if (exponent == 0) {
// Shift so one bit goes to where the exponent would be,
// then clear that bit to mimic a not-subnormal number!
// Aka, if there are 12 leading zeroes, shift left once
uint32_t shift = std::countl_zero(mantissa) - static_cast<uint32_t>(63 - EXPONENT_SHIFT_F64);
mantissa <<= shift;
mantissa &= MANTISSA_MASK_F64;
// The shift is subtracted by 1 because denormals by default
// are offset by 1 (exponent 0 doesn't have implied 1 bit)
exponent -= static_cast<int64_t>(shift - 1) << EXPONENT_SHIFT_F64;
}
// In reality this doesn't get the full exponent -- Only the least significant bit
// Only that's needed because square roots of higher exponent bits simply multiply the
// result by 2!!
uint32_t key = static_cast<uint32_t>((static_cast<uint64_t>(exponent) | mantissa) >> 37);
uint64_t new_exp =
(static_cast<uint64_t>((0xbfcLL << EXPONENT_SHIFT_F64) - exponent) >> 1) & EXPONENT_MASK_F64;
// Remove the bits relating to anything higher than the LSB of the exponent
const auto &entry = RSQRTE_TABLE[0x1f & (key >> 11)];
// The result is given by an estimate then an adjustment based on the original
// key that was computed
uint64_t new_mantissa = static_cast<uint64_t>(entry.base + entry.dec * static_cast<int64_t>(key & 0x7ff));
return c64(new_exp | new_mantissa).f;
}
#include <dolphin/ppc_math.h>
#endif // _SRC_DUSK_MATH_H_
+24 -3
View File
@@ -21,6 +21,12 @@ enum class GameLanguage : u8 {
Italian = OS_LANGUAGE_ITALIAN,
};
enum class DiscVerificationState : u8 {
Unknown = 0,
Success,
HashMismatch,
};
namespace config {
template <>
struct ConfigEnumRange<BloomMode> {
@@ -33,6 +39,12 @@ struct ConfigEnumRange<GameLanguage> {
static constexpr auto min = GameLanguage::English;
static constexpr auto max = GameLanguage::Italian;
};
template <>
struct ConfigEnumRange<DiscVerificationState> {
static constexpr auto min = DiscVerificationState::Unknown;
static constexpr auto max = DiscVerificationState::HashMismatch;
};
}
// Persistent user settings
@@ -45,6 +57,8 @@ struct UserSettings {
ConfigVar<bool> enableFullscreen;
ConfigVar<bool> enableVsync;
ConfigVar<bool> lockAspectRatio;
ConfigVar<bool> enableFpsOverlay;
ConfigVar<int> fpsOverlayCorner;
} video;
struct {
@@ -55,6 +69,8 @@ struct UserSettings {
ConfigVar<int> soundEffectsVolume;
ConfigVar<int> fanfareVolume;
ConfigVar<bool> enableReverb;
ConfigVar<bool> enableHrtf;
ConfigVar<bool> menuSounds;
} audio;
// Game settings
@@ -65,7 +81,6 @@ struct UserSettings {
// QoL
ConfigVar<bool> enableQuickTransform;
ConfigVar<bool> hideTvSettingsScreen;
ConfigVar<bool> skipWarningScreen;
ConfigVar<bool> biggerWallets;
ConfigVar<bool> noReturnRupees;
ConfigVar<bool> disableRupeeCutscenes;
@@ -76,13 +91,15 @@ struct UserSettings {
ConfigVar<bool> fastClimbing;
ConfigVar<bool> noMissClimbing;
ConfigVar<bool> fastTears;
ConfigVar<bool> no2ndFishForCat;
ConfigVar<bool> instantSaves;
ConfigVar<bool> instantText;
ConfigVar<bool> sunsSong;
ConfigVar<bool> autoSave;
// Preferences
ConfigVar<bool> enableMirrorMode;
ConfigVar<bool> disableMainHUD;
ConfigVar<bool> minimalHUD;
ConfigVar<bool> pauseOnFocusLost;
ConfigVar<bool> enableLinkDollRotation;
ConfigVar<bool> enableAchievementNotifications;
@@ -116,6 +133,8 @@ struct UserSettings {
ConfigVar<bool> invertCameraXAxis;
ConfigVar<bool> invertCameraYAxis;
ConfigVar<float> freeCameraSensitivity;
ConfigVar<bool> debugFlyCam;
ConfigVar<bool> debugFlyCamLockEvents;
// Cheats
ConfigVar<bool> infiniteHearts;
@@ -142,17 +161,19 @@ struct UserSettings {
// Tools
ConfigVar<bool> speedrunMode;
ConfigVar<bool> liveSplitEnabled;
ConfigVar<bool> recordingMode;
} game;
struct {
ConfigVar<std::string> isoPath;
ConfigVar<DiscVerificationState> isoVerification;
ConfigVar<std::string> graphicsBackend;
ConfigVar<bool> skipPreLaunchUI;
ConfigVar<bool> showPipelineCompilation;
ConfigVar<bool> wasPresetChosen;
ConfigVar<bool> enableCrashReporting;
ConfigVar<bool> duskMenuOpen;
ConfigVar<int> cardFileType;
ConfigVar<bool> enableAdvancedSettings;
} backend;
};
+13
View File
@@ -5,6 +5,7 @@
#include "Z2AudioLib/Z2EnvSeMgr.h"
#include "Z2AudioLib/Z2LinkMgr.h"
#include "dusk/audio.h"
#include "dusk/settings.h"
class mDoAud_zelAudio_c : public Z2AudioMgr {
public:
@@ -132,6 +133,18 @@ inline void mDoAud_seStart(u32 i_sfxID, const Vec* i_sePos, u32 param_2, s8 i_re
-1.0f, -1.0f, 0);
}
#if TARGET_PC
inline void mDoAud_seStartMenu(u32 i_sfxID) {
if (!mDoAud_zelAudio_c::isInitFlag()) {
return;
}
if (!dusk::getSettings().audio.menuSounds.getValue()) {
return;
}
mDoAud_seStart(i_sfxID, nullptr, 0, 0);
}
#endif
inline void mDoAud_seStartLevel(u32 i_sfxID, const Vec* i_sePos, u32 param_2, s8 i_reverb) {
DUSK_AUDIO_SKIP()
Z2AudioMgr::getInterface()->seStartLevel(i_sfxID, i_sePos, param_2, i_reverb, 1.0f, 1.0f,
@@ -1,9 +1,9 @@
#ifndef J3DSTRUCT_H
#define J3DSTRUCT_H
#include <cstring>
#include <gx.h>
#include <mtx.h>
#include <mtx.h>
#include "global.h"
#include "JSystem/JMath/JMath.h"
@@ -11,7 +11,7 @@
/**
* @ingroup jsystem-j3d
*
*
*/
struct J3DLightInfo {
bool operator==(J3DLightInfo& other) const;
@@ -28,7 +28,7 @@ struct J3DLightInfo {
/**
* @ingroup jsystem-j3d
*
*
*/
struct J3DTextureSRTInfo {
// NOTE: Big endian when loaded from file!
@@ -79,7 +79,7 @@ enum J3DTexMtxMode {
/**
* @ingroup jsystem-j3d
*
*
*/
struct J3DTexMtxInfo {
bool operator==(J3DTexMtxInfo& other) const;
@@ -97,7 +97,7 @@ struct J3DTexMtxInfo {
/**
* @ingroup jsystem-j3d
*
*
*/
struct J3DIndTexMtxInfo {
J3DIndTexMtxInfo& operator=(J3DIndTexMtxInfo const&);
@@ -107,7 +107,7 @@ struct J3DIndTexMtxInfo {
/**
* @ingroup jsystem-j3d
*
*
*/
struct J3DFogInfo {
bool operator==(J3DFogInfo&) const;
@@ -126,7 +126,7 @@ struct J3DFogInfo {
/**
* @ingroup jsystem-j3d
*
*
*/
struct J3DNBTScaleInfo {
bool operator==(const J3DNBTScaleInfo& other) const;
@@ -153,7 +153,7 @@ struct J3DIndTexOrderInfo {
/**
* @ingroup jsystem-j3d
*
*
*/
struct J3DTevSwapModeInfo {
/* 0x0 */ u8 mRasSel;
@@ -164,7 +164,7 @@ struct J3DTevSwapModeInfo {
/**
* @ingroup jsystem-j3d
*
*
*/
struct J3DTevSwapModeTableInfo {
/* 0x0 */ u8 field_0x0;
@@ -175,7 +175,7 @@ struct J3DTevSwapModeTableInfo {
/**
* @ingroup jsystem-j3d
*
*
*/
struct J3DTevStageInfo {
/* 0x0 */ u8 field_0x0;
@@ -202,7 +202,7 @@ struct J3DTevStageInfo {
/**
* @ingroup jsystem-j3d
*
*
*/
struct J3DIndTevStageInfo {
/* 0x0 */ u8 mIndStage;
@@ -219,7 +219,7 @@ struct J3DIndTevStageInfo {
/**
* @ingroup jsystem-j3d
*
*
*/
struct J3DTexCoordInfo {
/* 0x0 */ u8 mTexGenType;
@@ -265,7 +265,7 @@ struct J3DBlendInfo {
/**
* @ingroup jsystem-j3d
*
*
*/
struct J3DTevOrderInfo {
void operator=(const J3DTevOrderInfo& other) {
@@ -59,6 +59,9 @@ public:
bool isActive() const { return mSeqList.getNumLinks() != 0; }
int getNumActiveSeqs() const { return mSeqList.getNumLinks(); }
void pause(bool paused) { mActivity.field_0x0.flags.flag2 = paused; }
#if TARGET_PC
JSUList<JAISeq>* getSeqList() { return &mSeqList; }
#endif
private:
/* 0x08 */ JAIAudience* mAudience;
@@ -207,4 +207,11 @@ void JPARegistAlphaEnv(JPAEmitterWorkData*, JPABaseParticle*);
void JPARegistPrmAlpha(JPAEmitterWorkData*, JPABaseParticle*);
void JPARegistPrmAlphaEnv(JPAEmitterWorkData*, JPABaseParticle*);
#if TARGET_PC
void JPAInterpBillboard(JPAEmitterWorkData*, JPABaseParticle*);
void JPAInterpRotBillboard(JPAEmitterWorkData*, JPABaseParticle*);
void JPAInterpDirection(JPAEmitterWorkData*, JPABaseParticle*);
void JPAInterpRotDirection(JPAEmitterWorkData*, JPABaseParticle*);
#endif
#endif /* JPABASESHAPE_H */
@@ -24,6 +24,9 @@ public:
void init_c(JPAEmitterWorkData*, JPABaseParticle*);
bool calc_p(JPAEmitterWorkData*);
bool calc_c(JPAEmitterWorkData*);
#if TARGET_PC
void interp(JPAEmitterWorkData*, void const* drawFunc);
#endif
bool canCreateChild(JPAEmitterWorkData*);
f32 getWidth(JPABaseEmitter const*) const;
f32 getHeight(JPABaseEmitter const*) const;
@@ -40,6 +40,9 @@ public:
JUTTransparency getTransparency() const { return JUTTransparency(mTransparency); }
u16 getNumColors() const { return mNumColors; }
ResTLUT* getColorTable() const { return mColorTable; }
#if TARGET_PC
void dataUploaded();
#endif
private:
/* 0x00 */ GXTlutObj mTlutObj;
@@ -75,6 +75,7 @@ public:
s32 getTransparency() const { return mTexInfo->alphaEnabled; }
s32 getWidth() const { return mTexInfo->width; }
s32 getHeight() const { return mTexInfo->height; }
JUTPalette* getPalette() const { return mPalette; }
void setCaptureFlag(bool flag) { mFlags &= 2 | flag; }
bool getCaptureFlag() const { return mFlags & 1; }
bool getEmbPaletteDelFlag() const { return mFlags & 2; }
@@ -82,7 +83,7 @@ public:
int getTlutName() const { return mTlutName; }
bool operator==(const JUTTexture& other) {
return mTexInfo == other.mTexInfo
&& field_0x2c == other.field_0x2c
&& mPalette == other.mPalette
&& mWrapS == other.mWrapS
&& mWrapT == other.mWrapT
&& mMinFilter == other.mMinFilter
@@ -100,7 +101,7 @@ private:
/* 0x20 */ const ResTIMG* mTexInfo;
/* 0x24 */ void* mTexData;
/* 0x28 */ JUTPalette* mEmbPalette;
/* 0x2C */ JUTPalette* field_0x2c;
/* 0x2C */ JUTPalette* mPalette;
/* 0x30 */ u8 mWrapS;
/* 0x31 */ u8 mWrapT;
/* 0x32 */ u8 mMinFilter;
@@ -556,8 +556,8 @@ void J3DModelLoader::readVertexData(const J3DVertexBlock& block, J3DVertexData&
if (attr == GX_VA_POS) {
// can be a little off due to 0x20 alignment, account for that
u32 expect = ((data.mVtxNum * vertStride) + 0x1F) & ~0x1F;
JUT_ASSERT(1234, expect == addrDiff);
// u32 expect = ((data.mVtxNum * vertStride) + 0x1F) & ~0x1F;
// JUT_ASSERT(1234, expect == addrDiff);
} else if (attr == GX_VA_NRM) {
data.mNrmNum = num;
} else if (attr == GX_VA_CLR0) {
+9 -1
View File
@@ -1,6 +1,9 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JASChannel.h"
#if TARGET_PC
#include "dusk/audio/DuskDsp.hpp"
#endif
#include "JSystem/JAudio2/JASAiCtrl.h"
#include "JSystem/JAudio2/JASCalc.h"
#include "JSystem/JAudio2/JASDriverIF.h"
@@ -170,7 +173,12 @@ void JASChannel::updateEffectorParam(JASDsp::TChannel* i_channel, u16* i_mixerVo
f32 pan = 0.5f;
f32 dolby = 0.0f;
switch (JASDriver::getOutputMode()) {
#if TARGET_PC
u32 effectiveOutputMode = dusk::audio::EnableHrtf ? JAS_OUTPUT_SURROUND : JASDriver::getOutputMode();
#else
u32 effectiveOutputMode = JASDriver::getOutputMode();
#endif
switch (effectiveOutputMode) {
case JAS_OUTPUT_MONO:
break;
case JAS_OUTPUT_STEREO:
-1
View File
@@ -302,7 +302,6 @@ void JASKernel::setupRootHeap(JKRSolidHeap* heap, u32 size) {
JKRHEAP_NAME(sSystemHeap, "JASKernel::sSystemHeap");
JUT_ASSERT(787, sSystemHeap);
sCommandHeap = JKR_NEW_ARGS (heap, 0) JASMemChunkPool<1024, JASThreadingModel::ObjectLevelLockable>;
JKRHEAP_NAME(sSystemHeap, "JASKernel::sCommandHeap");
JUT_ASSERT(790, sCommandHeap);
JASDram = heap;
}
@@ -442,6 +442,7 @@ static JAUSectionHeap* JAUNewSectionHeap(JKRSolidHeap* heap, bool param_1) {
JAUSectionHeap* JAUNewSectionHeap(bool param_0) {
s32 freeSize = JASDram->getFreeSize();
JKRSolidHeap* sectionHeap = JKRCreateSolidHeap(freeSize, JASDram, true);
JKRHEAP_NAME(sectionHeap, "sectionHeap");
JUT_ASSERT(821, sectionHeap);
return JAUNewSectionHeap(sectionHeap, param_0);
}
+8 -5
View File
@@ -222,16 +222,11 @@ void* JKRExpHeap::do_alloc(u32 size, int alignment) {
OSReport_Error("Free block list as follows:\n");
OSReport_Error("Start | End | Size \n");
int i = 0;
for (const CMemBlock* block = mHeadFreeList; block; block = block->mNext) {
if (block->mMagic) {
// Allocated, ignore.
continue;
}
if (i++ > 10) {
OSReport_Error("<more>\n");
break;
}
auto blockStart = (uintptr_t)block - (uintptr_t)mStart;
auto blockEnd = (uintptr_t)block + block->size - (uintptr_t)mStart;
@@ -239,6 +234,14 @@ void* JKRExpHeap::do_alloc(u32 size, int alignment) {
OSReport_Error("%08X | %08X | %08X\n", (u32) blockStart, (u32) blockEnd, (u32) blockSize);
}
OSReport_Error("Child heaps as follows:\n");
OSReport_Error("Start | End | Name \n");
const JSUTree<JKRHeap>& tree = getHeapTree();
for (JSUTreeIterator iter(tree.getFirstChild()); iter != tree.getEndChild(); ++iter) {
OSReport_Error("%08X | %08X | %s\n", iter->getStartAddr(), iter->getEndAddr(), iter->getName());
}
CRASH("Aborting due to allocation failure!");
}
#else
+255 -113
View File
@@ -9,6 +9,9 @@
#include <mtx.h>
#include <gx.h>
#if TARGET_PC
#include "dusk/frame_interpolation.h"
#endif
#include "tracy/Tracy.hpp"
void JPASetPointSize(JPAEmitterWorkData* work) {
@@ -418,50 +421,95 @@ static projectionFunc p_prj[3] = {
loadPrjAnm,
};
void JPADrawBillboard(JPAEmitterWorkData* work, JPABaseParticle* param_1) {
if (param_1->checkStatus(JPAPtclStts_Invisible)) {
#if TARGET_PC
void JPAInterpBillboard(JPAEmitterWorkData* work, JPABaseParticle* ptcl) {
Mtx ptclPosMtx;
MTXTrans(ptclPosMtx, ptcl->mPosition.x, ptcl->mPosition.y, ptcl->mPosition.z);
dusk::frame_interp::record_final_mtx(ptclPosMtx, ptcl);
}
void JPAInterpRotBillboard(JPAEmitterWorkData* work, JPABaseParticle* ptcl) {
Mtx ptclPosMtx;
f32 sinRot = JMASSin(ptcl->mRotateAngle);
f32 cosRot = JMASCos(ptcl->mRotateAngle);
MTXTrans(ptclPosMtx, ptcl->mPosition.x, ptcl->mPosition.y, ptcl->mPosition.z);
ptclPosMtx[0][0] = cosRot;
ptclPosMtx[0][1] = -sinRot;
ptclPosMtx[1][0] = sinRot;
ptclPosMtx[1][1] = cosRot;
dusk::frame_interp::record_final_mtx(ptclPosMtx, ptcl);
}
#endif
void JPADrawBillboard(JPAEmitterWorkData* work, JPABaseParticle* ptcl) {
if (ptcl->checkStatus(JPAPtclStts_Invisible)) {
return;
}
JGeometry::TVec3<f32> local_48;
MTXMultVec(work->mPosCamMtx, &param_1->mPosition, &local_48);
Mtx local_38;
local_38[0][0] = work->mGlobalPtclScl.x * param_1->mParticleScaleX;
local_38[0][3] = local_48.x;
local_38[1][1] = work->mGlobalPtclScl.y * param_1->mParticleScaleY;
local_38[1][3] = local_48.y;
local_38[2][2] = 1.0f;
local_38[2][3] = local_48.z;
local_38[0][1] = local_38[0][2] = local_38[1][0] = local_38[1][2] = local_38[2][0] = local_38[2][1] = 0.0f;
GXLoadPosMtxImm(local_38, 0);
p_prj[work->mPrjType](work, local_38);
JGeometry::TVec3<f32> pos;
#if TARGET_PC
Mtx ptclPosMtx;
if (dusk::frame_interp::lookup_replacement(ptcl, ptclPosMtx)) {
pos.set(ptclPosMtx[0][3], ptclPosMtx[1][3], ptclPosMtx[2][3]);
MTXMultVec(work->mPosCamMtx, &pos, &pos);
} else
#endif
{
MTXMultVec(work->mPosCamMtx, &ptcl->mPosition, &pos);
}
Mtx posMtx;
posMtx[0][0] = work->mGlobalPtclScl.x * ptcl->mParticleScaleX;
posMtx[0][3] = pos.x;
posMtx[1][1] = work->mGlobalPtclScl.y * ptcl->mParticleScaleY;
posMtx[1][3] = pos.y;
posMtx[2][2] = 1.0f;
posMtx[2][3] = pos.z;
posMtx[0][1] = posMtx[0][2] = posMtx[1][0] = posMtx[1][2] = posMtx[2][0] = posMtx[2][1] = 0.0f;
GXLoadPosMtxImm(posMtx, GX_PNMTX0);
p_prj[work->mPrjType](work, posMtx);
GXCallDisplayList(jpa_dl, sizeof(jpa_dl));
}
void JPADrawRotBillboard(JPAEmitterWorkData* work, JPABaseParticle* param_1) {
if (param_1->checkStatus(JPAPtclStts_Invisible)) {
void JPADrawRotBillboard(JPAEmitterWorkData* work, JPABaseParticle* ptcl) {
if (ptcl->checkStatus(JPAPtclStts_Invisible)) {
return;
}
JGeometry::TVec3<f32> local_48;
MTXMultVec(work->mPosCamMtx, &param_1->mPosition, &local_48);
f32 sinRot = JMASSin(param_1->mRotateAngle);
f32 cosRot = JMASCos(param_1->mRotateAngle);
f32 particleX = work->mGlobalPtclScl.x * param_1->mParticleScaleX;
f32 particleY = work->mGlobalPtclScl.y * param_1->mParticleScaleY;
if (work->mpRes->getUsrIdx() == 0x89d7) {
int a = 0;
}
Mtx local_38;
local_38[0][0] = cosRot * particleX;
local_38[0][1] = -sinRot * particleY;
local_38[0][3] = local_48.x;
local_38[1][0] = sinRot * particleX;
local_38[1][1] = cosRot * particleY;
local_38[1][3] = local_48.y;
local_38[2][2] = 1.0f;
local_38[2][3] = local_48.z;
local_38[0][2] = local_38[1][2] = local_38[2][0] = local_38[2][1] = 0.0f;
GXLoadPosMtxImm(local_38, 0);
p_prj[work->mPrjType](work, local_38);
JGeometry::TVec3<f32> pos;
f32 sinRot, cosRot;
#if TARGET_PC
Mtx ptclPosMtx;
MTXTrans(ptclPosMtx, ptcl->mPosition.x, ptcl->mPosition.y, ptcl->mPosition.z);
if (dusk::frame_interp::lookup_replacement(ptcl, ptclPosMtx)) {
pos.set(ptclPosMtx[0][3], ptclPosMtx[1][3], ptclPosMtx[2][3]);
sinRot = ptclPosMtx[1][0];
cosRot = ptclPosMtx[0][0];
MTXMultVec(work->mPosCamMtx, &pos, &pos);
} else
#endif
{
MTXMultVec(work->mPosCamMtx, &ptcl->mPosition, &pos);
sinRot = JMASSin(ptcl->mRotateAngle);
cosRot = JMASCos(ptcl->mRotateAngle);
}
f32 particleX = work->mGlobalPtclScl.x * ptcl->mParticleScaleX;
f32 particleY = work->mGlobalPtclScl.y * ptcl->mParticleScaleY;
Mtx posMtx;
posMtx[0][0] = cosRot * particleX;
posMtx[0][1] = -sinRot * particleY;
posMtx[0][3] = pos.x;
posMtx[1][0] = sinRot * particleX;
posMtx[1][1] = cosRot * particleY;
posMtx[1][3] = pos.y;
posMtx[2][2] = 1.0f;
posMtx[2][3] = pos.z;
posMtx[0][2] = posMtx[1][2] = posMtx[2][0] = posMtx[2][1] = 0.0f;
GXLoadPosMtxImm(posMtx, GX_PNMTX0);
p_prj[work->mPrjType](work, posMtx);
GXCallDisplayList(jpa_dl, sizeof(jpa_dl));
}
@@ -484,7 +532,7 @@ void JPADrawYBillboard(JPAEmitterWorkData* work, JPABaseParticle* param_1) {
local_38[2][2] = work->mYBBCamMtx[2][2];
local_38[2][3] = local_48.z;
local_38[0][1] = local_38[0][2] = local_38[1][0] = local_38[2][0] = 0.0f;
GXLoadPosMtxImm(local_38, 0);
GXLoadPosMtxImm(local_38, GX_PNMTX0);
p_prj[work->mPrjType](work, local_38);
GXCallDisplayList(jpa_dl, sizeof(jpa_dl));
}
@@ -517,7 +565,7 @@ void JPADrawRotYBillboard(JPAEmitterWorkData* work, JPABaseParticle* param_1) {
local_38[2][1] = local_94 * fVar1;
local_38[2][2] = local_90;
local_38[2][3] = local_48.z;
GXLoadPosMtxImm(local_38, 0);
GXLoadPosMtxImm(local_38, GX_PNMTX0);
p_prj[work->mPrjType](work, local_38);
GXCallDisplayList(jpa_dl, sizeof(jpa_dl));
}
@@ -681,103 +729,197 @@ static u8* p_dl[2] = {
jpa_dl_x,
};
void JPADrawDirection(JPAEmitterWorkData* param_0, JPABaseParticle* param_1) {
if (param_1->checkStatus(JPAPtclStts_Invisible)) {
#if TARGET_PC
void JPAInterpDirection(JPAEmitterWorkData* work, JPABaseParticle* ptcl) {
JGeometry::TVec3<f32> axisY;
JGeometry::TVec3<f32> axisZ;
p_direction[work->mDirType](work, ptcl, &axisY);
if (axisY.isZero()) {
return;
}
ZoneScoped;
axisY.normalize();
axisZ.cross(ptcl->mBaseAxis, axisY);
JGeometry::TVec3<f32> local_6c;
JGeometry::TVec3<f32> local_78;
p_direction[param_0->mDirType](param_0, param_1, &local_6c);
if (local_6c.isZero()) {
if (axisZ.isZero()) {
return;
}
local_6c.normalize();
local_78.cross(param_1->mBaseAxis, local_6c);
if (local_78.isZero()) {
return;
}
local_78.normalize();
param_1->mBaseAxis.cross(local_6c, local_78);
param_1->mBaseAxis.normalize();
Mtx local_60;
f32 fVar1 = param_0->mGlobalPtclScl.x * param_1->mParticleScaleX;
f32 fVar2 = param_0->mGlobalPtclScl.y * param_1->mParticleScaleY;
local_60[0][0] = param_1->mBaseAxis.x;
local_60[0][1] = local_6c.x;
local_60[0][2] = local_78.x;
local_60[0][3] = param_1->mPosition.x;
local_60[1][0] = param_1->mBaseAxis.y;
local_60[1][1] = local_6c.y;
local_60[1][2] = local_78.y;
local_60[1][3] = param_1->mPosition.y;
local_60[2][0] = param_1->mBaseAxis.z;
local_60[2][1] = local_6c.z;
local_60[2][2] = local_78.z;
local_60[2][3] = param_1->mPosition.z;
p_plane[param_0->mPlaneType](local_60, fVar1, fVar2);
MTXConcat(param_0->mPosCamMtx, local_60, local_60);
GXLoadPosMtxImm(local_60, 0);
p_prj[param_0->mPrjType](param_0, local_60);
GXCallDisplayList(p_dl[param_0->mDLType], sizeof(jpa_dl));
axisZ.normalize();
ptcl->mBaseAxis.cross(axisY, axisZ);
ptcl->mBaseAxis.normalize();
Mtx posMtx;
f32 scaleX = work->mGlobalPtclScl.x * ptcl->mParticleScaleX;
f32 scaleY = work->mGlobalPtclScl.y * ptcl->mParticleScaleY;
posMtx[0][0] = ptcl->mBaseAxis.x;
posMtx[0][1] = axisY.x;
posMtx[0][2] = axisZ.x;
posMtx[0][3] = ptcl->mPosition.x;
posMtx[1][0] = ptcl->mBaseAxis.y;
posMtx[1][1] = axisY.y;
posMtx[1][2] = axisZ.y;
posMtx[1][3] = ptcl->mPosition.y;
posMtx[2][0] = ptcl->mBaseAxis.z;
posMtx[2][1] = axisY.z;
posMtx[2][2] = axisZ.z;
posMtx[2][3] = ptcl->mPosition.z;
p_plane[work->mPlaneType](posMtx, scaleX, scaleY);
dusk::frame_interp::record_final_mtx(posMtx, ptcl);
}
void JPADrawRotDirection(JPAEmitterWorkData* param_0, JPABaseParticle* param_1) {
if (param_1->checkStatus(JPAPtclStts_Invisible)) {
void JPAInterpRotDirection(JPAEmitterWorkData* work, JPABaseParticle* ptcl) {
f32 sinRot = JMASSin(ptcl->mRotateAngle);
f32 cosRot = JMASCos(ptcl->mRotateAngle);
JGeometry::TVec3<f32> axisY;
JGeometry::TVec3<f32> axisZ;
p_direction[work->mDirType](work, ptcl, &axisY);
if (axisY.isZero()) {
return;
}
axisY.normalize();
axisZ.cross(ptcl->mBaseAxis, axisY);
if (axisZ.isZero()) {
return;
}
axisZ.normalize();
ptcl->mBaseAxis.cross(axisY, axisZ);
ptcl->mBaseAxis.normalize();
f32 scaleX = work->mGlobalPtclScl.x * ptcl->mParticleScaleX;
f32 scaleY = work->mGlobalPtclScl.y * ptcl->mParticleScaleY;
Mtx mtx1;
Mtx mtx2;
p_rot[work->mRotType](sinRot, cosRot, mtx1);
p_plane[work->mPlaneType](mtx1, scaleX, scaleY);
mtx2[0][0] = ptcl->mBaseAxis.x;
mtx2[0][1] = axisY.x;
mtx2[0][2] = axisZ.x;
mtx2[0][3] = ptcl->mPosition.x;
mtx2[1][0] = ptcl->mBaseAxis.y;
mtx2[1][1] = axisY.y;
mtx2[1][2] = axisZ.y;
mtx2[1][3] = ptcl->mPosition.y;
mtx2[2][0] = ptcl->mBaseAxis.z;
mtx2[2][1] = axisY.z;
mtx2[2][2] = axisZ.z;
mtx2[2][3] = ptcl->mPosition.z;
MTXConcat(mtx2, mtx1, mtx1);
dusk::frame_interp::record_final_mtx(mtx1, ptcl);
}
#endif
void JPADrawDirection(JPAEmitterWorkData* work, JPABaseParticle* ptcl) {
if (ptcl->checkStatus(JPAPtclStts_Invisible)) {
return;
}
ZoneScoped;
f32 sinRot = JMASSin(param_1->mRotateAngle);
f32 cosRot = JMASCos(param_1->mRotateAngle);
JGeometry::TVec3<f32> local_6c;
JGeometry::TVec3<f32> local_78;
p_direction[param_0->mDirType](param_0, param_1, &local_6c);
Mtx posMtx;
#if TARGET_PC
if (!dusk::frame_interp::lookup_replacement(ptcl, posMtx))
#endif
{
JGeometry::TVec3<f32> axisY;
JGeometry::TVec3<f32> axisZ;
p_direction[work->mDirType](work, ptcl, &axisY);
if (local_6c.isZero()) {
if (axisY.isZero()) {
return;
}
axisY.normalize();
axisZ.cross(ptcl->mBaseAxis, axisY);
if (axisZ.isZero()) {
return;
}
axisZ.normalize();
ptcl->mBaseAxis.cross(axisY, axisZ);
ptcl->mBaseAxis.normalize();
f32 scaleX = work->mGlobalPtclScl.x * ptcl->mParticleScaleX;
f32 scaleY = work->mGlobalPtclScl.y * ptcl->mParticleScaleY;
posMtx[0][0] = ptcl->mBaseAxis.x;
posMtx[0][1] = axisY.x;
posMtx[0][2] = axisZ.x;
posMtx[0][3] = ptcl->mPosition.x;
posMtx[1][0] = ptcl->mBaseAxis.y;
posMtx[1][1] = axisY.y;
posMtx[1][2] = axisZ.y;
posMtx[1][3] = ptcl->mPosition.y;
posMtx[2][0] = ptcl->mBaseAxis.z;
posMtx[2][1] = axisY.z;
posMtx[2][2] = axisZ.z;
posMtx[2][3] = ptcl->mPosition.z;
p_plane[work->mPlaneType](posMtx, scaleX, scaleY);
}
MTXConcat(work->mPosCamMtx, posMtx, posMtx);
GXLoadPosMtxImm(posMtx, GX_PNMTX0);
p_prj[work->mPrjType](work, posMtx);
GXCallDisplayList(p_dl[work->mDLType], sizeof(jpa_dl));
}
void JPADrawRotDirection(JPAEmitterWorkData* work, JPABaseParticle* ptcl) {
if (ptcl->checkStatus(JPAPtclStts_Invisible)) {
return;
}
local_6c.normalize();
local_78.cross(param_1->mBaseAxis, local_6c);
ZoneScoped;
if (local_78.isZero()) {
return;
Mtx mtx1;
Mtx mtx2;
#if TARGET_PC
if (!dusk::frame_interp::lookup_replacement(ptcl, mtx1))
#endif
{
f32 sinRot = JMASSin(ptcl->mRotateAngle);
f32 cosRot = JMASCos(ptcl->mRotateAngle);
JGeometry::TVec3<f32> axisY;
JGeometry::TVec3<f32> axisZ;
p_direction[work->mDirType](work, ptcl, &axisY);
if (axisY.isZero()) {
return;
}
axisY.normalize();
axisZ.cross(ptcl->mBaseAxis, axisY);
if (axisZ.isZero()) {
return;
}
axisZ.normalize();
ptcl->mBaseAxis.cross(axisY, axisZ);
ptcl->mBaseAxis.normalize();
f32 scaleX = work->mGlobalPtclScl.x * ptcl->mParticleScaleX;
f32 scaleY = work->mGlobalPtclScl.y * ptcl->mParticleScaleY;
p_rot[work->mRotType](sinRot, cosRot, mtx1);
p_plane[work->mPlaneType](mtx1, scaleX, scaleY);
mtx2[0][0] = ptcl->mBaseAxis.x;
mtx2[0][1] = axisY.x;
mtx2[0][2] = axisZ.x;
mtx2[0][3] = ptcl->mPosition.x;
mtx2[1][0] = ptcl->mBaseAxis.y;
mtx2[1][1] = axisY.y;
mtx2[1][2] = axisZ.y;
mtx2[1][3] = ptcl->mPosition.y;
mtx2[2][0] = ptcl->mBaseAxis.z;
mtx2[2][1] = axisY.z;
mtx2[2][2] = axisZ.z;
mtx2[2][3] = ptcl->mPosition.z;
MTXConcat(mtx2, mtx1, mtx1);
}
local_78.normalize();
param_1->mBaseAxis.cross(local_6c, local_78);
param_1->mBaseAxis.normalize();
f32 particleX = param_0->mGlobalPtclScl.x * param_1->mParticleScaleX;
f32 particleY = param_0->mGlobalPtclScl.y * param_1->mParticleScaleY;
Mtx auStack_80;
Mtx local_60;
p_rot[param_0->mRotType](sinRot, cosRot, auStack_80);
p_plane[param_0->mPlaneType](auStack_80, particleX, particleY);
local_60[0][0] = param_1->mBaseAxis.x;
local_60[0][1] = local_6c.x;
local_60[0][2] = local_78.x;
local_60[0][3] = param_1->mPosition.x;
local_60[1][0] = param_1->mBaseAxis.y;
local_60[1][1] = local_6c.y;
local_60[1][2] = local_78.y;
local_60[1][3] = param_1->mPosition.y;
local_60[2][0] = param_1->mBaseAxis.z;
local_60[2][1] = local_6c.z;
local_60[2][2] = local_78.z;
local_60[2][3] = param_1->mPosition.z;
MTXConcat(local_60, auStack_80, auStack_80);
MTXConcat(param_0->mPosCamMtx, auStack_80, local_60);
GXLoadPosMtxImm(local_60, 0);
p_prj[param_0->mPrjType](param_0, local_60);
GXCallDisplayList(p_dl[param_0->mDLType], sizeof(jpa_dl));
MTXConcat(work->mPosCamMtx, mtx1, mtx2);
GXLoadPosMtxImm(mtx2, GX_PNMTX0);
p_prj[work->mPrjType](work, mtx2);
GXCallDisplayList(p_dl[work->mDLType], sizeof(jpa_dl));
}
void JPADrawDBillboard(JPAEmitterWorkData* param_0, JPABaseParticle* param_1) {
@@ -204,6 +204,28 @@ void JPABaseParticle::init_c(JPAEmitterWorkData* work, JPABaseParticle* parent)
mTexAnmIdx = 0;
}
#if TARGET_PC
void JPABaseParticle::interp(JPAEmitterWorkData* work, void const* drawFunc) {
static bool enable = false;
if (!enable)
return;
// don't interpolate the first frame
if (mAge == 0)
return;
if (drawFunc == JPADrawBillboard) {
JPAInterpBillboard(work, this);
} else if (drawFunc == JPADrawRotBillboard) {
JPAInterpRotBillboard(work, this);
} else if (drawFunc == JPADrawDirection) {
JPAInterpDirection(work, this);
} else if (drawFunc == JPADrawRotDirection) {
JPAInterpRotDirection(work, this);
}
}
#endif
bool JPABaseParticle::calc_p(JPAEmitterWorkData* work) {
if (++mAge >= mLifeTime) {
return true;
@@ -247,6 +269,17 @@ bool JPABaseParticle::calc_p(JPAEmitterWorkData* work) {
mOffsetPosition.y + mLocalPosition.y * work->mPublicScale.y,
mOffsetPosition.z + mLocalPosition.z * work->mPublicScale.z);
#if TARGET_PC
JPABaseShape* pBsp = work->mpRes->getBsp();
work->mGlobalPtclScl.x = work->mpEmtr->mGlobalPScl.x * pBsp->getBaseSizeX();
work->mGlobalPtclScl.y = work->mpEmtr->mGlobalPScl.y * pBsp->getBaseSizeY();
work->mDirType = pBsp->getDirType();
work->mRotType = pBsp->getRotType();
work->mDLType = pBsp->getType() == 4 || pBsp->getType() == 8;
work->mPlaneType = work->mDLType ? 2 : pBsp->getBasePlaneType();
interp(work, (void const*)work->mpRes->mpDrawParticleFuncList[0]);
#endif
return false;
}
@@ -289,6 +322,23 @@ bool JPABaseParticle::calc_c(JPAEmitterWorkData* work) {
mOffsetPosition.y + mLocalPosition.y * work->mPublicScale.y,
mOffsetPosition.z + mLocalPosition.z * work->mPublicScale.z);
#if TARGET_PC
JPABaseShape* pBsp = work->mpRes->getBsp();
JPAChildShape* pCsp = work->mpRes->getCsp();
if (pCsp->isScaleInherited()) {
work->mGlobalPtclScl.x = work->mpEmtr->mGlobalPScl.x * pBsp->getBaseSizeX();
work->mGlobalPtclScl.y = work->mpEmtr->mGlobalPScl.y * pBsp->getBaseSizeY();
} else {
work->mGlobalPtclScl.x = work->mpEmtr->mGlobalPScl.x * pCsp->getScaleX();
work->mGlobalPtclScl.y = work->mpEmtr->mGlobalPScl.y * pCsp->getScaleY();
}
work->mDirType = pCsp->getDirType();
work->mRotType = pCsp->getRotType();
work->mDLType = pCsp->getType() == 4 || pCsp->getType() == 8;
work->mPlaneType = work->mDLType ? 2 : pCsp->getBasePlaneType();
interp(work, (void const*)work->mpRes->mpDrawParticleChildFuncList[0]);
#endif
return false;
}
+6
View File
@@ -38,3 +38,9 @@ bool JUTPalette::load() {
return check;
}
#if TARGET_PC
void JUTPalette::dataUploaded() {
GXInitTlutObjData(&mTlutObj, (void*)mColorTable);
}
#endif
+9 -9
View File
@@ -27,7 +27,7 @@ void JUTTexture::storeTIMG(ResTIMG const* param_0, u8 param_1) {
mTexData = (void*)((intptr_t)mTexInfo + 0x20);
}
field_0x2c = NULL;
mPalette = NULL;
mTlutName = 0;
mWrapS = mTexInfo->wrapS;
mWrapT = mTexInfo->wrapT;
@@ -95,7 +95,7 @@ void JUTTexture::storeTIMG(ResTIMG const* param_0, JUTPalette* param_1, GXTlut p
}
mEmbPalette = param_1;
setEmbPaletteDelFlag(false);
field_0x2c = NULL;
mPalette = NULL;
if (param_1 != NULL) {
mTlutName = param_2;
if (param_2 != param_1->getTlutName()) {
@@ -120,11 +120,11 @@ void JUTTexture::storeTIMG(ResTIMG const* param_0, JUTPalette* param_1, GXTlut p
void JUTTexture::attachPalette(JUTPalette* param_0) {
if (mTexInfo->indexTexture) {
if (param_0 == NULL && mEmbPalette != NULL) {
field_0x2c = mEmbPalette;
mPalette = mEmbPalette;
} else {
field_0x2c = param_0;
mPalette = param_0;
}
initTexObj(field_0x2c->getTlutName());
initTexObj(mPalette->getTlutName());
}
}
@@ -133,9 +133,9 @@ void JUTTexture::init() {
initTexObj();
} else {
if (mEmbPalette != NULL) {
field_0x2c = mEmbPalette;
mPalette = mEmbPalette;
initTexObj(field_0x2c->getTlutName());
initTexObj(mPalette->getTlutName());
} else {
OS_REPORT("This texture is CI-Format, but EmbPalette is NULL.\n");
}
@@ -179,8 +179,8 @@ void JUTTexture::initTexObj(GXTlut param_0) {
}
void JUTTexture::load(GXTexMapID param_0) {
if (field_0x2c) {
field_0x2c->load();
if (mPalette) {
mPalette->load();
}
GXLoadTexObj(&mTexObj, param_0);
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 457 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

+276
View File
@@ -0,0 +1,276 @@
*, *:before, *:after {
box-sizing: border-box;
}
body {
overflow: visible;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
font-family: "Fira Sans";
font-weight: normal;
font-size: 20dp;
color: #E0DBC8;
display: flex;
flex-direction: column;
justify-content: flex-end;
align-items: stretch;
z-index: 1;
pointer-events: none;
}
fps,
toast {
position: absolute;
border: 1dp #92875B;
background-color: rgba(21, 22, 16, 80%);
}
toast {
top: 40dp;
right: 40dp;
display: flex;
flex-flow: column;
border-radius: 14dp;
overflow: hidden;
backdrop-filter: blur(5dp);
box-shadow: 0 0 15dp 3dp;
filter: opacity(0);
transform: scale(0.9);
transform-origin: center;
transition: filter transform 0.2s cubic-in-out;
padding: 18dp 24dp;
gap: 8dp;
}
toast[open] {
filter: opacity(1);
transform: scale(1);
}
/*toast:hover {
cursor: pointer;
background-color: rgba(61, 59, 36, 80%);
}
toast:active {
background-color: rgba(45, 43, 26, 80%);
}*/
toast heading {
display: flex;
gap: 18dp;
align-items: center;
font-family: "Fira Sans Condensed";
font-size: 18dp;
font-weight: bold;
text-transform: uppercase;
color: #92875B;
}
toast heading > span {
flex: 1 0 auto;
}
toast heading > row {
flex: 1 0 auto;
display: flex;
align-items: center;
gap: 4dp;
}
toast message {
display: flex;
flex-flow: column;
gap: 8dp;
}
toast message row {
display: flex;
}
toast message row.muted {
opacity: 0.5;
}
toast progress {
height: 4dp;
position: absolute;
left: 0;
bottom: 0;
width: 100%;
}
toast progress fill {
background-color: rgba(194, 164, 45, 80%);
}
toast.achievement {
border: 1dp #C2A42D;
}
toast.achievement heading {
color: #C2A42D;
}
toast.controller-warning {
top: auto;
right: auto;
bottom: 40dp;
left: 50%;
width: 440dp;
max-width: 90%;
transform: translateX(-50%) scale(0.9);
}
toast.controller-warning[open] {
transform: translateX(-50%) scale(1);
}
toast.controller-warning heading {
color: #C2A42D;
}
toast.menu-notification {
top: 40dp;
right: auto;
bottom: auto;
left: 50%;
max-width: 90%;
transform: translateX(-50%) scale(0.9);
}
toast.menu-notification[open] {
transform: translateX(-50%) scale(1);
}
toast.menu-notification message {
align-items: center;
text-align: center;
}
toast.menu-notification message row {
align-items: center;
gap: 6dp;
}
icon {
font-family: "Material Symbols Rounded";
font-weight: normal;
display: inline-block;
vertical-align: middle;
}
icon.arrow-forward {
width: 24dp;
height: 24dp;
font-size: 24dp;
decorator: text("&#xe5c8;" center center);
}
icon.trophy {
width: 24dp;
height: 24dp;
font-size: 24dp;
decorator: text("&#xe71a;" center center);
}
icon.controller {
width: 24dp;
height: 24dp;
font-size: 24dp;
decorator: text("&#xf135;" center center);
}
icon.warning {
width: 24dp;
height: 24dp;
font-size: 24dp;
decorator: text("&#xe002;" center center);
}
fps {
display: none;
z-index: 99;
font-size: 18dp;
font-weight: bold;
padding: 9dp 12dp;
border-radius: 7dp;
pointer-events: none;
white-space: nowrap;
}
fps[open] {
display: block;
}
fps[corner=tl] {
top: 12dp;
left: 12dp;
}
fps[corner=tr] {
top: 12dp;
right: 12dp;
}
fps[corner=bl] {
bottom: 12dp;
left: 12dp;
}
fps[corner=br] {
bottom: 12dp;
right: 12dp;
}
logo {
position: absolute;
width: 100dp;
height: 100dp;
bottom: 40dp;
left: 40dp;
opacity: 0;
transition: opacity 0.5s linear-in-out;
}
logo[open] {
opacity: 0.65;
}
logo img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
filter: drop-shadow(#0008 0 0 14dp);
transform-origin: center;
}
logo img.inner {
animation: 24s linear-in-out infinite logo-inner-spin;
}
logo img.outer {
animation: 8s linear-in-out infinite logo-outer-spin;
}
@keyframes logo-inner-spin {
from {
transform: rotate(360deg);
}
to {
transform: rotate(0deg);
}
}
@keyframes logo-outer-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
+45
View File
@@ -0,0 +1,45 @@
*, *:before, *:after {
box-sizing: border-box;
}
body {
overflow: visible;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
font-family: "Fira Sans Condensed";
font-weight: bold;
font-size: 18dp;
color: #E0DBC8;
}
button {
cursor: pointer;
focus: auto;
}
popup {
width: 100%;
display: flex;
align-items: stretch;
height: 64dp;
background-color: rgba(21, 22, 16, 80%);
border-bottom: 2dp #92875B;
backdrop-filter: blur(5dp);
transform: translateY(-64dp);
transition: transform 0.2s cubic-in-out;
}
popup[open] {
transform: translateY(0);
}
popup tab-bar {
flex: 1 1 0;
}
popup tab-bar tab {
opacity: 0.35;
color: #E0DBC8;
}
+405
View File
@@ -0,0 +1,405 @@
*, *:before, *:after {
box-sizing: border-box;
}
body {
width: 100%;
height: 100%;
font-family: "Fira Sans";
font-weight: normal;
font-size: 20dp;
color: #FFFFFF;
filter: opacity(0);
transition: filter 1s 0.2s linear-in-out;
z-index: -1;
}
.gradient {
position: absolute;
width: 100%;
height: 100%;
/* The color gradient from the Figma bands really badly. A fully black gradient does as well, but not as badly. */
decorator: horizontal-gradient(#000000FF #00000000);
}
body.mirrored .gradient {
decorator: horizontal-gradient(#00000000 #000000FF);
}
.background {
position: absolute;
width: 100%;
height: 100%;
decorator: image(../prelaunch-bg.png cover left center);
opacity: 0;
transition: opacity 1s linear-in-out;
}
body[open] {
filter: opacity(1);
}
body[open] .background {
opacity: 1;
}
body.disc-ready .background {
opacity: 0;
}
content {
display: block;
width: 100%;
height: 100%;
filter: opacity(0);
transition: filter 0.2s linear-in-out;
}
content[open] {
filter: opacity(1);
}
menu {
position: absolute;
left: 96dp;
right: auto;
top: 50%;
transform: translateY(-50%);
/* Scale based on a reference screen width, 428/1216 */
width: 35.230264vw;
min-width: 428dp;
max-width: 856dp;
height: auto;
display: flex;
flex-direction: column;
gap: 48dp;
}
body.mirrored menu {
left: auto;
right: 96dp;
}
hero {
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-start;
gap: 8dp;
}
body.mirrored hero {
align-items: flex-end;
}
hero img {
width: 100%;
}
.eyebrow {
font-family: "Alegreya SC";
font-size: 32dp;
}
@media (min-width: 1216dp) {
.eyebrow {
/* Same logic as .menu, 32/1216 */
font-size: 2.631579vw;
}
}
.eyebrow span {
font-weight: bold;
}
#menu-list {
display: flex;
flex-direction: column;
gap: 12dp;
align-items: flex-start;
}
#menu-list button {
width: 428dp;
height: 54dp;
padding: 8dp 16dp;
border-radius: 8dp;
text-align: left;
text-transform: uppercase;
font-family: "Fira Sans Condensed";
font-size: 32dp;
font-weight: normal;
cursor: pointer;
/* Define a fully transparent gradient as the default state, otherwise a white flash occurs */
decorator: horizontal-gradient(#00000000 #00000000);
}
#menu-list button:disabled {
opacity: 0.75;
cursor: default;
decorator: horizontal-gradient(#00000000 #00000000);
}
#menu-list button.anim-done {
transition: decorator color opacity 0.1s linear-in-out;
}
#menu-list button:hover,
#menu-list button:focus-visible {
color: black;
decorator: horizontal-gradient(#FEE685FF #FEE68500);
}
body.mirrored #menu-list {
align-items: flex-end;
}
body.mirrored #menu-list button {
text-align: right;
}
body.mirrored #menu-list button:hover,
body.mirrored #menu-list button:focus-visible {
decorator: horizontal-gradient(#FEE68500 #FEE685FF);
}
disc-info {
position: absolute;
left: 96dp;
right: auto;
bottom: 72dp;
display: flex;
flex-direction: column;
gap: 12dp;
font-size: 24dp;
font-effect: glow(0dp 4dp 0dp 4dp black);
text-align: left;
}
body.mirrored disc-info {
left: auto;
right: 96dp;
text-align: right;
}
version-info {
position: absolute;
right: 96dp;
left: auto;
bottom: 72dp;
display: flex;
flex-direction: column;
gap: 12dp;
text-align: right;
font-size: 24dp;
font-effect: glow(0dp 4dp 0dp 4dp black);
text-align: right;
}
body.mirrored version-info {
right: auto;
left: 96dp;
text-align: left;
}
#disc-status {
display: flex;
align-items: center;
gap: 8dp;
}
#disc-status[status=good] {
color: #D8F999;
}
#disc-status[status=bad] {
color: #FFC9C9;
}
#disc-status[status=verifying] {
color: #FFFFFF;
}
#disc-status[status=mismatch] {
color: #FFD6A7;
}
#disc-status[status=unknown] {
color: rgba(224, 219, 200, 65%);
}
#disc-status[status=pending] {
color: #FEE685;
}
#disc-status icon {
display: none;
width: 24dp;
height: 24dp;
font-family: "Material Symbols Rounded";
font-weight: normal;
font-size: 24dp;
}
#disc-status[status] icon {
display: block;
}
#disc-status[status=good] icon {
decorator: text("&#xe5ca;" center center);
}
#disc-status[status=bad] icon {
decorator: text("&#xe5cd;" center center);
}
#disc-status[status=verifying] icon {
decorator: text("&#xe8b5;" center center);
}
#disc-status[status=mismatch] icon {
decorator: text("&#xe002;" center center);
}
#disc-status[status=unknown] icon {
decorator: text("&#xe887;" center center);
}
#disc-status[status=pending] icon {
decorator: text("&#xe863;" center center);
}
#disc-version {
font-size: 20dp;
}
/* TODO: Hidden until an actual update checker is introduced */
.update {
display: none;
font-size: 16dp;
font-weight: bold;
cursor: pointer;
color: #D8F999;
}
.detail,
.update span {
color: #A6A09B;
}
/* Startup animation */
.intro-item {
opacity: 0;
transform: translateY(10dp);
transition: opacity transform 0.3s 0.1s cubic-in-out;
}
body.animate-in .intro-item {
opacity: 1;
transform: translateY(0dp);
}
.delay-0 {
transition: opacity transform 0.3s 0.1s cubic-in-out;
}
.delay-1 {
transition: opacity transform 0.3s 0.2s cubic-in-out;
}
.delay-2 {
transition: opacity transform 0.3s 0.3s cubic-in-out;
}
.delay-3 {
transition: opacity transform 0.3s 0.4s cubic-in-out;
}
.delay-4 {
transition: opacity transform 0.3s 0.5s cubic-in-out;
}
.delay-5 {
transition: opacity transform 0.3s 0.6s cubic-in-out;
}
/* Mobile layout */
@media (max-height: 640dp) {
.gradient {
decorator: horizontal-gradient(#00000000 #000000FF);
}
body.mirrored .gradient {
decorator: horizontal-gradient(#000000FF #00000000);
}
menu {
left: 20dp;
right: 20dp;
width: auto;
min-width: 0;
max-width: none;
flex-direction: row;
align-items: center;
justify-content: space-between;
gap: 16dp;
}
body.mirrored menu {
left: 20dp;
right: 20dp;
flex-direction: row-reverse;
}
hero {
flex: 1 1 0;
min-width: 0;
max-width: 48%;
}
body.mirrored hero {
align-items: flex-end;
}
hero img {
width: 100%;
}
#menu-list {
flex: 1 1 0;
min-width: 0;
max-width: 52%;
align-items: flex-end;
}
#menu-list button {
width: 100%;
max-width: 100%;
text-align: right;
}
#menu-list button:hover,
#menu-list button:focus-visible {
decorator: horizontal-gradient(#FEE68500 #FEE685FF);
}
body.mirrored #menu-list {
align-items: flex-start;
}
body.mirrored #menu-list button {
text-align: left;
}
body.mirrored #menu-list button:hover,
body.mirrored #menu-list button:focus-visible {
decorator: horizontal-gradient(#FEE685FF #FEE68500);
}
.eyebrow,
disc-info,
version-info {
display: none;
}
}
+81
View File
@@ -0,0 +1,81 @@
tab-bar {
display: flex;
position: relative;
min-width: 0;
overflow: auto hidden;
clip: always;
text-transform: uppercase;
}
tab-bar scrollbarhorizontal,
tab-bar scrollbarhorizontal sliderarrowdec,
tab-bar scrollbarhorizontal sliderarrowinc,
tab-bar scrollbarhorizontal slidertrack,
tab-bar scrollbarhorizontal sliderbar {
width: 0;
height: 0;
}
tab-bar tab {
flex: 0 0 auto;
padding: 0 24dp;
line-height: 64dp;
white-space: nowrap;
decorator: vertical-gradient(#c2a42d00 #c2a42d00);
transition: decorator 0.1s linear-in-out, opacity 0.1s linear-in-out;
cursor: pointer;
}
tab-bar tab:selected {
opacity: 1;
border-bottom: 4dp #C2A42D;
font-effect: glow(0dp 4dp 0dp 4dp black);
}
tab-bar tab:focus-visible,
tab-bar tab:hover {
opacity: 1;
font-effect: glow(0dp 4dp 0dp 4dp black);
decorator: vertical-gradient(#c2a42d00 #c2a42d26);
}
tab-bar tab:active {
decorator: vertical-gradient(#c2a42d10 #c2a42d40);
}
tab-bar[closable] tab-end-spacer {
display: block;
flex: 0 0 64dp;
width: 64dp;
pointer-events: none;
}
tab-bar[closable] close {
display: block;
position: fixed;
top: 8dp;
right: 8dp;
z-index: 1;
width: 48dp;
height: 48dp;
font-family: "Material Symbols Rounded";
font-weight: normal;
font-size: 24dp;
color: rgba(224, 219, 200, 70%);
backdrop-filter: blur(2dp);
border-radius: 6dp;
decorator: text("&#xe5cd;" center center);
transition: color background-color 0.12s linear-in-out;
cursor: pointer;
}
tab-bar[closable] close:hover,
tab-bar[closable] close:focus-visible {
color: #fff;
background-color: rgba(194, 164, 45, 24%);
}
tab-bar[closable] close:active {
color: #fff;
background-color: rgba(194, 164, 45, 40%);
}
+147
View File
@@ -0,0 +1,147 @@
*, *:before, *:after {
box-sizing: border-box;
}
body {
overflow: visible;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
font-family: "Fira Sans Condensed";
font-size: 24dp;
color: #FFFFFF;
display: flex;
flex-direction: column;
justify-content: flex-end;
align-items: stretch;
}
.tuner-root {
width: 100%;
min-height: 45%;
display: flex;
flex-direction: column;
justify-content: flex-end;
align-items: stretch;
decorator: vertical-gradient(#00000000 #151610F2);
filter: opacity(0);
transition: filter 0.2s linear-in-out;
}
.tuner-root[open] {
filter: opacity(1);
}
.tuner {
width: 100%;
max-width: 1216dp;
margin-left: auto;
margin-right: auto;
display: flex;
flex-direction: column;
gap: 24dp;
padding: 48dp 64dp;
}
@media (max-height: 800dp) {
.tuner-root {
min-height: 38%;
}
.tuner {
gap: 16dp;
padding: 32dp 48dp;
}
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
gap: 24dp;
}
.carousel-container {
flex: 1 1 auto;
display: flex;
justify-content: flex-end;
min-width: 0;
}
.description {
font-size: 18dp;
line-height: 22dp;
color: rgba(255, 255, 255, 50%);
}
.divider {
margin: 1dp 0;
border-top: 1dp rgba(217, 217, 217, 50%);
}
.footer {
display: flex;
justify-content: space-between;
align-items: center;
gap: 24dp;
}
footer-button {
display: block;
width: 100%;
max-width: 220dp;
border: 0;
padding: 0;
background-color: transparent;
font-family: "Fira Sans Condensed";
font-weight: bold;
font-size: 20dp;
line-height: 24dp;
text-transform: uppercase;
color: #FFFFFF;
opacity: 1;
cursor: pointer;
}
footer-button.return {
text-align: left;
}
footer-button.reset {
text-align: right;
}
.stepped-carousel {
display: flex;
align-items: center;
justify-content: center;
gap: 16dp;
width: auto;
min-width: 246dp;
padding: 0;
background-color: transparent;
font-family: "Fira Sans Condensed";
font-weight: bold;
}
.stepped-carousel-value {
line-height: 29dp;
min-width: 166dp;
text-align: center;
white-space: nowrap;
opacity: 0.9;
}
.stepped-carousel-arrow {
width: 24dp;
height: 24dp;
min-width: 24dp;
padding: 0;
border: 0;
background-color: transparent;
opacity: 1;
cursor: pointer;
font-family: "Material Symbols Rounded";
font-weight: normal;
}
+493
View File
@@ -0,0 +1,493 @@
*, *:before, *:after {
box-sizing: border-box;
}
body {
display: flex;
width: 100%;
height: 100%;
padding: 64dp;
font-family: "Fira Sans";
font-weight: normal;
font-style: normal;
font-size: 15dp;
color: #E0DBC8;
}
window {
display: flex;
flex-flow: column;
height: 100%;
width: 100%;
max-width: 1088dp;
max-height: 768dp;
margin: auto;
border-radius: 14dp;
overflow: hidden;
border: 2dp #92875B;
backdrop-filter: blur(5dp);
box-shadow: 0 0 25dp 5dp;
background-color: rgba(21, 22, 16, 90%);
filter: opacity(0);
transform: scale(0.9);
transform-origin: center;
transition: filter transform 0.2s cubic-in-out;
}
window.small {
height: auto;
width: auto;
}
window.modal {
max-width: 640dp;
}
window[open] {
filter: opacity(1);
transform: scale(1);
}
@media (max-height: 640dp) {
body {
padding: 16dp;
}
window {
box-shadow: none;
}
}
window tab-bar {
flex: 0 0 64dp;
height: 64dp;
background-color: rgba(217, 217, 217, 10%);
font-family: "Fira Sans Condensed";
font-weight: bold;
font-size: 18dp;
border-bottom: 2dp #92875B;
}
window tab-bar tab {
opacity: 0.25;
}
window content {
display: flex;
flex: 1 1 auto;
min-width: 0;
min-height: 0;
overflow: hidden;
}
window content pane {
display: flex;
flex-flow: column;
flex: 1 1 0;
min-width: 0;
min-height: 0;
padding: 24dp;
padding-bottom: 0dp;
gap: 8dp;
overflow: hidden auto;
font-size: 20dp;
}
window content pane:not(:last-of-type) {
border-right: 1dp #92875B;
}
window content pane > * {
flex: 0 0 auto;
}
window content pane:last-of-type > div {
line-height: 1.625;
}
window content pane > spacer {
display: block;
/* Completes the 24dp bottom inset after the pane's 8dp gap. */
flex: 0 0 16dp;
height: 16dp;
pointer-events: none;
}
scrollbarvertical {
width: 8dp;
margin: 4dp 4dp 4dp 0;
}
scrollbarvertical sliderarrowdec,
scrollbarvertical sliderarrowinc {
width: 0;
height: 0;
}
scrollbarvertical slidertrack {
width: 8dp;
}
scrollbarvertical sliderbar {
width: 8dp;
min-height: 24dp;
background-color: rgba(224, 219, 200, 45%);
border-radius: 2dp;
transition: background-color 0.2s cubic-in-out;
}
scrollbarvertical sliderbar:hover,
scrollbarvertical sliderbar:active {
background-color: rgba(194, 164, 45, 80%);
}
scrollbarhorizontal {
height: 0;
}
scrollbarhorizontal sliderarrowdec,
scrollbarhorizontal sliderarrowinc {
width: 0;
height: 0;
}
scrollbarhorizontal slidertrack,
scrollbarhorizontal sliderbar {
width: 0;
height: 0;
}
.section-heading {
font-family: "Fira Sans Condensed";
font-weight: bold;
text-transform: uppercase;
font-size: 22dp;
opacity: 0.25;
}
.section-heading:not(:first-of-type) {
padding-top: 12dp;
}
button {
text-align: center;
background-color: rgba(17, 16, 10, 20%);
opacity: 0.9;
padding: 8dp 16dp;
border-radius: 14dp;
box-shadow: rgba(146, 135, 91, 25%) 0 0 0 1dp;
font-size: 20dp;
transition: background-color 0.1s linear-in-out, opacity 0.1s linear-in-out;
cursor: pointer;
focus: auto;
}
button:not(:disabled):hover,
button:not(:disabled):focus-visible {
background-color: rgba(204, 184, 119, 20%);
box-shadow: #C2A42D 0 0 0 2dp;
}
button:not(:disabled):selected {
opacity: 1;
background-color: rgba(204, 184, 119, 40%);
}
button:not(:disabled):active {
opacity: 1;
background-color: rgba(204, 184, 119, 40%);
box-shadow: #C2A42D 0 0 0 2dp;
}
button.modal-btn {
flex: 1 1 0;
text-align: center;
}
select-button {
display: flex;
align-items: center;
gap: 8dp;
background-color: rgba(17, 16, 10, 20%);
opacity: 0.9;
padding: 8dp 16dp;
border-radius: 14dp;
box-shadow: rgba(146, 135, 91, 25%) 0 0 0 1dp;
transition: background-color 0.1s linear-in-out, opacity 0.1s linear-in-out;
cursor: pointer;
focus: auto;
}
select-button:not(:disabled):hover,
select-button:not(:disabled):focus-visible {
background-color: rgba(204, 184, 119, 20%);
box-shadow: #C2A42D 0 0 0 2dp;
}
select-button:not(:disabled):selected {
opacity: 1;
background-color: rgba(204, 184, 119, 40%);
}
select-button:not(:disabled):active {
opacity: 1;
background-color: rgba(204, 184, 119, 40%);
box-shadow: #C2A42D 0 0 0 2dp;
}
select-button:disabled {
opacity: 0.35;
cursor: default;
}
select-button key {
font-family: "Fira Sans Condensed";
font-weight: bold;
font-size: 18dp;
text-transform: uppercase;
flex: 0 1 auto;
}
select-button value {
flex: 1 1 auto;
text-align: right;
font-size: 20dp;
}
select-button value.modified {
font-weight: bold;
}
select-button input {
text-align: right;
font-size: 20dp;
}
icon {
width: 1em;
height: 1em;
font-family: "Material Symbols Rounded";
font-weight: normal;
display: inline-block;
vertical-align: middle;
}
icon.warning {
decorator: text("&#xe002;" center center);
}
icon.error {
decorator: text("&#xe000;" center center);
}
icon.verifying {
decorator: text("&#xe8b5;" center center);
}
icon.celebration {
decorator: text("&#xea65;" center center);
}
icon.question-mark {
decorator: text("&#xeb8b;" center center);
}
.achievement-row {
display: flex;
align-items: flex-start;
gap: 10dp;
padding: 12dp 0;
border-bottom: 1dp rgba(146, 135, 91, 30%);
}
.achievement-info {
display: block;
flex: 1 1 0;
min-width: 0;
}
.achievement-header {
display: flex;
align-items: center;
}
.achievement-name {
flex: 1;
font-weight: bold;
}
.achievement-name.unlocked {
color: #ffa826;
}
.achievement-badge {
font-size: 14dp;
opacity: 0.7;
}
.achievement-badge.unlocked {
color: #44cc55;
opacity: 1;
}
.achievement-badge.locked {
color: #cc4444;
opacity: 1;
}
.achievement-desc {
display: block;
color: rgba(224, 219, 200, 55%);
font-size: 16dp;
margin: 4dp 0 0 0;
}
.achievement-progress {
display: block;
font-size: 13dp;
color: rgba(224, 219, 200, 45%);
}
progress {
display: block;
width: 100%;
height: 6dp;
border-radius: 3dp;
background-color: rgba(255, 255, 255, 10%);
margin: 6dp 0 2dp 0;
}
progress.progress-done fill {
background-color: #44aa22;
border-radius: 3dp;
}
progress.progress-ongoing fill {
background-color: #2255bb;
border-radius: 3dp;
}
button.achievement-clear {
flex: 0 0 auto;
align-self: center;
font-size: 14dp;
padding: 2dp 8dp;
opacity: 0.45;
}
.preset-grid {
display: flex;
flex-direction: row;
gap: 20dp;
flex: 0 1 auto;
align-items: flex-start;
width: 100%;
}
.preset-col {
display: flex;
flex-flow: column;
gap: 12dp;
flex: 1 1 0;
}
.preset-desc {
display: block;
font-size: 16dp;
text-align: center;
}
.modal-dialog {
display: flex;
flex-direction: column;
align-items: flex-start;
padding: 24dp;
gap: 20dp;
flex: 0 1 auto;
width: 100%;
text-align: left;
}
window.modal.danger {
border: 2dp #852221;
}
.modal-header {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
width: 100%;
flex: 0 0 auto;
gap: 16dp;
}
.modal-header icon {
font-size: 24dp;
color: #92875B;
}
.modal-title {
display: block;
font-family: "Fira Sans Condensed";
font-weight: bold;
text-transform: uppercase;
font-size: 18dp;
color: #92875B;
flex: 1 1 auto;
}
window.modal.danger .modal-title,
window.modal.danger .modal-header icon {
color: #B3261E;
}
.modal-body {
display: block;
width: 100%;
flex: 0 1 auto;
min-width: 0;
font-size: 20dp;
color: #FFFFFF;
font-weight: normal;
}
.modal-body span.tip {
font-size: 14dp;
color: #92875B;
}
.verification-progress {
display: flex;
flex-direction: column;
gap: 10dp;
width: 100%;
}
.verification-file {
display: block;
font-size: 17dp;
color: #FFFFFF;
}
progress.verification-progress-bar {
height: 8dp;
margin: 2dp 0 0 0;
}
.verification-detail {
display: block;
font-size: 14dp;
color: rgba(224, 219, 200, 65%);
}
.modal-actions {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: stretch;
align-items: stretch;
gap: 12dp;
width: 100%;
flex: 0 0 auto;
padding-top: 4dp;
}
+24 -1
View File
@@ -1,5 +1,10 @@
#include "Z2AudioLib/Z2Audience.h"
#include "Z2AudioLib/Z2SoundInfo.h"
#if TARGET_PC
#include "dusk/audio/DuskDsp.hpp"
#include "dusk/settings.h"
#include <cmath>
#endif
#include "Z2AudioLib/Z2Calc.h"
#include "Z2AudioLib/Z2Param.h"
#include "JSystem/JAudio2/JAISound.h"
@@ -701,6 +706,11 @@ f32 Z2Audience::calcRelPosVolume(const Vec& param_0, f32 param_1, int camID) {
f32 Z2Audience::calcRelPosPan(const Vec& param_0, int camID) {
Vec local_54 = param_0;
local_54.y = 0.0f;
#if TARGET_PC
if (dusk::getSettings().game.enableMirrorMode) {
local_54.x = -local_54.x;
}
#endif
f32 dVar6 = VECMag(&local_54);
if (dVar6 < 0.1f) {
@@ -734,9 +744,22 @@ f32 Z2Audience::calcRelPosPan(const Vec& param_0, int camID) {
f32 Z2Audience::calcRelPosDolby(const Vec& param_0, int camID) {
f32 fVar1 = param_0.z + mAudioCamera[camID].getDolbyCenterZ();
#if TARGET_PC
if (dusk::audio::EnableHrtf) {
// Normalize the direction so result is purely front/back orientation,
// independent of how far away the sound is
f32 lenSq = param_0.x * param_0.x + param_0.y * param_0.y + param_0.z * param_0.z;
if (lenSq < 0.0001f) {
return 0.5f;
}
f32 zNorm = param_0.z / sqrtf(lenSq);
f32 t = (zNorm + 1.0f) * 0.5f;
return 0.5f - 0.5f * cosf(t * static_cast<f32>(M_PI));
}
#endif
if (fVar1 > mSetting.field_0x48) {
return 1.0f;
}
}
if (fVar1 < mSetting.field_0x44) {
return 0.0f;
+4 -1
View File
@@ -4962,13 +4962,16 @@ int daAlink_c::create() {
setArcName(checkWolf());
setOriginalHeap(&mpArcHeap, 0xA2800);
JKRHEAP_NAME(mpArcHeap, "Alink ArcHeap");
if (dComIfG_resLoad(&mPhaseReq, mArcName, mpArcHeap) != cPhs_COMPLEATE_e) {
return cPhs_INIT_e;
}
setShieldArcName();
setOriginalHeap(&mpShieldArcHeap, 0x7000);
if (dComIfG_resLoad(&mShieldPhaseReq, mShieldArcName, mpShieldArcHeap) != cPhs_COMPLEATE_e) {
JKRHEAP_NAME(mpShieldArcHeap, "Alink ShieldArcHeap");
if (dComIfG_resLoad(&mShieldPhaseReq, mShieldArcName, mpShieldArcHeap) != cPhs_COMPLEATE_e)
{
return cPhs_INIT_e;
}
+13
View File
@@ -8,6 +8,10 @@
#include "d/actor/d_a_horse.h"
#include "d/actor/d_a_crod.h"
#include "d/d_msg_object.h"
#ifdef TARGET_PC
#include "d/actor/d_a_obj_carry.h"
#include "dusk/achievements.h"
#endif
#if DEBUG
#include "d/d_s_menu.h"
@@ -677,6 +681,15 @@ BOOL daAlink_c::checkDamageAction() {
}
setDamagePoint(dmg, at_mtrl == dCcD_MTRL_FIRE || at_mtrl == dCcD_MTRL_ICE, TRUE, 0);
#ifdef TARGET_PC
if (tghit_ac_name == fpcNm_Obj_Carry_e) {
auto* carry = static_cast<daObjCarry_c*>(tghit_ac);
if (carry->prm_chk_type_ironball() && carry->checkCannon()) {
dusk::AchievementSystem::get().signal("iron_ball_hit_player");
}
}
#endif
if (armor_no_dmg && at_mtrl != dCcD_MTRL_ELECTRIC && at_mtrl != dCcD_MTRL_ICE) {
setGuardSe(var_r29);
+16 -20
View File
@@ -44,16 +44,14 @@ void daAlink_c::handleWolfHowl() {
bool canHowl = false;
if (mLinkAcch.ChkGroundHit() && !checkModeFlg(MODE_PLAYER_FLY) && !checkMagneBootsOn()) {
if (!checkForestOldCentury()) {
if (checkMidnaRide()) {
if ((checkWolf() &&
(checkModeFlg(MODE_UNK_1000) || dComIfGp_checkPlayerStatus0(0, 0x10))) ||
(!checkWolf() &&
(checkEventRun() || getMidnaActor()->checkMetamorphoseEnable()) &&
(checkModeFlg(4) || dComIfGp_checkPlayerStatus0(0, 0x10))))
{
canHowl = true;
}
if (checkMidnaRide()) {
if ((checkWolf() &&
(checkModeFlg(MODE_UNK_1000) || dComIfGp_checkPlayerStatus0(0, 0x10))) ||
(!checkWolf() &&
(checkEventRun() || getMidnaActor()->checkMetamorphoseEnable()) &&
(checkModeFlg(4) || dComIfGp_checkPlayerStatus0(0, 0x10))))
{
canHowl = true;
}
}
}
@@ -124,16 +122,14 @@ void daAlink_c::handleQuickTransform() {
bool canTransform = false;
if (mLinkAcch.ChkGroundHit() && !checkModeFlg(MODE_PLAYER_FLY) && !checkMagneBootsOn()) {
if (!checkForestOldCentury()) {
if (checkMidnaRide()) {
if ((checkWolf() &&
(checkModeFlg(MODE_UNK_1000) || dComIfGp_checkPlayerStatus0(0, 0x10))) ||
(!checkWolf() &&
(checkEventRun() || getMidnaActor()->checkMetamorphoseEnable()) &&
(checkModeFlg(4) || dComIfGp_checkPlayerStatus0(0, 0x10))))
{
canTransform = true;
}
if (checkMidnaRide()) {
if ((checkWolf() &&
(checkModeFlg(MODE_UNK_1000) || dComIfGp_checkPlayerStatus0(0, 0x10))) ||
(!checkWolf() &&
(checkEventRun() || getMidnaActor()->checkMetamorphoseEnable()) &&
(checkModeFlg(4) || dComIfGp_checkPlayerStatus0(0, 0x10))))
{
canTransform = true;
}
}
}
+4
View File
@@ -18,6 +18,10 @@ enum {
};
void daAlink_c::hsChainShape_c::draw() {
if (dusk::getSettings().game.superClawshot) {
return;
}
static const int dummy = 0;
daAlink_c* alink = (daAlink_c*)getUserArea();
+2 -2
View File
@@ -2721,7 +2721,7 @@ int daAlink_c::procHorseRun() {
}
if (mProcVar2.field_0x300c == 0) {
set3DStatus(BUTTON_STATUS_HOLD_ON, 4);
set3DStatus(BUTTON_STATUS_HOLD_ON, IF_DUSK(dusk::getSettings().game.enableMirrorMode ? 1 :) 4);
}
} else {
if (mProcVar3.field_0x300e != 0) {
@@ -2731,7 +2731,7 @@ int daAlink_c::procHorseRun() {
}
if (mProcVar2.field_0x300c == 0) {
set3DStatus(BUTTON_STATUS_HOLD_ON, 1);
set3DStatus(BUTTON_STATUS_HOLD_ON, IF_DUSK(dusk::getSettings().game.enableMirrorMode ? 4 :) 1);
}
}
+1 -2
View File
@@ -41,12 +41,11 @@ void daAlink_c::setOriginalHeap(JKRExpHeap** i_ppheap, u32 i_size) {
u32 var_r28 = 0x10;
u32 size = ROUND(i_size, 16);
#if TARGET_PC
size *= 2;
size *= 20; // Increase Link's heap size to prevent mods from crashing with higher-quality models.
#endif
JKRHeap* parent = mDoExt_getGameHeap();
JKRExpHeap* heap = JKRExpHeap::create(size + (var_r29 + var_r28), parent, true);
JKRHEAP_NAME(heap, "Alink original");
*i_ppheap = heap;
}
}
+4
View File
@@ -254,7 +254,11 @@ BOOL daBdoor_c::checkArea() {
if (fabsf(vec.z) > 100.0f) {
return false;
}
#ifdef TARGET_PC
return (s16)((s32)fabs(current.angle.y - 0x7fff - player->current.angle.y) & 0xffff) <= 0x4000 ? 1 : 0;
#else
return (s16)fabs((f64)(current.angle.y - 0x7fff - player->current.angle.y)) <= 0x4000 ? 1 : 0;
#endif
}
BOOL daBdoor_c::checkFront() {
+4
View File
@@ -825,7 +825,11 @@ int daBdoorL1_c::checkArea() {
if (fabsf(local_48.z) > 100.0f) {
return 0;
}
#ifdef TARGET_PC
if ((s16)((s32)fabs(current.angle.y - 0x7fff - player->current.angle.y) & 0xffff) <= 0x4000) {
#else
if ((s16)fabs((f64)(current.angle.y - 0x7fff - player->current.angle.y)) <= 0x4000) {
#endif
return 1;
} else {
return 0;
+4
View File
@@ -348,7 +348,11 @@ int daBdoorL5_c::checkArea() {
if (fabsf(local_48.z) > 100.0f) {
return 0;
}
#ifdef TARGET_PC
if ((s16)((s32)fabs(current.angle.y - 0x7fff - player->current.angle.y) & 0xffff) <= 0x4000) {
#else
if ((s16)fabs((f64)(current.angle.y - 0x7fff - player->current.angle.y)) <= 0x4000) {
#endif
return 1;
} else {
return 0;
+5 -1
View File
@@ -1317,8 +1317,12 @@ int daMBdoorL1_c::checkArea() {
if (fabsf(local_48.z) > 110.0f) {
return 0;
}
#ifdef TARGET_PC
if ((s16)((s32)fabs(angle - 0x7fff - player->current.angle.y) & 0xffff) > 0x4000) {
#else
if ((s16)fabs((f64)(angle - 0x7fff - player->current.angle.y)) > 0x4000) {
#endif
return 0;
} else {
return 1;
+11
View File
@@ -17,6 +17,11 @@
#include <cstdio>
#include <cstring>
#if TARGET_PC
#include <f_ap/f_ap_game.h>
#include <dusk/autosave.h>
#endif
char* daDoor20_c::getStopBmdName() {
switch (door_param2_c::getKind(this)) {
case 3:
@@ -196,6 +201,7 @@ void daDoor20_c::setEventPrm() {
} else {
roomNo = FRoomNo;
}
if (dComIfGp_roomControl_checkStatusFlag(roomNo, 1)) {
if (door_param2_c::getKind(this) == 9) {
if (daPy_py_c::checkNowWolf()) {
@@ -564,6 +570,11 @@ int daDoor20_c::openEnd(int param_1) {
openEnd_1();
break;
}
#if TARGET_PC
triggerAutoSave();
#endif
return 1;
}
+6
View File
@@ -517,6 +517,12 @@ void daE_OctBg_c::core_fish_attack() {
field_0xbaf = cM_rndFX(80.0f) + 100.0f;
}
}
#if AVOID_UB
else {
in_f31 = cM_rndF(400.0f) + 80.0f;
field_0xbaf = cM_rndFX(80.0f) + 100.0f;
}
#endif
} else if (current.pos.abs(cStack_5c) < 400.0f) {
in_f31 = cM_rndF(50.0f) + 20.0f;
field_0xbaf = cM_rndFX(20.0f) + 40.0f;
+5
View File
@@ -282,6 +282,11 @@ static void e_th_spin_B(e_th_class* i_this) {
i_this->current.pos += spC;
f32 speed_target;
#if AVOID_UB
speed_target = 0;
#endif
f32 anm_frame = i_this->mpModelMorf->getFrame();
switch (i_this->mMode) {
+8
View File
@@ -3519,7 +3519,15 @@ void daKago_c::action() {
checkSizeBg();
setFlyEffect();
#if TARGET_PC
if (dusk::getSettings().game.enableMirrorMode) {
mStickX = -mDoCPd_c::getStickX3D(PAD_1);
} else {
mStickX = mDoCPd_c::getStickX3D(PAD_1);
}
#else
mStickX = mDoCPd_c::getStickX3D(PAD_1);
#endif
mStickY = mDoCPd_c::getStickY(PAD_1);
u8 prevIsWaterfall = mIsWaterfall;
+17
View File
@@ -463,6 +463,23 @@ int daMidna_c::createHeap() {
JKRReadIdxResource(mBckHeap[0].getBuffer(), mBckHeap[0].getBufferSize(), 0x1DC, dComIfGp_getAnmArchive());
J3DAnmTransform* md_anm = (J3DAnmTransform*)J3DAnmLoaderDataBase::load(mBckHeap[0].getBuffer());
modelData = (J3DModelData*)dComIfG_getObjectRes(l_arcName, 14);
#if TARGET_PC
J3DTexture* tex = modelData->getTexture();
JUTNameTab* nametable = modelData->getTextureName();
if (tex != NULL && nametable != NULL) {
for (u16 i = 0; i < tex->getNum(); i++) {
const char* name = nametable->getName(i);
if (name != NULL && strcmp(name, "midona_eye") == 0) {
ResTIMG* timg = tex->getResTIMG(i);
timg->mipmapEnabled = false;
tex->loadGXTexObj(i);
break;
}
}
}
#endif
JUT_ASSERT(852, modelData != NULL);
mpMorf = JKR_NEW mDoExt_McaMorfSO(modelData, &mMorfCB, NULL, md_anm, J3DFrameCtrl::EMode_LOOP, 1.0f, 0, -1, NULL, 0, 0x11000284);
if (mpMorf == NULL || mpMorf->getModel() == NULL) {
+17 -7
View File
@@ -40,6 +40,7 @@ dMirror_packet_c::dMirror_packet_c() {
void dMirror_packet_c::reset() {
#if TARGET_PC
mbReset = true;
mbHadEntry = false;
#else
mModelCount = 0;
#endif
@@ -84,11 +85,21 @@ void dMirror_packet_c::calcMinMax() {
}
int dMirror_packet_c::entryModel(J3DModel* i_model) {
#if TARGET_PC
if (mbReset) {
mModelCount = 0;
mbReset = false;
}
#endif
if (mModelCount >= 0x40) {
return 0;
}
mModels[mModelCount++] = i_model;
#if TARGET_PC
mbHadEntry = true;
#endif
return 1;
}
@@ -592,13 +603,6 @@ int daMirror_c::execute() {
return 1;
}
#if TARGET_PC
if (mPacket.mbReset) {
mPacket.mModelCount = 0;
mPacket.mbReset = false;
}
#endif
daPy_py_c* player = daPy_getLinkPlayerActorClass();
JUT_ASSERT(0, player != NULL);
@@ -624,6 +628,12 @@ int daMirror_c::draw() {
mDoExt_modelUpdateDL(mpModel);
}
#if TARGET_PC
if (mPacket.mbReset && !mPacket.mbHadEntry) {
mPacket.mModelCount = 0;
}
mPacket.mbHadEntry = true;
#endif
dComIfGd_getOpaListBG()->entryImm(&mPacket, 0);
return 1;
}
+2 -3
View File
@@ -956,7 +956,7 @@ static void npc_ne_tame(npc_ne_class* i_this) {
i_this->mpMorf->setPlaySpeed(i_this->mAnmSpeed);
/* dSv_event_flag_c::F_0470 - Fishing Pond - Reserved for fishing */
if (dComIfGs_isEventBit(dSv_event_flag_c::saveBitLabels[470])) {
if (IF_DUSK(dusk::getSettings().game.no2ndFishForCat) || dComIfGs_isEventBit(dSv_event_flag_c::saveBitLabels[470])) {
if (fpcEx_Search(s_fish_sub, _this) != NULL) {
i_this->mAction = npc_ne_class::ACT_HOME;
i_this->mMode = 10;
@@ -2948,8 +2948,7 @@ static int daNpc_Ne_Execute(npc_ne_class* i_this) {
if (i_this->mWantsFish && (i_this->mCounter & 0xf) == 0) {
/* dSv_event_flag_c::F_0470 - Fishing Pond - Reserved for fishing */
if (dComIfGs_isEventBit(dSv_event_flag_c::saveBitLabels[470])
&& i_this->mDistToTarget < 1500.0f) {
if ((IF_DUSK(dusk::getSettings().game.no2ndFishForCat) || dComIfGs_isEventBit(dSv_event_flag_c::saveBitLabels[470])) && i_this->mDistToTarget < 1500.0f) {
if (fopAcM_SearchByName(fpcNm_MG_ROD_e) != NULL) {
i_this->mNoFollow = false;
} else {
+2
View File
@@ -14,6 +14,7 @@
#include "d/actor/d_a_obj_automata.h"
#include "d/d_msg_object.h"
#include "d/actor/d_a_obj_scannon.h"
#include "dusk/frame_interpolation.h"
#include <cstring>
const daNpc_Toby_HIOParam daNpc_Toby_Param_c::m = {
@@ -1398,6 +1399,7 @@ int daNpc_Toby_c::cutRepairSCannon(int arg0) {
old.pos = current.pos;
setAngle(cM_deg2s(5.0f * f32(mPath.getArg0())));
mEventTimer = mPath.getArg2();
dusk::frame_interp::request_presentation_sync();
}
} else if (!mHide) {
mHide = 1;
+11 -7
View File
@@ -62,6 +62,16 @@ void daObj_Balloon_c::saveBestScore() {
dComIfGp_setMessageCountNumber(m_balloon_score);
}
#if TARGET_PC
static void minigameReset() {
// !@bug d_a_obj_balloon.rel unload used to zero these file-statics; with static linking they dangle across scenes.
m_combo_type = 0xFFFFFFFF;
m_combo_count = 0;
m_combo_next_score = 0;
m_balloon_score = 0;
}
#endif
static u8 hio_set;
static daObj_Balloon_HIO_c l_HIO;
@@ -205,13 +215,6 @@ int daObj_Balloon_c::_delete() {
Z2GetAudioMgr()->seStop(Z2SE_OBJ_WATERMILL_ROUND, 0);
if (mHIOInit) {
hio_set = false;
#ifdef TARGET_PC
// !@bug d_a_obj_balloon.rel unload used to zero these file-statics; with static linking they dangle across scenes.
m_combo_type = 0xFFFFFFFF;
m_combo_count = 0;
m_combo_next_score = 0;
m_balloon_score = 0;
#endif
}
return 1;
}
@@ -253,6 +256,7 @@ int daObj_Balloon_c::create() {
}
if (!hio_set) {
IF_DUSK(minigameReset());
mHIOInit = true;
hio_set = true;
l_HIO.field_0x04 = -1;
+51
View File
@@ -11,6 +11,8 @@
#include "d/d_bg_w.h"
#include "d/d_cc_uty.h"
#include "d/d_com_inf_game.h"
#include "dusk/frame_interpolation.h"
#include "dusk/settings.h"
struct daObjKLift00_HIO_c : public mDoHIO_entry_c {
daObjKLift00_HIO_c();
@@ -295,6 +297,11 @@ int daObjKLift00_c::Create() {
if(getLock())
mStopSwingingFrames = 5;
#if TARGET_PC
mChainInterpPrevValid = false;
mChainInterpCurrValid = false;
#endif
return 1;
}
@@ -436,6 +443,34 @@ int daObjKLift00_c::Execute(Mtx** i_mtx) {
return 1;
}
#if TARGET_PC
static void klift00_interp_callback(bool isSimFrame, void* pUserWork) {
static_cast<daObjKLift00_c*>(pUserWork)->onInterpCallback();
}
void daObjKLift00_c::onInterpCallback() {
if (!mChainInterpPrevValid || !mChainInterpCurrValid) {
return;
}
const f32 alpha = dusk::frame_interp::get_interpolation_step();
cXyz savedPositions[64];
for (int i = 0; i < mNumChains; i++) {
savedPositions[i] = mChainPositions[i].mCurrentPos;
const cXyz& p0 = mChainInterpPrev[i];
const cXyz& p1 = mChainInterpCurr[i];
mChainPositions[i].mCurrentPos = p0 + (p1 - p0) * alpha;
}
setMtx();
for (int i = 0; i < mNumChains; i++) {
mChainPositions[i].mCurrentPos = savedPositions[i];
}
}
#endif
int daObjKLift00_c::Draw() {
g_env_light.settingTevStruct(16, &current.pos, &tevStr);
g_env_light.setLightTevColorType_MAJI(mpLiftPlatform, &tevStr);
@@ -457,6 +492,22 @@ int daObjKLift00_c::Draw() {
dComIfGd_setList();
#if TARGET_PC
if (dusk::getSettings().game.enableFrameInterpolation) {
if (mChainInterpCurrValid) {
memcpy(mChainInterpPrev, mChainInterpCurr, mNumChains * sizeof(cXyz));
mChainInterpPrevValid = true;
}
for (int i = 0; i < mNumChains; i++) {
mChainInterpCurr[i] = mChainPositions[i].mCurrentPos;
}
mChainInterpCurrValid = true;
dusk::frame_interp::add_interpolation_callback(&klift00_interp_callback, this);
}
#endif
return 1;
}
+9
View File
@@ -12,6 +12,10 @@
#include "SSystem/SComponent/c_counter.h"
#include <cstring>
#if TARGET_PC
#include "dusk/settings.h"
#endif
#define DRAW_TYPE_YELLOW 0
#define DRAW_TYPE_RED 1
@@ -1422,6 +1426,11 @@ int dAttention_c::Run() {
}
void dAttention_c::Draw() {
#if TARGET_PC
if (dusk::getSettings().game.recordingMode) {
return;
}
#endif
if (mAttParam.CheckFlag(dAttParam_c::EFlag_ARROW_OFF)) {
draw[0].field_0x173 = 3;
draw[1].field_0x173 = 3;
+219 -40
View File
@@ -31,6 +31,7 @@
#if TARGET_PC
#include "dusk/frame_interpolation.h"
#include "dusk/logging.h"
#include "imgui.h"
#endif
namespace {
@@ -794,16 +795,15 @@ void dCamera_c::updatePad() {
if (mTriggerLeftLast > mCamSetup.ManualEndVal()) {
if (mLockLActive == 0) {
#if TARGET_PC
mCamParam.mManualMode = 0;
#endif
mLockLJustActivated = 1;
} else {
mLockLJustActivated = 0;
}
mLockLActive = 1;
#if TARGET_PC
mCamParam.mManualMode = 0;
#endif
} else {
mLockLJustActivated = 0;
mLockLActive = 0;
@@ -1041,6 +1041,11 @@ void dCamera_c::debugDrawInit() {
bool dCamera_c::Run() {
#if TARGET_PC
ResetView();
if (executeDebugFlyCam()) {
mFrameCounter++;
mTicks++;
return true;
}
#endif
daAlink_c* link = daAlink_getAlinkActorClass();
@@ -1176,14 +1181,14 @@ bool dCamera_c::Run() {
clrFlag(0x200000);
}
} else {
sp0F = (this->*engine_tbl[mCamParam.Algorythmn(mCamStyle)])(mCamStyle);
#if TARGET_PC
if (mCamParam.Algorythmn(mCamStyle) != 1) {
mCamParam.mManualMode = 0;
}
#endif
sp0F = (this->*engine_tbl[mCamParam.Algorythmn(mCamStyle)])(mCamStyle);
field_0x170++;
field_0x160++;
mCurCamStyleTimer++;
@@ -1488,7 +1493,7 @@ void dCamera_c::CalcTrimSize() {
mTrimHeight += -mTrimHeight * 0.25f;
break;
case 2:
#if WIDESCREEN_SUPPORT
#if !TARGET_PC && WIDESCREEN_SUPPORT
if (mDoGph_gInf_c::isWide() && mDoGph_gInf_c::isWideZoom()) {
mTrimHeight += (16.0f - mTrimHeight) * 0.25f;
break;
@@ -3096,10 +3101,6 @@ bool dCamera_c::bumpCheck(u32 i_flags) {
field_0x968 *= mMonitor.field_0xc / 5.0f;
}
#if TARGET_PC
if (!dusk::getSettings().game.freeCamera || !mCamParam.mManualMode) {
#endif
f32 tmp = field_0x96c * (mIsWolf == 1 ? 30.0f : 30.0f);
center += vec3.norm() * (tmp * globe.V().Sin());
cSGlobe globe2(vec2 - center);
@@ -3113,10 +3114,6 @@ bool dCamera_c::bumpCheck(u32 i_flags) {
vec = lin_chk1.GetCross();
}
#if TARGET_PC
}
#endif
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(20, 235, " U");
@@ -4208,6 +4205,11 @@ bool dCamera_c::chaseCamera(s32 param_0) {
chase->field_0x8 -= chase->field_0xc;
chase->field_0x8c = 0;
chase->field_0x90 = false;
#if TARGET_PC
freeCamera();
#endif
return true;
}
@@ -4631,10 +4633,6 @@ bool dCamera_c::chaseCamera(s32 param_0) {
sp110 = mViewCache.mDirection.R();
mViewCache.mDirection.R(mViewCache.mDirection.R() + (fVar55 - mViewCache.mDirection.R()) * chase->field_0x74);
#if TARGET_PC
freeCamera();
#endif
chase->field_0x64 = mViewCache.mCenter + mViewCache.mDirection.Xyz();
mViewCache.mEye = chase->field_0x64;
@@ -4649,6 +4647,11 @@ bool dCamera_c::chaseCamera(s32 param_0) {
if (chase->field_0x1c != 0) {
chase->field_0x1c--;
}
#if TARGET_PC
freeCamera();
#endif
return true;
}
@@ -7096,10 +7099,12 @@ bool dCamera_c::subjectCamera(s32 param_0) {
cXyz sp1E0(val0, val2, val1);
#if TARGET_PC
f32 aspect = mDoGph_gInf_c::getAspect();
f32 baseAspect = FB_WIDTH / FB_HEIGHT;
if (aspect > baseAspect) {
sp1E0.z += (aspect - baseAspect) * 4;
if (sp13) {
f32 aspect = mDoGph_gInf_c::getAspect();
f32 baseAspect = FB_WIDTH / FB_HEIGHT;
if (aspect > baseAspect) {
sp1E0.z += (aspect - baseAspect) * 4;
}
}
#endif
@@ -7475,37 +7480,198 @@ bool dCamera_c::test2Camera(s32 param_0) {
return false;
}
static constexpr f32 FLYCAM_SPEED = 0.5f;
static constexpr f32 FLYCAM_FAST_SPEED = 4.0f;
static constexpr f32 FLYCAM_ROTATION_SPEED = 0.002f;
static constexpr f32 FLYCAM_TRIGGER_DEADZONE = 20.0f;
static constexpr s16 FLYCAM_ROLL_SPEED = 256;
static ImVec2 sFlyCamLastMousePos = {-1.f, -1.f};
#if TARGET_PC
bool dCamera_c::executeDebugFlyCam() {
if (!dusk::getSettings().game.debugFlyCam) {
if (mDebugFlyCam.initialized) {
deactivateDebugFlyCam();
}
sFlyCamLastMousePos = {-1.f, -1.f};
return false;
}
dEvt_control_c* event = dComIfGp_getEvent();
if (event == nullptr) {
return false;
}
if (!mDebugFlyCam.initialized && (event->mEventStatus != 0 || dComIfGp_isPauseFlag())) {
dusk::getSettings().game.debugFlyCam.setValue(false);
return false;
}
if (!mDebugFlyCam.initialized) {
mDebugFlyCam.savedCenter = mCenter;
mDebugFlyCam.savedEye = mEye;
mDebugFlyCam.savedFovy = mFovy;
mDebugFlyCam.savedBank = mBank;
f32 dx = mCenter.x - mEye.x;
f32 dy = mCenter.y - mEye.y;
f32 dz = mCenter.z - mEye.z;
mDebugFlyCam.yaw = atan2f(dz, dx);
f32 horizontal = sqrtf(dx * dx + dz * dz);
mDebugFlyCam.pitch = atan2f(dy, horizontal);
mDebugFlyCam.initialized = true;
}
if (dusk::getSettings().game.debugFlyCamLockEvents) {
event->mEventStatus = 1;
dComIfGp_getEventManager().setCameraPlay(1);
} else {
if (event->mEventStatus != 0) {
event->mEventStatus = 0;
}
dComIfGp_getEventManager().setCameraPlay(0);
}
f32 stickY = 0.f;
f32 stickX = 0.f;
f32 cStickY = 0.f;
f32 cStickX = 0.f;
f32 trigL = 0.f;
f32 trigR = 0.f;
f32 rollInput = 0.f;
bool fast = false;
if (dusk::getSettings().game.debugFlyCamLockEvents) {
interface_of_controller_pad& pad = mDoCPd_c::getCpadInfo(0);
stickY = pad.mMainStickPosY * 72.0f;
stickX = pad.mMainStickPosX * 72.0f;
cStickY = pad.mCStickPosY * 59.0f;
cStickX = pad.mCStickPosX * 59.0f;
trigL = pad.mTriggerLeft * 150.0f;
trigR = pad.mTriggerRight * 150.0f;
fast = mDoCPd_c::getHoldZ(PAD_1);
if (mDoCPd_c::getHoldY(PAD_1)) rollInput -= 1.f;
if (mDoCPd_c::getHoldX(PAD_1)) rollInput += 1.f;
}
{
ImGuiIO& io = ImGui::GetIO();
if (!io.WantCaptureKeyboard) {
f32 kbX = 0.0f, kbY = 0.0f;
if (ImGui::IsKeyDown(ImGuiKey_W) || ImGui::IsKeyDown(ImGuiKey_UpArrow)) kbY += 1.f;
if (ImGui::IsKeyDown(ImGuiKey_S) || ImGui::IsKeyDown(ImGuiKey_DownArrow)) kbY -= 1.f;
if (ImGui::IsKeyDown(ImGuiKey_D) || ImGui::IsKeyDown(ImGuiKey_RightArrow)) kbX += 1.f;
if (ImGui::IsKeyDown(ImGuiKey_A) || ImGui::IsKeyDown(ImGuiKey_LeftArrow)) kbX -= 1.f;
f32 len = sqrtf(kbX * kbX + kbY * kbY);
if (len > 1.f) { kbX /= len; kbY /= len; }
stickX += kbX * 72.0f;
stickY += kbY * 72.0f;
if (ImGui::IsKeyDown(ImGuiKey_Space)) trigR += 150.0f;
if (ImGui::IsKeyDown(ImGuiKey_LeftCtrl)) trigL += 150.0f;
if (ImGui::IsKeyDown(ImGuiKey_LeftShift)) fast = true;
if (ImGui::IsKeyDown(ImGuiKey_Q)) rollInput -= 1.0f;
if (ImGui::IsKeyDown(ImGuiKey_E)) rollInput += 1.0f;
}
bool mouseValid = !io.WantCaptureMouse && io.MousePos.x >= 0.0f && io.MousePos.y >= 0.0f;
if (mouseValid && sFlyCamLastMousePos.x >= 0.0f) {
cStickX -= (io.MousePos.x - sFlyCamLastMousePos.x) * 2.0f;
cStickY -= (io.MousePos.y - sFlyCamLastMousePos.y) * 2.0f;
}
sFlyCamLastMousePos = mouseValid ? io.MousePos : ImVec2{-1.0f, -1.0f};
}
f32 verticalDisp = 0.0f;
if (trigR >= FLYCAM_TRIGGER_DEADZONE) {
verticalDisp += trigR;
}
if (trigL >= FLYCAM_TRIGGER_DEADZONE) {
verticalDisp -= trigL;
}
f32 moveDy = stickY * sinf(mDebugFlyCam.pitch) + verticalDisp;
f32 moveDx = stickY * cosf(mDebugFlyCam.yaw) * cosf(mDebugFlyCam.pitch) - stickX * sinf(mDebugFlyCam.yaw);
f32 moveDz = stickY * sinf(mDebugFlyCam.yaw) * cosf(mDebugFlyCam.pitch) + stickX * cosf(mDebugFlyCam.yaw);
f32 speed = fast ? FLYCAM_FAST_SPEED : FLYCAM_SPEED;
mEye.x += speed * moveDx;
mEye.y += speed * moveDy;
mEye.z += speed * moveDz;
static constexpr f32 FLYCAM_TARGET_DIST = 100.0f;
mCenter.x = mEye.x + cosf(mDebugFlyCam.yaw) * cosf(mDebugFlyCam.pitch) * FLYCAM_TARGET_DIST;
mCenter.z = mEye.z + sinf(mDebugFlyCam.yaw) * cosf(mDebugFlyCam.pitch) * FLYCAM_TARGET_DIST;
mCenter.y = mEye.y + sinf(mDebugFlyCam.pitch) * FLYCAM_TARGET_DIST;
mBank = mBank + static_cast<s16>(rollInput * FLYCAM_ROLL_SPEED * (fast ? FLYCAM_FAST_SPEED / FLYCAM_SPEED : 1.f));
Reset(mCenter, mEye);
f32 yawInput = dusk::getSettings().game.invertCameraXAxis ? cStickX : -cStickX;
mDebugFlyCam.yaw += yawInput * FLYCAM_ROTATION_SPEED;
mDebugFlyCam.yaw = fmodf(mDebugFlyCam.yaw + 2.0f * (f32)M_PI, 2.0f * (f32)M_PI);
f32 maxPitch = (f32)M_PI / 2.0f - 0.1f;
f32 minPitch = -(f32)M_PI / 2.0f + 0.1f;
mDebugFlyCam.pitch = std::clamp(mDebugFlyCam.pitch + cStickY * FLYCAM_ROTATION_SPEED, minPitch, maxPitch);
return true;
}
void dCamera_c::deactivateDebugFlyCam() {
Reset(mDebugFlyCam.savedCenter, mDebugFlyCam.savedEye, mDebugFlyCam.savedFovy, mDebugFlyCam.savedBank.Val());
dEvt_control_c* event = dComIfGp_getEvent();
if (event != nullptr && event->mEventStatus != 0) {
event->mEventStatus = 0;
}
dComIfGp_getEventManager().setCameraPlay(0);
mDebugFlyCam.initialized = false;
}
bool dCamera_c::freeCamera() {
if (!dusk::getSettings().game.freeCamera) {
if (dusk::getSettings().game.freeCamera && mGear == 1) {
mGear = 0;
}
if (!dusk::getSettings().game.freeCamera || mCamStyle == 70)
{
mCamParam.mManualMode = 0;
return false;
}
if (!mCamParam.mManualMode) {
mCamParam.freeXAngle = mViewCache.mDirection.mAzimuth.Degree();
mCamParam.freeYAngle = mViewCache.mDirection.mInclination.Degree();
}
cXyz camMovement = {mPadInfo.mCStick.mLastPosX, mPadInfo.mCStick.mLastPosY, 0.0f};
f32 magnitude = sqrt(mPadInfo.mCStick.mLastPosX * mPadInfo.mCStick.mLastPosX + mPadInfo.mCStick.mLastPosY * mPadInfo.mCStick.mLastPosY);
if (mPadInfo.mCStick.mLastPosX != 0 || mPadInfo.mCStick.mLastPosY != 0) {
if (!mCamParam.mManualMode) {
mCamParam.mManualMode = 1;
mCamParam.freeXAngle = mViewCache.mDirection.mAzimuth.Degree();
mCamParam.freeYAngle = mViewCache.mDirection.mInclination.Degree();
}
mCamParam.mManualMode = 1;
camMovement = camMovement.normalize();
camMovement.y *= dusk::getSettings().game.invertCameraYAxis ? 1.0f : -1.0f;
mCamParam.freeXAngle += camMovement.x * magnitude * dusk::getSettings().game.freeCameraSensitivity * 4.0f;
mCamParam.freeYAngle += camMovement.y * magnitude * dusk::getSettings().game.freeCameraSensitivity * 4.0f;
mCamParam.freeXAngle += camMovement.x * magnitude * dusk::getSettings().game.freeCameraSensitivity * 5.0f;
mCamParam.freeYAngle += camMovement.y * magnitude * dusk::getSettings().game.freeCameraSensitivity * 5.0f;
}
if (mCamParam.mManualMode) {
mCamParam.freeYAngle = std::clamp(mCamParam.freeYAngle, -35.0f, 60.0f);
mViewCache.mDirection.mAzimuth = cSAngle(mCamParam.freeXAngle);
mViewCache.mDirection.mInclination = cSAngle(mCamParam.freeYAngle);
mViewCache.mDirection.mRadius = std::clamp((mCamParam.freeYAngle + 35.0f) * 10.0f, 300.0f, 10000.0f);
fopAc_ac_c* player = dComIfGp_getPlayer(0);
if (!mCamParam.mManualMode || player == nullptr) {
return false;
}
return mCamParam.mManualMode;
f32 minYAngle = -30.0f;
f32 maxAngle = 50.0f;
mCamParam.freeYAngle = std::clamp(mCamParam.freeYAngle, minYAngle, maxAngle);
mViewCache.mDirection.mAzimuth = cSAngle(mCamParam.freeXAngle);
mViewCache.mDirection.mInclination = cSAngle(mCamParam.freeYAngle);
cXyz finalEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
mViewCache.mEye = finalEye;
return true;
}
#endif
@@ -11148,12 +11314,25 @@ static int camera_draw(camera_process_class* i_this) {
}
#endif
int trim_height = body->TrimHeight();
#if TARGET_PC
auto trim_height = body->TrimHeight();
if (mDoGph_gInf_c::isWideZoom()) {
const auto target_ar = FB_WIDTH / (FB_HEIGHT - trim_height * 2.0f);
const auto current_ar = mDoGph_gInf_c::m_safeWidthF / mDoGph_gInf_c::m_safeHeightF;
if (current_ar < target_ar) {
trim_height = FB_HEIGHT / 2.0f * (1.0f - current_ar / target_ar);
} else {
trim_height = 0.0f;
}
}
trim_height *= viewport->height / FB_HEIGHT;
window->setScissor(0.0f, trim_height, viewport->width, viewport->height - trim_height * 2.0f);
#else
int trim_height = body->TrimHeight();
window->setScissor(0.0f, trim_height, FB_WIDTH, FB_HEIGHT - trim_height * 2.0f);
#endif
+73
View File
@@ -11,6 +11,62 @@
#include "JSystem/JGadget/define.h"
#include <cstring>
#include "dusk/logging.h"
#if TARGET_PC
#include "dusk/ui/ui.hpp"
namespace {
static int sJaiSkip = -1;
static JSUList<JAIStream>* get_stream_list() {
return Z2GetSoundMgr()->getStreamMgr()->getStreamList();
}
static int get_stream_count(JSUList<JAIStream>* list) {
int i = 0;
for (JSULink<JAIStream>* l = list != nullptr ? list->getFirst() : nullptr; l != nullptr;
l = l->getNext()) {
i++;
}
return i;
}
static void pause_stream(int skip_first, bool paused) {
int i = 0;
JSUList<JAIStream>* list = get_stream_list();
for (JSULink<JAIStream>* l = list->getFirst(); l != nullptr; l = l->getNext(), ++i) {
if (i >= skip_first) {
l->getObject()->pause(paused);
}
}
}
static void pause_streams(int skip_first) {
if (!dusk::ui::is_prelaunch_open()) {
return;
}
JSUList<JAIStream>* list = get_stream_list();
if (list == nullptr || get_stream_count(list) <= skip_first) {
return;
}
pause_stream(skip_first, true);
sJaiSkip = skip_first;
}
static void unpause_streams(bool require_prelaunch_hidden) {
if (sJaiSkip < 0) {
return;
}
if (require_prelaunch_hidden && dusk::ui::is_prelaunch_open()) {
return;
}
pause_stream(sJaiSkip, false);
sJaiSkip = -1;
}
} // namespace
#endif
s16 dDemo_c::m_branchId = -1;
namespace {
@@ -1006,7 +1062,16 @@ int dDemo_c::start(u8 const* p_data, cXyz* p_translation, f32 rotationY) {
m_control->setSuspend(0);
}
#if TARGET_PC
const int existing_streams = get_stream_count(get_stream_list());
#endif
m_control->forward(0);
#if TARGET_PC
pause_streams(existing_streams);
#endif
m_translation = p_translation;
if (m_translation != NULL) {
@@ -1034,6 +1099,10 @@ static void dummyString2() {
void dDemo_c::end() {
JUT_ASSERT(1956, m_system != NULL);
#if TARGET_PC
unpause_streams(false);
#endif
m_control->destroyObject_all();
m_object->remove();
m_data = NULL;
@@ -1054,6 +1123,10 @@ void dDemo_c::branch() {
int dDemo_c::update() {
JUT_ASSERT(2064, m_system != NULL);
#if TARGET_PC
unpause_streams(true);
#endif
if (m_data == NULL) {
if (m_branchData == NULL) {
return 0;
+45 -9
View File
@@ -22,6 +22,10 @@
#include "dusk/frame_interpolation.h"
#include "dusk/gx_helper.h"
#include "dusk/logging.h"
static const void* getInterpKey(const void* base, int idx) {
return reinterpret_cast<const void*>(reinterpret_cast<uintptr_t>(base) ^ idx);
}
#endif
class dDlst_2Dm_c {
@@ -1062,7 +1066,15 @@ void dDlst_shadowReal_c::reset() {
}
void dDlst_shadowReal_c::imageDraw(Mtx param_0) {
GXSetProjection(mRenderProjMtx, GX_ORTHOGRAPHIC);
#ifdef TARGET_PC
Mtx render_proj_mtx;
if (dusk::frame_interp::lookup_replacement(getInterpKey(mpModels[0], 2), render_proj_mtx)) {
GXSetProjection(render_proj_mtx, GX_ORTHOGRAPHIC);
} else
#endif
{
GXSetProjection(mRenderProjMtx, GX_ORTHOGRAPHIC);
}
JUT_ASSERT(1916, mModelNum);
J3DModelData* model_data;
J3DModel** models = mpModels;
@@ -1075,7 +1087,15 @@ void dDlst_shadowReal_c::imageDraw(Mtx param_0) {
for (u16 j = 0; j < model_data->getShapeNum(); j++) {
if (!model_data->getShapeNodePointer(j)->checkFlag(1)) {
shape_pkt = (*models)->getShapePacket(j);
shape_pkt->setBaseMtxPtr(&mViewMtx);
#ifdef TARGET_PC
Mtx view_mtx;
if (dusk::frame_interp::lookup_replacement(getInterpKey(mpModels[0], 1), view_mtx)) {
shape_pkt->setBaseMtxPtr(&view_mtx);
} else
#endif
{
shape_pkt->setBaseMtxPtr(&mViewMtx);
}
shape_pkt->drawFast();
shape_pkt->setBaseMtxPtr((Mtx*)param_0);
}
@@ -1096,7 +1116,18 @@ void dDlst_shadowReal_c::draw() {
GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
GXSetCurrentMtx(GX_PNMTX0);
GXLoadTexMtxImm(mReceiverProjMtx, GX_TEXMTX0, GX_MTX3x4);
#ifdef TARGET_PC
Mtx view_mtx, recv_proj_mtx;
const auto have_view_mtx = dusk::frame_interp::lookup_replacement(getInterpKey(mpModels[0], 1), view_mtx);
const auto have_recv_proj_mtx = dusk::frame_interp::lookup_replacement(getInterpKey(mpModels[0], 3), recv_proj_mtx);
if (have_view_mtx && have_recv_proj_mtx) {
cMtx_concat(recv_proj_mtx, view_mtx, recv_proj_mtx);
GXLoadTexMtxImm(recv_proj_mtx, GX_TEXMTX0, GX_MTX3x4);
} else
#endif
{
GXLoadTexMtxImm(mReceiverProjMtx, GX_TEXMTX0, GX_MTX3x4);
}
mShadowRealPoly.draw();
}
@@ -1253,6 +1284,13 @@ u8 dDlst_shadowReal_c::setShadowRealMtx(cXyz* param_0, cXyz* param_1, f32 param_
cMtx_lookAt(mViewMtx, &local_64, param_1, 0);
C_MTXOrtho(mRenderProjMtx, param_2, -param_2, -param_2, param_2, 1.0f, 10000.0f);
C_MTXLightOrtho(mReceiverProjMtx, param_2, -param_2, -param_2, param_2, 0.5f, -0.5f, 0.5f, 0.5f);
#ifdef TARGET_PC
const auto keybase = mpModels[0];
dusk::frame_interp::record_final_mtx(mViewMtx, getInterpKey(keybase, 1));
dusk::frame_interp::record_final_mtx(mRenderProjMtx, getInterpKey(keybase, 2));
dusk::frame_interp::record_final_mtx(mReceiverProjMtx, getInterpKey(keybase, 3));
#endif
cMtx_concat(mReceiverProjMtx, mViewMtx, mReceiverProjMtx);
return r29;
}
@@ -1277,6 +1315,10 @@ u32 dDlst_shadowReal_c::set(u32 i_key, J3DModel* i_model, cXyz* param_2, f32 par
}
}
#ifdef TARGET_PC
// provide a stable key for interpolation
mpModels[0] = i_model;
#endif
field_0x1 = setShadowRealMtx(&sp60, param_2, param_3, param_4, param_7, param_5);
if (!field_0x1) {
@@ -1370,12 +1412,6 @@ void dDlst_shadowSimple_c::draw() {
GXCallDisplayList(l_shadowVolumeDL, 0x40);
}
#if TARGET_PC
static const void* getInterpKey(const void* base, int idx) {
return reinterpret_cast<const void*>(reinterpret_cast<uintptr_t>(base) ^ idx);
}
#endif
void dDlst_shadowSimple_c::set(cXyz* param_0, f32 param_1, f32 param_2, cXyz* param_3,
s16 param_4, f32 param_5, TGXTexObj* param_6) {
if (param_5 < 0.0f) {
+4 -4
View File
@@ -1595,7 +1595,7 @@ void dMap_c::_move(f32 i_centerX, f32 i_centerZ, int i_roomNo, f32 param_3) {
calcMapCmPerTexel(field_0x80, &field_0x58);
getPack(field_0x80, &mPackX, &mPackZ);
mCenterX += mPackX;
mCenterX += IF_DUSK(dusk::getSettings().game.enableMirrorMode ? -mPackX :) mPackX;
mCenterZ -= mPackZ;
mCenterX += field_0x64;
mCenterZ += mPackPlusZ;
@@ -1657,7 +1657,7 @@ void dMap_c::_move(f32 i_centerX, f32 i_centerZ, int i_roomNo, f32 param_3) {
calcMapCmPerTexel(field_0x80, &field_0x58);
getPack(field_0x80, &mPackX, &mPackZ);
mCenterX += mPackX;
mCenterX += IF_DUSK(dusk::getSettings().game.enableMirrorMode ? -mPackX :) mPackX;
mCenterZ -= mPackZ;
}
break;
@@ -1737,7 +1737,7 @@ void dMap_c::_move(f32 i_centerX, f32 i_centerZ, int i_roomNo, f32 param_3) {
calcMapCmPerTexel(field_0x80, &field_0x58);
getPack(field_0x80, &mPackX, &mPackZ);
mCenterX += mPackX;
mCenterX += IF_DUSK(dusk::getSettings().game.enableMirrorMode ? -mPackX :) mPackX;
mCenterZ -= mPackZ;
field_0x8f = 4;
#if DEBUG
@@ -1829,7 +1829,7 @@ void dMap_c::_move(f32 i_centerX, f32 i_centerZ, int i_roomNo, f32 param_3) {
sp14 += temp_f31_2 * (spC - sp14);
sp10 += temp_f31_2 * (sp8 - sp10);
mCenterX += sp14;
mCenterX += IF_DUSK(dusk::getSettings().game.enableMirrorMode ? -sp14 :) sp14;
mCenterZ -= sp10;
break;
}
+134 -1
View File
@@ -15,12 +15,47 @@
#include <cstring>
#ifdef TARGET_PC
#include <span>
#include <numbers>
#include <array>
constexpr u16 kMapResolutionMultiplier = 4;
constexpr u16 kMapImageSide = 16 * kMapResolutionMultiplier;
constexpr u32 kMapImageTotalPixels = kMapImageSide * kMapImageSide;
typedef std::function<u8(size_t, size_t)> PaintI8Fn;
void paint_i8(std::span<u8> dst, size_t width, PaintI8Fn paint) {
const auto blocksAcross = width >> 3;
for (size_t i = 0; i < dst.size(); i++) {
// 8x4 block swizzling for I8
const auto blockIdx = i >> 5;
const auto localIdx = i & 31;
const auto blockY = blockIdx / blocksAcross;
const auto blockX = blockIdx % blocksAcross;
const auto localY = localIdx >> 3;
const auto localX = localIdx & 7;
const auto x = (blockX << 3) + localX;
const auto y = (blockY << 2) + localY;
dst[i] = paint(x, y);
}
}
#endif
void dMpath_n::dTexObjAggregate_c::create() {
static int const data[7] = {
79, 80, 77, 78, 76, 81, 82,
79, // 0: im_map_icon_square_4i.bti
80, // 1: im_map_icon_tresurebox_4i.bti
77, // 2: im_map_icon_enter_4i.bti
78, // 3: im_map_icon_nijumaru_4i.bti
76, // 4: im_map_icon_circle_4i.bti
81, // 5: im_map_icon_try_force_4i.bti
82, // 6: map_icon_circle16x16_4i.bti
};
for (int lp1 = 0; lp1 < 7; lp1++) {
@@ -32,6 +67,104 @@ void dMpath_n::dTexObjAggregate_c::create() {
JUT_ASSERT(74, image->magFilter == GX_NEAR);
mDoLib_setResTimgObj(image, mp_texObj[lp1], 0, NULL);
}
#if TARGET_PC
static bool hqTexsDrawn = false;
static u8 hqCircleData[kMapImageTotalPixels];
static u8 hqCircleAltData[kMapImageTotalPixels];
static u8 hqNijumaruData[kMapImageTotalPixels];
static u8 hqEnterData[kMapImageTotalPixels];
static u8 hqTryForceData[kMapImageTotalPixels];
if (!hqTexsDrawn) {
constexpr auto center = kMapImageSide / 2.0f;
constexpr auto radiusSq = center * center;
// 6: map_icon_circle16x16_4i.bti - simple circle
paint_i8(std::span{hqCircleData}, kMapImageSide, [=](auto x, auto y) {
const auto dx = (x + 0.5f) - center;
const auto dy = (y + 0.5f) - center;
return (dx * dx + dy * dy < radiusSq) ? 0x11 : 0;
});
// 4: im_map_icon_circle_4i.bti - outlined circle
paint_i8(std::span{hqCircleAltData}, kMapImageSide, [=](auto x, auto y) {
constexpr auto innerRadius = kMapImageSide * 3.0f / 8.0f;
constexpr auto innerRadiusSq = innerRadius * innerRadius;
const auto dx = (x + 0.5f) - center;
const auto dy = (y + 0.5f) - center;
const auto dSq = dx * dx + dy * dy;
return dSq < radiusSq ? (dSq < innerRadiusSq ? 0x22 : 0x11) : 0;
});
// 3: im_map_icon_nijumaru_4i.bti - concentric rings
paint_i8(std::span{hqNijumaruData}, kMapImageSide, [=](auto x, auto y) {
constexpr u8 nijumaruRings[] = {0x11, 0x22, 0x11, 0x11, 0x22, 0x22};
const auto dx = (x + 0.5f) - center;
const auto dy = (y + 0.5f) - center;
const auto dSq = dx * dx + dy * dy;
if (dSq < radiusSq) {
const auto ringIndex =
static_cast<size_t>(std::trunc(std::sqrt(dSq) / kMapImageSide * 12));
return nijumaruRings[ringIndex];
}
return u8{0};
});
// 2: im_map_icon_enter_4i.bti - outlined octagram
paint_i8(std::span{hqEnterData}, kMapImageSide, [=](auto x, auto y) {
constexpr auto outlineWidth = kMapImageSide / 6.0f;
const auto adx = std::abs((x + 0.5f) - center);
const auto ady = std::abs((y + 0.5f) - center);
const auto dist =
std::min(adx + ady, std::max(adx, ady) * std::numbers::sqrt2_v<float>) -
kMapImageSide / 2.0f;
return dist > 0.0f ? 0 : (dist > -outlineWidth ? 0x22 : 0x33);
});
// 5: im_map_icon_try_force_4i.bti - outlined circle with triangle
paint_i8(std::span{hqTryForceData}, kMapImageSide, [=](auto x, auto y) {
constexpr auto innerRadiusNorm = 5.0f / 12.0f;
constexpr auto innerRadius = kMapImageSide * innerRadiusNorm;
constexpr auto innerRadiusSq = innerRadius * innerRadius;
constexpr auto triRadius = kMapImageSide * innerRadiusNorm / 2.0f;
const auto dx = (x + 0.5f) - center;
const auto dy = (y + 0.5f) - center;
const auto dSq = dx * dx + dy * dy;
const auto triSideDist = (std::numbers::sqrt3_v<float> * std::abs(dx) - dy) * 0.5f;
const auto insideTri = std::max(dy, triSideDist) < triRadius;
return insideTri ? 0x22 : (dSq < radiusSq ? (dSq < innerRadiusSq ? 0x33 : 0x22) : 0);
});
hqTexsDrawn = true;
}
constexpr auto replacements = std::to_array<std::pair<size_t, const u8*> >({
{2, hqEnterData},
{3, hqNijumaruData},
{4, hqCircleAltData},
{5, hqTryForceData},
{6, hqCircleData},
});
for (const auto& [idx, data] : replacements) {
JKR_DELETE(mp_texObj[idx]);
const auto texobj = JKR_NEW TGXTexObj();
GXInitTexObj(
texobj, data, kMapImageSide, kMapImageSide, GX_TF_I8, GX_CLAMP, GX_CLAMP, GX_FALSE);
GXInitTexObjLOD(texobj, GX_NEAR, GX_NEAR, 0.0f, 0.0f, 0.0f, GX_FALSE, GX_FALSE, GX_ANISO_1);
mp_texObj[idx] = texobj;
}
#endif
}
void dMpath_n::dTexObjAggregate_c::remove() {
+43 -1
View File
@@ -856,7 +856,46 @@ void dMenu_DmapBg_c::decGoldFrameAlphaRate() {
setGoldFrameAlphaRate(rate);
}
void dMenu_DmapBg_c::dMapBgWide() {
// Scale Base HUD
mBaseScreen->scale(mDoGph_gInf_c::hudAspectScaleUp, 1.0f);
mBaseScreen->translate(mDoGph_gInf_c::getSafeMinXF(), 0.0f);
// Boss Key, Compass & Map icons
mBaseScreen->search(MULTI_CHAR('key_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
mBaseScreen->search(MULTI_CHAR('con_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
mBaseScreen->search(MULTI_CHAR('map_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
// Text Header
mBaseScreen->search(MULTI_CHAR('t_t00'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
mBaseScreen->search(MULTI_CHAR('f_t_00'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
// C Button
mBaseScreen->search(MULTI_CHAR('c_btn2'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
// Scale Buttons HUD
mButtonScreen->scale(mDoGph_gInf_c::hudAspectScaleUp, 1.0f);
mButtonScreen->translate(mDoGph_gInf_c::getSafeMinXF(), 0.0f);
// Buttons
mButtonScreen->search(MULTI_CHAR('cont_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
// C Button
mButtonScreen->search(MULTI_CHAR('c_btn'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
mButtonScreen->search(MULTI_CHAR('c_text_s'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
mButtonScreen->search(MULTI_CHAR('c_text'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
mButtonScreen->search(MULTI_CHAR('f_text_s'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
mButtonScreen->search(MULTI_CHAR('f_text'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
// Decorations
mButtonScreen->search(MULTI_CHAR('kazari_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f);
}
void dMenu_DmapBg_c::draw() {
#if TARGET_PC
dMapBgWide();
#endif
u32 scissor_left;
u32 scissor_top;
u32 scissor_width;
@@ -903,7 +942,10 @@ void dMenu_DmapBg_c::draw() {
f32 local_28c = mpBackTexture->getBounds().i.x;
mpBackTexture->setBlackWhite(color_black, color_white);
mpBackTexture->draw(local_28c, field_0xd94 + mpBackTexture->getBounds().i.y, mpBackTexture->getWidth(),
mpBackTexture->getHeight(), false, false, false);
mpBackTexture->getHeight(),
IF_DUSK(dusk::getSettings().game.enableMirrorMode ? true :) false,
false,
false);
grafContext->scissor(field_0xd94 + mDoGph_gInf_c::getMinXF(),
scissor_top, mDoGph_gInf_c::getWidthF(),
+2 -2
View File
@@ -368,7 +368,7 @@ void dMenu_StageMapCtrl_c::initGetTreasureList(u8 param_0, s8 param_1) {
}
inline static s16 rightModeCnvRot(s16 param_0) {
return param_0;
return IF_DUSK(dusk::getSettings().game.enableMirrorMode ? -param_0 :) param_0;
}
bool dMenu_StageMapCtrl_c::getTreasureList(f32* o_posX, f32* o_posY, s8* param_2, u8* o_swbit,
@@ -405,7 +405,7 @@ bool dMenu_StageMapCtrl_c::getTreasureList(f32* o_posX, f32* o_posY, s8* param_2
}
inline static f32 rightModeCnvPos(f32 param_0) {
return param_0;
return IF_DUSK(dusk::getSettings().game.enableMirrorMode ? -param_0 :) param_0;
}
void dMenu_StageMapCtrl_c::cnvPosTo2Dpos(f32 param_0, f32 param_1, f32* param_2,
+18
View File
@@ -919,9 +919,20 @@ void dMenu_Fmap_c::region_map_proc() {
}
mpDraw2DBack->regionMapMove(mpStick);
int stage_no, room_no;
#if TARGET_PC
f32 arrow_pos_x = mpDraw2DBack->getArrowPos2DX();
if (dusk::getSettings().game.enableMirrorMode) {
arrow_pos_x = mpDraw2DBack->getMirrorPosX(arrow_pos_x, 0.0f);
}
f32 pos_x = arrow_pos_x - mDoGph_gInf_c::getMinXF() - mDoGph_gInf_c::getWidthF() * 0.5f;
#else
f32 pos_x = mpDraw2DBack->getArrowPos2DX() - mDoGph_gInf_c::getMinXF()
- mDoGph_gInf_c::getWidthF() * 0.5f;
#endif
f32 pos_y = mpDraw2DBack->getArrowPos2DY() - mDoGph_gInf_c::getHeightF() * 0.5f;
mpMenuFmapMap->getPointStagePathInnerNo(getNowFmapRegionData(), pos_x, pos_y,
mStayStageNo, &stage_no, &room_no);
if (mStageCursor != stage_no || mRoomCursor != room_no || mResetAreaName) {
@@ -2464,6 +2475,13 @@ void dMenu_Fmap_c::portalWarpMapMove(STControl* i_stick) {
f32 arrow_y = mpDraw2DBack->getArrowPos2DY();
u8 uVar6 = 0xff;
#if TARGET_PC
if (dusk::getSettings().game.enableMirrorMode) {
arrow_x = mpDraw2DBack->getMirrorPosX(arrow_x, 0.0f);
}
#endif
for (int i = 0; i < portal_dat->mCount; i++) {
if (portals[i].mRegionNo == mpDraw2DBack->getRegionCursor() + 1
&& checkDrawPortalIcon(portals[i].mStageNo, portals[i].mSwitchNo))
+58 -1
View File
@@ -20,6 +20,15 @@
#include "dusk/frame_interpolation.h"
#include <cstring>
#if TARGET_PC
void dMenu_Fmap2DBack_c::fMapBackWide() {
mpBaseScreen->scale(mDoGph_gInf_c::hudAspectScaleUp, 1.0f);
mpBaseScreen->translate(mDoGph_gInf_c::getSafeMinXF(), 0.0f);
mpBackScreen->scale(mDoGph_gInf_c::hudAspectScaleUp, 1.0f);
mpBackScreen->translate(mDoGph_gInf_c::getSafeMinXF(), 0.0f);
}
#endif
dMenu_Fmap2DBack_c::dMenu_Fmap2DBack_c() {
dMeter2Info_setMapDrugFlag(0);
@@ -267,6 +276,10 @@ dMenu_Fmap2DBack_c::~dMenu_Fmap2DBack_c() {
}
void dMenu_Fmap2DBack_c::draw() {
#if TARGET_PC
fMapBackWide();
#endif
calcBlink();
J2DGrafContext* grafPort = dComIfGp_getCurrentGrafPort();
@@ -1030,6 +1043,12 @@ void dMenu_Fmap2DBack_c::allmap_move2(STControl* param_0) {
calcAllMapPos2D((mArrowPos3DX + control_xpos) - mStageTransX,
(mArrowPos3DZ + control_ypos) - mStageTransZ, &sp14, &sp10);
#if TARGET_PC
if (dusk::getSettings().game.enableMirrorMode) {
sp14 = getMirrorPosX(sp14, 0.0f);
}
#endif
mSelectRegion = 0xff;
for (int i = 7; i >= 0; i--) {
int val = field_0x1230[i];
@@ -1199,7 +1218,7 @@ f32 dMenu_Fmap2DBack_c::getMapScissorAreaSizeX() {
}
f32 dMenu_Fmap2DBack_c::getMapScissorAreaSizeRealX() {
#if PLATFORM_GCN && !TARGET_PC
#if PLATFORM_GCN
return getMapScissorAreaSizeX();
#else
return getMapScissorAreaSizeX() * mDoGph_gInf_c::getScale();
@@ -1384,6 +1403,15 @@ void dMenu_Fmap2DBack_c::regionTextureDraw() {
if (uVar10 != uVar9) {
bool b = 0;
f32 v = mTransX + (dVar14 + (mRegionMinMapX[uVar10] + field_0xf0c[uVar10]));
#if TARGET_PC
if (dusk::getSettings().game.enableMirrorMode) {
b = true;
v = getMirrorPosX(mTransX + (dVar14 + (mRegionMinMapX[uVar10] + field_0xf0c[uVar10])),
mRegionMapSizeX[uVar10] * mZoom * 0.5f);
}
#endif
mpAreaTex[uVar10]->draw(
v, mTransZ + (dVar13 + (mRegionMinMapY[uVar10] + field_0xf2c[uVar10])),
mRegionMapSizeX[uVar10] * mZoom, mRegionMapSizeY[uVar10] * mZoom, b, false,
@@ -1391,6 +1419,15 @@ void dMenu_Fmap2DBack_c::regionTextureDraw() {
} else {
bool b = 0;
f32 v = mTransX + (dVar14 + (mRegionMinMapX[uVar9] + field_0xf0c[uVar9]));
#if TARGET_PC
if (dusk::getSettings().game.enableMirrorMode) {
b = true;
v = getMirrorPosX(mTransX + (dVar14 + (mRegionMinMapX[uVar9] + field_0xf0c[uVar9])),
mRegionMapSizeX[uVar9] * mZoom * 0.5f);
}
#endif
mpAreaTex[uVar9]->draw(
v, mTransZ + (dVar13 + (mRegionMinMapY[uVar9] + field_0xf2c[uVar9])),
mRegionMapSizeX[uVar9] * mZoom, mRegionMapSizeY[uVar9] * mZoom, b, false,
@@ -1407,6 +1444,11 @@ void dMenu_Fmap2DBack_c::stageTextureDraw() {
mpSpotTexture->setAlpha(mAlphaRate * 255.0f * field_0xfa8 * mSpotTextureFadeAlpha);
}
#if TARGET_PC
JUTPalette* pPalette = mpSpotTexture->getTexture(0)->getPalette();
pPalette->dataUploaded();
#endif
mpSpotTexture->draw(mTransX + getMapScissorAreaLX(), mTransZ + getMapScissorAreaLY(),
getMapScissorAreaSizeRealX(), getMapScissorAreaSizeRealY(), false, false,
false);
@@ -2179,6 +2221,17 @@ void dMenu_Fmap2DBack_c::setArrowPosAxis(f32 i_posX, f32 i_posZ) {
control_ypos = 0.0f;
}
#if TARGET_PC
void dMenu_Fmap2DTop_c::fMapTopWide() {
mpTitleScreen->search(MULTI_CHAR('spot0_n'))->scale(mDoGph_gInf_c::hudAspectScaleUp, 1.0f);
mpTitleScreen->search(MULTI_CHAR('spot2_n'))->scale(mDoGph_gInf_c::hudAspectScaleUp, 1.0f);
mpTitleScreen->search(MULTI_CHAR('name_n'))->translate(mDoGph_gInf_c::ScaleHUDXLeft(-243.0f), -169.0f);
mpTitleScreen->search(MULTI_CHAR('sub_n_n'))->translate(mDoGph_gInf_c::ScaleHUDXLeft(-80.0f), -154.0f);
mpTitleScreen->search(MULTI_CHAR('btn_i_n'))->translate(mDoGph_gInf_c::ScaleHUDXLeft(-241.0f), 177.0f);
mpTitleScreen->search(MULTI_CHAR('cont_n'))->translate(mDoGph_gInf_c::ScaleHUDXRight(515.0f), 83.0f);
}
#endif
dMenu_Fmap2DTop_c::dMenu_Fmap2DTop_c(JKRExpHeap* i_heap, STControl* i_stick) {
mpHeap = i_heap;
mTransX = 0.0f;
@@ -2572,6 +2625,10 @@ void dMenu_Fmap2DTop_c::setAllAlphaRate(f32 i_rate, bool i_init) {
}
void dMenu_Fmap2DTop_c::draw() {
#if TARGET_PC
fMapTopWide();
#endif
u32 scissor_left, scissor_top, scissor_width, scissor_height;
J2DOrthoGraph* ctx = static_cast<J2DOrthoGraph*>(dComIfGp_getCurrentGrafPort());
ctx->setup2D();
+8
View File
@@ -17,6 +17,10 @@
#include "d/d_msg_scrn_arrow.h"
#include "d/d_lib.h"
#ifdef TARGET_PC
#include "dusk/achievements.h"
#endif
#if VERSION == VERSION_GCN_JPN
#define D_MENU_LETTER_LINE_MAX 9
#else
@@ -514,6 +518,10 @@ void dMenu_Letter_c::read_open_init() {
setAButtonString(0);
setBButtonString(0);
mpBlackTex->setAlpha(0);
#ifdef TARGET_PC
dusk::AchievementSystem::get().signal("open_letter");
#endif
}
void dMenu_Letter_c::read_open_move() {
+17
View File
@@ -343,6 +343,11 @@ void dMenuMapCommon_c::drawIcon(f32 i_posX, f32 i_posY, f32 param_3, f32 param_4
}
f32 pos_x = icon_pos_x + i_posX;
#if TARGET_PC
if (dusk::getSettings().game.enableMirrorMode) {
pos_x = getMirrorCenterPosX(pos_x, 0.0f);
}
#endif
mpDrawCursor->setPos(pos_x, icon_pos_y + i_posY);
mpDrawCursor->setScale(mIconInfo[info_idx].scale * g_fmapHIO.mMapIconHIO.mPortalCursorScale);
mpDrawCursor->draw();
@@ -364,6 +369,12 @@ void dMenuMapCommon_c::drawIcon(f32 i_posX, f32 i_posY, f32 param_3, f32 param_4
}
f32 pos_x = (icon_pos_x + i_posX);
#if TARGET_PC
if (dusk::getSettings().game.enableMirrorMode) {
pos_x = getMirrorCenterPosX(pos_x, 0.0f);
}
#endif
mpPortalIcon->setPos(pos_x, icon_pos_y + i_posY);
mpPortalIcon->setScale(mIconInfo[info_idx].scale * g_fmapHIO.mMapIconHIO.mPortalIconScale);
mpPortalIcon->draw();
@@ -399,6 +410,12 @@ void dMenuMapCommon_c::drawIcon(f32 i_posX, f32 i_posY, f32 param_3, f32 param_4
}
f32 pos_x = i_posX + (icon_pos_x - (icon_size_x / 2));
#if TARGET_PC
if (dusk::getSettings().game.enableMirrorMode) {
pos_x = getMirrorCenterPosX(i_posX + (icon_pos_x - (icon_size_x / 2)), icon_size_x / 2);
}
#endif
mPictures[mIconInfo[info_idx].icon_no]->draw(pos_x, (i_posY + (icon_pos_y - icon_size_y / 2)),
icon_size_x, icon_size_y, false, false, false);
+11 -8
View File
@@ -24,9 +24,10 @@
#include "d/actor/d_a_horse.h"
#include <cstring>
#if TARGET_PC
#include "dusk/memory.h"
#include "dusk/memory.h"
#include "dusk/settings.h"
#endif
int dMeter2_c::_create() {
stage_stag_info_class* stag_info = dComIfGp_getStageStagInfo();
@@ -316,6 +317,14 @@ int dMeter2_c::_execute() {
}
int dMeter2_c::_draw() {
#if TARGET_PC
if (dusk::getSettings().game.recordingMode || dusk::getSettings().game.minimalHUD ||
dusk::getSettings().game.debugFlyCam)
{
return 1;
}
#endif
if (mpMap != NULL) {
mpMap->_draw();
}
@@ -424,12 +433,6 @@ void dMeter2_c::setLifeZero() {
void dMeter2_c::checkStatus() {
mStatus = 0;
#if TARGET_PC
if (dusk::getSettings().game.disableMainHUD) {
mStatus |= 0xF0000000;
}
#endif
field_0x12c = field_0x128;
field_0x128 = daPy_py_c::checkNowWolf();
+4
View File
@@ -2306,6 +2306,10 @@ void dMeter_drawHIO_c::updateOnWide() {
// River Canoe Minigame
g_drawHIO.mMiniGame.mCounterPosX[1] = mDoGph_gInf_c::ScaleHUDXRight(g_drawHIO.mMiniGame.mCounterPosX[1]);
g_drawHIO.mMiniGame.mIconPosX[1] = mDoGph_gInf_c::ScaleHUDXRight(g_drawHIO.mMiniGame.mIconPosX[1]);
// Bulblin Count in Hidden Village
g_drawHIO.mMiniGame.mCounterPosX[2] = mDoGph_gInf_c::ScaleHUDXRight(g_drawHIO.mMiniGame.mCounterPosX[2]);
g_drawHIO.mMiniGame.mIconPosX[2] = mDoGph_gInf_c::ScaleHUDXRight(g_drawHIO.mMiniGame.mIconPosX[2]);
#endif
}
+1 -1
View File
@@ -2066,7 +2066,7 @@ bool jmessage_tSequenceProcessor::do_isReady() {
case 0:
case 5:
case 6:
if (mDoCPd_c::getTrigA(PAD_1) || field_0xb2 != 0) {
if (mDoCPd_c::getTrigA(PAD_1) || field_0xb2 != 0 IF_DUSK(|| (dusk::getSettings().game.instantText && mDoCPd_c::getHoldB(0)))) {
field_0xa4 = 0;
pReference->onBatchFlag();
pReference->setCharCnt(D_MSG_CLASS_CHAR_CNT_MAX);
+47 -1
View File
@@ -32,6 +32,9 @@
#if TARGET_PC
#include "dusk/settings.h"
#include <vector>
#include <array>
#include <algorithm>
#endif
static void dMsgObject_addFundRaising(s16 param_0);
@@ -424,6 +427,16 @@ static void dummyStrings() {
dMsgObject_HIO_c g_MsgObject_HIO_c;
int dMsgObject_c::_execute() {
#if TARGET_PC
if (dusk::getSettings().game.enableMirrorMode) {
// enable wii message index override
g_MsgObject_HIO_c.mMessageDisplay = 1;
} else if (!dusk::getSettings().game.enableMirrorMode && g_MsgObject_HIO_c.mMessageDisplay == 1) {
g_MsgObject_HIO_c.mMessageDisplay = 0;
}
#endif
field_0x4c7 = 0;
if (mpTalkHeap != NULL) {
field_0x148 = mDoExt_setCurrentHeap(mpTalkHeap);
@@ -1594,7 +1607,7 @@ u8 dMsgObject_c::isSend() {
return 2;
}
} else {
if (IF_DUSK((dusk::getSettings().game.instantText && mDoCPd_c::getHoldB(0)) ||)
if (IF_DUSK((dusk::getSettings().game.instantText && mDoCPd_c::getHoldB(0) && !isShopItemMessage()) ||)
mDoCPd_c::getTrigA(0) != 0 || mDoCPd_c::getTrigB(0) != 0) {
return 2;
}
@@ -1866,6 +1879,39 @@ bool dMsgObject_c::isTalkMessage() {
return true;
}
#if TARGET_PC
bool dMsgObject_c::isShopItemMessage() {
// Probably a better way to do this than just listing every message id, but this works for now
// Note: Keep contents sorted so we can use binary search
const auto shopMsgIds = std::to_array<std::vector<s16>>({
{},
// zel_01.bmg - Seras Shop
{7001, 7003, 7004, 7005, 7006, 7007, 7008, 7009, 7010, 7013, 7014, 7022, 7023, 7028, 7029,
7044, 7045, 7053},
// zel_02.bmg - Kakariko Shops
{5181, 5182, 5251, 5253, 5254, 5256, 5258, 5259, 5653, 5654, 5656, 5660, 5661, 5664, 5665,
5697, 5698, 5699, 5803, 5804, 5806, 5810, 5811, 5812, 5814, 5821, 5823, 5824, 5987, 5988,
5989, 5990, 5991, 5992, 5993, 5994, 5995, 5996, 5997, 5998, 5999},
// zel_03.bmg - Death Mountain Shop
{5303, 5304, 5306, 5310, 5311, 5314, 5315, 5322, 5323, 5324, 5496, 5497, 5498, 5499},
// zel_04.bmg - Castle Town Shops
{5407, 5408, 5409, 5410, 5411, 5412, 5413, 5414, 5415, 5416, 5417, 5418, 5419, 5420, 5431,
5432, 5434, 5435, 5436, 5437, 5438, 5439, 5440, 5441, 5444, 5449, 5450, 5451, 5452, 5462},
// zel_05.bmg - Oocca Shop
{9428, 9429, 9430, 9431, 9432, 9437, 9443, 9448, 9449, 9451, 9459}
});
u16 id = mMessageID;
s16 group = dMsgObject_getGroupID();
if (group < shopMsgIds.size()) {
return std::ranges::binary_search(shopMsgIds[group], id);
}
return false;
}
#endif
const char* dMsgObject_c::getSmellName() {
JMSMesgInfo_c* info_header_p = (JMSMesgInfo_c*)((char*)mpMsgRes + 0x20);
char* data_ptr = (char*)info_header_p + info_header_p->header.size;
+9
View File
@@ -6,6 +6,10 @@
#include "d/d_com_inf_game.h"
#include "d/d_pane_class.h"
#if TARGET_PC
#include "dusk/settings.h"
#endif
dMsgScrnArrow_c::dMsgScrnArrow_c() {
mpScreen = JKR_NEW J2DScreen();
JUT_ASSERT(0, mpScreen != NULL);
@@ -65,6 +69,11 @@ dMsgScrnArrow_c::~dMsgScrnArrow_c() {
}
void dMsgScrnArrow_c::draw() {
#if TARGET_PC
if (dusk::getSettings().game.recordingMode) {
return;
}
#endif
J2DGrafContext* graf_ctx = dComIfGp_getCurrentGrafPort();
mpScreen->draw(0.0f, 0.0f, graf_ctx);
}
+24
View File
@@ -8,6 +8,10 @@
#include "d/d_pane_class.h"
#include <cstring>
#if TARGET_PC
#include "dusk/settings.h"
#endif
dMsgScrnBase_c::dMsgScrnBase_c() {
init();
}
@@ -57,12 +61,22 @@ void dMsgScrnBase_c::init() {
}
void dMsgScrnBase_c::multiDraw() {
#if TARGET_PC
if (dusk::getSettings().game.recordingMode) {
return;
}
#endif
if (field_0x48 != NULL) {
dComIfGd_set2DOpa(field_0x48);
}
}
void dMsgScrnBase_c::draw() {
#if TARGET_PC
if (dusk::getSettings().game.recordingMode) {
return;
}
#endif
J2DGrafContext* ctx = dComIfGp_getCurrentGrafPort();
ctx->setup2D();
@@ -72,10 +86,20 @@ void dMsgScrnBase_c::draw() {
}
void dMsgScrnBase_c::drawSelf() {
#if TARGET_PC
if (dusk::getSettings().game.recordingMode) {
return;
}
#endif
drawOutFont(0.0f, 0.0f, 1.0f);
}
void dMsgScrnBase_c::drawOutFont(f32 param_0, f32 param_1, f32 param_2) {
#if TARGET_PC
if (dusk::getSettings().game.recordingMode) {
return;
}
#endif
mpOutFont->draw(NULL, param_0, param_1, param_2);
}
+9
View File
@@ -6,6 +6,10 @@
#include "d/d_msg_object.h"
#include "d/d_pane_class.h"
#if TARGET_PC
#include "dusk/settings.h"
#endif
dMsgScrnBoss_c::dMsgScrnBoss_c() {
static u64 t_tag[7] = {
MULTI_CHAR('sfontb0'), MULTI_CHAR('sfontb1'), MULTI_CHAR('sfontb2'), MULTI_CHAR('sfontl0'), MULTI_CHAR('sfontl1'), MULTI_CHAR('sfontl2'), MULTI_CHAR('sfont00'),
@@ -91,6 +95,11 @@ void dMsgScrnBoss_c::exec() {
}
void dMsgScrnBoss_c::drawSelf() {
#if TARGET_PC
if (dusk::getSettings().game.recordingMode) {
return;
}
#endif
J2DGrafContext* ctx = dComIfGp_getCurrentGrafPort();
ctx->setup2D();
drawOutFont(0.0f, 0.0f, 1.0f);
+9
View File
@@ -13,6 +13,10 @@
#include "d/d_msg_out_font.h"
#include "d/d_pane_class.h"
#if TARGET_PC
#include "dusk/settings.h"
#endif
dMsgScrnKanban_c::dMsgScrnKanban_c(JKRExpHeap* param_0) {
if (param_0 != NULL) {
field_0xd4 = param_0;
@@ -176,6 +180,11 @@ void dMsgScrnKanban_c::exec() {
}
void dMsgScrnKanban_c::draw() {
#if TARGET_PC
if (dusk::getSettings().game.recordingMode) {
return;
}
#endif
J2DGrafContext* grafContext = dComIfGp_getCurrentGrafPort();
grafContext->setup2D();
mpScreen->draw(0.0f, 0.0f, grafContext);

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