mirror of
https://github.com/open-goal/jak-project.git
synced 2024-11-23 06:09:57 +00:00
[jak2] float patch for bogus collide frags (#2686)
Should fix https://github.com/open-goal/jak-project/issues/2679 Here's a test program that will trigger the bug when near these guards: ```lisp (define *cquery* (new 'global 'collide-query)) (defun test-bad-collide () (let ((lower (new 'static 'vector :x 1681893.8750 :y 61314.2031 :z 345208.6562 :w 1.)) (upper (new 'static 'vector :x 1701603.8750 :y 67624.0625 :z 357881.0312 :w 1.)) ;(cquery (new 'stack-no-clear 'collide-query)) ) (set! (-> *cquery* collide-with) (the-as collide-spec 1)) (set! (-> *cquery* ignore-process0) #f) (set! (-> *cquery* ignore-process1) #f) (set! (-> *cquery* ignore-pat) (new 'static 'pat-surface :noentity #x1 :nojak #x1 :probe #x1 :noendlessfall #x1)) (set! (-> *cquery* action-mask) (collide-action solid)) (set! (-> *cquery* bbox min quad) (-> lower quad)) (set! (-> *cquery* bbox max quad) (-> upper quad)) (format 0 "doing collide...~%") (fill-using-bounding-box *collide-cache* *cquery*) (format 0 "have ~d and ~d~%" (-> *collide-cache* num-tris) (-> *collide-cache* num-prims)) ) (none) ) ``` As far as I can tell, there's a totally invalid collide-hash with an inside `axis-scale.z`. On the PS2, it gets ignore because of how float->int works for floats that are too big. On PC, it ends up using a negative value and loop forever.
This commit is contained in:
parent
6eaa95608e
commit
08741f0a42
@ -405,6 +405,8 @@ L20:
|
||||
mtir vi07, vf29.z | nop
|
||||
b L19 | nop
|
||||
mtir vi02, vf29.x | nop
|
||||
|
||||
;;;;;;;;;; WEIRD TRIANGLES
|
||||
L21:
|
||||
iaddiu vi03, vi00, 0x158 | nop
|
||||
ilwr.x vi08, vi03 | nop
|
||||
|
@ -639,40 +639,42 @@ u64 execute(void* ctxt) {
|
||||
c->sq(s5, 96, sp); // sq s5, 96(sp)
|
||||
c->sq(gp, 112, sp); // sq gp, 112(sp)
|
||||
// nop // sll r0, r0, 0
|
||||
c->lw(v1, 40, a1); // lw v1, 40(a1)
|
||||
c->lw(v1, 40, a1); // lw v1, 40(a1) v1 = frag.dimension_array;
|
||||
// nop // sll r0, r0, 0
|
||||
c->lqc2(vf1, 44, a1); // lqc2 vf1, 44(a1)
|
||||
c->lui(a3, 1); // lui a3, 1
|
||||
c->lqc2(vf2, 128, a2); // lqc2 vf2, 128(a2)
|
||||
c->ori(a3, a3, 257); // ori a3, a3, 257
|
||||
c->lqc2(vf3, 144, a2); // lqc2 vf3, 144(a2)
|
||||
c->dsubu(v1, v1, a3); // dsubu v1, v1, a3
|
||||
c->lqc2(vf6, 60, a1); // lqc2 vf6, 60(a1)
|
||||
c->vsub(DEST::xyzw, vf2, vf2, vf1); // vsub.xyzw vf2, vf2, vf1
|
||||
c->lq(a3, 160, a2); // lq a3, 160(a2)
|
||||
c->vsub(DEST::xyzw, vf3, vf3, vf1); // vsub.xyzw vf3, vf3, vf1
|
||||
c->lq(t0, 176, a2); // lq t0, 176(a2)
|
||||
c->lqc2(vf1, 44, a1); // lqc2 vf1, 44(a1) vf1 = frag.bbox.min
|
||||
c->lui(a3, 1); // lui a3, 1 a3 = 0x10000
|
||||
c->lqc2(vf2, 128, a2); // lqc2 vf2, 128(a2) vf2 = query.bbox.min
|
||||
c->ori(a3, a3, 257); // ori a3, a3, 257 a3=0x10101
|
||||
c->lqc2(vf3, 144, a2); // lqc2 vf3, 144(a2) vf3 = query.bbox.max
|
||||
c->dsubu(v1, v1, a3); // dsubu v1, v1, a3 some math on the dim array
|
||||
c->lqc2(vf6, 60, a1); // lqc2 vf6, 60(a1) vf6 = frag.axis_scale;
|
||||
c->vsub(DEST::xyzw, vf2, vf2, vf1); // vsub.xyzw vf2, vf2, vf1 vf2 = query.min - frag.min
|
||||
c->lq(a3, 160, a2); // lq a3, 160(a2) a3 = query.bbox.min.i
|
||||
c->vsub(DEST::xyzw, vf3, vf3, vf1); // vsub.xyzw vf3, vf3, vf1 vf3 = query.max - frag.min
|
||||
c->lq(t0, 176, a2); // lq t0, 176(a2) t0 = query.bbox.max.i
|
||||
c->pextlb(v1, r0, v1); // pextlb v1, r0, v1
|
||||
c->lq(t1, 76, a1); // lq t1, 76(a1)
|
||||
c->pextlh(v1, r0, v1); // pextlh v1, r0, v1
|
||||
c->lq(t2, 92, a1); // lq t2, 92(a1)
|
||||
c->pcgtw(t0, t1, t0); // pcgtw t0, t1, t0
|
||||
c->vftoi0(DEST::xyzw, vf4, vf2); // vftoi0.xyzw vf4, vf2
|
||||
c->pcgtw(a3, a3, t2); // pcgtw a3, a3, t2
|
||||
c->vftoi0(DEST::xyzw, vf5, vf3); // vftoi0.xyzw vf5, vf3
|
||||
c->por(a3, t0, a3); // por a3, t0, a3
|
||||
c->vmul(DEST::xyzw, vf2, vf2, vf6); // vmul.xyzw vf2, vf2, vf6
|
||||
c->ppach(a3, r0, a3); // ppach a3, r0, a3
|
||||
c->vmul(DEST::xyzw, vf3, vf3, vf6); // vmul.xyzw vf3, vf3, vf6
|
||||
c->lq(t1, 76, a1); // lq t1, 76(a1) t1 = frag.bbox.min.i
|
||||
c->pextlh(v1, r0, v1); // pextlh v1, r0, v1 v1 = dimensions, int.
|
||||
c->lq(t2, 92, a1); // lq t2, 92(a1) t2 = frag.bbox.max.i
|
||||
c->pcgtw(t0, t1, t0); // pcgtw t0, t1, t0 check for bbox miss.
|
||||
c->vftoi0(DEST::xyzw, vf4, vf2); // vftoi0.xyzw vf4, vf2 vf4 = int(q.min - f.min)
|
||||
c->pcgtw(a3, a3, t2); // pcgtw a3, a3, t2 check for bbox miss.
|
||||
c->vftoi0(DEST::xyzw, vf5, vf3); // vftoi0.xyzw vf5, vf3 vf5 = int(q.max - f.min)
|
||||
c->por(a3, t0, a3); // por a3, t0, a3 or miss
|
||||
c->vmul(DEST::xyzw, vf2, vf2, vf6); // vmul.xyzw vf2, vf2, vf6 axis scale
|
||||
c->ppach(a3, r0, a3); // ppach a3, r0, a3 or stuff
|
||||
c->vmul(DEST::xyzw, vf3, vf3, vf6); // vmul.xyzw vf3, vf3, vf6 axis scale
|
||||
c->dsll(t0, a3, 16); // dsll t0, a3, 16
|
||||
c->mov128_gpr_vf(a3, vf4); // qmfc2.i a3, vf4
|
||||
c->mov128_gpr_vf(a3, vf4); // qmfc2.i a3, vf4 a3 = int(q.min - f.min)
|
||||
bc = c->sgpr64(t0) != 0; // bne t0, r0, L75
|
||||
c->mov128_gpr_vf(t0, vf5); // qmfc2.i t0, vf5
|
||||
c->mov128_gpr_vf(t0, vf5); // qmfc2.i t0, vf5 t0 = int(q.max - f.min)
|
||||
if (bc) {goto block_17;} // branch non-likely
|
||||
|
||||
c->vftoi0(DEST::xyzw, vf2, vf2); // vftoi0.xyzw vf2, vf2
|
||||
// patch because there's a totally bogus collide fragment with an axis scale of
|
||||
// 0.00012207031, 0.00012207031, 1807931
|
||||
c->vftoi0_sat(DEST::xyzw, vf2, vf2); // vftoi0.xyzw vf2, vf2
|
||||
c->psraw(a3, a3, 4); // psraw a3, a3, 4
|
||||
c->vftoi0(DEST::xyzw, vf3, vf3); // vftoi0.xyzw vf3, vf3
|
||||
c->vftoi0_sat(DEST::xyzw, vf3, vf3); // vftoi0.xyzw vf3, vf3
|
||||
c->psraw(t0, t0, 4); // psraw t0, t0, 4
|
||||
// nop // sll r0, r0, 0
|
||||
c->sq(a3, 368, a2); // sq a3, 368(a2)
|
||||
|
@ -1344,6 +1344,15 @@ struct ExecutionContext {
|
||||
}
|
||||
}
|
||||
|
||||
void vftoi0_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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mfc1(int dst, int src) {
|
||||
s32 val;
|
||||
memcpy(&val, &fprs[src], 4);
|
||||
|
Loading…
Reference in New Issue
Block a user