mirror of
https://github.com/open-goal/jak-project
synced 2026-09-10 04:22:13 -04:00
up to collide-probe
This commit is contained in:
@@ -327,6 +327,29 @@
|
||||
"rewrite":
|
||||
"(dma-buffer-add-cnt-vif2 $buf $qwc $vif0 $vif1)"
|
||||
},
|
||||
{
|
||||
// A direct buffer cursor needs no alias binding, so let insertion leaves a single let.
|
||||
"name": "dma-buffer-add-cnt-vif2-direct-object-packet",
|
||||
"match":
|
||||
"(let (($packet (the-as object (-> $buf base)))) (set! (-> (the-as dma-packet $packet) dma) (new 'static 'dma-tag :id (dma-tag-id cnt))) (set! (-> (the-as dma-packet $packet) vif0) $vif0) (set! (-> (the-as dma-packet $packet) vif1) $vif1) (set! (-> $buf base) (&+ (the-as pointer $packet) 16)))",
|
||||
"rewrite":
|
||||
"(dma-buffer-add-cnt-vif2 $buf 0 $vif0 $vif1)"
|
||||
},
|
||||
{
|
||||
// Constructor keyword order follows the original instruction order and is not canonicalized.
|
||||
"name": "dma-buffer-add-cnt-vif2-qwc-after-id-object-packet",
|
||||
"match":
|
||||
"(let* (($alias $buf) ($packet (the-as object (-> $alias base)))) (set! (-> (the-as dma-packet $packet) dma) (new 'static 'dma-tag :id (dma-tag-id cnt) :qwc $qwc)) (set! (-> (the-as dma-packet $packet) vif0) $vif0) (set! (-> (the-as dma-packet $packet) vif1) $vif1) (set! (-> $alias base) (&+ (the-as pointer $packet) 16)))",
|
||||
"rewrite":
|
||||
"(dma-buffer-add-cnt-vif2 $buf $qwc $vif0 $vif1)"
|
||||
},
|
||||
{
|
||||
"name": "dma-buffer-add-ref-vif2-object-packet",
|
||||
"match":
|
||||
"(let (($packet (the-as object (-> $buf base)))) (set! (-> (the-as dma-packet $packet) dma) (new 'static 'dma-tag :qwc $qwc :id (dma-tag-id ref) :addr $addr)) (set! (-> (the-as dma-packet $packet) vif0) $vif0) (set! (-> (the-as dma-packet $packet) vif1) $vif1) (set! (-> $buf base) (&+ (the-as pointer $packet) 16)))",
|
||||
"rewrite":
|
||||
"(dma-buffer-add-ref-vif2 $buf $qwc $addr $vif0 $vif1)"
|
||||
},
|
||||
{
|
||||
"name": "dma-buffer-add-next-vif2-object-packet",
|
||||
"match":
|
||||
|
||||
@@ -2740,6 +2740,13 @@
|
||||
[2, "v1", "(pointer process-drawable)"]
|
||||
],
|
||||
"update-time-of-day": [[46, "v0", "(array float)"]],
|
||||
"sky-add-frame-data": [
|
||||
[[3, 16], "a1", "dma-packet"],
|
||||
[[18, 75], "a0", "sky-frame-data"],
|
||||
[[92, 103], "v1", "dma-packet"]
|
||||
],
|
||||
"sky-upload": [[[11, 22], "v1", "dma-packet"]],
|
||||
"sky-draw": [[[1, 12], "a0", "dma-packet"]],
|
||||
"sky-make-light": [[[10, 23], "a0", "sky-sun-data"]],
|
||||
"make-sky-textures": [
|
||||
[[90, 94], "a0", "dma-packet"],
|
||||
|
||||
@@ -161,7 +161,6 @@ set(RUNTIME_SOURCE
|
||||
mips2c/jak1_functions/collide_cache.cpp
|
||||
mips2c/jak1_functions/collide_edge_grab.cpp
|
||||
mips2c/jak1_functions/collide_mesh.cpp
|
||||
mips2c/jak1_functions/collide_probe.cpp
|
||||
mips2c/jak1_functions/generic_merc.cpp
|
||||
mips2c/jak1_functions/merc_blend_shape.cpp
|
||||
mips2c/jak1_functions/ocean_vu0.cpp
|
||||
@@ -170,7 +169,6 @@ set(RUNTIME_SOURCE
|
||||
mips2c/jak1_functions/sky_tng.cpp
|
||||
mips2c/jak1_functions/test_func.cpp
|
||||
mips2c/jak1_functions/texture.cpp
|
||||
mips2c/jak1_functions/time_of_day.cpp
|
||||
|
||||
mips2c/jak2_functions/bones.cpp
|
||||
mips2c/jak2_functions/collide_cache.cpp
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,272 +0,0 @@
|
||||
|
||||
//--------------------------MIPS2C---------------------
|
||||
|
||||
#include "game/kernel/jak1/kscheme.h"
|
||||
#include "game/mips2c/mips2c_private.h"
|
||||
using namespace jak1;
|
||||
|
||||
// clang-format off
|
||||
namespace Mips2C::jak1 {
|
||||
namespace time_of_day_interp_colors_scratch {
|
||||
|
||||
struct Cache {
|
||||
void* fake_scratchpad_data; // *fake-scratchpad-data*
|
||||
} cache;
|
||||
|
||||
u64 execute(void* ctxt) {
|
||||
auto* c = (ExecutionContext*)ctxt;
|
||||
bool bc = false;
|
||||
c->daddiu(sp, sp, -16); // daddiu sp, sp, -16
|
||||
c->sd(ra, 0, sp); // sd ra, 0(sp)
|
||||
c->sd(fp, 8, sp); // sd fp, 8(sp)
|
||||
c->mov64(fp, t9); // or fp, t9, r0
|
||||
// nop // sll r0, r0, 0
|
||||
c->lui(v1, 28672); // lui v1, 28672 0x7000
|
||||
c->daddiu(t4, a1, 12); // daddiu t4, a1, 12
|
||||
//c->ori(v1, v1, 2064); // ori v1, v1, 2064 SPAD mods
|
||||
get_fake_spad_addr(v1, cache.fake_scratchpad_data, 2064, c);
|
||||
// Unknown instr: ld a3, L168(fp)
|
||||
// L168:
|
||||
// .word 0xff00ff
|
||||
// .word 0x8000ff
|
||||
c->gprs[a3].du32[0] = 0xff00ff;
|
||||
c->gprs[a3].du32[1] = 0x8000ff;
|
||||
|
||||
c->lui(t0, 4096); // lui t0, 4096
|
||||
c->lw(t1, 4, a1); // lw t1, 4(a1)
|
||||
c->ori(a1, t0, 54272); // ori a1, t0, 54272 = (0x1000D400) SPR TO
|
||||
c->lq(t0, 1852, a2); // lq t0, 1852(a2)
|
||||
c->addiu(t2, t1, 31); // addiu t2, t1, 31
|
||||
c->lq(t1, 1868, a2); // lq t1, 1868(a2)
|
||||
c->sra(t3, t2, 5); // sra t3, t2, 5
|
||||
c->lq(t2, 1884, a2); // lq t2, 1884(a2)
|
||||
c->sll(t3, t3, 5); // sll t3, t3, 5
|
||||
c->lq(a2, 1900, a2); // lq a2, 1900(a2)
|
||||
|
||||
// wait for DMA to finish, can just remove this
|
||||
/*
|
||||
block_1:
|
||||
c->lw(t5, 0, a1); // lw t5, 0(a1)
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
c->andi(t5, t5, 256); // andi t5, t5, 256
|
||||
// nop // sll r0, r0, 0
|
||||
bc = c->sgpr64(t5) != 0; // bne t5, r0, L62
|
||||
// nop // sll r0, r0, 0
|
||||
if (bc) {goto block_1;} // branch non-likely
|
||||
*/
|
||||
|
||||
{
|
||||
// c->sw(t4, 16, a1); // sw t4, 16(a1)
|
||||
u32 madr = c->sgpr64(t4);
|
||||
c->daddiu(t3, t3, -32); // daddiu t3, t3, -32
|
||||
// c->sw(v1, 128, a1); // sw v1, 128(a1)
|
||||
u32 sadr = c->sgpr64(v1);
|
||||
c->addiu(t5, r0, 64); // addiu t5, r0, 64
|
||||
//c->sw(t5, 32, a1); // sw t5, 32(a1)
|
||||
u32 qwc = c->sgpr64(t5);
|
||||
c->addiu(t5, r0, 256); // addiu t5, r0, 256
|
||||
// c->sw(t5, 0, a1); // sw t5, 0(a1)
|
||||
spad_to_dma(cache.fake_scratchpad_data, madr, sadr, qwc);
|
||||
c->daddiu(t4, t4, 1024); // daddiu t4, t4, 1024
|
||||
}
|
||||
|
||||
block_3:
|
||||
c->mov64(t6, v1); // or t6, v1, r0
|
||||
c->xori(v1, v1, 1024); // xori v1, v1, 1024
|
||||
bc = ((s64)c->sgpr64(t3)) <= 0; // blez t3, L66
|
||||
c->daddiu(t3, t3, -32); // daddiu t3, t3, -32
|
||||
if (bc) {goto block_7;} // branch non-likely
|
||||
|
||||
|
||||
/*
|
||||
block_4:
|
||||
c->lw(t5, 0, a1); // lw t5, 0(a1)
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
c->andi(t5, t5, 256); // andi t5, t5, 256
|
||||
// nop // sll r0, r0, 0
|
||||
bc = c->sgpr64(t5) == 0; // beq t5, r0, L65
|
||||
// nop // sll r0, r0, 0
|
||||
if (bc) {goto block_6;} // branch non-likely
|
||||
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
//beq r0, r0, L64 // beq r0, r0, L64
|
||||
// nop // sll r0, r0, 0
|
||||
goto block_4; // branch always
|
||||
*/
|
||||
|
||||
{
|
||||
// block_6:
|
||||
// c->sw(t4, 16, a1); // sw t4, 16(a1)
|
||||
u32 madr = c->sgpr64(t4);
|
||||
// nop // sll r0, r0, 0
|
||||
// c->sw(v1, 128, a1); // sw v1, 128(a1)
|
||||
u32 sadr = c->sgpr64(v1);
|
||||
c->addiu(t5, r0, 64); // addiu t5, r0, 64
|
||||
// c->sw(t5, 32, a1); // sw t5, 32(a1)
|
||||
u32 qwc = c->sgpr64(t5);
|
||||
c->addiu(t5, r0, 256); // addiu t5, r0, 256
|
||||
// c->sw(t5, 0, a1); // sw t5, 0(a1)
|
||||
spad_to_dma(cache.fake_scratchpad_data, madr, sadr, qwc);
|
||||
c->daddiu(t4, t4, 1024); // daddiu t4, t4, 1024
|
||||
//beq r0, r0, L67 // beq r0, r0, L67
|
||||
// nop // sll r0, r0, 0
|
||||
}
|
||||
goto block_9; // branch always
|
||||
|
||||
|
||||
|
||||
block_7:
|
||||
/*
|
||||
c->lw(t5, 0, a1); // lw t5, 0(a1)
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
c->andi(t5, t5, 256); // andi t5, t5, 256
|
||||
// nop // sll r0, r0, 0
|
||||
bc = c->sgpr64(t5) == 0; // beq t5, r0, L67
|
||||
// nop // sll r0, r0, 0
|
||||
if (bc) {goto block_9;} // branch non-likely
|
||||
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
//beq r0, r0, L66 // beq r0, r0, L66
|
||||
// nop // sll r0, r0, 0
|
||||
goto block_7; // branch always
|
||||
*/
|
||||
|
||||
/*
|
||||
fmt::print("{} -> {} [{}]\n", c->gprs[a0].du32[0], c->gprs[t5].du32[0], c->gprs[t3].ds64[0]);
|
||||
fmt::print("[2] t0: {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x}\n", c->gprs[t0].du16[0], c->gprs[t0].du16[1], c->gprs[t0].du16[2], c->gprs[t0].du16[3], c->gprs[t0].du16[4], c->gprs[t0].du16[5], c->gprs[t0].du16[6], c->gprs[t0].du16[7]);
|
||||
fmt::print("[2] t1: {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x}\n", c->gprs[t1].du16[0], c->gprs[t1].du16[1], c->gprs[t1].du16[2], c->gprs[t1].du16[3], c->gprs[t1].du16[4], c->gprs[t1].du16[5], c->gprs[t1].du16[6], c->gprs[t1].du16[7]);
|
||||
fmt::print("[2] t2: {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x}\n", c->gprs[t2].du16[0], c->gprs[t2].du16[1], c->gprs[t2].du16[2], c->gprs[t2].du16[3], c->gprs[t2].du16[4], c->gprs[t2].du16[5], c->gprs[t2].du16[6], c->gprs[t2].du16[7]);
|
||||
fmt::print("[2] a2: {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x}\n", c->gprs[a2].du16[0], c->gprs[a2].du16[1], c->gprs[a2].du16[2], c->gprs[a2].du16[3], c->gprs[a2].du16[4], c->gprs[a2].du16[5], c->gprs[a2].du16[6], c->gprs[a2].du16[7]);
|
||||
*/
|
||||
block_9:
|
||||
c->lq(t9, 12, t6); // lq t9, 12(t6)
|
||||
c->daddiu(t5, a0, 128); // daddiu t5, a0, 128
|
||||
c->lq(t7, 28, t6); // lq t7, 28(t6)
|
||||
// nop // sll r0, r0, 0
|
||||
c->pextlb(t8, r0, t9); // pextlb t8, r0, t9
|
||||
c->mfc1(r0, f31); // mfc1 r0, f31
|
||||
c->pextub(t9, r0, t9); // pextub t9, r0, t9
|
||||
c->mfc1(r0, f31); // mfc1 r0, f31
|
||||
c->pmulth(r0, t8, t0); // pmulth r0, t8, t0
|
||||
c->mfc1(r0, f31); // mfc1 r0, f31
|
||||
c->pextlb(t8, r0, t7); // pextlb t8, r0, t7
|
||||
c->mfc1(r0, f31); // mfc1 r0, f31
|
||||
c->pmaddh(r0, t9, t1); // pmaddh r0, t9, t1
|
||||
c->mfc1(r0, f31); // mfc1 r0, f31
|
||||
c->pextub(t7, r0, t7); // pextub t7, r0, t7
|
||||
c->mfc1(r0, f31); // mfc1 r0, f31
|
||||
c->pmaddh(r0, t8, t2); // pmaddh r0, t8, t2
|
||||
c->lq(t8, 44, t6); // lq t8, 44(t6)
|
||||
c->addiu(t6, t6, 32); // addiu t6, t6, 32
|
||||
// nop // sll r0, r0, 0
|
||||
c->pmaddh(r0, t7, a2); // pmaddh r0, t7, a2
|
||||
c->lq(t7, 28, t6); // lq t7, 28(t6)
|
||||
c->pextlb(t9, r0, t8); // pextlb t9, r0, t8
|
||||
c->mfc1(r0, f31); // mfc1 r0, f31
|
||||
|
||||
block_10:
|
||||
c->pextub(t8, r0, t8); // pextub t8, r0, t8
|
||||
// fmt::print("[0] t1: {:02x} {:02x} {:02x} {:02x}\n", c->gprs[t1].du32[0], c->gprs[t1].du32[1], c->gprs[t1].du32[2], c->gprs[t1].du32[3]);
|
||||
c->mfc1(r0, f31); // mfc1 r0, f31
|
||||
c->pmfhl_lh(ra); // pmfhl.lh ra
|
||||
// fmt::print("[1] ra: {:02x} {:02x} {:02x} {:02x}\n", c->gprs[ra].du32[0], c->gprs[ra].du32[1], c->gprs[ra].du32[2], c->gprs[ra].du32[3]);
|
||||
c->mfc1(r0, f31); // mfc1 r0, f31
|
||||
c->pmulth(r0, t9, t0); // pmulth r0, t9, t0
|
||||
|
||||
c->mfc1(r0, f31); // mfc1 r0, f31
|
||||
c->psrlh(t9, ra, 6); // psrlh t9, ra, 6
|
||||
// fmt::print("[3] t9: {:02x} {:02x} {:02x} {:02x}\n", c->gprs[t9].du32[0], c->gprs[t9].du32[1], c->gprs[t9].du32[2], c->gprs[t9].du32[3]);
|
||||
c->mfc1(r0, f31); // mfc1 r0, f31
|
||||
c->pcpyud(ra, t9, t9); // pcpyud ra, t9, t9
|
||||
c->mfc1(r0, f31); // mfc1 r0, f31
|
||||
c->paddh(t9, ra, t9); // paddh t9, ra, t9
|
||||
c->mfc1(r0, f31); // mfc1 r0, f31
|
||||
c->pminh(t9, t9, a3); // pminh t9, t9, a3
|
||||
c->mfc1(r0, f31); // mfc1 r0, f31
|
||||
c->ppacb(ra, r0, t9); // ppacb ra, r0, t9
|
||||
c->mfc1(r0, f31); // mfc1 r0, f31
|
||||
c->pextlb(t9, r0, t7); // pextlb t9, r0, t7
|
||||
c->mfc1(r0, f31); // mfc1 r0, f31
|
||||
c->pmaddh(r0, t8, t1); // pmaddh r0, t8, t1
|
||||
c->sw(ra, 0, a0); // sw ra, 0(a0)
|
||||
c->pextub(t7, r0, t7); // pextub t7, r0, t7
|
||||
c->mfc1(r0, f31); // mfc1 r0, f31
|
||||
c->pmaddh(r0, t9, t2); // pmaddh r0, t9, t2
|
||||
c->lq(t8, 44, t6); // lq t8, 44(t6)
|
||||
c->addiu(t6, t6, 32); // addiu t6, t6, 32
|
||||
c->addiu(a0, a0, 4); // addiu a0, a0, 4
|
||||
c->pmaddh(r0, t7, a2); // pmaddh r0, t7, a2
|
||||
c->lq(t7, 28, t6); // lq t7, 28(t6)
|
||||
/*
|
||||
fmt::print(" N0");
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
fmt::print(" {:02x}", c->gprs[t8].du8[i*4 + j]);
|
||||
}
|
||||
fmt::print(" |");
|
||||
}
|
||||
fmt::print("\n N1");
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
fmt::print(" {:02x}", c->gprs[t7].du8[i*4 + j]);
|
||||
}
|
||||
fmt::print(" |");
|
||||
}
|
||||
fmt::print("\n");
|
||||
*/
|
||||
// fmt::print("next: {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x}\n", c->gprs[t8].du32[0], c->gprs[t8].du32[1], c->gprs[t8].du32[2], c->gprs[t8].du32[3],
|
||||
// c->gprs[t7].du32[0], c->gprs[t7].du32[1], c->gprs[t7].du32[2], c->gprs[t7].du32[3]);
|
||||
bc = c->sgpr64(a0) != c->sgpr64(t5); // bne a0, t5, L68
|
||||
c->pextlb(t9, r0, t8); // pextlb t9, r0, t8
|
||||
if (bc) {goto block_10;} // branch non-likely
|
||||
|
||||
bc = ((s64)c->sgpr64(t3)) >= 0; // bgez t3, L63
|
||||
// nop // sll r0, r0, 0
|
||||
if (bc) {goto block_3;} // branch non-likely
|
||||
|
||||
c->gprs[v0].du64[0] = 0; // or v0, r0, r0
|
||||
c->ld(ra, 0, sp); // ld ra, 0(sp)
|
||||
c->ld(fp, 8, sp); // ld fp, 8(sp)
|
||||
//jr ra // jr ra
|
||||
c->daddiu(sp, sp, 16); // daddiu sp, sp, 16
|
||||
goto end_of_function; // return
|
||||
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
end_of_function:
|
||||
return c->gprs[v0].du64[0];
|
||||
}
|
||||
|
||||
void link() {
|
||||
cache.fake_scratchpad_data = intern_from_c("*fake-scratchpad-data*").c();
|
||||
gLinkedFunctionTable.reg("time-of-day-interp-colors-scratch", execute, 512);
|
||||
}
|
||||
|
||||
} // namespace time_of_day_interp_colors_scratch
|
||||
} // namespace Mips2C
|
||||
|
||||
@@ -25,28 +25,28 @@
|
||||
;; moving-sphere-moving-sphere-intersect
|
||||
;; unused
|
||||
|
||||
|
||||
(defconstant COLLISION_MISS -100000000.0)
|
||||
|
||||
(defglobalconstant COLLIDE_FUNC_COUNTERS #t)
|
||||
|
||||
(#when COLLIDE_FUNC_COUNTERS
|
||||
(define *raw-ray-sphere-intersect-count* 0)
|
||||
(define *ray-sphere-intersect-count* 0)
|
||||
(define *ray-circle-intersect-count* 0)
|
||||
(define *ray-cylinder-intersect-count* 0)
|
||||
(define *collide-do-primitives-count* 0)
|
||||
(define *moving-sphere-triangle-intersect-count* 0)
|
||||
(define *moving-sphere-sphere-intersect-count* 0)
|
||||
(define *moving-sphere-moving-sphere-intersect-count* 0)
|
||||
)
|
||||
(define *raw-ray-sphere-intersect-count* 0)
|
||||
(define *ray-sphere-intersect-count* 0)
|
||||
(define *ray-circle-intersect-count* 0)
|
||||
(define *ray-cylinder-intersect-count* 0)
|
||||
(define *collide-do-primitives-count* 0)
|
||||
(define *moving-sphere-triangle-intersect-count* 0)
|
||||
(define *moving-sphere-sphere-intersect-count* 0)
|
||||
(define *moving-sphere-moving-sphere-intersect-count* 0)
|
||||
(define *collide-probe-make-list-count* 0)
|
||||
(define *collide-probe-make-list-item-count* 0)
|
||||
(define *collide-probe-make-list-timer* (new 'global 'stopwatch)))
|
||||
|
||||
(defun raw-ray-sphere-intersect ((origin vector) (direction vector) (radius float))
|
||||
"Check if a ray intersects a sphere at the origin.
|
||||
Return the fraction along the ray where the intersection occurs, or COLLISION_MISS
|
||||
if there is no collision."
|
||||
|
||||
;; This function is rewritten in plain GOAL
|
||||
|
||||
;; Parameterize the ray with:
|
||||
;; ray(t) = origin + t * direction with 0 <= t <= 1
|
||||
;; A point p is on the origin if:
|
||||
@@ -62,10 +62,8 @@
|
||||
;; a = dot(dir, dir)
|
||||
;; b = dot(dir, origin)
|
||||
;; c = dot(origin, origin) - r^2
|
||||
|
||||
(#when COLLIDE_FUNC_COUNTERS
|
||||
(+! *raw-ray-sphere-intersect-count* 1))
|
||||
|
||||
;; this matches the order of operations in the original, just in case rounding matters.
|
||||
(let ((c (+ (+ (square (-> origin x))
|
||||
(square (-> origin y)))
|
||||
@@ -464,10 +462,9 @@
|
||||
(set! contact-fraction COLLISION_MISS)))
|
||||
contact-fraction))
|
||||
|
||||
|
||||
(#when COLLIDE_FUNC_COUNTERS
|
||||
(defun clear-collide-func-counters ()
|
||||
"Clear the collision function counters at the start of a frame."
|
||||
"Clear the collision function counters and probe-list profile at the start of a frame."
|
||||
(set! *raw-ray-sphere-intersect-count* 0)
|
||||
(set! *ray-sphere-intersect-count* 0)
|
||||
(set! *ray-circle-intersect-count* 0)
|
||||
@@ -476,10 +473,12 @@
|
||||
(set! *moving-sphere-triangle-intersect-count* 0)
|
||||
(set! *moving-sphere-sphere-intersect-count* 0)
|
||||
(set! *moving-sphere-moving-sphere-intersect-count* 0)
|
||||
(set! *collide-probe-make-list-count* 0)
|
||||
(set! *collide-probe-make-list-item-count* 0)
|
||||
(stopwatch-init *collide-probe-make-list-timer*)
|
||||
(none))
|
||||
|
||||
(defun display-collide-func-counters ()
|
||||
"Display the collision function counters, three per line."
|
||||
"Display the collision function counters and probe-list frame totals."
|
||||
(format *stdcon*
|
||||
" krrs ~7D rs ~7D rc ~7D~%"
|
||||
*raw-ray-sphere-intersect-count*
|
||||
@@ -494,4 +493,9 @@
|
||||
" mss ~7D msms ~7D~%"
|
||||
*moving-sphere-sphere-intersect-count*
|
||||
*moving-sphere-moving-sphere-intersect-count*)
|
||||
(format *stdcon*
|
||||
" probe-list ~7D calls ~7D items ~3D us~%"
|
||||
*collide-probe-make-list-count*
|
||||
*collide-probe-make-list-item-count*
|
||||
(the int (* 1000000.0 (stopwatch-elapsed-seconds *collide-probe-make-list-timer*))))
|
||||
(none)))
|
||||
|
||||
@@ -0,0 +1,955 @@
|
||||
|
||||
(#unless PC_PORT
|
||||
;; A BASIC value points just after its allocation's type word. Raw EE loads from such a value
|
||||
;; therefore subtract four from the displayed field offset.
|
||||
(defconstant PROBE-BASIC-BIAS 4)
|
||||
(defconstant PROBE-STACK-CHILD (offset-of collide-probe-stack-elem child)) ;; 0
|
||||
(defconstant PROBE-STACK-COUNT (offset-of collide-probe-stack-elem count)) ;; 4
|
||||
;; The work kind occupies the high halfword of collide-probe-stack-elem.count.
|
||||
(defconstant PROBE-STACK-KIND (+ (offset-of collide-probe-stack-elem count) 2)) ;; 6
|
||||
(defconstant PROBE-STACK-STRIDE (type-size collide-probe-stack-elem)) ;; 8
|
||||
(defconstant PROBE-DRAWABLE-CHILD-COUNT (- (offset-of draw-node child-count) PROBE-BASIC-BIAS)) ;; 2
|
||||
(defconstant PROBE-DRAWABLE-FLAGS (- (offset-of draw-node flags) PROBE-BASIC-BIAS)) ;; 3
|
||||
(defconstant PROBE-DRAWABLE-CHILD (- (offset-of draw-node child) PROBE-BASIC-BIAS)) ;; 4
|
||||
;; The same four-byte payload is draw-node.child or collide-fragment.mesh according to work kind.
|
||||
(defconstant PROBE-CANDIDATE-PAYLOAD PROBE-DRAWABLE-CHILD)
|
||||
(defconstant PROBE-DRAWABLE-BSPHERE (- (offset-of draw-node bsphere) PROBE-BASIC-BIAS)) ;; 12
|
||||
(defconstant PROBE-DRAW-NODE-STRIDE (type-size draw-node)) ;; 32
|
||||
(defconstant PROBE-INSTANCE-STRIDE (type-size instance-tie)) ;; 64
|
||||
(defconstant PROBE-FRAGMENT-STRIDE (type-size collide-fragment)) ;; 32
|
||||
(defconstant PROBE-FRAGMENT-MESH (- (offset-of collide-fragment mesh) PROBE-BASIC-BIAS)) ;; 4
|
||||
(defconstant PROBE-BUCKET-COLLIDE-FRAG (- (offset-of prototype-bucket-tie collide-frag) PROBE-BASIC-BIAS)) ;; 136
|
||||
(defconstant PROBE-FRAGMENT-ARRAY-LENGTH (- (offset-of drawable-inline-array-collide-fragment length) PROBE-BASIC-BIAS)) ;; 2
|
||||
;; data is an inline BASIC array. This displacement passes its type word and lands on the first
|
||||
;; collide-fragment's GOAL pointer.
|
||||
(defconstant PROBE-FRAGMENT-ARRAY-DATA (offset-of drawable-inline-array-collide-fragment data 0)) ;; 32
|
||||
(defconstant PROBE-INSTANCE-BUCKET (- (offset-of instance-tie bucket-ptr) PROBE-BASIC-BIAS)) ;; 8
|
||||
(defconstant PROBE-INSTANCE-BSPHERE (- (offset-of instance-tie bsphere) PROBE-BASIC-BIAS)) ;; 12
|
||||
(defconstant PROBE-INSTANCE-ORIGIN-LOW (- (offset-of instance-tie origin data 0) PROBE-BASIC-BIAS)) ;; 28
|
||||
(defconstant PROBE-INSTANCE-MAX-SCALE (- (offset-of instance-tie max-scale) PROBE-BASIC-BIAS)) ;; 34
|
||||
(defconstant PROBE-INSTANCE-FLAGS (- (offset-of instance-tie flags) PROBE-BASIC-BIAS)) ;; 42
|
||||
(defconstant PROBE-INSTANCE-ORIGIN-HIGH (- (offset-of instance-tie origin data 8) PROBE-BASIC-BIAS)) ;; 44
|
||||
(defconstant PROBE-QUERY-MIN (offset-of collide-work collide-box4w min)) ;; 16
|
||||
(defconstant PROBE-QUERY-MAX (offset-of collide-work collide-box4w max)) ;; 32
|
||||
(defconstant PROBE-QUERY-ROW-X (offset-of collide-work inv-mat vector 0)) ;; 48
|
||||
(defconstant PROBE-QUERY-ROW-Y (offset-of collide-work inv-mat vector 1)) ;; 64
|
||||
(defconstant PROBE-QUERY-ROW-Z (offset-of collide-work inv-mat vector 2)) ;; 80
|
||||
(defconstant PROBE-QUERY-TRANSLATION (offset-of collide-work inv-mat vector 3)) ;; 96
|
||||
(defconstant PROBE-RESULT-COUNT (offset-of collide-list num-items)) ;; 0
|
||||
(defconstant PROBE-RESULT-ITEMS (offset-of collide-list items 0)) ;; 16
|
||||
;; collide-list-item is eight bytes as a structure, but this fixed inline array gives each
|
||||
;; physical slot sixteen-byte alignment.
|
||||
(defconstant PROBE-RESULT-ITEM-STRIDE 16)
|
||||
(defconstant PROBE-RESULT-MESH (offset-of collide-list-item mesh)) ;; 0
|
||||
(defconstant PROBE-RESULT-INSTANCE (offset-of collide-list-item inst))) ;; 4
|
||||
|
||||
|
||||
|
||||
;; The inverse probe transform establishes an axis-aligned box space for the rotated line-sphere
|
||||
;; query. Entry 0 transforms four bounding spheres into that space and leaves integer minimum and
|
||||
;; maximum corners in vf9..vf16. Entry 32 rebuilds a compressed TIE instance transform around its
|
||||
;; world bounding-sphere center and composes it with the probe transform. Entry 54 uses the composed
|
||||
;; transform and the instance's maximum scale to conservatively bound four prototype fragments;
|
||||
;; vf22.x/y/z/w holds one scaled radius for each sphere. The EE rejects the resulting boxes against
|
||||
;; collide-work.collide-box4w.
|
||||
(#unless PC_PORT
|
||||
(defvu0 collide-vu0-block
|
||||
(rlet ((probe-row-x :reg vf01)
|
||||
(probe-row-y :reg vf02)
|
||||
(probe-row-z :reg vf03)
|
||||
(probe-translation :reg vf04)
|
||||
(sphere-0 :reg vf05)
|
||||
(sphere-1 :reg vf06)
|
||||
(sphere-2 :reg vf07)
|
||||
(sphere-3 :reg vf08)
|
||||
(min-0 :reg vf09)
|
||||
(max-0 :reg vf10)
|
||||
(min-1 :reg vf11)
|
||||
(max-1 :reg vf12)
|
||||
(min-2 :reg vf13)
|
||||
(max-2 :reg vf14)
|
||||
(min-3 :reg vf15)
|
||||
(max-3 :reg vf16))
|
||||
;; Transform the four centers and expand each result by its source sphere radius.
|
||||
(vu-pair (nop) (mulaw.xyzw ACC probe-translation vf00))
|
||||
(vu-pair (nop) (maddax.xyzw ACC probe-row-x sphere-0))
|
||||
(vu-pair (nop) (madday.xyzw ACC probe-row-y sphere-0))
|
||||
(vu-pair (nop) (maddz.xyz sphere-0 probe-row-z sphere-0))
|
||||
(vu-pair (nop) (mulaw.xyzw ACC probe-translation vf00))
|
||||
(vu-pair (nop) (maddax.xyzw ACC probe-row-x sphere-1))
|
||||
(vu-pair (nop) (madday.xyzw ACC probe-row-y sphere-1))
|
||||
(vu-pair (nop) (maddz.xyz sphere-1 probe-row-z sphere-1))
|
||||
(vu-pair (nop) (mulaw.xyzw ACC probe-translation vf00))
|
||||
(vu-pair (nop) (maddax.xyzw ACC probe-row-x sphere-2))
|
||||
(vu-pair (nop) (madday.xyzw ACC probe-row-y sphere-2))
|
||||
(vu-pair (nop) (maddz.xyz sphere-2 probe-row-z sphere-2))
|
||||
(vu-pair (nop) (mulaw.xyzw ACC probe-translation vf00))
|
||||
(vu-pair (nop) (maddax.xyzw ACC probe-row-x sphere-3))
|
||||
(vu-pair (nop) (madday.xyzw ACC probe-row-y sphere-3))
|
||||
(vu-pair (nop) (maddz.xyz sphere-3 probe-row-z sphere-3))
|
||||
(vu-pair (nop) (subw.xyz min-0 sphere-0 sphere-0))
|
||||
(vu-pair (nop) (subw.xyz min-1 sphere-1 sphere-1))
|
||||
(vu-pair (nop) (subw.xyz min-2 sphere-2 sphere-2))
|
||||
(vu-pair (nop) (subw.xyz min-3 sphere-3 sphere-3))
|
||||
(vu-pair (nop) (addw.xyz max-0 sphere-0 sphere-0))
|
||||
(vu-pair (nop) (addw.xyz max-1 sphere-1 sphere-1))
|
||||
(vu-pair (nop) (addw.xyz max-2 sphere-2 sphere-2))
|
||||
(vu-pair (nop) (addw.xyz max-3 sphere-3 sphere-3))
|
||||
(vu-pair (nop) (ftoi0.xyzw min-0 min-0))
|
||||
(vu-pair (nop) (ftoi0.xyzw min-1 min-1))
|
||||
(vu-pair (nop) (ftoi0.xyzw min-2 min-2))
|
||||
(vu-pair (nop) (ftoi0.xyzw min-3 min-3))
|
||||
(vu-pair (nop) (ftoi0.xyzw max-0 max-0))
|
||||
(vu-pair (nop) (ftoi0.xyzw max-1 max-1))
|
||||
(vu-pair (nop) (ftoi0.xyzw max-2 max-2 :e))
|
||||
(vu-pair (nop) (ftoi0.xyzw max-3 max-3)))
|
||||
(label compose-instance-transform)
|
||||
(rlet ((probe-row-x :reg vf01)
|
||||
(probe-row-y :reg vf02)
|
||||
(probe-row-z :reg vf03)
|
||||
(probe-translation :reg vf04)
|
||||
(instance-row-x :reg vf17)
|
||||
(instance-row-y :reg vf18)
|
||||
(instance-row-z :reg vf19)
|
||||
(instance-translation :reg vf20)
|
||||
(instance-max-scale :reg vf21)
|
||||
(instance-origin :reg vf23))
|
||||
;; Basis rows are signed Q12 fixed point and maximum scale is unsigned Q12. Translation
|
||||
;; is quantized in 64-unit steps relative to the instance's world bounding-sphere center.
|
||||
(vu-pair (nop) (itof0.xyzw instance-translation instance-translation))
|
||||
(vu-pair (nop) (itof12.xyzw instance-row-x instance-row-x))
|
||||
(vu-pair (nop) (itof12.xyzw instance-row-y instance-row-y))
|
||||
(vu-pair (nop) (itof12.xyzw instance-row-z instance-row-z))
|
||||
(vu-pair (nop) (add.xyz instance-translation instance-translation instance-origin))
|
||||
(vu-pair (nop) (itof12.xyzw instance-max-scale instance-max-scale))
|
||||
;; Compose the instance translation and three basis rows into the probe's box space.
|
||||
(vu-pair (nop) (mulax.xyzw ACC probe-row-x instance-translation))
|
||||
(vu-pair (nop) (madday.xyzw ACC probe-row-y instance-translation))
|
||||
(vu-pair (nop) (maddaz.xyzw ACC probe-row-z instance-translation))
|
||||
(vu-pair (nop) (maddw.xyz instance-translation probe-translation vf00))
|
||||
(vu-pair (nop) (mulax.xyzw ACC probe-row-x instance-row-x))
|
||||
(vu-pair (nop) (madday.xyzw ACC probe-row-y instance-row-x))
|
||||
(vu-pair (nop) (maddaz.xyzw ACC probe-row-z instance-row-x))
|
||||
(vu-pair (nop) (maddx.xyz instance-row-x probe-translation vf00))
|
||||
(vu-pair (nop) (mulax.xyzw ACC probe-row-x instance-row-y))
|
||||
(vu-pair (nop) (madday.xyzw ACC probe-row-y instance-row-y))
|
||||
(vu-pair (nop) (maddaz.xyzw ACC probe-row-z instance-row-y))
|
||||
(vu-pair (nop) (maddx.xyz instance-row-y probe-translation vf00))
|
||||
(vu-pair (nop) (mulax.xyzw ACC probe-row-x instance-row-z))
|
||||
(vu-pair (nop) (madday.xyzw ACC probe-row-y instance-row-z))
|
||||
(vu-pair (nop) (maddaz.xyzw ACC probe-row-z instance-row-z :e))
|
||||
(vu-pair (nop) (maddx.xyz instance-row-z probe-translation vf00)))
|
||||
(label transform-prototype-spheres)
|
||||
(rlet ((instance-row-x :reg vf17)
|
||||
(instance-row-y :reg vf18)
|
||||
(instance-row-z :reg vf19)
|
||||
(instance-translation :reg vf20)
|
||||
(instance-max-scale :reg vf21)
|
||||
(scaled-radii :reg vf22)
|
||||
(sphere-0 :reg vf05)
|
||||
(sphere-1 :reg vf06)
|
||||
(sphere-2 :reg vf07)
|
||||
(sphere-3 :reg vf08)
|
||||
(min-0 :reg vf09)
|
||||
(max-0 :reg vf10)
|
||||
(min-1 :reg vf11)
|
||||
(max-1 :reg vf12)
|
||||
(min-2 :reg vf13)
|
||||
(max-2 :reg vf14)
|
||||
(min-3 :reg vf15)
|
||||
(max-3 :reg vf16))
|
||||
;; Transform each prototype sphere and conservatively scale its radius by the instance.
|
||||
(vu-pair (nop) (mulaw.xyzw ACC instance-translation vf00))
|
||||
(vu-pair (nop) (maddax.xyzw ACC instance-row-x sphere-0))
|
||||
(vu-pair (nop) (madday.xyzw ACC instance-row-y sphere-0))
|
||||
(vu-pair (nop) (maddz.xyzw min-0 instance-row-z sphere-0))
|
||||
(vu-pair (nop) (mulaw.xyzw ACC instance-translation vf00))
|
||||
(vu-pair (nop) (maddax.xyzw ACC instance-row-x sphere-1))
|
||||
(vu-pair (nop) (madday.xyzw ACC instance-row-y sphere-1))
|
||||
(vu-pair (nop) (maddz.xyzw min-1 instance-row-z sphere-1))
|
||||
(vu-pair (nop) (mulaw.xyzw ACC instance-translation vf00))
|
||||
(vu-pair (nop) (maddax.xyzw ACC instance-row-x sphere-2))
|
||||
(vu-pair (nop) (madday.xyzw ACC instance-row-y sphere-2))
|
||||
(vu-pair (nop) (maddz.xyzw min-2 instance-row-z sphere-2))
|
||||
(vu-pair (nop) (mulaw.xyzw ACC instance-translation vf00))
|
||||
(vu-pair (nop) (maddax.xyzw ACC instance-row-x sphere-3))
|
||||
(vu-pair (nop) (madday.xyzw ACC instance-row-y sphere-3))
|
||||
(vu-pair (nop) (maddz.xyzw min-3 instance-row-z sphere-3))
|
||||
(vu-pair (nop) (mulw.x scaled-radii instance-max-scale sphere-0))
|
||||
(vu-pair (nop) (mulw.y scaled-radii instance-max-scale sphere-1))
|
||||
(vu-pair (nop) (mulw.z scaled-radii instance-max-scale sphere-2))
|
||||
(vu-pair (nop) (mulw.w scaled-radii instance-max-scale sphere-3))
|
||||
(vu-pair (nop) (addx.xyz max-0 min-0 scaled-radii))
|
||||
(vu-pair (nop) (subx.xyz min-0 min-0 scaled-radii))
|
||||
(vu-pair (nop) (addy.xyz max-1 min-1 scaled-radii))
|
||||
(vu-pair (nop) (suby.xyz min-1 min-1 scaled-radii))
|
||||
(vu-pair (nop) (addz.xyz max-2 min-2 scaled-radii))
|
||||
(vu-pair (nop) (subz.xyz min-2 min-2 scaled-radii))
|
||||
(vu-pair (nop) (addw.xyz max-3 min-3 scaled-radii))
|
||||
(vu-pair (nop) (subw.xyz min-3 min-3 scaled-radii))
|
||||
(vu-pair (nop) (ftoi0.xyzw max-0 max-0))
|
||||
(vu-pair (nop) (ftoi0.xyzw min-0 min-0))
|
||||
(vu-pair (nop) (ftoi0.xyzw max-1 max-1))
|
||||
(vu-pair (nop) (ftoi0.xyzw min-1 min-1))
|
||||
(vu-pair (nop) (ftoi0.xyzw max-2 max-2))
|
||||
(vu-pair (nop) (ftoi0.xyzw min-2 min-2))
|
||||
(vu-pair (nop) (ftoi0.xyzw max-3 max-3 :e))
|
||||
(vu-pair (nop) (ftoi0.xyzw min-3 min-3)))))
|
||||
|
||||
|
||||
|
||||
(#unless PC_PORT
|
||||
(defun collide-probe-node ((nodes (inline-array draw-node)) (node-count int) (result collide-list))
|
||||
"Traverse node-count draw nodes against the active rotated line-sphere probe. Bounding spheres
|
||||
are culled four at a time in VU0; overlapping child spans are visited through the scratchpad
|
||||
stack, and surviving collision-fragment meshes are appended to result with no instance.
|
||||
Callers must stay within the stack's 1024 entries and the result's 256 entries."
|
||||
(rlet ((stack-top :reg a0)
|
||||
(query-min :reg a1 :class i128)
|
||||
(result :reg a2)
|
||||
(query-max :reg a3 :class i128)
|
||||
(stack-base :reg v1)
|
||||
(result-count :reg t0)
|
||||
(result-cursor :reg t1)
|
||||
(span :reg t2)
|
||||
(remaining :reg t3)
|
||||
(kind :reg t4)
|
||||
(probe-row-x :reg vf1)
|
||||
(probe-row-y :reg vf2)
|
||||
(probe-row-z :reg vf3)
|
||||
(probe-translation :reg vf4)
|
||||
(sphere-0 :reg vf5)
|
||||
(sphere-1 :reg vf6)
|
||||
(sphere-2 :reg vf7)
|
||||
(sphere-3 :reg vf8)
|
||||
(min-0 :reg vf9)
|
||||
(max-0 :reg vf10)
|
||||
(min-1 :reg vf11)
|
||||
(max-1 :reg vf12)
|
||||
(min-2 :reg vf13)
|
||||
(max-2 :reg vf14)
|
||||
(min-3 :reg vf15)
|
||||
(max-3 :reg vf16))
|
||||
(asm-block save-state-and-seed-stack
|
||||
(rlet ((work :reg t0)
|
||||
(seed-kind :reg a1))
|
||||
(add.i sp sp -96)
|
||||
(s.d ra sp)
|
||||
(s.q s2 sp 16)
|
||||
(s.q s3 sp 32)
|
||||
(s.q s4 sp 48)
|
||||
(s.q s5 sp 64)
|
||||
(s.q gp sp 80)
|
||||
(m! work *collide-work*)
|
||||
(m! stack-base *collide-probe-stack*)
|
||||
(s.w nodes stack-base PROBE-STACK-CHILD)
|
||||
(add.i stack-top stack-base PROBE-STACK-STRIDE)
|
||||
(s.h node-count stack-base PROBE-STACK-COUNT)
|
||||
(add.i seed-kind r0 1)
|
||||
(s.h seed-kind stack-base PROBE-STACK-KIND))
|
||||
(rlet ((work :reg t0))
|
||||
(l.q query-min work PROBE-QUERY-MIN)
|
||||
(l.q query-max work PROBE-QUERY-MAX)
|
||||
(l.vf probe-row-x work PROBE-QUERY-ROW-X)
|
||||
(l.vf probe-row-y work PROBE-QUERY-ROW-Y)
|
||||
(l.vf probe-row-z work PROBE-QUERY-ROW-Z)
|
||||
(l.vf probe-translation work PROBE-QUERY-TRANSLATION))
|
||||
(l.w result-count result PROBE-RESULT-COUNT)
|
||||
(sll result-cursor result-count 4)
|
||||
(add result-cursor result-cursor result)
|
||||
(add.i result-cursor result-cursor PROBE-RESULT-ITEMS))
|
||||
;; Work entries are popped from the end. Their count word is split into a remaining halfword
|
||||
;; and a kind halfword even though the reflected structure exposes it as one uint32.
|
||||
(asm-block pop-span
|
||||
(label pop-span)
|
||||
(b.eq stack-top stack-base done :delay (nop!))
|
||||
(add.i stack-top stack-top (- PROBE-STACK-STRIDE))
|
||||
(l.w span stack-top PROBE-STACK-CHILD)
|
||||
(l.hu remaining stack-top PROBE-STACK-COUNT)
|
||||
(l.hu kind stack-top PROBE-STACK-KIND))
|
||||
;; Drawable arrays are padded, so this path can fetch all four spheres before remaining
|
||||
;; determines which results are consumed.
|
||||
(asm-block cull-four-spheres
|
||||
(label cull-four)
|
||||
(l.vf sphere-0 span PROBE-DRAWABLE-BSPHERE)
|
||||
(l.vf sphere-1 span (+ PROBE-DRAWABLE-BSPHERE PROBE-DRAW-NODE-STRIDE))
|
||||
(add.i t5 remaining -4)
|
||||
(l.vf sphere-2 span (+ PROBE-DRAWABLE-BSPHERE (* 2 PROBE-DRAW-NODE-STRIDE)))
|
||||
(b.lt t5 r0 reduce-four :delay (l.vf sphere-3 span (+ PROBE-DRAWABLE-BSPHERE (* 3 PROBE-DRAW-NODE-STRIDE))))
|
||||
(pref span (+ PROBE-DRAWABLE-BSPHERE (* 4 PROBE-DRAW-NODE-STRIDE)) :hint 0)
|
||||
(label reduce-four)
|
||||
(callms 0)
|
||||
(nop!)
|
||||
(m t5 min-0)
|
||||
(m t6 max-0)
|
||||
(m s2 min-1)
|
||||
(m s3 max-1)
|
||||
(m s4 min-2)
|
||||
(m s5 max-2)
|
||||
(m ra min-3)
|
||||
(m t9 max-3)
|
||||
;; Each packed result is nonzero if candidate-min exceeds query-max or query-min exceeds
|
||||
;; candidate-max. Packing the high halfwords and shifting drops W, leaving the XYZ reject.
|
||||
(pcgt.w t5 t5 query-max)
|
||||
(l.w t8 span PROBE-CANDIDATE-PAYLOAD)
|
||||
(pcgt.w t7 query-min t6)
|
||||
(l.w t6 span (+ PROBE-CANDIDATE-PAYLOAD PROBE-DRAW-NODE-STRIDE))
|
||||
(or.q t5 t5 t7)
|
||||
(l.w t7 span (+ PROBE-CANDIDATE-PAYLOAD (* 2 PROBE-DRAW-NODE-STRIDE)))
|
||||
(ppach gp r0 t5)
|
||||
(l.w t5 span (+ PROBE-CANDIDATE-PAYLOAD (* 3 PROBE-DRAW-NODE-STRIDE)))
|
||||
(pcgt.w s2 s2 query-max)
|
||||
(mmi-nop!)
|
||||
(pcgt.w s3 query-min s3)
|
||||
(mmi-nop!)
|
||||
(or.q s3 s2 s3)
|
||||
(mmi-nop!)
|
||||
(ppach s3 r0 s3)
|
||||
(mmi-nop!)
|
||||
(pcgt.w s4 s4 query-max)
|
||||
(mmi-nop!)
|
||||
(pcgt.w s5 query-min s5)
|
||||
(mmi-nop!)
|
||||
(or.q s5 s4 s5)
|
||||
(mmi-nop!)
|
||||
(ppach s5 r0 s5)
|
||||
(mmi-nop!)
|
||||
(pcgt.w ra ra query-max)
|
||||
(mmi-nop!)
|
||||
(pcgt.w t9 query-min t9)
|
||||
(mmi-nop!)
|
||||
(or.q t9 ra t9)
|
||||
(mmi-nop!)
|
||||
(ppach t9 r0 t9)
|
||||
(mmi-nop!)
|
||||
(sll s4 gp 16)
|
||||
(sll gp s3 16)
|
||||
(sll ra s5 16)
|
||||
(sll t9 t9 16))
|
||||
;; A nonzero kind describes draw nodes. Push each overlapping child span back onto the LIFO.
|
||||
(asm-block push-overlapping-children
|
||||
(b.z kind append-fragment-leaves :delay (nop!))
|
||||
(b.nz s4 after-node-0 :delay (add.i remaining remaining -1))
|
||||
(nop!)
|
||||
(l.bu s5 span PROBE-DRAWABLE-CHILD-COUNT)
|
||||
(nop!)
|
||||
(l.bu s4 span PROBE-DRAWABLE-FLAGS)
|
||||
(add.i stack-top stack-top PROBE-STACK-STRIDE)
|
||||
(s.w t8 stack-top -8)
|
||||
(nop!)
|
||||
(s.h s5 stack-top -4)
|
||||
(nop!)
|
||||
(s.h s4 stack-top -2)
|
||||
(label after-node-0)
|
||||
(b.z remaining finish-node-group :delay (nop!))
|
||||
(b.nz gp after-node-1 :delay (add.i remaining remaining -1))
|
||||
(nop!)
|
||||
(l.bu t8 span (+ PROBE-DRAWABLE-CHILD-COUNT PROBE-DRAW-NODE-STRIDE))
|
||||
(nop!)
|
||||
(l.bu gp span (+ PROBE-DRAWABLE-FLAGS PROBE-DRAW-NODE-STRIDE))
|
||||
(add.i stack-top stack-top PROBE-STACK-STRIDE)
|
||||
(s.w t6 stack-top -8)
|
||||
(nop!)
|
||||
(s.h t8 stack-top -4)
|
||||
(nop!)
|
||||
(s.h gp stack-top -2)
|
||||
(label after-node-1)
|
||||
(b.z remaining finish-node-group :delay (nop!))
|
||||
(b.nz ra after-node-2 :delay (add.i remaining remaining -1))
|
||||
(nop!)
|
||||
(l.bu t6 span (+ PROBE-DRAWABLE-CHILD-COUNT (* 2 PROBE-DRAW-NODE-STRIDE)))
|
||||
(nop!)
|
||||
(l.bu t8 span (+ PROBE-DRAWABLE-FLAGS (* 2 PROBE-DRAW-NODE-STRIDE)))
|
||||
(add.i stack-top stack-top PROBE-STACK-STRIDE)
|
||||
(s.w t7 stack-top -8)
|
||||
(nop!)
|
||||
(s.h t6 stack-top -4)
|
||||
(nop!)
|
||||
(s.h t8 stack-top -2)
|
||||
(label after-node-2)
|
||||
(b.z remaining finish-node-group :delay (nop!))
|
||||
(b.nz t9 finish-node-group :delay (add.i remaining remaining -1))
|
||||
(nop!)
|
||||
(l.bu t6 span (+ PROBE-DRAWABLE-CHILD-COUNT (* 3 PROBE-DRAW-NODE-STRIDE)))
|
||||
(nop!)
|
||||
(l.bu t7 span (+ PROBE-DRAWABLE-FLAGS (* 3 PROBE-DRAW-NODE-STRIDE)))
|
||||
(add.i stack-top stack-top PROBE-STACK-STRIDE)
|
||||
(s.w t5 stack-top -8)
|
||||
(nop!)
|
||||
(s.h t6 stack-top -4)
|
||||
(nop!)
|
||||
(s.h t7 stack-top -2)
|
||||
(label finish-node-group)
|
||||
(b.gt remaining r0 cull-four :delay (add.i span span (* 4 PROBE-DRAW-NODE-STRIDE)))
|
||||
(b pop-span :delay (nop!)))
|
||||
;; Kind zero means the span consists of collision-fragment leaves. The shared candidate
|
||||
;; payload is their mesh field; non-instanced results carry #f in the instance slot.
|
||||
(asm-block append-fragment-leaves
|
||||
(label append-fragment-leaves)
|
||||
(b.nz s4 after-fragment-0 :delay (add.i remaining remaining -1))
|
||||
(add.i result-count result-count 1)
|
||||
(s.w t8 result-cursor PROBE-RESULT-MESH)
|
||||
(add.i result-cursor result-cursor PROBE-RESULT-ITEM-STRIDE)
|
||||
(s.w s7 result-cursor (- PROBE-RESULT-INSTANCE PROBE-RESULT-ITEM-STRIDE))
|
||||
(label after-fragment-0)
|
||||
(b.z remaining finish-fragment-group :delay (nop!))
|
||||
(b.nz gp after-fragment-1 :delay (add.i remaining remaining -1))
|
||||
(add.i result-count result-count 1)
|
||||
(s.w t6 result-cursor PROBE-RESULT-MESH)
|
||||
(add.i result-cursor result-cursor PROBE-RESULT-ITEM-STRIDE)
|
||||
(s.w s7 result-cursor (- PROBE-RESULT-INSTANCE PROBE-RESULT-ITEM-STRIDE))
|
||||
(label after-fragment-1)
|
||||
(b.z remaining finish-fragment-group :delay (nop!))
|
||||
(b.nz ra after-fragment-2 :delay (add.i remaining remaining -1))
|
||||
(add.i result-count result-count 1)
|
||||
(s.w t7 result-cursor PROBE-RESULT-MESH)
|
||||
(add.i result-cursor result-cursor PROBE-RESULT-ITEM-STRIDE)
|
||||
(s.w s7 result-cursor (- PROBE-RESULT-INSTANCE PROBE-RESULT-ITEM-STRIDE))
|
||||
(label after-fragment-2)
|
||||
(b.z remaining finish-fragment-group :delay (nop!))
|
||||
(b.nz t9 finish-fragment-group :delay (add.i remaining remaining -1))
|
||||
(add.i result-count result-count 1)
|
||||
(s.w t5 result-cursor PROBE-RESULT-MESH)
|
||||
(add.i result-cursor result-cursor PROBE-RESULT-ITEM-STRIDE)
|
||||
(s.w s7 result-cursor (- PROBE-RESULT-INSTANCE PROBE-RESULT-ITEM-STRIDE))
|
||||
(label finish-fragment-group)
|
||||
(b.gt remaining r0 cull-four :delay (add.i span span (* 4 PROBE-DRAW-NODE-STRIDE)))
|
||||
(b pop-span :delay (nop!)))
|
||||
(asm-block finish
|
||||
(label done)
|
||||
(nop!)
|
||||
(s.w result-count result PROBE-RESULT-COUNT)
|
||||
(m v0 r0)
|
||||
(l.d ra sp)
|
||||
(l.q gp sp 80)
|
||||
(l.q s5 sp 64)
|
||||
(l.q s4 sp 48)
|
||||
(l.q s3 sp 32)
|
||||
(l.q s2 sp 16)
|
||||
(jr ra :delay (add.i sp sp 96))
|
||||
(nop! :count 3)))))
|
||||
|
||||
|
||||
(#unless PC_PORT
|
||||
(defun collide-probe-instance-tie ((drawables object) (drawable-count int) (result collide-list) (draw-node-span? int))
|
||||
"Traverse an instance-TIE tree against the active rotated line-sphere probe. Draw-node spans and
|
||||
direct instance spans share an eight-byte scratchpad stack. Surviving instances contribute
|
||||
their prototype collision fragments after the packed instance transform is composed with the
|
||||
probe transform in VU0. draw-node-span? is one for draw nodes and zero for direct instances.
|
||||
Callers must stay within the stack's 1024 entries and the result's 256 entries."
|
||||
(rlet ((stack-top :reg a0)
|
||||
(instance-batch-count :reg a1)
|
||||
(result :reg a2)
|
||||
(node-batch-count :reg a3)
|
||||
(stack-base :reg v1)
|
||||
(query-min :reg t0 :class i128)
|
||||
(query-max :reg t1 :class i128)
|
||||
(kind :reg t2)
|
||||
(remaining :reg t3)
|
||||
(span :reg t4)
|
||||
(probe-row-x :reg vf1)
|
||||
(probe-row-y :reg vf2)
|
||||
(probe-row-z :reg vf3)
|
||||
(probe-translation :reg vf4)
|
||||
(sphere-0 :reg vf5)
|
||||
(sphere-1 :reg vf6)
|
||||
(sphere-2 :reg vf7)
|
||||
(sphere-3 :reg vf8)
|
||||
(min-0 :reg vf9)
|
||||
(max-0 :reg vf10)
|
||||
(min-1 :reg vf11)
|
||||
(max-1 :reg vf12)
|
||||
(min-2 :reg vf13)
|
||||
(max-2 :reg vf14)
|
||||
(min-3 :reg vf15)
|
||||
(max-3 :reg vf16))
|
||||
;; Seed the work stack with either the root draw-node span or the direct instance span.
|
||||
(rlet ((work :reg t2))
|
||||
(asm-block save-state-and-seed-stack
|
||||
(label entry)
|
||||
(add.i sp sp -80)
|
||||
(s.d ra sp)
|
||||
(s.q s3 sp 16)
|
||||
(s.q s4 sp 32)
|
||||
(s.q s5 sp 48)
|
||||
(s.q gp sp 64)
|
||||
(m! work *collide-work*)
|
||||
(m! stack-base *collide-probe-stack*)
|
||||
(s.w drawables stack-base PROBE-STACK-CHILD)
|
||||
(add.i stack-top stack-base PROBE-STACK-STRIDE)
|
||||
(s.h drawable-count stack-base PROBE-STACK-COUNT)
|
||||
(s.h draw-node-span? stack-base PROBE-STACK-KIND)
|
||||
(add.i instance-batch-count r0 0)
|
||||
(add.i node-batch-count r0 0)
|
||||
(l.q query-min work PROBE-QUERY-MIN)
|
||||
(l.q query-max work PROBE-QUERY-MAX)
|
||||
(l.vf probe-row-x work PROBE-QUERY-ROW-X)
|
||||
(l.vf probe-row-y work PROBE-QUERY-ROW-Y)
|
||||
(l.vf probe-row-z work PROBE-QUERY-ROW-Z)
|
||||
(l.vf probe-translation work PROBE-QUERY-TRANSLATION)))
|
||||
;; Negative work kinds are individual instances. Zero denotes a direct instance span, and a
|
||||
;; positive kind denotes a draw-node span.
|
||||
(asm-block pop-work
|
||||
(label pop-work)
|
||||
(b.eq stack-top stack-base done :delay (nop!))
|
||||
(add.i stack-top stack-top (- PROBE-STACK-STRIDE))
|
||||
(l.w span stack-top PROBE-STACK-CHILD)
|
||||
(l.h kind stack-top PROBE-STACK-KIND)
|
||||
(l.hu remaining stack-top PROBE-STACK-COUNT)
|
||||
(b.lt kind r0 process-instance :delay (nop!)))
|
||||
;; Both span kinds expose a bounding sphere at the same offset. Draw nodes are 32 bytes while
|
||||
;; instances are 64, so the paths use different strides. Their separate batch counters are
|
||||
;; retained here but are not consumed below.
|
||||
(asm-block load-broadphase-four
|
||||
(label load-broadphase-four)
|
||||
(b.z kind load-instance-four :delay (nop!))
|
||||
(l.vf sphere-0 span PROBE-DRAWABLE-BSPHERE)
|
||||
(add.i node-batch-count node-batch-count 1)
|
||||
(l.vf sphere-1 span (+ PROBE-DRAWABLE-BSPHERE PROBE-DRAW-NODE-STRIDE))
|
||||
(add.i t5 remaining -4)
|
||||
(l.vf sphere-2 span (+ PROBE-DRAWABLE-BSPHERE (* 2 PROBE-DRAW-NODE-STRIDE)))
|
||||
(b.lt t5 r0 node-prefetched :delay (l.vf sphere-3 span (+ PROBE-DRAWABLE-BSPHERE (* 3 PROBE-DRAW-NODE-STRIDE))))
|
||||
(pref span (+ PROBE-DRAWABLE-BSPHERE (* 4 PROBE-DRAW-NODE-STRIDE)) :hint 0)
|
||||
(label node-prefetched)
|
||||
(b reduce-broadphase-four :delay (nop!))
|
||||
(label load-instance-four)
|
||||
(l.vf sphere-0 span PROBE-INSTANCE-BSPHERE)
|
||||
(add.i instance-batch-count instance-batch-count 1)
|
||||
(l.vf sphere-1 span (+ PROBE-INSTANCE-BSPHERE PROBE-INSTANCE-STRIDE))
|
||||
(add.i t5 remaining -4)
|
||||
(l.vf sphere-2 span (+ PROBE-INSTANCE-BSPHERE (* 2 PROBE-INSTANCE-STRIDE)))
|
||||
(b.lt t5 r0 reduce-broadphase-four :delay (l.vf sphere-3 span (+ PROBE-INSTANCE-BSPHERE (* 3 PROBE-INSTANCE-STRIDE))))
|
||||
(pref span (+ PROBE-INSTANCE-BSPHERE (* 4 PROBE-INSTANCE-STRIDE)) :hint 0)
|
||||
(pref span (+ PROBE-INSTANCE-BSPHERE (* 6 PROBE-INSTANCE-STRIDE)) :hint 0))
|
||||
;; VU0 transforms four spheres to query-box space. The EE combines the two separating-axis
|
||||
;; comparisons, packs their XYZ results, and leaves one reject bit in each scalar.
|
||||
(asm-block reduce-broadphase-four
|
||||
(label reduce-broadphase-four)
|
||||
(callms 0)
|
||||
(m s5 min-0)
|
||||
(m t7 max-0)
|
||||
(m gp min-1)
|
||||
(m ra max-1)
|
||||
(m t9 min-2)
|
||||
(m t8 max-2)
|
||||
(m t6 min-3)
|
||||
(m t5 max-3)
|
||||
(nop!)
|
||||
(pcgt.w s5 s5 query-max)
|
||||
(mmi-nop!)
|
||||
(pcgt.w t7 query-min t7)
|
||||
(mmi-nop!)
|
||||
(or.q t7 s5 t7)
|
||||
(mmi-nop!)
|
||||
(ppach t7 r0 t7)
|
||||
(mmi-nop!)
|
||||
(pcgt.w gp gp query-max)
|
||||
(mmi-nop!)
|
||||
(pcgt.w ra query-min ra)
|
||||
(mmi-nop!)
|
||||
(or.q ra gp ra)
|
||||
(mmi-nop!)
|
||||
(ppach ra r0 ra)
|
||||
(mmi-nop!)
|
||||
(pcgt.w t9 t9 query-max)
|
||||
(mmi-nop!)
|
||||
(pcgt.w t8 query-min t8)
|
||||
(mmi-nop!)
|
||||
(or.q t8 t9 t8)
|
||||
(mmi-nop!)
|
||||
(ppach t8 r0 t8)
|
||||
(mmi-nop!)
|
||||
(pcgt.w t6 t6 query-max)
|
||||
(mmi-nop!)
|
||||
(pcgt.w t5 query-min t5)
|
||||
(mmi-nop!)
|
||||
(or.q t5 t6 t5)
|
||||
(mmi-nop!)
|
||||
(ppach t5 r0 t5)
|
||||
(mmi-nop!)
|
||||
(sll t9 t7 16)
|
||||
(sll t7 ra 16)
|
||||
(sll t6 t8 16)
|
||||
(sll t5 t5 16))
|
||||
;; For a draw-node span, push each overlapping child span. The flags byte becomes the next
|
||||
;; work kind, so children-are-draw-nodes naturally selects the next interpretation.
|
||||
(asm-block queue-node-children
|
||||
(b.z kind queue-instance-hits :delay (nop!))
|
||||
(b.nz t9 after-node-0 :delay (add.i remaining remaining -1))
|
||||
(nop!)
|
||||
(l.w t8 span PROBE-DRAWABLE-CHILD)
|
||||
(nop!)
|
||||
(l.bu t9 span PROBE-DRAWABLE-CHILD-COUNT)
|
||||
(nop!)
|
||||
(l.bu ra span PROBE-DRAWABLE-FLAGS)
|
||||
(add.i stack-top stack-top PROBE-STACK-STRIDE)
|
||||
(s.w t8 stack-top (- PROBE-STACK-STRIDE))
|
||||
(nop!)
|
||||
(s.h t9 stack-top (- PROBE-STACK-COUNT PROBE-STACK-STRIDE))
|
||||
(nop!)
|
||||
(s.h ra stack-top (- PROBE-STACK-KIND PROBE-STACK-STRIDE))
|
||||
(label after-node-0)
|
||||
(b.z remaining finish-node-group :delay (nop!))
|
||||
(b.nz t7 after-node-1 :delay (add.i remaining remaining -1))
|
||||
(nop!)
|
||||
(l.w t7 span (+ PROBE-DRAWABLE-CHILD PROBE-DRAW-NODE-STRIDE))
|
||||
(nop!)
|
||||
(l.bu t8 span (+ PROBE-DRAWABLE-CHILD-COUNT PROBE-DRAW-NODE-STRIDE))
|
||||
(nop!)
|
||||
(l.bu t9 span (+ PROBE-DRAWABLE-FLAGS PROBE-DRAW-NODE-STRIDE))
|
||||
(add.i stack-top stack-top PROBE-STACK-STRIDE)
|
||||
(s.w t7 stack-top (- PROBE-STACK-STRIDE))
|
||||
(nop!)
|
||||
(s.h t8 stack-top (- PROBE-STACK-COUNT PROBE-STACK-STRIDE))
|
||||
(nop!)
|
||||
(s.h t9 stack-top (- PROBE-STACK-KIND PROBE-STACK-STRIDE))
|
||||
(label after-node-1)
|
||||
(b.z remaining finish-node-group :delay (nop!))
|
||||
(b.nz t6 after-node-2 :delay (add.i remaining remaining -1))
|
||||
(nop!)
|
||||
(l.w t6 span (+ PROBE-DRAWABLE-CHILD (* 2 PROBE-DRAW-NODE-STRIDE)))
|
||||
(nop!)
|
||||
(l.bu t7 span (+ PROBE-DRAWABLE-CHILD-COUNT (* 2 PROBE-DRAW-NODE-STRIDE)))
|
||||
(nop!)
|
||||
(l.bu t8 span (+ PROBE-DRAWABLE-FLAGS (* 2 PROBE-DRAW-NODE-STRIDE)))
|
||||
(add.i stack-top stack-top PROBE-STACK-STRIDE)
|
||||
(s.w t6 stack-top (- PROBE-STACK-STRIDE))
|
||||
(nop!)
|
||||
(s.h t7 stack-top (- PROBE-STACK-COUNT PROBE-STACK-STRIDE))
|
||||
(nop!)
|
||||
(s.h t8 stack-top (- PROBE-STACK-KIND PROBE-STACK-STRIDE))
|
||||
(label after-node-2)
|
||||
(b.z remaining finish-node-group :delay (nop!))
|
||||
(b.nz t5 finish-node-group :delay (add.i remaining remaining -1))
|
||||
(nop!)
|
||||
(l.w t5 span (+ PROBE-DRAWABLE-CHILD (* 3 PROBE-DRAW-NODE-STRIDE)))
|
||||
(nop!)
|
||||
(l.bu t6 span (+ PROBE-DRAWABLE-CHILD-COUNT (* 3 PROBE-DRAW-NODE-STRIDE)))
|
||||
(nop!)
|
||||
(l.bu t7 span (+ PROBE-DRAWABLE-FLAGS (* 3 PROBE-DRAW-NODE-STRIDE)))
|
||||
(add.i stack-top stack-top PROBE-STACK-STRIDE)
|
||||
(s.w t5 stack-top (- PROBE-STACK-STRIDE))
|
||||
(nop!)
|
||||
(s.h t6 stack-top (- PROBE-STACK-COUNT PROBE-STACK-STRIDE))
|
||||
(nop!)
|
||||
(s.h t7 stack-top (- PROBE-STACK-KIND PROBE-STACK-STRIDE))
|
||||
(label finish-node-group)
|
||||
(b.gt remaining r0 load-broadphase-four :delay (add.i span span (* 4 PROBE-DRAW-NODE-STRIDE)))
|
||||
(b pop-work :delay (nop!)))
|
||||
;; A direct span cannot be processed until its prototype data is known. Queue each surviving
|
||||
;; instance as a negative-kind single item, preserving the same LIFO traversal order.
|
||||
(asm-block queue-instance-hits
|
||||
(label queue-instance-hits)
|
||||
(b.nz t9 after-instance-0 :delay (add.i remaining remaining -1))
|
||||
(add.i stack-top stack-top PROBE-STACK-STRIDE)
|
||||
(s.w span stack-top (- PROBE-STACK-STRIDE))
|
||||
(add.i t8 r0 -1)
|
||||
(s.h r0 stack-top (- PROBE-STACK-COUNT PROBE-STACK-STRIDE))
|
||||
(nop!)
|
||||
(s.h t8 stack-top (- PROBE-STACK-KIND PROBE-STACK-STRIDE))
|
||||
(label after-instance-0)
|
||||
(b.z remaining finish-instance-group :delay (add.i span span PROBE-INSTANCE-STRIDE))
|
||||
(b.nz t7 after-instance-1 :delay (add.i remaining remaining -1))
|
||||
(add.i stack-top stack-top PROBE-STACK-STRIDE)
|
||||
(s.w span stack-top (- PROBE-STACK-STRIDE))
|
||||
(add.i t7 r0 -1)
|
||||
(s.h r0 stack-top (- PROBE-STACK-COUNT PROBE-STACK-STRIDE))
|
||||
(nop!)
|
||||
(s.h t7 stack-top (- PROBE-STACK-KIND PROBE-STACK-STRIDE))
|
||||
(label after-instance-1)
|
||||
(b.z remaining finish-instance-group :delay (add.i span span PROBE-INSTANCE-STRIDE))
|
||||
(b.nz t6 after-instance-2 :delay (add.i remaining remaining -1))
|
||||
(add.i stack-top stack-top PROBE-STACK-STRIDE)
|
||||
(s.w span stack-top (- PROBE-STACK-STRIDE))
|
||||
(add.i t6 r0 -1)
|
||||
(s.h r0 stack-top (- PROBE-STACK-COUNT PROBE-STACK-STRIDE))
|
||||
(nop!)
|
||||
(s.h t6 stack-top (- PROBE-STACK-KIND PROBE-STACK-STRIDE))
|
||||
(label after-instance-2)
|
||||
(b.z remaining finish-instance-group :delay (add.i span span PROBE-INSTANCE-STRIDE))
|
||||
(b.nz t5 finish-instance-group :delay (add.i remaining remaining -1))
|
||||
(add.i stack-top stack-top PROBE-STACK-STRIDE)
|
||||
(s.w span stack-top (- PROBE-STACK-STRIDE))
|
||||
(add.i t5 r0 -1)
|
||||
(s.h r0 stack-top (- PROBE-STACK-COUNT PROBE-STACK-STRIDE))
|
||||
(nop!)
|
||||
(s.h t5 stack-top (- PROBE-STACK-KIND PROBE-STACK-STRIDE))
|
||||
(label finish-instance-group)
|
||||
(b.gt remaining r0 load-broadphase-four :delay (add.i span span PROBE-INSTANCE-STRIDE))
|
||||
(b pop-work :delay (nop!)))
|
||||
(rlet ((instance :reg t2)
|
||||
(instance-row-x :reg vf17)
|
||||
(instance-row-y :reg vf18)
|
||||
(instance-row-z :reg vf19)
|
||||
(instance-translation :reg vf20)
|
||||
(instance-max-scale :reg vf21)
|
||||
(scaled-radii :reg vf22)
|
||||
(instance-origin :reg vf23))
|
||||
;; TIE stores its affine transform as signed halfwords. Translation is split across the two
|
||||
;; matrix halves and encoded in 64-unit steps; basis rows use signed Q12 fixed point and
|
||||
;; max-scale is unsigned Q12. VU entry 32 converts and composes this with the probe inverse.
|
||||
(asm-block decode-instance-transform
|
||||
(label process-instance)
|
||||
(rlet ((queued-instance :reg t4))
|
||||
(m instance queued-instance)
|
||||
(rlet ((instance-flags :reg t4)
|
||||
(bucket :reg t3)
|
||||
(fragment-array :reg t6))
|
||||
(l.hu instance-flags queued-instance PROBE-INSTANCE-FLAGS)
|
||||
(nop!)
|
||||
(l.w bucket instance PROBE-INSTANCE-BUCKET)
|
||||
;; The branch tests flags before its delay load replaces the same register.
|
||||
(b.nz instance-flags finish-instance :delay (l.hu t4 instance PROBE-INSTANCE-MAX-SCALE))
|
||||
(nop!)
|
||||
(l.w fragment-array bucket PROBE-BUCKET-COLLIDE-FRAG)
|
||||
(nop!)))
|
||||
(rlet ((max-scale-bits :reg t4 :class i128)
|
||||
(origin-high-bits :reg t3 :class i128)
|
||||
(origin-low-bits :reg t5 :class i128)
|
||||
(fragment-array :reg t6))
|
||||
(l.q origin-high-bits instance PROBE-INSTANCE-ORIGIN-HIGH)
|
||||
(b.z fragment-array finish-instance :delay (l.q origin-low-bits instance PROBE-INSTANCE-ORIGIN-LOW))
|
||||
(pextlw max-scale-bits max-scale-bits max-scale-bits)
|
||||
(mmi-nop!)
|
||||
(pcpyld max-scale-bits max-scale-bits max-scale-bits)
|
||||
(mmi-nop!)
|
||||
(pcpyud t8 origin-high-bits r0)
|
||||
(mmi-nop!)
|
||||
(pcpyud t7 origin-low-bits r0)
|
||||
(mmi-nop!)
|
||||
(pextlh t8 t8 r0)
|
||||
(mmi-nop!)
|
||||
(sra.w t8 t8 10)
|
||||
(mmi-nop!)
|
||||
(pextlh t9 origin-low-bits r0))
|
||||
(rlet ((max-scale-bits :reg t4 :class i128)
|
||||
(origin-high-bits :reg t3 :class i128)
|
||||
(fragment-count :reg t5)
|
||||
(fragment-array :reg t6))
|
||||
(l.hu fragment-count fragment-array PROBE-FRAGMENT-ARRAY-LENGTH)
|
||||
(sra.w t9 t9 16)
|
||||
(mmi-nop!)
|
||||
(pextlh t7 t7 r0)
|
||||
(m instance-translation t8)
|
||||
(sra.w t7 t7 16)
|
||||
(m instance-row-x t9)
|
||||
(pextlh origin-high-bits origin-high-bits r0)
|
||||
(m instance-row-y t7)
|
||||
(sra.w origin-high-bits origin-high-bits 16)
|
||||
(l.vf instance-origin instance PROBE-INSTANCE-BSPHERE)
|
||||
(m instance-row-z origin-high-bits)
|
||||
(rlet ((result-count :reg t3))
|
||||
(l.w result-count result PROBE-RESULT-COUNT))
|
||||
(m instance-max-scale max-scale-bits)
|
||||
(add.i t7 fragment-count -4)
|
||||
(callms 32)))
|
||||
(rlet ((result-count :reg t3)
|
||||
(result-cursor :reg t4)
|
||||
(fragment-count :reg t5)
|
||||
(fragment-cursor :reg t6))
|
||||
(asm-block prepare-fragment-cursor
|
||||
(sll result-cursor result-count 4)
|
||||
(add result-cursor result-cursor result)
|
||||
(add fragment-count fragment-count r0)
|
||||
(add.i result-cursor result-cursor PROBE-RESULT-ITEMS)
|
||||
(add.i fragment-cursor fragment-cursor PROBE-FRAGMENT-ARRAY-DATA)
|
||||
(b.lt t7 r0 cull-fragment-tail :delay (l.q t7 fragment-cursor PROBE-DRAWABLE-BSPHERE))
|
||||
(nop!)
|
||||
(l.q t8 fragment-cursor (+ PROBE-DRAWABLE-BSPHERE PROBE-FRAGMENT-STRIDE))
|
||||
(nop!)
|
||||
(l.q t9 fragment-cursor (+ PROBE-DRAWABLE-BSPHERE (* 2 PROBE-FRAGMENT-STRIDE)))
|
||||
(nop!)
|
||||
(l.q ra fragment-cursor (+ PROBE-DRAWABLE-BSPHERE (* 3 PROBE-FRAGMENT-STRIDE)))
|
||||
(nop!)
|
||||
(m.ni sphere-0 t7)
|
||||
(nop!)
|
||||
(m.ni sphere-1 t8)
|
||||
(nop!)
|
||||
(m.ni sphere-2 t9)
|
||||
(nop!)
|
||||
(m.ni sphere-3 ra))
|
||||
;; Entry 54 transforms four prototype spheres by the composed instance transform and scales
|
||||
;; their radii conservatively. The EE then performs the same packed XYZ rejection as above.
|
||||
(asm-block cull-four-fragments
|
||||
(label cull-four-fragments)
|
||||
;; Entry 54 raises E before its final drain instruction; wait for completion
|
||||
;; before transferring the eight integer bounds back to the EE.
|
||||
(callms 54)
|
||||
(nop! :count 3)
|
||||
(vnop)
|
||||
(nop!)
|
||||
(m s3 max-0)
|
||||
(nop!)
|
||||
(m t9 min-0)
|
||||
(nop!)
|
||||
(m s4 max-1)
|
||||
(nop!)
|
||||
(m s5 min-1)
|
||||
(nop!)
|
||||
(m gp max-2)
|
||||
(nop!)
|
||||
(m ra min-2)
|
||||
(nop!)
|
||||
(m t8 max-3)
|
||||
(nop!)
|
||||
(m t7 min-3)
|
||||
(nop!)
|
||||
(pcgt.w s3 query-min s3)
|
||||
(mmi-nop!)
|
||||
(pcgt.w t9 t9 query-max)
|
||||
(mmi-nop!)
|
||||
(or.q t9 t9 s3)
|
||||
(mmi-nop!)
|
||||
(ppach t9 r0 t9)
|
||||
(mmi-nop!)
|
||||
(pcgt.w s4 query-min s4)
|
||||
(mmi-nop!)
|
||||
(pcgt.w s5 s5 query-max)
|
||||
(mmi-nop!)
|
||||
(or.q s5 s5 s4)
|
||||
(mmi-nop!)
|
||||
(ppach s5 r0 s5)
|
||||
(mmi-nop!)
|
||||
(pcgt.w gp query-min gp)
|
||||
(mmi-nop!)
|
||||
(pcgt.w ra ra query-max)
|
||||
(mmi-nop!)
|
||||
(or.q ra ra gp)
|
||||
(mmi-nop!)
|
||||
(ppach ra r0 ra)
|
||||
(mmi-nop!)
|
||||
(pcgt.w t8 query-min t8)
|
||||
(mmi-nop!)
|
||||
(pcgt.w t7 t7 query-max)
|
||||
(mmi-nop!)
|
||||
(or.q t7 t7 t8)
|
||||
(mmi-nop!)
|
||||
(ppach t7 r0 t7)
|
||||
(mmi-nop!)
|
||||
(sll gp t9 16)
|
||||
(sll t9 s5 16)
|
||||
(sll t8 ra 16)
|
||||
(sll t7 t7 16))
|
||||
;; Append the mesh pointer and originating instance for each surviving fragment. The result
|
||||
;; cursor follows the list's physical sixteen-byte inline spacing.
|
||||
(asm-block append-four-fragments
|
||||
(b.nz gp after-fragment-0 :delay (nop!))
|
||||
(nop!)
|
||||
(l.w ra fragment-cursor PROBE-FRAGMENT-MESH)
|
||||
(add.i result-count result-count 1)
|
||||
(s.w instance result-cursor PROBE-RESULT-INSTANCE)
|
||||
(add.i result-cursor result-cursor PROBE-RESULT-ITEM-STRIDE)
|
||||
(s.w ra result-cursor (- PROBE-RESULT-MESH PROBE-RESULT-ITEM-STRIDE))
|
||||
(label after-fragment-0)
|
||||
(add.i fragment-count fragment-count -1)
|
||||
(add.i fragment-cursor fragment-cursor PROBE-FRAGMENT-STRIDE)
|
||||
(b.z fragment-count finish-fragment-group :delay (nop!))
|
||||
(b.nz t9 after-fragment-1 :delay (nop!))
|
||||
(nop!)
|
||||
(l.w t9 fragment-cursor PROBE-FRAGMENT-MESH)
|
||||
(add.i result-count result-count 1)
|
||||
(s.w instance result-cursor PROBE-RESULT-INSTANCE)
|
||||
(add.i result-cursor result-cursor PROBE-RESULT-ITEM-STRIDE)
|
||||
(s.w t9 result-cursor (- PROBE-RESULT-MESH PROBE-RESULT-ITEM-STRIDE))
|
||||
(label after-fragment-1)
|
||||
(add.i fragment-count fragment-count -1)
|
||||
(add.i fragment-cursor fragment-cursor PROBE-FRAGMENT-STRIDE)
|
||||
(b.z fragment-count finish-fragment-group :delay (nop!))
|
||||
(b.nz t8 after-fragment-2 :delay (nop!))
|
||||
(nop!)
|
||||
(l.w t8 fragment-cursor PROBE-FRAGMENT-MESH)
|
||||
(add.i result-count result-count 1)
|
||||
(s.w instance result-cursor PROBE-RESULT-INSTANCE)
|
||||
(add.i result-cursor result-cursor PROBE-RESULT-ITEM-STRIDE)
|
||||
(s.w t8 result-cursor (- PROBE-RESULT-MESH PROBE-RESULT-ITEM-STRIDE))
|
||||
(label after-fragment-2)
|
||||
(add.i fragment-count fragment-count -1)
|
||||
(add.i fragment-cursor fragment-cursor PROBE-FRAGMENT-STRIDE)
|
||||
(b.z fragment-count finish-fragment-group :delay (nop!))
|
||||
(b.nz t7 after-fragment-3 :delay (nop!))
|
||||
(nop!)
|
||||
(l.w t7 fragment-cursor PROBE-FRAGMENT-MESH)
|
||||
(add.i result-count result-count 1)
|
||||
(s.w instance result-cursor PROBE-RESULT-INSTANCE)
|
||||
(add.i result-cursor result-cursor PROBE-RESULT-ITEM-STRIDE)
|
||||
(s.w t7 result-cursor (- PROBE-RESULT-MESH PROBE-RESULT-ITEM-STRIDE))
|
||||
(label after-fragment-3)
|
||||
(add.i fragment-count fragment-count -1)
|
||||
(add.i fragment-cursor fragment-cursor PROBE-FRAGMENT-STRIDE)
|
||||
(b.z fragment-count finish-fragment-group :delay (l.vf sphere-0 fragment-cursor PROBE-DRAWABLE-BSPHERE))
|
||||
(nop!)
|
||||
(l.vf sphere-1 fragment-cursor (+ PROBE-DRAWABLE-BSPHERE PROBE-FRAGMENT-STRIDE))
|
||||
(nop!)
|
||||
(l.vf sphere-2 fragment-cursor (+ PROBE-DRAWABLE-BSPHERE (* 2 PROBE-FRAGMENT-STRIDE)))
|
||||
(b cull-four-fragments :delay (l.vf sphere-3 fragment-cursor (+ PROBE-DRAWABLE-BSPHERE (* 3 PROBE-FRAGMENT-STRIDE)))))
|
||||
(asm-block finish-fragment-group
|
||||
(label finish-fragment-group)
|
||||
(nop!)
|
||||
(s.w result-count result PROBE-RESULT-COUNT)
|
||||
(b pop-work :delay (nop!)))
|
||||
;; Fewer than four remaining fragments use the same composed transform inline. The sphere's
|
||||
;; center is transformed, its radius is multiplied by max-scale, and its integer bounds are
|
||||
;; rejected before the mesh is appended.
|
||||
(asm-block cull-fragment-tail
|
||||
(label cull-fragment-tail)
|
||||
(rlet ((tail-center :reg vf24)
|
||||
(tail-max :reg vf25))
|
||||
(m sphere-0 t7)
|
||||
(nop!)
|
||||
(mula.w.vf instance-translation vf0)
|
||||
(nop!)
|
||||
(madda.x.vf instance-row-x sphere-0)
|
||||
(nop!)
|
||||
(madda.y.vf instance-row-y sphere-0)
|
||||
(nop!)
|
||||
(madd.z.vf tail-center instance-row-z sphere-0)
|
||||
(nop!)
|
||||
(mul.w.vf.x scaled-radii instance-max-scale sphere-0)
|
||||
(nop!)
|
||||
(add.x.vf.xyz tail-max tail-center scaled-radii)
|
||||
(nop!)
|
||||
(rlet ((tail-min :reg vf24))
|
||||
(sub.x.vf.xyz tail-min tail-center scaled-radii)
|
||||
(nop!)
|
||||
(ftoi.vf tail-max tail-max)
|
||||
(nop!)
|
||||
(ftoi.vf tail-min tail-min)
|
||||
(nop!)
|
||||
(m t8 tail-max)
|
||||
(nop!)
|
||||
(m t7 tail-min)
|
||||
(nop!)
|
||||
(pcgt.w t8 query-min t8)
|
||||
(mmi-nop!)
|
||||
(pcgt.w t7 t7 query-max)
|
||||
(mmi-nop!)
|
||||
(or.q t7 t7 t8)
|
||||
(mmi-nop!)
|
||||
(ppach t7 r0 t7)
|
||||
(mmi-nop!)
|
||||
(sll t7 t7 16)
|
||||
(nop!)
|
||||
(b.nz t7 after-tail-fragment :delay (nop!))
|
||||
(nop!)
|
||||
(l.w t7 fragment-cursor PROBE-FRAGMENT-MESH)
|
||||
(add.i result-count result-count 1)
|
||||
(s.w instance result-cursor PROBE-RESULT-INSTANCE)
|
||||
(add.i result-cursor result-cursor PROBE-RESULT-ITEM-STRIDE)
|
||||
(s.w t7 result-cursor (- PROBE-RESULT-MESH PROBE-RESULT-ITEM-STRIDE))
|
||||
(label after-tail-fragment)
|
||||
(add.i fragment-count fragment-count -1)
|
||||
(add.i fragment-cursor fragment-cursor PROBE-FRAGMENT-STRIDE)
|
||||
(b.gt fragment-count r0 cull-fragment-tail :delay (l.q t7 fragment-cursor PROBE-DRAWABLE-BSPHERE))
|
||||
(nop!)
|
||||
(s.w result-count result PROBE-RESULT-COUNT))))
|
||||
(asm-block finish-instance (label finish-instance) (b pop-work :delay (nop!)))))
|
||||
(asm-block restore-state
|
||||
(label done)
|
||||
(m v0 r0)
|
||||
(l.d ra sp)
|
||||
(l.q gp sp 64)
|
||||
(l.q s5 sp 48)
|
||||
(l.q s4 sp 32)
|
||||
(l.q s3 sp 16)
|
||||
(jr ra :delay (add.i sp sp 80))
|
||||
(nop! :count 2)))))
|
||||
File diff suppressed because it is too large
Load Diff
@@ -12,31 +12,22 @@
|
||||
|
||||
(defun make-light-kit ((group light-group) (heading float) (dir0-level float) (dir1-level float) (dir2-level float))
|
||||
"Build a three-directional-light kit. dir0 and dir1 are opposing warm diagonal lights rotated
|
||||
around Y by heading in 65,536-units-per-turn rotation units; dir2 points straight down. The
|
||||
around Y by heading in rotation units; dir2 points straight down. The
|
||||
three level arguments set their respective light strengths."
|
||||
(let ((rotation (new 'stack-no-clear 'matrix)))
|
||||
(matrix-rotate-y! rotation heading)
|
||||
(let ((dir0 (-> group dir0)))
|
||||
(set! (-> dir0 direction x) -0.612)
|
||||
(set! (-> dir0 direction y) 0.5)
|
||||
(set! (-> dir0 direction z) 0.612)
|
||||
(set! (-> dir0 direction w) 0.0))
|
||||
(set-vector! (-> dir0 direction) -0.612 0.5 0.612 0.0))
|
||||
(set-vector! (-> group dir0 color) 0.8 0.775 0.7 1.0)
|
||||
(set! (-> group dir0 levels x) dir0-level)
|
||||
(let ((dir1 (-> group dir1)))
|
||||
(set! (-> dir1 direction x) 0.612)
|
||||
(set! (-> dir1 direction y) 0.5)
|
||||
(set! (-> dir1 direction z) -0.612)
|
||||
(set! (-> dir1 direction w) 0.0))
|
||||
(set-vector! (-> dir1 direction) 0.612 0.5 -0.612 0.0))
|
||||
(set-vector! (-> group dir1 color) 0.8 0.775 0.7 1.0)
|
||||
(set! (-> group dir1 levels x) dir1-level)
|
||||
(vector-matrix*! (-> group dir0 direction) (-> group dir0 direction) rotation)
|
||||
(vector-matrix*! (-> group dir1 direction) (-> group dir1 direction) rotation))
|
||||
(let ((dir2 (-> group dir2)))
|
||||
(set! (-> dir2 direction x) 0.0)
|
||||
(set! (-> dir2 direction y) -1.0)
|
||||
(set! (-> dir2 direction z) 0.0)
|
||||
(set! (-> dir2 direction w) 0.0))
|
||||
(set-vector! (-> dir2 direction) 0.0 -1.0 0.0 0.0))
|
||||
(set-vector! (-> group dir2 color) 0.8 0.775 0.7 1.0)
|
||||
(set! (-> group dir2 levels x) dir2-level)
|
||||
(none))
|
||||
@@ -47,10 +38,7 @@
|
||||
(let ((group (-> context light-group 2)))
|
||||
(make-light-kit group 2730.6667 1.0 1.0 0.8)
|
||||
(let ((dir2 (-> group dir2)))
|
||||
(set! (-> dir2 direction x) 0.0)
|
||||
(set! (-> dir2 direction y) -1.0)
|
||||
(set! (-> dir2 direction z) 0.0)
|
||||
(set! (-> dir2 direction w) 0.0))
|
||||
(set-vector! (-> dir2 direction) 0.0 -1.0 0.0 0.0))
|
||||
(set-vector! (-> group dir2 color) 0.75 0.375 0.0 1.0))
|
||||
(make-light-kit (-> context light-group 3) 53703.11 0.9 0.9 0.5)
|
||||
(make-light-kit (-> context light-group 4) 54613.332 0.9 0.9 0.4)
|
||||
@@ -71,39 +59,24 @@
|
||||
"Initialize Village 2 light groups 1 through 6 with the authored directional colors and levels."
|
||||
(let ((group (-> context light-group 1)))
|
||||
(let ((directional (-> group dir0)))
|
||||
(set! (-> directional direction x) 0.0)
|
||||
(set! (-> directional direction y) 1.0)
|
||||
(set! (-> directional direction z) 0.0)
|
||||
(set! (-> directional direction w) 1.0))
|
||||
(set-vector! (-> directional direction) 0.0 1.0 0.0 1.0))
|
||||
(set-vector! (-> group dir0 color) 0.375 0.25 0.25 1.0)
|
||||
(set! (-> group dir0 levels x) 1.0)
|
||||
(let ((directional (-> group dir1)))
|
||||
(set! (-> directional direction x) -0.6119)
|
||||
(set! (-> directional direction y) 0.5)
|
||||
(set! (-> directional direction z) -0.6119)
|
||||
(set! (-> directional direction w) 1.0))
|
||||
(set-vector! (-> directional direction) -0.6119 0.5 -0.6119 1.0))
|
||||
(set-vector! (-> group dir1 color) 0.25 0.75 1.0 1.0)
|
||||
(set! (-> group dir1 levels x) 0.666)
|
||||
(let ((directional (-> group dir2)))
|
||||
(set! (-> directional direction x) 0.9961)
|
||||
(set! (-> directional direction y) 0.0)
|
||||
(set! (-> directional direction z) -0.0871)
|
||||
(set! (-> directional direction w) 1.0))
|
||||
(set-vector! (-> directional direction) 0.9961 0.0 -0.0871 1.0))
|
||||
(set-vector! (-> group dir2 color) 0.0 0.25 1.0 1.0)
|
||||
(set! (-> group dir2 levels x) 1.0))
|
||||
(let ((group (-> context light-group 2)))
|
||||
(let ((directional (-> group dir0)))
|
||||
(set! (-> directional direction x) 0.2239)
|
||||
(set! (-> directional direction y) 0.5)
|
||||
(set! (-> directional direction z) 0.836)
|
||||
(set! (-> directional direction w) 1.0))
|
||||
(set-vector! (-> directional direction) 0.2239 0.5 0.836 1.0))
|
||||
(set-vector! (-> group dir0 color) 0.8 0.8 0.8 1.0)
|
||||
(set! (-> group dir0 levels x) 0.7)
|
||||
(let ((directional (-> group dir1)))
|
||||
(set! (-> directional direction x) -0.2959)
|
||||
(set! (-> directional direction y) 0.5)
|
||||
(set! (-> directional direction z) -0.8133)
|
||||
(set! (-> directional direction w) 1.0))
|
||||
(set-vector! (-> directional direction) -0.2959 0.5 -0.8133 1.0))
|
||||
(set-vector! (-> group dir1 color) 0.8 0.8 0.8 1.0)
|
||||
(set! (-> group dir1 levels x) 0.7))
|
||||
(let ((group (-> context light-group 3)))
|
||||
@@ -114,10 +87,7 @@
|
||||
(set-vector! (-> group dir0 color) 0.675 0.45 0.15 1.0))
|
||||
(let ((group (-> context light-group 5)))
|
||||
(let ((directional (-> group dir0)))
|
||||
(set! (-> directional direction x) 0.2425)
|
||||
(set! (-> directional direction y) -0.9701)
|
||||
(set! (-> directional direction z) 0.0)
|
||||
(set! (-> directional direction w) 0.0))
|
||||
(set-vector! (-> directional direction) 0.2425 -0.9701 0.0 0.0))
|
||||
(set-vector! (-> group dir0 color) 2.0 1.0 0.0 1.0)
|
||||
(set! (-> group dir1 levels x) 0.0)
|
||||
(set! (-> group dir2 levels x) 0.0))
|
||||
@@ -133,82 +103,53 @@
|
||||
(let ((group (-> context light-group 1)))
|
||||
(make-light-kit group 0.0 1.0 0.0 0.0)
|
||||
(let ((directional (-> group dir0)))
|
||||
(set! (-> directional direction x) 0.0)
|
||||
(set! (-> directional direction y) 1.0)
|
||||
(set! (-> directional direction z) 0.0)
|
||||
(set! (-> directional direction w) 1.0))
|
||||
(set-vector! (-> directional direction) 0.0 1.0 0.0 1.0))
|
||||
(set-vector! (-> group dir0 color) 1.0 0.9 0.0 1.0))
|
||||
(let ((group (-> context light-group 2)))
|
||||
(make-light-kit group 0.0 1.0 0.0 0.0)
|
||||
(let ((directional (-> group dir0)))
|
||||
(set! (-> directional direction x) 0.0)
|
||||
(set! (-> directional direction y) 1.0)
|
||||
(set! (-> directional direction z) 0.0)
|
||||
(set! (-> directional direction w) 1.0))
|
||||
(set-vector! (-> directional direction) 0.0 1.0 0.0 1.0))
|
||||
(set-vector! (-> group dir0 color) 1.0 0.9 0.0 1.0))
|
||||
(let ((group (-> context light-group 3)))
|
||||
(make-light-kit group 0.0 1.0 0.0 0.0)
|
||||
(let ((directional (-> group dir0)))
|
||||
(set! (-> directional direction x) 0.0)
|
||||
(set! (-> directional direction y) 1.0)
|
||||
(set! (-> directional direction z) 0.0)
|
||||
(set! (-> directional direction w) 1.0))
|
||||
(set-vector! (-> directional direction) 0.0 1.0 0.0 1.0))
|
||||
(set-vector! (-> group dir0 color) 1.0 0.9 0.0 1.0))
|
||||
(let ((group (-> context light-group 4)))
|
||||
(make-light-kit group 0.0 1.0 0.0 0.0)
|
||||
(let ((directional (-> group dir0)))
|
||||
(set! (-> directional direction x) 0.0)
|
||||
(set! (-> directional direction y) 1.0)
|
||||
(set! (-> directional direction z) 0.0)
|
||||
(set! (-> directional direction w) 1.0))
|
||||
(set-vector! (-> directional direction) 0.0 1.0 0.0 1.0))
|
||||
(set-vector! (-> group dir0 color) 1.0 0.9 0.0 1.0))
|
||||
(let ((group (-> context light-group 5)))
|
||||
(make-light-kit group 0.0 1.0 0.0 0.0)
|
||||
(let ((directional (-> group dir0)))
|
||||
(set! (-> directional direction x) 0.0)
|
||||
(set! (-> directional direction y) 1.0)
|
||||
(set! (-> directional direction z) 0.0)
|
||||
(set! (-> directional direction w) 1.0))
|
||||
(set-vector! (-> directional direction) 0.0 1.0 0.0 1.0))
|
||||
(set-vector! (-> group dir0 color) 1.0 0.9 0.0 1.0))
|
||||
(let ((group (-> context light-group 6)))
|
||||
(make-light-kit group 0.0 1.0 0.0 0.0)
|
||||
(let ((directional (-> group dir0)))
|
||||
(set! (-> directional direction x) 0.0)
|
||||
(set! (-> directional direction y) 1.0)
|
||||
(set! (-> directional direction z) 0.0)
|
||||
(set! (-> directional direction w) 1.0))
|
||||
(set-vector! (-> directional direction) 0.0 1.0 0.0 1.0))
|
||||
(set-vector! (-> group dir0 color) 1.0 0.9 0.0 1.0))
|
||||
(none))
|
||||
|
||||
|
||||
(defun make-village3-light-kit ((context mood-context))
|
||||
"Initialize Village 3 light groups 1 and 2 with cyan upper and amber downward lighting."
|
||||
(let ((group (-> context light-group 1)))
|
||||
(let ((directional (-> group dir0)))
|
||||
(set! (-> directional direction x) 0.6281)
|
||||
(set! (-> directional direction y) 0.7208)
|
||||
(set! (-> directional direction z) 0.2929)
|
||||
(set! (-> directional direction w) 1.0))
|
||||
(set-vector! (-> directional direction) 0.6281 0.7208 0.2929 1.0))
|
||||
(set-vector! (-> group dir0 color) 0.5 1.0 1.0 1.0)
|
||||
(set! (-> group dir0 levels x) 1.0)
|
||||
(let ((directional (-> group dir2)))
|
||||
(set! (-> directional direction x) 0.0)
|
||||
(set! (-> directional direction y) -1.0)
|
||||
(set! (-> directional direction z) 0.0)
|
||||
(set! (-> directional direction w) 1.0))
|
||||
(set-vector! (-> directional direction) 0.0 -1.0 0.0 1.0))
|
||||
(set-vector! (-> group dir2 color) 0.625 0.375 0.1 1.0))
|
||||
(let ((group (-> context light-group 2)))
|
||||
(let ((directional (-> group dir0)))
|
||||
(set! (-> directional direction x) 0.6281)
|
||||
(set! (-> directional direction y) 0.7208)
|
||||
(set! (-> directional direction z) 0.2929)
|
||||
(set! (-> directional direction w) 1.0))
|
||||
(set-vector! (-> directional direction) 0.6281 0.7208 0.2929 1.0))
|
||||
(set-vector! (-> group dir0 color) 0.25 0.5 0.5 1.0)
|
||||
(set! (-> group dir0 levels x) 1.0)
|
||||
(let ((directional (-> group dir2)))
|
||||
(set! (-> directional direction x) 0.0)
|
||||
(set! (-> directional direction y) -1.0)
|
||||
(set! (-> directional direction z) 0.0)
|
||||
(set! (-> directional direction w) 1.0))
|
||||
(set-vector! (-> directional direction) 0.0 -1.0 0.0 1.0))
|
||||
(set-vector! (-> group dir2 color) 0.625 0.375 0.1 1.0))
|
||||
(none))
|
||||
|
||||
|
||||
@@ -30,223 +30,115 @@
|
||||
(set! (-> *target* sidekick 0 draw light-index) (the-as uint light-index))
|
||||
light-index)))
|
||||
|
||||
(#when PC_PORT
|
||||
(defun update-mood-itimes ((context mood-context))
|
||||
"Convert the eight floating palette weights into the packed values used by time-of-day palette
|
||||
interpolation. Each times vector has one in xyz and its weight in w, so multiplying xyz by w
|
||||
broadcasts the weight. Conversion to 20.12 fixed point followed by a six-bit arithmetic shift
|
||||
produces 4.6 values; packing pairs of 32-bit lanes into high halfwords stores all eight weights
|
||||
in four itimes quadwords."
|
||||
(local-vars
|
||||
(slot0-raw uint128)
|
||||
(slot0-fixed uint128)
|
||||
(packed01 uint128)
|
||||
(packed45 uint128)
|
||||
(slot1-raw uint128)
|
||||
(slot1-fixed uint128)
|
||||
(packed23 uint128)
|
||||
(packed67 uint128)
|
||||
(slot2-raw uint128)
|
||||
(slot2-fixed uint128)
|
||||
(slot3-raw uint128)
|
||||
(slot3-fixed uint128)
|
||||
(slot4-raw uint128)
|
||||
(slot4-fixed uint128)
|
||||
(slot5-raw uint128)
|
||||
(slot5-fixed uint128)
|
||||
(slot6-raw uint128)
|
||||
(slot6-fixed uint128)
|
||||
(slot7-raw uint128)
|
||||
(slot7-fixed uint128))
|
||||
;; og:preserve-this pc mood debug
|
||||
(with-pc
|
||||
(case *mood-override-debug*
|
||||
(('copy #t) (dotimes (mti 8) (set! (-> context times mti w) (-> *mood-override-table* mti))))
|
||||
(('mult) (dotimes (mti 8) (*! (-> context times mti w) (-> *mood-override-table* mti))))))
|
||||
(rlet ((vf1 :class vf)
|
||||
(vf2 :class vf)
|
||||
(vf3 :class vf)
|
||||
(vf4 :class vf)
|
||||
(vf5 :class vf)
|
||||
(vf6 :class vf)
|
||||
(vf7 :class vf)
|
||||
(vf8 :class vf))
|
||||
(nop!)
|
||||
(nop!)
|
||||
(.lvf vf1 (&-> context times 0 quad))
|
||||
(nop!)
|
||||
(.lvf vf2 (&-> context times 1 quad))
|
||||
(.mul.w.vf.xyz vf1 vf1 vf1)
|
||||
(.lvf vf3 (&-> context times 2 quad))
|
||||
(.mul.w.vf.xyz vf2 vf2 vf2)
|
||||
(.lvf vf4 (&-> context times 3 quad))
|
||||
(.mul.w.vf.xyz vf3 vf3 vf3)
|
||||
(.lvf vf5 (&-> context times 4 quad))
|
||||
(.mul.w.vf.xyz vf4 vf4 vf4)
|
||||
(.lvf vf6 (&-> context times 5 quad))
|
||||
(.mul.w.vf.xyz vf5 vf5 vf5)
|
||||
(.lvf vf7 (&-> context times 6 quad))
|
||||
(.mul.w.vf.xyz vf6 vf6 vf6)
|
||||
(.lvf vf8 (&-> context times 7 quad))
|
||||
(.mul.w.vf.xyz vf7 vf7 vf7)
|
||||
(nop!)
|
||||
(.mul.w.vf.xyz vf8 vf8 vf8)
|
||||
(nop!)
|
||||
(vftoi12.xyzw vf1 vf1)
|
||||
(nop!)
|
||||
(vftoi12.xyzw vf2 vf2)
|
||||
(nop!)
|
||||
(vftoi12.xyzw vf3 vf3)
|
||||
(nop!)
|
||||
(vftoi12.xyzw vf4 vf4)
|
||||
(nop!)
|
||||
(vftoi12.xyzw vf5 vf5)
|
||||
(nop!)
|
||||
(vftoi12.xyzw vf6 vf6)
|
||||
(nop!)
|
||||
(vftoi12.xyzw vf7 vf7)
|
||||
(nop!)
|
||||
(vftoi12.xyzw vf8 vf8)
|
||||
(nop!)
|
||||
(.mov slot0-raw vf1)
|
||||
(nop!)
|
||||
(.mov slot1-raw vf2)
|
||||
(nop!)
|
||||
(.mov slot2-raw vf3)
|
||||
(.pw.sra slot0-fixed slot0-raw 6)
|
||||
(.mov slot3-raw vf4)
|
||||
(.pw.sra slot1-fixed slot1-raw 6)
|
||||
(.mov slot4-raw vf5)
|
||||
(.pw.sra slot2-fixed slot2-raw 6)
|
||||
(.mov slot5-raw vf6)
|
||||
(.pw.sra slot3-fixed slot3-raw 6)
|
||||
(.mov slot6-raw vf7)
|
||||
(.pw.sra slot4-fixed slot4-raw 6)
|
||||
(.mov slot7-raw vf8)
|
||||
(.pw.sra slot5-fixed slot5-raw 6)
|
||||
(.pw.sra slot6-fixed slot6-raw 6)
|
||||
(nop!)
|
||||
(.pw.sra slot7-fixed slot7-raw 6)
|
||||
(nop!)
|
||||
(.ppach packed01 slot1-fixed slot0-fixed)
|
||||
(nop!)
|
||||
(.ppach packed23 slot3-fixed slot2-fixed)
|
||||
(set! (-> context itimes 0 quad) packed01)
|
||||
(.ppach packed45 slot5-fixed slot4-fixed)
|
||||
(set! (-> context itimes 1 quad) packed23)
|
||||
(.ppach packed67 slot7-fixed slot6-fixed)
|
||||
(set! (-> context itimes 2 quad) packed45)
|
||||
(nop!)
|
||||
(set! (-> context itimes 3 quad) packed67)
|
||||
0
|
||||
(none))))
|
||||
|
||||
(#unless PC_PORT
|
||||
(defun update-mood-itimes ((context mood-context))
|
||||
"Convert the eight floating palette weights into the packed values used by time-of-day palette
|
||||
interpolation. Each times vector has one in xyz and its weight in w, so multiplying xyz by w
|
||||
broadcasts the weight. Conversion to 20.12 fixed point followed by a six-bit arithmetic shift
|
||||
produces 4.6 values; packing pairs of 32-bit lanes into high halfwords stores all eight weights
|
||||
in four itimes quadwords."
|
||||
(rlet ((time-data (&-> context times 0 quad))
|
||||
(itime-data (&-> context itimes 0 quad))
|
||||
(time0 :reg vf1)
|
||||
(time1 :reg vf2)
|
||||
(time2 :reg vf3)
|
||||
(time3 :reg vf4)
|
||||
(time4 :reg vf5)
|
||||
(time5 :reg vf6)
|
||||
(time6 :reg vf7)
|
||||
(time7 :reg vf8)
|
||||
(slot0-raw :class i128)
|
||||
(slot0-fixed :class i128)
|
||||
(packed01 :class i128)
|
||||
(packed45 :class i128)
|
||||
(slot1-raw :class i128)
|
||||
(slot1-fixed :class i128)
|
||||
(packed23 :class i128)
|
||||
(packed67 :class i128)
|
||||
(slot2-raw :class i128)
|
||||
(slot2-fixed :class i128)
|
||||
(slot3-raw :class i128)
|
||||
(slot3-fixed :class i128)
|
||||
(slot4-raw :class i128)
|
||||
(slot4-fixed :class i128)
|
||||
(slot5-raw :class i128)
|
||||
(slot5-fixed :class i128)
|
||||
(slot6-raw :class i128)
|
||||
(slot6-fixed :class i128)
|
||||
(slot7-raw :class i128)
|
||||
(slot7-fixed :class i128))
|
||||
(nop!)
|
||||
(nop!)
|
||||
(l.vf time0 time-data)
|
||||
(nop!)
|
||||
(l.vf time1 time-data 16)
|
||||
(mul.w.vf.xyz time0 time0 time0)
|
||||
(l.vf time2 time-data 32)
|
||||
(mul.w.vf.xyz time1 time1 time1)
|
||||
(l.vf time3 time-data 48)
|
||||
(mul.w.vf.xyz time2 time2 time2)
|
||||
(l.vf time4 time-data 64)
|
||||
(mul.w.vf.xyz time3 time3 time3)
|
||||
(l.vf time5 time-data 80)
|
||||
(mul.w.vf.xyz time4 time4 time4)
|
||||
(l.vf time6 time-data 96)
|
||||
(mul.w.vf.xyz time5 time5 time5)
|
||||
(l.vf time7 time-data 112)
|
||||
(mul.w.vf.xyz time6 time6 time6)
|
||||
(nop!)
|
||||
(mul.w.vf.xyz time7 time7 time7)
|
||||
(nop!)
|
||||
(ftoi.vf time0 time0 :fixed 12)
|
||||
(nop!)
|
||||
(ftoi.vf time1 time1 :fixed 12)
|
||||
(nop!)
|
||||
(ftoi.vf time2 time2 :fixed 12)
|
||||
(nop!)
|
||||
(ftoi.vf time3 time3 :fixed 12)
|
||||
(nop!)
|
||||
(ftoi.vf time4 time4 :fixed 12)
|
||||
(nop!)
|
||||
(ftoi.vf time5 time5 :fixed 12)
|
||||
(nop!)
|
||||
(ftoi.vf time6 time6 :fixed 12)
|
||||
(nop!)
|
||||
(ftoi.vf time7 time7 :fixed 12)
|
||||
(nop!)
|
||||
(m slot0-raw time0)
|
||||
(nop!)
|
||||
(m slot1-raw time1)
|
||||
(nop!)
|
||||
(m slot2-raw time2)
|
||||
(sra.w slot0-fixed slot0-raw 6)
|
||||
(m slot3-raw time3)
|
||||
(sra.w slot1-fixed slot1-raw 6)
|
||||
(m slot4-raw time4)
|
||||
(sra.w slot2-fixed slot2-raw 6)
|
||||
(m slot5-raw time5)
|
||||
(sra.w slot3-fixed slot3-raw 6)
|
||||
(m slot6-raw time6)
|
||||
(sra.w slot4-fixed slot4-raw 6)
|
||||
(m slot7-raw time7)
|
||||
(sra.w slot5-fixed slot5-raw 6)
|
||||
(sra.w slot6-fixed slot6-raw 6)
|
||||
(mmi-nop!)
|
||||
(sra.w slot7-fixed slot7-raw 6)
|
||||
(mmi-nop!)
|
||||
(ppach packed01 slot1-fixed slot0-fixed)
|
||||
(mmi-nop!)
|
||||
(ppach packed23 slot3-fixed slot2-fixed)
|
||||
(s.q packed01 itime-data)
|
||||
(ppach packed45 slot5-fixed slot4-fixed)
|
||||
(s.q packed23 itime-data 16)
|
||||
(ppach packed67 slot7-fixed slot6-fixed)
|
||||
(s.q packed45 itime-data 32)
|
||||
(nop!)
|
||||
(s.q packed67 itime-data 48)
|
||||
0
|
||||
(none))))
|
||||
(defun update-mood-itimes ((context mood-context))
|
||||
"Convert the eight floating palette weights into the packed values used by time-of-day palette
|
||||
interpolation. Each times vector has one in xyz and its weight in w, so multiplying xyz by w
|
||||
broadcasts the weight. Conversion to 20.12 fixed point followed by a six-bit arithmetic shift
|
||||
produces 4.6 values; packing pairs of 32-bit lanes into high halfwords stores all eight weights
|
||||
in four itimes quadwords."
|
||||
(local-vars
|
||||
(slot0-raw uint128)
|
||||
(slot0-fixed uint128)
|
||||
(packed01 uint128)
|
||||
(packed45 uint128)
|
||||
(slot1-raw uint128)
|
||||
(slot1-fixed uint128)
|
||||
(packed23 uint128)
|
||||
(packed67 uint128)
|
||||
(slot2-raw uint128)
|
||||
(slot2-fixed uint128)
|
||||
(slot3-raw uint128)
|
||||
(slot3-fixed uint128)
|
||||
(slot4-raw uint128)
|
||||
(slot4-fixed uint128)
|
||||
(slot5-raw uint128)
|
||||
(slot5-fixed uint128)
|
||||
(slot6-raw uint128)
|
||||
(slot6-fixed uint128)
|
||||
(slot7-raw uint128)
|
||||
(slot7-fixed uint128))
|
||||
;; og:preserve-this pc mood debug
|
||||
(with-pc
|
||||
(case *mood-override-debug*
|
||||
(('copy #t) (dotimes (mti 8) (set! (-> context times mti w) (-> *mood-override-table* mti))))
|
||||
(('mult) (dotimes (mti 8) (*! (-> context times mti w) (-> *mood-override-table* mti))))))
|
||||
(rlet ((vf1 :class vf)
|
||||
(vf2 :class vf)
|
||||
(vf3 :class vf)
|
||||
(vf4 :class vf)
|
||||
(vf5 :class vf)
|
||||
(vf6 :class vf)
|
||||
(vf7 :class vf)
|
||||
(vf8 :class vf))
|
||||
(nop!)
|
||||
(nop!)
|
||||
(.lvf vf1 (&-> context times 0 quad))
|
||||
(nop!)
|
||||
(.lvf vf2 (&-> context times 1 quad))
|
||||
(.mul.w.vf.xyz vf1 vf1 vf1)
|
||||
(.lvf vf3 (&-> context times 2 quad))
|
||||
(.mul.w.vf.xyz vf2 vf2 vf2)
|
||||
(.lvf vf4 (&-> context times 3 quad))
|
||||
(.mul.w.vf.xyz vf3 vf3 vf3)
|
||||
(.lvf vf5 (&-> context times 4 quad))
|
||||
(.mul.w.vf.xyz vf4 vf4 vf4)
|
||||
(.lvf vf6 (&-> context times 5 quad))
|
||||
(.mul.w.vf.xyz vf5 vf5 vf5)
|
||||
(.lvf vf7 (&-> context times 6 quad))
|
||||
(.mul.w.vf.xyz vf6 vf6 vf6)
|
||||
(.lvf vf8 (&-> context times 7 quad))
|
||||
(.mul.w.vf.xyz vf7 vf7 vf7)
|
||||
(nop!)
|
||||
(.mul.w.vf.xyz vf8 vf8 vf8)
|
||||
(nop!)
|
||||
(vftoi12.xyzw vf1 vf1)
|
||||
(nop!)
|
||||
(vftoi12.xyzw vf2 vf2)
|
||||
(nop!)
|
||||
(vftoi12.xyzw vf3 vf3)
|
||||
(nop!)
|
||||
(vftoi12.xyzw vf4 vf4)
|
||||
(nop!)
|
||||
(vftoi12.xyzw vf5 vf5)
|
||||
(nop!)
|
||||
(vftoi12.xyzw vf6 vf6)
|
||||
(nop!)
|
||||
(vftoi12.xyzw vf7 vf7)
|
||||
(nop!)
|
||||
(vftoi12.xyzw vf8 vf8)
|
||||
(nop!)
|
||||
(.mov slot0-raw vf1)
|
||||
(nop!)
|
||||
(.mov slot1-raw vf2)
|
||||
(nop!)
|
||||
(.mov slot2-raw vf3)
|
||||
(.pw.sra slot0-fixed slot0-raw 6)
|
||||
(.mov slot3-raw vf4)
|
||||
(.pw.sra slot1-fixed slot1-raw 6)
|
||||
(.mov slot4-raw vf5)
|
||||
(.pw.sra slot2-fixed slot2-raw 6)
|
||||
(.mov slot5-raw vf6)
|
||||
(.pw.sra slot3-fixed slot3-raw 6)
|
||||
(.mov slot6-raw vf7)
|
||||
(.pw.sra slot4-fixed slot4-raw 6)
|
||||
(.mov slot7-raw vf8)
|
||||
(.pw.sra slot5-fixed slot5-raw 6)
|
||||
(.pw.sra slot6-fixed slot6-raw 6)
|
||||
(nop!)
|
||||
(.pw.sra slot7-fixed slot7-raw 6)
|
||||
(nop!)
|
||||
(.ppach packed01 slot1-fixed slot0-fixed)
|
||||
(nop!)
|
||||
(.ppach packed23 slot3-fixed slot2-fixed)
|
||||
(set! (-> context itimes 0 quad) packed01)
|
||||
(.ppach packed45 slot5-fixed slot4-fixed)
|
||||
(set! (-> context itimes 1 quad) packed23)
|
||||
(.ppach packed67 slot7-fixed slot6-fixed)
|
||||
(set! (-> context itimes 2 quad) packed45)
|
||||
(nop!)
|
||||
(set! (-> context itimes 3 quad) packed67)
|
||||
0
|
||||
(none)))
|
||||
|
||||
(defun update-mood-prt-color ((context mood-context))
|
||||
"Derive a missing particle tint from seventy-five percent ambient light and twenty-five percent
|
||||
@@ -255,14 +147,11 @@
|
||||
(ambient-color (-> groups 0 ambi color))
|
||||
(directional-color (new 'stack-no-clear 'vector)))
|
||||
(vector4-lerp! directional-color (-> groups 0 dir0 color) (-> groups 0 dir1 color) (-> groups 0 dir1 levels x))
|
||||
(set! (-> context current-prt-color x)
|
||||
(* 0.5 (+ (-> ambient-color x) (* 0.5 (+ (-> ambient-color x) (-> directional-color x))))))
|
||||
(set! (-> context current-prt-color y)
|
||||
(* 0.5 (+ (-> ambient-color y) (* 0.5 (+ (-> ambient-color y) (-> directional-color y))))))
|
||||
(set! (-> context current-prt-color z)
|
||||
(* 0.5 (+ (-> ambient-color z) (* 0.5 (+ (-> ambient-color z) (-> directional-color z))))))
|
||||
(set! (-> context current-prt-color w)
|
||||
(* 0.5 (+ (-> ambient-color w) (* 0.5 (+ (-> ambient-color w) (-> directional-color w)))))))
|
||||
(set-vector! (-> context current-prt-color)
|
||||
(* 0.5 (+ (-> ambient-color x) (* 0.5 (+ (-> ambient-color x) (-> directional-color x)))))
|
||||
(* 0.5 (+ (-> ambient-color y) (* 0.5 (+ (-> ambient-color y) (-> directional-color y)))))
|
||||
(* 0.5 (+ (-> ambient-color z) (* 0.5 (+ (-> ambient-color z) (-> directional-color z)))))
|
||||
(* 0.5 (+ (-> ambient-color w) (* 0.5 (+ (-> ambient-color w) (-> directional-color w)))))))
|
||||
(let ((shadow-color (-> context current-shadow-color)))
|
||||
(vector-copy! shadow-color (-> context current-prt-color))
|
||||
shadow-color))
|
||||
@@ -292,12 +181,12 @@
|
||||
(let ((snapshot (-> context mood-lights-table data snapshot-a-index)))
|
||||
(set! (-> context times snapshot-a-index w) 1.0)
|
||||
(vector-copy! (-> context current-prt-color) (-> snapshot prt-color))
|
||||
(set! (-> groups 0 ambi color quad) (-> snapshot amb-color quad))
|
||||
(vector-copy! (-> groups 0 ambi color) (-> snapshot amb-color))
|
||||
(set! (-> groups 0 ambi levels x) 1.0)
|
||||
(vector-copy! (-> context current-shadow) (-> snapshot shadow))
|
||||
(let ((color-level (+ (* 2.0 (-> snapshot lgt-color x)) (* 4.0 (-> snapshot lgt-color y)) (-> snapshot lgt-color z))))
|
||||
(set! (-> groups 0 dir0 direction quad) (-> snapshot direction quad))
|
||||
(set! (-> groups 0 dir0 color quad) (-> snapshot lgt-color quad))
|
||||
(vector-copy! (-> groups 0 dir0 direction) (-> snapshot direction))
|
||||
(vector-copy! (-> groups 0 dir0 color) (-> snapshot lgt-color))
|
||||
(set! (-> groups 0 dir0 levels x) 1.0)
|
||||
(set! (-> groups 0 dir0 levels y) color-level)))
|
||||
(set! (-> *time-of-day-context* light-masks-0 level-index) (the-as uint (ash 1 snapshot-a-index)))
|
||||
@@ -316,21 +205,21 @@
|
||||
(let ((color-level-a (* (+ (* 2.0 (-> snapshot-a lgt-color x)) (* 4.0 (-> snapshot-a lgt-color y)) (-> snapshot-a lgt-color z))
|
||||
(- 1.0 blend)))
|
||||
(color-level-b (* (+ (* 2.0 (-> snapshot-b lgt-color x)) (* 4.0 (-> snapshot-b lgt-color y)) (-> snapshot-b lgt-color z)) blend)))
|
||||
(set! (-> groups 0 dir0 direction quad) (-> snapshot-a direction quad))
|
||||
(set! (-> groups 0 dir0 color quad) (-> snapshot-a lgt-color quad))
|
||||
(vector-copy! (-> groups 0 dir0 direction) (-> snapshot-a direction))
|
||||
(vector-copy! (-> groups 0 dir0 color) (-> snapshot-a lgt-color))
|
||||
(set! (-> groups 0 dir0 levels x) (- 1.0 blend))
|
||||
(set! (-> groups 0 dir0 levels y) color-level-a)
|
||||
(set! (-> groups 0 dir1 direction quad) (-> snapshot-b direction quad))
|
||||
(set! (-> groups 0 dir1 color quad) (-> snapshot-b lgt-color quad))
|
||||
(vector-copy! (-> groups 0 dir1 direction) (-> snapshot-b direction))
|
||||
(vector-copy! (-> groups 0 dir1 color) (-> snapshot-b lgt-color))
|
||||
(set! (-> groups 0 dir1 levels x) blend)
|
||||
(set! (-> groups 0 dir1 levels y) color-level-b)))
|
||||
(set! (-> *time-of-day-context* light-masks-0 level-index) (the-as uint (ash 1 snapshot-a-index)))
|
||||
(set! (-> *time-of-day-context* light-masks-1 level-index) (the-as uint (ash 1 snapshot-b-index)))
|
||||
(set! (-> *time-of-day-context* light-interp level-index) blend)))
|
||||
(if (and (= (-> context current-prt-color x) 0.0)
|
||||
(= (-> context current-prt-color y) 0.0)
|
||||
(= (-> context current-prt-color z) 0.0))
|
||||
(update-mood-prt-color context))
|
||||
(= (-> context current-prt-color y) 0.0)
|
||||
(= (-> context current-prt-color z) 0.0))
|
||||
(update-mood-prt-color context))
|
||||
blend))
|
||||
|
||||
(defun update-mood-sky-texture ((context mood-context) (hour float))
|
||||
@@ -1084,9 +973,10 @@
|
||||
(cond
|
||||
((and (= egg-top-reminder 2) (nonzero? blue-transition-time))
|
||||
(if (< (the-as uint 60) blue-transition-time)
|
||||
(set! (-> context times 2 w) 2.0)
|
||||
(set! (-> context times 2 w) (* 0.033333335 (the float blue-transition-time))))
|
||||
(if (not (paused?)) (set! (-> context state 2) (+ blue-transition-time -1)))
|
||||
(set! (-> context times 2 w) 2.0)
|
||||
(set! (-> context times 2 w) (* 0.033333335 (the float blue-transition-time))))
|
||||
(if (not (paused?))
|
||||
(set! (-> context state 2) (+ blue-transition-time -1)))
|
||||
(set! (-> context times 1 w) 1.0)
|
||||
(update-mood-jungleb-blue context hour level-index))
|
||||
((and (nonzero? egg-top-reminder) (!= blue-transition-time 180))
|
||||
@@ -1098,23 +988,14 @@
|
||||
(set! (-> context state 1) (the-as uint 0))
|
||||
(set! (-> context state 0) (the-as uint 255))
|
||||
(let ((fog-snapshot (-> context mood-fog-table data)))
|
||||
(set! (-> fog-snapshot 0 fog-color x) 0.0)
|
||||
(set! (-> fog-snapshot 0 fog-color y) 0.0)
|
||||
(set! (-> fog-snapshot 0 fog-color z) 0.0)
|
||||
(set! (-> fog-snapshot 0 fog-color w) 128.0))
|
||||
(set-vector! (-> fog-snapshot 0 fog-color) 0.0 0.0 0.0 128.0))
|
||||
(set! (-> context mood-fog-table data 0 fog-dists x) 98304.0)
|
||||
(set-vector! (-> context mood-fog-table data 0 erase-color) 0.0 0.0 0.0 128.0)
|
||||
(let ((sun-snapshot (-> context mood-sun-table data)))
|
||||
(set! (-> sun-snapshot 0 sun-color x) 0.0)
|
||||
(set! (-> sun-snapshot 0 sun-color y) 0.0)
|
||||
(set! (-> sun-snapshot 0 sun-color z) 0.0)
|
||||
(set! (-> sun-snapshot 0 sun-color w) 0.0))
|
||||
(set-vector! (-> sun-snapshot 0 sun-color) 0.0 0.0 0.0 0.0))
|
||||
(set-vector! (-> context mood-sun-table data 0 env-color) 48.0 60.0 96.0 255.0)
|
||||
(let ((light-snapshot (-> context mood-lights-table data)))
|
||||
(set! (-> light-snapshot 0 direction x) 0.0)
|
||||
(set! (-> light-snapshot 0 direction y) 1.0)
|
||||
(set! (-> light-snapshot 0 direction z) 0.0)
|
||||
(set! (-> light-snapshot 0 direction w) 0.0))
|
||||
(set-vector! (-> light-snapshot 0 direction) 0.0 1.0 0.0 0.0))
|
||||
(set-vector! (-> context mood-lights-table data 0 lgt-color) 0.287 0.283 0.4 1.0)
|
||||
(set-vector! (-> context mood-lights-table data 0 amb-color) 0.166125 0.2125 0.4 1.0)
|
||||
(set-vector! (-> context mood-lights-table data 0 prt-color) 0.14235 0.1645 0.2875 1.0)
|
||||
@@ -1127,10 +1008,7 @@
|
||||
(let ((group (-> context light-group 2)))
|
||||
(quad-copy! (the-as pointer group) (the-as pointer (-> context light-group)) 12)
|
||||
(let ((down-light (-> group dir2)))
|
||||
(set! (-> down-light direction x) 0.0)
|
||||
(set! (-> down-light direction y) 1.0)
|
||||
(set! (-> down-light direction z) 0.0)
|
||||
(set! (-> down-light direction w) 0.0))
|
||||
(set-vector! (-> down-light direction) 0.0 1.0 0.0 0.0))
|
||||
(set-vector! (-> group dir2 color) 0.0 0.5 0.75 1.0)
|
||||
(set! (-> group dir2 levels x) 1.0))
|
||||
(let ((jungle-group (-> *jungle-mood* light-group 1))
|
||||
@@ -1138,10 +1016,7 @@
|
||||
(let ((ambient-offset (new 'stack-no-clear 'vector)))
|
||||
(quad-copy! (the-as pointer group) (the-as pointer (-> context light-group)) 12)
|
||||
(let ((down-light (-> group dir2)))
|
||||
(set! (-> down-light direction x) 0.0)
|
||||
(set! (-> down-light direction y) 1.0)
|
||||
(set! (-> down-light direction z) 0.0)
|
||||
(set! (-> down-light direction w) 0.0))
|
||||
(set-vector! (-> down-light direction) 0.0 1.0 0.0 0.0))
|
||||
(set-vector! (-> group dir2 color) 0.4 0.25 0.1 1.0)
|
||||
(set! (-> group dir2 levels x) 1.0)
|
||||
(set-vector! ambient-offset 0.25 0.25 0.25 0.0)
|
||||
@@ -1149,7 +1024,7 @@
|
||||
(quad-copy! (the-as pointer jungle-group) (the-as pointer group) 12))
|
||||
(let ((landmark-position (new 'stack-no-clear 'vector))
|
||||
(target-position (target-joint-pos)))
|
||||
(set-vector! landmark-position 1482752.0 (-> target-position y) -985088.0 1.0)
|
||||
(set-vector! landmark-position (meters 362) (-> target-position y) -985088.0 1.0)
|
||||
(let ((distance (vector-vector-distance landmark-position target-position)))
|
||||
(when (< distance 81920.0)
|
||||
(let ((horizontal-fade (* 0.000034877234 (+ -53248.0 distance)))
|
||||
@@ -1161,31 +1036,26 @@
|
||||
(let* ((height-level (- 1.0 (fmax 0.0 (fmin 1.0 height-fade))))
|
||||
(fire-level (* (- 1.0 (fmax 0.0 (fmin 1.0 horizontal-fade))) height-level)))
|
||||
(let ((down-light (-> groups 0 dir2)))
|
||||
(set! (-> down-light direction x) 0.0)
|
||||
(set! (-> down-light direction y) 1.0)
|
||||
(set! (-> down-light direction z) 0.0)
|
||||
(set! (-> down-light direction w) 0.0))
|
||||
(set-vector! (-> down-light direction) 0.0 1.0 0.0 0.0))
|
||||
(set-vector! (-> groups 0 dir2 color) 0.4 0.25 0.1 1.0)
|
||||
(set! (-> groups 0 dir2 levels x) fire-level)
|
||||
(let ((down-light (-> jungle-groups 0 dir2)))
|
||||
(set! (-> down-light direction x) 0.0)
|
||||
(set! (-> down-light direction y) 1.0)
|
||||
(set! (-> down-light direction z) 0.0)
|
||||
(set! (-> down-light direction w) 0.0))
|
||||
(set-vector! (-> down-light direction) 0.0 1.0 0.0 0.0))
|
||||
(set-vector! (-> jungle-groups 0 dir2 color) 0.4 0.25 0.1 1.0)
|
||||
(set! (-> jungle-groups 0 dir2 levels x) fire-level)
|
||||
(set-vector! bright-ambient 0.25 0.25 0.25 0.0)
|
||||
(vector+! bright-ambient bright-ambient (the-as vector (-> groups 0 ambi color)))
|
||||
(vector4-lerp! (-> groups 0 ambi color) (-> groups 0 ambi color) bright-ambient fire-level)))))
|
||||
(set-vector! landmark-position 1146880.0 (-> target-position y) -1232896.0 1.0)
|
||||
(if (< (vector-vector-distance landmark-position target-position) 10240.0) (set! *teleport* #t))
|
||||
(set-vector! landmark-position 1781760.0 -163840.0 -1038336.0 1.0)
|
||||
(set-vector! landmark-position (meters 280) (-> target-position y) (meters -301) 1.0)
|
||||
(if (< (vector-vector-distance landmark-position target-position) 10240.0)
|
||||
(set! *teleport* #t))
|
||||
(set-vector! landmark-position (meters 435) (meters -40) -1038336.0 1.0)
|
||||
(let ((distance (vector-vector-distance landmark-position target-position)))
|
||||
(when (< distance 147456.0)
|
||||
(let ((fade (* 0.000030517578 (+ -114688.0 distance))))
|
||||
(set-target-light-index 2)
|
||||
(set! (-> *time-of-day-context* target-interp) (- 1.0 (fmax 0.0 (fmin 1.0 fade)))))))
|
||||
(set-vector! landmark-position 1105920.0 -188416.0 -1204224.0 1.0)
|
||||
(set-vector! landmark-position (meters 270) (meters -46) (meters -294) 1.0)
|
||||
(let ((distance (vector-vector-distance landmark-position target-position)))
|
||||
(when (< distance 106496.0)
|
||||
(let ((fade (* 0.000030517578 (+ -73728.0 distance))))
|
||||
@@ -1449,7 +1319,7 @@
|
||||
(none))
|
||||
|
||||
(defun update-mood-darkcave ((context mood-context) (hour float) (level-index int))
|
||||
"Update Dark Eco Plant's mood, lava glow, and proximity-based local lighting."
|
||||
"Update"
|
||||
(when (not (paused?))
|
||||
(clear-mood-times context)
|
||||
(set! (-> context times 0 w) 1.0)
|
||||
@@ -1561,8 +1431,7 @@
|
||||
(time uint8)))
|
||||
|
||||
(defun update-mood-village3 ((context mood-context) (hour float) (level-index int))
|
||||
"Update Volcanic Crater's mood, lava and caustic effects, local light kits, and target lighting
|
||||
transitions."
|
||||
"Update Volcanic Crater's mood, lava effects, local light kits, and target lighting transitions."
|
||||
(update-mood-fog context hour)
|
||||
(update-mood-sky-texture context hour)
|
||||
(clear-mood-times context)
|
||||
@@ -1574,31 +1443,19 @@
|
||||
(dark-ambient-color (new 'stack-no-clear 'vector))
|
||||
(up-direction (new 'stack-no-clear 'vector)))
|
||||
(let ((snapshot (-> context mood-lights-table data)))
|
||||
(set! (-> snapshot 0 direction x) -0.067)
|
||||
(set! (-> snapshot 0 direction y) 0.25)
|
||||
(set! (-> snapshot 0 direction z) 0.966)
|
||||
(set! (-> snapshot 0 direction w) 0.0))
|
||||
(set-vector! (-> snapshot 0 direction) -0.067 0.25 0.966 0.0))
|
||||
(set-vector! (-> context mood-lights-table data 0 lgt-color) 0.0 0.0 0.0 1.0)
|
||||
(set-vector! (-> context mood-lights-table data 0 amb-color) 0.449 0.35 0.599 1.0)
|
||||
(let ((snapshot (-> context mood-lights-table data 1)))
|
||||
(set! (-> snapshot direction x) 0.259)
|
||||
(set! (-> snapshot direction y) 0.966)
|
||||
(set! (-> snapshot direction z) 0.0)
|
||||
(set! (-> snapshot direction w) 0.0))
|
||||
(set-vector! (-> snapshot direction) 0.259 0.966 0.0 0.0))
|
||||
(set-vector! (-> context mood-lights-table data 1 lgt-color) 0.66 0.436 0.291 1.0)
|
||||
(set-vector! (-> context mood-lights-table data 1 amb-color) 0.358 0.575 0.716 1.0)
|
||||
(let ((snapshot (-> context mood-lights-table data 2)))
|
||||
(set! (-> snapshot direction x) -0.067)
|
||||
(set! (-> snapshot direction y) 0.25)
|
||||
(set! (-> snapshot direction z) -0.966)
|
||||
(set! (-> snapshot direction w) 0.0))
|
||||
(set-vector! (-> snapshot direction) -0.067 0.25 -0.966 0.0))
|
||||
(set-vector! (-> context mood-lights-table data 2 lgt-color) 0.0 0.0 0.0 1.0)
|
||||
(set-vector! (-> context mood-lights-table data 2 amb-color) 0.383 0.366 0.599 1.0)
|
||||
(let ((snapshot (-> context mood-lights-table data 3)))
|
||||
(set! (-> snapshot direction x) 0.866)
|
||||
(set! (-> snapshot direction y) 0.5)
|
||||
(set! (-> snapshot direction z) 0.0)
|
||||
(set! (-> snapshot direction w) 0.0))
|
||||
(set-vector! (-> snapshot direction) 0.866 0.5 0.0 0.0))
|
||||
(set-vector! (-> context mood-lights-table data 3 lgt-color) 0.0 0.0 0.0 1.0)
|
||||
(set-vector! (-> context mood-lights-table data 3 amb-color) 0.304 0.409 0.76 1.0)
|
||||
(let ((group (-> context light-group 1)))
|
||||
@@ -1638,11 +1495,12 @@
|
||||
(let ((lava-blend (* 0.015625 (the float (logand (-> mood-state time) 63)))))
|
||||
(set! (-> mood-state scale) (the float (the int (rand-vu-float-range 128.0 255.0))))
|
||||
(set! (-> context times 7 w) (* lava-blend (-> mood-state scale)))))))
|
||||
(else (set-vector! local-light-color 0.19 0.128 0.128 1.0)))))
|
||||
(else
|
||||
(set-vector! local-light-color 0.19 0.128 0.128 1.0)))))
|
||||
(let ((landmark-position (new 'stack-no-clear 'vector))
|
||||
(target-position (target-joint-pos)))
|
||||
0.0
|
||||
(set-vector! landmark-position 4454400.0 196608.0 -14725120.0 1.0)
|
||||
(set-vector! landmark-position 4454400.0 (meters 48) (meters -3595) 1.0)
|
||||
(let ((distance (vector-vector-distance landmark-position target-position)))
|
||||
(when (< distance 122880.0)
|
||||
(let ((fade (* 0.000016276043 (+ -61440.0 distance))))
|
||||
@@ -1742,7 +1600,7 @@
|
||||
(when *time-of-day-effects*
|
||||
(let ((landmark-position (new 'stack-no-clear 'vector))
|
||||
(camera-position (-> *math-camera* trans)))
|
||||
(set-vector! landmark-position 868352.0 151552.0 -7720960.0 1.0)
|
||||
(set-vector! landmark-position (meters 212) (meters 37) (meters -1885) 1.0)
|
||||
(let ((distance (vector-vector-distance landmark-position camera-position)))
|
||||
(cond
|
||||
((< distance 614400.0)
|
||||
@@ -1750,12 +1608,16 @@
|
||||
(let* ((distance-fade (* 0.0000048828124 (+ -409600.0 distance)))
|
||||
(phase-blend (fmax 0.0 (fmin 1.0 distance-fade))))
|
||||
(let ((mood-state (the-as ogre-states (-> context state))))
|
||||
(if (not (paused?)) (+! (-> mood-state lava-time) (rand-vu-float-range 64.0 2048.0)))
|
||||
(if (not (movie?)) (update-mood-lightning context 2 2 18 4 0.5 #f))
|
||||
(if (not (paused?))
|
||||
(+! (-> mood-state lava-time) (rand-vu-float-range 64.0 2048.0)))
|
||||
(if (not (movie?))
|
||||
(update-mood-lightning context 2 2 18 4 0.5 #f))
|
||||
(cond
|
||||
((or (nonzero? *lightning-time2*) (movie?))
|
||||
(if (not (paused?)) (+! (-> mood-state lava-fade) 0.2))
|
||||
(if (< 1.0 (-> mood-state lava-fade)) (set! (-> mood-state lava-fade) 1.0))
|
||||
(if (not (paused?))
|
||||
(+! (-> mood-state lava-fade) 0.2))
|
||||
(if (< 1.0 (-> mood-state lava-fade))
|
||||
(set! (-> mood-state lava-fade) 1.0))
|
||||
(let* ((lava-fade (-> mood-state lava-fade))
|
||||
(lava-light (-> context light-group 0 dir2))
|
||||
(lava-level (+ 0.875 (* 0.125 (sin (-> mood-state lava-time)))))
|
||||
@@ -1764,26 +1626,24 @@
|
||||
(set-vector! (-> lava-light color) 1.0 0.38 0.0 1.0)
|
||||
(set! (-> lava-light levels x) (* lava-level (- 1.0 phase-blend) lava-fade))
|
||||
(set! (-> lava-light levels y) (* lava-color-level (- 1.0 phase-blend) lava-fade))))
|
||||
(else (set! (-> mood-state lava-fade) 0.0))))
|
||||
(else
|
||||
(set! (-> mood-state lava-fade) 0.0))))
|
||||
(let ((groups (-> context light-group))
|
||||
(phase-groups (-> *ogre2-mood* light-group)))
|
||||
(cond
|
||||
((= phase-blend 0.0)
|
||||
(set! (-> groups 0 dir0 direction quad) (-> phase-groups 0 dir0 direction quad))
|
||||
(set! (-> groups 0 dir0 color quad) (-> phase-groups 0 dir0 color quad))
|
||||
(set! (-> groups 0 dir0 levels quad) (-> phase-groups 0 dir0 levels quad))
|
||||
(set! (-> groups 0 dir1 direction quad) (-> phase-groups 0 dir1 direction quad))
|
||||
(set! (-> groups 0 dir1 color quad) (-> phase-groups 0 dir1 color quad))
|
||||
(set! (-> groups 0 dir1 levels quad) (-> phase-groups 0 dir1 levels quad))
|
||||
(set! (-> groups 0 ambi direction quad) (-> phase-groups 0 ambi direction quad))
|
||||
(set! (-> groups 0 ambi color quad) (-> phase-groups 0 ambi color quad))
|
||||
(set! (-> groups 0 ambi levels quad) (-> phase-groups 0 ambi levels quad))
|
||||
(vector-copy! (-> groups 0 dir0 direction) (-> phase-groups 0 dir0 direction))
|
||||
(vector-copy! (-> groups 0 dir0 color) (-> phase-groups 0 dir0 color))
|
||||
(vector-copy! (-> groups 0 dir0 levels) (-> phase-groups 0 dir0 levels))
|
||||
(vector-copy! (-> groups 0 dir1 direction) (-> phase-groups 0 dir1 direction))
|
||||
(vector-copy! (-> groups 0 dir1 color) (-> phase-groups 0 dir1 color))
|
||||
(vector-copy! (-> groups 0 dir1 levels) (-> phase-groups 0 dir1 levels))
|
||||
(vector-copy! (-> groups 0 ambi direction) (-> phase-groups 0 ambi direction))
|
||||
(vector-copy! (-> groups 0 ambi color) (-> phase-groups 0 ambi color))
|
||||
(vector-copy! (-> groups 0 ambi levels) (-> phase-groups 0 ambi levels))
|
||||
(vector-copy! (-> context current-shadow) (-> *ogre2-mood* current-shadow)))
|
||||
(else
|
||||
(vector4-lerp! (the-as vector (-> groups 0))
|
||||
(the-as vector (-> phase-groups 0))
|
||||
(the-as vector (-> groups 0))
|
||||
phase-blend)
|
||||
(vector4-lerp! (-> groups 0 dir0 direction) (-> phase-groups 0 dir0 direction) (-> groups 0 dir0 direction) phase-blend)
|
||||
(vector4-lerp! (-> groups 0 dir0 color) (-> phase-groups 0 dir0 color) (-> groups 0 dir0 color) phase-blend)
|
||||
(vector4-lerp! (-> groups 0 dir0 levels) (-> phase-groups 0 dir0 levels) (-> groups 0 dir0 levels) phase-blend)
|
||||
(vector4-lerp! (-> groups 0 dir1 direction) (-> phase-groups 0 dir1 direction) (-> groups 0 dir1 direction) phase-blend)
|
||||
@@ -1794,7 +1654,7 @@
|
||||
(vector4-lerp! (-> groups 0 ambi levels) (-> phase-groups 0 ambi levels) (-> groups 0 ambi levels) phase-blend)
|
||||
(vector4-lerp! (-> context current-shadow) (-> *ogre2-mood* current-shadow) (-> context current-shadow) phase-blend))))))
|
||||
(else
|
||||
(set-vector! landmark-position 2973696.0 184320.0 -13414400.0 1.0)
|
||||
(set-vector! landmark-position (meters 726) (meters 45) (meters -3275) 1.0)
|
||||
(let ((distance (vector-vector-distance landmark-position camera-position)))
|
||||
(when (< distance 1298432.0)
|
||||
(update-mood-quick *ogre3-mood* 0 0 0 level-index)
|
||||
@@ -1804,27 +1664,24 @@
|
||||
(phase-groups (-> *ogre3-mood* light-group)))
|
||||
(cond
|
||||
((= phase-blend 0.0)
|
||||
(set! (-> groups 0 dir0 direction quad) (-> phase-groups 0 dir0 direction quad))
|
||||
(set! (-> groups 0 dir0 color quad) (-> phase-groups 0 dir0 color quad))
|
||||
(set! (-> groups 0 dir0 levels quad) (-> phase-groups 0 dir0 levels quad))
|
||||
(set! (-> groups 0 dir1 direction quad) (-> phase-groups 0 dir1 direction quad))
|
||||
(set! (-> groups 0 dir1 color quad) (-> phase-groups 0 dir1 color quad))
|
||||
(set! (-> groups 0 dir1 levels quad) (-> phase-groups 0 dir1 levels quad))
|
||||
(set! (-> groups 0 dir2 direction quad) (-> phase-groups 0 dir2 direction quad))
|
||||
(set! (-> groups 0 dir2 color quad) (-> phase-groups 0 dir2 color quad))
|
||||
(set! (-> groups 0 dir2 levels quad) (-> phase-groups 0 dir2 levels quad))
|
||||
(set! (-> groups 0 ambi direction quad) (-> phase-groups 0 ambi direction quad))
|
||||
(set! (-> groups 0 ambi color quad) (-> phase-groups 0 ambi color quad))
|
||||
(set! (-> groups 0 ambi levels quad) (-> phase-groups 0 ambi levels quad))
|
||||
(vector-copy! (-> groups 0 dir0 direction) (-> phase-groups 0 dir0 direction))
|
||||
(vector-copy! (-> groups 0 dir0 color) (-> phase-groups 0 dir0 color))
|
||||
(vector-copy! (-> groups 0 dir0 levels) (-> phase-groups 0 dir0 levels))
|
||||
(vector-copy! (-> groups 0 dir1 direction) (-> phase-groups 0 dir1 direction))
|
||||
(vector-copy! (-> groups 0 dir1 color) (-> phase-groups 0 dir1 color))
|
||||
(vector-copy! (-> groups 0 dir1 levels) (-> phase-groups 0 dir1 levels))
|
||||
(vector-copy! (-> groups 0 dir2 direction) (-> phase-groups 0 dir2 direction))
|
||||
(vector-copy! (-> groups 0 dir2 color) (-> phase-groups 0 dir2 color))
|
||||
(vector-copy! (-> groups 0 dir2 levels) (-> phase-groups 0 dir2 levels))
|
||||
(vector-copy! (-> groups 0 ambi direction) (-> phase-groups 0 ambi direction))
|
||||
(vector-copy! (-> groups 0 ambi color) (-> phase-groups 0 ambi color))
|
||||
(vector-copy! (-> groups 0 ambi levels) (-> phase-groups 0 ambi levels))
|
||||
(vector-copy! (-> context current-shadow) (-> *ogre3-mood* current-shadow))
|
||||
(vector-copy! (-> context current-fog fog-color) (-> *ogre3-mood* current-fog fog-color))
|
||||
(vector-copy! (-> context current-fog fog-dists) (-> *ogre3-mood* current-fog fog-dists))
|
||||
(vector-copy! (-> context current-fog erase-color) (-> *ogre3-mood* current-fog erase-color)))
|
||||
(else
|
||||
(vector4-lerp! (the-as vector (-> groups 0))
|
||||
(the-as vector (-> phase-groups 0))
|
||||
(the-as vector (-> groups 0))
|
||||
phase-blend)
|
||||
(vector4-lerp! (-> groups 0 dir0 direction) (-> phase-groups 0 dir0 direction) (-> groups 0 dir0 direction) phase-blend)
|
||||
(vector4-lerp! (-> groups 0 dir0 color) (-> phase-groups 0 dir0 color) (-> groups 0 dir0 color) phase-blend)
|
||||
(vector4-lerp! (-> groups 0 dir0 levels) (-> phase-groups 0 dir0 levels) (-> groups 0 dir0 levels) phase-blend)
|
||||
(vector4-lerp! (-> groups 0 dir1 direction) (-> phase-groups 0 dir1 direction) (-> groups 0 dir1 direction) phase-blend)
|
||||
@@ -1882,21 +1739,18 @@
|
||||
(groups (-> context light-group)))
|
||||
(let ((snapshot (-> context mood-lights-table data 2)))
|
||||
(set! (-> context times 2 w) palette-fade)
|
||||
(vector+float*! (the-as vector (-> groups 0)) (the-as vector (-> groups 0)) (-> snapshot direction) palette-fade)
|
||||
(vector+float*! (-> groups 0 dir0 direction) (-> groups 0 dir0 direction) (-> snapshot direction) palette-fade)
|
||||
(vector+float*! (-> groups 0 dir0 color) (-> groups 0 dir0 color) (-> snapshot lgt-color) palette-fade))
|
||||
(vector-normalize! (the-as vector (-> groups 0)) 1.0)))
|
||||
(vector-normalize! (-> groups 0 dir0 direction) 1.0)))
|
||||
(let ((arena-position (new 'stack-no-clear 'vector))
|
||||
(camera-position (-> *math-camera* trans)))
|
||||
(set-vector! arena-position 12378112.0 1990656.0 -19873792.0 1.0)
|
||||
(set-vector! arena-position (meters 3022) (meters 486) (meters -4852) 1.0)
|
||||
(let ((distance (vector-vector-distance arena-position camera-position)))
|
||||
(when (< distance 819200.0)
|
||||
(let* ((distance-fade (* 0.0000048828124 (+ -614400.0 distance)))
|
||||
(arena-light-level (- 1.0 (fmax 0.0 (fmin 1.0 distance-fade)))))
|
||||
(let ((arena-light (-> *finalboss2-mood* light-group 0 dir2)))
|
||||
(set! (-> arena-light direction x) 0.0)
|
||||
(set! (-> arena-light direction y) -1.0)
|
||||
(set! (-> arena-light direction z) 0.0)
|
||||
(set! (-> arena-light direction w) 1.0))
|
||||
(set-vector! (-> arena-light direction) 0.0 -1.0 0.0 1.0))
|
||||
(set-vector! (-> *finalboss2-mood* light-group 0 dir2 color) 1.0 0.8 2.0 1.0)
|
||||
(set! (-> *finalboss2-mood* light-group 0 dir2 levels x) arena-light-level)))))
|
||||
(cond
|
||||
@@ -1905,10 +1759,7 @@
|
||||
(secret-light-fade (fmax 0.0 (fmin 1.0 secret-light-time)))
|
||||
(groups (-> context light-group)))
|
||||
(let ((secret-light (-> groups 0 dir2)))
|
||||
(set! (-> secret-light direction x) -0.5768)
|
||||
(set! (-> secret-light direction y) 0.1697)
|
||||
(set! (-> secret-light direction z) -0.799)
|
||||
(set! (-> secret-light direction w) 1.0))
|
||||
(set-vector! (-> secret-light direction) -0.5768 0.1697 -0.799 1.0))
|
||||
(set-vector! (-> groups 0 dir2 color) 1.0 1.0 1.0 1.0)
|
||||
(set! (-> groups 0 dir2 levels x) secret-light-fade)
|
||||
(let ((shadow-direction (-> context current-shadow)))
|
||||
@@ -1924,7 +1775,8 @@
|
||||
(set! (-> *default-shadow-settings* shadow-dir x) (-> shadow-direction x))
|
||||
(set! (-> *default-shadow-settings* shadow-dir y) (-> shadow-direction y))
|
||||
(set! (-> *default-shadow-settings* shadow-dir z) (-> shadow-direction z)))))
|
||||
(else (set-time! (-> mood-state secret-time))))
|
||||
(else
|
||||
(set-time! (-> mood-state secret-time))))
|
||||
(let* ((sun-time (* 0.00019607843 (the float (- (current-time) (-> mood-state start-time)))))
|
||||
(sun-fade (fmax 0.0 (fmin 1.0 sun-time)))
|
||||
(sun-fade (fmax 0.0 (fmin 1.0 sun-fade))))
|
||||
@@ -1955,22 +1807,19 @@
|
||||
(groups (-> context light-group)))
|
||||
(let ((snapshot (-> context mood-lights-table data 2)))
|
||||
(set! (-> context times 2 w) palette-fade)
|
||||
(vector+float*! (the-as vector (-> groups 0)) (the-as vector (-> groups 0)) (-> snapshot direction) palette-fade)
|
||||
(vector+float*! (-> groups 0 dir0 direction) (-> groups 0 dir0 direction) (-> snapshot direction) palette-fade)
|
||||
(vector+float*! (-> groups 0 dir0 color) (-> groups 0 dir0 color) (-> snapshot lgt-color) palette-fade))
|
||||
(vector-normalize! (the-as vector (-> groups 0)) 1.0))
|
||||
(vector-normalize! (-> groups 0 dir0 direction) 1.0))
|
||||
(let ((arena-position (new 'stack-no-clear 'vector))
|
||||
(camera-position (-> *math-camera* trans)))
|
||||
(set-vector! arena-position 12378112.0 1990656.0 -19873792.0 1.0)
|
||||
(set-vector! arena-position (meters 3022) (meters 486) (meters -4852) 1.0)
|
||||
(let ((distance (vector-vector-distance arena-position camera-position)))
|
||||
(when (< distance 819200.0)
|
||||
(let* ((distance-fade (* 0.0000048828124 (+ -614400.0 distance)))
|
||||
(groups (-> context light-group))
|
||||
(arena-light-level (- 1.0 (fmax 0.0 (fmin 1.0 distance-fade)))))
|
||||
(let ((arena-light (-> groups 0 dir2)))
|
||||
(set! (-> arena-light direction x) 0.0)
|
||||
(set! (-> arena-light direction y) -1.0)
|
||||
(set! (-> arena-light direction z) 0.0)
|
||||
(set! (-> arena-light direction w) 1.0))
|
||||
(set-vector! (-> arena-light direction) 0.0 -1.0 0.0 1.0))
|
||||
(set-vector! (-> groups 0 dir2 color) 1.0 0.8 2.0 1.0)
|
||||
(set! (-> groups 0 dir2 levels x) arena-light-level))))))))
|
||||
(update-mood-itimes context)
|
||||
@@ -1996,21 +1845,24 @@
|
||||
(set! (-> context times 3 w) (-> *palette-fade-controls* control 3 fade))
|
||||
(update-mood-flames context 4 3 0 0.45 0.001953125 1.0)
|
||||
(update-mood-light context 1 4 5 0.875 0.25 20.0 32)
|
||||
(if (not (paused?)) (+! (-> context state 5) 1))
|
||||
(if (not (paused?))
|
||||
(+! (-> context state 5) 1))
|
||||
(let ((state-data (the-as (pointer number) (-> context state))))
|
||||
(let ((light-flicker (+ 0.5 (* 0.5 (cos (the float (* (logand (+ (-> (the-as (pointer uint8) state-data) 5) 32) 255) 512)))))))
|
||||
(cond
|
||||
((movie?))
|
||||
((nonzero? (-> (the-as (pointer uint8) state-data) 7))
|
||||
(set! (-> context times 2 w) 1.0)
|
||||
(if (not (paused?)) (+! (-> (the-as (pointer uint8) state-data) 7) -1)))
|
||||
(if (not (paused?))
|
||||
(+! (-> (the-as (pointer uint8) state-data) 7) -1)))
|
||||
((nonzero? (-> (the-as (pointer uint8) state-data) 6))
|
||||
(if (not (paused?)) (+! (-> (the-as (pointer uint8) state-data) 6) -1)))
|
||||
(if (not (paused?))
|
||||
(+! (-> (the-as (pointer uint8) state-data) 6) -1)))
|
||||
(else
|
||||
(set! (-> (the-as (pointer uint8) state-data) 7) (the-as uint (the int (rand-vu-float-range 2.0 20.0))))
|
||||
(if (zero? (the int (rand-vu-float-range 0.0 3.0)))
|
||||
(set! (-> (the-as (pointer uint8) state-data) 6) (the-as uint (the int (rand-vu-float-range 2.0 120.0))))
|
||||
(set! (-> (the-as (pointer uint8) state-data) 6) (the-as uint (the int (rand-vu-float-range 2.0 20.0)))))))
|
||||
(set! (-> (the-as (pointer uint8) state-data) 6) (the-as uint (the int (rand-vu-float-range 2.0 120.0))))
|
||||
(set! (-> (the-as (pointer uint8) state-data) 6) (the-as uint (the int (rand-vu-float-range 2.0 20.0)))))))
|
||||
(let ((light-color (new 'stack-no-clear 'vector))
|
||||
(warm-light-color (new 'stack-no-clear 'vector))
|
||||
(groups (-> context light-group)))
|
||||
@@ -2018,15 +1870,12 @@
|
||||
(set-vector! warm-light-color 0.75 0.725 0.5 1.0)
|
||||
(vector4-lerp! light-color light-color warm-light-color light-flicker)
|
||||
(let ((primary-group (-> groups 0)))
|
||||
(set! (-> primary-group dir0 direction x) 0.0)
|
||||
(set! (-> primary-group dir0 direction y) 1.0)
|
||||
(set! (-> primary-group dir0 direction z) 0.0)
|
||||
(set! (-> primary-group dir0 direction w) 1.0))
|
||||
(set! (-> groups 0 dir0 color quad) (-> light-color quad))
|
||||
(set-vector! (-> primary-group dir0 direction) 0.0 1.0 0.0 1.0))
|
||||
(vector-copy! (-> groups 0 dir0 color) light-color)
|
||||
(set! (-> groups 0 dir0 levels x) 1.0)))
|
||||
(let ((landmark-position (new 'stack-no-clear 'vector))
|
||||
(target-position (target-joint-pos)))
|
||||
(set-vector! landmark-position 11227136.0 (-> target-position y) -20164608.0 1.0)
|
||||
(set-vector! landmark-position (meters 2741) (-> target-position y) (meters -4923) 1.0)
|
||||
(let ((distance (vector-vector-distance landmark-position target-position)))
|
||||
(when (< distance 409600.0)
|
||||
(let* ((distance-fade (* 0.000048828126 (+ -389120.0 distance)))
|
||||
@@ -2034,7 +1883,7 @@
|
||||
(set! (-> context current-fog fog-dists y) (* 4096.0 (+ 250.0 (* 300.0 fog-fade))))))))
|
||||
(let ((shield-position (new 'stack-no-clear 'vector))
|
||||
(camera-position (-> *math-camera* trans)))
|
||||
(set-vector! shield-position 11427840.0 (-> camera-position y) -19251200.0 1.0)
|
||||
(set-vector! shield-position (meters 2790) (-> camera-position y) (meters -4700) 1.0)
|
||||
(let ((distance (vector-vector-distance shield-position camera-position))
|
||||
(groups (-> context light-group)))
|
||||
(cond
|
||||
@@ -2042,45 +1891,39 @@
|
||||
(let* ((distance-fade (* 0.000012207031 (+ -409600.0 distance)))
|
||||
(shield-proximity (- 1.0 (fmax 0.0 (fmin 1.0 distance-fade))))
|
||||
(shield-flicker (+ 0.5
|
||||
(* 0.125 (cos (the float (* 4000 (/ (-> *display* time-factor) 5) (-> *display* integral-frame-counter))))) ;; og:preserve-this changed for high fps
|
||||
(* 0.125
|
||||
(cos (the float (shl (the int (* (/ (-> *display* time-factor) 5) (-> *display* integral-frame-counter))) 11)))) ;; og:preserve-this changed for high fps
|
||||
(* 0.25 (cos (the float (* 1500 (/ (-> *display* time-factor) 5) (-> *display* integral-frame-counter))))) ;; og:preserve-this changed for high fps
|
||||
))
|
||||
(* 0.125 (cos (the float (* 4000 (-> *display* integral-frame-counter)))))
|
||||
(* 0.125 (cos (the float (shl (-> *display* integral-frame-counter) 11))))
|
||||
(* 0.25 (cos (the float (* 1500 (-> *display* integral-frame-counter)))))))
|
||||
(shield-color (new 'stack-no-clear 'vector)))
|
||||
(let ((bright-shield-color (new 'stack-no-clear 'vector)))
|
||||
(set-vector! shield-color 0.275 0.1 1.025 1.0)
|
||||
(set-vector! bright-shield-color 0.35 0.1 1.1 1.0)
|
||||
(vector4-lerp! bright-shield-color shield-color bright-shield-color shield-flicker)
|
||||
(cond
|
||||
((= (-> *palette-fade-controls* control 7 fade) 1.0) (set! (-> (the-as (pointer float) state-data) 2) 1.0))
|
||||
((= (-> *palette-fade-controls* control 7 fade) 1.0)
|
||||
(set! (-> (the-as (pointer float) state-data) 2) 1.0))
|
||||
(else
|
||||
(if (not (paused?)) (+! (-> (the-as (pointer float) state-data) 2) -0.1))
|
||||
(if (not (paused?))
|
||||
(+! (-> (the-as (pointer float) state-data) 2) -0.1))
|
||||
(set! (-> (the-as (pointer float) state-data) 2) (fmax 0.0 (fmin 1.0 (-> (the-as (pointer float) state-data) 2))))))
|
||||
(set-vector! shield-color 0.1 0.1 0.1 1.0)
|
||||
(let ((shield-fade (* (-> (the-as (pointer float) state-data) 2) shield-proximity)))
|
||||
(vector4-lerp! shield-color shield-color bright-shield-color shield-fade)
|
||||
(set! (-> context times 7 w) (* (+ 0.8 (/ shield-flicker 10)) shield-fade))))
|
||||
(let ((shield-light (-> groups 0 dir1)))
|
||||
(set! (-> shield-light direction x) 0.0)
|
||||
(set! (-> shield-light direction y) -1.0)
|
||||
(set! (-> shield-light direction z) 0.0)
|
||||
(set! (-> shield-light direction w) 1.0))
|
||||
(set! (-> groups 0 dir1 color quad) (-> shield-color quad)))
|
||||
(set-vector! (-> shield-light direction) 0.0 -1.0 0.0 1.0))
|
||||
(vector-copy! (-> groups 0 dir1 color) shield-color))
|
||||
(set! (-> groups 0 dir1 levels x) 1.0))
|
||||
(else
|
||||
(let ((shield-light (-> groups 0 dir1)))
|
||||
(set! (-> shield-light direction x) 0.0)
|
||||
(set! (-> shield-light direction y) -1.0)
|
||||
(set! (-> shield-light direction z) 0.0)
|
||||
(set! (-> shield-light direction w) 1.0))
|
||||
(set-vector! (-> shield-light direction) 0.0 -1.0 0.0 1.0))
|
||||
(set-vector! (-> groups 0 dir1 color) 0.1 0.1 0.1 1.0)
|
||||
(set! (-> groups 0 dir1 levels x) 1.0))))))
|
||||
(let ((landmark-position (new 'stack-no-clear 'vector))
|
||||
(target-position (target-joint-pos)))
|
||||
0.0
|
||||
(when (< 204800.0 (-> target-position y))
|
||||
(set-vector! landmark-position 11440128.0 (-> target-position y) -19298304.0 1.0)
|
||||
(set-vector! landmark-position (meters 2793) (-> target-position y) -19298304.0 1.0)
|
||||
(let ((distance (vector-vector-distance landmark-position target-position))
|
||||
(groups (-> context light-group)))
|
||||
(when (< distance 172032.0)
|
||||
|
||||
@@ -553,9 +553,6 @@
|
||||
(label output-complete))
|
||||
(none))))
|
||||
|
||||
(#when PC_PORT
|
||||
(def-mips2c time-of-day-interp-colors-scratch (function (pointer rgba) time-of-day-palette mood-context none)))
|
||||
|
||||
(defun init-time-of-day-context ((context time-of-day-context))
|
||||
"Initialize the fixed title-screen directional and ambient light colors and enable their levels."
|
||||
(set-vector! (-> context title-light-group dir0 color) 0.82 0.82 0.82 1.0)
|
||||
|
||||
@@ -0,0 +1,832 @@
|
||||
;;-*-Lisp-*-
|
||||
(in-package goal)
|
||||
(bundles "ENGINE.CGO" "GAME.CGO")
|
||||
(require "engine/gfx/sky/sky-tng.gc")
|
||||
|
||||
;; Reference-only Emotion Engine implementation of the original inline VU0 sky polygon renderer.
|
||||
;; This file is intentionally not part of any project or DGO manifest.
|
||||
|
||||
;; Each sky vertex is three consecutive quadwords:
|
||||
;;
|
||||
;; +0x00 homogeneous position
|
||||
;; +0x10 perspective texture coordinates (s, t, q, unused)
|
||||
;; +0x20 floating-point RGBA
|
||||
;;
|
||||
;; Polygon lists are closed by repeating the first complete 48-byte record after the last distinct
|
||||
;; vertex. render-sky-tri and render-sky-quad transform their input into the scratch pages at
|
||||
;; #x70003000 and #x70003800, preserving STQ and color. draw-large-polygon alternates those pages
|
||||
;; through four Sutherland-Hodgman clipping passes before emitting ST/RGBAQ/XYZF into the DMA
|
||||
;; buffer. The persistent VU0 registers are initialized once per layer:
|
||||
;;
|
||||
;; vf31..vf28 camera rows scaled into the homogeneous clip volume
|
||||
;; vf26 inverse homogeneous scale used after clipping
|
||||
;; vf25 screen/fog offset, with z forced to zero
|
||||
;; vf24 normalized scrolling texture offset
|
||||
;; vf23.x GS layer depth (zero normally, 256 for the base layer)
|
||||
;; vf13 pfog0, fog-min, fog-max, and the 3071 fog ceiling
|
||||
(#unless PC_PORT
|
||||
(asm-data (label sky-fog-ceiling)
|
||||
(word #x453ff000) ;; 3071.0
|
||||
(label sky-screen-offset-2049)
|
||||
(word #x45001000) ;; 2049.0
|
||||
(label sky-texel-phase-scale)
|
||||
(word #x37800000) ;; 1 / 65536
|
||||
(label sky-screen-offset-2047)
|
||||
(word #x44ffe000)) ;; 2047.0
|
||||
(defun init-sky-regs ()
|
||||
"Load the camera, projection, fog, and initial layer state used by the inline VU0 sky path.
|
||||
Select vertical screen offset 2049 when camera translation y is positive and 2047 otherwise."
|
||||
(declare (asm-func none))
|
||||
(rlet ((camera :reg v1)
|
||||
(screen-offset :reg a0)
|
||||
(work :reg a1)
|
||||
(address :reg a2)
|
||||
(function-base :reg fp)
|
||||
(result :reg v0))
|
||||
(add.i sp sp -32)
|
||||
(s.d function-base sp 8)
|
||||
(m function-base t9)
|
||||
(m! camera *math-camera*)
|
||||
(add.i screen-offset sp 16)
|
||||
(s.q r0 screen-offset)
|
||||
(m work screen-offset)
|
||||
(lea.field address camera (hvdf-off))
|
||||
(l.q address address)
|
||||
(s.q address work)
|
||||
(m f0 r0)
|
||||
(l.s.field f1 camera (trans y))
|
||||
(c.lt.s f0 f1)
|
||||
(b.fpf sky-use-2047-offset :delay (nop!))
|
||||
(l.s f0 function-base sky-screen-offset-2049)
|
||||
(s.s f0 screen-offset 4)
|
||||
(m work f0)
|
||||
(b sky-screen-offset-ready :delay (nop!))
|
||||
(label sky-use-2047-offset)
|
||||
(l.s f0 function-base sky-screen-offset-2047)
|
||||
(s.s f0 screen-offset 4)
|
||||
(m work f0)
|
||||
(label sky-screen-offset-ready)
|
||||
;; Keep the fog range beside the runtime texture state so the projection loop can retain it
|
||||
;; in vf13 without further scalar loads.
|
||||
(m! work *sky-tng-data*)
|
||||
(lea.field work work (fog))
|
||||
(l.s.field f0 camera (pfog0))
|
||||
(s.s f0 work)
|
||||
(l.s.field f0 camera (fog-min))
|
||||
(s.s f0 work 4)
|
||||
(l.s.field f0 camera (fog-max))
|
||||
(s.s f0 work 8)
|
||||
(l.s f0 function-base sky-fog-ceiling)
|
||||
(s.s f0 work 12)
|
||||
(asm-block load-persistent-sky-vectors
|
||||
(l.vf vf31 camera 572)
|
||||
(l.vf vf30 camera 588)
|
||||
(l.vf vf29 camera 604)
|
||||
(l.vf vf28 camera 620)
|
||||
(l.vf vf14 camera 700)
|
||||
(l.vf vf26 camera 716)
|
||||
(l.vf vf25 screen-offset)
|
||||
(m! camera *sky-tng-data*)
|
||||
(l.vf vf13 camera 60)
|
||||
(mul.vf vf31 vf31 vf14)
|
||||
(mul.vf vf30 vf30 vf14)
|
||||
(mul.vf vf29 vf29 vf14)
|
||||
(mul.vf vf28 vf28 vf14)
|
||||
(vmove.z vf25 vf0)
|
||||
(vmove.xyzw vf24 vf0)
|
||||
(vmove.xyzw vf23 vf0))
|
||||
(m camera vf23)
|
||||
(m result r0)
|
||||
(l.d function-base sp 8)
|
||||
(jr ra :delay (add.i sp sp 32))
|
||||
(nop! :count 3)))
|
||||
(defun set-tex-offset ((s-offset int) (t-offset int))
|
||||
"Convert wrapped 16-bit texture phases to normalized offsets in vf24.xy; clear z and w."
|
||||
(declare (asm-func none))
|
||||
(rlet ((offset :reg v1)
|
||||
(function-base :reg fp)
|
||||
(result :reg v0))
|
||||
(add.i sp sp -32)
|
||||
(s.d function-base sp 8)
|
||||
(m function-base t9)
|
||||
(add.i offset sp 16)
|
||||
(s.q r0 offset)
|
||||
(l.s f0 function-base sky-texel-phase-scale)
|
||||
(m f1 a0)
|
||||
(cvt.s.w f1 f1)
|
||||
(mul.s f0 f0 f1)
|
||||
(s.s f0 offset)
|
||||
(l.s f0 function-base sky-texel-phase-scale)
|
||||
(m f1 a1)
|
||||
(cvt.s.w f1 f1)
|
||||
(mul.s f0 f0 f1)
|
||||
(s.s f0 offset 4)
|
||||
(m f0 r0)
|
||||
(s.s f0 offset 8)
|
||||
(m f0 r0)
|
||||
(s.s f0 offset 12)
|
||||
(l.vf vf24 offset)
|
||||
(m offset vf24)
|
||||
(m result r0)
|
||||
(l.d function-base sp 8)
|
||||
(jr ra :delay (add.i sp sp 32))
|
||||
(nop! :count 2)))
|
||||
(defun draw-large-polygon ()
|
||||
"Clip the closed scratch polygon against the four side planes, then append its GS vertices.
|
||||
The private calling convention carries the polygon count in t0, the DMA buffer in a1, and
|
||||
the alternating scratch pages in t4 and t5. Return #f if clipping removes every vertex."
|
||||
(declare (asm-func none))
|
||||
(nop!)
|
||||
(add.i sp sp -8)
|
||||
(nop!)
|
||||
(s.d ra sp)
|
||||
;; Sutherland-Hodgman clipping alternates pages so that each pass may stream its output without
|
||||
;; disturbing unread input. t2 selects x or y within each position; the positive helper tests
|
||||
;; component <= w and the negative helper tests component >= -w.
|
||||
(asm-block clip-sky-side-planes
|
||||
(m! t9 clip-polygon-against-positive-hyperplane)
|
||||
(m a2 t4)
|
||||
(m a3 t5)
|
||||
(jalr ra t9 :delay (add t2 a2 r0))
|
||||
(b.z t0 sky-polygon-clipped-away :delay (nop!))
|
||||
(m a2 t5)
|
||||
(m a3 t4)
|
||||
(jalr ra t9 :delay (add.i t2 a2 4))
|
||||
(b.z t0 sky-polygon-clipped-away :delay (m! t9 clip-polygon-against-negative-hyperplane))
|
||||
(m a2 t4)
|
||||
(m a3 t5)
|
||||
(jalr ra t9 :delay (add t2 a2 r0))
|
||||
(b.z t0 sky-polygon-clipped-away :delay (nop!))
|
||||
(m a2 t5)
|
||||
(m a3 t4)
|
||||
(jalr ra t9 :delay (add.i t2 a2 4))
|
||||
(b.z t0 sky-polygon-clipped-away :delay (l.w.field a3 a1 (base))))
|
||||
;; vf27 is the GIF tag for this polygon. Its first word is replaced by the clipped vertex
|
||||
;; count before ST/RGBAQ/XYZF records are written behind it.
|
||||
(m a2 t4)
|
||||
(nop!)
|
||||
(s.vf vf27 a3)
|
||||
(add.i a3 a3 16)
|
||||
(s.w t0 a3 -16)
|
||||
(nop!)
|
||||
(label emit-sky-polygon-vertices)
|
||||
(asm-block project-sky-vertex
|
||||
(l.vf vf1 a2)
|
||||
(nop!)
|
||||
(l.vf vf2 a2 16)
|
||||
(nop!)
|
||||
(l.vf vf3 a2 32)
|
||||
;; Recover 1/w after clipping, undo the homogeneous clip scale, and convert the packed color.
|
||||
(vdiv Q vf0.w vf1.w)
|
||||
(mul.vf vf1 vf1 vf26)
|
||||
(nop!)
|
||||
(ftoi.vf vf3 vf3)
|
||||
(nop!)
|
||||
;; Add the scrolling phase before perspective division so STQ remains perspective correct.
|
||||
(add.vf vf2 vf2 vf24)
|
||||
(nop!)
|
||||
(waitq)
|
||||
(nop!)
|
||||
(vmulq.xyz vf1 vf1 Q)
|
||||
(s.vf vf3 a3 16)
|
||||
(vmulq.xyzw vf2 vf2 Q)
|
||||
(add.i a2 a2 48)
|
||||
;; Map to GS screen space. vf23.x selects the layer depth, while w becomes the clamped fog
|
||||
;; value carried in XYZF after 12.4 fixed-point conversion.
|
||||
(add.vf vf1 vf1 vf25)
|
||||
(add.i a3 a3 48)
|
||||
(vmulz.z vf1 vf1 vf0)
|
||||
(nop!)
|
||||
(vminiz.w vf1 vf1 vf13)
|
||||
(nop!)
|
||||
(vaddx.z vf1 vf1 vf23)
|
||||
(nop!)
|
||||
(vmaxy.w vf1 vf1 vf13)
|
||||
(nop!)
|
||||
(s.vf vf2 a3 -48)
|
||||
(add.i t0 t0 -1)
|
||||
(vftoi4.xyzw vf1 vf1)
|
||||
(nop!)
|
||||
(b.nz t0 emit-sky-polygon-vertices :delay (s.vf vf1 a3 -16)))
|
||||
(s.w.field a3 a1 (base))
|
||||
(nop!)
|
||||
(l.d ra sp)
|
||||
(add.i v0 s7 8)
|
||||
(jr ra :delay (add.i sp sp 8))
|
||||
(label sky-polygon-clipped-away)
|
||||
(l.d ra sp)
|
||||
(m v0 s7)
|
||||
(jr ra :delay (add.i sp sp 8))
|
||||
(jr ra :delay (add sp sp r0))
|
||||
(nop! :count 2))
|
||||
(defun clip-polygon-against-positive-hyperplane ()
|
||||
"Clip a closed scratch polygon against component <= w. t2 points at the selected x or y
|
||||
component of the first position, a2 and a3 are the input and output pages, and t0 is replaced
|
||||
by the output vertex count. Every crossing interpolates position, STQ, and color together."
|
||||
(declare (asm-func none))
|
||||
(asm-block classify-first-positive-vertex
|
||||
(nop!)
|
||||
(m t1 t0)
|
||||
(add.i t0 r0 0)
|
||||
(l.s f1 t2)
|
||||
(add.i t2 t2 48)
|
||||
(l.s f0 a2 12)
|
||||
(m t3 a3)
|
||||
(l.vf vf1 a2)
|
||||
(add.i a2 a2 48)
|
||||
(c.lt.s f0 f1)
|
||||
(l.vf vf2 a2 -32)
|
||||
(b.fpf positive-inside-a :delay (l.vf vf3 a2 -16)))
|
||||
;; The a/b paths alternate vf1..vf3 and vf4..vf6 as the previous and current records. This
|
||||
;; avoids moving the three qwords at every edge while retaining the closed-list traversal.
|
||||
(asm-block walk-positive-outside
|
||||
(label positive-outside-a)
|
||||
(l.s f3 t2)
|
||||
(add.i t2 t2 48)
|
||||
(l.s f2 a2 12)
|
||||
(add.i t1 t1 -1)
|
||||
(l.vf vf4 a2)
|
||||
(add.i a2 a2 48)
|
||||
(c.lt.s f2 f3)
|
||||
(l.vf vf5 a2 -32)
|
||||
(b.fpf positive-enter-from-a :delay (l.vf vf6 a2 -16))
|
||||
(b.z t1 positive-clip-finish :delay (nop!))
|
||||
(label positive-outside-b)
|
||||
(l.s f1 t2)
|
||||
(add.i t2 t2 48)
|
||||
(l.s f0 a2 12)
|
||||
(add.i t1 t1 -1)
|
||||
(l.vf vf1 a2)
|
||||
(add.i a2 a2 48)
|
||||
(c.lt.s f0 f1)
|
||||
(l.vf vf2 a2 -32)
|
||||
(b.fpf positive-enter-from-b :delay (l.vf vf3 a2 -16))
|
||||
(b.nz t1 positive-outside-a :delay (nop!))
|
||||
(b positive-clip-finish :delay (nop!))
|
||||
;; Outside -> inside: solve the plane distance linearly and append only the crossing point.
|
||||
;; The inside endpoint remains current and is emitted by the following inside path.
|
||||
(label positive-enter-from-a)
|
||||
(sub.s f7 f0 f1)
|
||||
(sub.vf vf7 vf4 vf1)
|
||||
(sub.s f8 f2 f3)
|
||||
(sub.vf vf8 vf5 vf2)
|
||||
(sub.s f5 f7 f8)
|
||||
(sub.vf vf9 vf6 vf3)
|
||||
(div.s f6 f7 f5)
|
||||
(add.i a3 a3 48)
|
||||
(m v1 f6)
|
||||
(m vf10 v1)
|
||||
(add.i t0 t0 1)
|
||||
(mula.w.vf vf1 vf0)
|
||||
(add.i t6 s7 8)
|
||||
(vmaddx.xyzw vf7 vf7 vf10)
|
||||
(nop!)
|
||||
(mula.w.vf vf2 vf0)
|
||||
(nop!)
|
||||
(vmaddx.xyzw vf8 vf8 vf10)
|
||||
(nop!)
|
||||
(mula.w.vf vf3 vf0)
|
||||
(nop!)
|
||||
(vmaddx.xyzw vf9 vf9 vf10)
|
||||
(nop!)
|
||||
(s.vf vf7 a3 -48)
|
||||
(nop!)
|
||||
(s.vf vf8 a3 -32)
|
||||
(nop!)
|
||||
(b.nz t1 positive-inside-b :delay (s.vf vf9 a3 -16))
|
||||
(b positive-clip-finish :delay (nop!))
|
||||
(label positive-enter-from-b)
|
||||
(sub.s f7 f0 f1)
|
||||
(sub.vf vf7 vf1 vf4)
|
||||
(sub.s f8 f2 f3)
|
||||
(sub.vf vf8 vf2 vf5)
|
||||
(sub.s f5 f8 f7)
|
||||
(sub.vf vf9 vf3 vf6)
|
||||
(div.s f6 f8 f5)
|
||||
(add.i a3 a3 48)
|
||||
(m v1 f6)
|
||||
(m vf10 v1)
|
||||
(add.i t0 t0 1)
|
||||
(mula.w.vf vf4 vf0)
|
||||
(add.i t6 s7 8)
|
||||
(vmaddx.xyzw vf7 vf7 vf10)
|
||||
(nop!)
|
||||
(mula.w.vf vf5 vf0)
|
||||
(nop!)
|
||||
(vmaddx.xyzw vf8 vf8 vf10)
|
||||
(nop!)
|
||||
(mula.w.vf vf6 vf0)
|
||||
(nop!)
|
||||
(vmaddx.xyzw vf9 vf9 vf10)
|
||||
(nop!)
|
||||
(s.vf vf7 a3 -48)
|
||||
(nop!)
|
||||
(s.vf vf8 a3 -32)
|
||||
(nop!)
|
||||
(b.z t1 positive-clip-finish :delay (s.vf vf9 a3 -16)))
|
||||
;; Inside -> inside copies the previous record. If the next record is outside, the leave path
|
||||
;; copies the inside endpoint and appends the crossing point as a second record.
|
||||
(asm-block walk-positive-inside
|
||||
(label positive-inside-a)
|
||||
(l.s f3 t2)
|
||||
(add.i t2 t2 48)
|
||||
(l.s f2 a2 12)
|
||||
(add.i t1 t1 -1)
|
||||
(l.vf vf4 a2)
|
||||
(add.i a2 a2 48)
|
||||
(c.lt.s f2 f3)
|
||||
(l.vf vf5 a2 -32)
|
||||
(b.fpt positive-leave-from-a :delay (l.vf vf6 a2 -16))
|
||||
(s.vf vf1 a3)
|
||||
(add.i a3 a3 48)
|
||||
(s.vf vf2 a3 -32)
|
||||
(add.i t0 t0 1)
|
||||
(b.z t1 positive-clip-finish :delay (s.vf vf3 a3 -16))
|
||||
(label positive-inside-b)
|
||||
(l.s f1 t2)
|
||||
(add.i t2 t2 48)
|
||||
(l.s f0 a2 12)
|
||||
(add.i t1 t1 -1)
|
||||
(l.vf vf1 a2)
|
||||
(add.i a2 a2 48)
|
||||
(c.lt.s f0 f1)
|
||||
(l.vf vf2 a2 -32)
|
||||
(b.fpt positive-leave-from-b :delay (l.vf vf3 a2 -16))
|
||||
(s.vf vf4 a3)
|
||||
(add.i a3 a3 48)
|
||||
(s.vf vf5 a3 -32)
|
||||
(add.i t0 t0 1)
|
||||
(b.nz t1 positive-inside-a :delay (s.vf vf6 a3 -16))
|
||||
(b positive-clip-finish :delay (nop!))
|
||||
(label positive-leave-from-a)
|
||||
(sub.s f7 f0 f1)
|
||||
(sub.vf vf7 vf1 vf4)
|
||||
(sub.s f8 f2 f3)
|
||||
(sub.vf vf8 vf2 vf5)
|
||||
(sub.s f5 f8 f7)
|
||||
(sub.vf vf9 vf3 vf6)
|
||||
(div.s f6 f8 f5)
|
||||
(add.i a3 a3 96)
|
||||
(m v1 f6)
|
||||
(m vf10 v1)
|
||||
(s.vf vf1 a3 -96)
|
||||
(mula.w.vf vf4 vf0)
|
||||
(s.vf vf2 a3 -80)
|
||||
(vmaddx.xyzw vf7 vf7 vf10)
|
||||
(s.vf vf3 a3 -64)
|
||||
(mula.w.vf vf5 vf0)
|
||||
(add.i t0 t0 2)
|
||||
(vmaddx.xyzw vf8 vf8 vf10)
|
||||
(add.i t6 s7 8)
|
||||
(mula.w.vf vf6 vf0)
|
||||
(nop!)
|
||||
(vmaddx.xyzw vf9 vf9 vf10)
|
||||
(nop!)
|
||||
(s.vf vf7 a3 -48)
|
||||
(nop!)
|
||||
(s.vf vf8 a3 -32)
|
||||
(nop!)
|
||||
(b.nz t1 positive-outside-b :delay (s.vf vf9 a3 -16))
|
||||
(b positive-clip-finish :delay (nop!))
|
||||
(label positive-leave-from-b)
|
||||
(sub.s f7 f0 f1)
|
||||
(sub.vf vf7 vf4 vf1)
|
||||
(sub.s f8 f2 f3)
|
||||
(sub.vf vf8 vf5 vf2)
|
||||
(sub.s f5 f7 f8)
|
||||
(sub.vf vf9 vf6 vf3)
|
||||
(div.s f6 f7 f5)
|
||||
(add.i a3 a3 96)
|
||||
(m v1 f6)
|
||||
(m vf10 v1)
|
||||
(s.vf vf4 a3 -96)
|
||||
(mula.w.vf vf1 vf0)
|
||||
(s.vf vf5 a3 -80)
|
||||
(vmaddx.xyzw vf7 vf7 vf10)
|
||||
(s.vf vf6 a3 -64)
|
||||
(mula.w.vf vf2 vf0)
|
||||
(add.i t0 t0 2)
|
||||
(vmaddx.xyzw vf8 vf8 vf10)
|
||||
(add.i t6 s7 8)
|
||||
(mula.w.vf vf3 vf0)
|
||||
(nop!)
|
||||
(vmaddx.xyzw vf9 vf9 vf10)
|
||||
(nop!)
|
||||
(s.vf vf7 a3 -48)
|
||||
(nop!)
|
||||
(s.vf vf8 a3 -32)
|
||||
(nop!)
|
||||
(b.nz t1 positive-outside-a :delay (s.vf vf9 a3 -16)))
|
||||
;; Restore the closed representation expected by the next clipping pass.
|
||||
(asm-block close-positive-polygon
|
||||
(label positive-clip-finish)
|
||||
(l.vf vf1 t3)
|
||||
(nop!)
|
||||
(l.vf vf2 t3 16)
|
||||
(nop!)
|
||||
(l.vf vf3 t3 32)
|
||||
(nop!)
|
||||
(s.vf vf1 a3)
|
||||
(nop!)
|
||||
(s.vf vf2 a3 16)
|
||||
(nop!)
|
||||
(jr ra :delay (s.vf vf3 a3 32))
|
||||
(jr ra :delay (add sp sp r0))
|
||||
(nop! :count 2)))
|
||||
(defun clip-polygon-against-negative-hyperplane ()
|
||||
"Clip a closed scratch polygon against component >= -w. This is the negative-plane mirror of
|
||||
clip-polygon-against-positive-hyperplane and uses the same private registers and closed output
|
||||
format."
|
||||
(declare (asm-func none))
|
||||
(asm-block classify-first-negative-vertex
|
||||
(nop!)
|
||||
(m t1 t0)
|
||||
(add.i t0 r0 0)
|
||||
(l.s f0 a2 12)
|
||||
(m t3 a3)
|
||||
(l.s f1 t2)
|
||||
(add.i t2 t2 48)
|
||||
(l.vf vf1 a2)
|
||||
(neg.s f0 f0)
|
||||
(nop!)
|
||||
(l.vf vf2 a2 16)
|
||||
(c.lt.s f1 f0)
|
||||
(add.i a2 a2 48)
|
||||
(b.fpf negative-inside-a :delay (l.vf vf3 a2 -16)))
|
||||
;; The two paths alternate register triples instead of copying the current 48-byte record.
|
||||
(asm-block walk-negative-outside
|
||||
(label negative-outside-a)
|
||||
(l.s f2 a2 12)
|
||||
(add.i t1 t1 -1)
|
||||
(l.s f3 t2)
|
||||
(add.i t2 t2 48)
|
||||
(l.vf vf4 a2)
|
||||
(neg.s f2 f2)
|
||||
(nop!)
|
||||
(l.vf vf5 a2 16)
|
||||
(c.lt.s f3 f2)
|
||||
(add.i a2 a2 48)
|
||||
(b.fpf negative-enter-from-a :delay (l.vf vf6 a2 -16))
|
||||
(b.z t1 negative-clip-finish :delay (nop!))
|
||||
(label negative-outside-b)
|
||||
(l.s f0 a2 12)
|
||||
(add.i t1 t1 -1)
|
||||
(l.s f1 t2)
|
||||
(add.i t2 t2 48)
|
||||
(l.vf vf1 a2)
|
||||
(neg.s f0 f0)
|
||||
(nop!)
|
||||
(l.vf vf2 a2 16)
|
||||
(c.lt.s f1 f0)
|
||||
(add.i a2 a2 48)
|
||||
(b.fpf negative-enter-from-b :delay (l.vf vf3 a2 -16))
|
||||
(b.nz t1 negative-outside-a :delay (nop!))
|
||||
(b negative-clip-finish :delay (nop!))
|
||||
;; Outside -> inside writes the interpolated crossing. f6 is the edge fraction measured from
|
||||
;; the outside endpoint; the same fraction is applied to position, STQ, and color.
|
||||
(label negative-enter-from-a)
|
||||
(sub.s f7 f0 f1)
|
||||
(sub.vf vf7 vf4 vf1)
|
||||
(sub.s f8 f2 f3)
|
||||
(sub.vf vf8 vf5 vf2)
|
||||
(sub.s f5 f7 f8)
|
||||
(sub.vf vf9 vf6 vf3)
|
||||
(div.s f6 f7 f5)
|
||||
(add.i a3 a3 48)
|
||||
(m v1 f6)
|
||||
(m vf10 v1)
|
||||
(add.i t0 t0 1)
|
||||
(mula.w.vf vf1 vf0)
|
||||
(add.i t6 s7 8)
|
||||
(vmaddx.xyzw vf7 vf7 vf10)
|
||||
(nop!)
|
||||
(mula.w.vf vf2 vf0)
|
||||
(nop!)
|
||||
(vmaddx.xyzw vf8 vf8 vf10)
|
||||
(nop!)
|
||||
(mula.w.vf vf3 vf0)
|
||||
(nop!)
|
||||
(vmaddx.xyzw vf9 vf9 vf10)
|
||||
(nop!)
|
||||
(s.vf vf7 a3 -48)
|
||||
(nop!)
|
||||
(s.vf vf8 a3 -32)
|
||||
(nop!)
|
||||
(b.nz t1 negative-inside-b :delay (s.vf vf9 a3 -16))
|
||||
(b negative-clip-finish :delay (nop!))
|
||||
(label negative-enter-from-b)
|
||||
(sub.s f7 f0 f1)
|
||||
(sub.vf vf7 vf1 vf4)
|
||||
(sub.s f8 f2 f3)
|
||||
(sub.vf vf8 vf2 vf5)
|
||||
(sub.s f5 f8 f7)
|
||||
(sub.vf vf9 vf3 vf6)
|
||||
(div.s f6 f8 f5)
|
||||
(add.i a3 a3 48)
|
||||
(m v1 f6)
|
||||
(m vf10 v1)
|
||||
(add.i t0 t0 1)
|
||||
(mula.w.vf vf4 vf0)
|
||||
(add.i t6 s7 8)
|
||||
(vmaddx.xyzw vf7 vf7 vf10)
|
||||
(nop!)
|
||||
(mula.w.vf vf5 vf0)
|
||||
(nop!)
|
||||
(vmaddx.xyzw vf8 vf8 vf10)
|
||||
(nop!)
|
||||
(mula.w.vf vf6 vf0)
|
||||
(nop!)
|
||||
(vmaddx.xyzw vf9 vf9 vf10)
|
||||
(nop!)
|
||||
(s.vf vf7 a3 -48)
|
||||
(nop!)
|
||||
(s.vf vf8 a3 -32)
|
||||
(nop!)
|
||||
(b.z t1 negative-clip-finish :delay (s.vf vf9 a3 -16)))
|
||||
;; Inside runs copy their previous record. A leaving edge emits the inside endpoint followed
|
||||
;; by the intersection, which is why those paths advance the output by two records.
|
||||
(asm-block walk-negative-inside
|
||||
(label negative-inside-a)
|
||||
(l.s f2 a2 12)
|
||||
(add.i t1 t1 -1)
|
||||
(l.s f3 t2)
|
||||
(add.i t2 t2 48)
|
||||
(l.vf vf4 a2)
|
||||
(neg.s f2 f2)
|
||||
(nop!)
|
||||
(l.vf vf5 a2 16)
|
||||
(c.lt.s f3 f2)
|
||||
(add.i a2 a2 48)
|
||||
(b.fpt negative-leave-from-a :delay (l.vf vf6 a2 -16))
|
||||
(s.vf vf1 a3)
|
||||
(add.i a3 a3 48)
|
||||
(s.vf vf2 a3 -32)
|
||||
(add.i t0 t0 1)
|
||||
(b.z t1 negative-clip-finish :delay (s.vf vf3 a3 -16))
|
||||
(label negative-inside-b)
|
||||
(l.s f0 a2 12)
|
||||
(add.i t1 t1 -1)
|
||||
(l.s f1 t2)
|
||||
(add.i t2 t2 48)
|
||||
(l.vf vf1 a2)
|
||||
(neg.s f0 f0)
|
||||
(nop!)
|
||||
(l.vf vf2 a2 16)
|
||||
(c.lt.s f1 f0)
|
||||
(add.i a2 a2 48)
|
||||
(b.fpt negative-leave-from-b :delay (l.vf vf3 a2 -16))
|
||||
(s.vf vf4 a3)
|
||||
(add.i a3 a3 48)
|
||||
(s.vf vf5 a3 -32)
|
||||
(add.i t0 t0 1)
|
||||
(b.nz t1 negative-inside-a :delay (s.vf vf6 a3 -16))
|
||||
(b negative-clip-finish :delay (nop!))
|
||||
(label negative-leave-from-a)
|
||||
(sub.s f7 f0 f1)
|
||||
(sub.vf vf7 vf1 vf4)
|
||||
(sub.s f8 f2 f3)
|
||||
(sub.vf vf8 vf2 vf5)
|
||||
(sub.s f5 f8 f7)
|
||||
(sub.vf vf9 vf3 vf6)
|
||||
(div.s f6 f8 f5)
|
||||
(add.i a3 a3 96)
|
||||
(m v1 f6)
|
||||
(m vf10 v1)
|
||||
(s.vf vf1 a3 -96)
|
||||
(mula.w.vf vf4 vf0)
|
||||
(s.vf vf2 a3 -80)
|
||||
(vmaddx.xyzw vf7 vf7 vf10)
|
||||
(s.vf vf3 a3 -64)
|
||||
(mula.w.vf vf5 vf0)
|
||||
(add.i t0 t0 2)
|
||||
(vmaddx.xyzw vf8 vf8 vf10)
|
||||
(add.i t6 s7 8)
|
||||
(mula.w.vf vf6 vf0)
|
||||
(nop!)
|
||||
(vmaddx.xyzw vf9 vf9 vf10)
|
||||
(nop!)
|
||||
(s.vf vf7 a3 -48)
|
||||
(nop!)
|
||||
(s.vf vf8 a3 -32)
|
||||
(nop!)
|
||||
(b.nz t1 negative-outside-b :delay (s.vf vf9 a3 -16))
|
||||
(b negative-clip-finish :delay (nop!))
|
||||
(label negative-leave-from-b)
|
||||
(sub.s f7 f0 f1)
|
||||
(sub.vf vf7 vf4 vf1)
|
||||
(sub.s f8 f2 f3)
|
||||
(sub.vf vf8 vf5 vf2)
|
||||
(sub.s f5 f7 f8)
|
||||
(sub.vf vf9 vf6 vf3)
|
||||
(div.s f6 f7 f5)
|
||||
(add.i a3 a3 96)
|
||||
(m v1 f6)
|
||||
(m vf10 v1)
|
||||
(s.vf vf4 a3 -96)
|
||||
(mula.w.vf vf1 vf0)
|
||||
(s.vf vf5 a3 -80)
|
||||
(vmaddx.xyzw vf7 vf7 vf10)
|
||||
(s.vf vf6 a3 -64)
|
||||
(mula.w.vf vf2 vf0)
|
||||
(add.i t0 t0 2)
|
||||
(vmaddx.xyzw vf8 vf8 vf10)
|
||||
(add.i t6 s7 8)
|
||||
(mula.w.vf vf3 vf0)
|
||||
(nop!)
|
||||
(vmaddx.xyzw vf9 vf9 vf10)
|
||||
(nop!)
|
||||
(s.vf vf7 a3 -48)
|
||||
(nop!)
|
||||
(s.vf vf8 a3 -32)
|
||||
(nop!)
|
||||
(b.nz t1 negative-outside-a :delay (s.vf vf9 a3 -16)))
|
||||
(asm-block close-negative-polygon
|
||||
(label negative-clip-finish)
|
||||
(l.vf vf1 t3)
|
||||
(nop!)
|
||||
(l.vf vf2 t3 16)
|
||||
(nop!)
|
||||
(l.vf vf3 t3 32)
|
||||
(nop!)
|
||||
(s.vf vf1 a3)
|
||||
(nop!)
|
||||
(s.vf vf2 a3 16)
|
||||
(nop!)
|
||||
(jr ra :delay (s.vf vf3 a3 32))
|
||||
(jr ra :delay (add sp sp r0))
|
||||
(nop! :count 2)))
|
||||
(defun render-sky-quad ((vertices (inline-array sky-vertex)) (dma-buf dma-buffer))
|
||||
"Transform four sky vertices into a closed five-record scratch polygon and tail-call the
|
||||
clipping and packet conversion path."
|
||||
(declare (asm-func none))
|
||||
;; vf31..vf28 are the persistent camera rows from init-sky-regs. Only x, y, and w are retained;
|
||||
;; z is cleared so the final layer depth is supplied explicitly by vf23.x.
|
||||
(asm-block prepare-sky-quad
|
||||
(m v1 a0)
|
||||
(m! v1 *math-camera*)
|
||||
;; Refresh the homogeneous scale with the rest of the camera state before building the page.
|
||||
(l.vf vf14 v1 700)
|
||||
(lui t4 #x7000)
|
||||
(ori t4 t4 #x3000)
|
||||
(lui t5 #x7000)
|
||||
(ori t5 t5 #x3800)
|
||||
(lui v1 #x3000)
|
||||
(m a3 t4)
|
||||
(or a0 a0 v1)
|
||||
(nop!)
|
||||
(l.vf vf1 a0)
|
||||
(add.i t0 r0 4)
|
||||
(l.vf vf2 a0 16)
|
||||
(nop!)
|
||||
(l.vf vf3 a0 32)
|
||||
(mula.x.vf vf31 vf1)
|
||||
(l.vf vf4 a0 48)
|
||||
(madda.y.vf vf30 vf1)
|
||||
(l.vf vf5 a0 64)
|
||||
(madda.z.vf vf29 vf1)
|
||||
(l.vf vf6 a0 80)
|
||||
(vmaddw.xyw vf1 vf28 vf1)
|
||||
(l.vf vf7 a0 96)
|
||||
(vmove.z vf1 vf0)
|
||||
(l.vf vf8 a0 112)
|
||||
(mula.x.vf vf31 vf4)
|
||||
(l.vf vf9 a0 128)
|
||||
(madda.y.vf vf30 vf4)
|
||||
(l.vf vf10 a0 144)
|
||||
(madda.z.vf vf29 vf4)
|
||||
(l.vf vf11 a0 160)
|
||||
(vmaddw.xyw vf4 vf28 vf4)
|
||||
(l.vf vf12 a0 176)
|
||||
(vmove.z vf4 vf0))
|
||||
(asm-block finish-sky-quad
|
||||
(s.vf vf2 a3 16)
|
||||
(mula.x.vf vf31 vf7)
|
||||
(s.vf vf3 a3 32)
|
||||
(madda.y.vf vf30 vf7)
|
||||
(s.vf vf5 a3 64)
|
||||
(madda.z.vf vf29 vf7)
|
||||
(s.vf vf6 a3 80)
|
||||
(vmaddw.xyw vf7 vf28 vf7)
|
||||
(s.vf vf8 a3 112)
|
||||
(vmove.z vf7 vf0)
|
||||
(s.vf vf9 a3 128)
|
||||
(mula.x.vf vf31 vf10)
|
||||
(s.vf vf11 a3 160)
|
||||
(madda.y.vf vf30 vf10)
|
||||
(s.vf vf12 a3 176)
|
||||
(madda.z.vf vf29 vf10)
|
||||
(s.vf vf2 a3 208)
|
||||
(vmaddw.xyw vf10 vf28 vf10)
|
||||
(s.vf vf3 a3 224)
|
||||
(vmove.z vf10 vf0)
|
||||
(s.vf vf1 a3)
|
||||
(nop!)
|
||||
;; Repeat record zero after record three to close the list.
|
||||
(s.vf vf1 a3 192)
|
||||
(nop!)
|
||||
(s.vf vf4 a3 48)
|
||||
(nop!)
|
||||
(s.vf vf7 a3 96)
|
||||
(nop!)
|
||||
(s.vf vf10 a3 144)
|
||||
(m! t9 draw-large-polygon)
|
||||
(jr t9 :delay (nop!))
|
||||
(jr ra :delay (add sp sp r0))
|
||||
(nop! :count 2)))
|
||||
(defun render-sky-tri ((vertices (inline-array sky-vertex)) (dma-buf dma-buffer))
|
||||
"Transform three sky vertices into a closed four-record scratch polygon and tail-call the
|
||||
clipping and packet conversion path."
|
||||
(declare (asm-func none))
|
||||
(asm-block prepare-sky-triangle
|
||||
(m v1 a0)
|
||||
(lui t4 #x7000)
|
||||
(ori t4 t4 #x3000)
|
||||
(lui t5 #x7000)
|
||||
(ori t5 t5 #x3800)
|
||||
(lui v1 #x3000)
|
||||
(m a3 t4)
|
||||
(or a0 a0 v1)
|
||||
(nop!)
|
||||
(l.vf vf1 a0)
|
||||
(add.i t0 r0 3)
|
||||
(l.vf vf2 a0 16)
|
||||
(nop!)
|
||||
(l.vf vf3 a0 32)
|
||||
(mula.x.vf vf31 vf1)
|
||||
(l.vf vf4 a0 48)
|
||||
(madda.y.vf vf30 vf1)
|
||||
(l.vf vf5 a0 64)
|
||||
(madda.z.vf vf29 vf1)
|
||||
(l.vf vf6 a0 80)
|
||||
(vmaddw.xyw vf1 vf28 vf1)
|
||||
(l.vf vf7 a0 96)
|
||||
(vmove.z vf1 vf0)
|
||||
(l.vf vf8 a0 112)
|
||||
(mula.x.vf vf31 vf4)
|
||||
(l.vf vf9 a0 128)
|
||||
(madda.y.vf vf30 vf4)
|
||||
(s.vf vf2 a3 16)
|
||||
(madda.z.vf vf29 vf4)
|
||||
(s.vf vf3 a3 32)
|
||||
(vmaddw.xyw vf4 vf28 vf4)
|
||||
(s.vf vf5 a3 64)
|
||||
(vmove.z vf4 vf0)
|
||||
(s.vf vf6 a3 80)
|
||||
(mula.x.vf vf31 vf7)
|
||||
(s.vf vf8 a3 112)
|
||||
(madda.y.vf vf30 vf7)
|
||||
(s.vf vf9 a3 128)
|
||||
(madda.z.vf vf29 vf7)
|
||||
(s.vf vf2 a3 160)
|
||||
(vmaddw.xyw vf7 vf28 vf7)
|
||||
(s.vf vf3 a3 176)
|
||||
(vmove.z vf7 vf0)
|
||||
(s.vf vf1 a3)
|
||||
(nop!)
|
||||
;; Repeat record zero after record two to close the list.
|
||||
(s.vf vf1 a3 144)
|
||||
(nop!)
|
||||
(s.vf vf4 a3 48)
|
||||
(nop!)
|
||||
(s.vf vf7 a3 96)
|
||||
(m! t9 draw-large-polygon)
|
||||
(jr t9 :delay (nop!))
|
||||
(jr ra :delay (add sp sp r0))
|
||||
(nop! :count 2)))
|
||||
(defun sky-duplicate-polys ((dma-buf dma-buffer) (begin (pointer uint128)) (end (pointer uint128)))
|
||||
"Append the half-open quadword range [begin, end) to dma-buf. An empty or reversed range writes
|
||||
nothing."
|
||||
(declare (asm-func none))
|
||||
(rlet ((cursor :reg v1)
|
||||
(quad :reg a3 :class i128)
|
||||
(result :reg v0))
|
||||
(l.w.field cursor a0 (base))
|
||||
(b sky-duplicate-test :delay (nop!))
|
||||
(label sky-duplicate-copy)
|
||||
(l.q quad a1)
|
||||
(s.q quad cursor)
|
||||
(add.i cursor cursor 16)
|
||||
(add.i a1 a1 16)
|
||||
(label sky-duplicate-test)
|
||||
(slt a3 a1 a2)
|
||||
(b.nz a3 sky-duplicate-copy :delay (nop!))
|
||||
(m a1 s7)
|
||||
(s.w.field cursor a0 (base))
|
||||
(m result r0)
|
||||
(jr ra :delay (add sp sp r0))
|
||||
(nop! :count 2)))
|
||||
(defun close-sky-buffer ((dma-buf dma-buffer))
|
||||
"Append the #x8000 terminator for a large-polygon stream and advance the buffer by one qword."
|
||||
(declare (asm-func none))
|
||||
(rlet ((terminator :reg v1)
|
||||
(cursor :reg v0))
|
||||
(nop!)
|
||||
(ori terminator r0 #x8000)
|
||||
(l.w.field cursor a0 (base))
|
||||
(s.q r0 cursor)
|
||||
(nop!)
|
||||
(s.w terminator cursor)
|
||||
(add.i cursor cursor 16)
|
||||
(jr ra :delay (s.w.field cursor a0 (base)))
|
||||
(jr ra :delay (add sp sp r0))
|
||||
(nop! :count 2))))
|
||||
+459
-1067
File diff suppressed because it is too large
Load Diff
@@ -2,6 +2,7 @@
|
||||
(in-package goal)
|
||||
(bundles "ENGINE.CGO" "GAME.CGO")
|
||||
(require "engine/gfx/sky/sky-h.gc")
|
||||
|
||||
(defun sky-set-sun-radii ((parms sky-parms) (index sky-sun-index) (sun-radius float) (halo-radius float) (aurora-radius float))
|
||||
"Set the apparent sun, halo, and aurora radii in the sun record selected by index's low bit."
|
||||
(let ((sun-index (logand index (sky-sun-index green-sun))))
|
||||
|
||||
@@ -54,17 +54,20 @@
|
||||
"Point dst-light toward the selected sun or moon, assign light-color's RGB bytes as normalized
|
||||
floats while replacing its alpha with 1, and enable the light's first level."
|
||||
(let* ((orbit-data (-> parms orbit orbit-index))
|
||||
(body-data (if (= orbit-index (sky-orbit-index moon)) (-> parms upload-data moon) (-> parms upload-data sun orbit-index)))
|
||||
(body-data (if (= orbit-index (sky-orbit-index moon))
|
||||
(-> parms upload-data moon)
|
||||
(-> parms upload-data sun orbit-index)))
|
||||
(byte-to-float 0.003921569)
|
||||
(inverse-distance (/ 1.0 (-> orbit-data dist)))
|
||||
(dst dst-light))
|
||||
(set! (-> dst direction x) (* (-> (the-as sky-sun-data body-data) pos x) inverse-distance))
|
||||
(set! (-> dst direction y) (* (-> (the-as sky-sun-data body-data) pos y) inverse-distance))
|
||||
(set! (-> dst direction z) (* (-> (the-as sky-sun-data body-data) pos z) inverse-distance))
|
||||
(set! (-> dst color x) (* (the float (-> light-color r)) byte-to-float))
|
||||
(set! (-> dst color y) (* (the float (-> light-color g)) byte-to-float))
|
||||
(set! (-> dst color z) (* (the float (-> light-color b)) byte-to-float))
|
||||
(set! (-> dst color w) 1.0)
|
||||
(set-vector! (-> dst color)
|
||||
(* (the float (-> light-color r)) byte-to-float)
|
||||
(* (the float (-> light-color g)) byte-to-float)
|
||||
(* (the float (-> light-color b)) byte-to-float)
|
||||
1.0)
|
||||
(set! (-> dst levels x) 1.0))
|
||||
(none))
|
||||
|
||||
@@ -359,228 +362,64 @@
|
||||
(vu-pair (nop) (nop)) ;; #x0cc
|
||||
))
|
||||
|
||||
(#unless PC_PORT
|
||||
;; Function-relative constants used while constructing the per-frame VIF and GIF records.
|
||||
(asm-data (label sky-radius)
|
||||
(word #x4a7a0000) ;; 4096000.0
|
||||
(label sky-no-kick)
|
||||
(word #x45400000) ;; 3072.0, which becomes the GS ADC bit after FTOI4
|
||||
(label sky-sun-strip-tag)
|
||||
(word #x00008022 #x20264000)
|
||||
(label sky-sun-fan-tag)
|
||||
(word #x00008012 #x2026c000)
|
||||
(label sky-alpha-tag)
|
||||
(word #x00000001 #x10000000))
|
||||
(defun sky-add-frame-data ((dma-buf dma-buffer) (unused object))
|
||||
"Append the 18-qword frame block, update its lighting and celestial upload image, and append the
|
||||
VIF reference that transfers the 27 celestial-data qwords to VU address 256."
|
||||
(declare (asm-func none) (allow-saved-regs))
|
||||
;; sky-frame-data is uploaded to VU address 291. Its first seven qwords contain the camera
|
||||
;; transform, projection scale/offset, fog scale, legacy 4096000 radius field, and ADC no-kick
|
||||
;; value. strip-giftag and save[5] are left untouched; this program loads the shared color A+D
|
||||
;; record and the later sun-specific fan, strip, and alpha records.
|
||||
(rlet ((buffer :reg gp)
|
||||
(frame-qwc :reg v1)
|
||||
(cursor :reg a1)
|
||||
(camera :reg a2)
|
||||
(function-base :reg fp)
|
||||
(result :reg v0))
|
||||
(add.i sp sp -32)
|
||||
(s.d ra sp)
|
||||
(s.d function-base sp 8)
|
||||
(m function-base t9)
|
||||
(s.q buffer sp 16)
|
||||
(m buffer a0)
|
||||
(asm-block append-frame-unpack
|
||||
(add.i frame-qwc r0 18)
|
||||
(m a0 buffer)
|
||||
(l.w.field cursor a0 (base))
|
||||
(lui a2 #x1000)
|
||||
(sll32 a3 frame-qwc 16)
|
||||
(srl32 a3 a3 16)
|
||||
(or a2 a2 a3)
|
||||
(s.d a2 cursor)
|
||||
(lui a2 256)
|
||||
(ori a2 a2 1028) ;; STCYCL 4,4
|
||||
(s.w a2 cursor 8)
|
||||
(lui a2 #x6c00)
|
||||
(ori a2 a2 291)
|
||||
(sll32 a3 frame-qwc 24)
|
||||
(srl32 a3 a3 8)
|
||||
(or a2 a2 a3) ;; UNPACK V4-32, 18 qwords, VU address 291
|
||||
(s.w a2 cursor 12)
|
||||
(add.i cursor cursor 16)
|
||||
(s.w.field cursor a0 (base)))
|
||||
(asm-block fill-camera-frame-data
|
||||
(l.w.field a0 buffer (base))
|
||||
(add cursor r0 a0)
|
||||
(m! camera *math-camera*)
|
||||
(lea.field t1 camera (camera-temp))
|
||||
(l.q camera t1)
|
||||
(l.q a3 t1 16)
|
||||
(l.q t0 t1 32)
|
||||
(l.q t1 t1 48)
|
||||
(s.q camera cursor)
|
||||
(s.q a3 cursor 16)
|
||||
(s.q t0 cursor 32)
|
||||
(s.q t1 cursor 48)
|
||||
(add.i cursor a0 64)
|
||||
(m! camera *math-camera*)
|
||||
(lea.field camera camera (hmge-scale))
|
||||
(l.q camera camera)
|
||||
(s.q camera cursor)
|
||||
(add.i cursor a0 80)
|
||||
(m! camera *math-camera*)
|
||||
(lea.field camera camera (hvdf-off))
|
||||
(l.q camera camera)
|
||||
(s.q camera cursor)
|
||||
;; Keep the sky on its fixed GS depth plane instead of applying the camera's Z offset.
|
||||
(m f0 r0)
|
||||
(s.s f0 a0 88)
|
||||
(m! cursor *math-camera*)
|
||||
(l.s.field f0 cursor (pfog0))
|
||||
(s.s f0 a0 96)
|
||||
(l.s f0 function-base sky-radius)
|
||||
(s.s f0 a0 100)
|
||||
(l.s f0 function-base sky-no-kick)
|
||||
(s.s f0 a0 108))
|
||||
(asm-block fill-gif-state
|
||||
;; Constant RGBAQ A+D record: RGBA=(128,96,96,32), Q=1.
|
||||
(lui cursor #x2060)
|
||||
(ori cursor cursor #x6080)
|
||||
(s.w cursor a0 128)
|
||||
(lui cursor #x3f80)
|
||||
(s.w cursor a0 132)
|
||||
(add.i cursor r0 1)
|
||||
(s.w cursor a0 136)
|
||||
(s.w r0 a0 140)
|
||||
;; Gouraud, alpha-blended fan and strip tags, each alternating A+D color and XYZF2.
|
||||
(l.d cursor function-base sky-sun-fan-tag)
|
||||
(pcpyld cursor r0 cursor)
|
||||
(s.d cursor a0 224)
|
||||
(add.i cursor r0 78)
|
||||
(s.d cursor a0 232)
|
||||
(l.d cursor function-base sky-sun-strip-tag)
|
||||
(pcpyld cursor r0 cursor)
|
||||
(s.d cursor a0 240)
|
||||
(add.i cursor r0 78)
|
||||
(s.d cursor a0 248)
|
||||
;; ALPHA_1 value 0x44 and its one-register A+D GIF tag.
|
||||
(add.i cursor r0 68)
|
||||
(s.d cursor a0 256)
|
||||
(add.i cursor r0 66)
|
||||
(s.d cursor a0 264)
|
||||
(l.d cursor function-base sky-alpha-tag)
|
||||
(pcpyld cursor r0 cursor)
|
||||
(s.d cursor a0 272)
|
||||
(add.i cursor r0 14)
|
||||
(s.d cursor a0 280))
|
||||
(l.w.field a0 buffer (base))
|
||||
(sll frame-qwc frame-qwc 4)
|
||||
(add frame-qwc a0 frame-qwc)
|
||||
(s.w.field frame-qwc buffer (base))
|
||||
;; Convert the current primary light group into the VU layout retained by sky-parms.
|
||||
(m! t9 vu-lights<-light-group!)
|
||||
(m! frame-qwc *sky-parms*)
|
||||
(lea.field a0 frame-qwc (default-vu-lights))
|
||||
(m! frame-qwc *time-of-day-context*)
|
||||
(lea.field a1 frame-qwc (light-group 0))
|
||||
(jalr ra t9 :delay (sll v0 ra 0))
|
||||
;; Refresh the standalone 27-qword image, then reference it with an UNPACK to address 256.
|
||||
(m! t9 qmem-copy<-!)
|
||||
(m! frame-qwc *sky-upload-data*)
|
||||
(lea.field a0 frame-qwc (data))
|
||||
(m! frame-qwc *sky-parms*)
|
||||
(lea.field a1 frame-qwc (upload-data data))
|
||||
(add.i a2 r0 432)
|
||||
(jalr ra t9 :delay (sll v0 ra 0))
|
||||
(l.w.field frame-qwc buffer (base))
|
||||
(lui a0 #x3000)
|
||||
(ori a0 a0 27)
|
||||
(m! a1 *sky-upload-data*)
|
||||
(lea.field a1 a1 (data))
|
||||
(sll32 a1 a1 1)
|
||||
(srl a1 a1 1)
|
||||
(or a0 a0 a1)
|
||||
(s.d a0 frame-qwc)
|
||||
(s.w r0 frame-qwc 8)
|
||||
(lui a0 #x6c1b)
|
||||
(ori a0 a0 256)
|
||||
(s.w a0 frame-qwc 12) ;; UNPACK V4-32, 27 qwords, VU address 256
|
||||
(add.i frame-qwc frame-qwc 16)
|
||||
(s.w.field frame-qwc buffer (base))
|
||||
(m result s7)
|
||||
(l.d ra sp)
|
||||
(l.d function-base sp 8)
|
||||
(l.q buffer sp 16)
|
||||
(jr ra :delay (add.i sp sp 32))
|
||||
(nop! :count 2)))
|
||||
(defun sky-upload ((dma-buf dma-buffer) (unused object))
|
||||
"Upload the old sky VU1 program and frame data, then append an MSCALF packet for entry zero."
|
||||
(declare (asm-func none) (allow-saved-regs))
|
||||
(rlet ((buffer :reg gp)
|
||||
(legacy-arg :reg s5)
|
||||
(cursor :reg v1)
|
||||
(result :reg v0))
|
||||
(add.i sp sp -48)
|
||||
(s.d ra sp)
|
||||
(s.q legacy-arg sp 16)
|
||||
(s.q buffer sp 32)
|
||||
(m buffer a0)
|
||||
(m legacy-arg a1)
|
||||
(m! t9 dma-buffer-add-vu-function)
|
||||
(m a0 buffer)
|
||||
(m! a1 sky-vu1-block)
|
||||
(add.i a2 r0 1)
|
||||
(jalr ra t9 :delay (sll v0 ra 0))
|
||||
(m! t9 sky-add-frame-data)
|
||||
(m a0 buffer)
|
||||
(m a1 legacy-arg)
|
||||
(jalr ra t9 :delay (sll v0 ra 0))
|
||||
(l.w.field cursor buffer (base))
|
||||
(lui a0 #x1000)
|
||||
(s.d a0 cursor)
|
||||
(lui a0 #x1500)
|
||||
(add.i a1 r0 0)
|
||||
(sll32 a1 a1 16)
|
||||
(srl32 a1 a1 16)
|
||||
(or a0 a0 a1)
|
||||
(s.w a0 cursor 8)
|
||||
(lui a0 #x1000)
|
||||
(s.w a0 cursor 12)
|
||||
(add.i cursor cursor 16)
|
||||
(s.w.field cursor buffer (base))
|
||||
(m result r0)
|
||||
(l.d ra sp)
|
||||
(l.q buffer sp 32)
|
||||
(l.q legacy-arg sp 16)
|
||||
(jr ra :delay (add.i sp sp 48))
|
||||
(nop! :count 3)))
|
||||
(defun sky-draw ((dma-buf dma-buffer))
|
||||
"Append the MSCALF packet that enters sky-vu1-block at draw-sun-0."
|
||||
(declare (asm-func none))
|
||||
(rlet ((buffer :reg v1)
|
||||
(cursor :reg a0)
|
||||
(command :reg a1)
|
||||
(entry :reg a2)
|
||||
(result :reg v0))
|
||||
(m buffer a0)
|
||||
(l.w.field cursor buffer (base))
|
||||
(lui command #x1000)
|
||||
(s.d command cursor)
|
||||
(lui command #x1500)
|
||||
(add.i entry r0 191)
|
||||
(sll32 entry entry 16)
|
||||
(srl32 entry entry 16)
|
||||
(or command command entry)
|
||||
(s.w command cursor 8)
|
||||
(lui command #x1000)
|
||||
(s.w command cursor 12)
|
||||
(add.i cursor cursor 16)
|
||||
(s.w.field cursor buffer (base))
|
||||
(m result r0)
|
||||
(jr ra :delay (add sp sp r0))
|
||||
(nop! :count 2))))
|
||||
(defun sky-add-frame-data ((dma-buf dma-buffer) (unused object))
|
||||
"Append the old sky renderer's 18-quadword frame constants, refresh its VU light block, copy
|
||||
the current circle, sun, and moon data into contiguous upload storage, and append the VIF
|
||||
transfer for that 27-quadword image."
|
||||
(let ((frame-qwc 18))
|
||||
(dma-buffer-add-cnt-vif2 dma-buf
|
||||
frame-qwc
|
||||
(new 'static 'vif-tag :imm #x404 :cmd (vif-cmd stcycl))
|
||||
(new 'static 'vif-tag :imm #x123 :cmd (vif-cmd unpack-v4-32) :num frame-qwc))
|
||||
(let ((frame (the-as sky-frame-data (-> dma-buf base))))
|
||||
(dotimes (i 4)
|
||||
(set! (-> frame world-homo-matrix vector i quad) (-> *math-camera* camera-temp vector i quad)))
|
||||
(vector-copy! (-> frame hmge-scale) (-> *math-camera* hmge-scale))
|
||||
(vector-copy! (-> frame hvdf-offset) (-> *math-camera* hvdf-off))
|
||||
;; The sky uses a fixed GS depth plane rather than the camera's z offset.
|
||||
(set! (-> frame hvdf-offset z) 0.0)
|
||||
(set! (-> frame pfog0) (-> *math-camera* pfog0))
|
||||
(set! (-> frame radius) 4096000.0)
|
||||
(set! (-> frame nokick) 3072.0)
|
||||
(set-vector! (-> frame col-adgif vector4w) #x20606080 #x3f800000 1 0)
|
||||
(set! (-> frame sun-fan-giftag dword 0) (the-as uint #x2026c00000008012))
|
||||
(set! (-> frame sun-fan-giftag dword 1) (the-as uint 78))
|
||||
(set! (-> frame sun-strip-giftag dword 0) (the-as uint #x2026400000008022))
|
||||
(set! (-> frame sun-strip-giftag dword 1) (the-as uint 78))
|
||||
(set! (-> frame sun-alpha dword 0) (the-as uint 68))
|
||||
(set! (-> frame sun-alpha dword 1) (the-as uint 66))
|
||||
(set! (-> frame sun-alpha-giftag dword 0) (the-as uint #x1000000000000001))
|
||||
(set! (-> frame sun-alpha-giftag dword 1) (the-as uint 14)))
|
||||
(&+! (-> dma-buf base) (* frame-qwc 16)))
|
||||
(vu-lights<-light-group! (-> *sky-parms* default-vu-lights) (-> *time-of-day-context* light-group 0))
|
||||
(qmem-copy<-! (the-as pointer (-> *sky-upload-data* circle))
|
||||
(the-as pointer (-> *sky-parms* upload-data circle))
|
||||
432)
|
||||
(dma-buffer-add-ref-vif2 dma-buf
|
||||
#x1b
|
||||
(the-as int (-> *sky-upload-data* circle))
|
||||
(new 'static 'vif-tag)
|
||||
(new 'static 'vif-tag :imm #x100 :num #x1b :cmd (vif-cmd unpack-v4-32)))
|
||||
#f)
|
||||
|
||||
(defun sky-upload ((dma-buf dma-buffer) (unused object))
|
||||
"Upload the old sky VU1 program and its current frame and celestial data, then start the
|
||||
program's setup entry point."
|
||||
(dma-buffer-add-vu-function dma-buf sky-vu1-block 1)
|
||||
(sky-add-frame-data dma-buf unused)
|
||||
(dma-buffer-add-cnt-vif2 dma-buf
|
||||
0
|
||||
(new 'static 'vif-tag :cmd (vif-cmd mscalf) :msk #x1 :imm #x0)
|
||||
(new 'static 'vif-tag :cmd (vif-cmd flushe) :msk #x1))
|
||||
(none))
|
||||
|
||||
(defun sky-draw ((dma-buf dma-buffer))
|
||||
"Append the VIF command that starts the old sky VU1 program's draw entry point."
|
||||
(dma-buffer-add-cnt-vif2 dma-buf
|
||||
0
|
||||
(new 'static 'vif-tag :cmd (vif-cmd mscalf) :msk #x1 :imm #xbf)
|
||||
(new 'static 'vif-tag :cmd (vif-cmd flushe) :msk #x1))
|
||||
(none))
|
||||
|
||||
;; set the suns
|
||||
(sky-set-sun-radii *sky-parms* (sky-sun-index sun) 60.0 200.0 300.0)
|
||||
@@ -589,10 +428,10 @@
|
||||
|
||||
(sky-set-sun-colors *sky-parms*
|
||||
(sky-sun-index green-sun)
|
||||
(new 'static 'rgba :r #xc2 :g #xfe :b #x78 :a #x80)
|
||||
(new 'static 'rgba :r #xc2 :g #xfe :b #x78 :a #x80)
|
||||
(new 'static 'rgba :r #xc2 :g #xfe :b #x78 :a #x20)
|
||||
(new 'static 'rgba :r #xc2 :g #xfe :b #x78))
|
||||
(static-rgba #xc2 #xfe #x78 #x80)
|
||||
(static-rgba #xc2 #xfe #x78 #x80)
|
||||
(static-rgba #xc2 #xfe #x78 #x20)
|
||||
(static-rgba #xc2 #xfe #x78 0))
|
||||
|
||||
(sky-set-orbit *sky-parms* (sky-orbit-index sun) 12.5 -15.0 0.0 9950.0 300.0 300.0)
|
||||
|
||||
|
||||
@@ -48,12 +48,15 @@
|
||||
(defmethod art-group-get-by-name ((this level) (name string))
|
||||
"Return this level's art group whose name matches name, or false."
|
||||
(countdown (i (-> this art-group art-group-array length))
|
||||
(if (name= (-> this art-group art-group-array i name) name) (return (-> this art-group art-group-array i))))
|
||||
(if (name= (-> this art-group art-group-array i name) name)
|
||||
(return (-> this art-group art-group-array i))))
|
||||
(the-as art-group #f))
|
||||
|
||||
(defmethod bsp-name ((this level))
|
||||
"Return the loaded BSP name when available, otherwise return this level's requested name."
|
||||
(if (and (!= (-> this status) 'inactive) (-> this bsp) (nonzero? (-> this bsp name))) (-> this bsp name) (-> this name)))
|
||||
(if (and (!= (-> this status) 'inactive)(-> this bsp) (nonzero? (-> this bsp name)))
|
||||
(-> this bsp name)
|
||||
(-> this name)))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; BSP
|
||||
@@ -67,9 +70,10 @@
|
||||
|
||||
(defun add-bsp-drawable ((bsp-data bsp-header) (level-data level) (unused symbol) (display-frame-data display-frame))
|
||||
"Draw a level BSP for the current display frame and optionally append its strip-line debug view."
|
||||
;; do the draw
|
||||
;; do the draw (just adds to background queues, real drawing is deferred again.)
|
||||
(draw bsp-data bsp-data display-frame-data)
|
||||
(if (nonzero? *display-strip-lines*) (debug-draw bsp-data bsp-data display-frame-data))
|
||||
(if (nonzero? *display-strip-lines*)
|
||||
(debug-draw bsp-data bsp-data display-frame-data))
|
||||
(none))
|
||||
|
||||
(defmethod print ((this level))
|
||||
@@ -80,7 +84,7 @@
|
||||
(defmethod relocate ((this bsp-header) (heap kheap) (name (pointer uint8)))
|
||||
"Validate a newly linked BSP for the currently loading level, preserve the corrected title and
|
||||
demo names, and connect the BSP and level to each other. Reject invalid types, versions, and
|
||||
visibility lists longer than 2048 entries."
|
||||
visibility lists longer than 2048 bytes."
|
||||
;; we expect that we'll have a loading-level set when we link/login a bsp-header
|
||||
(let ((loading-level (-> *level* loading-level)))
|
||||
(if loading-level
|
||||
@@ -114,7 +118,8 @@
|
||||
(defmethod load-required-packages ((this level))
|
||||
"Load the common package requested by a non-debug BSP when its level package list is nonempty."
|
||||
(when (not (or (not (-> this bsp)) (= *kernel-boot-mode* 'debug-boot)))
|
||||
(if (not (null? (-> this info packages))) (load-package "common" global)))
|
||||
(if (not (null? (-> this info packages)))
|
||||
(load-package "common" global)))
|
||||
this)
|
||||
|
||||
;;;;;;;;;;;;;;
|
||||
@@ -265,7 +270,9 @@
|
||||
|
||||
(defmethod level-status ((this level-group) (level-name symbol))
|
||||
"Return the status of the loaded level matching level-name, or false."
|
||||
(let ((loaded-level (level-get *level* level-name))) (if loaded-level (-> loaded-level status))))
|
||||
(let ((loaded-level (level-get *level* level-name)))
|
||||
(if loaded-level
|
||||
(-> loaded-level status))))
|
||||
|
||||
(defmethod level-status-set! ((this level) (want-status symbol))
|
||||
"Move this level toward want-status through the legal load, login, birth, activation,
|
||||
@@ -304,7 +311,7 @@
|
||||
(remove-by-param1 *background-draw-engine* (-> this bsp))
|
||||
(add-connection *background-draw-engine*
|
||||
*dproc*
|
||||
(the (function object object object object object) add-bsp-drawable)
|
||||
add-bsp-drawable
|
||||
(-> this bsp)
|
||||
this
|
||||
#f)
|
||||
@@ -1037,7 +1044,7 @@
|
||||
0)
|
||||
|
||||
(defun update-sound-banks ()
|
||||
"Reconcile the two resident sound-bank slots with the distinct banks required by active levels.
|
||||
"Set up sound banks based on the currently loaded levels.
|
||||
Do nothing while the loader RPC is busy or a movie is active, report more than two requirements,
|
||||
and perform at most one load or unload per call."
|
||||
(if (nonzero? (rpc-busy? RPC-SOUND-LOADER)) (return 0))
|
||||
@@ -1122,7 +1129,8 @@
|
||||
(define-extern *entity* entity)
|
||||
(set! *entity* (the entity #f)))))))))
|
||||
(let ((ordinary-slots-empty #f))
|
||||
(if (and (= (-> *level* level0 status) 'inactive) (= (-> *level* level1 status) 'inactive)) (set! ordinary-slots-empty #t))
|
||||
(if (and (= (-> *level* level0 status) 'inactive) (= (-> *level* level1 status) 'inactive))
|
||||
(set! ordinary-slots-empty #t))
|
||||
(if discarded-level (return 0))
|
||||
(let ((need-level0 #f)
|
||||
(need-level1 #f))
|
||||
@@ -1367,7 +1375,8 @@
|
||||
(format *stdcon*
|
||||
" nick ~A cur ~S cont ~A~%~%"
|
||||
(-> *load-state* vis-nick)
|
||||
(let ((lev-name (and *target* (-> *target* current-level name)))) (if lev-name (symbol->string lev-name)))
|
||||
(let ((lev-name (and *target* (-> *target* current-level name))))
|
||||
(if lev-name (symbol->string lev-name)))
|
||||
(-> *game-info* current-continue name))
|
||||
; (let ((t9-16 format)
|
||||
; (a0-53 *stdcon*)
|
||||
|
||||
@@ -0,0 +1,415 @@
|
||||
;;-*-Lisp-*-
|
||||
(in-package goal)
|
||||
(bundles "ENGINE.CGO" "GAME.CGO")
|
||||
(require "engine/level/load-boundary.gc")
|
||||
|
||||
;; Reference-only Emotion Engine implementation of the original inline VU0 boundary renderer.
|
||||
;; This file is intentionally not part of any project or DGO manifest.
|
||||
|
||||
;; Boundary faces use the sky clipper's closed 48-byte polygon records:
|
||||
;;
|
||||
;; +0x00 homogeneous position
|
||||
;; +0x10 perspective texture coordinates
|
||||
;; +0x20 floating-point RGBA
|
||||
;;
|
||||
;; The input uses three consecutive lbvtx values for each logical vertex. The first two logical
|
||||
;; colors hold the forward- and backward-facing display colors; the remaining vertices reuse the
|
||||
;; selected color. Triangles become records 0, 1, 2, 0 and quads become 0, 1, 2, 3, 0 in the
|
||||
;; #x70003000 scratch page. draw-boundary-polygon alternates that page with #x70003800 while the
|
||||
;; sky clippers apply x <= w, y <= w, x >= -w, and y >= -w.
|
||||
(#unless PC_PORT
|
||||
(asm-data (label boundary-fog-ceiling) (word #x453ff000)) ;; 3071.0
|
||||
(defun init-boundary-regs ()
|
||||
"Load the camera, homogeneous projection, fog range, and zero texture phase used by boundary
|
||||
drawing. Unlike the sky path, vf25 keeps the camera's ordinary homogeneous screen offset."
|
||||
(declare (asm-func none))
|
||||
(rlet ((camera :reg v1 :type math-camera)
|
||||
(fog-data :reg a0 :type sky-tng-data)
|
||||
(function-base :reg fp)
|
||||
(result :reg v0)
|
||||
(camera-x :reg vf31)
|
||||
(camera-y :reg vf30)
|
||||
(camera-z :reg vf29)
|
||||
(camera-w :reg vf28)
|
||||
(homogeneous-scale :reg vf14)
|
||||
(inverse-homogeneous-scale :reg vf26)
|
||||
(screen-offset :reg vf25)
|
||||
(texture-offset :reg vf24)
|
||||
(fog-range :reg vf13))
|
||||
(add.i sp sp -16)
|
||||
(s.d function-base sp 8)
|
||||
(m function-base t9)
|
||||
(m! camera *math-camera*)
|
||||
(m! fog-data *sky-tng-data*)
|
||||
(lea.field fog-data fog-data (fog))
|
||||
;; Keep fog parameters resident in vf13 so the packet loop needs no scalar camera loads.
|
||||
(l.s.field f0 camera (pfog0))
|
||||
(s.s f0 fog-data)
|
||||
(l.s.field f0 camera (fog-min))
|
||||
(s.s f0 fog-data 4)
|
||||
(l.s.field f0 camera (fog-max))
|
||||
(s.s f0 fog-data 8)
|
||||
(l.s f0 function-base boundary-fog-ceiling)
|
||||
(s.s f0 fog-data 12)
|
||||
(asm-block load-boundary-camera-state
|
||||
(l.vf.field camera-x camera (camera-temp vector 0 quad))
|
||||
(l.vf.field camera-y camera (camera-temp vector 1 quad))
|
||||
(l.vf.field camera-z camera (camera-temp vector 2 quad))
|
||||
(l.vf.field camera-w camera (camera-temp vector 3 quad))
|
||||
(l.vf.field homogeneous-scale camera (hmge-scale quad))
|
||||
(l.vf.field inverse-homogeneous-scale camera (inv-hmge-scale quad))
|
||||
(l.vf.field screen-offset camera (hvdf-off quad))
|
||||
(rlet ((sky-data :reg v1 :type sky-tng-data))
|
||||
;; Load the packed fog limits after the last camera field access.
|
||||
(m! sky-data *sky-tng-data*)
|
||||
(l.vf.field fog-range sky-data (fog)))
|
||||
(mul.vf camera-x camera-x homogeneous-scale)
|
||||
(mul.vf camera-y camera-y homogeneous-scale)
|
||||
(mul.vf camera-z camera-z homogeneous-scale)
|
||||
(mul.vf camera-w camera-w homogeneous-scale)
|
||||
(vmove.xyzw texture-offset vf0))
|
||||
;; Mirror the cleared texture phase in the EE register file.
|
||||
(rlet ((texture-offset-bits :reg v1))
|
||||
(m texture-offset-bits texture-offset))
|
||||
(m result r0)
|
||||
(l.d function-base sp 8)
|
||||
(jr ra :delay (add.i sp sp 16))
|
||||
(nop! :count 2)))
|
||||
(defun draw-boundary-polygon ()
|
||||
"Clip a closed boundary polygon against the four side planes and append ST/RGBAQ/XYZF records.
|
||||
The private calling convention carries the vertex count in t0, DMA buffer in a1, and scratch
|
||||
pages in t4 and t5. Return #f when clipping removes every vertex."
|
||||
(declare (asm-func none))
|
||||
(rlet ((dma-buf :reg a1 :type dma-buffer)
|
||||
(input-page :reg a2)
|
||||
(output :reg a3)
|
||||
(page-a :reg t4)
|
||||
(page-b :reg t5)
|
||||
(vertex-count :reg t0)
|
||||
(component :reg t2)
|
||||
(clip-function :reg t9)
|
||||
(position :reg vf1)
|
||||
(stq :reg vf2)
|
||||
(color :reg vf3)
|
||||
(gif-tag :reg vf27)
|
||||
(inverse-homogeneous-scale :reg vf26)
|
||||
(screen-offset :reg vf25)
|
||||
(texture-offset :reg vf24)
|
||||
(fog-range :reg vf13)
|
||||
(result :reg v0))
|
||||
(nop!)
|
||||
(add.i sp sp -8)
|
||||
(nop!)
|
||||
(s.d ra sp)
|
||||
;; Each pass streams into the other scratch page. component points at x for the first and
|
||||
;; third passes and y for the second and fourth.
|
||||
(asm-block clip-boundary-side-planes
|
||||
(m! clip-function clip-polygon-against-positive-hyperplane)
|
||||
(m input-page page-a)
|
||||
(m output page-b)
|
||||
(jalr ra clip-function :delay (add component input-page r0))
|
||||
(b.z vertex-count boundary-polygon-clipped-away :delay (nop!))
|
||||
(m input-page page-b)
|
||||
(m output page-a)
|
||||
(jalr ra clip-function :delay (add.i component input-page 4))
|
||||
(b.z vertex-count boundary-polygon-clipped-away :delay (m! clip-function clip-polygon-against-negative-hyperplane))
|
||||
(m input-page page-a)
|
||||
(m output page-b)
|
||||
(jalr ra clip-function :delay (add component input-page r0))
|
||||
(b.z vertex-count boundary-polygon-clipped-away :delay (nop!))
|
||||
(m input-page page-b)
|
||||
(m output page-a)
|
||||
(jalr ra clip-function :delay (add.i component input-page 4))
|
||||
(b.z vertex-count boundary-polygon-clipped-away :delay (l.w.field output dma-buf (base))))
|
||||
;; vf27 supplies the fixed GIF tag. The clipped count replaces its first word before emitting
|
||||
;; one three-qword GS vertex for every remaining polygon point.
|
||||
(m input-page page-a)
|
||||
(nop!)
|
||||
(s.vf gif-tag output)
|
||||
(add.i output output 16)
|
||||
(s.w vertex-count output -16)
|
||||
(nop!)
|
||||
(label emit-boundary-vertices)
|
||||
(asm-block project-boundary-vertex
|
||||
(l.vf position input-page)
|
||||
(nop!)
|
||||
(l.vf stq input-page 16)
|
||||
(nop!)
|
||||
(l.vf color input-page 32)
|
||||
(div.w.w Q vf0 position)
|
||||
(mul.vf position position inverse-homogeneous-scale)
|
||||
(nop!)
|
||||
(ftoi.vf color color)
|
||||
(nop!)
|
||||
(add.vf stq stq texture-offset)
|
||||
(nop!)
|
||||
(waitq)
|
||||
(nop!)
|
||||
(mulq.vf.xyz position position Q)
|
||||
(s.vf color output 16)
|
||||
(mulq.vf stq stq Q)
|
||||
(add.i input-page input-page 48)
|
||||
(add.vf position position screen-offset)
|
||||
(add.i output output 48)
|
||||
;; Boundary geometry keeps projected depth instead of using the sky layer value.
|
||||
;; Clamp z to the near side of the GS range, and fog between fog-min and fog-max.
|
||||
(max.z.vf.z position position vf0)
|
||||
(nop!)
|
||||
(min.z.vf.w position position fog-range)
|
||||
(nop!)
|
||||
(max.y.vf.w position position fog-range)
|
||||
(nop!)
|
||||
(s.vf stq output -48)
|
||||
(add.i vertex-count vertex-count -1)
|
||||
(ftoi.vf position position :fixed 4)
|
||||
(nop!)
|
||||
(b.nz vertex-count emit-boundary-vertices :delay (s.vf position output -16)))
|
||||
(s.w.field output dma-buf (base))
|
||||
(nop!)
|
||||
(l.d ra sp)
|
||||
(add.i result s7 8)
|
||||
(jr ra :delay (add.i sp sp 8))
|
||||
(label boundary-polygon-clipped-away)
|
||||
(l.d ra sp)
|
||||
(m result s7)
|
||||
(jr ra :delay (add.i sp sp 8))
|
||||
(jr ra :delay (add sp sp r0))
|
||||
(nop! :count 2)))
|
||||
(defun render-boundary-quad ((vertices lbvtx) (dma-buf dma-buffer))
|
||||
"Transform four boundary vertices into a closed scratch polygon, select the forward or backward
|
||||
display color from its camera-facing sign, and tail-call draw-boundary-polygon."
|
||||
(declare (asm-func none))
|
||||
(rlet ((vertex-data :reg a0)
|
||||
(input-copy :reg v1)
|
||||
(output :reg a3)
|
||||
(page-a :reg t4)
|
||||
(page-b :reg t5)
|
||||
(vertex-count :reg t0)
|
||||
(draw-function :reg t9)
|
||||
(facing-bits :reg v0)
|
||||
(point-0 :reg vf1)
|
||||
(tex-0 :reg vf2)
|
||||
(forward-color :reg vf3)
|
||||
(point-1 :reg vf4)
|
||||
(tex-1 :reg vf5)
|
||||
(backward-color :reg vf6)
|
||||
(point-2 :reg vf7)
|
||||
(tex-2 :reg vf8)
|
||||
(point-3-and-facing :reg vf10)
|
||||
(tex-3 :reg vf11)
|
||||
(camera-x :reg vf31)
|
||||
(camera-y :reg vf30)
|
||||
(camera-z :reg vf29)
|
||||
(camera-w :reg vf28)
|
||||
(homogeneous-scale :reg vf14))
|
||||
(m input-copy vertex-data)
|
||||
(rlet ((camera :reg v1 :type math-camera))
|
||||
(m! camera *math-camera*)
|
||||
;; Refresh the homogeneous scale with the rest of the boundary camera state.
|
||||
(l.vf.field homogeneous-scale camera (hmge-scale quad)))
|
||||
(lui page-a #x7000)
|
||||
(ori page-a page-a #x3000)
|
||||
(lui page-b #x7000)
|
||||
(ori page-b page-b #x3800)
|
||||
(m output page-a)
|
||||
;; Each logical input record is position, STQ, and color. Only the first two colors are
|
||||
;; loaded: forward-color is installed provisionally, then replaced when the face points the
|
||||
;; other way.
|
||||
(asm-block transform-boundary-quad
|
||||
(nop!)
|
||||
(l.vf point-0 vertex-data)
|
||||
(add.i vertex-count r0 4)
|
||||
(l.vf tex-0 vertex-data 16)
|
||||
(nop!)
|
||||
(l.vf forward-color vertex-data 32)
|
||||
(mula.x.vf camera-x point-0)
|
||||
(l.vf point-1 vertex-data 48)
|
||||
(madda.y.vf camera-y point-0)
|
||||
(l.vf tex-1 vertex-data 64)
|
||||
(madda.z.vf camera-z point-0)
|
||||
(l.vf backward-color vertex-data 80)
|
||||
(madd.w.vf point-0 camera-w point-0)
|
||||
(l.vf point-2 vertex-data 96)
|
||||
(nop!)
|
||||
(l.vf tex-2 vertex-data 112)
|
||||
(mula.x.vf camera-x point-1)
|
||||
(nop!)
|
||||
(madda.y.vf camera-y point-1)
|
||||
(l.vf point-3-and-facing vertex-data 144)
|
||||
(madda.z.vf camera-z point-1)
|
||||
(l.vf tex-3 vertex-data 160)
|
||||
(madd.w.vf point-1 camera-w point-1)
|
||||
(nop! :count 2)
|
||||
(s.vf tex-0 output 16)
|
||||
(mula.x.vf camera-x point-2)
|
||||
(s.vf forward-color output 32)
|
||||
(madda.y.vf camera-y point-2)
|
||||
(s.vf tex-1 output 64)
|
||||
(madda.z.vf camera-z point-2)
|
||||
(s.vf forward-color output 80)
|
||||
(madd.w.vf point-2 camera-w point-2)
|
||||
(s.vf tex-2 output 112)
|
||||
(nop!)
|
||||
(s.vf forward-color output 128)
|
||||
(mula.x.vf camera-x point-3-and-facing)
|
||||
(s.vf tex-3 output 160)
|
||||
(madda.y.vf camera-y point-3-and-facing)
|
||||
(s.vf forward-color output 176)
|
||||
(madda.z.vf camera-z point-3-and-facing)
|
||||
(s.vf tex-0 output 208)
|
||||
(madd.w.vf point-3-and-facing camera-w point-3-and-facing)
|
||||
(s.vf forward-color output 224)
|
||||
(nop!)
|
||||
(s.vf point-0 output)
|
||||
(nop!)
|
||||
(s.vf point-0 output 192)
|
||||
(nop!)
|
||||
(s.vf point-1 output 48)
|
||||
(nop!)
|
||||
(s.vf point-2 output 96)
|
||||
(nop!)
|
||||
(s.vf point-3-and-facing output 144))
|
||||
;; The scalar triple product dot(cross(p1-p0, p2-p0), p0) determines which side faces the
|
||||
;; camera origin after transformation. The sum is placed in vf10.y; moving the low 64 bits
|
||||
;; into v0 makes that lane's sign available to the integer branch.
|
||||
(asm-block choose-boundary-quad-color
|
||||
(m! draw-function draw-boundary-polygon)
|
||||
(sub.vf point-1 point-1 point-0)
|
||||
(nop!)
|
||||
(sub.vf point-2 point-2 point-0)
|
||||
(nop!)
|
||||
(outer.product.a.vf acc point-1 point-2)
|
||||
(nop!)
|
||||
(outer.product.b.vf point-3-and-facing point-2 point-1 acc)
|
||||
(nop!)
|
||||
(mul.vf point-3-and-facing point-3-and-facing point-0)
|
||||
(nop!)
|
||||
(add.x.vf.y point-3-and-facing point-3-and-facing point-3-and-facing)
|
||||
(nop!)
|
||||
(add.z.vf.y point-3-and-facing point-3-and-facing point-3-and-facing)
|
||||
(nop!)
|
||||
(m facing-bits point-3-and-facing)
|
||||
(nop!)
|
||||
(b.ge facing-bits r0 use-backward-quad-color :delay (nop!))
|
||||
(jr draw-function :delay (nop!)))
|
||||
(label use-backward-quad-color)
|
||||
;; Recolor only the four distinct records. The duplicate closure retains the provisional
|
||||
;; color, which also participates in interpolation if clipping crosses the final edge.
|
||||
(s.vf backward-color output 32)
|
||||
(nop!)
|
||||
(s.vf backward-color output 80)
|
||||
(nop!)
|
||||
(s.vf backward-color output 128)
|
||||
(nop!)
|
||||
(s.vf backward-color output 176)
|
||||
(nop!)
|
||||
(jr draw-function :delay (nop!))
|
||||
(jr ra :delay (add sp sp r0))
|
||||
(nop! :count 2)))
|
||||
(defun render-boundary-tri ((vertices lbvtx) (dma-buf dma-buffer))
|
||||
"Transform three boundary vertices into a closed scratch polygon, select the forward or backward
|
||||
display color from its camera-facing sign, and tail-call draw-boundary-polygon."
|
||||
(declare (asm-func none))
|
||||
(rlet ((vertex-data :reg a0)
|
||||
(input-copy :reg v1)
|
||||
(output :reg a3)
|
||||
(page-a :reg t4)
|
||||
(page-b :reg t5)
|
||||
(vertex-count :reg t0)
|
||||
(draw-function :reg t9)
|
||||
(facing-bits :reg v0)
|
||||
(point-0 :reg vf1)
|
||||
(tex-0 :reg vf2)
|
||||
(forward-color :reg vf3)
|
||||
(point-1 :reg vf4)
|
||||
(tex-1 :reg vf5)
|
||||
(backward-color :reg vf6)
|
||||
(point-2 :reg vf7)
|
||||
(tex-2 :reg vf8)
|
||||
(facing :reg vf10)
|
||||
(camera-x :reg vf31)
|
||||
(camera-y :reg vf30)
|
||||
(camera-z :reg vf29)
|
||||
(camera-w :reg vf28))
|
||||
(m input-copy vertex-data)
|
||||
(lui page-a #x7000)
|
||||
(ori page-a page-a #x3000)
|
||||
(lui page-b #x7000)
|
||||
(ori page-b page-b #x3800)
|
||||
(m output page-a)
|
||||
(asm-block transform-boundary-triangle
|
||||
(nop!)
|
||||
(l.vf point-0 vertex-data)
|
||||
(add.i vertex-count r0 3)
|
||||
(l.vf tex-0 vertex-data 16)
|
||||
(nop!)
|
||||
(l.vf forward-color vertex-data 32)
|
||||
(mula.x.vf camera-x point-0)
|
||||
(l.vf point-1 vertex-data 48)
|
||||
(madda.y.vf camera-y point-0)
|
||||
(l.vf tex-1 vertex-data 64)
|
||||
(madda.z.vf camera-z point-0)
|
||||
(l.vf backward-color vertex-data 80)
|
||||
(madd.w.vf point-0 camera-w point-0)
|
||||
(l.vf point-2 vertex-data 96)
|
||||
(nop!)
|
||||
(l.vf tex-2 vertex-data 112)
|
||||
(mula.x.vf camera-x point-1)
|
||||
(nop!)
|
||||
(madda.y.vf camera-y point-1)
|
||||
(s.vf tex-0 output 16)
|
||||
(madda.z.vf camera-z point-1)
|
||||
(s.vf forward-color output 32)
|
||||
(madd.w.vf point-1 camera-w point-1)
|
||||
(s.vf tex-1 output 64)
|
||||
(nop!)
|
||||
(s.vf forward-color output 80)
|
||||
(mula.x.vf camera-x point-2)
|
||||
(s.vf tex-2 output 112)
|
||||
(madda.y.vf camera-y point-2)
|
||||
(s.vf forward-color output 128)
|
||||
(madda.z.vf camera-z point-2)
|
||||
(s.vf tex-0 output 160)
|
||||
(madd.w.vf point-2 camera-w point-2)
|
||||
(s.vf forward-color output 176)
|
||||
(nop!)
|
||||
(s.vf point-0 output)
|
||||
(nop!)
|
||||
(s.vf point-0 output 144)
|
||||
(nop!)
|
||||
(s.vf point-1 output 48)
|
||||
(nop!)
|
||||
(s.vf point-2 output 96))
|
||||
(asm-block choose-boundary-triangle-color
|
||||
(m! draw-function draw-boundary-polygon)
|
||||
(sub.vf point-1 point-1 point-0)
|
||||
(nop!)
|
||||
(sub.vf point-2 point-2 point-0)
|
||||
(nop!)
|
||||
(outer.product.a.vf acc point-1 point-2)
|
||||
(nop!)
|
||||
(outer.product.b.vf facing point-2 point-1 acc)
|
||||
(nop!)
|
||||
(mul.vf facing facing point-0)
|
||||
(nop!)
|
||||
(add.x.vf.y facing facing facing)
|
||||
(nop!)
|
||||
(add.z.vf.y facing facing facing)
|
||||
(nop!)
|
||||
(m facing-bits facing)
|
||||
(nop!)
|
||||
(b.ge facing-bits r0 use-backward-triangle-color :delay (nop!))
|
||||
(jr draw-function :delay (nop!)))
|
||||
(label use-backward-triangle-color)
|
||||
;; The fourth record repeats point zero, so it receives the selected color as well.
|
||||
(s.vf backward-color output 32)
|
||||
(nop!)
|
||||
(s.vf backward-color output 80)
|
||||
(nop!)
|
||||
(s.vf backward-color output 128)
|
||||
(nop!)
|
||||
(s.vf backward-color output 176)
|
||||
(nop!)
|
||||
(jr draw-function :delay (nop!))
|
||||
(jr ra :delay (add sp sp r0))
|
||||
(nop! :count 2))))
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
;; Boundary coordinates and the byte-sized links used while triangulating a closed polygon.
|
||||
;; v0/v1/v2 are previous/next/active in *triangulation-buffer*, then triangle vertex indices in
|
||||
;; load-boundary.data[0..tri-cnt). ix remembers the original vertex ordinal.
|
||||
;; load-boundary.data[0..tri-cnt). ix is the original vertex index.
|
||||
(deftype lbvtx (structure)
|
||||
((x float)
|
||||
(y float)
|
||||
@@ -33,16 +33,14 @@
|
||||
:type uint8
|
||||
(invalid 0) ;; No command.
|
||||
(load 1) ;; Replace the desired pair of loaded levels.
|
||||
(cmd2 2) ;; Reserved; no executor or boundary data uses it.
|
||||
(cmd2 2) ;; Unused
|
||||
(display 3) ;; Set a loaded level's display mode.
|
||||
(vis 4) ;; Select the active visibility nickname.
|
||||
(force-vis 5) ;; Bypass BSP visibility outside this level's inside boxes.
|
||||
(checkpt 6) ;; Select a continue point.
|
||||
)
|
||||
|
||||
;; Command to execute when crossing. bparm is reserved padding; parm contains the two GOAL object
|
||||
;; parameters. The named overlays describe the meanings used by each command without changing the
|
||||
;; original generic lev0/lev1 vocabulary.
|
||||
;; Command to execute when crossing.
|
||||
(deftype load-boundary-crossing-command (structure)
|
||||
((cmd load-boundary-cmd)
|
||||
(bparm uint8 3)
|
||||
|
||||
@@ -36,9 +36,9 @@
|
||||
|
||||
;; The editor uses the same system as sky for drawing large polygons.
|
||||
|
||||
;; The PC renderer keeps the persistent VU0 state in the MIPS2C context.
|
||||
(#when PC_PORT
|
||||
(def-mips2c init-boundary-regs (function none)))
|
||||
;; Boundary rendering shares the sky polygon renderer's clipping logic.
|
||||
;; Projection differs in two ways: it uses the camera's ordinary
|
||||
;; screen offset and preserves projected depth instead of replacing it with a sky layer depth.
|
||||
|
||||
(defun-debug add-boundary-shader ((shader-texture texture-id) (dma-buf dma-buffer))
|
||||
"Append the fixed five-register ADGIF shader used by
|
||||
@@ -66,418 +66,119 @@
|
||||
(&+! (-> dma-buf base) 80)
|
||||
(none))
|
||||
|
||||
;; The polygon conversion and both entry points use that same context on PC.
|
||||
(#when PC_PORT
|
||||
(def-mips2c draw-boundary-polygon function)
|
||||
(def-mips2c render-boundary-quad (function lbvtx dma-buffer none))
|
||||
(def-mips2c render-boundary-tri (function lbvtx dma-buffer none)))
|
||||
(defun init-boundary-regs ()
|
||||
"Snapshot the camera, projection, fog, and roof giftag used by subsequent boundary polygon calls."
|
||||
(let ((state *sky-polygon-renderer*))
|
||||
(dotimes (i 4)
|
||||
(sky-vector4*! (-> state transform vector i) (-> *math-camera* camera-temp vector i) (-> *math-camera* hmge-scale)))
|
||||
(vector-copy! (-> state inv-hmge-scale) (-> *math-camera* inv-hmge-scale))
|
||||
(vector-copy! (-> state screen-offset) (-> *math-camera* hvdf-off))
|
||||
(set-vector! (-> state fog-clamp) (-> *math-camera* pfog0) (-> *math-camera* fog-min) (-> *math-camera* fog-max) 3071.0)
|
||||
(vector-copy! (-> *sky-tng-data* fog) (-> state fog-clamp))
|
||||
(set-vector! (-> state texture-offset) 0.0 0.0 0.0 0.0)
|
||||
(set-sky-giftag (-> *sky-tng-data* giftag-roof)))
|
||||
(none))
|
||||
|
||||
;; Boundary faces use the sky clipper's closed 48-byte polygon records:
|
||||
;;
|
||||
;; +0x00 homogeneous position
|
||||
;; +0x10 perspective texture coordinates
|
||||
;; +0x20 floating-point RGBA
|
||||
;;
|
||||
;; The input uses three consecutive lbvtx values for each logical vertex. The first two logical
|
||||
;; colors hold the forward- and backward-facing display colors; the remaining vertices reuse the
|
||||
;; selected color. Triangles become records 0, 1, 2, 0 and quads become 0, 1, 2, 3, 0 in the
|
||||
;; #x70003000 scratch page. draw-boundary-polygon alternates that page with #x70003800 while the
|
||||
;; sky clippers apply x <= w, y <= w, x >= -w, and y >= -w.
|
||||
(#unless PC_PORT
|
||||
(asm-data (label boundary-fog-ceiling) (word #x453ff000)) ;; 3071.0
|
||||
(defun init-boundary-regs ()
|
||||
"Load the camera, homogeneous projection, fog range, and zero texture phase used by boundary
|
||||
drawing. Unlike the sky path, vf25 keeps the camera's ordinary homogeneous screen offset."
|
||||
(declare (asm-func none))
|
||||
(rlet ((camera :reg v1 :type math-camera)
|
||||
(fog-data :reg a0 :type sky-tng-data)
|
||||
(function-base :reg fp)
|
||||
(result :reg v0)
|
||||
(camera-x :reg vf31)
|
||||
(camera-y :reg vf30)
|
||||
(camera-z :reg vf29)
|
||||
(camera-w :reg vf28)
|
||||
(homogeneous-scale :reg vf14)
|
||||
(inverse-homogeneous-scale :reg vf26)
|
||||
(screen-offset :reg vf25)
|
||||
(texture-offset :reg vf24)
|
||||
(fog-range :reg vf13))
|
||||
(add.i sp sp -16)
|
||||
(s.d function-base sp 8)
|
||||
(m function-base t9)
|
||||
(m! camera *math-camera*)
|
||||
(m! fog-data *sky-tng-data*)
|
||||
(lea.field fog-data fog-data (fog))
|
||||
;; Keep fog parameters resident in vf13 so the packet loop needs no scalar camera loads.
|
||||
(l.s.field f0 camera (pfog0))
|
||||
(s.s f0 fog-data)
|
||||
(l.s.field f0 camera (fog-min))
|
||||
(s.s f0 fog-data 4)
|
||||
(l.s.field f0 camera (fog-max))
|
||||
(s.s f0 fog-data 8)
|
||||
(l.s f0 function-base boundary-fog-ceiling)
|
||||
(s.s f0 fog-data 12)
|
||||
(asm-block load-boundary-camera-state
|
||||
(l.vf.field camera-x camera (camera-temp vector 0 quad))
|
||||
(l.vf.field camera-y camera (camera-temp vector 1 quad))
|
||||
(l.vf.field camera-z camera (camera-temp vector 2 quad))
|
||||
(l.vf.field camera-w camera (camera-temp vector 3 quad))
|
||||
(l.vf.field homogeneous-scale camera (hmge-scale quad))
|
||||
(l.vf.field inverse-homogeneous-scale camera (inv-hmge-scale quad))
|
||||
(l.vf.field screen-offset camera (hvdf-off quad))
|
||||
(rlet ((sky-data :reg v1 :type sky-tng-data))
|
||||
;; Load the packed fog limits after the last camera field access.
|
||||
(m! sky-data *sky-tng-data*)
|
||||
(l.vf.field fog-range sky-data (fog)))
|
||||
(mul.vf camera-x camera-x homogeneous-scale)
|
||||
(mul.vf camera-y camera-y homogeneous-scale)
|
||||
(mul.vf camera-z camera-z homogeneous-scale)
|
||||
(mul.vf camera-w camera-w homogeneous-scale)
|
||||
(vmove.xyzw texture-offset vf0))
|
||||
;; Mirror the cleared texture phase in the EE register file.
|
||||
(rlet ((texture-offset-bits :reg v1)) (m texture-offset-bits texture-offset))
|
||||
(m result r0)
|
||||
(l.d function-base sp 8)
|
||||
(jr ra :delay (add.i sp sp 16))
|
||||
(nop! :count 2)))
|
||||
(defun draw-boundary-polygon ()
|
||||
"Clip a closed boundary polygon against the four side planes and append ST/RGBAQ/XYZF records.
|
||||
The private calling convention carries the vertex count in t0, DMA buffer in a1, and scratch
|
||||
pages in t4 and t5. Return #f when clipping removes every vertex."
|
||||
(declare (asm-func none))
|
||||
(rlet ((dma-buf :reg a1 :type dma-buffer)
|
||||
(input-page :reg a2)
|
||||
(output :reg a3)
|
||||
(page-a :reg t4)
|
||||
(page-b :reg t5)
|
||||
(vertex-count :reg t0)
|
||||
(component :reg t2)
|
||||
(clip-function :reg t9)
|
||||
(position :reg vf1)
|
||||
(stq :reg vf2)
|
||||
(color :reg vf3)
|
||||
(gif-tag :reg vf27)
|
||||
(inverse-homogeneous-scale :reg vf26)
|
||||
(screen-offset :reg vf25)
|
||||
(texture-offset :reg vf24)
|
||||
(fog-range :reg vf13)
|
||||
(result :reg v0))
|
||||
(nop!)
|
||||
(add.i sp sp -8)
|
||||
(nop!)
|
||||
(s.d ra sp)
|
||||
;; Each pass streams into the other scratch page. component points at x for the first and
|
||||
;; third passes and y for the second and fourth.
|
||||
(asm-block clip-boundary-side-planes
|
||||
(m! clip-function clip-polygon-against-positive-hyperplane)
|
||||
(m input-page page-a)
|
||||
(m output page-b)
|
||||
(jalr ra clip-function :delay (add component input-page r0))
|
||||
(b.z vertex-count boundary-polygon-clipped-away :delay (nop!))
|
||||
(m input-page page-b)
|
||||
(m output page-a)
|
||||
(jalr ra clip-function :delay (add.i component input-page 4))
|
||||
(b.z vertex-count boundary-polygon-clipped-away :delay (m! clip-function clip-polygon-against-negative-hyperplane))
|
||||
(m input-page page-a)
|
||||
(m output page-b)
|
||||
(jalr ra clip-function :delay (add component input-page r0))
|
||||
(b.z vertex-count boundary-polygon-clipped-away :delay (nop!))
|
||||
(m input-page page-b)
|
||||
(m output page-a)
|
||||
(jalr ra clip-function :delay (add.i component input-page 4))
|
||||
(b.z vertex-count boundary-polygon-clipped-away :delay (l.w.field output dma-buf (base))))
|
||||
;; vf27 supplies the fixed GIF tag. The clipped count replaces its first word before emitting
|
||||
;; one three-qword GS vertex for every remaining polygon point.
|
||||
(m input-page page-a)
|
||||
(nop!)
|
||||
(s.vf gif-tag output)
|
||||
(add.i output output 16)
|
||||
(s.w vertex-count output -16)
|
||||
(nop!)
|
||||
(label emit-boundary-vertices)
|
||||
(asm-block project-boundary-vertex
|
||||
(l.vf position input-page)
|
||||
(nop!)
|
||||
(l.vf stq input-page 16)
|
||||
(nop!)
|
||||
(l.vf color input-page 32)
|
||||
(div.w.w Q vf0 position)
|
||||
(mul.vf position position inverse-homogeneous-scale)
|
||||
(nop!)
|
||||
(ftoi.vf color color)
|
||||
(nop!)
|
||||
(add.vf stq stq texture-offset)
|
||||
(nop!)
|
||||
(waitq)
|
||||
(nop!)
|
||||
(mulq.vf.xyz position position Q)
|
||||
(s.vf color output 16)
|
||||
(mulq.vf stq stq Q)
|
||||
(add.i input-page input-page 48)
|
||||
(add.vf position position screen-offset)
|
||||
(add.i output output 48)
|
||||
;; Boundary geometry keeps projected depth instead of using the sky layer value.
|
||||
;; Clamp z to the near side of the GS range, and fog between fog-min and fog-max.
|
||||
(max.z.vf.z position position vf0)
|
||||
(nop!)
|
||||
(min.z.vf.w position position fog-range)
|
||||
(nop!)
|
||||
(max.y.vf.w position position fog-range)
|
||||
(nop!)
|
||||
(s.vf stq output -48)
|
||||
(add.i vertex-count vertex-count -1)
|
||||
(ftoi.vf position position :fixed 4)
|
||||
(nop!)
|
||||
(b.nz vertex-count emit-boundary-vertices :delay (s.vf position output -16)))
|
||||
(s.w.field output dma-buf (base))
|
||||
(nop!)
|
||||
(l.d ra sp)
|
||||
(add.i result s7 8)
|
||||
(jr ra :delay (add.i sp sp 8))
|
||||
(label boundary-polygon-clipped-away)
|
||||
(l.d ra sp)
|
||||
(m result s7)
|
||||
(jr ra :delay (add.i sp sp 8))
|
||||
(jr ra :delay (add sp sp r0))
|
||||
(nop! :count 2)))
|
||||
(defun render-boundary-quad ((vertices lbvtx) (dma-buf dma-buffer))
|
||||
"Transform four boundary vertices into a closed scratch polygon, select the forward or backward
|
||||
display color from its camera-facing sign, and tail-call draw-boundary-polygon."
|
||||
(declare (asm-func none))
|
||||
(rlet ((vertex-data :reg a0)
|
||||
(input-copy :reg v1)
|
||||
(output :reg a3)
|
||||
(page-a :reg t4)
|
||||
(page-b :reg t5)
|
||||
(vertex-count :reg t0)
|
||||
(draw-function :reg t9)
|
||||
(facing-bits :reg v0)
|
||||
(point-0 :reg vf1)
|
||||
(tex-0 :reg vf2)
|
||||
(forward-color :reg vf3)
|
||||
(point-1 :reg vf4)
|
||||
(tex-1 :reg vf5)
|
||||
(backward-color :reg vf6)
|
||||
(point-2 :reg vf7)
|
||||
(tex-2 :reg vf8)
|
||||
(point-3-and-facing :reg vf10)
|
||||
(tex-3 :reg vf11)
|
||||
(camera-x :reg vf31)
|
||||
(camera-y :reg vf30)
|
||||
(camera-z :reg vf29)
|
||||
(camera-w :reg vf28)
|
||||
(homogeneous-scale :reg vf14))
|
||||
(m input-copy vertex-data)
|
||||
(rlet ((camera :reg v1 :type math-camera))
|
||||
(m! camera *math-camera*)
|
||||
;; Refresh the homogeneous scale with the rest of the boundary camera state.
|
||||
(l.vf.field homogeneous-scale camera (hmge-scale quad)))
|
||||
(lui page-a #x7000)
|
||||
(ori page-a page-a #x3000)
|
||||
(lui page-b #x7000)
|
||||
(ori page-b page-b #x3800)
|
||||
(m output page-a)
|
||||
;; Each logical input record is position, STQ, and color. Only the first two colors are
|
||||
;; loaded: forward-color is installed provisionally, then replaced when the face points the
|
||||
;; other way.
|
||||
(asm-block transform-boundary-quad
|
||||
(nop!)
|
||||
(l.vf point-0 vertex-data)
|
||||
(add.i vertex-count r0 4)
|
||||
(l.vf tex-0 vertex-data 16)
|
||||
(nop!)
|
||||
(l.vf forward-color vertex-data 32)
|
||||
(mula.x.vf camera-x point-0)
|
||||
(l.vf point-1 vertex-data 48)
|
||||
(madda.y.vf camera-y point-0)
|
||||
(l.vf tex-1 vertex-data 64)
|
||||
(madda.z.vf camera-z point-0)
|
||||
(l.vf backward-color vertex-data 80)
|
||||
(madd.w.vf point-0 camera-w point-0)
|
||||
(l.vf point-2 vertex-data 96)
|
||||
(nop!)
|
||||
(l.vf tex-2 vertex-data 112)
|
||||
(mula.x.vf camera-x point-1)
|
||||
(nop!)
|
||||
(madda.y.vf camera-y point-1)
|
||||
(l.vf point-3-and-facing vertex-data 144)
|
||||
(madda.z.vf camera-z point-1)
|
||||
(l.vf tex-3 vertex-data 160)
|
||||
(madd.w.vf point-1 camera-w point-1)
|
||||
(nop! :count 2)
|
||||
(s.vf tex-0 output 16)
|
||||
(mula.x.vf camera-x point-2)
|
||||
(s.vf forward-color output 32)
|
||||
(madda.y.vf camera-y point-2)
|
||||
(s.vf tex-1 output 64)
|
||||
(madda.z.vf camera-z point-2)
|
||||
(s.vf forward-color output 80)
|
||||
(madd.w.vf point-2 camera-w point-2)
|
||||
(s.vf tex-2 output 112)
|
||||
(nop!)
|
||||
(s.vf forward-color output 128)
|
||||
(mula.x.vf camera-x point-3-and-facing)
|
||||
(s.vf tex-3 output 160)
|
||||
(madda.y.vf camera-y point-3-and-facing)
|
||||
(s.vf forward-color output 176)
|
||||
(madda.z.vf camera-z point-3-and-facing)
|
||||
(s.vf tex-0 output 208)
|
||||
(madd.w.vf point-3-and-facing camera-w point-3-and-facing)
|
||||
(s.vf forward-color output 224)
|
||||
(nop!)
|
||||
(s.vf point-0 output)
|
||||
(nop!)
|
||||
(s.vf point-0 output 192)
|
||||
(nop!)
|
||||
(s.vf point-1 output 48)
|
||||
(nop!)
|
||||
(s.vf point-2 output 96)
|
||||
(nop!)
|
||||
(s.vf point-3-and-facing output 144))
|
||||
;; The scalar triple product dot(cross(p1-p0, p2-p0), p0) determines which side faces the
|
||||
;; camera origin after transformation. The sum is placed in vf10.y; moving the low 64 bits
|
||||
;; into v0 makes that lane's sign available to the integer branch.
|
||||
(asm-block choose-boundary-quad-color
|
||||
(m! draw-function draw-boundary-polygon)
|
||||
(sub.vf point-1 point-1 point-0)
|
||||
(nop!)
|
||||
(sub.vf point-2 point-2 point-0)
|
||||
(nop!)
|
||||
(outer.product.a.vf acc point-1 point-2)
|
||||
(nop!)
|
||||
(outer.product.b.vf point-3-and-facing point-2 point-1 acc)
|
||||
(nop!)
|
||||
(mul.vf point-3-and-facing point-3-and-facing point-0)
|
||||
(nop!)
|
||||
(add.x.vf.y point-3-and-facing point-3-and-facing point-3-and-facing)
|
||||
(nop!)
|
||||
(add.z.vf.y point-3-and-facing point-3-and-facing point-3-and-facing)
|
||||
(nop!)
|
||||
(m facing-bits point-3-and-facing)
|
||||
(nop!)
|
||||
(b.ge facing-bits r0 use-backward-quad-color :delay (nop!))
|
||||
(jr draw-function :delay (nop!)))
|
||||
(label use-backward-quad-color)
|
||||
;; Recolor only the four distinct records. The duplicate closure retains the provisional
|
||||
;; color, which also participates in interpolation if clipping crosses the final edge.
|
||||
(s.vf backward-color output 32)
|
||||
(nop!)
|
||||
(s.vf backward-color output 80)
|
||||
(nop!)
|
||||
(s.vf backward-color output 128)
|
||||
(nop!)
|
||||
(s.vf backward-color output 176)
|
||||
(nop!)
|
||||
(jr draw-function :delay (nop!))
|
||||
(jr ra :delay (add sp sp r0))
|
||||
(nop! :count 2)))
|
||||
(defun render-boundary-tri ((vertices lbvtx) (dma-buf dma-buffer))
|
||||
"Transform three boundary vertices into a closed scratch polygon, select the forward or backward
|
||||
display color from its camera-facing sign, and tail-call draw-boundary-polygon."
|
||||
(declare (asm-func none))
|
||||
(rlet ((vertex-data :reg a0)
|
||||
(input-copy :reg v1)
|
||||
(output :reg a3)
|
||||
(page-a :reg t4)
|
||||
(page-b :reg t5)
|
||||
(vertex-count :reg t0)
|
||||
(draw-function :reg t9)
|
||||
(facing-bits :reg v0)
|
||||
(point-0 :reg vf1)
|
||||
(tex-0 :reg vf2)
|
||||
(forward-color :reg vf3)
|
||||
(point-1 :reg vf4)
|
||||
(tex-1 :reg vf5)
|
||||
(backward-color :reg vf6)
|
||||
(point-2 :reg vf7)
|
||||
(tex-2 :reg vf8)
|
||||
(facing :reg vf10)
|
||||
(camera-x :reg vf31)
|
||||
(camera-y :reg vf30)
|
||||
(camera-z :reg vf29)
|
||||
(camera-w :reg vf28))
|
||||
(m input-copy vertex-data)
|
||||
(lui page-a #x7000)
|
||||
(ori page-a page-a #x3000)
|
||||
(lui page-b #x7000)
|
||||
(ori page-b page-b #x3800)
|
||||
(m output page-a)
|
||||
(asm-block transform-boundary-triangle
|
||||
(nop!)
|
||||
(l.vf point-0 vertex-data)
|
||||
(add.i vertex-count r0 3)
|
||||
(l.vf tex-0 vertex-data 16)
|
||||
(nop!)
|
||||
(l.vf forward-color vertex-data 32)
|
||||
(mula.x.vf camera-x point-0)
|
||||
(l.vf point-1 vertex-data 48)
|
||||
(madda.y.vf camera-y point-0)
|
||||
(l.vf tex-1 vertex-data 64)
|
||||
(madda.z.vf camera-z point-0)
|
||||
(l.vf backward-color vertex-data 80)
|
||||
(madd.w.vf point-0 camera-w point-0)
|
||||
(l.vf point-2 vertex-data 96)
|
||||
(nop!)
|
||||
(l.vf tex-2 vertex-data 112)
|
||||
(mula.x.vf camera-x point-1)
|
||||
(nop!)
|
||||
(madda.y.vf camera-y point-1)
|
||||
(s.vf tex-0 output 16)
|
||||
(madda.z.vf camera-z point-1)
|
||||
(s.vf forward-color output 32)
|
||||
(madd.w.vf point-1 camera-w point-1)
|
||||
(s.vf tex-1 output 64)
|
||||
(nop!)
|
||||
(s.vf forward-color output 80)
|
||||
(mula.x.vf camera-x point-2)
|
||||
(s.vf tex-2 output 112)
|
||||
(madda.y.vf camera-y point-2)
|
||||
(s.vf forward-color output 128)
|
||||
(madda.z.vf camera-z point-2)
|
||||
(s.vf tex-0 output 160)
|
||||
(madd.w.vf point-2 camera-w point-2)
|
||||
(s.vf forward-color output 176)
|
||||
(nop!)
|
||||
(s.vf point-0 output)
|
||||
(nop!)
|
||||
(s.vf point-0 output 144)
|
||||
(nop!)
|
||||
(s.vf point-1 output 48)
|
||||
(nop!)
|
||||
(s.vf point-2 output 96))
|
||||
(asm-block choose-boundary-triangle-color
|
||||
(m! draw-function draw-boundary-polygon)
|
||||
(sub.vf point-1 point-1 point-0)
|
||||
(nop!)
|
||||
(sub.vf point-2 point-2 point-0)
|
||||
(nop!)
|
||||
(outer.product.a.vf acc point-1 point-2)
|
||||
(nop!)
|
||||
(outer.product.b.vf facing point-2 point-1 acc)
|
||||
(nop!)
|
||||
(mul.vf facing facing point-0)
|
||||
(nop!)
|
||||
(add.x.vf.y facing facing facing)
|
||||
(nop!)
|
||||
(add.z.vf.y facing facing facing)
|
||||
(nop!)
|
||||
(m facing-bits facing)
|
||||
(nop!)
|
||||
(b.ge facing-bits r0 use-backward-triangle-color :delay (nop!))
|
||||
(jr draw-function :delay (nop!)))
|
||||
(label use-backward-triangle-color)
|
||||
;; The fourth record repeats point zero, so it receives the selected color as well.
|
||||
(s.vf backward-color output 32)
|
||||
(nop!)
|
||||
(s.vf backward-color output 80)
|
||||
(nop!)
|
||||
(s.vf backward-color output 128)
|
||||
(nop!)
|
||||
(s.vf backward-color output 176)
|
||||
(nop!)
|
||||
(jr draw-function :delay (nop!))
|
||||
(jr ra :delay (add sp sp r0))
|
||||
(nop! :count 2))))
|
||||
(defun boundary-emit-polygon! ((vertices (inline-array sky-vertex)) (vertex-count int) (dma-buf dma-buffer))
|
||||
"Append one boundary GIF tag and its perspective-correct ST, RGBAQ, and 12.4 XYZF records."
|
||||
(let* ((state *sky-polygon-renderer*)
|
||||
(packet-start (-> dma-buf base))
|
||||
(giftag (the-as gs-gif-tag packet-start))
|
||||
(output (the-as (pointer uint128) (&+ packet-start 16))))
|
||||
(set! (-> giftag qword) (-> state giftag qword))
|
||||
(set! (-> (the-as (pointer uint32) packet-start) 0) vertex-count)
|
||||
(dotimes (i vertex-count)
|
||||
(let* ((vertex (-> vertices i))
|
||||
(q (/ 1.0 (-> vertex pos w)))
|
||||
(st (new 'stack-no-clear 'vector))
|
||||
(color-int (new 'stack-no-clear 'vector))
|
||||
(projected (new 'stack-no-clear 'vector))
|
||||
(projected-int (new 'stack-no-clear 'vector)))
|
||||
(vector-copy! st (-> vertex stq))
|
||||
(+! (-> st x) (-> state texture-offset x))
|
||||
(+! (-> st y) (-> state texture-offset y))
|
||||
(sky-vector4-float*! st st q)
|
||||
(vector-cvt.w.s! color-int (-> vertex col))
|
||||
(sky-vector4*! projected (-> vertex pos) (-> state inv-hmge-scale))
|
||||
(*! (-> projected x) q)
|
||||
(*! (-> projected y) q)
|
||||
(*! (-> projected z) q)
|
||||
(+! (-> projected x) (-> state screen-offset x))
|
||||
(+! (-> projected y) (-> state screen-offset y))
|
||||
(+! (-> projected z) (-> state screen-offset z))
|
||||
(+! (-> projected w) (-> state screen-offset w))
|
||||
(set! (-> projected z) (max (-> projected z) 0.0))
|
||||
(set! (-> projected w) (max (-> state fog-clamp y) (min (-> projected w) (-> state fog-clamp z))))
|
||||
(sky-vector4-float*! projected projected 16.0)
|
||||
(vector-cvt.w.s! projected-int projected)
|
||||
(set! (-> output (* i 3)) (-> st quad))
|
||||
(set! (-> output (+ (* i 3) 1)) (-> color-int quad))
|
||||
(set! (-> output (+ (* i 3) 2)) (-> projected-int quad))))
|
||||
(set! (-> dma-buf base) (&+ packet-start (* (+ 1 (* vertex-count 3)) 16))))
|
||||
(none))
|
||||
|
||||
(defun draw-boundary-polygon ()
|
||||
"Clip the current boundary polygon against the four homogeneous side planes, then emit it."
|
||||
(let* ((state *sky-polygon-renderer*)
|
||||
(vertices-a (-> state vertices-a))
|
||||
(vertices-b (-> state vertices-b))
|
||||
(vertex-count (-> state vertex-count)))
|
||||
(when (nonzero? vertex-count)
|
||||
(set! vertex-count (sky-clip-polygon! vertices-a vertices-b vertex-count 0 #t)))
|
||||
(when (nonzero? vertex-count)
|
||||
(set! vertex-count (sky-clip-polygon! vertices-b vertices-a vertex-count 1 #t)))
|
||||
(when (nonzero? vertex-count)
|
||||
(set! vertex-count (sky-clip-polygon! vertices-a vertices-b vertex-count 0 #f)))
|
||||
(when (nonzero? vertex-count)
|
||||
(set! vertex-count (sky-clip-polygon! vertices-b vertices-a vertex-count 1 #f)))
|
||||
(when (nonzero? vertex-count)
|
||||
(boundary-emit-polygon! vertices-a vertex-count (-> state dma-buf))))
|
||||
(none))
|
||||
|
||||
(defun boundary-back-facing? ((vertices (inline-array sky-vertex)))
|
||||
"Test the transformed triangle's scalar triple product, matching the original VU facing branch."
|
||||
(let* ((p0 (-> vertices 0 pos))
|
||||
(p1 (-> vertices 1 pos))
|
||||
(p2 (-> vertices 2 pos))
|
||||
(edge-1-x (- (-> p1 x) (-> p0 x)))
|
||||
(edge-1-y (- (-> p1 y) (-> p0 y)))
|
||||
(edge-1-z (- (-> p1 z) (-> p0 z)))
|
||||
(edge-2-x (- (-> p2 x) (-> p0 x)))
|
||||
(edge-2-y (- (-> p2 y) (-> p0 y)))
|
||||
(edge-2-z (- (-> p2 z) (-> p0 z)))
|
||||
(normal-x (- (* edge-1-y edge-2-z) (* edge-1-z edge-2-y)))
|
||||
(normal-y (- (* edge-1-z edge-2-x) (* edge-1-x edge-2-z)))
|
||||
(normal-z (- (* edge-1-x edge-2-y) (* edge-1-y edge-2-x))))
|
||||
(>= (+ (* normal-x (-> p0 x)) (* normal-y (-> p0 y)) (* normal-z (-> p0 z))) 0.0)))
|
||||
|
||||
(defun render-boundary-polygon ((vertices lbvtx) (dma-buf dma-buffer) (vertex-count int))
|
||||
"Transform a boundary polygon, select its forward or backward display color, clip it, and emit it."
|
||||
(let* ((state *sky-polygon-renderer*)
|
||||
(input (the-as (inline-array sky-vertex) vertices))
|
||||
(output (-> state vertices-a)))
|
||||
(set! (-> state dma-buf) dma-buf)
|
||||
(set! (-> state vertex-count) vertex-count)
|
||||
(dotimes (i vertex-count)
|
||||
(let ((dst (-> output i))
|
||||
(src (-> input i)))
|
||||
;; Unlike sky geometry, boundary polygons retain transformed z for depth and facing.
|
||||
(vector-matrix*! (-> dst pos) (-> src pos) (-> state transform))
|
||||
(vector-copy! (-> dst stq) (-> src stq))))
|
||||
(let ((color (if (boundary-back-facing? output) (-> input 1 col) (-> input 0 col))))
|
||||
(dotimes (i vertex-count)
|
||||
(vector-copy! (-> output i col) color)))
|
||||
(draw-boundary-polygon))
|
||||
(none))
|
||||
|
||||
(defun render-boundary-quad ((vertices lbvtx) (dma-buf dma-buffer))
|
||||
"Transform and render a four-vertex boundary face."
|
||||
(render-boundary-polygon vertices dma-buf 4)
|
||||
(none))
|
||||
|
||||
(defun render-boundary-tri ((vertices lbvtx) (dma-buf dma-buffer))
|
||||
"Transform and render a three-vertex boundary face."
|
||||
(render-boundary-polygon vertices dma-buf 3)
|
||||
(none))
|
||||
|
||||
;; the polygon curently rendering.
|
||||
(define *boundary-polygon*
|
||||
@@ -502,8 +203,7 @@
|
||||
"Build and draw the vertical quad joining two boundary vertices
|
||||
between bot-plane and top-plane. uv-phase? selects the alternate UV orientation used to flash the
|
||||
selected boundary."
|
||||
(rlet ((vf27 :class vf))
|
||||
(let ((start (-> boundary data start-index)))
|
||||
(let ((start (-> boundary data start-index)))
|
||||
(let ((end (-> boundary data end-index)))
|
||||
(let ((polygon-pos (-> *boundary-polygon* 0)))
|
||||
(set! (-> polygon-pos x) (-> start x))
|
||||
@@ -569,19 +269,14 @@
|
||||
(set! (-> polygon-uv z) 1.0)
|
||||
(set! (-> polygon-uv v w) 1.0))))
|
||||
(init-boundary-regs)
|
||||
(#unless PC_PORT
|
||||
(.lvf vf27 (&-> *sky-tng-data* giftag-roof qword)))
|
||||
(#when PC_PORT
|
||||
(set-sky-vf27 (&-> *sky-tng-data* giftag-roof qword)))
|
||||
(render-boundary-quad (-> *boundary-polygon* 0) dma-buf)
|
||||
0
|
||||
(none)))
|
||||
(none))
|
||||
|
||||
(defun-debug draw-boundary-cap ((boundary load-boundary) (plane-y float) (dma-buf dma-buffer) (uv-phase? symbol))
|
||||
"Draw every cached triangle of a closed boundary at plane-y.
|
||||
uv-phase? selects the alternate UV orientation used to flash the selected boundary."
|
||||
(rlet ((vf27 :class vf))
|
||||
(dotimes (i (-> boundary tri-cnt))
|
||||
(dotimes (i (-> boundary tri-cnt))
|
||||
(let ((v0 (-> boundary data (-> boundary data i v0)))
|
||||
(v1 (-> boundary data (-> boundary data i v1)))
|
||||
(v2 (-> boundary data (-> boundary data i v2))))
|
||||
@@ -634,13 +329,9 @@
|
||||
(set! (-> polygon-uv z) 1.0)
|
||||
(set! (-> polygon-uv v w) 1.0))))
|
||||
(init-boundary-regs)
|
||||
(#unless PC_PORT
|
||||
(.lvf vf27 (&-> *sky-tng-data* giftag-roof qword)))
|
||||
(#when PC_PORT
|
||||
(set-sky-vf27 (&-> *sky-tng-data* giftag-roof qword)))
|
||||
(render-boundary-tri (-> *boundary-polygon* 0) dma-buf))
|
||||
0
|
||||
(none)))
|
||||
(none))
|
||||
|
||||
(defun-debug boundary-set-color ((color-vertex lbvtx) (command load-boundary-crossing-command))
|
||||
"Set a debug polygon color from command's load-boundary command
|
||||
@@ -693,88 +384,30 @@
|
||||
0
|
||||
(none))
|
||||
|
||||
(#unless PC_PORT
|
||||
(defun-debug render-boundary ((boundary load-boundary))
|
||||
"Append debug rendering for boundary to the debug DMA bucket. Closed
|
||||
boundaries draw their triangulated top cap; open boundaries draw vertical side quads. The selected
|
||||
boundary alternates UV phase to flash."
|
||||
(let* ((uv-phase? (or (!= boundary (-> *lb-editor-parms* boundary)) (logtest? (-> *display* real-actual-frame-counter) 4)))
|
||||
(dma-buf (-> *display* frames (-> *display* on-screen) frame global-buf))
|
||||
(packet-start (-> dma-buf base)))
|
||||
(let* ((buffer dma-buf)
|
||||
(cnt-tag (the-as object (-> buffer base))))
|
||||
(set! (-> (the-as dma-packet cnt-tag) dma) (new 'static 'dma-tag :qwc #x4 :id (dma-tag-id cnt)))
|
||||
(set! (-> (the-as dma-packet cnt-tag) vif0) (new 'static 'vif-tag))
|
||||
(set! (-> (the-as dma-packet cnt-tag) vif1) (new 'static 'vif-tag :imm #x4 :cmd (vif-cmd direct) :msk #x1))
|
||||
(set! (-> buffer base) (&+ (the-as pointer cnt-tag) 16)))
|
||||
(let* ((buffer dma-buf)
|
||||
(giftag (the-as object (-> buffer base))))
|
||||
(set! (-> (the-as gs-gif-tag giftag) tag) (new 'static 'gif-tag64 :nloop #x1 :eop #x1 :nreg #x3))
|
||||
(set! (-> (the-as gs-gif-tag giftag) regs) GIF_REGS_ALL_AD)
|
||||
(set! (-> buffer base) (&+ (the-as pointer giftag) 16)))
|
||||
(let* ((buffer dma-buf)
|
||||
(gs-state (-> buffer base)))
|
||||
(set! (-> (the-as (pointer gs-zbuf) gs-state) 0) (new 'static 'gs-zbuf :zbp #x1c0 :psm (gs-psm ct24)))
|
||||
(set! (-> (the-as (pointer gs-reg64) gs-state) 1) (gs-reg64 zbuf-1))
|
||||
(set! (-> (the-as (pointer gs-test) gs-state) 2)
|
||||
(new 'static 'gs-test :ate #x1 :atst (gs-atest greater-equal) :aref #x26 :zte #x1 :ztst (gs-ztest greater-equal)))
|
||||
(set! (-> (the-as (pointer gs-reg64) gs-state) 3) (gs-reg64 test-1))
|
||||
(set! (-> (the-as (pointer gs-alpha) gs-state) 4) (new 'static 'gs-alpha :b #x1 :d #x1))
|
||||
(set! (-> (the-as (pointer gs-reg64) gs-state) 5) (gs-reg64 alpha-1))
|
||||
(set! (-> buffer base) (&+ gs-state 48)))
|
||||
|
||||
(defun-debug render-boundary ((boundary load-boundary))
|
||||
"Append debug rendering for boundary to the debug DMA bucket. Closed boundaries draw their
|
||||
triangulated top cap; open boundaries draw vertical side quads. The selected boundary
|
||||
alternates UV phase to flash."
|
||||
(let ((uv-phase? (or (!= boundary (-> *lb-editor-parms* boundary)) (logtest? (-> *display* real-actual-frame-counter) 4))))
|
||||
(with-dma-buffer-add-bucket ((dma-buf (-> (current-frame) global-buf)) (bucket-id debug))
|
||||
(dma-buffer-add-gs-set-flusha dma-buf
|
||||
(zbuf-1 (new 'static 'gs-zbuf :zbp #x1c0 :psm (gs-psm ct24)))
|
||||
(test-1 (new 'static 'gs-test :ate #x1 :atst (gs-atest greater-equal) :aref #x26 :zte #x1 :ztst (gs-ztest greater-equal)))
|
||||
(alpha-1 (new 'static 'gs-alpha :b #x1 :d #x1)))
|
||||
(boundary-set-color (-> *boundary-polygon* 2) (-> boundary cmd-fwd))
|
||||
(boundary-set-color (-> *boundary-polygon* 5) (-> boundary cmd-bwd))
|
||||
(let ((vif-block (the-as object (-> dma-buf base))))
|
||||
(&+! (-> dma-buf base) 16)
|
||||
(add-boundary-shader (new 'static 'texture-id :index #x33 :page #x2) dma-buf)
|
||||
(cond
|
||||
((logtest? (-> boundary flags) (load-boundary-flags closed))
|
||||
(draw-boundary-cap boundary (-> boundary top-plane) dma-buf uv-phase?))
|
||||
(else
|
||||
(dotimes (i (the-as int (+ (-> boundary num-points) -1)))
|
||||
(draw-boundary-side boundary i (+ i 1) dma-buf uv-phase?))))
|
||||
(close-sky-buffer dma-buf)
|
||||
(let ((block-qwc (/ (the-as int (+ (- -16 (the-as int vif-block)) (the-as int (-> dma-buf base)))) 16)))
|
||||
(set! (-> (the-as dma-packet vif-block) dma) (new 'static 'dma-tag :id (dma-tag-id cnt) :qwc block-qwc))
|
||||
(set! (-> (the-as dma-packet vif-block) vif0) (new 'static 'vif-tag))
|
||||
(set! (-> (the-as dma-packet vif-block) vif1) (new 'static 'vif-tag :cmd (vif-cmd direct) :msk #x1 :imm block-qwc))))
|
||||
(let ((packet-end (-> dma-buf base)))
|
||||
(let ((next-tag (the-as object (-> dma-buf base))))
|
||||
(set! (-> (the-as dma-packet next-tag) dma) (new 'static 'dma-tag :id (dma-tag-id next)))
|
||||
(set! (-> (the-as dma-packet next-tag) vif0) (new 'static 'vif-tag))
|
||||
(set! (-> (the-as dma-packet next-tag) vif1) (new 'static 'vif-tag))
|
||||
(set! (-> dma-buf base) (&+ (the-as pointer next-tag) 16)))
|
||||
(dma-bucket-insert-tag (-> *display* frames (-> *display* on-screen) frame bucket-group)
|
||||
(bucket-id debug)
|
||||
packet-start
|
||||
(the-as (pointer dma-tag) packet-end))))
|
||||
0
|
||||
(none)))
|
||||
|
||||
(#when PC_PORT
|
||||
(defun-debug render-boundary ((boundary load-boundary))
|
||||
"Append debug rendering for boundary to the debug DMA bucket. Closed boundaries draw their
|
||||
triangulated top cap; open boundaries draw vertical side quads. The selected boundary
|
||||
alternates UV phase to flash."
|
||||
(let ((uv-phase? (or (!= boundary (-> *lb-editor-parms* boundary)) (logtest? (-> *display* real-actual-frame-counter) 4))))
|
||||
(with-dma-buffer-add-bucket ((dma-buf (-> (current-frame) global-buf)) (bucket-id debug))
|
||||
(dma-buffer-add-gs-set-flusha dma-buf
|
||||
(zbuf-1 (new 'static 'gs-zbuf :zbp #x1c0 :psm (gs-psm ct24)))
|
||||
(test-1 (new 'static 'gs-test :ate #x1 :atst (gs-atest greater-equal) :aref #x26 :zte #x1 :ztst (gs-ztest greater-equal)))
|
||||
(alpha-1 (new 'static 'gs-alpha :b #x1 :d #x1)))
|
||||
(boundary-set-color (-> *boundary-polygon* 2) (-> boundary cmd-fwd))
|
||||
(boundary-set-color (-> *boundary-polygon* 5) (-> boundary cmd-bwd))
|
||||
(with-cnt-vif-block-qwc (dma-buf)
|
||||
(add-boundary-shader (new 'static 'texture-id :index #x33 :page #x2) dma-buf)
|
||||
(cond
|
||||
((logtest? (-> boundary flags) (load-boundary-flags closed))
|
||||
(draw-boundary-cap boundary (-> boundary top-plane) dma-buf uv-phase?))
|
||||
(else
|
||||
(dotimes (i (the-as int (+ (-> boundary num-points) -1)))
|
||||
(draw-boundary-side boundary i (+ i 1) dma-buf uv-phase?))))
|
||||
(close-sky-buffer dma-buf))))
|
||||
0
|
||||
(none)))
|
||||
(with-cnt-vif-block-qwc (dma-buf)
|
||||
(add-boundary-shader (new 'static 'texture-id :index #x33 :page #x2) dma-buf)
|
||||
(cond
|
||||
((logtest? (-> boundary flags) (load-boundary-flags closed))
|
||||
(draw-boundary-cap boundary (-> boundary top-plane) dma-buf uv-phase?))
|
||||
(else
|
||||
(dotimes (i (the-as int (+ (-> boundary num-points) -1)))
|
||||
(draw-boundary-side boundary i (+ i 1) dma-buf uv-phase?))))
|
||||
(close-sky-buffer dma-buf))))
|
||||
0
|
||||
(none))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Load Boundary File
|
||||
@@ -1479,6 +1112,7 @@
|
||||
(return (load-boundary-crossing-result none)))
|
||||
(let ((plane-scale (/ (- (-> current-pos y) (-> previous-pos y)) (- (-> boundary top-plane) (-> previous-pos y))))
|
||||
(crossing-point (new 'stack-no-clear 'vector)))
|
||||
;; This is incorrect --
|
||||
(set! (-> crossing-point x) (+ (-> previous-pos x) (* plane-scale (- (-> current-pos x) (-> previous-pos x)))))
|
||||
(set! (-> crossing-point y) (+ (-> previous-pos y) (* plane-scale (- (-> current-pos y) (-> previous-pos y)))))
|
||||
(set! (-> crossing-point z) (+ (-> previous-pos z) (* plane-scale (- (-> current-pos z) (-> previous-pos z)))))
|
||||
|
||||
@@ -106,9 +106,7 @@
|
||||
(defun load-game-text-info ((group-name string) (destination-symbol symbol) (heap kheap))
|
||||
"Synchronously ensure group-name is loaded in the selected language into heap and publish the
|
||||
linked game-text-info through destination-symbol. Reuse matching data; otherwise reset the heap,
|
||||
load and link the language/group TXT file, and clear destination-symbol on link failure. EE maps
|
||||
English to UK English in SCEE territory; PC reads its selected text language. Errors are reported
|
||||
while the function always returns zero."
|
||||
load and link the language/group TXT file, and clear destination-symbol on link failure."
|
||||
(local-vars (result int) (loaded-text game-text-info) (language-id language-enum) (load-size int) (heap-free int))
|
||||
(set! loaded-text (the-as game-text-info (-> destination-symbol value)))
|
||||
;; split languages in PC port
|
||||
|
||||
@@ -313,6 +313,38 @@ TEST(Demacro, Jak1RecognizesDmaCntPacketsWithExplicitQwc) {
|
||||
)");
|
||||
}
|
||||
|
||||
TEST(Demacro, Jak1RecognizesDirectDmaCntAndRefPackets) {
|
||||
const auto rules =
|
||||
demacro::load_rules(file_util::get_file_path({"decompiler/config/jak1/demacro.jsonc"}));
|
||||
const std::string source = R"((begin
|
||||
(let ((packet (the-as object (-> dma-buf base))))
|
||||
(set! (-> (the-as dma-packet packet) dma) (new 'static 'dma-tag :id (dma-tag-id cnt)))
|
||||
(set! (-> (the-as dma-packet packet) vif0) vif0)
|
||||
(set! (-> (the-as dma-packet packet) vif1) vif1)
|
||||
(set! (-> dma-buf base) (&+ (the-as pointer packet) 16)))
|
||||
(let* ((dma-state dma-buf)
|
||||
(packet (the-as object (-> dma-state base))))
|
||||
(set! (-> (the-as dma-packet packet) dma)
|
||||
(new 'static 'dma-tag :id (dma-tag-id cnt) :qwc qwc))
|
||||
(set! (-> (the-as dma-packet packet) vif0) vif0)
|
||||
(set! (-> (the-as dma-packet packet) vif1) vif1)
|
||||
(set! (-> dma-state base) (&+ (the-as pointer packet) 16)))
|
||||
(let ((packet (the-as object (-> dma-buf base))))
|
||||
(set! (-> (the-as dma-packet packet) dma)
|
||||
(new 'static 'dma-tag :qwc qwc :id (dma-tag-id ref) :addr addr))
|
||||
(set! (-> (the-as dma-packet packet) vif0) vif0)
|
||||
(set! (-> (the-as dma-packet packet) vif1) vif1)
|
||||
(set! (-> dma-buf base) (&+ (the-as pointer packet) 16))))
|
||||
)";
|
||||
const auto result = demacro::rewrite(source, rules);
|
||||
EXPECT_EQ(result.rewrite_count(), 3);
|
||||
EXPECT_EQ(result.source, R"((begin
|
||||
(dma-buffer-add-cnt-vif2 dma-buf 0 vif0 vif1)
|
||||
(dma-buffer-add-cnt-vif2 dma-buf qwc vif0 vif1)
|
||||
(dma-buffer-add-ref-vif2 dma-buf qwc addr vif0 vif1))
|
||||
)");
|
||||
}
|
||||
|
||||
TEST(Demacro, Jak1RecognizesDmaNextPackets) {
|
||||
const auto rules =
|
||||
demacro::load_rules(file_util::get_file_path({"decompiler/config/jak1/demacro.jsonc"}));
|
||||
|
||||
Reference in New Issue
Block a user