From 20a6839e07404db29300ee56c6b5be3942d748da Mon Sep 17 00:00:00 2001 From: water111 <48171810+water111@users.noreply.github.com> Date: Mon, 2 Jan 2023 12:13:19 -0500 Subject: [PATCH] [jak2] fix hud and some particles (#2088) Fixes: - a very old bug in depth in DirectRenderer, probably from the original tfrag stuff. Looked at PCSX2 source code to see how 32/24 bit depths are handled. This fixes hud sprites being drawn behind level geometry. - saturate `vftoi4` like the ps2 does when the float is too large, fixing hidden text in `hud`. For now it's only using this in the font code because this saturation is actually kinda slow and hasn't been a problem in other places. - fix crazy particle spawning issue with blue gun and dripping stuff. This would happen if particles kill themselves while being processed (through a callback) --- .../opengl_renderer/DirectRenderer.cpp | 6 +++--- game/mips2c/jak2_functions/font.cpp | 16 ++++++++-------- game/mips2c/mips2c_private.h | 19 +++++++++++++++++++ .../engine/gfx/sprite/particles/sparticle.gc | 2 +- goal_src/jak2/engine/level/level.gc | 19 +++++++++++++++++++ 5 files changed, 50 insertions(+), 12 deletions(-) diff --git a/game/graphics/opengl_renderer/DirectRenderer.cpp b/game/graphics/opengl_renderer/DirectRenderer.cpp index d465be6b6..1fcdcc90b 100644 --- a/game/graphics/opengl_renderer/DirectRenderer.cpp +++ b/game/graphics/opengl_renderer/DirectRenderer.cpp @@ -797,7 +797,7 @@ void DirectRenderer::handle_xyzf2_packed(const u8* data, u8 f = (upper >> 36); bool adc = upper & (1ull << 47); - handle_xyzf2_common(x << 16, y << 16, z << 8, f, render_state, prof, !adc); + handle_xyzf2_common(x << 16, y << 16, z, f, render_state, prof, !adc); } void DirectRenderer::handle_xyz2_packed(const u8* data, @@ -1090,7 +1090,7 @@ void DirectRenderer::handle_xyzf2(u64 val, u32 z = (val >> 32) & 0xffffff; u32 f = (val >> 56) & 0xff; - handle_xyzf2_common(x << 16, y << 16, z << 8, f, render_state, prof, true); + handle_xyzf2_common(x << 16, y << 16, z, f, render_state, prof, true); } void DirectRenderer::TestState::from_register(GsTest reg) { @@ -1147,7 +1147,7 @@ void DirectRenderer::PrimitiveBuffer::push(const math::Vector& rgba, v.rgba = rgba; v.xyzf[0] = (float)vert[0] / (float)UINT32_MAX; v.xyzf[1] = (float)vert[1] / (float)UINT32_MAX; - v.xyzf[2] = (float)vert[2] / (float)UINT32_MAX; + v.xyzf[2] = (float)vert[2] / (float)0xffffff; v.xyzf[3] = (float)vert[3]; v.stq = st; v.tex_unit = unit; diff --git a/game/mips2c/jak2_functions/font.cpp b/game/mips2c/jak2_functions/font.cpp index 44c61d87e..e7d776036 100644 --- a/game/mips2c/jak2_functions/font.cpp +++ b/game/mips2c/jak2_functions/font.cpp @@ -1853,7 +1853,7 @@ u64 execute(void* ctxt) { // nop // sll r0, r0, 0 // nop // sll r0, r0, 0 // nop // sll r0, r0, 0 - c->vftoi4(DEST::xyzw, vf1, vf1); // vftoi4.xyzw vf1, vf1 + c->vftoi4_sat(DEST::xyzw, vf1, vf1); // vftoi4.xyzw vf1, vf1 // nop // sll r0, r0, 0 c->vmulq(DEST::xyz, vf2, vf2); // vmulq.xyz vf2, vf2, Q // nop // sll r0, r0, 0 @@ -1875,7 +1875,7 @@ u64 execute(void* ctxt) { // nop // sll r0, r0, 0 // nop // sll r0, r0, 0 // nop // sll r0, r0, 0 - c->vftoi4(DEST::xyzw, vf2, vf2); // vftoi4.xyzw vf2, vf2 + c->vftoi4_sat(DEST::xyzw, vf2, vf2); // vftoi4.xyzw vf2, vf2 // nop // sll r0, r0, 0 c->vmulq(DEST::xyz, vf3, vf3); // vmulq.xyz vf3, vf3, Q // nop // sll r0, r0, 0 @@ -1897,7 +1897,7 @@ u64 execute(void* ctxt) { // nop // sll r0, r0, 0 // nop // sll r0, r0, 0 // nop // sll r0, r0, 0 - c->vftoi4(DEST::xyzw, vf3, vf3); // vftoi4.xyzw vf3, vf3 + c->vftoi4_sat(DEST::xyzw, vf3, vf3); // vftoi4.xyzw vf3, vf3 // nop // sll r0, r0, 0 c->vmulq(DEST::xyz, vf4, vf4); // vmulq.xyz vf4, vf4, Q // nop // sll r0, r0, 0 @@ -1927,7 +1927,7 @@ u64 execute(void* ctxt) { c->vadd_bc(DEST::x, BC::w, vf23, vf23, vf14); // vaddw.x vf23, vf23, vf14 block_153: - c->vftoi4(DEST::xyzw, vf4, vf4); // vftoi4.xyzw vf4, vf4 + c->vftoi4_sat(DEST::xyzw, vf4, vf4); // vftoi4.xyzw vf4, vf4 // nop // sll r0, r0, 0 // nop // sll r0, r0, 0 // nop // sll r0, r0, 0 @@ -2667,7 +2667,7 @@ u64 execute(void* ctxt) { // nop // sll r0, r0, 0 c->lqc2(vf11, 640, v1); // lqc2 vf11, 640(v1) // nop // sll r0, r0, 0 - c->vftoi4(DEST::xyzw, vf1, vf1); // vftoi4.xyzw vf1, vf1 + c->vftoi4_sat(DEST::xyzw, vf1, vf1); // vftoi4.xyzw vf1, vf1 // nop // sll r0, r0, 0 c->vmulq(DEST::xyz, vf2, vf2); // vmulq.xyz vf2, vf2, Q // nop // sll r0, r0, 0 @@ -2689,7 +2689,7 @@ u64 execute(void* ctxt) { // nop // sll r0, r0, 0 // nop // sll r0, r0, 0 // nop // sll r0, r0, 0 - c->vftoi4(DEST::xyzw, vf2, vf2); // vftoi4.xyzw vf2, vf2 + c->vftoi4_sat(DEST::xyzw, vf2, vf2); // vftoi4.xyzw vf2, vf2 // nop // sll r0, r0, 0 c->vmulq(DEST::xyz, vf3, vf3); // vmulq.xyz vf3, vf3, Q // nop // sll r0, r0, 0 @@ -2711,7 +2711,7 @@ u64 execute(void* ctxt) { // nop // sll r0, r0, 0 // nop // sll r0, r0, 0 // nop // sll r0, r0, 0 - c->vftoi4(DEST::xyzw, vf3, vf3); // vftoi4.xyzw vf3, vf3 + c->vftoi4_sat(DEST::xyzw, vf3, vf3); // vftoi4.xyzw vf3, vf3 // nop // sll r0, r0, 0 c->vmulq(DEST::xyz, vf4, vf4); // vmulq.xyz vf4, vf4, Q // nop // sll r0, r0, 0 @@ -2741,7 +2741,7 @@ u64 execute(void* ctxt) { c->vadd_bc(DEST::x, BC::w, vf23, vf23, vf14); // vaddw.x vf23, vf23, vf14 block_229: - c->vftoi4(DEST::xyzw, vf4, vf4); // vftoi4.xyzw vf4, vf4 + c->vftoi4_sat(DEST::xyzw, vf4, vf4); // vftoi4.xyzw vf4, vf4 // nop // sll r0, r0, 0 // nop // sll r0, r0, 0 // nop // sll r0, r0, 0 diff --git a/game/mips2c/mips2c_private.h b/game/mips2c/mips2c_private.h index 15e6562d9..d20bed0af 100644 --- a/game/mips2c/mips2c_private.h +++ b/game/mips2c/mips2c_private.h @@ -1307,6 +1307,25 @@ struct ExecutionContext { } } + s32 float_to_int_sat(float f) { + if (f >= (float)INT32_MAX) { + return INT32_MAX; + } else if (f <= (float)INT32_MIN) { + return INT32_MIN; + } else { + return f; + } + } + + void vftoi4_sat(DEST mask, int dst, int src) { + auto s = vf_src(src); + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + vfs[dst].ds32[i] = float_to_int_sat(s.f[i] * 16.f); + } + } + } + void vftoi0(DEST mask, int dst, int src) { auto s = vf_src(src); for (int i = 0; i < 4; i++) { diff --git a/goal_src/jak2/engine/gfx/sprite/particles/sparticle.gc b/goal_src/jak2/engine/gfx/sprite/particles/sparticle.gc index 9d0d4d742..baf65d198 100644 --- a/goal_src/jak2/engine/gfx/sprite/particles/sparticle.gc +++ b/goal_src/jak2/engine/gfx/sprite/particles/sparticle.gc @@ -271,7 +271,7 @@ (defun sp-kill-particle ((arg0 sparticle-system) (arg1 sparticle-cpuinfo)) (cond - ((>= (the-as int arg1) #x70000000) + ((in-scratchpad? arg1) (set! (-> arg1 timer) 0) 0 ) diff --git a/goal_src/jak2/engine/level/level.gc b/goal_src/jak2/engine/level/level.gc index 1d1db1deb..bb5243625 100644 --- a/goal_src/jak2/engine/level/level.gc +++ b/goal_src/jak2/engine/level/level.gc @@ -10,6 +10,24 @@ (define-extern level-update-after-load (function level login-state level)) (define-extern *level-type-list* type) +(defun give-all-stuff () + (send-event *target* 'get-pickup 18 #x447a0000) + (send-event *target* 'get-pickup 17 #x447a0000) + (send-event *target* 'get-pickup 13 #x447a0000) + (send-event *target* 'get-pickup 14 #x447a0000) + (send-event *target* 'get-pickup 15 #x447a0000) + (send-event *target* 'get-pickup 16 #x447a0000) + (send-event *target* 'get-pickup 7 #x42c80000) + (logior! (-> *game-info* features) (game-feature gun gun-yellow gun-red gun-blue gun-dark board darkjak)) + (let ((v0-7 + (logior (-> *game-info* debug-features) (game-feature gun gun-yellow gun-red gun-blue gun-dark board darkjak)) + ) + ) + (set! (-> *game-info* debug-features) v0-7) + v0-7 + ) + ) + (defmacro test-play () "Temporary start macro" `(begin @@ -28,6 +46,7 @@ (suspend) ) (set! *display-profile* #t) + (give-all-stuff) ;;(set! *stats-profile-bars* #t) ) )