diff --git a/src/SB/Core/x/xAnim.h b/src/SB/Core/x/xAnim.h index 6e5d1e45b..e2891bb98 100644 --- a/src/SB/Core/x/xAnim.h +++ b/src/SB/Core/x/xAnim.h @@ -14,6 +14,8 @@ typedef struct xAnimActiveEffect; typedef struct xAnimSingle; typedef struct xAnimPlay; +extern U32 gxAnimUseGrowAlloc; + struct xAnimFile { xAnimFile* Next; diff --git a/src/SB/Core/x/xEntMotion.h b/src/SB/Core/x/xEntMotion.h index e830f9aa8..379e5b3f8 100644 --- a/src/SB/Core/x/xEntMotion.h +++ b/src/SB/Core/x/xEntMotion.h @@ -147,7 +147,7 @@ struct xEntPenData xMat4x3 omat; }; -struct xEntMotion +struct xEntMotion // Size: 0x70 { xEntMotionAsset* asset; U8 type; diff --git a/src/SB/Game/zPlatform.cpp b/src/SB/Game/zPlatform.cpp index e47fdbf78..63974cba5 100644 --- a/src/SB/Game/zPlatform.cpp +++ b/src/SB/Game/zPlatform.cpp @@ -6,6 +6,8 @@ #include "xMath.h" #include "xMath3.h" +#include "xstransvc.h" +#include "zGlobals.h" #include @@ -25,6 +27,9 @@ char* str8 = "skatepark_bumper"; char* str9 = "skatepark_flipper"; char* str10 = "Check1"; +void zPlatformTranslate(xEnt* xent, xVec3* dpos, xMat4x3* dmat); +void zPlatform_Move(xEnt* entPlat, xScene* s, float dt, xEntFrame* frame); + static void genericPlatRender(xEnt* ent) { if (!ent->model || !xEntIsVisible(ent)) @@ -40,9 +45,152 @@ void zPlatform_Init(void* plat, void* asset) zPlatform_Init((zPlatform*)plat, (xEntAsset*)asset); } +// FIXME: some asset pointer shenanigans plus a few other quirky spots void zPlatform_Init(zPlatform* plat, xEntAsset* asset) { + // asset pointer points to packed structure with more than just an xEntAsset inside! + xPlatformAsset* platAsset = (xPlatformAsset*)((char*)asset + sizeof(xEntAsset)); + xEntMotionAsset* entMotionAsset = (xEntMotionAsset*)((char*)platAsset + sizeof(xPlatformAsset)); + xLinkAsset* linkAsset = (xLinkAsset*)((char*)entMotionAsset + sizeof(xLinkAsset)); + zEntInit(plat, asset, 'PLAT'); + + plat->passet = platAsset; + plat->subType = platAsset->type; + + if (plat->linkCount != 0) + { + plat->link = linkAsset; + } + else + { + plat->link = NULL; + } + + plat->update = zPlatform_Update; + plat->move = zPlatform_Move; + plat->eventFunc = zPlatformEventCB; + plat->transl = zPlatformTranslate; + plat->render = genericPlatRender; + + plat->am = NULL; + plat->bm = NULL; + plat->state = ZPLATFORM_STATE_INIT; + plat->plat_flags = 0x0; + plat->fmrt = NULL; + plat->pauseMult = 1.0; + plat->pauseDelta = 0.0f; + + if (plat->subType == ZPLATFORM_SUBTYPE_BREAKAWAY) + { + plat->collis = (xEntCollis*)xMemAlloc(gActiveHeap, sizeof(xEntCollis), 0); + + xModelInstance* modelInst = NULL; + + plat->collis->chk = 0x0; + plat->collis->pen = 0x0; + + // TODO: does collis need to be null terminated??? + // this manual memory management is weird as heck but it matches the disassembly + *((U32*)&plat->collis->colls[18]) = NULL; + + plat->am = plat->model; + platAsset->ba.bustModelID = 0x0; + + if (linkAsset->dstAssetID != NULL) + { + modelInst = (xModelInstance*)xSTFindAsset(linkAsset->dstAssetID, (U32*)&plat->flags); + } + + if (modelInst != NULL) + { + xEntLoadModel(plat, (RpAtomic*)modelInst); + plat->bm = plat->model; + } + else + { + plat->bm = NULL; + } + + plat->model = plat->am; + plat->collModel = NULL; + } + else if (plat->subType == ZPLATFORM_SUBTYPE_SPRINGBOARD) + { + xAnimFile* animFile = NULL; + + xAnimFile* anim1File; + if (platAsset->sb.animID[0] != NULL) + { + anim1File = (xAnimFile*)xSTFindAsset(platAsset->sb.animID[0], NULL); + } + else + { + anim1File = NULL; + } + + void* anim2File; + if (platAsset->sb.animID[1] != NULL) + { + anim2File = xSTFindAsset(platAsset->sb.animID[1], NULL); + } + else + { + anim2File = NULL; + } + + if (anim1File != NULL || anim2File != NULL) + { + gxAnimUseGrowAlloc = TRUE; + + plat->atbl = xAnimTableNew("", NULL, 0x0); + xAnimTableNewState(plat->atbl, "Idle", 0x10, 0x0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, + xAnimDefaultBeforeEnter, NULL, NULL); + + if (anim1File != NULL) + { + xAnimTableNewState(plat->atbl, "Spring", 0x20, 0, 1.0f, NULL, NULL, 0.0f, NULL, + NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewTransition(plat->atbl, "Spring", "Idle", + (xAnimTransitionConditionalCallback)0x0, + (xAnimTransitionCallback)0x0, 0x10, 0, 0.0f, 0.0f, 0, 0, + 0.1f, NULL); + + animFile = xAnimFileNew(anim1File, "", 0, (xAnimFile**)0x0); + xAnimTableAddFile(plat->atbl, animFile, "Spring"); + } + + if (anim2File != NULL) + { + animFile = xAnimFileNew(anim2File, "", 0, NULL); + xAnimTableAddFile(plat->atbl, animFile, "Idle"); + } + else + { + xAnimTableAddFile(plat->atbl, animFile, "Idle"); + plat->atbl->StateList->Speed = 1.0f; + } + + // TODO: if this isn't matching, it's because the globals struct isn't defined correctly + // Figure out why that is + gxAnimUseGrowAlloc = FALSE; + xAnimPoolAlloc(&globals.scenePreload->mempool, plat, plat->atbl, plat->model); + } + } + else if (plat->subType == ZPLATFORM_SUBTYPE_FM) + { + plat->fmrt = (zPlatFMRunTime*)xMemAlloc(gActiveHeap, sizeof(zPlatFMRunTime), 0); + } + + xEntMotionInit(&plat->motion, plat, + (xEntMotionAsset*)((char*)asset + sizeof(xEntAsset) + sizeof(xPlatformAsset))); + xEntDriveInit(&plat->drv, plat); + + if (plat->asset->modelInfoID == xStrHash("teeter_totter_pat") || + plat->asset->modelInfoID == xStrHash("teeter_totter_pat_bind")) + { + plat->flags |= 0x2; + } } void zPlatform_Save(zPlatform* ent, xSerial* s) @@ -55,6 +203,10 @@ void zPlatform_Load(zPlatform* ent, xSerial* s) zEntLoad(ent, s); } +void zPlatform_Update(xEnt* ent, xScene* sc, float dt) +{ +} + void zPlatform_Move(xEnt* entPlat, xScene* s, float dt, xEntFrame* frame) { zPlatform* plat = (zPlatform*)entPlat; @@ -155,7 +307,7 @@ void zPlatform_Reset(zPlatform* plat, xScene* sc) else if (plat->subType == ZPLATFORM_SUBTYPE_BREAKAWAY) { plat->tmr = plat->passet->ba.ba_delay; - plat->state = ZPLATFORM_STATE_UNK2; + plat->state = ZPLATFORM_STATE_INIT; plat->pflags &= 0xF9; plat->collis->chk = 0x0; @@ -242,3 +394,8 @@ U32 zMechIsStartingBack(zPlatform* ent, U16 param_2) return param_2 == 3; } } + +S32 zPlatformEventCB(xBase* from, xBase* to, U32 toEvent, const F32* toParam, xBase* base3) +{ + return 1; +} diff --git a/src/SB/Game/zPlatform.h b/src/SB/Game/zPlatform.h index ac505c8db..031096700 100644 --- a/src/SB/Game/zPlatform.h +++ b/src/SB/Game/zPlatform.h @@ -135,13 +135,13 @@ struct zPlatform : zEnt { xPlatformAsset* passet; // 0xD4 xEntMotion motion; - U16 state; - U16 plat_flags; - F32 tmr; - S32 ctr; - xMovePoint* src; - xModelInstance* am; - xModelInstance* bm; + U16 state; // 0x144 + U16 plat_flags; // 0x146 + F32 tmr; // 0x148 + S32 ctr; // 0x14C + xMovePoint* src; // 0x150 + xModelInstance* am; // 0x154 + xModelInstance* bm; // 0x158 S32 moving; xEntDrive drv; zPlatFMRunTime* fmrt; @@ -162,7 +162,7 @@ struct zPlatform : zEnt #define ZPLATFORM_SUBTYPE_FM 13 #define ZPLATFORM_STATE_UNK1 0x3 -#define ZPLATFORM_STATE_UNK2 0x0 +#define ZPLATFORM_STATE_INIT 0x0 #define ZPLATFORM_STATE_UNK3 0x2 void zPlatform_Init(void* plat, void* asset); @@ -171,7 +171,9 @@ void zPlatform_Setup(zPlatform* plat, xScene* sc); void zPlatform_Save(zPlatform* ent, xSerial* s); void zPlatform_Load(zPlatform* ent, xSerial* s); void zPlatform_Reset(zPlatform* plat, xScene* sc); +void zPlatform_Update(xEnt* ent, xScene* sc, float dt); U32 zPlatform_PaddleCollide(xCollis* coll, const xVec3* hitsource, const xVec3* hitvel, U32 worldSpaceNorm); +S32 zPlatformEventCB(xBase* from, xBase* to, U32 toEvent, const F32* toParam, xBase* base3); #endif