From c72a086e495c5c2eb74e68583d0f16473650f779 Mon Sep 17 00:00:00 2001 From: Tyler Wilding Date: Tue, 30 Jul 2024 23:30:53 -0400 Subject: [PATCH] jak2: support mirror mode (#3616) Fixes #3210 ![image](https://github.com/user-attachments/assets/86bb6a67-bc6a-4169-aa82-d6a46ecd43d7) TIL that on the PS4/PS5, mirror mode breaks the upscaling --- decompiler/config/jak2/all-types.gc | 13 ++++++++++ .../config/jak3/ntsc_v1/type_casts.jsonc | 16 ++++--------- game/overlord/jak2/srpc.cpp | 3 +++ game/overlord/jak2/srpc.h | 1 + goal_src/jak1/engine/sound/gsound-h.gc | 2 ++ goal_src/jak1/pc/pckernel-h.gc | 2 ++ goal_src/jak1/pc/pckernel.gc | 3 ++- goal_src/jak2/engine/game/game-info.gc | 24 +++++++++++++++---- goal_src/jak2/engine/game/settings.gc | 1 + goal_src/jak2/engine/gfx/math-camera.gc | 8 ++++--- goal_src/jak2/engine/sound/gsound-h.gc | 13 ++++++++++ goal_src/jak2/engine/sound/gsound.gc | 13 ++++++++++ goal_src/jak2/engine/target/target-turret.gc | 4 +++- goal_src/jak2/pc/pckernel.gc | 8 +++++++ .../jak2/engine/sound/gsound-h_REF.gc | 1 + 15 files changed, 91 insertions(+), 21 deletions(-) diff --git a/decompiler/config/jak2/all-types.gc b/decompiler/config/jak2/all-types.gc index 44fc205c1..b6c1626c5 100644 --- a/decompiler/config/jak2/all-types.gc +++ b/decompiler/config/jak2/all-types.gc @@ -2515,6 +2515,7 @@ (iop-mem 48) (cancel-dgo 49) (set-stereo-mode 50) ;; sound-rpc-set-stereo-mode + (set-mirror 201) ) (defenum sound-group @@ -2829,6 +2830,17 @@ :flag-assert #x900000004 ) +; added +(defenum sound-mirror-mode + :type uint8 + (normal) + (mirrored) + ) + +; added for mirror mode +(deftype sound-rpc-set-mirror-mode (sound-rpc-cmd) + ((mirror sound-mirror-mode))) + (deftype sound-rpc-union (structure) ((data uint32 20 :offset-assert 0) (load-bank sound-rpc-load-bank :offset 0) @@ -2852,6 +2864,7 @@ (shutdown sound-rpc-shutdown :offset 0) (list-sounds sound-rpc-list-sounds :offset 0) (unload-music sound-rpc-unload-music :offset 0) + (mirror-mode sound-rpc-set-mirror-mode :overlay-at (-> data 0)) ) :method-count-assert 9 :size-assert #x50 diff --git a/decompiler/config/jak3/ntsc_v1/type_casts.jsonc b/decompiler/config/jak3/ntsc_v1/type_casts.jsonc index ab8d28d5d..61bf2d69a 100644 --- a/decompiler/config/jak3/ntsc_v1/type_casts.jsonc +++ b/decompiler/config/jak3/ntsc_v1/type_casts.jsonc @@ -2742,20 +2742,12 @@ [27, "gp", "process-drawable"], [30, "gp", "process-drawable"] ], - "(method 23 weapon-trail)": [ - [[0, 100], "gp", "weapon-trail-crumb"] - ], + "(method 23 weapon-trail)": [[[0, 100], "gp", "weapon-trail-crumb"]], "(method 22 weapon-trail)": [[32, "v0", "light-trail-breadcrumb"]], "(method 22 tread-trail)": [[19, "v0", "light-trail-breadcrumb"]], - "(method 23 tread-trail)": [ - [[0, 100], "s5", "tread-trail-crumb"] - ], - "(method 23 tire-trail)": [ - [[0, 74], "s5", "tire-trail-crumb"] - ], - "(method 22 tire-trail)": [ - [[18, 24], "v1", "tire-trail-crumb"] - ], + "(method 23 tread-trail)": [[[0, 100], "s5", "tread-trail-crumb"]], + "(method 23 tire-trail)": [[[0, 74], "s5", "tire-trail-crumb"]], + "(method 22 tire-trail)": [[[18, 24], "v1", "tire-trail-crumb"]], "(trans idle fma-sphere)": [[39, "a2", "process-drawable"]], "part-water-splash-callback": [[3, "v1", "float"]], "(method 15 water-control)": [[48, "v1", "float"]], diff --git a/game/overlord/jak2/srpc.cpp b/game/overlord/jak2/srpc.cpp index 077c06f60..5991b511a 100644 --- a/game/overlord/jak2/srpc.cpp +++ b/game/overlord/jak2/srpc.cpp @@ -460,6 +460,9 @@ void* RPC_Loader(unsigned int /*fno*/, void* data, int size) { snd_SetPlayBackMode(0); } } break; + case Jak2SoundCommand::mirror_mode: { + gMirrorMode = cmd->mirror.value; + } break; default: ASSERT_MSG(false, fmt::format("Unhandled RPC Loader command {}", int(cmd->j2command))); } diff --git a/game/overlord/jak2/srpc.h b/game/overlord/jak2/srpc.h index fa0338887..cd2338fe2 100644 --- a/game/overlord/jak2/srpc.h +++ b/game/overlord/jak2/srpc.h @@ -58,6 +58,7 @@ enum class Jak2SoundCommand : u16 { iop_mem = 48, cancel_dgo = 49, set_stereo_mode = 50, + mirror_mode = 201, }; struct SoundRpcCommand { diff --git a/goal_src/jak1/engine/sound/gsound-h.gc b/goal_src/jak1/engine/sound/gsound-h.gc index 8a75cda20..010027bc2 100644 --- a/goal_src/jak1/engine/sound/gsound-h.gc +++ b/goal_src/jak1/engine/sound/gsound-h.gc @@ -74,6 +74,7 @@ (list-sounds) (unload-music) (set-fps) + ;; og:preserve-this mirror mode (set-mirror 201)) ;; flavors for music @@ -279,6 +280,7 @@ (shutdown sound-rpc-shutdown :overlay-at (-> data 0)) (list-sounds sound-rpc-list-sounds :overlay-at (-> data 0)) (unload-music sound-rpc-unload-music :overlay-at (-> data 0)) + ;; og:preserve-this mirror mode (mirror-mode sound-rpc-set-mirror-mode :overlay-at (-> data 0)))) ;; GOAL-side sound specification. diff --git a/goal_src/jak1/pc/pckernel-h.gc b/goal_src/jak1/pc/pckernel-h.gc index 38c084538..3039062ac 100644 --- a/goal_src/jak1/pc/pckernel-h.gc +++ b/goal_src/jak1/pc/pckernel-h.gc @@ -75,6 +75,8 @@ ;; how many entries the spool anim log has. only 164 are used in-game. (defconstant PC_SPOOL_LOG_LENGTH 170) +(define *PC-MIRROR-MODE-SET* #f) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; types and enums ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/goal_src/jak1/pc/pckernel.gc b/goal_src/jak1/pc/pckernel.gc index c5a4d2054..57840b336 100644 --- a/goal_src/jak1/pc/pckernel.gc +++ b/goal_src/jak1/pc/pckernel.gc @@ -129,7 +129,8 @@ (when (zero? (-> date stat)) (set-time-of-day (+ (the float (bcd->dec (-> date hour))) (/ (the float (bcd->dec (-> date minute))) 60)))))) (pc-set-gfx-hack (pc-gfx-hack no-tex) (logtest? (-> obj cheats) (pc-cheats no-tex))) - (if (pc-cheats? (-> obj cheats) mirror) + (if (or (pc-cheats? (-> obj cheats) mirror) + *PC-MIRROR-MODE-SET*) (sound-set-mirror-mode (sound-mirror-mode mirrored)) (sound-set-mirror-mode (sound-mirror-mode normal))) ;; run cheats end!!! diff --git a/goal_src/jak2/engine/game/game-info.gc b/goal_src/jak2/engine/game/game-info.gc index ce7d32be7..eae06b5ab 100644 --- a/goal_src/jak2/engine/game/game-info.gc +++ b/goal_src/jak2/engine/game/game-info.gc @@ -1643,12 +1643,28 @@ ) (defmethod adjust-to-screen-flip ((this cpad-info)) - (when (logtest? (-> *game-info* secrets) (game-secrets hflip-screen)) + ;; og:preserve-this mirror mode flag + (when (or (logtest? (-> *game-info* secrets) (game-secrets hflip-screen)) + *PC-MIRROR-MODE-SET*) (set! (-> this leftx) (- 255 (the-as int (-> this leftx)))) (set! (-> this rightx) (- 255 (the-as int (-> this rightx)))) - ) - 0 - ) + ;; while in the progress menu, invert left/right as well + (when *progress-process* + ;; right = 5th bit and 1st index for pressure + ;; left = 7th bit and 2nd index for pressure + (let ((right-pressed? (logtest? (-> this button0) (pad-buttons right))) + (right-pressure (-> this abutton 0)) + (left-pressed? (logtest? (-> this button0) (pad-buttons left))) + (left-pressure (-> this abutton 1))) + (when right-pressed? + (logclear! (-> this button0) (pad-buttons right)) + (logior! (-> this button0) (pad-buttons left))) + (when left-pressed? + (logclear! (-> this button0) (pad-buttons left)) + (logior! (-> this button0) (pad-buttons right))) + (set! (-> this abutton 0) left-pressure) + (set! (-> this abutton 1) right-pressure)))) + 0) (defmethod game-info-method-28 ((this game-info) (arg0 game-score) (arg1 float)) (when (!= arg1 0.0) diff --git a/goal_src/jak2/engine/game/settings.gc b/goal_src/jak2/engine/game/settings.gc index 7db58045c..e7b57ed03 100644 --- a/goal_src/jak2/engine/game/settings.gc +++ b/goal_src/jak2/engine/game/settings.gc @@ -1215,6 +1215,7 @@ (set! (-> s5-0 display-dy) (-> s4-0 display-dy)) (set! (-> *video-params* display-dy) (* (/ (-> s4-0 display-dy) 2) 2)) ) + ;; og:preserve-this If this flag worked end-to-end (i believe it doesn't), mirror mode would come a bit easier (set! (-> *blit-displays-work* horizontal-flip-flag) (logtest? (-> *game-info* secrets) (game-secrets hflip-screen)) ) diff --git a/goal_src/jak2/engine/gfx/math-camera.gc b/goal_src/jak2/engine/gfx/math-camera.gc index 364bb3645..10131b6a2 100644 --- a/goal_src/jak2/engine/gfx/math-camera.gc +++ b/goal_src/jak2/engine/gfx/math-camera.gc @@ -220,9 +220,11 @@ renderers that want a single matrix. ;; #xffffffff, which overflows the 24-bit z buffer. ;; cheating this by 1 bit seems to fix it. (#when PC_PORT - ;; #x4b002032 -> #x4b002031 - (set! (-> arg0 isometric vector 3 z) (the-as float (- (the-as int (-> arg0 isometric vector 3 z)) 1))) - ) + ;; #x4b002032 -> #x4b002031 + (set! (-> arg0 isometric vector 3 z) (the-as float (- (the-as int (-> arg0 isometric vector 3 z)) 1))) + ;; also do mirror game check here. + (when *PC-MIRROR-MODE-SET* + (*! (-> arg0 perspective vector 0 x) -1.))) ) (set! (-> arg0 isometric trans w) f30-0) (let ((f1-28 (-> arg0 perspective vector 0 x)) diff --git a/goal_src/jak2/engine/sound/gsound-h.gc b/goal_src/jak2/engine/sound/gsound-h.gc index 9452e31b8..f7fdec925 100644 --- a/goal_src/jak2/engine/sound/gsound-h.gc +++ b/goal_src/jak2/engine/sound/gsound-h.gc @@ -61,6 +61,8 @@ (iop-mem 48) (cancel-dgo 49) (set-stereo-mode 50) ;; sound-rpc-set-stereo-mode + ;; og:preserve-this mirror mode + (set-mirror 201) ) (defenum sound-group @@ -96,6 +98,11 @@ (unk) ) +(defenum sound-mirror-mode + :type uint8 + (normal) + (mirrored)) + (defenum stream-status :type uint32 :bitfield #t @@ -402,6 +409,10 @@ () ) +;; og:preserve-this added for mirror mode +(deftype sound-rpc-set-mirror-mode (sound-rpc-cmd) + ((mirror sound-mirror-mode))) + (deftype sound-rpc-union (structure) ((data uint32 20) @@ -426,6 +437,8 @@ (shutdown sound-rpc-shutdown :overlay-at (-> data 0)) (list-sounds sound-rpc-list-sounds :overlay-at (-> data 0)) (unload-music sound-rpc-unload-music :overlay-at (-> data 0)) + ;; og:preserve-this mirror mode + (mirror-mode sound-rpc-set-mirror-mode :overlay-at (-> data 0)) ) ) diff --git a/goal_src/jak2/engine/sound/gsound.gc b/goal_src/jak2/engine/sound/gsound.gc index 86b393ba1..eddaf653b 100644 --- a/goal_src/jak2/engine/sound/gsound.gc +++ b/goal_src/jak2/engine/sound/gsound.gc @@ -283,6 +283,19 @@ 0 ) +;; og:preserve-this mirror mode +(define *sound-current-mirror* (sound-mirror-mode normal)) + +;; og:preserve-this mirror mode +(defun sound-set-mirror-mode ((mode sound-mirror-mode)) + (when (!= mode *sound-current-mirror*) + (let ((cmd (the sound-rpc-set-mirror-mode (add-element *sound-loader-rpc*)))) + (set! (-> cmd command) (sound-command set-mirror)) + (set! (-> cmd mirror) mode)) + (call *sound-loader-rpc* (the-as uint 0) (the-as pointer 0) (the-as uint 0)) + (set! *sound-current-mirror* mode)) + (none)) + (define *sound-player-enable* #t) (defun swap-sound-buffers ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 float)) diff --git a/goal_src/jak2/engine/target/target-turret.gc b/goal_src/jak2/engine/target/target-turret.gc index a045da93f..7dd3d86b8 100644 --- a/goal_src/jak2/engine/target/target-turret.gc +++ b/goal_src/jak2/engine/target/target-turret.gc @@ -1592,7 +1592,9 @@ (f30-1 (vector-vector-angle-safe s2-2 (vector-! (new 'stack-no-clear 'vector) s5-1 s3-1))) ) (let ((f0-10 (- (atan (-> s4-1 x) (-> s4-1 y))))) - (if (logtest? (-> *game-info* secrets) (game-secrets hflip-screen)) + ;; og:preserve-this mirror mode + (if (or (logtest? (-> *game-info* secrets) (game-secrets hflip-screen)) + *PC-MIRROR-MODE-SET*) (set! f0-10 (* -1.0 f0-10)) ) (set! (-> this arrow-angle) (deg-seek (-> this arrow-angle) f0-10 (* 65536.0 (seconds-per-frame)))) diff --git a/goal_src/jak2/pc/pckernel.gc b/goal_src/jak2/pc/pckernel.gc index 4465b16a3..4f84d95ac 100644 --- a/goal_src/jak2/pc/pckernel.gc +++ b/goal_src/jak2/pc/pckernel.gc @@ -594,6 +594,9 @@ (defmethod update-cheats ((obj pc-settings-jak2)) "run cheats." + ;; sync mirror mode cheat + (set! *PC-MIRROR-MODE-SET* (logtest? (-> *game-info* secrets) (game-secrets hflip-screen))) + ;; run cheats here. ;;;;;;;;;;;;;;;;;;; @@ -635,6 +638,11 @@ (pc-set-gfx-hack (pc-gfx-hack no-tex) (pc-cheats? (-> obj cheats) no-textures)) + (if (or (logtest? (-> *game-info* secrets) (game-secrets hflip-screen)) + *PC-MIRROR-MODE-SET*) + (sound-set-mirror-mode (sound-mirror-mode mirrored)) + (sound-set-mirror-mode (sound-mirror-mode normal))) + ;; run cheats end!!! ;;;;;;;;;;;;;;;;;;;; diff --git a/test/decompiler/reference/jak2/engine/sound/gsound-h_REF.gc b/test/decompiler/reference/jak2/engine/sound/gsound-h_REF.gc index 48d705dee..ce6e0a506 100644 --- a/test/decompiler/reference/jak2/engine/sound/gsound-h_REF.gc +++ b/test/decompiler/reference/jak2/engine/sound/gsound-h_REF.gc @@ -687,6 +687,7 @@ (shutdown sound-rpc-shutdown :overlay-at (-> data 0)) (list-sounds sound-rpc-list-sounds :overlay-at (-> data 0)) (unload-music sound-rpc-unload-music :overlay-at (-> data 0)) + (mirror-mode sound-rpc-set-mirror-mode :overlay-at (-> data 0)) ) )