From 1c5de6a176ae320675610f68250df5ee998442b3 Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Sun, 14 Dec 2025 21:52:16 -0600 Subject: [PATCH 01/17] xParSys: Match static xParGroupUpdateR function --- src/SB/Core/x/xParSys.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/SB/Core/x/xParSys.cpp b/src/SB/Core/x/xParSys.cpp index 5c106bec9..7ac128f5a 100644 --- a/src/SB/Core/x/xParSys.cpp +++ b/src/SB/Core/x/xParSys.cpp @@ -47,3 +47,29 @@ void xParSysSetup(xParSys* t) t->parent = (xParSys*)xSTFindAsset(t->cmd->flag, 0); t->parent = t->parent; } + +static void xParGroupUpdateR(xParSys* s, xParGroup* g, F32 dt) +{ + if (s->parent != NULL) + { + xParGroupUpdateR(s->parent, g, dt); + } + + if (!s->group->m_active) + { + return; + } + + for (U32 i = 0; i < s->cmdCount; i++) + { + xParCmd* cmd = &s->cmd[i]; + if (cmd != NULL && cmd->tasset != NULL) + { + void (*func)(xParCmd*, xParGroup*, F32) = xParCmdGetUpdateFunc(cmd->tasset->type); + if (func != NULL) + { + func(cmd, g, dt); + } + } + } +} From c442f4e5b34659b6112ba3890f81f095f14e8853 Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Sun, 14 Dec 2025 21:53:57 -0600 Subject: [PATCH 02/17] xParSys: Match static xParGroupUpdate function --- src/SB/Core/x/xParSys.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/SB/Core/x/xParSys.cpp b/src/SB/Core/x/xParSys.cpp index 7ac128f5a..53ed96112 100644 --- a/src/SB/Core/x/xParSys.cpp +++ b/src/SB/Core/x/xParSys.cpp @@ -73,3 +73,19 @@ static void xParGroupUpdateR(xParSys* s, xParGroup* g, F32 dt) } } } + +static void xParGroupUpdate(xParSys* s, xParGroup* g, F32 dt) +{ + for (U32 i = 0; i < s->cmdCount; i++) + { + xParCmd* cmd = &s->cmd[i]; + if (cmd != NULL && cmd->tasset != NULL) + { + void (*func)(xParCmd*, xParGroup*, F32) = xParCmdGetUpdateFunc(cmd->tasset->type); + if (func != NULL) + { + func(cmd, g, dt); + } + } + } +} From 58add1dfa1025d21474d84b0e4dce61c91dc4145 Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Sun, 14 Dec 2025 22:07:39 -0600 Subject: [PATCH 03/17] xParSys: Close match on xParSysRender --- src/SB/Core/x/xParSys.cpp | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/SB/Core/x/xParSys.cpp b/src/SB/Core/x/xParSys.cpp index 53ed96112..f3c379b92 100644 --- a/src/SB/Core/x/xParSys.cpp +++ b/src/SB/Core/x/xParSys.cpp @@ -1,7 +1,10 @@ #include "xParSys.h" -#include #include "zScene.h" +#include "xRenderState.h" +#include "zRenderState.h" + +#include static xVec3 par_offset_right; static xVec3 par_offset_up; @@ -89,3 +92,23 @@ static void xParGroupUpdate(xParSys* s, xParGroup* g, F32 dt) } } } + +void xParSysRender(xBase* b) +{ + xParSys* s = (xParSys*)b; + zRenderState(SDRS_Particles); + + xParGroup* g = s->group; + while (g != NULL) + { + if (g->m_active && g->m_visible && g->m_alive && !g->m_culled && g->draw != NULL) + { + xRenderStateSetTexture(s->txtr_particle); + xRenderStateSetSrcBlendMode(s->tasset->renderSrcBlendMode); + xRenderStateSetDstBlendMode(s->tasset->renderDstBlendMode); + g->draw(b, g); + } + + g = g->m_next; + } +} From 4ca2361af14b0122139f4b72b1997301b9f98c67 Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Sun, 14 Dec 2025 22:27:30 -0600 Subject: [PATCH 04/17] xParSys: Complete match on xParSysReset and xParSysExit --- src/SB/Core/x/xParSys.cpp | 25 +++++++++++++++++++++++++ src/SB/Core/x/xParSys.h | 1 + 2 files changed, 26 insertions(+) diff --git a/src/SB/Core/x/xParSys.cpp b/src/SB/Core/x/xParSys.cpp index f3c379b92..bf940da7c 100644 --- a/src/SB/Core/x/xParSys.cpp +++ b/src/SB/Core/x/xParSys.cpp @@ -51,6 +51,31 @@ void xParSysSetup(xParSys* t) t->parent = t->parent; } +void xParSysReset(xParSys* t) +{ + xBaseReset(t, t->tasset); + + if (t->group != NULL) + { + xParGroupKillAllParticles(t->group); + + t->visible = t->tasset->parFlags & 0x1; + + xParGroupSetAging(t->group, (((t->tasset->parFlags >> 1) & 0x1) ^ 0x1) & 0xFF); + xParGroupSetVisibility(t->group, t->visible); + xParGroupSetBack2Life(t->group,(((t->tasset->parFlags >> 2) & 0x1) ^ 0x1) & 0xFF); + } +} + +void xParSysExit(xParSys* t) +{ + if (t->group != NULL) + { + xParGroupKillAllParticles(t->group); + xParGroupUnregister(t->group); + } +} + static void xParGroupUpdateR(xParSys* s, xParGroup* g, F32 dt) { if (s->parent != NULL) diff --git a/src/SB/Core/x/xParSys.h b/src/SB/Core/x/xParSys.h index 4ee1b7ee7..81ddf1f6d 100644 --- a/src/SB/Core/x/xParSys.h +++ b/src/SB/Core/x/xParSys.h @@ -47,6 +47,7 @@ void xParCmdTexInit(xParCmdTex* tex); void xParSysInit(void* b, void* tasset); void xParSysInit(xBase* b, xParSysAsset* tasset); void xParSysSetup(xParSys* t); +void xParSysReset(xParSys* t); void xParSysExit(xParSys* t); void xParSysRender(xBase* b); S32 xParSysEventCB(xBase*, xBase*, U32, F32*, xBase*); From 78f9e8dd583cfe450b027cb979d7dd00e75ae77a Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Mon, 15 Dec 2025 23:39:44 -0600 Subject: [PATCH 05/17] xParCmd: Remove unneeded forward decl for xParGroup --- src/SB/Core/x/xParCmd.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/SB/Core/x/xParCmd.h b/src/SB/Core/x/xParCmd.h index 2f6660eb9..301fbb009 100644 --- a/src/SB/Core/x/xParCmd.h +++ b/src/SB/Core/x/xParCmd.h @@ -54,8 +54,6 @@ struct xParCmd xParCmdAsset* tasset; }; -struct xParGroup; - typedef void (*xParCmdUpdateFunc)(xParCmd* c, xParGroup* ps, F32 dt); void xParCmdInit(); From 17f072339db879ff785cecf84e659fc5a86cb0c6 Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Mon, 15 Dec 2025 23:40:53 -0600 Subject: [PATCH 06/17] xParSys: Near-equivalent match for xParSysInit --- src/SB/Core/x/xParSys.cpp | 57 +++++++++++++++++++++++++++++++++++++++ src/SB/Core/x/xParSys.h | 2 +- 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/src/SB/Core/x/xParSys.cpp b/src/SB/Core/x/xParSys.cpp index bf940da7c..5e7f459f6 100644 --- a/src/SB/Core/x/xParSys.cpp +++ b/src/SB/Core/x/xParSys.cpp @@ -39,6 +39,63 @@ void xParSysInit(void* b, void* tasset) void xParSysInit(xBase* b, xParSysAsset* tasset) { + xParSys* t = (xParSys*)b; + + xBaseInit(b, tasset); + t->eventFunc = &xParSysEventCB; + t->tasset = tasset; + + if (t->linkCount > 0) + { + // TODO: is this a compiler scheduling issue or a true mismatch? + t->link = (xLinkAsset*)((char*)t->tasset + tasset->cmdSize + sizeof(xParSysAsset)); + } + else + { + t->link = NULL; + } + + t->visible = tasset->parFlags & 0x1; + t->cmdCount = tasset->cmdCount; + if (t->cmdCount) + { + t->cmd = (xParCmd*)xMemAlloc(gActiveHeap, t->cmdCount * sizeof(xParCmd), FALSE); + } + else + { + t->cmd = NULL; + } + + // Some arcane magic required due to how the asset command data is packed + U32 i; + U8* cmdPtr = (U8*)&tasset[1]; + for (i = 0; i < t->cmdCount; i++) + { + *(U32*)(&t->cmd[i]) = TRUE; + *(U32*)(&t->cmd[i].tasset) = (U32)cmdPtr; + cmdPtr += xParCmdGetSize(*(U32*)cmdPtr); + } + + t->group = (xParGroup*)xMemAlloc(gActiveHeap, sizeof(xParGroup), FALSE); + xParGroupInit(t->group); + xParGroupSetPriority(t->group, tasset->priority); + xParGroupRegister(t->group); + xParGroupSetAging(t->group, (((tasset->parFlags >> 1) & 0x1) ^ 0x1) & 0xFF); + xParGroupSetVisibility(t->group, t->visible); + xParGroupSetBack2Life(t->group,(((tasset->parFlags >> 2) & 0x1) ^ 0x1) & 0xFF); + t->parent = NULL; + + for (i = 0; i < t->cmdCount; i++) + { + if (t->cmd[i].tasset->type == XPARCMD_TYPE_TEX) + { + t->group->m_cmdTex = (xParCmdTex*)t->cmd[i].tasset; + xParCmdTexInit(t->group->m_cmdTex); + break; + } + } + + t->group->draw = sParSysInfo[t->tasset->renderFunc].func; } void xParSysSetup(xParSys* t) diff --git a/src/SB/Core/x/xParSys.h b/src/SB/Core/x/xParSys.h index 81ddf1f6d..a91d56770 100644 --- a/src/SB/Core/x/xParSys.h +++ b/src/SB/Core/x/xParSys.h @@ -50,7 +50,7 @@ void xParSysSetup(xParSys* t); void xParSysReset(xParSys* t); void xParSysExit(xParSys* t); void xParSysRender(xBase* b); -S32 xParSysEventCB(xBase*, xBase*, U32, F32*, xBase*); +S32 xParSysEventCB(xBase*, xBase*, U32, const F32*, xBase*); void xParSysUpdate(xBase* to, xScene*, F32 dt); U8 using_ptank_render(const xParSysAsset&); From 0b273f3e65181c6b4bbe4a5e96a72ccf08cb90d2 Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Tue, 16 Dec 2025 00:07:10 -0600 Subject: [PATCH 07/17] xParSys: Match sdata and rodata segments, par_sprite_begin func --- src/SB/Core/gc/iParMgr.h | 4 ++++ src/SB/Core/x/xParSys.cpp | 17 +++++++++++++++-- src/SB/Core/x/xParSys.h | 9 ++++++++- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/SB/Core/gc/iParMgr.h b/src/SB/Core/gc/iParMgr.h index 4168278ce..e13f769e4 100644 --- a/src/SB/Core/gc/iParMgr.h +++ b/src/SB/Core/gc/iParMgr.h @@ -42,8 +42,12 @@ void iRenderSetCameraViewMatrix(xMat4x3* m); void iRenderFlush(); void iRenderTrianglesImmediate(S32 vertType, S32 vertTypeSize, void* data, S32 dataSize, U16* index, S32 indexSize); +void iParMgrRenderParSys_Streak(void* data, xParGroup* ps); void iParMgrRenderParSys_QuadStreak(void* data, xParGroup* ps); +void iParMgrRenderParSys_InvStreak(void* data, xParGroup* ps); void iParMgrRenderParSys_Flat(void* data, xParGroup* ps); +void iParMgrRenderParSys_Static(void* data, xParGroup* ps); +void iParMgrRenderParSys_Ground(void* data, xParGroup* ps); void iParMgrRenderParSys_Sprite(void* data, xParGroup* ps); #endif diff --git a/src/SB/Core/x/xParSys.cpp b/src/SB/Core/x/xParSys.cpp index 5e7f459f6..fe12e4b2f 100644 --- a/src/SB/Core/x/xParSys.cpp +++ b/src/SB/Core/x/xParSys.cpp @@ -3,18 +3,31 @@ #include "zScene.h" #include "xRenderState.h" #include "zRenderState.h" +#include "zGlobals.h" #include static xVec3 par_offset_right; static xVec3 par_offset_up; -static xParSysInfo sParSysInfo[7]; +static void render_par_sprite(void* data, xParGroup* ps); -static S32 sBlendTable[11] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; +static xParSysInfo sParSysInfo[7] = { + { XPARSYSINFO_TYPE_SPRITE, render_par_sprite }, + { XPARSYSINFO_TYPE_STREAK, iParMgrRenderParSys_Streak }, + { XPARSYSINFO_TYPE_FLAT, iParMgrRenderParSys_Flat }, + { XPARSYSINFO_TYPE_STATIC, iParMgrRenderParSys_Static }, + { XPARSYSINFO_TYPE_GROUND, iParMgrRenderParSys_Ground }, + { XPARSYSINFO_TYPE_QUADSTREAK, iParMgrRenderParSys_QuadStreak }, + { XPARSYSINFO_TYPE_INVSTREAK, iParMgrRenderParSys_InvStreak } +}; + +static const S32 sBlendTable[11] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; static void par_sprite_begin() { + par_offset_right = globals.camera.mat.right * 0.5f; + par_offset_up = globals.camera.mat.up * 0.5f; } static void render_par_sprite(void* data, xParGroup* ps) diff --git a/src/SB/Core/x/xParSys.h b/src/SB/Core/x/xParSys.h index a91d56770..b3fec8c91 100644 --- a/src/SB/Core/x/xParSys.h +++ b/src/SB/Core/x/xParSys.h @@ -6,10 +6,17 @@ #include "xParGroup.h" #include "iParMgr.h" #include "xstransvc.h" +#include "xScene.h" #include -struct xScene; +#define XPARSYSINFO_TYPE_SPRITE 0 +#define XPARSYSINFO_TYPE_STREAK 1 +#define XPARSYSINFO_TYPE_FLAT 2 +#define XPARSYSINFO_TYPE_STATIC 3 +#define XPARSYSINFO_TYPE_GROUND 4 +#define XPARSYSINFO_TYPE_QUADSTREAK 5 +#define XPARSYSINFO_TYPE_INVSTREAK 6 struct xParSysAsset : xBaseAsset { From b49912e6668a9393e52b8f40a130547807b83c37 Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Tue, 16 Dec 2025 00:12:39 -0600 Subject: [PATCH 08/17] xParSys: Thanks Square for 100% match on xParSysInit --- src/SB/Core/x/xParSys.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/SB/Core/x/xParSys.cpp b/src/SB/Core/x/xParSys.cpp index fe12e4b2f..b60a65a94 100644 --- a/src/SB/Core/x/xParSys.cpp +++ b/src/SB/Core/x/xParSys.cpp @@ -60,8 +60,7 @@ void xParSysInit(xBase* b, xParSysAsset* tasset) if (t->linkCount > 0) { - // TODO: is this a compiler scheduling issue or a true mismatch? - t->link = (xLinkAsset*)((char*)t->tasset + tasset->cmdSize + sizeof(xParSysAsset)); + t->link = (xLinkAsset*)((char*)&t->tasset[1] + tasset->cmdSize); } else { From c9af11f33d0312c26f150a693130243a147170c2 Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Tue, 16 Dec 2025 14:14:32 -0600 Subject: [PATCH 09/17] xVec3: Add negative operator overload declaration --- src/SB/Core/x/xVec3.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SB/Core/x/xVec3.h b/src/SB/Core/x/xVec3.h index 7eb08a531..fbfe67d0d 100644 --- a/src/SB/Core/x/xVec3.h +++ b/src/SB/Core/x/xVec3.h @@ -26,6 +26,7 @@ struct xVec3 xVec3& operator=(const xVec3&); xVec3 operator+(const xVec3&) const; xVec3 operator-(const xVec3&) const; + xVec3 operator-() const; xVec3 operator*(F32) const; xVec3 operator/(F32) const; xVec3& operator+=(const xVec3&); From 7b9cc928fcc3fc16b378acb1f600839eff03ab8c Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Tue, 16 Dec 2025 14:14:53 -0600 Subject: [PATCH 10/17] xParSys: 100% match on par_sprite_update --- src/SB/Core/x/xParSys.cpp | 94 ++++++++++++++++++++++++++++++++++++++ src/SB/Core/x/xPtankPool.h | 2 +- 2 files changed, 95 insertions(+), 1 deletion(-) diff --git a/src/SB/Core/x/xParSys.cpp b/src/SB/Core/x/xParSys.cpp index b60a65a94..beebf5933 100644 --- a/src/SB/Core/x/xParSys.cpp +++ b/src/SB/Core/x/xParSys.cpp @@ -4,6 +4,7 @@ #include "xRenderState.h" #include "zRenderState.h" #include "zGlobals.h" +#include "xPtankPool.h" #include @@ -30,6 +31,99 @@ static void par_sprite_begin() par_offset_up = globals.camera.mat.up * 0.5f; } +static void par_sprite_update(xParSys& sys, xParGroup& group) +{ + if (!using_ptank_render(*sys.tasset)) + { + return; + } + + U32 pivot = sys.tasset->parFlags; + xVec3 offset_right; + if (pivot & 0x8) + { + offset_right = par_offset_right; + } + else if (pivot & 0x20) + { + offset_right = -par_offset_right; + } + else + { + offset_right = 0.0f; + } + + xVec3 offset_up; + if (pivot & 0x10) + { + offset_up = -par_offset_up; + } + else if (pivot & 0x40) + { + offset_up = par_offset_up; + } + else + { + offset_up = 0.0f; + } + + ptank_pool__pos_color_size_uv2 pool; + pool.rs.texture = sys.txtr_particle; + pool.rs.src_blend = sBlendTable[sys.tasset->renderSrcBlendMode]; + pool.rs.dst_blend = sBlendTable[sys.tasset->renderDstBlendMode]; + pool.rs.flags = 0x0; + pool.reset(); + + xParCmdTex* tex = group.m_cmdTex; + xPar* p = group.m_root; + while (p != NULL) + { + RwSphere testSphere; + testSphere.center = *(RwV3d*)&p->m_pos; + testSphere.radius = p->m_size; + + if (RwCameraFrustumTestSphere(globals.camera.lo_cam, &testSphere)) + { + pool.next(); + + if (!pool.valid()) + { + break; + } + + xVec3& loc = *pool.pos; + loc = p->m_pos; + loc += offset_right * p->m_size; + loc += offset_up * p->m_size; + + pool.color->r = p->m_c[0]; + pool.color->g = p->m_c[1]; + pool.color->b = p->m_c[2]; + pool.color->a = p->m_c[3]; + + pool.size->assign(p->m_size, p->m_size); + + if (tex) + { + pool.uv[0].x = p->m_texIdx[0] * tex->unit_width + tex->x1; + pool.uv[0].y = p->m_texIdx[1] * tex->unit_height + tex->y1; + + pool.uv[1].x = (p->m_texIdx[0] + 1) * tex->unit_width + tex->x1; + pool.uv[1].y = (p->m_texIdx[1] + 1) * tex->unit_height + tex->y1; + } + else + { + pool.uv[0].assign(0.0f, 0.0f); + pool.uv[1].assign(1.0f, 1.0f); + } + } + + p = p->m_next; + } + + pool.flush(); +} + static void render_par_sprite(void* data, xParGroup* ps) { if (using_ptank_render((*(xParSysAsset*)&ps->m_culled)) == 0) diff --git a/src/SB/Core/x/xPtankPool.h b/src/SB/Core/x/xPtankPool.h index 4c5c5205a..31a7d8eeb 100644 --- a/src/SB/Core/x/xPtankPool.h +++ b/src/SB/Core/x/xPtankPool.h @@ -117,7 +117,7 @@ struct ptank_pool__color_mat_uv2 : ptank_pool { }; // total size: 0x38 -struct ptank_pool__pos_color_size_uv2 : public ptank_pool +struct ptank_pool__pos_color_size_uv2 : ptank_pool { xVec3* pos; iColor_tag* color; From e38bb66a61a07a1d680291c884491b6b40f81de4 Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Tue, 16 Dec 2025 15:58:34 -0600 Subject: [PATCH 11/17] xParSys: Match xParSysEventCB and xParSysUpdate --- src/SB/Core/x/xParSys.cpp | 77 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/src/SB/Core/x/xParSys.cpp b/src/SB/Core/x/xParSys.cpp index beebf5933..b4a8d8ed5 100644 --- a/src/SB/Core/x/xParSys.cpp +++ b/src/SB/Core/x/xParSys.cpp @@ -239,6 +239,83 @@ void xParSysExit(xParSys* t) } } +S32 xParSysEventCB(xBase* from, xBase* to, U32 toEvent, const F32* toParam, xBase* toParamWidget) +{ + xParSys* t = (xParSys*)to; + + switch (toEvent) + { + case eEventReset: + xParSysReset(t); + break; + case eEventVisible: + t->visible = TRUE; + if (t->group != NULL) + { + xParGroupSetVisibility(t->group, t->visible); + } + break; + case eEventInvisible: + t->visible = FALSE; + if (t->group != NULL) + { + xParGroupSetVisibility(t->group, t->visible); + } + break; + case eEventOn: + if (t->group != NULL) + { + xParGroupSetActive(t->group, TRUE); + } + break; + case eEventOff: + if (t->group != NULL) + { + xParGroupSetActive(t->group, FALSE); + } + break; + } + + return TRUE; +} + +static void xParGroupUpdateR(xParSys* s, xParGroup* g, F32 dt); +static void xParGroupUpdate(xParSys* s, xParGroup* g, F32 dt); +void xParSysUpdate(xBase* to, xScene* scn, F32 dt) +{ + xParSys* s = (xParSys*)to; + xParSys* parent = s->parent; + if (s->tasset->renderFunc == NULL) + { + par_sprite_begin(); + } + + xParGroup* g = s->group; + while (g != NULL) + { + if (g->m_active) + { + if (parent) + { + xParGroupUpdateR(parent, g, dt); + } + + if (g->m_alive) + { + xParGroupUpdate(s, g, dt); + } + } + + xParGroupAnimate(g, dt); + if (g->m_num_of_particles > 0 && !s->tasset->renderFunc) + { + par_sprite_update(*s, *g); + } + + g = g->m_next; + } +} + static void xParGroupUpdateR(xParSys* s, xParGroup* g, F32 dt) { if (s->parent != NULL) From 982059923bc4fbd3cd452942bfe535ae08686073 Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Tue, 16 Dec 2025 16:20:01 -0600 Subject: [PATCH 12/17] xParSys: Fix mismatches in xParSysSetup and render_par_sprite --- src/SB/Core/x/xParSys.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/SB/Core/x/xParSys.cpp b/src/SB/Core/x/xParSys.cpp index b4a8d8ed5..ba03007ce 100644 --- a/src/SB/Core/x/xParSys.cpp +++ b/src/SB/Core/x/xParSys.cpp @@ -126,7 +126,7 @@ static void par_sprite_update(xParSys& sys, xParGroup& group) static void render_par_sprite(void* data, xParGroup* ps) { - if (using_ptank_render((*(xParSysAsset*)&ps->m_culled)) == 0) + if (!using_ptank_render(*((xParSys*)data)->tasset)) { iParMgrRenderParSys_Sprite(data, ps); } @@ -206,12 +206,11 @@ void xParSysInit(xBase* b, xParSysAsset* tasset) void xParSysSetup(xParSys* t) { - if (t != 0 && t->link != 0 && t->link->param[1]) + if (t != NULL && t->tasset != NULL && t->tasset->parentParSysID != 0x0) { - t->parent = (xParSys*)zSceneFindObject(t->cmd->flag); + t->parent = (xParSys*)zSceneFindObject(t->tasset->parentParSysID); } - t->parent = (xParSys*)xSTFindAsset(t->cmd->flag, 0); - t->parent = t->parent; + t->txtr_particle = (RwTexture*)xSTFindAsset(t->tasset->textureID, 0); } void xParSysReset(xParSys* t) From 8578a0a1a0697e94477dba5c2cccb913cbb46226 Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Tue, 16 Dec 2025 21:29:41 -0600 Subject: [PATCH 13/17] xParSys: 100% match on xParSysRender --- src/SB/Core/x/xParSys.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/SB/Core/x/xParSys.cpp b/src/SB/Core/x/xParSys.cpp index ba03007ce..a2adf1b81 100644 --- a/src/SB/Core/x/xParSys.cpp +++ b/src/SB/Core/x/xParSys.cpp @@ -359,10 +359,11 @@ static void xParGroupUpdate(xParSys* s, xParGroup* g, F32 dt) void xParSysRender(xBase* b) { + xParGroup* g; xParSys* s = (xParSys*)b; zRenderState(SDRS_Particles); - xParGroup* g = s->group; + g = s->group; while (g != NULL) { if (g->m_active && g->m_visible && g->m_alive && !g->m_culled && g->draw != NULL) @@ -370,7 +371,7 @@ void xParSysRender(xBase* b) xRenderStateSetTexture(s->txtr_particle); xRenderStateSetSrcBlendMode(s->tasset->renderSrcBlendMode); xRenderStateSetDstBlendMode(s->tasset->renderDstBlendMode); - g->draw(b, g); + g->draw(s, g); } g = g->m_next; From d4d97ae6fac9634a3de3b68b75fa34ef77927c5e Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Tue, 16 Dec 2025 22:35:14 -0600 Subject: [PATCH 14/17] xPtankPool: Match weak funcs from xParSys --- src/SB/Core/x/xPtankPool.h | 85 +++++++++++++++++++++++++++++++++++--- 1 file changed, 79 insertions(+), 6 deletions(-) diff --git a/src/SB/Core/x/xPtankPool.h b/src/SB/Core/x/xPtankPool.h index 31a7d8eeb..c21009366 100644 --- a/src/SB/Core/x/xPtankPool.h +++ b/src/SB/Core/x/xPtankPool.h @@ -48,12 +48,32 @@ struct ptank_pool U32 size; } hide; - bool valid() const; - void reset(); + bool valid() const + { + return ptank != NULL; + } + + bool at_block_end() const + { + return (used & 0x3F) == 0; + } + + void unlock_block() + { + RpPTankAtomicUnlock(ptank); + RPATOMICPTANKPLUGINDATA(ptank)->instFlags |= 0x800000; + RPATOMICPTANKPLUGINDATA(ptank)->actPCount = used; + used = 0; + } + + void reset() + { + ptank = NULL; + used = 0; + } + void flush(); void grab_block(ptank_group_type type); - bool at_block_end() const; - void unlock_block(); void lock_block(); }; @@ -125,8 +145,61 @@ struct ptank_pool__pos_color_size_uv2 : ptank_pool xVec2* uv; S32 stride; - void next(); - void flush(); + void next() + { + if (at_block_end()) + { + if (valid()) + { + unlock_block(); + } + + grab_block(PGT_POS_COLOR_SIZE_UV2); + + if (!valid()) + { + return; + } + + lock_block(); + } + else + { + pos = (xVec3*)((char*)pos + stride); + color = (iColor_tag*)((char*)color + stride); + size = (xVec2*)((char*)size + stride); + uv = (xVec2*)((char*)uv + stride); + } + + used += 1; + } + + void lock_block() + { + RpPTankLockStruct ls_color; + RpPTankLockStruct ls_pos; + RpPTankLockStruct ls_size; + RpPTankLockStruct ls_uv; + + RpPTankAtomicLock(ptank, &ls_pos, rpPTANKLFLAGPOSITION, rpPTANKLOCKWRITE); + RpPTankAtomicLock(ptank, &ls_color, rpPTANKLFLAGCOLOR, rpPTANKLOCKWRITE); + RpPTankAtomicLock(ptank, &ls_size, rpPTANKLFLAGSIZE, rpPTANKLOCKWRITE); + RpPTankAtomicLock(ptank, &ls_uv, rpPTANKLFLAGVTX2TEXCOORDS, rpPTANKLOCKWRITE); + + pos = (xVec3*)ls_pos.data; + color = (iColor_tag*)ls_color.data; + size = (xVec2*)ls_size.data; + uv = (xVec2*)ls_uv.data; + stride = ls_pos.stride; + } + + void flush() + { + hide.data = (U8*)size + stride; + hide.stride = stride; + hide.size = 4; + ptank_pool::flush(); + } }; void xPTankPoolSceneEnter(); From 324c7fd347201e7e3054f9029044362b99a73cad Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Tue, 16 Dec 2025 22:35:25 -0600 Subject: [PATCH 15/17] xParSys: Match using_ptank_render --- src/SB/Core/x/xParSys.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/SB/Core/x/xParSys.h b/src/SB/Core/x/xParSys.h index b3fec8c91..d74bf13c8 100644 --- a/src/SB/Core/x/xParSys.h +++ b/src/SB/Core/x/xParSys.h @@ -60,6 +60,9 @@ void xParSysRender(xBase* b); S32 xParSysEventCB(xBase*, xBase*, U32, const F32*, xBase*); void xParSysUpdate(xBase* to, xScene*, F32 dt); -U8 using_ptank_render(const xParSysAsset&); +bool using_ptank_render(const xParSysAsset& tasset) +{ + return (tasset.parFlags >> 7) & 0x1; +} #endif From 9daf4cfd47ff318c2dc8182e58b14b4609e02dc6 Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Tue, 16 Dec 2025 22:35:36 -0600 Subject: [PATCH 16/17] Configure xParSys.cpp to use sym on --- configure.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.py b/configure.py index 9abc51445..d78a59818 100644 --- a/configure.py +++ b/configure.py @@ -568,7 +568,7 @@ def MatchingFor(*versions): Object(NonMatching, "SB/Core/x/xNPCBasic.cpp"), Object(NonMatching, "SB/Game/zEntPlayerBungeeState.cpp", extra_cflags=["-sym on"]), Object(NonMatching, "SB/Game/zCollGeom.cpp"), - Object(NonMatching, "SB/Core/x/xParSys.cpp"), + Object(NonMatching, "SB/Core/x/xParSys.cpp", extra_cflags=["-sym on"]), Object(NonMatching, "SB/Core/x/xParEmitter.cpp"), Object(Matching, "SB/Core/x/xVolume.cpp"), Object(NonMatching, "SB/Core/x/xParEmitterType.cpp"), From acd159b9676c48e882f7b1a9da061bfe0559ae2f Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Tue, 16 Dec 2025 22:45:07 -0600 Subject: [PATCH 17/17] xParSys: Inline using_ptank_render for linker --- src/SB/Core/x/xParSys.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SB/Core/x/xParSys.h b/src/SB/Core/x/xParSys.h index d74bf13c8..9fc48034b 100644 --- a/src/SB/Core/x/xParSys.h +++ b/src/SB/Core/x/xParSys.h @@ -60,7 +60,7 @@ void xParSysRender(xBase* b); S32 xParSysEventCB(xBase*, xBase*, U32, const F32*, xBase*); void xParSysUpdate(xBase* to, xScene*, F32 dt); -bool using_ptank_render(const xParSysAsset& tasset) +inline bool using_ptank_render(const xParSysAsset& tasset) { return (tasset.parFlags >> 7) & 0x1; }