diff --git a/decompiler/config/jak2/all-types.gc b/decompiler/config/jak2/all-types.gc index 6db10747e3..dd72daa169 100644 --- a/decompiler/config/jak2/all-types.gc +++ b/decompiler/config/jak2/all-types.gc @@ -2880,7 +2880,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)) + (mirror-mode sound-rpc-set-mirror-mode :offset 0) ) :method-count-assert 9 :size-assert #x50 diff --git a/decompiler/config/jak3/all-types.gc b/decompiler/config/jak3/all-types.gc index ced83190fc..3d6e31bcc6 100644 --- a/decompiler/config/jak3/all-types.gc +++ b/decompiler/config/jak3/all-types.gc @@ -2616,6 +2616,8 @@ (iop-mem) (cancel-dgo) (set-stereo-mode) + ;; og:preserve-this mirror mode + (set-mirror 201) ) ;; +++gsound-h:sound-group @@ -2953,6 +2955,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) ;; guessed by decompiler (load-bank sound-rpc-load-bank :offset-assert 0 :overlay-at data) @@ -2976,6 +2989,7 @@ (shutdown sound-rpc-shutdown :offset-assert 0 :overlay-at data) (list-sounds sound-rpc-list-sounds :offset-assert 0 :overlay-at data) (unload-music sound-rpc-unload-music :offset-assert 0 :overlay-at data) + (mirror-mode sound-rpc-set-mirror-mode :offset-assert 0 :overlay-at data) ) :method-count-assert 9 :size-assert #x50 diff --git a/game/overlord/jak3/rpc_interface.h b/game/overlord/jak3/rpc_interface.h index e13a31c409..d565c4a5ba 100644 --- a/game/overlord/jak3/rpc_interface.h +++ b/game/overlord/jak3/rpc_interface.h @@ -171,6 +171,8 @@ enum class SoundCommand : u16 { // LINVEL_NOM = 37, CANCEL_DGO = 49, SET_STEREO_MODE = 50, + // custom below + MIRROR_MODE = 201, }; struct SoundPlayParams { @@ -274,6 +276,11 @@ struct Rpc_Loader_Set_Stereo_Mode : public Rpc_Player_Base_Cmd { }; static_assert(sizeof(Rpc_Loader_Set_Stereo_Mode) == 8); +struct Rpc_Loader_Set_Mirror_Mode : public Rpc_Player_Base_Cmd { + u8 mode; +}; +static_assert(sizeof(Rpc_Loader_Set_Mirror_Mode) == 6); + constexpr int kPlayerCommandStride = 0x50; constexpr int kLoaderCommandStride = 0x50; diff --git a/game/overlord/jak3/srpc.cpp b/game/overlord/jak3/srpc.cpp index 9a9253acf0..43fa9993f3 100644 --- a/game/overlord/jak3/srpc.cpp +++ b/game/overlord/jak3/srpc.cpp @@ -584,6 +584,15 @@ void* RPC_Loader(unsigned int, void* msg, int size) { PrintSounds(); } break; + case SoundCommand::MIRROR_MODE: { + auto* cmd = (Rpc_Loader_Set_Mirror_Mode*)m_ptr; + if (cmd->mode == 0) { + g_CameraInvert = false; + } else { + g_CameraInvert = true; + } + } break; + default: ovrld_log(LogCategory::WARN, "[RPC Loader] Unsupported Loader {}", (int)((const Rpc_Player_Base_Cmd*)m_ptr)->command); diff --git a/goal_src/jak3/engine/game/game-info.gc b/goal_src/jak3/engine/game/game-info.gc index 284d9a7f3e..4563f51cd3 100644 --- a/goal_src/jak3/engine/game/game-info.gc +++ b/goal_src/jak3/engine/game/game-info.gc @@ -1890,10 +1890,27 @@ (if (and (not (paused?)) (zero? (-> this number)) (-> *setting-control* user-current player-control-override)) (override-player-controls this) ) - (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)))) - ) + ;; 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 ) diff --git a/goal_src/jak3/engine/game/settings.gc b/goal_src/jak3/engine/game/settings.gc index 85ba2e6631..cb3e8f9719 100644 --- a/goal_src/jak3/engine/game/settings.gc +++ b/goal_src/jak3/engine/game/settings.gc @@ -1792,9 +1792,11 @@ (set! (-> s5-0 screeny) (-> s4-0 screeny)) (set! (-> *video-params* display-dy) (* (/ (-> s4-0 screeny) 2) 2)) ) + ;; og:preserve-this If this flag worked end-to-end (i believe it doesn't), mirror mode would come a bit easier + ;; atleast in jak2 (havn't checked fully yet for jak3, assuming its the same) (set-horizontal-flip-flag *blit-displays-work* - (logtest? (-> *game-info* secrets) (game-secrets hflip-screen)) + (or (logtest? (-> *game-info* secrets) (game-secrets hflip-screen)) *PC-MIRROR-MODE-SET*) ) (set! (-> s5-0 letterbox-speed) (-> s4-0 letterbox-speed)) (seek! diff --git a/goal_src/jak3/engine/gfx/blit-displays.gc b/goal_src/jak3/engine/gfx/blit-displays.gc index 94322046cd..a9b16b90f1 100644 --- a/goal_src/jak3/engine/gfx/blit-displays.gc +++ b/goal_src/jak3/engine/gfx/blit-displays.gc @@ -711,15 +711,17 @@ (when (and (-> *setting-control* user-current render) (>= (the-as uint 1) (-> this count-down))) ;; handle horizontal flip by copying to fx buf, then copying back. ;; this is done before any HUD/text rendering. - (when (and (get-horizontal-flip-flag this) (not (get-menu-mode this))) - (with-dma-buffer-add-bucket ((s4-2 (-> *display* frames (-> *display* on-screen) global-buf)) - (bucket-id debug-no-zbuf1) - ) - (fx-copy-buf s4-2) - (fx-to-raster-flipped this s4-2) - (reset-display-gs-state *display* s4-2) - ) - ) + ;; og:preserve-this Disabled right now to get mirror mode work (but technically be somewhat inaccurate) + ;; can be fixed later when mirror mode is properly supported via the flag end-to-end by the gfx pipeline + ;; (when (and (get-horizontal-flip-flag this) (not (get-menu-mode this))) + ;; (with-dma-buffer-add-bucket ((s4-2 (-> *display* frames (-> *display* on-screen) global-buf)) + ;; (bucket-id debug-no-zbuf1) + ;; ) + ;; (fx-copy-buf s4-2) + ;; (fx-to-raster-flipped this s4-2) + ;; (reset-display-gs-state *display* s4-2) + ;; ) + ;; ) ;; draw "depth-cue" or a simple attempt at anti-aliasing. This happens before particles, and diff --git a/goal_src/jak3/engine/gfx/math-camera.gc b/goal_src/jak3/engine/gfx/math-camera.gc index 0a4d928c8f..0e6468d3da 100644 --- a/goal_src/jak3/engine/gfx/math-camera.gc +++ b/goal_src/jak3/engine/gfx/math-camera.gc @@ -209,9 +209,11 @@ Without this corrector, the fogginess of the world would change as the FOV chang ;; #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 rvec x)) diff --git a/goal_src/jak3/engine/sound/gsound-h.gc b/goal_src/jak3/engine/sound/gsound-h.gc index f346d2583f..878973b4a5 100644 --- a/goal_src/jak3/engine/sound/gsound-h.gc +++ b/goal_src/jak3/engine/sound/gsound-h.gc @@ -58,6 +58,8 @@ (iop-mem) (cancel-dgo) (set-stereo-mode) + ;; og:preserve-this mirror mode + (set-mirror 201) ) (defenum sound-bank-mode @@ -111,6 +113,12 @@ (unk2) ) +;; og:preserve-this mirror mode +(defenum sound-mirror-mode + :type uint8 + (normal) + (mirrored)) + (defenum stream-status :type uint32 :bitfield #t @@ -415,6 +423,9 @@ () ) +;; 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) @@ -439,6 +450,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/jak3/engine/sound/gsound.gc b/goal_src/jak3/engine/sound/gsound.gc index 3c7993835a..4a157c51e3 100644 --- a/goal_src/jak3/engine/sound/gsound.gc +++ b/goal_src/jak3/engine/sound/gsound.gc @@ -482,6 +482,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 vector) (arg4 vector) (arg5 float)) @@ -646,7 +659,7 @@ (sound-unit-vector-convert (-> gp-0 cam-forward) fwd) (sound-unit-vector-convert (-> gp-0 cam-left) left) (set! (-> gp-0 cam-scale) (the int (* 65536.0 scale))) - (set! (-> gp-0 cam-inverted) (if (logtest? (-> *game-info* secrets) (game-secrets hflip-screen)) + (set! (-> gp-0 cam-inverted) (if (or (logtest? (-> *game-info* secrets) (game-secrets hflip-screen)) *PC-MIRROR-MODE-SET*) 1 0 ) diff --git a/goal_src/jak3/levels/common/external-player-control.gc b/goal_src/jak3/levels/common/external-player-control.gc index 9c6d82be51..99095c728c 100644 --- a/goal_src/jak3/levels/common/external-player-control.gc +++ b/goal_src/jak3/levels/common/external-player-control.gc @@ -56,7 +56,9 @@ (set! (-> s5-0 x) (/ (-> s5-0 x) 2)) (set! (-> s5-0 z) (/ (-> s5-0 z) 2)) (set! (-> arg0 leftx) (the-as uint (the int (* 255.0 (-> s5-0 x))))) - (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! (-> arg0 leftx) (the-as uint (* (the-as uint -1) (-> arg0 leftx)))) ) (set! (-> arg0 lefty) (the-as uint (the int (* 255.0 (-> s5-0 z))))) diff --git a/goal_src/jak3/levels/desert/hover/scorpion-gun.gc b/goal_src/jak3/levels/desert/hover/scorpion-gun.gc index a4f58fd6da..f36a8622a7 100644 --- a/goal_src/jak3/levels/desert/hover/scorpion-gun.gc +++ b/goal_src/jak3/levels/desert/hover/scorpion-gun.gc @@ -592,14 +592,16 @@ 0 ) (('off-to-left) - (logior! (-> this offscreen) (if (logtest? (-> *game-info* secrets) (game-secrets hflip-screen)) + ;; og:preserve-this mirror mode + (logior! (-> this offscreen) (if (or (logtest? (-> *game-info* secrets) (game-secrets hflip-screen)) *PC-MIRROR-MODE-SET*) 2 1 ) ) ) (('off-to-right) - (logior! (-> this offscreen) (if (logtest? (-> *game-info* secrets) (game-secrets hflip-screen)) + ;; og:preserve-this mirror mode + (logior! (-> this offscreen) (if (or (logtest? (-> *game-info* secrets) (game-secrets hflip-screen)) *PC-MIRROR-MODE-SET*) 1 2 ) diff --git a/goal_src/jak3/levels/forest/for-turret.gc b/goal_src/jak3/levels/forest/for-turret.gc index 79b14ecb8c..873fe075f1 100644 --- a/goal_src/jak3/levels/forest/for-turret.gc +++ b/goal_src/jak3/levels/forest/for-turret.gc @@ -244,7 +244,9 @@ (f30-0 (vector-vector-angle-safe sv-140 (vector-! (new 'stack-no-clear 'vector) sv-128 sv-136))) ) (set! sv-240 (atan (-> s2-4 x) (-> s2-4 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! sv-240 (* -1.0 sv-240)) ) (let ((v1-105 (new 'stack-no-clear 'vector))) diff --git a/goal_src/jak3/levels/wascity/defend/was-pre-game.gc b/goal_src/jak3/levels/wascity/defend/was-pre-game.gc index 5b840d2216..87610f7cac 100644 --- a/goal_src/jak3/levels/wascity/defend/was-pre-game.gc +++ b/goal_src/jak3/levels/wascity/defend/was-pre-game.gc @@ -2278,7 +2278,8 @@ ) (set! s3-0 (logior s3-0 (ash 1 s1-0))) (let ((v1-50 (cond - ((logtest? (-> *game-info* secrets) (game-secrets hflip-screen)) + ;; og:preserve-this mirror mode + ((or (logtest? (-> *game-info* secrets) (game-secrets hflip-screen)) *PC-MIRROR-MODE-SET*) (case s1-0 ((1) 3 @@ -3013,7 +3014,8 @@ (v1-6 (new 'stack-no-clear 'vector)) ) (let ((a0-7 (cond - ((logtest? (-> *game-info* secrets) (game-secrets hflip-screen)) + ;; og:preserve-this mirror mode + ((or (logtest? (-> *game-info* secrets) (game-secrets hflip-screen)) *PC-MIRROR-MODE-SET*) (case (-> self index) ((1) 3 @@ -3075,7 +3077,8 @@ (v1-6 (new 'stack-no-clear 'vector)) ) (let ((a0-7 (cond - ((logtest? (-> *game-info* secrets) (game-secrets hflip-screen)) + ;; og:preserve-this mirror mode + ((or (logtest? (-> *game-info* secrets) (game-secrets hflip-screen)) *PC-MIRROR-MODE-SET*) (case (-> self index) ((1) 3 diff --git a/goal_src/jak3/levels/wascity/wasgun-hud.gc b/goal_src/jak3/levels/wascity/wasgun-hud.gc index 00d11168f3..2b2c54524c 100644 --- a/goal_src/jak3/levels/wascity/wasgun-hud.gc +++ b/goal_src/jak3/levels/wascity/wasgun-hud.gc @@ -15,9 +15,12 @@ ) (when (wascity-turret-get-reticle-fire-pos s4-0) (transform-point-vector! s5-0 s4-0) - (if (logtest? (-> *game-info* secrets) (game-secrets hflip-screen)) - (set! (-> s5-0 x) (- (-> s5-0 x))) - ) + ;; og:preserve-this mirror mode + ;; Since we don't properly flip the screen, don't mess with the hud (or the reticule moves in the opposite direction) + ;; (if (or (logtest? (-> *game-info* secrets) (game-secrets hflip-screen)) + ;; *PC-MIRROR-MODE-SET*) + ;; (set! (-> s5-0 x) (- (-> s5-0 x))) + ;; ) (+! (-> s5-0 x) -1792.0) (+! (-> s5-0 y) -1840.0) (set-hud-piece-position! (-> this sprites 0) (the int (-> s5-0 x)) (the int (-> s5-0 y))) @@ -62,7 +65,8 @@ (let ((s3-0 (the-as object (new 'stack-no-clear 'vector4w)))) (set! (-> (the-as vector4w s3-0) quad) (the-as uint128 0)) (when (transform-point-qword! (the-as vector4w s3-0) (-> this position s5-2)) - (when (logtest? (-> *game-info* secrets) (game-secrets hflip-screen)) + ;; og:preserve-this mirror mode + (when (or (logtest? (-> *game-info* secrets) (game-secrets hflip-screen)) *PC-MIRROR-MODE-SET*) (+! (-> (the-as (pointer uint32) s3-0) 0) -32768) (set! (-> (the-as (pointer uint32) s3-0) 0) (the-as uint (- (the-as int (-> (the-as (pointer uint32) s3-0) 0)))) @@ -130,7 +134,9 @@ ) (b! (< (-> this minfo s5-3 pos y) (+ -20480.0 (get-base-height *ocean-map*))) cfg-53) (transform-point-vector! s3-3 (-> this minfo s5-3 pos)) - (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! (-> s3-3 x) (- (-> s3-3 x))) ) (+! (-> s3-3 x) -2048.0) @@ -275,14 +281,16 @@ 0 ) (('off-to-left) - (logior! (-> this offscreen) (if (logtest? (-> *game-info* secrets) (game-secrets hflip-screen)) + ;; og:preserve-this mirror mode + (logior! (-> this offscreen) (if (or (logtest? (-> *game-info* secrets) (game-secrets hflip-screen)) *PC-MIRROR-MODE-SET*) 2 1 ) ) ) (('off-to-right) - (logior! (-> this offscreen) (if (logtest? (-> *game-info* secrets) (game-secrets hflip-screen)) + ;; og:preserve-this mirror mode + (logior! (-> this offscreen) (if (or (logtest? (-> *game-info* secrets) (game-secrets hflip-screen)) *PC-MIRROR-MODE-SET*) 1 2 ) diff --git a/goal_src/jak3/pc/pckernel.gc b/goal_src/jak3/pc/pckernel.gc index fed259194d..02627f5398 100644 --- a/goal_src/jak3/pc/pckernel.gc +++ b/goal_src/jak3/pc/pckernel.gc @@ -496,6 +496,9 @@ (defmethod update-cheats ((obj pc-settings-jak3)) "run cheats." + ;; sync mirror mode cheat + (set! *PC-MIRROR-MODE-SET* (logtest? (-> *game-info* secrets) (game-secrets hflip-screen))) + ;; run cheats here. ;;;;;;;;;;;;;;;;;;; @@ -537,6 +540,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/jak3/engine/sound/gsound-h_REF.gc b/test/decompiler/reference/jak3/engine/sound/gsound-h_REF.gc index 8392702d66..f3da96ddd8 100644 --- a/test/decompiler/reference/jak3/engine/sound/gsound-h_REF.gc +++ b/test/decompiler/reference/jak3/engine/sound/gsound-h_REF.gc @@ -718,6 +718,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)) ) )