diff --git a/configure.py b/configure.py index 5fe4d51..1575602 100644 --- a/configure.py +++ b/configure.py @@ -339,7 +339,7 @@ def MatchingFor(*versions): Object(NonMatching, "SB/Game/zParticleCustom.cpp"), Object(NonMatching, "SB/Core/gc/iWad.cpp"), Object(NonMatching, "SB/Core/gc/iTRC.cpp"), - Object(NonMatching, "SB/Core/gc/iException.cpp"), + Object(Matching, "SB/Core/gc/iException.cpp"), Object(NonMatching, "SB/Core/gc/iScrFX.cpp"), Object(NonMatching, "SB/Core/gc/iARAMTmp.cpp"), diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stdlib.h b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stdlib.h index ffd0d5c..c5dfcbd 100644 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stdlib.h +++ b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stdlib.h @@ -18,4 +18,4 @@ long abs(long n); } #endif -#endif \ No newline at end of file +#endif diff --git a/src/SB/Core/gc/iAnim.h b/src/SB/Core/gc/iAnim.h new file mode 100644 index 0000000..594f67a --- /dev/null +++ b/src/SB/Core/gc/iAnim.h @@ -0,0 +1,16 @@ +#ifndef IANIM_H +#define IANIM_H + +#include "xMath3.h" + +extern U8* giAnimScratch; + +void iAnimInit(); +F32 iAnimDuration(void* RawData); +U32 iAnimBoneCount(void* RawData); +void iAnimBlend(F32 BlendFactor, F32 BlendRecip, U16* BlendTimeOffset, F32* BoneTable, + U32 BoneCount, xVec3* Tran1, xQuat* Quat1, xVec3* Tran2, xQuat* Quat2, + xVec3* TranDest, xQuat* QuatDest); +void iAnimEval(void* RawData, float time, unsigned int flags, class xVec3* tran, class xQuat* quat); + +#endif diff --git a/src/SB/Core/gc/iAnimSKB.h b/src/SB/Core/gc/iAnimSKB.h new file mode 100644 index 0000000..d67fc03 --- /dev/null +++ b/src/SB/Core/gc/iAnimSKB.h @@ -0,0 +1,26 @@ +#ifndef IANIMSKB_H +#define IANIMSKB_H + +#include "xMath3.h" + +struct iAnimSKBHeader +{ + U32 Magic; + U32 Flags; + U16 BoneCount; + U16 TimeCount; + U32 KeyCount; + F32 Scale[3]; +}; + +struct iAnimSKBKey +{ + U16 TimeIndex; + S16 Quat[4]; + S16 Tran[3]; +}; + +void iAnimEvalSKB(iAnimSKBHeader* data, F32 time, U32 flags, xVec3* tran, xQuat* quat); +F32 iAnimDurationSKB(iAnimSKBHeader* data); + +#endif diff --git a/src/SB/Core/gc/iCollide.h b/src/SB/Core/gc/iCollide.h new file mode 100644 index 0000000..41f9af9 --- /dev/null +++ b/src/SB/Core/gc/iCollide.h @@ -0,0 +1,17 @@ +#ifndef ICOLLIDE_H +#define ICOLLIDE_H + +#include "xMath3.h" +#include "xModel.h" +#include "xEnv.h" +#include "xCollide.h" + +void iBoxForModelLocal(xBox* o, const xModelInstance* m); +void iBoxForModel(xBox* o, const xModelInstance* m); +S32 iSphereHitsEnv3(const xSphere* b, const xEnv* env, xCollis* colls, U8 ncolls, F32 sth); +S32 iSphereHitsModel3(const xSphere* b, const xModelInstance* m, xCollis* colls, U8 ncolls, + F32 sth); +U32 iRayHitsModel(const xRay3* r, const xModelInstance* m, xCollis* coll); +void iCollideInit(xScene* sc); + +#endif diff --git a/src/SB/Core/gc/iCollideFast.h b/src/SB/Core/gc/iCollideFast.h new file mode 100644 index 0000000..2e3dcb8 --- /dev/null +++ b/src/SB/Core/gc/iCollideFast.h @@ -0,0 +1,8 @@ +#ifndef ICOLLIDEFAST_H +#define ICOLLIDEFAST_H + +#include "xScene.h" + +void iCollideFastInit(xScene* sc); + +#endif diff --git a/src/SB/Core/gc/iColor.h b/src/SB/Core/gc/iColor.h new file mode 100644 index 0000000..c01e8ba --- /dev/null +++ b/src/SB/Core/gc/iColor.h @@ -0,0 +1,23 @@ +#ifndef ICOLOR_H +#define ICOLOR_H + +#include + +struct iColor_tag +{ + U8 r; + U8 g; + U8 b; + U8 a; + + iColor_tag& operator=(const iColor_tag& rhs) + { + this->r = rhs.r; + this->g = rhs.g; + this->b = rhs.b; + this->a = rhs.a; + return *this; + }; +}; + +#endif diff --git a/src/SB/Core/gc/iCutscene.h b/src/SB/Core/gc/iCutscene.h new file mode 100644 index 0000000..8872dc6 --- /dev/null +++ b/src/SB/Core/gc/iCutscene.h @@ -0,0 +1,15 @@ +#ifndef ICUTSCENE_H +#define ICUTSCENE_H + +#include "xCutscene.h" +#include "xSnd.h" + +void iCSSoundSetup(xCutscene* csn); +void* iCSSoundGetData(xSndVoiceInfo* vp, U32* size); +U32 iCSFileOpen(xCutscene* csn); +void iCSFileAsyncRead(xCutscene* csn, void* dest, U32 size); +void iCSFileAsyncSkip(xCutscene* csn, U32 amount); +void iCSFileClose(xCutscene* csn); +S32 iCSLoadStep(xCutscene* csn); + +#endif diff --git a/src/SB/Core/gc/iDraw.h b/src/SB/Core/gc/iDraw.h new file mode 100644 index 0000000..c772b4f --- /dev/null +++ b/src/SB/Core/gc/iDraw.h @@ -0,0 +1,10 @@ +#ifndef IDRAW_H +#define IDRAW_H + +#include + +void iDrawSetFBMSK(U32 abgr); +void iDrawBegin(); +void iDrawEnd(); + +#endif diff --git a/src/SB/Core/gc/iEnv.h b/src/SB/Core/gc/iEnv.h new file mode 100644 index 0000000..acceb7a --- /dev/null +++ b/src/SB/Core/gc/iEnv.h @@ -0,0 +1,30 @@ +#ifndef IENV_H +#define IENV_H + +#include "xJSP.h" + +#include +#include + +struct iEnv +{ + RpWorld* world; + RpWorld* collision; + RpWorld* fx; + RpWorld* camera; + xJSPHeader* jsp; + RpLight* light[2]; + RwFrame* light_frame[2]; + S32 memlvl; +}; + +struct xEnvAsset; + +void iEnvLoad(iEnv* env, const void* data, U32 datasize, S32 dataType); +void iEnvFree(iEnv* env); +void iEnvDefaultLighting(iEnv*); +void iEnvLightingBasics(iEnv*, xEnvAsset*); +void iEnvRender(iEnv* env); +void iEnvEndRenderFX(iEnv*); + +#endif diff --git a/src/SB/Core/gc/iException.cpp b/src/SB/Core/gc/iException.cpp index e69de29..7cc017f 100644 --- a/src/SB/Core/gc/iException.cpp +++ b/src/SB/Core/gc/iException.cpp @@ -0,0 +1,8 @@ +#include "iException.h" + +void iExceptionMemCrash(const char* loc, U32 size, const char* arg3) +{ + OSReport("Out of memory crash, Loc=%s Size=%d\n", loc, size); + OSReport("%s\n", arg3); + OSPanic("iException.cpp", 25, ""); +} diff --git a/src/SB/Core/gc/iException.h b/src/SB/Core/gc/iException.h new file mode 100644 index 0000000..1ef1cd2 --- /dev/null +++ b/src/SB/Core/gc/iException.h @@ -0,0 +1,8 @@ +#ifndef IEXCEPTION_H +#define IEXCEPTION_H + +#include "dolphin.h" +#include "dolphin/os.h" +#include + +#endif diff --git a/src/SB/Core/gc/iFMV.h b/src/SB/Core/gc/iFMV.h new file mode 100644 index 0000000..5d0a57c --- /dev/null +++ b/src/SB/Core/gc/iFMV.h @@ -0,0 +1,29 @@ +#ifndef IFMV_H +#define IFMV_H + +#include +#include +#include + +struct _GXRenderModeObj; + +struct iFMV +{ + static void* mXFBs[2]; + static void* mCurrentFrameBuffer; + static _GXRenderModeObj* mRenderMode; + static U8 mFirstFrame; + + static void InitDisplay(_GXRenderModeObj*); + static void InitGX(); + static void InitVI(); + static void Suspend(); + static void Resume(); +}; + +void* iFMVmalloc(size_t size); +void iFMVfree(void* mem); +U32 iFMVPlay(char* filename, U32 buttons, F32 time, bool skippable, bool lockController); +static void Setup_surface_array(); +void Decompress_frame(HBINK bnk, HRAD3DIMAGE rad_image, long flags); +#endif diff --git a/src/SB/Core/gc/iFX.h b/src/SB/Core/gc/iFX.h new file mode 100644 index 0000000..3e81ed1 --- /dev/null +++ b/src/SB/Core/gc/iFX.h @@ -0,0 +1,4 @@ +#ifndef IFX_H +#define IFX_H + +#endif \ No newline at end of file diff --git a/src/SB/Core/gc/iFile.h b/src/SB/Core/gc/iFile.h new file mode 100644 index 0000000..9a3250b --- /dev/null +++ b/src/SB/Core/gc/iFile.h @@ -0,0 +1,71 @@ +#ifndef IFILE_H +#define IFILE_H + +#include +#include + +enum IFILE_READSECTOR_STATUS +{ + IFILE_RDSTAT_NOOP, + IFILE_RDSTAT_INPROG, + IFILE_RDSTAT_DONE, + IFILE_RDSTAT_FAIL, + IFILE_RDSTAT_QUEUED, + IFILE_RDSTAT_EXPIRED +}; + +#ifdef GAMECUBE +struct tag_iFile +{ + U32 flags; + char path[128]; + S32 entrynum; + DVDFileInfo fileInfo; + S32 unkC4; + S32 asynckey; + S32 unknown[7]; + S32 unkE8; + S32 offset; +}; +#else +#ifdef PS2 +struct tag_iFile +{ + U32 flags; + char path[128]; + S32 fd; + S32 offset; + S32 length; +}; +#endif +#endif + +#define IFILE_OPEN_READ 0x1 +#define IFILE_OPEN_WRITE 0x2 +#define IFILE_OPEN_ABSPATH 0x4 + +#define IFILE_SEEK_SET 0 +#define IFILE_SEEK_CUR 1 +#define IFILE_SEEK_END 2 + +struct tag_xFile; + +void iFileInit(); +void iFileExit(); +U32* iFileLoad(char* name, U32* buffer, U32* size); +U32 iFileOpen(const char* name, S32 flags, tag_xFile* file); +S32 iFileSeek(tag_xFile* file, S32 offset, S32 whence); +U32 iFileRead(tag_xFile* file, void* buf, U32 size); +S32 iFileReadAsync(tag_xFile* file, void* buf, U32 aSize, void (*callback)(tag_xFile*), + S32 priority); +IFILE_READSECTOR_STATUS iFileReadAsyncStatus(S32 key, S32* amtToFar); +U32 iFileClose(tag_xFile* file); +U32 iFileGetSize(tag_xFile* file); +void iFileReadStop(); +void iFileFullPath(const char* relname, char* fullname); +void iFileSetPath(char* path); +U32 iFileFind(const char* name, int, tag_xFile* file); +void iFileGetInfo(tag_xFile* file, U32* addr, U32* length); +void iFileAsyncService(); + +#endif diff --git a/src/SB/Core/gc/iLight.h b/src/SB/Core/gc/iLight.h new file mode 100644 index 0000000..d19b54d --- /dev/null +++ b/src/SB/Core/gc/iLight.h @@ -0,0 +1,49 @@ +#ifndef ILIGHT_H +#define ILIGHT_H + +#include "xFColor.h" +#include "xMath3.h" + +#include +#include + +#define ILIGHT_TYPE_NONE 0 +#define ILIGHT_TYPE_POINT 1 +#define ILIGHT_TYPE_SPOT 2 +#define ILIGHT_TYPE_SPOTSOFT 3 + +#define ILIGHT_ENV_NONE 0 +#define ILIGHT_ENV_ATOMIC 1 +#define ILIGHT_ENV_WORLD 2 +#define ILIGHT_ENV_ATOMICWORLD 3 + +// Size: 0x3C +struct iLight +{ + // 0x0 + U32 type; + RpLight* hw; + + //0x8 + xSphere sph; + F32 radius_sq; + + //0x1C + _xFColor color; + + //0x2C + xVec3 dir; + F32 coneangle; +}; + +extern RpWorld* gLightWorld; + +void iLightInit(RpWorld* world); +iLight* iLightCreate(iLight* light, U32 type); +void iLightModify(iLight* light, U32 flags); +void iLightSetColor(iLight* light, _xFColor* col); +void iLightSetPos(iLight* light, xVec3* pos); +void iLightDestroy(iLight* light); +void iLightEnv(iLight* light, S32 env); + +#endif diff --git a/src/SB/Core/gc/iMath.h b/src/SB/Core/gc/iMath.h new file mode 100644 index 0000000..d90af35 --- /dev/null +++ b/src/SB/Core/gc/iMath.h @@ -0,0 +1,17 @@ +#ifndef IMATH_H +#define IMATH_H + +#include +#include + +#ifdef __MWERKS__ +#define iabs(x) (float)(__fabs((float)x)) +#else +#define iabs(x) fabsf(x) +#endif + +F32 isin(F32 x); +F32 icos(F32 x); +F32 itan(F32 x); + +#endif diff --git a/src/SB/Core/gc/iMath3.h b/src/SB/Core/gc/iMath3.h new file mode 100644 index 0000000..678a787 --- /dev/null +++ b/src/SB/Core/gc/iMath3.h @@ -0,0 +1,30 @@ +#ifndef IMATH3_H +#define IMATH3_H + +#include "xMath3.h" +#include "xIsect.h" +#include "xRay3.h" + +#include + +union xiMat4x3Union +{ + //xMat4x3 xm; CURRENTLY BROKEN. DONT KNOW WHY + RwMatrix im; +}; + +void iMath3Init(); +void iSphereIsectVec(const xSphere* s, const xVec3* v, xIsect* isx); +void iSphereIsectRay(const xSphere* s, const xRay3* r, xIsect* isx); +void iSphereIsectSphere(const xSphere* s, const xSphere* p, xIsect* isx); +void iSphereInitBoundVec(xSphere* s, const xVec3* v); +void iSphereBoundVec(xSphere* o, const xSphere* s, const xVec3* v); +void iCylinderIsectVec(const xCylinder* c, const xVec3* v, xIsect* isx); +void iBoxVecDist(const xBox* box, const xVec3* v, xIsect* isx); +void iBoxIsectVec(const xBox* b, const xVec3* v, xIsect* isx); +void iBoxIsectRay(const xBox* b, const xRay3* r, xIsect* isx); +void iBoxIsectSphere(const xBox* box, const xSphere* p, xIsect* isx); +void iBoxInitBoundVec(xBox* b, const xVec3* v); +void iBoxBoundVec(xBox* o, const xBox* b, const xVec3* v); + +#endif diff --git a/src/SB/Core/gc/iMemMgr.h b/src/SB/Core/gc/iMemMgr.h new file mode 100644 index 0000000..67096c6 --- /dev/null +++ b/src/SB/Core/gc/iMemMgr.h @@ -0,0 +1,9 @@ +#ifndef IMEMMGR_H +#define IMEMMGR_H + +#include + +void iMemInit(); +void iMemExit(); + +#endif \ No newline at end of file diff --git a/src/SB/Core/gc/iMix.c b/src/SB/Core/gc/iMix.c new file mode 100644 index 0000000..e69de29 diff --git a/src/SB/Core/gc/iMix.h b/src/SB/Core/gc/iMix.h new file mode 100644 index 0000000..93eaa61 --- /dev/null +++ b/src/SB/Core/gc/iMix.h @@ -0,0 +1,11 @@ +#ifndef IMIX_H +#define IMIX_H + +#include "iSnd.h" +struct _AXVPB; + +extern "C" { +void MIXUnMute(_AXVPB* p); +} + +#endif diff --git a/src/SB/Core/gc/iModel.h b/src/SB/Core/gc/iModel.h new file mode 100644 index 0000000..b9ddb99 --- /dev/null +++ b/src/SB/Core/gc/iModel.h @@ -0,0 +1,28 @@ +#ifndef IMODEL_H +#define IMODEL_H + +#include "xMath3.h" +#include "xModel.h" + +#include +#include + +void iModelInit(); +U32 iModelNumBones(RpAtomic* model); +S32 iModelCull(RpAtomic* model, RwMatrixTag* mat); +S32 iModelSphereCull(xSphere* sphere); +RpAtomic* iModelFile_RWMultiAtomic(RpAtomic* model); +void iModelSetMaterialTexture(RpAtomic* model, void* texture); +void iModelResetMaterial(RpAtomic* model); +S32 iModelCullPlusShadow(RpAtomic* model, RwMatrix* mat, xVec3* shadowVec, S32* shadowOutside); +void iModelTagEval(RpAtomic* model, const xModelTag* tag, RwMatrixTag* mat, xVec3* dest); +U32 iModelTagSetup(xModelTag* tag, RpAtomic* model, F32 x, F32 y, F32 z); +void iModelSetMaterialAlpha(RpAtomic* model, U8 alpha); +U32 iModelVertCount(RpAtomic* model); +void iModelMaterialMul(RpAtomic* model, F32 rm, F32 gm, F32 bm); +RpAtomic* iModelFileNew(void* buffer, U32 size); +void iModelRender(RpAtomic* model, RwMatrix* mat); +void iModelUnload(RpAtomic* userdata); +void iModelAnimMatrices(RpAtomic* model, xQuat* quat, xVec3* tran, RwMatrixTag* mat); + +#endif diff --git a/src/SB/Core/gc/iMorph.h b/src/SB/Core/gc/iMorph.h new file mode 100644 index 0000000..a3b0333 --- /dev/null +++ b/src/SB/Core/gc/iMorph.h @@ -0,0 +1,12 @@ +#ifndef IMORPH_H +#define IMORPH_H + +#include "types.h" + +#include +#include + +void iMorphOptimize(RpAtomic* model, S32 normals); +void iMorphRender(RpAtomic* model, RwMatrix* mat, S16** v_array, S16* weight, U32 normals, F32 scale); + +#endif \ No newline at end of file diff --git a/src/SB/Core/gc/iPad.h b/src/SB/Core/gc/iPad.h new file mode 100644 index 0000000..a35fdb2 --- /dev/null +++ b/src/SB/Core/gc/iPad.h @@ -0,0 +1,25 @@ +#ifndef IPAD_H +#define IPAD_H + +#include + +struct _tagiPad +{ + S32 port; +}; + +struct _tagxPad; +struct _tagxRumble; + +S32 iPadInit(); +_tagxPad* iPadEnable(_tagxPad* pad, S16 port); +S32 iPadConvStick(float value); +S32 iPadUpdate(_tagxPad* pad, U32* on); +S32 iPadConvFromGCN(U32 a, U32 b, U32 c); +void iPadRumbleFx(_tagxPad* p, _tagxRumble* r, F32 time_passed); +void iPadStopRumble(_tagxPad* pad); +void iPadStopRumble(); +void iPadStartRumble(_tagxPad* pad, _tagxRumble* rumble); +void iPadKill(); + +#endif diff --git a/src/SB/Core/gc/iParMgr.h b/src/SB/Core/gc/iParMgr.h new file mode 100644 index 0000000..d64f594 --- /dev/null +++ b/src/SB/Core/gc/iParMgr.h @@ -0,0 +1,27 @@ +#ifndef IPARMGR_H +#define IPARMGR_H + +#include "xMath3.h" + +#include + +struct tagiRenderInput +{ + U16* m_index; + RwIm3DVertex* m_vertex; + F32* m_vertexTZ; + U32 m_mode; + S32 m_vertexType; + S32 m_vertexTypeSize; + S32 m_indexCount; + S32 m_vertexCount; + xMat4x3 m_camViewMatrix; + xVec4 m_camViewR; + xVec4 m_camViewU; +}; + +void iParMgrInit(); +void iParMgrUpdate(F32 elapsedTime); +void iParMgrRender(); + +#endif diff --git a/src/SB/Core/gc/iScrFX.cpp b/src/SB/Core/gc/iScrFX.cpp index 004f6af..e69de29 100644 --- a/src/SB/Core/gc/iScrFX.cpp +++ b/src/SB/Core/gc/iScrFX.cpp @@ -1,117 +0,0 @@ -// ported from bfbb repo -#include "iScrFX.h" - -#include - -extern RwRaster *g_rast_gctapdance; -extern S32 g_alreadyTriedAlloc; -extern _iMotionBlurData sMBD; -extern U32 sMotionBlurEnabled; -extern F32 lbl_803CE168; // 0.0f -extern F32 lbl_803CE174; // 1.0f -extern F32 lbl_803CE178; // 0.5f -extern F32 lbl_803CE17C; // 254f - -void iScrFxInit() {} - -void iScrFxBegin() { - RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void *)rwFILTERNEAREST); - RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void *)rwFOGTYPENAFOGTYPE); - RwRenderStateSet(rwRENDERSTATEZTESTENABLE, NULL); - RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, NULL); - RwRenderStateSet(rwRENDERSTATETEXTURERASTER, NULL); - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)true); - RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA); - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA); -} - -void iScrFxEnd() { - RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void *)rwFOGTYPENAFOGTYPE); - RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)true); - RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void *)true); - RwRenderStateSet(rwRENDERSTATETEXTURERASTER, NULL); - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)false); - RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDONE); - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDZERO); -} - -void iCameraMotionBlurActivate(U32 activate) { sMotionBlurEnabled = activate; } - -// The instructions regarding the setting of sMotionBlurEnabled and -// sMBD.motionBlurAlpha are in the wrong order. -void iCameraSetBlurriness(F32 amount) { - if (amount <= lbl_803CE168) { - sMotionBlurEnabled = 0; - } else { - if (amount > lbl_803CE174) { - amount = lbl_803CE174; - } - sMotionBlurEnabled = 1; - sMBD.motionBlurAlpha = (S32)(lbl_803CE17C * amount + lbl_803CE178); - } -} - -// Instructions in the wrong order. -void iScrFxCameraCreated(RwCamera *pCamera) { - sMBD.motionBlurAlpha = 0x90; - sMBD.motionBlurFrontBuffer = NULL; - sMBD.index[0] = 0; - sMBD.index[1] = 1; - sMBD.index[2] = 2; - sMBD.index[3] = 0; - sMBD.index[4] = 2; - sMBD.index[5] = 3; - iScrFxMotionBlurOpen(pCamera); -} - -void iScrFxCameraEndScene(RwCamera *pCamera) { - if ((sMotionBlurEnabled != 0) && (sMBD.motionBlurAlpha != 0)) { - iScrFxMotionBlurRender(pCamera, sMBD.motionBlurAlpha & 0xff); - } -} - -void iScrFxPostCameraEnd(RwCamera *pCamera) { GCMB_SiphonFrameBuffer(pCamera); } - -RwRaster *FBMBlur_DebugIntervention(RwCamera *camera, RwRaster *ras) { - return ras; -} - -S32 iScrFxMotionBlurOpen(RwCamera *camera) { return 0; } - -S32 iScrFxCameraDestroyed(RwCamera *pCamera) { - GCMB_KillFrameBufferCopy(); - if (sMBD.motionBlurFrontBuffer != NULL) { - RwRasterDestroy(sMBD.motionBlurFrontBuffer); - sMBD.motionBlurFrontBuffer = NULL; - return 1; - } - return 0; -} - -// WIP. -void iScrFxMotionBlurRender(RwCamera *camera, U32 col) { - if (sMBD.motionBlurFrontBuffer != NULL) { - RwRGBA col; - col.alpha = 0xf8; - iCameraOverlayRender(camera, (RwRaster *)sMBD.motionBlurFrontBuffer, col); - } -} - -void GCMB_MakeFrameBufferCopy(const RwCamera *camera) {} - -void GCMB_KillFrameBufferCopy() { - if (g_rast_gctapdance != NULL) { - RwRasterDestroy(g_rast_gctapdance); - } - g_rast_gctapdance = NULL; - g_alreadyTriedAlloc = 0; -} - -void GCMB_SiphonFrameBuffer(const RwCamera *camera) { - if ((g_rast_gctapdance == NULL) && (g_alreadyTriedAlloc == 0)) { - GCMB_MakeFrameBufferCopy(camera); - } - if (g_rast_gctapdance != NULL) { - RwGameCubeCameraTextureFlush(g_rast_gctapdance, 0); - } -} diff --git a/src/SB/Core/gc/iSnd.h b/src/SB/Core/gc/iSnd.h new file mode 100644 index 0000000..0455a3e --- /dev/null +++ b/src/SB/Core/gc/iSnd.h @@ -0,0 +1,78 @@ +#ifndef ISND_H +#define ISND_H + +#include + +struct xSndVoiceInfo; +struct tag_xFile; +struct _AXVPB; + +struct iSndVol +{ + S16 volL; + S16 volR; +}; + +struct iSndInfo +{ + U32 flags; + iSndVol vol; + U32 pitch; + S32 lastStreamBuffer; +}; + +// Size: 0x20 +// This was not in dwarf data +struct vinfo +{ + _AXVPB* voice; + S32 buffer[4]; + U32 _0x14; + S32 buffer2[2]; +}; + +// Size: ??? +// Not in dwarf data +struct sDSPADPCM +{ + S32 buffer[6]; +}; + +// not in dwarf data, +enum isound_effect +{ + iSND_EFFECT_NONE, + iSND_EFFECT_CAVE +}; + +void arq_callback(long); +void iSndExit(); + +void iSndPause(U32 snd, U32 pause); +void iSndSetEnvironmentalEffect(isound_effect); +void iSndInit(); +void iSndCalcVol(xSndVoiceInfo* xSndVoiceInfo, vinfo* vinfo); +void iSndCalcVol3d(xSndVoiceInfo* xSndVoiceInfo, vinfo* vinfo); +void iSndVolUpdate(xSndVoiceInfo* info, vinfo* vinfo); +void iSndUpdateSounds(); +void iSndUpdate(); +void iSndSuspendCD(U32); +void iSndMessWithEA(sDSPADPCM* param1); +U32 SampleToNybbleAddress(U32 sample); +void iSndInitSceneLoaded(); +S32 iSndIsPlaying(U32 assetID); +S32 iSndIsPlaying(U32 assetID, U32 parid); +void iSndWaitForDeadSounds(); +void iSndSceneExit(); +void sndloadcb(tag_xFile* tag); +S32 iSndLoadSounds(void*); +void iSndSetExternalCallback(void (*func_ptr)(U32)); +void iSndAXFree(_AXVPB** param1); +void iSndStartStereo(U32 id1, U32 id2, F32 pitch); +void iSndStop(U32 snd); +void iSndSetVol(U32 snd, F32 vol); +void iSndSetPitch(U32 snd, F32 pitch); +F32 iSndGetVol(U32 snd); +void iSndStereo(U32 stereo); + +#endif diff --git a/src/SB/Core/gc/iSystem.h b/src/SB/Core/gc/iSystem.h new file mode 100644 index 0000000..81c15e8 --- /dev/null +++ b/src/SB/Core/gc/iSystem.h @@ -0,0 +1,26 @@ +#ifndef ISYSTEM_H +#define ISYSTEM_H + +#include +#include + +extern "C" { +void* malloc(U32 __size); +void free(void* __ptr); +} + +void iVSync(); + +#define GET_MAKER_CODE() (*((U32*)0x80000004)) +#define GET_BUS_FREQUENCY() (*((U32*)0x800000F8)) + +void** psGetMemoryFunctions(); +void iVSync(); +U16 my_dsc(U16 dsc); + +void MemoryProtectionErrorHandler(U16 last, OSContext* ctx, U64 unk1, U64 unk2); +void TRCInit(); + +void null_func(); + +#endif diff --git a/src/SB/Core/gc/iTime.h b/src/SB/Core/gc/iTime.h new file mode 100644 index 0000000..e73b748 --- /dev/null +++ b/src/SB/Core/gc/iTime.h @@ -0,0 +1,38 @@ +#ifndef ITIME_H +#define ITIME_H + +#include + +#define JANUARY 1 +#define FEBRUARY 2 +#define MARCH 3 +#define APRIL 4 +#define MAY 5 +#define JUNE 6 +#define JULY 7 +#define AUGUST 8 +#define SEPTEMBER 9 +#define OCTOBER 10 +#define NOVEMBER 11 +#define DECEMBER 12 + +typedef S64 iTime; + +S32 iGetMinute(); +S32 iGetHour(); +S32 iGetDay(); +S32 iGetMonth(); +char* iGetCurrFormattedDate(char* input); +char* iGetCurrFormattedTime(char* input); +void iTimeInit(); +void iTimeExit(); +iTime iTimeGet(); +F32 iTimeDiffSec(iTime t0, iTime t1); +F32 iTimeDiffSec(iTime time); +void iTimeGameAdvance(F32 elapsed); +void iTimeSetGame(F32 time); +void iProfileClear(U32 sceneID); +void iFuncProfileDump(); +void iFuncProfileParse(char* elfPath, S32 profile); + +#endif diff --git a/src/SB/Core/gc/iWad.cpp b/src/SB/Core/gc/iWad.cpp index e69de29..c721e73 100644 --- a/src/SB/Core/gc/iWad.cpp +++ b/src/SB/Core/gc/iWad.cpp @@ -0,0 +1,4082 @@ +#include "iWad.h" + +static iTime sStartupTime; +static F32 sGameTime; +extern U32 add; +extern U32 size; +extern OSHeapHandle the_heap; +extern U16 last_error; +extern OSContext* last_context; +static st_ISGSESSION g_isgdata_MAIN = { 0 }; + +// iTime + +void iFuncProfileFuncs(int, int, float) +{ +} + +void iFuncProfileDump() +{ +} + +void iProfileClear(U32 sceneID) +{ +} + +void iTimeSetGame(F32 time) +{ + sGameTime = time; +} + +void iTimeGameAdvance(F32 elapsed) +{ + sGameTime += elapsed; +} + +F32 iTimeGetGame() +{ + return sGameTime; +} + +F32 iTimeDiffSec(iTime t0, iTime t1) +{ + return iTimeDiffSec(t1 - t0); +} + +F32 iTimeDiffSec(iTime time) +{ + return (F32)time / (GET_BUS_FREQUENCY() / 4); +} + +iTime iTimeGet() +{ + return OSGetTime() - sStartupTime; +} + +// WIP. +char* iGetCurrFormattedTime(char* input) +{ + OSTime ticks = OSGetTime(); + OSCalendarTime td; + OSTicksToCalendarTime(ticks, &td); + bool pm = false; + // STUFF. + char* ret = input; + // STUFF. + if (pm) + { + ret[8] = 'P'; + ret[9] = '.'; + ret[10] = 'M'; + ret[11] = '.'; + } + else + { + ret[8] = 'A'; + ret[9] = '.'; + ret[10] = 'M'; + ret[11] = '.'; + } + ret[12] = '\0'; + return ret + (0xd - (S32)input); +} + +// Template for future use. TODO +char* iGetCurrFormattedDate(char* input) +{ + return NULL; +} + +S32 iGetMonth() +{ + OSTime ticks = OSGetTime(); + OSCalendarTime td; + OSTicksToCalendarTime(ticks, &td); + return td.mon + 1; +} + +S32 iGetDay() +{ + OSTime ticks = OSGetTime(); + OSCalendarTime td; + OSTicksToCalendarTime(ticks, &td); + return td.mday; +} + +S32 iGetHour() +{ + OSTime ticks = OSGetTime(); + OSCalendarTime td; + OSTicksToCalendarTime(ticks, &td); + return td.hour; +} + +S32 iGetMinute() +{ + OSTime ticks = OSGetTime(); + OSCalendarTime td; + OSTicksToCalendarTime(ticks, &td); + return td.min; +} + +extern "C" { + +void* malloc(U32 __size) +{ + if ((S32)__size <= 0) + { + return NULL; + } + + void* result = OSAllocFromHeap(the_heap, __size); + + if (result == NULL) + { + null_func(); + } + + return result; +} + +void free(void* __ptr) +{ + if (__ptr != NULL) + { + OSFreeToHeap(the_heap, __ptr); + } +} +} + +S32 RenderWareExit() +{ + RwEngineStop(); + RwEngineClose(); + return RwEngineTerm(); +} + +void iSystemExitRWFailSafe() +{ + RwEngineStop(); + RwEngineClose(); +} + +void iSystemExit() // TO-DO - Need to update function calls +{ + xDebugExit(); + xMathExit(); + RwEngineStop(); + RwEngineClose(); + RwEngineTerm(); + xSndMgrExit(); + xPadKill(); + xMemExit(); + OSPanic("GGVE", 0x1e7, + "(With apologies to Jim Morrison) This the end, my only friend, The End."); +} + +void MemoryProtectionErrorHandler(U16 last, OSContext* ctx, U64 unk1, U64 unk2) +{ + last_error = last; + last_context = ctx; +} + +U16 my_dsc(U16 dsc) +{ + return dsc; +} + +void iVSync() +{ + VIWaitForRetrace(); +} + +// iSnd + +void iSndSuspendCD(U32) +{ +} + +void iSndSetExternalCallback(void* func_ptr) +{ +} + +// void iSndStartStereo(iSndHandle id1, iSndHandle id2) +// { +// } + +// void iSndExit() +// { +// FSOUND_Close(); +// } + +// iSaveGame + +// Not 100% on what this does or if it's correctly defined for all cases. Seems to be used for allocation alignment +#define ALIGN_THING(x, n) (n + x - 1 & -x) + +// name is a total guess for now +struct st_ISG_TPL_TEX +{ + struct UnkIn + { + U32 unk_0; + U32 unk_4; + void* unk_8; + U32 unk_c; + U32 unk_10[4]; + U8 unk_20; + U8 unk_21; + U8 unk_22; + U8 unk_23; + }; + struct UnkOut + { + U8 unk_0; + U8 unk_1; + U8 unk_2; + U8 unk_3; + U32 unk_4; + void* unk_8; + }; + + UnkIn* unk_0; + UnkOut* unk_4; +}; + +// WIP. Looks like some sort of header for a file with embedded texture information. +struct st_ISG_TPL_TEXPALETTE +{ + U32 magic; + U32 count; + st_ISG_TPL_TEX* unk_8; +}; + +struct IconData +{ + char game_name[0x20]; + char buf0[0x20]; + char buf1[0x1800]; + char buf2[8][0x800]; + char pad[0x200]; + char footer[0x200]; +}; + +static volatile S32 g_isginit; +static S32 g_legalSectSize[] = { 0x2000, 0, -1 }; +static st_ISG_TPL_TEXPALETTE* g_rawicon; +static st_ISG_TPL_TEXPALETTE* g_rawbanr; +static U32 g_iconsize; +static U32 g_banrsize; +static U8 isMounted; + +S32 iSGAutoSave_Monitor(st_ISGSESSION* isg, S32 idx_target) +{ + if (isg == NULL) + { + return 0; + } + + U32 ret = iSGTgtState(isg, idx_target, NULL); + if (ret == 0 || (ret & 1) == 0) + { + globals.autoSaveFeature = 0; + return 0; + } + return 1; +} + +void iSGAutoSave_Startup() +{ +} + +U8 iSGCheckMemoryCard(st_ISGSESSION* isgdata, S32 index) +{ + s32 memSize; + s32 sectorSize; + + switch (CARDProbeEx(index, &memSize, §orSize)) + { + case CARD_RESULT_READY: + return 1; + } + return 0; +} + +static S32 iSG_curKosher(CARDStat* stat, CARDFileInfo* info) // FIX +{ + S32 rc = 1; + + if ((stat->iconAddr < 1 || stat->iconAddr > 0x7fffffff) && + (stat->commentAddr < 1 || stat->commentAddr > 0x7fffffff)) + { + rc = 0; + } + else + { + char stuff[0x200] = { 0 }; + sprintf(stuff, "SPONGEBOB:WHENROBOTSATTACK::RyanNeilDan"); + void* alloc = xMemPushTemp(0x5e00 + 0x1f); + // align buf address to 32 bytes + char* buf = (char*)((U32)alloc + 0x1f & ~0x1f); + + S32 result; + do + { + result = CARDRead(info, buf, 0x5e00, 0); + } while (result == CARD_RESULT_BUSY); + + if (result == CARD_RESULT_READY) + { + if (memcmp(buf + 0x5a40, stuff, strlen(stuff) - 1)) + { + rc = 0; + } + + if (memcmp(buf, "Battle for Bikini Bottom", strlen("Battle for Bikini Bottom") - 1)) + { + rc = 0; + } + } + + xMemPopTemp(alloc); + } + + return rc; +} + +static S32 iSG_mc_fdel(st_ISG_MEMCARD_DATA* mcdata, const char* fname) +{ + if (mcdata->chan < 0 || mcdata->chan > 1) + { + return 0; + } + + if (isMounted == 0) + { + return 0; + } + + s32 result; + do + { + result = CARDDelete(mcdata->chan, fname); + } while (result == CARD_RESULT_BUSY); + + S32 ret; + if (result == CARD_RESULT_NOFILE) + { + ret = 1; + } + else if (result == CARD_RESULT_READY) + { + ret = 1; + } + else + { + ret = 0; + switch (result) + { + case CARD_RESULT_IOERROR: + mcdata->unk_12c = 1; + break; + case CARD_RESULT_NOPERM: + case CARD_RESULT_FATAL_ERROR: + case CARD_RESULT_WRONGDEVICE: + break; + } + } + return ret; +} + +static S32 iSG_mc_fclose(st_ISG_MEMCARD_DATA* mcdata, CARDStat* stat) +{ + S32 ret = 0; + s32 result; + do + { + result = CARDClose(&mcdata->finfo); + } while (result == CARD_RESULT_BUSY); + + if (result == CARD_RESULT_READY) + { + ret = 1; + } + + if (stat != NULL) + { + memcpy(stat, &mcdata->fstat, sizeof(CARDStat)); + } + + memset(&mcdata->finfo, 0, sizeof(CARDFileInfo)); + memset(&mcdata->fstat, 0, sizeof(CARDStat)); + + return ret; +} + +static S32 iSG_mc_fclose(st_ISG_MEMCARD_DATA* mcdata) +{ + return iSG_mc_fclose(mcdata, NULL); +} + +static S32 iSG_mc_fopen(st_ISG_MEMCARD_DATA* mcdata, const char* fname, S32 fsize, + en_ISG_IOMODE mode, en_ASYNC_OPERR* operr) +{ + S32 ret = 0; + CARDFileInfo* finfo = &mcdata->finfo; + CARDStat* stat = &mcdata->fstat; + if (operr != NULL) + { + *operr = ISG_OPERR_NONE; + } + + if (mode == ISG_IOMODE_READ) + { + s32 result; + do + { + result = CARDOpen(mcdata->chan, (char*)fname, finfo); + } while (result == CARD_RESULT_BUSY); + + if (result == CARD_RESULT_READY) + { + ret = 1; + } + } + else + { + S32 res = iSG_mc_fdel(mcdata, fname); + if (mcdata->unk_12c == 0 && res > 0) + { + s32 result; + do + { + result = CARDCreate(mcdata->chan, (char*)fname, fsize, finfo); + } while (result == CARD_RESULT_BUSY); + + if (result == CARD_RESULT_READY) + { + ret = 1; + mcdata->unk_98 = 0; + } + else if (operr != NULL) + { + switch (result) + { + case CARD_RESULT_WRONGDEVICE: + case CARD_RESULT_NOCARD: + *operr = ISG_OPERR_NOCARD; + break; + case CARD_RESULT_IOERROR: + case CARD_RESULT_BROKEN: + mcdata->unk_12c = 1; + *operr = ISG_OPERR_DAMAGE; + break; + case CARD_RESULT_NOENT: + case CARD_RESULT_INSSPACE: + *operr = ISG_OPERR_NOROOM; + break; + default: + *operr = ISG_OPERR_OTHER; + break; + case CARD_RESULT_READY: + case CARD_RESULT_BUSY: + case CARD_RESULT_EXIST: + case CARD_RESULT_NOPERM: + break; + } + } + } + } + + if (ret != 0) + { + s32 result; + do + { + result = CARDGetStatus(mcdata->chan, finfo->fileNo, stat); + } while (result == CARD_RESULT_BUSY); + + if (result == CARD_RESULT_READY) + { + ret = 1; + } + } + + if (ret != 0) + { + if (memcmp(stat->gameName, "GQPE", 4) != 0 || memcmp(stat->company, "78", 2) != 0) + { + iSG_mc_fclose(mcdata); + ret = 0; + } + } + + return ret; +} + +static S32 iSG_fileKosher(st_ISG_MEMCARD_DATA* mcdata, const char* param2, int param3, int* param4) +{ + S32 rc = 0; + en_ASYNC_OPERR operr = ISG_OPERR_NONE; + + if (param4) + { + *param4 = 0; + } + + if (iSG_mc_fopen(mcdata, param2, -1, ISG_IOMODE_READ, &operr) == 0) + { + return -1; + } + + S32 ret = iSG_curKosher(&mcdata->fstat, &mcdata->finfo); + iSG_mc_fclose(mcdata); + + if (ret == 0) + { + rc = 0; + if (param3 && iSG_mc_fdel(mcdata, param2) && param4) + { + *param4 = 1; + } + } + else + { + rc = 1; + } + return rc; +} + +S32 iSGCheckForCorruptFiles(st_ISGSESSION* isgdata, char files[][64]) +{ + if (isgdata->slot < 0) + { + return 0; + } + + S32 i; + char* name; + st_ISG_MEMCARD_DATA* mcdata = &isgdata->mcdata[isgdata->slot]; + S32 ret = 0; + memset(files, NULL, 0xc0); + + for (i = 0; i < ISG_NUM_FILES; ++i) + { + name = iSGMakeName(ISG_NGTYP_GAMEFILE, NULL, i); + if (iSG_fileKosher(mcdata, name, 0, NULL) == 0) + { + strcpy(files[ret], name); + ret++; + } + } + return ret; +} + +S32 iSGCheckForWrongDevice() +{ + char* workarea = (char*)RwMalloc(0x10000 - 0x6000); + + S32 ret = -1; + for (S32 i = 0; i < ISG_NUM_SLOTS; ++i) + { + s32 result = CARDMount(i, workarea, NULL); + + switch (result) + { + case CARD_RESULT_READY: + case CARD_RESULT_BROKEN: + case CARD_RESULT_ENCODING: + CARDUnmount(i); + break; + case CARD_RESULT_WRONGDEVICE: + ret = i; + i = ISG_NUM_SLOTS; + break; + } + } + + RwFree(workarea); + + return ret; +} + +static void iSG_cb_asyndone(s32, s32) +{ +} + +static S32 iSG_mcqa_fwrite(st_ISG_MEMCARD_DATA* mcdata, char* buf, S32 len) +{ + S32 ret = 0; + S32 x = 1000; + CARDStat* fstat = &mcdata->fstat; + s32 result; + do + { + result = CARDGetResultCode(mcdata->chan); + } while (result == CARD_RESULT_BUSY); + + if (result != CARD_RESULT_READY) + { + return 0; + } + + CARDGetXferredBytes(mcdata->chan); + s32 asynresult; + do + { + asynresult = CARDWriteAsync(&mcdata->finfo, buf, len, mcdata->unk_98, iSG_cb_asyndone); + } while (asynresult == CARD_RESULT_BUSY); + + if (asynresult != CARD_RESULT_READY) + { + return 0; + } + + result = CARD_RESULT_BUSY; + do + { + if (x++ > 500) + { + result = CARDGetResultCode(mcdata->chan); + xSndUpdate(); + CARDGetXferredBytes(mcdata->chan); + x = 0; + } + iTRCDisk::CheckDVDAndResetState(); + } while (result == CARD_RESULT_BUSY); + + if (asynresult == CARD_RESULT_READY) + { + mcdata->unk_98 += len; + + do + { + result = CARDGetStatus(mcdata->chan, mcdata->finfo.fileNo, fstat); + } while (result == CARD_RESULT_BUSY); + + if (result == CARD_RESULT_READY) + { + ret = 1; + } + } + return ret; +} + +static S32 iSG_mcqa_fread(st_ISG_MEMCARD_DATA* mcdata, char* buf, S32 len, S32 offset) +{ + S32 x = 1000; + s32 result = CARDGetResultCode(mcdata->chan); + do + { + result = CARDGetResultCode(mcdata->chan); + } while (result == CARD_RESULT_BUSY); + + if (result != CARD_RESULT_READY) + { + return 0; + } + + CARDGetXferredBytes(mcdata->chan); + do + { + result = CARDReadAsync(&mcdata->finfo, buf, len, offset, iSG_cb_asyndone); + } while (result == CARD_RESULT_BUSY); + + if (result != CARD_RESULT_READY) + { + return 0; + } + + result = CARD_RESULT_BUSY; + do + { + if (x++ > 500) + { + xSndUpdate(); + CARDGetXferredBytes(mcdata->chan); + result = CARDGetResultCode(mcdata->chan); + x = 0; + } + iTRCDisk::CheckDVDAndResetState(); + } while (result == CARD_RESULT_BUSY); + return result != 0 ? 0 : 1; +} + +static S32 iSG_mc_format(st_ISG_MEMCARD_DATA* mcdata, S32, S32* canRecover) +{ + if (mcdata->unk_12c != 0) + { + if (canRecover != NULL) + { + *canRecover = 0; + } + return 0; + } + + if (canRecover != NULL) + { + *canRecover = 1; + } + + s32 result; + do + { + result = CARDFormat(mcdata->chan); + } while (result == CARD_RESULT_BUSY); + + S32 ret; + if (result == CARD_RESULT_READY) + { + ret = 1; + } + else + { + ret = 0; + + switch (result) + { + case CARD_RESULT_IOERROR: + mcdata->unk_12c = 1; + if (canRecover != NULL) + { + *canRecover = 0; + } + break; + case CARD_RESULT_NOCARD: + if (canRecover != NULL) + { + *canRecover = -1; + } + ret = -1; + break; + case CARD_RESULT_FATAL_ERROR: + case CARD_RESULT_WRONGDEVICE: + case CARD_RESULT_NOFILE: + break; + } + } + return ret; +} + +static void iSG_cb_unmount(s32 chan, s32 result) +{ + st_ISGSESSION* session = &g_isgdata_MAIN; + if (chan != session->slot) + { + return; + } + session->slot = -1; + if (session->chgfunc != NULL) + { + session->chgfunc(session->cltdata, ISG_CHG_TARGET); + } + memset(&session->mcdata[chan], 0, sizeof(st_ISG_MEMCARD_DATA)); +} + +static S32 iSG_tpl_unpack(st_ISG_TPL_TEXPALETTE* tpl) +{ + if (tpl->magic != 0x20af30) + { + return 0; + } + + tpl->unk_8 = (st_ISG_TPL_TEX*)((U32)tpl + (U32)tpl->unk_8); + for (S32 i = 0; i < tpl->count; ++i) + { + st_ISG_TPL_TEX* x = &tpl->unk_8[i]; + if (x->unk_0 != NULL) + { + x->unk_0 = (st_ISG_TPL_TEX::UnkIn*)((U32)tpl + (U32)x->unk_0); + if (x->unk_0->unk_23 == 0) + { + x->unk_0->unk_8 = (void*)((U32)tpl + (U32)x->unk_0->unk_8); + x->unk_0->unk_23 = 1; + } + } + if (x->unk_4 != NULL) + { + x->unk_4 = (st_ISG_TPL_TEX::UnkOut*)((U32)tpl + (U32)x->unk_4); + if (x->unk_4->unk_2 == 0) + { + x->unk_4->unk_8 = tpl; + x->unk_4->unk_2 = 1; + } + } + } + return 1; +} + +static st_ISG_TPL_TEX* iSG_tpl_TEXGet(st_ISG_TPL_TEXPALETTE* tpl, U32 n) +{ + return &tpl->unk_8[n]; +} + +static char* iSG_bfr_icondata(char* param1, CARDStat* stat, char* param3, int param4) +{ + IconData data = { 0 }; + static st_ISG_TPL_TEXPALETTE* ico_pal; + static st_ISG_TPL_TEX* ico_desc; + static U32 i = 0; + + sprintf(data.footer, "SPONGEBOB:WHENROBOTSATTACK::RyanNeilDan"); + strncpy(data.game_name, "Battle for Bikini Bottom", sizeof(data.game_name)); + data.game_name[0x1f] = NULL; + + if (param3) + { + strncpy(data.buf0, param3, sizeof(data.buf0)); + } + data.buf0[0x1f] = NULL; + + ico_pal = g_rawbanr; + ico_desc = iSG_tpl_TEXGet(ico_pal, 0); + memcpy(data.buf1, ico_desc->unk_0->unk_8, sizeof(data.buf1)); + + ico_pal = g_rawicon; + for (i = 0; i < 8; i++) + { + ico_desc = iSG_tpl_TEXGet(ico_pal, i); + memcpy(data.buf2[i], ico_desc->unk_0->unk_8, sizeof(data.buf2[i])); + } + + memcpy(param1, &data, sizeof(data)); + + S32 t = ALIGN_THING(param4, 0x200); + return param1 + (t + (sizeof(IconData) - 1) & -t); +} + +static S32 iSG_bnr_unpack(st_ISG_TPL_TEXPALETTE* tpl) +{ + return iSG_tpl_unpack(tpl); +} + +static S32 iSG_load_icondata() +{ + g_rawicon = (st_ISG_TPL_TEXPALETTE*)iFileLoad("/SBGCIcon.tpl", NULL, &g_iconsize); + g_rawbanr = (st_ISG_TPL_TEXPALETTE*)iFileLoad("/SBGCBanner.tpl", NULL, &g_banrsize); + iSG_tpl_unpack(g_rawicon); + iSG_bnr_unpack(g_rawbanr); + + return g_rawicon && (S32)g_iconsize && g_rawbanr && (S32)g_banrsize ? 1 : 0; +} + +static S32 iSG_get_finfo(st_ISG_MEMCARD_DATA* mcdata, const char* dpath) +{ + S32 rc = 0; + en_ASYNC_OPERR operr = ISG_OPERR_NONE; + + if (iSG_mc_fopen(mcdata, dpath, -1, ISG_IOMODE_READ, &operr)) + { + rc = 1; + memcpy(&mcdata->unk_b0, &mcdata->fstat, sizeof(CARDStat)); + memcpy(&mcdata->unk_9c, &mcdata->finfo, sizeof(CARDFileInfo)); + iSG_mc_fclose(mcdata); + } + + return rc; +} + +static S32 iSG_cubeicon_size(S32 slot, S32 param2) +{ + if ((U32)slot > 1) + { + return -1; + } + + S32 t = ALIGN_THING(param2, 0x200); + + // FIXME: Macro not quite right + // return ALIGN_THING(t, sizeof(IconData)); + return -t & sizeof(IconData) + t - 1; +} + +static S32 iSG_isSpaceForFile(st_ISG_MEMCARD_DATA* mcdata, S32 param2, const char* param3, + S32* param4, S32* param5, S32* param6) +{ + S32 rc = 0; + S32 result = 0; + s32 byteNotUsed = 0; + s32 filesNotUsed = 0; + S32 len; + + if (mcdata->unk_0 == 0) + { + return 0; + } + len = iSG_cubeicon_size(mcdata->chan, mcdata->sectorSize); + len = len + param2; + len = ALIGN_THING(mcdata->sectorSize, len); + + do + { + result = CARDFreeBlocks(mcdata->chan, &byteNotUsed, &filesNotUsed); + } while (result == CARD_RESULT_BUSY); + + if (result == CARD_RESULT_READY) + { + if (param5) + { + *param5 = byteNotUsed / mcdata->sectorSize; + } + if (param4) + { + *param4 = len / mcdata->sectorSize; + } + } + else + { + return 0; + } + + if (param6) + { + *param6 = 1; + } + + if (iSG_get_finfo(mcdata, param3)) + { + if (param6) + { + *param6 = *param6 - 1 & ~(*param6 - 1 >> 0x1f); // FIXME: Fakematch + } + if (len <= mcdata->unk_b0.length + byteNotUsed) + { + rc = 1; + } + } + else + { + if (len <= byteNotUsed && filesNotUsed > 0) + { + rc = 1; + } + } + + return rc; +} + +static S32 iSG_mc_isGCcard(st_ISG_MEMCARD_DATA* mcdata, int* param2, int* param3) +{ + S32 result = 0; + S32 rc = 0; + + s32 xferBytes = 0; + u16 encoding = 0; + s32 memSize = 0; + s32 sectorSize = 0; + + if (param2) + { + *param2 = 0; + } + + if (param3) + { + *param3 = 0; + } + + if (mcdata->unk_0 == 0) + { + return 0; + } + if (mcdata->unk_12c) + { + return 0; + } + + do + { + result = CARDProbeEx(mcdata->chan, &memSize, §orSize); + } while (result == CARD_RESULT_BUSY); + + if (result == CARD_RESULT_READY) + { + rc = 1; + } + + if (rc != 0) + { + do + { + result = CARDCheckEx(mcdata->chan, &xferBytes); + } while (result == CARD_RESULT_BUSY); + + if (result == CARD_RESULT_READY) + { + rc = 1; + } + else if (result == CARD_RESULT_BROKEN) + { + rc = 2; + } + else + { + if (result == CARD_RESULT_ENCODING) + { + rc = 3; + if (param2) + { + *param2 = 1; + } + } + else + { + rc = 0; + if (result == CARD_RESULT_ENCODING && param2) + { + *param2 = 1; + } + if (result == CARD_RESULT_IOERROR && param3) + { + *param3 = 1; + } + } + } + } + + if (rc == 1) + { + do + { + result = CARDGetEncoding(mcdata->chan, &encoding); + } while (result == CARD_RESULT_BUSY); + + if (result == CARD_RESULT_READY && encoding && param2) + { + *param2 = 1; + } + } + + return rc; +} + +// Looks equivalent. Can't get variable initializtions to match. +S32 iSG_mcidx2slot(S32 param1, S32* out_slot, S32* param3) +{ + s32 cardReady[ISG_NUM_SLOTS] = {}; + S32 ret = 0; + S32 idk = 0; + s32 memSize = 0; + s32 sectorSize = 0; + *out_slot = -1; + + for (S32 i = 0; i < ISG_NUM_SLOTS; i++) + { + s32 result; + do + { + result = CARDProbeEx(i, &memSize, §orSize); + } while (result == CARD_RESULT_BUSY); + + if (result == CARD_RESULT_READY) + { + cardReady[i] = TRUE; + } + } + + for (S32 i = 0; i < ISG_NUM_SLOTS; i++) + { + if (cardReady[i]) + { + if (idk == param1) + { + *out_slot = i; + ret = 1; + break; + } + idk++; + } + } + + if (param3) + { + for (S32 i = 0; i < ISG_NUM_SLOTS; i++) + { + param3[i] = cardReady[i]; + } + } + + return ret; +} + +static S32 iSG_mc_fread(st_ISG_MEMCARD_DATA* mcdata, char* buf, S32 len, S32 offset) +{ + return iSG_mcqa_fread(mcdata, buf, len, offset); +} + +S32 iSGReadLeader(st_ISGSESSION* isgdata, const char* fname, char* databuf, S32 numbytes, S32 async) +{ + S32 bufsize; + S32 iconsize; + S32 allocsize; + char* readbuf; + + S32 readret = 0; + st_ISG_MEMCARD_DATA* data; + void* alloc = NULL; + + en_ASYNC_OPERR operr = ISG_OPERR_NONE; + if (isgdata->slot < 0) + { + isgdata->unk_26c = ISG_OPSTAT_FAILURE; + isgdata->unk_268 = ISG_OPERR_NOCARD; + return 0; + } + data = &isgdata->mcdata[isgdata->slot]; + + if (data->unk_12c != 0) + { + isgdata->unk_26c = ISG_OPSTAT_FAILURE; + isgdata->unk_268 = ISG_OPERR_DAMAGE; + return 0; + } + + iTRCDisk::CheckDVDAndResetState(); + iconsize = iSG_cubeicon_size(data->chan, data->sectorSize); + S32 sectorsize200 = ALIGN_THING(data->sectorSize, 0x200); + if ((S32)databuf % 32 != 0 || numbytes - (numbytes / sectorsize200) * sectorsize200 != 0) + { + S32 tmpsize = (numbytes + 0x1ff & ~0x1ff); + allocsize = tmpsize + 0x1f; + alloc = xMemPushTemp(allocsize); + memset(alloc, 0, allocsize); + bufsize = tmpsize; + readbuf = (char*)((U32)alloc + 0x1f & ~0x1f); + } + else + { + readbuf = databuf; + bufsize = numbytes; + } + + iTRCDisk::CheckDVDAndResetState(); + + if (iSG_mc_fopen(data, fname, -1, ISG_IOMODE_READ, &operr) != 0) + { + readret = (bool)iSG_mc_fread(data, (char*)readbuf, bufsize, iconsize); + iSG_mc_fclose(data); + } + + if (readret != 0 && alloc != NULL) + { + memcpy(databuf, readbuf, numbytes); + } + if (alloc != NULL) + { + xMemPopTemp(alloc); + } + + isgdata->unk_268 = ISG_OPERR_NONE; + if (readret != 0) + { + isgdata->unk_26c = ISG_OPSTAT_SUCCESS; + } + else + { + isgdata->unk_26c = ISG_OPSTAT_FAILURE; + if (data->unk_12c != 0) + { + isgdata->unk_268 = ISG_OPERR_DAMAGE; + } + else + { + isgdata->unk_268 = ISG_OPERR_OTHER; + } + } + return readret; +} + +static void iSG_upd_icostat(CARDStat*, CARDStat* stat) +{ + CARDSetCommentAddress(stat, 0); + CARDSetBannerFormat(stat, CARD_STAT_BANNER_RGB5A3); + CARDSetIconAddress(stat, 0x40); + CARDSetIconAnim(stat, CARD_STAT_ANIM_LOOP); + + for (S32 i = 0; i < CARD_ICON_MAX; ++i) + { + CARDSetIconFormat(stat, i, CARD_STAT_BANNER_RGB5A3); + CARDSetIconSpeed(stat, i, CARD_STAT_SPEED_MIDDLE); + } +} + +static void iSG_timestamp(CARDStat*) +{ +} + +static S32 iSG_mc_fwrite(st_ISG_MEMCARD_DATA* mcdata, char* buf, S32 len) +{ + return iSG_mcqa_fwrite(mcdata, buf, len); +} + +S32 iSGSaveFile(st_ISGSESSION* isgdata, const char* fname, char* data, S32 n, S32 async, char* arg5) +// Only 25%, adding cus it may be useful for the actual function +{ + void* alloc; + S32 allocsize; + char* icondata; + S32 iconsize; + + S32 writeret = 0; + en_ASYNC_OPERR operr = ISG_OPERR_NONE; + CARDStat statA = { 0 }; + CARDStat statB = { 0 }; + + ResetButton::DisableReset(); + if (isgdata->slot < 0) + { + isgdata->unk_26c = ISG_OPSTAT_FAILURE; + isgdata->unk_268 = ISG_OPERR_NOCARD; + return 0; + } + + st_ISG_MEMCARD_DATA* mcdata = &isgdata->mcdata[isgdata->slot]; + if (mcdata->unk_12c != 0) + { + isgdata->unk_26c = ISG_OPSTAT_FAILURE; + isgdata->unk_268 = ISG_OPERR_DAMAGE; + return 0; + } + + iTRCDisk::CheckDVDAndResetState(); + iconsize = iSG_cubeicon_size(isgdata->slot, mcdata->sectorSize); + S32 sectorsize200 = ALIGN_THING(mcdata->sectorSize, 0x200); + iconsize += ALIGN_THING(sectorsize200, n); + + allocsize = iconsize + 0x1f; + alloc = xMemPushTemp(allocsize); + memset(alloc, 0, allocsize); + icondata = (char*)((U32)alloc + 0x1f & 0xFFFFFFE0); + + memcpy(iSG_bfr_icondata(icondata, &statA, arg5, mcdata->sectorSize), data, n); + iTRCDisk::CheckDVDAndResetState(); + + if (iSG_mc_fopen(mcdata, fname, iconsize, ISG_IOMODE_WRITE, &operr) != 0) + { + if (iSG_mc_fwrite(mcdata, icondata, iconsize) != 0) + { + writeret = 1; + } + else + { + writeret = 0; + operr = ISG_OPERR_SVWRITE; + } + + if (writeret != 0) + { + iSG_upd_icostat(&statA, &mcdata->fstat); + iSG_timestamp(&mcdata->fstat); + s32 result; + do + { + result = CARDSetStatus(mcdata->chan, mcdata->finfo.fileNo, &mcdata->fstat); + } while (result == CARD_RESULT_BUSY); + + if (result != CARD_RESULT_READY) + { + writeret = 0; + } + } + + if (writeret != 0) + { + s32 result; + do + { + result = CARDSetAttributes(mcdata->chan, mcdata->finfo.fileNo, CARD_ATTR_PUBLIC); + } while (result == CARD_RESULT_BUSY); + } + + iSG_mc_fclose(mcdata, &statB); + } + xMemPopTemp(alloc); + + if (writeret == 0 && mcdata->unk_12c == 0) + { + iSG_mc_fdel(mcdata, fname); + } + + ResetButton::EnableReset(); + iTRCDisk::CheckDVDAndResetState(); + + isgdata->unk_268 = ISG_OPERR_NONE; + if (writeret != 0) + { + isgdata->unk_26c = ISG_OPSTAT_SUCCESS; + } + else + { + isgdata->unk_26c = ISG_OPSTAT_FAILURE; + if (operr != ISG_OPERR_NONE) + { + isgdata->unk_268 = operr; + } + else + { + isgdata->unk_268 = ISG_OPERR_UNKNOWN; + } + } + return writeret; +} + +S32 iSGSetupGameDir(st_ISGSESSION* isgdata, const char* dname, S32 force_iconfix) +{ + return 1; +} + +static S32 iSG_mc_isformatted(st_ISG_MEMCARD_DATA* mcdata) +{ + S32 result = 0; + S32 rc = 0; + s32 xferBytes = 0; + + if (mcdata->unk_0 == 0) + { + rc = 0; + } + else if (mcdata->unk_12c) + { + rc = 0; + } + else + { + do + { + result = CARDCheckEx(mcdata->chan, &xferBytes); + } while (result == CARD_RESULT_BUSY); + + if (result == CARD_RESULT_READY) + { + rc = 1; + } + else if (result == CARD_RESULT_BROKEN) + { + rc = 0; + } + else + { + rc = 0; + } + } + + return rc; +} + +S32 iSGSelectGameDir(st_ISGSESSION* isgdata, const char* dname) +{ + if (isgdata->slot < 0) + { + return 0; + } + st_ISG_MEMCARD_DATA* data = &isgdata->mcdata[isgdata->slot]; + + if (data->unk_0 == 0) + { + return 0; + } + + if (iSG_mc_isGCcard(data, NULL, NULL) == 0) + { + return 0; + } + + if (iSG_mc_isformatted(data) == 0) + { + return 0; + } + + S32 count = 0; + for (S32 idx = 0; idx < ISG_NUM_FILES; ++idx) + { + const char* n = iSGMakeName(ISG_NGTYP_GAMEFILE, NULL, idx); + if (iSG_get_finfo(data, n) != 0) + { + count++; + } + } + + return count != 0; +} + +void iSGMakeTimeStamp(char* str) +{ + OSCalendarTime calendar_time = { 0 }; + OSTime time = OSGetTime(); + OSTicksToCalendarTime(time, &calendar_time); + sprintf(str, "%02d/%02d/%04d %02d:%02d:%02d", calendar_time.mon + 1, calendar_time.mday, + calendar_time.year, calendar_time.hour, calendar_time.min, calendar_time.sec); +} + +static S32 iSG_get_fmoddate(st_ISG_MEMCARD_DATA* mcdata, const char* fname, int* sec, int* min, + int* hr, int* mon, int* day, int* yr) +{ + S32 rc = 1; + OSCalendarTime time = { 0 }; + + if (iSG_get_finfo(mcdata, fname) == 0) + { + rc = 0; + } + else + { + OSTime t = mcdata->unk_b0.time; + t = OSSecondsToTicks(t); + OSTicksToCalendarTime(t, &time); + + if (sec) + { + *sec = time.sec; + } + if (min) + { + *min = time.min; + } + if (hr) + { + *hr = time.hour; + } + if (mon) + { + *mon = time.mon + 1; + } + if (day) + { + *day = time.mday; + } + if (mon) + { + *mon = time.mon + 1; + } + if (day) + { + *day = time.mday; + } + if (yr) + { + *yr = time.year; + } + } + + return rc; +} + +char* iSGFileModDate(st_ISGSESSION* isgdata, const char* fname, S32* sec, S32* min, S32* hr, + S32* mon, S32* day, S32* yr) +{ + static char datestr[0x40] = { 0 }; + int sec_str = 0; + int min_str = 0; + int hr_str = 0; + int mon_str = 0; + int day_str = 0; + int yr_str = 0; + if (iSG_get_fmoddate(&isgdata->mcdata[isgdata->slot], fname, &sec_str, &min_str, &hr_str, + &mon_str, &day_str, &yr_str) != 0) + { + sprintf(datestr, "%02d/%02d/%04d %02d:%02d:%02d", mon_str, day_str, yr_str, hr_str, min_str, + sec_str); + + if (sec != NULL) + { + *sec = sec_str; + } + if (min != NULL) + { + *min = min_str; + } + if (hr != NULL) + { + *hr = hr_str; + } + if (mon != NULL) + { + *mon = mon_str; + } + if (day != NULL) + { + *day = day_str; + } + if (yr != NULL) + { + *yr = yr_str; + } + } + else + { + sprintf(datestr, ""); + } + return datestr; +} + +char* iSGFileModDate(st_ISGSESSION* isgdata, const char* fname) +{ + return iSGFileModDate(isgdata, fname, NULL, NULL, NULL, NULL, NULL, NULL); +} + +static S32 iSG_get_fsize(st_ISG_MEMCARD_DATA* mcdata, const char* param2) +{ + S32 rc = -1; + + if (iSG_get_finfo(mcdata, param2)) + { + rc = mcdata->unk_b0.length; + } + + if (rc < 0) + { + rc = -1; + } + + return rc; +} + +S32 iSGFileSize(st_ISGSESSION* isgdata, const char* fname) +{ + S32 ret = 0; + if (isgdata->slot < 0) + { + return -1; + } + st_ISG_MEMCARD_DATA* data = &isgdata->mcdata[isgdata->slot]; + iTRCDisk::CheckDVDAndResetState(); + ret = iSG_get_fsize(data, fname); + if (ret >= 0) + { + ret -= iSG_cubeicon_size(data->chan, data->sectorSize); + if (ret < 0) + { + ret = -1; + } + } + return ret; +} + +S32 iSGTgtHaveRoomStartup(st_ISGSESSION* isgdata, S32 tidx, S32 fsize, const char* dpath, + const char* fname, S32* bytesNeeded, S32* availOnDisk, S32* needFile) +{ + st_ISG_MEMCARD_DATA* data; + S32 i; + S32 count; + S32 opened; + S32 is_space; + if (isgdata->slot < 0) + { + return 0; + } + data = &isgdata->mcdata[isgdata->slot]; + if (data->unk_0 == NULL) + { + return 0; + } + count = 0; + if (fname == NULL) + { + for (i = 0; i < ISG_NUM_FILES; ++i) + { + iTRCDisk::CheckDVDAndResetState(); + fname = iSGMakeName(ISG_NGTYP_GAMEFILE, NULL, i); + if (iSG_get_finfo(data, fname) != 0) + { + count++; + } + } + } + + is_space = iSG_isSpaceForFile(data, fsize, fname, bytesNeeded, availOnDisk, needFile); + if (count > 0 && *bytesNeeded > *availOnDisk) + { + if (needFile != NULL && *bytesNeeded > *availOnDisk) + { + *needFile = 0; + return 0; + } + return 1; + } + + CARDFileInfo fileInfo; + opened = 0; + for (i = 0; i < CARD_MAX_FILE && isgdata->slot >= 0 && isgdata->slot < ISG_NUM_SLOTS; ++i) + { + if (CARDFastOpen(isgdata->slot, i, &fileInfo) == 0) + { + opened++; + CARDClose(&fileInfo); + } + } + + if (opened >= CARD_MAX_FILE) + { + if (count > 0) + { + if (needFile != NULL) + { + *needFile = 0; + } + return 0; + } + *needFile = -1; + return 0; + } + + if (*bytesNeeded > *availOnDisk) + { + return 0; + } + return (count >= 3) ? 0 : is_space; +} + +S32 iSGTgtHaveRoom(st_ISGSESSION* isgdata, S32 tidx, S32 fsize, const char* dpath, + const char* fname, S32* bytesNeeded, S32* availOnDisk, S32* needFile) +{ + st_ISG_MEMCARD_DATA* data; + S32 i; + S32 count; + S32 opened; + S32 is_space; + if (isgdata->slot < 0) + { + return 0; + } + data = &isgdata->mcdata[isgdata->slot]; + if (data->unk_0 == NULL) + { + return 0; + } + count = 0; + if (fname == NULL) + { + for (i = 0; i < ISG_NUM_FILES; ++i) + { + iTRCDisk::CheckDVDAndResetState(); + fname = iSGMakeName(ISG_NGTYP_GAMEFILE, NULL, i); + if (iSG_get_finfo(data, fname) != 0) + { + count++; + } + } + } + + is_space = iSG_isSpaceForFile(data, fsize, fname, bytesNeeded, availOnDisk, needFile); + if (count > 0 && *bytesNeeded > *availOnDisk) + { + if (needFile != NULL && *bytesNeeded > *availOnDisk) + { + *needFile = 0; + return 0; + } + return 1; + } + + CARDFileInfo fileInfo; + opened = 0; + for (i = 0; i < CARD_MAX_FILE && isgdata->slot >= 0 && isgdata->slot < ISG_NUM_SLOTS; ++i) + { + if (CARDFastOpen(isgdata->slot, i, &fileInfo) == 0) + { + opened++; + CARDClose(&fileInfo); + } + } + + if (opened >= CARD_MAX_FILE) + { + if (count > 0) + { + if (needFile != NULL) + { + *needFile = 0; + } + return 1; + } + return 0; + } + + return (*bytesNeeded > *availOnDisk) ? 0 : is_space; +} + +static S32 iSG_mc_exists(S32 slot) +{ + S32 ret = 0; + s32 memSize = 0; + s32 sectorSize = 0; + + if (slot < -1) + { + return 0; + } + + S32 result; + do + { + result = CARDProbeEx(slot, &memSize, §orSize); + } while (result == CARD_RESULT_BUSY); + + if (result == CARD_RESULT_READY) + { + ret = 1; + } + + return ret; +} + +U32 iSGTgtState(st_ISGSESSION* isgdata, S32 tgtidx, const char* dpath) +{ + S32 isSectSizeValid = 0; + S32 state = 0; + + S32 rc = 0; + + S32 slot = 0; + S32 x = 0; + S32 y = 0; + iTRCDisk::CheckDVDAndResetState(); + + iSG_mcidx2slot(tgtidx, &slot, NULL); + if (slot != isgdata->slot) + { + iSGTgtSetActive(isgdata, tgtidx); + } + + if (isgdata->slot < 0) + { + return 0x1000000; + } + + st_ISG_MEMCARD_DATA* data = &isgdata->mcdata[isgdata->slot]; + if (data->unk_0 == NULL) + { + return 0; + } + + if (iSG_mc_exists(isgdata->slot)) + { + state |= 1; + } + else + { + return 0; + } + + if (data->unk_12c != 0) + { + return state | 0x1000000; + } + + rc = iSG_mc_isGCcard(data, &x, &y); + if (x != 0) + { + state |= 0x4000000; + } + + if (y != 0) + { + state |= 0x2000000; + } + + if (rc == 0) + { + return state; + } + + if (g_legalSectSize[0] > 0) + { + for (S32 i = 0; g_legalSectSize[i] > 0; i++) + { + if (data->sectorSize == g_legalSectSize[i]) + { + isSectSizeValid = 1; + break; + } + } + if (isSectSizeValid == 0) + { + state |= 0x8000004; + return state & ~4; + } + } + + if (iSG_mc_isformatted(data) == 0) + { + return state | 4; + } + else + { + return state | 0xe; + } + + return state; +} + +S32 iSGTgtFormat(st_ISGSESSION* isgdata, S32 tgtidx, S32 async, S32* canRecover) +{ + S32 slot = 0; + S32 rc = 0; + iTRCDisk::CheckDVDAndResetState(); + if (iSG_mc_exists(isgdata->slot) == 0) + { + return 0; + } + + iSG_mcidx2slot(tgtidx, &slot, NULL); + // FIXME: r3 and r0 are swapped here for some reason ... + if (slot != isgdata->slot) + { + return 0; + } + + st_ISG_MEMCARD_DATA* data = &isgdata->mcdata[isgdata->slot]; + if (data->unk_0 == NULL) + { + return 0; + } + + if (iSG_mc_isGCcard(data, NULL, NULL) == 0) + { + return 0; + } + + rc = iSG_mc_format(data, 0, canRecover); + if (rc == -1) + { + return -1; + } + return rc == 0 ? 0 : 1; +} + +S32 iSGTgtPhysSlotIdx(st_ISGSESSION* isgdata, S32 tidx) +{ + S32 idx = -1; + if (iSG_mcidx2slot(tidx, &idx, NULL)) + { + return idx; + } + return -1; +} + +S32 iSGTgtCount(st_ISGSESSION* isgdata, S32* max) +{ + s32 memSize = 0; + s32 sectorSize = 0; + S32 ret = 0; + + if (max != NULL) + { + *max = 2; + } + + for (S32 i = 0; i < ISG_NUM_SLOTS; ++i) + { + iTRCDisk::CheckDVDAndResetState(); + s32 result; + do + { + result = CARDProbeEx(i, &memSize, §orSize); + } while (result == CARD_RESULT_BUSY); + if (result == CARD_RESULT_READY) + { + ret++; + } + } + + return ret; +} + +static S32 iSG_mc_unmount(S32 slot) +{ + S32 rc = 0; + S32 result; + + do + { + result = CARDUnmount(slot); + } while (result == CARD_RESULT_BUSY); + + if (result == CARD_RESULT_READY) + { + rc = 1; + } + else if (result == CARD_RESULT_NOCARD) + { + rc = 1; + } + + return rc; +} + +void iSGSessionEnd(st_ISGSESSION* isgdata) +{ + iTRCDisk::CheckDVDAndResetState(); + for (S32 i = 0; i < ISG_NUM_SLOTS; i++) + { + if (isgdata->mcdata[i].unk_0) + { + iSG_mc_unmount(i); + isgdata->mcdata[i].unk_0 = 0; + } + } + + memset(isgdata, 0, sizeof(st_ISGSESSION)); +} + +static S32 iSG_chk_icondata() +{ + return 1; +} + +st_ISGSESSION* iSGSessionBegin(void* cltdata, void (*chgfunc)(void*, en_CHGCODE), S32 monitor) +{ + iTRCDisk::CheckDVDAndResetState(); + memset(&g_isgdata_MAIN, 0, sizeof(st_ISGSESSION)); + + g_isgdata_MAIN.slot = -1; + g_isgdata_MAIN.chgfunc = chgfunc; + g_isgdata_MAIN.cltdata = cltdata; + + iSG_chk_icondata(); + return &g_isgdata_MAIN; +} + +char* iSGMakeName(en_NAMEGEN_TYPE type, const char* base, S32 idx) +{ + static volatile S32 rotate = 0; // fakematch?? + static char rotatebuf[8][32] = { 0 }; + + const char* fmt_sd = "%s%02d"; + char* use_buf = rotatebuf[rotate++]; + if (rotate == 8) + { + rotate = 0; + } + + *use_buf = NULL; + switch (type) + { + case ISG_NGTYP_GAMEFILE: + + if (base != NULL) + { + sprintf(use_buf, fmt_sd, base, idx); + } + else + { + sprintf(use_buf, fmt_sd, "SpongeBob", idx); + } + break; + case ISG_NGTYP_GAMEDIR: + case ISG_NGTYP_CONFIG: + case ISG_NGTYP_ICONTHUM: + break; + } + + return use_buf; +} + +static void iSG_discard_icondata() +{ + OSFreeToHeap(__OSCurrHeap, g_rawicon); + OSFreeToHeap(__OSCurrHeap, g_rawbanr); + g_rawicon = NULL; + g_iconsize = 0; + g_rawbanr = NULL; + g_banrsize = 0; +} + +S32 iSGShutdown() +{ + iSG_discard_icondata(); + return 1; +} + +static S32 iSG_start_your_engines() +{ + CARDInit(); + return 1; +} + +S32 iSGStartup() +{ + if (g_isginit++ != 0) + { + return g_isginit; + } + + iSG_start_your_engines(); + iSG_load_icondata(); + return g_isginit; +} + +// iPar + +void iParMgrRender() +{ +} + +void iParMgrUpdate(float) +{ +} + +// iPad + +PADStatus sPadData[PAD_MAX_CONTROLLERS]; + +void iPadKill() +{ +} + +void iPadStopRumble() +{ + PADControlMotor(mPad[globals.currentActivePad].port, 0); // Scheduling memes. +} + +void iPadStopRumble(_tagxPad* pad) +{ + PADControlMotor(pad->port, 0); +} + +S32 iPadUpdate(_tagxPad* pad, U32* on) +{ + U16 buttons; + U32 temp_on; + + if (pad->port == 0) + { + PADRead(sPadData); + PADClamp(sPadData); + } + + PADStatus* padData = (PADStatus*)&sPadData; + switch (padData[pad->port].err) + { + case PAD_ERR_NO_CONTROLLER: + xTRCPad(pad->port, TRC_PadMissing); + PADReset(0x80000000 >> pad->port); + goto defaultError; + + case PAD_ERR_NOT_READY: + case PAD_ERR_TRANSFER: + return 0; + + default: + defaultError: + return 0; + + case PAD_ERR_NONE: + temp_on = iPadConvFromGCN(padData[pad->port].button, 1, 0x80); + temp_on |= iPadConvFromGCN(sPadData[pad->port].button, 2, 0x20); + temp_on |= iPadConvFromGCN(sPadData[pad->port].button, 4, 0x40); + temp_on |= iPadConvFromGCN(sPadData[pad->port].button, 8, 0x10); + buttons = sPadData[pad->port].button; + + if (buttons & 0x10) + { + temp_on |= iPadConvFromGCN(sPadData[pad->port].button, 0x20, 0x2000); + temp_on |= iPadConvFromGCN(sPadData[pad->port].button, 0x40, 0x200); + if (sPadData[pad->port].triggerLeft >= 0x18) + { + temp_on |= 0x200; + } + if (sPadData[pad->port].triggerRight >= 0x18) + { + temp_on |= 0x2000; + } + temp_on |= 0x100000; + } + else + { + temp_on |= iPadConvFromGCN(sPadData[pad->port].button, 0x20, 0x1000); + temp_on |= iPadConvFromGCN(sPadData[pad->port].button, 0x40, 0x100); + if (sPadData[pad->port].triggerLeft >= 0x18) + { + temp_on |= 0x100; + } + if (sPadData[pad->port].triggerRight >= 0x18) + { + temp_on |= 0x1000; + } + } + + temp_on |= iPadConvFromGCN(sPadData[pad->port].button, 0x100, 0x10000); + temp_on |= iPadConvFromGCN(sPadData[pad->port].button, 0x200, 0x80000); + temp_on |= iPadConvFromGCN(sPadData[pad->port].button, 0x800, 0x40000); + temp_on |= iPadConvFromGCN(sPadData[pad->port].button, 0x400, 0x20000); + temp_on |= iPadConvFromGCN(sPadData[pad->port].button, 0x1000, 0x1); + (*on) = temp_on; + + pad->analog1.x = iPadConvStick(sPadData[pad->port].stickX); + pad->analog1.y = -iPadConvStick(sPadData[pad->port].stickY); // Scheduling memes. + pad->analog2.x = iPadConvStick(sPadData[pad->port].substickX); + pad->analog2.y = -iPadConvStick(sPadData[pad->port].substickY); // Same as above. + if (gTrcPad[pad->port].state != TRC_PadInserted) + { + xTRCPad(pad->port, TRC_PadInserted); + } + } + return 1; +} + +_tagxPad* iPadEnable(_tagxPad* pad, S16 port) +{ + pad->port = port; + pad->slot = 0; + pad->state = ePad_Enabled; + gTrcPad[pad->port].state = TRC_PadInserted; + pad->flags |= 3; + pad->flags |= 4; + return pad; +} + +S32 iPadInit() +{ + PADInit(); + return 1; +} + +// iMorph + +// iModel + +// iMemMgr + +extern xMemInfo_tag gMemInfo; +extern OSHeapHandle he; +extern OSHeapHandle hs; +extern unsigned char _stack_addr[]; +extern U32 HeapSize; +extern U32 mem_top_alloc; +extern U32 mem_base_alloc; + +void iMemExit() +{ + free((void*)gMemInfo.DRAM.addr); + gMemInfo.DRAM.addr = 0; +} + +// I dont have a name for these yet + +void iBoxBoundVec(xBox* o, const xBox* b, const xVec3* v) +{ + xVec3Init(&o->lower, MIN(v->x, b->lower.x), MIN(v->y, b->lower.y), MIN(v->z, b->lower.z)); + xVec3Init(&o->upper, MAX(v->x, b->upper.x), MAX(v->y, b->upper.y), MAX(v->z, b->upper.z)); +} + +void iBoxInitBoundVec(xBox* b, const xVec3* v) +{ + xVec3Copy(&b->lower, v); + xVec3Copy(&b->upper, v); +} + +void iBoxIsectVec(const xBox* b, const xVec3* v, xIsect* isx) +{ + if (v->x >= b->lower.x && v->x <= b->upper.x && v->y >= b->lower.y && v->y <= b->upper.y && + v->z >= b->lower.z && v->z <= b->upper.z) + { + isx->penned = -1.0f; + } + else + { + isx->penned = 1.0f; + } +} + +void iBoxVecDist(const xBox* box, const xVec3* v, xIsect* isx) +{ + if (v->x < box->lower.x) + { + if (v->y < box->lower.y) + { + if (v->z < box->lower.z) + { + isx->norm.x = box->lower.x - v->x; + isx->norm.y = box->lower.y - v->y; + isx->norm.z = box->lower.z - v->z; + isx->flags = isx->flags & ~0x1F000000 | 0x00000000; + isx->flags |= 0x80000000; + } + else if (v->z <= box->upper.z) + { + isx->norm.x = box->lower.x - v->x; + isx->norm.y = box->lower.y - v->y; + isx->norm.z = 0.0f; + isx->flags = isx->flags & ~0x1F000000 | 0x01000000; + isx->flags |= 0x40000000; + } + else + { + isx->norm.x = box->lower.x - v->x; + isx->norm.y = box->lower.y - v->y; + isx->norm.z = box->upper.z - v->z; + isx->flags = isx->flags & ~0x1F000000 | 0x02000000; + isx->flags |= 0x80000000; + } + } + else if (v->y <= box->upper.y) + { + if (v->z < box->lower.z) + { + isx->norm.x = box->lower.x - v->x; + isx->norm.y = 0.0f; + isx->norm.z = box->lower.z - v->z; + isx->flags = isx->flags & ~0x1F000000 | 0x03000000; + isx->flags |= 0x40000000; + } + else if (v->z <= box->upper.z) + { + isx->norm.x = box->lower.x - v->x; + isx->norm.y = 0.0f; + isx->norm.z = 0.0f; + isx->flags = isx->flags & ~0x1F000000 | 0x04000000; + isx->flags |= 0x20000000; + } + else + { + isx->norm.x = box->lower.x - v->x; + isx->norm.y = 0.0f; + isx->norm.z = box->upper.z - v->z; + isx->flags = isx->flags & ~0x1F000000 | 0x05000000; + isx->flags |= 0x40000000; + } + } + else + { + if (v->z < box->lower.z) + { + isx->norm.x = box->lower.x - v->x; + isx->norm.y = box->upper.y - v->y; + isx->norm.z = box->lower.z - v->z; + isx->flags = isx->flags & ~0x1F000000 | 0x06000000; + isx->flags |= 0x80000000; + } + else if (v->z <= box->upper.z) + { + isx->norm.x = box->lower.x - v->x; + isx->norm.y = box->upper.y - v->y; + isx->norm.z = 0.0f; + isx->flags = isx->flags & ~0x1F000000 | 0x07000000; + isx->flags |= 0x40000000; + } + else + { + isx->norm.x = box->lower.x - v->x; + isx->norm.y = box->upper.y - v->y; + isx->norm.z = box->upper.z - v->z; + isx->flags = isx->flags & ~0x1F000000 | 0x08000000; + isx->flags |= 0x80000000; + } + } + } + else if (v->x <= box->upper.x) + { + if (v->y < box->lower.y) + { + if (v->z < box->lower.z) + { + isx->norm.x = 0.0f; + isx->norm.y = box->lower.y - v->y; + isx->norm.z = box->lower.z - v->z; + isx->flags = isx->flags & ~0x1F000000 | 0x09000000; + isx->flags |= 0x40000000; + } + else if (v->z <= box->upper.z) + { + isx->norm.x = 0.0f; + isx->norm.y = box->lower.y - v->y; + isx->norm.z = 0.0f; + isx->flags = isx->flags & ~0x1F000000 | 0x0A000000; + isx->flags |= 0x20000000; + } + else + { + isx->norm.x = 0.0f; + isx->norm.y = box->lower.y - v->y; + isx->norm.z = box->upper.z - v->z; + isx->flags = isx->flags & ~0x1F000000 | 0x0B000000; + isx->flags |= 0x40000000; + } + } + else if (v->y <= box->upper.y) + { + if (v->z < box->lower.z) + { + isx->norm.x = 0.0f; + isx->norm.y = 0.0f; + isx->norm.z = box->lower.z - v->z; + isx->flags = isx->flags & ~0x1F000000 | 0x0C000000; + isx->flags |= 0x20000000; + } + else if (v->z <= box->upper.z) + { + } + else + { + isx->norm.x = 0.0f; + isx->norm.y = 0.0f; + isx->norm.z = box->upper.z - v->z; + isx->flags = isx->flags & ~0x1F000000 | 0x0E000000; + isx->flags |= 0x20000000; + } + } + else + { + if (v->z < box->lower.z) + { + isx->norm.x = 0.0f; + isx->norm.y = box->upper.y - v->y; + isx->norm.z = box->lower.z - v->z; + isx->flags = isx->flags & ~0x1F000000 | 0x0F000000; + isx->flags |= 0x40000000; + } + else if (v->z <= box->upper.z) + { + isx->norm.x = 0.0f; + isx->norm.y = box->upper.y - v->y; + isx->norm.z = 0.0f; + isx->flags = isx->flags & ~0x1F000000 | 0x10000000; + isx->flags |= 0x20000000; + } + else + { + isx->norm.x = 0.0f; + isx->norm.y = box->upper.y - v->y; + isx->norm.z = box->upper.z - v->z; + isx->flags = isx->flags & ~0x1F000000 | 0x11000000; + isx->flags |= 0x40000000; + } + } + } + else + { + if (v->y < box->lower.y) + { + if (v->z < box->lower.z) + { + isx->norm.x = box->upper.x - v->x; + isx->norm.y = box->lower.y - v->y; + isx->norm.z = box->lower.z - v->z; + isx->flags = isx->flags & ~0x1F000000 | 0x12000000; + isx->flags |= 0x80000000; + } + else if (v->z <= box->upper.z) + { + isx->norm.x = box->upper.x - v->x; + isx->norm.y = box->lower.y - v->y; + isx->norm.z = 0.0f; + isx->flags = isx->flags & ~0x1F000000 | 0x13000000; + isx->flags |= 0x40000000; + } + else + { + isx->norm.x = box->upper.x - v->x; + isx->norm.y = box->lower.y - v->y; + isx->norm.z = box->upper.z - v->z; + isx->flags = isx->flags & ~0x1F000000 | 0x14000000; + isx->flags |= 0x80000000; + } + } + else if (v->y <= box->upper.y) + { + if (v->z < box->lower.z) + { + isx->norm.x = box->upper.x - v->x; + isx->norm.y = 0.0f; + isx->norm.z = box->lower.z - v->z; + isx->flags = isx->flags & ~0x1F000000 | 0x15000000; + isx->flags |= 0x40000000; + } + else if (v->z <= box->upper.z) + { + isx->norm.x = box->upper.x - v->x; + isx->norm.y = 0.0f; + isx->norm.z = 0.0f; + isx->flags = isx->flags & ~0x1F000000 | 0x16000000; + isx->flags |= 0x20000000; + } + else + { + isx->norm.x = box->upper.x - v->x; + isx->norm.y = 0.0f; + isx->norm.z = box->upper.z - v->z; + isx->flags = isx->flags & ~0x1F000000 | 0x17000000; + isx->flags |= 0x40000000; + } + } + else + { + if (v->z < box->lower.z) + { + isx->norm.x = box->upper.x - v->x; + isx->norm.y = box->upper.y - v->y; + isx->norm.z = box->lower.z - v->z; + isx->flags = isx->flags & ~0x1F000000 | 0x18000000; + isx->flags |= 0x80000000; + } + else if (v->z <= box->upper.z) + { + isx->norm.x = box->upper.x - v->x; + isx->norm.y = box->upper.y - v->y; + isx->norm.z = 0.0f; + isx->flags = isx->flags & ~0x1F000000 | 0x19000000; + isx->flags |= 0x40000000; + } + else + { + isx->norm.x = box->upper.x - v->x; + isx->norm.y = box->upper.y - v->y; + isx->norm.z = box->upper.z - v->z; + isx->flags = isx->flags & ~0x1F000000 | 0x1A000000; + isx->flags |= 0x80000000; + } + } + } + + isx->dist = xVec3Length(&isx->norm); +} + +void iSphereBoundVec(xSphere* o, const xSphere* s, const xVec3* v) +{ + F32 scale; + xSphere temp; + xSphere* tp; + U32 usetemp; + xIsect isx; + + usetemp = (o == s); + + iSphereIsectVec(s, v, &isx); + + if (isx.penned <= 0.0f) + { + if (!usetemp) + { + memcpy(o, s, sizeof(xSphere)); + } + } + else + { + if (usetemp) + { + tp = &temp; + } + else + { + tp = o; + } + + xVec3Copy(&tp->center, &isx.norm); + + scale = (isx.dist - s->r) / (2.0f * isx.dist); + + xVec3SMul(&tp->center, &tp->center, scale); + xVec3Add(&tp->center, &tp->center, &s->center); + + tp->r = 0.5f * (isx.dist + s->r); + + if (usetemp) + { + memcpy(o, tp, sizeof(xSphere)); + } + } +} + +void iSphereInitBoundVec(xSphere* s, const xVec3* v) +{ + xVec3Copy(&s->center, v); + + s->r = 0.00001f; +} + +void iMath3Init() +{ +} + +// Sin, Cos, Tan + +F32 itan(F32 x) +{ + return std::tanf(x); +} + +F32 icos(F32 x) +{ + return std::cosf(x); +} + +F32 isin(F32 x) +{ + return std::sinf(x); +} + +// iLight + +void iLightEnv(iLight* light, S32 env) +{ + RwUInt32 flags = 0; + + switch (env) + { + case ILIGHT_ENV_NONE: + flags = 0; + break; + case ILIGHT_ENV_ATOMIC: + flags = rpLIGHTLIGHTWORLD; + break; + case ILIGHT_ENV_WORLD: + flags = rpLIGHTLIGHTATOMICS; + break; + case ILIGHT_ENV_ATOMICWORLD: + flags = rpLIGHTLIGHTATOMICS | rpLIGHTLIGHTWORLD; + break; + } + + RpLightSetFlags(light->hw, flags); +} + +void iLightDestroy(iLight* light) +{ + RwFrame* frame; + + light->type = ILIGHT_TYPE_NONE; + + _rwFrameSyncDirty(); + + frame = RpLightGetFrame(light->hw); + + if (frame) + { + RwFrameDestroy(frame); + } + + RpLightDestroy(light->hw); +} + +void iLightSetPos(iLight* light, xVec3* pos) +{ + RwFrame* f = RpLightGetFrame(light->hw); + RwMatrix* m = RwFrameGetMatrix(f); + + RwMatrixGetPos(m)->x = pos->x; + RwMatrixGetPos(m)->y = pos->y; + RwMatrixGetPos(m)->z = pos->z; + + RwMatrixUpdate(m); + + RwFrameUpdateObjects(f); +} + +void iLightSetColor(iLight* light, _xFColor* col) +{ + RpLightSetColor(light->hw, (RwRGBAReal*)col); +} + +void iLightModify(iLight* light, U32 flags) // Remove xVec ops +{ + if (flags & 0x5) + { + RwFrame* frame = RpLightGetFrame(light->hw); + RwMatrix temp; + + *(xVec3*)RwMatrixGetRight(&temp) = g_O3; + *(xVec3*)RwMatrixGetUp(&temp) = g_O3; + *(xVec3*)RwMatrixGetAt(&temp) = light->dir; + *(xVec3*)RwMatrixGetPos(&temp) = light->sph.center; + + RwFrameTransform(frame, &temp, rwCOMBINEREPLACE); + } + + if (flags & 0x2) + { + RpLightSetRadius(light->hw, light->sph.r); + } + + if (flags & 0x8) + { + RpLightSetColor(light->hw, (RwRGBAReal*)&light->color); + } + + if (flags & 0x10) + { + if (light->type == ILIGHT_TYPE_SPOT || light->type == ILIGHT_TYPE_SPOTSOFT) + { + RpLightSetConeAngle(light->hw, light->coneangle); + } + } +} + +iLight* iLightCreate(iLight* light, U32 type) +{ + RwFrame* frame; + + switch (type) + { + case ILIGHT_TYPE_POINT: + light->hw = RpLightCreate(rpLIGHTPOINT); + break; + case ILIGHT_TYPE_SPOT: + light->hw = RpLightCreate(rpLIGHTSPOT); + break; + case ILIGHT_TYPE_SPOTSOFT: + light->hw = RpLightCreate(rpLIGHTSPOTSOFT); + break; + default: + return NULL; + } + + if (!light->hw) + { + return NULL; + } + + frame = RwFrameCreate(); + + if (!frame) + { + RpLightDestroy(light->hw); + return NULL; + } + + RpLightSetFlags(light->hw, rpLIGHTLIGHTATOMICS); + RpLightSetFrame(light->hw, frame); + + RwFrameUpdateObjects(frame); + + light->type = type; + light->sph.center.x = 0.0f; + light->sph.center.y = 0.0f; + light->sph.center.z = 0.0f; + light->sph.r = 0.0f; + light->color.r = 1.0f; + light->color.g = 1.0f; + light->color.b = 1.0f; + light->color.a = 1.0f; + light->dir.x = 0.0f; + light->dir.y = 0.0f; + light->dir.z = 1.0f; + light->coneangle = 0.0f; + + return light; +} + +void iLightInit(RpWorld* world) +{ + gLightWorld = world; +} + +// Don't know what to call this + +// iFxUVCreatepipe +//_iGCURenderCallback + +// iFMV + +// FIXME: These should be in a RW header somewhere +extern GXRenderModeObj* _RwDlRenderMode; +extern "C" { +void RwGameCubeGetXFBs(void*, void*); +} + +//.bss +static U32 Bink_surface_type[5]; + +//.sbss +static S32 frame_num; +U32 fuckingSurfaceType; //??? +static HBINK Bink; +static HRAD3DIMAGE Image; +static S32 Paused; +static void* pixels; +static volatile F32 vol; +S32 ip; +s32 oof; +void* iFMV::mXFBs[2]; +void* iFMV::mCurrentFrameBuffer; +GXRenderModeObj* iFMV::mRenderMode; + +// .sdata +static float Width_scale = 1.0f; +static float Height_scale = 1.0f; +U8 iFMV::mFirstFrame = 1; + +static void* arammalloc(size_t size) +{ + return (void*)ARAlloc(size); +} + +// Something weird is going on here... +static void aramfree(void* mem) +{ + u32 vol; + ARFree(&vol); +} + +static void DrawFrame(float arg0, float arg1, float arg2, float arg3) +{ + GXRenderModeObj* rm = _RwDlRenderMode; + Mtx idt; + Mtx44 mtx; + + GXSetViewport(0.0f, 0.0f, rm->fbWidth, rm->efbHeight, 0.0f, 1.0f); + GXSetScissor(0, 0, rm->fbWidth, rm->efbHeight); + GXSetDispCopySrc(0, 0, rm->fbWidth, rm->efbHeight); + GXSetDispCopyDst(rm->fbWidth, rm->xfbHeight); + GXSetDispCopyYScale((float)rm->xfbHeight / rm->efbHeight); + GXSetCopyFilter(rm->aa, rm->sample_pattern, GX_TRUE, rm->vfilter); + + if (rm->aa) + { + GXSetPixelFmt(GX_PF_RGB565_Z16, GX_ZC_LINEAR); + } + else + { + GXSetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR); + } + + GXSetDispCopyGamma(GX_GM_1_0); + C_MTXOrtho(mtx, 0.0f, 480.0f, 0.0f, 640.0f, 0.0f, 10000.0f); + GXSetProjection(mtx, GX_ORTHOGRAPHIC); + PSMTXIdentity(idt); + GXLoadPosMtxImm(idt, 0); + + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT); + GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_NRM_NBT, GX_S16, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_NRM_NBT, GX_RGBA8, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_NRM_NBT, GX_RGBA6, 0); + + GXSetNumTexGens(1); + GXSetNumChans(1); + GXSetNumTevStages(1); + GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 0x3c); + GXSetTevOp(GX_TEVSTAGE0, GX_MODULATE); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); + + if (rm->field_rendering) + { + u32 field = VIGetNextField(); + GXSetViewportJitter(0.0f, 0.0f, rm->fbWidth, rm->efbHeight, 0.0f, 1.0f, field); + } + else + { + GXSetViewport(0.0f, 0.0f, rm->fbWidth, rm->efbHeight, 0.0f, 1.0f); + } + + GXInvalidateVtxCache(); + GXInvalidateTexAll(); + Blit_RAD_3D_image(Image, arg0, arg1, arg2, arg3, 1.0f); +} + +static void xDrawLine2D_LocaliFMVVersion(F32 arg0, F32 arg1, F32 arg2, F32 arg3) +{ + RwRGBA color = { -1, -1, -1, -1 }; + + F32 nearz = RwIm2DGetNearScreenZ(); + void* texraster_state; + RwRenderStateGet(rwRENDERSTATETEXTURERASTER, &texraster_state); + void* vtx_alpha_state; + RwRenderStateGet(rwRENDERSTATEVERTEXALPHAENABLE, &vtx_alpha_state); + RwIm2DVertex verts[2]; + + // RwIm2DVertexSetRealRGBA + + RwIm2DVertexSetScreenX(&verts[0], arg0); + RwIm2DVertexSetScreenY(&verts[0], arg1); + RwIm2DVertexSetScreenZ(&verts[0], nearz); + RwIm2DVertexSetIntRGBA(&verts[0], color.red, color.green, color.blue, color.alpha); + + RwIm2DVertexSetScreenX(&verts[1], arg2); + RwIm2DVertexSetScreenY(&verts[1], arg3); + RwIm2DVertexSetScreenZ(&verts[1], nearz); + RwIm2DVertexSetIntRGBA(&verts[1], color.red, color.green, color.blue, color.alpha); + + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, NULL); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, NULL); + + // { arg2, arg3, nearz, -1 }; + RwIm2DRenderLine(verts, 2, 0, 1); + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, texraster_state); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, vtx_alpha_state); +} + +static void Show_frame() +{ + RwRGBA color = { 0 }; + RwCamera* cam = iCameraCreate(640, 480, FALSE); + RwCameraClear(cam, &color, rwCAMERACLEARIMAGE); + + RwCameraBeginUpdate(cam); + Width_scale = 640 / Bink->unk_0; + Height_scale = 480 / Bink->unk_4; + xDrawLine2D_LocaliFMVVersion(0.0f, 0.0f, 0.0f, 0.0f); + DrawFrame(0.0f, 0.0f, Width_scale, Height_scale); + RwCameraEndUpdate(cam); + RwCameraShowRaster(cam, NULL, 0); + + iCameraDestroy(cam); +} + +static void PlayFMV(char* fname, u32 buttons, F32 time) +{ + GXCullMode cull_mode; + GXGetCullMode(&cull_mode); + iFMV::InitDisplay(_RwDlRenderMode); + iPadStopRumble(globals.pad0); + RADSetAudioMemory(arammalloc, aramfree); + RADSetMemory(iFMVmalloc, iFMVfree); + Setup_surface_array(); + + for (char* c = fname; *c != NULL; c++) + { + if (*c == '\\') + { + *c = '/'; + } + } + + tag_xFile file; + DVDFileInfo* pfinfo = &file.ps.fileInfo; + do + { + if (iTRCDisk::IsDiskIDed()) + { + Bink = BinkOpen(fname, NULL); + if (Bink == NULL) + { + BinkGetError(); + } + } + if (iTRCDisk::CheckDVDAndResetState() != 0) + { + break; + } + if (Bink == NULL) + { + iFileOpen(fname, 0, &file); + DVDSeekAsyncPrio(pfinfo, 0, NULL, 2); + if (iTRCDisk::CheckDVDAndResetState()) + { + DVDCancel(&pfinfo->cb); + break; + } + else + { + DVDCancel(&pfinfo->cb); + } + } + } while (Bink == NULL); + + if (Bink != NULL) + { + if (Bink->unk_f0 != 0) + { + for (ip = 0; ip <= Bink->unk_f0; ++ip) + { + vol = gSnd.categoryVolFader[SND_CAT_CUTSCENE]; + vol = vol * vol; + vol = vol * 32768.0f; + BinkSetVolume(Bink, ip, vol); + } + } + + Image = Open_RAD_3D_image(NULL, Bink->unk_0, Bink->unk_4, fuckingSurfaceType); + if (Image != NULL) + { + if (frame_num != 0) + { + BinkGoto(Bink, frame_num, 0); + } + oof = 0; + + do + { + if (iTRCDisk::CheckDVDAndResetState()) + { + goto superbreak; + } + if (BinkWait(Bink) == 0) + { + Decompress_frame(Bink, Image, 1); + Show_frame(); + BinkNextFrame(Bink); + } + else if (Paused) + { + Show_frame(); + } + xPadUpdate(globals.currentActivePad, 0.0f); + + F32 t = (float)Bink->unk_c / (Bink->unk_14 / Bink->unk_18); + if (buttons && t >= time && globals.pad0->pressed & buttons) + { + frame_num = -1; + goto superbreak; + } + } while (Bink->unk_c < Bink->unk_8 - 1); + frame_num = -1; + } + superbreak: + if (frame_num != -1) + { + frame_num = Bink->unk_c; + } + Close_RAD_3D_image(Image); + Image = NULL; + BinkClose(Bink); + Bink = NULL; + } + + GXSetCullMode(cull_mode); + iVSync(); + xPadUpdate(globals.currentActivePad, 0.0f); +} + +U32 iFMVPlay(char* filename, U32 buttons, F32 time, bool skippable, bool lockController) +{ + if (filename == NULL) + { + return 1; + } + + frame_num = 0; + while (frame_num >= 0) + { + PlayFMV(filename, buttons, time); + } + return 0; +} + +void _MovieFree(void* mem) +{ + RwFree(mem); +} + +void* _MovieAlloc(U32 size) +{ + return RwMalloc(size); +} + +// iFile + +struct file_queue_entry +{ + tag_xFile* file; + void* buf; + U32 size; + U32 offset; + IFILE_READSECTOR_STATUS stat; + void (*callback)(tag_xFile* file); + U32 asynckey; +}; + +extern file_queue_entry file_queue[4]; + +static U32 tbuffer[1024 + 8]; +static U32* buffer32; +volatile U32 iFileSyncAsyncReadActive; + +void iFileGetInfo(tag_xFile* file, U32* addr, U32* length) +{ + if (addr) + { + *addr = file->ps.fileInfo.startAddr; + } + + if (length) + { + *length = file->ps.fileInfo.length; + } +} + +U32 iFileFind(const char* name, S32 x, tag_xFile* file) +{ + return iFileOpen(name, 0, file); +} + +void iFileSetPath(const char* path) +{ +} + +U32 iFileGetSize(tag_xFile* file) +{ + return file->ps.fileInfo.length; +} + +U32 iFileClose(tag_xFile* file) +{ + tag_iFile* ps = &file->ps; + S32 ret; + + ret = DVDClose(&file->ps.fileInfo); + ret = DVDClose(&file->ps.fileInfo); + + if (!ret) + { + return 1; + } + + ps->flags = 0; + return 0; +} + +static void async_cb(s32 result, DVDFileInfo* fileInfo) +{ + file_queue_entry* entry = &file_queue[(S32)fileInfo->cb.userData]; + s32 r7 = DVD_RESULT_FATAL_ERROR; + + switch (result) + { + case DVD_RESULT_FATAL_ERROR: + { + xTRCDisk(TRC_DiskFatal); + return; + } + case DVD_RESULT_GOOD: + case DVD_RESULT_IGNORED: + { + if (result >= DVD_RESULT_GOOD) + { + r7 = result; + } + + break; + } + } + + if (r7 < DVD_RESULT_GOOD) + { + entry->stat = IFILE_RDSTAT_FAIL; + + if (entry->callback) + { + entry->callback(entry->file); + } + } + else if (r7 + entry->offset >= entry->size || + r7 + entry->offset + entry->file->ps.offset >= entry->file->ps.fileInfo.length) + { + entry->stat = IFILE_RDSTAT_DONE; + entry->offset = entry->size; + + if (entry->callback) + { + entry->callback(entry->file); + } + + entry->file->ps.asynckey = -1; + } + else + { + entry->offset += r7; + entry->stat = IFILE_RDSTAT_INPROG; + + s32 length; + if ((entry->size - entry->offset < 0x8000)) + { + length = ALIGN(entry->size - entry->offset, 4); + } + else + { + length = 0x10000 - 0x8000; + } + + if (length + entry->offset + entry->file->ps.offset > entry->file->ps.fileInfo.length) + { + // length = OSRoundUp32B(entry->file->ps.fileInfo.length - entry->file->ps.offset - + // entry->offset); + length = entry->file->ps.fileInfo.length; + length -= entry->file->ps.offset; + length -= entry->offset; + length = length + 32 - 1; + length = length & ~(32 - 1); + } + + void* addr = (void*)((U32)entry->buf + entry->offset); + DVDReadAsync(&entry->file->ps.fileInfo, addr, length, + entry->file->ps.offset + entry->offset, async_cb); + } +} + +S32 iFileReadAsync(tag_xFile* file, void* buf, U32 aSize, void (*callback)(tag_xFile*), + S32 priority) +{ + static S32 fopcount = 1; + tag_iFile* ps = &file->ps; + S32 i; + + for (i = 0; i < 4; i++) + { + if (file_queue[i].stat != IFILE_RDSTAT_QUEUED && file_queue[i].stat != IFILE_RDSTAT_INPROG) + { + S32 id = fopcount++ << 2; + S32 asynckey = id + i; + + file_queue[i].file = file; + file_queue[i].buf = buf; + file_queue[i].size = aSize; + file_queue[i].offset = 0; + file_queue[i].stat = IFILE_RDSTAT_QUEUED; + file_queue[i].callback = callback; + file_queue[i].asynckey = asynckey; + + aSize = (aSize < 32) ? ALIGN(aSize, 4) : 32; + + ps->fileInfo.cb.userData = (void*)i; + + DVDReadAsync(&ps->fileInfo, buf, aSize, ps->offset, async_cb); + + ps->asynckey = asynckey; + + return id + i; + } + } + + return -1; +} + +IFILE_READSECTOR_STATUS iFileReadAsyncStatus(S32 key, S32* amtToFar) +{ + if (key != file_queue[key & 0x3].asynckey) + { + return IFILE_RDSTAT_EXPIRED; + } + + if (amtToFar) + { + *amtToFar = file_queue[key & 0x3].offset; + } + + return file_queue[key & 0x3].stat; +} + +static void ifilereadCB(tag_xFile* file) +{ + iFileSyncAsyncReadActive = 0; +} + +U32 iFileRead(tag_xFile* file, void* buf, U32 size) +{ + tag_iFile* ps = &file->ps; + + iFileSeek(file, ps->offset, IFILE_SEEK_SET); + + iFileSyncAsyncReadActive = 1; + + iFileReadAsync(file, buf, size, ifilereadCB, 0); + + while (iFileSyncAsyncReadActive) + { + iTRCDisk::CheckDVDAndResetState(); + } + + return size; +} + +U32 iFileOpen(const char* name, S32 flags, tag_xFile* file) +{ + tag_iFile* ps = &file->ps; + + if (flags & IFILE_OPEN_ABSPATH) + { + strcpy(ps->path, name); + } + else + { + iFileFullPath(name, ps->path); + } + + ps->entrynum = DVDConvertPathToEntrynum(ps->path); + + if (ps->entrynum == -1) + { + return 1; + } + + if (!DVDFastOpen(ps->entrynum, &ps->fileInfo)) + { + ps->entrynum = -1; + return 1; + } + + ps->unkC4 = 0; + ps->flags = 0x1; + + iFileSeek(file, 0, IFILE_SEEK_SET); + + return 0; +} + +U32* iFileLoad(const char* name, U32* buffer, U32* size) +{ + char path[128]; + tag_xFile file; + S32 fileSize, alignedSize; + + iFileFullPath(name, path); + iFileOpen(name, IFILE_OPEN_ABSPATH, &file); + + fileSize = iFileGetSize(&file); + + if (!buffer) + { + buffer = (U32*)OSAlloc(OSRoundUp32B(fileSize)); + } + + alignedSize = OSRoundUp32B(fileSize); + + iFileRead(&file, buffer, alignedSize); + + if (size) + { + *size = alignedSize; + } + + iFileClose(&file); + + return buffer; +} + +// iEnv + +static S32 sBeginDrawFX; +static RpWorld* sPipeWorld; +static RwCamera* sPipeCamera; +static iEnv* lastEnv; + +// This is named JspPS2_ClumpRender on PS2 +static void Jsp_ClumpRender(RpClump* clump, xJSPNodeInfo* nodeInfo) +{ + S32 backcullon = 1; + S32 zbufferon = 1; + RwLLLink* cur = rwLinkListGetFirstLLLink(&clump->atomicList); + RwLLLink* end = rwLinkListGetTerminator(&clump->atomicList); + + while (cur != end) + { + RpAtomic* apAtom = rwLLLinkGetData(cur, RpAtomic, inClumpLink); + + if (RpAtomicGetFlags(apAtom) & rpATOMICRENDER) + { + RwFrame* frame = RpAtomicGetFrame(apAtom); + + if (!iModelCull(apAtom, &frame->ltm)) + { + if (backcullon) + { + if (nodeInfo->nodeFlags & 0x4) + { + backcullon = 0; + RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLNONE); + } + } + else + { + if (!(nodeInfo->nodeFlags & 0x4)) + { + backcullon = 1; + RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLBACK); + } + } + + if (zbufferon) + { + if (nodeInfo->nodeFlags & 0x2) + { + zbufferon = 0; + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE); + } + } + else + { + if (!(nodeInfo->nodeFlags & 0x2)) + { + zbufferon = 1; + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE); + } + } + + RpAtomicRender(apAtom); + } + } + + cur = rwLLLinkGetNext(cur); + nodeInfo++; + } +} + +void iEnvEndRenderFX(iEnv*) +{ + iEnv* env = lastEnv; + + if (env->fx && globalCamera && sBeginDrawFX) + { + RpWorldRemoveCamera(env->fx, globalCamera); + RpWorldAddCamera(env->world, globalCamera); + + sBeginDrawFX = 0; + } +} + +void iEnvRender(iEnv* env, bool) +{ + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + + if (env->jsp) + { + Jsp_ClumpRender(env->jsp->clump, env->jsp->jspNodeList); + } + else + { + RpWorldRender(env->world); + } + + lastEnv = env; +} + +void iEnvLightingBasics(iEnv*, xEnvAsset*) +{ +} + +void iEnvDefaultLighting(iEnv*) +{ +} + +void iEnvFree(iEnv* env) +{ + _rwFrameSyncDirty(); + + RpWorldDestroy(env->world); + env->world = NULL; + + if (env->fx) + { + RpWorldDestroy(env->fx); + env->fx = NULL; + } + + if (env->collision) + { + RpWorldDestroy(env->collision); + env->collision = NULL; + } +} + +static RpAtomic* SetPipelineCB(RpAtomic* atomic, void* data) +{ + if (RwCameraBeginUpdate(sPipeCamera)) + { + RpAtomicInstance(atomic); + RwCameraEndUpdate(sPipeCamera); + } + + if (data) + { + RpAtomicSetPipeline(atomic, (RxPipeline*)data); + } + + return atomic; +} + +// iXF / iDraw + +void iDrawEnd() +{ + return; +} + +void iDrawBegin() +{ + return; +} + +void iDrawSetFBMSK(U32 abgr) +{ + size_t tmp, hi; + + hi = abgr >> 24; + + if (hi == 0) + { + GXSetAlphaUpdate(GX_TRUE); + } + else if (hi == 255) + { + GXSetAlphaUpdate(GX_FALSE); + } + + tmp = abgr & 0x00FFFFFF; + + if (tmp == 0) + { + GXSetColorUpdate(GX_TRUE); + } + else + { + GXSetColorUpdate(GX_FALSE); + } +} + +// iCS + +U32 read_sizzze = 0; + +S32 iCSLoadStep(xCutscene* csn) +{ + S32 bytes; + XFILE_READSECTOR_STATUS cdstat; + U32 skipAccum; + U32 tmpSize; + void* foundModel; + U32 i; + + if (csn->Waiting) + { + cdstat = xFileReadAsyncStatus(csn->File.ps.asynckey, &bytes); + + if (cdstat == XFILE_RDSTAT_INPROG || cdstat == XFILE_RDSTAT_QUEUED) + { + return 0; + } + } + + if (csn->DataLoading >= 0) + { + skipAccum = 0; + + while (csn->DataLoading < (S32)csn->Info->NumData) + { + if (csn->Data[csn->DataLoading].DataType == XCUTSCENEDATA_TYPE_6) + { + foundModel = NULL; + } + else + { + foundModel = xSTFindAsset(csn->Data[csn->DataLoading].AssetID, &tmpSize); + } + + if (foundModel || csn->Data[csn->DataLoading].ChunkSize == 0) + { + csn->Data[csn->DataLoading].DataPtr = foundModel; + + skipAccum += ALIGN(csn->Data[csn->DataLoading].ChunkSize, 2048); + + csn->DataLoading++; + } + else + { + if (skipAccum) + { + iCSFileAsyncSkip(csn, skipAccum); + + skipAccum = 0; + } + + if (csn->GotData) + { + if (csn->Data[csn->DataLoading].DataType == XCUTSCENEDATA_TYPE_6) + { + csn->Data[csn->DataLoading].DataPtr = + RwMalloc(csn->Data[csn->DataLoading].ChunkSize); + + memcpy(csn->Data[csn->DataLoading].DataPtr, csn->AlignBuf, + csn->Data[csn->DataLoading].ChunkSize); + } + else + { + csn->Data[csn->DataLoading].DataPtr = + iModelFileNew(csn->AlignBuf, csn->Data[csn->DataLoading].ChunkSize); + } + + csn->Data[csn->DataLoading].DataType |= 0x80000000; + csn->DataLoading++; + csn->GotData = 0; + } + else + { + iCSFileAsyncRead(csn, csn->AlignBuf, + ALIGN(csn->Data[csn->DataLoading].ChunkSize, 2048)); + + csn->GotData = 1; + return 0; + } + } + } + + if (skipAccum) + { + iCSFileAsyncSkip(csn, skipAccum); + } + + csn->DataLoading = -1; + } + + if (csn->DataLoading == -1) + { + if (csn->GotData) + { + iCSSoundSetup(csn); + + if (csn->SndNumChannel != 0) + { + xSndPauseAll(1, 1); + xSndUpdate(); + + if (csn->SndNumChannel == 2) + { + // Stereo + + csn->SndHandle[0] = xSndPlay(csn->SndAssetID[0], 0.9f, -99999.0f, 255, 0x200, 0, + SND_CAT_CUTSCENE, 0.0f); + csn->SndHandle[1] = xSndPlay(csn->SndAssetID[1], 0.9f, -99999.0f, 255, 0x200, 0, + SND_CAT_CUTSCENE, 0.0f); + } + else + { + // Mono + + csn->SndHandle[0] = xSndPlay(csn->SndAssetID[0], 0.9f, -99999.0f, 255, 0x200, 0, + SND_CAT_CUTSCENE, 0.0f); + csn->SndHandle[1] = 0; + } + } + + csn->GotData = 0; + csn->DataLoading = -2; + } + else + { + iCSFileAsyncRead(csn, csn->Play, csn->TimeChunkOffs[1] - csn->TimeChunkOffs[0]); + + csn->GotData = 1; + return 0; + } + } + + if (csn->DataLoading == -2) + { + if (csn->Info->NumTime > 1) + { + iCSFileAsyncRead(csn, csn->Stream, csn->TimeChunkOffs[2] - csn->TimeChunkOffs[1]); + } + + csn->DataLoading = -3; + } + + for (i = 0; i < csn->SndNumChannel; i++) + { + } + + csn->Ready = 1; + return 1; +} + +void iCSFileClose(xCutscene* csn) +{ + iFileReadStop(); + + csn->Opened = 0; +} + +static void iCSAsyncReadCB(tag_xFile* file) +{ + S32 bytes; + xCutscene* csn; + + if (file) + { + if (iFileReadAsyncStatus(file->ps.asynckey, &bytes) == IFILE_RDSTAT_DONE) + { + iFileSeek(file, bytes, IFILE_SEEK_CUR); + } + + csn = xCutscene_CurrentCutscene(); + csn->Waiting = 0; + } +} + +void iCSFileAsyncRead(xCutscene* csn, void* dest, U32 size) +{ + U32* buf = (U32*)dest; + U32 i; + + read_sizzze = size; + csn->Waiting = 1; + + for (i = 0; i < size / 4; i++) + { + buf[i] = 0xDEADBEEF; + } + + iFileReadAsync(&csn->File, dest, size, iCSAsyncReadCB, 0); +} + +void* iCSSoundGetData(xSndVoiceInfo* vp, U32* size) +{ + U32 channelIndex; + U32 dataIndex; + xCutscene* csn; + void* retdata; + xCutsceneData* data; + U32 numChannel; + U32 numData; + S32 sndChannelIndex; + U32 r4; + U32 sndChannelReq; + + csn = xCutscene_CurrentCutscene(); + + numChannel = csn->SndNumChannel; + retdata = NULL; + sndChannelIndex = -1; + + for (channelIndex = 0; channelIndex < numChannel; channelIndex++) + { + if (csn->SndAssetID[channelIndex] == vp->assetID) + { + sndChannelIndex = channelIndex; + sndChannelReq = csn->SndChannelReq[channelIndex]; + } + } + + if (sndChannelIndex == -1) + { + return NULL; + } + + if (!csn->Waiting && csn->Stream->ChunkIndex == sndChannelReq) + { + numData = csn->Stream->NumData; + data = (xCutsceneData*)(csn->Stream + 1); + } + else + { + numData = csn->Play->NumData; + data = (xCutsceneData*)(csn->Play + 1); + + if (csn->SndChannelReq[sndChannelIndex] != csn->Play->ChunkIndex) + { + csn->SndChannelReq[sndChannelIndex] = csn->Play->ChunkIndex; + } + } + + r4 = 0; + + for (dataIndex = 0; dataIndex < numData; dataIndex++) + { + if (data->DataType == XCUTSCENEDATA_TYPE_SOUND) + { + if (!retdata) + { + retdata = (void*)(data + 1); + *size = data->ChunkSize; + } + + if (sndChannelIndex == r4) + { + retdata = (void*)(data + 1); + *size = data->ChunkSize; + + break; + } + else + { + r4++; + } + } + + data = (xCutsceneData*)((U8*)data + ALIGN(data->ChunkSize, 16) + sizeof(xCutsceneData)); + } + + if (!retdata) + { + return NULL; + } + + while ((U32)retdata & 0x1F) + { + retdata = (void*)((U8*)retdata + 16); + *size -= 16; + } + + csn->SndChannelReq[sndChannelIndex]++; + + return retdata; +} + +void iCSSoundSetup(xCutscene* csn) +{ + xCutsceneData* data; + U32 dataIndex; + U32 numData; + + data = (xCutsceneData*)(csn->Play + 1); + numData = csn->Play->NumData; + + for (dataIndex = 0; dataIndex < numData; dataIndex++) + { + if (data->DataType == XCUTSCENEDATA_TYPE_SOUND) + { + if (csn->SndNumChannel >= 2) + { + break; + } + + csn->SndAssetID[csn->SndNumChannel] = data->AssetID; + csn->SndNumChannel++; + } + + data = (xCutsceneData*)((U8*)data + ALIGN(data->ChunkSize, 16) + sizeof(xCutsceneData)); + } +} + +// iAsync + +// Easy file, will work on soon + +// iAnimSKB + +void iAnimEvalSKB(iAnimSKBHeader* data, F32 time, U32 flags, xVec3* tran, xQuat* quat) +{ + U32 i, tidx, bcount, tcount; + iAnimSKBKey* keys; + F32* times; + U16* offsets; + S32 asdf; // unused + F32 scalex, scaley, scalez; + + tcount = data->TimeCount; + bcount = data->BoneCount; + + keys = (iAnimSKBKey*)(data + 1); + times = (F32*)(keys + data->KeyCount); + offsets = (U16*)(times + tcount); + + if (time < 0.0f) + { + time = 0.0f; + } + + if (time > times[tcount - 1]) + { + time = times[tcount - 1]; + } + + tidx = (tcount - 1) % 4; + + while (times[tidx] < time) + { + tidx += 4; + } + + while (tidx && time <= times[tidx]) + { + tidx--; + } + + offsets += tidx * bcount; + + if (flags & 0x1) + { + bcount = 1; + } + + if (flags & 0x2) + { + bcount--; + offsets++; + } + + if (tcount == 1) + { + // non-matching: float constants are loaded outside of loop + + scalex = data->Scale[0]; + scaley = data->Scale[1]; + scalez = data->Scale[2]; + + for (i = 0; i < bcount; i++, quat++, tran++) + { + iAnimSKBKey* k = &keys[i]; + + quat->v.x = k->Quat[0] * (1.0f / SHRT_MAX); + quat->v.y = k->Quat[1] * (1.0f / SHRT_MAX); + quat->v.z = k->Quat[2] * (1.0f / SHRT_MAX); + quat->s = k->Quat[3] * (1.0f / SHRT_MAX); + + tran->x = k->Tran[0] * scalex; + tran->y = k->Tran[1] * scaley; + tran->z = k->Tran[2] * scalez; + } + } + else + { + // non-matching: float constants are loaded outside of loop + + scalex = data->Scale[0]; + scaley = data->Scale[1]; + scalez = data->Scale[2]; + + for (i = 0; i < bcount; i++, quat++, tran++) + { + // no idea if this part even functionally matches. + // come back to this when not lazy + + RtQuatSlerpCache qcache; + RtQuat q1, q2; + RwReal time1, time2, lerp; + iAnimSKBKey* k = &keys[*offsets]; + U32 costheta, theta; // unused + + offsets++; + + time1 = time - times[k->TimeIndex]; + time2 = times[k[1].TimeIndex] - times[k[0].TimeIndex]; + lerp = time1 / time2; + + q1.imag.x = k[0].Quat[0] * (1.0f / SHRT_MAX); + q1.imag.y = k[0].Quat[1] * (1.0f / SHRT_MAX); + q1.imag.z = k[0].Quat[2] * (1.0f / SHRT_MAX); + q1.real = k[0].Quat[3] * (1.0f / SHRT_MAX); + + q2.imag.x = k[1].Quat[0] * (1.0f / SHRT_MAX); + q2.imag.y = k[1].Quat[1] * (1.0f / SHRT_MAX); + q2.imag.z = k[1].Quat[2] * (1.0f / SHRT_MAX); + q2.real = k[1].Quat[3] * (1.0f / SHRT_MAX); + + RtQuatSetupSlerpCache(&q1, &q2, &qcache); + RtQuatSlerp((RtQuat*)quat, &q1, &q2, lerp, &qcache); + + tran->x = + lerp * (scalex * k[1].Tran[0] - scalex * k[0].Tran[0]) + scalex * k[0].Tran[0]; + tran->y = + lerp * (scaley * k[1].Tran[1] - scaley * k[0].Tran[1]) + scaley * k[1].Tran[1]; + tran->z = + lerp * (scalez * k[1].Tran[2] - scalez * k[0].Tran[2]) + scalez * k[1].Tran[2]; + } + } +} + +// iAnimBlend + +// non-matching: incorrect instruction order and regalloc +void iAnimBlend(F32 BlendFactor, F32 BlendRecip, U16* BlendTimeOffset, F32* BoneTable, + U32 BoneCount, xVec3* Tran1, xQuat* Quat1, xVec3* Tran2, xQuat* Quat2, + xVec3* TranDest, xQuat* QuatDest) +{ + U32 i; + U32 invert = 0; + RtQuat* q2; + RtQuat ident = { 0.0f, 0.0f, 0.0f, 1.0f }; + xVec3* t2; + + if (!Quat2) + { + q2 = &ident; + invert = 1; + t2 = (xVec3*)&ident.imag; + } + else + { + q2 = (RtQuat*)Quat2; + t2 = Tran2; + } + + if (BlendFactor < 0.0f) + { + BlendFactor = -BlendFactor; + invert ^= 1; + } + + if (!BoneTable && !BlendTimeOffset) + { + F32 lerp = BlendFactor * BlendRecip; + + if (lerp < 0.0f) + { + lerp = 0.0f; + } + else if (lerp > 1.0f) + { + lerp = 1.0f; + } + + if (invert) + { + lerp = 1.0f - lerp; + } + + if (Quat1) + { + // non-matching: 0.0f constant is loaded outside of loop + + for (i = 0; i < BoneCount; i++) + { + RtQuatSlerpCache qcache; + + RtQuatSetupSlerpCache((RtQuat*)Quat1, q2, &qcache); + RtQuatSlerp((RtQuat*)QuatDest, (RtQuat*)Quat1, q2, lerp, &qcache); + + Quat1++; + + if (Quat2) + { + q2++; + } + + QuatDest++; + } + } + + if (Tran1) + { + if (Quat2) + { + for (i = 0; i < BoneCount; i++, TranDest++, t2++, Tran1++) + { + TranDest->x = lerp * (t2->x - Tran1->x) + Tran1->x; + TranDest->y = lerp * (t2->y - Tran1->y) + Tran1->y; + TranDest->z = lerp * (t2->z - Tran1->z) + Tran1->z; + } + } + else + { + for (i = 0; i < BoneCount; i++, TranDest++, Tran1++) + { + TranDest->x = lerp * (t2->x - Tran1->x) + Tran1->x; + TranDest->y = lerp * (t2->y - Tran1->y) + Tran1->y; + TranDest->z = lerp * (t2->z - Tran1->z) + Tran1->z; + } + } + } + } + else + { + F32 baselerp; + + if (!BlendTimeOffset) + { + baselerp = BlendFactor * BlendRecip; + + if (baselerp < 0.0f) + { + baselerp = 0.0f; + } + else if (baselerp > 1.0f) + { + baselerp = 1.0f; + } + + if (invert) + { + baselerp = 1.0f - baselerp; + } + } + + for (i = 0; i < BoneCount; i++) + { + F32 lerp; + + if (BlendTimeOffset) + { + baselerp = -(1 / 1024.0f * BlendTimeOffset[i * 2] - BlendFactor); + + if (BlendTimeOffset[i * 2 + 1] != 0) + { + baselerp *= 1 / 1024.0f * BlendTimeOffset[i * 2 + 1]; + + if (baselerp < 0.0f) + { + baselerp = 0.0f; + } + else if (baselerp > 1.0f) + { + baselerp = 1.0f; + } + } + else + { + if (baselerp < 0.0f) + { + baselerp = 0.0f; + } + else + { + baselerp = 1.0f; + } + } + + if (invert) + { + baselerp = 1.0f - baselerp; + } + } + + if (BoneTable) + { + lerp = baselerp * BoneTable[i]; + } + else + { + lerp = baselerp; + } + + if (Quat1) + { + RtQuatSlerpCache qcache; + + RtQuatSetupSlerpCache((RtQuat*)Quat1, q2, &qcache); + RtQuatSlerp((RtQuat*)QuatDest, (RtQuat*)Quat1, q2, lerp, &qcache); + + Quat1++; + + if (Quat2) + { + q2++; + } + + QuatDest++; + } + + if (Tran1) + { + TranDest->x = lerp * (t2->x - Tran1->x) + Tran1->x; + TranDest->y = lerp * (t2->y - Tran1->y) + Tran1->y; + TranDest->z = lerp * (t2->z - Tran1->z) + Tran1->z; + + Tran1++; + + if (Quat2) + { + t2++; + } + + TranDest++; + } + } + } +} + +U32 iAnimBoneCount(void* RawData) +{ + if (*(U32*)RawData == '1BKS') + { + return ((iAnimSKBHeader*)RawData)->BoneCount; + } + + return 0; +} + +F32 iAnimDuration(void* RawData) +{ + return iAnimDurationSKB((iAnimSKBHeader*)RawData); +} + +void iAnimEval(void* RawData, F32 time, U32 flags, xVec3* tran, xQuat* quat) +{ + iAnimEvalSKB((iAnimSKBHeader*)RawData, time, flags, tran, quat); +} + +void iAnimInit() +{ + return; +} diff --git a/src/SB/Core/gc/iWad.h b/src/SB/Core/gc/iWad.h new file mode 100644 index 0000000..ddcc2fe --- /dev/null +++ b/src/SB/Core/gc/iWad.h @@ -0,0 +1,45 @@ +#ifndef IWAD_H +#define IWAD_H + +#include "../src/sb/game/zGlobals.h" + +#include "iAnim.h" +#include "iAnimSKB.h" +#include "iCollide.h" +#include "iCollideFast.h" +#include "iColor.h" +#include "iCutscene.h" +#include "iDraw.h" +#include "iEnv.h" +#include "iFile.h" +#include "iFMV.h" +#include "iFX.h" +#include "iLight.h" +#include "iMath.h" +#include "iMath3.h" +#include "iMemMgr.h" +#include "iMix.h" +#include "iModel.h" +#include "iMorph.h" +#include "iPad.h" +#include "iParMgr.h" +#include "isavegame.h" +#include "iScrFX.h" +#include "iSnd.h" +#include "iSystem.h" +#include "iTime.h" +#include "iTRC.h" +#include "ngcrad3d.h" +#include "xDebug.h" +#include "xPad.h" +#include "xTRC.h" +#include "stdlib.h" +#include "../include/dolphin/dvd.h" +#include "xstransvc.h" +#include +#include +#include + +void iFuncProfileFuncs(int, int, float); + +#endif diff --git a/src/SB/Core/gc/isavegame.h b/src/SB/Core/gc/isavegame.h new file mode 100644 index 0000000..e18c5d4 --- /dev/null +++ b/src/SB/Core/gc/isavegame.h @@ -0,0 +1,184 @@ +#ifndef ISAVEGAME_H +#define ISAVEGAME_H + +#include + +#include + +enum en_ISG_IOMODE +{ + ISG_IOMODE_READ = 0x1, + ISG_IOMODE_WRITE, + ISG_IOMODE_APPEND +}; + +enum en_ISGMC_ERRSTATUS +{ + ISGMC_ERR_NONE, + ISGMC_ERR_NOMEMCARD, + ISGMC_ERR_MKDIR, + ISGMC_ERR_OPEN, + ISGMC_ERR_CLOSE, + ISGMC_ERR_READ, + ISGMC_ERR_WRITE +}; + +enum en_ASYNC_OPCODE +{ + ISG_OPER_NOOP, + ISG_OPER_INIT, + ISG_OPER_SAVE, + ISG_OPER_LOAD +}; + +// This enum might be incorrect. The tooling choked on the enum values +// being 0xFFFFFFFF +enum en_ASYNC_OPSTAT +{ + ISG_OPSTAT_FAILURE = 0xFFFFFFFF, + ISG_OPSTAT_INPROG = 0, + ISG_OPSTAT_SUCCESS +}; + +enum en_ASYNC_OPERR +{ + ISG_OPERR_NONE, + ISG_OPERR_NOOPER, + ISG_OPERR_MULTIOPER, + ISG_OPERR_INITFAIL, + ISG_OPERR_GAMEDIR, + ISG_OPERR_NOCARD, + ISG_OPERR_NOROOM, + ISG_OPERR_DAMAGE, + ISG_OPERR_CORRUPT, + ISG_OPERR_OTHER, + ISG_OPERR_SVNOSPACE, + ISG_OPERR_SVINIT, + ISG_OPERR_SVWRITE, + ISG_OPERR_SVOPEN, + ISG_OPERR_LDINIT, + ISG_OPERR_LDREAD, + ISG_OPERR_LDOPEN, + ISG_OPERR_TGTERR, + ISG_OPERR_TGTREM, + ISG_OPERR_TGTPREP, + ISG_OPERR_UNKNOWN, + ISG_OPERR_NOMORE +}; + +enum en_CHGCODE +{ + ISG_CHG_NONE, + ISG_CHG_TARGET, + ISG_CHG_GAMELIST +}; + +/* DWARF Definitions (PS2) + +class st_ISG_MEMCARD_DATA { + // total size: 0x100 +public: + signed int mcport; // offset 0x0, size 0x4 + signed int mcslot; // offset 0x4, size 0x4 + signed int mcfp; // offset 0x8, size 0x4 + enum en_ISG_IOMODE fmode; // offset 0xC, size 0x4 + char gamepath[64]; // offset 0x10, size 0x40 + class sceMcTblGetDir finfo; // offset 0x80, size 0x40 + signed int cur_mcop; // offset 0xC0, size 0x4 + enum en_ISGMC_ERRSTATUS mcerr; // offset 0xC4, size 0x4 + signed int allow_cache; // offset 0xC8, size 0x4 +}; + +class st_ISGSESSION { + // total size: 0x9C +public: + class st_ISG_MEMCARD_DATA * mcdata; // offset 0x0, size 0x4 + char gameroot[64]; // offset 0x4, size 0x40 + char gamedir[64]; // offset 0x44, size 0x40 + enum en_ASYNC_OPCODE as_curop; // offset 0x84, size 0x4 + enum en_ASYNC_OPSTAT as_opstat; // offset 0x88, size 0x4 + enum en_ASYNC_OPERR as_operr; // offset 0x8C, size 0x4 + void * cltdata; // offset 0x90, size 0x4 + enum en_CHGCODE chgcode; // offset 0x94, size 0x4 + void (* chgfunc)(void *, enum en_CHGCODE); // offset 0x98, size 0x4 +}; + + +*/ + +// Size should be 0x130 +struct st_ISG_MEMCARD_DATA +{ + S32 unk_0; + S32 chan; + S32 sectorSize; + CARDFileInfo finfo; + CARDStat fstat; + S32 unk_pad5[3]; + S32 unk_98; + CARDFileInfo unk_9c; + CARDStat unk_b0; + S32 unk_pad6[4]; + S32 unk_12c; +}; + +#define ISG_NUM_SLOTS 2 +#define ISG_NUM_FILES 3 +struct st_ISGSESSION +{ + st_ISG_MEMCARD_DATA mcdata[ISG_NUM_SLOTS]; + S32 slot; + S32 unk_264; + en_ASYNC_OPERR unk_268; + en_ASYNC_OPSTAT unk_26c; + S32 unk_270; + void (*chgfunc)(void*, en_CHGCODE); // 0x274 + void* cltdata; // 0x278 + S32 unk_27c; +}; + +enum en_NAMEGEN_TYPE +{ + ISG_NGTYP_GAMEDIR, + ISG_NGTYP_GAMEFILE, + ISG_NGTYP_CONFIG, + ISG_NGTYP_ICONTHUM +}; + +S32 iSGStartup(); +S32 iSGShutdown(); +char* iSGMakeName(en_NAMEGEN_TYPE type, const char* base, S32 idx); +st_ISGSESSION* iSGSessionBegin(void* cltdata, void (*chgfunc)(void*, en_CHGCODE), S32 monitor); +void iSGSessionEnd(st_ISGSESSION* isgdata); +S32 iSGTgtCount(st_ISGSESSION* isgdata, S32* max); +S32 iSGTgtPhysSlotIdx(st_ISGSESSION* isgdata, S32 tidx); +U32 iSGTgtState(st_ISGSESSION* isgdata, S32 tgtidx, const char* dpath); +S32 iSGTgtFormat(st_ISGSESSION* isgdata, S32 tgtidx, S32 async, S32* canRecover); +S32 iSGTgtSetActive(st_ISGSESSION* isgdata, S32 tgtidx); +S32 iSGTgtHaveRoom(st_ISGSESSION* isgdata, S32 tidx, S32 fsize, const char* dpath, + const char* fname, S32* bytesNeeded, S32* availOnDisk, S32* needFile); +S32 iSGTgtHaveRoomStartup(st_ISGSESSION* isgdata, S32 tidx, S32 fsize, const char* dpath, + const char* fname, S32* bytesNeeded, S32* availOnDisk, S32* needFile); +U8 iSGCheckMemoryCard(st_ISGSESSION* isgdata, S32 index); +S32 iSGFileSize(st_ISGSESSION* isgdata, const char* fname); +char* iSGFileModDate(st_ISGSESSION* isgdata, const char* fname); +char* iSGFileModDate(st_ISGSESSION* isgdata, const char* fname, S32* sec, S32* min, S32* hr, + S32* mon, S32* day, S32* yr); +en_ASYNC_OPSTAT iSGPollStatus(st_ISGSESSION* isgdata, en_ASYNC_OPCODE* curop, S32 block); +en_ASYNC_OPERR iSGOpError(st_ISGSESSION* isgdata, char* errmsg); +S32 iSGReadLeader(st_ISGSESSION* isgdata, const char* fname, char* databuf, S32 numbytes, + S32 async); +S32 iSGSelectGameDir(st_ISGSESSION* isgdata, const char* dname); +void iSGMakeTimeStamp(char* str); +S32 iSGSetupGameDir(st_ISGSESSION* isgdata, const char* dname, S32 force_iconfix); +S32 iSGSaveFile(st_ISGSESSION* isgdata, const char* fname, char* data, S32 n, S32 async, char*); +S32 iSGLoadFile(st_ISGSESSION* isgdata, const char* fname, char* databuf, S32 async); +S32 iSG_mcidx2slot(S32 param1, S32* out_slot, S32* param3); +void iSGAutoSave_Startup(); +st_ISGSESSION* iSGAutoSave_Connect(S32 idx_target, void* cltdata, void (*chg)(void*, en_CHGCODE)); +void iSGAutoSave_Disconnect(st_ISGSESSION* isg); +S32 iSGAutoSave_Monitor(st_ISGSESSION* isg, S32 idx_target); +S32 iSGCheckForWrongDevice(); +S32 iSGCheckForCorruptFiles(st_ISGSESSION*, char files[][64]); + +#endif diff --git a/src/SB/Core/gc/ngcrad3d.h b/src/SB/Core/gc/ngcrad3d.h new file mode 100644 index 0000000..a43ea9d --- /dev/null +++ b/src/SB/Core/gc/ngcrad3d.h @@ -0,0 +1,4 @@ +#ifndef NGCRAD3D_H +#define NGCRAD3D_H + +#endif diff --git a/src/SB/Core/x/containers.h b/src/SB/Core/x/containers.h new file mode 100644 index 0000000..05b894a --- /dev/null +++ b/src/SB/Core/x/containers.h @@ -0,0 +1,57 @@ +#ifndef CONTAINERS_H +#define CONTAINERS_H + +#include + +struct tier_queue_allocator +{ + struct block_data + { + U8 prev; + U8 next; + U16 flags; + void* data; + }; + + block_data* blocks; + U32 _unit_size; + U32 _block_size; + U32 _block_size_shift; + U32 _max_blocks; + U32 _max_blocks_shift; + U8 head; +}; + +template struct tier_queue +{ + U32 first; + U32 _size; + U32 wrap_mask; + tier_queue_allocator* alloc; + U8 blocks[256]; +}; + +template struct static_queue +{ + U32 _first; + U32 _size; + U32 _max_size; + U32 _max_size_mask; + T* _buffer; + void clear(); +}; + +template struct fixed_queue +{ + U32 _first; + U32 _last; + T _buffer[N + 1]; + + void reset(); + void push_front(const T& element); + bool full() const; + void pop_back(); + bool empty() const; +}; + +#endif diff --git a/src/SB/Core/x/iCamera.h b/src/SB/Core/x/iCamera.h new file mode 100644 index 0000000..7a701db --- /dev/null +++ b/src/SB/Core/x/iCamera.h @@ -0,0 +1,39 @@ +#ifndef ICAMERA_H +#define ICAMERA_H + +#include +#include + +#include "xMath3.h" +#include "iEnv.h" +#include "iTime.h" + +struct iFogParams +{ + RwFogType type; + F32 start; + F32 stop; + F32 density; + RwRGBA fogcolor; + RwRGBA bgcolor; + U8* table; +}; + +extern RwCamera* globalCamera; + +RwCamera* iCameraCreate(S32 width, S32 height, S32 mainGameCamera); +void iCameraDestroy(RwCamera* camera); +void iCameraBegin(RwCamera* cam, S32 clear); +void iCameraEnd(RwCamera* cam); +void iCameraShowRaster(RwCamera* cam); +void iCameraFrustumPlanes(RwCamera* cam, xVec4* frustplane); +void iCameraUpdatePos(RwCamera* cam, xMat4x3* pos); +void iCameraSetFOV(RwCamera* cam, F32 fov); +void iCameraAssignEnv(RwCamera* camera, iEnv* env_geom); +void iCamGetViewMatrix(RwCamera* camera, xMat4x3* view_matrix); +void iCameraSetNearFarClip(F32 nearPlane, F32 farPlane); +void iCameraSetFogParams(iFogParams* fp, F32 time); +void iCameraUpdateFog(RwCamera* cam, iTime t); +void iCameraSetFogRenderStates(); + +#endif diff --git a/src/SB/Core/x/xAnim.h b/src/SB/Core/x/xAnim.h new file mode 100644 index 0000000..d9a5823 --- /dev/null +++ b/src/SB/Core/x/xAnim.h @@ -0,0 +1,229 @@ +#ifndef XANIM_H +#define XANIM_H + +#include + +#include "xMath3.h" +#include "xMemMgr.h" + +typedef struct xAnimState; +typedef struct xAnimTransition; +typedef struct xAnimTransitionList; +typedef struct xAnimEffect; +typedef struct xAnimActiveEffect; +typedef struct xAnimSingle; +typedef struct xAnimPlay; + +extern U32 gxAnimUseGrowAlloc; + +struct xAnimFile +{ + xAnimFile* Next; + const char* Name; + U32 ID; + U32 FileFlags; + + // 0x10 + F32 Duration; + F32 TimeOffset; + U16 BoneCount; + U8 NumAnims[2]; + + // 0x20 + void** RawData; +}; + +struct xAnimMultiFileEntry +{ + U32 ID; + xAnimFile* File; +}; + +struct xAnimMultiFileBase +{ + U32 Count; +}; + +struct xAnimMultiFile : xAnimMultiFileBase +{ + xAnimMultiFileEntry Files[1]; +}; + +typedef void (*xAnimStateBeforeEnterCallback)(xAnimPlay*, xAnimState*); +typedef void (*xAnimStateCallback)(xAnimState*, xAnimSingle*, void*); +typedef void (*xAnimStateBeforeAnimMatricesCallback)(xAnimPlay*, xQuat*, xVec3*, S32); + +struct xAnimState +{ + xAnimState* Next; + const char* Name; + U32 ID; + U32 Flags; + + // 0x10 + U32 UserFlags; + F32 Speed; + xAnimFile* Data; + xAnimEffect* Effects; + + // 0x20 + xAnimTransitionList* Default; + xAnimTransitionList* List; + F32* BoneBlend; + F32* TimeSnap; + + // 0x30 + F32 FadeRecip; + U16* FadeOffset; + void* CallbackData; + xAnimMultiFile* MultiFile; + + // 0x40 + xAnimStateBeforeEnterCallback BeforeEnter; + xAnimStateCallback StateCallback; + xAnimStateBeforeAnimMatricesCallback BeforeAnimMatrices; +}; + +typedef U32 (*xAnimTransitionConditionalCallback)(xAnimTransition*, xAnimSingle*, void*); +typedef U32 (*xAnimTransitionCallback)(xAnimTransition*, xAnimSingle*, void*); + +struct xAnimTransition +{ + xAnimTransition* Next; + xAnimState* Dest; + xAnimTransitionConditionalCallback Conditional; + xAnimTransitionCallback Callback; + U32 Flags; + U32 UserFlags; + F32 SrcTime; // 0x18 + F32 DestTime; // 0x1C + U16 Priority; + U16 QueuePriority; + F32 BlendRecip; // 0x24 + U16* BlendOffset; +}; + +struct xAnimTransitionList +{ + xAnimTransitionList* Next; + xAnimTransition* T; +}; + +struct xAnimTable +{ + xAnimTable* Next; // 0x0 + const char* Name; // 0x4 + xAnimTransition* TransitionList; // 0x8 + xAnimState* StateList; + U32 AnimIndex; + U32 MorphIndex; + U32 UserFlags; +}; + +typedef U32 (*xAnimEffectCallback)(U32, xAnimActiveEffect*, xAnimSingle*, void*); + +struct xAnimEffect +{ + xAnimEffect* Next; + U32 Flags; + F32 StartTime; + F32 EndTime; + xAnimEffectCallback Callback; +}; + +struct xAnimActiveEffect +{ + xAnimEffect* Effect; + U32 Handle; +}; + +struct xAnimSingle +{ + U32 SingleFlags; + xAnimState* State; + F32 Time; + F32 CurrentSpeed; + + // Offset: 0x10 + F32 BilinearLerp[2]; + xAnimEffect* Effect; + U32 ActiveCount; + + // Offset: 0x20 + F32 LastTime; + xAnimActiveEffect* ActiveList; + xAnimPlay* Play; + xAnimTransition* Sync; + + // Offset: 0x30 + xAnimTransition* Tran; + xAnimSingle* Blend; + F32 BlendFactor; + U32 pad; +}; + +typedef struct xModelInstance; + +struct xAnimPlay +{ + xAnimPlay* Next; + U16 NumSingle; // 0x4 + U16 BoneCount; // 0x6 + xAnimSingle* Single; // 0x8 + void* Object; // 0xC + xAnimTable* Table; // 0x10 + xMemPool* Pool; + xModelInstance* ModelInst; + void (*BeforeAnimMatrices)(xAnimPlay*, xQuat*, xVec3*, S32); +}; + +class AnimTableList { // size: 0xC +public: + char * name; // offset 0x0, size 0x4 + class xAnimTable * (* constructor)(); // offset 0x4, size 0x4 + unsigned int id; // offset 0x8, size 0x4 +}; + +void xAnimInit(); +void xAnimTempTransitionInit(U32 count); +xAnimFile* xAnimFileNew(void* rawData, const char* name, U32 flags, xAnimFile** linkedList); +xAnimTable* xAnimTableNew(const char* name, xAnimTable** linkedList, U32 userFlags); +xAnimState* xAnimTableNewState(xAnimTable* table, const char* name, U32 flags, U32 userFlags, + F32 speed, F32* boneBlend, F32* timeSnap, F32 fadeRecip, + U16* fadeOffset, void* callbackData, + xAnimStateBeforeEnterCallback beforeEnter, + xAnimStateCallback stateCallback, + xAnimStateBeforeAnimMatricesCallback beforeAnimMatrices); +xAnimTransition* xAnimTableNewTransition(xAnimTable* table, const char* source, const char* dest, + xAnimTransitionConditionalCallback conditional, + xAnimTransitionCallback callback, U32 flags, U32 userFlags, + F32 srcTime, F32 destTime, U16 priority, U16 queuePriority, + F32 blendRecip, U16* blendOffset); +void xAnimDefaultBeforeEnter(xAnimPlay* play, xAnimState* state); +void xAnimPoolInit(xMemPool* pool, U32 count, U32 singles, U32 blendFlags, U32 effectMax); +xAnimPlay* xAnimPoolAlloc(xMemPool* pool, void* object, xAnimTable* table, + xModelInstance* modelInst); +void xAnimPoolFree(xAnimPlay*); +xAnimState* xAnimTableGetState(xAnimTable* table, const char* name); +void xAnimTableAddTransition(xAnimTable* table, xAnimTransition* tran, const char* source); +void xAnimTableAddFile(xAnimTable* table, xAnimFile* file, const char* states); +xAnimState* xAnimTableAddFileID(xAnimTable* table, xAnimFile* file, U32 stateID, U32 subStateID, + U32 subStateCount); +xAnimState* xAnimTableGetStateID(xAnimTable* table, U32 ID); +void xAnimPlaySetState(xAnimSingle* single, xAnimState* state, F32 startTime); +void xAnimPlayChooseTransition(xAnimPlay* play); +void xAnimPlayStartTransition(xAnimPlay* play, xAnimTransition* transition); +void xAnimPlayUpdate(xAnimPlay* play, F32 timeDelta); +void xAnimPlayEval(xAnimPlay* play); + +inline F32 xAnimFileRawTime(xAnimFile* data, float time) +{ + if (data->FileFlags & 0x1000 || (data->FileFlags & 0x2000 && time > data->Duration * 0.5f)) + { + return data->TimeOffset + data->Duration - time; + } + return data->TimeOffset + time; +} + + +#endif diff --git a/src/SB/Core/x/xBase.h b/src/SB/Core/x/xBase.h new file mode 100644 index 0000000..a6f3269 --- /dev/null +++ b/src/SB/Core/x/xBase.h @@ -0,0 +1,42 @@ +#ifndef XBASE_H +#define XBASE_H + +#include "xLinkAsset.h" +#include "xserializer.h" + +// Size: 0x8 +struct xBaseAsset +{ + U32 id; + U8 baseType; + U8 linkCount; + U16 baseFlags; +}; + +struct xBase; + +typedef S32 (*xBaseEventCB)(xBase*, xBase*, U32, const F32*, xBase*); + +// Size: 0x10 +struct xBase +{ + U32 id; + U8 baseType; // see en_ZBASETYPE in zBase.h + U8 linkCount; + U16 baseFlags; + xLinkAsset* link; + xBaseEventCB eventFunc; // 0xC +}; + +void xBaseInit(xBase* xb, xBaseAsset* asset); +void xBaseSetup(xBase* xb); +void xBaseSave(xBase* ent, xSerial* s); +void xBaseLoad(xBase* ent, xSerial* s); +void xBaseReset(xBase* xb, xBaseAsset* asset); +U32 xBaseIsValid(xBase* xb); +void xBaseValidate(xBase* xb); +bool xBaseIsEnabled(const xBase* xb); +void xBaseDisable(xBase* xb); +void xBaseEnable(xBase* xb); + +#endif diff --git a/src/SB/Core/x/xBehaveGoalSimple.h b/src/SB/Core/x/xBehaveGoalSimple.h new file mode 100644 index 0000000..350a6e2 --- /dev/null +++ b/src/SB/Core/x/xBehaveGoalSimple.h @@ -0,0 +1,58 @@ +#ifndef XBEHAVEGOALSIMPLE_H +#define XBEHAVEGOALSIMPLE_H + +#include "xFactory.h" +#include "xRMemData.h" +#include "xBehaviour.h" + +struct xGoalEmpty : xGoal +{ + xGoalEmpty(S32 goalID) : xGoal(goalID) + { + } + + virtual const char* Name() + { + return "xGoalEmpty"; + } + + virtual void Clear() + { + } +}; + +struct xGoalGeneric : xGoal +{ + S32 (*fun_enter)(xGoal*, void*, F32, void*); + S32 (*fun_exit)(xGoal*, void*, F32, void*); + S32 (*fun_suspend)(xGoal*, void*, F32, void*); + S32 (*fun_resume)(xGoal*, void*, F32, void*); + S32 (*fun_sysevent)(xGoal*, void*, xBase*, xBase*, U32, const F32*, xBase*, S32*); + void* usrData; + + xGoalGeneric(S32 goalID) : xGoal(goalID) + { + } + + virtual const char* Name() + { + return "xGoalGeneric"; + } + + virtual void Clear() + { + } + + virtual S32 Enter(F32 dt, void* updCtxt); + virtual S32 Exit(F32 dt, void* updCtxt); + virtual S32 Suspend(F32 dt, void* updCtxt); + virtual S32 Resume(F32 dt, void* updCtxt); + virtual S32 SysEvent(xBase* from, xBase* to, U32 toEvent, const F32* toParam, + xBase* toParamWidget, S32* handled); +}; + +void xGoalSimple_RegisterTypes(xFactory* fac); +xFactoryInst* GOALCreate_Generic(S32 who, RyzMemGrow* growCtxt, void* dat); +void GOALDestroy_Generic(xFactoryInst* item); + +#endif diff --git a/src/SB/Core/x/xBehaveMgr.h b/src/SB/Core/x/xBehaveMgr.h new file mode 100644 index 0000000..c58dfd8 --- /dev/null +++ b/src/SB/Core/x/xBehaveMgr.h @@ -0,0 +1,40 @@ +#ifndef XBEHAVEMGR_H +#define XBEHAVEMGR_H + +#include "xBase.h" +#include "xBehaviour.h" +#include "xordarray.h" +#include "xFactory.h" + +struct xBehaveMgr : RyzMemData +{ + xFactory* goalFactory; + xPsyche* psypool; + st_XORDEREDARRAY psylist; + + xBehaveMgr() + { + } + + ~xBehaveMgr() + { + } + + void Startup(S32, S32); + void RegBuiltIn(); + xPsyche* Subscribe(xBase* owner, S32 i); + void UnSubscribe(xPsyche* psy); + void ScenePrepare(); + void SceneFinish(); + void SceneReset(); + xFactory* GetFactory(); +}; + +void xBehaveMgr_ScenePrepare(); +void xBehaveMgr_SceneReset(); +void xBehaveMgr_Startup(); +void xBehaveMgr_Shutdown(); +void xBehaveMgr_SceneFinish(); +xBehaveMgr* xBehaveMgr_GetSelf(); + +#endif diff --git a/src/SB/Core/x/xBehaviour.h b/src/SB/Core/x/xBehaviour.h index 9ea9513..0d23c90 100644 --- a/src/SB/Core/x/xBehaviour.h +++ b/src/SB/Core/x/xBehaviour.h @@ -1,29 +1,23 @@ #ifndef XBEHAVIOUR_H #define XBEHAVIOUR_H -#include "xEnt.h" +#include "xBase.h" +#include "xListItem.h" +#include "xFactory.h" +#include "xScene.h" -enum PSY_BRAIN_STATUS -{ - PSY_STAT_BLANK, - PSY_STAT_GROW, - PSY_STAT_EXTEND, - PSY_STAT_THINK, - PSY_STAT_NOMORE, - PSY_STAT_FORCE = 0x7fffffff -}; - -enum en_pendtype +enum en_GOALSTATE { - PEND_TRAN_NONE, - PEND_TRAN_SET, - PEND_TRAN_PUSH, - PEND_TRAN_POP, - PEND_TRAN_POPTO, - PEND_TRAN_POPALL, - PEND_TRAN_SWAP, - PEND_TRAN_INPROG, - PEND_TRAN_NOMORE + GOAL_STAT_UNKNOWN, + GOAL_STAT_PROCESS, + GOAL_STAT_ENTER, + GOAL_STAT_EXIT, + GOAL_STAT_SUSPEND, + GOAL_STAT_RESUME, + GOAL_STAT_PAUSED, + GOAL_STAT_DONE, + GOAL_STAT_NOMORE, + GOAL_STAT_FORCE = 0x7fffffff }; enum en_trantype @@ -41,162 +35,50 @@ enum en_trantype GOAL_TRAN_FORCE = 0x7fffffff }; -enum en_GOALSTATE +enum en_pendtype { - GOAL_STAT_UNKNOWN, - GOAL_STAT_PROCESS, - GOAL_STAT_ENTER, - GOAL_STAT_EXIT, - GOAL_STAT_SUSPEND, - GOAL_STAT_RESUME, - GOAL_STAT_PAUSED, - GOAL_STAT_DONE, - GOAL_STAT_NOMORE, - GOAL_STAT_FORCE = 0x7fffffff + PEND_TRAN_NONE, + PEND_TRAN_SET, + PEND_TRAN_PUSH, + PEND_TRAN_POP, + PEND_TRAN_POPTO, + PEND_TRAN_POPALL, + PEND_TRAN_SWAP, + PEND_TRAN_INPROG, + PEND_TRAN_NOMORE }; -enum en_npcgol +enum PSY_BRAIN_STATUS { - NME_GOAL_UNKNOWN, - NME_GOAL_CRIT_IDLE = 0x4e474300, - NME_GOAL_CRIT_PATROL, - NME_GOAL_CRIT_DYING, - NME_GOAL_CRIT_DEAD, - NME_GOAL_CRIT_BATTACK, - NME_GOAL_CRIT_JATTACK, - NME_GOAL_CRIT_JDYING, - NME_GOAL_TURR_IDLE = 0x4e474700, - NME_GOAL_TURR_RELOAD, - NME_GOAL_TURR_HURT, - NME_GOAL_TURR_DEAD, - NME_GOAL_TURR_TREADY, - NME_GOAL_TURR_TTURN, - NME_GOAL_TURR_TSHOOT, - NME_GOAL_TURR_PDORMANT, - NME_GOAL_TURR_PALERT, - NME_GOAL_TURR_PPATALPHA, - NME_GOAL_TURR_BIDLE, - NME_GOAL_TURR_BTURN, - NME_GOAL_TURR_BSHOOT, - NME_GOAL_TURR_BHURT, - NME_GOAL_TURR_SPIRAL, - NME_GOAL_IDLE = 0x4e474e00, - NME_GOAL_PATROL, - NME_GOAL_WANDER, - NME_GOAL_FIDGET, - NME_GOAL_WAITING, - NME_GOAL_DEAD, - NME_GOAL_NOMANLAND, - NME_GOAL_LIMBO, - NME_GOAL_DEV_ANIMVIEW = 0x4e474400, - NME_GOAL_DEV_HEROMODE, - NME_GOAL_TIKI_IDLE = 0x4e475400, - NME_GOAL_TIKI_PATROL, - NME_GOAL_TIKI_HIDE, - NME_GOAL_TIKI_COUNT, - NME_GOAL_TIKI_DYING, - NME_GOAL_TIKI_DEAD, - NME_GOAL_AFTERLIFE = 0x4e475300, - NME_GOAL_SPAWN, - NME_GOAL_WOUND, - NME_GOAL_SPOOKED, - NME_GOAL_NOTICE, - NME_GOAL_SCAREWAIT, - NME_GOAL_SCARE, - NME_GOAL_TAUNT, - NME_GOAL_EVILPAT = 0x4e475000, - NME_GOAL_STUNNED, - NME_GOAL_PATCARRY, - NME_GOAL_PATTWIRL, - NME_GOAL_PATTHROW, - NME_GOAL_TRIGGER_NORMAL = 0x4e475800, - NME_GOAL_TRIGGER_SCARY, - NME_GOAL_TRIGGER_DETECT, - NME_GOAL_TRIGGER_ALERT, - NME_GOAL_TRIGGER_BATTLE, - NME_GOAL_TRIGGER_WOUND, - NME_GOAL_TRIGGER_ATTACK, - NME_GOAL_TRIGGER_VINIVICIVIDI, - NME_GOAL_FOGGER_AWARE = 0x4e474500, - NME_GOAL_FOGGER_BATTLE, - NME_GOAL_FOGGER_ATTACK, - NME_GOAL_SLAMMER_AWARE, - NME_GOAL_SLAMMER_BATTLE, - NME_GOAL_SLAMMER_ATTACK, - NME_GOAL_SPINNER_AWARE, - NME_GOAL_SPINNER_BATTLE, - NME_GOAL_FLINGER_NORMAL, - NME_GOAL_FLINGER_AWARE, - NME_GOAL_FLINGER_BATTLE, - NME_GOAL_FLINGER_ATTACK, - NME_GOAL_FLINGER_BOING, - NME_GOAL_FLINGER_FLEE, - NME_GOAL_FLINGER_PANIC, - NME_GOAL_FLINGER_MOVE, - NME_GOAL_POPPER_NORMAL, - NME_GOAL_POPPER_AWARE, - NME_GOAL_POPPER_WOUND, - NME_GOAL_POPPER_EVADE, - NME_GOAL_POPPER_BATTLE, - NME_GOAL_POPPER_ATTACK, - NME_GOAL_ZAP_NORMAL, - NME_GOAL_ZAP_AWARE, - NME_GOAL_ZAP_BATTLE, - NME_GOAL_ZAP_WOUND, - NME_GOAL_ZAP_ZAP, - NME_GOAL_ZAP_MOVE, - NME_GOAL_MERV_NORMAL, - NME_GOAL_MERV_AWARE, - NME_GOAL_MERV_BATTLE, - NME_GOAL_MERV_ZAP, - NME_GOAL_MERV_BOMB, - NME_GOAL_MERV_BOWL, - NME_GOAL_MERV_WOUND, - NME_GOAL_MERV_MOVE, - NME_GOAL_BUCK_RUNNING, - NME_GOAL_BUCK_BIRTHING, - NME_GOAL_BUCK_DYING, - NME_GOAL_BUCK_DEAD, - NME_GOAL_DENNIS_NORMAL, - NME_GOAL_DENNIS_EVADE, - NME_GOAL_DENNIS_BATTLE, - NME_GOAL_DENNIS_ATTACK, - NME_GOAL_DENNIS_TAUNT, - NME_GOAL_DENNIS_DAMAGE, - NME_GOAL_DENNIS_DEAD, - NME_GOAL_DENTOO_NORMAL, - NME_GOAL_DENTOO_EVADE, - NME_GOAL_DENTOO_BATTLE, - NME_GOAL_DENTOO_ATTACK, - NME_GOAL_DENTOO_TAUNT, - NME_GOAL_DENTOO_DAMAGE, - NME_GOAL_DENTOO_DEAD, - NME_GOAL_SBBAT_IDLE, - NME_GOAL_SBBAT_DEAD, - NME_GOAL_NOMORE, - NME_GOAL_FORCE = 0x7fffffff + PSY_STAT_BLANK, + PSY_STAT_GROW, + PSY_STAT_EXTEND, + PSY_STAT_THINK, + PSY_STAT_NOMORE, + PSY_STAT_FORCE = 0x7fffffff }; -enum en_npcgspot +enum en_psynote { - NME_GSPOT_START = 0x20, - NME_GSPOT_RESUME, - NME_GSPOT_LOOP, - NME_GSPOT_FINISH, - NME_GSPOT_STARTALT, - NME_GSPOT_ALTA, - NME_GSPOT_ALTB, - NME_GSPOT_PATROLPAUSE, - NME_GSPOT_NEXT, - NME_GSPOT_NOMORE, - NME_GSPOT_FORCEINT = 0x7fffffff + PSY_NOTE_HASRESUMED, + PSY_NOTE_HASENTERED, + PSY_NOTE_ANIMCHANGED, + PSY_NOTE_NOMORE, + PSY_NOTE_FORCE = 0x7fffffff }; +struct xGoal; + struct xPSYNote { + virtual void Notice(en_psynote note, xGoal* goal, void*) + { + } }; -struct xGoal; +typedef S32 (*xGoalProcessCallback)(xGoal*, void*, en_trantype*, F32, void*); +typedef S32 (*xGoalChkRuleCallback)(xGoal*, void*, en_trantype*, F32, void*); +typedef S32 (*xGoalPreCalcCallback)(xGoal*, void*, F32, void*); struct xPsyche : RyzMemData { @@ -215,54 +97,134 @@ struct xPsyche : RyzMemData S32 cnt_transLastTimestep; PSY_BRAIN_STATUS psystat; xBase fakebase; -}; -struct xListItem_1 -{ - S32 flg_travFilter; - xGoal* next; - xGoal* prev; + xGoal* GIDInStack(S32 gid) const; + void ImmTranOn(); + void ImmTranOff(); + S32 ImmTranIsOn(); + S32 HasGoal(S32 goal); + xGoal* GetCurGoal() const; + S32 GIDOfActive() const; + S32 GIDOfPending() const; + S32 GIDOfSafety() const + { + return gid_safegoal; + } + S32 Timestep(F32 dt, void* updCtxt); + xGoal* FindGoal(S32 gid); + S32 GoalSet(S32 gid, S32 r5); + S32 GoalPop(S32 gid_popto, S32 r5); + S32 GoalNone(S32 denyExplicit); + S32 GoalSwap(S32 gid, S32 r5); + S32 GoalPopRecover(S32 overpend); + S32 GoalPopToBase(S32 overpend); + S32 GoalPush(S32 gid, S32 r5); + S32 GoalSet(S32 gid); + + void BrainBegin(); + void BrainExtend(); + void BrainEnd(); + xGoal* AddGoal(S32 gid, void* createData); + void FreshWipe(); + void SetOwner(xBase*, void*); + void KillBrain(xFactory*); + void Lobotomy(xFactory*); + void SetSafety(S32 goalID) + { + gid_safegoal = goalID; + } + void Amnesia(S32); + void SetNotify(xPSYNote* notice) + { + cb_notice = notice; + } + + xBase* GetClient() + { + return this->clt_owner; + } }; -struct xGoal : xListItem_1, xFactoryInst +struct xGoal : xListItem, xFactoryInst { - xPsyche* psyche; //0x18 + + xPsyche* psyche; // 0x18 + S32 goalID; en_GOALSTATE stat; - S32 flg_able; //0x20 - S32 (*fun_process)(xGoal*, void*, en_trantype*, F32, void*); + S32 flg_able; // 0x24 + xGoalProcessCallback fun_process; + xGoalPreCalcCallback fun_precalc; + xGoalChkRuleCallback fun_chkRule; + void* cbdata; - S32 Exit(); - S32 Suspend(); - S32 SysEvent(); - S32 Enter(); - S32 Resume(); - S32 Process(en_trantype* trantype, F32 dt, void* updCtxt); -}; + xGoal(S32 goalID) + { + this->goalID = goalID; + this->flg_able = 0; + this->stat = GOAL_STAT_UNKNOWN; + } -struct zNMEGoalCommon : xGoal -{ - U32 anid_played; - struct + S32 GetID() const + { + return this->goalID; + } + + void SetFlags(S32 flags) + { + flg_able = flags; + } + void AddFlags(S32 flags); + xPsyche* GetPsyche() const; + void SetCallbacks(xGoalProcessCallback process, xGoalChkRuleCallback chkRule, + xGoalPreCalcCallback precalc, void* cbdata); + S32 GetFlags() const + { + return flg_able; + } + + void SetPsyche(xPsyche* psyche); + const char* Name(); + void SetState(en_GOALSTATE state); + en_GOALSTATE GetState() const; + xBase* GetOwner() const; + + // vtable + virtual void Clear() = 0; + + virtual S32 Enter(F32 dt, void* updCtxt) + { + + return 0; + } + + virtual S32 Exit(F32 dt, void* updCtxt) { - S32 flg_npcgauto : 8; - S32 flg_npcgable : 16; - S32 bul_entered : 1; - S32 bul_resumed : 1; - S32 bul_unused : 6; - } flags; - struct + return 0; + } + + virtual S32 Suspend(F32 dt, void* updCtxt) + { + return 0; + } + + virtual S32 Resume(F32 dt, void* updCtxt) + { + return 0; + } + + virtual S32 PreCalc(F32 dt, void* updCtxt); + virtual S32 EvalRules(en_trantype* trantype, F32 dt, void* updCtxt); + virtual S32 Process(en_trantype* trantype, float dt, void* ctxt, xScene* scene); + + virtual S32 SysEvent(xBase* from, xBase* to, U32 toEvent, const F32* toParam, + xBase* toParamWidget, S32* handled) { - S32 flg_info : 16; - S32 flg_user : 16; - }; + return 1; + } - S32 CollReview(); - S32 GoalHandleMail(); - void Clear(); - S32 Enter(); - S32 Resume(); - S32 Process(en_trantype* trantyp, F32 dt, void* ctxt); +protected: + ~xGoal(); // prevents implicit destructors from being generated in subclasses of xGoal }; #endif diff --git a/src/SB/Core/x/xBound.h b/src/SB/Core/x/xBound.h new file mode 100644 index 0000000..e6a3416 --- /dev/null +++ b/src/SB/Core/x/xBound.h @@ -0,0 +1,52 @@ +#ifndef XBOUND_H +#define XBOUND_H + +#include "xQuickCull.h" +#include "xMath3.h" +#include "xCollide.h" + +// Size: 0x4C +struct xBound +{ + xQCData qcd; + + U8 type; // Offset: 0x20 (or 0x84) + U8 pad[3]; + union + { + xSphere sph; + xBBox box; + xCylinder cyl; + }; + xMat4x3* mat; +}; + +#define XBOUND_TYPE_NA 0 // None/invalid +#define XBOUND_TYPE_SPHERE 1 // Sphere - xBound::sph +#define XBOUND_TYPE_BOX 2 // Axis aligned bounding box - xBound::box +#define XBOUND_TYPE_CYL 3 // Cylinder - xBound::cyl (unused?) +#define XBOUND_TYPE_OBB 4 // Oriented bounding box - xBound::box and xBound::mat + +void xBoundGetBox(xBox& box, const xBound& bound); +void xBoundDraw(const xBound* bound); +void xQuickCullForBound(xQCData* qc, const xBound* bound); +xVec3* xBoundCenter(xBound* bound); +const xVec3* xBoundCenter(const xBound* bound); +void xBoundUpdate(xBound* b); +void xBoundHitsBound(const xBound* a, const xBound* b, xCollis* c); +void xRayHitsBound(const xRay3* r, const xBound* b, xCollis* c); +void xSphereHitsBound(const xSphere* o, const xBound* b, xCollis* c); +void xVecHitsBound(const xVec3* v, const xBound* b, xCollis* c); +F32 xsqrt(F32 x); + +inline xVec3* xBoundCenter(xBound* bound) +{ + return &bound->sph.center; +} + +inline const xVec3* xBoundCenter(const xBound* bound) +{ + return &bound->sph.center; +} + +#endif diff --git a/src/SB/Core/x/xCM.h b/src/SB/Core/x/xCM.h new file mode 100644 index 0000000..e0ceb58 --- /dev/null +++ b/src/SB/Core/x/xCM.h @@ -0,0 +1,97 @@ +#ifndef XCM_H +#define XCM_H + +#include +#include "xColor.h" +#include "xBase.h" + +struct xCreditsData +{ + U32 dummy; +}; + +class xCMheader +{ + // total size: 0x18 +public: + unsigned int magic; // offset 0x0, size 0x4 + unsigned int version; // offset 0x4, size 0x4 + unsigned int crdID; // offset 0x8, size 0x4 + unsigned int state; // offset 0xC, size 0x4 + float total_time; // offset 0x10, size 0x4 + unsigned int total_size; // offset 0x14, size 0x4 +}; + +class sxy +{ + // total size: 0x8 +public: + float x; // offset 0x0, size 0x4 + float y; // offset 0x4, size 0x4 +}; + +class fade +{ + // total size: 0x8 +public: + float start; // offset 0x0, size 0x4 + float end; // offset 0x4, size 0x4 +}; + +class xCMtextbox +{ + // total size: 0x20 +public: + unsigned int font; // offset 0x0, size 0x4 + class iColor_tag color; // offset 0x4, size 0x4 + class sxy char_size; // offset 0x8, size 0x8 + class sxy char_spacing; // offset 0x10, size 0x8 + class sxy box; // offset 0x18, size 0x8 +}; + +class xCMpreset +{ + // total size: 0x4C +public: + unsigned short num; // offset 0x0, size 0x2 + unsigned short align; // offset 0x2, size 0x2 + float delay; // offset 0x4, size 0x4 + float innerspace; // offset 0x8, size 0x4 + class xCMtextbox box[2]; // offset 0xC, size 0x40 +}; + +class xCMhunk +{ + // total size: 0x18 +public: + unsigned int hunk_size; // offset 0x0, size 0x4 + unsigned int preset; // offset 0x4, size 0x4 + float t0; // offset 0x8, size 0x4 + float t1; // offset 0xC, size 0x4 + char * text1; // offset 0x10, size 0x4 + char * text2; // offset 0x14, size 0x4 +}; + +class xCMcredits +{ + // total size: 0x38 +public: + unsigned int credits_size; // offset 0x0, size 0x4 + float len; // offset 0x4, size 0x4 + unsigned int flags; // offset 0x8, size 0x4 + sxy in; // offset 0xC, size 0x8 + sxy out; // offset 0x14, size 0x8 + float scroll_rate; // offset 0x1C, size 0x4 + float lifetime; // offset 0x20, size 0x4 + fade fin; // offset 0x24, size 0x8 + fade fout; // offset 0x2C, size 0x8 + unsigned int num_presets; // offset 0x34, size 0x4 +}; + +void xCMupdate(F32 dt); +void xCMrender(); +void xCMrender(F32 time, xCreditsData* data); +void xCMstart(xCreditsData* data, F32, xBase* parent); +void xCMstop(); + +#endif diff --git a/src/SB/Core/x/xCamera.h b/src/SB/Core/x/xCamera.h new file mode 100644 index 0000000..cc609bc --- /dev/null +++ b/src/SB/Core/x/xCamera.h @@ -0,0 +1,236 @@ +#ifndef XCAMERA_H +#define XCAMERA_H + +#include "iCamera.h" + +#include "xBase.h" +#include "xMath3.h" +#include "xBound.h" +#include "xMath2.h" + +#include + +struct xScene; + +enum _tagTransType +{ + eTransType_None, + eTransType_Interp1, + eTransType_Interp2, + eTransType_Interp3, + eTransType_Interp4, + eTransType_Linear, + eTransType_Interp1Rev, + eTransType_Interp2Rev, + eTransType_Interp3Rev, + eTransType_Interp4Rev, + eTransType_Total +}; + +struct _tagxCamFollowAsset +{ + F32 rotation; + F32 distance; + F32 height; + F32 rubber_band; + F32 start_speed; + F32 end_speed; +}; + +struct _tagxCamShoulderAsset +{ + F32 distance; + F32 height; + F32 realign_speed; + F32 realign_delay; +}; + +struct _tagp2CamStaticAsset +{ + U32 unused; +}; + +struct _tagxCamPathAsset +{ + U32 assetID; + F32 time_end; + F32 time_delay; +}; + +struct _tagp2CamStaticFollowAsset +{ + F32 rubber_band; +}; + +struct xCamAsset : xBaseAsset +{ + xVec3 pos; + xVec3 at; + xVec3 up; + xVec3 right; + xVec3 view_offset; + S16 offset_start_frames; + S16 offset_end_frames; + F32 fov; + F32 trans_time; + _tagTransType trans_type; + U32 flags; + F32 fade_up; + F32 fade_down; + union + { + _tagxCamFollowAsset cam_follow; + _tagxCamShoulderAsset cam_shoulder; + _tagp2CamStaticAsset cam_static; + _tagxCamPathAsset cam_path; + _tagp2CamStaticFollowAsset cam_staticFollow; + }; + U32 valid_flags; + U32 markerid[2]; + U8 cam_type; + U8 pad[3]; +}; + +struct xCamera : xBase +{ + RwCamera* lo_cam; + // Offset: 0x14 + xMat4x3 mat; + // Offset: 0x54 + xMat4x3 omat; + xMat3x3 mbasis; + xBound bound; + xMat4x3* tgt_mat; + xMat4x3* tgt_omat; + xBound* tgt_bound; + xVec3 focus; + xScene* sc; + xVec3 tran_accum; + F32 fov; + U32 flags; + F32 tmr; + F32 tm_acc; + F32 tm_dec; + F32 ltmr; + F32 ltm_acc; + F32 ltm_dec; + F32 dmin; + F32 dmax; + F32 dcur; + F32 dgoal; + F32 hmin; + F32 hmax; + F32 hcur; + F32 hgoal; + F32 pmin; + F32 pmax; + F32 pcur; + F32 pgoal; + F32 depv; + F32 hepv; + F32 pepv; + F32 orn_epv; + F32 yaw_epv; + F32 pitch_epv; + F32 roll_epv; + xQuat orn_cur; + xQuat orn_goal; + xQuat orn_diff; + F32 yaw_cur; + F32 yaw_goal; + F32 pitch_cur; + F32 pitch_goal; + F32 roll_cur; + F32 roll_goal; + F32 dct; + F32 dcd; + F32 dccv; + F32 dcsv; + F32 hct; + F32 hcd; + F32 hccv; + F32 hcsv; + F32 pct; + F32 pcd; + F32 pccv; + F32 pcsv; + F32 orn_ct; + F32 orn_cd; + F32 orn_ccv; + F32 orn_csv; + F32 yaw_ct; + F32 yaw_cd; + F32 yaw_ccv; + F32 yaw_csv; + F32 pitch_ct; + F32 pitch_cd; + F32 pitch_ccv; + F32 pitch_csv; + F32 roll_ct; + F32 roll_cd; + F32 roll_ccv; + F32 roll_csv; + xVec4 frustplane[12]; +}; + +struct xBinaryCamera +{ + struct zone_data + { + F32 distance; + F32 height; + F32 height_focus; + }; + + struct config + { + zone_data zone_rest; + zone_data zone_above; + zone_data zone_below; + F32 move_speed; + F32 turn_speed; + F32 stick_speed; + F32 stick_yaw_vel; + F32 max_yaw_vel; + F32 margin_angle; + }; + + config cfg; + xCamera* camera; + xQuat cam_dir; + xVec3* s1; + xVec3* s2; + F32 s2_radius; + xVec2 stick_offset; + + void init(); + void start(xCamera& camera); + void stop(); + void update(F32 dt); + void add_tweaks(char const*); + void set_targets(xVec3 const& par_1, xVec3 const& par_2, F32 par_3); + void render_debug(); +}; + +F32 xVec3Length(const xVec3* vec); +void xCameraInit(xCamera* cam, U32 width, U32 height); +void xCameraSetScene(xCamera* cam, xScene* sc); +void xCameraReset(xCamera* cam, F32 d, F32 h, F32 pitch); +void xCameraExit(xCamera* cam); +void xCameraUpdate(xCamera* cam, F32 dt); +void xCameraBegin(xCamera* cam, S32); +void xCameraEnd(xCamera* cam, F32 seconds, S32 update_scrn_fx); +void xCameraShowRaster(xCamera* cam); +F32 xCameraGetFOV(const xCamera* cam); +void xCameraSetFOV(xCamera* cam, F32 fov); +void xCameraMove(xCamera* cam, U32 flags, F32 dgoal, F32 hgoal, F32 pgoal, + F32 tm, F32 tm_acc, F32 tm_dec); +void xCameraMove(xCamera* cam, const xVec3& loc); +void xCameraRotate(xCamera* cam, const xMat3x3& m, F32 time, F32 accel, F32 decl); +F32 xCameraGetFOV(const xCamera* cam); +void xCameraDoCollisions(S32 do_collis, S32 owner); +void xCameraSetTargetMatrix(xCamera* cam, xMat4x3* mat); +void xCameraFXShake(F32 maxTime, F32 magnitude, F32 cycleMax, F32 rotate_magnitude, + F32 radius, xVec3* epicenter, xVec3* player); + +#endif diff --git a/src/SB/Core/x/xClimate.h b/src/SB/Core/x/xClimate.h new file mode 100644 index 0000000..868dd93 --- /dev/null +++ b/src/SB/Core/x/xClimate.h @@ -0,0 +1,41 @@ +#ifndef XCLIMATE_H +#define XCLIMATE_H + +#include +#include "xVec3.h" + +struct xEnvAsset; +struct zParEmitter; + +extern const float snow_life; + +struct _tagRain +{ + S32 rain; + F32 strength; + zParEmitter* rain_emitter; + zParEmitter* snow_emitter; +}; + +struct _tagWind +{ + F32 strength; + F32 angle; + xVec3 dir; +}; + +struct _tagClimate +{ + _tagRain rain; + _tagWind wind; +}; + +void xClimateUpdate(_tagClimate* climate, F32 seconds); +void UpdateRain(_tagClimate* climate, F32 seconds); +void UpdateWind(_tagClimate* climate, F32 seconds); +void xClimateSetRain(F32 stre); +void xClimateSetSnow(F32 stre); +void xClimateInitAsset(_tagClimate* climate, xEnvAsset* easset); +void xClimateInit(_tagClimate* climate); + +#endif diff --git a/src/SB/Core/x/xClumpColl.h b/src/SB/Core/x/xClumpColl.h index 48f66f6..982d7be 100644 --- a/src/SB/Core/x/xClumpColl.h +++ b/src/SB/Core/x/xClumpColl.h @@ -2,7 +2,7 @@ #define XCLUMPCOLL_H #include -#include + #include #include @@ -20,30 +20,46 @@ struct xClumpCollBSPVertInfo U16 meshVertIndex; }; -struct _class_26 +struct xClumpCollBSPTriangle { union { xClumpCollBSPVertInfo i; - U32 rawIdx; RwV3d* p; - }; -}; - -struct xClumpCollBSPTriangle -{ - _class_26 v; + } v; U8 flags; - U8 detailed_info_cache_index; + U8 platData; U16 matIndex; }; struct xClumpCollBSPTree { - S32 numBranchNodes; + U32 numBranchNodes; xClumpCollBSPBranchNode* branchNodes; - S32 numTriangles; + U32 numTriangles; xClumpCollBSPTriangle* triangles; }; +struct nodeInfo +{ + U32 type; + U32 index; +}; +struct RwMeshCache +{ + U32 lengthOfMeshesArray; + RwResEntry* meshes[1]; +}; + +struct TempAtomicList +{ + RpAtomic* atomic; + RpGeometry* geom; + RpMeshHeader* meshHeader; + RwMeshCache* meshCache; +}; + +void xClumpColl_InstancePointers(xClumpCollBSPTree* tree, RpClump* clump); +xClumpCollBSPTree* xClumpColl_StaticBufferInit(void* data, U32 param_2); + #endif diff --git a/src/SB/Core/x/xCollide.h b/src/SB/Core/x/xCollide.h new file mode 100644 index 0000000..c42bc32 --- /dev/null +++ b/src/SB/Core/x/xCollide.h @@ -0,0 +1,138 @@ +#ifndef XCOLLIDE_H +#define XCOLLIDE_H + +#include "xEnv.h" +#include "xModel.h" +#include "xQuickCull.h" +#include "iMath3.h" + +struct xModelInstance; + +struct xCollis +{ + struct tri_data + { + U32 index; + F32 r; + F32 d; + + tri_data& operator=(const tri_data& o) + { + index = o.index; + r = o.r; + d = o.d; + return *this; + }; + }; + + U32 flags; + U32 oid; + void* optr; + xModelInstance* mptr; + F32 dist; // 0x10 + xVec3 norm; + xVec3 tohit; + xVec3 depen; + xVec3 hdng; + union + { + struct + { + F32 t; + F32 u; + F32 v; + } tuv; + tri_data tri; + }; +}; + +struct xParabola +{ + xVec3 initPos; + xVec3 initVel; + F32 gravity; + F32 minTime; + F32 maxTime; +}; + +// Size: 0x144 +struct xSweptSphere +{ + xVec3 start; + xVec3 end; + F32 radius; + F32 dist; + // Offset: 0x20 + xiMat4x3Union basis; + xiMat4x3Union invbasis; + // Offset: 0xa0 + xBox box; + // Offset: 0xb8 + xQCData qcd; + // Offset: 0xd8 + F32 boxsize; + F32 curdist; + // Offset: 0xe0 + xVec3 contact; + xVec3 polynorm; + U32 oid; + void* optr; + // Offset: 0x100 + xModelInstance* mptr; + S32 hitIt; + xVec3 worldPos; + xVec3 worldContact; + // Offset: 0x120 + xVec3 worldNormal; + // Offset: 0x12c + xVec3 worldTangent; + // Offset: 0x138 + xVec3 worldPolynorm; +}; + +enum _xCollsIdx +{ + k_XCOLLS_IDX_FLOOR, + k_XCOLLS_IDX_CEIL, + k_XCOLLS_IDX_FRONT, + k_XCOLLS_IDX_LEFT, + k_XCOLLS_IDX_REAR, + k_XCOLLS_IDX_RIGHT, + k_XCOLLS_IDX_COUNT +}; + +struct xScene; + +void xCollideInit(xScene* sc); +S32 xSweptSphereToBox(xSweptSphere* sws, xBox* box, xMat4x3* mat); +S32 xSweptSphereToModel(xSweptSphere* sws, RpAtomic* model, RwMatrix* mat); +S32 xSweptSphereToScene(xSweptSphere* sws, xScene* sc, xEnt* mover, U8 collType); +void xSweptSpherePrepare(xSweptSphere* sws, xVec3* start, xVec3* end, F32 radius); +void xSweptSphereGetResults(xSweptSphere* sws); +U32 xSphereHitsOBB_nu(const xSphere* s, const xBox* b, const xMat4x3* m, xCollis* coll); +U32 xSphereHitsSphere(const xSphere* a, const xSphere* b, xCollis* coll); +U32 xSphereHitsBox(const xSphere* a, const xBox* b, xCollis* coll); +U32 xBoxHitsSphere(const xBox* a, const xSphere* b, xCollis* coll); +U32 xBoxHitsObb(const xBox* a, const xBox* b, const xMat4x3* mat, xCollis* coll); +bool xSphereHitsOBB(const xSphere&, const xBox&, const xMat4x3&); +bool xSphereHitsSphere(const xVec3&, F32, const xVec3&, F32); +bool xSphereHitsVCylinder(const xVec3& sc, F32 sr, const xVec3& cc, F32 cr, F32 ch); +bool xSphereHitsVCircle(const xSphere& s, const xVec3& c, F32 r); +bool xSphereHitsVCircle(const xVec3& sc, F32 sr, const xVec3& cc, F32 cr); +U32 xSphereHitsModel(const xSphere* b, const xModelInstance* m, xCollis* coll); + +S32 xParabolaHitsEnv(xParabola* p, const xEnv* env, xCollis* colls); +void xParabolaEvalPos(const xParabola*, xVec3*, F32); +void xParabolaEvalVel(const xParabola*, xVec3*, F32); + +void xVec3AddScaled(xVec3*, const xVec3*, F32); +xVec3 xCollisTriHit(const xCollis::tri_data& tri, const xModelInstance& model); +bool xModelAnimCollDirty(const xModelInstance& cm); +void xModelAnimCollRefresh(const xModelInstance& cm); + +inline bool xSphereHitsVCircle(const xSphere& s, const xVec3& c, F32 r) +{ + return xSphereHitsVCircle(s.center, s.r, c, r); +} + +#endif diff --git a/src/SB/Core/x/xCollideFast.h b/src/SB/Core/x/xCollideFast.h new file mode 100644 index 0000000..46867a6 --- /dev/null +++ b/src/SB/Core/x/xCollideFast.h @@ -0,0 +1,12 @@ +#ifndef XCOLLIDEFAST_H +#define XCOLLIDEFAST_H + +#include "xMath3.h" +#include "xRay3.h" +#include "xScene.h" + +void xCollideFastInit(xScene* sc); +U32 xRayHitsSphereFast(const xRay3* r, const xSphere* s); +U32 xRayHitsBoxFast(const xRay3* r, const xBox* b); + +#endif diff --git a/src/SB/Core/x/xCollis.h b/src/SB/Core/x/xCollis.h deleted file mode 100644 index de753d0..0000000 --- a/src/SB/Core/x/xCollis.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef XCOLLIS_H -#define XCOLLIS_H -#include "xModel.h" - -struct tri_data_0 -{ - U32 index; - F32 r; - F32 d; -}; - -struct _class_8 -{ - F32 t; - F32 u; - F32 v; -}; - -struct xCollis -{ - U32 flags; - U32 oid; - void* optr; - xModelInstance* mptr; - F32 dist; - F32 test_dist; - xVec3 norm; - xVec3 tohit; - xVec3 depen; - xVec3 hdng; - union - { - _class_8 tuv; - tri_data_0 tri; - }; -}; - -struct anim_coll_data -{ -}; - -#endif diff --git a/src/SB/Core/x/xColor.h b/src/SB/Core/x/xColor.h new file mode 100644 index 0000000..fcd3ef1 --- /dev/null +++ b/src/SB/Core/x/xColor.h @@ -0,0 +1,23 @@ +#ifndef XCOLOR_H +#define XCOLOR_H + +#include "iColor.h" + +extern const iColor_tag g_RED; +extern const iColor_tag g_GREEN; +extern const iColor_tag g_BLUE; +extern const iColor_tag g_CYAN; +extern const iColor_tag g_YELLOW; +extern const iColor_tag g_WHITE; +extern const iColor_tag g_GRAY50; +extern const iColor_tag g_NEON_RED; +extern const iColor_tag g_NEON_GREEN; +extern const iColor_tag g_NEON_BLUE; +extern const iColor_tag g_PIMP_GOLD; +extern const iColor_tag g_ORANGE; +extern const iColor_tag g_LAVENDER; +extern const iColor_tag g_PINK; + +iColor_tag xColorFromRGBA(U8 r, U8 g, U8 b, U8 a); + +#endif diff --git a/src/SB/Core/x/xCounter.h b/src/SB/Core/x/xCounter.h new file mode 100644 index 0000000..9cf2764 --- /dev/null +++ b/src/SB/Core/x/xCounter.h @@ -0,0 +1,29 @@ +#ifndef XCOUNTER_H +#define XCOUNTER_H + +#include "xBase.h" + +struct xCounterAsset : xBaseAsset +{ + S16 count; +}; + +struct _xCounter : xBase +{ + xCounterAsset* asset; + S16 count; + U8 state; + U8 counterFlags; +}; + +#define XCOUNTER_ISSPATULA 0x1 + +void xCounterInit(); +void xCounterInit(void* b, void* asset); +void xCounterInit(xBase* b, xCounterAsset* asset); +void xCounterReset(xBase* b); +void xCounterSave(_xCounter* ent, xSerial* s); +void xCounterLoad(_xCounter* ent, xSerial* s); +int xCounterEventCB(xBase*, xBase* to, U32 toEvent, const F32*, xBase*); + +#endif diff --git a/src/SB/Core/x/xCurveAsset.h b/src/SB/Core/x/xCurveAsset.h new file mode 100644 index 0000000..045ae42 --- /dev/null +++ b/src/SB/Core/x/xCurveAsset.h @@ -0,0 +1,29 @@ +#ifndef XCURVEASSET_H +#define XCURVEASSET_H + +#include + +enum xCurveType +{ + xCVT_BAKED +}; + +enum xCurveClamp +{ + xCC_CONSTANT, + xCC_CYCLE, + xCC_OSCILLATE +}; + +struct xCurveAsset +{ + xCurveType type; + xCurveClamp clamp; + F32 delta; + S32 numPoints; + F32* points; +}; + +F32 xCurveAssetEvaluate(const xCurveAsset* curve_asset, F32 t); + +#endif diff --git a/src/SB/Core/x/xCutscene.h b/src/SB/Core/x/xCutscene.h new file mode 100644 index 0000000..3dac4c6 --- /dev/null +++ b/src/SB/Core/x/xCutscene.h @@ -0,0 +1,108 @@ +#ifndef XCUTSCENE_H +#define XCUTSCENE_H + +#include "xFile.h" + +struct xCutsceneInfo +{ + U32 Magic; + U32 AssetID; + U32 NumData; + U32 NumTime; + U32 MaxModel; + U32 MaxBufEven; + U32 MaxBufOdd; + U32 HeaderSize; + U32 VisCount; + U32 VisSize; + U32 BreakCount; + U32 pad; + char SoundLeft[16]; + char SoundRight[16]; +}; + +struct xCutsceneData +{ + U32 DataType; + U32 AssetID; + U32 ChunkSize; + union + { + U32 FileOffset; + void* DataPtr; + }; +}; + +#define XCUTSCENEDATA_TYPE_SOUND 5 +#define XCUTSCENEDATA_TYPE_6 6 + +struct xCutsceneBreak +{ + F32 Time; + S32 Index; +}; + +struct xCutsceneTime +{ + F32 StartTime; + F32 EndTime; + U32 NumData; + U32 ChunkIndex; +}; + +struct XCSNNosey +{ + void* userdata; + S32 flg_nosey; +}; + +struct xCutscene +{ + xCutsceneInfo* Info; + xCutsceneData* Data; + U32* TimeChunkOffs; + U32* Visibility; + xCutsceneBreak* BreakList; + xCutsceneTime* Play; + xCutsceneTime* Stream; + U32 Waiting; + U32 BadReadPause; + F32 BadReadSpeed; + void* RawBuf; + void* AlignBuf; + F32 Time; + F32 CamTime; + U32 PlayIndex; + U32 Ready; + S32 DataLoading; + U32 GotData; + U32 ShutDownWait; + F32 PlaybackSpeed; + U32 Opened; + tag_xFile File; + S32 AsyncID; + void* MemBuf; + void* MemCurr; + U32 SndStarted; + U32 SndNumChannel; + U32 SndChannelReq[2]; + U32 SndAssetID[2]; + U32 SndHandle[2]; + XCSNNosey* cb_nosey; + void NoseySet(XCSNNosey* nosey); +}; + +struct xEnt; + +extern U32 gFrameCount; + +void xCutscene_Init(void* toc); +xCutscene* xCutscene_CurrentCutscene(); +void xCutscene_Render(xCutscene* csn, xEnt**, S32*, F32*); +U32 iCSFileOpen(xCutscene* csn); +xCutscene* xCutscene_Create(U32 id); +S32 xCutscene_Destroy(xCutscene* csn); +S32 xCutscene_LoadStart(xCutscene* csn); +S32 xCutscene_Update(xCutscene* csn, F32 dt); + +#endif diff --git a/src/SB/Core/x/xCutsceneMgr.h b/src/SB/Core/x/xCutsceneMgr.h new file mode 100644 index 0000000..7b287f8 --- /dev/null +++ b/src/SB/Core/x/xCutsceneMgr.h @@ -0,0 +1,40 @@ +#ifndef XCUTSCENEMGR_H +#define XCUTSCENEMGR_H + +#include "xBase.h" +#include "xCutscene.h" + +struct xCutsceneMgrAsset : xBaseAsset +{ + U32 cutsceneAssetID; + U32 flags; + F32 interpSpeed; + F32 startTime[15]; + F32 endTime[15]; + U32 emitID[15]; +}; + +struct xCutsceneZbuffer +{ + F32 start; + F32 end; + F32 nearPlane; + F32 farPlane; +}; + +struct xCutsceneZbufferHack +{ + char* name; + xCutsceneZbuffer times[4]; +}; + +struct xCutsceneMgr : xBase +{ + xCutsceneMgrAsset* tasset; + xCutscene* csn; // 0x14 + U32 stop; // 0x18 + xCutsceneZbufferHack* zhack; + F32 oldfov; +}; + +#endif diff --git a/src/SB/Core/x/xDebug.h b/src/SB/Core/x/xDebug.h new file mode 100644 index 0000000..d9ca11d --- /dev/null +++ b/src/SB/Core/x/xDebug.h @@ -0,0 +1,105 @@ +#ifndef XDEBUG_H +#define XDEBUG_H + +#include "xFont.h" + +#include + +extern U32 gFrameCount; + +struct uint_data +{ + U32 value_def; + U32 value_min; + U32 value_max; +}; + +struct float_data +{ + F32 value_def; + F32 value_min; + F32 value_max; +}; + +struct bool_data +{ + U8 value_def; +}; + +struct select_data +{ + U32 value_def; + U32 labels_size; + char** labels; + void* values; +}; + +struct flag_data +{ + U32 value_def; + U32 mask; +}; + +struct raw_data +{ + U8 pad[16]; +}; + +struct int_data +{ + S32 value_def; + S32 value_min; + S32 value_max; +}; + +struct tweak_callback; +struct tweak_info +{ + substr name; + void* value; + tweak_callback* cb; + void* context; + U8 type; + U8 value_size; + U16 flags; + union + { + int_data int_context; + uint_data uint_context; + float_data float_context; + bool_data bool_context; + select_data select_context; + flag_data flag_context; + raw_data all_context; + }; +}; + +struct tweak_callback +{ + void (*on_change)(tweak_info&); + void (*on_select)(tweak_info&); + void (*on_unselect)(tweak_info&); + void (*on_start_edit)(tweak_info&); + void (*on_stop_edit)(tweak_info&); + void (*on_expand)(tweak_info&); + void (*on_collapse)(tweak_info&); + void (*on_update)(tweak_info&); + void (*convert_mem_to_tweak)(tweak_info&, void*); + void (*convert_tweak_to_mem)(tweak_info&, void*); +}; + +void xprintf(const char* msg, ...); +S32 xDebugModeAdd(char* mode, void(*debugFunc)); +void xDebugInit(); +void xDebugUpdate(); +void xDebugExit(); +void xDebugTimestampScreen(); + +void xDebugAddTweak(const char*, F32*, F32, F32, const tweak_callback*, void*, U32); +void xDebugRemoveTweak(const char*); +void xDebugUpdate(); + +F32 NSCREENY(F32 scale); +F32 NSCREENX(F32 scale); + +#endif diff --git a/src/SB/Core/x/xDecal.h b/src/SB/Core/x/xDecal.h new file mode 100644 index 0000000..958d5c3 --- /dev/null +++ b/src/SB/Core/x/xDecal.h @@ -0,0 +1,84 @@ +#ifndef XDECAL_H +#define XDECAL_H + +#include "xMath2.h" +#include "xMath3.h" +#include "containers.h" +#include "iColor.h" + +#include +#include + +struct xDecalEmitter +{ + enum texture_mode + { + TM_DEFAULT, + TM_RANDOM, + TM_CYCLE, + MAX_TM, + FORCE_INT_TM = 0xffffffff + }; + + struct config + { + U32 flags; + F32 life_time; + U32 blend_src; + U32 blend_dst; + struct + { + xVec2 uv[2]; + U8 rows; + U8 cols; + texture_mode mode; + } texture; + }; + + struct unit_data + { + U8 flags; + U8 curve_index; + U8 u; + U8 v; + F32 frac; + F32 age; + F32 cull_size; + xMat4x3 mat; + }; + + struct curve_node + { + F32 time; + iColor_tag color; + F32 scale; + }; + + config cfg; + struct + { + RwTexture* asset; + U32 units; + xVec2 size; + xVec2 isize; + S32 prev; + } texture; + static_queue units; + curve_node* curve; + U32 curve_size; + U32 curve_index; + F32 ilife; + + void set_curve(const curve_node* curve, size_t size); + void refresh_config(); + void set_texture(const char* name); + void set_default_config(); + void init(S32 max_size, const char*); +}; + +void xDecalInit(); +void xDecalUpdate(F32 dt); +void xDecalDestroy(); +void xDecalRender(); + +#endif diff --git a/src/SB/Core/x/xDraw.h b/src/SB/Core/x/xDraw.h new file mode 100644 index 0000000..6e91c87 --- /dev/null +++ b/src/SB/Core/x/xDraw.h @@ -0,0 +1,12 @@ +#ifndef XDRAW_H +#define XDRAW_H + +#include "iColor.h" +#include "xMath3.h" + +void xDrawSetColor(iColor_tag); +void xDrawSphere2(const xSphere*, U32); +void xDrawOBB(const xBox*, const xMat4x3*); +void xDrawBox(const xBox*); + +#endif diff --git a/src/SB/Core/x/xDynAsset.h b/src/SB/Core/x/xDynAsset.h new file mode 100644 index 0000000..2aae649 --- /dev/null +++ b/src/SB/Core/x/xDynAsset.h @@ -0,0 +1,13 @@ +#ifndef XDYNASSET_H +#define XDYNASSET_H + +#include "xBase.h" + +struct xDynAsset : xBaseAsset +{ + U32 type; + U16 version; + U16 handle; +}; + +#endif diff --git a/src/SB/Core/x/xEnt.cpp b/src/SB/Core/x/xEnt.cpp new file mode 100644 index 0000000..903687a --- /dev/null +++ b/src/SB/Core/x/xEnt.cpp @@ -0,0 +1,1979 @@ +#include "xEnt.h" + +#include "xEvent.h" +#include "xString.h" +#include "xGroup.h" +#include "xstransvc.h" +#include "xFX.h" +#include "xShadow.h" +#include "xMathInlines.h" +#include "xMath.h" + +#include "zBase.h" +#include "zPlatform.h" +#include "zEntDestructObj.h" +#include "zCollGeom.h" +#include "zSurface.h" +#include "zLight.h" +#include "zGrid.h" + +#include "iMath3.h" +#include "iCollide.h" +#include "iModel.h" +#include "iMath.h" + +#include + +static F32 nsn_angle = DEG2RAD(30); +static F32 sEntityTimePassed; +static xBox all_ents_box; +static S32 all_ents_box_init; + +namespace +{ + namespace anim_coll + { + void reset(xEnt& ent) + { + if (!ent.anim_coll) + { + ent.anim_coll = (xEnt::anim_coll_data*)xMemAllocSize(sizeof(xEnt::anim_coll_data)); + ent.anim_coll->flags = 0; + ent.anim_coll->verts = NULL; + } + + xModelInstance& model = *ent.model; + xMat4x3& mat = *(xMat4x3*)model.Mat; + xEnt::anim_coll_data& ac = *ent.anim_coll; + + if (!(ac.flags & 0x8)) + { + switch (model.BoneCount) + { + case 1: + { + ac.flags |= 0x1; + ac.old_mat = mat; + ac.new_mat = g_I3; + break; + } + case 0: + { + break; + } + default: + { + ac.flags |= 0x2; + ac.old_mat = mat; + ac.new_mat = g_I3; + + xModelAnimCollStart(model); + + xBox& box = ent.bound.box.box; + xVec3 size = box.upper - box.lower; + F32 max_size = size.x; + + if (max_size < size.y) + { + max_size = size.y; + } + + if (max_size < size.z) + { + max_size = size.z; + } + + max_size += 1.0f; + + box.upper += max_size; + box.lower -= max_size; + + model.Data->boundingSphere.radius *= 3.0f; + } + } + } + } + + void refresh(xEnt& ent) + { + xEnt::anim_coll_data& ac = *ent.anim_coll; + xMat4x3& bone_mat = *(xMat4x3*)(ent.model->Mat + 1); + + xMat4x3Mul((xMat4x3*)ent.model->Mat, &bone_mat, &ac.old_mat); + + ac.new_mat = bone_mat; + bone_mat = g_I3; + } + + void pre_move(xEnt& ent); + void post_move(xEnt& ent); + } // namespace anim_coll +} // namespace + +void xEntSetTimePassed(F32 sec) +{ + sEntityTimePassed = sec; +} + +void xEntSceneInit() +{ + all_ents_box_init = 1; +} + +void xEntSceneExit() +{ +} + +void xEntAddHittableFlag(xEnt* ent) +{ + if (ent->baseType == eBaseTypeNPC || ent->baseType == eBaseTypeDestructObj || + ent->baseType == eBaseTypeButton || ent->baseType == eBaseTypeBoulder || + (ent->baseType == eBaseTypePlatform && ent->subType == ZPLATFORM_SUBTYPE_PADDLE)) + { + ent->moreFlags |= 0x10; + } + else + { + for (U32 i = 0; i < ent->linkCount; i++) + { + if (ent->link[i].srcEvent == eEventHit || ent->link[i].srcEvent == eEventHit_Cruise || + ent->link[i].srcEvent == eEventHit_Melee || + ent->link[i].srcEvent == eEventHit_BubbleBounce || + ent->link[i].srcEvent == eEventHit_BubbleBash || + ent->link[i].srcEvent == eEventHit_BubbleBowl || + ent->link[i].srcEvent == eEventHit_PatrickSlam || + ent->link[i].srcEvent == eEventHit_Throw || + ent->link[i].srcEvent == eEventHit_PaddleLeft || + ent->link[i].srcEvent == eEventHit_PaddleRight) + { + ent->moreFlags |= 0x10; + break; + } + } + } +} + +static const char* __deadstripped() +{ + return ""; +} + +static void hack_receive_shadow(xEnt* ent) +{ + static U32 receive_models[15] = { + xStrHash("db03_path_a"), xStrHash("db03_path_b"), xStrHash("db03_path_c"), + xStrHash("db03_path_d"), xStrHash("db03_path_e"), xStrHash("db03_path_f"), + xStrHash("db03_path_g"), xStrHash("db03_path_h"), xStrHash("db03_path_i"), + xStrHash("db03_path_j"), xStrHash("db03_path_k"), xStrHash("db03_path_l"), + xStrHash("db03_path_m"), // No db03_path_n, odd + xStrHash("db03_path_o"), xStrHash("db03_path_p"), + }; + + U32* end = receive_models + sizeof(receive_models) / sizeof(U32); + U32* cur = receive_models; + + while (cur != end) + { + if (ent->asset->modelInfoID == *cur) + { + ent->baseFlags |= 0x10; + ent->asset->baseFlags |= 0x10; + break; + } + + cur++; + } +} + +static const char* __deadstripped2() +{ + return "%s.DFF\0" + "%s.SKA\0" + "ent-table\0" + "idle\0" + "anim-file\0" + "anim-table"; +} + +static void xEntAddShadowRecFlag(xEnt* ent) +{ + switch (ent->baseType - 6) + { + case eBaseTypeUnknown: + case eBaseTypeEnv: + case eBaseTypePendulum: + case eBaseTypeVFX: + case eBaseTypeLight: + case eBaseTypeEGenerator: + { + if (ent->model->PipeFlags & 0x0000ff00) + { + ent->baseFlags &= 0xffef; + } + break; + } + case eBaseTypeTrigger: + case eBaseTypeVillain: + case eBaseTypePlayer: + case eBaseTypePickup: + case eBaseTypePlatform: + case eBaseTypeCamera: + case eBaseTypeDoor: + case eBaseTypeSavePoint: + case eBaseTypeItem: + case eBaseTypeStatic: + case eBaseTypeDynamic: + case eBaseTypeMovePoint: + case eBaseTypeTimer: + case eBaseTypeBubble: + case eBaseTypePortal: + case eBaseTypeGroup: + case eBaseTypeSFX: + case eBaseTypeFFX: + case eBaseTypeCounter: + case eBaseTypeHangable: + case eBaseTypeButton: + case eBaseTypeProjectile: + case eBaseTypeSurface: + case eBaseTypeDestructObj: + case eBaseTypeGust: + case eBaseTypeVolume: + case eBaseTypeDispatcher: + case eBaseTypeCond: + case eBaseTypeUI: + case eBaseTypeUIFont: + case eBaseTypeProjectileType: + case eBaseTypeLobMaster: + case eBaseTypeFog: + case eBaseTypeParticleEmitter: + case eBaseTypeParticleSystem: + case eBaseTypeCutsceneMgr: + default: + { + ent->baseFlags &= 0xffef; + break; + } + } + + hack_receive_shadow(ent); +} + +void xEntInit(xEnt* ent, xEntAsset* asset) +{ + xBaseInit(ent, asset); + + // non-matching: instruction order + + ent->asset = asset; + ent->update = xEntUpdate; + ent->bupdate = xEntDefaultBoundUpdate; + ent->render = xEntRender; + ent->move = NULL; + ent->transl = xEntDefaultTranslate; + ent->flags = asset->flags; + ent->miscflags = 0; + ent->moreFlags = asset->moreFlags; + ent->subType = asset->subtype; + ent->pflags = asset->pflags; + ent->ffx = NULL; + ent->num_ffx = 0; + ent->driver = NULL; + ent->model = NULL; + ent->collModel = NULL; + ent->camcollModel = NULL; + ent->frame = NULL; + ent->collis = NULL; + ent->lightKit = NULL; + ent->simpShadow = NULL; + ent->entShadow = NULL; + ent->baseFlags |= 0x20; + + xGridBoundInit(&ent->gridb, ent); + + ent->anim_coll = NULL; + + if (all_ents_box_init) + { + iBoxInitBoundVec(&all_ents_box, &asset->pos); + all_ents_box_init = 0; + } + else + { + iBoxBoundVec(&all_ents_box, &all_ents_box, &asset->pos); + } +} + +void xEntInitForType(xEnt* ent) +{ + ent->update = xEntUpdate; + ent->render = xEntRender; + + if (ent->collType == XENT_COLLTYPE_TRIG) + { + ent->pflags &= ~0x3; + ent->chkby = XENT_COLLTYPE_NPC | XENT_COLLTYPE_PLYR; + ent->penby = 0; + } + else if (ent->collType == XENT_COLLTYPE_STAT) + { + ent->pflags &= ~0x3; + ent->chkby = XENT_COLLTYPE_NPC | XENT_COLLTYPE_PLYR; + ent->penby = XENT_COLLTYPE_NPC | XENT_COLLTYPE_PLYR; + } + else if (ent->collType == XENT_COLLTYPE_DYN) + { + ent->pflags |= 0x1; + ent->move = NULL; + ent->frame = (xEntFrame*)xMemAllocSize(sizeof(xEntFrame)); + + memset(ent->frame, 0, sizeof(xEntFrame)); + + ent->pflags &= (U8)~0x2; + ent->chkby = XENT_COLLTYPE_NPC | XENT_COLLTYPE_PLYR; + ent->penby = XENT_COLLTYPE_NPC | XENT_COLLTYPE_PLYR; + } + else if (ent->collType == XENT_COLLTYPE_NPC) + { + ent->pflags |= 0x1; + ent->move = NULL; + ent->pflags |= 0x2; + ent->chkby = XENT_COLLTYPE_PLYR; + ent->penby = XENT_COLLTYPE_PLYR; + } + else if (ent->collType == XENT_COLLTYPE_PLYR) + { + ent->pflags |= 0x1; + ent->move = NULL; + ent->frame = (xEntFrame*)xMemAllocSize(sizeof(xEntFrame)); + + memset(ent->frame, 0, sizeof(xEntFrame)); + + ent->pflags |= 0x2; + ent->chkby = 0; + ent->penby = 0; + + ent->collis = (xEntCollis*)xMemAllocSize(sizeof(xEntCollis)); + ent->collis->chk = 0x2F; + ent->collis->pen = 0x2E; + ent->collis->post = 0; + ent->collis->depenq = 0; + } + + if ((ent->moreFlags & 0x20 || ent->flags & 0x2) && !ent->frame) + { + ent->frame = (xEntFrame*)xMemAllocSize(sizeof(xEntFrame)); + + memset(ent->frame, 0, sizeof(xEntFrame)); + } + + ent->baseFlags |= 0x20; + + // non-matching: instruction order in epilogue :| + // no idea how to fix that +} + +namespace +{ + F32 get_lower_extent(const xBound& bound) + { + switch (bound.type) + { + case XBOUND_TYPE_SPHERE: + { + return bound.sph.r; + } + case XBOUND_TYPE_BOX: + { + return bound.box.center.y - bound.box.box.lower.y; + } + case XBOUND_TYPE_OBB: + { + if (0.0f == bound.mat->up.x && 0.0f == bound.mat->up.z) + { + return bound.box.center.y - + (bound.mat->up.y * bound.box.box.lower.y + bound.mat->pos.y); + } + else + { + xBox box; + xBoundGetBox(box, bound); + + return bound.box.center.y - box.lower.y; + } + } + case XBOUND_TYPE_CYL: + default: + { + return 0.0f; + } + } + } + + bool collide_downward(xVec3& loc, xEnt*& hit, xScene& s, xEnt& ent, F32 max_dist) + { + xRay3 ray; + U8 old_bound_type; + F32 old_bound_radius; + xCollis coll; + + F32 f31 = get_lower_extent(ent.bound); + xVec3* r30 = xBoundCenter(&ent.bound); + + ray.origin = *r30; + ray.dir.assign(0.0f, -1.0f, 0.0f); + ray.min_t = 0.0f; + ray.max_t = max_dist + f31; + ray.flags = 0xC00; + + old_bound_type = ent.bound.type; + old_bound_radius = ent.bound.sph.r; + + ent.bound.type = XBOUND_TYPE_SPHERE; + ent.bound.sph.r = 0.0f; + + r30->y = FLOAT_MAX; + + coll.flags = 0x100; + + xRayHitsSceneFlags(&s, &ray, &coll, XENT_COLLTYPE_PLYR, 0x26); + + ent.bound.type = old_bound_type; + ent.bound.sph.r = old_bound_radius; + + r30->y = ray.origin.y; + + if (!(coll.flags & 0x1)) + { + return false; + } + + loc = *(xVec3*)&ent.model->Mat->pos; + loc.y -= coll.dist - f31; + + hit = (xEnt*)coll.optr; + + return true; + } + + void drop_stacked_entity(xEnt&); + + void stacked_owner_destroyed(zEntDestructObj&, void* context) + { + drop_stacked_entity(*(xEnt*)context); + } + + void mount_stacked_entity(xEnt& ent, xEnt& driver) + { + if (driver.collType == XENT_COLLTYPE_DYN) + { + if (ent.driver) + { + ent.driver->driving_count--; + } + + ent.driver = &driver; + + driver.driving_count++; + + if (driver.baseType == eBaseTypeDestructObj) + { + zEntDestructObj* d = (zEntDestructObj*)&driver; + d->destroy_notify = stacked_owner_destroyed; + d->notify_context = &ent; + } + } + } + + void dismount_stacked_entity(xEnt& ent) + { + if (ent.driver) + { + if (ent.driver->baseType == eBaseTypeDestructObj) + { + zEntDestructObj* d = (zEntDestructObj*)ent.driver; + d->destroy_notify = NULL; + d->notify_context = NULL; + } + + ent.driver = NULL; + } + } + + void setup_stacked_entity(xEnt& ent) + { + ent.pflags = 0x4; + } + + void drop_stacked_entity(xEnt& ent) + { + ent.pflags = 0x4; + + dismount_stacked_entity(ent); + } + + void stop_stacked_entity(xEnt& ent) + { + ent.pflags = 0; + } + + void update_stacked_entity(xScene& sc, xEnt& ent, F32 dt) + { + xEntApplyPhysics(&ent, &sc, dt); + xEntMove(&ent, &sc, dt); + + F32 dist = ent.model->Mat->pos.y - ent.frame->mat.pos.y; + xVec3 loc; + xEnt* hit; + + if (!(dist <= 0.0f) && collide_downward(loc, hit, sc, ent, dist)) + { + ent.frame->mat.pos.y = loc.y; + stop_stacked_entity(ent); + + if (hit) + { + mount_stacked_entity(ent, *hit); + } + } + } +} // namespace + +void xEntSetup(xEnt* ent) +{ + xSurface* surf; + xModelInstance* minst; + S32 i; + xLinkAsset* la; + xEnt* dent; + + xBaseSetup(ent); + + ent->baseFlags |= 0x20; + + if (ent->asset->surfaceID) + { + surf = (xSurface*)xSceneResolvID(g_xSceneCur, ent->asset->surfaceID); + + if (surf) + { + surf->type = XSURFACE_TYPE_1; + surf->ent = ent; + + minst = ent->model; + + while (minst) + { + minst->Surf = surf; + minst = minst->Next; + } + } + } + + for (i = 0; i < ent->linkCount; i++) + { + la = &ent->link[i]; + + if (la->dstEvent == eEventDrivenby) + { + dent = (xEnt*)xSceneResolvID(g_xSceneCur, la->dstAssetID); + + if (dent) + { + ent->driver = dent; + ent->driveMode = (S32)la->param[0]; + + dent->driving_count++; + } + } + } + + ent->model->RedMultiplier = ent->asset->redMult; + ent->model->GreenMultiplier = ent->asset->greenMult; + ent->model->BlueMultiplier = ent->asset->blueMult; + ent->model->Alpha = ent->asset->seeThru; + + xEntAddHittableFlag(ent); + xEntAddShadowRecFlag(ent); + + zCollGeom_EntSetup(ent); + + if (ent->model) + { + if (ent->bound.type == XBOUND_TYPE_BOX) + { + iBoxForModel(&ent->bound.box.box, (ent->collModel) ? ent->collModel : ent->model); + } + else if (ent->bound.type == XBOUND_TYPE_OBB) + { + iBoxForModelLocal(&ent->bound.box.box, (ent->collModel) ? ent->collModel : ent->model); + } + } + + if (ent->moreFlags & 0x20) + { + anim_coll::reset(*ent); + } + + if (ent->flags & 0x2) + { + setup_stacked_entity(*ent); + } +} + +void xEntSave(xEnt* ent, xSerial* s) +{ + xBaseSave(ent, s); + + if (xEntIsVisible(ent)) + { + s->Write_b1(1); + } + else + { + s->Write_b1(0); + } +} + +void xEntLoad(xEnt* ent, xSerial* s) +{ + S32 b; + + xBaseLoad(ent, s); + + b = 0; + s->Read_b1(&b); + + if (b) + { + xEntShow(ent); + } + else + { + xEntHide(ent); + } +} + +void xEntReset(xEnt* ent) +{ + xMat4x3 frame; + xModelInstance* minst; + + xBaseReset(ent, ent->asset); + + ent->baseFlags |= 0x20; + ent->flags = ent->asset->flags; + ent->miscflags = 0; + ent->moreFlags = ent->asset->moreFlags; + + xEntAddHittableFlag(ent); + xEntAddShadowRecFlag(ent); + + xMat3x3Euler(&frame, ent->asset->ang.x, ent->asset->ang.y, ent->asset->ang.z); + + xVec3SMulBy(&frame.right, ent->asset->scale.x); + xVec3SMulBy(&frame.up, ent->asset->scale.y); + xVec3SMulBy(&frame.at, ent->asset->scale.z); + xVec3Copy(&frame.pos, &ent->asset->pos); + + frame.flags = 0; + + if (ent->model) + { + xModelSetFrame(ent->model, &frame); + + if (ent->collModel) + { + xModelSetFrame(ent->collModel, &frame); + } + + if (ent->moreFlags & 0x20) + { + anim_coll::reset(*ent); + } + + minst = ent->model; + + while (minst) + { + minst->RedMultiplier = ent->asset->redMult; + minst->GreenMultiplier = ent->asset->greenMult; + minst->BlueMultiplier = ent->asset->blueMult; + + minst->Alpha = minst->Data->geometry->matList.materials[0]->color.alpha / 255.0f; + minst->Scale.x = 0.0f; + minst->Scale.y = 0.0f; + minst->Scale.z = 0.0f; + + minst = minst->Next; + } + } + + if (ent->frame) + { + xMat4x3Copy(&ent->frame->mat, &frame); + + ent->frame->oldmat = ent->frame->mat; + + xVec3Copy(&ent->frame->dpos, &g_O3); + xVec3Copy(&ent->frame->dvel, &g_O3); + xVec3Copy(&ent->frame->vel, &g_O3); + xVec3Copy(&ent->frame->oldvel, &g_O3); + xVec3Copy(&ent->frame->rot.axis, &ent->asset->ang); + + ent->frame->rot.angle = 0.0f; + + xRotCopy(&ent->frame->oldrot, &ent->frame->rot); + } + + if (ent->bupdate && ent->model) + { + ent->bupdate(ent, (xVec3*)&ent->model->Mat->pos); + } + + ent->num_updates = xrand() & 127; + + if (ent->flags & 0x2) + { + setup_stacked_entity(*ent); + } +} + +xModelInstance* xEntLoadModel(xEnt* ent, RpAtomic* imodel) +{ + xModelInstance* model; + + model = xModelInstanceAlloc(imodel, ent, 0, 0, NULL); + + while (imodel = iModelFile_RWMultiAtomic(imodel)) + { + xModelInstanceAttach(xModelInstanceAlloc(imodel, ent, 0x8, 0, NULL), model); + } + + if (ent) + { + ent->model = model; + } + + return model; +} + +void xEntAddToPos(xEnt* ent, const xVec3* v) +{ + xVec3AddTo(&ent->frame->mat.pos, v); +} + +void xEntSetupPipeline(xModelInstance* model) +{ + xEntSetupPipeline(model->Surf, model->Data); +} + +static S32 setMaterialTextureRestore; +S32 sSetPipeline; +static RxPipeline* oldPipe; + +void xEntSetupPipeline(xSurface* surf, RpAtomic* model) +{ + setMaterialTextureRestore = 0; + sSetPipeline = 0; + + if (surf) + { + zSurfaceProps* pp = (zSurfaceProps*)surf->moprops; + + if (pp) + { + if (pp->texanim_flags & 0x1) + { + xGroup* g = (xGroup*)zSceneFindObject(pp->texanim[0].group); + + if (g) + { + U32 texid = xGroupGetItem(g, pp->texanim[0].group_idx); + RwTexture* texptr = (RwTexture*)xSTFindAsset(texid, NULL); + + if (texptr) + { + iModelSetMaterialTexture(model, texptr); + setMaterialTextureRestore = 1; + } + } + } + + if (pp->texanim_flags & 0x2) + { + xGroup* g = (xGroup*)zSceneFindObject(pp->texanim[1].group); + + if (g) + { + U32 texid = xGroupGetItem(g, pp->texanim[1].group_idx); + RwTexture* texptr = (RwTexture*)xSTFindAsset(texid, NULL); + + if (texptr) + { + xFXanimUV2PSetTexture(texptr); + sSetPipeline = 1; + } + } + } + else if (pp->uvfx_flags & 0x2) + { + RwTexture* texptr = (RwTexture*)xSTFindAsset(pp->asset->matfx.dualmapID, NULL); + + if (texptr) + { + xFXanimUV2PSetTexture(texptr); + sSetPipeline = 1; + } + } + else + { + xFXanimUV2PSetTexture(NULL); + } + + if (pp->uvfx_flags & 0x3) + { + sSetPipeline = 1; + + xFXanimUVSetTranslation(&pp->uvfx[0].trans); + xFXanimUV2PSetTranslation(&pp->uvfx[1].trans); + xFXanimUVSetScale(&pp->uvfx[0].scale); + xFXanimUV2PSetScale(&pp->uvfx[1].scale); + xFXanimUVSetAngle(RAD2DEG(PI * 0.9824379f / 100000) * pp->uvfx[0].rot); + xFXanimUV2PSetAngle(RAD2DEG(PI * 0.9824379f / 100000) * pp->uvfx[1].rot); + } + + if (sSetPipeline) + { + oldPipe = model->pipeline; + xFXanimUVAtomicSetup(model); + } + } + } +} + +void xEntRestorePipeline(xModelInstance* model) +{ + xEntRestorePipeline(model->Surf, model->Data); +} + +void xEntRestorePipeline(xSurface*, RpAtomic* model) +{ + if (setMaterialTextureRestore) + { + iModelResetMaterial(model); + setMaterialTextureRestore = 0; + } + + if (sSetPipeline) + { + model->pipeline = oldPipe; + sSetPipeline = 0; + } +} + +void xEntRender(xEnt* ent) +{ + S32 shadowOutside; + xVec3 shadVec; + + if (ent->model == NULL || !xEntIsVisible(ent) || ent->model->Flags & 0x400) + { + return; + } + + ent->isCulled = 0; + + if (ent->baseType == eBaseTypePlayer || (ent->baseType == eBaseTypeNPC && !(ent->flags & 0x40))) + { + // non-matching: 10.0f is loaded too early + + shadVec.x = ent->model->Mat->pos.x; + shadVec.y = ent->model->Mat->pos.y - 10.0f; + shadVec.z = ent->model->Mat->pos.z; + + if (iModelCullPlusShadow(ent->model->Data, ent->model->Mat, &shadVec, &shadowOutside)) + { + if (shadowOutside) + { + ent->isCulled = 1; + return; + } + else + { + goto postrender; + } + } + } + else + { + if (iModelCull(ent->model->Data, ent->model->Mat)) + { + ent->isCulled = 1; + return; + } + } + + xModelRender(ent->model); + +postrender: + + if ((ent->baseType == eBaseTypeNPC && !(ent->flags & 0x40)) || ent->baseType == eBaseTypePlayer) + { + zLightAddLocal(ent); + xShadow_ListAdd(ent); + } +} + +void xEntUpdate(xEnt* ent, xScene* sc, F32 dt) +{ + xEntBeginUpdate(ent, sc, dt); + + if (ent->pflags & 0x2) + { + xEntApplyPhysics(ent, sc, dt); + } + + if (ent->pflags & 0x1) + { + xEntMove(ent, sc, dt); + } + + xFFXApply(ent, sc, dt); + + if (ent->collis) + { + xEntCollide(ent, sc, dt); + } + + if (ent->flags & 0x2 && ent->pflags & 0x4) + { + update_stacked_entity(*sc, *ent, dt); + } + + xEntEndUpdate(ent, sc, dt); +} + +void xEntBeginUpdate(xEnt* ent, xScene* sc, F32 dt) +{ + if (ent->model) + { + xModelUpdate(ent->model, dt); + + if (ent->frame) + { + xVec3Copy(&ent->frame->oldvel, &ent->frame->vel); + + ent->frame->oldmat = ent->frame->mat; + + xRotCopy(&ent->frame->oldrot, &ent->frame->rot); + xMat4x3Copy(&ent->frame->mat, xModelGetFrame(ent->model)); + + ent->frame->mode = 0; + } + } +} + +void xEntEndUpdate(xEnt* ent, xScene* sc, F32 dt) +{ + ent->num_updates++; + + if (ent->model) + { + if (ent->frame) + { + if (!(ent->frame->mode & 0x20000)) + { + xMat3x3Copy((xMat4x3*)ent->model->Mat, &ent->frame->mat); + } + + if (!(ent->frame->mode & 0x10000)) + { + xVec3* mpos = (xVec3*)&ent->model->Mat->pos; + xVec3Copy(mpos, &ent->frame->mat.pos); + } + } + + if (ent->bupdate) + { + xVec3* upos = (xVec3*)&ent->model->Mat->pos; + ent->bupdate(ent, upos); + } + + xModelEval(ent->model); + + if (ent->moreFlags & 0x20) + { + anim_coll::refresh(*ent); + } + + if (ent->endUpdate) + { + ent->endUpdate(ent, sc, dt); + } + } +} + +void xEntDefaultBoundUpdate(xEnt* ent, xVec3* pos) +{ + xBound* bound = &ent->bound; + + if (bound->type == XBOUND_TYPE_SPHERE) + { + xVec3Copy(&bound->sph.center, pos); + + bound->sph.center.y += 0.7f; + bound->sph.r = 0.7f; + } + + xBoundUpdate(bound); + zGridUpdateEnt(ent); +} + +void xEntDefaultTranslate(xEnt* ent, xVec3* dpos, xMat4x3* dmat) +{ + if (dmat) + { + if (ent->model) + { + xMat4x3Mul((xMat4x3*)ent->model->Mat, (xMat4x3*)ent->model->Mat, dmat); + } + + if (ent->frame) + { + xMat4x3Mul(&ent->frame->mat, &ent->frame->mat, dmat); + } + + xMat4x3Toworld(xEntGetCenter(ent), dmat, xEntGetCenter(ent)); + } + else + { + if (ent->model) + { + xVec3AddTo(xEntGetPos(ent), dpos); + } + + if (ent->frame) + { + xVec3AddTo(&ent->frame->mat.pos, dpos); + } + + xVec3AddTo(xEntGetCenter(ent), dpos); + } +} + +static void xEntRotationToMatrix(xEntFrame* frame) +{ + if (frame->mode & 0x20) + { + if (frame->mode & 0x400) + { + xVec3AddTo(&frame->rot.axis, &frame->drot.axis); + xMat3x3Euler(&frame->mat, frame->rot.axis.x, frame->rot.axis.y, frame->rot.axis.z); + } + else + { + frame->rot.angle = xAngleClamp(frame->rot.angle + frame->drot.angle); + + xMat3x3Rot(&frame->mat, &frame->rot.axis, frame->rot.angle); + } + } +} + +void xEntMotionToMatrix(xEnt* ent, xEntFrame* frame) +{ + if (frame->mode & 0x1000) + { + xEntRotationToMatrix(frame); + } + + if (frame->mode & 0x2) + { + if (frame->mode & 0x800) + { + xMat3x3RMulVec(&frame->dpos, &frame->mat, &frame->dpos); + } + + xEntAddToPos(ent, &frame->dpos); + } + + if (frame->mode & 0x8) + { + if (frame->mode & 0x800) + { + xMat3x3RMulVec(&frame->dvel, &frame->mat, &frame->dvel); + } + + xVec3AddTo(&frame->vel, &frame->dvel); + } + + if (!(frame->mode & 0x1000)) + { + xEntRotationToMatrix(frame); + } +} + +void xEntMove(xEnt* ent, xScene* sc, F32 dt) +{ + if (ent->moreFlags & 0x20) + { + anim_coll::pre_move(*ent); + } + + ent->move(ent, sc, dt, ent->frame); + + xEntMotionToMatrix(ent, ent->frame); + + if (ent->driver) + { + xEntFrame* dframe = ent->driver->frame; + + if (ent->driveMode == 0) + { + xVec3 dpos; + xVec3Sub(&dpos, &dframe->mat.pos, &dframe->oldmat.pos); + + ent->transl(ent, &dpos, NULL); + } + else if (ent->driveMode == 1) + { + RwMatrixUpdate((RwMatrix*)&dframe->oldmat); + + xMat4x3 invOldmat; + RwMatrixInvert((RwMatrix*)&invOldmat, (RwMatrix*)&dframe->oldmat); + + xMat4x3 deltaMat; + xMat4x3Mul(&deltaMat, &invOldmat, &dframe->mat); + + ent->transl(ent, NULL, &deltaMat); + } + } + + if (ent->moreFlags & 0x20) + { + anim_coll::post_move(*ent); + } +} + +namespace +{ + namespace anim_coll + { + void post_move(xEnt& ent) + { + xMat4x3& mat = *(xMat4x3*)ent.model->Mat; + xEnt::anim_coll_data& ac = *ent.anim_coll; + + ac.old_mat = ent.frame->mat; + + xMat4x3Mul(&mat, &ac.new_mat, &ac.old_mat); + + ent.frame->mat = mat; + } + + void pre_move(xEnt& ent) + { + xMat4x3& mat = *(xMat4x3*)ent.model->Mat; + xEnt::anim_coll_data& ac = *ent.anim_coll; + + ent.frame->mat = mat = ac.old_mat; + } + } // namespace anim_coll +} // namespace + +void xEntApplyPhysics(xEnt* ent, xScene* sc, F32 dt) +{ + xVec3 dposvel = { 0, 0, 0 }; + + if (ent->pflags & 0x4 && sc->flags & 0x1) + { + ent->frame->vel.y += sc->gravity * dt; + } + + if (ent->pflags & 0x10 && sc->flags & 0x2) + { + F32 tfric = -(sc->friction * dt - 1.0f); + xVec3SMulBy(&ent->frame->vel, tfric); + } + + if (ent->pflags & 0x8 && sc->flags & 0x4) + { + F32 tdrag = -(sc->drag * dt - 1.0f); + xVec3SMulBy(&ent->frame->vel, tdrag); + } + + xVec3Add(&dposvel, &ent->frame->vel, &ent->frame->oldvel); + xVec3SMulBy(&dposvel, 0.5f * dt); + + if (dposvel.y < 0.0f) + { + F32 dposXZ = xsqrt(SQR(dposvel.x) + SQR(dposvel.z)); + F32 scaleXZ = (dposXZ > 0.00001f) ? ((0.63f * (30.0f * dt)) / dposXZ) : 0.0f; + F32 scaleY = (0.63f * (30.0f * dt)) / (F32)iabs(dposvel.y); + + if (scaleXZ < 1.0f) + { + dposvel.x *= scaleXZ; + dposvel.z *= scaleXZ; + } + + if (scaleY < 1.0f) + { + dposvel.y *= scaleY; + } + } + + xEntAddToPos(ent, &dposvel); +} + +void xEntCollide(xEnt* ent, xScene* sc, F32 dt) +{ + if (ent->model) + { + if (ent->collis->chk & 0x2E) + { + xEntBeginCollide(ent, sc, dt); + } + + if (ent->collis->chk & 0x8) + { + xEntCollCheckNPCsByGrid(ent, sc, xEntCollCheckOneEntNoDepen); + } + + if (ent->collis->chk & 0x6) + { + xEntCollCheckByGrid(ent, sc, xEntCollCheckOneEntNoDepen); + } + + if (ent->collis->chk & 0x20) + { + xEntCollCheckEnv(ent, sc); + } + + xCollis* coll = &ent->collis->colls[0]; + + if (ent->collis->chk & 0x2E) + { + F32 h_dot_n; + + if (ent->bound.type == XBOUND_TYPE_SPHERE) + { + h_dot_n = ent->bound.sph.r; + } + else + { + h_dot_n = 0.7f; + } + + if (ent->pflags & 0x80 && coll->flags & 0x1) + { + F32 depen_len = xVec3Dot(&coll->hdng, &coll->norm); + + if (depen_len > 0.0f) + { + xVec3Inv(&coll->norm, &coll->norm); + depen_len = -depen_len; + } + + depen_len = depen_len * coll->dist + h_dot_n; + + if (depen_len < 0.0f || depen_len > h_dot_n) + { + depen_len = CLAMP(depen_len, 0.0f, h_dot_n); + } + + xVec3SMul(&coll->depen, &coll->norm, depen_len); + } + + if (ent->frame->vel.y <= 0.0f) + { + xEntCollideFloor(ent, sc, dt); + } + else + { + xEntCollideCeiling(ent, sc, dt); + } + + xEntCollideWalls(ent, sc, dt); + xEntEndCollide(ent, sc, dt); + } + } +} + +void xEntBeginCollide(xEnt* ent, xScene*, F32) +{ + U8 idx; + xCollis* coll; + + if (ent->bupdate) + { + ent->bupdate(ent, &ent->frame->mat.pos); + } + + for (idx = 0; idx < 18; idx++) + { + coll = &ent->collis->colls[idx]; + + coll->flags = 0x1F00; + coll->optr = NULL; + coll->mptr = NULL; + coll->dist = FLOAT_MAX; + } + + ent->collis->idx = 6; + ent->collis->stat_sidx = 6; + ent->collis->stat_eidx = 6; + ent->collis->dyn_sidx = 6; + ent->collis->dyn_eidx = 6; + ent->collis->npc_sidx = 6; + ent->collis->npc_eidx = 6; + ent->collis->env_sidx = 6; + ent->collis->env_eidx = 6; +} + +void xEntEndCollide(xEnt* ent, xScene* sc, F32 dt) +{ + if (ent->collis->post) + { + ent->collis->post(ent, sc, dt, ent->collis); + } +} + +void xEntCollCheckEnv(xEnt* p, xScene* sc) +{ + xCollis* coll; + U8 ncolls; + + p->collis->env_sidx = p->collis->idx; + + coll = &p->collis->colls[p->collis->idx]; + coll->flags = 0x1F00; + + ncolls = 18 - p->collis->idx; + + p->collis->idx += (U8)iSphereHitsEnv3(&p->bound.sph, sc->env, coll, ncolls, 0.78539819f); + p->collis->env_eidx = p->collis->idx; +} + +static void xEntCollCheckOneGrid(xEnt* p, xScene* sc, xEnt* (*hitIt)(xEnt*, xScene*, void*), + xGrid* grid) +{ + xVec3* r26 = xEntGetCenter(p); + xGridIterator it; + S32 px, pz; + + xGridBound* cell = xGridIterFirstCell(grid, r26->x, r26->y, r26->z, px, pz, it); + + while (cell) + { + if (xQuickCullIsects(&p->bound.qcd, (xQCData*)(cell + 1))) + { + hitIt((xEnt*)cell->data, sc, p); + } + + cell = xGridIterNextCell(it); + } + + // non-matching: float scheduling + + F32 halfsizez = (grid->csizez * 0.5f); + F32 halfsizex = (grid->csizex * 0.5f); + + F32 clcenterx = grid->csizex * px; + F32 clcenterz = grid->csizez * pz; + + clcenterx += grid->minx; + clcenterx += halfsizex; + + clcenterz += halfsizez; + clcenterz += grid->minz; + + static S32 k; + + if (r26->x < clcenterx) + { + if (r26->z < clcenterz) + { + k = 0; + } + else + { + k = 1; + } + } + else + { + if (r26->z < clcenterz) + { + k = 3; + } + else + { + k = 2; + } + } + + static S32 offs[4][3][2] = { + { { -1, 0 }, { -1, -1 }, { 0, -1 } }, + { { 0, -1 }, { 1, -1 }, { 1, 0 } }, + { { 1, 0 }, { 1, 1 }, { 0, 1 } }, + { { 0, 1 }, { -1, 1 }, { -1, 0 } }, + }; + + for (S32 i = 0; i < 3; i++) + { + S32 _x = px + offs[k][i][1]; + S32 _z = pz + offs[k][i][0]; + + cell = xGridIterFirstCell(grid, _x, _z, it); + + while (cell) + { + if (xQuickCullIsects(&p->bound.qcd, (xQCData*)(cell + 1))) + { + hitIt((xEnt*)cell->data, sc, p); + } + + cell = xGridIterNextCell(it); + } + } + + cell = xGridIterFirstCell(&grid->other, it); + + while (cell) + { + if (xQuickCullIsects(&p->bound.qcd, (xQCData*)(cell + 1))) + { + hitIt((xEnt*)cell->data, sc, p); + } + + cell = xGridIterNextCell(it); + } +} + +void xEntCollCheckByGrid(xEnt* p, xScene* sc, xEnt* (*hitIt)(xEnt*, xScene*, void*)) +{ + p->collis->stat_sidx = p->collis->idx; + p->collis->dyn_sidx = p->collis->idx; + + xEntCollCheckOneGrid(p, sc, hitIt, &colls_grid); + xEntCollCheckOneGrid(p, sc, hitIt, &colls_oso_grid); + + p->collis->stat_eidx = p->collis->idx; + p->collis->dyn_eidx = p->collis->idx; +} + +void xEntCollCheckNPCsByGrid(xEnt* p, xScene* sc, xEnt* (*hitIt)(xEnt*, xScene*, void*)) +{ + p->collis->npc_sidx = p->collis->idx; + + xEntCollCheckOneGrid(p, sc, hitIt, &npcs_grid); + + p->collis->npc_eidx = p->collis->idx; +} + +void xEntCollCheckStats(xEnt* p, xScene* sc, xEnt* (*hitIt)(xEnt*, xScene*, void*)) +{ + p->collis->stat_sidx = p->collis->idx; + + xSceneForAllStatics(sc, hitIt, p); + + p->collis->stat_eidx = p->collis->idx; +} + +void xEntCollCheckDyns(xEnt* p, xScene* sc, xEnt* (*hitIt)(xEnt*, xScene*, void*)) +{ + p->collis->dyn_sidx = p->collis->idx; + + xSceneForAllDynamics(sc, hitIt, p); + + p->collis->dyn_eidx = p->collis->idx; +} + +void xEntCollCheckNPCs(xEnt* p, xScene* sc, xEnt* (*hitIt)(xEnt*, xScene*, void*)) +{ + p->collis->npc_sidx = p->collis->idx; + + xSceneForAllNPCs(sc, hitIt, p); + + p->collis->npc_eidx = p->collis->idx; +} + +S32 xent_entent = 0; +xEnt* xEntCollCheckOneEntNoDepen(xEnt* ent, xScene* sc, void* data) +{ + xent_entent = 1; + + xEnt* p = (xEnt*)data; + xCollis* coll; + U32 modl_coll = 0; + + if (p->collis->idx >= 15) + { + xent_entent = 0; + return NULL; + } + + if ((ent->chkby & p->collType) == 0) + { + xent_entent = 0; + return ent; + } + + if (ent->id == p->id && (ent == p || ent->baseType != eBaseTypeBoulder)) + { + xent_entent = 0; + return ent; + } + + coll = &p->collis->colls[p->collis->idx]; + + if (ent->collLev == 5 && p->collType & (XENT_COLLTYPE_NPC | XENT_COLLTYPE_PLYR)) + { + modl_coll = 1; + } + + if (modl_coll) + { + coll->flags = 0; + } + else + { + coll->flags = 0x1F00; + } + + xBoundHitsBound(&p->bound, &ent->bound, coll); + + if (coll->flags & 0x1) + { + if (modl_coll) + { + xBound tmp; + xBound* bptr; // unused + U8 ncolls; + xVec3 *upper, *lower; + U8 idx; + + coll->flags = 0x1F00; + + if (p->bound.type == XBOUND_TYPE_SPHERE) + { + xModelInstance* r4 = (ent->collModel) ? ent->collModel : ent->model; + ncolls = 15 - p->collis->idx; + idx = iSphereHitsModel3(&p->bound.sph, r4, coll, ncolls, 0.78539819f); + } + else if (p->bound.type == XBOUND_TYPE_BOX) + { + upper = &p->bound.box.box.upper; + lower = &p->bound.box.box.lower; + + tmp.type = XBOUND_TYPE_SPHERE; + + xVec3Add(&tmp.sph.center, upper, lower); + xVec3SMulBy(&tmp.sph.center, 0.5f); + + tmp.sph.r = + 0.167f * (upper->x + upper->y + upper->z - lower->x - lower->y - lower->z); + + // none of the code above is used for anything... maybe debug stuff + + xModelInstance* r4 = (ent->collModel) ? ent->collModel : ent->model; + ncolls = 15 - p->collis->idx; + idx = iSphereHitsModel3(&p->bound.sph, r4, coll, ncolls, 0.78539819f); + } + + // idx might be undefined here...! + + for (U8 i = 0; i < idx; i++) + { + coll[i].optr = ent; + coll[i].mptr = ent->model; + + p->collis->idx++; + } + + xent_entent = 0; + return ent; + } + else + { + coll->oid = ent->id; + coll->optr = ent; + coll->mptr = ent->model; + + p->collis->idx++; + + if (ent->pflags & 0x20 && ent->bound.type == XBOUND_TYPE_SPHERE && + p->bound.type == XBOUND_TYPE_SPHERE && coll->hdng.y < -0.866025f) + { + F32 rsum = p->bound.sph.r + ent->bound.sph.r; + F32 dx = p->bound.sph.center.x - ent->bound.sph.center.x; + F32 dy = p->bound.sph.center.y - ent->bound.sph.center.y; + F32 dz = p->bound.sph.center.z - ent->bound.sph.center.z; + + F32 hsqr = SQR(rsum) - (SQR(dx) + SQR(dz)); + + if (hsqr >= 0.0f) + { + coll->depen.x = 0.0f; + coll->depen.y = xsqrt(hsqr) - dy; + coll->depen.z = 0.0f; + coll->dist = 0.7f - coll->depen.y; + coll->hdng.x = 0.0f; + coll->hdng.y = -1.0f; + coll->hdng.z = 0.0f; + } + } + } + } + + xent_entent = 0; + return ent; +} + +void xEntCollideFloor(xEnt* p, xScene* sc, F32 dt) +{ + xCollis* coll = &p->collis->colls[0]; + U8 idx; + xCollis* ml = coll; + xVec3 motion; + F32 mlen; + S32 stepping = 0; + F32 sbr; + + if (p->bound.type == XBOUND_TYPE_SPHERE) + { + sbr = p->bound.sph.r; + } + else + { + sbr = 0.7f; + } + + xVec3Copy(&motion, &p->frame->mat.pos); + xVec3SubFrom(&motion, &p->frame->oldmat.pos); + + motion.y = 0.0f; + mlen = xVec3Length(&motion); + + for (idx = 6; idx < p->collis->idx; idx++) + { + xCollis* mf = &p->collis->colls[idx]; + + if (mf->flags & 0x1) + { + xEnt* fent = (xEnt*)mf->optr; + + if (fent) + { + if ((fent->collType == XENT_COLLTYPE_DYN || fent->collType == XENT_COLLTYPE_STAT) || + (fent->pflags & 0x20 && 0.0f == mf->hdng.x && 0.0f == mf->hdng.z)) + { + if (!((p->collis->depenq) ? + p->collis->depenq(p, fent, sc, dt, mf) : + (fent->collType & p->collis->pen && fent->penby & p->collType))) + { + continue; + } + } + else + { + continue; + } + } + else if (!(p->collis->pen & 0x20)) + { + continue; + } + + if (mf->dist < ml->dist) + { + if (mf->hdng.y < -icos(PI / 3) && + (mf->norm.y > icos(nsn_angle) || + p->frame->oldmat.pos.y > dt * (sc->gravity * dt) + p->frame->mat.pos.y)) + { + ml = mf; + stepping = 0; + } + else if (mlen > 0.001f && mf->hdng.y < 0.65f / sbr - 1.0f && + mf->norm.y > icos(nsn_angle)) + { + stepping = 1; + ml = mf; + } + } + } + } + + if (ml != coll) + { + F32 flr_dist = ml->dist * (F32)iabs(ml->hdng.y); + xEnt* fent; // unused + + *coll = *ml; + + if (flr_dist < sbr) + { + ml->flags |= 0x6; + + if (stepping) + { + p->frame->mat.pos.y += 1.5f * dt; + p->frame->mat.pos.x += ml->depen.x; + p->frame->mat.pos.z += ml->depen.z; + } + else + { + p->frame->mat.pos.y += ml->depen.y; + } + + p->frame->vel.y = 0.0f; + } + } +} + +void xEntCollideCeiling(xEnt* p, xScene* sc, F32 dt) +{ + xCollis* coll = &p->collis->colls[1]; + U8 idx; + xCollis* ml = coll; + F32 sbr; + + if (p->bound.type == XBOUND_TYPE_SPHERE) + { + sbr = p->bound.sph.r; + } + else + { + sbr = 0.7f; + } + + for (idx = 6; idx < p->collis->idx; idx++) + { + xCollis* mf = &p->collis->colls[idx]; + xEnt* fent = (xEnt*)mf->optr; + + if (fent) + { + if (!((p->collis->depenq) ? + p->collis->depenq(p, fent, sc, dt, mf) : + (fent->collType & p->collis->pen && fent->penby & p->collType))) + { + continue; + } + } + else if (!(p->collis->pen & 0x20)) + { + continue; + } + + if (mf->hdng.y > icos(0.78539819f) && mf->dist < ml->dist) + { + ml = mf; + } + } + + if (ml != coll) + { + F32 ceil_dist = ml->dist * (F32)iabs(ml->hdng.y); + + *coll = *ml; + + ml->flags |= 0xA; + + if (ceil_dist < sbr) + { + p->frame->mat.pos.y -= sbr - ceil_dist; + p->frame->vel.y = 0.0f; + } + } +} + +void xEntCollideWalls(xEnt* p, xScene* sc, F32 dt) +{ + xCollis* coll; + xEnt* cent; + U8 idx, sidx; + F32 sbr; + + if (p->bound.type == XBOUND_TYPE_SPHERE) + { + sbr = p->bound.sph.r; + } + else + { + sbr = 0.7f; + } + + if (p->collis->pen & 0x8) + { + idx = p->collis->npc_eidx; + sidx = p->collis->npc_sidx; + + while (sidx < idx) + { + coll = &p->collis->colls[sidx]; + cent = (xEnt*)coll->optr; + + if (!(coll->flags & 0x2) && coll->dist < sbr && + ((p->collis->depenq) ? p->collis->depenq(p, cent, sc, dt, coll) : + cent->penby & p->collType)) + { + if (0.0f != coll->depen.x || 0.0f != coll->depen.z) + { + coll->depen.y = 0.0f; + } + + xEntAddToPos(p, &coll->depen); + } + + sidx++; + } + } + + if (p->collis->pen & 0x4) + { + idx = p->collis->dyn_eidx; + sidx = p->collis->dyn_sidx; + + while (sidx < idx) + { + coll = &p->collis->colls[sidx]; + cent = (xEnt*)coll->optr; + + if (!(coll->flags & 0x2) && coll->dist < sbr && + ((p->collis->depenq) ? p->collis->depenq(p, cent, sc, dt, coll) : + cent->penby & p->collType)) + { + coll->depen.y = 0.0f; + + xEntAddToPos(p, &coll->depen); + } + + sidx++; + } + } + + if (p->collis->pen & 0x2) + { + idx = p->collis->stat_eidx; + sidx = p->collis->stat_sidx; + + while (sidx < idx) + { + coll = &p->collis->colls[sidx]; + cent = (xEnt*)coll->optr; + + if (!(coll->flags & 0x2) && coll->dist < sbr && + ((p->collis->depenq) ? p->collis->depenq(p, cent, sc, dt, coll) : + cent->penby & p->collType)) + { + coll->depen.y = 0.0f; + + xEntAddToPos(p, &coll->depen); + } + + sidx++; + } + } + + if (p->collis->pen & 0x20) + { + idx = p->collis->env_eidx; + sidx = p->collis->env_sidx; + + while (sidx < idx) + { + coll = &p->collis->colls[sidx]; + cent = (xEnt*)coll->optr; + + if (!(coll->flags & 0x2) && coll->dist < sbr) + { + coll->depen.y = 0.0f; + + xEntAddToPos(p, &coll->depen); + } + + sidx++; + } + } +} + +void xEntSetNostepNormAngle(F32 angle) +{ + nsn_angle = angle; +} + +xBox* xEntGetAllEntsBox() +{ + return &all_ents_box; +} + +void xEntAnimateCollision(xEnt& ent, bool on) +{ + if (on && !(ent.moreFlags & 0x20)) + { + ent.moreFlags |= 0x20; + + if (!ent.frame) + { + ent.frame = (xEntFrame*)xMemAllocSize(sizeof(xEntFrame)); + + memset(ent.frame, 0, sizeof(xEntFrame)); + } + + anim_coll::reset(ent); + } + else if (!on && ent.moreFlags & 0x20) + { + ent.moreFlags &= (U8)~0x20; + } +} + +bool xEntValidType(U8 type) +{ + return type == eBaseTypeTrigger || type == eBaseTypeVillain || type == eBaseTypePlayer || + type == eBaseTypePickup || type == eBaseTypePlatform || type == eBaseTypeDoor || + type == eBaseTypeSavePoint || type == eBaseTypeItem || type == eBaseTypeStatic || + type == eBaseTypeDynamic || type == eBaseTypeBubble || type == eBaseTypePendulum || + type == eBaseTypeHangable || type == eBaseTypeButton || type == eBaseTypeProjectile || + type == eBaseTypeDestructObj || type == eBaseTypeUI || type == eBaseTypeUIFont || + type == eBaseTypeProjectileType || type == eBaseTypeEGenerator || type == eBaseTypeNPC || + type == eBaseTypeBoulder || type == eBaseTypeTeleportBox || type == eBaseTypeZipLine; +} + +void xEntReposition(xEnt& ent, const xMat4x3& mat) +{ + *(xMat4x3*)ent.model->Mat = mat; + + if (ent.collModel && ent.collModel != ent.model) + { + *(xMat4x3*)ent.collModel->Mat = mat; + } + + if (ent.frame) + { + ent.frame->mat = mat; + } + + if (ent.bound.mat) + { + *ent.bound.mat = mat; + } + + ent.bound.sph.center = mat.pos; + + xBoundUpdate(&ent.bound); + zGridUpdateEnt(&ent); +} + +void xEntInitShadow(xEnt& ent, xEntShadow& shadow) +{ + ent.entShadow = &shadow; + + shadow.vec.assign(0.0f, 1.0f, 0.0f); + shadow.pos = ent.asset->pos; + shadow.shadowModel = NULL; + shadow.dst_cast = -1.0f; + shadow.radius[0] = -1.0f; + shadow.radius[1] = -1.0f; +} diff --git a/src/SB/Core/x/xEnt.h b/src/SB/Core/x/xEnt.h index bab5d78..e097784 100644 --- a/src/SB/Core/x/xEnt.h +++ b/src/SB/Core/x/xEnt.h @@ -1,88 +1,84 @@ #ifndef XENT_H #define XENT_H -#include -#include "xEnv.h" -#include "xCollis.h" +#include +#include +#include + +#include "xBase.h" +#include "xMath3.h" +#include "xModel.h" +#include "xLightKit.h" #include "xGrid.h" -#include "xFX.h" -#include "xShadow.h" +#include "xBound.h" +#include "xFFX.h" +#include "xCollide.h" struct xEntAsset : xBaseAsset { + // Offset: 0x8 U8 flags; U8 subtype; U8 pflags; U8 moreFlags; + U8 pad; + //U8 padding[3]; // this padding is added automatically. it should not be here + + // Offset: 0x10 U32 surfaceID; + + // Offset: 0x14 xVec3 ang; + + // Offset: 0x20 xVec3 pos; + + // Offset: 0x2C xVec3 scale; + + // Offset: 0x38 F32 redMult; F32 greenMult; F32 blueMult; F32 seeThru; + + // Offset: 0x48 F32 seeThruSpeed; U32 modelInfoID; U32 animListID; }; -struct xModelInstance; - -struct xAnimPlay -{ - xAnimPlay* Next; - U16 NumSingle; - U16 BoneCount; - xAnimSingle* Single; - void* Object; - xAnimTable* Table; - xMemPool* Pool; - xModelInstance* ModelInst; - void (*BeforeAnimMatrices)(xAnimPlay*, xQuat*, xVec3*, S32); -}; - -struct xScene -{ - U32 sceneID; - U16 flags; - U16 num_trigs; - U16 num_stats; - U16 num_dyns; - U16 num_npcs; - U16 num_act_ents; - F32 gravity; - F32 drag; - F32 friction; - U16 num_ents_allocd; - U16 num_trigs_allocd; - U16 num_stats_allocd; - U16 num_dyns_allocd; - U16 num_npcs_allocd; - xEnt** trigs; - xEnt** stats; - xEnt** dyns; - xEnt** npcs; - xEnt** act_ents; - xEnv* env; - xMemPool mempool; - xBase* (*resolvID)(U32); - unsigned char* (*base2Name)(xBase*); - unsigned char* (*id2Name)(U32); -}; +struct xEnt; +struct xScene; struct xEntFrame { xMat4x3 mat; + + // Offset: 0x40 xMat4x3 oldmat; + + // Offset: 0x80 xVec3 oldvel; + + // Offset: 0x8C xRot oldrot; + + // Offset: 0x9C xRot drot; xRot rot; + + // Offset: 0xBC + xVec3 dpos; + + // Offset: 0xC8 xVec3 dvel; + + // Offset: 0xD4 xVec3 vel; + + // Offset: 0xE0 U32 mode; - xVec3 dpos; }; struct xEntCollis @@ -91,92 +87,200 @@ struct xEntCollis U8 pen; U8 env_sidx; U8 env_eidx; + U8 npc_sidx; U8 npc_eidx; U8 dyn_sidx; U8 dyn_eidx; + U8 stat_sidx; U8 stat_eidx; U8 idx; + xCollis colls[18]; void (*post)(xEnt*, xScene*, F32, xEntCollis*); U32 (*depenq)(xEnt*, xEnt*, xScene*, F32, xCollis*); }; -struct xEntShadow +struct xShadowSimpleCache; +struct xEntShadow; + +typedef void (*xEntUpdateCallback)(xEnt*, xScene*, F32); +typedef void (*xEntBoundUpdateCallback)(xEnt*, xVec3*); +typedef void (*xEntMoveCallback)(xEnt*, xScene*, F32, xEntFrame*); +typedef void (*xEntRenderCallback)(xEnt*); +typedef void (*xEntTranslateCallback)(xEnt*, xVec3*, xMat4x3*); + +// Size: 0xD0 +struct xEnt : xBase { - xVec3 pos; - xVec3 vec; - RpAtomic* shadowModel; - F32 dst_cast; - F32 radius[2]; - struct + struct anim_coll_data { - S32 flg_castOnOneDFF : 1; - S32 flg_castOnAllDFF : 1; - S32 flg_disableEnvCast : 1; - S32 flg_shadowUnused : 29; + U32 flags; + U32 bones; + xMat4x3 old_mat; + xMat4x3 new_mat; + U32 verts_size; + xVec3* verts; + xVec3* normals; }; -}; -struct xEnt : xBase -{ + // Offset: 0x10 xEntAsset* asset; - U16 idx; + U16 idx; //0x14 + U16 num_updates; + + // Offset: 0x18 U8 flags; U8 miscflags; U8 subType; - U8 pflags; - U16 moreFlags; - struct - { - U8 _isCulled : 2; - U8 collisionEventReceived : 2; - }; + + // Offset: 0x1B + U8 pflags; // p -> physics flags + U8 moreFlags; //0x1c + U8 isCulled; U8 driving_count; U8 num_ffx; - U8 collType; + + // Offset: 0x20 + U8 collType; // XENT_COLLTYPE_* (defined below) U8 collLev; - U8 chkby; - U8 penby; - void (*visUpdate)(xEnt*); + U8 chkby; // XENT_COLLTYPE_* bitmask + U8 penby; // XENT_COLLTYPE_* bitmask + + // Offset: 0x24 xModelInstance* model; xModelInstance* collModel; xModelInstance* camcollModel; - void (*update)(xEnt*, xScene*, F32); - void (*endUpdate)(xEnt*, xScene*, F32); - void (*bupdate)(xEnt*, xVec3*); - void (*move)(xEnt*, xScene*, F32, xEntFrame*); - void (*render)(xEnt*); + xLightKit* lightKit; + + // Offset: 0x34 + xEntUpdateCallback update; + xEntUpdateCallback endUpdate; + xEntBoundUpdateCallback bupdate; + xEntMoveCallback move; + + // Offset: 0x44 + xEntRenderCallback render; xEntFrame* frame; - xEntCollis* collis; + xEntCollis* collis; //0x4c + + // Offset: 0x50 xGridBound gridb; + + // Offset: 0x64 xBound bound; - void (*transl)(xEnt*, xVec3*, xMat4x3*); - xFFX* ffx; + + // Offset: 0xB0 + xEntTranslateCallback transl; //0xb0 + xFFX* ffx; //0xb4 xEnt* driver; - xEnt* driven; S32 driveMode; + + // Offset: 0xC0 xShadowSimpleCache* simpShadow; xEntShadow* entShadow; anim_coll_data* anim_coll; - void* user_data; + void* user_data; // 0xCC }; -struct xEntNPCAsset +// collision types +#define XENT_COLLTYPE_NONE 0x0 +#define XENT_COLLTYPE_TRIG 0x1 // trigger (TRIG) +#define XENT_COLLTYPE_STAT 0x2 // static (SIMP) +#define XENT_COLLTYPE_DYN 0x4 // dynamic (PLAT) +#define XENT_COLLTYPE_NPC 0x8 // npc/enemy (VIL) +#define XENT_COLLTYPE_PLYR 0x10 // player (PLYR) + +// Size: 0x40 +struct xEntShadow { - S32 npcFlags; - S32 npcModel; - S32 npcProps; - U32 movepoint; - U32 taskWidgetPrime; - U32 taskWidgetSecond; + enum radius_enum + { + RADIUS_CACHE, + RADIUS_RASTER, + MAX_RADIUS + }; + + xVec3 pos; + xVec3 vec; + RpAtomic* shadowModel; + F32 dst_cast; + F32 radius[2]; }; -struct xEntNPCAssetIN : xEntNPCAsset +extern S32 xent_entent; + +xMat4x3* xEntGetFrame(const xEnt* ent); +void xEntEnable(xEnt* ent); +xVec3* xEntGetCenter(const xEnt* ent); +xVec3* xEntGetPos(const xEnt* ent); +U32 xEntIsVisible(const xEnt* ent); +void xEntHide(xEnt* ent); +void xEntShow(xEnt* ent); +void xEntInitShadow(xEnt& ent, xEntShadow& shadow); +void xEntReposition(xEnt& ent, const xMat4x3& mat); +bool xEntValidType(U8 type); +void xEntAnimateCollision(xEnt& ent, bool on); +xBox* xEntGetAllEntsBox(); +void xEntSetNostepNormAngle(F32 angle); +void xEntCollideWalls(xEnt* p, xScene* sc, F32 dt); +void xEntCollideCeiling(xEnt* p, xScene* sc, F32 dt); +void xEntCollideFloor(xEnt* p, xScene* sc, F32 dt); +xEnt* xEntCollCheckOneEntNoDepen(xEnt* ent, xScene* sc, void* data); +void xEntCollCheckNPCs(xEnt* p, xScene* sc, xEnt* (*hitIt)(xEnt*, xScene*, void*)); +void xEntCollCheckDyns(xEnt* p, xScene* sc, xEnt* (*hitIt)(xEnt*, xScene*, void*)); +void xEntCollCheckStats(xEnt* p, xScene* sc, xEnt* (*hitIt)(xEnt*, xScene*, void*)); +void xEntCollCheckNPCsByGrid(xEnt* p, xScene* sc, xEnt* (*hitIt)(xEnt*, xScene*, void*)); +void xEntCollCheckByGrid(xEnt* p, xScene* sc, xEnt* (*hitIt)(xEnt*, xScene*, void*)); +void xEntCollCheckEnv(xEnt* p, xScene* sc); +void xEntEndCollide(xEnt* ent, xScene* sc, F32 dt); +void xEntBeginCollide(xEnt* ent, xScene* sc, F32 dt); +void xEntCollide(xEnt* ent, xScene* sc, F32 dt); +void xEntApplyPhysics(xEnt* ent, xScene* sc, F32 dt); +void xEntMove(xEnt* ent, xScene* sc, F32 dt); +void xEntMotionToMatrix(xEnt* ent, xEntFrame* frame); +void xEntDefaultTranslate(xEnt* ent, xVec3* dpos, xMat4x3* dmat); +void xEntDefaultBoundUpdate(xEnt* ent, xVec3* pos); +void xEntEndUpdate(xEnt* ent, xScene* sc, F32 dt); +void xEntBeginUpdate(xEnt* ent, xScene* sc, F32 dt); +void xEntUpdate(xEnt* ent, xScene* sc, F32 dt); +void xEntRender(xEnt* ent); +void xEntRestorePipeline(xSurface*, RpAtomic* model); +void xEntRestorePipeline(xModelInstance* model); +void xEntSetupPipeline(xSurface* surf, RpAtomic* model); +void xEntSetupPipeline(xModelInstance* model); +void xEntAddToPos(xEnt* ent, const xVec3* v); +xModelInstance* xEntLoadModel(xEnt* ent, RpAtomic* imodel); +void xEntReset(xEnt* ent); +void xEntLoad(xEnt* ent, xSerial* s); +void xEntSave(xEnt* ent, xSerial* s); +void xEntSetup(xEnt* ent); +void xEntInitForType(xEnt* ent); +void xEntInit(xEnt* ent, xEntAsset* asset); +void xEntAddHittableFlag(xEnt* ent); +void xEntSceneExit(); +void xEntSceneInit(); +void xEntSetTimePassed(F32 sec); + +inline void xEntHide(xEnt* ent) { - U32 navigation_mesh_id; - U32 settings; -}; + ent->flags &= ~0x1; +} + +inline void xEntShow(xEnt* ent) +{ + ent->flags |= 0x1; +} + +inline xVec3* xEntGetPos(const xEnt* ent) +{ + return &xModelGetFrame(ent->model)->pos; +} + +inline xVec3* xEntGetCenter(const xEnt* ent) +{ + return (xVec3*)xBoundCenter(&ent->bound); +} #endif diff --git a/src/SB/Core/x/xEntBoulder.h b/src/SB/Core/x/xEntBoulder.h new file mode 100644 index 0000000..4564ba3 --- /dev/null +++ b/src/SB/Core/x/xEntBoulder.h @@ -0,0 +1,87 @@ +#ifndef XENTBOULDER_H +#define XENTBOULDER_H + +#include "xEnt.h" +#include "xDynAsset.h" +#include "xShadowSimple.h" + +struct xEntBoulderAsset +{ + F32 gravity; + F32 mass; + F32 bounce; + F32 friction; + F32 statFric; + F32 maxVel; + F32 maxAngVel; + F32 stickiness; + F32 bounceDamp; + U32 flags; + F32 killtimer; + U32 hitpoints; + U32 soundID; + F32 volume; + F32 minSoundVel; + F32 maxSoundVel; + F32 innerRadius; + F32 outerRadius; +}; + +struct xEntBoulder : xEnt +{ + xEntBoulderAsset* basset; + xShadowSimpleCache simpShadow_embedded; + xEntShadow entShadow_embedded; + xVec3 localCenter; + xVec3 vel; + xVec3 rotVec; + xVec3 force; + xVec3 instForce; + F32 angVel; + F32 timeToLive; + S32 hitpoints; + F32 lastRolling; + U32 rollingID; + U8 collis_chk; + U8 collis_pen; + U8 pad1[2]; +}; + +struct xBoulderGeneratorAsset : xDynAsset +{ + U32 object; + xVec3 offset; + F32 offsetRand; + xVec3 initvel; + F32 velAngleRand; + F32 velMagRand; + xVec3 initaxis; + F32 angvel; +}; + +struct xBoulderGenerator : xBase +{ + xBoulderGeneratorAsset* bgasset; + S32 numBoulders; + S32 nextBoulder; + xEntBoulder** boulderList; + S32* boulderAges; + U32 isMarker; + void* objectPtr; + F32 lengthOfInitVel; + xVec3 perp1; + xVec3 perp2; +}; + +void xEntBoulder_Init(void* ent, void* asset); +void xEntBoulder_Init(xEntBoulder* ent, xEntAsset* asset); +void xEntBoulder_BubbleBowl(F32 multiplier); +void xEntBoulder_Setup(xEntBoulder* ent); +void xEntBoulder_Reset(xEntBoulder* ent, xScene* scene); +void xEntBoulder_RealBUpdate(xEnt* ent, xVec3* pos); +void xEntBoulder_Kill(xEntBoulder* ent); +void xBoulderGenerator_Init(xBase& data, xDynAsset& asset, size_t); +void xBoulderGenerator_Init(xBoulderGenerator* bg, xBoulderGeneratorAsset* asset); +void xBoulderGenerator_Init(xBase& data, xDynAsset& asset); + +#endif diff --git a/src/SB/Core/x/xEntDrive.h b/src/SB/Core/x/xEntDrive.h new file mode 100644 index 0000000..b2a6f6b --- /dev/null +++ b/src/SB/Core/x/xEntDrive.h @@ -0,0 +1,41 @@ +#ifndef XENTDRIVE_H +#define XENTDRIVE_H + +#include "xEnt.h" +#include "xCollide.h" + +struct xEntDrive +{ + struct tri_data : xCollis::tri_data + { + xVec3 loc; + F32 yaw; + const xCollis* coll; + }; + + U32 flags; + F32 otm; + F32 otmr; + F32 os; + F32 tm; + F32 tmr; + F32 s; + xEnt* odriver; + xEnt* driver; + xEnt* driven; + xVec3 op; + xVec3 p; + xVec3 q; + F32 yaw; + xVec3 dloc; + + // 0x5c + tri_data tri; +}; + +void xEntDriveInit(xEntDrive* drv, xEnt* driven); +void xEntDriveMount(xEntDrive* drv, xEnt* driver, F32 mt, const xCollis* coll); +void xEntDriveDismount(xEntDrive* drv, F32 dmt); +void xEntDriveUpdate(xEntDrive* drv, xScene* s, F32 dt, xCollis* coll); + +#endif diff --git a/src/SB/Core/x/xEntMotion.h b/src/SB/Core/x/xEntMotion.h new file mode 100644 index 0000000..379e5b3 --- /dev/null +++ b/src/SB/Core/x/xEntMotion.h @@ -0,0 +1,183 @@ +#ifndef XENTMOTION_H +#define XENTMOTION_H + +#include "xEnt.h" +#include "xMovePoint.h" +#include "xColor.h" + +struct xEntMotionERData +{ + xVec3 ret_pos; + xVec3 ext_dpos; + F32 ext_tm; + F32 ext_wait_tm; + F32 ret_tm; + F32 ret_wait_tm; +}; + +struct xEntMotionOrbitData +{ + xVec3 center; + F32 w; + F32 h; + F32 period; +}; + +struct xEntMotionSplineData +{ + S32 unknown; +}; + +struct xEntMotionMPData +{ + U32 flags; + U32 mp_id; + F32 speed; +}; + +struct xEntMotionMechData +{ + U8 type; + U8 flags; + U8 sld_axis; + U8 rot_axis; + F32 sld_dist; + F32 sld_tm; + F32 sld_acc_tm; + F32 sld_dec_tm; + F32 rot_dist; + F32 rot_tm; + F32 rot_acc_tm; + F32 rot_dec_tm; + F32 ret_delay; + F32 post_ret_delay; +}; + +struct xEntMotionPenData +{ + U8 flags; + U8 plane; + U8 pad[2]; + F32 len; + F32 range; + F32 period; + F32 phase; +}; + +struct xEntMotionAsset +{ + U8 type; + U8 use_banking; + U16 flags; + union + { + xEntMotionERData er; + xEntMotionOrbitData orb; + xEntMotionSplineData spl; + xEntMotionMPData mp; + xEntMotionMechData mech; + xEntMotionPenData pen; + }; +}; + +struct xEntERData +{ + xVec3 a; + xVec3 b; + xVec3 dir; + F32 et; + F32 wet; + F32 rt; + F32 wrt; + F32 p; + F32 brt; + F32 ert; + S32 state; +}; + +struct xEntOrbitData +{ + xVec3 orig; + xVec3 c; + F32 a; + F32 b; + F32 p; + F32 w; +}; + +struct xEntSplineData +{ + S32 unknown; +}; + +struct xEntMPData +{ + F32 curdist; + F32 speed; + xMovePoint* dest; + xMovePoint* src; + xSpline3* spl; + F32 dist; + U32 padalign; + xQuat aquat; + xQuat bquat; +}; + +struct xEntMechData +{ + xVec3 apos; + xVec3 bpos; + xVec3 dir; + F32 arot; + F32 brot; + F32 ss; + F32 sr; + S32 state; + F32 tsfd; + F32 trfd; + F32 tsbd; + F32 trbd; + F32* rotptr; +}; + +struct xEntPenData +{ + xVec3 top; + F32 w; + xMat4x3 omat; +}; + +struct xEntMotion // Size: 0x70 +{ + xEntMotionAsset* asset; + U8 type; + U8 pad; + U16 flags; + F32 t; + F32 tmr; + F32 d; + union + { + xEntERData er; + xEntOrbitData orb; + xEntSplineData spl; + xEntMPData mp; + xEntMechData mech; + xEntPenData pen; + }; + xEnt* owner; + xEnt* target; +}; + +void xEntMotionInit(xEntMotion* motion, xEnt*, xEntMotionAsset* asset); +void xEntMotionReset(xEntMotion* motion, xScene* sc); +void xEntMotionMove(xEntMotion* motion, xScene* sc, F32 dt, xEntFrame* frame); +void xEntMotionTranslate(xEntMotion* motion, const xVec3* dpos, xMat4x3* dmat); +void xEntMotionDebugInit(U16 num_xems); +void xEntMotionDebugAdd(xEntMotion*); +void xEntMotionDebugExit(); +void xEntMotionStop(xEntMotion* motion); +void xEntMotionRun(xEntMotion* motion); +U32 xEntMotionIsStopped(const xEntMotion* motion); + +#endif diff --git a/src/SB/Core/x/xEnv.h b/src/SB/Core/x/xEnv.h index e10a85f..d72573b 100644 --- a/src/SB/Core/x/xEnv.h +++ b/src/SB/Core/x/xEnv.h @@ -1,43 +1,54 @@ #ifndef XENV_H #define XENV_H -#include "xModel.h" -#include "xJSP.h" +#include "iEnv.h" +#include "xLightKit.h" +#include "xBase.h" -struct iEnvMatOrder +struct xEnv { - U16 jspIndex; - U16 nodeIndex; - S32 matGroup; - RpAtomic* atomic; - xJSPNodeInfo* nodeInfo; + iEnv* geom; + iEnv ienv; + xLightKit* lightKit; }; -struct iEnv +struct xEnvAsset : xBaseAsset { - RpWorld* world; - RpWorld* collision; - RpWorld* fx; - RpWorld* camera; - S32 jsp_count; - U32* jsp_aid; - xJSPHeader** jsp_list; - xBox* jsp_bound; - S32* jsp_visibilityCount; - S32 jspMatOrderCount; - iEnvMatOrder* jspMatOrderList; - RpLight* light[2]; - RwFrame* light_frame[2]; - S32 memlvl; - U16 numOpaque; - U16 numTransparent; + U32 bspAssetID; + U32 startCameraAssetID; + U32 climateFlags; + F32 climateStrengthMin; + F32 climateStrengthMax; + U32 bspLightKit; + U32 objectLightKit; + F32 padF1; + U32 bspCollisionAssetID; + U32 bspFXAssetID; + U32 bspCameraAssetID; + U32 bspMapperID; + U32 bspMapperCollisionID; + U32 bspMapperFXID; + F32 loldHeight; }; -struct xEnv +struct _zEnv : xBase { - iEnv* geom; - iEnv ienv; - xLightKit* lightKit; + xEnvAsset* easset; }; +void zEnvInit(void* env, void* easset); +void zEnvInit(_zEnv* env, xEnvAsset* easset); +void zEnvSetup(_zEnv* env); +void zEnvStartingCamera(_zEnv* env); +void zEnvRender(xEnv* env); +void zEnvSave(_zEnv* ent, xSerial* s); +void zEnvLoad(_zEnv* ent, xSerial* s); +void zEnvReset(_zEnv* env); +S32 zEnvEventCB(xBase*, xBase* to, U32 toEvent, const F32* toParam, xBase*); + +void xEnvLoadBsp(xEnv* env, const void* data, U32 datasize, S32 dataType); +void xEnvFree(xEnv* env); +void xEnvSetup(xEnv* env); +void xEnvRender(xEnv* env); + #endif diff --git a/src/SB/Core/x/xMail.h b/src/SB/Core/x/xEvent.h similarity index 56% rename from src/SB/Core/x/xMail.h rename to src/SB/Core/x/xEvent.h index 775c85e..87b739b 100644 --- a/src/SB/Core/x/xMail.h +++ b/src/SB/Core/x/xEvent.h @@ -1,5 +1,7 @@ -#ifndef XMAIL_H -#define XMAIL_h +#ifndef XEVENT_H +#define XEVENT_H + +#include "xBase.h" enum en_xEventTags { @@ -182,14 +184,14 @@ enum en_xEventTags eEventAttackOn, eEventAttackOff, eEventDrop, - eEventUIAddChar, - eEventUIDelChar, - eEventUIStringEmpty, - eEventUIStringFull, - eEventUISendStringAsCheat, - eEventUISetMaxChars, - eEventUICheatOK, - eEventUICheatBad, + eEventVilReport_StartingIdle, + eEventVilReport_StartingSleep, + eEventVilReport_StartingGuard, + eEventVilReport_StartingPatrol, + eEventVilReport_StartingDazed, + eEventVilReport_StartingLook, + eEventVilReport_StartingListen, + eEventVilReport_StartingInvestigate, eEventVilReport_StartingChase, eEventVilReport_StartingAttack, eEventVilReport_StartingRetreat, @@ -210,11 +212,11 @@ enum en_xEventTags eEventAccelerate, eEventMoveToTarget, eEventSwingerFollow, - eEventImpact, - eEventStartTimer, - eEventFinishedTimer, - eEventUIReset, - eEventSetScaleFactor, + eEventShaggyMount, + eEventShaggyWitchDrop, + eEventShaggySwap, + eEventShaggyState, + eEventShaggyAction, eEventEnterEntity, eEventExitEntity, eEventEnterEntityFLAG, @@ -223,23 +225,23 @@ enum en_xEventTags eEventFollowTarget, eEventFaceTarget, eEventWatchTarget, - eEventCarChangeLaneRight, - eEventCarChangeLaneLeft, - eEventCarStart, - eEventCarSetSwerveMode, - eEventIncreaseSpeed, - eEventDecreaseSpeed, + eEventShaggyCollideOnly, + eEventShaggy1_ThrowTarget, + eEventShaggy8_CallEnable, + eEventShaggy8_CallDisable, + eEventShaggy8_SetMagnet, + eEventShaggy8_ClearMagnet, eEventStartMoving, eEventStopMoving, eEventSwoosh, - eEventTurretDestroyed, - eEventNPCSpeakStop, - eEventStartRumbleEffect, - eEventNavigateTo, - eEventNPCSpeakStart, - eEventNPCAlert, - eEventNPCPatrolDelay, - eEventNPCScrambleActionEnd, + eEventShaggySetDown, + eEventShaggyGrabEnable, + eEventShaggyGrabDisable, + eEventShaggyGrabbed, + eEventShaggyThrown, + eEventVilDoAction, + eEventGangDoBossAction, + eEventVilFakeChaseOn, eEventVilFakeChaseOff, eEventBossMMPushButton, eEventVilReport_DecayComplete, @@ -258,35 +260,35 @@ enum en_xEventTags eEventTranslucentOn, eEventTranslucentOff, eEventTranslucentToggle, - eEventZipLineEnvDamage, + eEventVilGangTalkOn, eEventVilGangTalkOff, eEventGivePowerUp, - eEventRaceTimerReset, - eEventFireCruiseBubble, - eEventCarSuccessAnimPlay, - eEventCarFailureAnimPlay, + eEventUnlockR001, + eEventUnlockS001, + eEventUnlockE001, + eEventUnlockF001, eEventDisableGroupContents, - eEventNPCCharge, + eEventShaggyPhysHack, eEventOccludeOn, eEventOccludeOff, - eEventRaceTimerPause, - eEventRaceTimerResume, - eEventRaceTimerSetBestTime, - eEventRaceTimerWarning1, - eEventRaceTimerWarning2, - eEventRaceTimerWarning3, - eEventRingChallengeStart, - eEventCarStop, - eEventRingChallengeRun, - eEventRingChallengeReset, - eEventRingChallengeSuccess, - eEventRingChallengeFailed, - eEventFormationChanged, - eEventChargeResume, - eEventChargePause, - eEventNPCChargeStop, - eEventNPCChargeCompleted, - eEventFormationChargeStart, + eEventWaveSetLinear, + eEventWaveSetRipple, + eEventSituationLaugh, + eEventSituationBossBattleGreenGhost, + eEventSituationBossBattleRedBeard, + eEventSituationBossBattleMasterMind, + eEventSituationBossBattleBlacknight, + eEventSituationPlayerScare, + eEventSituationPlayerSafe, + eEventSituationPlayerDanger, + eEventSituationPlayerChaseBegin, + eEventSituationPlayerChaseEnd, + eEventSituationPlayerSeeShaggy, + eEventSituationPlayerSeeFood, + eEventSituationPlayerSeeToken, + eEventSituationPlayerSeeScoobySnack, + eEventSituationPlayerSeePowerup, + eEventSituationPlayerSeeMonster, eEventSituationPlayerSuccess, eEventSituationPlayerFailure, eEventDispatcher_ShowHud, @@ -294,19 +296,19 @@ enum en_xEventTags eEventDispatcher_FadeOut, eEventSetRain, eEventSetSnow, - eEventScriptNoop, + eEventShaggyMowerStopMode, eEventScriptReset, eEventWaitForInput, eEventPlayMovie, - eEventCelebrationAnimPlay, + eEventDefeatedMM, eEventDispatcher_SetGameState_GameStats, - eEventMusicNewSong, + eEventPlayMusic, eEventForward, eEventReverse, - eEventDeprecatedRumbleTest, - eEventDeprecatedRumbleLight, - eEventDeprecatedRumbleMedium, - eEventDeprecatedRumbleHeavy, + eEventPlayerRumbleTest, + eEventPlayerRumbleLight, + eEventPlayerRumbleMedium, + eEventPlayerRumbleHeavy, eEventDispatcherScreenAdjustON, eEventDispatcherScreenAdjustOFF, eEventSetSkyDome, @@ -428,10 +430,10 @@ enum en_xEventTags eEventSetState, eEventEnterSpongeBob, eEventEnterPatrick, - eEventEnterSandyUNUSED, + eEventEnterSandy, eEventExitSpongeBob, eEventExitPatrick, - eEventExitSandyUNUSED, + eEventExitSandy, eEventNPCSpecial_PlatformSnap, eEventNPCSpecial_PlatformFall, eEventGooSetWarb, @@ -500,7 +502,7 @@ enum en_xEventTags eEventSituationSeeKingJellyfish, eEventSituationSeePrawn, eEventSituationSeeDutchman, - eEventSituationSeeSandyBossUNUSED, + eEventSituationSeeSandyBoss, eEventSituationSeePatrickBoss, eEventSituationSeeSpongeBobBoss, eEventSituationSeeRobotPlankton, @@ -515,7 +517,7 @@ enum en_xEventTags eEventCameraFXShake, eEventBulletTime, eEventThrown, - eEventNPCPatrol, + eEventUpdateAnimMatrices, eEventEnterCruise, eEventExitCruise, eEventCruiseFired, @@ -537,19 +539,6 @@ enum en_xEventTags eEventBubbleWipe, eEventSetLightKit, eEventSetOpacity, - eEventDispatcher_SetSoundEffect, - eEventScale, - eEventSetReference, - eEventWarpSetWorld, - eEventWarpSetTask, - eEventWarpGo, - eEventSetCount, - eEventGetDashSpeed, - eEventDashTrip, - eEventDashBurst, - eEventDashFast, - eEventDashNormal, - eEventDashSlow, eEventTakeSocks, eEventDispatcherAssert, eEventBorn, @@ -557,319 +546,22 @@ enum en_xEventTags eEventPlatUnpause, eEventStoreOptions, eEventRestoreOptions, - eEventUISetMotion, - eEventUIMotionFinished, - eEventUIMotionLoop, - eEventDestructibleLaunch, - eEventDestructibleRespawn, - eEventKaboomStart, - eEventKaboomStop, - eEventNPCAttack, - eEventNPCDefend, - eEventTrainCarSpeed, - eEventTrainJunctOut1, - eEventTrainJunctOut2, - eEventTrainJunctSwitch, - eEventTrainJunctPassed, - eEventTrainCarDetach, - eEventTrainCarExplode, - eEventNet_InitNetAPI, - eEventNet_UpdateConnection, - eEventNet_UpdateOnlineTask, - eEventNet_UpdateUserList, - eEventNet_CheckForNewContent, - eEventNet_SelectDevice, - eEventNet_SelectContent, - eEventNet_VerifyContent, - eEventNet_RemoveContent, - eEventNet_SelectDeviceAfterRemove, - eEventNet_ConfirmUseContentIdx, - eEventNet_ConfirmNoUseContentIdx, - eEventNet_NoContentInstalled, - eEventNet_NoContentAvailable, - eEventNet_NewContentAvailable, - eEventSceneEnableDraw, - eEventSceneDisableDraw, - eEventLightningStart, - eEventLightningStop, - eEventChangeBossUIStage, - eEventStaticCameraStart, - eEventStaticCameraEnd, - eEventSetCameraStartOrientation, - eEventNMESetMovepointPath, - eEventNMEScareBegin, - eEventNMEScareSkip, - eEventNMESetMovepointGroup, - eEventVentSetStateIdle, - eEventVentSetStateWarn, - eEventVentSetStateDamage, - eEventVentSetStateOff, - eEventWaterhoseStart, - eEventWaterhoseStop, - eEventWaterhoseSetLength, - eEventCarried, - eEventExplode, - eEventJumpTo, - eEventJumpOnSpawn, - eEventPlayerHit, - eEventStartFade, - eEventFadeDownDone, - eEventFadeUpDone, - eEventBounce, - eEventLaunchNPC, - eEventUpgradePowerUp, - eEventBulletStreak, - eEventSetFollowCameraOrientation, - eEventHDRFade, - eEventStart, - eEventSuccess, - eEventFailure, - eEventEnableRestore, - eEventDisableRestore, - eEventNPCSpawn, - eEventSpawnDone, - eEventSpawnedNPCKilled, - eEventSpawnedNPCNoHealth, - eEventSpawnedNPCAllKilled, - eEventSpawnedNPCAllNoHealth, - eEventDashTimerSet, - eEventDashNotOutOfTime, - eEventDashOutOfTime, - eEventForceSceneReset, - eEventNPCActive, - eEventNPCInactive, - eEventDuplicatorActive, - eEventDuplicatorInactive, - eEventDashEnterTunnel, - eEventDashExitTunnel, - eEventStopRumbleEffect, - eEventDashChaseLasersOn, - eEventDashChaseLasersOff, - eEventJumpRandomOnSpawn, - eEventHit_Cartwheel, - eEventUIVisible_FocusOn_Select, - eEventUIFocusOff_Unselect_Invisible, - eEventCopyReference, - eEventUIMotionFinishedIn, - eEventUIMotionFinishedOut, - eEventUISignalActivateScreen, - eEventUISignalDeactivateScreen, - eEventUISignalActivatedScreen, - eEventUISignalSwitchScreens, - eEventUISignalStartFadeOut, - eEventUISignalStartFadeIn, - eEventUISignalScreenMotionInDone, - eEventUISignalScreenMotionOutDone, - eEventUISignalMainBoxInDone, - eEventUISignalMainBoxOutDone, - eEventUIResetMotion, - eEventUIEnableHDR, - eEventUIDisableHDR, - eEventUIBrighten, - eEventUIUnbrighten, - eEventUISignalDeactivatedScreen, - eEventNPCDetectAlways, - eEventNPCDetectNever, - eEventNPCDetectNormal, - eEventNPCFightDefault, - eEventCameraCollidePartial, - eEventMusicTempSong, - eEvaluateCounterValue, - eEventCount0, - eEventRotToAbsoluteX, - eEventRotToAbsoluteY, - eEventRotToAbsoluteZ, - eEventTriggerAnim, - eEventTriggeredAnimDone, - eEventUISignalMore, - eEventUISignalNoMore, - eEventUISignalLess, - eEventUISignalNoLess, - eEventUISignalUp, - eEventUISignalDown, - eEventUISignalSyncToCurrent, - eEventUISignalEffect, - eEventFreezePlayer, - eEventUnfreezePlayer, - eEventUISignalMapStart, - eEventUISignalMapEnd, - eEventTransToAbsoluteX, - eEventTransToAbsoluteY, - eEventTransToAbsoluteZ, - eEventJSPVisibilityIncrement, - eEventJSPVisibilityDecrement, - eEventEnterCamera, - eEventExitCamera, - eEventPadPressE, - eEventSetDashJumpParameters, - eEventViperFacePlayer, - eEventViperFaceMovement, - eEventRequestStart, - eEventUIAutoMenuRun, - eEventUIAutoMenuRunUp, - eEventUIAutoMenuRunDown, - eEventUIAutoMenuRunLeft, - eEventUIAutoMenuRunRight, - eEventIncrementSuccess, - eEventDecrementSuccess, - eEventIncrementFailed, - eEventDecrementFailed, - eEventMusicTempSongStop, - eEventNPCScrambleActionBegin, - eEventNPCScrambleAlert, - eEventNPCSetTurretAttackRadius, - eEventGooFreezeStart, - eEventGooMeltStart, - eEventNPCNotice, - eEventBossStageSet, - eEventBossStageBegan, - eEventBossStageEnded, - eEventBossStageBeganA, - eEventBossStageEndedA, - eEventBossStageBeganB, - eEventBossStageEndedB, - eEventBossStageBeganC, - eEventBossStageEndedC, - eEventVisibilityCullOn, - eEventVisibilityCullOff, - eEventRBandCameraStart, - eEventRBandCameraEnd, - eEventMindyStart, - eEventMindyEnd, - eEventFlamethrowerStart, - eEventFlamethrowerStop, - eEventFlamethrowerSetLength, - eEventNPCTakeNoDamageOn, - eEventNPCTakeNoDamageOff, - eEventStaticCameraStartFOVFilter, - eEventStaticCameraRestoreFOV, - eEventUIXboxDemoExitToLauncher, - eEventSpawn, - eEventSpawned, - eEventCreditsSetDest, - eEventAllowAttractMode, - eEventDisallowAttractMode, - eEventRocketAttack, - eEventCollisionReset, - eEventAutoSave, - eEventOpenBonus, - eEventFlagLevel, - eEventLevelEnd, - eEventNet_GetLocalContentDevice, - eEventDispatcher_PauseGame_Safe, - eEventOverrideFreqency, - eEventResetFrequency, - eEventSetShotDelay, - eEventSetShotsInGroup, - eEventDispatcher_UserSelectYes, - eEventDispatcher_UserSelectNo, - eEventDispatcher_UserSelectBack, - eEventLaunchFireWorks, - eEventDispatcher_UserSelectionReset, - eEventSetAsBounceBack, - eEventUIResetUnlockables, - eEventUISysMessageWaitResponse, - eEventUISysMessageWaitConfirm, - eEventUISysMessageConfirm, - eEventUISysMessageAccept, - eEventUISysMessageDecline, - eEventSetAsBounceBack_Cancel, - eEventDispatcher_PauseGame, - eEventPattyWagonStartEngine, - eEventPattyWagonStopEngine, - eEventSpawnBubblesOn, - eEventSpawnBubblesOff, - eEventNet_XBLiveToggleSignIn, - eEventNet_XBLiveManageFriends, - eEventApplyOnResetOn, - eEventApplyOnResetOff, - eEventSnapTo, - eEventThrow, - eEventFirstZipLine, - eEventFirstLedgeGrab, - eEventFirstIncredimeterPickup, - eEventUISparkTrail, - eEventUIGetBattleScenes, - eEventUIBattleScenesAvailable, - eEventUIBattleScenesNotAvailable, - eEventNet_XBLiveToggleAppearOnline, - eEventSys_ReturnPrevScreen, - eEventSys_Nope, - eEventDispatcher_SubtitlesOn, - eEventDispatcher_SubtitlesOff, - eEventUISetBoxMapping, - eEventTBoxPlayerEjected, - eEventDamagePlayer, - eEventFirstHealthPickup, - eEventTokenPickupComplete, - eEventDispatcher_LoadSavePromptDead, - eEventUIFlipVisibility, - eEventNet_XBLiveRebootToDashboard, - eEventFirstPowerupPoint, eEventCount }; -enum en_npcmsg -{ - NME_MID_NONE, - NME_MID_SYSEVENT, - NME_MID_RESPAWN, - NME_MID_DAMAGE, - NME_MID_EXPLOSION, - NME_MID_BUNNYHOP, - NME_MID_NEWDEST, - NME_MID_DTRON_NMEEMIT, - NME_MID_DTRON_NMEAVAIL, - NME_MID_DTRON_ISDEAD, - NME_MID_CHAT_REQUEST, - NME_MID_CHAT_DECLINE, - NME_MID_CHAT_ACCEPT, - NME_MID_CHAT_DONE, - NME_MID_CHAT_ABORT, - NME_MID_TALKSTART, - NME_MID_TALKON, - NME_MID_TALKOFF, - NME_MID_SAWPLYR, - NME_MID_NEEDMEDIC, - NME_MID_UNDERATTACK, - NME_MID_NMEDIED, - NME_MID_PLYRSPATULA, - NME_MID_BECOMESCARED, - NME_MID_NOLONGERSCARED, - NME_MID_CELEBRATE, - NME_MID_STUN, - NME_MID_SCRIPTBEGIN, - NME_MID_SCRIPTEND, - NME_MID_SCRIPTHALT, - NME_MID_NOMORE, - NME_MID_FORCE = 0x7fffffff -}; - -enum en_msgdata -{ - NME_MDAT_BLANK, - NME_MDAT_SYSEVENT, - NME_MDAT_BLAST, - NME_MDAT_CHAT, - NME_MDAT_SPAWN, - NME_MDAT_TARGET, - NME_MDAT_DAMAGE, - NME_MDAT_STUN, - NME_MDAT_SCRIPT, - NME_MDAT_MOUNT, - NME_MDAT_AREANOTIFY, - NME_MDAT_NOMORE, - NME_MDAT_FORCE = 0x7fffffff -}; - -enum en_carystat -{ - zNMECARRY_NONE, - zNMECARRY_PICKUP, - zNMECARRY_TWIRL, - zNMECARRY_THROW, - zNMECARRY_ATTEMPTPICKUP, - zNMECARRY_FORCEINT = 0x7fffffff -}; +// Oddly, all the zEntEvent functions are in xEvent, not zEvent +void zEntEvent(char* to, U32 toEvent); +void zEntEvent(U32 toID, U32 toEvent); +void zEntEvent(U32 toID, U32 toEvent, F32 toParam0, F32 toParam1, F32 toParam2, + F32 toParam3); +void zEntEvent(xBase* to, U32 toEvent); +void zEntEvent(xBase* to, U32 toEvent, F32 toParam0, F32 toParam1, F32 toParam2, + F32 toParam3); +void zEntEvent(xBase* to, U32 toEvent, const F32* toParam); +void zEntEvent(xBase* to, U32 toEvent, const F32* toParam, xBase* toParamWidget); +void zEntEvent(xBase* from, xBase* to, U32 toEvent); +void zEntEvent(xBase* from, xBase* to, U32 toEvent, const F32* toParam); +void zEntEvent(xBase* from, U32 fromEvent, xBase* to, U32 toEvent, const F32* toParam, + xBase* toParamWidget, S32 forceEvent); #endif diff --git a/src/SB/Core/x/xFColor.h b/src/SB/Core/x/xFColor.h new file mode 100644 index 0000000..3e0596f --- /dev/null +++ b/src/SB/Core/x/xFColor.h @@ -0,0 +1,14 @@ +#ifndef XFCOLOR_H +#define XFCOLOR_H + +#include + +struct _xFColor +{ + F32 r; + F32 g; + F32 b; + F32 a; +}; + +#endif diff --git a/src/SB/Core/x/xFFX.h b/src/SB/Core/x/xFFX.h new file mode 100644 index 0000000..17499f6 --- /dev/null +++ b/src/SB/Core/x/xFFX.h @@ -0,0 +1,60 @@ +#ifndef XFFX_H +#define XFFX_H + +#include "xMath3.h" + +struct xScene; +struct xEnt; + +struct xFFX +{ + U32 flags; + void (*doEffect)(xEnt*, xScene*, F32, void*); + void* fdata; + xFFX* next; +}; + +struct xFFXShakeState +{ + xVec3 disp; + F32 dur; + F32 freq; + F32 tmr; + F32 alpha; + F32 lval; + xFFXShakeState* next; +}; + +struct xFFXRotMatchState +{ + S32 lgrounded; + xVec3 lfup; + xVec3 lfat; + xVec3 plfat; + F32 tmr; + F32 mrate; + F32 tmatch; + F32 rrate; + F32 trelax; + F32 max_decl; + xFFXRotMatchState* next; +}; + +void xFFXPoolInit(U32 num_ffx); +xFFX* xFFXAlloc(); +void xFFXFree(xFFX* ffx); +void xFFXTurnOn(xFFX* f); +void xFFXTurnOff(xFFX* f); +S16 xFFXAddEffect(xEnt* ent, xFFX* f); +S16 xFFXAddEffect(xEnt* ent, void (*dof)(xEnt*, xScene*, F32, void*), void* fd); +U32 xFFXRemoveEffectByFData(xEnt* ent, void* fdata); +void xFFXApplyOne(xFFX* ffx, xEnt* ent, xScene* sc, F32 dt); +void xFFXApply(xEnt* ent, xScene* sc, F32 dt); +void xFFXShakeUpdateEnt(xEnt* ent, xScene* sc, F32 dt, void* fdata); +void xFFXShakePoolInit(U32 num); +xFFXShakeState* xFFXShakeAlloc(); +void xFFXShakeFree(xFFXShakeState* s); +void xFFXRotMatchPoolInit(U32 num); +xFFXRotMatchState* xFFXRotMatchAlloc(); + +#endif diff --git a/src/SB/Core/x/xFX.h b/src/SB/Core/x/xFX.h index 1b1232c..4f85a47 100644 --- a/src/SB/Core/x/xFX.h +++ b/src/SB/Core/x/xFX.h @@ -1,10 +1,133 @@ #ifndef XFX_H #define XFX_H -#include "xMath.h" +#include "xMath3.h" +#include "containers.h" +#include "iColor.h" -struct xFFX +#include +#include + +class xModelInstance; + +struct xFXRing { + U32 texture; + F32 lifetime; + xVec3 pos; + F32 time; // 0x14 + F32 ring_radius; + F32 ring_radius_delta; // 0x1c + F32 ring_tilt; + F32 ring_tilt_delta; // 0x24? + F32 ring_height; // 0x28 + F32 ring_height_delta; + iColor_tag ring_color; + U16 ring_segs; + U8 u_repeat; + U8 v_repeat; + xFXRing** parent; +}; + +struct xFXRibbon +{ + struct config + { + F32 life_time; + U32 blend_src; + U32 blend_dst; + F32 pivot; + }; + + struct joint_data + { + U32 flags; + U32 born; + xVec3 loc; + xVec3 norm; + F32 orient; + F32 scale; + F32 alpha; + }; + + struct curve_node + { + F32 time; + iColor_tag color; + F32 scale; + }; + + config cfg; + bool activated; + RwRaster* raster; + tier_queue joints; + curve_node* curve; + U32 curve_size; + U32 curve_index; + F32 ilife; + U32 mtime; + U32 mlife; + + void init(const char*, const char*); + void set_texture(const char* name); + void set_curve(const curve_node* curve, size_t size); + void refresh_config(); + void set_default_config(); + void update_curve_tweaks(); + void debug_init(const char*, const char*); + void debug_update_curve(); + void debug_update(F32); }; +#define RING_COUNT 8 + +extern xFXRing ringlist[RING_COUNT]; + +void xFXInit(); +xFXRing* xFXRingCreate(const xVec3* pos, const xFXRing* params); +void xFXRingRender(); +void xFX_SceneEnter(RpWorld* world); +void xFX_SceneExit(RpWorld* world); +void xFXUpdate(F32 dt); +RpAtomic* AtomicDisableMatFX(RpAtomic* atomic); +void xFXPreAllocMatFX(RpClump* clump); + +RpAtomic* xFXBubbleRender(RpAtomic* atomic); + +void xFXanimUV2PSetTexture(RwTexture* texture); +void xFXanimUVSetTranslation(const xVec3* trans); +void xFXanimUV2PSetTranslation(const xVec3* trans); +void xFXanimUVSetScale(const xVec3* scale); +void xFXanimUV2PSetScale(const xVec3* scale); +void xFXanimUVSetAngle(F32 angle); +void xFXanimUV2PSetAngle(F32 angle); +RpAtomic* xFXanimUVAtomicSetup(RpAtomic* atomic); +U32 xFXanimUVCreate(); +void xFXFireworksInit(const char* fireworksTrailEmitter, const char* fireworksEmitter1, + const char* fireworksEmitter2, const char* fireworksSound, + const char* fireworksLaunchSound); +void xFXFireworksLaunch(F32 countdownTime, const xVec3* pos, F32 fuelTime); +void xFXFireworksUpdate(F32 dt); +void xFXStreakInit(); +void xFXStreakUpdate(F32 dt); +void xFXStreakUpdate(U32 streakID, const xVec3*, const xVec3*); +void xFXStreakRender(); +void xFXStreakStop(U32); +void xFXShineInit(); +void xFXShineUpdate(F32 dt); +void xFXShineRender(); +RpAtomic* xFXAtomicEnvMapSetup(RpAtomic* atomic, U32 envmapID, F32 shininess); +void xFXRibbonSceneEnter(); +void xFXRibbonUpdate(F32 dt); +void xFXRibbonRender(); +void xFXAuraInit(); +void xFXAuraUpdate(F32 dt); +void xFXAuraRender(); +void xFXRenderProximityFade(const xModelInstance& model, F32 near_dist, F32 far_dist); +void xFXSceneInit(); +void xFXSceneSetup(); +void xFXSceneReset(); +void xFXScenePrepare(); +void xFXSceneFinish(); + #endif diff --git a/src/SB/Core/x/xFXHighDynamicRange.h b/src/SB/Core/x/xFXHighDynamicRange.h new file mode 100644 index 0000000..e69de29 diff --git a/src/SB/Core/x/xFactory.h b/src/SB/Core/x/xFactory.h new file mode 100644 index 0000000..b3ed128 --- /dev/null +++ b/src/SB/Core/x/xFactory.h @@ -0,0 +1,55 @@ +#ifndef XFACTORY_H +#define XFACTORY_H + +#include + +#include "xRMemData.h" +#include "xordarray.h" + +struct xFactoryInst : RyzMemData +{ + S32 itemType; + xFactoryInst* nextprod; + xFactoryInst* prevprod; + + xFactoryInst() + { + itemType = 0; + prevprod = NULL; + nextprod = NULL; + } + + ~xFactoryInst() + { + } +}; + +typedef xFactoryInst* (*XGOFTypeInfoCreator)(S32, RyzMemGrow*, void*); +typedef void (*XGOFTypeInfoDestroyer)(xFactoryInst*); + +struct XGOFTypeInfo +{ + S32 tid; + XGOFTypeInfoCreator creator; + XGOFTypeInfoDestroyer destroyer; +}; + +struct xFactory : RyzMemData +{ + XGOFTypeInfo* infopool; + st_XORDEREDARRAY infolist; + xFactoryInst* products; + RyzMemGrow growContextData; + + xFactory(S32 maxTypes); + void DestroyItem(xFactoryInst* item); + void DestroyAll(); + xFactoryInst* CreateItem(S32 typeID, void* userdata, RyzMemGrow* callerzgrow); + void GrowDataDisable(); + void GrowDataEnable(xBase* user, S32 isResume); + S32 RegItemType(S32 tid, XGOFTypeInfoCreator create, XGOFTypeInfoDestroyer destroy); + S32 RegItemType(XGOFTypeInfo* info); + ~xFactory(); +}; + +#endif diff --git a/src/SB/Core/x/xFile.h b/src/SB/Core/x/xFile.h new file mode 100644 index 0000000..3ff4e2b --- /dev/null +++ b/src/SB/Core/x/xFile.h @@ -0,0 +1,26 @@ +#ifndef XFILE_H +#define XFILE_H + +#include "iFile.h" + +enum XFILE_READSECTOR_STATUS +{ + XFILE_RDSTAT_NOOP, + XFILE_RDSTAT_INPROG, + XFILE_RDSTAT_DONE, + XFILE_RDSTAT_FAIL, + XFILE_RDSTAT_QUEUED, + XFILE_RDSTAT_EXPIRED +}; + +struct tag_xFile +{ + char relname[32]; + tag_iFile ps; + void* user_data; +}; + +void xFileSetUserData(tag_xFile* file, void* userdata); +XFILE_READSECTOR_STATUS xFileReadAsyncStatus(S32 key, S32* amtToFar); + +#endif diff --git a/src/SB/Core/x/xFog.h b/src/SB/Core/x/xFog.h new file mode 100644 index 0000000..d7fd9f1 --- /dev/null +++ b/src/SB/Core/x/xFog.h @@ -0,0 +1,35 @@ +#ifndef XFOG_H +#define XFOG_H + +#include "xEnt.h" +#include "xBase.h" + +#include + +struct xFogAsset : xBaseAsset +{ + U8 bkgndColor[4]; + U8 fogColor[4]; + F32 fogDensity; + F32 fogStart; + F32 fogStop; + F32 transitionTime; + U8 fogType; + U8 padFog[3]; +}; + +struct _xFog : xBase +{ + xFogAsset* tasset; +}; + +void xFogClearFog(); +void xFogInit(void* b, void* tasset); +void xFogInit(xBase* ent, xFogAsset* tasset); +void xFogReset(_xFog* ent); +void xFogSave(_xFog* ent, xSerial* s); +void xFogLoad(_xFog* ent, xSerial* s); +S32 xFogEventCB(xBase* to, xBase* from, U32 toEvent, const F32* toParam, xBase* b3); +void xFogUpdate(xBase* ent, xScene* sc, F32 dt); + +#endif diff --git a/src/SB/Core/x/xFont.h b/src/SB/Core/x/xFont.h new file mode 100644 index 0000000..055fa11 --- /dev/null +++ b/src/SB/Core/x/xFont.h @@ -0,0 +1,219 @@ +#ifndef XFONT_H +#define XFONT_H + +#include "xMath2.h" +#include "iColor.h" +#include "xString.h" + +#include + +struct xfont +{ + U32 id; + F32 width; + F32 height; + F32 space; + iColor_tag color; + basic_rect clip; + + static void init(); + static void set_render_state(RwRaster* raster); + static void restore_render_state(); + static xfont create(); + static xfont create(U32 id, F32 width, F32 height, F32 space, iColor_tag color, + const basic_rect& clip); + + basic_rect bounds(char c) const; + basic_rect bounds(const char* text) const; + basic_rect bounds(const char* text, size_t text_size, F32 max_width, + size_t& size) const; + void start_render() const; + void stop_render() const; + void irender(const char* text, F32 x, F32 y) const; + void irender(const char* text, size_t text_size, F32 x, F32 y) const; + void render(const char* text, F32 x, F32 y) const; + + xfont& operator=(const xfont& rhs) + { + id = rhs.id; + width = rhs.width; + height = rhs.height; + space = rhs.space; + + *(U32*)(&color) = *(U32*)(&rhs.color); + + *(U32*)(&clip.x) = *(U32*)(&rhs.clip.x); + *(U32*)(&clip.y) = *(U32*)(&rhs.clip.y); + *(U32*)(&clip.w) = *(U32*)(&rhs.clip.w); + *(U32*)(&clip.h) = *(U32*)(&rhs.clip.h); + + return *this; + } +}; + +struct xtextbox +{ + struct callback; + struct tag_type; + struct layout; + + struct jot + { + substr s; + + struct + { + // Offset: 0x8 + bool invisible : 1; // bit 24 + bool ethereal : 1; // bit 25 + bool merge : 1; // bit 26 + bool word_break : 1; // bit 27 + bool word_end : 1; // bit 28 + bool line_break : 1; // bit 29 + bool stop : 1; // bit 30 + bool tab : 1; // bit 31 + + // Offset: 0x9 + bool insert : 1; // bit 24 + bool dynamic : 1; // bit 25 + bool page_break : 1; // bit 26 + bool stateful : 1; // bit 27 + U16 dummy : 4; // bits 28-31 + } flag; + // Offset: 0xC + U16 context_size; + + // Offset: 0x10 + void* context; + basic_rect bounds; + basic_rect render_bounds; + const callback* cb; + tag_type* tag; + + void intersect_flags(const jot& other); + void reset_flags(); + }; + + struct split_tag + { + substr tag; + substr name; + substr action; + substr value; + }; + + struct tag_type + { + substr name; + void (*parse_tag)(jot&, const xtextbox&, const xtextbox&, const split_tag&); + void (*reset_tag)(jot&, const xtextbox&, const xtextbox&, const split_tag&); + void* context; + }; + + struct callback + { + void (*render)(const jot&, const xtextbox&, F32, F32); + void (*layout_update)(const jot&, xtextbox&, const xtextbox&); + void (*render_update)(const jot&, xtextbox&, const xtextbox&); + }; + + struct jot_line + { + basic_rect bounds; + F32 baseline; + size_t first; + size_t last; + U8 page_break; + }; + + struct tag_entry + { + substr name; + char op; + substr* args; + size_t args_size; + }; + + struct tag_entry_list + { + tag_entry* entries; + size_t size; + }; + + xfont font; + basic_rect bounds; + U32 flags; + F32 line_space; + F32 tab_stop; + F32 left_indent; + F32 right_indent; + callback* cb; + void* context; + const char** texts; + const size_t* text_sizes; + size_t texts_size; + substr text; + size_t text_hash; + + static callback text_cb; + + static void text_render(const jot& j, const xtextbox& tb, F32 x, F32 y); + static tag_entry_list read_tag(const substr& s); + static tag_entry* find_entry(const tag_entry_list& el, const substr& name); + static size_t read_list(const tag_entry& e, F32* v, size_t vsize); + static size_t read_list(const tag_entry& e, S32* v, size_t vsize); + static void clear_layout_cache(); + static void register_tags(const tag_type* tag, size_t count); + static tag_type* find_format_tag(const substr& s); + static tag_type* find_format_tag(const substr& s, S32& index); + static xtextbox create(); + static xtextbox create(const xfont& font, const basic_rect& bounds, U32 flags, + F32 line_space, F32 tab_stop, F32 left_indent, + F32 right_indent); + + void set_text(const char* text); + void set_text(const char* text, size_t text_size); + void set_text(const char** texts, size_t size); + void set_text(const char** texts, const size_t* text_sizes, size_t size); + layout& temp_layout(bool cache) const; + void render(bool cache) const; + void render(layout& l, S32 begin_jot, S32 end_jot) const; + F32 yextent(F32 max, S32& size, bool cache) const; + F32 yextent(F32 max, S32& size, const layout& l, S32 begin_jot, + S32 end_jot) const; +}; + +struct xtextbox::layout +{ + xtextbox tb; + jot _jots[512]; + size_t _jots_size; + jot_line _lines[128]; + size_t _lines_size; + U8 context_buffer[1024]; + size_t context_buffer_size; + U16 dynamics[64]; + size_t dynamics_size; + + void refresh(const xtextbox& tb, bool force); + void refresh_end(const xtextbox& tb); + void clear(); + void trim_line(jot_line& line); + void erase_jots(size_t begin_jot, size_t end_jot); + void merge_line(jot_line& line); + void bound_line(jot_line& line); + bool fit_line(); + void next_line(); + void calc(const xtextbox& ctb, size_t start_text); + void render(const xtextbox& ctb, S32 begin_jot, S32 end_jot); + F32 yextent(F32 max, S32& size, S32 begin_jot, S32 end_jot) const; + bool changed(const xtextbox& ctb); + size_t jots_size() const; +}; + +void render_fill_rect(const basic_rect& bounds, iColor_tag color); + +F32 NSCREENX(F32); +F32 NSCREENY(F32); + +#endif diff --git a/src/SB/Core/x/xGlobals.h b/src/SB/Core/x/xGlobals.h new file mode 100644 index 0000000..b254ffe --- /dev/null +++ b/src/SB/Core/x/xGlobals.h @@ -0,0 +1,60 @@ +#ifndef XGLOBALS_H +#define XGLOBALS_H + +#include "xCamera.h" +#include "xPad.h" +#include "xUpdateCull.h" +#include "iCamera.h" +#include "iTime.h" + +#include +#include + +struct xGlobals +{ + // 0x00 in globals + xCamera camera; + + // 0x31C in globals + _tagxPad* pad0; + _tagxPad* pad1; + _tagxPad* pad2; + _tagxPad* pad3; + S32 profile; + + // 0x330 in globals + char profFunc[6][128]; + + // 0x630 in globals + xUpdateCullMgr* updateMgr; + S32 sceneFirst; + char sceneStart[32]; + RpWorld* currWorld; + + // 0x65C in globals + iFogParams fog; + iFogParams fogA; + iFogParams fogB; + + // 0x6B0 in globals + iTime fog_t0; + iTime fog_t1; + + // 0x6C0 in globals + S32 option_vibration; + U32 QuarterSpeed; + F32 update_dt; + S32 useHIPHOP; + + // 0x6D0 in globals + U8 NoMusic; + U8 currentActivePad; + U8 firstStartPressed; + + // 0x6D4 in globals + U32 minVSyncCnt; + U8 dontShowPadMessageDuringLoadingOrCutScene; + U8 autoSaveFeature; +}; + +#endif diff --git a/src/SB/Core/x/xGrid.h b/src/SB/Core/x/xGrid.h index 00a684f..2d759f3 100644 --- a/src/SB/Core/x/xGrid.h +++ b/src/SB/Core/x/xGrid.h @@ -1,9 +1,29 @@ #ifndef XGRID_H #define XGRID_H -#include "xQuickCull.h" +#include -struct xGridBound; +#include "xMath3.h" + +struct xEnt; +struct xQCData; + +struct xGridBound +{ + void* data; + U16 gx; + U16 gz; + + // Offset: 0x8 + U8 ingrid; + U8 oversize; + U8 deleted; + U8 gpad; + + // Offset: 0xC + xGridBound** head; + xGridBound* next; +}; struct xGrid { @@ -11,52 +31,145 @@ struct xGrid U8 pad[3]; U16 nx; U16 nz; + + // Offset: 0x8 F32 minx; F32 minz; F32 maxx; F32 maxz; + + // Offset: 0x18 F32 csizex; F32 csizez; F32 inv_csizex; F32 inv_csizez; + + // Offset: 0x28 F32 maxr; xGridBound** cells; xGridBound* other; - S32 iter_active; }; -struct xGridBound +struct xGridIterator { - void* data; - U16 gx; - U16 gz; - U8 oversize; - U8 deleted; - U8 gpad; - U8 pad; - xGrid* grid; - xGridBound** head; - xGridBound* next; + xGridBound** listhead; + xGridBound* curcell; + U32 delfound; }; -struct xBBox +typedef S32 (*GridEntCallback)(xEnt*, void*); + +extern volatile S32 gGridIterActive; + +void xGridBoundInit(xGridBound* gridb, void* data); +void xGridKill(xGrid* grid); +void xGridEmpty(xGrid* grid); +S32 xGridRemove(xGridBound* gridb); +xGridBound** xGridGetCell(xGrid* grid, const xEnt* ent, S32& grx, S32& grz); +void xGridGetCell(xGrid* grid, F32 posx, F32 posy, F32 posz, S32& grx, S32& grz); +xGridBound* xGridIterFirstCell(xGrid* grid, S32 grx, S32 grz, xGridIterator& iter); +xGridBound* xGridIterFirstCell(xGrid* grid, F32 posx, F32, F32 posz, S32& grx, S32& grz, + xGridIterator& it); +xGridBound* xGridIterFirstCell(xGridBound** head, xGridIterator& it); +xGridBound* xGridIterNextCell(xGridIterator& it); +void xGridIterClose(xGridIterator& it); +void xGridCheckPosition(xGrid* grid, xVec3* pos, xQCData* qcd, GridEntCallback hitCB, void* cbdata); +S32 xGridEntIsTooBig(xGrid* grid, const xEnt* ent); +S32 xGridAdd(xGrid* grid, xEnt* ent); + +inline xGridBound* xGridIterFirstCell(xGridBound** head, xGridIterator& it) { - xVec3 center; - xBox box; -}; + xGridBound* cell = *head; + + if (!cell) + { + return NULL; + } + + it.delfound = 0; + it.listhead = head; + it.curcell = cell; + + gGridIterActive++; -struct xBound + return cell; +} + +inline xGridBound* xGridIterFirstCell(xGrid* grid, S32 grx, S32 grz, xGridIterator& iter) { - xQCData qcd; - U8 type; - U8 pad[3]; - union + if (grx < 0 || grx >= grid->nx) { - xSphere sph; - xBBox box; - xCylinder cyl; - }; - xMat4x3* mat; -}; + return NULL; + } + + if (grz < 0 || grz >= grid->nz) + { + return NULL; + } + + return xGridIterFirstCell(grid->cells + grz * grid->nx + grx, iter); +} + +inline xGridBound* xGridIterNextCell(xGridIterator& it) +{ + if (it.curcell) + { + it.curcell = it.curcell->next; + } + + while (it.curcell) + { + if (!it.curcell->deleted) + { + return it.curcell; + } + + it.delfound = 1; + it.curcell = it.curcell->next; + } + + xGridIterClose(it); + return NULL; +} + +inline void xGridIterClose(xGridIterator& it) +{ + if (it.listhead) + { + gGridIterActive--; + + if (it.delfound && !gGridIterActive) + { + xGridBound* cell = *it.listhead; + xGridBound** head = it.listhead; + + while (cell) + { + if (cell->deleted) + { + *head = cell->next; + + cell->next = NULL; + cell->head = NULL; + cell->ingrid = 0; + cell->deleted = 0; + cell->gx = 0xFFFF; + cell->gz = 0xFFFF; + + cell = *head; + } + else + { + head = &cell->next; + cell = cell->next; + } + } + } + + it.listhead = NULL; + it.curcell = NULL; + it.delfound = 0; + } +} #endif diff --git a/src/SB/Core/x/xGroup.h b/src/SB/Core/x/xGroup.h new file mode 100644 index 0000000..f067ebc --- /dev/null +++ b/src/SB/Core/x/xGroup.h @@ -0,0 +1,35 @@ +#ifndef XGROUP_H +#define XGROUP_H + +#include "xBase.h" + +struct xGroupAsset : xBaseAsset +{ + U16 itemCount; + U16 groupFlags; +}; + +struct xGroup : xBase +{ + xGroupAsset* asset; + xBase** item; + U32 last_index; + S32 flg_group; + + U32 get_any(); +}; + +void xGroupInit(void* b, void* asset); +void xGroupInit(xBase* b, xGroupAsset* asset); +void xGroupSetup(xGroup* g); +void xGroupSave(xGroup* ent, xSerial* s); +void xGroupLoad(xGroup* ent, xSerial* s); +void xGroupReset(xGroup* ent); +S32 xGroupEventCB(xBase* to, xBase* from, U32 toEvent, const F32* toParam, + xBase* toParamWidget); +U32 xGroupGetCount(xGroup* g); +xBase* xGroupGetItemPtr(xGroup* g, U32 index); +xBase* xGroupFindItemPtr(xGroup* g, U32 index); +U32 xGroupGetItem(xGroup* g, U32 index); + +#endif diff --git a/src/SB/Core/x/xHud.h b/src/SB/Core/x/xHud.h new file mode 100644 index 0000000..9b6b015 --- /dev/null +++ b/src/SB/Core/x/xHud.h @@ -0,0 +1,206 @@ +#ifndef XHUD_H +#define XHUD_H + +#include "xBase.h" +#include "xVec3.h" +#include "xDynAsset.h" +#include "xModel.h" + +typedef struct asset; +typedef struct widget; + +namespace xhud +{ + struct block_allocator + { + U32 _block_size; + U32 _alloc_size; + void* _top; // FIXME: This is a holder* + block_allocator* _next_alloc; + + static block_allocator* _head_alloc; + + block_allocator(U32 a0, U32 a1); + + static void flush_all(); + void flush(); + void set_increment(U32 a0); + void size_reserve(U32 size); + void* alloc(); + void free(void* ptr); + }; + + struct color32u + { + U8 r; + U8 g; + U8 b; + U8 a; + }; + + struct render_context + { + xVec3 loc; + xVec3 size; + xVec3 rot; + F32 r; + F32 g; + F32 b; + F32 a; + }; + + struct asset : xDynAsset + { + xVec3 loc; + xVec3 size; + + static const char* type_name() + { + return "hud"; + } + }; + + struct motive; + struct motive_node; + + struct widget + { + struct + { + U8 visible; + U8 enabled; + } flag; + render_context rc; + render_context start_rc; + const asset* a; + enum _enum + { + ACT_NONE, + ACT_SHOW, + ACT_HIDE, + MAX_ACT + } activity; + + virtual void destroy() {} + virtual U32 type() const; + virtual bool is(U32 id) const; + virtual void init() {} + virtual void setup() { presetup(); } + virtual void update(F32 dt) { updater(dt); } + virtual void render() {} + virtual void dispatch(xBase* b1, U32 event, const F32* toParam, xBase* b2); + + motive_node* _motive_top; + motive_node* _motive_temp; + motive_node** _motive_temp_tail; + + static void disable_all(bool); + static void setup_all(); + static void update_all(F32 dt); + static void render_all(); + + static void init_base(xBase&, const xBaseAsset&, unsigned long); + static S32 cb_dispatch(xBase*, xBase*, U32, const F32*, xBase*); + + widget(const asset& a); + void destruct(); + void presetup(); + void updater(F32 dt); + void dispatcher(xBase*, U32, const F32*, xBase*); + + + void disable() + { + flag.enabled = 0; + } + + void add_tweaks() + { + + } + + void enable() + { + flag.enabled = 1; + } + + void clear_motives(); + void clear_motives(bool (*fp_update)(widget&, motive&, F32), void* context); + void add_motive(const motive& m); + void hide(); + void show(); + + bool visible() const + { + return flag.visible && enabled(); + } + + U8 enabled() const + { + return flag.enabled; + } + + static block_allocator* motive_allocator(); + }; + + struct motive + { + F32* value; + F32 delta; + F32 start_delta; + F32 max_offset; + F32 offset; + F32 accel; + bool (*fp_update)(widget&, motive&, F32); + void* context; + U8 inverse; + + motive(F32* value, F32 delta, F32 max_offset, F32 accel, bool (*fp_update)(xhud::widget&, motive&, F32), void* context) + { + this->value = value; + this->delta = delta; + this->start_delta = delta; + this->max_offset = max_offset; + this->offset = 0.0f; + this->accel = accel; + this->fp_update = fp_update; + this->context = context; + } + motive(const motive& other); + + bool update(widget& w, F32 dt) + { + return fp_update(w, *this, dt); + } + + void finish() + { + if (value != NULL) + { + *value += (max_offset - offset); + } + offset = max_offset; + } + }; + + struct motive_node + { + motive m; + motive_node* next; + }; + + void init(); + void setup(); + void destroy(); + void update(F32 dt); + void render(); + void render_model(xModelInstance& model, const render_context& context); + + bool linear_motive_update(widget& w, motive& m, F32); + bool accelerate_motive_update(widget& w, motive& m, F32); + bool delay_motive_update(widget& w, motive& m, F32); + + xModelInstance* load_model(U32); +}; // namespace xhud + +#endif diff --git a/src/SB/Core/x/xHudFontMeter.h b/src/SB/Core/x/xHudFontMeter.h new file mode 100644 index 0000000..4e4d696 --- /dev/null +++ b/src/SB/Core/x/xHudFontMeter.h @@ -0,0 +1,36 @@ +#ifndef XHUDFONTMETER_H +#define XHUDFONTMETER_H + +#include "xHudMeter.h" +#include "xFont.h" + +namespace xhud +{ + struct font_context + { + U32 id; + S32 justify; + F32 w; + F32 h; + F32 space; + F32 drop_x; + F32 drop_y; + color32u c; + color32u drop_c; + }; + + struct font_meter_widget : meter_widget + { + font_context font; + font_context start_font; + S32 precision; + xVec2 offset; + char buffer[12]; + S32 last_value; + xfont xf; + + static void load(xBase& data, xDynAsset& asset, size_t); + }; +} // namespace xhud + +#endif diff --git a/src/SB/Core/x/xHudMeter.h b/src/SB/Core/x/xHudMeter.h new file mode 100644 index 0000000..d9b6fb6 --- /dev/null +++ b/src/SB/Core/x/xHudMeter.h @@ -0,0 +1,40 @@ +#ifndef XHUDMETER_H +#define XHUDMETER_H + +#include "xHud.h" +#include "xSnd.h" + +namespace xhud +{ + struct meter_asset : asset + { + F32 start_value; + F32 min_value; + F32 max_value; + F32 increment_time; + F32 decrement_time; + struct _class_0 + { + U32 start_increment; + U32 increment; + U32 start_decrement; + U32 decrement; + } sound; + }; + + struct meter_widget : widget + { + meter_asset& res; + F32 value; + F32 min_value; + F32 max_value; + F32 end_value; + F32 value_vel; + F32 value_accel; + F32 ping_delay; + F32 pitch; + sound_queue<4> pings; + }; +} // namespace xhud + +#endif diff --git a/src/SB/Core/x/xHudModel.h b/src/SB/Core/x/xHudModel.h new file mode 100644 index 0000000..edd2e4c --- /dev/null +++ b/src/SB/Core/x/xHudModel.h @@ -0,0 +1,40 @@ +#ifndef XHUDMODEL_H +#define XHUDMODEL_H + +#include "xAnim.h" +#include "xHud.h" + +namespace xhud +{ + struct model_asset : asset + { + U32 model; + + static const char* type_name() + { + return "hud:model"; + } + }; + + struct model_widget : widget + { + U32 mid; + xModelInstance* model; + + model_widget(const model_asset&); + + static void load(xBase& data, xDynAsset& asset, size_t); + + void destruct(); + + virtual void destroy(); + virtual U32 type() const; + virtual bool is(U32 id) const; + virtual void update(F32 dt); + virtual void render(); + }; +} // namespace xhud + +xAnimTable* XHUD_AnimTable_Idle(); + +#endif diff --git a/src/SB/Core/x/xHudText.h b/src/SB/Core/x/xHudText.h new file mode 100644 index 0000000..19c2e93 --- /dev/null +++ b/src/SB/Core/x/xHudText.h @@ -0,0 +1,42 @@ +#ifndef XHUDTEXT_H +#define XHUDTEXT_H + +#include "xHud.h" +#include "xFont.h" + +namespace xhud +{ + struct text_asset : asset + { + U32 text_box; + U32 text; + + static const char* type_name() + { + return "hud:text"; + } + }; + + struct text_widget : widget + { + char text[128]; + xtextbox tb; + + text_widget(); // possibly temp, added so zCombo.cpp compiles + text_widget(const text_asset&); + + static void load(xBase& data, xDynAsset& asset, size_t); + + void destruct(); + + virtual void destroy(); + virtual U32 type() const; + virtual bool is(U32 id) const; + virtual void setup(); + virtual void update(F32 dt); + virtual void render(); + }; + +}; // namespace xhud + +#endif diff --git a/src/SB/Core/x/xHudUnitMeter.h b/src/SB/Core/x/xHudUnitMeter.h new file mode 100644 index 0000000..a773520 --- /dev/null +++ b/src/SB/Core/x/xHudUnitMeter.h @@ -0,0 +1,33 @@ +#ifndef XHUDUNITMETER_H +#define XHUDUNITMETER_H + +#include "xHudMeter.h" +#include "xModel.h" + +namespace xhud +{ + struct model_info + { + U32 id; + xVec3 loc; + xVec3 size; + }; + + struct unit_meter_asset : meter_asset + { + model_info model[2]; + xVec3 offset; + U32 fill_forward; + }; + + struct unit_meter_widget : meter_widget + { + unit_meter_asset res; + xModelInstance* model[2][6]; + F32 anim_time; + + static void load(xBase& data, xDynAsset& asset, size_t); + }; +} // namespace xhud + +#endif diff --git a/src/SB/Core/x/xIni.h b/src/SB/Core/x/xIni.h new file mode 100644 index 0000000..86b01d7 --- /dev/null +++ b/src/SB/Core/x/xIni.h @@ -0,0 +1,37 @@ +#ifndef XINI_H +#define XINI_H + +#include + +struct xIniValue +{ + char* tok; + char* val; +}; + +struct xIniSection +{ + char* sec; + S32 first; + S32 count; +}; + +struct xIniFile +{ + S32 NumValues; + S32 NumSections; + xIniValue* Values; + xIniSection* Sections; + void* mem; + char name[256]; + char pathname[256]; +}; + +xIniFile* xIniParse(char* buf, S32 len); +void xIniDestroy(xIniFile* ini); +S32 xIniGetIndex(xIniFile* ini, char* tok); +S32 xIniGetInt(xIniFile* ini, char* tok, S32 def); +F32 xIniGetFloat(xIniFile* ini, char* tok, F32 def); +char* xIniGetString(xIniFile* ini, char* tok, char* def); + +#endif diff --git a/src/SB/Core/x/xIsect.h b/src/SB/Core/x/xIsect.h new file mode 100644 index 0000000..64524d8 --- /dev/null +++ b/src/SB/Core/x/xIsect.h @@ -0,0 +1,17 @@ +#ifndef XISECT_H +#define XISECT_H + +#include "xMath3.h" + +struct xIsect +{ + U32 flags; + F32 penned; + F32 contained; + F32 lapped; + xVec3 point; + xVec3 norm; + F32 dist; +}; + +#endif diff --git a/src/SB/Core/x/xJSP.h b/src/SB/Core/x/xJSP.h index e6bc85b..fad7731 100644 --- a/src/SB/Core/x/xJSP.h +++ b/src/SB/Core/x/xJSP.h @@ -1,74 +1,29 @@ #ifndef XJSP_H #define XJSP_H -#include +#include +#include +#include +#include "xClumpColl.h" struct xJSPNodeInfo { S32 originalMatIndex; - U16 nodeFlags; - S16 sortOrder; -}; - -struct xJSPNodeTreeBranch -{ - U16 leftNode; - U16 rightNode; - U8 leftType; - U8 rightType; - U16 coord; - F32 leftValue; - F32 rightValue; -}; - -struct xJSPNodeTreeLeaf -{ - S32 nodeIndex; - S32 leafCount; - RwBBox box; -}; - -struct xJSPNodeTree -{ - S32 numBranchNodes; - xJSPNodeTreeBranch* branchNodes; - S32 numLeafNodes; - xJSPNodeTreeLeaf* leafNodes; -}; - -struct xJSPMiniLightTie -{ - RwLLLink lightInWorldSector; - RpLight* light; -}; - -struct RpTie -{ -}; - -struct xJSPNodeLight -{ - RpAtomic* atomic; - S32 lightCount; - RpTie dummyTie; - RpWorldSector dummySector; - xJSPMiniLightTie dummyLightTie[16]; + S32 nodeFlags; }; struct xJSPHeader { - S8 idtag[4]; + char idtag[4]; U32 version; U32 jspNodeCount; RpClump* clump; xClumpCollBSPTree* colltree; xJSPNodeInfo* jspNodeList; - U32 stripVecCount; - RwV3d* stripVecList; - U16 vertDataFlags; - U16 vertDataStride; - xJSPNodeTree* nodetree; - xJSPNodeLight* nodelight; }; +RpMesh* AddMeshCB(RpMesh* mesh, RpMeshHeader* header, RwV3d** param_3); +void xJSP_MultiStreamRead(void* data, U32 size, xJSPHeader** jsp); +void xJSP_Destroy(xJSPHeader* jsp); + #endif diff --git a/src/SB/Core/x/xJaw.h b/src/SB/Core/x/xJaw.h new file mode 100644 index 0000000..df06d45 --- /dev/null +++ b/src/SB/Core/x/xJaw.h @@ -0,0 +1,9 @@ +#ifndef XJAW_H +#define XJAW_H + +#include + +void* xJaw_FindData(U32 soundID); +F32 xJaw_EvalData(void* data, F32 time); + +#endif diff --git a/src/SB/Core/x/xLaserBolt.h b/src/SB/Core/x/xLaserBolt.h new file mode 100644 index 0000000..c4b96f0 --- /dev/null +++ b/src/SB/Core/x/xLaserBolt.h @@ -0,0 +1,133 @@ +#ifndef XLASERBOLT_H +#define XLASERBOLT_H + +#include "xDecal.h" +#include "xEnt.h" +#include "xFX.h" +#include "xMath2.h" +#include "xMath3.h" +#include "xParEmitter.h" + +#include +#include + +enum fx_when_enum +{ + FX_WHEN_LAUNCH, + FX_WHEN_IMPACT, + FX_WHEN_BIRTH, + FX_WHEN_DEATH, + FX_WHEN_HEAD, + FX_WHEN_TAIL, + FX_WHEN_KILL, + MAX_FX_WHEN +}; + +enum fx_type_enum +{ + FX_TYPE_PARTICLE, + FX_TYPE_DECAL, + FX_TYPE_DECAL_DIST, + FX_TYPE_CALLBACK +}; + +enum fx_orient_enum +{ + FX_ORIENT_DEFAULT, + FX_ORIENT_PATH, + FX_ORIENT_IPATH, + FX_ORIENT_HIT_NORM, + FX_ORIENT_HIT_REFLECT, + MAX_FX_ORIENT, + FORCE_INT_FX_ORIENT = 0xffffffff +}; + +struct bolt +{ + xVec3 origin; + xVec3 dir; + xVec3 loc; + xVec3 hit_norm; + F32 dist; + F32 hit_dist; + F32 prev_dist; + F32 prev_check_dist; + xEnt* hit_ent; + F32 emitted; + void* context; +}; + +struct xLaserBoltEmitter +{ + struct config + { + F32 radius; + F32 length; + F32 vel; + F32 fade_dist; + F32 kill_dist; + F32 safe_dist; + F32 hit_radius; + F32 rand_ang; + F32 scar_life; + xVec2 bolt_uv[2]; + S32 hit_interval; + F32 damage; + }; + + struct static_queue + { + U32 _first; + U32 _size; + U32 _max_size; + U32 _max_size_mask; + bolt* _buffer; + }; + + struct effect_data + { + struct effect_callback + { + void (*fp)(bolt&, void*); + void* context; + }; + + fx_type_enum type; + fx_orient_enum orient; + F32 rate; + union + { + xParEmitter* par; + xDecalEmitter* decal; + effect_callback callback; + }; + F32 irate; + }; + + config cfg; + static_queue bolts; + F32 ialpha; + RwRaster* bolt_raster; + S32 start_collide; + effect_data* fx[7]; + U32 fxsize[7]; + + void set_texture(char* name); + void set_texture(U32 aid); + void set_texture(RwTexture* tex); + void set_texture(RwRaster* raster); + void reset(); + void refresh_config(); + void emit(const xVec3& loc, const xVec3& dir); + void update(F32 dt); + void render(); + void attach_effects(fx_when_enum when, effect_data* fx, size_t fxsize); + void pre_collide(bolt& b); + void collide_update(bolt& b); + RxObjSpace3DVertex* render(bolt& b, RxObjSpace3DVertex* vert); + RxObjSpace3DVertex* get_vert_buffer(S32& dat); + void applyDamage(bolt& b); + void reset_fx(fx_when_enum when); +}; + +#endif diff --git a/src/SB/Core/x/xLightKit.h b/src/SB/Core/x/xLightKit.h new file mode 100644 index 0000000..9191017 --- /dev/null +++ b/src/SB/Core/x/xLightKit.h @@ -0,0 +1,30 @@ +#ifndef XLIGHTKIT_H +#define XLIGHTKIT_H + +#include +#include +#include + +struct xLightKitLight +{ + U32 type; + RwRGBAReal color; + F32 matrix[16]; + F32 radius; + F32 angle; + RpLight* platLight; +}; + +struct xLightKit +{ + U32 tagID; + U32 groupID; + U32 lightCount; + xLightKitLight* lightList; +}; + +xLightKit* xLightKit_Prepare(void* data); +void xLightKit_Enable(xLightKit* lkit, RpWorld* world); +void xLightKit_Destroy(xLightKit* lkit); + +#endif diff --git a/src/SB/Core/x/xLinkAsset.h b/src/SB/Core/x/xLinkAsset.h new file mode 100644 index 0000000..31895de --- /dev/null +++ b/src/SB/Core/x/xLinkAsset.h @@ -0,0 +1,16 @@ +#ifndef XLINKASSET_H +#define XLINKASSET_H + +#include + +struct xLinkAsset +{ + U16 srcEvent; + U16 dstEvent; + U32 dstAssetID; + F32 param[4]; + U32 paramWidgetAssetID; + U32 chkAssetID; +}; + +#endif diff --git a/src/SB/Core/x/xListItem.h b/src/SB/Core/x/xListItem.h new file mode 100644 index 0000000..6e0fe9a --- /dev/null +++ b/src/SB/Core/x/xListItem.h @@ -0,0 +1,26 @@ +#ifndef XLISTITEM_H +#define XLISTITEM_H + +#include + +template struct xListItem +{ + S32 flg_travFilter; + T* next; + T* prev; + + xListItem() + { + flg_travFilter = 0; + prev = NULL; + next = NULL; + } + + T* Next(); + void Insert(T* list); + T* RemHead(T** listhead); + T* Head(); + void Remove(); +}; + +#endif diff --git a/src/SB/Core/x/xMarkerAsset.h b/src/SB/Core/x/xMarkerAsset.h new file mode 100644 index 0000000..c074fb2 --- /dev/null +++ b/src/SB/Core/x/xMarkerAsset.h @@ -0,0 +1,11 @@ +#ifndef XMARKERASSET_H +#define XMARKERASSET_H + +#include "xMath3.h" + +struct xMarkerAsset +{ + xVec3 pos; +}; + +#endif \ No newline at end of file diff --git a/src/SB/Core/x/xMath.h b/src/SB/Core/x/xMath.h index 9928922..8f1ca7f 100644 --- a/src/SB/Core/x/xMath.h +++ b/src/SB/Core/x/xMath.h @@ -1,113 +1,69 @@ #ifndef XMATH_H #define XMATH_H -#include "xMem.h" +#include -struct xVec2 -{ - F32 x; - F32 y; -}; - -struct xVec3 -{ - union - { - RwV3d m_RwV3d; - F32 x; - }; - F32 y; - F32 z; - F32 a[3]; -}; - -struct xBox -{ - xVec3 upper; - xVec3 lower; -}; +#include "iMath.h" -struct xQuat -{ - xVec3 v; - F32 s; -}; - -struct _class_20 -{ - xVec3* verts; -}; - -struct xMat3x3 -{ - xVec3 right; - S32 flags; - xVec3 up; - U32 pad1; - xVec3 at; - U32 pad2; -}; +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define xabs(x) iabs(x) -struct xMat4x3 : xMat3x3 -{ - xVec3 pos; - U32 pad3; -}; +#define CLAMP(x, a, b) (MAX((a), MIN((x), (b)))) -struct xRot -{ - xVec3 axis; - F32 angle; -}; +#define SQR(x) ((x) * (x)) -struct xCylinder -{ - xVec3 center; - F32 r; - F32 h; -}; +#define ALIGN(x, a) ((x) + ((a)-1) & ~((a)-1)) -struct xSphere -{ - xVec3 center; - F32 r; -}; +// Override these to point to their corresponding symbols in .sdata2 +// For example: +// #undef PI +// #undef ONEEIGHTY +// #define PI _771_1 +// #define ONEEIGHTY _778_0 +#define PI 3.1415927f +#define ONEEIGHTY 180.0f -struct xCoef -{ - F32 a[4]; -}; +#define DEG2RAD(x) ((PI) * (x) / (ONEEIGHTY)) +#define RAD2DEG(x) ((ONEEIGHTY) * (x) / (PI)) -struct xCoef3 -{ - xCoef x; - xCoef y; - xCoef z; -}; +#define FLOAT_MAX 1e38f +#define FLOAT_MIN -1e38f -struct xSpline3 +struct xFuncPiece { - U16 type; - U16 flags; - U32 N; - U32 allocN; - xVec3* points; - F32* time; - xVec3* p12; - xVec3* bctrl; - F32* knot; - xCoef3* coef; - U32 arcSample; - F32* arcLength; + F32 coef[5]; + F32 end; + S32 order; + xFuncPiece* next; }; -struct xParabola -{ - xVec3 initPos; - xVec3 initVel; - F32 gravity; - F32 minTime; - F32 maxTime; -}; +F32 xlog(F32 f); + +void xMathInit(); +void xMathExit(); +F32 xatof(const char* x); +void xsrand(U32 seed); +U32 xrand(); +F32 xurand(); +U32 xMathSolveQuadratic(F32 a, F32 b, F32 c, F32* x1, F32* x2); +U32 xMathSolveCubic(F32 a, F32 b, F32 c, F32 d, F32* x1, F32* x2, F32* x3); +F32 xAngleClamp(F32 a); +F32 xAngleClampFast(F32 a); +F32 xDangleClamp(F32 a); +void xAccelMove(F32& x, F32& v, F32 a, F32 dt, F32 endx, F32 maxv); +F32 xAccelMoveTime(F32 dx, F32 a, F32, F32 maxv); +void xAccelMove(F32& x, F32& v, F32 a, F32 dt, F32 maxv); +void xAccelStop(F32& x, F32& v, F32 a, F32 dt); +F32 xFuncPiece_Eval(xFuncPiece* func, F32 param, xFuncPiece** iterator); +void xFuncPiece_EndPoints(xFuncPiece* func, F32 pi, F32 pf, F32 fi, F32 ff); +void xFuncPiece_ShiftPiece(xFuncPiece* shift, xFuncPiece* func, F32 newZero); +F32 xSCurve(F32 t, F32 softness); +F32 xSCurve(F32 t); +void xsqrtfast(F32& dst, F32 num); + +F32 xrmod(F32 ang); + +template T range_limit(T v, T minv, T maxv); #endif diff --git a/src/SB/Core/x/xMath2.h b/src/SB/Core/x/xMath2.h new file mode 100644 index 0000000..81f9367 --- /dev/null +++ b/src/SB/Core/x/xMath2.h @@ -0,0 +1,59 @@ +#ifndef XMATH2_H +#define XMATH2_H + +#include + +template struct basic_rect +{ + T x; + T y; + T w; + T h; + + const static basic_rect m_Null; + const static basic_rect m_Unit; + + basic_rect& assign(T x, T y, T w, T h); + basic_rect& contract(T x, T y, T w, T h); + basic_rect& move(T x, T y); + basic_rect& scale(T s); + basic_rect& scale(T x, T y); + basic_rect& scale(T x, T y, T w, T h); + void clip(basic_rect& a, basic_rect& b) const; + void set_bounds(T x1, T y1, T x2, T y2); + void get_bounds(T& x1, T& y1, T& x2, T& y2) const; + bool empty() const; + void set_size(T w, T h); + void set_size(T s); + void center(T x, T y); + + basic_rect& operator|=(const basic_rect& other); +}; + +struct xVec2 +{ + F32 x; + F32 y; + + xVec2& assign(F32 xy) + { + return assign(xy,xy); + } + xVec2& assign(F32 x, F32 y); + F32 length() const; + F32 normal() const; + xVec2& normalize(); + F32 dot(const xVec2&) const; + + xVec2& operator=(F32); + xVec2 operator*(F32) const; + xVec2 operator/=(F32); + xVec2& operator+=(const xVec2&); + xVec2& operator*=(F32); +}; + +F32 xVec2Dist(F32 x1, F32 y1, F32 x2, F32 y2); +F32 xVec2Dot(const xVec2* a, const xVec2* b); +void xVec2Init(xVec2* v, F32 _x, F32 _y); + +#endif diff --git a/src/SB/Core/x/xMath3.h b/src/SB/Core/x/xMath3.h new file mode 100644 index 0000000..1e2b2ed --- /dev/null +++ b/src/SB/Core/x/xMath3.h @@ -0,0 +1,163 @@ +#ifndef XMATH3_H +#define XMATH3_H + +#include "xMath.h" + +#include "xVec3.h" +#include "xVec3Inlines.h" + +// Size: 0x30 +struct xMat3x3 +{ + xVec3 right; + S32 flags; + xVec3 up; + U32 pad1; + xVec3 at; + U32 pad2; +}; + +// Size: 0x40 +struct xMat4x3 : xMat3x3 +{ + xVec3 pos; + U32 pad3; +}; + +struct xSphere +{ + xVec3 center; + F32 r; +}; + +// Size: 0x18 +struct xBox +{ + xVec3 upper; + xVec3 lower; +}; + +struct xBBox +{ + xVec3 center; + xBox box; +}; + +struct xCylinder +{ + xVec3 center; + F32 r; + F32 h; +}; + +struct xQuat +{ + xVec3 v; + F32 s; +}; + +struct xVec4 +{ + F32 x; + F32 y; + F32 z; + F32 w; +}; + +struct xRot +{ + xVec3 axis; + F32 angle; +}; + +struct xLine3 +{ + xVec3 p1; + xVec3 p2; +}; + +struct xRay3; + +extern const xQuat g_IQ; +extern const xVec3 g_O3; +extern xVec3 g_X3; +extern xVec3 g_Y3; +extern xVec3 g_Z3; +extern xMat4x3 g_I3; +extern xVec3 g_Onez; + +void xMat3x3Copy(xMat3x3* o, const xMat3x3* m); // TODO: These functions should be inline +void xMat4x3Copy(xMat4x3* o, const xMat4x3* m); +void xMat4x3Mul(xMat4x3* o, const xMat4x3* a, const xMat4x3* b); +void xMat3x3Euler(xMat3x3* m, F32 yaw, F32 pitch, F32 roll); +void xMat4x3Toworld(xVec3* o, const xMat4x3* m, const xVec3* v); +void xMat3x3RotC(xMat3x3* m, F32 _x, F32 _y, F32 _z, F32 t); +void xMat3x3RotY(xMat3x3* m, F32 t); +void xMat3x3MulRotC(xMat3x3* o, xMat3x3* m, F32 _x, F32 _y, F32 _z, F32 t); +void xMat4x3Identity(xMat4x3* m); +void xMat3x3Normalize(xMat3x3* o, const xMat3x3* m); +void xMat4x3Tolocal(xVec3* o, const xMat4x3* m, const xVec3* v); +void xMat3x3Tolocal(xVec3* o, const xMat3x3* m, const xVec3* v); +void xMat4x3MoveLocalRight(xMat4x3* m, F32 mag); +void xMat4x3MoveLocalAt(xMat4x3* m, F32 mag); +void xMat4x3MoveLocalUp(xMat4x3* m, F32 mag); +void xMat4x3OrthoInv(xMat4x3* o, const xMat4x3* m); +void xMat3x3GetEuler(const xMat3x3* m, xVec3* a); +void xMat3x3Euler(xMat3x3* m, const xVec3* ypr); +void xQuatToMat(const xQuat* q, xMat3x3* m); +void xQuatDiff(xQuat* o, const xQuat* a, const xQuat* b); +F32 xQuatGetAngle(const xQuat* q); +void xQuatFromMat(xQuat* q, const xMat3x3* m); +void xQuatSlerp(xQuat* q, const xQuat* a, const xQuat* b, F32 t); +void xQuatConj(xQuat* o, const xQuat* q); +void xQuatCopy(xQuat*, const xQuat*); +void xMat3x3LookAt(xMat3x3* m, const xVec3* pos, const xVec3* at); +F32 xMat3x3LookVec(xMat3x3* m, const xVec3* at); +void xBoxInitBoundOBB(xBox* o, const xBox* b, const xMat4x3* m); +void xBoxUnion(xBox& a, const xBox& b, const xBox& c); +void xMat3x3Scale(xMat3x3* m, const xVec3* s); +void xMat3x3ScaleC(xMat3x3* m, F32 x, F32 y, F32 z); +void xMat3x3RMulRotY(xMat3x3* o, const xMat3x3* m, F32 t); +void xMat3x3Mul(xMat3x3* o, const xMat3x3* a, const xMat3x3* b); +void xMat3x3SMul(xMat3x3*, const xMat3x3*, F32); +void xBoxFromLine(xBox& box, const xLine3& line); +void xBoxFromRay(xBox& box, const xRay3& ray); +void xMat3x3Identity(xMat3x3* matrix); // TODO: These functions should be inline +S32 xPointInBox(const xBox* b, const xVec3* p); +void xMat3x3LMulVec(xVec3* o, const xMat3x3* m, const xVec3* v); + +void xQuatMul(xQuat* o, const xQuat* a, const xQuat* b); +void xQuatFlip(xQuat* o1, xQuat* o2); +void xQuatNormalize(xQuat* arg01, xQuat* arg02); + +void xQuatSMul(xQuat* q, const xQuat* a, F32 t); +void xQuatAdd(xQuat* q, const xQuat* a, const xQuat* b); +F32 xQuatDot(const xQuat* a, const xQuat* b); + +F32 fabs(F32 x); // Unsure where this should come from. + +inline void xRotCopy(xRot* o, const xRot* r) +{ + o->axis.x = r->axis.x; + o->axis.y = r->axis.y; + o->axis.z = r->axis.z; + o->angle = r->angle; +} + +static inline void xMat3x3RMulVec(xVec3* o, const xMat3x3* m, const xVec3* v) +{ + F32 x = m->right.x * v->x + m->up.x * v->y + m->at.x * v->z; + F32 y = m->right.y * v->x + m->up.y * v->y + m->at.y * v->z; + F32 z = m->right.z * v->x + m->up.z * v->y + m->at.z * v->z; + + o->x = x; + o->y = y; + o->z = z; +} + +inline void xMat3x3Rot(xMat3x3* m, const xVec3* a, F32 t) +{ + xMat3x3RotC(m, a->x, a->y, a->z, t); +} + +#endif diff --git a/src/SB/Core/x/xMathInlines.h b/src/SB/Core/x/xMathInlines.h new file mode 100644 index 0000000..4aec695 --- /dev/null +++ b/src/SB/Core/x/xMathInlines.h @@ -0,0 +1,18 @@ +#ifndef XMATHINLINES_H +#define XMATHINLINES_H + +#include + +F32 xsqrt(F32 x); +F32 xfmod(F32 a, F32 b); +F32 xatan2(F32 y, F32 x); +F32 xasin(F32 x); +F32 xacos(F32 x); +F32 xexp(F32 x); +F32 xpow(F32 x, F32 y); + +F32 SQ(F32 x); + +void xsqrtfast(F32& out, F32 x); + +#endif diff --git a/src/SB/Core/x/xMem.h b/src/SB/Core/x/xMem.h deleted file mode 100644 index 9ae262e..0000000 --- a/src/SB/Core/x/xMem.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef XMEM_H -#define XMEM_H - -#include -#include -#include -#include - -struct xBase; - -struct RyzMemGrow -{ - S32 flg_grow; - S32 amt; - signed char* ptr; - xBase* user; - S32 amt_last; - signed char* ptr_last; - xBase* user_last; -}; - -struct RyzMemData -{ - void __dl(); - void* __nw(U32 amt, RyzMemGrow* growCtxt); -}; - -struct xFactoryInst : RyzMemData -{ - S32 itemType; - xFactoryInst* nextprod; - xFactoryInst* prevprod; -}; - -struct xMemPool -{ - void* FreeList; - U16 NextOffset; - U16 Flags; - void* UsedList; - void (*InitCB)(xMemPool*, void*); - void* Buffer; - U16 Size; - U16 NumRealloc; - U32 Total; -}; - -#endif diff --git a/src/SB/Core/x/xMemMgr.h b/src/SB/Core/x/xMemMgr.h new file mode 100644 index 0000000..0e03b48 --- /dev/null +++ b/src/SB/Core/x/xMemMgr.h @@ -0,0 +1,114 @@ +#ifndef XMEMMGR_H +#define XMEMMGR_H + +#include + +// Size: 0x10 +struct xHeapState_tag +{ + U32 curr; + U16 blk_ct; + U16 pad; + U32 used; + U32 wasted; +}; + +struct xMemBlock_tag +{ + U32 addr; + U32 size; + S32 align; +}; + +struct xMemBlkInfo_tag +{ + xMemBlock_tag* header; + U32 pre; + U32 block; + U32 post; + U32 curr; + U32 waste; + U32 total; +}; + +struct xMemHeap_tag +{ + U32 flags; + U32 hard_base; + U32 size; + S16 opp_heap[2]; + + // Offset: 0x10 + xHeapState_tag state[12]; + + // Offset: 0xD0 + U16 state_idx; + U16 max_blks; + xMemBlock_tag* blk; + xMemBlock_tag* lastblk; +}; + +struct xMemArea_tag +{ + U32 addr; + U32 size; + U32 flags; +}; + +struct xMemInfo_tag +{ + xMemArea_tag system; + + // Offset: 0xC + xMemArea_tag stack; + + // Offset: 0x18 + xMemArea_tag DRAM; + + // Offset: 0x24 + xMemArea_tag SRAM; +}; + +struct xMemPool; +typedef void (*xMemPoolInitCB)(xMemPool*, void*); +struct xMemPool +{ + void* FreeList; + U16 NextOffset; + U16 Flags; + void* UsedList; + xMemPoolInitCB InitCB; + void* Buffer; + U16 Size; + U16 NumRealloc; + U32 Total; +}; + +extern U32 gActiveHeap; + +void xMemInit(); +void xMemExit(); +void xMemInitHeap(xMemHeap_tag* heap, U32 base, U32 size, U32 flags); +U32 xMemGetBlockInfo(xMemHeap_tag* heap, U32 size, S32 align, xMemBlkInfo_tag* info); +void* xMemGrowAlloc(U32 heapID, U32 size); +void* xMemAlloc(U32 heapID, U32 size, S32 align); +void* xMemPushTemp(U32 size); +void xMemPopTemp(void* memory); +S32 xMemPushBase(U32 heapID); +S32 xMemPushBase(); +S32 xMemPopBase(U32 heapID, S32 depth); +S32 xMemPopBase(S32 depth); +S32 xMemGetBase(U32 heapID); +void xMemRegisterBaseNotifyFunc(void (*func)()); +S32 xMemGetBase(); +void xMemPoolAddElements(xMemPool* pool, void* buffer, U32 count); +void xMemPoolSetup(xMemPool* pool, void* buffer, U32 nextOffset, U32 flags, + xMemPoolInitCB initCB, U32 size, U32 count, U32 numRealloc); +void* xMemPoolAlloc(xMemPool* pool); +void xMemPoolFree(xMemPool* pool, void* data); + +#define xMemGrowAllocSize(size) xMemGrowAlloc(gActiveHeap, size) +#define xMemAllocSize(size) xMemAlloc(gActiveHeap, size, 0) +#define xMemAllocSizeAlign(size, align) xMemAlloc(gActiveHeap, size, align) + +#endif diff --git a/src/SB/Core/x/xMgr.h b/src/SB/Core/x/xMgr.h new file mode 100644 index 0000000..4c1b6ae --- /dev/null +++ b/src/SB/Core/x/xMgr.h @@ -0,0 +1,8 @@ +#ifndef XMGR_H +#define XMGR_H + +struct xMgr +{ +}; + +#endif \ No newline at end of file diff --git a/src/SB/Core/x/xModel.h b/src/SB/Core/x/xModel.h index f02d33f..9ff8f9d 100644 --- a/src/SB/Core/x/xModel.h +++ b/src/SB/Core/x/xModel.h @@ -1,225 +1,17 @@ #ifndef XMODEL_H #define XMODEL_H -#include -#include #include #include -#include "xMath.h" -#include "xSound.h" - -struct xLinkAsset -{ - U16 srcEvent; - U16 dstEvent; - U32 dstAssetID; - F32 param[4]; - U32 paramWidgetAssetID; - U32 chkAssetID; -}; - -struct xBase -{ - U32 id; - U8 baseType; - U8 linkCount; - U16 baseFlags; - xLinkAsset* link; - void (*eventFunc)(xBase*, xBase*, U32, F32*, xBase*, U32); -}; - -struct xBaseAsset -{ - U32 id; - U8 baseType; - U8 linkCount; - U16 baseFlags; -}; - -struct xMovePointAsset : xBaseAsset -{ - xVec3 pos; - U16 wt; - U8 on; - U8 bezIndex; - U8 flg_props; - U8 pad; - U16 numPoints; - F32 delay; - F32 zoneRadius; - F32 arenaRadius; -}; - -struct xMovePoint : xBase -{ - xMovePointAsset* asset; - xVec3* pos; - xMovePoint** nodes; - xMovePoint* prev; - U32 node_wt_sum; - U8 on; - U8 pad[3]; - F32 delay; - xSpline3* spl; -}; - -struct xAnimPhysicsData -{ - xVec3* tranTable; - F32* yawTable; - S32 tranCount; -}; - -struct xAnimFile -{ - xAnimFile* Next; - unsigned char* Name; - U32 ID; - U32 FileFlags; - F32 Duration; - F32 TimeOffset; - U16 BoneCount; - U8 NumAnims[2]; - void** RawData; - xAnimPhysicsData* PhysicsData; -}; - -struct xAnimSingle; -struct xAnimActiveEffect; - -struct xAnimEffect -{ - xAnimEffect* Next; - U16 Flags; - U16 Probability; - F32 StartTime; - F32 EndTime; - U32 (*Callback)(U32, xAnimActiveEffect*, xAnimSingle*, void*); -}; - -struct xAnimActiveEffect -{ - xAnimEffect* Effect; - union - { - U32 Handle; - iSndHandle SndHandle; - }; -}; - -struct xAnimState; - -struct xAnimTransition -{ - xAnimTransition* Next; - xAnimState* Dest; - U32 (*Conditional)(xAnimTransition*, xAnimSingle*, void*); - U32 (*Callback)(xAnimTransition*, xAnimSingle*, void*); - U32 Flags; - U32 UserFlags; - F32 SrcTime; - F32 DestTime; - U16 Priority; - U16 QueuePriority; - F32 BlendRecip; - U16* BlendOffset; -}; - -struct xAnimTransitionList -{ - xAnimTransitionList* Next; - xAnimTransition* T; -}; - -struct xAnimMultiFileBase -{ - U32 Count; -}; - -struct xAnimMultiFileEntry -{ - U32 ID; - xAnimFile* File; -}; - -struct xAnimMultiFile : xAnimMultiFileBase -{ - xAnimMultiFileEntry Files[1]; -}; - -struct xAnimPlay; - -struct xAnimState -{ - xAnimState* Next; - unsigned char* Name; - U32 ID; - U32 Flags; - U32 UserFlags; - F32 Speed; - xAnimFile* Data; - xAnimEffect* Effects; - xAnimTransitionList* Default; - xAnimTransitionList* List; - F32* BoneBlend; - F32* TimeSnap; - F32 FadeRecip; - U16* FadeOffset; - void* CallbackData; - xAnimMultiFile* MultiFile; - void (*BeforeEnter)(xAnimPlay*, xAnimState*, void*); - void (*StateCallback)(xAnimState*, xAnimSingle*, void*); - void (*BeforeAnimMatrices)(xAnimPlay*, xQuat*, xVec3*, S32); -}; - -struct xAnimSingle -{ - U32 SingleFlags; - xAnimState* State; - F32 Time; - F32 CurrentSpeed; - F32 BilinearLerp[2]; - xAnimEffect* Effect; - U32 ActiveCount; - F32 LastTime; - xAnimActiveEffect* ActiveList; - xAnimPlay* Play; - xAnimTransition* Sync; - xAnimTransition* Tran; - xAnimSingle* Blend; - F32 BlendFactor; - xVec3 PhysDisp; - F32 YawDisp; - U32 pad[1]; -}; - -struct xAnimTable -{ - signed char* Name; - xAnimTransition* TransitionList; - xAnimState* StateList; - U32 AnimIndex; - U32 MorphIndex; - U32 UserFlags; -}; -struct xModelAssetParam -{ - U32 HashID; - U8 WordLength; - U8 String[3]; -}; - -struct xModelAssetInfo -{ - U32 Magic; - U32 NumModelInst; - U32 AnimTableID; - U32 CombatID; - U32 BrainID; -}; +#include "xAnim.h" +#include "xLightKit.h" +#include "xSurface.h" +#include "xMath3.h" +#include "xMath2.h" +#include "xModelBucket.h" -struct xModelInstance; +struct xModelBucket; struct xModelPool { @@ -228,100 +20,55 @@ struct xModelPool xModelInstance* List; }; -struct xModelPipe -{ - U32 Flags; - U8 Layer; - U8 AlphaDiscard; - U16 PipePad; -}; - -struct xEnt; - -struct xSurface : xBase -{ - U32 idx; - U32 type; - union - { - U32 mat_idx; - xEnt* ent; - void* obj; - }; - F32 friction; - U8 state; - U8 pad[3]; - void* moprops; -}; - -struct xModelBucket -{ - RpAtomic* Data; - RpAtomic* OriginalData; - union - { - xModelInstance* List; - xModelBucket** BackRef; - }; - S32 ClipFlags; - xModelPipe Pipe; -}; - -struct xLightKitLight -{ - U32 type; - RwRGBAReal color; - F32 matrix[16]; - F32 radius; - F32 angle; - RpLight* platLight; -}; - -struct xLightKit -{ - U32 tagID; - U32 groupID; - U32 lightCount; - xLightKitLight* lightList; -}; - struct xModelInstance { xModelInstance* Next; xModelInstance* Parent; xModelPool* Pool; - xAnimPlay* Anim; + xAnimPlay* Anim; // 0xC + + // Offset: 0x10 RpAtomic* Data; - xModelPipe Pipe; - U8 InFrustum; - U8 TrueClip; - S8 sortBias; - U8 modelpad; + U32 PipeFlags; F32 RedMultiplier; F32 GreenMultiplier; + + // Offset: 0x20 F32 BlueMultiplier; F32 Alpha; F32 FadeStart; F32 FadeEnd; + + // Offset: 0x30 xSurface* Surf; xModelBucket** Bucket; xModelInstance* BucketNext; xLightKit* LightKit; + + // Offset: 0x40 void* Object; - U16 Flags; - U8 BoneCount; - U8 BoneIndex; - U8* BoneRemap; - RwMatrixTag* Mat; + U16 Flags; // 0x44 + U8 BoneCount; // 0x46 + U8 BoneIndex; // 0x47 + U8* BoneRemap; // 0x48 + RwMatrix* Mat; // 0x4C + + // Offset: 0x50 xVec3 Scale; - xBox animBound; - xBox combinedAnimBound; U32 modelID; U32 shadowID; RpAtomic* shadowmapAtomic; - _class_20 anim_coll; + struct + { + xVec3* verts; + } anim_coll; }; +// NOTE (Square): Theses are based on the access pattern found in zUI_Render. +// I doubt they wrote this out by hand every time, but I'm just guessing on the macro here. +#define XMODELINSTANCE_GET_SRCBLEND(inst) (((inst)->PipeFlags >> 0x8) & 0xf) +#define XMODELINSTANCE_GET_DSTBLEND(inst) (((inst)->PipeFlags >> 0xc) & 0xf) + struct xModelTag { xVec3 v; @@ -329,20 +76,90 @@ struct xModelTag F32 wt[4]; }; -struct activity_data_1 +struct xModelTagWithNormal : xModelTag { + xVec3 normal; }; -struct xModelBlur +struct xModelAssetParam { - activity_data_1* activity; + U32 HashID; + U8 WordLength; + U8 String[3]; +}; - void render_enable(U8 enabled); - void render_all(); - void update_all(F32 dt); - void reset_all(); - void scene_exit(); - void scene_enter(); +struct xModelAssetInfo +{ + U32 Magic; + U32 NumModelInst; + U32 AnimTableID; + U32 CombatID; + U32 BrainID; }; +struct xModelAssetInst +{ + U32 ModelID; + U16 Flags; + U8 Parent; + U8 Bone; + F32 MatRight[3]; + F32 MatUp[3]; + F32 MatAt[3]; + F32 MatPos[3]; +}; + +struct xModelPipeLookup +{ + RpAtomic* model; + U32 PipeFlags; +}; + +struct xModelPipeInfo +{ + U32 ModelHashID; + U32 SubObjectBits; + U32 PipeFlags; +}; + +extern S32 xModelPipeNumTables; +extern S32 xModelPipeCount[16]; +extern xModelPipeInfo* xModelPipeData[16]; +extern S32 xModelLookupCount; +extern xModelPipeLookup* xModelLookupList; +extern S32 xModelInstStaticAlloc; + +U32 xModelGetPipeFlags(RpAtomic* model); +void xModelInit(); +void xModelPoolInit(U32 count, U32 numMatrices); +void xModelAnimCollStart(xModelInstance& m); +void xModelSetFrame(xModelInstance* modelInst, const xMat4x3* frame); +xModelInstance* xModelInstanceAlloc(RpAtomic* data, void* object, U16 flags, U8 boneIndex, + U8* boneRemap); +void xModelInstanceFree(xModelInstance* modelInst); +void xModelInstanceAttach(xModelInstance* inst, xModelInstance* parent); +void xModelRender(xModelInstance* modelInst); +void xModelRenderSingle(xModelInstance* modelInst); +void xModelRender2D(const xModelInstance& model, const basic_rect& r, const xVec3& from, + const xVec3& to); +void xModelSetMaterialAlpha(xModelInstance* modelInst, U8 alpha); +void xModelUpdate(xModelInstance* modelInst, F32 timeDelta); +xMat4x3* xModelGetFrame(xModelInstance* modelInst); +void xModelEval(xModelInstance* modelInst); +void xModel_SceneEnter(RpWorld* world); +void xModel_SceneExit(RpWorld* world); +xSphere* xModelGetLocalSBound(xModelInstance* model); +void xModelGetBoneMat(xMat4x3& mat, const xModelInstance& model, size_t index); +void xModelInstanceUpgradeBrotherShared(xModelInstance* inst, U32 flags); + +inline void xModelSetFrame(xModelInstance* modelInst, const xMat4x3* frame) +{ + xMat4x3Copy((xMat4x3*)modelInst->Mat, frame); +} + +inline xMat4x3* xModelGetFrame(xModelInstance* modelInst) +{ + return (xMat4x3*)modelInst->Mat; +} + #endif diff --git a/src/SB/Core/x/xModelBucket.h b/src/SB/Core/x/xModelBucket.h new file mode 100644 index 0000000..40f4cf2 --- /dev/null +++ b/src/SB/Core/x/xModelBucket.h @@ -0,0 +1,43 @@ +#ifndef XMODELBUCKET_H +#define XMODELBUCKET_H + +#include "xModel.h" + +struct xModelBucket +{ + RpAtomic* Data; + RpAtomic* OriginalData; + xModelInstance* List; + S32 ClipFlags; + U32 PipeFlags; +}; + +struct xModelAlphaBucket +{ + RpAtomic* Data; + xModelInstance* MInst; + F32 AlphaFade; + F32 SortValue; + U32 Layer; +}; + +extern S32 xModelBucketEnabled; + +void xModelBucket_RenderAlpha(); + +S32 CmpAlphaBucket(const void* _a, const void* _b); +void xModelBucket_PreCountReset(); +void xModelBucket_PreCountBucket(RpAtomic* data, U32 pipeFlags, U32 subObjects); +void xModelBucket_PreCountAlloc(S32 maxAlphaModels); +void xModelBucket_InsertBucket(RpAtomic* data, U32 pipeFlags, U32 subObjects); +void xModelBucket_Init(); +void xModelBucket_Deinit(); +xModelBucket** xModelBucket_GetBuckets(RpAtomic* data); +void xModelBucket_Begin(); +void xModelBucket_Add(xModelInstance* minst); +void xModelBucket_RenderOpaque(); +void xModelBucket_RenderAlphaBegin(); +void xModelBucket_RenderAlphaLayer(S32 maxLayer); +void xModelBucket_RenderAlphaEnd(); + +#endif diff --git a/src/SB/Core/x/xMorph.h b/src/SB/Core/x/xMorph.h new file mode 100644 index 0000000..3ee24ac --- /dev/null +++ b/src/SB/Core/x/xMorph.h @@ -0,0 +1,47 @@ +#ifndef XMORPH_H +#define XMORPH_H + +#include "iMorph.h" +#include "xMath3.h" + +#include +#include + +struct xMorphSeqFile +{ + U32 Magic; + U32 Flags; + U32 TimeCount; + U32 ModelCount; +}; + +struct xMorphFrame +{ + RpAtomic* Model; + F32 RecipTime; + F32 Scale; + U16 Flags; + U16 NumVerts; + S16* Targets[4]; + S16 WeightStart[4]; + S16 WeightEnd[4]; +}; + +struct xMorphTargetFile +{ + U32 Magic; + U16 NumTargets; + U16 NumVerts; + U32 Flags; + F32 Scale; + xVec3 Center; + F32 Radius; +}; + +typedef void*(*xMorphFindAssetCallback)(U32, char*); + +xMorphSeqFile* xMorphSeqSetup(void* data, xMorphFindAssetCallback FindAssetCB); +void xMorphRender(xMorphSeqFile* seq, RwMatrix* mat, F32 time); +F32 xMorphSeqDuration(xMorphSeqFile* seq); + +#endif \ No newline at end of file diff --git a/src/SB/Core/x/xMovePoint.h b/src/SB/Core/x/xMovePoint.h new file mode 100644 index 0000000..4e0af7c --- /dev/null +++ b/src/SB/Core/x/xMovePoint.h @@ -0,0 +1,56 @@ +#ifndef XMOVEPOINT_H +#define XMOVEPOINT_H + +#include "xBase.h" +#include "xMath3.h" +#include "xSpline.h" + +struct xScene; + +struct xMovePointAsset : xBaseAsset +{ + xVec3 pos; + U16 wt; + + U8 on; + U8 bezIndex; + U8 flg_props; + U8 pad; + U16 numPoints; + + F32 delay; + F32 zoneRadius; + F32 arenaRadius; +}; + +struct xMovePoint : xBase +{ + xMovePointAsset* asset; + + // Offset: 0x14 + xVec3* pos; + xMovePoint** nodes; + xMovePoint* prev; + U32 node_wt_sum; + + // Offset: 0x24 + U8 on; + U8 pad[3]; + + // Offset: 0x28 + F32 delay; + xSpline3* spl; +}; + +xVec3* xMovePointGetPos(xMovePoint* m); +F32 xMovePointGetNext(const xMovePoint* m, const xMovePoint* prev, xMovePoint** next, + xVec3* hdng); +void xMovePointSplineDestroy(xMovePoint* m); +void xMovePointSplineSetup(xMovePoint* m); +void xMovePointSetup(xMovePoint* m, xScene* sc); +void xMovePointReset(xMovePoint* m); +void xMovePointLoad(xMovePoint* ent, xSerial* s); +void xMovePointSave(xMovePoint* ent, xSerial* s); +void xMovePointInit(xMovePoint* m, xMovePointAsset* asset); + +#endif diff --git a/src/SB/Core/x/xNME.h b/src/SB/Core/x/xNME.h deleted file mode 100644 index 9f7e7a2..0000000 --- a/src/SB/Core/x/xNME.h +++ /dev/null @@ -1,613 +0,0 @@ -#ifndef XNME_H -#define XNME_H - -#include "xEnt.h" -#include "xModel.h" -#include "xBehaviour.h" -#include "xFrag.h" -#include "xPar.h" -#include "xMail.h" -#include "xSound.h" - -enum en_allow -{ - ALLOW_NEVER, - ALLOW_NORMAL, - ALLOW_ALWAYS, - ALLOW_NOMORE -}; - -enum en_nmesimp -{ - NME_SIMP_HAPPY, - NME_SIMP_DEAD, - NME_SIMP_IGNORANT, - NME_SIMP_WARYDETECT, - NME_SIMP_WARY, - NME_SIMP_WORRIED, - NME_SIMP_CONFUSED, - NME_SIMP_BIGBULLY, - NPC_STAT_NOMORE -}; - -enum en_haztyp -{ - HAZ_TYP_UNKNOWN, - HAZ_TYP_EXPLODE, - HAZ_TYP_IMPACT, - HAZ_TYP_IMPACTWET, - HAZ_TYP_IMPACTBOOM, - HAZ_TYP_DAZED, - HAZ_TYP_SPAWNBALL_XX, - HAZ_TYP_SPAWNBALL_GG, - HAZ_TYP_SPAWNBALL_TR, - HAZ_TYP_SPAWNBALL_PT, - HAZ_TYP_SPAWNGROW, - HAZ_TYP_BUCKOBOOM_V1, - HAZ_TYP_TIKIBOOM, - HAZ_TYP_SLAMWAVE_V1, - HAZ_TYP_SLAMWAVE_V2, - HAZ_TYP_SLAMWAVE_V3, - HAZ_TYP_FLING_V1, - HAZ_TYP_FLING_V2, - HAZ_TYP_FLING_V3, - HAZ_TYP_FLING_FROGFISH, - HAZ_TYP_SPITPUDDLE_V1, - HAZ_TYP_SPITPUDDLE_V2, - HAZ_TYP_SPITPUDDLE_V3, - HAZ_TYP_ICECREAMSPLAT, - HAZ_TYP_SPITSTEAM, - HAZ_TYP_SPITSPLASH, - HAZ_TYP_POPPER_V1, - HAZ_TYP_POPPER_V2, - HAZ_TYP_POPPER_V3, - HAZ_TYP_MERVBOMB_V1, - HAZ_TYP_MERVBOMB_V2, - HAZ_TYP_MERVBOMB_V3, - HAZ_TYP_MERVLET_V1, - HAZ_TYP_MERVLET_V2, - HAZ_TYP_MERVLET_V3, - HAZ_TYP_ZAPBALL_V1, - HAZ_TYP_ZAPBALL_V2, - HAZ_TYP_ZAPBOOM_V1, - HAZ_TYP_ZAPBOOM_V2, - HAZ_TYP_TURBALL_V1, - HAZ_TYP_TURBALL_V2, - HAZ_TYP_TURBALL_V3, - HAZ_TYP_TURBOOM, - HAZ_TYP_GOLFBALL, - HAZ_TYP_GOLFBOOM, - HAZ_TYP_GOLFJUNK_A, - HAZ_TYP_GOLFJUNK_B, - HAZ_TYP_GOLFJUNK_C, - HAZ_TYP_GOLFJUNK_D, - HAZ_TYP_GOLFJUNK_E, - HAZ_TYP_DENNIS_KNIFE, - HAZ_TYP_DENNIS_KNIFEBOOM, - HAZ_TYP_TUNEBORN, - HAZ_TYP_TUNEBANG, - HAZ_TYP_TUNEBOOM, - HAZ_TYP_TUNEFLYT, - HAZ_TYP_SWIMWAKE, - HAZ_TYP_BOWWAVE, - HAZ_TYP_SPLASH_RING, - HAZ_TYP_SPLISH_DROP, - HAZ_TYP_VISSPLASH_WAVE, - HAZ_TYP_VISSPLASH_DROP, - HAZ_TYP_VISSPLASH_WATER, - HAZ_TYP_VISSPLASH_CHOC, - HAZ_TYP_VISSPLASH_LAVA, - HAZ_TYP_VISSPLASH_BILE, - HAZ_TYP_VISSPLASH_OIL, - HAZ_TYP_VISSPLASH_SAUCE, - HAZ_TYP_VISSPLASH_TOXIC, - HAZ_TYP_REFLECT_V1, - HAZ_TYP_PLYRBANG_V1, - HAZ_TYP_POWERUP_EXPLOSION_V1, - HAZ_TYP_NOMORE, - HAZ_TYP_FORCE = 0x7fffffff -}; - -enum en_npcdmg -{ - DMGTYP_UNDECIDED, - DMGTYP_ABOVE, - DMGTYP_BELOW, - DMGTYP_SIDE, - DMGTYP_INSTAKILL, - DMGTYP_WOUNDEVENT, - DMGTYP_KILLEVENT, - DMGTYP_NMEATTACK, - DMGTYP_HITBYTOSS, - DMGTYP_NMEKNOCKED, - DMGTYP_ROPE, - DMGTYP_CRUISEBUBBLE, - DMGTYP_FRIENDLYFIRE, - DMGTYP_REFLECTED, - DMGTYP_BOULDER, - DMGTYP_BUBBOWL, - DMGTYP_THUNDER_TIKI_EXPLOSION, - DMGTYP_DAMAGE_SURFACE, - DMGTYP_BUNGEED, - DMGTYP_SURFACE, - DMGTYP_CARTWHEEL, - DMGTYP_CARSMASH, - DMGTYP_SLIDE, - DMGTYP_EXPLOSION, - DMGTYP_BBOWLZAP, - DMGTYP_NOMORE, - DMGTYP_FORCEINT = 0x7fffffff -}; - -enum en_plyrpup -{ - ePowerupLevelDisabled, - ePowerupLevelNormal, - ePowerupLevelLevelMax, - ePowerupLevelHealthMax, - ePowerupLevelCount -}; - -enum en_denstage -{ - DEN_STAGE_UNKNOWN, - DEN_STAGE_INTRO, - DEN_STAGE_A, - DEN_STAGE_B, - DEN_STAGE_C, - DEN_STAGE_OUTRO, - DEN_STAGE_NOMORE -}; - -enum en_dbcmode -{ - DEN_CAMMOD_UNKNOWN, - DEN_CAMMOD_NORMAL, - DEN_CAMMOD_BINARY, - DEN_CAMMOD_NOMORE -}; - -enum en_vis -{ - VIS_PREPARE_TO_DIE, - VIS_HORROR_FLIK, - VIS_OH_DEAR_GAHD, - VIS_GET_BACK_HERE, - VIS_I_SEEE_YOUUU, - VIS_GREY_AND_FOGGY, - VIS_LIKE_A_BIRDIE, - VIS_EARTHWORM_JIM, - VIS_NOBODY_AROUND, - VIS_NOMORE -}; - -enum en_dtbcmode -{ - DENT_CAMMOD_UNKNOWN, - DENT_CAMMOD_NORMAL, - DENT_CAMMOD_BINARY, - DENT_CAMMOD_NOMORE -}; - -enum en_dentstage -{ - DENT_STAGE_UNKNOWN, - DENT_STAGE_INTRO, - DENT_STAGE_A, - DENT_STAGE_B, - DENT_STAGE_C, - DENT_STAGE_OUTRO, - DENT_STAGE_NOMORE -}; - -struct xGroupAsset : xBaseAsset -{ - U16 itemCount; - U16 groupFlags; -}; - -struct xGroup : xBase // Move after filling in more headers -{ - xGroupAsset* asset; - xBase** item; - U32 last_index; - S32 flg_group; -}; - -struct OriginalBackupData -{ - struct - { - S32 flg_enableWander : 1; - S32 flg_enablePatrol : 1; - S32 flg_enableDetect : 1; - S32 flg_activeOn : 1; - S32 flg_takeNoDamage : 1; - S32 flg_unused : 27; - }; - union - { - en_allow overrideDetect; - S32 alignmeproperly; - }; - union - { - en_allow overrideAttack; - S32 alignmeproperlyToo; - }; -}; - -struct Restore -{ - U8 chkby; - U8 penby; - U8 padpad[2]; - union - { - en_npcgol gid_compare; - S32 gid_COMPARE; - }; -}; - -struct NMERuntime -{ - struct - { - S32 flg_enableWander : 1; - S32 flg_enablePatrol : 1; - S32 flg_enableDetect : 1; - S32 flg_activeOn : 1; - S32 flg_takeNoDamage : 1; - S32 flg_unused : 27; - }; - union - { - en_allow overrideDetect; - S32 alignmeproperly; - }; - union - { - en_allow overrideAttack; - S32 alignmeproperlyToo; - }; - OriginalBackupData orig; - Restore restore; -}; - -struct zNMEDriver -{ - xEnt* ent_driver; - F32 tym_mount; - xMat4x3 mat_parLast; - xMat4x3 mat_ownerLast; - struct - { - S32 flg_inContact : 1; - S32 flg_matchOrient : 1; - S32 flg_unused : 30; - }; - - void WheelTurnsYou_C(xMat4x3* mat_owner); - void ReviewCollide(xEntCollis* npccol); -}; - -struct zNMECommon; - -struct zMovePoint : xMovePoint -{ -}; - -struct zNMENavNet -{ - zMovePoint* nav_past; - zMovePoint* nav_curr; - zMovePoint* nav_dest; - zMovePoint* nav_lead; - xSpline3* spl_mvptspline; - F32 len_mvptspline; - F32 dst_curspline; - zNMECommon* nme_owner; - - S32 MvptCycle(); -}; - -struct zNMESoundTable -{ - iSndGroupHandle sndGroupHandle[10]; - unsigned char* assetNames[10]; - F32 timer[10]; - F32 time[10]; - S32 flags[10]; -}; - -struct xDynAsset : xBaseAsset -{ - U32 type; - U16 version; - U16 handle; -}; - -struct zNMEAsset : xDynAsset -{ - xEntAsset ent_asset; -}; - -struct Damage_1 -{ - F32 tym_invuln; -}; - -struct Physics -{ - F32 acc_grav; - F32 spd_maxFall; -}; - -struct Movement_1 -{ - F32 spd_move; - F32 acc_move; - F32 dst_deviant; - F32 spd_turnrate; -}; - -struct NMECfgCommon -{ - Damage_1 damage; - Physics physics; - Movement_1 movement; -}; - -struct SimpShadParm -{ - F32 rad_shadow; - unsigned char* nam_shadowTexture; - RwRaster* rast_shadow; -}; - -struct FullShadParm -{ - S32 tobeDetermined; -}; - -struct ShadowRadii -{ - F32 rad_noShadow; - F32 rad_complexShadow; -}; - -struct NMEShadParms -{ - SimpShadParm simpshad; - FullShadParm fullshad; - ShadowRadii shadrad; -}; - -struct zNMEArena -{ - S32 flg_arena; - xVec3 pos_arena; - F32 rad_arena; - zMovePoint* nav_arena; - zMovePoint* nav_refer_dest; - zMovePoint* nav_refer_curr; - - zMovePoint* NextBestNav(zMovePoint* nav_from); - S32 Cycle(zNMECommon* npc, S32 peek); -}; - -struct NMESysEvent -{ - S32 doLinkEvents; - S32 handled; - xBase* from; - xBase* to; - union - { - U32 toEvent; - en_xEventTags toEvent_asEnum; - }; - F32 toParam[4]; - xBase* toParamWidget; - U32 toParamWidgetID; -}; - -struct NMEBlastInfo -{ - xVec3 pos_blast; - F32 rad_blast; - F32 spd_expand; -}; - -struct NMEChatInfo -{ - xVec3 pos_chat; - F32 tym_chat; -}; - -struct NMESpawnInfo -{ - xVec3 pos_spawn; - zMovePoint* nav_firstMovepoint; - zMovePoint* nav_spawnReference; - S32 spawnSuccess; -}; - -struct NMETargetInfo -{ - xBase* bas_tgt; - xVec3 pos_tgt; -}; - -struct NMEDamageInfo -{ - en_npcdmg dmg_type; - xBase* dmg_from; - xVec3 vec_dmghit; - S32 amt_damage; - union - { - S32 fac_powerup; - en_plyrpup pup_player; - }; -}; - -struct NMEStunInfo -{ - F32 tym_stuntime; - en_carystat carrystate; - S32 allowStun; -}; - -struct NMEScriptInfo -{ - U32 aid_playanim; -}; - -struct NMEMountInfo -{ - xEnt* ent_toMount; - xCollis* col_forMount; -}; - -struct NMEDestInfo -{ - xVec3 pos_there; - zMovePoint* nav_there; -}; - -struct NMEAreaInfo -{ - zNMECommon* npc_origin; - xVec3 pos_origin; -}; - -struct NMEMsg -{ - en_npcmsg msgid; - U32 sendto; - U32 from; - en_msgdata infotype; - union - { - NMESysEvent sysevent; - NMEBlastInfo blastarea; - NMEChatInfo chatter; - NMESpawnInfo spawning; - NMETargetInfo target; - NMEDamageInfo dmgdata; - NMEStunInfo stundata; - NMEScriptInfo scriptdata; - NMEMountInfo mountdata; - NMEDestInfo destdata; - NMEAreaInfo areadata; - }; - void* attached; - NMEMsg* next; - F32 tmr_delay; -}; - -struct Health_3 -{ - S32 pts_healthMax; -}; - -struct Ranges_2 -{ - F32 rad_tooclose[2]; - F32 rad_lob; - F32 rad_lobgrey; - F32 rad_aware; - F32 rad_awaregrey; -}; - -struct Attack_3 -{ - F32 spd_proj; - S32 num_salvo; - F32 tym_shoot; - F32 dst_spreadHorz; -}; - -struct Battle_6 -{ - F32 tym_reload; - F32 tym_leapDelay; - S32 num_atakPerLeap; -}; - -struct NMECfgDennis -{ - Health_3 health; - Ranges_2 ranges; - Attack_3 attack; - Battle_6 battle; -}; - -struct DennisLetMeKnow : xPSYNote -{ -}; - -// DenTooMeter : BarMeter FIX LATER -struct DenTooMeter -{ - U8 lastPaused; - //TextureScroller denTooTexureScroller; FIX LATER - - void update(); - void setup(); - void* ct(); -}; - -struct Health_8 -{ - S32 pts_healthMax; -}; - -struct Ranges_5 -{ - F32 rad_tooclose; - F32 rad_lob; - F32 rad_lobgrey; - F32 rad_aware; - F32 rad_awaregrey; -}; - -struct Attack_0 -{ -}; - -struct ThrowSide -{ - F32 spd_proj; - S32 num_salvo; - F32 dst_spreadHorz; -}; - -struct ThrowToes -{ - F32 spd_proj; - S32 num_salvo; - F32 dst_nearTgt; - F32 dst_farTgt; - F32 hyt_elevate; -}; - -struct Battle_2 -{ - F32 tym_reload; - F32 tym_leapDelay; - S32 num_atakPerLeap; -}; - -struct NMECfgDenToo -{ - Health_8 health; - Ranges_5 ranges; - Attack_0 attack; - ThrowSide throwSide; - ThrowToes throwToes; - Battle_2 battle; -}; - -#endif diff --git a/src/SB/Core/x/xNPCBasic.h b/src/SB/Core/x/xNPCBasic.h new file mode 100644 index 0000000..121f313 --- /dev/null +++ b/src/SB/Core/x/xNPCBasic.h @@ -0,0 +1,131 @@ +#ifndef XNPCBASIC_H +#define XNPCBASIC_H + +#include "xEnt.h" +#include "xFactory.h" +#include "xShadowSimple.h" +#include "xColor.h" + +enum en_npcperf +{ + eNPCPerfZero, + + // These two are only guesses! Need more info to be sure. + eNPCPerfEnable, + eNPCPerfDisable, +}; + +// Values names in this enum not known at all, it is not present in the dwarf +// debug info. +enum en_npcdcat +{ + eNPCDCAT_Zero, + eNPCDCAT_Seven = 7, + eNPCDCAT_Eight = 8, + eNPCDCAT_Eleven = 11, +}; + +struct xNPCBasic : xEnt, xFactoryInst +{ + // Offset: 0xDC + void (*f_setup)(xEnt*); + void (*f_reset)(xEnt*); + + // Offset: 0xE4 + struct + { + S32 flg_basenpc : 16; + S32 inUpdate : 8; + S32 flg_upward : 8; + } flags1; + + // Offset: 0xE8 + S32 colFreq; + S32 colFreqReset; + + // Offset: 0xF0 + struct + { + U32 flg_colCheck : 8; + U32 flg_penCheck : 8; + U32 flg_unused : 16; + } flags2; + + // Offset: 0xF4 + S32 myNPCType; + + // Offset: 0xF8 + xEntShadow entShadow_embedded; + + // Offset: 0x138 + xShadowSimpleCache simpShadow_embedded; + + xNPCBasic(S32); + + S32 SelfType() const; + void RestoreColFlags() + { + flags2.flg_colCheck = ColChkFlags(); + flags2.flg_penCheck = ColPenFlags(); + chkby = ColChkByFlags(); + penby = ColPenByFlags(); + pflags = PhysicsFlags(); + colFreq = -1; + } + + void DBG_PStatClear(); + void DBG_PStatCont(en_npcperf stat); + void DBG_PStatOn(en_npcperf stat); + S32 DBG_IsNormLog(en_npcdcat input, S32 input2); + void DBG_HaltOnMe(U32, char*); + + // DO NOT CHANGE THE ORDER OF THESE, the order determines the + // vtable layout which needs to remain fixed. + virtual void Init(xEntAsset* asset); + virtual void PostInit(); + virtual void Setup(); + virtual void PostSetup(); + virtual void Reset(); + virtual void Process(xScene* xscn, F32 dt); + virtual void BUpdate(xVec3*); + virtual void NewTime(xScene* xscn, F32 dt); + virtual void Move(xScene* xscn, F32 dt, xEntFrame* frm); + virtual S32 SysEvent(xBase* from, xBase* to, U32 toEvent, const F32* toParam, + xBase* toParamWidget, S32* handled); + virtual void Render(); + virtual void Save(xSerial*) const; + virtual void Load(xSerial*); + virtual void CollideReview(); + + /* These most likely return a combination of XENT_COLLTYPE_* values */ + virtual U8 ColChkFlags() const + { + return 0; + } + + virtual U8 ColPenFlags() const + { + return 0; + } + + virtual U8 ColChkByFlags() const + { + return 0; + } + + virtual U8 ColPenByFlags() const + { + return 0; + } + + virtual U8 PhysicsFlags() const + { + return 0; + } + + virtual void Destroy(); +}; + +void NPC_spdBasedColFreq(xNPCBasic* npc, F32 dt); + +#endif diff --git a/src/SB/Core/x/xPad.h b/src/SB/Core/x/xPad.h new file mode 100644 index 0000000..c4ef619 --- /dev/null +++ b/src/SB/Core/x/xPad.h @@ -0,0 +1,113 @@ +#ifndef XPAD_H +#define XPAD_H + +#include "xRumble.h" +#include "xMath2.h" +#include "iPad.h" + +enum _tagPadState +{ + ePad_Disabled, + ePad_DisabledError, + ePad_Enabled, + ePad_Missing, + ePad_Total +}; + +enum _tagPadInit +{ + ePadInit_Open1, + ePadInit_WaitStable2, + ePadInit_EnableAnalog3, + ePadInit_EnableAnalog3LetsAllPissOffChris, + ePadInit_EnableRumble4, + ePadInit_EnableRumbleTest5, + ePadInit_PressureS6, + ePadInit_PressureSTest7, + ePadInit_Complete8a, + ePadInit_Complete8b, + ePadInit_Finished9 +}; + +struct _tagPadAnalog +{ + S8 x; + S8 y; +}; + +struct analog_data +{ + xVec2 offset; + xVec2 dir; + F32 mag; + F32 ang; +}; + +struct _tagxPad +{ + S8 value[22]; + + // Offset: 0x16 + S8 last_value[22]; + + // Offset: 0x2C + U32 on; + + // Offset: 0x30 + U32 pressed; + U32 released; + + // Offset: 0x38 + _tagPadAnalog analog1; + _tagPadAnalog analog2; + _tagPadState state; + U32 flags; + _tagxRumble rumble_head; + S16 port; + S16 slot; + _tagiPad context; + F32 al2d_timer; + F32 ar2d_timer; + F32 d_timer; + F32 up_tmr[22]; + F32 down_tmr[22]; + analog_data analog[2]; +}; + +// Named after PS2 buttons to match the "PadPress*" events +#define XPAD_BUTTON_START 0x1 +#define XPAD_BUTTON_SELECT 0x2 +#define XPAD_BUTTON_UP 0x10 +#define XPAD_BUTTON_RIGHT 0x20 +#define XPAD_BUTTON_DOWN 0x40 +#define XPAD_BUTTON_LEFT 0x80 +#define XPAD_BUTTON_L1 0x100 // L on gamecube +#define XPAD_BUTTON_L2 0x200 +#define XPAD_BUTTON_R1 0x1000 // R on gamecube +#define XPAD_BUTTON_R2 0x2000 +#define XPAD_BUTTON_X 0x10000 // A on gamecube +#define XPAD_BUTTON_O 0x20000 // X on gamecube +#define XPAD_BUTTON_SQUARE 0x40000 // Y on gamecube +#define XPAD_BUTTON_TRIANGLE 0x80000 // B on gamecube + +// GameCube +#define XPAD_BUTTON_Z 0x100000 + +extern _tagxPad mPad[4]; +extern _tagxRumble mRumbleList[32]; +extern _tagxPad* gPlayerPad; + +S32 xPadInit(); +_tagxPad* xPadEnable(S32 idx); +void xPadRumbleEnable(S32 idx, S32 enable); +S32 xPadUpdate(S32 idx, F32 time_passed); +void xPadNormalizeAnalog(_tagxPad& pad, S32 inner_zone, S32 outer_zone); +void xPadKill(); +_tagxRumble* xPadGetRumbleSlot(); +void xPadDestroyRumbleChain(_tagxPad* pad); +void xPadDestroyRumbleChain(S32 idx); +S32 xPadAddRumble(S32 idx, _tagRumbleType type, F32 time, S32 replace, U32 fxflags); + +void xPadAnalogIsDigital(F32, F32); + +#endif diff --git a/src/SB/Core/x/xPar.h b/src/SB/Core/x/xPar.h index 3cee0af..77b0878 100644 --- a/src/SB/Core/x/xPar.h +++ b/src/SB/Core/x/xPar.h @@ -1,176 +1,34 @@ #ifndef XPAR_H #define XPAR_H -#include "xMath.h" -#include "xEnt.h" - -struct xPECircle -{ - F32 radius; - F32 deflection; - xVec3 dir; -}; - -struct xPESphere -{ - F32 radius; -}; - -struct xPERect -{ - F32 x_len; - F32 z_len; -}; - -struct xPELine -{ - xVec3 pos1; - xVec3 pos2; - F32 radius; -}; - -struct xPEVolume -{ - U32 emit_volumeID; -}; - -struct xPEOffsetPoint -{ - xVec3 offset; -}; - -struct xPEVCyl -{ - F32 height; - F32 radius; - F32 deflection; -}; - -struct xPEEntBone -{ - U8 flags; - U8 type; - U8 bone; - U8 pad1; - xVec3 offset; - F32 radius; - F32 deflection; -}; - -struct xPEEntBound -{ - U8 flags; - U8 type; - U8 pad1; - U8 pad2; - F32 expand; - F32 deflection; -}; - -struct xParEmitterAsset : xBaseAsset -{ - U8 emit_flags; - U8 emit_type; - U16 pad; - U32 propID; - union - { - xPECircle e_circle; - xPESphere e_sphere; - xPERect e_rect; - xPELine e_line; - xPEVolume e_volume; - xPEOffsetPoint e_offsetp; - xPEVCyl e_vcyl; - xPEEntBone e_entbone; - xPEEntBound e_entbound; - }; - U32 attachToID; - xVec3 pos; - xVec3 vel; - F32 vel_angle_variation; - U32 cull_mode; - F32 cull_dist_sqr; -}; - -struct xParGroup -{ -}; - -struct xParInterp -{ - F32 val[2]; - U32 interp; - F32 freq; - F32 oofreq; -}; - -struct xParEmitterPropsAsset : xBaseAsset -{ - U32 parSysID; - union - { - xParInterp rate; - xParInterp value[1]; - }; - xParInterp life; - xParInterp size_birth; - xParInterp size_death; - xParInterp color_birth[4]; - xParInterp color_death[4]; - xParInterp vel_scale; - xParInterp vel_angle; - xVec3 vel; - U32 emit_limit; - F32 emit_limit_reset_time; -}; - -struct xParEmitterCustomSettings : xParEmitterPropsAsset -{ - U32 custom_flags; - U32 attachToID; - xVec3 pos; - xVec3 last_emit_position; - xVec3 vel; - xVec3 last_emit_velocity; - F32 vel_angle_variation; - U8 rot[3]; - U8 padding; - F32 radius; - F32 emit_interval_current; - xBase* emit_volume; -}; - -struct xParSys -{ -}; - -struct xParEmitter : xBase -{ - xParEmitterAsset* tasset; - xParGroup* group; - xParEmitterPropsAsset* prop; - U8 rate_mode; - xVec3 last_emit_position; - xVec3 last_emit_velocity; - F32 rate; - F32 rate_time; - F32 rate_fraction; - F32 rate_fraction_cull; - U8 emit_flags; - U8 emit_pad[3]; - U8 rot[3]; - xModelTag tag; - F32 oocull_distance_sqr; - F32 distance_to_cull_sqr; - void* attachTo; - xParSys* parSys; - xBase* emit_volume; - xVec3 last_attach_loc; -}; - -struct zParEmitter : xParEmitter -{ -}; +#include "xMath3.h" + +struct xParEmitterAsset; + +struct xPar +{ + xPar* m_next; + xPar* m_prev; + F32 m_lifetime; + U8 m_c[4]; + xVec3 m_pos; + F32 m_size; + xVec3 m_vel; + F32 m_sizeVel; + U8 m_flag; + U8 m_mode; + U8 m_texIdx[2]; + U8 m_rotdeg[3]; + U8 pad8; + F32 totalLifespan; + xParEmitterAsset* m_asset; + F32 m_cvel[4]; + F32 m_cfl[4]; +}; + +void xParMemInit(); +xPar* xParAlloc(); +void xParFree(xPar* par); +void xParInit(xPar* p); #endif diff --git a/src/SB/Core/x/xParCmd.h b/src/SB/Core/x/xParCmd.h new file mode 100644 index 0000000..2f6660e --- /dev/null +++ b/src/SB/Core/x/xParCmd.h @@ -0,0 +1,366 @@ +#ifndef XPARCMD_H +#define XPARCMD_H + +#include "xParGroup.h" + +#define XPARCMD_TYPE_MOVE 0 +#define XPARCMD_TYPE_MOVERANDOM 1 +#define XPARCMD_TYPE_ACCELERATE 2 +#define XPARCMD_TYPE_VELOCITYAPPLY 3 +#define XPARCMD_TYPE_JET 4 +#define XPARCMD_TYPE_UNK5 5 +#define XPARCMD_TYPE_KILLSLOW 6 +#define XPARCMD_TYPE_FOLLOW 7 +#define XPARCMD_TYPE_ORBITPOINT 8 +#define XPARCMD_TYPE_ORBITLINE 9 +#define XPARCMD_TYPE_MOVERANDOMPAR 10 +#define XPARCMD_TYPE_SCALE3RDPOLYREG 11 +#define XPARCMD_TYPE_TEX 12 +#define XPARCMD_TYPE_TEXANIM 13 +#define XPARCMD_TYPE_PLAYERCOLLISION 14 +#define XPARCMD_TYPE_RANDOMVELOCITYPAR 15 +#define XPARCMD_TYPE_CUSTOM 16 +#define XPARCMD_TYPE_KILLDISTANCE 17 +#define XPARCMD_TYPE_AGE 18 +#define XPARCMD_TYPE_ALPHA3RDPOLYREG 19 +#define XPARCMD_TYPE_APPLYWIND 20 +#define XPARCMD_TYPE_ROTPAR 21 +#define XPARCMD_TYPE_APPLYCAMMAT 22 +#define XPARCMD_TYPE_ROTATEAROUND 23 +#define XPARCMD_TYPE_SMOKEALPHA 24 +#define XPARCMD_TYPE_SCALE 25 +#define XPARCMD_TYPE_CLIPVOLUMES 26 +#define XPARCMD_TYPE_ANIMALMAGENTISM 27 +#define XPARCMD_TYPE_DAMAGEPLAYER 28 +#define XPARCMD_TYPE_COLLIDEFALL 29 +#define XPARCMD_TYPE_SHAPER 30 +#define XPARCMD_TYPE_ALPHAINOUT 31 +#define XPARCMD_TYPE_SIZEINOUT 32 +#define XPARCMD_TYPE_DAMPENSPEED 33 +#define XPARCMD_TYPE_COLLIDEFALLSTICKY 34 +#define XPARCMD_TYPE_COUNT 35 + +struct xParCmdAsset +{ + U32 type; + U8 enabled; + U8 mode; + U8 pad[2]; +}; + +struct xParCmd +{ + U32 flag; + xParCmdAsset* tasset; +}; + +struct xParGroup; + +typedef void (*xParCmdUpdateFunc)(xParCmd* c, xParGroup* ps, F32 dt); + +void xParCmdInit(); +void xParCmdRegister(U32 parType, U32 size, xParCmdUpdateFunc func); +U32 xParCmdGetSize(U32 parType); +xParCmdUpdateFunc xParCmdGetUpdateFunc(U32 parType); + +// XPARCMD_TYPE_MOVE +void xParCmdMove_Update(xParCmd* c, xParGroup* ps, F32 dt); + +struct xParCmdMove : xParCmdAsset +{ + xVec3 dir; +}; + +// XPARCMD_TYPE_MOVERANDOM +void xParCmdMoveRandom_Update(xParCmd* c, xParGroup* ps, F32 dt); + +// XPARCMD_TYPE_ACCELERATE +void xParCmdAccelerate_Update(xParCmd* c, xParGroup* ps, F32 dt); + +struct xParCmdAccelerate : xParCmdAsset +{ + xVec3 acc; +}; + +// XPARCMD_TYPE_VELOCITYAPPLY +void xParCmdVelocityApply_Update(xParCmd* c, xParGroup* ps, F32 dt); + +// XPARCMD_TYPE_JET +void xParCmdJet_Update(xParCmd* c, xParGroup* ps, F32 dt); + +struct xParCmdJet : xParCmdAsset +{ + xVec3 center; + xVec3 acc; + F32 gravity; + F32 epsilon; + F32 radiusSqr; +}; + +// XPARCMD_TYPE_UNK5 +struct xParCmdUnk5 : xParCmdAsset // not in dwarf +{ + S32 unknown; +}; + +// XPARCMD_TYPE_KILLSLOW +void xParCmdKillSlow_Update(xParCmd* c, xParGroup* ps, F32 dt); + +struct xParCmdKillSlow : xParCmdAsset +{ + F32 speedLimitSqr; + U32 kill_less_than; +}; + +// XPARCMD_TYPE_FOLLOW +void xParCmdFollow_Update(xParCmd* c, xParGroup* ps, F32 dt); + +struct xParCmdFollow : xParCmdAsset +{ + F32 gravity; + F32 epsilon; +}; + +// XPARCMD_TYPE_ORBITPOINT +void xParCmdOrbitPoint_Update(xParCmd* c, xParGroup* ps, F32 dt); + +struct xParCmdOrbitPoint : xParCmdAsset +{ + xVec3 center; + F32 gravity; + F32 epsilon; + F32 maxRadiusSqr; +}; + +// XPARCMD_TYPE_ORBITLINE +void xParCmdOrbitLine_Update(xParCmd* c, xParGroup* ps, F32 dt); + +struct xParCmdOrbitLine : xParCmdAsset +{ + xVec3 p; + xVec3 axis; + F32 gravity; + F32 epsilon; + F32 maxRadiusSqr; +}; + +// XPARCMD_TYPE_MOVERANDOMPAR +void xParCmdMoveRandomPar_Update(xParCmd* c, xParGroup* ps, F32 dt); + +struct xParCmdMoveRandomPar : xParCmdAsset +{ + xVec3 dim; +}; + +// XPARCMD_TYPE_SCALE3RDPOLYREG +void xParCmdScale3rdPolyReg_Update(xParCmd* c, xParGroup* ps, F32 dt); + +struct xParCmdScale3rdPolyReg : xParCmdAsset // not in dwarf +{ + S32 unknown[4]; +}; + +// XPARCMD_TYPE_TEX +void xParCmdTex_Update(xParCmd* c, xParGroup* ps, F32 dt); + +struct xParCmdTex : xParCmdAsset +{ + F32 x1; + F32 y1; + F32 x2; + F32 y2; + U8 birthMode; + U8 rows; + U8 cols; + U8 unit_count; + F32 unit_width; + F32 unit_height; +}; + +// XPARCMD_TYPE_TEXANIM +void xParCmdTexAnim_Update(xParCmd* c, xParGroup* ps, F32 dt); + +struct xParCmdTexAnim : xParCmdAsset +{ + U8 anim_mode; + U8 anim_wrap_mode; + U8 pad_anim; + U8 throttle_spd_less_than; + F32 throttle_spd_sqr; + F32 throttle_time; + F32 throttle_time_elapsed; +}; + +// XPARCMD_TYPE_PLAYERCOLLISION +void xParCmdPlayerCollision_Update(xParCmd* c, xParGroup* ps, F32 dt); + +// XPARCMD_TYPE_RANDOMVELOCITYPAR +void xParCmdRandomVelocityPar_Update(xParCmd* c, xParGroup* ps, F32 dt); + +struct xParCmdRandomVelocityPar : xParCmdAsset +{ + F32 x; + F32 y; + F32 z; +}; + +// XPARCMD_TYPE_CUSTOM +void xParCmdCustom_Update(xParCmd* c, xParGroup* ps, F32 dt); + +struct xParCmdCustom : xParCmdAsset // not in dwarf +{ + U32 unknown; +}; + +void xParCmdCustom_Grass_Update(xParCmd* c, xParGroup* ps, F32 dt); + +// XPARCMD_TYPE_KILLDISTANCE +void xParCmdKillDistance_Update(xParCmd* c, xParGroup* ps, F32 dt); + +struct xParCmdKillDistance : xParCmdAsset +{ + F32 dSqr; + U32 kill_greater_than; +}; + +// XPARCMD_TYPE_AGE +void xParCmdAge_Update(xParCmd* c, xParGroup* ps, F32 dt); + +struct xParCmdAge : xParCmdAsset // not in dwarf +{ + F32 unknown; +}; + +// XPARCMD_TYPE_ALPHA3RDPOLYREG +void xParCmdAlpha3rdPolyReg_Update(xParCmd* c, xParGroup* ps, F32 dt); + +struct xParCmdAlpha3rdPolyReg : xParCmdAsset // not in dwarf +{ + S32 unknown[4]; +}; + +// XPARCMD_TYPE_APPLYWIND +void xParCmdApplyWind_Update(xParCmd* c, xParGroup* ps, F32 dt); + +struct xParCmdApplyWind : xParCmdAsset // not in dwarf +{ + F32 unknown; +}; + +// XPARCMD_TYPE_ROTPAR +void xParCmdRotPar_Update(xParCmd* c, xParGroup* ps, F32 dt); + +struct xParCmdRotPar : xParCmdAsset +{ + xVec3 min; + xVec3 max; +}; + +// XPARCMD_TYPE_APPLYCAMMAT +void xParCmdApplyCamMat_Update(xParCmd* c, xParGroup* ps, F32 dt); + +struct xParCmdApplyCamMat : xParCmdAsset +{ + xVec3 apply; +}; + +// XPARCMD_TYPE_ROTATEAROUND +void xParCmdRotateAround_Update(xParCmd* c, xParGroup* ps, F32 dt); + +struct xParCmdRotateAround : xParCmdAsset +{ + xVec3 pos; + F32 unused1; + F32 radius_growth; + F32 yaw; +}; + +// XPARCMD_TYPE_SMOKEALPHA +void xParCmdSmokeAlpha_Update(xParCmd* c, xParGroup* ps, F32 dt); + +struct xParCmdSmokeAlpha : xParCmdAsset // not in dwarf +{ + S32 unknown; +}; + +// XPARCMD_TYPE_SCALE +void xParCmdScale_Update(xParCmd* c, xParGroup* ps, F32 dt); + +struct xParCmdScale : xParCmdAsset // not in dwarf +{ + S32 unknown; +}; + +// XPARCMD_TYPE_CLIPVOLUMES +void xParCmdClipVolumes_Update(xParCmd* c, xParGroup* ps, F32 dt); + +// XPARCMD_TYPE_ANIMALMAGENTISM +void xParCmdAnimalMagentism_Update(xParCmd* c, xParGroup* ps, F32 dt); + +struct xParCmdAnimalMagnetism : xParCmdAsset // not in dwarf +{ + F32 unknown; +}; + +// XPARCMD_TYPE_DAMAGEPLAYER +void xParCmdDamagePlayer_Update(xParCmd* c, xParGroup* ps, F32 dt); + +struct xParCmdDamagePlayer : xParCmdAsset +{ + S32 damage; + S32 granular; +}; + +// XPARCMD_TYPE_COLLIDEFALL +void xParCmdCollideFall_Update(xParCmd* c, xParGroup* ps, F32 dt); + +struct xParCmdCollideFall : xParCmdAsset +{ + F32 y; + F32 bounce; +}; + +// XPARCMD_TYPE_SHAPER +void xParCmd_Shaper_Update(xParCmd* c, xParGroup* ps, F32 dt); + +struct xParCmdShaperData : xParCmdAsset +{ + F32 custAlpha[4]; + F32 custSize[4]; + F32 dampSpeed; + F32 gravity; +}; + +// XPARCMD_TYPE_ALPHAINOUT +void xParCmd_AlphaInOut_Update(xParCmd* c, xParGroup* ps, F32 dt); + +struct xParCmdAlphaInOutData : xParCmdAsset +{ + F32 custAlpha[4]; +}; + +// XPARCMD_TYPE_SIZEINOUT +void xParCmd_SizeInOut_Update(xParCmd* c, xParGroup* ps, F32 dt); + +struct xParCmdSizeInOutData : xParCmdAsset +{ + F32 custSize[4]; +}; + +// XPARCMD_TYPE_DAMPENSPEED +void xParCmd_DampenSpeed_Update(xParCmd* c, xParGroup* ps, F32 dt); + +struct xParCmdDampenData : xParCmdAsset +{ + F32 dampSpeed; +}; + +// XPARCMD_TYPE_COLLIDEFALLSTICKY +void xParCmdCollideFallSticky_Update(xParCmd* c, xParGroup* ps, F32 dt); + +struct xParCmdCollideFallSticky : xParCmdCollideFall +{ + F32 sticky; +}; + +#endif diff --git a/src/SB/Core/x/xParEmitter.h b/src/SB/Core/x/xParEmitter.h new file mode 100644 index 0000000..7a208a4 --- /dev/null +++ b/src/SB/Core/x/xParEmitter.h @@ -0,0 +1,113 @@ +#ifndef XPAREMITTER_H +#define XPAREMITTER_H + +#include "xBase.h" +#include "xModel.h" +#include "xParEmitterType.h" +#include "xParGroup.h" +#include "xParSys.h" + +struct xParInterp +{ + F32 val[2]; + U32 interp; + F32 freq; + F32 oofreq; + + void set(F32, F32, F32, U32); +}; + +// Size 0x138 +struct xParEmitterPropsAsset : xBaseAsset +{ + U32 parSysID; + union + { + xParInterp rate; + xParInterp value[1]; + }; + xParInterp life; + xParInterp size_birth; + xParInterp size_death; + xParInterp color_birth[4]; + xParInterp color_death[4]; + xParInterp vel_scale; + xParInterp vel_angle; + xVec3 vel; + U32 emit_limit; + F32 emit_limit_reset_time; +}; + +// Size 0x16c +struct xParEmitterCustomSettings : xParEmitterPropsAsset +{ + U32 custom_flags; + U32 attachToID; + xVec3 pos; + xVec3 vel; + F32 vel_angle_variation; + U8 rot[3]; + U8 padding; + F32 radius; + F32 emit_interval_current; + void* emit_volume; +}; + +struct xParEmitterAsset : xBaseAsset +{ + U8 emit_flags; + U8 emit_type; + U16 pad; + U32 propID; + union + { + xPECircle e_circle; + _tagEmitSphere e_sphere; + _tagEmitRect e_rect; + _tagEmitLine e_line; + _tagEmitVolume e_volume; + _tagEmitOffsetPoint e_offsetp; + xPEVCyl e_vcyl; + xPEEntBone e_entbone; + xPEEntBound e_entbound; + }; + U32 attachToID; + xVec3 pos; + xVec3 vel; + F32 vel_angle_variation; + U32 cull_mode; + F32 cull_dist_sqr; +}; + +struct xParEmitter : xBase +{ + xParEmitterAsset* tasset; + xParGroup* group; + xParEmitterPropsAsset* prop; + U8 rate_mode; + F32 rate; + F32 rate_time; + F32 rate_fraction; + F32 rate_fraction_cull; + U8 emit_flags; + U8 emit_pad[3]; + U8 rot[3]; + xModelTag tag; + F32 oocull_distance_sqr; + F32 distance_to_cull_sqr; + void* attachTo; + xParSys* parSys; + void* emit_volume; + xVec3 last_attach_loc; +}; + +struct xScene; + +void xParEmitterInit(void* b, void* tasset); +void xParEmitterSetup(xParEmitter* t); +void xParEmitterDestroy(); +void xParEmitterUpdate(xBase* to, xScene*, F32 dt); +xPar* xParEmitterEmitCustom(xParEmitter* p, F32 dt, xParEmitterCustomSettings* info); +F32 xParInterpCompute(S32 interp_mode, xParInterp* r, F32 time, S32 time_has_elapsed, F32 last_val); + +#endif diff --git a/src/SB/Core/x/xParEmitterType.h b/src/SB/Core/x/xParEmitterType.h new file mode 100644 index 0000000..8f494c2 --- /dev/null +++ b/src/SB/Core/x/xParEmitterType.h @@ -0,0 +1,69 @@ +#ifndef XPAREMITTERTYPE_H +#define XPAREMITTERTYPE_H + +#include "xMath3.h" + +struct xPECircle +{ + F32 radius; + F32 deflection; + xVec3 dir; +}; + +struct _tagEmitSphere +{ + F32 radius; +}; + +struct _tagEmitRect +{ + F32 x_len; + F32 z_len; +}; + +struct _tagEmitLine +{ + xVec3 pos1; + xVec3 pos2; + F32 radius; +}; + +struct _tagEmitVolume +{ + U32 emit_volumeID; +}; + +struct _tagEmitOffsetPoint +{ + xVec3 offset; +}; + +struct xPEVCyl +{ + F32 height; + F32 radius; + F32 deflection; +}; + +struct xPEEntBone +{ + U8 flags; + U8 type; + U8 bone; + U8 pad1; + xVec3 offset; + F32 radius; + F32 deflection; +}; + +struct xPEEntBound +{ + U8 flags; + U8 type; + U8 pad1; + U8 pad2; + F32 expand; + F32 deflection; +}; + +#endif diff --git a/src/SB/Core/x/xParGroup.h b/src/SB/Core/x/xParGroup.h new file mode 100644 index 0000000..3fbad09 --- /dev/null +++ b/src/SB/Core/x/xParGroup.h @@ -0,0 +1,48 @@ +#ifndef XPARGROUP_H +#define XPARGROUP_H + +#include "xPar.h" + +struct xParCmdTex; + +struct xParGroup +{ + xPar* m_root; + xPar* m_dead; + S32 m_num_of_particles; + U8 m_alive; + U8 m_killWhenDead; + U8 m_active; + U8 m_visible; + U8 m_culled; + U8 m_priority; + U8 m_flags; + U8 m_regidx; + xParGroup* m_next; + xParGroup* m_prev; + void (*draw)(void*, xParGroup*); + xParCmdTex* m_cmdTex; +}; + +#define XPARGROUP_UNK1 0x1 +#define XPARGROUP_ALLOCPARS 0x2 +#define XPARGROUP_NOAGING 0x4 +#define XPARGROUP_NOBACK2LIFE 0x8 +#define XPARGROUP_UNK10 0x10 + +void xParGroupInit(xParGroup* ps); +void xParGroupSetAging(xParGroup* ps, S32 age); +void xParGroupSetBack2Life(xParGroup* ps, S32 b2l); +void xParGroupSetVisibility(xParGroup* ps, S32 vis); +void xParGroupSetPriority(xParGroup* ps, U8 val); +void xParGroupRegister(xParGroup* ps); +void xParGroupUnregister(xParGroup* ps); +void xParGroupSetActive(xParGroup* ps, U32 isActive); +void xParGroupKillAllParticles(xParGroup* ps); +void xParGroupAnimate(xParGroup* ps, F32 dt); +void xParGroupAddParP(xParGroup* ps, xPar* p); +xPar* xParGroupAddPar(xParGroup* ps); +void xParGroupKillPar(xParGroup* ps, xPar* p); +void xParGroupAddParToDeadList(xParGroup* ps, xPar* p); + +#endif diff --git a/src/SB/Core/x/xParMgr.h b/src/SB/Core/x/xParMgr.h new file mode 100644 index 0000000..52e0d3e --- /dev/null +++ b/src/SB/Core/x/xParMgr.h @@ -0,0 +1,11 @@ +#ifndef XPARMGR_H +#define XPARMGR_H + +#include + +void xParMgrInit(); +void xParMgrKillAllParticles(); +void xParMgrUpdate(F32 elapsedTime); +void xParMgrRender(); + +#endif diff --git a/src/SB/Core/x/xParSys.h b/src/SB/Core/x/xParSys.h new file mode 100644 index 0000000..2b94a8f --- /dev/null +++ b/src/SB/Core/x/xParSys.h @@ -0,0 +1,44 @@ +#ifndef XPARSYS_H +#define XPARSYS_H + +#include "xBase.h" +#include "xParCmd.h" +#include "xParGroup.h" + +#include + +struct xScene; + +struct xParSysAsset : xBaseAsset +{ + U32 type; + U32 parentParSysID; + U32 textureID; + U8 parFlags; + U8 priority; + U16 maxPar; + U8 renderFunc; + U8 renderSrcBlendMode; + U8 renderDstBlendMode; + U8 cmdCount; + U32 cmdSize; +}; + +struct xParSys : xBase +{ + xParSysAsset* tasset; + U32 cmdCount; + xParCmd* cmd; + xParSys* parent; + xParGroup* group; + U8 visible; + RwTexture* txtr_particle; +}; + +void xParSysInit(void* b, void* tasset); +void xParSysSetup(xParSys* t); +void xParSysExit(xParSys* t); +void xParSysRender(xBase* b); +void xParSysUpdate(xBase* to, xScene*, F32 dt); + +#endif diff --git a/src/SB/Core/x/xPartition.h b/src/SB/Core/x/xPartition.h new file mode 100644 index 0000000..6a6edd1 --- /dev/null +++ b/src/SB/Core/x/xPartition.h @@ -0,0 +1,46 @@ +#ifndef XPARTITION_H +#define XPARTITION_H + +#include +#include "xMath3.h" +#include "xEnv.h" +#include "xVolume.h" + +struct _tagPartLink +{ + void* data; + _tagPartLink* next; +}; + +struct _tagPartSpace +{ + S32 total; + _tagPartLink head; +}; + +struct _tagPartition +{ + xVec3 min; + xVec3 max; + xVec3 space_dim; + S32 total_x; + S32 total_y; + S32 total_z; + _tagPartSpace* space; + _tagPartSpace global; +}; + +void xPartitionReset(); +_tagPartLink* PartitionGetFreeLink(); +void PartitionSpaceReset(_tagPartSpace* space); +void PartitionSpaceInsert(_tagPartSpace* space, void* data); +S32 xPartitionGetTrueIdx(_tagPartition* part, S32 x_spaces, S32 y_spaces, S32 z_spaces); +void xPartitionWorld(_tagPartition* part, xEnv* env, S32 x_spaces, S32 y_spaces, + S32 z_spaces); +void xPartitionVolume(_tagPartition* part, xVolume* volume, S32 x_spaces, S32 y_spaces, + S32 z_spaces); +void xPartitionDump(_tagPartition* part, char* string); +S32 xPartitionUpdate(_tagPartition* part, void* data, S32 old_idx, xVec3* current_pos); +S32 xPartitionInsert(_tagPartition* part, void* insert_data, xVec3* insert_pos); + +#endif diff --git a/src/SB/Core/x/xPlayer.h b/src/SB/Core/x/xPlayer.h deleted file mode 100644 index fb908fc..0000000 --- a/src/SB/Core/x/xPlayer.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef XPLAYER_H -#define XPLAYER_H - -#include "xEnt.h" - -struct zEnt : xEnt -{ - xAnimTable* atbl; -}; - -struct zPlayer : zEnt -{ - xVec3 trigLastFramePos; - S32 zPlayerFlags; - U32 lorezModelID; - xModelInstance* lorezModel; - xModelInstance* hirezModel; - - void PostRenderCleanup(); - void RenderCustomUI(); - void zPlayerEventCB(xBase* from, xBase* to, U32 toEvent, F32* toParam, xBase* toParamWidget, - U32 toParamWidgetID); - U32 TalkDoneCheck(xAnimTransition* tran); - U32 TalkCheck(xAnimTransition* tran); - U8 AllowInteraction(); - void AttackHit(); - xEnt* GetGrabbed(); -}; - -#endif diff --git a/src/SB/Core/x/xPtankPool.h b/src/SB/Core/x/xPtankPool.h new file mode 100644 index 0000000..56b6429 --- /dev/null +++ b/src/SB/Core/x/xPtankPool.h @@ -0,0 +1,65 @@ +#ifndef XPTANKPOOL_H +#define XPTANKPOOL_H + +#include +#include +#include +#include + +struct iColor_tag; +struct xVec2; +struct xVec3; + +enum ptank_group_type +{ + PGT_COLOR_MAT_UV2, + PGT_POS_COLOR_SIZE_UV2, + MAX_PGT +}; + +struct render_state +{ + RwTexture* texture; + U32 src_blend; + U32 dst_blend; + U32 flags; +}; + +struct _class +{ + U8* data; + S32 stride; + U32 size; +}; + +struct ptank_pool +{ + render_state rs; + U32 used; + RpAtomic* ptank; + _class hide; + + bool valid() const; + void reset(); + void flush(); + void grab_block(ptank_group_type type); +}; + +// total size: 0x38 +struct ptank_pool__pos_color_size_uv2 : public ptank_pool +{ + xVec3* pos; + iColor_tag* color; + xVec2* size; + xVec2* uv; + S32 stride; + + void next(); + void flush(); +}; + +void xPTankPoolSceneEnter(); +void xPTankPoolSceneExit(); +void xPTankPoolRender(); + +#endif diff --git a/src/SB/Core/x/xQuickCull.h b/src/SB/Core/x/xQuickCull.h index 6a445bc..cff957b 100644 --- a/src/SB/Core/x/xQuickCull.h +++ b/src/SB/Core/x/xQuickCull.h @@ -1,15 +1,64 @@ -#include "xMath.h" +#ifndef XQUICKCULL_H +#define XQUICKCULL_H +#include "xVec3.h" +#include "xMath3.h" + +// Size: 0x20 struct xQCData { - U8 xmin; - U8 ymin; - U8 zmin; - U8 zmin_dup; - U8 xmax; - U8 ymax; - U8 zmax; - U8 zmax_dup; + S8 xmin; + S8 ymin; + S8 zmin; + S8 zmin_dup; + S8 xmax; + S8 ymax; + S8 zmax; + S8 zmax_dup; xVec3 min; xVec3 max; }; + +struct xQCControl +{ + F32 world_xmin; + F32 world_ymin; + F32 world_zmin; + F32 world_xmax; + F32 world_ymax; + F32 world_zmax; + F32 world_xsz; + F32 world_ysz; + F32 world_zsz; + F32 scale_x; + F32 scale_y; + F32 scale_z; + F32 center_x; + F32 center_y; + F32 center_z; +}; + +extern xQCControl xqc_def_ctrl; + +struct xBound; +struct xBox; + +void xQuickCullInit(const xBox* box); +void xQuickCullInit(xQCControl* ctrl, const xBox* box); + +void xQuickCullInit(xQCControl* ctrl, F32 xmin, F32 ymin, F32 zmin, F32 xmax, + F32 ymax, F32 zmax); +void xQuickCullInit(xQCControl* ctrl, const xBox* box); +S32 xQuickCullIsects(const xQCData* a, const xQCData* b); +void xQuickCullForBound(xQCControl* ctrl, xQCData* q, const xBound* b); +void xQuickCullCellForVec(xQCControl* ctrl, xQCData* c, const xVec3* v); +void xQuickCullCellMerge(xQCData* dest, const xQCData* a, const xQCData* b); +void xQuickCullForLine(xQCControl* ctrl, xQCData* q, const xLine3* ln); +void xQuickCullForRay(xQCControl* ctrl, xQCData* q, const xRay3* r); +void xQuickCullForSphere(xQCControl* ctrl, xQCData* q, const xSphere* s); +void xQuickCullForBox(xQCControl* ctrl, xQCData* q, const xBox* box); +void xQuickCullForOBB(xQCControl* ctrl, xQCData* q, const xBox* b, const xMat4x3* m); +void xQuickCullForEverything(xQCData* q); +void xQuickCullForBound(xQCData* q, const xBound* b); + +#endif diff --git a/src/SB/Core/x/xRMemData.h b/src/SB/Core/x/xRMemData.h new file mode 100644 index 0000000..9d0a94b --- /dev/null +++ b/src/SB/Core/x/xRMemData.h @@ -0,0 +1,33 @@ +#ifndef XRMEMDATA_H +#define XRMEMDATA_H + +#include "xBase.h" + +#include + +struct RyzMemGrow +{ + S32 flg_grow; + S32 amt; + char* ptr; + xBase* user; + S32 amt_last; + char* ptr_last; + xBase* user_last; + + RyzMemGrow* Init(xBase* growuser); + RyzMemGrow* Resume(xBase*); + void Done(); + S32 IsEnabled() + { + return this->flg_grow & 1; + } +}; + +struct RyzMemData +{ + void* operator new(size_t amt, S32, RyzMemGrow* growCtxt); + void operator delete(void*); +}; + +#endif diff --git a/src/SB/Core/x/xRay3.h b/src/SB/Core/x/xRay3.h new file mode 100644 index 0000000..5a2698b --- /dev/null +++ b/src/SB/Core/x/xRay3.h @@ -0,0 +1,15 @@ +#ifndef XRAY3_H +#define XRAY3_H + +#include "xMath3.h" + +struct xRay3 +{ + xVec3 origin; + xVec3 dir; + F32 min_t; + F32 max_t; + S32 flags; +}; + +#endif diff --git a/src/SB/Core/x/xRenderState.h b/src/SB/Core/x/xRenderState.h new file mode 100644 index 0000000..9bb8c57 --- /dev/null +++ b/src/SB/Core/x/xRenderState.h @@ -0,0 +1,11 @@ +#ifndef XRENDERSTATE_H +#define XRENDERSTATE_H + +#include +#include + +void xRenderStateSetDstBlendMode(S32 xmode); +void xRenderStateSetSrcBlendMode(S32 xmode); +void xRenderStateSetTexture(RwTexture* texture); + +#endif diff --git a/src/SB/Core/x/xRumble.h b/src/SB/Core/x/xRumble.h new file mode 100644 index 0000000..f161cf1 --- /dev/null +++ b/src/SB/Core/x/xRumble.h @@ -0,0 +1,33 @@ +#ifndef XRUMBLE_H +#define XRUMBLE_H + +#include + +enum _tagRumbleType +{ + eRumble_Off, + eRumble_Hi, + eRumble_VeryLightHi, + eRumble_VeryLight, + eRumble_LightHi, + eRumble_Light, + eRumble_MediumHi, + eRumble_Medium, + eRumble_HeavyHi, + eRumble_Heavy, + eRumble_VeryHeavyHi, + eRumble_VeryHeavy, + eRumble_Total, + eRumbleForceU32 = 0x7fffffff +}; + +struct _tagxRumble +{ + _tagRumbleType type; + F32 seconds; + _tagxRumble* next; + S16 active; + U16 fxflags; +}; + +#endif diff --git a/src/SB/Core/x/xSFX.h b/src/SB/Core/x/xSFX.h new file mode 100644 index 0000000..355d8cc --- /dev/null +++ b/src/SB/Core/x/xSFX.h @@ -0,0 +1,41 @@ +#ifndef XSFX_H +#define XSFX_H + +#include "xBase.h" +#include "xMath3.h" + +#include "iColor.h" + +struct xSFXAsset : xBaseAsset +{ + U16 flagsSFX; + U16 freq; + F32 freqm; + U32 soundAssetID; + U32 attachID; + U8 loopCount; + U8 priority; + U8 volume; + U8 pad; + xVec3 pos; + F32 innerRadius; + F32 outerRadius; +}; + +struct xSFX : xBase +{ + xSFXAsset* asset; + U32 sndID; + F32 cachedOuterDistSquared; +}; + +void xSFXInit(void* t, void* asset); +void xSFXInit(xSFX* t, xSFXAsset* asset); +void xSFXSave(xSFX* ent, xSerial* s); +void xSFXLoad(xSFX* ent, xSerial* s); +void xSFXEnvironmentalStreamSceneExit(); +void xSFXUpdateEnvironmentalStreamSounds(xSFX* pSFXList, U32 numSounds); +S32 xSFXEventCB(xBase* to, xBase* from, U32 toEvent, const F32* toParam, xBase*); +S32 xSFXWillSendDone(xSFX*); + +#endif diff --git a/src/SB/Core/x/xScene.h b/src/SB/Core/x/xScene.h new file mode 100644 index 0000000..c883872 --- /dev/null +++ b/src/SB/Core/x/xScene.h @@ -0,0 +1,66 @@ +#ifndef XSCENE_H +#define XSCENE_H + +#include "xBase.h" +#include "xEnt.h" +#include "xEnv.h" +#include "xMemMgr.h" +#include "xRay3.h" + +typedef const char* (*xSceneBase2NameCallback)(xBase*); +typedef const char* (*xSceneID2NameCallback)(U32); +typedef xBase* (*xSceneResolvIDCallback)(U32); +typedef xEnt* (*xSceneEntCallback)(xEnt* ent, xScene* sc, void* data); + +struct xScene +{ + U32 sceneID; + U16 flags; + U16 num_ents; + U16 num_trigs; + U16 num_stats; + U16 num_dyns; + U16 num_npcs; + U16 num_act_ents; + U16 num_nact_ents; + F32 gravity; + F32 drag; + F32 friction; + U16 num_ents_allocd; + U16 num_trigs_allocd; + U16 num_stats_allocd; + U16 num_dyns_allocd; + U16 num_npcs_allocd; + xEnt** trigs; + xEnt** stats; + xEnt** dyns; + xEnt** npcs; + xEnt** act_ents; + xEnt** nact_ents; + xEnv* env; + xMemPool mempool; + xSceneResolvIDCallback resolvID; + xSceneBase2NameCallback base2Name; + xSceneID2NameCallback id2Name; +}; + +extern xScene* g_xSceneCur; + +void xSceneInit(xScene* sc, U16 num_trigs, U16 num_stats, U16 num_dyns, U16 num_npcs); +void xSceneExit(xScene* sc); +void xSceneSave(xScene* sc, xSerial* s); +void xSceneLoad(xScene* sc, xSerial* s); +void xSceneSetup(xScene* sc); +void xSceneAddEnt(xScene* sc, xEnt* ent); +xBase* xSceneResolvID(xScene* sc, U32 id); +const char* xSceneID2Name(xScene* sc, U32 id); +void xSceneForAllEnts(xScene* sc, xSceneEntCallback func, void* data); +void xSceneForAllStatics(xScene* sc, xSceneEntCallback func, void* data); +void xSceneForAllDynamics(xScene* sc, xSceneEntCallback func, void* data); +void xSceneForAllNPCs(xScene* sc, xSceneEntCallback func, void* data); +void xRayHitsTikiLandableEnt(xScene* sc, xRay3* r, xQCData* qcr, xEnt* ent, void* colldata); +void xRayHitsEnt(xScene* sc, xRay3* r, xQCData* qcr, xEnt* ent, void* colldata); +void xRayHitsScene(xScene* sc, xRay3* r, xCollis* coll); +void xRayHitsSceneFlags(xScene* sc, xRay3* r, xCollis* coll, U8 collType, U8 chk); + +#endif diff --git a/src/SB/Core/x/xScrFx.h b/src/SB/Core/x/xScrFx.h new file mode 100644 index 0000000..2d1162f --- /dev/null +++ b/src/SB/Core/x/xScrFx.h @@ -0,0 +1,23 @@ +#ifndef XSCRFX_H +#define XSCRFX_H + +#include "xCamera.h" +#include "iColor.h" + +#include + +void xScrFxUpdate(RwCamera* cam, F32 dt); +void xScrFxRender(RwCamera*); +void xScrFxDrawScreenSizeRectangle(); +void xScrFxFade(iColor_tag* base, iColor_tag* dest, F32 seconds, void (*callback)(), + S32 hold); +S32 xScrFxIsLetterbox(); +void xScrFxLetterboxReset(); +S32 xScrFXGlareAdd(xVec3* pos, F32 life, F32 intensity, F32 size, F32 r, + F32 g, F32 b, F32 a, RwRaster* raster); +void xScrFXFullScreenGlareRender(); +void xScrFXGlareRender(xCamera* cam); +void xScrFxLetterbox(S32 enable); +void xScrFxReset(); + +#endif diff --git a/src/SB/Core/x/xShadow.h b/src/SB/Core/x/xShadow.h index 68773ef..1947f13 100644 --- a/src/SB/Core/x/xShadow.h +++ b/src/SB/Core/x/xShadow.h @@ -1,39 +1,44 @@ #ifndef XSHADOW_H #define XSHADOW_H -#include "xMath.h" +#include "xEnt.h" -struct xEnt; +#include +#include -struct xShadowSimplePoly +struct xShadowPoly { xVec3 vert[3]; xVec3 norm; }; -struct xShadowSimpleCache +struct xShadowCache { - U16 flags; - U8 alpha; - U8 pad; - U32 collPriority; xVec3 pos; - xVec3 at; - F32 tol_movement; - F32 radiusOptional; - xEnt* castOnEnt; - xShadowSimplePoly poly; - F32 envHeight; - F32 shadowHeight; - union - { - U32 raster; - RwRaster* ptr_raster; - }; - F32 dydx; - F32 dydz; - xVec3 corner[4]; - void* collSkipsItem; + F32 radius; + U32 entCount; + U32 polyCount; + F32 polyRayDepth[5]; + U16 castOnEnt; + U16 castOnPoly; + xEnt* ent[16]; + xShadowPoly poly[256]; }; +struct xShadowMgr +{ + xEnt* ent; + xShadowCache* cache; + int priority; + int cacheReady; +}; + +void xShadow_ListAdd(xEnt* ent); +void xShadowSetWorld(RpWorld* world); +void xShadowSetLight(xVec3* param1, xVec3* param2, F32 param3); +void xShadowManager_Init(S32 numEnts); +void xShadowManager_Reset(); +void xShadowManager_Render(); +void xShadowRender(xEnt* ent, F32 max_dist); + #endif diff --git a/src/SB/Core/x/xShadowSimple.h b/src/SB/Core/x/xShadowSimple.h new file mode 100644 index 0000000..dd58595 --- /dev/null +++ b/src/SB/Core/x/xShadowSimple.h @@ -0,0 +1,45 @@ +#ifndef XSHADOWSIMPLE_H +#define XSHADOWSIMPLE_H + +#include "xEnt.h" + +struct xShadowSimplePoly +{ + xVec3 vert[3]; + xVec3 norm; +}; + +// Size: 0x66 +struct xShadowSimpleCache +{ + U16 flags; + U8 alpha; + U8 pad; + + // Offset: 0x4 + U32 collPriority; + xVec3 pos; + xVec3 at; + + // Offset: 0x20 + xEnt* castOnEnt; + xShadowSimplePoly poly; + F32 envHeight; + F32 shadowHeight; + U32 raster; + + // Offset: 0x40 + F32 dydx; + F32 dydz; + xVec3 corner[4]; +}; + +void xShadowSimple_Render(); +void xShadowSimple_Add(xShadowSimpleCache* cache, xEnt* ent, F32 radius, F32 ecc); +void xShadowSimple_CacheInit(xShadowSimpleCache* cache, xEnt* ent, U8 alpha); +void xShadowSimple_Init(); +void xShadowSimple_AddVerts(xShadowSimpleCache* cache); +void xShadowSimple_CalcCorners(xShadowSimpleCache* cache, xEnt* ent, F32 radius, F32 ecc); +void xShadowSimple_SceneCollide(xShadowSimpleCache* cache, xVec3* pos, F32 depth); + +#endif diff --git a/src/SB/Core/x/xSkyDome.h b/src/SB/Core/x/xSkyDome.h new file mode 100644 index 0000000..f1de32f --- /dev/null +++ b/src/SB/Core/x/xSkyDome.h @@ -0,0 +1,10 @@ +#ifndef XSKYDOME_H +#define XSKYDOME_H + +#include "xEnt.h" + +void xSkyDome_Setup(); +void xSkyDome_AddEntity(xEnt* ent, S32 sortorder, S32 lockY); +void xSkyDome_Render(); + +#endif diff --git a/src/SB/Core/x/xSnd.h b/src/SB/Core/x/xSnd.h new file mode 100644 index 0000000..1873b48 --- /dev/null +++ b/src/SB/Core/x/xSnd.h @@ -0,0 +1,149 @@ +#ifndef XSND_H +#define XSND_H + +#include +#include "xVec3.h" +#include "xMath3.h" +#include "iSnd.h" +#include "xEnt.h" + +enum sound_category +{ + SND_CAT_INVALID = 0xffffffff, + SND_CAT_GAME = 0, + SND_CAT_DIALOG, + SND_CAT_MUSIC, + SND_CAT_CUTSCENE, + SND_CAT_UI, + SND_CAT_NUM_CATEGORIES +}; + +struct xSndVoiceInfo +{ + U32 assetID; + U32 sndID; + U32 parentID; + xVec3* parentPos; + S32 internalID; + U32 flags; + U16 pad; + U16 priority; + F32 vol; + F32 pitch; + U32 sample_rate; + U32 deadct; + sound_category category; + xVec3 actualPos; + xVec3 playPos; + F32 innerRadius2; + F32 outerRadius2; + U32 lock_owner; + iSndInfo ps; +}; + +enum sound_listener_game_mode +{ + SND_LISTENER_MODE_PLAYER, + SND_LISTENER_MODE_CAMERA +}; + +struct xSndGlobals +{ + U32 stereo; + U32 SndCount; + F32 categoryVolFader[5]; + // Evidence from iSndUpdateSounds() and xSndInit() show that this array is size 64 instead of 48 + xSndVoiceInfo voice[64]; + xMat4x3 listenerMat[2]; + sound_listener_game_mode listenerMode; + U32 suspendCD; + xVec3 right; + xVec3 up; + xVec3 at; + xVec3 pos; +}; + +struct _xSndDelayed +{ + U32 id; + F32 vol; + F32 pitch; + U32 priority; + U32 flags; + U32 parentID; + xEnt* parentEnt; + xVec3* pos; + F32 innerRadius; + F32 outerRadius; + sound_category category; + F32 delay; + U32 pad0; +}; + +template struct sound_queue +{ + U32 _playing[N + 1]; + S32 head; + S32 tail; +}; + +enum sound_effect +{ + SND_EFFECT_NONE, + SND_EFFECT_CAVE +}; + +enum sound_listener_type +{ + SND_LISTENER_CAMERA, + SND_LISTENER_PLAYER, + SND_MAX_LISTENER_TYPES +}; + +extern xSndGlobals gSnd; + +void xSndSceneInit(); +void xSndResume(); +void xSndUpdate(); +void xSndSetEnvironmentalEffect(sound_effect effectType); +void xSndSuspend(); +void xSndSetVol(U32 snd, F32 vol); +void xSndSetPitch(U32 snd, F32 pitch); +void xSndStop(U32 snd); +void xSndStopAll(U32 mask); +void xSndPauseAll(U32 pause_effects, U32 pause_streams); +void xSndPauseCategory(U32 mask, U32 pause); +void xSndDelayedInit(); +void reset_faders(); +void xSndParentDied(U32 pid); +void xSndCalculateListenerPosition(); +void xSndDelayedUpdate(); +void update_faders(F32 timeElapsed); +void xSndProcessSoundPos(const xVec3* pActual, xVec3* pProcessed); +void xSndInternalUpdateVoicePos(xSndVoiceInfo* voiceInfo); +void xSndSetListenerData(sound_listener_type listenerType, const xMat4x3* matrix); +void xSndSelectListenerMode(sound_listener_game_mode listenerGameMode); +void xSndExit(); +void xSndMgrExit(); +U32 xSndPlay(U32 id, F32 vol, F32 pitch, U32 priority, U32 flags, U32 parentID, + sound_category category, F32 delay); +U32 xSndPlay3D(U32 id, F32 vol, F32 pitch, U32 priority, U32 flags, xEnt* parent, F32 innerRadius, + F32 outerRadius, sound_category category, F32 delay); +U32 xSndPlay3D(U32 id, F32 vol, F32 pitch, U32 priority, U32 flags, const xVec3* pos, + F32 innerRadius, F32 outerRadius, sound_category category, F32 delay); +U32 xSndPlayInternal(U32 id, F32 vol, F32 pitch, U32 priority, U32 flags, U32 parentID, + xEnt* parentEnt, const xVec3* pos, F32 innerRadius, F32 outerRadius, + sound_category category, F32 delay); +void xSndStartStereo(U32 id1, U32 id2, F32 pitch); +U8 xSndIsPlayingByHandle(U32 sndID); +U32 xSndIsPlaying(U32 assetID); +U32 xSndIDIsPlaying(U32 sndID); +void xSndStop(U32 snd); +void xSndParentDied(U32 pid); +void xSndStopChildren(U32 pid); +void xSndSetVol(U32 snd, F32 vol); +void xSndSetPitch(U32 snd, F32 pitch); +void xSndSetCategoryVol(sound_category category, F32 vol); +void xSndSetExternalCallback(void (*callback)(U32)); + +#endif diff --git a/src/SB/Core/x/xSound.h b/src/SB/Core/x/xSound.h deleted file mode 100644 index db803a8..0000000 --- a/src/SB/Core/x/xSound.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef XSOUND_H -#define XSOUND_H - -#include - -enum iSndHandle -{ -}; - -enum iSndGroupHandle -{ -}; - -struct zStreamedSound -{ - unsigned char* mAssetName; - F32 mCycleTime; - U32 mFlags; - F32 mSoonestTimeToPlay; - iSndGroupHandle mSoundGroupHdl; - - void StopLastPlayedSound(); -}; - -struct zStreamedSoundList -{ - U32 mNumSounds; - zStreamedSound* mSounds; -}; - -#endif diff --git a/src/SB/Core/x/xSpline.h b/src/SB/Core/x/xSpline.h new file mode 100644 index 0000000..50a103e --- /dev/null +++ b/src/SB/Core/x/xSpline.h @@ -0,0 +1,37 @@ +#ifndef XSPLINE_H +#define XSPLINE_H + +#include "xMath3.h" + +struct xCoef +{ + F32 a[4]; +}; + +struct xCoef3 +{ + xCoef x; + xCoef y; + xCoef z; +}; + +struct xSpline3 +{ + U16 type; + U16 flags; + U32 N; + U32 allocN; + xVec3* points; + F32* time; + xVec3* p12; + xVec3* bctrl; + F32* knot; + xCoef3* coef; + U32 arcSample; + F32* arcLength; +}; + +void xSpline3_ArcInit(xSpline3* spl, U32 sample); +xSpline3* xSpline3_Bezier(xVec3* points, F32* time, U32 numpoints, U32 numalloc, xVec3* p1, xVec3* p2); + +#endif diff --git a/src/SB/Core/x/xString.h b/src/SB/Core/x/xString.h new file mode 100644 index 0000000..8ceaf92 --- /dev/null +++ b/src/SB/Core/x/xString.h @@ -0,0 +1,47 @@ +#ifndef XSTRING_H +#define XSTRING_H + +#include +#include + +struct substr +{ + const char* text; + size_t size; + + static substr create(const char* text, size_t size); +}; + +// substr constructor +#define SUBSTR(str) (str), (sizeof((str)) - 1) + +U32 xStrHash(const char* str); +U32 xStrHash(const char* str, size_t size); +U32 xStrHashCat(U32 prefix, const char* str); +char* xStrupr(char* string); +S32 xStricmp(const char* string1, const char* string2); +char* xStrTok(char* string, const char* control, char** nextoken); +char* xStrTokBuffer(const char* string, const char* control, void* buffer); +S32 xStrParseFloatList(F32* dest, const char* strbuf, S32 max); + +S32 imemcmp(void const* d1, void const* d2, size_t size); +S32 icompare(const substr& s1, const substr& s2); + +size_t rskip_ws(substr& s); +size_t rskip_ws(const char*& text, size_t& size); +bool is_ws(char c); +const char* find_char(const substr& s, char c); +const char* find_char(const substr& s, const substr& cs); +const char* skip_ws(substr& s); +const char* skip_ws(const char*& text, size_t& size); +size_t atox(const substr& s); +size_t atox(const substr& s, size_t& read_size); +size_t trim_ws(substr& s); +size_t trim_ws(const char*& text, size_t& size); + +extern "C" { +U32 tolower__21_esc__2_unnamed_esc__2_xString_cpp_esc__2_Fc(U32 param_1); +U32 tolower__21_esc__2_unnamed_esc__2_xString_cpp_esc__2_Fi(U32 param_1); +} + +#endif diff --git a/src/SB/Core/x/xSurface.h b/src/SB/Core/x/xSurface.h new file mode 100644 index 0000000..922d96f --- /dev/null +++ b/src/SB/Core/x/xSurface.h @@ -0,0 +1,35 @@ +#ifndef XSURFACE_H +#define XSURFACE_H + +#include "xBase.h" + +struct xEnt; + +struct xSurface : xBase +{ + U32 idx; + U32 type; + union + { + U32 mat_idx; + xEnt* ent; + void* obj; + }; + F32 friction; + U8 state; + U8 pad[3]; + void* moprops; +}; + +#define XSURFACE_TYPE_1 1 +#define XSURFACE_TYPE_3 3 + +void xSurfaceInit(U16 num_surfs); +void xSurfaceExit(); +void xSurfaceSave(xSurface* ent, xSerial* s); +void xSurfaceLoad(xSurface* ent, xSerial* s); +void xSurfaceReset(xSurface* ent); +U16 xSurfaceGetNumSurfaces(); +xSurface* xSurfaceGetByIdx(U16 n); + +#endif diff --git a/src/SB/Core/x/xSystem.h b/src/SB/Core/x/xSystem.h new file mode 100644 index 0000000..4dac5a1 --- /dev/null +++ b/src/SB/Core/x/xSystem.h @@ -0,0 +1,6 @@ +#ifndef XSYSTEM_H +#define XSYSTEM_H + +void xSystem_GapTrackReport(); + +#endif \ No newline at end of file diff --git a/src/SB/Core/x/xTRC.h b/src/SB/Core/x/xTRC.h new file mode 100644 index 0000000..70a70b9 --- /dev/null +++ b/src/SB/Core/x/xTRC.h @@ -0,0 +1,40 @@ +#ifndef XTRC_H +#define XTRC_H + +#include "iTRC.h" + +enum _tagTRCState +{ + TRC_Unknown, + TRC_PadMissing, + TRC_PadInserted, + TRC_PadInvalidNoAnalog, + TRC_PadInvalidType, + TRC_DiskNotIdentified, + TRC_DiskIdentified, + TRC_DiskTrayOpen, + TRC_DiskTrayClosed, + TRC_DiskNoDisk, + TRC_DiskInvalid, + TRC_DiskRetry, + TRC_DiskFatal, + TRC_Total +}; + +struct _tagTRCPadInfo +{ + S32 id; + _tagTRCState state; +}; + +_tagTRCPadInfo gTrcPad[]; +_tagTRCState gTrcDisk[]; + +void xTRCInit(); +void xTRCPad(S32 pad_id, _tagTRCState state); +void xTRCRender(); +void xTRCReset(); +void xTRCDisk(_tagTRCState state); +void render_mem_card_no_space(S32 needed, S32 available, S32 neededFiles, bool enabled); + +#endif diff --git a/src/SB/Core/x/xTextAsset.h b/src/SB/Core/x/xTextAsset.h new file mode 100644 index 0000000..459d473 --- /dev/null +++ b/src/SB/Core/x/xTextAsset.h @@ -0,0 +1,13 @@ +#ifndef XTEXTASSET_H +#define XTESTASSET_H + +#include + +struct xTextAsset +{ + U32 len; +}; + +#define xTextAssetGetText(t) ((char*)((xTextAsset*)(t) + 1)) + +#endif diff --git a/src/SB/Core/x/xTimer.h b/src/SB/Core/x/xTimer.h new file mode 100644 index 0000000..51dc086 --- /dev/null +++ b/src/SB/Core/x/xTimer.h @@ -0,0 +1,31 @@ +#ifndef XTIMER_H +#define XTIMER_H + +#include "xBase.h" + +struct xTimerAsset : xBaseAsset +{ + F32 seconds; + F32 randomRange; +}; + +struct xTimer : xBase +{ + xTimerAsset* tasset; + U8 state; + U8 runsInPause; + U16 flags; + F32 secondsLeft; +}; + +struct xScene; + +void xTimerInit(void* b, void* tasset); +void xTimerInit(xBase* b, xTimerAsset* tasset); +void xTimerReset(xTimer* ent); +void xTimerSave(xTimer* ent, xSerial* s); +void xTimerLoad(xTimer* ent, xSerial* s); +S32 xTimerEventCB(xBase*, xBase* to, U32 toEvent, const F32* toParam, xBase*); +void xTimerUpdate(xBase* to, xScene*, F32 dt); + +#endif diff --git a/src/SB/Core/x/xUpdateCull.h b/src/SB/Core/x/xUpdateCull.h new file mode 100644 index 0000000..0a1c537 --- /dev/null +++ b/src/SB/Core/x/xUpdateCull.h @@ -0,0 +1,59 @@ +#ifndef XUPDATECULL_H +#define XUPDATECULL_H + +#include + +struct xGroup; + +typedef U32 (*xUpdateCullEntCallback)(void* ent, void* cbdata); + +struct xUpdateCullEnt +{ + U16 index; + S16 groupIndex; + xUpdateCullEntCallback cb; + void* cbdata; + xUpdateCullEnt* nextInGroup; +}; + +struct xUpdateCullGroup +{ + U32 active; + U16 startIndex; + U16 endIndex; + xGroup* groupObject; +}; + +typedef void (*xUpdateCullActivateCallback)(void*); +typedef void (*xUpdateCullDeactivateCallback)(void*); + +struct xUpdateCullMgr +{ + U32 entCount; + U32 entActive; + void** ent; + xUpdateCullEnt** mgr; + U32 mgrCount; + U32 mgrCurr; + xUpdateCullEnt* mgrList; + U32 grpCount; + xUpdateCullGroup* grpList; + xUpdateCullActivateCallback activateCB; + xUpdateCullDeactivateCallback deactivateCB; +}; + +union FloatAndVoid +{ + F32 f; + void* v; +}; + +U32 xUpdateCull_AlwaysTrueCB(void* ent, void* cbdata); +U32 xUpdateCull_DistanceSquaredCB(void* ent, void* cbdata); +xUpdateCullMgr* xUpdateCull_Init(void** ent, U32 entCount, xGroup** group, U32 groupCount); +void xUpdateCull_Update(xUpdateCullMgr* m, U32 percent_update); +void xUpdateCull_SetCB(xUpdateCullMgr* m, void* entity, xUpdateCullEntCallback cb, void* cbdata); +void xUpdateCull_Reset(xUpdateCullMgr* m); +void xUpdateCull_MakeActive(xUpdateCullMgr* m, xUpdateCullEnt* e); + +#endif diff --git a/src/SB/Core/x/xVec3.h b/src/SB/Core/x/xVec3.h new file mode 100644 index 0000000..d7b38e5 --- /dev/null +++ b/src/SB/Core/x/xVec3.h @@ -0,0 +1,70 @@ +#ifndef XVEC3_H +#define XVEC3_H + +#include + +struct xVec3 +{ + F32 x; + F32 y; + F32 z; + + static const xVec3 m_Null; + static const xVec3 m_UnitAxisX; + static const xVec3 m_UnitAxisY; + + static xVec3 create(F32 x, F32 y, F32 z); + static xVec3 create(F32 f); + + xVec3& operator=(F32 f) + { + x = y = z = f; + return *this; + } + // FIXME: This should not be declared. Declaring it causes the assignment operator for the + // anonymous struct "camera" in hook_asset to call it rather than just copy the vec members. + xVec3& operator=(const xVec3&); + xVec3 operator+(const xVec3&) const; + xVec3 operator-(const xVec3&) const; + xVec3 operator*(F32) const; + xVec3& operator+=(const xVec3&); + xVec3& operator+=(F32 f) + { + this->x += f; + this->y += f; + this->z += f; + + return *this; + } + xVec3& operator-=(const xVec3&); + xVec3& operator-=(F32 f) + { + this->x -= f; + this->y -= f; + this->z -= f; + + return *this; + } + + xVec3& operator*=(F32); + xVec3& operator/=(F32); + + xVec3& right_normalize(); + xVec3& safe_normalize(const xVec3& val); + xVec3& up_normalize(); + xVec3 up_normal() const; + xVec3& assign(F32 x, F32 y, F32 z); + F32 length() const; + F32 length2() const; + xVec3& invert(); + F32 dot(const xVec3& c) const; + xVec3& normalize(); + xVec3& assign(F32 val); +}; + +F32 xVec3Normalize(xVec3* o, const xVec3* v); +F32 xVec3NormalizeFast(xVec3* o, const xVec3* v); +void xVec3Copy(xVec3* dst, const xVec3* src); +F32 xVec3Dot(const xVec3* a, const xVec3* b); + +#endif diff --git a/src/SB/Core/x/xVec3Inlines.h b/src/SB/Core/x/xVec3Inlines.h new file mode 100644 index 0000000..a09f848 --- /dev/null +++ b/src/SB/Core/x/xVec3Inlines.h @@ -0,0 +1,37 @@ +#ifndef XVEC3INLINES_H +#define XVEC3INLINES_H + +#include "xVec3.h" + +void xVec3Sub(xVec3* o, const xVec3* a, const xVec3* b); +void xVec3Cross(xVec3* o, const xVec3* a, const xVec3* b); +void xVec3Inv(xVec3* o, const xVec3* v); +void xVec3Copy(xVec3* o, const xVec3* v); +F32 xVec3Length(const xVec3* v); +void xVec3SMul(xVec3* o, const xVec3* v, F32 s); +void xVec3Add(xVec3* o, const xVec3* a, const xVec3* b); +void xVec3Init(xVec3* v, F32 _x, F32 _y, F32 _z); +void xVec3AddTo(xVec3* o, const xVec3* v); +void xVec3Lerp(xVec3* o, const xVec3* a, const xVec3* b, F32 t); +void xVec3ScaleC(xVec3* o, const xVec3* v, F32 x, F32 y, F32 z); +F32 xVec3Dist(const xVec3* a, const xVec3* b); +F32 xVec3Dist2(const xVec3* vecA, const xVec3* vecB); +F32 xVec3Length2(const xVec3* vec); +F32 xVec3LengthFast(F32 x, F32 y, F32 z); +void xVec3AddScaled(xVec3* o, const xVec3* v, F32 s); + +inline void xVec3SMulBy(xVec3* v, F32 s) +{ + v->x *= s; + v->y *= s; + v->z *= s; +} + +inline void xVec3SubFrom(xVec3* o, const xVec3* v) +{ + o->x -= v->x; + o->y -= v->y; + o->z -= v->z; +} + +#endif diff --git a/src/SB/Core/x/xVolume.h b/src/SB/Core/x/xVolume.h new file mode 100644 index 0000000..d278ff4 --- /dev/null +++ b/src/SB/Core/x/xVolume.h @@ -0,0 +1,27 @@ +#ifndef XVOLUME_H +#define XVOLUME_H + +#include "xBase.h" +#include "xBound.h" + +struct xVolumeAsset : xBaseAsset +{ + U32 flags; + xBound bound; + F32 rot; + F32 xpivot; + F32 zpivot; +}; + +struct xVolume : xBase +{ + xVolumeAsset* asset; + + void Init(xVolumeAsset* asset); + void Reset(); + void Save(xSerial* s); + void Load(xSerial* s); + xBound* GetBound(); +}; + +#endif diff --git a/src/SB/Core/x/xbinio.h b/src/SB/Core/x/xbinio.h new file mode 100644 index 0000000..53ba1e9 --- /dev/null +++ b/src/SB/Core/x/xbinio.h @@ -0,0 +1,77 @@ +#ifndef XBINIO_H +#define XBINIO_H + +#include "xFile.h" + +enum en_BIO_ASYNC_ERRCODES +{ + BINIO_ASYNC_FAIL = -1, + BINIO_ASYNC_NOOP, + BINIO_ASYNC_INPROG, + BINIO_ASYNC_DONE, + BINIO_ASYNC_FORCEENUMSIZEINT = 0x7fffffff +}; + +enum en_FIOERRCODES +{ + FIOERR_NONE, + FIOERR_READFAIL, + FIOERR_WRITEFAIL, + FIOERR_SEEKFAIL, + FIOERR_USERABORT +}; + +struct st_FILELOADINFO +{ + void (*destroy)(st_FILELOADINFO*); + S32 (*readBytes)(st_FILELOADINFO*, char*, S32); + S32 (*readMShorts)(st_FILELOADINFO*, S16*, S32); + S32 (*readMLongs)(st_FILELOADINFO*, S32*, S32); + S32 (*readMFloats)(st_FILELOADINFO*, F32*, S32); + S32 (*readMDoubles)(st_FILELOADINFO*, F64*, S32); + S32 (*readIShorts)(st_FILELOADINFO*, S16*, S32); + S32 (*readILongs)(st_FILELOADINFO*, S32*, S32); + S32 (*readIFloats)(st_FILELOADINFO*, F32*, S32); + S32 (*readIDoubles)(st_FILELOADINFO*, F64*, S32); + S32 (*skipBytes)(st_FILELOADINFO*, S32); + S32 (*seekSpot)(st_FILELOADINFO*, S32); + void (*setDoubleBuf)(st_FILELOADINFO*, char*, S32); + void (*discardDblBuf)(st_FILELOADINFO*); + S32 (*asyncIRead)(st_FILELOADINFO*, S32, char*, S32, S32); + S32 (*asyncMRead)(st_FILELOADINFO*, S32, char*, S32, S32); + en_BIO_ASYNC_ERRCODES (*asyncReadStatus)(st_FILELOADINFO*); + U32 lockid; + en_FIOERRCODES error; + U32 basesector; + void* privdata; + void* xtradata; + void* asyndata; + S32 filesize; + S32 remain; + S32 position; +}; + +struct st_FILESAVEINFO +{ + void (*destroy)(st_FILESAVEINFO*); + S32 (*writeBytes)(st_FILESAVEINFO*, char*, S32); + S32 (*writeMShorts)(st_FILESAVEINFO*, S16*, S32); + S32 (*writeMLongs)(st_FILESAVEINFO*, S32*, S32); + S32 (*writeMFloats)(st_FILESAVEINFO*, F32*, S32); + S32 (*writeMDoubles)(st_FILESAVEINFO*, F64*, S32); + S32 (*writeIShorts)(st_FILESAVEINFO*, S16*, S32); + S32 (*writeILongs)(st_FILESAVEINFO*, S32*, S32); + S32 (*writeIFloats)(st_FILESAVEINFO*, F32*, S32); + S32 (*writeIDoubles)(st_FILESAVEINFO*, F64*, S32); + S32 (*seekSpot)(st_FILESAVEINFO*, S32); + S32 length; + S32 position; + en_FIOERRCODES error; + U32 lockid; + void* privdata; + void* xtradata; +}; + +st_FILELOADINFO* xBinioLoadCreate(const char* filename); + +#endif diff --git a/src/SB/Core/x/xhipio.h b/src/SB/Core/x/xhipio.h new file mode 100644 index 0000000..9b93ca2 --- /dev/null +++ b/src/SB/Core/x/xhipio.h @@ -0,0 +1,90 @@ +#ifndef XHIPIO_H +#define XHIPIO_H + +#include "xbinio.h" + +enum en_READ_ASYNC_STATUS +{ + HIP_RDSTAT_NONE = -1, + HIP_RDSTAT_INPROG, + HIP_RDSTAT_SUCCESS, + HIP_RDSTAT_FAILED, + HIP_RDSTAT_NOBYPASS, + HIP_RDSTAT_NOASYNC +}; + +struct st_HIPLOADBLOCK +{ + S32 endpos; + U32 blk_id; + S32 blk_remain; + S32 flags; +}; + +struct st_HIPLOADDATA +{ + st_FILELOADINFO* fli; + S32 lockid; + S32 bypass; + S32 bypass_recover; + U32 base_sector; + S32 use_async; + en_READ_ASYNC_STATUS asyn_stat; + S32 pos; + S32 top; + S32 readTop; + st_HIPLOADBLOCK stk[8]; +}; + +struct st_HIPLOADFUNCS +{ + st_HIPLOADDATA* (*create)(const char*, char*, S32); + void (*destroy)(st_HIPLOADDATA*); + U32 (*basesector)(st_HIPLOADDATA*); + U32 (*enter)(st_HIPLOADDATA*); + void (*exit)(st_HIPLOADDATA*); + S32 (*readBytes)(st_HIPLOADDATA*, char*, S32); + S32 (*readShorts)(st_HIPLOADDATA*, S16*, S32); + S32 (*readLongs)(st_HIPLOADDATA*, S32*, S32); + S32 (*readFloats)(st_HIPLOADDATA*, F32*, S32); + S32 (*readString)(st_HIPLOADDATA*, char*); + S32 (*setBypass)(st_HIPLOADDATA*, S32, S32); + void (*setSpot)(st_HIPLOADDATA*, S32); + en_READ_ASYNC_STATUS (*pollRead)(st_HIPLOADDATA*); +}; + +struct st_HIPSAVEBLOCK +{ + S32 pos; + S32 len; + S32 flags; +}; + +struct st_HIPSAVEDATA +{ + st_FILESAVEINFO* fsi; + S32 lockid; + S32 pos; + S32 top; + S32 writeTop; + st_HIPSAVEBLOCK stk[8]; +}; + +struct st_HIPSAVEFUNCS +{ + st_HIPSAVEDATA* (*create)(const char*); + void (*destroy)(st_HIPSAVEDATA*); + void (*open)(st_HIPSAVEDATA*, U32); + void (*close)(st_HIPSAVEDATA*); + void (*writeBytes)(st_HIPSAVEDATA*, char*, S32); + void (*writeShorts)(st_HIPSAVEDATA*, S16*, S32); + void (*writeLongs)(st_HIPSAVEDATA*, S32*, S32); + void (*writeFloats)(st_HIPSAVEDATA*, F32*, S32); + void (*writeString)(st_HIPSAVEDATA*, char*); + S32 (*curSpot)(st_HIPSAVEDATA*); + S32 (*spotLong)(st_HIPSAVEDATA*, S32, U32); +}; + +st_HIPLOADFUNCS* get_HIPLFuncs(); + +#endif diff --git a/src/SB/Core/x/xordarray.h b/src/SB/Core/x/xordarray.h new file mode 100644 index 0000000..43ed6a0 --- /dev/null +++ b/src/SB/Core/x/xordarray.h @@ -0,0 +1,26 @@ +#ifndef XORDARRAY_H +#define XORDARRAY_H + +#include + +struct st_XORDEREDARRAY +{ + void** list; + S32 cnt; + S32 max; + S32 warnlvl; +}; + +typedef S32 (*XOrdCompareCallback)(void* vkey, void* vitem); +typedef S32 (*XOrdTestCallback)(const void* vkey, void* vitem); + +void XOrdInit(st_XORDEREDARRAY* array, S32 size, S32 tempAlloc); +void XOrdReset(st_XORDEREDARRAY* array); +void XOrdDone(st_XORDEREDARRAY* array, S32 wasTempAlloc); +void XOrdAppend(st_XORDEREDARRAY* array, void* elt); +void XOrdInsert(st_XORDEREDARRAY* array, void* elt, XOrdCompareCallback compare); +void* XOrdRemove(st_XORDEREDARRAY* array, void* elt, S32 index); +S32 XOrdLookup(st_XORDEREDARRAY* array, const void* key, XOrdTestCallback test); +void XOrdSort(st_XORDEREDARRAY* array, S32 (*test)(void*, void*)); + +#endif diff --git a/src/SB/Core/x/xpkrsvc.h b/src/SB/Core/x/xpkrsvc.h new file mode 100644 index 0000000..7b25e75 --- /dev/null +++ b/src/SB/Core/x/xpkrsvc.h @@ -0,0 +1,224 @@ +#ifndef XPKRSVC_H +#define XPKRSVC_H + +#include +#include + +#include "xhipio.h" +#include "xordarray.h" + +struct st_PACKER_ASSETTYPE +{ + U32 typetag; + U32 tflags; + S32 typalign; + void* (*readXForm)(void*, U32, void*, U32, U32*); + void* (*writeXForm)(void*, U32, void*, void*, U32, U32*); + S32 (*assetLoaded)(void*, U32, void*, S32); + void* (*makeData)(void*, U32, void*, S32*, S32*); + void (*cleanup)(void*, U32, void*); + void (*assetUnloaded)(void*, U32); + void (*writePeek)(void*, U32, void*, char*); +}; + +struct st_PKR_ASSET_TOCINFO +{ + U32 aid; + st_PACKER_ASSETTYPE* typeref; + U32 sector; + U32 plus_offset; + U32 size; + void* mempos; +}; + +enum en_LAYER_TYPE +{ + PKR_LTYPE_DEFAULT, + PKR_LTYPE_TEXTURE, + PKR_LTYPE_BSP, + PKR_LTYPE_MODEL, + PKR_LTYPE_ANIMATION, + PKR_LTYPE_VRAM, + PKR_LTYPE_SRAM, + PKR_LTYPE_SNDTOC, + PKR_LTYPE_CUTSCENE, + PKR_LTYPE_CUTSCENETOC, + PKR_LTYPE_JSPINFO, + PKR_LTYPE_NOMORE, + PKR_LTYPE_ALL = 0xffffffff +}; + +enum en_PKR_LAYER_LOAD_DEST +{ + PKR_LDDEST_SKIP, + PKR_LDDEST_KEEPSTATIC, + PKR_LDDEST_KEEPMALLOC, + PKR_LDDEST_RWHANDOFF, + PKR_LDDEST_NOMORE, + PKR_LDDEST_FORCE = 0x7fffffff +}; + +struct st_PACKER_READ_DATA; +struct st_PACKER_ATOC_NODE +{ + U32 aid; + U32 asstype; + S32 d_off; + S32 d_size; + S32 d_pad; + U32 d_chksum; + S32 assalign; + S32 infoflag; + S32 loadflag; + char* memloc; + S32 x_size; + S32 readcnt; + S32 readrem; + st_PACKER_ASSETTYPE* typeref; + st_HIPLOADDATA* ownpkg; + st_PACKER_READ_DATA* ownpr; + + // looks like this was removed in the GC version + // Evidence: memory allocation; Name function returns a constant + // char basename[32]; + + char* Name() const; +}; + +struct st_PACKER_LTOC_NODE +{ + en_LAYER_TYPE laytyp; + st_XORDEREDARRAY assref; + S32 flg_ldstat; + S32 danglecnt; + U32 chksum; + S32 laysize; + char* laymem; + char* laytru; +}; + +struct st_PACKER_READ_DATA +{ + st_PACKER_ASSETTYPE* types; + void* userdata; + U32 opts; + U32 pkgver; + S32 cltver; + S32 subver; + S32 compatver; + st_HIPLOADDATA* pkg; + U32 base_sector; + S32 lockid; + char packfile[128]; + S32 asscnt; + S32 laycnt; + st_XORDEREDARRAY asstoc; + st_XORDEREDARRAY laytoc; + st_PACKER_ATOC_NODE* pool_anode; + S32 pool_nextaidx; + st_XORDEREDARRAY typelist[129]; + time_t time_made; + time_t time_mod; +}; + +struct st_PACKER_READ_FUNCS +{ + U32 api_ver; + st_PACKER_READ_DATA* (*Init)(void*, char*, U32, S32*, st_PACKER_ASSETTYPE*); + void (*Done)(st_PACKER_READ_DATA*); + S32 (*LoadLayer)(st_PACKER_READ_DATA*, en_LAYER_TYPE); + U32 (*GetAssetSize)(st_PACKER_READ_DATA*, U32); + void* (*LoadAsset)(st_PACKER_READ_DATA*, U32, char*, void*); + void* (*AssetByType)(st_PACKER_READ_DATA*, U32, S32, U32*); + S32 (*AssetCount)(st_PACKER_READ_DATA*, U32); + S32 (*IsAssetReady)(st_PACKER_READ_DATA*, U32); + S32 (*SetActive)(st_PACKER_READ_DATA*, en_LAYER_TYPE); + char* (*AssetName)(st_PACKER_READ_DATA*, U32); + U32 (*GetBaseSector)(st_PACKER_READ_DATA*); + S32 (*GetAssetInfo)(st_PACKER_READ_DATA*, U32, st_PKR_ASSET_TOCINFO*); + S32 (*GetAssetInfoByType)(st_PACKER_READ_DATA*, U32, S32, st_PKR_ASSET_TOCINFO*); + S32 (*PkgHasAsset)(st_PACKER_READ_DATA*, U32); + U32 (*PkgTimeStamp)(st_PACKER_READ_DATA*); + void (*PkgDisconnect)(st_PACKER_READ_DATA*); +}; + +st_PACKER_READ_FUNCS* PKRGetReadFuncs(S32 apiver); +S32 PKRStartup(); +S32 PKRShutdown(); +S32 PKRLoadStep(S32); +st_PACKER_READ_DATA* PKR_ReadInit(void* userdata, char* pkgfile, U32 opts, S32* cltver, + st_PACKER_ASSETTYPE* typelist); +void PKR_ReadDone(st_PACKER_READ_DATA* pr); +S32 PKR_SetActive(st_PACKER_READ_DATA* pr, en_LAYER_TYPE layer); +S32 PKR_parse_TOC(st_HIPLOADDATA* pkg, st_PACKER_READ_DATA* pr); +S32 PKR_LoadStep_Async(); +char* PKR_LayerMemReserve(st_PACKER_READ_DATA* pr, st_PACKER_LTOC_NODE* layer); +void PKR_LayerMemRelease(st_PACKER_READ_DATA* pr, st_PACKER_LTOC_NODE* layer); +void PKR_drv_guardLayer(st_PACKER_LTOC_NODE*); +S32 PKR_drv_guardVerify(st_PACKER_LTOC_NODE*); +en_PKR_LAYER_LOAD_DEST PKR_layerLoadDest(en_LAYER_TYPE layer); +S32 PKR_layerTypeNeedsXForm(en_LAYER_TYPE layer); +S32 PKR_findNextLayerToLoad(st_PACKER_READ_DATA** work_on_pkg, st_PACKER_LTOC_NODE** next_layer); +void PKR_updateLayerAssets(st_PACKER_LTOC_NODE* laynode); +void PKR_xformLayerAssets(st_PACKER_LTOC_NODE* laynode); +void PKR_xform_asset(st_PACKER_ATOC_NODE* assnode, S32 dumpable_layer); +void* PKR_FindAsset(st_PACKER_READ_DATA* pr, U32 aid); +S32 PKR_LoadLayer(st_PACKER_READ_DATA* pr, en_LAYER_TYPE layer); +void* PKR_LoadAsset(st_PACKER_READ_DATA* pr, U32 aid, char*, void*); +U32 PKR_GetAssetSize(st_PACKER_READ_DATA* pr, U32 aid); +S32 PKR_AssetCount(st_PACKER_READ_DATA* pr, U32 type); +void* PKR_AssetByType(st_PACKER_READ_DATA* pr, U32 type, S32 idx, U32* size); +S32 PKR_IsAssetReady(st_PACKER_READ_DATA* pr, U32 aid); +U32 PKR_getPackTimestamp(st_PACKER_READ_DATA* pr); +void PKR_Disconnect(st_PACKER_READ_DATA* pr); +U32 PKRAssetIDFromInst(void* asset_inst); +char* PKR_AssetName(st_PACKER_READ_DATA* pr, U32 aid); +U32 PKR_GetBaseSector(st_PACKER_READ_DATA* pr); +S32 PKR_GetAssetInfo(st_PACKER_READ_DATA* pr, U32 aid, st_PKR_ASSET_TOCINFO* tocainfo); +S32 PKR_GetAssetInfoByType(st_PACKER_READ_DATA* pr, U32 type, S32 idx, + st_PKR_ASSET_TOCINFO* tocainfo); +S32 PKR_PkgHasAsset(st_PACKER_READ_DATA* pr, U32 aid); +S32 PKR_FRIEND_assetIsGameDup(U32 aid, const st_PACKER_READ_DATA* skippr, S32 oursize, U32 ourtype, + U32 chksum, char*); +S32 PKR_makepool_anode(st_PACKER_READ_DATA* pr, S32 cnt); +void PKR_kiilpool_anode(st_PACKER_READ_DATA* pr); +st_PACKER_ATOC_NODE* PKR_newassnode(st_PACKER_READ_DATA* pr, U32 aid); +st_PACKER_LTOC_NODE* PKR_newlaynode(en_LAYER_TYPE layer, S32 refcnt); +void PKR_oldlaynode(st_PACKER_LTOC_NODE* laytoc); +S32 OrdComp_R_Asset(void* vkey, void* vitem); +S32 OrdTest_R_AssetID(const void* vkey, void* vitem); +S32 LOD_r_HIPA(st_HIPLOADDATA* pkg, st_PACKER_READ_DATA* pr); +S32 LOD_r_PACK(st_HIPLOADDATA* pkg, st_PACKER_READ_DATA* pr); +S32 LOD_r_PVER(st_HIPLOADDATA* pkg, st_PACKER_READ_DATA* pr); +S32 LOD_r_PFLG(st_HIPLOADDATA* pkg, st_PACKER_READ_DATA* pr); +S32 LOD_r_PCNT(st_HIPLOADDATA* pkg, st_PACKER_READ_DATA* pr); +S32 LOD_r_PCRT(st_HIPLOADDATA* pkg, st_PACKER_READ_DATA* pr); +S32 LOD_r_PMOD(st_HIPLOADDATA* pkg, st_PACKER_READ_DATA* pr); +S32 ValidatePlatform(st_HIPLOADDATA* pkg, st_PACKER_READ_DATA* pr, S32 plattag, char* plat, + char* vid, char* lang, char* title); +S32 LOD_r_PLAT(st_HIPLOADDATA* pkg, st_PACKER_READ_DATA* pr); +S32 LOD_r_DICT(st_HIPLOADDATA* pkg, st_PACKER_READ_DATA* pr); +S32 LOD_r_ATOC(st_HIPLOADDATA* pkg, st_PACKER_READ_DATA* pr); +S32 LOD_r_AINF(st_HIPLOADDATA* pkg, st_PACKER_READ_DATA* pr); +S32 LOD_r_AHDR(st_HIPLOADDATA* pkg, st_PACKER_READ_DATA* pr); +S32 LOD_r_ADBG(st_HIPLOADDATA* pkg, st_PACKER_READ_DATA* pr, st_PACKER_ATOC_NODE* assnode); +S32 LOD_r_LTOC(st_HIPLOADDATA* pkg, st_PACKER_READ_DATA* pr); +S32 LOD_r_LINF(st_HIPLOADDATA* pkg, st_PACKER_READ_DATA* pr); +S32 LOD_r_LHDR(st_HIPLOADDATA* pkg, st_PACKER_READ_DATA* pr); +S32 LOD_r_LHDR(st_HIPLOADDATA* pkg, st_PACKER_READ_DATA* pr); +S32 LOD_r_LDBG(st_HIPLOADDATA* pkg, st_PACKER_READ_DATA* pr, st_PACKER_LTOC_NODE* laynode); +S32 LOD_r_STRM(st_HIPLOADDATA* pkg, st_PACKER_READ_DATA* pr); +S32 LOD_r_DHDR(st_HIPLOADDATA* pkg, st_PACKER_READ_DATA* pr); +S32 LOD_r_DPAK(st_HIPLOADDATA* pkg, st_PACKER_READ_DATA* pr); +void PKR_spew_verhist(); +st_PACKER_ASSETTYPE* PKR_type2typeref(U32 asstype, st_PACKER_ASSETTYPE* types); +void PKR_bld_typecnt(st_PACKER_READ_DATA* pr); +S32 PKR_typeHdlr_idx(st_PACKER_READ_DATA* pr, U32 type); +void PKR_alloc_chkidx(); +void* PKR_getmem(U32 id, S32 amount, U32, S32 align); +void* PKR_getmem(U32 id, S32 amount, U32, S32 align, S32 isTemp, char** memtrue); +void PKR_relmem(U32 id, S32 blksize, void* memptr, U32, S32 isTemp); +void PKR_push_memmark(); +void PKR_pop_memmark(); + +#endif diff --git a/src/SB/Core/x/xsavegame.h b/src/SB/Core/x/xsavegame.h new file mode 100644 index 0000000..a62b609 --- /dev/null +++ b/src/SB/Core/x/xsavegame.h @@ -0,0 +1,217 @@ +#ifndef XSAVEGAME_H +#define XSAVEGAME_H + +#include + +#include "iTime.h" +#include "isavegame.h" + +struct st_XSAVEGAME_READCONTEXT +{ +}; + +struct st_XSAVEGAME_WRITECONTEXT +{ +}; + +enum en_SAVEGAME_MODE +{ + XSG_MODE_LOAD = 0xa, + XSG_MODE_SAVE +}; + +struct st_XSAVEGAME_DATA; + +struct st_XSAVEGAME_CLIENT +{ + U32 idtag; + S32 (*cltinfo)(void*, st_XSAVEGAME_DATA*, S32*, S32*); + S32 (*cltproc)(void*, st_XSAVEGAME_DATA*, st_XSAVEGAME_WRITECONTEXT*); + S32 (*cltload)(void*, st_XSAVEGAME_DATA*, st_XSAVEGAME_READCONTEXT*, U32, S32); + void* cltdata; + S32 needamt; + S32 maxamt; + S32 realamt; + char* buf_sizepos; + char* buf_maxpos; + S32 blokact; + S32 blokmax; + char* blokpos; + char* readpos; + S32 readamt; + S32 readremain; +}; + +struct st_XSAVEGAME_DATA +{ + S32 gfile_idx; + en_SAVEGAME_MODE mode; + U32 stage; + S32 gslot; + char label[64]; + S32 progress; + S32 thumbIconIdx; + iTime playtime; + char* membuf; + S32 memsize; + char* buf_curpos; + char* buf_sizespot; + char* buf_cksmspot; + S32 totamt; + U32 chksum; + U32 upd_tally; + S32 cltneed; + S32 cltmax; + S32 chdrneed; + S32 stkcnt; + st_XSAVEGAME_CLIENT cltstk[128]; + st_XSAVEGAME_CLIENT dfltloadclt; + U32 file_chksum; + U32 read_chksum; + S32 readsize; + char* loadbuf; + S32 loadsize; + char* walkpos; + S32 walkremain; + st_ISGSESSION* isgsess; +}; + +struct XSGAutoData +{ + S32 flg_autodata; + S32 lastTarg; + S32 lastGame; + S32 lastPhysicalSlot; + st_ISGSESSION* isg_monitor; + + S32 IsValid(); + void MarkInvalid(); + S32 SetCache(S32 targ, S32 game, S32 physicalSlot); + void Discard(); + st_ISGSESSION* HWConnect(S32 targ); + void HWDisconnect(st_ISGSESSION* isgsess); + S32 HWCheckConnect(S32 targ); + S32 LastPhysicalSlot(); + S32 LastGame(); + S32 LastTarget(); +}; + +enum en_XSGASYNC_STATUS +{ + XSG_ASTAT_NOOP, + XSG_ASTAT_INPROG, + XSG_ASTAT_SUCCESS, + XSG_ASTAT_FAILED +}; + +struct st_XSAVEGAME_LEADER +{ + char gameLabel[64]; + S32 progress; + iTime gametime; + char thumbIconIdx; +}; + +enum en_XSG_WHYFAIL +{ + XSG_WHYERR_NONE, + XSG_WHYERR_NOCARD, + XSG_WHYERR_NOROOM, + XSG_WHYERR_DAMAGE, + XSG_WHYERR_CARDYANKED, + XSG_WHYERR_OTHER, + XSG_WHYERR_NOMORE +}; + +struct st_XSG_SHORTLABEL +{ + const char* msglong; + const char* msgshort; +}; + +S32 xSGStartup(); +S32 xSGShutdown(); +st_XSAVEGAME_DATA* xSGInit(en_SAVEGAME_MODE mode); +S32 xSGDone(st_XSAVEGAME_DATA* xsgdata); +S32 xSGCheckForCorruptFiles(st_XSAVEGAME_DATA* xsgdata, char files[][64]); +S32 xSGTgtCount(st_XSAVEGAME_DATA* xsgdata, S32* max); +S32 xSGTgtPhysSlotIdx(st_XSAVEGAME_DATA* xsgdata, S32 tidx); +S32 xSGTgtIsFormat(st_XSAVEGAME_DATA* xsgdata, S32 tidx, S32* badEncode); +S32 xSGTgtFormatTgt(st_XSAVEGAME_DATA* xsgdata, S32 tidx, S32* canRecover); +S32 xSGTgtSelect(st_XSAVEGAME_DATA* xsgdata, S32 tidx); +S32 xSGTgtHasGameDir(st_XSAVEGAME_DATA* xsgdata, S32 tidx); +S32 xSGTgtHaveRoom(st_XSAVEGAME_DATA* xsgdata, S32 tidx, S32 fsize, S32 slotidx, + S32* bytesNeeded, S32* availOnDisk, S32* needFile); +S32 xSGTgtHaveRoomStartup(st_XSAVEGAME_DATA* xsgdata, S32 tidx, S32 fsize, S32 slotidx, + S32* bytesNeeded, S32* availOnDisk, S32* needFile); +U8 xSGCheckMemoryCard(st_XSAVEGAME_DATA* xsgdata, S32 index); +void xSGGameSet(st_XSAVEGAME_DATA* xsgdata, S32 gidx); +S32 xSGGameIsEmpty(st_XSAVEGAME_DATA* xsgdata, S32 gidx); +S32 xSGGameSize(st_XSAVEGAME_DATA* xsgdata, S32 gidx); +char* xSGGameModDate(st_XSAVEGAME_DATA* xsgdata, S32 gidx); +char* xSGGameLabel(st_XSAVEGAME_DATA* xsgdata, S32 gidx); +S32 xSGGameThumbIndex(st_XSAVEGAME_DATA* xsgdata, S32 gidx); +S32 xSGGameProgress(st_XSAVEGAME_DATA* xsgdata, S32 gidx); +S32 xSGAddSaveClient(st_XSAVEGAME_DATA* xsgdata, U32 clttag, void* cltdata, + S32 (*infofunc)(void*, st_XSAVEGAME_DATA*, S32*, S32*), + S32 (*procfunc)(void*, st_XSAVEGAME_DATA*, st_XSAVEGAME_WRITECONTEXT*)); +S32 xSGAddLoadClient(st_XSAVEGAME_DATA* xsgdata, U32 clttag, void* cltdata, + S32 (*loadfunc)(void*, st_XSAVEGAME_DATA*, st_XSAVEGAME_READCONTEXT*, + U32, S32)); +S32 xSGSetup(st_XSAVEGAME_DATA* xsgdata); +S32 xSGSetup(st_XSAVEGAME_DATA* xsgdata, S32 gidx, char* label, S32 progress, iTime playtime, + S32 thumbIconIdx); +S32 xSGProcess(st_XSAVEGAME_DATA* xsgdata); +S32 xSGWrapup(st_XSAVEGAME_DATA* xsgdata); +en_XSGASYNC_STATUS xSGAsyncStatus(st_XSAVEGAME_DATA* xsgdata, S32 block, en_XSG_WHYFAIL* whyFail, + char* errmsg); +S32 xSG_cb_leader_svinfo(void*, st_XSAVEGAME_DATA*, S32* cur_space, S32* max_fullgame); +S32 xSG_cb_leader_svproc(void* cltdata, st_XSAVEGAME_DATA* original_xsgdata, + st_XSAVEGAME_WRITECONTEXT* wctxt); +S32 xSG_cb_leader_load(void*, st_XSAVEGAME_DATA* original_xsgdata, + st_XSAVEGAME_READCONTEXT* rctxt, U32, S32); +S32 xSGWriteData(st_XSAVEGAME_DATA* xsgdata, st_XSAVEGAME_WRITECONTEXT* wctxt, char* data, + S32 elesiz, S32 n); +S32 xSGWriteStrLen(const char* str); +S32 xSGWriteData(st_XSAVEGAME_DATA* xsgdata, st_XSAVEGAME_WRITECONTEXT* wctxt, char* data, + S32 n); +S32 xSGWriteData(st_XSAVEGAME_DATA* xsgdata, st_XSAVEGAME_WRITECONTEXT* wctxt, S32* data, + S32 n); +S32 xSGWriteData(st_XSAVEGAME_DATA* xsgdata, st_XSAVEGAME_WRITECONTEXT* wctxt, U32* data, + S32 n); +S32 xSGWriteData(st_XSAVEGAME_DATA* xsgdata, st_XSAVEGAME_WRITECONTEXT* wctxt, F32* data, + S32 n); +S32 xSGReadData(st_XSAVEGAME_DATA* xsgdata, st_XSAVEGAME_READCONTEXT* rctxt, char* buff, + S32 elesiz, S32 n); +S32 xSGReadData(st_XSAVEGAME_DATA* xsgdata, st_XSAVEGAME_READCONTEXT* rctxt, char* buff, S32 n); +S32 xSGReadData(st_XSAVEGAME_DATA* xsgdata, st_XSAVEGAME_READCONTEXT* rctxt, S32* buff, + S32 n); +S32 xSGReadData(st_XSAVEGAME_DATA* xsgdata, st_XSAVEGAME_READCONTEXT* rctxt, U32* buff, + S32 n); +S32 xSGReadData(st_XSAVEGAME_DATA* xsgdata, st_XSAVEGAME_READCONTEXT* rctxt, F32* buff, + S32 n); +S32 xSG_grab_leaders(st_XSAVEGAME_DATA* xsgdata); +S32 xSG_chdir_gamedir(st_XSAVEGAME_DATA* xsgdata); +char* xSG_cm_slotname(st_XSAVEGAME_DATA* xsgdata, S32 gidx); +void xSG_areaComposeLabel(char* label, int, char*, int); +S32 xSG_sv_flipinfo(st_XSAVEGAME_DATA* xsgdata); +S32 xSG_sv_prepdest(st_XSAVEGAME_DATA* xsgdata); +S32 xSG_sv_flipproc(st_XSAVEGAME_DATA* xsgdata); +S32 xSG_sv_bldchksum(st_XSAVEGAME_DATA* xsgdata); +S32 xSG_smem_blkopen(st_XSAVEGAME_DATA* xsgdata); +S32 xSG_smem_blkclose(st_XSAVEGAME_DATA* xsgdata); +S32 xSG_smem_cltopen(st_XSAVEGAME_DATA* xsgdata, st_XSAVEGAME_CLIENT* clt); +S32 xSG_smem_cltclose(st_XSAVEGAME_DATA* xsgdata, st_XSAVEGAME_CLIENT* clt); +S32 xSG_sv_commit(st_XSAVEGAME_DATA* xsgdata); +void xSG_cb_ISGChange(void*, en_CHGCODE what); +S32 xSG_ld_prepload(st_XSAVEGAME_DATA* xsgdata); +S32 xSG_ld_readgame(st_XSAVEGAME_DATA* xsgdata); +S32 xSG_ld_readhead(st_XSAVEGAME_DATA* xsgdata); +S32 xSG_ld_validate(st_XSAVEGAME_DATA* xsgdata); +S32 xSG_ld_findcltblk(st_XSAVEGAME_DATA* xsgdata); +S32 xSG_ld_flipload(st_XSAVEGAME_DATA* xsgdata); +XSGAutoData* xSGAutoSave_GetCache(); +void xSGAutoSave_Startup(); +void ASG_ISG_changed(void*, en_CHGCODE what); + +#endif diff --git a/src/SB/Core/x/xserializer.h b/src/SB/Core/x/xserializer.h new file mode 100644 index 0000000..bf1d598 --- /dev/null +++ b/src/SB/Core/x/xserializer.h @@ -0,0 +1,51 @@ +#ifndef XSERIALIZER_H +#define XSERIALIZER_H + +#include +#include "xsavegame.h" + +struct st_SERIAL_CLIENTINFO +{ + U32 idtag; + S32* membuf; + S32 trueoff; + S32 actsize; +}; + +struct xSerial +{ + U32 idtag; + S32 baseoff; + st_SERIAL_CLIENTINFO* ctxtdata; + S32 warned; + S32 curele; + S32 bitidx; + S32 bittally; + + xSerial(); + ~xSerial(); + + void setClient(U32 idtag); + + S32 Write_b1(S32 bits); + S32 Write_b7(U32 bits); + S32 Write(U8 data); + S32 Write(S16 data); + S32 Write(S32 data); + S32 Write(U32 data); + S32 Write(F32 data); + S32 Read_b1(S32* bits); + S32 Read_b7(U32* bits); + S32 Read(U8* buf); + S32 Read(S16* buf); + S32 Read(S32* buf); + S32 Read(U32* buf); + S32 Read(F32* buf); + void operator delete(void*); +}; + +void xSerialTraverse(S32 (*func)(U32 clientID, xSerial* xser)); +void xSerialWipeMainBuffer(); +S32 xSerial_svgame_register(st_XSAVEGAME_DATA* sgctxt, en_SAVEGAME_MODE mode); + +#endif diff --git a/src/SB/Core/x/xstransvc.h b/src/SB/Core/x/xstransvc.h new file mode 100644 index 0000000..889a9e8 --- /dev/null +++ b/src/SB/Core/x/xstransvc.h @@ -0,0 +1,41 @@ +#ifndef XSTRANSVC_H +#define XSTRANSVC_H + +#include "xpkrsvc.h" + +struct st_STRAN_SCENE +{ + U32 scnid; + S32 lockid; + st_PACKER_READ_DATA* spkg; + S32 isHOP; + void* userdata; + char fnam[256]; +}; + +struct st_STRAN_DATA +{ + st_STRAN_SCENE hipscn[16]; + U32 loadlock; +}; + +S32 xSTStartup(st_PACKER_ASSETTYPE* handlers); +S32 xSTPreLoadScene(U32 sid, void* userdata, S32 flg_hiphop); +S32 xSTQueueSceneAssets(U32 sid, S32 flg_hiphop); +void xSTUnLoadScene(U32 sid, S32 flg_hiphop); +F32 xSTLoadStep(U32); +void xSTDisconnect(U32 sid, S32 flg_hiphop); +S32 xSTSwitchScene(U32 sid, void* userdata, S32 (*progmon)(void*, F32)); +void* xSTFindAsset(U32 aid, U32* size); +S32 xSTAssetCountByType(U32 type); +void* xSTFindAssetByType(U32 type, S32 idx, U32* size); +char* xSTAssetName(U32 aid); +char* xSTAssetName(void* raw_HIP_asset); +S32 xSTGetAssetInfo(U32 aid, st_PKR_ASSET_TOCINFO* tocainfo); +S32 xSTGetAssetInfoByType(U32 type, S32 idx, st_PKR_ASSET_TOCINFO* ainfo); +char* xST_xAssetID_HIPFullPath(U32 aid); +S32 PKRShutdown(); +char* xST_xAssetID_HIPFullPath(U32 aid, U32* sceneID); +S32 xSTShutdown(); + +#endif diff --git a/src/SB/Core/x/xutil.h b/src/SB/Core/x/xutil.h new file mode 100644 index 0000000..2b63111 --- /dev/null +++ b/src/SB/Core/x/xutil.h @@ -0,0 +1,17 @@ +#ifndef XUTIL_H +#define XUTIL_H + +#include + +S32 xUtilStartup(); +S32 xUtilShutdown(); +char* xUtil_idtag2string(U32 srctag, S32 bufidx); +U32 xUtil_crc_init(); +U32 xUtil_crc_update(U32 crc_accum, char* data, S32 datasize); +S32 xUtil_yesno(F32 wt_yes); +void xUtil_wtadjust(F32* wts, S32 cnt, F32 arbref); + +template +T* xUtil_select(T** arg0, S32 arg1, const F32* arg3); + +#endif diff --git a/src/SB/Game/zActionLine.h b/src/SB/Game/zActionLine.h new file mode 100644 index 0000000..3940263 --- /dev/null +++ b/src/SB/Game/zActionLine.h @@ -0,0 +1,17 @@ +#ifndef ZACTIONLINE_H +#define ZACTIONLINE_H + +#include "xVec3.h" + +struct _tagActionLine +{ + U32 flags; + xVec3 pos[4]; + F32 time_left; +}; + +void zActionLineInit(); +void zActionLineUpdate(F32 seconds); +void zActionLineRender(); + +#endif diff --git a/src/SB/Game/zAssetTypes.h b/src/SB/Game/zAssetTypes.h new file mode 100644 index 0000000..e583102 --- /dev/null +++ b/src/SB/Game/zAssetTypes.h @@ -0,0 +1,48 @@ +#ifndef ZASSETTYPES_H +#define ZASSETTYPES_H + +#include +#include +#include +#include "xSnd.h" + +#include "xJSP.h" + +#include "zEntCruiseBubble.h" +#include "zEntPlayerAnimationTables.h" +#include "xHudModel.h" +#include "zNPCTypeAmbient.h" +#include "zNPCTypeCommon.h" +#include "zNPCTypeBossPatrick.h" +#include "zNPCTypeBossPlankton.h" +#include "zNPCTypeBossSandy.h" +#include "zNPCTypeBossSB1.h" +#include "zNPCTypeBossSB2.h" +#include "zNPCTypeDuplotron.h" +#include "zNPCTypeDutchman.h" +#include "zNPCHazard.h" +#include "zNPCTypeKingJelly.h" +#include "zNPCTypePrawn.h" +#include "zNPCTypeRobot.h" +#include "zNPCTypeTest.h" +#include "zNPCTypeTiki.h" + +struct RwMemory +{ + U8* start; + U32 length; +}; + +class HackModelRadius { +public: + U32 assetid; + F32 radius; +}; + +void FootstepHackSceneEnter(); +void jsp_shadow_hack(xJSPHeader* param_1); + +U32 xSndPlay3D(U32 id, F32 vol, F32 pitch, U32 priority, U32 flags, xEnt* pos, F32 radius, + sound_category category, F32 delay); + +#endif diff --git a/src/SB/Game/zBase.h b/src/SB/Game/zBase.h new file mode 100644 index 0000000..64f9ab0 --- /dev/null +++ b/src/SB/Game/zBase.h @@ -0,0 +1,81 @@ +#ifndef ZBASE_H +#define ZBASE_H + +enum en_ZBASETYPE +{ + eBaseTypeUnknown, + eBaseTypeTrigger, + eBaseTypeVillain, + eBaseTypePlayer, + eBaseTypePickup, + eBaseTypeEnv, + eBaseTypePlatform, + eBaseTypeCamera, + eBaseTypeDoor, + eBaseTypeSavePoint, + eBaseTypeItem, + eBaseTypeStatic, + eBaseTypeDynamic, + eBaseTypeMovePoint, + eBaseTypeTimer, + eBaseTypeBubble, + eBaseTypePortal, + eBaseTypeGroup, + eBaseTypePendulum, + eBaseTypeSFX, + eBaseTypeFFX, + eBaseTypeVFX, + eBaseTypeCounter, + eBaseTypeHangable, + eBaseTypeButton, + eBaseTypeProjectile, + eBaseTypeSurface, + eBaseTypeDestructObj, + eBaseTypeGust, + eBaseTypeVolume, + eBaseTypeDispatcher, + eBaseTypeCond, + eBaseTypeUI, + eBaseTypeUIFont, + eBaseTypeProjectileType, + eBaseTypeLobMaster, + eBaseTypeFog, + eBaseTypeLight, + eBaseTypeParticleEmitter, + eBaseTypeParticleSystem, + eBaseTypeCutsceneMgr, + eBaseTypeEGenerator, + eBaseTypeScript, + eBaseTypeNPC, + eBaseTypeHud, + eBaseTypeNPCProps, + eBaseTypeParticleEmitterProps, + eBaseTypeBoulder, + eBaseTypeCruiseBubble, + eBaseTypeTeleportBox, + eBaseTypeBusStop, + eBaseTypeTextBox, + eBaseTypeTalkBox, + eBaseTypeTaskBox, + eBaseTypeBoulderGenerator, + eBaseTypeNPCSettings, + eBaseTypeDiscoFloor, + eBaseTypeTaxi, + eBaseTypeHUD_model, + eBaseTypeHUD_font_meter, + eBaseTypeHUD_unit_meter, + eBaseTypeBungeeHook, + eBaseTypeCameraFly, + eBaseTypeTrackPhysics, + eBaseTypeZipLine, + eBaseTypeArena, + eBaseTypeDuplicator, + eBaseTypeLaserBeam, + eBaseTypeTurret, + eBaseTypeCameraTweak, + eBaseTypeSlideProps, + eBaseTypeHUD_text, + eBaseTypeCount +}; + +#endif \ No newline at end of file diff --git a/src/SB/Game/zCamMarker.h b/src/SB/Game/zCamMarker.h new file mode 100644 index 0000000..f26cd4d --- /dev/null +++ b/src/SB/Game/zCamMarker.h @@ -0,0 +1,20 @@ +#ifndef ZCAMMARKER_H +#define ZCAMMARKER_H + +#include +#include "zCamera.h" +#include "xBase.h" +#include "xCamera.h" +#include "xEvent.h" + +struct zCamMarker : xBase +{ + xCamAsset* asset; +}; + +void zCamMarkerInit(xBase* b, xCamAsset* asset); +void zCamMarkerSave(zCamMarker* m, xSerial* s); +void zCamMarkerLoad(zCamMarker* m, xSerial* s); +int zCamMarkerEventCB(xBase* from, xBase* to, U32 toEvent, const F32* toParam, xBase* b3); + +#endif diff --git a/src/SB/Game/zCamera.h b/src/SB/Game/zCamera.h new file mode 100644 index 0000000..1d33f20 --- /dev/null +++ b/src/SB/Game/zCamera.h @@ -0,0 +1,122 @@ +#ifndef ZCAMERA_H +#define ZCAMERA_H + +#include "xCamera.h" + +enum WallJumpViewState +{ + WJVS_DISABLED, + WJVS_DISABLING, + WJVS_ENABLED, + WJVS_ENABLING +}; + +enum camera_owner_enum +{ + CO_BOULDER = 0x1, + CO_CRUISE_BUBBLE, + CO_BUNGEE = 0x4, + CO_BOSS = 0x8, + CO_OOB = 0x10, + CO_ZIPLINE = 0x20, + CO_TURRET = 0x40, + CO_REWARDANIM = 0x80 +}; + +struct zFlyKey +{ + S32 frame; + F32 matrix[12]; + F32 aperture[2]; + F32 focal; +}; + +extern F32 zcam_overrot_tmr; +extern S32 zcam_near; +extern S32 zcam_mode; +extern S32 zcam_bbounce; +extern S32 zcam_lbbounce; +extern S32 zcam_convers; +extern S32 zcam_lconvers; +extern S32 zcam_longbounce; +extern S32 zcam_highbounce; +extern S32 zcam_cutscene; +extern S32 zcam_reward; +extern xVec3* zcam_playervel; +extern S32 zcam_fly; +extern S32 zcam_flypaused; +extern void* zcam_flydata; +extern U32 zcam_flysize; +extern F32 zcam_flytime; +extern U32 zcam_flyasset_current; +extern xCamAsset* zcam_dest; +extern F32 zcam_tmr; +extern F32 zcam_ttm; +extern F32 zcam_fovcurr; +extern F32 zcam_fovdest; + +extern xCamera zcam_backupcam; +extern xCamera zcam_backupconvers; +extern xQuat zcam_quat; + +extern F32 zcam_pad_pyaw_scale; +extern F32 zcam_pad_pitch_scale; +extern F32 zcam_near_d; +extern F32 zcam_near_h; +extern F32 zcam_near_pitch; +extern F32 zcam_far_d; +extern F32 zcam_far_h; +extern F32 zcam_far_pitch; +extern F32 zcam_wall_d; +extern F32 zcam_wall_h; +extern F32 zcam_wall_pitch; +extern F32 zcam_above_d; +extern F32 zcam_above_h; +extern F32 zcam_above_pitch; +extern F32 zcam_below_d; +extern F32 zcam_below_h; +extern F32 zcam_below_pitch; +extern F32 zcam_highbounce_d; +extern F32 zcam_highbounce_h; +extern F32 zcam_highbounce_pitch; +extern F32 zcam_overrot_min; +extern F32 zcam_overrot_mid; +extern F32 zcam_overrot_max; +extern F32 zcam_overrot_rate; +extern F32 zcam_overrot_tstart; +extern F32 zcam_overrot_tend; +extern F32 zcam_overrot_velmin; +extern F32 zcam_overrot_velmax; +extern F32 zcam_overrot_tmanual; +extern F32 zcam_mintgtheight; + +void zCameraReset(xCamera* cam); +void zCameraSetBbounce(S32 bbouncing); +void zCameraSetHighbounce(S32 hbounce); +void zCameraSetLongbounce(S32 hbounce); +void zCameraSetPlayerVel(xVec3* vel); +void zCameraSetConvers(int on); +void zCameraDoTrans(xCamAsset* asset, float ttime); +U32 zCamera_FlyOnly(); +void zCameraTranslate(xCamera* camera, F32 x, F32 y, F32 z); +void zCameraReset(xCamera* camera); +void zCameraUpdate(xCamera* camera, F32 dt); + +void zCameraEnableInput(); +void zCameraDisableInput(); +U32 zCameraIsTrackingDisabled(); +void zCameraEnableTracking(camera_owner_enum owner); +void zCameraDisableTracking(camera_owner_enum owner); +void zCameraDisableLassoCam(); +void zCameraEnableLassoCam(); +void zCameraSetLassoCamFactor(F32 new_factor); +F32 zCameraGetLassoCamFactor(); +void zCameraEnableWallJump(xCamera* cam, const xVec3& collNormal); +S32 zCameraGetConvers(); +void zCameraTranslate(xCamera* cam, F32 x, F32 y, F32 z); +void zCameraDisableWallJump(xCamera* cam); +void zCameraSetReward(S32 reward); +void zCameraMinTargetHeightSet(F32 min_height); +void zCameraMinTargetHeightClear(); + +#endif diff --git a/src/SB/Game/zCameraFly.h b/src/SB/Game/zCameraFly.h new file mode 100644 index 0000000..f860041 --- /dev/null +++ b/src/SB/Game/zCameraFly.h @@ -0,0 +1,29 @@ +#ifndef ZCAMERAFLY_H +#define ZCAMERAFLY_H + +#include +#include "xBase.h" +#include "xDynAsset.h" +#include "xScene.h" + +struct CameraFly_asset : xDynAsset +{ + U32 flyID; +}; + +struct zCameraFly : xBase +{ + CameraFly_asset* casset; +}; + +void zCameraFly_Init(xBase& data, xDynAsset& asset, size_t); +void zCameraFly_Init(zCameraFly* data, CameraFly_asset* asset); +void zCameraFly_Setup(zCameraFly* fly); +void zCameraFly_Update(xBase* to, xScene* scene, F32 dt); +void zCameraFly_Save(zCameraFly* fly, xSerial* s); +void zCameraFly_Load(zCameraFly* fly, xSerial* s); +U32 zCameraFlyProcessStopEvent(); +void zCameraFlyStart(U32 id); +S32 zCameraFlyEventCB(xBase* from, xBase* to, U32 toEvent, const F32* toParam, xBase* b3); + +#endif diff --git a/src/SB/Game/zCameraTweak.h b/src/SB/Game/zCameraTweak.h new file mode 100644 index 0000000..ab90cbc --- /dev/null +++ b/src/SB/Game/zCameraTweak.h @@ -0,0 +1,30 @@ +#ifndef ZCAMERATWEAK_H +#define ZCAMERATWEAK_H + +#include "xDynAsset.h" + +#include + +struct CameraTweak_asset : xDynAsset +{ + S32 priority; + F32 time; + F32 pitch_adjust; + F32 dist_adjust; +}; + +struct zCameraTweak : xBase +{ + CameraTweak_asset* casset; +}; + +F32 zCameraTweakGlobal_GetPitch(); +F32 zCameraTweakGlobal_GetH(); +F32 zCameraTweakGlobal_GetD(); +void zCameraTweakGlobal_Update(F32 dt); +void zCameraTweakGlobal_Reset(); +void zCameraTweak_Init(xBase& data, xDynAsset& asset, size_t); +void zCameraTweak_Save(zCameraTweak* tweak, xSerial* s); +void zCameraTweak_Load(zCameraTweak* tweak, xSerial* s); + +#endif diff --git a/src/SB/Game/zCollGeom.h b/src/SB/Game/zCollGeom.h new file mode 100644 index 0000000..be51d59 --- /dev/null +++ b/src/SB/Game/zCollGeom.h @@ -0,0 +1,21 @@ +#ifndef ZCOLLGEOM_H +#define ZCOLLGEOM_H + +#include "xEnt.h" + +#include +#include + +struct zCollGeomTable +{ + RpAtomic* baseModel; + RpAtomic* colModel[1]; + RpAtomic* camcolModel; +}; + +U32 zCollGeom_EntSetup(xEnt* ent); +void zCollGeom_Init(); +void zCollGeom_CamEnable(xEnt* ent); +void zCollGeom_CamDisable(xEnt* ent); + +#endif diff --git a/src/SB/Game/zCombo.h b/src/SB/Game/zCombo.h new file mode 100644 index 0000000..3b1f317 --- /dev/null +++ b/src/SB/Game/zCombo.h @@ -0,0 +1,15 @@ +#ifndef ZCOMBO_H +#define ZCOMBO_H + +#include +#include "xFont.h" +#include "xHud.h" +#include "zEntPickup.h" + +void zCombo_Setup(); +void zCombo_Add(int); +void zCombo_Update(F32); +void zCombo_HideImmediately(); +void zComboHideMessage(xhud::widget& w, xhud::motive& motive); + +#endif diff --git a/src/SB/Game/zConditional.h b/src/SB/Game/zConditional.h new file mode 100644 index 0000000..816563f --- /dev/null +++ b/src/SB/Game/zConditional.h @@ -0,0 +1,32 @@ +#ifndef ZCONDITIONAL_H +#define ZCONDITIONAL_H + +#include "xBase.h" + +#define CONDITION_EQ 0 +#define CONDITION_GT 1 +#define CONDITION_LT 2 +#define CONDITION_GE 3 +#define CONDITION_LE 4 +#define CONDITION_NE 5 + +struct zCondAsset : xBaseAsset +{ + U32 constNum; + U32 expr1; + U32 op; + U32 value_asset; +}; + +struct _zConditional : xBase +{ + zCondAsset* asset; +}; + +void zConditionalInit(xBase* base, zCondAsset* asset); +void zConditionalInit(void* b, void* asset); +void zConditionalLoad(_zConditional* ent, xSerial* s); +void zConditionalSave(_zConditional* ent, xSerial* s); +U32 zConditional_Evaluate(_zConditional* c); + +#endif diff --git a/src/SB/Game/zCutsceneMgr.h b/src/SB/Game/zCutsceneMgr.h new file mode 100644 index 0000000..5c2719f --- /dev/null +++ b/src/SB/Game/zCutsceneMgr.h @@ -0,0 +1,47 @@ +#ifndef ZCUTSCENEMGR_H +#define ZCUTSCENEMGR_H + +#include "xCutsceneMgr.h" +#include "rpworld.h" + +struct xScene; +struct zCutsceneMgr : xCutsceneMgr +{ +}; + +struct zCutsceneHack +{ + char* cinname; + char* modelname; + F32 radius; + U32 tworoot; + U32 noshadow; + U32 alphaBits; + RpAtomic* (*renderCB)(RpAtomic*); +}; + +struct zCutSceneNames +{ + char name[64]; + S32 played; + S32 skipOK; +}; + +void zCutsceneMgrInit(void* b, void* tasset); +void zCutsceneMgrInit(xBase* b, xCutsceneMgrAsset* tasset); +void zCutsceneMgrReset(zCutsceneMgr* mgr); +void zCutsceneMgrSave(zCutsceneMgr*, xSerial* s); +void zCutsceneMgrLoad(zCutsceneMgr*, xSerial* s); +RpAtomic* HackBoundCB(RpAtomic* atomic, void* data); +RpMaterial* HackAlphaSetMaterialAlphaCB(RpMaterial* material, void* data); +RpAtomic* HackAlphaCB(RpAtomic* atomic, void* data); +void zCutSceneNamesTable_clearAll(); +void zCutsceneMgrPlayStart(zCutsceneMgr* t); +S32 zCutsceneMgrEventCB(xBase*, xBase* to, U32 toEvent, const F32*, xBase*); + +void zCutsceneMgrKillFX(zCutsceneMgr* t); +void zCutsceneMgrUpdateFX(zCutsceneMgr* t); +void zCutsceneMgrUpdate(xBase* to, xScene* sc, F32 dt); +void check_hide_entities(); + +#endif diff --git a/src/SB/Game/zDiscoFloor.h b/src/SB/Game/zDiscoFloor.h new file mode 100644 index 0000000..3b06d5e --- /dev/null +++ b/src/SB/Game/zDiscoFloor.h @@ -0,0 +1,97 @@ +#ifndef ZDISCOFLOOR_H +#define ZDISCOFLOOR_H + +#include "zEntSimpleObj.h" + +#include "xBase.h" +#include "xMath3.h" + +struct z_disco_floor_asset : xBaseAsset +{ + U32 flags; + struct + { + F32 transition; + F32 state; + } interval; + struct + { + U32 off; + U32 transition; + U32 on; + } prefix_offset; + U32 state_mask_size; + U32 states_offset; + U32 states_size; +}; + +struct z_disco_floor : xBase +{ + struct tile_data + { + bool culled; + zEntSimpleObj* ent; + xSphere sphere; + }; + + struct + { + bool enabled; + bool forward; + bool culled; + bool glow_culled; + } flag; + z_disco_floor_asset* asset; + + U8** state_masks; + U8* active_state_mask; + U8* next_state_mask; + const char* prefix[3]; + tile_data* tiles[3]; + U32 tiles_size; + U32 min_state; + U32 max_state; + U32 state; + U32 next_state; + U32 state_counter; + F32 transition_delay; + F32 state_delay; + F32 transition_time; + F32 state_time; + xSphere bound; + F32 pulse_time; + F32 pulse_glow[3]; + F32 cull_dist_glow; + F32 cull_dist_update; + F32 glow_fade; + F32 sound_delay; + S32 curr_note; + + static void init(); + static void init(void* ent, void* asset); + static void post_setup(); + static void destroy(); + static void render_all(); + static void effects_render_all(); + static S32 event_handler(xBase*, xBase* to, U32 event, const F32* argf, xBase*); + + void load(z_disco_floor_asset& asset); + void setup(); + void reset(); + void update(xScene&, F32 dt); + void set_state(size_t state, bool immediate); + void enable(); + void disable(); + void set_state_range(S32 min, S32 max, bool immediate); + void set_transition_delay(F32 s); + void set_state_delay(F32 s); + void refresh_spheres(); + void update_pulse(F32 dt); + void refresh_bound(); + void refresh_cull_dist(); + void distance_cull(); + void render(S32 group); + void effects_render(S32 group); +}; + +#endif diff --git a/src/SB/Game/zDispatcher.h b/src/SB/Game/zDispatcher.h new file mode 100644 index 0000000..e3abc3e --- /dev/null +++ b/src/SB/Game/zDispatcher.h @@ -0,0 +1,83 @@ +#ifndef ZDISPATCHER_H +#define ZDISPATCHER_H + +#include "xBase.h" + +struct st_ZDISPATCH_DATA : xBase +{ + xBaseAsset* rawass; + S32 placeholder; +}; + +struct st_ZDISPATCH_DEPOT +{ + st_ZDISPATCH_DATA* raw_pool; + S32 raw_cnt; +}; + +enum en_DISPATCH_COMMAND +{ + ZDSP_CMD_INITDFLT = 0xffffffff, + ZDSP_CMD_CTRL_CFGGET = 0, + ZDSP_CMD_CTRL_CFGSET, + ZDSP_CMD_CTRL_VIBEGET, + ZDSP_CMD_CTRL_VIBESET, + ZDSP_CMD_SNDMOD_GET, + ZDSP_CMD_SNDMOD_SET, + ZDSP_CMD_SNDVOL_GET, + ZDSP_CMD_SNDVOL_SET, + ZDSP_CMD_SNDVOL_INCR, + ZDSP_CMD_SNDVOL_DECR, + ZDSP_CMD_MUSVOL_GET, + ZDSP_CMD_MUSVOL_SET, + ZDSP_CMD_MUSVOL_INCR, + ZDSP_CMD_MUSVOL_DECR, + ZDSP_CMD_SFXVOL_GET, + ZDSP_CMD_SFXVOL_SET, + ZDSP_CMD_SFXVOL_INCR, + ZDSP_CMD_SFXVOL_DECR, + ZDSP_CMD_GSTATE_GET, + ZDSP_CMD_GSTATE_SET, + ZDSP_CMD_GMODE_GET, + ZDSP_CMD_GMODE_SET, + ZDSP_CHECKPNT_SET, + ZDSP_CMD_NOMORE +}; + +struct st_ZDISPATCH_CONTEXT +{ + en_DISPATCH_COMMAND cmd; + void* indata; + void* inxtra; + void* result; +}; + +struct zScene; + +void zDispatcher_Startup(); +void zDispatcher_Shutdown(); +void zDispatcher_scenePrepare(); +void zDispatcher_sceneFinish(); +st_ZDISPATCH_DATA* zDispatcher_memPool(S32 cnt); +st_ZDISPATCH_DATA* zDispatcher_getInst(st_ZDISPATCH_DATA* pool, S32 idx); +void zDispatcher_Init(st_ZDISPATCH_DATA* dspdata, xBaseAsset* bass); +void zDispatcher_InitDep(st_ZDISPATCH_DATA* dspdata, zScene*); +void zDispatcher_Save(st_ZDISPATCH_DATA* dspdata, xSerial* s); +void zDispatcher_Load(st_ZDISPATCH_DATA* dspdata, xSerial* s); +void ZDSP_instInit(st_ZDISPATCH_DATA* dspdata, xBaseAsset* bass); +void ZDSP_instInitDep(st_ZDISPATCH_DATA* dspdata, zScene* scene); +void ZDSP_instReset(st_ZDISPATCH_DATA* dspdata, zScene* scene); +void ZDSP_readAsset(st_ZDISPATCH_DATA* dspdata); +void ZDSP_injectCmd(st_ZDISPATCH_DATA* dspdata, en_DISPATCH_COMMAND cmd); +void ZDSP_injectCmd(st_ZDISPATCH_DATA* dspdata, en_DISPATCH_COMMAND cmd, S32); +void ZDSP_injectCmd(st_ZDISPATCH_DATA* dspdata, en_DISPATCH_COMMAND cmd, void* indata, void* inxtra, + void* result); +S32 ZDSP_doCommand(st_ZDISPATCH_DATA* dspdata, st_ZDISPATCH_CONTEXT* cmdCtxt); +void zDispatcherStoreOptions(); +void zDispatcherRestoreOptions(); +S32 ZDSP_elcb_event(xBase*, xBase* xb, U32 toEvent, const F32* toParam, + xBase* toParamWidget); +void WRAP_xsnd_setMusicVolume(S32 i); +void WRAP_xsnd_setSFXVolume(S32 i); + +#endif diff --git a/src/SB/Game/zEGenerator.h b/src/SB/Game/zEGenerator.h new file mode 100644 index 0000000..53c380e --- /dev/null +++ b/src/SB/Game/zEGenerator.h @@ -0,0 +1,46 @@ +#ifndef ZEGENERATOR_H +#define ZEGENERATOR_H + +#include "zEnt.h" +#include "zLightning.h" + +#include + +struct zEGenAsset : xEntAsset +{ + xVec3 src_dpos; + U8 damage_type; + U8 flags; + F32 ontime; + U32 onAnimID; +}; + +struct zEGenerator : zEnt +{ + zEGenAsset* zasset; + U16 flags; + U16 num_dsts; + F32 tmr; + xAnimFile* afile; + xVec3 src_pos; + xVec3 dst_pos; + xVec3 dst_off; + xBase* dst; + zLightning* lfx[2]; +}; + +void zEGenerator_Init(void* egen, void* asset); +void zEGenerator_Init(zEGenerator* egen, xEntAsset* asset); +void zEGenerator_Setup(zEGenerator* egen, xScene* sc); +void zEGenerator_Save(zEGenerator* ent, xSerial* s); +void zEGenerator_Load(zEGenerator* ent, xSerial* s); +void zEGenerator_Reset(zEGenerator* egen, xScene* sc); +void zEGenerator_Move(zEGenerator* egen, xScene* sc, F32 dt); +void zEGenerator_Render(zEGenerator* egen); +void zEGenerator_TurnOn(zEGenerator* egen); +void zEGenerator_TurnOff(zEGenerator* egen); +void zEGenerator_ToggleOn(zEGenerator* egen); +S32 zEGeneratorEventCB(xBase* to, xBase* from, U32 toEvent, const F32* toParam, + xBase* toParamWidget); + +#endif diff --git a/src/SB/Game/zEnt.cpp b/src/SB/Game/zEnt.cpp new file mode 100644 index 0000000..1355560 --- /dev/null +++ b/src/SB/Game/zEnt.cpp @@ -0,0 +1,935 @@ +#include "zEnt.h" + +#include + +#include "zGlobals.h" +#include "zAnimList.h" +#include "zNPCTypeCommon.h" +#include "xNPCBasic.h" +#include "xstransvc.h" +#include "xString.h" +#include "xMath.h" +#include "xutil.h" +#include "iModel.h" +#include "xSnd.h" +#include "xCollide.h" +#include "zNPCTypes.h" +#include +#include + +void zEntInit(zEnt* ent, xEntAsset* asset, U32 type) +{ + xEntInit(ent, asset); + ent->update = (xEntUpdateCallback)zEntUpdate; + + // Surprisingly, this is not a switch statement. + if (type == 0x504c5952) + { + ent->collType = 0x10; + ent->collLev = 0x4; + ent->bound.type = 0x1; + zEntParseModelInfo(ent, asset->modelInfoID); + } + else if (type == 0x56494c20) + { + ent->collType = 0x8; + ent->collLev = 0x4; + ent->bound.type = 0x1; + ent->moreFlags = ent->moreFlags | 0x10; + zEntParseModelInfo(ent, asset->modelInfoID); + } + else if (type == 0x4954454d) + { + ent->collType = 0x2; + ent->collLev = 0x4; + ent->bound.type = 0x1; + ent->eventFunc = NULL; + zEntParseModelInfo(ent, asset->modelInfoID); + } + else if (type == 0x504b5550) + { + ent->collType = 0; + ent->bound.type = 0; + } + else if (type == 0x504c4154) + { + ent->collType = 0x4; + if (asset->moreFlags & 2) + { + ent->collLev = 0x5; + } + else + { + ent->collLev = 0x4; + } + zEntParseModelInfo(ent, asset->modelInfoID); + ent->bound.type = 0x4; + ent->bound.mat = (xMat4x3*)ent->model->Mat; + } + else if (type == 0x50454e44) + { + ent->collType = 0x4; + if (asset->moreFlags & 2) + { + ent->collLev = 0x5; + } + else + { + ent->collLev = 0x4; + } + zEntParseModelInfo(ent, asset->modelInfoID); + ent->bound.type = 0x4; + ent->bound.mat = (xMat4x3*)ent->model->Mat; + } + else if (type == 0x54524947) + { + ent->collType = 0x1; + ent->bound.type = 0; + } + else if (type == 0x48414e47) + { + ent->collType = 0x4; + ent->collLev = 0x4; + ent->bound.type = 0x1; + zEntParseModelInfo(ent, asset->modelInfoID); + } + else if (type == 0x53494d50) + { + ent->collType = 0x2; + if (asset->moreFlags & 2) + { + ent->collLev = 0x5; + } + else + { + ent->collLev = 0x4; + } + ent->bound.type = 0x4; + zEntParseModelInfo(ent, asset->modelInfoID); + ent->bound.mat = (xMat4x3*)ent->model->Mat; + } + else if (type == 0x55492020) + { + } + else if (type == 0x4255544e) + { + ent->collType = 0x4; + if (asset->moreFlags & 2) + { + ent->collLev = 0x5; + } + else + { + ent->collLev = 0x4; + } + ent->bound.type = 0x4; + ent->moreFlags = ent->moreFlags | 0x10; + zEntParseModelInfo(ent, asset->modelInfoID); + ent->bound.mat = (xMat4x3*)ent->model->Mat; + } + else if (type == 0x44535452) + { + ent->collType = 0x4; + if (asset->moreFlags & 2) + { + ent->collLev = 0x5; + } + else + { + ent->collLev = 0x4; + } + ent->bound.type = 0x4; + ent->moreFlags = ent->moreFlags | 0x10; + zEntParseModelInfo(ent, asset->modelInfoID); + ent->bound.mat = (xMat4x3*)ent->model->Mat; + } + else if (type == 0x4547454e) + { + ent->collType = 0x4; + if (asset->moreFlags & 2) + { + ent->collLev = 0x5; + } + else + { + ent->collLev = 0x4; + } + ent->bound.type = 0x4; + zEntParseModelInfo(ent, asset->modelInfoID); + ent->bound.mat = (xMat4x3*)ent->model->Mat; + } + else if (type == 0x54424f58) + { + ent->collType = 0x2; + ent->collLev = 0x5; + ent->bound.type = 0x4; + zEntParseModelInfo(ent, asset->modelInfoID); + ent->bound.mat = (xMat4x3*)ent->model->Mat; + } + + if (asset->animListID != 0) + { + S32 num_used = zAnimListGetNumUsed(asset->animListID); + if (num_used > 0) + { + ent->atbl = zAnimListGetTable(asset->animListID); + xAnimPoolAlloc(&globals.sceneCur->mempool, ent, ent->atbl, ent->model); + xAnimState* ast = xAnimTableGetState(ent->atbl, "idle"); + if (ast != NULL) + { + xAnimSingle* single = ent->model->Anim->Single; + single->State = ast; + single->Time = 0.0f; + single->CurrentSpeed = 1.0f; + xModelEval(ent->model); + } + } + else + { + ent->atbl = NULL; + } + } + else + { + ent->atbl = NULL; + } + + xEntInitForType(ent); +} + +void zEntSetup(zEnt* ent) +{ + xEntSetup(ent); + checkpoint_collision_hack(ent); +} + +// Equivalent +// This function needs to be declared inline to generate the correct mangled name for model_id +inline void checkpoint_collision_hack(zEnt* ent) +{ + // instruction swap involving the guard for this static initializer. + // Might be due to the sda reloc access for model_id getting moved down + static U32 model_id = xStrHash("checkpoint_bind"); + if (ent->asset->modelInfoID == model_id) + { + ent->bound.type = 0x2; + xVec3* lower = &ent->bound.box.box.lower; + xVec3* upper = &ent->bound.box.box.upper; + *lower = *upper = xEntGetFrame(ent)->pos; + + lower->x += -0.5f; + lower->z += -0.5f; + + upper->x += 0.5f; + upper->y += 5.0f; + upper->z += 0.5f; + + xEntDefaultBoundUpdate(ent, &xEntGetFrame(ent)->pos); + + ent->miscflags = ent->miscflags | 8; + + xEntAnimateCollision(*ent, 0); + xModelAnimCollStop(*(ent->collModel != NULL ? ent->collModel : ent->model)); + + ent->moreFlags = ent->moreFlags & 0xdd; + ent->asset->moreFlags = ent->asset->moreFlags & 0xdd; + ent->baseFlags = ent->baseFlags & 0xffef; + ent->asset->baseFlags = ent->asset->baseFlags & 0xffef; + } +} + +void zEntSave(zEnt* ent, xSerial* s) +{ + xEntSave(ent, s); +} + +void zEntLoad(zEnt* ent, xSerial* s) +{ + xEntLoad(ent, s); +} + +void zEntReset(zEnt* ent) +{ + xEntReset(ent); + + if (ent->asset->animListID != 0 && ent->atbl != NULL) + { + xAnimState* ast = xAnimTableGetState(ent->atbl, "idle"); + if (ast != NULL) + { + xAnimSingle* single = ent->model->Anim->Single; + single->State = ast; + single->Time = 0.0f; + single->CurrentSpeed = 1.0f; + xModelEval(ent->model); + } + } + + if (!(ent->miscflags & 1) && ent->asset->modelInfoID != 0 && ent->model != NULL && + ent->model->Anim != NULL && ent->model->Anim->Table != NULL && + strcmp("xEntAutoEventSimple", ent->model->Anim->Table->Name) == 0) + { + ent->model->Anim = ent->model->Anim; + xAnimPlaySetState(ent->model->Anim->Single, ent->model->Anim->Table->StateList, 0.0f); + ent->miscflags = ent->miscflags | 1; + } + checkpoint_collision_hack(ent); +} + +void zEntUpdate(zEnt* ent, zScene* scene, F32 elapsedSec) +{ + xEntUpdate(ent, scene, elapsedSec); +} + +void zEntEventAll(xBase* from, U32 fromEvent, U32 toEvent, F32* toParam) +{ + zScene* s = globals.sceneCur; + for (U16 i = 0; i < s->num_base; i++) + { + zEntEvent(from, fromEvent, s->base[i], toEvent, toParam, NULL, 0); + } +} + +void zEntEventAllOfType(xBase* from, U32 fromEvent, U32 toEvent, F32* toParam, U32 type) +{ + zScene* s = globals.sceneCur; + if (s == NULL) + { + return; + } + + for (U16 i = 0; i < s->num_base; i++) + { + xBase* base = s->base[i]; + if (type == base->baseType) + { + zEntEvent(from, fromEvent, base, toEvent, toParam, NULL, 0); + } + } +} + +void zEntEventAllOfType(U32 toEvent, U32 type) +{ + zEntEventAllOfType(NULL, 0, toEvent, NULL, type); +} + +xModelInstance* zEntRecurseModelInfo(void* info, xEnt* ent) +{ + xModelAssetInfo* zinfo = (xModelAssetInfo*)info; + xModelAssetInst* zinst = (xModelAssetInst*)(zinfo + 1); + U32 bufsize; + xModelInstance* tempInst[64]; + + for (U32 i = 0; i < zinfo->NumModelInst; i++) + { + RpAtomic* imodel = (RpAtomic*)xSTFindAsset(zinst[i].ModelID, &bufsize); + if (*(U32*)&imodel->object.object == 0x464e494d) + { + tempInst[i] = zEntRecurseModelInfo(imodel, ent); + if (i != 0) + { + tempInst[i]->Flags |= zinst[i].Flags; + tempInst[i]->BoneIndex = zinst[i].Bone; + xModelInstanceAttach(tempInst[i], tempInst[zinst[i].Parent]); + } + } + else + { + if (i == 0) + { + tempInst[i] = xModelInstanceAlloc(imodel, ent, 0, 0, 0); + tempInst[i]->modelID = zinst[i].ModelID; + while (imodel = iModelFile_RWMultiAtomic(imodel), imodel != NULL) + { + xModelInstanceAttach(xModelInstanceAlloc(imodel, ent, 0x2000, 0, NULL), + tempInst[i]); + } + } + else + { + tempInst[i] = xModelInstanceAlloc(imodel, ent, zinst[i].Flags, zinst[i].Bone, NULL); + xModelInstanceAttach(tempInst[i], tempInst[zinst[i].Parent]); + + while (imodel = iModelFile_RWMultiAtomic(imodel), imodel != NULL) + { + xModelInstanceAttach(xModelInstanceAlloc(imodel, ent, 0x2000, 0, NULL), + tempInst[i]); + } + } + } + } + if (zinfo->AnimTableID != 0) + { + xAnimTable* table = (xAnimTable*)xSTFindAsset(zinfo->AnimTableID, &bufsize); + tempInst[0]->Anim = xAnimPoolAlloc(&globals.sceneCur->mempool, ent, table, tempInst[0]); + } + return tempInst[0]; +} + +void zEntParseModelInfo(xEnt* ent, U32 assetID) +{ + U32 bufsize[4]; + void* info = xSTFindAsset(assetID, bufsize); + if (*(U32*)info == 0x464e494d) + { + ent->model = zEntRecurseModelInfo(info, ent); + } + else + { + xEntLoadModel(ent, (RpAtomic*)info); + ent->model->modelID = assetID; + } +} + +// This function suffers from a couple floating point memes +// Additionally it has a jumptable that needs to be generated in the correct place. +void zEntAnimEvent(zEnt* ent, U32 animEvent, const F32* animParam) +{ + xAnimPlay* play = ent->model->Anim; + if (play == NULL) + { + return; + } + + xAnimSingle* single = play->Single; + if (single == NULL) + { + return; + } + + if (ent->miscflags & 1) + { + zEntAnimEvent_AutoAnim(ent, animEvent, animParam); + } + else + { + switch (animEvent) + { + case 0xc3: + case 0xc4: + if (animParam == NULL) + { + break; + } + + S32 anum = (int)*animParam - 1; + if (anum < 0 || anum >= 10 || ent->atbl == NULL) + { + break; + } + + char name[12]; + if (animEvent == 0xc4) + { + sprintf(name, "loop%d", anum); + } + else + { + sprintf(name, "stop%d", anum); + } + + xAnimState* ast = xAnimTableGetState(ent->atbl, name); + if (ast == NULL) + { + break; + } + + xAnimPlaySetState(single, ast, 0.0f); + single->CurrentSpeed = 1.0f; + xAnimPlayUpdate(play, 0.0f); + xAnimPlayEval(play); + + if (ent->asset->modelInfoID != 0x8D398D0C /*is this an address???*/ || + animEvent != 0xc3) + { + break; + } + + xSndPlay3D(xStrHash("Check1"), 0.77f, 0.0f, 0x80, 0, (xVec3*)&ent->model->Mat->pos, + 0.0f, SND_CAT_GAME, 0.0f); + + break; + case 0xc5: + if (strcmp(single->State->Name, "idle") == 0) + { + break; + } + char name2[12]; + strcpy(name2, single->State->Name); + name2[0] = 's'; + name2[1] = 't'; + + single->State = xAnimTableGetState(ent->atbl, name2); + break; + case 0xc6: + single->CurrentSpeed = 0.0f; + break; + case 199: + single->CurrentSpeed = 1.0f; + break; + case 200: + if (single->CurrentSpeed) + { + single->CurrentSpeed = 0.0f; + } + else + { + single->CurrentSpeed = 1.0f; + } + break; + case 0xc9: + if (animParam == NULL) + { + break; + } + + S32 anum2 = (int)animParam[0] - 1; + S32 anum3 = (int)animParam[1] - 1; + if (anum2 < 0 || anum2 > anum3 || anum3 >= 10 || ent->atbl == NULL) + { + break; + } + + S32 anum4 = xrand(); + anum3 = anum3 - anum2 + 1; + anum4 %= anum3; + + char name3[12]; + sprintf(name3, "stop%d", anum2 + anum4); + + xAnimState* ast2 = xAnimTableGetState(ent->atbl, name3); + if (ast2 == NULL) + { + break; + } + + xAnimPlaySetState(single, ast2, 0.0f); + single->CurrentSpeed = 1.0f; + xAnimPlayUpdate(play, 0.0f); + xAnimPlayEval(play); + break; + case 0xca: + if (animParam == NULL) + { + break; + } + + S32 anum5 = (int)*animParam - 1; + F32 prob = 0.01f * animParam[1]; + if (anum5 < 0 || anum5 >= 10) + { + break; + } + + // Inverting this if screws up the float comparison + if (xurand() < prob && ent->atbl != NULL) + { + char name4[12]; + sprintf(name4, "stop%d", anum5); + xAnimState* ast3 = xAnimTableGetState(ent->atbl, name4); + if (ast3 == NULL) + { + break; + } + + single->CurrentSpeed = 1.0f; + xAnimPlaySetState(single, ast3, 0.0f); + xAnimPlayUpdate(play, 0.0f); + xAnimPlayEval(play); + } + break; + } + } +} + +U32 g_hash_xentanim[5] = { 0 }; +char* g_strz_xentanim[5] = { + "Idle01", "Anim02", "Anim03", "Anim04", "Anim05", +}; +// Thank you floating point memes. Very cool. +xAnimTable* xEnt_AnimTable_AutoEventSmall() +{ + char** names = g_strz_xentanim; + U32* hash = g_hash_xentanim; + xAnimTransition* deftran = NULL; + if (*hash == 0) + { + for (S32 i = 0; i < 5; i++) + { + hash[i] = xStrHash(names[i]); + } + } + + xAnimTable* table = xAnimTableNew("xEntAutoEventSimple", NULL, 0); + + for (S32 i = 0; i < 5; i++) + { + if (i == 0) + { + xAnimTableNewState(table, names[i], 0x10, 1, 1.0f, NULL, NULL, 0.0f, NULL, NULL, + xAnimDefaultBeforeEnter, NULL, NULL); + } + else + { + xAnimTableNewState(table, names[i], 0x20, 1, 1.0f, NULL, NULL, 0.0f, NULL, NULL, + xAnimDefaultBeforeEnter, NULL, NULL); + } + if (deftran != NULL) + { + xAnimTableAddTransition(table, deftran, names[i]); + } + else + { + if (i != 0) + { + deftran = xAnimTableNewTransition(table, names[i], names[0], 0, 0, 0x10, 0, 0.0f, + 0.0f, 1, 0, 0.25f, 0); + } + } + } + return table; +} + +// This function needs the floats to be replaced with literals +// and the jumptable to be generated in the right spot. +void zEntAnimEvent_AutoAnim(zEnt* ent, U32 animEvent, const F32* animParam) +{ + xAnimPlay* play = ent->model->Anim; + xAnimSingle* single = play->Single; + + switch (animEvent) + { + case 0xc3: + case 0xc4: + if (animParam == NULL) + { + break; + } + + S32 anum = (int)*animParam + -1; + if (anum < 0 || anum >= 5) + { + break; + } + + xAnimTable* tab1 = ent->model->Anim->Table; + if (tab1 == NULL) + { + break; + } + + xAnimState* ast = xAnimTableGetStateID(tab1, g_hash_xentanim[anum]); + if (ast == NULL) + { + break; + } + + if (anum != 0) + { + if (animEvent == 0xc4) + { + ast->Flags = ast->Flags & 0xffffffdf; + ast->Flags = ast->Flags | 0x10; + } + else + { + ast->Flags = ast->Flags | 0x20; + ast->Flags = ast->Flags & 0xffffffef; + } + } + xAnimPlaySetState(single, ast, 0.0f); + single->CurrentSpeed = 1.0f; + xAnimPlayUpdate(play, 0.0f); + xAnimPlayEval(play); + break; + case 0xc5: + xAnimTable* tab2 = ent->model->Anim->Table; + if (tab2 == NULL) + { + break; + } + + xAnimState* ast2 = xAnimTableGetStateID(tab2, g_hash_xentanim[0]); + if (ast2 != 0) + { + xAnimPlaySetState(single, ast2, 0.0f); + single->CurrentSpeed = 0.0f; + xAnimPlayUpdate(play, 0.0f); + xAnimPlayEval(play); + } + break; + case 0xc6: + single->CurrentSpeed = 0.0f; + break; + case 199: + single->CurrentSpeed = 1.0f; + break; + case 200: + if (single->CurrentSpeed > 0.0f) + { + single->CurrentSpeed = 0.0f; + } + else + { + single->CurrentSpeed = 1.0f; + } + break; + case 0xc9: + if (animParam == NULL) + { + break; + } + + S32 anum1 = (int)animParam[0] - 1; + S32 anum2 = (int)animParam[1] - 1; + if (anum1 < 0 || anum2 < 0 || anum1 > anum2 || anum2 >= 5) + { + break; + } + + S32 anum3 = xrand(); + anum2 = anum2 - anum1 + 1; + anum3 %= anum2; + anum1 += anum3; + + xAnimTable* tab3 = ent->model->Anim->Table; + if (tab3 == NULL) + { + break; + } + + xAnimState* ast3 = xAnimTableGetStateID(tab3, g_hash_xentanim[anum1]); + if (ast3 == NULL) + { + break; + } + + if (anum1 != 0) + { + ast3->Flags = ast3->Flags | 0x20; + ast3->Flags = ast3->Flags & 0xffffffef; + } + xAnimPlaySetState(single, ast3, 0.0f); + single->CurrentSpeed = 1.0f; + xAnimPlayUpdate(play, 0.0f); + xAnimPlayEval(play); + break; + case 0xca: + if (xUtil_yesno(0.01f * animParam[1]) != 0) + { + zEntAnimEvent_AutoAnim(ent, 0xc3, animParam); + } + break; + } +} + +xModelAssetParam* zEntGetModelParams(U32 assetID, U32* size) +{ + U32 bufsize; + void* info = xSTFindAsset(assetID, &bufsize); + xModelAssetInfo* minf = (xModelAssetInfo*)info; + + if (minf->Magic == 0x464e494d) + { + *size = bufsize - (minf->NumModelInst * 0x38 + 0x14); + if (*size != 0) + { + return (xModelAssetParam*)((char*)minf + minf->NumModelInst * 0x38 + 0x14); + } + } + else + { + *size = 0; + } + + return NULL; +} + +char* zParamGetString(xModelAssetParam* param, U32 size, char* tok, char* def) +{ + U32 hash = xStrHash(tok); + + while (param != NULL && size != 0) + { + if (param->HashID == hash) + { + return (char*)param->String; + } + + // S32 i = param->WordLength * 4; + size -= param->WordLength * 4 + 8; + param = (xModelAssetParam*)((char*)param + (param->WordLength * 4 + 8)); + } + return def; +} + +S32 zParamGetInt(xModelAssetParam* param, U32 size, const char* tok, S32 def) +{ + return zParamGetInt(param, size, (char*)tok, def); +} + +S32 zParamGetInt(xModelAssetParam* param, U32 size, char* tok, S32 def) +{ + char* str = zParamGetString(param, size, tok, NULL); + if (str != NULL) + { + return atoi(str); + } + return def; +} + +F32 zParamGetFloat(xModelAssetParam* param, U32 size, const char* tok, F32 def) +{ + return zParamGetFloat(param, size, (char*)tok, def); +} + +F32 zParamGetFloat(xModelAssetParam* param, U32 size, char* tok, F32 def) +{ + char* str = zParamGetString(param, size, tok, NULL); + if (str != NULL) + { + return xatof(str); + } + return def; +} + +S32 zParamGetFloatList(xModelAssetParam* param, U32 size, const char* tok, S32 count, F32* def, + F32* result) +{ + return zParamGetFloatList(param, size, (char*)tok, count, def, result); +} + +S32 zParamGetFloatList(xModelAssetParam* param, U32 size, char* tok, S32 count, F32* def, + F32* result) +{ + char* str = zParamGetString(param, size, tok, NULL); + S32 act = 0; + + if (def != NULL) + { + for (S32 i = 0; i < count; i++) + { + result[i] = def[i]; + } + } + + if (str != NULL) + { + act = xStrParseFloatList(result, str, count); + } + return act; +} + +S32 zParamGetVector(xModelAssetParam* param, U32 size, const char* tok, xVec3 vec1, xVec3* vec2) +{ + return zParamGetVector(param, size, (char*)tok, vec1, vec2); +} + +S32 zParamGetVector(xModelAssetParam* param, U32 size, char* tok, xVec3 vec1, xVec3* vec2) +{ + char* str = zParamGetString(param, size, tok, NULL); + S32 list = 0; + + xVec3 vec = { 0 }; + + xVec3Copy(vec2, &vec1); + if (str != NULL) + { + list = xStrParseFloatList((F32*)&vec, str, 3); + if (list > 0) + { + vec2->x = vec.x; + } + + if (list > 1) + { + vec2->y = vec.y; + } + + if (list > 2) + { + vec2->z = vec.z; + } + } + return list; +} + +// clang-format off +_ShadowParams gShadowParams[] = { + {NPC_TYPE_HAMMER, 0.33f, 2.0f}, + {NPC_TYPE_GLOVE, 0.0f, 1.25f}, + {NPC_TYPE_PLANKNPC, -0.25f, 0.75f}, + {NPC_TYPE_SLEEPY, 0.5f, 1.0f}, + {NPC_TYPE_BOSSSANDY, 1.0f, 2.0f}, +}; +// clang-format on + +void zEntGetShadowParams(xEnt* ent, xVec3* center, F32* radius, xEntShadow::radius_enum rtype) +{ + *center = *xBoundCenter(&ent->bound); + F32 r; + if (ent->entShadow != NULL) + { + r = ent->entShadow->radius[rtype]; + if (r > 0.0f) + { + *radius = r; + return; + } + } + + if (ent->bound.type == 0x1) + { + r = ent->bound.sph.r; + } + else + { + xVec3* lower = &ent->bound.box.box.lower; + xVec3* upper = &ent->bound.box.box.upper; + r = 0.167f * (upper->x + upper->y + upper->z - lower->x - lower->y - lower->z); + } + + *radius = r < 0.01f ? 2.0f : 2.4f * r; + + if (ent == &globals.player.ent) + { + *radius *= 1.5f; + } + else if (ent->baseType == 0x2b) + { + zNPCCommon* zp = (zNPCCommon*)ent; + _ShadowParams* sp = gShadowParams; + for (U32 i = 0; i < 5; i++) + { + if (sp->type == zp->SelfType()) + { + xVec3* at = (xVec3*)&ent->model->Mat->at; + xVec3AddScaled(center, at, sp->at); + *radius *= sp->rad; + return; + } + sp++; + } + } +} + +void xModelAnimCollStop(xModelInstance& m) +{ + m.Flags = m.Flags & 0xe7ff; +} + +xMat4x3* xEntGetFrame(const xEnt* ent) +{ + return xModelGetFrame(ent->model); +} + +void xSndPlay3D(U32 id, F32 vol, F32 pitch, U32 priority, U32 flags, const xVec3* pos, F32 radius, + sound_category category, F32 delay) +{ + xSndPlay3D(id, vol, pitch, priority, flags, pos, radius / 4.0f, radius, category, delay); +} + +S32 xNPCBasic::SelfType() const +{ + return myNPCType; +}; diff --git a/src/SB/Game/zEnt.h b/src/SB/Game/zEnt.h new file mode 100644 index 0000000..71673ce --- /dev/null +++ b/src/SB/Game/zEnt.h @@ -0,0 +1,63 @@ +#ifndef ZENT_H +#define ZENT_H + +#include "xEnt.h" +#include "xAnim.h" + +#include "zScene.h" +#include "zEvent.h" + +//For inline/weak functions +#include "xSnd.h" + +struct zScene; + +struct _ShadowParams +{ + U32 type; + F32 at; + F32 rad; +}; + +struct zEnt : xEnt +{ + xAnimTable* atbl; +}; + +void checkpoint_collision_hack(zEnt* ent); +char* zParamGetString(xModelAssetParam* param, U32 size, char* tok, char* def); +S32 zParamGetFloatList(xModelAssetParam* param, U32 size, const char* tok, S32 count, + F32* def, F32* result); +void zEntGetShadowParams(xEnt* ent, xVec3* center, F32* radius, xEntShadow::radius_enum rtype); +S32 zParamGetVector(xModelAssetParam* param, U32 size, const char* tok, xVec3 result, xVec3*); +S32 zParamGetVector(xModelAssetParam* param, U32 size, char* tok, xVec3 result, xVec3*); +S32 zParamGetFloatList(xModelAssetParam* param, U32 size, char* tok, S32 count, F32* def, + F32* result); +S32 zParamGetFloatList(xModelAssetParam* param, U32 size, char* tok, S32 count, F32* def, + F32* result); +F32 zParamGetFloat(xModelAssetParam* param, U32 size, const char* tok, F32 def); +F32 zParamGetFloat(xModelAssetParam* param, U32 size, char* tok, F32 def); +S32 zParamGetInt(xModelAssetParam* param, U32 size, const char* tok, S32 def); +S32 zParamGetInt(xModelAssetParam* param, U32 size, char* tok, S32 def); +xModelAssetParam* zEntGetModelParams(U32 assetID, U32* size); +void zEntAnimEvent_AutoAnim(zEnt* ent, U32 animEvent, const F32* animParam); +xAnimTable* xEnt_AnimTable_AutoEventSmall(); +void zEntAnimEvent(zEnt* ent, U32 animEvent, const F32* animParam); +void zEntParseModelInfo(xEnt* ent, U32 assetID); +xModelInstance* zEntRecurseModelInfo(void* info, xEnt* ent); +void zEntEventAllOfType(U32 toEvent, U32 type); +void zEntEventAll(xBase* from, U32 fromEvent, U32 toEvent, F32* toParam); +void zEntUpdate(zEnt* ent, zScene* scene, F32 elapsedSec); +void zEntReset(zEnt* ent); +void zEntLoad(zEnt* ent, xSerial* s); +void zEntSave(zEnt* ent, xSerial* s); +void zEntSetup(zEnt* ent); +void zEntInit(zEnt* ent, xEntAsset* asset, U32 type); + +// TODO: Misplaced Inlines/Weak functions +WEAK void xModelAnimCollStop(xModelInstance& m); +WEAK xMat4x3* xEntGetFrame(const xEnt* ent); +WEAK void xSndPlay3D(U32 id, F32 vol, F32 pitch, U32 priority, U32 flags, + const xVec3* pos, F32 radius, sound_category category, F32 delay); + +#endif diff --git a/src/SB/Game/zEntButton.h b/src/SB/Game/zEntButton.h new file mode 100644 index 0000000..db2c527 --- /dev/null +++ b/src/SB/Game/zEntButton.h @@ -0,0 +1,48 @@ +#ifndef ZENTBUTTON_H +#define ZENTBUTTON_H + +#include "zEnt.h" + +#include "xEntMotion.h" + +struct zEntButtonAsset +{ + U32 modelPressedInfoID; + U32 actMethod; + S32 initButtonState; + S32 isReset; + F32 resetDelay; + U32 buttonActFlags; +}; + +struct _zEntButton : zEnt +{ + zEntButtonAsset* basset; + xEntMotion motion; + U32 state; + F32 speed; + U32 oldState; + S32 oldMotState; + F32 counter; + xModelInstance* modelPressed; + F32 holdTimer; + U32 hold; + F32 topHeight; +}; + +void zEntButton_Init(void* ent, void* asset); +void zEntButton_Init(_zEntButton* ent, xEntAsset* asset); +void zEntButton_Move(_zEntButton* ent, xScene* sc, F32 dt, xEntFrame* frame); +void zEntButton_Setup(_zEntButton* ent, xScene* sc); +void zEntButton_Save(_zEntButton* ent, xSerial* s); +void zEntButton_Load(_zEntButton* ent, xSerial* s); +void zEntButton_Reset(_zEntButton* ent, xScene* sc); +void zEntButton_Update(_zEntButton* ent, xScene* sc, F32 dt); +void zEntButton_Render(_zEntButton* ent); +void zEntButton_SetReady(_zEntButton* ent); +void zEntButton_Press(_zEntButton* ent); +void zEntButton_Press(_zEntButton* ent, U32 mask); +void zEntButton_Hold(_zEntButton* ent, U32 mask); +void zEntButton_SceneUpdate(F32 dt); + +#endif diff --git a/src/SB/Game/zEntCruiseBubble.h b/src/SB/Game/zEntCruiseBubble.h new file mode 100644 index 0000000..19ded2c --- /dev/null +++ b/src/SB/Game/zEntCruiseBubble.h @@ -0,0 +1,655 @@ +#ifndef ZENTCRUISEBUBBLE_H + +#define ZENTCRUISEBUBBLE_H + +#include "xDebug.h" + +#include "zNPCHazard.h" +#include "zShrapnel.h" +#include + +#include "zRumble.h" + +// I have no idea where to put this. This is only used by +// cruise_bubble::tweak_group::register_tweaks() so far. +// If you are searching the project for 'auto_tweak' you are +// probably working on one of the bosses which also seem to use this. +// As of now I'm not sure if you should include this declaration, +// define your own or find a good place for shared use. +// NOTE (Square): pretty sure this is from xDebug +namespace auto_tweak +{ + template + void load_param(T1&, T2, T2, T2, xModelAssetParam*, U32, const char*); +}; + +namespace cruise_bubble +{ + namespace + { + enum state_enum + { + BEGIN_STATE_PLAYER, + STATE_PLAYER_HALT = 0x0, + STATE_PLAYER_AIM, + STATE_PLAYER_FIRE, + STATE_PLAYER_WAIT, + END_STATE_PLAYER, + BEGIN_STATE_MISSLE = 0x4, + BACKUP_STATE_MISSLE = 0x3, + STATE_MISSLE_APPEAR, + STATE_MISSLE_FLY, + STATE_MISSLE_EXPLODE, + END_STATE_MISSLE, + BEGIN_STATE_CAMERA = 0x7, + BACKUP_STATE_CAMERA = 0x6, + STATE_CAMERA_AIM, + STATE_CAMERA_SEIZE, + STATE_CAMERA_ATTACH, + STATE_CAMERA_SURVEY, + STATE_CAMERA_RESTORE, + END_STATE_CAMERA, + MAX_STATE = 0xc, + BACKUP_STATE_PLAYER = 0xffffffff, + STATE_INVALID = 0xffffffff + }; + + enum thread_enum + { + THREAD_PLAYER, + THREAD_MISSLE, + THREAD_CAMERA, + MAX_THREAD + }; + + struct state_type + { + state_enum type; + + state_type(state_enum type); + + virtual void start(); + virtual void stop(); + virtual state_enum update(F32 dt) = 0; + virtual void render(); + virtual void abort(); + }; + + struct state_player_fire : state_type + { + U8 wand_shown; + + state_player_fire(); + + void start(); + void stop(); + state_enum update(F32 dt); + void update_wand(F32 dt); + }; + + struct state_camera_aim : state_type + { + F32 phi; + F32 phi_vel; + F32 height; + F32 height_vel; + F32 dist; + F32 dist_vel; + xQuat facing; + xQuat target; + F32 control_delay; + F32 seize_delay; + + state_camera_aim(); + + void start(); + void stop(); + state_enum update(F32 dt); + + void apply_turn() const; + void turn(F32 dt); + void collide_inward(); + void apply_motion() const; + void stop(F32 dt); + void move(F32 dt); + }; + + struct state_player_halt : state_type + { + U8 first_update; + F32 time; + xVec3 last_motion; + + state_player_halt(); + + void start(); + void stop(); + state_enum update(F32 dt); + }; + + struct state_missle_explode : state_type + { + F32 hit_time; + + state_missle_explode(); + + void start(); + void stop(); + state_enum update(F32 dt); + + F32 get_radius() const; + void start_effects(); + void cb_droplet(zFrag* frag, zFragAsset* fa); + void perturb_direction(const xVec3&, F32, F32, F32, F32); + void get_next_quadrant(F32&, F32&, F32&, F32&); + void reset_quadrants(U32 size, F32 ring); + void apply_damage(F32 radius); + void apply_damage_hazards(F32); + U8 hazard_check(NPCHazard& haz, void* context); + }; + + struct state_camera_attach : state_type + { + F32 reticle_delay; + + state_camera_attach(); + + void start(); + void stop(); + state_enum update(F32 dt); + + void lock_targets(); + void lock_hazard_targets(); + static U8 hazard_check(NPCHazard& haz, void* context); + void get_view_bound(xBound& bound) const; + }; + + struct state_missle_fly : state_type + { + F32 life; + F32 vel; + xVec3 rot; + // Offset: 0x1c + xVec3 rot_vel; + // Offset: 0x28 + F32 engine_pitch; + xVec3 last_loc; + // Offset: 0x38 + F32 flash_time; + + state_missle_fly(); + + void start(); + void stop(); + state_enum update(F32 dt); + void abort(); + void update_flash(F32 dt); + void update_engine_sound(F32 dt); + + U8 collide_hazards(); + static bool hazard_check(NPCHazard& haz, void* context); + U8 collide(); + U8 hit_test(xVec3& hit_loc, xVec3& hit_norm, xVec3& hit_depen, xEnt*& hit_ent) const; + void update_move(F32 dt); + void update_turn(F32 dt); + void calculate_rotation(xVec2& d1, xVec2& v1, F32 dt, const xVec2& d0, const xVec2& v0, + const xVec2& a0, const xVec2& a1) const; + }; + + struct state_missle_appear : state_type + { + state_missle_appear(); + + void start(); + void stop(); + state_enum update(F32 dt); + void move(); + void update_effects(F32 dt); + }; + + struct state_camera_seize : state_type + { + F32 blend_time; + xVec3 start_loc; + xQuat start_dir; + xQuat end_dir; + xQuat cur_dir; + F32 last_s; + F32 fov; + F32 wipe_bubbles; + + state_camera_seize(); + + void start(); + void stop(); + state_enum update(F32 dt); + + void refresh_missle_alpha(F32); + void update_turn(F32); + void update_move(F32); + }; + + struct state_player_aim : state_type + { + F32 yaw; + F32 yaw_vel; + F32 turn_delay; + + state_player_aim(); + + void start(); + void stop(); + state_enum update(F32 dt); + + void update_animation(F32 dt); + void apply_yaw(); + void face_camera(F32 dt); + }; + + struct state_camera_restore : state_type + { + F32 control_delay; + + state_camera_restore(); + + void start(); + void stop(); + state_enum update(F32 dt); + }; + + struct state_camera_survey : state_type + { + F32 time; + xVec2 start_sp; + F32 path_distance[127]; + + state_camera_survey(); + + void start(); + void stop(); + state_enum update(F32 dt); + + void move(); + void eval_missle_path(F32 dist, xVec3& loc, F32& roll) const; + void lerp(F32& x, F32 t, F32 a, F32 b) const; + void lerp(xVec3& v, F32 t, const xVec3& a, const xVec3& b) const; + S32 find_nearest(F32) const; + void init_path(); + bool control_jerked() const; + }; + + struct state_player_wait : state_type + { + state_player_wait(); + + void start(); + state_enum update(F32 dt); + }; + + // Size: 0x1b8 + struct tweak_group + { + F32 aim_delay; + // Size: 0x10, Offset: 0x4 + struct _class_2 + { + F32 halt_time; // 0x4 + struct _class_4 + { + F32 turn_speed; // 0x8 + F32 anim_delta; // 0xC + } aim; + struct _class_11 + { + F32 delay_wand; // 0x10 + } fire; + } player; + + // Size: 0x5c, Offset: 0x14 + struct _class_22 + { + F32 life; + F32 hit_dist; // 0x18 + F32 crash_angle; // 0x1c + F32 collide_twist; // 0x20 + S32 hit_tests; // 0x24 + struct _class_27 + { + F32 delay_show; // 0x28 + F32 delay_fly; // 0x2c + xVec3 offset; // 0x30 + } appear; + struct _class_32 + { + F32 accel; // 0x3c + F32 max_vel; // 0x40 + F32 engine_pitch_max; // 0x44 + F32 engine_pitch_sensitivity; // 0x48 + // Offset: 0x4c + F32 flash_interval; + struct _class_38 + { + F32 xdelta; // 0x50 + F32 ydelta; // 0x54 + F32 xdecay; // 0x58 + F32 ydecay; // 0x5c + F32 ybound; // 0x60 + F32 roll_frac; // 0x64 + } turn; + } fly; + struct _class_49 + { + F32 hit_radius; // 0x68 + F32 hit_duration; // 0x6c + } explode; + } missle; + + // Size: 0x5c, Offset: 0x70 + struct _class_10 + { + struct _class_15 + { + F32 dist; + F32 height; // 0x74 + F32 pitch; // 0x78 + F32 accel; // 0x7c + F32 max_vel; // 0x80 + F32 stick_decel; // 0x84 + F32 stick_accel; // 0x88 + F32 stick_max_vel; // 0x8c + F32 turn_speed; // 0x90 + } aim; + struct _class_24 + { + F32 delay; // 0x94 + F32 blend_time; // 0x98 + F32 fade_dist; // 0x9c + F32 hide_dist; // 0xa0 + F32 fov; // 0xa4 + } seize; + struct _class_30 + { + F32 duration; // 0xa8 + F32 min_duration; // 0xac + F32 min_dist; // 0xb0 + F32 cut_dist; // 0xb4 + F32 drift_dist; // 0xb8 + F32 drift_softness; // 0xbc + F32 jerk_offset; // 0xc0 + F32 jerk_deflect; // 0xc4 + } survey; + struct _class_39 + { + F32 control_delay; // 0xc8 + } restore; + } camera; + + // Size: 0x18, Offset: 0xcc + struct _class_48 + { + F32 env_alpha; + F32 env_coeff; // 0xd0 + U32 env_texture; // 0xd4 + F32 fresnel_alpha; // 0xd8 + F32 fresnel_coeff; // 0xdc + U32 fresnel_texture; // 0xe0 + } material; + + // Size: 0x14, Offset: 0xe4 + struct _class_9 + { + // Offset: 0xe4 + F32 dist_min; + F32 dist_max; + // Offset: 0xec + F32 ang_show; + F32 ang_hide; + F32 delay_retarget; + } reticle; + + // Size: 0x10, Offset: 0xf8 + struct _class_20 + { + // Offset: 0xf8 + F32 sample_rate; + F32 bubble_rate; // 0xfc + F32 bubble_emit_radius; // 0x100 + F32 wake_emit_radius; // 0x104 + } trail; + + // Size: 0x10, Offset: 0x108 + struct _class_29 + { + U32 emit; // 0x108 + F32 radius; // 0x10c + F32 vel; // 0x110 + F32 rand_vel; // 0x11 + } blast; + + // Size: 0x24, Offset: 0x118 + struct _class_35 + { + F32 dist_min; + F32 dist_max; + U32 emit_min; + U32 emit_max; + F32 vel_min; + F32 vel_max; + F32 vel_perturb; + F32 vel_angle; + F32 rot_vel_max; + } droplet; + + // Size: 0x44, Offset: 0x13c + struct _class_43 + { + F32 glow_size; + // Offset: 0x140 + F32 time_fade; + F32 time_glow; + struct _class_46 + { + F32 size; + F32 du; + F32 dv; + } swirl; + struct _class_5 + { + F32 size; + F32 du; + F32 dv; + } wind; + struct _class_12 + { + F32 size; + } reticle; + struct _class_18 + { + F32 size; + } target; + struct _class_23 + { + // Offset: 0x168 + S32 font; + F32 font_width; + F32 font_height; + F32 x; + F32 y; + // Offset: 0x17c + F32 glow_size; + } timer; + } hud; + + // Size: 0xc, Offset: 0x180 + struct _class_34 + { + F32 freq; + F32 decay; + F32 min_freq; + } dialog; + + void* context; + tweak_callback cb_missle_model; + + void load(xModelAssetParam* params, U32 size); + + void register_tweaks(bool init, xModelAssetParam* ap, U32 apsize, const char*); + }; + + struct uv_animated_model + { + RpAtomic* model; + RwTexCoords* uv; + S32 uvsize; + xVec2 offset; + xVec2 offset_vel; + + bool init(RpAtomic*); + bool clone_uv(RwTexCoords*&, S32&, RpAtomic*) const; + bool get_uv(RwTexCoords*&, S32&, RpAtomic*) const; + void update(F32 dt); + void refresh(); + }; + + struct sound_config + { + // offset 0x0 + char* name; + // offset 0x4 + F32 volume; + // offset 0x8 + F32 radius_inner; + // offset 0xc + F32 radius_outer; + // offset 0x10 + U8 streamed; // might be bool, not sure + U8 looping; // might be bool, not sure + // offset 0x14 + _tagSDRumbleType rumble; + // offset 0x18 + S32 first; + // offset 0x1c + S32 last; + // offset 0x20 + U32 id; + // offset 0x24 + U32 handle; + }; + + struct hud_gizmo + { + S32 flags; + basic_rect bound; + F32 alpha; + // Offset: 0x18 + F32 alpha_vel; + F32 glow; + F32 glow_vel; + F32 opacity; + const xVec3* target; + xModelInstance* model; + }; + + struct missle_record_data + { + xVec3 loc; + F32 roll; + + missle_record_data(const xVec3& loc, F32 roll); + }; + } // namespace + + void init_sound(); + void stop_sound(S32 which, U32 handle); + U32 play_sound(S32 which, F32 volFactor); + U32 play_sound(S32 which, F32 volFactor, const xVec3* pos); + void set_pitch(S32 which, F32 pitch, U32 handle); + void show_wand(); + void hide_wand(); + void show_missle(); + void hide_missle(); + void capture_camera(); + void release_camera(); + bool camera_taken(); + bool camera_leave(); + void start_damaging(); + // void damage_entity(xEnt& ent, const xVec3& loc, const xVec3& dir, const xVec3& hit_norm, + // F32 radius, bool explosive); + U8 can_damage(xEnt* ent); + U8 was_damaged(xEnt* ent); + void notify_triggers(xScene& s, const xSphere& o, const xVec3& dir); + void exit_triggers(xScene& s); + void signal_event(U32 toEvent); + void refresh_trail(xMat4x3& mat, xQuat& quat); + void start_trail(); + void stop_trail(); + void set_state(thread_enum thread, state_enum state); + bool check_launch(); + void kill(bool reset_camera, bool abortive); + void distort_screen(F32); + void update_player(xScene& s, F32 dt); + xVec3& get_player_loc(); + void render_player(); + void refresh_controls(); + void update_state(xScene* s, F32 dt); + void render_state(); + RpAtomic* custom_bubble_render(RpAtomic* atomic); + void init_states(); + void init_missle_model(); + void reset_wake_ribbons(); + void init_wake_ribbons(); + void reset_explode_decal(); + void init_explode_decal(); + void init_shrapnel(); + void add_trail_sample(const xVec3& loc0, const xVec3& dir0, const xVec3& loc1, + const xVec3& dir1, F32 dt); + void update_trail(F32 dt); + void refresh_missle_model(); + void update_missle(xScene& s, F32 dt); + void render_missle(); + xModelInstance* load_model(U32); + void render_model_2d(xModelInstance* m, const basic_rect& bound, F32 alpha); + void render_glow(xModelInstance* m, const basic_rect& r, F32 glow, F32 alpha); + void init_hud(); + void show_gizmo(hud_gizmo& gizmo, const basic_rect& rect, xModelInstance* m); + void update_gizmo(hud_gizmo& gizmo, F32 dt); + void flash_hud(); + void render_timer(F32 alpha, F32 glow); + void lerp(iColor_tag& c, F32 t, iColor_tag a, iColor_tag b); + void lerp(U8& x, F32 t, U8 a, U8 b); + void update_hud(F32 dt); + void render_hud(); + void show_hud(); + void hide_hud(); + xVec3 world_to_screen(const xVec3& loc); + S32 find_locked_target(const xVec3* target); + void lock_target(S32 index, const xVec3* target, F32 opacity); + void check_lock_target(const xVec3* target); + U32 check_anim_aim(xAnimTransition*, xAnimSingle*); + void load_cheat_tweak(); + void load_settings(); + void init(); + void init_debug(); + void reset(); + void launch(); + bool update(xScene* s, F32 dt); + bool render(); + void render_debug(); + void render_screen(); + void insert_player_animations(xAnimTable& table); + bool active(); + F32 exploding(); + void get_explode_sphere(xVec3& center, F32& radius); + xEnt** get_explode_hits(S32& size); + void add_life(F32, F32); + void set_life(F32 life); + void reset_life(); + // xBase* param names are guessed as they go unused and wont appear in dwarf + bool event_handler(xBase* from, U32 event, const F32* fparam, xBase* to); + xMat4x3* get_player_mat(); + xMat4x3* get_missle_mat(); +} // namespace cruise_bubble + +xAnimTable* anim_table(); + +#endif diff --git a/src/SB/Game/zEntDestructObj.h b/src/SB/Game/zEntDestructObj.h new file mode 100644 index 0000000..1b5e014 --- /dev/null +++ b/src/SB/Game/zEntDestructObj.h @@ -0,0 +1,78 @@ +#ifndef ZENTDESTRUCTOBJ_H +#define ZENTDESTRUCTOBJ_H + +#include "zEnt.h" +#include "xSFX.h" +#include "zParEmitter.h" +#include "zGlobals.h" +#include "zRumble.h" +#include "xVec3.h" +#include "xString.h" +#include "xstransvc.h" +#include "zShrapnel.h" +#include "zCollGeom.h" +#include "iCollide.h" + +#define DOBJ_STATE_INIT 0 +#define DOBJ_STATE_RESET 1 +#define DOBJ_STATE_DESTROYED 2 + +struct zEntDestructObjAsset +{ + F32 animSpeed; + U32 initAnimState; + U32 health; + U32 spawnItemID; + U32 dflags; // 0x10 + U8 collType; + U8 fxType; + U8 pad[2]; + F32 blast_radius; + F32 blast_strength; + U32 shrapnelID_destroy; // 0x20 + U32 shrapnelID_hit; // 0x24 + U32 sfx_destroy; // 0x28 + U32 sfx_hit; // 0x2C + U32 hitModelId; // 0x30 + U32 destroyModelId; // 0x34 +}; + +struct zEntDestructObj : zEnt +{ + zEntDestructObjAsset* dasset; // Offset 0xD4 + U32 state; + U32 healthCnt; + F32 fx_timer; // Offset 0xE0 + zParEmitter* fx_emitter; + F32 respawn_timer; + U32 throw_target; + zShrapnelAsset* shrapnel_destroy; // Offset 0xF0 + zShrapnelAsset* shrapnel_hit; + xModelInstance* base_model; + xModelInstance* hit_model; + xModelInstance* destroy_model; // Offset 0x100 + void (*destroy_notify)(zEntDestructObj&, void*); + void* notify_context; + xSFXAsset* sfx_destroy; // 0x10C + xSFXAsset* sfx_hit; // 0x110 +}; + +void zEntDestructObj_FindFX(); +void zEntDestructObj_Init(void* ent, void* asset); +void zEntDestructObj_Init(zEntDestructObj* ent, xEntAsset* asset); + +// TODO: update unk with callback signatures from zEnt +void zEntDestructObj_Move(zEntDestructObj* ent, xScene* scene, F32 unk, xEntFrame* frame); +void zEntDestructObj_Update(zEntDestructObj* ent, xScene* scene, F32 unk); +void zEntDestructObj_Hit(zEntDestructObj* ent, U32 mask); +U32 zEntDestructObj_GetHit(zEntDestructObj* ent, U32 mask); +void zEntDestructObj_Save(zEntDestructObj* ent, xSerial* s); +void zEntDestructObj_Load(zEntDestructObj* ent, xSerial* s); +void zEntDestructObj_Setup(zEntDestructObj* ent); +void zEntDestructObj_Reset(zEntDestructObj* ent, xScene* scene); +U32 zEntDestructObj_isDestroyed(zEntDestructObj* ent); +void zEntDestructObj_DestroyFX(zEntDestructObj* ent); +S32 zEntDestructObjEventCB(xBase* from, xBase* to, U32 toEvent, const F32* toParam, + xBase* baseUnk3); + +#endif diff --git a/src/SB/Game/zEntHangable.h b/src/SB/Game/zEntHangable.h new file mode 100644 index 0000000..5335607 --- /dev/null +++ b/src/SB/Game/zEntHangable.h @@ -0,0 +1,42 @@ +#ifndef ZENTHANGABLE_H +#define ZENTHANGABLE_H + +#include "zEnt.h" + +struct xEntHangableAsset +{ + U32 flags; + F32 pivotOffset; + F32 leverArm; + F32 gravity; + F32 accel; + F32 decay; + F32 grabDelay; + F32 stopDecel; +}; + +struct zEntHangable : zEnt +{ + xEntHangableAsset* hangInfo; + xVec3 pivot; + xVec3 endpos; + xVec3 vel; + xVec3 swingplane; + F32 grabTimer; + F32 spin; + U32 state; + zEnt* shaggy; + S32 enabled; + zEnt* follow; + S32 moving; + F32 candle_timer; + S32 candle_state; +}; + +void zEntHangable_SetupFX(); +void zEntHangable_Init(void* ent, void* asset); +void zEntHangable_Save(zEntHangable* ent, xSerial* s); +void zEntHangable_Load(zEntHangable* ent, xSerial* s); +void zEntHangable_Reset(zEntHangable* ent); + +#endif diff --git a/src/SB/Game/zEntPickup.h b/src/SB/Game/zEntPickup.h new file mode 100644 index 0000000..639a5c2 --- /dev/null +++ b/src/SB/Game/zEntPickup.h @@ -0,0 +1,89 @@ +#ifndef ZENTPICKUP_H +#define ZENTPICKUP_H + +#include "zEnt.h" +#include "zPickupTable.h" +#include "zParEmitter.h" + +#include "xEntDrive.h" +#include "xPar.h" +#include "xShadowSimple.h" +#include "iColor.h" + +struct zEntPickup : zEnt +{ + xShadowSimpleCache simpShadow_embedded; + U32 state; // 0x16C + zAssetPickup* p; + void* anim; + F32 animTime; + F32 timer; // 0x17C + F32 shake_timer; + xVec3 shake_pos; + S32 snackGateInfoDisplayed; + F32 fx_timer; + xPar* fx_par; + zParEmitter* fx_emit; + F32 fx_scale; + xVec3 grab_pos; + U32 flyflags; + S32 flg_opts; + xVec3 vel; + xVec3 droppos; + xBase* followTarget; + xVec3 followOffset; + xBase* dropParent; + xEnt* useThisEntPos; + xEntDrive drv; + U16 pickupFlags; // 0x264 +}; + +struct xEntPickupAsset +{ + U32 pickupHash; + U16 pickupFlags; + U16 pickupValue; +}; + +struct zPickupAuraInfo +{ + F32 size; + F32 yoffset; + iColor_tag color; +}; + +extern zParEmitter* gEmitShinySparkles; +extern U32 gEnableRewardsQueue; +extern zPickupAuraInfo zPickupAuraTable[]; + +void zEntPickup_Startup(); +void zEntPickupInit(void* ent, void* asset); +void zEntPickupInit(zEntPickup* ent, xEntAsset* asset); +void zEntPickup_Setup(zEntPickup* p); +void zEntPickup_Setup(); +S32 zEntPickupEventCB(xBase*, xBase* to, U32 toEvent, const F32* toParam, + xBase* toParamWidget); +void zEntPickup_FlyToInterface(zEntPickup*, F32); +void zEntPickup_CheckAllPickupsAgainstPlayer(xScene* sc, F32 dt); +void zEntPickup_DoPickup(zEntPickup* ent); +void zEntPickup_GivePickup(zEntPickup* ent); +void zEntPickup_GiveAllRewardsNow(); +void zEntPickup_Update(zEntPickup* ent, xScene* sc, F32 dt); +void zEntPickup_Reset(zEntPickup* ent); +void zEntPickup_Save(zEntPickup* ent, xSerial* s); +void zEntPickup_Load(zEntPickup* ent, xSerial* s); +void zEntPickup_FlushGrabbed(); +void zEntPickup_MakeDroppable(zEntPickup* ent, xVec3* pos, xBase* dropParent); +void zEntPickup_Drop(zEntPickup* ent); +void zEntPickup_Render(zEntPickup* plist, U32 pcount); +void zEntPickup_RenderOne(xEnt* ent); +void zEntPickup_RenderList(zEntPickup* plist, U32 pcount); +void zEntPickup_UpdateFlyToInterface(zEntPickup* ent, U32 pcount, F32 dt); +void zEntPickup_SceneEnter(); +void zEntPickup_SceneReset(); +void zEntPickup_SceneUpdate(F32 dt); +void zEntPickup_SpawnNRewards(U32* pickups, U32 num, xVec3* ppos); +void zEntPickup_SpawnNRewards(U32* pickups, U32 num, xVec3 pos); +void zEntPickup_RewardPostSetup(); + +#endif diff --git a/src/SB/Game/zEntPlayer.h b/src/SB/Game/zEntPlayer.h new file mode 100644 index 0000000..ae42d00 --- /dev/null +++ b/src/SB/Game/zEntPlayer.h @@ -0,0 +1,439 @@ +#ifndef ZENTPLAYER_H +#define ZENTPLAYER_H + +#include "xMath3.h" +#include "xEnt.h" +#include "xAnim.h" +#include "zEnt.h" +#include "zLasso.h" + +enum zControlOwner +{ + CONTROL_OWNER_GLOBAL = 0x1, + CONTROL_OWNER_EVENT, + CONTROL_OWNER_OOB = 0x4, + CONTROL_OWNER_BOSS = 0x8, + CONTROL_OWNER_TALK_BOX = 0x10, + CONTROL_OWNER_TAXI = 0x20, + CONTROL_OWNER_BUS_STOP = 0x40, + CONTROL_OWNER_TELEPORT_BOX = 0x80, + CONTROL_OWNER_CRUISE_BUBBLE = 0x100, + CONTROL_OWNER_FLY_CAM = 0x200, + CONTROL_OWNER_FROZEN = 0x400, + CONTROL_OWNER_TURRET = 0x800, + CONTROL_OWNER_REWARDANIM = 0x1000, + CONTROL_OWNER_BUNGEE = 0x2000, + CONTROL_OWNER_SPRINGBOARD = 0x4000, + CONTROL_OWNER_CUTSCENE = 0x8000 +}; + +enum _tagePlayerSnd +{ + ePlayerSnd_Invalid, + ePlayerSnd_Land, + ePlayerSnd_Jump, + ePlayerSnd_DoubleJump, + ePlayerSnd_BowlWindup, + ePlayerSnd_BowlRelease, + ePlayerSnd_BubbleBashStart, + ePlayerSnd_BubbleBashHit1, + ePlayerSnd_BubbleBashHitStart = 0x7, + ePlayerSnd_BubbleBashHit2, + ePlayerSnd_BubbleBashHitEnd = 0x8, + ePlayerSnd_BubbleWand, + ePlayerSnd_CruiseStart, + ePlayerSnd_CruiseNavigate, + ePlayerSnd_CruiseHit, + ePlayerSnd_BounceStrike, + ePlayerSnd_BoulderStart, + ePlayerSnd_BoulderRoll, + ePlayerSnd_BoulderEnd, + ePlayerSnd_BellyMelee, + ePlayerSnd_BellySmash, + ePlayerSnd_Lift1, + ePlayerSnd_Throw, + ePlayerSnd_Chop, + ePlayerSnd_Kick, + ePlayerSnd_Heli, + ePlayerSnd_LassoThrow, + ePlayerSnd_LassoYank, + ePlayerSnd_LassoStretch, + ePlayerSnd_Ouch1, + ePlayerSnd_OuchStart = 0x1b, + ePlayerSnd_Ouch2, + ePlayerSnd_Ouch3, + ePlayerSnd_Ouch4, + ePlayerSnd_OuchEnd = 0x1e, + ePlayerSnd_Death, + ePlayerSnd_FruitCrackle, + ePlayerSnd_CheckPoint, + ePlayerSnd_PickupSpatula, + ePlayerSnd_PickupUnderwear, + ePlayerSnd_Bus, + ePlayerSnd_Taxi, + ePlayerSnd_SlideLoop, + ePlayerSnd_BeginBungee, + ePlayerSnd_BungeeWind = 0x27, + ePlayerSnd_BungeeAttach, + ePlayerSnd_BungeeRelease, + ePlayerSnd_EndBungee = 0x29, + ePlayerSnd_PickupSpatulaComment, + ePlayerSnd_BungeeDive1, + ePlayerSnd_BungeeDive2, + ePlayerSnd_Sneak, + ePlayerSnd_SlipLoop, + ePlayerSnd_Total +}; + +enum _tagePlayerStreamSnd +{ + ePlayerStreamSnd_Invalid, + ePlayerStreamSnd_PickupSock1, + ePlayerStreamSnd_PickupSock2, + ePlayerStreamSnd_PickupSock3, + ePlayerStreamSnd_UnderwearComment1, + ePlayerStreamSnd_UnderwearComment2, + ePlayerStreamSnd_UnderwearComment3, + ePlayerStreamSnd_EnterScene1, + ePlayerStreamSnd_EnterScene2, + ePlayerStreamSnd_EnterScene3, + ePlayerStreamSnd_EnterScene4, + ePlayerStreamSnd_EnterScene5, + ePlayerStreamSnd_EnterScene6, + ePlayerStreamSnd_EnterScene7, + ePlayerStreamSnd_SpatulaComment1, + ePlayerStreamSnd_ShinyComment1, + ePlayerStreamSnd_ShinyComment2, + ePlayerStreamSnd_ShinyComment3, + ePlayerStreamSnd_ShinyComment4, + ePlayerStreamSnd_ShinyComment5, + ePlayerStreamSnd_SpongeBallComment1, + ePlayerStreamSnd_SpongeBallComment2, + ePlayerStreamSnd_SpongeBallComment3, + ePlayerStreamSnd_CruiseComment1, // 0x17 -> "Say hello to my little bubble friend." + ePlayerStreamSnd_CruiseComment2, // 0x18 -> "SpongeBob to mission control, the launch is a go." + ePlayerStreamSnd_CruiseComment3, // 0x19 -> "Bubble Power!" + ePlayerStreamSnd_BowlComment1, + ePlayerStreamSnd_BowlComment2, + ePlayerStreamSnd_BowlComment3, + ePlayerStreamSnd_BowlComment4, + ePlayerStreamSnd_BowlComment5, + ePlayerStreamSnd_PushButton1, + ePlayerStreamSnd_PushButton2, + ePlayerStreamSnd_PushButton3, + ePlayerStreamSnd_BellySmashComment1, + ePlayerStreamSnd_BellySmashComment2, + ePlayerStreamSnd_BellySmashComment3, + ePlayerStreamSnd_ChopComment1, + ePlayerStreamSnd_ChopComment2, + ePlayerStreamSnd_ChopComment3, + ePlayerStreamSnd_KickComment1, + ePlayerStreamSnd_KickComment2, + ePlayerStreamSnd_KickComment3, + ePlayerStreamSnd_RopingComment1, + ePlayerStreamSnd_RopingComment2, + ePlayerStreamSnd_RopingComment3, + ePlayerStreamSnd_HeliComment1, + ePlayerStreamSnd_HeliComment2, + ePlayerStreamSnd_HeliComment3, + ePlayerStreamSnd_DestroyTiki1, + ePlayerStreamSnd_DestroyTiki2, + ePlayerStreamSnd_DestroyTiki3, + ePlayerStreamSnd_DestroyRobot1, + ePlayerStreamSnd_DestroyRobot2, + ePlayerStreamSnd_DestroyRobot3, + ePlayerStreamSnd_SeeWoodTiki, + ePlayerStreamSnd_SeeLoveyTiki, + ePlayerStreamSnd_SeeShhhTiki, + ePlayerStreamSnd_SeeThunderTiki, + ePlayerStreamSnd_SeeStoneTiki, + ePlayerStreamSnd_SeeFodder, + ePlayerStreamSnd_SeeHammer, + ePlayerStreamSnd_SeeTarTar, + ePlayerStreamSnd_SeeGLove, + ePlayerStreamSnd_SeeMonsoon, + ePlayerStreamSnd_SeeSleepyTime, + ePlayerStreamSnd_SeeArf, + ePlayerStreamSnd_SeeTubelets, + ePlayerStreamSnd_SeeSlick, + ePlayerStreamSnd_SeeKingJellyfish, + ePlayerStreamSnd_SeePrawn, + ePlayerStreamSnd_SeeDutchman, + ePlayerStreamSnd_SeeSandyBoss, + ePlayerStreamSnd_SeePatrickBoss1, + ePlayerStreamSnd_SeePatrickBoss2, + ePlayerStreamSnd_SeeSpongeBobBoss, + ePlayerStreamSnd_SeeRobotPlankton, + ePlayerStreamSnd_PickupSpecialGeneric1, + ePlayerStreamSnd_PickupSpecialGeneric2, + ePlayerStreamSnd_GoldenUnderwear4, + ePlayerStreamSnd_GoldenUnderwear5, + ePlayerStreamSnd_GoldenUnderwear6, + ePlayerStreamSnd_Combo1, + ePlayerStreamSnd_Combo2, + ePlayerStreamSnd_Combo3, + ePlayerStreamSnd_Combo4, + ePlayerStreamSnd_Combo5, + ePlayerStreamSnd_BigCombo1, + ePlayerStreamSnd_BigCombo2, + ePlayerStreamSnd_BigCombo3, + ePlayerStreamSnd_BigCombo4, + ePlayerStreamSnd_BigCombo5, + ePlayerStreamSnd_Lift1, + ePlayerStreamSnd_Exclaim1, + ePlayerStreamSnd_Exclaim2, + ePlayerStreamSnd_Exclaim3, + ePlayerStreamSnd_Exclaim4, + ePlayerStreamSnd_BeginBungee, + ePlayerStreamSnd_BungeeAttachComment = 0x61, + ePlayerStreamSnd_BungeeBeginDive, + ePlayerStreamSnd_BungeeDive1 = 0x62, + ePlayerStreamSnd_BungeeDive2, + ePlayerStreamSnd_BungeeEndDive = 0x63, + ePlayerStreamSnd_BungeeBeginDeath, + ePlayerStreamSnd_BungeeDeath1 = 0x64, + ePlayerStreamSnd_BungeeDeath2, + ePlayerStreamSnd_BungeeDeath3, + ePlayerStreamSnd_BungeeDeath4, + ePlayerStreamSnd_BungeeDeath5, + ePlayerStreamSnd_BungeeDeath6, + ePlayerStreamSnd_BungeeDeath7, + ePlayerStreamSnd_BungeeDeath8, + ePlayerStreamSnd_BungeeDeath9, + ePlayerStreamSnd_BungeeDeath10, + ePlayerStreamSnd_BungeeDeath11, + ePlayerStreamSnd_BungeeDeath12, + ePlayerStreamSnd_BungeeDeath13, + ePlayerStreamSnd_BungeeDeath14, + ePlayerStreamSnd_BungeeDeath15, + ePlayerStreamSnd_BungeeDeath16, + ePlayerStreamSnd_BungeeDeath17, + ePlayerStreamSnd_BungeeDeath18, + ePlayerStreamSnd_BungeeEndDeath = 0x75, + ePlayerStreamSnd_EndBungee = 0x75, + ePlayerStreamSnd_Total +}; + +struct zDelayedStreamSound +{ + _tagePlayerStreamSnd start; + _tagePlayerStreamSnd end; + F32 delay; +}; + +struct zPlayerSndTimer +{ + F32 timer; + F32 time; +}; + +// TODO: Why are there two of these enums with the same effect, should there be? +enum _zPlayerType +{ + ePlayer_SB, + ePlayer_Patrick, + ePlayer_Sandy, + ePlayer_MAXTYPES +}; + +enum _CurrentPlayer +{ + eCurrentPlayerSpongeBob, + eCurrentPlayerPatrick, + eCurrentPlayerSandy, + eCurrentPlayerCount +}; + +enum _zPlayerWallJumpState +{ + k_WALLJUMP_NOT, + k_WALLJUMP_LAUNCH, + k_WALLJUMP_FLIGHT, + k_WALLJUMP_LAND +}; + +struct zJumpParam +{ + F32 PeakHeight; + F32 TimeGravChange; + F32 TimeHold; + F32 ImpulseVel; +}; + +struct zLedgeGrabParams +{ + F32 animGrab; + F32 zdist; + xVec3 tranTable[60]; + S32 tranCount; + xEnt* optr; + xMat4x3 omat; + F32 y0det; + F32 dydet; + F32 r0det; + F32 drdet; + F32 thdet; + F32 rtime; + F32 ttime; + F32 tmr; + xVec3 spos; + xVec3 epos; + xVec3 tpos; + S32 nrays; + S32 rrand; + F32 startrot; + F32 endrot; +}; + +// Size: 0x448 +struct zPlayerSettings +{ + _zPlayerType pcType; + F32 MoveSpeed[6]; + F32 AnimSneak[3]; + F32 AnimWalk[3]; + F32 AnimRun[3]; + F32 JumpGravity; + F32 GravSmooth; + F32 FloatSpeed; + F32 ButtsmashSpeed; + zJumpParam Jump; + zJumpParam Bounce; + zJumpParam Spring; + zJumpParam Wall; + zJumpParam Double; + zJumpParam SlideDouble; + zJumpParam SlideJump; + F32 WallJumpVelocity; + zLedgeGrabParams ledge; + F32 spin_damp_xz; + F32 spin_damp_y; + U8 talk_anims; + U8 talk_filter_size; + U8 talk_filter[4]; +}; + +struct zPlayerCarryInfo +{ + xEnt* grabbed; + U32 grabbedModelID; + xMat4x3 spin; + xEnt* throwTarget; + xEnt* flyingToTarget; + F32 minDist; + F32 maxDist; + F32 minHeight; + F32 maxHeight; + F32 maxCosAngle; + F32 throwMinDist; + F32 throwMaxDist; + F32 throwMinHeight; + F32 throwMaxHeight; + F32 throwMaxStack; + F32 throwMaxCosAngle; + F32 throwTargetRotRate; + F32 targetRot; + U32 grabTarget; + xVec3 grabOffset; + F32 grabLerpMin; + F32 grabLerpMax; + F32 grabLerpLast; + U32 grabYclear; + F32 throwGravity; + F32 throwHeight; + F32 throwDistance; + F32 fruitFloorDecayMin; + F32 fruitFloorDecayMax; + F32 fruitFloorBounce; + F32 fruitFloorFriction; + F32 fruitCeilingBounce; + F32 fruitWallBounce; + F32 fruitLifetime; + xEnt* patLauncher; +}; + +struct zPlayerLassoInfo +{ + xEnt* target; // 0x1880 in globals + F32 dist; + U8 destroy; + U8 targetGuide; + F32 lassoRot; + xEnt* swingTarget; // 0x1890 + xEnt* releasedSwing; + F32 copterTime; + S32 canCopter; + zLasso lasso; + xAnimState* zeroAnim; +}; + +#define SHINY_MAX 99999 + +extern _CurrentPlayer gCurrentPlayer; +extern S32 gWaitingToAutoSave; + +void zEntPlayer_Load(xEnt*, xSerial*); + +S32 zEntPlayer_Damage(xBase* src, U32 damage); +S32 zEntPlayer_Damage(xBase* src, U32 damage, const xVec3* knockback); + +xAnimTable* zSandy_AnimTable(); +xAnimTable* zPatrick_AnimTable(); +xAnimTable* zEntPlayer_AnimTable(); +xAnimTable* zSpongeBobTongue_AnimTable(); + +void zEntPlayerExit(xEnt*); +void zEntPlayerPreReset(); +void zEntPlayerReset(xEnt* ent); +void zEntPlayer_LoadSounds(); +void zEntPlayer_UnloadSounds(); +void zEntPlayer_ShadowModelEnable(); +void zEntPlayer_ShadowModelDisable(); + +void zEntPlayerJumpStart(class xEnt* ent, class zJumpParam* jump); +S32 zEntPlayer_IsSneaking(); + +void zEntPlayer_setBoulderMode(U32 mode); +void zEntPlayer_GiveHealth(S32); +void zEntPlayer_GiveSpatula(S32); +void zEntPlayer_GivePatsSocksCurrentLevel(S32 quantity); + +void zEntPlayer_LoadCheckPoint(); + +void zEntPlayer_MinimalRender(zEnt* ent); +U8 zEntPlayer_MinimalUpdate(xEnt* ent, xScene* sc, F32 dt, xVec3& drive_motion); + +S32 zEntPlayer_MoveInfo(); + +void zEntPlayer_SNDPlay(_tagePlayerSnd player_snd, F32 delay); +void zEntPlayer_SNDPlayRandom(_tagePlayerSnd player_snd_start, _tagePlayerSnd player_snd_end, + F32 delay); +void zEntPlayer_SNDPlayStream(_tagePlayerStreamSnd player_snd); +void zEntPlayer_SNDPlayStream(_tagePlayerStreamSnd player_snd, U32 flags); +// Only plays sound if player's spatula count is between lower and upper +void zEntPlayer_SNDPlayStream(U32 lower, U32 upper, _tagePlayerStreamSnd player_snd, U32 flags); + +// Only plays sound if player's spatula count is between lower and upper +void zEntPlayer_SNDPlayStreamRandom(U32 lower, U32 upper, _tagePlayerStreamSnd player_snd_start, + _tagePlayerStreamSnd player_snd_end, F32 delay); +void zEntPlayer_SNDPlayStreamRandom(_tagePlayerStreamSnd player_snd_start, + _tagePlayerStreamSnd player_snd_end, F32 delay); + +void zEntPlayer_SNDSetVol(_tagePlayerSnd player_snd, F32 new_vol); +void zEntPlayer_SNDSetPitch(_tagePlayerSnd player_snd, F32 new_pitch); +void zEntPlayer_SNDStop(_tagePlayerSnd player_snd); + +void zEntPlayerSpeakStop(); + +void zEntPlayerControlOff(zControlOwner owner); +void zEntPlayerControlOn(zControlOwner owner); + +void zEntPlayer_StoreCheckPoint(xVec3* pos, F32 rot, U32 initCamID); +S32 load_talk_filter(U8* filter, xModelAssetParam* params, U32 params_size, S32 max_size); + +S32 zEntPlayer_DamageNPCKnockBack(xBase* src, U32 damage, xVec3* npcPos); + +S32 zEntPlayer_DamageNPCKnockBack(xBase* src, U32 damage, xVec3* npcPos); +void zEntPlayer_PredictPos(xVec3* pos, F32 timeIntoFuture, F32 leadFactor, S32 useTurn); + +#endif diff --git a/src/SB/Game/zEntPlayerAnimationTables.h b/src/SB/Game/zEntPlayerAnimationTables.h new file mode 100644 index 0000000..efea2b7 --- /dev/null +++ b/src/SB/Game/zEntPlayerAnimationTables.h @@ -0,0 +1,4 @@ +#include "xAnim.h" + +xAnimTable* zEntPlayer_BoulderVehicleAnimTable(); +xAnimTable* zEntPlayer_TreeDomeSBAnimTable(); diff --git a/src/SB/Game/zEntPlayerBungeeState.h b/src/SB/Game/zEntPlayerBungeeState.h new file mode 100644 index 0000000..ac1dfbb --- /dev/null +++ b/src/SB/Game/zEntPlayerBungeeState.h @@ -0,0 +1,74 @@ +#ifndef ZENTPLAYERBUNGEESTATE_H +#define ZENTPLAYERBUNGEESTATE_H + +#include "xDynAsset.h" +#include "xEnt.h" + +namespace bungee_state +{ + struct hook_asset : xDynAsset + { + U32 entity; + xVec3 center; + struct + { + F32 dist; + F32 travel_time; + } attach; + struct + { + F32 dist; + F32 free_fall_time; + F32 accel; + } detach; + struct + { + F32 unused1; + F32 unused2; + } turn; + struct + { + F32 frequency; + F32 gravity; + F32 dive; + F32 min_dist; + F32 max_dist; + F32 damp; + } vertical; + struct + { + F32 max_dist; + } horizontal; + struct + { + F32 rest_dist; + F32 view_angle; + F32 offset; + F32 offset_dir; + F32 turn_speed; + F32 vel_scale; + F32 roll_speed; + xVec3 unused1; + } camera; + struct + { + F32 hit_loss; + F32 damage_velocity; + F32 hit_velocity; + } collision; + }; + + struct hook_type : xBase + { + hook_asset* asset; + xEnt* ent; + }; + + void load(xBase& data, xDynAsset& asset, size_t); + bool active(); + bool landed(); + bool destroy(); + void insert_animations(xAnimTable& table); +} // namespace bungee_state + +#endif diff --git a/src/SB/Game/zEntPlayerOOBState.h b/src/SB/Game/zEntPlayerOOBState.h new file mode 100644 index 0000000..42469d4 --- /dev/null +++ b/src/SB/Game/zEntPlayerOOBState.h @@ -0,0 +1,190 @@ +#ifndef ZENTPLAYEROOBSTATE_H +#define ZENTPLAYEROOBSTATE_H + +#include "xserializer.h" +#include "zTalkBox.h" +#include "zTaskBox.h" + +extern bool oob_player_teleported; + +namespace oob_state +{ + bool render(); + void fx_render(); + void read_persistent(xSerial& s); + void write_persistent(xSerial& s); + + float oob_timer(); + + bool IsPlayerInControl(); + + struct callback + { + virtual void on_stop(); + }; + + enum state_enum + { + STATE_INVALID = -1, + BEGIN_STATE, + STATE_IN = 0, + STATE_OUT, + STATE_GRAB, + STATE_DROP, + END_STATE, + MAX_STATE = 0x4 + }; + + namespace + { + struct state_type + { + state_enum type; + + void start(); + void stop(); + }; + + struct in_state_type : state_type + { + void start(); + void stop(); + }; + + struct out_state_type : state_type + { + void start(); + void stop(); + }; + + struct grab_state_type : state_type + { + enum substate_enum + { + SS_INVALID = -1, + SS_REORIENT, + SS_BEGIN_WAIT, + SS_MOVING_IN, + SS_STOPPING, + SS_STOPPED, + SS_TUTORIAL, + SS_STARTING, + SS_MOVING_OUT, + SS_START_FADE_OUT, + SS_FADE_OUT, + MAX_SS + }; + + struct tutorial_callback : callback + { + grab_state_type& owner; + + void on_stop(); + }; + + tutorial_callback cb; + substate_enum move_substate; + substate_enum fade_substate; + xVec3 player_start; + float reorient_time; + float angle_delta; + float delay; + float fade_start_time; + float fade_time; + unsigned int scene_reset; + + // Todo: this is not in the DWARF, but is required for + // tutorial_callback::on_stop to match. Probably + // not correct. + char pad[4]; + + unsigned char finished_tutorial; + + substate_enum (*updatess)(grab_state_type&, xScene&, float&)[10]; + bool update_reorient(xScene&, F32&); + substate_enum update_stopping(xScene&, float&); + + void start(); + void stop(); + }; + + struct _class_9 + { + int flags; + state_type* state; + unsigned char control; + state_type* states[4]; + float out_time; + float max_out_time; + float reset_time; + xModelInstance* model; + xVec2 loc; + xVec2 dir; + float fade_alpha; + unsigned char render_hand; + unsigned char vertical; + float vel; + float accel; + ztalkbox* tutorial; + struct + { + float near_d; + float near_h; + float near_pitch; + float far_d; + float far_h; + float far_pitch; + xMat4x3* tgt_mat; + xMat4x3* tgt_omat; + } cam_data; + }; + + struct tagFixed + { + float out_time; + float reset_time; + float cam_dist; + float cam_height; + float cam_pitch; + float reorient_time; + char* hand_model; + xVec2 in_loc; + xVec2 out_loc; + struct + { + float in_wait_time; + float in_vel; + float in_stop_dist; + float out_wait_time; + float out_vel; + float out_start_dist; + float fade_start_time; + float fade_time; + } grab; + struct + { + float in_vel; + float in_stop_dist; + float out_wait_time; + float out_vel; + float out_start_dist; + float fade_start_time; + float fade_time; + } drop; + float hand_size_x; + float hand_size_y; + float hand_yaw; + float hand_pitch; + float hand_roll; + }; + } // namespace + + struct idiot_level_data + { + bool triggered; // offset 0x0, size 0x1 + U32 scene; // offset 0x4, size 0x4 + }; + +} // namespace oob_state + +#endif diff --git a/src/SB/Game/zEntSimpleObj.h b/src/SB/Game/zEntSimpleObj.h new file mode 100644 index 0000000..dd4d4fb --- /dev/null +++ b/src/SB/Game/zEntSimpleObj.h @@ -0,0 +1,57 @@ +#ifndef ZENTSIMPLEOBJ_H +#define ZENTSIMPLEOBJ_H + +#include "zEnt.h" +#include "xShadow.h" +#include "xString.h" +#include "xstransvc.h" +#include "iAnim.h" +#include "iModel.h" +#include "zFX.h" +#include "xEnt.h" +#include "zCollGeom.h" +#include "zGlobals.h" +#include "xSkyDome.h" +#include "zGoo.h" +#include "zShrapnel.h" +#include "xMath.h" +#include "zGame.h" +#include "zLOD.h" + +struct xSimpleObjAsset +{ + F32 animSpeed; + U32 initAnimState; + U8 collType; + U8 flags; +}; + +struct zEntSimpleObj : zEnt +{ + xSimpleObjAsset* sasset; // 0xD4 + U32 sflags; + void* anim; + F32 animTime; +}; + +struct zScene; + +extern void iModelAnimMatrices(RpAtomic*, xQuat*, xVec3*, RwMatrixTag*); + +void zEntSimpleObj_MgrInit(zEntSimpleObj** entList, U32 entCount); +void zEntSimpleObj_MgrUpdateRender(RpWorld* world, F32 dt); +void zEntSimpleObj_MgrCustomUpdate(zScene* s, F32 dt); +void zEntSimpleObj_MgrCustomRender(); +void zEntTrackPhysics_Init(void* ent, void* asset); +void zEntSimpleObj_Init(void* ent, void* asset); +void zEntSimpleObj_Render(xEnt* ent); +void zEntSimpleObj_Init(zEntSimpleObj* ent, xEntAsset* asset, bool arg2); +void zEntSimpleObj_Move(xEnt*, xScene*, F32, xEntFrame*); +void zEntSimpleObj_Setup(zEntSimpleObj* ent); +void zEntSimpleObj_Update(zEntSimpleObj* ent, xScene* scene, F32 dt); +void zEntSimpleObj_Save(zEntSimpleObj* ent, xSerial* s); +void zEntSimpleObj_Load(zEntSimpleObj* ent, xSerial* s); +void zEntSimpleObj_Reset(zEntSimpleObj* ent, xScene* scene); +s32 zEntSimpleObjEventCB(xBase* from, xBase* to, U32 toEvent, const F32* toParam, xBase* base3); + +#endif diff --git a/src/SB/Game/zEntTeleportBox.h b/src/SB/Game/zEntTeleportBox.h new file mode 100644 index 0000000..5a45793 --- /dev/null +++ b/src/SB/Game/zEntTeleportBox.h @@ -0,0 +1,50 @@ +#ifndef ZENTTELEPORTBOX_H +#define ZENTTELEPORTBOX_H + +#include "zEnt.h" +#include "xDynAsset.h" + +struct teleport_asset : xDynAsset +{ + U32 marker; + U32 opened; + U32 launchAngle; + U32 camAngle; + U32 targetID; +}; + +struct _zEntTeleportBox : zEnt +{ + U32 status; + teleport_asset* tasset; + zEnt* target; + U32 currPlrState; + U32 prevPlrState; + U32 jumpInAnim; + U32 jumpOutAnim; + U32 JOtoOpenAnim; + U32 JItoOpenAnim; + xBox trig[2]; + U32 currPlayerIn; + U32 prevPlayerIn; + U32 currPlayerNear; + U32 prevPlayerNear; + F32 lastdt; + F32 plrCtrlTimer; +}; + +void zEntTeleportBox_Init(xBase& data, xDynAsset& asset, size_t); +void zEntTeleportBox_Init(_zEntTeleportBox* ent, teleport_asset* asset); +void zEntTeleportBox_InitAll(); +void zEntTeleportBox_Setup(_zEntTeleportBox* ent); +void zEntTeleportBox_Update(xEnt* rawent, xScene* sc, F32 dt); +void zEntTeleportBox_Save(_zEntTeleportBox* ent, xSerial* s); +void zEntTeleportBox_Load(_zEntTeleportBox* ent, xSerial* s); +void zEntTeleportBox_Open(_zEntTeleportBox* ent); +void zEntTeleportBox_Close(_zEntTeleportBox* ent); +S32 zEntTeleportBox_isOpen(_zEntTeleportBox* ent); +S32 zEntTeleportBox_isClosed(_zEntTeleportBox* ent); +S32 zEntTeleportBox_playerIn(); +S32 zEntTeleportBoxEventCB(xBase*, xBase* to, U32 toEvent, const F32*, xBase*); + +#endif diff --git a/src/SB/Game/zEntTrigger.h b/src/SB/Game/zEntTrigger.h new file mode 100644 index 0000000..d6c4f82 --- /dev/null +++ b/src/SB/Game/zEntTrigger.h @@ -0,0 +1,37 @@ +#ifndef ZENTTRIGGER_H +#define ZENTTRIGGER_H + +#include "zEnt.h" + +struct zEntTrigger : zEnt +{ + xMat4x3 triggerMatrix; + xBox triggerBox; + U32 entered; +}; + +struct xTriggerAsset +{ + xVec3 p[4]; + xVec3 direction; + U32 flags; +}; + +#define ZENTTRIGGER_TYPE_BOX 0 +#define ZENTTRIGGER_TYPE_SPHERE 1 +#define ZENTTRIGGER_TYPE_VCYLINDER 2 +#define ZENTTRIGGER_TYPE_VSPHERE 3 +#define ZENTTRIGGER_TYPE_4 4 +#define ZENTTRIGGER_TYPE_5 5 + +void zEntTriggerInit(void* ent, void* asset); +void zEntTriggerInit(zEntTrigger* ent, xEntAsset* asset); +void zEntTriggerUpdate(zEntTrigger* trig, xScene*, F32); +S32 zEntTriggerEventCB(xBase*, xBase* to, U32 toEvent, const F32*, xBase*); +void zEntTriggerSave(zEntTrigger* ent, xSerial* s); +void zEntTriggerLoad(zEntTrigger* ent, xSerial* s); +void zEntTriggerReset(zEntTrigger* ent); +bool zEntTriggerHitsSphere(const zEntTrigger& trig, const xSphere& o, const xVec3& dir); +xTriggerAsset* zEntTriggerAsset(const zEntTrigger& trig); + +#endif diff --git a/src/SB/Game/zEnv.h b/src/SB/Game/zEnv.h new file mode 100644 index 0000000..6c21e77 --- /dev/null +++ b/src/SB/Game/zEnv.h @@ -0,0 +1,22 @@ +#ifndef ZENV_H +#define ZENV_H + +#include "xBase.h" +#include "xEnv.h" + +struct _zEnv : xBase +{ + xEnvAsset* easset; +}; + +void zEnvInit(void* env, void* easset); +void zEnvInit(_zEnv* env, xEnvAsset* easset); +void zEnvSetup(_zEnv* env); +void zEnvStartingCamera(_zEnv* env); +void zEnvRender(xEnv* env); +void zEnvSave(_zEnv* ent, xSerial* s); +void zEnvLoad(_zEnv* ent, xSerial* s); +void zEnvReset(_zEnv* env); +S32 zEnvEventCB(xBase*, xBase* to, U32 toEvent, const F32* toParam, xBase*); + +#endif diff --git a/src/SB/Game/zEvent.h b/src/SB/Game/zEvent.h new file mode 100644 index 0000000..eacf35c --- /dev/null +++ b/src/SB/Game/zEvent.h @@ -0,0 +1,11 @@ +#ifndef ZEVENT_H +#define ZEVENT_H + +#include "xEvent.h" + +#include +#include "xEvent.h" + +char* zEventName(U32 eventEnum); + +#endif diff --git a/src/SB/Game/zFX.h b/src/SB/Game/zFX.h new file mode 100644 index 0000000..35ff944 --- /dev/null +++ b/src/SB/Game/zFX.h @@ -0,0 +1,102 @@ +#ifndef ZFX_H +#define ZFX_H + +#include "xString.h" +#include "xEnt.h" +#include "xFX.h" + +#include +#include + +struct tweak_info; +struct tweak_callback; + +enum zFXGooState +{ + zFXGooStateNormal, + zFXGooStateFreezing, + zFXGooStateFrozen, + zFXGooStateMelting, + zFXGooStateInactive = 0xdeadbeef, + zFXGooStateForce32Bit = 0xffffffff +}; + +struct zFXGooInstance +{ + RpAtomic* atomic; + S32 freezeGroup; + xVec3* orig_verts; + RwRGBA* orig_colors; + F32 time; + F32 timer; + F32 w0; + F32 w2; + F32 warbc[4]; + F32 state_time[4]; + xVec3 center; + S32 padding; // Padding used for zFXGoo_SceneExit(). + zFXGooState state; + F32 warb_time; + F32 alpha; + F32 min; + F32 max; + xVec3* ref_parentPos; + xVec3 pos_parentOnFreeze; +}; + +extern U32 gFXSurfaceFlags; + +void on_spawn_bubble_wall(const tweak_info& tweak); +void zFX_SceneEnter(RpWorld* world); +void zFX_SceneExit(RpWorld* world); +void zFX_SceneReset(); +void zFXHammer(xVec3* pos); +void zFXPorterWave(const xVec3* pos); + +void zFXGooEnable(RpAtomic* atomic, S32 freezeGroup); + +void zFXGoo_SceneEnter(); +void zFXGoo_SceneReset(); +void zFXGoo_SceneExit(); + +void zFXGooEventSetWarb(xEnt* obj, const F32* param); +void zFXGooEventSetFreezeDuration(xEnt* obj, const F32 param); +void zFXGooEventMelt(xEnt* obj); + +void zFXGooUpdate(F32 dt); + +void zFXUpdate(F32 dt); + +S32 zFXGooIs(xEnt* obj, F32& depth, U32 playerCheck); + +void zFX_SpawnBubbleHit(const xVec3* pos, U32 num); +void zFX_SpawnBubbleWall(); +void zFX_SpawnBubbleSlam(const xVec3* pos, U32 num, F32 rang, F32 bvel, F32 rvel); + +void reset_poppers(); + +void reset_entrails(); + +static void init_poppers(); + +void update_poppers(F32 dt); + +void update_entrails(F32 dt); + +void xDebugAddTweak(const char* unk1, const char* unk2, const tweak_callback* unk3, void* unk4, + U32 unk5); + +xFXRing* zFXMuscleArmWave(const xVec3* pos); + +void zFX_SpawnBubbleTrail(const xVec3*, unsigned int); +void zFX_SpawnBubbleTrail(const xVec3* pos, unsigned int num, const xVec3* pos_rnd, + const xVec3* vel_rnd); +void zFX_SpawnBubbleTrail(const xVec3*, const xVec3*, const xVec3*, const xVec3*, unsigned int, + const xVec3*, const xVec3*, float); +void zFX_SpawnBubbleMenuTrail(const xVec3* pos, U32 num, const xVec3* pos_rnd, + const xVec3* vel_rnd); + +void zFXPopOn(xEnt& ent, F32 rate, F32 time); +void zFXPopOff(xEnt& ent, F32 rate, F32 time); + +#endif diff --git a/src/SB/Game/zFeet.h b/src/SB/Game/zFeet.h new file mode 100644 index 0000000..f73d030 --- /dev/null +++ b/src/SB/Game/zFeet.h @@ -0,0 +1,8 @@ +#ifndef ZFEET_H +#define ZFEET_H + +#include + +void zFeetGetIDs(); + +#endif \ No newline at end of file diff --git a/src/SB/Game/zGame.h b/src/SB/Game/zGame.h new file mode 100644 index 0000000..beed9a9 --- /dev/null +++ b/src/SB/Game/zGame.h @@ -0,0 +1,119 @@ +#ifndef ZGAME_H +#define ZGAME_H + +#include "zEntPlayer.h" +#include "zGameState.h" + +extern _CurrentPlayer gPendingPlayer; +extern F32 sTimeElapsed; +extern U32 gLevelChanged; +extern U32 startPressed; +extern U8 sHackSmoothedUpdate; +extern U32 gBusStopIsRunning; + +enum eGameWhereAmI +{ + eGameWhere_NA, + eGameWhere_InitStart, + eGameWhere_InitScene, + eGameWhere_InitCamera, + eGameWhere_InitMusic, + eGameWhere_InitOther, + eGameWhere_InitEnd, + eGameWhere_ExitStart, + eGameWhere_ExitRumble, + eGameWhere_ExitHUD, + eGameWhere_ExitSound, + eGameWhere_ExitCamera, + eGameWhere_ExitScene, + eGameWhere_ExitEnd, + eGameWhere_SetupScene, + eGameWhere_SetupZFX, + eGameWhere_SetupPlayer, + eGameWhere_SetupCamera, + eGameWhere_SetupScrFX, + eGameWhere_SetupSceneLoad, + eGameWhere_SetupMusicNotify, + eGameWhere_SetupHudSetup, + eGameWhere_SetupSkydome, + eGameWhere_SetupSceneEvents, + eGameWhere_SetupUpdateCull, + eGameWhere_SetupLOD, + eGameWhere_SetupExtras, + eGameWhere_SetupEnd, + eGameWhere_LoopStart, + eGameWhere_CutsceneFinish, + eGameWhere_LoopDo, + eGameWhere_LoopCalcTime, + eGameWhere_LoopPadUpdate, + eGameWhere_LoopTRCCheck, + eGameWhere_LoopCheats, + eGameWhere_LoopSceneUpdate, + eGameWhere_LoopPlayerUpdate, + eGameWhere_LoopSoundUpdate, + eGameWhere_LoopSFXWidgets, + eGameWhere_LoopHUDUpdate, + eGameWhere_LoopCameraUpdate, + eGameWhere_LoopCameraFXUpdate, + eGameWhere_LoopFlyToInterface, + eGameWhere_LoopCameraBegin, + eGameWhere_LoopSceneRender, + eGameWhere_LoopCameraEnd, + eGameWhere_LoopCameraShowRaster, + eGameWhere_LoopCameraFXEnd, + eGameWhere_LoopMusicUpdate, + eGameWhere_LoopUpdateMode, + eGameWhere_LoopContinue, + eGameWhere_LoopEndGameLoop, + eGameWhere_SaveLoop, + eGameWhere_ModeSceneSwitch, + eGameWhere_ModeCutsceneFinish, + eGameWhere_ModeGameExit, + eGameWhere_ModeGameInit, + eGameWhere_ModeGameSetup, + eGameWhere_ModeSwitchAutoSave, + eGameWhere_ModeSwitchCutsceneFinish, + eGameWhere_ModeStoreCheckpoint, + eGameWhere_LoseChanceReset, + eGameWhere_LoseChanceResetDone, + eGameWhere_TransitionBubbles, + eGameWhere_TransitionBegin, + eGameWhere_TransitionSnapShot, + eGameWhere_TransitionUpdate, + eGameWhere_TransitionPadUpdate, + eGameWhere_TransitionTRCCheck, + eGameWhere_TransitionCameraClear, + eGameWhere_TransitionCameraBegin, + eGameWhere_TransitionRenderBackground, + eGameWhere_TransitionSpawnBubbles, + eGameWhere_TransitionDrawEnd, + eGameWhere_TransitionUpdateBubbles, + eGameWhere_TransitionCameraEnd, + eGameWhere_TransitionCameraShowRaster, + eGameWhere_TransitionUpdateEnd, + eGameWhere_TransitionUIRender, + eGameWhere_TransitionUIRenderEnd, + eGameWhere_TransitionEnd, + eGameWhere_TransitionEnded, + eGameWhere_SetupPlayerInit, + eGameWhere_SetupPlayerCamera, + eGameWhere_SetupPlayerEnd +}; + +extern iTime sTimeCurrent; +extern iTime sTimeLast; +extern F32 sTimeElapsed; + +void zGameSetupPlayer(); +void xDrawBegin(); +void xDrawEnd(); +S32 zGameIsPaused(); +void zGameScreenTransitionBegin(); +void zGameScreenTransitionUpdate(F32 percentComplete, char* msg); +void zGameScreenTransitionUpdate(F32 percentComplete, char* msg, U8* rgba); +void zGameScreenTransitionEnd(); +void zGameModeSwitch(eGameMode modeNew); +void zGameStall(); +void zGameStats_Init(); + +#endif diff --git a/src/SB/Game/zGameExtras.h b/src/SB/Game/zGameExtras.h new file mode 100644 index 0000000..a97ac48 --- /dev/null +++ b/src/SB/Game/zGameExtras.h @@ -0,0 +1,89 @@ +#ifndef ZGAMEEXTRAS_H +#define ZGAMEEXTRAS_H + +#include "xserializer.h" + +struct EGGItem; + +struct EGGMisc +{ + S32 other; +}; + +struct EGGData +{ + union + { + S32 placeholder; + EGGMisc misc; + }; +}; + +struct EGGItemFuncs +{ + void (*fun_update)(F32, EGGItem*); + void (*fun_init)(EGGItem*); + void (*fun_reset)(EGGItem*); + void (*fun_done)(EGGItem*); +}; + +struct EGGItem +{ + S32 (*fun_check)(EGGItem*); + EGGItemFuncs* funcs; + S32 enabled; + EGGData eggdata; +}; + +struct GECheat +{ + U32* key_code; + void (*fun_cheat)(); + S32 flg_keep; + S32 flg_mode; +}; + +S32 zGameExtras_ExtrasFlags(); +void zGameExtras_MoDay(S32* month, S32* day); +void zGameExtras_SceneReset(); +void zGameExtras_SceneInit(); +void zGameExtras_SceneExit(); +void zGameExtras_SceneUpdate(F32 dt); +S32 zGameExtras_CheatFlags(); +void zGameExtras_NewGameReset(); +void zGameExtras_Save(xSerial* xser); +void zGameExtras_Load(xSerial* xser); +S32 TestCheat(U32* cheat); +S32 EGG_check_ExtrasFlags(EGGItem* egg); +void AddToCheatPressed(U32 param_1); +void GEC_CheatFlagAdd(S32 bit); +void GEC_CheatFlagToggle(S32 bit); +void GEC_dfltSound(); +void GEC_cb_AddShiny(); +void GEC_cb_AddSpatulas(); +void GEC_cb_BubbleBowl(); +void GEC_cb_CruiseBubble(); +void GEC_cb_MonsterGallery(); +void GEC_cb_UnlockArtTheatre(); +void GEC_cb_ChaChing(); +void GEC_cb_RestoreHealth(); +void GEC_cb_ExpertMode(); +void GEC_cb_ShrapBobMode(); +void GEC_cb_NoPantsMode(); +void GEC_cb_CruiseControl(); +void GEC_cb_SwapCCLR(); +void GEC_cb_SwapCCUD(); +void GEC_villSound(); +void GEC_cb_BigPlank(); +void GEC_cb_Medics(); +void GEC_cb_DogTrix(); +void GEC_cb_SmallPeep(); +void GEC_cb_SmallCostars(); +void GEC_cb_RichPeep(); +void GEC_cb_PanHandle(); +void zGame_HackGalleryInit(); +U32 zGame_HackIsGallery(); + +template T xUtil_choose(T const* list, S32 size, F32 const* c); + +#endif diff --git a/src/SB/Game/zGameState.h b/src/SB/Game/zGameState.h new file mode 100644 index 0000000..8cc518d --- /dev/null +++ b/src/SB/Game/zGameState.h @@ -0,0 +1,108 @@ +#ifndef ZGAMESTATE_H +#define ZGAMESTATE_H + +#include + +enum _GameOstrich +{ + eGameOstrich_Loading, + eGameOstrich_PlayingMovie, + eGameOstrich_InScene, + eGameOstrich_Total +}; + +enum eGameMode +{ + eGameMode_Boot, + eGameMode_Intro, + eGameMode_Title, + eGameMode_Start, + eGameMode_Load, + eGameMode_Options, + eGameMode_Save, + eGameMode_Pause, + eGameMode_Stall, + eGameMode_WorldMap, + eGameMode_MonsterGallery, + eGameMode_ConceptArtGallery, + eGameMode_Game, + eGameMode_Count +}; + +// These enums are fake, but they're likely similar to how they were in the original code +// Enums are way easier to use than a bunch of macros in this case +// (taken from bfbbpc) + +enum eGameState +{ + eGameState_FirstTime, + eGameState_Play, + eGameState_LoseChance, + eGameState_GameOver, + eGameState_GameStats, + eGameState_SceneSwitch, + eGameState_Dead, + eGameState_Exit, + eGameState_Count +}; + +enum ePauseState +{ + ePauseState_Pause, + ePauseState_Options, + ePauseState_Count +}; + +enum eSaveState +{ + eSaveState_SelectMemCard, + eSaveState_SelectSlot, + eSaveState_Saving, + eSaveState_Count +}; + +enum eOptionsState +{ + eOptionsState_Options, + eOptionsState_Count +}; + +enum eLoadState +{ + eLoadState_SelectMemCard, + eLoadState_SelectSlot, + eLoadState_Loading, + eLoadState_Count +}; + +enum eTitleState +{ + eTitleState_Start, + eTitleState_Attract, + eTitleState_Count +}; + +enum eIntroState +{ + eIntroState_Sony, + eIntroState_Publisher, + eIntroState_Developer, + eIntroState_License, + eIntroState_Count +}; + +extern S32 gGameState; +extern eGameMode gGameMode; +extern _GameOstrich gGameOstrich; + +S32 zGameStateGet(); +eGameMode zGameModeGet(); +_GameOstrich zGameGetOstrich(); +void zGameSetOstrich(_GameOstrich o); +S32 zGameStateFindEvent(U32* eventList, S32 eventCount, S32 targetMode, S32 targetEvent, + S32* new_mode, S32* new_state); +void zGameStateSwitchEvent(S32 event); +void zGameStateSwitch(S32 theNewState); +void zGameModeSwitch(eGameMode modeNew); + +#endif diff --git a/src/SB/Game/zGlobals.h b/src/SB/Game/zGlobals.h new file mode 100644 index 0000000..348052a --- /dev/null +++ b/src/SB/Game/zGlobals.h @@ -0,0 +1,327 @@ +#ifndef ZGLOBALS_H +#define ZGLOBALS_H + +#include "xGlobals.h" +#include "xShadowSimple.h" +#include "xEntDrive.h" + +#include "zEnt.h" +#include "zEntPlayer.h" +#include "zScene.h" + +struct zGlobalSettings +{ + // 0x874 in globals + U16 AnalogMin; + U16 AnalogMax; + F32 SundaeTime; + F32 SundaeMult; + U32 InitialShinyCount; + U32 InitialSpatulaCount; + + // 0x888 in globals + S32 ShinyValuePurple; + S32 ShinyValueBlue; + S32 ShinyValueGreen; + S32 ShinyValueYellow; + S32 ShinyValueRed; + + // 0x89C in globals + S32 ShinyValueCombo0; + S32 ShinyValueCombo1; + S32 ShinyValueCombo2; + S32 ShinyValueCombo3; + S32 ShinyValueCombo4; + S32 ShinyValueCombo5; + S32 ShinyValueCombo6; + S32 ShinyValueCombo7; + S32 ShinyValueCombo8; + S32 ShinyValueCombo9; + S32 ShinyValueCombo10; + S32 ShinyValueCombo11; + S32 ShinyValueCombo12; + S32 ShinyValueCombo13; + S32 ShinyValueCombo14; + S32 ShinyValueCombo15; + + // 0x8DC in globals + F32 ComboTimer; + U32 Initial_Specials; + U32 TakeDamage; + F32 DamageTimeHit; + F32 DamageTimeSurface; + F32 DamageTimeEGen; + F32 DamageSurfKnock; + F32 DamageGiveHealthKnock; + U32 CheatSpongeball; + U32 CheatPlayerSwitch; + U32 CheatAlwaysPortal; + U32 CheatFlyToggle; + U32 DisableForceConversation; + F32 StartSlideAngle; + F32 StopSlideAngle; + F32 RotMatchMaxAngle; + F32 RotMatchMatchTime; + F32 RotMatchRelaxTime; + F32 Gravity; + F32 BBashTime; + F32 BBashHeight; + F32 BBashDelay; + F32 BBashCVTime; + F32 BBounceSpeed; + F32 BSpinMinFrame; + F32 BSpinMaxFrame; + F32 BSpinRadius; + F32 SandyMeleeMinFrame; + F32 SandyMeleeMaxFrame; + F32 SandyMeleeRadius; + F32 BubbleBowlTimeDelay; + F32 BubbleBowlLaunchPosLeft; + F32 BubbleBowlLaunchPosUp; + F32 BubbleBowlLaunchPosAt; + F32 BubbleBowlLaunchVelLeft; + F32 BubbleBowlLaunchVelUp; + F32 BubbleBowlLaunchVelAt; + F32 BubbleBowlPercentIncrease; + F32 BubbleBowlMinSpeed; + F32 BubbleBowlMinRecoverTime; + F32 SlideAccelVelMin; + F32 SlideAccelVelMax; + F32 SlideAccelStart; + F32 SlideAccelEnd; + F32 SlideAccelPlayerFwd; + F32 SlideAccelPlayerBack; + F32 SlideAccelPlayerSide; + F32 SlideVelMaxStart; + F32 SlideVelMaxEnd; + F32 SlideVelMaxIncTime; + F32 SlideVelMaxIncAccel; + F32 SlideAirHoldTime; + F32 SlideAirSlowTime; + F32 SlideAirDblHoldTime; + F32 SlideAirDblSlowTime; + F32 SlideVelDblBoost; + U8 SlideApplyPhysics; + // 0x9BD in globals + U8 PowerUp[2]; + U8 InitialPowerUp[2]; +}; + +struct xEntBoulder; +struct zEntHangable; +struct zPlatform; +struct xSurface; +struct zAssetPickupTable; +struct zCutsceneMgr; + +struct zCheckPoint +{ + xVec3 pos; + F32 rot; + U32 initCamID; +}; + +#define LEVEL_COUNT 15 + +struct zPlayerGlobals +{ + // 0x6E0 in globals + zEnt ent; + + // 0x7B4 in globals + xEntShadow entShadow_embedded; + xShadowSimpleCache simpShadow_embedded; + + // 0x874 in globals + zGlobalSettings g; + + // 0x9C4 in globals + zPlayerSettings* s; + zPlayerSettings sb; + zPlayerSettings patrick; + zPlayerSettings sandy; + + // 0x16A0 in globals + xModelInstance* model_spongebob; + xModelInstance* model_patrick; + xModelInstance* model_sandy; + + // 0x16AC in globals + U32 Visible; + U32 Health; // 0x16b0 + S32 Speed; + F32 SpeedMult; + S32 Sneak; + S32 Teeter; + F32 SlipFadeTimer; + S32 Slide; + F32 SlideTimer; + S32 Stepping; + S32 JumpState; + S32 LastJumpState; + + // 0x16DC in globals + F32 JumpTimer; + F32 LookAroundTimer; + U32 LookAroundRand; + U32 LastProjectile; + F32 DecelRun; + F32 DecelRunSpeed; + F32 HotsauceTimer; + F32 LeanLerp; + F32 ScareTimer; + xBase* ScareSource; + F32 CowerTimer; + F32 DamageTimer; // 0x1708 + F32 SundaeTimer; + F32 ControlOffTimer; + F32 HelmetTimer; + + // Offset: 0x1718 + U32 WorldDisguise; + U32 Bounced; + F32 FallDeathTimer; + F32 HeadbuttVel; + F32 HeadbuttTimer; + U32 SpecialReceived; + xEnt* MountChimney; + F32 MountChimOldY; + U32 MaxHealth; + + // Offset: 0x173C + U32 DoMeleeCheck; + F32 VictoryTimer; + F32 BadGuyNearTimer; + F32 ForceSlipperyTimer; + F32 ForceSlipperyFriction; + F32 ShockRadius; + F32 ShockRadiusOld; + F32 Face_ScareTimer; + + // Offset: 0x175C + U32 Face_ScareRandom; + U32 Face_Event; + F32 Face_EventTimer; + F32 Face_PantTimer; + U32 Face_AnimSpecific; + U32 IdleRand; + F32 IdleMinorTimer; + F32 IdleMajorTimer; + F32 IdleSitTimer; + S32 Transparent; + zEnt* FireTarget; + U32 ControlOff; // 0x1788 + U32 ControlOnEvent; + + // Offset: 0x1790 + U32 AutoMoveSpeed; + F32 AutoMoveDist; + xVec3 AutoMoveTarget; + xBase* AutoMoveObject; + zEnt* Diggable; + F32 DigTimer; // 0x17AC + zPlayerCarryInfo carry; + zPlayerLassoInfo lassoInfo; + xModelTag BubbleWandTag[2]; + xModelInstance* model_wand; // 0x19E0 + xEntBoulder* bubblebowl; + F32 bbowlInitVel; // 0x19E8 + zEntHangable* HangFound; + zEntHangable* HangEnt; + zEntHangable* HangEntLast; + xVec3 HangPivot; + xVec3 HangVel; + F32 HangLength; + xVec3 HangStartPos; + F32 HangStartLerp; + xModelTag HangPawTag[4]; + F32 HangPawOffset; + F32 HangElapsed; + F32 Jump_CurrGravity; + F32 Jump_HoldTimer; + F32 Jump_ChangeTimer; + + // Offset: 0x1AB8 + S32 Jump_CanDouble; + S32 Jump_CanFloat; + S32 Jump_SpringboardStart; + zPlatform* Jump_Springboard; + S32 CanJump; + S32 CanBubbleSpin; + S32 CanBubbleBounce; + S32 CanBubbleBash; + + // Offset: 0x1AD8 in globals + S32 IsJumping; + S32 IsDJumping; + S32 IsBubbleSpinning; + S32 IsBubbleBouncing; + S32 IsBubbleBashing; + S32 IsBubbleBowling; + S32 WasDJumping; + S32 IsCoptering; + _zPlayerWallJumpState WallJumpState; + S32 cheat_mode; + + // Offset: 0x1B00 in globals + U32 Inv_Shiny; + U32 Inv_Spatula; + U32 Inv_PatsSock[LEVEL_COUNT]; + U32 Inv_PatsSock_Max[LEVEL_COUNT]; + + // Offset: 0x1B80 in globals + U32 Inv_PatsSock_CurrentLevel; + U32 Inv_LevelPickups[LEVEL_COUNT]; + U32 Inv_LevelPickups_CurrentLevel; + + // Offset: 0x1BC4 in globals + U32 Inv_PatsSock_Total; + xModelTag BubbleTag; + xEntDrive drv; + xSurface* floor_surf; + xVec3 floor_norm; + + // Offset: 0x1C74 in globals + S32 slope; + xCollis earc_coll; + xSphere head_sph; + xModelTag center_tag; + xModelTag head_tag; + U32 TongueFlags[2]; + xVec3 RootUp; + xVec3 RootUpTarget; + zCheckPoint cp; + U32 SlideTrackSliding; + U32 SlideTrackCount; + xEnt* SlideTrackEnt[111]; + U32 SlideNotGroundedSinceSlide; + xVec3 SlideTrackDir; + xVec3 SlideTrackVel; + F32 SlideTrackDecay; + F32 SlideTrackLean; + F32 SlideTrackLand; + U8 sb_model_indices[14]; + xModelInstance* sb_models[14]; + U32 currentPlayer; + xVec3 PredictRotate; + xVec3 PredictTranslate; + F32 PredictAngV; + xVec3 PredictCurrDir; + F32 PredictCurrVel; + F32 KnockBackTimer; + F32 KnockIntoAirTimer; // 0x1FB4 +}; + +struct zGlobals : xGlobals +{ + zPlayerGlobals player; + zAssetPickupTable* pickupTable; // 0x1FB8 + zCutsceneMgr* cmgr; // 0x1FBC + zScene* sceneCur; // 0x1FC0 + zScene* scenePreload; +}; + +extern zGlobals globals; +extern xGlobals* xglobals; + +#endif diff --git a/src/SB/Game/zGoo.h b/src/SB/Game/zGoo.h new file mode 100644 index 0000000..bcb8314 --- /dev/null +++ b/src/SB/Game/zGoo.h @@ -0,0 +1,18 @@ +#ifndef ZGOO_H +#define ZGOO_H + +#include "xEnt.h" + +#include +#include + +void zGooInit(S32 nobj); +void zGooExit(); +S32 zGooAdd(xEnt* obj, F32 depth, S32 freezeGroup); +S32 zGooIs(xEnt* obj, F32& depth, U32 playerCheck); +void zGooCollsBegin(); +void zGooCollsEnd(); +void zGooStopTide(); +void zGooMeltFinished(RpAtomic* atomic); + +#endif diff --git a/src/SB/Game/zGrid.h b/src/SB/Game/zGrid.h new file mode 100644 index 0000000..40b0645 --- /dev/null +++ b/src/SB/Game/zGrid.h @@ -0,0 +1,18 @@ +#ifndef ZGRID_H +#define ZGRID_H + +#include "zScene.h" + +#include "xEnt.h" +#include "xGrid.h" + +extern xGrid colls_grid; +extern xGrid colls_oso_grid; +extern xGrid npcs_grid; + +void zGridUpdateEnt(xEnt* ent); +void zGridExit(zScene*); +void zGridInit(zScene* s); +void zGridReset(zScene* s); + +#endif diff --git a/src/SB/Game/zGust.h b/src/SB/Game/zGust.h new file mode 100644 index 0000000..a30bf70 --- /dev/null +++ b/src/SB/Game/zGust.h @@ -0,0 +1,44 @@ +#ifndef ZGUST_H +#define ZGUST_H + +#include "xBase.h" +#include "xMath3.h" + +#include "zVolume.h" + +#include + +struct zGustAsset : xBaseAsset +{ + U32 flags; + U32 volumeID; + U32 effectID; + xVec3 vel; + F32 fade; + F32 partMod; +}; + +struct zGust : xBase +{ + U32 flags; + zGustAsset* asset; + zVolume* volume; + zVolume* fx_volume; + F32 debris_timer; +}; + +struct zGustData +{ + U32 gust_on; + zGust* g[4]; + float lerp[4]; +}; + +void zGustInit(); +void zGustSetup(); +zGust* zGustGetGust(U16 n); +void zGustSave(zGust* ent, xSerial* s); +void zGustLoad(zGust* ent, xSerial* s); +void zGustUpdateFX(F32 seconds); + +#endif diff --git a/src/SB/Game/zHud.h b/src/SB/Game/zHud.h new file mode 100644 index 0000000..89aa8a7 --- /dev/null +++ b/src/SB/Game/zHud.h @@ -0,0 +1,17 @@ +#ifndef ZHUD_H +#define ZHUD_H + +#include + +namespace zhud +{ + void render(); + void update(F32 dt); + void show(); + void hide(); + void init(); + void destroy(); + void setup(); +} // namespace zhud + +#endif diff --git a/src/SB/Game/zLOD.h b/src/SB/Game/zLOD.h new file mode 100644 index 0000000..3b85a82 --- /dev/null +++ b/src/SB/Game/zLOD.h @@ -0,0 +1,29 @@ +#ifndef ZLOD_H +#define ZLOD_H + +#include "xModelBucket.h" + +struct zLODTable +{ + xModelBucket** baseBucket; + F32 noRenderDist; + xModelBucket** lodBucket[3]; + F32 lodDist[3]; +}; + +struct zLODManager +{ + S32 numextra; + zLODTable* lod; + xModelInstance* model; + F32 adjustNoRenderDist; +}; + +void zLOD_Setup(); +void zLOD_Update(U32 percent_update); +zLODTable* zLOD_Get(xEnt* ent); +void AddToLODList(xModelInstance* model); +xEnt* AddToLODList(xEnt* ent); +void zLOD_UseCustomTable(xEnt* ent, zLODTable* lod); + +#endif diff --git a/src/SB/Game/zLasso.h b/src/SB/Game/zLasso.h new file mode 100644 index 0000000..f307d43 --- /dev/null +++ b/src/SB/Game/zLasso.h @@ -0,0 +1,59 @@ +#ifndef ZLASSO_H +#define ZLASSO_H + +#include "xMath3.h" +#include "xModel.h" +#include "xString.h" +#include "zEnt.h" + +struct zLasso +{ + U32 flags; + F32 secsTotal; + F32 secsLeft; + F32 stRadius; + F32 tgRadius; // 0x10 + F32 crRadius; + xVec3 stCenter; // 0x18 + xVec3 tgCenter; // 0x24 + xVec3 crCenter; // 0x30 + xVec3 stNormal; // 0x3C + xVec3 tgNormal; + xVec3 crNormal; // 0x48 + xVec3 honda; + F32 stSlack; + F32 stSlackDist; + F32 tgSlack; + F32 tgSlackDist; + F32 crSlack; + F32 currDist; + F32 lastDist; + xVec3 lastRefs[5]; + U8 reindex[5]; + xVec3 anchor; + xModelTag tag; + xModelInstance* model; +}; + +struct zLassoGuide +{ + xModelInstance* poly; + xAnimState* lassoAnim; + S32 vertMap[16]; +}; + +struct zLassoGuideList // Size: 0xE0 +{ + xEnt* target; + U32 numGuides; + zLassoGuide guide[3]; +}; + +void zLasso_scenePrepare(); +void zLasso_InitTimer(zLasso* lasso, F32 interpTime); +void zLasso_ResetTimer(zLasso* lasso, F32 interpTime); +void zLasso_AddGuide(xEnt* ent, xAnimState* lassoAnim, xModelInstance modelInst); +void zLasso_SetGuide(xEnt* ent, xAnimState* lassoAnim); +void zLasso_InterpToGuide(zLasso* lasso); + +#endif diff --git a/src/SB/Game/zLight.h b/src/SB/Game/zLight.h new file mode 100644 index 0000000..85429ec --- /dev/null +++ b/src/SB/Game/zLight.h @@ -0,0 +1,65 @@ +#ifndef ZLIGHT_H +#define ZLIGHT_H + +#include "zVolume.h" + +#include "xEnt.h" +#include "xEnv.h" +#include "iLight.h" + +// Size: 0x38 +struct zLightAsset : xBaseAsset +{ + // 0x8 + U8 lightType; + U8 lightEffect; + U8 lightPad[2]; + U32 lightFlags; + + // 0x10 + F32 lightColor[4]; + xVec3 lightDir; + + // 0x20 + F32 lightConeAngle; + xSphere lightSphere; + U32 attachID; +}; + +// Size: 0x64 +struct _zLight : xBase +{ + // 0x10 + U32 flags; + zLightAsset* tasset; + + // 0x18 + iLight light; + xBase* attached_to; + S32 true_idx; + F32* reg; + + // 0x60 + S32 effect_idx; +}; + +struct xScene; + +void zLightInit(void* b, void* tasset); +void zLightInit(xBase* b, zLightAsset* tasset); +void zLightResolveLinks(); +void zLightSave(_zLight* ent, xSerial* s); +void zLightLoad(_zLight* ent, xSerial* s); +void zLightAddLocalEnv(); +void zLightAddLocal(xEnt* ent); +void zLightRemoveLocalEnv(); +void zLightResetAll(xEnv* env); +void zLightReset(_zLight* param_1); +void zLightSetVolume(zVolume* vol); +void zLightDestroyAll(); +void zLightDestroy(_zLight* param_1); +void zLightUpdate(xBase* to, xScene*, F32 dt); +S32 zLightEventCB(xBase* param_1, xBase* to, U32 toEvent, const float* param_4, + xBase* param_5); + +#endif diff --git a/src/SB/Game/zLightEffect.h b/src/SB/Game/zLightEffect.h new file mode 100644 index 0000000..19f2a69 --- /dev/null +++ b/src/SB/Game/zLightEffect.h @@ -0,0 +1,29 @@ +#ifndef ZLIGHTEFFECT_H +#define ZLIGHTEFFECT_H + +#include "iLight.h" +#include "xBase.h" +#include "zLight.h" + +#include + +typedef void (*lightInitFunc)(_zLight*); + +void zLightEffectSet(_zLight* zlight, S32 idx); +void zLightOn(_zLight* zl, S32 on); +static F32 leGetRandom(); +void zLightEffectInitStrobe(_zLight* zlight); +void zLightEffectInitDim(_zLight* zlight); +void zLightEffectInitHalfDim(_zLight* zlight); +void zLightEffectInitRandomCol(_zLight* zlight); +void zLightEffectInitFlicker(_zLight* zlight); +static void EffectFlicker(_zLight* zlight, F32 seconds, F32 min, F32 rnd); +void zLightEffectFlicker(_zLight* zlight, F32 seconds); +void zLightEffectFlickerSlow(_zLight* zlight, F32 seconds); +void zLightEffectFlickerErratic(_zLight* zlight, F32 seconds); + +void zLightEffectInitCauldron(_zLight* zlight); +static F32 leBlendToCol(F32 f1, F32 f2, F32 f3); +void zLightEffectCauldron(_zLight* zlight, F32 seconds); + +#endif diff --git a/src/SB/Game/zLightning.h b/src/SB/Game/zLightning.h new file mode 100644 index 0000000..ad8fb7c --- /dev/null +++ b/src/SB/Game/zLightning.h @@ -0,0 +1,116 @@ +#ifndef ZLIGHTNING_H +#define ZLIGHTNING_H + +#include "xMath3.h" +#include "iColor.h" + +#include "zFX.h" + +struct _tagLightningAdd +{ + U32 type; + F32 setup_degrees; + F32 move_degrees; + F32 rot_radius; + xVec3* start; + xVec3* end; + S16 total_points; + S16 end_points; + F32 time; + F32 arc_height; + F32 thickness; + iColor_tag color; + F32 rand_radius; + U32 flags; + F32 zeus_normal_offset; + F32 zeus_back_offset; + F32 zeus_side_offset; +}; + +struct _tagLightningLine +{ + F32 unused; +}; + +struct _tagLightningRot +{ + F32 deg[16]; + F32 degrees; + F32 height; +}; + +struct _tagLightningZeus +{ + F32 normal_offset; + F32 back_offset; + F32 side_offset; +}; + +struct zLightning +{ + U32 type; + U32 flags; + union + { + struct + { + xVec3 base_point[16]; + xVec3 point[16]; + S16 total_points; + S16 end_points; + F32 arc_height; + xVec3 arc_normal; + F32 thickness[16]; + union + { + _tagLightningLine line; + _tagLightningRot rot; + _tagLightningZeus zeus; + }; + F32 rand_radius; + } legacy; + struct + { + xVec3 endPoint[2]; + xVec3 direction; + F32 length; + F32 scale; + F32 width; + F32 endParam[2]; + F32 endVel[2]; + F32 paramSpan[2]; + F32 arc_height; + xVec3 arc_normal; + } func; + }; + iColor_tag color; + F32 time_left; + F32 time_total; +}; + +void lightningTweakChangeType(tweak_info& t); +void lightningTweakStart(tweak_info& t); +void zLightningInit(); +zLightning* zLightningAdd(_tagLightningAdd* add); +void UpdateLightning(zLightning* l, F32 seconds); +void zLightningUpdate(F32 seconds); +void zLightningFunc_Render(zLightning* l); +void zLightningShow(zLightning* l, S32 show); +void zLightningKill(zLightning* l); +void RenderLightning(zLightning* l); +void zLightningRender(); +void zLightningModifyEndpoints(zLightning* l, xVec3* start, xVec3* end); +void xDebugAddTweak(char* name, U8* property, U8 param_3, U8 param_4, tweak_callback* callback, + void* param_6, U32 param_7); +void xDebugAddFlagTweak(char* name, U32* property, U32 param_3, tweak_callback* callback, + void* param_5, U32 param_6); +void xDebugAddSelectTweak(char* name, U32* param_2, char** param_3, U32* param_4, U32 param_5, + tweak_callback* callback, void* param_7, U32 param_8); +void xDebugAddTweak(char* name, S16* property, S16 param_3, S16 param_4, tweak_callback* callback, + void* param_6, U32 param_7); + +void zLightningInit(); +void zLightningUpdate(F32 seconds); +void zLightningRender(); + +#endif diff --git a/src/SB/Game/zMain.h b/src/SB/Game/zMain.h new file mode 100644 index 0000000..8d04588 --- /dev/null +++ b/src/SB/Game/zMain.h @@ -0,0 +1,4 @@ +#ifndef ZMAIN_H +#define ZMAIN_H + +#endif \ No newline at end of file diff --git a/src/SB/Game/zMenu.h b/src/SB/Game/zMenu.h new file mode 100644 index 0000000..fd444b7 --- /dev/null +++ b/src/SB/Game/zMenu.h @@ -0,0 +1,18 @@ +#ifndef ZMENU_H +#define ZMENU_H + +#include + +bool menu_fmv_played; + +U32 zMenuUpdateMode(); +U32 zMenuIsPaused(); +S32 zMenuLoopContinue(); +void zMenuFirstBootSet(U32 isFirstBoot); +void zMenuFMVPlay(char*, U32, F32, bool, bool); +bool zMenuCardCheckStartup(S32* bytesNeeded, S32* availOnDisk, S32* neededFiles); +S32 zMenuGetBadCard(); +U32 zMenuGetCorruptFiles(char name[][64]); +S32 zMenuIsFirstBoot(); + +#endif diff --git a/src/SB/Game/zMovePoint.cpp b/src/SB/Game/zMovePoint.cpp new file mode 100644 index 0000000..bc06743 --- /dev/null +++ b/src/SB/Game/zMovePoint.cpp @@ -0,0 +1,142 @@ +#include "zMovePoint.h" +#include "zNPCSupplement.h" + +#include "xEvent.h" + +#include + +// PORTED DIRECTLY FROM BFBB + +extern zMovePoint* g_mvpt_list; +extern S32 g_mvpt_cnt; +extern F32 lbl_803CDD40; +extern F32 lbl_803CDD44; + +// Random load word at the end of the function for some reason. +zMovePoint* zMovePoint_GetMemPool(S32 cnt) +{ + /*if (cnt != 0) + { + g_mvpt_list = (zMovePoint*)xMemAllocSize(cnt * sizeof(zMovePoint)); + } + else + { + g_mvpt_list = NULL; + } + g_mvpt_cnt = cnt; + return g_mvpt_list;*/ + + g_mvpt_list = cnt ? (zMovePoint*)xMemAllocSize(cnt * sizeof(zMovePoint)) : NULL; + g_mvpt_cnt = cnt; + return g_mvpt_list; +} + +void zMovePointInit(zMovePoint* m, xMovePointAsset* asset) +{ + xMovePointInit((xMovePoint*)m, asset); + m->eventFunc = zMovePointEventCB; + if (m->linkCount) + { + m->link = + (xLinkAsset*)(((U32*)asset + sizeof(xMovePointAsset) / 4) + (U32)asset->numPoints); + } + else + { + m->link = NULL; + } +} + +zMovePoint* zMovePoint_GetInst(S32 n) +{ + return &g_mvpt_list[n]; +} + +void zMovePointSetup(zMovePoint* mvpt, zScene* scn) +{ + xMovePointSetup((xMovePoint*)mvpt, (xScene*)scn); +} + +zMovePoint* zMovePoint_From_xAssetID(U32 aid) +{ + zMovePoint* pnt = g_mvpt_list; + zMovePoint* ret = NULL; + for (S32 i = g_mvpt_cnt; i > 0; i--) + { + if (pnt->asset->id == aid) + { + ret = pnt; + break; + } + pnt++; + } + return ret; +} + +void zMovePointSave(zMovePoint* ent, xSerial* s) +{ + xMovePointSave((xMovePoint*)ent, s); +} + +void zMovePointLoad(zMovePoint* ent, xSerial* s) +{ + xMovePointLoad((xMovePoint*)ent, s); +} + +void zMovePointReset(zMovePoint* m) +{ + xMovePointReset((xMovePoint*)m); +} + +S32 zMovePointEventCB(xBase* from, xBase* to, U32 toEvent, const F32* toParam, xBase* b3) +{ + switch (toEvent) + { + case eEventOn: + ((zMovePoint*)to)->on = true; + break; + case eEventOff: + ((zMovePoint*)to)->on = false; + break; + case eEventArrive: + break; + case eEventReset: + zMovePointReset((zMovePoint*)to); + break; + case eEventMakeASplash: + xVec3* pos = ((zMovePoint*)to)->pos; + if (pos != NULL) + { + if (*toParam < lbl_803CDD40) + { + NPCC_MakeASplash(pos, lbl_803CDD44); + } + else + { + NPCC_MakeASplash(pos, *toParam); + } + } + break; + } + return eEventEnable; +} + +F32 zMovePointGetNext(const zMovePoint* current, const zMovePoint* prev, zMovePoint** next, + xVec3* hdng) +{ + return xMovePointGetNext((xMovePoint*)current, (xMovePoint*)prev, (xMovePoint**)next, hdng); +} + +xVec3* zMovePointGetPos(const zMovePoint* m) +{ + return xMovePointGetPos((xMovePoint*)m); +} + +F32 zMovePointGetDelay(const zMovePoint* m) +{ + return xMovePointGetDelay((xMovePoint*)m); +} + +F32 xMovePointGetDelay(const xMovePoint* m) +{ + return m->delay; +} diff --git a/src/SB/Game/zMovePoint.h b/src/SB/Game/zMovePoint.h new file mode 100644 index 0000000..fb58329 --- /dev/null +++ b/src/SB/Game/zMovePoint.h @@ -0,0 +1,43 @@ +#ifndef ZMOVEPOINT_H +#define ZMOVEPOINT_H + +#include "xMovePoint.h" + +#include "zScene.h" + +#include + +struct zMovePoint : xMovePoint +{ + F32 RadiusZone() + { + return asset->zoneRadius; + } + F32 Delay() + { + return asset->delay; + } + xVec3* PosGet() + { + return pos; + } + U32 NumNodes(); + U8 IsOn(); +}; + +zMovePoint* zMovePoint_GetMemPool(S32 cnt); +void zMovePointInit(zMovePoint* m, xMovePointAsset* asset); +zMovePoint* zMovePoint_GetInst(S32 n); +void zMovePointSetup(zMovePoint* mvpt, zScene* scn); +zMovePoint* zMovePoint_From_xAssetID(U32 aid); +void zMovePointSave(zMovePoint* ent, xSerial* s); +void zMovePointLoad(zMovePoint* ent, xSerial* s); +void zMovePointReset(zMovePoint* m); +S32 zMovePointEventCB(xBase* from, xBase* to, U32 toEvent, const F32* toParam, xBase* b3); +F32 zMovePointGetNext(const zMovePoint* current, const zMovePoint* prev, zMovePoint** next, + xVec3* hdng); +xVec3* zMovePointGetPos(const zMovePoint* m); +F32 zMovePointGetDelay(const zMovePoint* m); +F32 xMovePointGetDelay(const xMovePoint* m); + +#endif diff --git a/src/SB/Game/zMusic.cpp b/src/SB/Game/zMusic.cpp new file mode 100644 index 0000000..3f6e499 --- /dev/null +++ b/src/SB/Game/zMusic.cpp @@ -0,0 +1,495 @@ +#include +#include "zMusic.h" +#include "xSnd.h" +#include "xMath.h" +#include "xString.h" +#include "zGlobals.h" +#include "zGameState.h" +#include "zScene.h" +#include + +#define TRACK_COUNT 2 + +static U32 sMusicSoundID[24][TRACK_COUNT]; +static zMusicTrackInfo sMusicTrack[TRACK_COUNT]; +static zVolumeInfo volume; + +// clang-format off +static zMusicSituation sMusicInfo[8] = { + { 0, 0, 0, 0.0f, 0.0f, 0.0f, 0, 0, 0, 0, 0}, + { 1, 0, 0, 0.0f, 1.0f, 0.0f, 0, 0, 1, 0, 0}, + { 0, 0, 0, 0.0f, 0.0f, 0.0f, 0, 0, 2, 0, 0}, + { 0, 0, 0, 0.0f, 2.0f, 0.0f, 0, 0, 3, 0, 0}, + { 0, 0, 0, 0.0f, 1.0f, 0.0f, 0, 0, 4, 0, 0}, + { 0, 0, 0, 0.0f, 0.0f, 0.0f, 0, 0, 5, 0, 0}, + { 1, 0, 0, 0.0f, 0.0f, 0.0f, 0, 0, 6, 0, 0}, + { 0, 0, 0, 0.0f, 0.0f, 0.0f, 0, 0, 7, 0, 0}, +}; +// clang-format on + +static U32 sMusicPaused; +static zMusicSituation* sMusicQueueData[TRACK_COUNT]; + +static S32 sMusicLastEnum[TRACK_COUNT] = { 0.0f, 0.0f }; +static F32 sMusicTimer[TRACK_COUNT] = { 0.0f, 0.0f }; + +extern eGameMode gGameMode; +extern zGlobals globals; + +static const F32 minDelay = 0.001f; + +static void volume_update(F32 vol); + +static void volume_reset() +{ + volume.cur = 0.0f; + volume.end = 1.0f; + volume.inc = 0.0f; + + memset(volume.adjusted, 0, sizeof(volume.adjusted)); +} + +// Reset both music tracks to their default volume. +void zMusicRefreshVolume() +{ + for (S32 i = 0; i < 2; i++) + { + zMusicTrackInfo* track = &sMusicTrack[i]; + if (track->snd_id != 0) + { + // Only reset volume if the sound ID is not blank. + xSndSetVol(track->snd_id, volume.cur); + } + } +} + +void zMusicInit() +{ + sMusicPaused = 0; + + for (int i = 0; i < sizeof(sMusicTrack) / sizeof(sMusicTrack[0]); i++) + { + sMusicTrack[i].snd_id = 0; + sMusicTrack[i].loop = 0; + sMusicTrack[i].situation = 0; + } + + sMusicSoundID[0][0] = xStrHash("music_00_hb_44"); + sMusicSoundID[0][1] = 1; + sMusicSoundID[1][0] = xStrHash("music_01_jf_44"); + sMusicSoundID[1][1] = 1; + sMusicSoundID[2][0] = xStrHash("music_02_bb_44"); + sMusicSoundID[2][1] = 1; + sMusicSoundID[3][0] = xStrHash("music_03_gl_44"); + sMusicSoundID[3][1] = 1; + sMusicSoundID[4][0] = xStrHash("music_04_b1_44"); + sMusicSoundID[4][1] = 1; + sMusicSoundID[5][0] = xStrHash("music_05_rb_44"); + sMusicSoundID[5][1] = 1; + sMusicSoundID[6][0] = xStrHash("music_06_bc_44"); + sMusicSoundID[6][1] = 1; + sMusicSoundID[7][0] = xStrHash("music_07_sm_44"); + sMusicSoundID[7][1] = 1; + sMusicSoundID[8][0] = xStrHash("music_08_b2_44"); + sMusicSoundID[8][1] = 1; + sMusicSoundID[9][0] = xStrHash("music_09_kf_44"); + sMusicSoundID[9][1] = 1; + sMusicSoundID[10][0] = xStrHash("music_10_gy_44"); + sMusicSoundID[10][1] = 1; + sMusicSoundID[11][0] = xStrHash("music_11_db_44"); + sMusicSoundID[11][1] = 1; + sMusicSoundID[12][0] = xStrHash("music_12_b3_44"); + sMusicSoundID[12][1] = 1; + sMusicSoundID[13][0] = xStrHash("music_13_mnu3_44"); + sMusicSoundID[13][1] = 1; + sMusicSoundID[14][0] = xStrHash("music_14_mnu4_44"); + sMusicSoundID[14][1] = 1; + sMusicSoundID[15][0] = xStrHash("music_15_slide_44"); + sMusicSoundID[15][1] = 1; + sMusicSoundID[16][0] = xStrHash("music_16_ambush_44"); + sMusicSoundID[16][1] = 1; + sMusicSoundID[17][0] = xStrHash("music_17_subboss_44"); + sMusicSoundID[17][1] = 1; + sMusicSoundID[18][0] = xStrHash("music_18_skatepark_44"); + sMusicSoundID[18][1] = 1; + sMusicSoundID[21][0] = xStrHash("music_21_Calliope1"); + sMusicSoundID[21][1] = 1; + sMusicSoundID[22][0] = xStrHash("music_22_Calliope2"); + sMusicSoundID[22][1] = 1; + sMusicSoundID[23][0] = xStrHash("music_23_Calliope3"); + sMusicSoundID[23][1] = 1; + + for (int i = 0; i < sizeof(sMusicInfo) / sizeof(sMusicInfo[0]); i++) + { + sMusicInfo[i].elapsedTime = sMusicInfo[i].delay; + sMusicInfo[i].count = 0; + } + volume_reset(); +} + +static S32 getCurrLevelMusicEnum() +{ + S32 snd_enum; + + switch (zSceneGetLevelIndex()) + { + case 0: + snd_enum = 0; + break; + case 1: + snd_enum = 1; + break; + case 2: + snd_enum = 2; + break; + case 3: + snd_enum = 3; + break; + case 4: + snd_enum = 4; + break; + case 5: + snd_enum = 5; + break; + case 6: + snd_enum = 6; + break; + case 7: + snd_enum = 0; + break; + case 8: + snd_enum = 8; + break; + case 9: + snd_enum = 9; + break; + case 10: + snd_enum = 10; + break; + case 11: + snd_enum = 11; + break; + case 12: + snd_enum = 12; + break; + case 13: + snd_enum = 2; + break; + case 14: + snd_enum = 13; + break; + default: + snd_enum = (xrand() % 23) + 1; + if (24 <= snd_enum) + { + snd_enum--; + } + if (((snd_enum == 4) || (snd_enum == 7)) || (snd_enum == 8)) + { + snd_enum = 5; + } + break; + } + + return snd_enum; +} + +static S32 zMusicDo(S32 track) +{ + S32 snd_enum; + F32 vol; + F32 pitch; + + vol = 1.0f; + if (globals.NoMusic != FALSE) + { + return 0; + } + + snd_enum = xrand() % 0x18; + switch (sMusicQueueData[track]->situation) + { + case 3: + case 5: + snd_enum = sMusicQueueData[track]->music_enum; + break; + case 6: + snd_enum = sMusicQueueData[track]->music_enum; + break; + case 0: + snd_enum = getCurrLevelMusicEnum(); + break; + case 7: + snd_enum = sMusicLastEnum[0]; + break; + case 2: + snd_enum = 1; + break; + case 4: + break; + default: + snd_enum = xrand() % 0x18; + } + + if (sMusicTrack[track].snd_id != 0) + { + xSndStop(sMusicTrack[track].snd_id); + sMusicTrack[track].snd_id = 0; + } + + sMusicTrack[track].loop = sMusicSoundID[snd_enum][1]; + + pitch = 0.0f; + if (snd_enum == 9 && globals.scenePreload->sceneID == 'KF04') + { + pitch = -12.0f; + vol *= 0.7f; + } + + // FIXME: loop operator + U32 snd_id = sMusicSoundID[snd_enum][track]; + sMusicTrack[track].snd_id = + xSndPlay(snd_id, vol, pitch, 0xFF, sMusicTrack[track].loop, 0, SND_CAT_MUSIC, 0.0f); + + // FIXME: This isn't quite right + if (sMusicTrack[track].snd_id != 0) + { + sMusicTrack[track].snd_id = snd_id; + sMusicTrack[track].assetID = sMusicSoundID[snd_enum][track]; + sMusicTrack[track].lastVol = vol; + if (sMusicQueueData[track] != NULL) + { + sMusicQueueData[track]->sndid = snd_id; + sMusicQueueData[track]->elapsedTime = 0.0f; + sMusicQueueData[track]->count += 1; + sMusicQueueData[track] = NULL; + } + sMusicLastEnum[track] = snd_enum; + return 1; + } + + return 0; +} + +void zMusicNotify(S32 situation) +{ + zMusicSituation* s; + S32 track; + + if (sMusicPaused) + { + return; + } + + s = &sMusicInfo[situation]; + + if (s->countMax != NULL && s->count >= s->countMax) + { + return; + } + + if (s->delay > s->elapsedTime) + { + return; + } + + track = s->track; + sMusicQueueData[track] = &sMusicInfo[situation]; + sMusicTimer[track] = s->punchDelay; + sMusicQueueData[track]->game_state = (gGameMode == eGameMode_Game); +} + +void zMusicNotifyEvent(const F32* toParam, xBase* base) +{ + S32 track; + zMusicSituation* s; + size_t musicInfoIdx; + S32 musicEnum; + + if (sMusicPaused) + { + return; + } + + if (toParam[1] == 0.0f) + { + musicInfoIdx = 5; + } + else + { + musicInfoIdx = 6; + } + musicEnum = toParam[0]; + s = &sMusicInfo[musicInfoIdx]; + track = s->track; + + // FIXME: Body (and maybe conditions) aren't quite right + if (musicEnum != sMusicLastEnum[track] && sMusicQueueData[track] == NULL && + (s->countMax == 0 || s->count < s->countMax) && !(s->delay > s->elapsedTime)) + { + sMusicTimer[track] = s->punchDelay; + sMusicQueueData[track] = s; + sMusicQueueData[track]->game_state = (gGameMode == eGameMode_Game); + sMusicQueueData[track]->music_enum = musicEnum; + } +} + +void zMusicUpdate(F32 dt) +{ + S32 i; + if (sMusicPaused == FALSE) + { + for (i = 0; i < 8; i++) + { + sMusicInfo[i].elapsedTime += dt; + } + + for (i = 0; i < TRACK_COUNT; i++) + { + // FIXME: This conditional isn't quite right + if ((sMusicTimer[i] != 0.0f || sMusicQueueData[i] != NULL) && + gGameMode & 0xC == sMusicQueueData[i]->game_state) + { + if (sMusicTimer[i] < 0.0f) + { + sMusicTimer[i] -= dt; + if (sMusicTimer[i] < 0.0f) + { + sMusicTimer[i] = 0.0f; + } + } + + if (sMusicTimer[i] == 0.0f && sMusicQueueData[i] != NULL) + { + zMusicDo(i); + } + } + } + + volume_update(dt); + } +} + +static void volume_update(F32 vol) +{ + F32 oldVol = volume.cur; + if (volume.inc >= 1e-5f && volume.inc <= -1e-5f) + { + volume.cur = volume.end; + } + else + { + volume.cur = volume.inc * vol + volume.cur; + } + + if ((volume.inc < 0.0f && volume.cur <= volume.end) || + (!(volume.inc < 0.0f) && volume.cur >= volume.end)) + { + volume.end = volume.cur; + volume.inc = 0.0f; + } + + for (S32 trackIdx = 0; trackIdx < TRACK_COUNT; trackIdx++) + { + if (sMusicTrack[trackIdx].snd_id != 0 && + (oldVol != volume.cur || volume.adjusted[trackIdx] != sMusicTrack[trackIdx].snd_id)) + { + F32 setVol = volume.cur * sMusicTrack[trackIdx].lastVol; + if (setVol > 1.0f) + { + setVol = 1.0f; + } + + xSndSetVol(sMusicTrack[trackIdx].snd_id, setVol); + volume.adjusted[trackIdx] = sMusicTrack[trackIdx].snd_id; + } + } +} + +// Stop all tracks and set them to null. +void zMusicKill() +{ + for (S32 i = 0; i < 2; i++) + { + zMusicTrackInfo* track = &sMusicTrack[i]; + if (track->snd_id != 0) + { + xSndStop(track->snd_id); + track->snd_id = 0; + track->loop = 0; + track->situation = NULL; + } + } +} + +// Pause music by stopping any non-null tracks. +void zMusicPause() +{ + if (sMusicPaused == 0) + { + for (S32 i = 0; i < 2; i++) + { + zMusicTrackInfo* track = &sMusicTrack[i]; + if (track->snd_id != 0) + { + xSndStop(track->snd_id); + } + } + sMusicPaused = 1; + } +} + +void zMusicUnpause(S32 kill) +{ + if (sMusicPaused == 0) + { + return; + } + + for (S32 i = 0; i < 2; i++) + { + zMusicTrackInfo* track = &sMusicTrack[i]; + if (track->snd_id == 0) + { + continue; + } + + if (kill != 0) + { + track->snd_id = 0; + } + else + { + S32 flags = i * 0x800; + flags |= ((track->loop != 0) ? 0x8000 : 0) | 0x10000; + flags |= 0x20000; + track->snd_id = + xSndPlay(track->assetID, track->lastVol, 0.0f, 0xff, flags, 0, SND_CAT_MUSIC, 0.0f); + } + } + + sMusicPaused = 0; +} + +// This version of it matches 33%. It's also functionally incorrect. +void zMusicSetVolume(float vol, float delay) +{ + volume.cur = vol; // This makes it introduce the "frsp" instruction. + volume.inc = vol - volume.cur; + + if (delay > + minDelay) // Doing the if statement likes this makes it generate the "blelr" instruction + { + volume.inc = vol / delay; + } +} + +void zMusicReset() +{ + S32 currMusic; + currMusic = getCurrLevelMusicEnum(); + if (sMusicLastEnum[0] != currMusic) + { + zMusicNotify(0); + } +} diff --git a/src/SB/Game/zMusic.h b/src/SB/Game/zMusic.h new file mode 100644 index 0000000..fd3790c --- /dev/null +++ b/src/SB/Game/zMusic.h @@ -0,0 +1,50 @@ +#ifndef ZMUSIC_H +#define ZMUSIC_H + +#include +#include "xBase.h" + +struct zMusicSituation +{ + S32 track; + U32 priority; + U32 countMax; + F32 delay; + F32 punchDelay; + F32 elapsedTime; + U32 count; + U32 sndid; + S32 situation; + S32 music_enum; + S32 game_state; +}; + +struct zVolumeInfo +{ + F32 cur; + F32 end; + F32 inc; + U32 adjusted[2]; +}; + +struct zMusicTrackInfo +{ + U32 snd_id; + U32 loop; + zMusicSituation* situation; + U32 assetID; + F32 lastVol; +}; + +void zMusicRefreshVolume(); +void zMusicNotify(S32 situation); +void zMusicNotifyEvent(const F32* toParam, xBase* base); +void zMusicSetVolume(F32 vol, F32 delay); +void zMusicKill(); +void zMusicPause(); +void zMusicUnpause(S32 kill); +void zMusicReset(); +void zMusicInit(); +void zMusicUpdate(F32 dt); + +#endif diff --git a/src/SB/Game/zNMECommon.cpp b/src/SB/Game/zNMECommon.cpp new file mode 100644 index 0000000..c11fe9c --- /dev/null +++ b/src/SB/Game/zNMECommon.cpp @@ -0,0 +1,490 @@ +#include "zNPCTypeCommon.h" + +#include +#include + +#include "zEntCruiseBubble.h" +#include "zEntTeleportBox.h" +#include "zGlobals.h" +#include "zNPCTypes.h" +#include "zNPCSndTable.h" +#include "zNPCSupport.h" +#include "zNPCFXCinematic.h" + +#include "iModel.h" +#include "iSnd.h" + +#include "xString.h" +#include "xDebug.h" + +extern char zNPCTypeCommon_strings[]; +extern char* g_strz_lassanim[3]; +extern S32 g_hash_lassanim[3]; +extern volatile S32 g_skipDescent; +extern NPCConfig* g_ncfghead; +extern NPCSndTrax g_sndTrax_General[]; +extern F32 lbl_803CE4C0; +extern S32 g_flg_wonder; +extern S32 g_isConversation; +extern xBase* g_ownerConversation; +extern F32 g_tmr_talkless; + +xFactoryInst* ZNPC_Create_Common(S32 who, RyzMemGrow* grow, void*) +{ + zNPCCommon* com = NULL; + + switch (who) + { + case NPC_TYPE_COMMON: + { + com = new (who, grow) zNPCCommon(who); + break; + } + } + + return com; +} + +void ZNPC_Destroy_Common(xFactoryInst* inst) +{ + delete inst; +} + +void ZNPC_Common_Startup() +{ + S32 i; + + for (i = 0; i < 3; i++) + { + g_hash_lassanim[i] = xStrHash(g_strz_lassanim[i]); + } + + NPCSupport_Startup(); + NPCS_Startup(); + zNPCSettings_MakeDummy(); + zNPCFXStartup(); +} + +void ZNPC_Common_Shutdown() +{ + NPCS_Shutdown(); + NPCSupport_Shutdown(); + zNPCFXShutdown(); +} + +void zNPCCommon_ScenePrepare() +{ + NPCS_SndTimersReset(); + NPCS_SndTablePrepare(g_sndTrax_General); + NPCSupport_ScenePrepare(); + zNPCCommon_WonderReset(); + g_skipDescent = 5; +} + +void zNPCCommon_SceneFinish() +{ + zNPCCommon::ConfigSceneDone(); + NPCSupport_SceneFinish(); + xDebugRemoveTweak(zNPCTypeCommon_strings + 0x42b); +} + +void zNPCCommon_SceneReset() +{ + NPCSupport_SceneReset(); + zNPCPlyrSnd_Reset(); + g_skipDescent = 5; +} + +void zNPCCommon_ScenePostInit() +{ + NPCSupport_ScenePostInit(); +} + +void zNPCCommon_Timestep(F32 dt) +{ + NPCSupport_Timestep(dt); + NPCS_SndTimersUpdate(dt); + zNPCPlyrSnd_Update(dt); + g_skipDescent -= 1; + if (g_skipDescent < 0) + { + g_skipDescent = 0; + } +} + +void zNPCCommon::Destroy() +{ + SelfDestroy(); +} + +void zNPCCommon::Process(xScene* xscn, F32 dt) +{ + if ((flg_misc & 4) != 0) + { + ModelScaleSet(&cfg_npc->scl_model); + } + flags1.flg_upward = flags1.flg_upward & ~0x2; + xNPCBasic::Process(xscn, dt); +} + +void zNPCCommon::ParseProps() +{ + for (S32 i = 0x3f; i < 0x42; i++) + { + switch (i) + { + case 0x3f: + MvptReset(NULL); + break; + default: + break; + } + } +} + +bool zNPCCommon::IsMountableType(en_ZBASETYPE type) +{ + switch (type) + { + case eBaseTypePlatform: + return true; + break; + default: + return false; + break; + } +} + +void zNPCCommon::SelfDestroy() +{ + xBehaveMgr* bmgr = xBehaveMgr_GetSelf(); + if (psy_instinct != NULL) + { + bmgr->UnSubscribe(psy_instinct); + } + psy_instinct = NULL; +} + +S32 zNPCCommon::GetVertPos(en_mdlvert vid, xVec3* pos) +{ + NPCConfig* cfg = cfg_npc; + if (!(cfg->flg_vert & 1 << vid)) + { + return 0; + } + iModelTagEval(model->Data, &cfg->tag_vert[vid], model->Mat, pos); + return 1; +} + +void zNPCCommon::ConfigSceneDone() +{ + g_ncfghead = 0; +} + +void zNPCCommon_WonderReset() +{ + g_isConversation = 0; + g_flg_wonder = 0; +} + +S32 NPCC_NPCIsConversing() +{ + return g_isConversation; +} + +void zNPCCommon::WonderOfTalking(S32 inprogress, xBase* owner) +{ + if (inprogress) + { + g_isConversation = 1; + if (owner) + { + g_ownerConversation = owner; + return; + } + else + { + g_ownerConversation = this; + return; + } + } + + g_isConversation = 0; + g_ownerConversation = NULL; +} + +S32 zNPCCommon::SomethingWonderful() +{ + S32 flg_wonder = g_flg_wonder; + + if (globals.player.Health < 1) + { + // Idk why they wouldn't do flg_wonder |= x here, but this is needed to match + flg_wonder = g_flg_wonder | 0b00000010; + } + + if (globals.player.ControlOff & 0xffffbeff) + { + flg_wonder |= 0b00000100; + } + + if (cruise_bubble::active() && (this->SelfType() & 0xffffff00) == 'NTF\0') + { + flg_wonder |= 0b01000000; + } + + if (globals.cmgr && globals.cmgr->csn) + { + flg_wonder |= 0b00000001; + } + + if (g_isConversation) + { + flg_wonder |= 0b00001000; + } + + if (!NPCC_LampStatus()) + { + flg_wonder |= 0b00100000; + } + + if (zEntTeleportBox_playerIn()) + { + flg_wonder |= 0b10000000; + } + + return flg_wonder; +} + +S32 zNPCCommon::SndIsAnyPlaying() +{ + S32 iVar1 = 0; + + for (S32 i = 0; i < 4; i++) + { + iVar1 = xSndIsPlaying(0, (U32)this + i); + if (iVar1) + { + break; + } + } + + return iVar1; +} + +U32 zNPCCommon::LassoInit() +{ + lassdata = PRIV_GetLassoData(); + if (lassdata != NULL) + { + memset(lassdata, 0, 0x18); + lassdata->stage = LASS_STAT_PENDING; + lassdata->lassoee = this; + } + if (lassdata) + { + return 1; + } + return 0; +} + +zNPCLassoInfo* zNPCCommon::GimmeLassInfo() +{ + return flg_vuln & 0x1000000 ? lassdata : NULL; +} + +void zNPCCommon::LassoNotify(en_LASSO_EVENT event) +{ + zNPCLassoInfo* lass = this->lassdata; + + if (!lass->stage && event) + { + return; + } + + switch (event) + { + case LASS_STAT_DONE: + { + lass->stage = LASS_STAT_PENDING; + break; + } + case LASS_STAT_PENDING: + { + lass->stage = LASS_STAT_DONE; + break; + } + case LASS_STAT_GRABBING: + { + lass->stage = LASS_STAT_GRABBING; + break; + } + case LASS_STAT_NOMORE: + { + lass->stage = LASS_STAT_TOSSING; + return; + } + case LASS_STAT_UNK_5: + { + lass->stage = LASS_STAT_DONE; + break; + } + } +} + +void zNPCCommon::AddDEVGoals(xPsyche*) +{ +} + +U32 zNPCCommon::DBG_Name() +{ + return 0; +} + +void zNPCCommon::DBG_AddTweakers() +{ +} + +void zNPCCommon::SelfSetup() +{ +} + +void zNPCCommon::DBG_RptDataSize() +{ +} + +U32 zNPCCommon::DBG_InstName() +{ + return this->DBG_Name(); +} + +xEntDrive* zNPCCommon::PRIV_GetDriverData() +{ + return NULL; +} +void zNPCCommon::ModelScaleSet(const xVec3* vec) +{ + ModelScaleSet(vec->x, vec->y, vec->z); +} + +xAnimTable* zNPCCommon::AnimGetTable() +{ + return model->Anim->Table; +} + +zNPCLassoInfo* zNPCCommon::PRIV_GetLassoData() +{ + return NULL; +} + +void zNPCCommon::DuploOwner(zNPCCommon* duper) +{ + npc_duplodude = duper; +} + +void zNPCCommon::SpeakBegin() +{ +} + +void zNPCCommon::SpeakEnd() +{ +} + +void zNPCCommon::SpeakStart(U32 param_1, U32 param_2, S32 param_3) +{ +} + +void zNPCCommon::SpeakStop() +{ +} + +F32 zNPCCommon::GenShadCacheRad() +{ + return lbl_803CE4C0; +} + +// xNPCBasic vtable at: 0x2949F4 +// vtable reference is stored immidately _after_ object fields in an xNPCBasic +// instance. That is, sizeof(xNPCBasic) = sizeof(visible fields) + an extra 4 +// bytes for the vtable pointer after those fields. +// vtable[0] = NULL (I think these first two are for RTTI which is disabled) +// vtable[1] = NULL +// vtable[2] = Init(FP9xEntAsset) +// vtable[3] = PostInit(Fv) +// vtable[4] = Setup(Fv) +// vtable[5] = PostSetup(Fv) +// vtable[6] = Reset(Fv) +// vtable[7] = Process(FP6xScenef) +// vtable[8] = BUpdate(FP5xVec3) +// vtable[9] = NewTime(FP6xScenef) +// vtable[10] = Move(FP6xScenefP9xEntFrame) +// vtable[11] = SysEvent(FP5xBaseP5xBaseUiPCfP5xBasePi) +// vtable[12] = Render(Fv) +// vtable[13] = Save(CFP7xSerial) +// vtable[14] = Load(FP7xSerial) +// vtable[15] = CollideReview(Fv) +// vtable[16] = ColChkFlags(CFv) +// vtable[17] = ColPenFlags(CFv) +// vtable[18] = ColChkByFlags(CFv) +// vtable[19] = ColPenByFlags(CFv) +// vtable[20] = PhysicsFlags(CFv) +xNPCBasic::xNPCBasic(S32 value) +{ + myNPCType = value; +} + +void xNPCBasic::Setup() +{ +} + +void xNPCBasic::Move(xScene* xscn, F32 dt, xEntFrame* frm) +{ +} + +S32 xNPCBasic::SysEvent(xBase* from, xBase* to, U32 toEvent, const F32* toParam, + xBase* toParamWidget, S32* handled) +{ + return 1; +} + +void xNPCBasic::DBG_PStatOn(en_npcperf stat) +{ +} + +void xNPCBasic::DBG_PStatCont(en_npcperf stat) +{ +} + +void xNPCBasic::PostInit() +{ +} + +void xNPCBasic::Render() +{ + xEntRender(this); +} + +void xPsyche::ImmTranOn() +{ + flg_psyche |= 1; +} + +void xPsyche::ImmTranOff() +{ + flg_psyche &= 0xfffffffe; +} + +S32 xPsyche::ImmTranIsOn() +{ + return flg_psyche & 1; +} + +S32 xPsyche::HasGoal(S32 goal) +{ + return FindGoal(goal) != NULL; +} + +U32 xSndIsPlaying(U32 assetID, U32 parid) +{ + return iSndIsPlaying(assetID, parid) & 0xff; +} diff --git a/src/SB/Game/zNMECommon.h b/src/SB/Game/zNMECommon.h new file mode 100644 index 0000000..ce42192 --- /dev/null +++ b/src/SB/Game/zNMECommon.h @@ -0,0 +1,654 @@ +#ifndef ZNPCTYPECOMMON_H +#define ZNPCTYPECOMMON_H + +#include "xNPCBasic.h" +#include "xDynAsset.h" +#include "xListItem.h" +#include "xEntDrive.h" +#include "xBehaveMgr.h" +#include "xEnt.h" +#include "xSFX.h" + +#include "zNPCSndTable.h" +#include "zMovePoint.h" +#include "zShrapnel.h" + +// DIRECTLY PORTED FROM BFBB + +typedef struct NPCMsg; + +enum en_npcparm +{ + NPC_PARM_NONE, + NPC_PARM_MOVERATE, + NPC_PARM_TURNRATE, + NPC_PARM_ACCEL, + NPC_PARM_DRIFT, + NPC_PARM_MASS, + NPC_PARM_TOSSGRAV, + NPC_PARM_TOSSELASTIC, + NPC_PARM_BND_ISBOX, + NPC_PARM_BND_CENTER, + NPC_PARM_BND_EXTENT, + NPC_PARM_HITPOINTS, + NPC_PARM_MODELSCALE, + NPC_PARM_DETECT_RAD, + NPC_PARM_DETECT_HYT, + NPC_PARM_DETECT_OFF, + NPC_PARM_ATTACK_RAD, + NPC_PARM_ATTACK_FOV, + NPC_PARM_SND_RAD, + NPC_PARM_TIMEFIDGET, + NPC_PARM_TIMEATTACK, + NPC_PARM_TIMESTUN, + NPC_PARM_TIMEALERT, + NPC_PARM_VTX_ATTACKBASE, + NPC_PARM_VTX_ATTACK, + NPC_PARM_VTX_ATTACK1, + NPC_PARM_VTX_ATTACK2, + NPC_PARM_VTX_ATTACK3, + NPC_PARM_VTX_ATTACK4, + NPC_PARM_VTX_EYEBALL, + NPC_PARM_VTX_DMGSMOKEA, + NPC_PARM_VTX_DMGSMOKEB, + NPC_PARM_VTX_DMGSMOKEC, + NPC_PARM_VTX_DMGFLAMEA, + NPC_PARM_VTX_DMGFLAMEB, + NPC_PARM_VTX_DMGFLAMEC, + NPC_PARM_VTX_PROPEL, + NPC_PARM_VTX_EXHAUST, + NPC_PARM_VTX_GEN01, + NPC_PARM_VTX_GEN02, + NPC_PARM_VTX_GEN03, + NPC_PARM_VTX_GEN04, + NPC_PARM_VTX_GEN05, + NPC_PARM_ATK_SIZE01, + NPC_PARM_ATK_FRAMES01, + NPC_PARM_ATK_FRAMES01A, + NPC_PARM_ATK_FRAMES01B, + NPC_PARM_ATK_FRAMES02, + NPC_PARM_ATK_FRAMES02A, + NPC_PARM_ATK_FRAMES02B, + NPC_PARM_ATK_FRAMES03, + NPC_PARM_ATK_FRAMES03A, + NPC_PARM_ATK_FRAMES03B, + NPC_PARM_ESTEEM_A, + NPC_PARM_ESTEEM_B, + NPC_PARM_ESTEEM_C, + NPC_PARM_ESTEEM_D, + NPC_PARM_ESTEEM_E, + NPC_PARM_SHADOW_CASTDIST, + NPC_PARM_SHADOW_RADCACHE, + NPC_PARM_SHADOW_RADRASTER, + NPC_PARAM_TEST_COUNT, + NPC_PARM_ENDTAG_INI, + NPC_PARM_FIRSTMVPT, + NPC_PARM_ENDTAG_PROPS, + NPC_PARM_BOGUSSHARE, + NPC_PARM_ENDTAG_SHARE, + NPC_PARM_NOMORE, + NPC_PARM_FORCEINT = 0x7fffffff +}; + +enum en_NPC_GOAL_SPOT +{ + NPC_GSPOT_START = 0x20, + NPC_GSPOT_RESUME, + NPC_GSPOT_FINISH, + NPC_GSPOT_STARTALT, + NPC_GSPOT_ALTA, + NPC_GSPOT_ALTB, + NPC_GSPOT_PATROLPAUSE, + NPC_GSPOT_NOMORE, + NPC_GSPOT_FORCEINT = 0x7fffffff +}; + +enum en_NPC_CARRY_STATE +{ + zNPCCARRY_NONE, + zNPCCARRY_PICKUP, + zNPCCARRY_THROW, + zNPCCARRY_ATTEMPTPICKUP, + zNPCCARRY_FORCEINT = 0x7fffffff +}; + +enum en_NPC_DAMAGE_TYPE +{ + DMGTYP_UNDECIDED, + DMGTYP_ABOVE, + DMGTYP_BELOW, + DMGTYP_SIDE, + DMGTYP_INSTAKILL, + DMGTYP_KILLEVENT, + DMGTYP_HITBYTOSS, + DMGTYP_NPCATTACK, + DMGTYP_ROPE, + DMGTYP_CRUISEBUBBLE, + DMGTYP_PROJECTILE, + DMGTYP_BOULDER, + DMGTYP_BUBBOWL, + DMGTYP_THUNDER_TIKI_EXPLOSION, + DMGTYP_DAMAGE_SURFACE, + DMGTYP_BUNGEED, + DMGTYP_SURFACE, + DMGTYP_NOMORE, + DMGTYP_FORCEINT = 0x7fffffff +}; + +enum en_npcvibe +{ + NPC_VIBE_SOFT, + NPC_VIBE_NORM, + NPC_VIBE_HARD, + NPC_VIBE_BUILD_A, + NPC_VIBE_BUILD_B, + NPC_VIBE_BUILD_C, + NPC_VIBE_NOMORE, + NPC_VIBE_FORCE = 0x7fffffff +}; + +struct xEntNPCAsset +{ + S32 npcFlags; + S32 npcModel; + S32 npcProps; + U32 movepoint; + U32 taskWidgetPrime; + U32 taskWidgetSecond; +}; + +enum en_npcbtyp +{ + NPCP_BASIS_NONE, + NPCP_BASIS_EVILROBOT, + NPCP_BASIS_FRIENDLYROBOT, + NPCP_BASIS_LOVINGCITIZEN, + NPCP_BASIS_GRUMPYCITIZEN, + NPCP_BASIS_NOMORE, + NPCP_BASIS_FORCE = 0x7fffffff +}; + +enum en_dupowavmod +{ + NPCP_DUPOWAVE_CONTINUOUS, + NPCP_DUPOWAVE_DISCREET, + NPCP_DUPOWAVE_NOMORE, + NPCP_DUPOWAVE_FORCE = 0x7fffffff +}; + +struct zNPCSettings : xDynAsset +{ + en_npcbtyp basisType; + S8 allowDetect; + U8 allowPatrol; + U8 allowWander; + U8 reduceCollide; + S8 useNavSplines; + S8 pad[3]; + S8 allowChase; + S8 allowAttack; + S8 assumeLOS; + S8 assumeFOV; + en_dupowavmod duploWaveMode; + F32 duploSpawnDelay; + S32 duploSpawnLifeMax; +}; + +struct NPCConfig : xListItem +{ + U32 modelID; + S32 flg_config; + F32 spd_turnMax; + F32 spd_moveMax; + F32 fac_accelMax; + F32 fac_driftMax; + F32 fac_gravKnock; + F32 fac_elastic; + S32 pts_damage; + S32 useBoxBound; + xVec3 off_bound; + xVec3 dim_bound; + F32 npcMass; + F32 npcMassInv; + F32 rad_detect; + F32 hyt_detect; + F32 off_detect; + F32 rad_attack; + F32 fov_attack; + xVec3 scl_model; + F32 tym_attack; + F32 tym_fidget; + F32 tym_stun; + F32 tym_alert; + F32 dst_castShadow; + F32 rad_shadowCache; + F32 rad_shadowRaster; + F32 rad_dmgSize; + S32 flg_vert; + xModelTag tag_vert[20]; + xVec3 animFrameRange[9]; + S32 cnt_esteem[5]; + F32 rad_sound; + NPCSndTrax* snd_trax; // 0x39C + NPCSndTrax* snd_traxShare; // 0x3A0 + S32 test_count; + U8 talk_filter[4]; + U8 talk_filter_size; +}; + +enum en_LASSO_STATUS +{ + LASS_STAT_DONE, + LASS_STAT_PENDING, + LASS_STAT_GRABBING, + LASS_STAT_TOSSING, + LASS_STAT_NOMORE, + LASS_STAT_UNK_5, // needed to match switch in zNPCCommon::LassoNotify, checks value of 5 + LASS_STAT_FORCEINT = 0x7fffffff +}; + +enum en_mdlvert +{ + NPC_MDLVERT_ATTACKBASE, + NPC_MDLVERT_ATTACK, + NPC_MDLVERT_ATTACK1, + NPC_MDLVERT_ATTACK2, + NPC_MDLVERT_ATTACK3, + NPC_MDLVERT_ATTACK4, + NPC_MDLVERT_LOSEYEBALL, + NPC_MDLVERT_DMGSMOKE_A, + NPC_MDLVERT_DMGSMOKE_B, + NPC_MDLVERT_DMGSMOKE_C, + NPC_MDLVERT_DMGFLAME_A, + NPC_MDLVERT_DMGFLAME_B, + NPC_MDLVERT_DMGFLAME_C, + NPC_MDLVERT_PROPEL, + NPC_MDLVERT_EXHAUST, + NPC_MDLVERT_GEN01, + NPC_MDLVERT_GEN02, + NPC_MDLVERT_GEN03, + NPC_MDLVERT_GEN04, + NPC_MDLVERT_GEN05, + NPC_MDLVERT_NOMORE, + NPC_MDLVERT_FORCEINT = 0x7fffffff +}; + +enum en_LASSO_EVENT +{ + LASS_EVNT_BEGIN, + LASS_EVNT_ENDED, + LASS_EVNT_GRABSTART, + LASS_EVNT_GRABEND, + LASS_EVNT_YANK, + LASS_EVNT_ABORT, + LASS_EVNT_NOMORE, + LASS_EVNT_FORCEINT = 0x7fffffff +}; + +enum en_NPC_MSG_ID +{ + NPC_MID_NONE, + NPC_MID_SYSEVENT, + NPC_MID_RESPAWN, + NPC_MID_DAMAGE, + NPC_MID_EXPLOSION, + NPC_MID_BUNNYHOP, + NPC_MID_DTRON_NPCEMIT, + NPC_MID_DTRON_NPCAVAIL, + NPC_MID_DTRON_ISDEAD, + NPC_MID_CHAT_REQUEST, + NPC_MID_CHAT_DECLINE, + NPC_MID_CHAT_ACCEPT, + NPC_MID_CHAT_DONE, + NPC_MID_CHAT_ABORT, + NPC_MID_TALKSTART, + NPC_MID_TALKON, + NPC_MID_TALKOFF, + NPC_MID_SAWPLYR, + NPC_MID_NEEDMEDIC, + NPC_MID_UNDERATTACK, + NPC_MID_NPCDIED, + NPC_MID_PLYRSPATULA, + NPC_MID_BECOMESCARED, + NPC_MID_NOLONGERSCARED, + NPC_MID_CELEBRATE, + NPC_MID_STUN, + NPC_MID_SCRIPTBEGIN, + NPC_MID_SCRIPTEND, + NPC_MID_SCRIPTHALT, + NPC_MID_DEV_ANIMSPIN, + NPC_MID_DEV_ANIMCYCLE, + NPC_MID_DEV_HEROMODE, + NPC_MID_DEV_DONE, + NPC_MID_NOMORE, + NPC_MID_FORCE = 0x7fffffff +}; + +enum en_NPC_MSG_DATA +{ + NPC_MDAT_BLANK, + NPC_MDAT_SYSEVENT, + NPC_MDAT_BLAST, + NPC_MDAT_CHAT, + NPC_MDAT_SPAWN, + NPC_MDAT_TARGET, + NPC_MDAT_DAMAGE, + NPC_MDAT_STUN, + NPC_MDAT_SCRIPT, + NPC_MDAT_MOUNT, + NPC_MDAT_AREANOTIFY, + NPC_MDAT_NOMORE, + NPC_MDAT_FORCE = 0x7fffffff +}; + +enum en_SM_NOTICES +{ + SM_NOTE_NPCDIED, + SM_NOTE_NPCSTANDBY, + SM_NOTE_NPCALIVE, + SM_NOTE_DUPPAUSE, + SM_NOTE_DUPRESUME, + SM_NOTE_DUPSETDELAY, + SM_NOTE_DUPDEAD, + SM_NOTE_KILLKIDS, + SM_NOTE_NOMORE, + SM_NOTE_FORCE = 0x7fffffff +}; + +struct zNPCLassoInfo +{ + en_LASSO_STATUS stage; + xEnt* lassoee; + xAnimState* holdGuideAnim; + xModelInstance* holdGuideModel; + xAnimState* grabGuideAnim; + xModelInstance* grabGuideModel; +}; + +struct zNPCCommon : xNPCBasic //Size of zNPCCommon: 0x2A0 +{ + xEntAsset* entass; // 0x1BC + xEntNPCAsset* npcass; // 0x1C0 + zNPCSettings* npcsetass; // 0x1C4 + S32 flg_vuln; // 0x1C8 + S32 flg_move; // 0x1CC + S32 flg_misc; // 0x1D0 + S32 flg_able; // 0x1D4 + NPCConfig* cfg_npc; // 0x1D8 + zNPCSettings npcset; // 0x1DC + zMovePoint* nav_past; // 0x208 + zMovePoint* nav_curr; // 0x20C + zMovePoint* nav_dest; // 0x210 + zMovePoint* nav_lead; + xSpline3* spl_mvptspline; + F32 len_mvptspline; + F32 dst_curspline; + xEntDrive* drv_data; + xPsyche* psy_instinct; // 0x228 + zNPCCommon* npc_duplodude; + F32 spd_throttle; //0x230 + S32 flg_xtrarend; + F32 tmr_fidget; //0x238 + F32 tmr_invuln; // 0x23C + zShrapnelAsset* explosion; // 0x240 + xModelAssetParam* parmdata; // 0x244 + U32 pdatsize; //0x248 + zNPCLassoInfo* lassdata; //0x24C + NPCSndQueue snd_queue[4]; //0x250 + + zNPCCommon(S32 myType); + + F32 TurnToFace(F32 dt, const xVec3* dir_want, F32 useTurnRate); + F32 ThrottleApply(F32 dt, const xVec3* dir, S32 force3D); + F32 ThrottleAccel(F32 dt, S32 speedup, F32 pct_max); + F32 ThrottleAdjust(F32 dt, F32 spd_want, F32 accel); + + F32 BoundAsRadius(int useCfg); + void VelStop(); + static void ConfigSceneDone(); + U32 LassoInit(); + zNPCLassoInfo* GimmeLassInfo(); + void AddDEVGoals(xPsyche*); + U32 DBG_Name(); // return type might be wrong + void DBG_AddTweakers(); + void DBG_RptDataSize(); + U32 DBG_InstName(); // return type might be wrong + xAnimTable* AnimGetTable(); + F32 AnimTimeRemain(xAnimState* ast); + F32 AnimTimeCurrent(); + F32 AnimDuration(xAnimState* ast); + bool IsMountableType(en_ZBASETYPE type); + void MvptReset(zMovePoint* nav_goto); + S32 MvptCycle(); + S32 HaveLOSToPos(xVec3*, float, xScene*, xBase*, xCollis*); + void ModelScaleSet(F32 x, F32 y, F32 z); + void ModelScaleSet(F32 unk); + void ModelScaleSet(const xVec3* vec); + xModelInstance* ModelAtomicFind(int index, int idx_prev, xModelInstance* mdl_prev); + xModelInstance* ModelAtomicHide(int index, xModelInstance* mdl); + xModelInstance* ModelAtomicShow(int index, xModelInstance* mdl); + S32 AnimStart(U32 animID, S32 forceRestart); + xAnimState* AnimFindState(U32 animID); + xAnimState* AnimCurState(); + xAnimSingle* AnimCurSingle(); + U32 AnimCurStateID(); + void GiveReward(); + S32 SndPlayFromSFX(xSFX* sfx, U32* sid_played); + S32 SndPlayRandom(en_NPC_SOUND sndtype); + S32 SndChanIsBusy(S32 flg_chan); + S32 LassoUseGuides(S32 idx_grabmdl, S32 idx_holdmdl); + S32 GetVertPos(en_mdlvert vid, xVec3* pos); + void Vibrate(en_npcvibe vibe, F32 duration); + void AddScripting(xPsyche* psy, S32 (*eval_script)(xGoal*, void*, en_trantype*, F32, void*), + S32 (*eval_playanim)(xGoal*, void*, en_trantype*, F32, void*), + S32 (*eval_attack)(xGoal*, void*, en_trantype*, F32, void*), + S32 (*eval_move)(xGoal*, void*, en_trantype*, F32, void*), + S32 (*eval_follow)(xGoal*, void*, en_trantype*, F32, void*), + S32 (*eval_lead)(xGoal*, void*, en_trantype*, F32, void*), + S32 (*eval_wait)(xGoal*, void*, en_trantype*, F32, void*)); + void AddBaseline(xPsyche*, int (*)(xGoal*, void*, en_trantype*, float, void*), + int (*)(xGoal*, void*, en_trantype*, float, void*), + int (*)(xGoal*, void*, en_trantype*, float, void*), + int (*)(xGoal*, void*, en_trantype*, float, void*), + int (*)(xGoal*, void*, en_trantype*, float, void*)); + + // defined from zNPCGoalRobo.cpp + xVec3* Center(); + xVec3* Pos(); + RwMatrix* BoneMat(S32 unk) const; + RwV3d* BonePos(S32 unk) const; + void XZVecToPlayer(xVec3* unk1, F32* unk2); + F32 XZDstSqToPos(const xVec3* unk1, xVec3* unk2, F32* unk3); + void XZVecToPos(xVec3* unk1, const xVec3* unk2, F32* unk3); + void XYZVecToPos(xVec3* dest, xVec3* unk2) + { + xVec3Sub(dest, unk2, Pos()); + } + F32 XYZDstSqToPlayer(xVec3* unk); + F32 XYZDstSqToPos(xVec3* unk1, xVec3* dest) + { + xVec3 dest_vec; + if (dest == NULL) + { + dest = &dest_vec; + } + XYZVecToPos(dest, unk1); + return xVec3Length2(dest); + } + void WonderOfTalking(S32 inprogress, xBase* owner); + // return type is probably wrong + S32 SomethingWonderful(); + S32 SndIsAnyPlaying(); + + // vTable (xNPCBasic) + + virtual void Init(xEntAsset* asset); + virtual void Reset(); + virtual void Setup(); + virtual void Process(xScene* xscn, F32 dt); + virtual void BUpdate(xVec3* pos); + virtual void NewTime(xScene* xscn, F32 dt); + virtual void Move(xScene* xscn, F32 dt, xEntFrame*); + virtual S32 SysEvent(xBase* from, xBase* to, U32 toEvent, const F32* toParam, + xBase* toParamWidget, S32* handled); + virtual void CollideReview(); + virtual void Destroy(); + + // vTable (zNPCCommon) + virtual S32 NPCMessage(NPCMsg* mail); + virtual void RenderExtra(); + virtual void RenderExtraPostParticles(); + virtual void ParseINI(); + virtual void ParseLinks(); + virtual void ParseProps(); + virtual void SelfSetup(); + virtual void SelfDestroy(); + virtual S32 IsHealthy(); + virtual S32 IsAlive(); + virtual void Damage(en_NPC_DAMAGE_TYPE damtype, xBase* who, const xVec3* vec_hit); + virtual S32 Respawn(const xVec3* pos, zMovePoint* mvptFirst, zMovePoint* mvptSpawnRef); + virtual void DuploOwner(zNPCCommon* duper); + virtual void DuploNotice(en_SM_NOTICES, void*); + virtual S32 CanRope(); + virtual void LassoNotify(en_LASSO_EVENT event); + virtual S32 SetCarryState(en_NPC_CARRY_STATE); + virtual void Stun(F32 stuntime); + virtual void SpeakBegin(); + virtual void SpeakEnd(); + virtual void SpeakStart(U32 sound, U32 param_2, S32 param_3); + virtual void SpeakStop(); + + virtual U32 AnimPick(S32 animID, en_NPC_GOAL_SPOT gspot, xGoal* goal) + { + return 0; + } + + virtual void GetParm(en_npcparm pid, void* val); + virtual void GetParmDefault(en_npcparm pid, void* val); + virtual F32 GenShadCacheRad(); + virtual xEntDrive* PRIV_GetDriverData(); + virtual zNPCLassoInfo* PRIV_GetLassoData(); + virtual S32 LassoSetup(); + +protected: + // This prevents implicit destructors from being generated in subclasses of zNPCCommon + ~zNPCCommon(); +}; + +struct NPCSysEvent +{ + S32 doLinkEvents; + S32 handled; + xBase* from; + xBase* to; + U32 toEvent; + F32 toParam[4]; + xBase* toParamWidget; +}; + +struct NPCBlastInfo +{ + xVec3 pos_blast; + F32 rad_blast; + F32 spd_expand; +}; + +struct NPCChatInfo +{ + xVec3 pos_chat; + F32 tym_chat; +}; + +struct NPCSpawnInfo +{ + xVec3 pos_spawn; + zMovePoint* nav_firstMovepoint; + zMovePoint* nav_spawnReference; + S32 spawnSuccess; +}; + +struct NPCTargetInfo +{ + xBase* bas_tgt; + xVec3 pos_tgt; +}; + +struct NPCDamageInfo +{ + en_NPC_DAMAGE_TYPE dmg_type; + xBase* dmg_from; + xVec3 vec_dmghit; +}; + +struct NPCStunInfo +{ + F32 tym_stuntime; + en_NPC_CARRY_STATE carrystate; + S32 allowStun; +}; + +struct NPCScriptInfo +{ + U32 aid_playanim; +}; + +struct NPCMountInfo +{ + xEnt* ent_toMount; + xCollis* col_forMount; +}; + +struct NPCAreaInfo +{ + zNPCCommon* npc_origin; + xVec3 pos_origin; +}; + +struct NPCMsg +{ + en_NPC_MSG_ID msgid; + U32 sendto; + U32 from; + en_NPC_MSG_DATA infotype; // 0xC + union + { + NPCSysEvent sysevent; + NPCBlastInfo blastarea; + NPCChatInfo chatter; + NPCSpawnInfo spawning; + NPCTargetInfo target; + NPCDamageInfo dmgdata; // 0x10 + NPCStunInfo stundata; + NPCScriptInfo scriptdata; + NPCMountInfo mountdata; + NPCAreaInfo areadata; + }; + void* attached; // 0x38 + NPCMsg* next; + F32 tmr_delay; // 0x40 +}; + +xFactoryInst* ZNPC_Create_Common(S32 who, RyzMemGrow* grow, void*); +void ZNPC_Destroy_Common(xFactoryInst* inst); +void zNPCCommon_ScenePrepare(); +void zNPCCommon_ScenePostInit(); +void zNPCCommon_SceneFinish(); +void zNPCPlyrSnd_Reset(); +void zNPCPlyrSnd_Update(F32 dt); +void zNPCCommon_SceneReset(); +void ZNPC_Destroy_Common(xFactoryInst* inst); +void zNPCSettings_MakeDummy(); +void ZNPC_Common_Startup(); +void zNPCCommon_WonderReset(); +void ZNPC_Common_Shutdown(); +void NPCC_BuildStandardAnimTran(xAnimTable* table, char** namelist, S32* ourAnims, S32 idx_dflt, + F32 blend); +void zNPCCommon_Timestep(xScene* xscn, F32 dt); + +xAnimTable* ZNPC_AnimTable_Common(); +xAnimTable* ZNPC_AnimTable_LassoGuide(); +S32 NPCC_NPCIsConversing(); +void zNPCCommon_EjectPhlemOnPawz(); +U32 xSndIsPlaying(U32 assetID, U32 parid); + +#endif diff --git a/src/SB/Game/zNPCSndTable.cpp b/src/SB/Game/zNPCSndTable.cpp new file mode 100644 index 0000000..846fd8b --- /dev/null +++ b/src/SB/Game/zNPCSndTable.cpp @@ -0,0 +1,62 @@ +#include "zNPCSndTable.h" +#include "zNPCGoalVillager.h" + +#include "xString.h" + +#include + +static char* g_strz_sndgroup[26]; +static unsigned int g_hash_sndgroup[26]; +static float g_tmrz_sndplay[26]; + +NPCSndProp g_sndProps[]; + +void NPCS_Startup() +{ + for (int i = 0; i < (int)(sizeof(g_strz_sndgroup) / sizeof(char*)); i++) + { + g_hash_sndgroup[i] = xStrHash(g_strz_sndgroup[i]); + } +} + +void NPCS_Shutdown() +{ +} + +int NPCS_SndOkToPlay(en_NPC_SOUND sndtype) +{ + if (sndtype == NPC_STYP_BOGUS) + { + return 1; + } + if (sndtype == NPC_STYP_LISTEND) + { + return 0; + } + return g_tmrz_sndplay[sndtype] < 0.0f; +} + +void NPCS_SndTypePlayed(en_NPC_SOUND sndtype, float delayNext) +{ + float tym = 2.0f; + + switch (sndtype) + { + case NPC_STYP_TIKISTACK: + tym = 0.15f; + break; + case NPC_STYP_TIKIEXPLODE: + tym = 2.0f; + break; + default: + tym = -1.0f; + break; + } + + if (delayNext > 0.0f) + { + tym = delayNext; + } + + g_tmrz_sndplay[sndtype] = tym; +} diff --git a/src/SB/Game/zNPCSndTable.h b/src/SB/Game/zNPCSndTable.h new file mode 100644 index 0000000..717d416 --- /dev/null +++ b/src/SB/Game/zNPCSndTable.h @@ -0,0 +1,61 @@ +#ifndef ZNPCSNDTABLE_H +#define ZNPCSNDTABLE_H + +#include + +enum en_NPC_SOUND +{ + NPC_STYP_BOGUS = -2, + NPC_STYP_LISTEND = 0, + NPC_STYP_ENCOUNTER, + NPC_STYP_CLANKING, + NPC_STYP_EXCLAIM, + NPC_STYP_OUCH, + NPC_STYP_CHEERING, + NPC_STYP_RESPAWN, + NPC_STYP_ALERT, + NPC_STYP_DIZZY, + NPC_STYP_DANCE, + NPC_STYP_LAUGH, + NPC_STYP_ATTACK, + NPC_STYP_PUNCH, + NPC_STYP_WEPLAUNCH, + NPC_STYP_LIGHTNING, + NPC_STYP_WARNBANG, + NPC_STYP_DEATH, + NPC_STYP_DEATHJELLY, + NPC_STYP_BONKED, + NPC_STYP_UNBONKED, + NPC_STYP_TIKISTACK, + NPC_STYP_TIKIEXPLODE, + NPC_STYP_TIKITHUNDER, + NPC_STYP_XSFXTALK, + NPC_STYP_ONELINER, + NPC_STYP_ONELINERTOO, + NPC_STYP_NOMORE, + NPC_STYP_FORCE = 0x7fffffff +}; + +struct NPCSndTrax +{ + en_NPC_SOUND typ_sound; + char* nam_sound; + U32 aid_sound; +}; + +struct NPCSndQueue //0x14 +{ + U32 sndDirect; //0x0 + en_NPC_SOUND sndtype; //0x4 + S32 flg_snd; //0x8 + F32 tmr_delay; //0xC + F32 radius; //0x10 +}; + +void NPCS_Startup(); +void NPCS_SndTimersReset(); +void NPCS_SndTimersUpdate(F32 dt); +void NPCS_SndTablePrepare(NPCSndTrax* trax); +void NPCS_Shutdown(); + +#endif diff --git a/src/SB/Game/zParCmd.h b/src/SB/Game/zParCmd.h new file mode 100644 index 0000000..047d05a --- /dev/null +++ b/src/SB/Game/zParCmd.h @@ -0,0 +1,8 @@ +#ifndef ZPARCMD_H +#define ZPARCMD_H + +// Note: all the xParCmd structs and functions are defined in xParCmd.h, don't redefine them here + +void zParCmdFindClipVolumes(); + +#endif \ No newline at end of file diff --git a/src/SB/Game/zParEmitter.cpp b/src/SB/Game/zParEmitter.cpp new file mode 100644 index 0000000..4142917 --- /dev/null +++ b/src/SB/Game/zParEmitter.cpp @@ -0,0 +1,35 @@ +#include "zParEmitter.h" + +#include +#include "zBase.h" +#include "zGlobals.h" +#include "xString.h" + +zParEmitter* zParEmitterFind(U32 asset_id) +{ + zScene* s = globals.sceneCur; + + if (s == NULL) + { + return NULL; + } + + zParEmitter* pe = (zParEmitter*)s->baseList[eBaseTypeParticleEmitter]; + + for (S32 i = s->baseCount[eBaseTypeParticleEmitter]; i > 0; i--) + { + if (pe->tasset->id == asset_id) + { + return pe; + } + pe++; + } + + return NULL; +} + +zParEmitter* zParEmitterFind(const char* asset_name) +{ + U32 asset_id = xStrHash(asset_name); + return zParEmitterFind(asset_id); +} diff --git a/src/SB/Game/zParEmitter.h b/src/SB/Game/zParEmitter.h new file mode 100644 index 0000000..2dce49f --- /dev/null +++ b/src/SB/Game/zParEmitter.h @@ -0,0 +1,14 @@ +#ifndef ZPAREMITTER_H +#define ZPAREMITTER_H + +#include +#include "xParEmitter.h" + +struct zParEmitter : xParEmitter +{ +}; + +zParEmitter* zParEmitterFind(U32 asset_id); +zParEmitter* zParEmitterFind(const char* asset_name); + +#endif diff --git a/src/SB/Game/zParPTank.h b/src/SB/Game/zParPTank.h new file mode 100644 index 0000000..37aa421 --- /dev/null +++ b/src/SB/Game/zParPTank.h @@ -0,0 +1,34 @@ +#ifndef ZPARPTANK_H +#define ZPARPTANK_H + +#include + +struct xVec3; + +struct RpAtomic; +struct zParPTank; +typedef void (*zParPTankUpdateCallback)(zParPTank*, float); + +// total size: 0x14 +struct zParPTank +{ + // 0x2 == Update when paused + U32 flags; // offset 0x0, size 0x4 + zParPTankUpdateCallback update; // offset 0x4, size 0x4 + RpAtomic* ptank; // offset 0x8, size 0x4 + U32 num_particles; // offset 0xC, size 0x4 + U32 max_particles; // offset 0x10, size 0x4 +}; + +void zParPTankInit(); +void zParPTankSceneEnter(); +void zParPTankSceneExit(); +void zParPTankSpawnBubbles(xVec3* pos, xVec3* vel, U32 count, F32 scale); +void zParPTankSpawnSnow(xVec3* pos, xVec3* vel, U32 count); +void zParPTankExit(); +void zParPTankRender(); +void zParPTankUpdate(F32 dt); + +extern const U32 gPTankDisable; + +#endif diff --git a/src/SB/Game/zParSys.h b/src/SB/Game/zParSys.h new file mode 100644 index 0000000..813c4c6 --- /dev/null +++ b/src/SB/Game/zParSys.h @@ -0,0 +1,10 @@ +#ifndef ZPARSYS_H +#define ZPARSYS_H + +#include "xParSys.h" + +struct zParSys : xParSys +{ +}; + +#endif diff --git a/src/SB/Game/zParticleSystemWaterfall.cpp b/src/SB/Game/zParticleSystemWaterfall.cpp index abcf743..bb663e9 100644 --- a/src/SB/Game/zParticleSystemWaterfall.cpp +++ b/src/SB/Game/zParticleSystemWaterfall.cpp @@ -1,109 +1,112 @@ -#include "zParticleSystemWaterfall.h" - -void zParticleGeneratorWaterfallSplash::deactivate() -{ - zParticleGenerator* pGen; - pGen->deactivate(); - locator.deactivate(); -} - -void zParticleGeneratorWaterfallSplash::activate() -{ - zParticleGenerator* pGen; - pGen->activate(); - locator.activate(*asset, attach_to); // Make const -} - -void zParticleGeneratorWaterfallSplash::reset() -{ - zParticleGenerator::reset(); - emitted = 0; - locator.restart(); - locator.deactivate(); - if (&flags != 0) // This arg needs fixed - { - locator.activate(*asset, attach_to); - } -} - -S32 zParticleSystemWaterfallSplash::get_asset_size() const -{ - return 56; // Calls for 0x38 -} - -void zParticleSystemWaterfallSplash::scene_enter() -{ - batch_group.create(); -} - -void zParticleGeneratorWaterfallMist::deactivate() -{ - zParticleGenerator* pGen; - pGen->deactivate(); - locator.deactivate(); -} - -void zParticleGeneratorWaterfallMist::activate() -{ - zParticleGenerator* pGen; - pGen->activate(); - locator.activate(*asset, attach_to); // Make const -} - -void zParticleGeneratorWaterfallMist::reset() -{ - zParticleGenerator::reset(); - emitted = 0; - locator.restart(); - locator.deactivate(); - if (&flags != 0) // This arg needs fixed - { - locator.activate(*asset, attach_to); - } -} - -S32 zParticleSystemWaterfallMist::get_asset_size() const -{ - return 52; // Calls for 0x34 -} - -void zParticleSystemWaterfallMist::scene_enter() -{ - batch_group.create(); -} - -void zParticleGeneratorWaterfall::deactivate() -{ - zParticleGenerator* pGen; - pGen->deactivate(); - locator.deactivate(); -} - -void zParticleGeneratorWaterfall::activate() -{ - zParticleGenerator* pGen; - pGen->activate(); - locator.activate(*asset, attach_to); // Make const -} - -void zParticleGeneratorWaterfall::reset() // 87% -{ - zParticleGenerator::reset(); - emitted = 0; - locator.restart(); - locator.deactivate(); - if (&flags != 0) // This arg needs fixed - { - locator.activate(*asset, attach_to); - } -} - -S32 zParticleSystemWaterfall::get_asset_size() const -{ - return 76; // Calls for 0x4c -} - -void zParticleSystemWaterfall::scene_enter() -{ - batch_group.create(); -} + +// #include "zParticleSystemWaterfall.h" + +// void zParticleGeneratorWaterfallSplash::deactivate() +// { +// zParticleGenerator* pGen; +// pGen->deactivate(); +// locator.deactivate(); +// } + +// void zParticleGeneratorWaterfallSplash::activate() +// { +// zParticleGenerator* pGen; +// pGen->activate(); +// locator.activate(*asset, attach_to); // Make const +// } + +// void zParticleGeneratorWaterfallSplash::reset() +// { +// zParticleGenerator::reset(); +// emitted = 0; +// locator.restart(); +// locator.deactivate(); +// if (&flags != 0) // This arg needs fixed +// { +// locator.activate(*asset, attach_to); +// } +// } + +// S32 zParticleSystemWaterfallSplash::get_asset_size() const +// { +// return 56; // Calls for 0x38 +// } + +// void zParticleSystemWaterfallSplash::scene_enter() +// { +// batch_group.create(); +// } + +// void zParticleGeneratorWaterfallMist::deactivate() +// { +// zParticleGenerator* pGen; +// pGen->deactivate(); +// locator.deactivate(); +// } + +// void zParticleGeneratorWaterfallMist::activate() +// { +// zParticleGenerator* pGen; +// pGen->activate(); +// locator.activate(*asset, attach_to); // Make const +// } + +// void zParticleGeneratorWaterfallMist::reset() +// { +// zParticleGenerator::reset(); +// emitted = 0; +// locator.restart(); +// locator.deactivate(); +// if (&flags != 0) // This arg needs fixed +// { +// locator.activate(*asset, attach_to); +// } +// } + +// S32 zParticleSystemWaterfallMist::get_asset_size() const +// { +// return 52; // Calls for 0x34 +// } + +// void zParticleSystemWaterfallMist::scene_enter() +// { +// batch_group.create(); +// } + +// void zParticleGeneratorWaterfall::deactivate() +// { +// zParticleGenerator* pGen; +// pGen->deactivate(); +// locator.deactivate(); +// } + +// void zParticleGeneratorWaterfall::activate() +// { +// zParticleGenerator* pGen; +// pGen->activate(); +// locator.activate(*asset, attach_to); // Make const +// } + +// void zParticleGeneratorWaterfall::reset() // 87% +// { +// zParticleGenerator::reset(); +// emitted = 0; +// locator.restart(); +// locator.deactivate(); +// if (&flags != 0) // This arg needs fixed +// { +// locator.activate(*asset, attach_to); +// } +// } + +// S32 zParticleSystemWaterfall::get_asset_size() const +// { +// return 76; // Calls for 0x4c +// } + +// void zParticleSystemWaterfall::scene_enter() +// { +// batch_group.create(); +// } + + diff --git a/src/SB/Game/zParticleSystemWaterfall.h b/src/SB/Game/zParticleSystemWaterfall.h index dbb704d..394ecb3 100644 --- a/src/SB/Game/zParticleSystemWaterfall.h +++ b/src/SB/Game/zParticleSystemWaterfall.h @@ -1,274 +1,276 @@ -#ifndef ZPARTICLESYSTEMWATERFALL_H -#define ZPARTICLESYSTEMWATERFALL_H - -#include "xNME.h" - -struct _class_0 -{ - F32 yaw; - F32 pitch; - F32 roll; -}; - -struct attach_fixed_data -{ -}; - -struct attach_entity_data -{ - U32 entity; - U8 bone; - U8 pad1; - U8 pad2; - U8 pad3; -}; - -struct attach_entity_tag_data -{ - U32 entity; - xVec3 tag; -}; - -struct attach_data -{ - union - { - attach_fixed_data fixed; - attach_entity_data entity; - attach_entity_tag_data entity_tag; - }; -}; - -struct motion_none_data -{ -}; - -struct motion_spiral_data -{ - U8 flags; - U8 points; - U8 pad1; - U8 pad2; - F32 radius_inner; - F32 radius_outer; - F32 duration; - F32 frequency; -}; - -struct motion_data -{ - union - { - motion_none_data none; - motion_spiral_data spiral; - }; -}; - -struct volume_point_data -{ -}; - -struct volume_sphere_data -{ - F32 radius; -}; - -struct volume_circle_data -{ - F32 radius; - F32 arc_length; -}; - -struct volume_line_data -{ - U8 flags; - U8 pad1; - U8 pad2; - U8 pad3; - F32 radius; - F32 length; -}; - -struct volume_model_data -{ - U8 flags; - U8 exclude; - U8 pad1; - U8 pad2; - F32 expand; -}; - -struct volume_data -{ - union - { - volume_point_data point; - volume_sphere_data sphere; - volume_circle_data circle; - volume_line_data line; - volume_model_data model; - }; -}; - -struct zParticleAsset : xDynAsset -{ - U8 flags; - U8 attach_flags; - U8 motion_flags; - U8 volume_flags; - F32 rate; - U32 texture; - U8 attach_type; - U8 motion_type; - U8 volume_type; - U8 system_type; - xVec3 location; - _class_0 axis; - attach_data attach; - motion_data motion; - volume_data volume; -}; - -struct zParticleGenerator : xBase -{ - zParticleAsset* asset; - S32 flags; - - void activate(); - void deactivate(); - void reset(); - void perturb_dir(xVec3& dir, F32 angle); - xEnt* get_attach_entity(zParticleAsset& asset); - void event_handler(xBase* to, U32 event); -}; - -struct relative_ordering -{ - S32 other; - U8 before_other; -}; - -struct zParticleSystem -{ - S32 type; - S32 need; - zParticleGenerator** generators; - S32 generators_size; - S32 generators_active; - - void destroy_generator(); - void scene_exit(); - void setup(); - void reset(); - void pre_render(); - void render(); - relative_ordering* get_ordering(S32& size); - void scene_enter(); - void update(); -}; - -struct xParticleBatchGroup -{ - U8* elements; - S32 elements_size; - - void create(); -}; - -struct zParticleSystemWaterfall : zParticleSystem -{ - S32 unk; - xParticleBatchGroup batch_group; - - S32 get_asset_size() const; - void update(F32 dt); - void scene_enter(); - zParticleGenerator* create_generator(zParticleAsset& asset); -}; - -struct activity_data -{ -}; - -struct zParticleLocator -{ - activity_data* activity; - - void restart(); - void scene_enter(); - U8 activate(zParticleAsset& asset, xEnt* attach_to); - void deactivate(); -}; - -struct zParticleGeneratorWaterfall : zParticleGenerator -{ - S32 unk; - zParticleSystemWaterfall* system; - xEnt* attach_to; - F32 emitted; //0x24 - zParticleLocator locator; - S32 batch_id; - xVec3 vel_dir; - - void deactivate(); - void activate(); - void reset(); - void create(zParticleSystemWaterfall& system, zParticleAsset& asset); - void update(F32 dt); -}; - -struct zParticleSystemWaterfallMist : zParticleSystem -{ - S32 unk; - xParticleBatchGroup batch_group; - - S32 get_asset_size() const; - void update(F32 dt); - void scene_enter(); - zParticleGenerator* create_generator(zParticleAsset& asset); -}; - -struct zParticleGeneratorWaterfallMist : zParticleGenerator -{ - S32 unk; - zParticleSystemWaterfallMist* system; - xEnt* attach_to; - F32 emitted; - zParticleLocator locator; - S32 batch_id; - - void deactivate(); - void activate(); - void reset(); - void create(zParticleSystemWaterfallMist& system, zParticleAsset& asset); - void update(F32 dt); -}; - -struct zParticleSystemWaterfallSplash : zParticleSystem -{ - S32 unk; - xParticleBatchGroup batch_group; - - S32 get_asset_size() const; - void update(F32 dt); - void scene_enter(); - zParticleGenerator* create_generator(zParticleAsset& asset); -}; - -struct zParticleGeneratorWaterfallSplash : zParticleGenerator -{ - S32 unk; - zParticleSystemWaterfallSplash* system; - xEnt* attach_to; - F32 emitted; - zParticleLocator locator; - S32 batch_id; - - void deactivate(); - void activate(); - void reset(); - void create(zParticleSystemWaterfallSplash& system, zParticleAsset& asset); - void update(F32 dt); -}; - -#endif + +// #ifndef ZPARTICLESYSTEMWATERFALL_H +// #define ZPARTICLESYSTEMWATERFALL_H + +// #include "xNME.h" + +// struct _class_0 +// { +// F32 yaw; +// F32 pitch; +// F32 roll; +// }; + +// struct attach_fixed_data +// { +// }; + +// struct attach_entity_data +// { +// U32 entity; +// U8 bone; +// U8 pad1; +// U8 pad2; +// U8 pad3; +// }; + +// struct attach_entity_tag_data +// { +// U32 entity; +// xVec3 tag; +// }; + +// struct attach_data +// { +// union +// { +// attach_fixed_data fixed; +// attach_entity_data entity; +// attach_entity_tag_data entity_tag; +// }; +// }; + +// struct motion_none_data +// { +// }; + +// struct motion_spiral_data +// { +// U8 flags; +// U8 points; +// U8 pad1; +// U8 pad2; +// F32 radius_inner; +// F32 radius_outer; +// F32 duration; +// F32 frequency; +// }; + +// struct motion_data +// { +// union +// { +// motion_none_data none; +// motion_spiral_data spiral; +// }; +// }; + +// struct volume_point_data +// { +// }; + +// struct volume_sphere_data +// { +// F32 radius; +// }; + +// struct volume_circle_data +// { +// F32 radius; +// F32 arc_length; +// }; + +// struct volume_line_data +// { +// U8 flags; +// U8 pad1; +// U8 pad2; +// U8 pad3; +// F32 radius; +// F32 length; +// }; + +// struct volume_model_data +// { +// U8 flags; +// U8 exclude; +// U8 pad1; +// U8 pad2; +// F32 expand; +// }; + +// struct volume_data +// { +// union +// { +// volume_point_data point; +// volume_sphere_data sphere; +// volume_circle_data circle; +// volume_line_data line; +// volume_model_data model; +// }; +// }; + +// struct zParticleAsset : xDynAsset +// { +// U8 flags; +// U8 attach_flags; +// U8 motion_flags; +// U8 volume_flags; +// F32 rate; +// U32 texture; +// U8 attach_type; +// U8 motion_type; +// U8 volume_type; +// U8 system_type; +// xVec3 location; +// _class_0 axis; +// attach_data attach; +// motion_data motion; +// volume_data volume; +// }; + +// struct zParticleGenerator : xBase +// { +// zParticleAsset* asset; +// S32 flags; + +// void activate(); +// void deactivate(); +// void reset(); +// void perturb_dir(xVec3& dir, F32 angle); +// xEnt* get_attach_entity(zParticleAsset& asset); +// void event_handler(xBase* to, U32 event); +// }; + +// struct relative_ordering +// { +// S32 other; +// U8 before_other; +// }; + +// struct zParticleSystem +// { +// S32 type; +// S32 need; +// zParticleGenerator** generators; +// S32 generators_size; +// S32 generators_active; + +// void destroy_generator(); +// void scene_exit(); +// void setup(); +// void reset(); +// void pre_render(); +// void render(); +// relative_ordering* get_ordering(S32& size); +// void scene_enter(); +// void update(); +// }; + +// struct xParticleBatchGroup +// { +// U8* elements; +// S32 elements_size; + +// void create(); +// }; + +// struct zParticleSystemWaterfall : zParticleSystem +// { +// S32 unk; +// xParticleBatchGroup batch_group; + +// S32 get_asset_size() const; +// void update(F32 dt); +// void scene_enter(); +// zParticleGenerator* create_generator(zParticleAsset& asset); +// }; + +// struct activity_data +// { +// }; + +// struct zParticleLocator +// { +// activity_data* activity; + +// void restart(); +// void scene_enter(); +// U8 activate(zParticleAsset& asset, xEnt* attach_to); +// void deactivate(); +// }; + +// struct zParticleGeneratorWaterfall : zParticleGenerator +// { +// S32 unk; +// zParticleSystemWaterfall* system; +// xEnt* attach_to; +// F32 emitted; //0x24 +// zParticleLocator locator; +// S32 batch_id; +// xVec3 vel_dir; + +// void deactivate(); +// void activate(); +// void reset(); +// void create(zParticleSystemWaterfall& system, zParticleAsset& asset); +// void update(F32 dt); +// }; + +// struct zParticleSystemWaterfallMist : zParticleSystem +// { +// S32 unk; +// xParticleBatchGroup batch_group; + +// S32 get_asset_size() const; +// void update(F32 dt); +// void scene_enter(); +// zParticleGenerator* create_generator(zParticleAsset& asset); +// }; + +// struct zParticleGeneratorWaterfallMist : zParticleGenerator +// { +// S32 unk; +// zParticleSystemWaterfallMist* system; +// xEnt* attach_to; +// F32 emitted; +// zParticleLocator locator; +// S32 batch_id; + +// void deactivate(); +// void activate(); +// void reset(); +// void create(zParticleSystemWaterfallMist& system, zParticleAsset& asset); +// void update(F32 dt); +// }; + +// struct zParticleSystemWaterfallSplash : zParticleSystem +// { +// S32 unk; +// xParticleBatchGroup batch_group; + +// S32 get_asset_size() const; +// void update(F32 dt); +// void scene_enter(); +// zParticleGenerator* create_generator(zParticleAsset& asset); +// }; + +// struct zParticleGeneratorWaterfallSplash : zParticleGenerator +// { +// S32 unk; +// zParticleSystemWaterfallSplash* system; +// xEnt* attach_to; +// F32 emitted; +// zParticleLocator locator; +// S32 batch_id; + +// void deactivate(); +// void activate(); +// void reset(); +// void create(zParticleSystemWaterfallSplash& system, zParticleAsset& asset); +// void update(F32 dt); +// }; + +// #endif + diff --git a/src/SB/Game/zPendulum.h b/src/SB/Game/zPendulum.h new file mode 100644 index 0000000..0f2d1dd --- /dev/null +++ b/src/SB/Game/zPendulum.h @@ -0,0 +1,30 @@ +#ifndef ZPENDULUM_H +#define ZPENDULUM_H + +#include "xEntMotion.h" + +#include "zEnt.h" + +#include + +struct _zPendulum : zEnt +{ + xEntMotion motion; + F32 lt; + F32 q1t; + F32 q3t; +}; + +void zPendulum_Init(void* pend, void* asset); +void zPendulum_Init(_zPendulum* pend, xEntAsset* asset); +void zPendulum_Save(_zPendulum* pend, xSerial* s); +void zPendulum_Load(_zPendulum* pend, xSerial* s); +void zPendulum_Setup(_zPendulum* pend, xScene* sc); +void zPendulum_Reset(_zPendulum* pend, xScene* sc); +void zPendulum_Update(_zPendulum* pend, xScene* sc, F32 dt); +void zPendulum_Move(_zPendulum* pend, xScene* sc, F32 dt, xEntFrame* frame); +void zPendulumTranslate(xEnt* xent, xVec3* dpos, xMat4x3* dmat); +S32 zPendulumEventCB(xBase* from, xBase* to, U32 event, const F32* toParam, + xBase* toParamWidget); + +#endif diff --git a/src/SB/Game/zPickupTable.h b/src/SB/Game/zPickupTable.h new file mode 100644 index 0000000..b90cfa1 --- /dev/null +++ b/src/SB/Game/zPickupTable.h @@ -0,0 +1,23 @@ +#ifndef ZPICKUPTABLE_H +#define ZPICKUPTABLE_H + +#include + +struct zAssetPickupTable +{ + U32 Magic; + U32 Count; +}; + +struct zAssetPickup +{ + U32 pickupHash; + U8 pickupType; + U8 pickupIndex; + U16 pickupFlags; + U32 quantity; + U32 modelID; + U32 animID; +}; + +#endif diff --git a/src/SB/Game/zPlatform.h b/src/SB/Game/zPlatform.h new file mode 100644 index 0000000..3be6b6f --- /dev/null +++ b/src/SB/Game/zPlatform.h @@ -0,0 +1,183 @@ +#ifndef ZPLATFORM_H +#define ZPLATFORM_H + +#include "zEnt.h" +#include "xEntMotion.h" +#include "xEntDrive.h" + +struct xPlatformERData +{ + S32 nodata; +}; + +struct xPlatformOrbitData +{ + S32 nodata; +}; + +struct xPlatformSplineData +{ + S32 nodata; +}; + +struct xPlatformMPData +{ + S32 nodata; +}; + +struct xPlatformMechData +{ + S32 nodata; +}; + +struct xPlatformPenData +{ + S32 nodata; +}; + +struct xPlatformConvBeltData +{ + F32 speed; +}; + +struct xPlatformFallingData +{ + F32 speed; + U32 bustModelID; +}; + +struct xPlatformFRData +{ + F32 fspeed; + F32 rspeed; + F32 ret_delay; + F32 post_ret_delay; +}; + +struct xPlatformBreakawayData +{ + F32 ba_delay; + U32 bustModelID; + F32 reset_delay; + U32 breakflags; +}; + +struct xPlatformSpringboardData +{ + F32 jmph[3]; + F32 jmpbounce; + U32 animID[3]; + xVec3 jmpdir; + U32 springflags; +}; + +struct xPlatformTeeterData +{ + F32 itilt; + F32 maxtilt; + F32 invmass; +}; + +struct xPlatformPaddleData +{ + S32 startOrient; + S32 countOrient; + F32 orientLoop; + F32 orient[6]; + U32 paddleFlags; + F32 rotateSpeed; + F32 accelTime; + F32 decelTime; + F32 hubRadius; +}; + +struct xPlatformFMData +{ + S32 nothingyet; +}; + +struct xPlatformAsset +{ + U8 type; + U8 pad; + U16 flags; + union + { + xPlatformERData er; + xPlatformOrbitData orb; + xPlatformSplineData spl; + xPlatformMPData mp; + xPlatformMechData mech; + xPlatformPenData pen; + xPlatformConvBeltData cb; + xPlatformFallingData fall; + xPlatformFRData fr; + xPlatformBreakawayData ba; + xPlatformSpringboardData sb; + xPlatformTeeterData teet; + xPlatformPaddleData paddle; + xPlatformFMData fm; + }; +}; + +struct zPlatFMRunTime +{ + U32 flags; + F32 tmrs[12]; + F32 ttms[12]; + F32 atms[12]; + F32 dtms[12]; + F32 vms[12]; + F32 dss[12]; +}; + +struct zPlatform : zEnt +{ + xPlatformAsset* passet; // 0xD4 + xEntMotion motion; + 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; + F32 pauseMult; + F32 pauseDelta; +}; + +#define ZPLATFORM_SUBTYPE_PLATFORM 0 +#define ZPLATFORM_SUBTYPE_MECH 4 +#define ZPLATFORM_SUBTYPE_PEN 5 +#define ZPLATFORM_SUBTYPE_CONVBELT 6 +#define ZPLATFORM_SUBTYPE_FALLING 7 +#define ZPLATFORM_SUBTYPE_FR 8 +#define ZPLATFORM_SUBTYPE_BREAKAWAY 9 +#define ZPLATFORM_SUBTYPE_SPRINGBOARD 10 +#define ZPLATFORM_SUBTYPE_TEETER 11 +#define ZPLATFORM_SUBTYPE_PADDLE 12 +#define ZPLATFORM_SUBTYPE_FM 13 + +#define ZPLATFORM_STATE_INIT 0x0 +#define ZPLATFORM_STATE_UNK1 0x3 +#define ZPLATFORM_STATE_UNK2 0x1 +#define ZPLATFORM_STATE_UNK3 0x2 +#define ZPLATFORM_STATE_UNK4 0x4 + +void zPlatform_Init(void* plat, void* asset); +void zPlatform_Init(zPlatform* plat, xEntAsset* asset); +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_PaddleStartRotate(class xEnt* entplat, S32 direction, S32 stutter); +void zPlatform_Update(xEnt* ent, xScene* sc, float dt); +void zPlatform_Shake(zPlatform* plat, F32 _unused, F32 ampl, F32 freq); +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 diff --git a/src/SB/Game/zPortal.cpp b/src/SB/Game/zPortal.cpp new file mode 100644 index 0000000..8ac82da --- /dev/null +++ b/src/SB/Game/zPortal.cpp @@ -0,0 +1,62 @@ +#include "xBase.h" +#include "xEvent.h" + +#include "zPortal.h" +#include "zGlobals.h" +#include "zScene.h" + +extern zGlobals globals; + +void zPortalInit(void* portal, void* passet) +{ + zPortalInit((_zPortal*)portal, (xPortalAsset*)passet); +} + +void zPortalInit(_zPortal* portal, xPortalAsset* passet) +{ + xBaseInit((xBase*)portal, (xBaseAsset*)passet); + + portal->passet = passet; + portal->eventFunc = (xBaseEventCB)zPortalEventCB; + + if (portal->linkCount != 0) + { + portal->link = (xLinkAsset*)(portal->passet + 1); + } +} + +void zPortalReset(_zPortal* portal) +{ + xBaseReset((xBase*)portal, (xBaseAsset*)portal->passet); +} + +void zPortalSave(_zPortal* ent, xSerial* s) +{ + xBaseSave((xBase*)ent, s); +} + +void zPortalLoad(_zPortal* ent, xSerial* s) +{ + xBaseLoad((xBase*)ent, s); +} + +S32 zPortalEventCB(xBase* from, xBase* to, U32 toEvent, const F32* toParam, xBase* b3) +{ + switch (toEvent) + { + case eEventReset: + { + zPortalReset((_zPortal*)to); + break; + } + case eEventTeleportPlayer: + { + if (globals.player.Health != 0) + { + zSceneSwitch((_zPortal*)to, false); + } + break; + } + } + return eEventEnable; +} diff --git a/src/SB/Game/zPortal.h b/src/SB/Game/zPortal.h new file mode 100644 index 0000000..8fe600e --- /dev/null +++ b/src/SB/Game/zPortal.h @@ -0,0 +1,25 @@ +#ifndef ZPORTAL_H +#define ZPORTAL_H + +#include "xBase.h" + +struct xPortalAsset : xBaseAsset +{ + U32 assetCameraID; + U32 assetMarkerID; + F32 ang; + U32 sceneID; +}; + +struct _zPortal : xBase +{ + xPortalAsset* passet; +}; + +void zPortalInit(void* portal, void* passet); +void zPortalInit(_zPortal* portal, xPortalAsset* passet); +void zPortalSave(_zPortal* ent, xSerial* s); +void zPortalLoad(_zPortal* ent, xSerial* s); +S32 zPortalEventCB(xBase* from, xBase* to, U32 toEvent, const F32* toParam, xBase* b3); + +#endif diff --git a/src/SB/Game/zRenderState.h b/src/SB/Game/zRenderState.h new file mode 100644 index 0000000..c9b793e --- /dev/null +++ b/src/SB/Game/zRenderState.h @@ -0,0 +1,38 @@ +#ifndef ZRENDERSTATE_H +#define ZRENDERSTATE_H + +#include + +enum _SDRenderState +{ + SDRS_Unknown, + SDRS_Default, + SDRS_OpaqueModels, + SDRS_AlphaModels, + SDRS_Bubble, + SDRS_Projectile, + SDRS_Font, + SDRS_HUD, + SDRS_Particles, + SDRS_Lightning, + SDRS_Streak, + SDRS_SkyBack, + SDRS_Environment, + SDRS_Fill, + SDRS_NPCVisual, + SDRS_OOBFade, + SDRS_OOBPlayerZ, + SDRS_OOBPlayerAlpha, + SDRS_OOBHand, + SDRS_Glare, + SDRS_Newsfish, + SDRS_CruiseHUD, + SDRS_DiscoFloorGlow, + SDRS_Total = 0xffffffff +}; + +void zRenderStateInit(); +_SDRenderState zRenderStateCurrent(); +void zRenderState(_SDRenderState newState); + +#endif \ No newline at end of file diff --git a/src/SB/Game/zRumble.h b/src/SB/Game/zRumble.h new file mode 100644 index 0000000..4c79463 --- /dev/null +++ b/src/SB/Game/zRumble.h @@ -0,0 +1,41 @@ +#ifndef ZRUMBLE_H +#define ZRUMBLE_H + +#include +#include "xEnt.h" +#include "xPad.h" + +enum _tagSDRumbleType +{ + SDR_None, + SDR_Test, + SDR_Damage, + SDR_Bounce, + SDR_EventLight, + SDR_EventMedium, + SDR_EventHeavy, + SDR_DustDestroyedObj, + SDR_XploDestroyedObj, + SDR_WebDestroyed, + SDR_Tiki, + SDR_LassoDestroy, + SDR_DamageByEGen, + SDR_BounceHit, + SDR_CruiseBubbleLaunch, + SDR_CruiseBubbleExplode, + SDR_TeleportStart, + SDR_Teleport, + SDR_TeleportEject, + SDR_Total +}; + +void zRumbleStart(S32 pad_id, _tagSDRumbleType rumble_type, xEnt* ent); +void zRumbleStart(S32 pad_id, _tagSDRumbleType rumble_type); +void zRumbleStart(_tagSDRumbleType rumble_type); +void zRumbleStart(_tagSDRumbleType rumble_type, xEnt* ent); +void zRumbleStartDistance(S32 pad_id, F32 real_dist, F32 max_dist, _tagRumbleType type, + F32 maxTime); +void zRumbleStartEntDistance(xEnt* ent, F32 dist, _tagRumbleType type, F32 maxTime); +S32 zPadAddRumble(_tagRumbleType type, F32 time, S32 replace, U32 fxflags); + +#endif diff --git a/src/SB/Game/zSaveLoad.h b/src/SB/Game/zSaveLoad.h new file mode 100644 index 0000000..aea967d --- /dev/null +++ b/src/SB/Game/zSaveLoad.h @@ -0,0 +1,105 @@ +#ifndef ZSAVELOAD_H +#define ZSAVELOAD_H + +#include +#include "xsavegame.h" +struct st_XSAVEGAME_DATA; + +struct zSaveLoadGame +{ + char label[64]; + char date[32]; + S32 progress; + U32 size; + S8 thumbIconIndex; +}; + +struct zSaveLoadUI +{ + U32 entry; + U32 nameID; + char* name; +}; + + +zSaveLoadGame zSaveLoadGameTable[3]; + +void zUpdateThumbIcon(); +void zSaveLoad_Tick(); +S32 zSaveLoad_poll(S32 i); +void zSendEventToThumbIcon(U32 toEvent); +void zChangeThumbIcon(const char* icon); + +void zSaveLoadInit(); +void zSaveLoadGameTableInit(zSaveLoadGame* saveTable); +void zSaveLoadUITableInit(zSaveLoadUI* saveTable); +void zSaveLoad_UIEvent(S32 p1, U32 p2); +st_XSAVEGAME_DATA* zSaveLoadSGInit(en_SAVEGAME_MODE mode); + +S32 zSaveLoadSGDone(st_XSAVEGAME_DATA* data); +S32 zSaveLoad_getgame(); +S32 zSaveLoad_getcard(); +S32 zSaveLoad_getMCavailable(); +S32 zSaveLoad_getMCneeded(); +S32 zSaveLoad_getMCAccessType(); +S32 zSaveLoadGetAutoSaveCard(); +S32 format(S32 num, S32 mode); +S32 CardtoTgt(S32 card); +S32 zSaveLoad_CardCount(); +S32 zSaveLoad_CardPrompt(S32 cardNumber); +S32 zSaveLoad_CardPromptFormat(S32 mode); +S32 zSaveLoad_CardPromptSpace(S32 mode); +S32 zSaveLoad_CardPromptGames(S32 mode); +S32 zSaveLoad_CardPromptGameSlotEmpty(); +S32 zSaveLoad_CardPromptOverwrite(); +S32 zSaveLoad_CardPromptOverwriteDamaged(); +S32 zSaveLoad_ErrorPrompt(S32 cardNumber); +S32 zSaveLoad_DamagedSaveGameErrorPrompt(S32 cardNumber); +S32 zSaveLoad_CardWrongDeviceErrorPrompt(S32 mode); +S32 zSaveLoad_CardDamagedErrorPrompt(S32 mode); +S32 zSaveLoad_SaveDamagedErrorPrompt(S32 cardNumber); +S32 zSaveLoad_CardYankedErrorPrompt(S32 cardNumber); +S32 zSaveLoad_ErrorFormatPrompt(S32 cardNumber); +S32 zSaveLoad_ErrorFormatCardYankedPrompt(S32 cardNumber); +S32 zSaveLoad_CardCheckSingle(S32 cardNumber); +S32 zSaveLoad_CardCheckFormattedSingle(S32 cardNumber); +S32 zSaveLoad_CardCheckSpaceSingle_doCheck(st_XSAVEGAME_DATA* xsgdata, S32 cardNumber); +S32 zSaveLoad_CardCheckSpaceSingle(S32 cardNumber); +S32 zSaveLoad_CardCheckGamesSingle_doCheck(st_XSAVEGAME_DATA* xsgdata, S32 cardNumber); +S32 zSaveLoad_CardCheckGamesSingle(S32 cardNumber); +S32 zSaveLoad_CardCheckSlotEmpty_hasGame_doCheck(st_XSAVEGAME_DATA* xsgdata, S32 cardNumber, + S32 gameNumber); +S32 zSaveLoad_CardCheckSlotEmpty_hasGame(S32 cardNumber, S32 gameNumber); +S32 zSaveLoad_CardCheckSlotOverwrite_Free(S32 cardNumber, S32 gameNumber); +S32 zSaveLoad_CardCheck(S32 cardNumber, S32 mode); +S32 zSaveLoad_CardCheckValid(S32 cardNumber, S32 mode); +S32 zSaveLoad_CardCheckSpace(S32 cardNumber, S32 mode); +S32 zSaveLoad_CardCheckGames(S32 cardNumber, S32 mode); +S32 zSaveLoad_CardCheckGameSlot(S32 cardNumber, S32 gameNumber, S32 mode); +S32 zSaveLoad_CardCheckSlotEmpty(S32 cardNumber, S32 gameNumber); +S32 zSaveLoad_CardCheckSlotOverwrite(S32 cardNumber, S32 gameNumber); +S32 zSaveLoad_CardPick(S32 mode); +bool IsValidName(char* name); +void BuildIt(char* build_txt, S32 i); +void zSaveLoad_BuildName(char* name_txt, S32 idx); +S32 zSaveLoad_GameSelect(S32 mode); +U8 zSaveLoadGetPreAutoSave(); +void zSaveLoadPreAutoSave(bool onOff); +void zSaveLoadAutoSaveUpdate(); +S32 zSaveLoad_DoAutoSave(); +S32 zSaveLoad_SaveGame(); +S32 zSaveLoad_LoadGame(); +U32 zSaveLoad_LoadLoop(); +U32 zSaveLoad_SaveLoop(); +void zSaveLoad_DispatchCB(U32 dispatchEvent, const F32* toParam); +S32 xSGT_SaveInfoCB(void* vp, st_XSAVEGAME_DATA* xsgdata, S32* need, S32* most); +S32 xSGT_SaveProcCB(void* vp, st_XSAVEGAME_DATA* xsgdata, st_XSAVEGAME_WRITECONTEXT* wctxt); +S32 xSGT_SaveInfoPrefsCB(void* p1, st_XSAVEGAME_DATA* data, S32* i, S32* j); +S32 xSGT_SaveProcPrefsCB(void* vp, st_XSAVEGAME_DATA* xsgdata, st_XSAVEGAME_WRITECONTEXT* wctxt); +S32 xSGT_LoadLoadCB(void* vp, st_XSAVEGAME_DATA* xsgdata, st_XSAVEGAME_READCONTEXT* rctxt, + U32 ui, S32 i); +S32 xSGT_LoadPrefsCB(void* vp, st_XSAVEGAME_DATA* xsgdata, st_XSAVEGAME_READCONTEXT* rctxt, + U32 ui, S32 i); +U32 zSaveLoad_slotIsEmpty(U32 slot); + +#endif diff --git a/src/SB/Game/zScene.cpp b/src/SB/Game/zScene.cpp new file mode 100644 index 0000000..5a9b789 --- /dev/null +++ b/src/SB/Game/zScene.cpp @@ -0,0 +1,3586 @@ +#include "zScene.h" + +#include "zEntTrigger.h" +#include "zMovePoint.h" +#include "zEntPickup.h" +#include "zEntSimpleObj.h" +#include "zPlatform.h" +#include "zPendulum.h" +#include "zEntHangable.h" +#include "zEntDestructObj.h" +#include "zEntButton.h" +#include "zPortal.h" +#include "zCamMarker.h" +#include "zGust.h" +#include "zVolume.h" +#include "zConditional.h" +#include "zEnv.h" +#include "zUI.h" +#include "zUIFont.h" +#include "zLight.h" +#include "zCutsceneMgr.h" +#include "zEGenerator.h" +#include "zScript.h" +#include "zDiscoFloor.h" +#include "zEntTeleportBox.h" +#include "zBusStop.h" +#include "zTextBox.h" +#include "zTalkBox.h" +#include "zTaskBox.h" +#include "zTaxi.h" +#include "zEntPlayerBungeeState.h" +#include "zCameraFly.h" +#include "zCameraTweak.h" +#include "zNPCMgr.h" +#include "zGlobals.h" +#include "zDispatcher.h" +#include "zThrown.h" +#include "zGrid.h" +#include "zFX.h" +#include "zSurface.h" +#include "zGoo.h" +#include "zParPTank.h" +#include "zAnimList.h" +#include "zParSys.h" +#include "zRenderState.h" +#include "zGame.h" +#include "zNPCGlyph.h" +#include "zNPCHazard.h" +#include "zEntPlayerOOBState.h" +#include "zActionLine.h" +#include "zGameState.h" +#include "zEntCruiseBubble.h" +#include "zHud.h" +#include "zMenu.h" +#include "zNPCTypeBossSandy.h" +#include "zNPCTypeBossPatrick.h" +#include "zCombo.h" +#include "zLOD.h" +#include "zMusic.h" +#include "zNPCTypeTiki.h" +#include "zGameExtras.h" +#include "zCollGeom.h" +#include "zFeet.h" +#include "zParCmd.h" +#include "zAssetTypes.h" + +#include "xNPCBasic.h" +#include "xString.h" +#include "xstransvc.h" +#include "xDynAsset.h" +#include "xParSys.h" +#include "xParEmitter.h" +#include "xEntBoulder.h" +#include "xTimer.h" +#include "xCounter.h" +#include "xSFX.h" +#include "xGroup.h" +#include "xSurface.h" +#include "xFog.h" +#include "xHudModel.h" +#include "xHudFontMeter.h" +#include "xHudUnitMeter.h" +#include "xHudText.h" +#include "iModel.h" +#include "xutil.h" +#include "xModelBucket.h" +#include "xFX.h" +#include "xDecal.h" +#include "xPtankPool.h" +#include "xSystem.h" +#include "xSkyDome.h" +#include "xShadow.h" +#include "xParMgr.h" +#include "xScrFx.h" +#include "xTRC.h" +#include "xCM.h" +#include "xMath.h" +#include "iMath.h" +#include "xMarkerAsset.h" +#include "xPartition.h" +#include "xMathInlines.h" + +#include +#include + +U8 HACK_BASETYPE; +static S32 bytesNeeded; +static S32 availOnDisk; +static S32 neededFiles; +static F32 offsetx; +static F32 offsety; +static U32 enableScreenAdj; +volatile static F32 oldOffsetx; +volatile static F32 oldOffsety; +static S32 sMemDepthSceneStart = -1; +static S32 sMemDepthJustHIPStart = -1; +_zEnv* gCurEnv; +U32 gTransitionSceneID; +F32 gSceneUpdateTime; +static xVec3 sOldPosPlayer; +static xVec3 sOldPosCamera; +static U32 sSuddenMove; + +struct zSceneLevel +{ + const char* desc; + const char* prefix; +}; + +// clang-format off +static zSceneLevel sLevelTable[] = +{ + { "Bikini Bottom", "HB" }, + { "Jellyfish Fields", "JF"} , + { "Downtown Bikini Bottom", "BB" }, + { "Goo Lagoon", "GL" }, + { "Poseidome", "B1" }, + { "Rock Bottom", "RB" }, + { "Mermalair", "BC" }, + { "Sand Mountain", "SM" }, + { "Industrial Park", "B2" }, + { "Kelp Forest", "KF" }, + { "Flying Dutchman's Graveyard", "GY" }, + { "Spongebob's Dream", "DB" }, + { "Chum Bucket Lab", "B3" }, + { "PLAYGROUND", "PG" }, + { "Start", "MN" } +}; +// clang-format on + +struct zSceneObjectInstanceDesc +{ + const char* name; + S32 baseType; + U32 assetType; + U32 sizeRuntime; + U32 (*func)(zScene* s, zSceneObjectInstanceDesc* desc, U32 base_idx); + void (*objectInitFunc)(void* ent, void* asset); + U32 (*querySubObjects)(void*); +}; + +static U32 zSceneInitFunc_DefaultEnt(zScene* s, zSceneObjectInstanceDesc* desc, U32 base_idx); +static U32 zSceneInitFunc_Default(zScene* s, zSceneObjectInstanceDesc* desc, U32 base_idx); +static U32 zSceneInitFunc_MovePoint(zScene* s, zSceneObjectInstanceDesc* desc, U32 base_idx); +static U32 zSceneInitFunc_SBNPC(zScene* s, zSceneObjectInstanceDesc* desc, U32 base_idx); +static U32 zSceneInitFunc_Player(zScene* s, zSceneObjectInstanceDesc* desc, U32 base_idx); +static U32 zSceneInitFunc_Camera(zScene* s, zSceneObjectInstanceDesc* desc, U32 base_idx); +static U32 zSceneInitFunc_Surface(zScene* s, zSceneObjectInstanceDesc* desc, U32 base_idx); +static U32 zSceneInitFunc_Gust(zScene* s, zSceneObjectInstanceDesc* desc, U32 base_idx); +static U32 zSceneInitFunc_Volume(zScene* s, zSceneObjectInstanceDesc* desc, U32 base_idx); +static U32 zSceneInitFunc_LobMaster(zScene* s, zSceneObjectInstanceDesc* desc, U32 base_idx); +static U32 zSceneInitFunc_Dispatcher(zScene* s, zSceneObjectInstanceDesc* desc, U32 base_idx); + +// clang-format off +static zSceneObjectInstanceDesc sInitTable[] = +{ + { "Trig", eBaseTypeTrigger, 'TRIG', sizeof(zEntTrigger), zSceneInitFunc_DefaultEnt, zEntTriggerInit, NULL }, + { "Move Point", eBaseTypeMovePoint, 'MVPT', sizeof(zMovePoint), zSceneInitFunc_MovePoint, NULL, NULL }, + { "Pickup", eBaseTypePickup, 'PKUP', sizeof(zEntPickup), zSceneInitFunc_DefaultEnt, zEntPickupInit, NULL }, + { "Simple", eBaseTypeStatic, 'SIMP', sizeof(zEntSimpleObj), zSceneInitFunc_DefaultEnt, zEntSimpleObj_Init, NULL }, + { "ParticleSystem", eBaseTypeParticleSystem, 'PARS', sizeof(xParSys), zSceneInitFunc_Default, xParSysInit, NULL }, + { "ParticleEmitter", eBaseTypeParticleEmitter, 'PARE', sizeof(xParEmitter), zSceneInitFunc_Default, xParEmitterInit, NULL }, + { "Track", eBaseTypeTrackPhysics, 'TRCK', sizeof(zEntSimpleObj), zSceneInitFunc_DefaultEnt, zEntTrackPhysics_Init, NULL }, + { "Platform", eBaseTypePlatform, 'PLAT', sizeof(zPlatform), zSceneInitFunc_DefaultEnt, zPlatform_Init, NULL }, + { "Pendulum", eBaseTypePendulum, 'PEND', sizeof(_zPendulum), zSceneInitFunc_DefaultEnt, zPendulum_Init, NULL }, + { "Hanger", eBaseTypeHangable, 'HANG', sizeof(zEntHangable), zSceneInitFunc_DefaultEnt, zEntHangable_Init, NULL }, + { "DestructObj", eBaseTypeDestructObj, 'DSTR', sizeof(zEntDestructObj), zSceneInitFunc_DefaultEnt, zEntDestructObj_Init, NULL }, + { "Boulder", eBaseTypeBoulder, 'BOUL', sizeof(xEntBoulder), zSceneInitFunc_DefaultEnt, xEntBoulder_Init, NULL }, + { "NPC", eBaseTypeNPC, 'VIL ', 0, zSceneInitFunc_SBNPC, NULL, NULL }, + { "Button", eBaseTypeButton, 'BUTN', sizeof(_zEntButton), zSceneInitFunc_DefaultEnt, zEntButton_Init, NULL }, + { "Player", eBaseTypePlayer, 'PLYR', sizeof(zEnt), zSceneInitFunc_Player, NULL, NULL }, + { "Timer", eBaseTypeTimer, 'TIMR', sizeof(xTimer), zSceneInitFunc_Default, xTimerInit, NULL }, + { "Counter", eBaseTypeCounter, 'CNTR', sizeof(_xCounter), zSceneInitFunc_Default, xCounterInit, NULL }, + { "SFX", eBaseTypeSFX, 'SFX ', sizeof(xSFX), zSceneInitFunc_Default, xSFXInit, NULL }, + { "Group", eBaseTypeGroup, 'GRUP', sizeof(xGroup), zSceneInitFunc_Default, xGroupInit, NULL }, + { "Portal", eBaseTypePortal, 'PORT', sizeof(_zPortal), zSceneInitFunc_Default, zPortalInit, NULL }, + { "Camera", eBaseTypeCamera, 'CAM ', sizeof(zCamMarker), zSceneInitFunc_Camera, NULL, NULL }, + { "Surface", eBaseTypeSurface, 'SURF', sizeof(xSurface), zSceneInitFunc_Surface, NULL, NULL }, + { "Gust", eBaseTypeGust, 'GUST', sizeof(zGust), zSceneInitFunc_Gust, NULL, NULL }, + { "Volume", eBaseTypeVolume, 'VOLU', sizeof(zVolume), zSceneInitFunc_Volume, NULL, NULL }, + { "Conditional", eBaseTypeCond, 'COND', sizeof(_zConditional), zSceneInitFunc_Default, zConditionalInit, NULL }, + { "Lob Master", eBaseTypeLobMaster, 'LOBM', 0, zSceneInitFunc_LobMaster, NULL, NULL }, + { "Env", eBaseTypeEnv, 'ENV ', sizeof(_zEnv), zSceneInitFunc_Default, zEnvInit, NULL }, + { "Dispatcher", eBaseTypeDispatcher, 'DPAT', 0, zSceneInitFunc_Dispatcher, NULL, NULL }, + { "UI", eBaseTypeUI, 'UI ', sizeof(_zUI), zSceneInitFunc_DefaultEnt, zUI_Init, NULL }, + { "UI Font", eBaseTypeUIFont, 'UIFT', sizeof(zUIFont), zSceneInitFunc_Default, zUIFont_Init, NULL }, + { "Fog", eBaseTypeFog, 'FOG ', sizeof(_xFog), zSceneInitFunc_Default, xFogInit, NULL }, + { "Light", eBaseTypeLight, 'LITE', sizeof(_zLight), zSceneInitFunc_Default, zLightInit, NULL }, + { "CutSceneMgr", eBaseTypeCutsceneMgr, 'CSNM', sizeof(zCutsceneMgr), zSceneInitFunc_Default, zCutsceneMgrInit, NULL }, + { "EGenerator", eBaseTypeEGenerator, 'EGEN', sizeof(zEGenerator), zSceneInitFunc_DefaultEnt, zEGenerator_Init, NULL }, + { "Script", eBaseTypeScript, 'SCRP', sizeof(_zScript), zSceneInitFunc_Default, zScriptInit, NULL }, + { "Disco Floor", eBaseTypeDiscoFloor, 'DSCO', sizeof(z_disco_floor), zSceneInitFunc_Default, z_disco_floor::init, NULL }, + { NULL } +}; +// clang-format on + +extern U32 _1251; +extern char byte_803D0884; +extern U32 _2014; + +extern U32 _1250; +extern F32 _1373; +extern F32 _1374; +extern F32 _1375; +extern F32 _1493; +extern F32 _1494; +extern F32 _1495; +extern F32 _1496_0; +extern U32 _2013; +extern F32 _2094; +extern F32 _2095_0; +extern F32 _2096_0; +extern F32 _2097_0; +extern F32 _2242; + +static void zSceneObjHashtableInit(S32 count); +static void zSceneObjHashtableExit(); +static S32 zSceneObjHashtableUsage(); +static void zSceneObjHashtableAdd(U32 id, xBase* base); +static xBase* zSceneObjHashtableGet(U32 id); +static xBase* zSceneExitSoundIteratorCB(xBase* b, zScene*, void*); +static void zSceneAutoSave(); + +namespace +{ + struct dynamic_type_data + { + const char* name; + S32 type; + size_t size; + bool is_ent; + void (*load)(xBase& data, xDynAsset& asset, size_t size); + }; + + extern const dynamic_type_data dynamic_types[14]; + + // clang-format off + const dynamic_type_data dynamic_types[] = + { + { "game_object:Teleport", eBaseTypeTeleportBox, sizeof(_zEntTeleportBox), true, zEntTeleportBox_Init }, + { "game_object:BusStop", eBaseTypeBusStop, sizeof(zBusStop), false, zBusStop_Init }, + { "game_object:text_box", eBaseTypeTextBox, sizeof(ztextbox), false, ztextbox::load }, + { "game_object:talk_box", eBaseTypeTalkBox, sizeof(ztalkbox), false, ztalkbox::load }, + { "game_object:task_box", eBaseTypeTaskBox, sizeof(ztaskbox), false, ztaskbox::load }, + { "game_object:BoulderGenerator", eBaseTypeBoulderGenerator, sizeof(xBoulderGenerator), false, xBoulderGenerator_Init }, + { "game_object:Taxi", eBaseTypeTaxi, sizeof(zTaxi), false, zTaxi_Init }, + { "hud:model", eBaseTypeHUD_model, sizeof(xBase) + sizeof(xhud::model_widget), false, xhud::model_widget::load }, + { "hud:meter:font", eBaseTypeHUD_font_meter, sizeof(xBase) + sizeof(xhud::font_meter_widget), false, xhud::font_meter_widget::load }, + { "hud:meter:unit", eBaseTypeHUD_unit_meter, sizeof(xBase) + sizeof(xhud::unit_meter_widget), false, xhud::unit_meter_widget::load }, + { "hud:text", eBaseTypeHUD_text, sizeof(xBase) + sizeof(xhud::text_widget), false, xhud::text_widget::load }, + { "game_object:bungee_hook", eBaseTypeBungeeHook, sizeof(bungee_state::hook_type), false, bungee_state::load }, + { "game_object:Flythrough", eBaseTypeCameraFly, sizeof(zCameraFly), false, zCameraFly_Init }, + { "game_object:Camera_Tweak", eBaseTypeCameraTweak, sizeof(zCameraTweak), false, zCameraTweak_Init } + }; + // clang-format on + + S32 count_dynamic_types(const char* name) + { + U32 type = xStrHash(name); + S32 dynaCount = xSTAssetCountByType('DYNA'); + S32 count = 0; + + for (S32 i = 0; i < dynaCount; i++) + { + U32 size; + xDynAsset* asset = (xDynAsset*)xSTFindAssetByType('DYNA', i, &size); + + if (asset && asset->type == type) + { + count++; + } + } + + return count; + } + + void add_dynamic_types(zScene& s) + { + for (S32 i = 0; i < sizeof(dynamic_types) / sizeof(dynamic_types[0]); i++) + { + S32 count = count_dynamic_types(dynamic_types[i].name); + + s.baseCount[dynamic_types[i].type] = count; + s.num_base += count; + } + } + + U32 init_dynamic_type(zScene& s, U32 index, const dynamic_type_data& d) + { + U32 count, type; + S32 dyn_size, i, cnt; + + s.baseList[d.type] = NULL; + + if (s.baseCount[d.type] == 0) + { + return index; + } + + if (d.size) + { + dyn_size = s.baseCount[d.type] * d.size; + s.baseList[d.type] = (xBase*)xMemAllocSize(dyn_size); + } + + type = xStrHash(d.name); + count = xSTAssetCountByType('DYNA'); + + for (i = 0, cnt = 0; i < (S32)count; i++) + { + U32 asset_size; + xDynAsset* a; + xBase* b; + + a = (xDynAsset*)xSTFindAssetByType('DYNA', i, &asset_size); + + if (a && a->type == type) + { + a->baseType = d.type; + + xSTAssetName(a); + + b = (xBase*)((U8*)s.baseList[d.type] + cnt * d.size); + + zSceneSet(b, index); + + if (d.load) + { + d.load(*b, *a, asset_size); + } + + if (d.is_ent) + { + xSceneAddEnt(&s, s.ents[index]); + } + + zSceneObjHashtableAdd(b->id, b); + + index++; + cnt++; + } + } + + return index; + } + + U32 init_dynamic_types(zScene& s, U32 index) + { + for (S32 i = 0; i < sizeof(dynamic_types) / sizeof(dynamic_types[0]); i++) + { + if (dynamic_types[i].load) + { + index = init_dynamic_type(s, index, dynamic_types[i]); + } + } + + return index; + } +} // namespace + +struct IDBasePair +{ + U32 id; + xBase* base; +}; + +static IDBasePair* scobj_idbps; +static S32 scobj_size = -1; +static S32 nidbps = -1; + +static U32 zSceneInitFunc_DefaultEnt(zScene* s, zSceneObjectInstanceDesc* desc, U32 base_idx) +{ + U8* block; + S32 count; + U32 assetSize, offset; + xBase* b; + + block = NULL; + assetSize = 0; + offset = desc->sizeRuntime; + count = s->baseCount[desc->baseType]; + + if (count) + { + block = (U8*)xMemAllocSize(count * offset); + + s->baseList[desc->baseType] = (xBase*)block; + } + + for (S32 i = 0; i < count; i++) + { + void* asset = xSTFindAssetByType(desc->assetType, i, &assetSize); + b = (xBase*)(block + i * offset); + + zSceneSet(b, base_idx); + + if (desc->objectInitFunc) + { + desc->objectInitFunc(b, asset); + } + + xSceneAddEnt(s, s->ents[base_idx]); + zSceneObjHashtableAdd(b->id, b); + + base_idx++; + } + + return base_idx; +} + +static U32 zSceneInitFunc_Default(zScene* s, zSceneObjectInstanceDesc* desc, U32 base_idx) +{ + U8* block; + S32 count; + U32 assetSize, offset; + xBase* b; + + block = NULL; + assetSize = 0; + offset = desc->sizeRuntime; + count = s->baseCount[desc->baseType]; + + if (count) + { + block = (U8*)xMemAllocSize(count * offset); + + s->baseList[desc->baseType] = (xBase*)block; + } + + for (S32 i = 0; i < count; i++) + { + void* asset = xSTFindAssetByType(desc->assetType, i, &assetSize); + b = (xBase*)(block + i * offset); + + zSceneSet(b, base_idx); + + if (desc->objectInitFunc) + { + desc->objectInitFunc(b, asset); + } + + zSceneObjHashtableAdd(b->id, b); + + base_idx++; + } + + return base_idx; +} + +static U32 zSceneInitFunc_MovePoint(zScene* s, zSceneObjectInstanceDesc* desc, U32 base_idx) +{ + S32 count; + U32 assetSize; + zMovePoint* movpBlock; + + assetSize = 0; + count = s->baseCount[desc->baseType]; + movpBlock = zMovePoint_GetMemPool(count); + + if (movpBlock) + { + s->baseList[desc->baseType] = movpBlock; + + for (S32 idx = 0; idx < count; idx++) + { + xBase* b = zMovePoint_GetInst(idx); + xBaseAsset* basset = (xBaseAsset*)xSTFindAssetByType('MVPT', idx, &assetSize); + + zSceneSet(b, base_idx); + zMovePointInit(zMovePoint_GetInst(idx), (xMovePointAsset*)basset); + zSceneObjHashtableAdd(b->id, b); + + base_idx++; + } + } + + return base_idx; +} + +static U32 zSceneInitFunc_SBNPC(zScene* s, zSceneObjectInstanceDesc* desc, U32 base_idx) +{ + S32 count; + + count = s->baseCount[desc->baseType]; + + if (count == 0) + { + return base_idx; + } + + s->baseList[desc->baseType] = NULL; + + for (S32 i = 0; i < count; i++) + { + xEnt* ent; + xEntAsset* assdat; + + assdat = (xEntAsset*)xSTFindAssetByType('VIL ', i, NULL); + ent = zNPCMgr_createNPCInst(i, assdat); + + zSceneSet(ent, base_idx); + xSceneAddEnt(s, s->ents[base_idx]); + zSceneObjHashtableAdd(ent->id, ent); + + base_idx++; + } + + return base_idx; +} + +static U32 zSceneInitFunc_Player(zScene* s, zSceneObjectInstanceDesc* desc, U32 base_idx) +{ + S32 count; + zEnt* entBlock; + + count = s->baseCount[desc->baseType]; + + if (count) + { + entBlock = (zEnt*)xMemAllocSize(count * sizeof(zEnt)); + + s->baseList[desc->baseType] = entBlock; + + for (S32 idx = 0; idx < count; idx++) + { + xBase* b = &globals.player.ent; + xEntAsset* asset; + + zSceneSet(b, base_idx); + + if (idx == count - 1) + { + xSceneAddEnt(s, s->ents[base_idx]); + } + + asset = (xEntAsset*)xSTFindAssetByType('PLYR', idx, NULL); + + globals.player.ent.id = asset->id; + + zSceneObjHashtableAdd(asset->id, b); + + base_idx++; + } + } + + return base_idx; +} + +static U32 zSceneInitFunc_Camera(zScene* s, zSceneObjectInstanceDesc* desc, U32 base_idx) +{ + S32 count; + zCamMarker* camBlock; + + count = s->baseCount[desc->baseType]; + + if (count) + { + camBlock = (zCamMarker*)xMemAllocSize(count * sizeof(zCamMarker)); + s->baseList[desc->baseType] = camBlock; + + for (S32 idx = 0; idx < count; idx++) + { + xBase* b = &camBlock[idx]; + xCamAsset* assetCam = (xCamAsset*)xSTFindAssetByType('CAM ', idx, NULL); + + zSceneSet(b, base_idx); + zCamMarkerInit(b, assetCam); + zSceneObjHashtableAdd(b->id, b); + + base_idx++; + } + } + + return base_idx; +} + +static U32 zSceneInitFunc_Surface(zScene* s, zSceneObjectInstanceDesc* desc, U32 base_idx) +{ + S32 count; + + count = s->baseCount[desc->baseType]; + + if (count) + { + s->baseList[desc->baseType] = xSurfaceGetByIdx(0); + + for (S32 idx = 0; idx < count; idx++) + { + xBase* b = xSurfaceGetByIdx(idx); + + zSceneSet(b, base_idx); + zSceneObjHashtableAdd(b->id, b); + + base_idx++; + } + } + + return base_idx; +} + +static U32 zSceneInitFunc_Gust(zScene* s, zSceneObjectInstanceDesc* desc, U32 base_idx) +{ + S32 count; + + count = s->baseCount[desc->baseType]; + + zGustInit(); + + if (count) + { + s->baseList[desc->baseType] = zGustGetGust(0); + + for (S32 idx = 0; idx < count; idx++) + { + xBase* b = zGustGetGust(idx); + + zSceneSet(b, base_idx); + zSceneObjHashtableAdd(b->id, b); + + base_idx++; + } + } + + return base_idx; +} + +static U32 zSceneInitFunc_Volume(zScene* s, zSceneObjectInstanceDesc* desc, U32 base_idx) +{ + S32 count; + + count = s->baseCount[desc->baseType]; + + zVolumeInit(); + + if (count) + { + s->baseList[desc->baseType] = zVolumeGetVolume(0); + + for (S32 idx = 0; idx < count; idx++) + { + xBase* b = zVolumeGetVolume(idx); + + zLightSetVolume((zVolume*)b); + + zSceneSet(b, base_idx); + zSceneObjHashtableAdd(b->id, b); + + base_idx++; + } + } + + return base_idx; +} + +static U32 zSceneInitFunc_LobMaster(zScene* s, zSceneObjectInstanceDesc* desc, U32 base_idx) +{ + return base_idx; +} + +static U32 zSceneInitFunc_Dispatcher(zScene* s, zSceneObjectInstanceDesc* desc, U32 base_idx) +{ + S32 count; + + count = s->baseCount[desc->baseType]; + + if (count) + { + st_ZDISPATCH_DATA* dpat_pool = zDispatcher_memPool(count); + s->baseList[desc->baseType] = dpat_pool; + + for (S32 idx = 0; idx < count; idx++) + { + xBase* b = zDispatcher_getInst(dpat_pool, idx); + xEntAsset* asset = (xEntAsset*)xSTFindAssetByType('DPAT', idx, NULL); + + zSceneSet(b, base_idx); + zDispatcher_Init((st_ZDISPATCH_DATA*)b, asset); + zSceneObjHashtableAdd(b->id, b); + + base_idx++; + } + } + + return base_idx; +} + +void zSceneSet(xBase* b, U32 index) +{ + globals.sceneCur->base[index] = b; +} + +static void PipeCountStuffCB(RpAtomic*, U32 pipeFlags, U32) +{ + if (pipeFlags) + { + xModelLookupCount++; + } +} + +static void PipeAddStuffCB(RpAtomic* data, U32 pipeFlags, U32) +{ + if (pipeFlags) + { + xModelLookupList[xModelLookupCount].model = data; + xModelLookupList[xModelLookupCount].PipeFlags = pipeFlags; + xModelLookupCount++; + } +} + +static void PipeForAllSceneModels(void (*pipeCB)(RpAtomic* data, U32 pipeFlags, U32 subObjects)) +{ + // non-matching: wrong registers + + S32 i, j, k; + S32 numModels = xSTAssetCountByType('MODL'); + + for (i = 0; i < numModels; i++) + { + RpAtomic* model = (RpAtomic*)xSTFindAssetByType('MODL', i, NULL); + + if (model) + { + st_PKR_ASSET_TOCINFO ainfo; + U32 numSubObjects, remainSubObjBits, currSubObjBits; + RpAtomic* tempmodel; + + xSTGetAssetInfoByType('MODL', i, &ainfo); + + numSubObjects = 0; + tempmodel = model; + + do + { + numSubObjects++; + tempmodel = iModelFile_RWMultiAtomic(tempmodel); + } while (tempmodel); + + remainSubObjBits = (1 << numSubObjects) - 1; + + for (j = 0; j < xModelPipeNumTables; j++) + { + for (k = 0; k < xModelPipeCount[j]; k++) + { + if (ainfo.aid == xModelPipeData[j][k].ModelHashID) + { + currSubObjBits = remainSubObjBits & xModelPipeData[j][k].SubObjectBits; + + if (currSubObjBits) + { + pipeCB(model, xModelPipeData[j][k].PipeFlags, currSubObjBits); + } + + remainSubObjBits &= ~currSubObjBits; + + if (!remainSubObjBits) + { + goto loc_800B1698; + } + } + } + } + + if (remainSubObjBits) + { + pipeCB(model, 0, remainSubObjBits); + } + } + + loc_800B1698: + continue; + } +} + +void zSceneInitEnvironmentalSoundEffect() +{ + switch (globals.sceneCur->sceneID) + { + case 'DB06': + case 'KF04': + case 'GL02': + case 'BB03': + case 'BC01': + case 'BC02': + case 'BC03': + case 'BC04': + case 'BC05': + { + xSndSetEnvironmentalEffect(SND_EFFECT_CAVE); + break; + } + default: + { + xSndSetEnvironmentalEffect(SND_EFFECT_NONE); + break; + } + } +} + +static U32 BaseTypeNeedsUpdate(U8 baseType) +{ + if (baseType == eBaseTypeUnknown || baseType == eBaseTypePlayer || baseType == eBaseTypeEnv || + baseType == eBaseTypeCamera || baseType == eBaseTypeStatic || + baseType == eBaseTypeMovePoint || baseType == eBaseTypeBubble || + baseType == eBaseTypePortal || baseType == eBaseTypeGroup || baseType == eBaseTypeSFX || + baseType == eBaseTypeFFX || baseType == eBaseTypeVFX || baseType == eBaseTypeCounter || + baseType == eBaseTypeProjectile || baseType == eBaseTypeGust || + baseType == eBaseTypeVolume || baseType == eBaseTypeDispatcher || + baseType == eBaseTypeCond || baseType == eBaseTypeUI || + baseType == eBaseTypeProjectileType || baseType == eBaseTypeLobMaster || + baseType == eBaseTypeCutsceneMgr || baseType == eBaseTypeHud || + baseType == eBaseTypeNPCProps || baseType == eBaseTypeParticleEmitterProps || + baseType == eBaseTypeCruiseBubble || baseType == eBaseTypeTextBox || + baseType == eBaseTypeTalkBox || baseType == eBaseTypeTaskBox || + baseType == eBaseTypeBoulderGenerator || baseType == eBaseTypeNPCSettings || + baseType == eBaseTypeTurret) + { + return 0; + } + + return 1; +} + +void add_scene_tweaks(); + +void zSceneInit(U32 theSceneID, S32 reloadInProgress) +{ + F32 pdone; + zScene* s; + U32 i; + + U8 rgba_bkgrd[4]; + *(U32*)rgba_bkgrd = _1250; + + gTransitionSceneID = theSceneID; + gOccludeCount = 0; + + char b[5]; + *(U32*)b = _1251; + b[4] = byte_803D0884; + + sprintf(b, xUtil_idtag2string(theSceneID, 0)); + xStrupr(b); + + theSceneID = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]; + + xUtil_idtag2string(theSceneID, 0); + + xFogClearFog(); + xSndSceneInit(); + + if (!reloadInProgress) + { + sMemDepthSceneStart = xMemPushBase(); + } + + zGameScreenTransitionBegin(); + zParPTankInit(); + + pdone = _1373; + + if (globals.useHIPHOP && !reloadInProgress) + { + zGameScreenTransitionUpdate(pdone, "... scene preload ...\n"); + + S32 ver_hop = xSTPreLoadScene(theSceneID, NULL, 0x2); + + if (ver_hop >= 0x000A000F) + { + xSTQueueSceneAssets(theSceneID, 0x2); + + do + { + rgba_bkgrd[0] = 0; + rgba_bkgrd[1] = 0; + rgba_bkgrd[2] = 0; + rgba_bkgrd[3] = 0; + + pdone += _1373; + + zGameScreenTransitionUpdate(pdone, "... scene loading ...\n", rgba_bkgrd); + } while (xSTLoadStep(theSceneID) < _1374); + + xSTDisconnect(theSceneID, 0x2); + } + } + + sMemDepthJustHIPStart = xMemPushBase(); + s = (zScene*)xMemAllocSize(sizeof(zScene)); + + globals.sceneCur = s; + + xSceneInit(s, 200, 2048, 2068, 250); + + s->env = (xEnv*)xMemAllocSize(sizeof(xEnv)); + s->sceneID = theSceneID; + + iTime time; + + time = iTimeGet(); + xUtil_idtag2string(theSceneID, 0); + iTimeDiffSec(time); + + xSTPreLoadScene(theSceneID, NULL, 0x1); + + time = iTimeGet(); + xUtil_idtag2string(theSceneID, 0); + iTimeDiffSec(time); + + xSTQueueSceneAssets(theSceneID, 0x1); + + time = iTimeGet(); + xUtil_idtag2string(theSceneID, 0); + iTimeDiffSec(time); + + pdone += _1373; + + zGameScreenTransitionUpdate(pdone, "... scene asset queue ...\n"); + + time = iTimeGet(); + xUtil_idtag2string(theSceneID, 0); + iTimeDiffSec(time); + + do + { + rgba_bkgrd[0] = 0; + rgba_bkgrd[1] = 0; + rgba_bkgrd[2] = 0; + rgba_bkgrd[3] = 0; + + pdone += _1373; + + zGameScreenTransitionUpdate(pdone, "... scene loading ...\n", rgba_bkgrd); + } while (xSTLoadStep(theSceneID) < _1374); + + xSTDisconnect(theSceneID, 0x1); + + time = iTimeGet(); + xUtil_idtag2string(theSceneID, 0); + iTimeDiffSec(time); + + pdone += _1373; + + zGameScreenTransitionUpdate(pdone, "...initializing scene - sound\n"); + + zEntPlayer_LoadSounds(); + iSndInitSceneLoaded(); + xPadRumbleEnable(globals.currentActivePad, globals.option_vibration); + + xSTSwitchScene(theSceneID, NULL, NULL); + + globals.sceneCur->resolvID = zSceneFindObject; + globals.sceneCur->id2Name = zSceneGetName; + globals.sceneCur->base2Name = zSceneGetName; + + g_xSceneCur = globals.sceneCur; + + xModelPipeNumTables = xSTAssetCountByType('PIPT'); + + for (S32 i = 0; i < xModelPipeNumTables; i++) + { + void* data = xSTFindAssetByType('PIPT', i, NULL); + + xModelPipeCount[i] = *(S32*)data; + xModelPipeData[i] = (xModelPipeInfo*)((S32*)data + 1); + } + + xModelLookupCount = 0; + + PipeForAllSceneModels(PipeCountStuffCB); + + if (xModelLookupCount) + { + xModelLookupList = + (xModelPipeLookup*)xMemAllocSize(xModelLookupCount * sizeof(xModelPipeLookup)); + + xModelLookupCount = 0; + + PipeForAllSceneModels(PipeAddStuffCB); + } + + xModelBucket_PreCountReset(); + PipeForAllSceneModels(xModelBucket_PreCountBucket); + + xModelBucket_PreCountAlloc(256); + PipeForAllSceneModels(xModelBucket_InsertBucket); + + xModelBucket_Init(); + add_scene_tweaks(); + xPTankPoolSceneEnter(); + zParPTankSceneEnter(); + xDecalInit(); + xFXScenePrepare(); + zLasso_scenePrepare(); + zDispatcher_scenePrepare(); + + S32 total_npcs = xSTAssetCountByType('VIL '); + zNPCMgr_scenePrepare(total_npcs); + + zAnimListInit(); + zGooInit(24); + + zGameScreenTransitionUpdate(_1375, "...initializing scene - base types\n"); + + for (i = 0; i < eBaseTypeCount; i++) + { + s->baseCount[i] = 0; + s->baseList[i] = NULL; + } + + zCollGeom_Init(); + zUI_Init(); + zUIFontInit(); + ztextbox::init(); + ztalkbox::init(); + ztaskbox::init(); + + xModelInstStaticAlloc = 1; + s->num_base = 0; + + for (i = 0; sInitTable[i].name; i++) + { + U32 typeCount = xSTAssetCountByType(sInitTable[i].assetType); + + s->baseCount[sInitTable[i].baseType] = typeCount; + s->num_base += typeCount; + + if (sInitTable[i].querySubObjects) + { + for (U32 j = 0; j < typeCount; j++) + { + s->num_base += sInitTable[i].querySubObjects( + xSTFindAssetByType(sInitTable[i].assetType, j, NULL)); + } + } + } + + add_dynamic_types(*s); + + if (s->num_base) + { + s->base = (xBase**)xMemAllocSize(s->num_base * sizeof(xBase*)); + } + else + { + s->base = NULL; + } + + zSceneObjHashtableInit(4096); + xFFXPoolInit(12); + xFFXShakePoolInit(3); + xFFXRotMatchPoolInit(1); + xEntSceneInit(); + xEntMotionDebugInit(s->baseCount[eBaseTypePlatform] + s->baseCount[eBaseTypePendulum] + + s->baseCount[eBaseTypeButton]); + zLightSetVolume(NULL); + xPartitionReset(); + xFXRibbonSceneEnter(); + + U32 base_idx = 0; + + for (i = 0; sInitTable[i].name; i++) + { + HACK_BASETYPE = sInitTable[i].baseType; + + if (sInitTable[i].func) + { + base_idx = sInitTable[i].func(s, &sInitTable[i], base_idx); + } + } + + init_dynamic_types(*s, base_idx); + + s->num_update_base = 0; + + for (i = 0; i < s->num_base; i++) + { + if (BaseTypeNeedsUpdate(s->base[i]->baseType)) + { + s->num_update_base++; + } + } + + s->update_base = (xBase**)xMemAllocSize(s->num_update_base * sizeof(xBase*)); + + base_idx = 0; + + for (i = 0; i < s->num_base; i++) + { + if (BaseTypeNeedsUpdate(s->base[i]->baseType)) + { + s->update_base[base_idx] = s->base[i]; + } + } + + xModelInstStaticAlloc = 0; + + zGameScreenTransitionEnd(); + zSceneObjHashtableUsage(); + zUI_ScenePortalInit(s); + zLightResolveLinks(); + zRenderStateInit(); + xFXStreakInit(); + xFXShineInit(); + xFXFireworksInit("PAREMIT_FIREWORKS_TRAIL", "PAREMIT_FIREWORKS1", "PAREMIT_FIREWORKS2", + "Fireworks_explode", "Fireworks_trail"); + zFeetGetIDs(); + zLightningInit(); + zParCmdFindClipVolumes(); + zEntDestructObj_FindFX(); + zShrapnel_SceneInit(globals.sceneCur); + zCameraTweakGlobal_Reset(); + zActionLineInit(); + xScrFxLetterboxReset(); + xShadowManager_Init(eBaseTypeNPC + 10); + + S32 lkitCount = xSTAssetCountByType('LKIT'); + void* lkitData; + + for (S32 i = 0; i < lkitCount; i++) + { + lkitData = xSTFindAssetByType('LKIT', i, NULL); + + xLightKit_Prepare(lkitData); + } + + xClimateInit(&gClimate); + zSceneInitEnvironmentalSoundEffect(); + + sHackSmoothedUpdate = 1; + + FootstepHackSceneEnter(); + zEntPickup_SceneEnter(); + xFXSceneInit(); + zGame_HackGalleryInit(); + iSndSuspendCD(0); +} + +void add_scene_tweaks() +{ +} + +void zSceneExit(S32 beginReload) +{ + zScene* s = globals.sceneCur; + + zThrown_Reset(); + zEntPickup_FlushGrabbed(); + zGridExit(s); + zSceneForAllBase(zSceneExitSoundIteratorCB, NULL); + xSndStopAll(~SND_CAT_UI); + xSndUpdate(); + iSndWaitForDeadSounds(); + iSndSceneExit(); + xSFXEnvironmentalStreamSceneExit(); + iSndSuspendCD(1); + iFuncProfileDump(); + + RpWorld* world = s->env->geom->world; + + xModel_SceneExit(world); + zFX_SceneExit(world); + zEntEventAll(NULL, 0, eEventRoomEnd, NULL); + zEntEventAll(NULL, 0, eEventSceneEnd, NULL); + + if (globals.sceneCur->pendingPortal) + { + char nextScene[8]; + char curScene[8]; + + strcpy(nextScene, xUtil_idtag2string(globals.sceneCur->pendingPortal->passet->sceneID, 0)); + strcpy(curScene, xUtil_idtag2string(globals.sceneCur->sceneID, 0)); + } + + // non-matching: two instructions are swapped here... + gOccludeCount = 0; + + if (globals.sceneCur->sceneID != 'MNU3') + { + zSceneSave(s, NULL); + } + + zEntPlayerExit(&globals.player.ent); + zSurfaceExit(); + zLightDestroyAll(); + xEntSceneExit(); + xEntMotionDebugExit(); + zSceneObjHashtableExit(); + + if (s->baseCount[eBaseTypeParticleSystem]) + { + zParSys* ps = (zParSys*)s->baseList[eBaseTypeParticleSystem]; + + for (U32 i = 0; i < s->baseCount[eBaseTypeParticleSystem]; i++) + { + if (xBaseIsValid(&ps[i])) + { + xParSysExit(&ps[i]); + } + } + } + + xParEmitterDestroy(); + xModelBucket_Deinit(); + xFXSceneFinish(); + zGooExit(); + zParPTankExit(); + zAnimListExit(); + zNPCMgr_sceneFinish(); + zDispatcher_sceneFinish(); + z_disco_floor::destroy(); + xDecalDestroy(); + zParPTankSceneExit(); + xPTankPoolSceneExit(); + zEntPlayer_UnloadSounds(); + + if (beginReload) + { + xSTUnLoadScene(globals.sceneCur->sceneID, 1); + xMemPopBase(sMemDepthJustHIPStart); + + sMemDepthJustHIPStart = -1; + } + else + { + xSTUnLoadScene(globals.sceneCur->sceneID, 1); + + if (globals.useHIPHOP) + { + xSTUnLoadScene(globals.sceneCur->sceneID, 2); + } + + xMemPopBase(sMemDepthSceneStart); + + sMemDepthSceneStart = -1; + sMemDepthJustHIPStart = -1; + } + + xSystem_GapTrackReport(); + xUtil_idtag2string(globals.sceneCur->sceneID, 0); + + globals.sceneCur = NULL; + + xSceneExit(s); +} + +void zSceneUpdateSFXWidgets() +{ + zScene* s = globals.sceneCur; + xSFXUpdateEnvironmentalStreamSounds((xSFX*)s->baseList[eBaseTypeSFX], + s->baseCount[eBaseTypeSFX]); +} + +static void HackSwapIt(char* buf, S32 size) +{ + // non-matching: r3 and r4 swapped + char* end = size + buf; + end--; + + for (S32 i = 0; i < size / 2; i++) + { + char tmp = *buf; + *buf = *end; + *end = tmp; + + buf++; + end--; + } +} + +void zSceneSwitch(_zPortal* p, S32 forceSameScene) +{ + globals.sceneCur->pendingPortal = p; + + xPortalAsset* passet = globals.sceneCur->pendingPortal->passet; + + gLevelChanged = (zSceneLeavingLevel() != 0); + + if (((char*)&passet->sceneID)[3] < '0' || ((char*)&passet->sceneID)[3] > '9') + { + char* id = (char*)&passet->sceneID; + HackSwapIt(id, 4); + } + + U32 nextSceneID = (((char*)&passet->sceneID)[0] << 24) | (((char*)&passet->sceneID)[1] << 16) | + (((char*)&passet->sceneID)[2] << 8) | ((char*)&passet->sceneID)[3]; + + if (!forceSameScene && nextSceneID == globals.sceneCur->sceneID) + { + U32 PlayerMarkerStartID = passet->assetMarkerID; + U32 PlayerMarkerStartCamID = passet->assetCameraID; + F32 PlayerStartAngle = passet->ang; + + if (zSceneFindObject(PlayerMarkerStartCamID)) + { + globals.player.cp.initCamID = PlayerMarkerStartCamID; + } + + if (PlayerStartAngle >= _1493) + { + xMarkerAsset* marker = (xMarkerAsset*)xSTFindAsset(PlayerMarkerStartID, NULL); + + if (marker) + { + xEnt& player = globals.player.ent; + xVec3& loc = (xVec3&)player.model->Mat->pos; + + xVec3 offset = marker->pos - loc; + + loc = player.frame->mat.pos = marker->pos; + + xCameraMove(&globals.camera, globals.camera.mat.pos + offset); + } + } + else + { + U32 size; + xMarkerAsset* m = (xMarkerAsset*)xSTFindAsset(PlayerMarkerStartID, &size); + + if (m) + { + xVec3Copy(&globals.player.ent.frame->mat.pos, &m->pos); + xVec3Copy((xVec3*)&globals.player.ent.model->Mat->pos, &m->pos); + + xCameraSetTargetMatrix(&globals.camera, xEntGetFrame(&globals.player.ent)); + } + + xEntFrame* frame = globals.player.ent.frame; + + frame->rot.angle = _1494 * PlayerStartAngle / _1495; + frame->rot.axis = xVec3::create(_1496_0, _1374, _1496_0); + + xMat3x3Euler(&frame->mat, frame->rot.angle, _1496_0, _1496_0); + + *(xMat3x3*)globals.player.ent.model->Mat = frame->mat; + + zCameraReset(&globals.camera); + } + + // non-matching: instruction order + + oob_player_teleported = true; + globals.sceneCur->pendingPortal = NULL; + } +} + +void zSceneSave(zScene* ent, xSerial* s) +{ + zEntPickup_FlushGrabbed(); + + U32 i; + xSerial xser; + + s = &xser; + + s->setClient('PLYR'); + s->Write_b1(1); + s->Write(globals.player.MaxHealth); + s->Write(gCurrentPlayer); + s->Write(globals.player.Inv_Shiny); + s->Write(globals.player.Inv_Spatula); + s->Write(globals.player.g.PowerUp[0]); + s->Write(globals.player.g.PowerUp[1]); + + for (i = 0; i < LEVEL_COUNT; i++) + { + s->Write(globals.player.Inv_PatsSock[i]); + s->Write(globals.player.Inv_LevelPickups[i]); + } + + s->Write(globals.player.Inv_PatsSock_Total); + + zCutsceneMgrSave(NULL, s); + oob_state::write_persistent(*s); + + s->setClient('CNTR'); + s->Write_b1(1); + + zUI_ScenePortalSave(s); + + char tempString[32]; + + strcpy(tempString, "HB09 ROBOT COUNTER 01"); + + char c = '1'; + U32 id; + + for (i = 0; i < LEVEL_COUNT; i++) + { + if (c > '9') + { + c = '0'; + tempString[19]++; + } + + tempString[20] = c; + + c++; + + id = xStrHash(tempString); + + s->Write(((_xCounter*)zSceneFindObject(id))->count); + } + + id = xStrHash("REMINDER_SOCK_CNTR"); + + s->Write(((_xCounter*)zSceneFindObject(id))->count); + + zGameExtras_Save(s); + + s->setClient(ent->sceneID); + s->Write_b1(1); + + xSceneSave(ent, s); + + s->Write(offsetx); + s->Write(offsety); + + for (U32 i = 0; i < globals.sceneCur->num_base; i++) + { + xBase* b = globals.sceneCur->base[i]; + + if (b->baseFlags & 0x2) + { + switch (b->baseType) + { + case eBaseTypeTrigger: + { + zEntTriggerSave((zEntTrigger*)b, s); + break; + } + case eBaseTypeNPC: + { + ((xNPCBasic*)b)->Save(s); + break; + } + case eBaseTypePickup: + { + zEntPickup_Save((zEntPickup*)b, s); + break; + } + case eBaseTypeEnv: + { + zEnvSave((_zEnv*)b, s); + break; + } + case eBaseTypeFog: + { + xFogSave((_xFog*)b, s); + break; + } + case eBaseTypeLight: + { + zLightSave((_zLight*)b, s); + break; + } + case eBaseTypePlatform: + { + zPlatform_Save((zPlatform*)b, s); + break; + } + case eBaseTypeCamera: + { + zCamMarkerSave((zCamMarker*)b, s); + break; + } + case eBaseTypeStatic: + { + zEntSimpleObj_Save((zEntSimpleObj*)b, s); + break; + } + case eBaseTypeMovePoint: + { + zMovePointSave((zMovePoint*)b, s); + break; + } + case eBaseTypeTimer: + { + xTimerSave((xTimer*)b, s); + break; + } + case eBaseTypePortal: + { + zPortalSave((_zPortal*)b, s); + break; + } + case eBaseTypeGroup: + { + xGroupSave((xGroup*)b, s); + break; + } + case eBaseTypePendulum: + { + zPendulum_Save((_zPendulum*)b, s); + break; + } + case eBaseTypeSFX: + { + xSFXSave((xSFX*)b, s); + break; + } + case eBaseTypeCounter: + { + xCounterSave((_xCounter*)b, s); + break; + } + case eBaseTypeHangable: + { + zEntHangable_Save((zEntHangable*)b, s); + break; + } + case eBaseTypeButton: + { + zEntButton_Save((_zEntButton*)b, s); + break; + } + case eBaseTypeSurface: + { + zSurfaceSave((xSurface*)b, s); + break; + } + case eBaseTypeDestructObj: + { + zEntDestructObj_Save((zEntDestructObj*)b, s); + break; + } + case eBaseTypeGust: + { + zGustSave((zGust*)b, s); + break; + } + case eBaseTypeScript: + { + zScriptSave((_zScript*)b, s); + break; + } + case eBaseTypeVolume: + { + ((xVolume*)b)->Save(s); + break; + } + case eBaseTypeDispatcher: + { + zDispatcher_Save((st_ZDISPATCH_DATA*)b, s); + break; + } + case eBaseTypeCond: + { + zConditionalSave((_zConditional*)b, s); + break; + } + case eBaseTypeUI: + { + zUI_Save((_zUI*)b, s); + break; + } + case eBaseTypeUIFont: + { + zUIFont_Save((zUIFont*)b, s); + break; + } + case eBaseTypeEGenerator: + { + zEGenerator_Save((zEGenerator*)b, s); + break; + } + case eBaseTypeTeleportBox: + { + zEntTeleportBox_Save((_zEntTeleportBox*)b, s); + break; + } + case eBaseTypeTaskBox: + { + ((ztaskbox*)b)->write(*s); + break; + } + case eBaseTypeTaxi: + { + zTaxi_Save((zTaxi*)b, s); + break; + } + case eBaseTypeCameraFly: + { + zCameraFly_Save((zCameraFly*)b, s); + break; + } + case eBaseTypeCameraTweak: + { + zCameraTweak_Save((zCameraTweak*)b, s); + break; + } + } + } + } +} + +void zSceneLoad(zScene* ent, xSerial* s) +{ + xSerial xser; + S32 sceneExist; + + s = &xser; + + s->setClient('PLYR'); + + sceneExist = 0; + s->Read_b1(&sceneExist); + + if (sceneExist) + { + s->Read(&globals.player.MaxHealth); + + globals.player.Health = globals.player.MaxHealth; + + s->Read((U32*)&gCurrentPlayer); + s->Read(&globals.player.Inv_Shiny); + s->Read(&globals.player.Inv_Spatula); + s->Read(&globals.player.g.PowerUp[0]); + s->Read(&globals.player.g.PowerUp[1]); + + for (S32 i = 0; i < LEVEL_COUNT; i++) + { + s->Read(&globals.player.Inv_PatsSock[i]); + s->Read(&globals.player.Inv_LevelPickups[i]); + } + + s->Read(&globals.player.Inv_PatsSock_Total); + + zCutsceneMgrLoad(NULL, s); + oob_state::read_persistent(*s); + } + + s->setClient('CNTR'); + + sceneExist = 0; + s->Read_b1(&sceneExist); + + if (sceneExist) + { + char tempString[32]; + + zUI_ScenePortalLoad(s); + + strcpy(tempString, "HB09 ROBOT COUNTER 01"); + + char c = '1'; + S32 i; + U32 id; + + for (i = 0; i < LEVEL_COUNT; i++) + { + if (c > '9') + { + c = '0'; + tempString[19]++; + } + + tempString[20] = c; + + c++; + + id = xStrHash(tempString); + + s->Read(&((_xCounter*)zSceneFindObject(id))->count); + } + + id = xStrHash("REMINDER_SOCK_CNTR"); + + s->Read(&((_xCounter*)zSceneFindObject(id))->count); + + zGameExtras_Load(s); + } + + s->setClient(ent->sceneID); + + sceneExist = 0; + s->Read_b1(&sceneExist); + + if (sceneExist) + { + xSceneLoad(ent, s); + + s->Read(&offsetx); + s->Read(&offsety); + + for (U16 i = 0; i < globals.sceneCur->num_base; i++) + { + xBase* b = globals.sceneCur->base[i]; + + if (b->baseFlags & 0x2) + { + switch (b->baseType) + { + case eBaseTypeTrigger: + { + zEntTriggerLoad((zEntTrigger*)b, s); + break; + } + case eBaseTypeNPC: + { + ((xNPCBasic*)b)->Load(s); + break; + } + case eBaseTypePlayer: + { + zEntPlayer_Load((xEnt*)b, s); + break; + } + case eBaseTypePickup: + { + zEntPickup_Load((zEntPickup*)b, s); + break; + } + case eBaseTypeEnv: + { + zEnvLoad((_zEnv*)b, s); + break; + } + case eBaseTypeFog: + { + xFogLoad((_xFog*)b, s); + break; + } + case eBaseTypeLight: + { + zLightLoad((_zLight*)b, s); + break; + } + case eBaseTypePlatform: + { + zPlatform_Load((zPlatform*)b, s); + break; + } + case eBaseTypeCamera: + { + zCamMarkerLoad((zCamMarker*)b, s); + break; + } + case eBaseTypeStatic: + { + zEntSimpleObj_Load((zEntSimpleObj*)b, s); + break; + } + case eBaseTypeMovePoint: + { + zMovePointLoad((zMovePoint*)b, s); + break; + } + case eBaseTypeTimer: + { + xTimerLoad((xTimer*)b, s); + break; + } + case eBaseTypePortal: + { + zPortalLoad((_zPortal*)b, s); + break; + } + case eBaseTypeGroup: + { + xGroupLoad((xGroup*)b, s); + break; + } + case eBaseTypePendulum: + { + zPendulum_Load((_zPendulum*)b, s); + break; + } + case eBaseTypeSFX: + { + xSFXLoad((xSFX*)b, s); + break; + } + case eBaseTypeCounter: + { + xCounterLoad((_xCounter*)b, s); + break; + } + case eBaseTypeHangable: + { + zEntHangable_Load((zEntHangable*)b, s); + break; + } + case eBaseTypeButton: + { + zEntButton_Load((_zEntButton*)b, s); + break; + } + case eBaseTypeSurface: + { + zSurfaceLoad((xSurface*)b, s); + break; + } + case eBaseTypeDestructObj: + { + zEntDestructObj_Load((zEntDestructObj*)b, s); + break; + } + case eBaseTypeGust: + { + zGustLoad((zGust*)b, s); + break; + } + case eBaseTypeScript: + { + zScriptLoad((_zScript*)b, s); + break; + } + case eBaseTypeVolume: + { + ((xVolume*)b)->Load(s); + break; + } + case eBaseTypeDispatcher: + { + zDispatcher_Load((st_ZDISPATCH_DATA*)b, s); + break; + } + case eBaseTypeCond: + { + zConditionalLoad((_zConditional*)b, s); + break; + } + case eBaseTypeUI: + { + zUI_Load((_zUI*)b, s); + break; + } + case eBaseTypeUIFont: + { + zUIFont_Load((zUIFont*)b, s); + break; + } + case eBaseTypeEGenerator: + { + zEGenerator_Load((zEGenerator*)b, s); + break; + } + case eBaseTypeTeleportBox: + { + zEntTeleportBox_Load((_zEntTeleportBox*)b, s); + break; + } + case eBaseTypeTaskBox: + { + ((ztaskbox*)b)->read(*s); + break; + } + case eBaseTypeTaxi: + { + zTaxi_Load((zTaxi*)b, s); + break; + } + case eBaseTypeCameraFly: + { + zCameraFly_Load((zCameraFly*)b, s); + break; + } + case eBaseTypeCameraTweak: + { + zCameraTweak_Load((zCameraTweak*)b, s); + break; + } + } + } + } + } +} + +S32 zSceneSetup_serialTraverseCB(U32 clientID, xSerial* xser); + +void zSceneReset() +{ + zScene* s = globals.sceneCur; + + zEntPlayerPreReset(); + + gOccludeCount = 0; + + xScrFxLetterboxReset(); + zEntPickup_FlushGrabbed(); + zEntPickup_SceneReset(); + zMusicReset(); + zThrown_Reset(); + zShrapnel_Reset(); + zFX_SceneReset(); + xFXSceneReset(); + xShadowManager_Reset(); + ztalkbox::reset_all(); + zCameraTweakGlobal_Reset(); + xPadDestroyRumbleChain(0); + + globals.cmgr = NULL; + + zEntEventAll(NULL, 0, eEventRoomEnd, NULL); + zEntEventAll(NULL, 0, eEventSceneEnd, NULL); + + zSceneSave(s, NULL); + zSceneAutoSave(); + + xSndStopAll(~SND_CAT_UI); + xSndUpdate(); + iSndWaitForDeadSounds(); + + for (U32 i = 0; i < s->num_base; i++) + { + if (s->base[i]) + { + switch (s->base[i]->baseType) + { + case eBaseTypePickup: + case eBaseTypeCamera: + case eBaseTypeDoor: + case eBaseTypeSavePoint: + case eBaseTypeItem: + case eBaseTypeStatic: + case eBaseTypeDynamic: + case eBaseTypeMovePoint: + case eBaseTypeTimer: + case eBaseTypeBubble: + case eBaseTypePortal: + case eBaseTypeGroup: + case eBaseTypeSFX: + case eBaseTypeFFX: + case eBaseTypeVFX: + case eBaseTypeButton: + case eBaseTypeProjectile: + case eBaseTypeSurface: + case eBaseTypeDestructObj: + case eBaseTypeGust: + case eBaseTypeVolume: + case eBaseTypeDispatcher: + case eBaseTypeCond: + case eBaseTypeUI: + case eBaseTypeUIFont: + case eBaseTypeProjectileType: + case eBaseTypeFog: + case eBaseTypeLight: + case eBaseTypeParticleEmitter: + case eBaseTypeParticleSystem: + case eBaseTypeCutsceneMgr: + default: + { + zEntEvent(NULL, 0, s->base[i], eEventReset, NULL, NULL, 1); + break; + } + case eBaseTypeCounter: + { + xCounterReset(s->base[i]); + break; + } + case eBaseTypePlayer: + { + zEntPlayerReset((xEnt*)s->base[i]); + break; + } + case eBaseTypePlatform: + { + zPlatform_Reset((zPlatform*)s->base[i], globals.sceneCur); + break; + } + case eBaseTypePendulum: + { + zPendulum_Reset((_zPendulum*)s->base[i], globals.sceneCur); + break; + } + case eBaseTypeHangable: + { + zEntHangable_Reset((zEntHangable*)s->base[i]); + break; + } + case eBaseTypeLobMaster: + { + zEntEvent(s->base[i], eEventReset); + break; + } + case eBaseTypeEGenerator: + { + zEGenerator_Reset((zEGenerator*)s->base[i], globals.sceneCur); + break; + } + case eBaseTypeEnv: + { + _zEnv* env = (_zEnv*)s->base[i]; + + if (env) + { + if (zSceneFindObject(env->easset->startCameraAssetID)) + { + zCameraReset(&globals.camera); + } + + xClimateInitAsset(&gClimate, env->easset); + } + } + } + } + } + + zNPCMgr_sceneReset(); + zEntPlayer_LoadCheckPoint(); + zSceneLoad(globals.sceneCur, NULL); + zSceneEnableVisited(s); + xSerialTraverse(zSceneSetup_serialTraverseCB); + xSkyDome_Setup(); + xUpdateCull_Reset(globals.updateMgr); + xUpdateCull_Update(globals.updateMgr, 100); + zGridReset(s); + + zEntEventAll(NULL, 0, eEventSceneBegin, NULL); + zEntEventAll(NULL, 0, eEventRoomBegin, NULL); + zEntEventAll(NULL, 0, eEventSceneReset, NULL); + + zNPCTiki_InitStacking(globals.sceneCur); + zNPCTiki_InitFX(globals.sceneCur); + + xUpdateCull_Update(globals.updateMgr, 100); + zLOD_Update(100); + + zGameExtras_SceneReset(); +} + +static void ActivateCB(xBase* base) +{ + base->baseFlags &= (U8)~0x40; +} + +static void DeactivateCB(xBase* base) +{ + base->baseFlags |= 0x40; +} + +// clang-format off +// jumptable for zSceneSetup +static U32 _2098_0[] = +{ +0x800B3418, 0x800B3418, 0x800B3418, +0x800B3418, 0x800B33B0, 0x800B32E0, +0x800B3318, 0x800B3418, 0x800B3418, +0x800B3418, 0x800B3418, 0x800B3378, +0x800B3418, 0x800B3334, 0x800B3418, +0x800B3418, 0x800B3418, 0x800B33DC, +0x800B3340, 0x800B3418, 0x800B3418, +0x800B3418, 0x800B3418, 0x800B3418, +0x800B335C, 0x800B3418, 0x800B33CC, +0x800B340C, 0x800B3418, 0x800B3418, +0x800B3388, 0x800B3418, 0x800B3418, +0x800B3418, 0x800B3418, 0x800B3418, +0x800B3418, 0x800B3418, 0x800B33D4, +0x800B33C4, 0x800B3418, 0x800B3394, +0x800B3418, 0x800B3304, 0x800B3418, +0x800B3418, 0x800B3418, 0x800B3414, +0x800B3418, 0x800B33E4, 0x800B33EC, +0x800B3418, 0x800B3418, 0x800B3418, +0x800B3418, 0x800B3418, 0x800B33F4, +0x800B33FC, 0x800B3418, 0x800B3418, +0x800B3418, 0x800B3418, 0x800B3404, +0x800B3380, 0x800B3418, 0x800B3418, +0x800B3418, 0x800B3418, 0x800B3418, +0x800B3418, 0x800B3418, 0x800B3418 +}; +// clang-format on + +void zSceneSetup() +{ + zScene* s = globals.sceneCur; + + globals.cmgr = NULL; + + xSceneSetup(s); + gUIMgr.Setup(s); + + s->gravity = _2094; + s->drag = _2095_0; + s->flags = 0x5; + + zNPCMgr_scenePostInit(); + + if (s->baseCount[eBaseTypeGust]) + { + zGustSetup(); + } + + if (s->baseCount[eBaseTypeVolume]) + { + zVolumeSetup(); + } + + { + U32 dontcaresize; + xCutscene_Init(xSTFindAssetByType('CTOC', 0, &dontcaresize)); + } + + zLOD_Setup(); + + gCurEnv = NULL; + + for (U32 i = 0; i < s->num_base; i++) + { + if (s->base[i]) + { + switch (s->base[i]->baseType) + { + case eBaseTypeEnv: + { + gCurEnv = (_zEnv*)s->base[i]; + + zEnvSetup(gCurEnv); + xClimateInitAsset(&gClimate, gCurEnv->easset); + + break; + } + case eBaseTypeNPC: + { + ((xNPCBasic*)s->base[i])->Setup(); + break; + } + case eBaseTypePlatform: + { + zPlatform_Reset((zPlatform*)s->base[i], s); + zPlatform_Setup((zPlatform*)s->base[i], s); + break; + } + case eBaseTypeMovePoint: + { + zMovePointSetup((zMovePoint*)s->base[i], s); + break; + } + case eBaseTypePendulum: + { + zPendulum_Reset((_zPendulum*)s->base[i], s); + zPendulum_Setup((_zPendulum*)s->base[i], s); + break; + } + case eBaseTypeButton: + { + zEntButton_Reset((_zEntButton*)s->base[i], s); + zEntButton_Setup((_zEntButton*)s->base[i], s); + break; + } + case eBaseTypeStatic: + { + zEntSimpleObj_Setup((zEntSimpleObj*)s->base[i]); + break; + } + case eBaseTypeTrackPhysics: + { + zEntSimpleObj_Setup((zEntSimpleObj*)s->base[i]); + break; + } + case eBaseTypeDispatcher: + { + zDispatcher_InitDep((st_ZDISPATCH_DATA*)s->base[i], s); + break; + } + case eBaseTypeEGenerator: + { + zEGenerator_Setup((zEGenerator*)s->base[i], s); + zEGenerator_Reset((zEGenerator*)s->base[i], s); + break; + } + case eBaseTypePickup: + { + zEntPickup_Setup((zEntPickup*)s->base[i]); + zEntPickup_Reset((zEntPickup*)s->base[i]); + break; + } + case eBaseTypeParticleSystem: + { + xParSysSetup((xParSys*)s->base[i]); + break; + } + case eBaseTypeSurface: + { + zSurfaceSetup((xSurface*)s->base[i]); + break; + } + case eBaseTypeParticleEmitter: + { + xParEmitterSetup((xParEmitter*)s->base[i]); + break; + } + case eBaseTypeGroup: + { + xGroupSetup((xGroup*)s->base[i]); + break; + } + case eBaseTypeTeleportBox: + { + zEntTeleportBox_Setup((_zEntTeleportBox*)s->base[i]); + break; + } + case eBaseTypeBusStop: + { + zBusStop_Setup((zBusStop*)s->base[i]); + break; + } + case eBaseTypeDiscoFloor: + { + ((z_disco_floor*)s->base[i])->setup(); + break; + } + case eBaseTypeTaxi: + { + zTaxi_Setup((zTaxi*)s->base[i]); + break; + } + case eBaseTypeCameraFly: + { + zCameraFly_Setup((zCameraFly*)s->base[i]); + break; + } + case eBaseTypeDestructObj: + { + zEntDestructObj_Setup((zEntDestructObj*)s->base[i]); + break; + } + case eBaseTypeBoulder: + { + xEntBoulder_Setup((xEntBoulder*)s->base[i]); + break; + } + case eBaseTypeUnknown: + case eBaseTypeZipLine: + case eBaseTypeHUD_text: + { + break; + } + } + } + } + + zEntPickup_Setup(); + zEntTeleportBox_InitAll(); + zEntHangable_SetupFX(); + zThrown_Setup(globals.sceneCur); + + for (U32 i = 0; i < s->num_base; i++) + { + if (s->base[i] && s->base[i]->baseType == eBaseTypeMovePoint) + { + xMovePointSplineSetup((xMovePoint*)s->base[i]); + } + } + + xFXSceneSetup(); + zSceneEnableVisited(s); + xSerialTraverse(zSceneSetup_serialTraverseCB); + xQuickCullInit(xEntGetAllEntsBox()); + zGridInit(s); + zNPCBSandy_AddBoundEntsToGrid(s); + zNPCBPatrick_AddBoundEntsToGrid(s); + zNPCTiki_InitStacking(globals.sceneCur); + zNPCTiki_InitFX(globals.sceneCur); + + enableScreenAdj = 0; + + for (U32 i = 0; i < s->num_base; i++) + { + if (s->base[i] && s->base[i]->baseType == eBaseTypeNPC) + { + xEnt* ent = (xEnt*)s->base[i]; + zLODTable* lod = zLOD_Get(ent); + + if (lod) + { + RpAtomic* tryshad = NULL; + + if (lod->lodBucket[2]) + { + tryshad = lod->lodBucket[2][0]->Data; + } + else if (lod->lodBucket[1]) + { + tryshad = lod->lodBucket[1][0]->Data; + } + else if (lod->lodBucket[0]) + { + tryshad = lod->lodBucket[0][0]->Data; + } + + if (tryshad && RpClumpGetNumAtomics(RpAtomicGetClump(tryshad)) == 1) + { + ent->entShadow->shadowModel = tryshad; + } + } + } + } + + { + int max_drivensort_tiers = 256; + U32 driven_swapped; + U32 i, j; + + do + { + driven_swapped = 0; + + for (i = 0; i < s->num_update_base; i++) + { + if (s->update_base[i]->baseFlags & 0x20) + { + xEnt* bdriven = (xEnt*)s->update_base[i]; + + if (bdriven->driver) + { + for (j = (i + 1) * 2; j < s->num_update_base; j++) + { + if (bdriven->driver == s->update_base[j]) + { + driven_swapped = 1; + + xBase* btmp = s->update_base[i]; + + s->update_base[i] = s->update_base[j]; + s->update_base[j] = btmp; + } + } + } + } + } + } while (--max_drivensort_tiers && driven_swapped); + } + + { + S32 i; + U32 f; + + xEnvAsset* easset = globals.sceneCur->zen->easset; + + if (easset->bspLightKit) + { + globals.sceneCur->env->lightKit = (xLightKit*)xSTFindAsset(easset->bspLightKit, NULL); + } + + if (easset->objectLightKit) + { + xLightKit* objLightKit = (xLightKit*)xSTFindAsset(easset->objectLightKit, NULL); + + if (objLightKit) + { + zScene* zsc = globals.sceneCur; + + for (i = 0; i < s->num_base; i++) + { + if (s->base[i]->baseFlags & 0x20) + { + xEnt* tgtent = (xEnt*)s->base[i]; + + if (tgtent->model) + { + f = tgtent->model->PipeFlags & (0x40 | 0x80); + + if (f != 0x40) + { + tgtent->lightKit = objLightKit; + } + } + } + } + } + } + + S32 lkitCount = xSTAssetCountByType('LKIT'); + + for (i = 0; i < lkitCount; i++) + { + xLightKit* lkit = (xLightKit*)xSTFindAssetByType('LKIT', i, NULL); + + if (lkit->groupID) + { + xGroup* group = (xGroup*)zSceneFindObject(lkit->groupID); + + if (group) + { + U32 j, nitam; + + nitam = xGroupGetCount(group); + + for (j = 0; j < nitam; j++) + { + xBase* itamz = xGroupGetItemPtr(group, j); + + if (itamz && (itamz->baseFlags & 0x20)) + { + xEnt* entitam = (xEnt*)itamz; + + if (entitam->model) + { + f = entitam->model->PipeFlags & (0x40 | 0x80); + + if (f != 0x40) + { + entitam->lightKit = lkit; + } + } + } + } + } + } + } + } + + zEntSimpleObj_MgrInit((zEntSimpleObj**)s->act_ents + s->baseCount[eBaseTypeTrigger] + + s->baseCount[eBaseTypePickup], + s->baseCount[eBaseTypeStatic]); + + xEnt** entList = + s->act_ents + s->baseCount[eBaseTypeTrigger] + s->baseCount[eBaseTypePickup]; // r28 + U32 entCount = s->baseCount[eBaseTypeStatic] + s->baseCount[eBaseTypePlatform] + + s->baseCount[eBaseTypePendulum] + s->baseCount[eBaseTypeHangable] + + s->baseCount[eBaseTypeDestructObj] + s->baseCount[eBaseTypeBoulder] + + s->baseCount[eBaseTypeNPC] + s->baseCount[eBaseTypeButton]; // r27 + + U32 i, j, k; + U32 numPrimeMovers = 0; // r24 + U32 numDriven = 0; // r25 + + for (i = 0; i < s->num_ents; i++) + { + if (s->ents[i]->baseFlags & 0x20) + { + s->ents[i]->isCulled = 0; + } + } + + for (i = 0; i < s->num_ents; i++) + { + if (s->ents[i]->baseFlags & 0x20) + { + if (s->ents[i]->driver) + { + if (!s->ents[i]->isCulled) + { + numDriven++; + s->ents[i]->isCulled = 2; + } + + xEnt* ent = s->ents[i]; + + while (ent->driver) + { + ent = ent->driver; + } + + if (!ent->isCulled) + { + numPrimeMovers++; + ent->isCulled = 1; + } + } + } + } + + U32 numGroups = 0; + + for (i = 0; i < s->num_base; i++) + { + if (s->base[i]->baseType == eBaseTypeGroup) + { + xGroup* grp = (xGroup*)s->base[i]; + + for (j = 0; j < grp->linkCount; j++) + { + // bug: grp->link needs to be changed to grp->link[j] + // currently the 1st link is checked over and over + // and any links after that are not checked + + if (grp->link->srcEvent == eEventSceneBegin && + grp->link->dstEvent == eEventGroupUpdateTogether) + { + numGroups++; + + U32 gcnt = xGroupGetCount(grp); + + for (k = 0; k < gcnt; k++) + { + xBase* gbase = xGroupGetItemPtr(grp, k); + + if (gbase && (gbase->baseFlags & 0x20)) + { + xEnt* gent = (xEnt*)gbase; + + if (gent->isCulled) + { + if (gent->isCulled == 1) + { + numDriven--; + } + + if (gent->isCulled != 1) + { + numPrimeMovers--; + } + + gent->isCulled = 0; + } + } + } + } + } + } + } + + xGroup* driveGroupList = NULL; + + if (numDriven) + { + U32 allocsize = numDriven * sizeof(xGroup) + numDriven * sizeof(xGroupAsset) + + (numDriven + numPrimeMovers) * sizeof(xBase*); + + driveGroupList = (xGroup*)RwMalloc(allocsize); + + memset(driveGroupList, 0, allocsize); + + xGroupAsset* grpAssetList = (xGroupAsset*)(driveGroupList + numDriven); + xBase** grpBaseList = (xBase**)(grpAssetList + numDriven); + + for (i = 0; i < numDriven; i++) + { + driveGroupList[i].baseType = eBaseTypeGroup; + driveGroupList[i].asset = &grpAssetList[i]; + driveGroupList[i].flg_group |= 0x1; + } + + for (i = 0, j = 0; i < s->num_base; i++) + { + if (s->base[i]->baseFlags & 0x20) + { + xEnt* ent = (xEnt*)s->base[i]; + + if (ent->isCulled == 1) + { + xGroupAsset* gasset = driveGroupList[j].asset; + + driveGroupList[j].item = grpBaseList; + *grpBaseList++ = ent; + gasset->itemCount++; + + for (k = 0; k < s->num_base; k++) + { + if (s->base[k]->baseFlags & 0x20) + { + xEnt* other = (xEnt*)s->base[k]; + + if (other->isCulled == 2) + { + xEnt* r12 = other; + + while (r12->driver) + { + r12 = r12->driver; + } + + if (ent == r12) + { + *grpBaseList++ = other; + gasset->itemCount++; + } + } + } + } + + if (gasset->itemCount > 1) + { + numPrimeMovers++; + } + + j++; + } + } + } + } + + xGroup** tempGrpList = NULL; + + if (numGroups) + { + tempGrpList = (xGroup**)RwMalloc(numGroups * sizeof(xGroup*)); + + xGroup** tempGrpCurr = tempGrpList; + + for (i = 0; i < s->num_base; i++) + { + if (s->base[i]->baseType == eBaseTypeGroup) + { + xGroup* grp = (xGroup*)s->base[i]; + + for (j = 0; j < grp->linkCount; j++) + { + // same bug as above + // grp->link should be changed to grp->link[j] + + if (grp->link->srcEvent == eEventSceneBegin && + grp->link->dstEvent == eEventGroupUpdateTogether) + { + *tempGrpCurr++ = grp; + } + } + } + } + + for (i = 0; i < numDriven; i++) + { + if (driveGroupList[i].asset->itemCount > 1) + { + *tempGrpCurr++ = &driveGroupList[i]; + } + } + } + + globals.updateMgr = xUpdateCull_Init((void**)entList, entCount, tempGrpList, numGroups); + globals.updateMgr->activateCB = (xUpdateCullActivateCallback)ActivateCB; + globals.updateMgr->deactivateCB = (xUpdateCullDeactivateCallback)DeactivateCB; + + FloatAndVoid defaultDist; + defaultDist.f = _2096_0; + + FloatAndVoid lodDist; + lodDist.f = _1496_0; + + for (i = 0; i < entCount; i++) + { + zLODTable* lod = zLOD_Get(entList[i]); + + if (lod) + { + if (lod->noRenderDist == _1496_0) + { + lod = NULL; + } + else + { + lodDist.f = SQR(_2097_0 + xsqrt(lod->noRenderDist)); + } + } + + xUpdateCull_SetCB(globals.updateMgr, entList[i], xUpdateCull_DistanceSquaredCB, + (lod) ? lodDist.v : defaultDist.v); + } + + if (tempGrpList) + { + RwFree(tempGrpList); + } + + if (driveGroupList) + { + RwFree(driveGroupList); + } + + for (i = 0; i < s->num_base; i++) + { + if (s->base[i]->baseFlags & 0x20) + { + ((xEnt*)s->base[i])->isCulled = 0; + } + } + + zNPCMgr_scenePostSetup(); + z_disco_floor::post_setup(); + zEntPickup_RewardPostSetup(); + + iColor_tag black; + *(U32*)&black = _2013; + + iColor_tag clear; + *(U32*)&clear = _2014; + + xScrFxFade(&black, &clear, _1374, NULL, 0); +} + +S32 zSceneSetup_serialTraverseCB(U32 clientID, xSerial* xser) +{ + char uiName[16]; + S32 val = 0; + xBase* b; + + xser->Read_b1(&val); + + if (val == 0) + { + return 1; + } + + sprintf(uiName, "%s", xUtil_idtag2string(clientID, 0)); + + uiName[1] = ' '; + + strcat(uiName, " VISITED"); + + b = zSceneFindObject(xStrHash(uiName)); + + if (b) + { + b->baseFlags |= 0x1; + } + + return 1; +} + +void zSceneUpdate(F32 dt) +{ + U32 i; + S32 isPaused; + zScene* s; + xBase** b; + + if (_1496_0 == dt) + { + return; + } + + isPaused = zGameIsPaused(); + gSceneUpdateTime = dt; + + if (!isPaused) + { + zEntPickup_SceneUpdate(dt); + zEntButton_SceneUpdate(dt); + } + + xEntSetTimePassed(dt); + + if (globals.cmgr) + { + zCutsceneMgrUpdate(globals.cmgr, globals.sceneCur, dt); + } + + s = globals.sceneCur; + b = s->update_base; + + gUIMgr.PreUpdate(s, dt); + + if (s->baseCount[eBaseTypeUIFont]) + { + zUIFont* ui = (zUIFont*)s->baseList[eBaseTypeUIFont]; + + for (i = 0; i < s->baseCount[eBaseTypeUIFont]; i++) + { + zUIFont_PreUpdate(&ui[i], s, dt); + } + } + + if (!isPaused) + { + zNPCMgr_sceneTimestep(s, dt); + } + else if (s->sceneID == 'B101') + { + zNPCBSandy_GameIsPaused(s); + } + else if (s->sceneID == 'B201') + { + zNPCBPatrick_GameIsPaused(s); + } + + ztextbox::update_all(*s, dt); + ztalkbox::update_all(*s, dt); + + gUIMgr.Update(s, dt); + + if (xVec3Dist(&sOldPosPlayer, (xVec3*)&globals.player.ent.model->Mat->pos) > _2242 || + xVec3Dist(&sOldPosCamera, &globals.camera.mat.pos) > _2242) + { + sSuddenMove = 1; + } + else + { + sSuddenMove = 0; + } + + sOldPosPlayer = *(xVec3*)&globals.player.ent.model->Mat->pos; + sOldPosCamera = globals.camera.mat.pos; + + xUpdateCull_Update(globals.updateMgr, sSuddenMove ? 100 : 5); + + for (i = 0; i < s->num_update_base; i++) + { + if (!(b[i]->baseFlags & 0x40)) + { + switch (b[i]->baseType) + { + case eBaseTypeUIFont: + { + if (((xEnt*)b[i])->update) + { + ((xEnt*)b[i])->update((xEnt*)b[i], s, dt); + } + break; + } + case eBaseTypeZipLine: + { + if (((xEnt*)b[i])->update && !isPaused) + { + ((xEnt*)b[i])->update((xEnt*)b[i], s, dt); + } + break; + } + case eBaseTypeTrigger: + case eBaseTypePickup: + case eBaseTypePlatform: + case eBaseTypeDoor: + case eBaseTypeSavePoint: + case eBaseTypeItem: + case eBaseTypeDynamic: + case eBaseTypePendulum: + case eBaseTypeHangable: + case eBaseTypeButton: + case eBaseTypeDestructObj: + case eBaseTypeEGenerator: + case eBaseTypeNPC: + case eBaseTypeBoulder: + case eBaseTypeTeleportBox: + { + if (((xEnt*)b[i])->update && !isPaused) + { + ((xEnt*)b[i])->update((xEnt*)b[i], s, dt); + } + break; + } + case eBaseTypeTimer: + { + if (!isPaused || ((xTimer*)b[i])->runsInPause) + { + xTimerUpdate(b[i], s, dt); + } + break; + } + case eBaseTypeScript: + { + if (!isPaused) + { + zScriptUpdate(b[i], s, dt); + } + break; + } + case eBaseTypeFog: + { + if (!isPaused) + { + xFogUpdate(b[i], s, dt); + } + break; + } + case eBaseTypeParticleEmitter: + { + if (!isPaused) + { + xParEmitterUpdate(b[i], s, dt); + } + break; + } + case eBaseTypeParticleSystem: + { + if (!isPaused && !zGameIsPaused()) + { + xParSysUpdate(b[i], s, dt); + } + break; + } + case eBaseTypeLight: + { + if (!isPaused) + { + zLightUpdate(b[i], s, dt); + } + break; + } + case eBaseTypeSurface: + { + if (!isPaused || ((xSurface*)b[i])->type == XSURFACE_TYPE_3) + { + zSurfaceUpdate(b[i], s, dt); + } + break; + } + case eBaseTypeBusStop: + { + if (!isPaused) + { + zBusStop_Update(b[i], s, dt); + } + break; + } + case eBaseTypeDiscoFloor: + { + if (!isPaused) + { + ((z_disco_floor*)b[i])->update(*s, dt); + } + + break; + } + case eBaseTypeTaxi: + { + if (!isPaused) + { + zTaxi_Update(b[i], s, dt); + } + break; + } + case eBaseTypeCameraFly: + { + if (!isPaused) + { + zCameraFly_Update(b[i], s, dt); + } + break; + } + } + } + } + + if (!isPaused) + { + zEntSimpleObj_MgrCustomUpdate(s, dt); + } + + if (isPaused) + { + zUI_ScenePortalUpdate(); + } + else + { + zUI_ScenePortalSetToCurrentLevel(s); + } + + zNPCCommon_EjectPhlemOnPawz(); + + if (!isPaused) + { + zActionLineUpdate(dt); + xFXStreakUpdate(dt); + xFXShineUpdate(dt); + xFXFireworksUpdate(dt); + zLightningUpdate(dt); + zGustUpdateFX(dt); + xClimateUpdate(&gClimate, dt); + zShrapnel_Update(dt); + zCombo_Update(dt); + zFXUpdate(dt); + zLOD_Update(sSuddenMove ? 100 : 5); + zParPTankUpdate(dt); + xDecalUpdate(dt); + xCMupdate(dt); + + if (s->pendingPortal) + { + zGameStateSwitch(eGameState_SceneSwitch); + } + } + else + { + zCombo_HideImmediately(); + } +} + +static void zSceneRenderPreFX() +{ + zScene* s = globals.sceneCur; + + globals.currWorld = s->env->geom->world; + + xLightKit_Enable(NULL, globals.currWorld); + + zRenderState(SDRS_SkyBack); + xSkyDome_Render(); + + zRenderState(SDRS_Environment); + zLightAddLocalEnv(); + zEnvRender(s->env); + zLightRemoveLocalEnv(); + + zRenderState(SDRS_OpaqueModels); + z_disco_floor::render_all(); + + U32 shadowHackCase = 0; + + xEnt** entptr = &s->act_ents[s->num_act_ents - 1]; + xEnt** entlast = &s->act_ents[s->baseCount[eBaseTypeTrigger] + s->baseCount[eBaseTypePickup] + + s->baseCount[eBaseTypeStatic]]; + + xModelBucket_Begin(); + zEntSimpleObj_MgrUpdateRender(globals.currWorld, sTimeElapsed); + zEntSimpleObj_MgrCustomRender(); + + while (entptr >= entlast) + { + xEnt* ent = *entptr; + + if (ent->collType != XENT_COLLTYPE_TRIG) + { + if (ent->collType == XENT_COLLTYPE_PLYR) + { + shadowHackCase = 1; + } + else if (ent->render) + { + xLightKit_Enable(ent->lightKit, globals.currWorld); + ent->render(ent); + } + } + + entptr--; + } + + zShrapnel_Render(); + zEntPickup_Render((zEntPickup*)s->baseList[eBaseTypePickup], s->baseCount[eBaseTypePickup]); + xModelBucket_RenderOpaque(); + zNPCCommon_Glyphs_RenderAll(1); + zNPCCommon_Hazards_RenderAll(1); + xLightKit_Enable(NULL, globals.currWorld); + zEntPickup_RenderList((zEntPickup*)s->baseList[eBaseTypePickup], s->baseCount[eBaseTypePickup]); + + if (shadowHackCase == 1 && globals.player.Transparent <= 0 && !oob_state::render()) + { + xLightKit_Enable(globals.player.ent.lightKit, globals.currWorld); + + globals.player.ent.render(&globals.player.ent); + + xLightKit_Enable(NULL, globals.currWorld); + } + + if (globals.cmgr && globals.cmgr->csn->Ready) + { + xLightKit* objLightKit = NULL; + + if (globals.sceneCur->zen->easset->objectLightKit) + { + objLightKit = + (xLightKit*)xSTFindAsset(globals.sceneCur->zen->easset->objectLightKit, NULL); + } + + if (objLightKit) + { + xLightKit_Enable(objLightKit, globals.currWorld); + } + + xCutscene_Render(globals.cmgr->csn, NULL, NULL, NULL); + + if (objLightKit) + { + xLightKit_Enable(NULL, globals.currWorld); + } + } + + zEntPlayer_ShadowModelEnable(); + xShadowManager_Render(); + zEntPlayer_ShadowModelDisable(); + xShadowSimple_Render(); + + zRenderState(SDRS_AlphaModels); + xModelBucket_RenderAlpha(); + z_disco_floor::effects_render_all(); + xFXRingRender(); + + zRenderState(SDRS_Lightning); + zLightningRender(); + zActionLineRender(); + + zRenderState(SDRS_Streak); + xFXStreakRender(); + xFXShineRender(); + xFXRibbonRender(); + xFXAuraRender(); + + zRenderState(SDRS_Particles); + + zParSys* psys = (zParSys*)s->baseList[eBaseTypeParticleSystem]; + + for (S32 i = s->baseCount[eBaseTypeParticleSystem] - 1; i >= 0; i--, psys++) + { + xParSysRender(psys); + } + + xLightKit_Enable(NULL, globals.currWorld); + + zRenderState(SDRS_NPCVisual); + zNPCMgr_scenePostRender(); + zNPCCommon_Glyphs_RenderAll(0); + zNPCCommon_Hazards_RenderAll(0); + + zRenderState(SDRS_AlphaModels); + xParMgrRender(); + zParPTankRender(); + xPTankPoolRender(); + zNPCMgr_scenePostParticleRender(); + xDecalRender(); +} + +static void zSceneRenderPostFX() +{ + zRenderState(SDRS_Glare); + + xScrFXGlareRender(&globals.camera); + xScrFXFullScreenGlareRender(); + + if (zGameModeGet() == eGameMode_Intro && + (zGameStateGet() == eIntroState_Sony || zGameStateGet() == eIntroState_Publisher)) + { + render_mem_card_no_space(bytesNeeded, availOnDisk, neededFiles, + zGameStateGet() == eIntroState_Sony); + } + + cruise_bubble::render_screen(); + oob_state::fx_render(); + + zRenderState(SDRS_Font); + ztextbox::render_all(); + ztalkbox::render_all(); + + zRenderState(SDRS_Font); + xDrawEnd(); + xDrawBegin(); + + RwCameraEndUpdate(globals.camera.lo_cam); + RwCameraClear(globals.camera.lo_cam, NULL, rwCAMERACLEARZ); + RwCameraBeginUpdate(globals.camera.lo_cam); + + zUIRenderAll(); + + eGameMode mode = zGameModeGet(); + + if (mode != eGameMode_Game && mode != eGameMode_Stall) + { + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, NULL); + zSceneSpawnRandomBubbles(); + + if (mode == eGameMode_Pause || mode == eGameMode_Save) + { + zParPTankUpdate(sTimeElapsed); + } + + zParPTankRender(); + } + + switch (mode) + { + case eGameMode_Load: + case eGameMode_WorldMap: + case eGameMode_ConceptArtGallery: + { + break; + } + default: + { + zRenderState(SDRS_HUD); + zhud::render(); + } + } + + xParMgrRender(); + + if (!zGameIsPaused()) + { + xCMrender(); + } + + if (zGameModeGet() == eGameMode_Intro && + (zGameStateGet() == eIntroState_Sony || zGameStateGet() == eIntroState_Publisher)) + { + render_mem_card_no_space(bytesNeeded, availOnDisk, neededFiles, + zGameStateGet() == eIntroState_Sony); + } + + xTRCRender(); + + if (zGameModeGet() == eGameMode_Intro && zGameStateGet() == eIntroState_License) + { + xScrFxDrawScreenSizeRectangle(); + } +} + +void zSceneRender() +{ + zSceneRenderPreFX(); + xScrFxRender(globals.camera.lo_cam); + zSceneRenderPostFX(); +} + +static void zSceneObjHashtableInit(S32 count) +{ + scobj_idbps = (IDBasePair*)xMemAllocSize(count * sizeof(IDBasePair)); + + memset(scobj_idbps, 0, count * sizeof(IDBasePair)); + + scobj_size = count; + nidbps = 0; +} + +static void zSceneObjHashtableExit() +{ + scobj_idbps = NULL; + scobj_size = -1; + nidbps = -1; +} + +static S32 zSceneObjHashtableUsage() +{ + return nidbps; +} + +static void zSceneObjHashtableAdd(U32 id, xBase* base) +{ + S32 k, chkd; + + chkd = id & (scobj_size - 1); + + for (k = 0; k < scobj_size; k++) + { + IDBasePair* idbp = &scobj_idbps[chkd]; + + if (idbp->id == 0) + { + idbp->id = id; + idbp->base = base; + nidbps++; + break; + } + + chkd++; + + if (chkd == scobj_size) + { + chkd = 0; + } + } +} + +static xBase* zSceneObjHashtableGet(U32 id) +{ + S32 k, chkd; + + chkd = id & (scobj_size - 1); + + for (k = 0; k < scobj_size; k++) + { + IDBasePair* idbp = &scobj_idbps[chkd]; + + if (idbp->id == id) + { + return idbp->base; + } + + if (idbp->id == 0) + { + return NULL; + } + + chkd++; + + if (chkd == scobj_size) + { + chkd = 0; + } + } + + return NULL; +} + +xBase* zSceneFindObject(U32 gameID) +{ + return zSceneObjHashtableGet(gameID); +} + +xBase* zSceneGetObject(S32 type, S32 idx) +{ + zScene* s = globals.sceneCur; + + if (s) + { + for (U32 i = 0; i < s->num_base; i++) + { + if (s->base[i] && type == s->base[i]->baseType) + { + if (idx == 0) + { + return s->base[i]; + } + else + { + idx--; + } + } + } + } + + return NULL; +} + +const char* zSceneGetName(U32 gameID) +{ + xBase* b = zSceneFindObject(gameID); + + if (b) + { + return zSceneGetName(b); + } + + return ""; +} + +const char* zSceneGetName(xBase* b) +{ + if (b) + { + const char* n = xSTAssetName(b->id); + + if (n) + { + return n; + } + } + + return ""; +} + +void zSceneForAllBase(xBase* (*func)(xBase*, zScene*, void*), void* data) +{ + zScene* s = globals.sceneCur; + + if (s) + { + for (U16 i = 0; i < s->num_base; i++) + { + if (!func(s->base[i], s, data)) + { + break; + } + } + } +} + +void zSceneForAllBase(xBase* (*func)(xBase*, zScene*, void*), S32 baseType, void* data) +{ + zScene* s = globals.sceneCur; + + if (s) + { + for (U16 i = 0; i < s->num_base; i++) + { + if (baseType == s->base[i]->baseType) + { + if (!func(s->base[i], s, data)) + { + break; + } + } + } + } +} + +static xBase* zSceneExitSoundIteratorCB(xBase* b, zScene*, void*) +{ + xSndParentDied((U32)b); + return b; +} + +void zSceneMemLvlChkCB() +{ +} + +U32 zSceneLeavingLevel() +{ + // non-matching: instruction order + + char curScene[4] = ""; + char nextScene[4] = ""; + + strncpy(curScene, xStrupr(xUtil_idtag2string(globals.sceneCur->sceneID, 0)), 4); + strncpy(nextScene, + xStrupr(xUtil_idtag2string(globals.sceneCur->pendingPortal->passet->sceneID, 0)), 4); + + return (curScene[0] != nextScene[3]); +} + +const char* zSceneGetLevelName(U32 sceneID) +{ + char c1 = (sceneID >> 24) & 0xFF; + char c2 = (sceneID >> 16) & 0xFF; + + for (S32 i = 0; i < sizeof(sLevelTable) / sizeof(sLevelTable[0]); i++) + { + if (c1 == sLevelTable[i].prefix[0] && c2 == sLevelTable[i].prefix[1]) + { + return sLevelTable[i].desc; + } + } + + return "Level Not Found"; +} + +U32 zSceneGetLevelIndex() +{ + return zSceneGetLevelIndex(globals.sceneCur->sceneID); +} + +U32 zSceneGetLevelIndex(U32 sceneID) +{ + char c1 = (sceneID >> 24) & 0xFF; + char c2 = (sceneID >> 16) & 0xFF; + + for (S32 i = 0; i < sizeof(sLevelTable) / sizeof(sLevelTable[0]); i++) + { + if (c1 == sLevelTable[i].prefix[0] && c2 == sLevelTable[i].prefix[1]) + { + return i; + } + } + + return 0; +} + +const char* zSceneGetLevelPrefix(U32 index) +{ + if (index >= sizeof(sLevelTable) / sizeof(sLevelTable[0])) + { + return NULL; + } + + return sLevelTable[index].prefix; +} + +const char* zSceneGetAreaname(U32) +{ + return "Temp"; +} + +U32 zSceneCalcProgress() +{ + return globals.player.Inv_Spatula; +} + +void zScene_UpdateFlyToInterface(F32 dt) +{ + zScene* s = globals.sceneCur; + + zEntPickup_UpdateFlyToInterface((zEntPickup*)s->baseList[eBaseTypePickup], + s->baseCount[eBaseTypePickup], dt); +} + +void zSceneCardCheckStartup_set(S32 needed, S32 available, S32 files) +{ + bytesNeeded = needed; + availOnDisk = available; + neededFiles = files; +} + +void zSceneEnableVisited(zScene* s) +{ + U32 uiNameID; + char uiName[64]; + char* sceneName; + + sceneName = xUtil_idtag2string(s->sceneID, 0); + + strcpy(uiName, sceneName); + + uiName[1] = ' '; + + strcat(uiName, " VISITED"); + + uiNameID = xStrHash(uiName); + + for (U32 i = 0; i < s->num_base; i++) + { + if (s->base[i] && s->base[i]->baseType == eBaseTypeUI && uiNameID == s->base[i]->id) + { + s->base[i]->baseFlags |= 0x1; + } + } +} + +void zSceneEnableScreenAdj(U32 enable) +{ + enableScreenAdj = enable; +} + +void zSceneSetOldScreenAdj() +{ + oldOffsetx = offsetx; + oldOffsety = offsety; +} + +U32 zScene_ScreenAdjustMode() +{ + return enableScreenAdj; +} + +xVec3 scale = { 0.2f, -0.7f, 1.5f }; + +void zSceneSpawnRandomBubbles() +{ + RwCamera* currentCamera = RwCameraGetCurrentCamera(); + + if (!currentCamera || zMenuIsFirstBoot()) + { + return; + } + + RwMatrix* mat = RwFrameGetMatrix(RwCameraGetFrame(currentCamera)); + F32 floatRand = xurand(); + + if (floatRand > 0.985f) + { + xVec3 pos, var_48; + F32 r; + + pos.x = mat->pos.x; + pos.y = mat->pos.y; + pos.z = mat->pos.z; + + r = xurand(); + r *= (((S32)(10000 * floatRand) % 2) ? 1 : -1); + + xVec3ScaleC(&var_48, (xVec3*)&mat->right, r, r, r); + xVec3Add(&pos, &pos, &var_48); + xVec3ScaleC(&var_48, (xVec3*)&mat->up, scale.y, scale.y, scale.y); + xVec3Add(&pos, &pos, &var_48); + xVec3ScaleC(&var_48, (xVec3*)&mat->at, scale.z, scale.z, scale.z); + xVec3Add(&pos, &pos, &var_48); + + zFX_SpawnBubbleMenuTrail(&pos, 1, NULL, NULL); + } +} + +static void zSceneAutoSave() +{ +} + +void xSystem_GapTrackReport() +{ +} + +void xDecalDestroy() +{ +} + +void xDecalRender() +{ +} + +U32 xBaseIsValid(xBase* xb) +{ + return xb->baseFlags & 0x4; +} + +void xModelBucket_RenderAlpha() +{ + xModelBucket_RenderAlphaBegin(); + xModelBucket_RenderAlphaLayer(31); + xModelBucket_RenderAlphaEnd(); +} + +void xNPCBasic::Save(xSerial*) const +{ +} + +void xNPCBasic::Load(xSerial*) +{ +} + +void xQuickCullInit(const xBox* box) +{ + xQuickCullInit(&xqc_def_ctrl, box); +} diff --git a/src/SB/Game/zScene.h b/src/SB/Game/zScene.h new file mode 100644 index 0000000..f325a95 --- /dev/null +++ b/src/SB/Game/zScene.h @@ -0,0 +1,72 @@ +#ifndef ZSCENE_H +#define ZSCENE_H + +#include "xScene.h" +#include "xClimate.h" + +#include "zPortal.h" +#include "xEnt.h" +#include "xEnv.h" +#include "zBase.h" + +struct zEnt; + +struct zScene : xScene +{ + _zPortal* pendingPortal; + union + { + U32 num_ents; + U32 num_base; + }; + union + { + xBase** base; + zEnt** ents; + }; + U32 num_update_base; + xBase** update_base; + U32 baseCount[eBaseTypeCount]; + xBase* baseList[eBaseTypeCount]; + _zEnv* zen; +}; + +extern _tagClimate gClimate; +extern _zEnv* gCurEnv; +extern U32 gTransitionSceneID; +extern F32 gSceneUpdateTime; + +void zSceneSet(xBase* b, U32 index); +void zSceneInitEnvironmentalSoundEffect(); +void zSceneInit(U32 theSceneID, S32 reloadInProgress); +void zSceneExit(S32 beginReload); +void zSceneUpdateSFXWidgets(); +void zSceneSwitch(_zPortal* p, S32 forceSameScene); +void zSceneSave(zScene* ent, xSerial* s); +void zSceneLoad(zScene* ent, xSerial* s); +void zSceneSetup(); +void zSceneUpdate(F32 dt); +void zSceneRender(); +xBase* zSceneFindObject(U32 gameID); +xBase* zSceneGetObject(S32 type, S32 idx); +const char* zSceneGetName(U32 gameID); +const char* zSceneGetName(xBase* b); +void zSceneForAllBase(xBase* (*func)(xBase*, zScene*, void*), void* data); +void zSceneForAllBase(xBase* (*func)(xBase*, zScene*, void*), S32 baseType, void* data); +void zSceneMemLvlChkCB(); +U32 zSceneLeavingLevel(); +const char* zSceneGetLevelName(U32 sceneID); +U32 zSceneGetLevelIndex(); +U32 zSceneGetLevelIndex(U32 sceneID); +const char* zSceneGetLevelPrefix(U32 index); +const char* zSceneGetAreaname(U32); +U32 zSceneCalcProgress(); +void zScene_UpdateFlyToInterface(F32 dt); +void zSceneCardCheckStartup_set(S32 needed, S32 available, S32 files); +void zSceneEnableVisited(zScene* s); +void zSceneEnableScreenAdj(U32 enable); +void zSceneSetOldScreenAdj(); +U32 zScene_ScreenAdjustMode(); +void zSceneSpawnRandomBubbles(); + +#endif diff --git a/src/SB/Game/zShrapnel.cpp b/src/SB/Game/zShrapnel.cpp new file mode 100644 index 0000000..305fd9a --- /dev/null +++ b/src/SB/Game/zShrapnel.cpp @@ -0,0 +1,3 @@ +#include "zShrapnel.h" + +#include diff --git a/src/SB/Core/x/xFrag.h b/src/SB/Game/zShrapnel.h similarity index 50% rename from src/SB/Core/x/xFrag.h rename to src/SB/Game/zShrapnel.h index a49cfe9..ccc0de2 100644 --- a/src/SB/Core/x/xFrag.h +++ b/src/SB/Game/zShrapnel.h @@ -1,26 +1,18 @@ -#ifndef XFRAG_H -#define XFRAG_H +#ifndef ZSHRAPNEL_H +#define ZSHRAPNEL_H -#include "xMath.h" -#include "xEnt.h" -#include "xPar.h" +#include "xModel.h" +#include "xCurveAsset.h" +#include "xCollide.h" -enum zFragType -{ - eFragInactive, - eFragGroup, - eFragShrapnel, - eFragParticle, - eFragProjectile, - eFragLightning, - eFragSound, - eFragShockwave, - eFragExplosion, - eFragDistortion, - eFragFire, - eFragCount, - eFragForceSize = 0x7fffffff -}; +#include "zParEmitter.h" +//#include "zLightning.h" + +#include +#include + +typedef struct zFrag; +typedef struct zShrapnelAsset; enum zFragLocType { @@ -34,15 +26,6 @@ enum zFragLocType eFragLocForceSize = 0x7fffffff }; -struct zFragAsset -{ - zFragType type; - U32 id; - U32 parentID[2]; - F32 lifetime; - F32 delay; -}; - struct zFragBone { S32 index; @@ -62,59 +45,41 @@ struct zFragLocation { zFragLocType type; zFragLocInfo info; - F32 rand_radius; }; -struct presence_volume +enum zFragType { - F32 knockback; - xVec3 center; - F32 radius; - F32 damage_player; - F32 damage_npc; - F32 damage_other; + eFragInactive, + eFragGroup, + eFragShrapnel, + eFragParticle, + eFragProjectile, + eFragLightning, + eFragSound, + eFragShockwave, + eFragCount, + eFragForceSize = 0x7fffffff }; -struct trail_emitter +struct zFragAsset { - S32 type; - xVec3 loc; - F32 emitted; - S32 glare_id; - F32 streak_delay; - F32 streaks_emitted; - F32 spark_delay; - F32 sparks_emitted; - presence_volume* presence; - iSndHandle tracking_sound; + zFragType type; + U32 id; + U32 parentID[2]; + F32 lifetime; + F32 delay; }; -struct zFrag; - struct zFragGroup { zFrag* list[21]; }; -struct zShrapnelAsset; - -struct zFragShrapnelAsset : zFragAsset -{ - U32 shrapnelID; - zShrapnelAsset* shrapAsset; -}; - -struct zFragShrapnel -{ - zFragShrapnelAsset* fasset; -}; - struct zFragParticleAsset : zFragAsset { zFragLocation source; zFragLocation vel; xParEmitterCustomSettings emit; - U32 flags; U32 parEmitterID; zParEmitter* parEmitter; }; @@ -124,19 +89,12 @@ struct zFragParticle zFragParticleAsset* fasset; }; -struct xCurveAsset -{ -}; - struct zFragProjectileAsset : zFragAsset { U32 modelInfoID; RpAtomic* modelFile; zFragLocation launch; zFragLocation vel; - zFragLocation velPlusMinus; - zFragLocation rot; - zFragLocation rotPlusMinus; F32 bounce; S32 maxBounces; U32 flags; @@ -159,9 +117,8 @@ struct zFragProjectile F32 tColl; S32 numBounces; F32 scale; + F32 parentScale; F32 alpha; - F32 bounceC1; - F32 bounceC2; xVec3 N; xVec3 axis; }; @@ -174,26 +131,28 @@ struct zFragLightningAsset : zFragAsset U32 endParentID; }; -struct zLightning; - struct zFragLightning { zFragLightningAsset* fasset; xModelInstance* startParent; xModelInstance* endParent; - zLightning* lightning; + //zLightning* lightning; }; struct zFragSoundAsset : zFragAsset { U32 assetID; zFragLocation source; + F32 volume; + F32 innerRadius; + F32 outerRadius; }; struct zFragSound { zFragSoundAsset* fasset; - iSndHandle soundID; + xVec3 location; + U32 soundID; }; struct zFragShockwaveAsset : zFragAsset @@ -221,71 +180,16 @@ struct zFragShockwave F32 deltColor[4]; }; -struct zFragExplosionAsset : zFragAsset -{ - U32 type; - zFragLocation loc; - U32 flags; -}; - -struct zFragExplosion -{ - zFragExplosionAsset* fasset; - trail_emitter trail; - xVec3 initPos; -}; - -struct zFragDistortionAsset : zFragAsset -{ - U32 type; - zFragLocation loc; - U32 flags; - F32 radius; - F32 duration; - F32 intensity; - F32 freq; - F32 repeat_delay; -}; - -struct zFragDistortion -{ - zFragDistortionAsset* fasset; - xVec3 loc; - S32 type; - F32 repeat_time; -}; - -struct zFragFireAsset : zFragAsset -{ - zFragLocation loc; - U32 flags; - F32 radius; - F32 scale; - F32 fuel; - F32 heat; - F32 damage; - F32 knockback; -}; - -struct zFragFire -{ - zFragFireAsset* fasset; -}; - struct zFragInfo { union { zFragGroup group; - zFragShrapnel shrapnel; zFragParticle particle; zFragProjectile projectile; zFragLightning lightning; zFragSound sound; zFragShockwave shockwave; - zFragExplosion explosion; - zFragDistortion distortion; - zFragFire fire; }; }; @@ -297,69 +201,11 @@ struct zFrag F32 alivetime; F32 lifetime; void (*update)(zFrag*, F32); - void (*destroy)(zFrag*); xModelInstance* parent[2]; zFrag* prev; zFrag* next; }; -struct _class_9 -{ - xVec3 endPoint[2]; - xVec3 endPointB; - xVec3 direction; - F32 length; - F32 scale; - F32 width; - F32 endParam[2]; - F32 endVel[2]; - F32 paramSpan[2]; -}; - -struct xColor_tag // Will need moved after we fill other files -{ - U8 r; - U8 g; - U8 b; - U8 a; - RwRGBA rgba; -}; - -struct zLightning -{ - U32 type; - U32 flags; - _class_9 func; - U32 numStrips; - F32 alphaRamp; - xColor_tag color; - F32 time_left; - F32 time_total; - zLightning* nextBranch; - zLightning* prevBranch; - F32 parentSegment; - F32 lastParentSegment; - F32 segmentsPerMeter; - F32 branchSpeed; - S32 damage; - F32 knockBackSpeed; - RwRaster* mainTexture; - RwRaster* branchTexture; - F32 sparkTimer; - xVec3 collisionPoint; - F32 genTime; - U8 randomizeBranchEndPoint; - U8 collisionEnabled; - iSndHandle sndHandle; - xEnt* followStart; - xVec3 followStartOffset; - xEnt* followEnd; - xVec3 followEndOffset; - void (*renderCB)(zLightning*, RxObjSpace3DVertex*, RxObjSpace3DVertex*, U32); - void* context; - F32 weightParam[12]; -}; - struct zShrapnelAsset { S32 fassetCount; @@ -367,4 +213,11 @@ struct zShrapnelAsset void (*initCB)(zShrapnelAsset*, xModelInstance*, xVec3*, void (*)(zFrag*, zFragAsset*)); }; +struct zScene; + +void zShrapnel_SceneInit(zScene*); +void zShrapnel_Update(F32 dt); +void zShrapnel_Reset(); +void zShrapnel_Render(); + #endif diff --git a/src/SB/Game/zTalkBox.cpp b/src/SB/Game/zTalkBox.cpp index e69de29..d7546f1 100644 --- a/src/SB/Game/zTalkBox.cpp +++ b/src/SB/Game/zTalkBox.cpp @@ -0,0 +1,21 @@ +#include "zTalkBox.h" + +#include + +// DIRECTLY PORTED FROM BFBB + +namespace +{ + struct SharedTalkboxState + { + void* padding[2]; // FIXME: variables not verified + ztalkbox* active; + }; + + SharedTalkboxState ztalkbox_shared; +} // namespace + +ztalkbox* ztalkbox::get_active() +{ + return ztalkbox_shared.active; +} diff --git a/src/SB/Game/zTalkBox.h b/src/SB/Game/zTalkBox.h new file mode 100644 index 0000000..0d335d7 --- /dev/null +++ b/src/SB/Game/zTalkBox.h @@ -0,0 +1,99 @@ +#ifndef ZTALKBOX_H +#define ZTALKBOX_H + +#include "zTextBox.h" +//#include "zNPCTypeCommon.h" + +#include "xScene.h" +#include "zNMECommon.h" + +// DIRECTLY PORTED FROM BFBB + +struct ztalkbox : xBase +{ + struct asset_type : xDynAsset + { + U32 dialog_box; + U32 prompt_box; + U32 quit_box; + bool trap : 8; + bool pause : 8; + bool allow_quit : 8; + bool trigger_pads : 8; + bool page : 8; + bool show : 8; + bool hide : 8; + bool audio_effect : 8; + U32 teleport; + struct + { + struct + { + bool time : 8; + bool prompt : 8; + bool sound : 8; + bool event : 8; + } type; + F32 delay; + S32 which_event; + } auto_wait; + struct + { + U32 skip; + U32 noskip; + U32 quit; + U32 noquit; + U32 yesno; + } prompt; + }; + + enum answer_enum + { + ANSWER_CONTINUE, + ANSWER_YES, + ANSWER_NO, + ANSWER_3, + }; + + struct callback + { + callback(); + virtual void on_signal(U32); + virtual void on_start(); + virtual void on_stop(); + virtual void on_answer(answer_enum); + }; + + struct + { + bool visible : 1; + } flag; + asset_type* asset; + ztextbox* dialog_box; + ztextbox* prompt_box; + ztextbox* quit_box; + struct + { + const char* skip; + const char* noskip; + const char* quit; + const char* noquit; + const char* yesno; + } prompt; + zNPCCommon* npc; + + static void init(); + static void load(xBase& data, xDynAsset& asset, size_t); + static void update_all(xScene& s, F32 dt); + static void render_all(); + static void reset_all(); + static void permit(U32 add_flags, U32 remove_flags); + + static ztalkbox* get_active(); + void start_talk(U32 textID, callback*, zNPCCommon*); // FIXME: params not verified + void stop_talk(); + + void set_text(U32 textID); +}; + +#endif diff --git a/src/SB/Game/zTaskBox.cpp b/src/SB/Game/zTaskBox.cpp index e69de29..d9b5841 100644 --- a/src/SB/Game/zTaskBox.cpp +++ b/src/SB/Game/zTaskBox.cpp @@ -0,0 +1,239 @@ +#include "zTaskBox.h" + +#include "xEvent.h" +#include "xstransvc.h" + +#include "zBase.h" +#include "zScene.h" +#include "zTalkBox.h" + +#include + +// CODE PORTED DIRECTLY FROM BFBB + +extern ztaskbox* shared; + +void ztaskbox::load(const asset_type& a) +{ + xBaseInit((xBase*)this, &(xBaseAsset)a); + this->baseType = eBaseTypeEnv; + // FIXME: can't force const to non-const? + // this->asset = &a; + + // FIXME: Define cb_dispatch + // this->eventFunc = cb_dispatch; + if (this->linkCount != 0) + { + this->link = (xLinkAsset*)(&a + 1); + } + bool enabled = a.enable; + this->state = STATE_INVALID; + if (!enabled) + { + this->flag.enabled = false; + this->current = NULL; + } + else + { + this->flag.enabled = true; + this->set_state(STATE_BEGIN); + this->current = this; + } + if (a.persistent) + { + this->baseFlags |= 2; + } +} + +void ztaskbox::read(xSerial& s) +{ + U8 data[4]; + data[0] = (U8)this->state; + s.Read(data); + set_state((ztaskbox::state_enum)data[0]); +} + +void ztaskbox::write(xSerial& s) +{ + s.Write((U8)this->state); +} + +// WIP. +void ztaskbox::start_talk(zNPCCommon* npc) +{ + ztaskbox* curr = this->current; + if (curr != NULL) + { + if (curr == this) + { + if (this->flag.enabled && this->state != STATE_INVALID) + { + //TODO!!! + } + } + else + { + curr->set_callback(this->cb); + this->current->start_talk(NULL); + } + } +} + +void ztaskbox::talk_callback::reset(ztaskbox& task) +{ + this->task = &task; + this->answer = ztalkbox::ANSWER_CONTINUE; +} + +void ztaskbox::stop_talk() +{ + ztaskbox* curr = this->current; + + if (curr == NULL) + { + return; + } + + if (curr != this) + { + curr->stop_talk(); + return; + } + + if (!this->flag.enabled || this->state == STATE_INVALID) + { + return; + } + + if (shared != this) + { + return; + } + + ztalkbox* other = (ztalkbox*)zSceneFindObject(this->asset->talk_box); + + if (other) + { + other->stop_talk(); + shared = NULL; + } +} + +void ztaskbox::enable() +{ + if (!this->flag.enabled) + { + this->flag.enabled = true; + set_state(STATE_BEGIN); + } +} + +void ztaskbox::disable() +{ + if (this->flag.enabled) + { + stop_talk(); + this->flag.enabled = false; + set_state(STATE_INVALID); + } +} + +void ztaskbox::reset() +{ + disable(); + if (this->asset->enable) + { + enable(); + } +} + +void ztaskbox::initiate() +{ + if (this->state == STATE_BEGIN) + { + set_state(STATE_DESCRIPTION); + } +} + +void ztaskbox::succeed() +{ + if (state == STATE_BEGIN || state == STATE_DESCRIPTION || state == STATE_REMINDER) + { + set_state(STATE_SUCCESS); + } +} + +void ztaskbox::fail() +{ + if (state == STATE_BEGIN || state == STATE_DESCRIPTION || state == STATE_REMINDER) + { + set_state(STATE_FAILURE); + } +} + +void ztaskbox::complete() +{ + if (this->flag.enabled) + { + this->state = STATE_INVALID; + this->flag.enabled = false; + zEntEvent(this, this, eEventTaskBox_OnComplete); + this->current = (ztaskbox*)zSceneFindObject(this->asset->next_task); + + // Bruh + if (this->current != NULL) + { + return; + } + } +} + +void ztaskbox::set_callback(callback* cb) +{ + this->cb = cb; +} + +// WIP. +void ztaskbox::init() +{ + shared = NULL; + // STUFF. +} + +ztaskbox::talk_callback::talk_callback() +{ +} + +void ztaskbox::load(xBase& data, xDynAsset& asset, size_t num) +{ + ((ztaskbox&)data).load((asset_type&)asset); +} + +bool ztaskbox::exists(state_enum stage) +{ + U32 state = this->asset->stages[stage]; + return state != STATE_BEGIN && xSTFindAsset(state, NULL); +} + +void ztaskbox::on_talk_start() +{ + if (this->cb != NULL) + { + cb->on_talk_start(); + } +} + +void ztaskbox::talk_callback::on_start() +{ + this->task->on_talk_start(); +} + +void ztaskbox::talk_callback::on_stop() +{ + this->task->on_talk_stop(answer); +} + +void ztaskbox::talk_callback::on_answer(ztalkbox::answer_enum answer) +{ + this->answer = answer; +} diff --git a/src/SB/Game/zTaskBox.h b/src/SB/Game/zTaskBox.h new file mode 100644 index 0000000..a1e5005 --- /dev/null +++ b/src/SB/Game/zTaskBox.h @@ -0,0 +1,90 @@ +#ifndef ZTASKBOX_H +#define ZTASKBOX_H + +#include "xBase.h" +#include "xDynAsset.h" + +#include "zNMECommon.h" +#include "zTalkBox.h" + +#include + +// DIRECTLY PORTED FROM BFBB + +struct ztaskbox : xBase +{ + struct flagData + { + U8 enabled : 8; + U32 dummy : 24; + }; + + enum state_enum + { + STATE_BEGIN, + STATE_DESCRIPTION, + STATE_REMINDER, + STATE_SUCCESS, + STATE_FAILURE, + STATE_END, + MAX_STATE, + STATE_INVALID = 0xffffffff + }; + + struct callback + { + virtual void on_talk_start(); + virtual void on_talk_stop(); + }; + + struct talk_callback : ztalkbox::callback + { + ztaskbox* task; + ztalkbox::answer_enum answer; + + talk_callback(); + void reset(ztaskbox& task); + void on_start(); + void on_stop(); + void on_answer(ztalkbox::answer_enum answer); + }; + + struct asset_type : xDynAsset + { + U8 persistent : 8; + U8 loop : 8; + U8 enable : 8; + U8 retry : 8; + U32 talk_box; + U32 next_task; + U32 stages[6]; + }; + + flagData flag; + asset_type* asset; + state_enum state; + callback* cb; + ztaskbox* current; + + void on_talk_start(); + void on_talk_stop(ztalkbox::answer_enum answer); + void set_state(state_enum state); + void set_callback(callback* cb); + void stop_talk(); + void start_talk(zNPCCommon* npc); + void write(xSerial& s); + void read(xSerial& s); + void load(const asset_type& a); + static void load(xBase& data, xDynAsset& asset, size_t num); + void enable(); + void disable(); + void reset(); + void initiate(); + void succeed(); + void fail(); + void complete(); + static void init(); + bool exists(state_enum stage); +}; + +#endif diff --git a/src/SB/Game/zTextBox.cpp b/src/SB/Game/zTextBox.cpp index e69de29..cd27a79 100644 --- a/src/SB/Game/zTextBox.cpp +++ b/src/SB/Game/zTextBox.cpp @@ -0,0 +1,467 @@ +#include "zTextBox.h" + +#include "zBase.h" + +#include "xEvent.h" +#include "xstransvc.h" +#include "xTextAsset.h" + +#include + +extern F32 _720_1; +extern F32 _721_1; +extern F32 _722_0; +extern F32 _723_0; +extern F32 _761_1; + +static RwIm2DVertex vert_701[6]; // todo: move to render_bk_tex_scale + +iColor_tag convert(const ztextbox::asset_type::color_type& color); + +namespace +{ + ztextbox* head_active; + + typedef void (*render_bk_callback)(const ztextbox& e); + + void render_bk_fill(const ztextbox& e); + void render_bk_tex_scale(const ztextbox& e); + void render_bk_tex_wrap(const ztextbox& e); + + render_bk_callback render_bk_table[] = { render_bk_fill, render_bk_tex_scale, + render_bk_tex_wrap }; + + void parse_tag_blahblah(xtextbox::jot&, const xtextbox&, const xtextbox&, + const xtextbox::split_tag&); + + xtextbox::tag_type new_tags[] = { SUBSTR("blahblah"), parse_tag_blahblah, NULL, NULL }; + U32 new_tags_size = sizeof(new_tags) / sizeof(new_tags[0]); + + void set_vert(RwIm2DVertex& vert, F32 x, F32 y, F32 u, F32 v, iColor_tag c, F32 nsz, F32 rcz); + + void render_bk_fill(const ztextbox& e) + { + const ztextbox::asset_type& a = *e.asset; + + render_fill_rect(e.tb.font.clip, convert(a.backdrop.color)); + } + + void render_bk_tex_scale(const ztextbox& e) + { + // non-matching: float instruction order + + iColor_tag c = convert(e.asset->backdrop.color); + + F32 rcz = _720_1 / RwCameraGetNearClipPlane(RwCameraGetCurrentCamera()); + F32 nsz = RwIm2DGetNearScreenZ(); + + xfont::set_render_state(e.bgtex); + + basic_rect r = e.tb.font.clip; + r.scale(_721_1, _722_0); + + set_vert(vert_701[0], r.x, r.y, _723_0, _720_1, c, nsz, rcz); + set_vert(vert_701[1], r.x, r.y + r.h, _723_0, _720_1, c, nsz, rcz); + set_vert(vert_701[2], r.x + r.w, r.y, _720_1, _723_0, c, nsz, rcz); + + vert_701[3] = vert_701[2]; + vert_701[4] = vert_701[1]; + + set_vert(vert_701[5], r.x + r.w, r.y + r.h, _720_1, _720_1, c, nsz, rcz); + + RwIm2DRenderPrimitive(rwPRIMTYPETRILIST, vert_701, 6); + + xfont::restore_render_state(); + } + + void set_vert(RwIm2DVertex& vert, F32 x, F32 y, F32 u, F32 v, iColor_tag c, F32 nsz, F32 rcz) + { + RwIm2DVertexSetScreenX(&vert, x); + RwIm2DVertexSetScreenY(&vert, y); + RwIm2DVertexSetScreenZ(&vert, nsz); + RwIm2DVertexSetU(&vert, u, rcz); + RwIm2DVertexSetV(&vert, v, rcz); + RwIm2DVertexSetIntRGBA(&vert, c.r, c.g, c.b, c.a); + } + + void render_bk_tex_wrap(const ztextbox& e) + { + } + + void init_textbox(ztextbox& e) + { + static const U32 xjlookup[] = { 0x0, 0x2, 0x1 }; + + ztextbox::asset_type& a = *e.asset; + + e.tb.flags = 0; + e.tb.font.id = a.font; + e.tb.font.width = a.size.width; + e.tb.font.height = a.size.height; + e.tb.font.space = a.space.x; + e.tb.line_space = a.space.y; + e.tb.font.color = convert(a.color); + e.tb.bounds.x = a.bounds.x + a.inset.left; + e.tb.bounds.y = a.bounds.y + a.inset.top; + e.tb.bounds.w = a.bounds.w - a.inset.left - a.inset.right; + e.tb.bounds.h = a.bounds.h - a.inset.top - a.inset.bottom; + e.tb.flags |= (a.xjustify >= 3) ? xjlookup[0] : xjlookup[a.xjustify]; + e.tb.set_text(e.segments, e.segments_size); + + if (a.expand < ztextbox::asset_type::MAX_EX && a.max_height > a.bounds.h) + { + S32 lines; + F32 minh = e.tb.bounds.h; + F32 maxh = a.max_height - a.inset.top - a.inset.bottom; + + e.tb.bounds.h = maxh; + e.tb.bounds.h = e.tb.yextent(maxh, lines, true); + + if (e.tb.bounds.h > minh) + { + F32 hmore = e.tb.bounds.h - minh; + + if (a.expand == ztextbox::asset_type::EX_CENTER) + { + e.tb.bounds.y -= _761_1 * hmore; + } + else if (a.expand == ztextbox::asset_type::EX_UP) + { + e.tb.bounds.y -= hmore; + } + } + else + { + e.tb.bounds.h = minh; + } + } + + e.tb.font.clip.x = e.tb.bounds.x - a.inset.left; + e.tb.font.clip.y = e.tb.bounds.y - a.inset.top; + e.tb.font.clip.w = e.tb.bounds.w + a.inset.left + a.inset.right; + e.tb.font.clip.h = e.tb.bounds.h + a.inset.top + a.inset.bottom; + } + + void parse_tag_blahblah(xtextbox::jot&, const xtextbox&, const xtextbox&, + const xtextbox::split_tag&) + { + } + + S32 cb_dispatch(xBase*, xBase* to, U32 event, const F32* argf, xBase*) + { + ztextbox& e = *(ztextbox*)to; + + switch (event) + { + case eEventReset: + case eEventSceneEnd: + { + e.reset(); + break; + } + case eEventFontBackdropOn: + { + e.flag.show_backdrop = true; + break; + } + case eEventFontBackdropOff: + { + e.flag.show_backdrop = false; + break; + } + case eEventVisible: + { + if (argf && *(U32*)&argf[0]) + { + e.set_text(*(U32*)&argf[0]); + } + + e.activate(); + break; + } + case eEventInvisible: + { + e.deactivate(); + break; + } + case eEventSetText: + { + if (argf) + { + e.set_text(*(U32*)&argf[0]); + } + + break; + } + case eEventAddText: + { + if (argf) + { + e.add_text(*(U32*)&argf[0]); + } + + break; + } + case eEventClearText: + { + e.clear_text(); + break; + } + } + + return 1; + } +} // namespace + +void ztextbox::load(const asset_type& a) +{ + xBaseInit(this, (xBaseAsset*)&a); + + baseType = eBaseTypeTextBox; + asset = (asset_type*)&a; + eventFunc = cb_dispatch; + + if (linkCount) + { + link = (xLinkAsset*)(&a + 1); + } + + tb.context = this; + prev = NULL; + next = NULL; + + memset(&flag, 0, sizeof(flag)); + + bgtex = NULL; + + if (a.backdrop.texture) + { + RwTexture* tex = (RwTexture*)xSTFindAsset(a.backdrop.texture, NULL); + bgtex = RwTextureGetRaster(tex); + } + + reset(); +} + +void ztextbox::update(xScene&, F32) +{ +} + +void ztextbox::reset() +{ + deactivate(); + + segments_size = 0; + flag.dirty = true; + flag.show_backdrop = true; + + set_text(asset->text); +} + +void ztextbox::render() +{ + if (flag.dirty) + { + init_textbox(*this); + flag.dirty = false; + } + + if (flag.show_backdrop) + { + render_backdrop(); + } + + tb.render(true); +} + +void ztextbox::render_backdrop() +{ + if (asset->backdrop.type < sizeof(render_bk_table) / sizeof(render_bk_table[0])) + { + render_bk_table[asset->backdrop.type](*this); + } +} + +void ztextbox::activate() +{ + if (flag.active) + { + return; + } + + flag.active = true; + flag.visible = true; + + prev = NULL; + next = head_active; + + if (head_active) + { + head_active->prev = this; + } + + head_active = this; +} + +void ztextbox::deactivate() +{ + if (!flag.active) + { + return; + } + + flag.active = false; + flag.visible = false; + + if (prev) + { + prev->next = next; + } + + if (next) + { + next->prev = prev; + } + + if (head_active == this) + { + head_active = next; + } +} + +void ztextbox::set_text(const char* s) +{ + clear_text(); + add_text(s); +} + +void ztextbox::set_text(U32 id) +{ + if (!id) + { + return; + } + + xTextAsset* ta = (xTextAsset*)xSTFindAsset(id, NULL); + + if (!ta) + { + clear_text(); + } + else + { + set_text(xTextAssetGetText(ta)); + } +} + +void ztextbox::add_text(const char* s) +{ + if (!s) + { + return; + } + + segments[segments_size] = s; + segments_size++; + + flag.dirty = true; +} + +void ztextbox::add_text(U32 id) +{ + if (!id) + { + return; + } + + xTextAsset* ta = (xTextAsset*)xSTFindAsset(id, NULL); + + if (ta) + { + add_text(xTextAssetGetText(ta)); + } +} + +void ztextbox::clear_text() +{ + segments_size = 0; + flag.dirty = true; +} + +void ztextbox::refresh() +{ + if (flag.dirty) + { + init_textbox(*this); + flag.dirty = false; + } +} + +void ztextbox::get_text(char* buffer, size_t buffer_size) const +{ + const char* const* it = segments; + const char* const* end = it + segments_size; + + while (it != end) + { + const char* s = *it; + U32 len = strlen(s); + + if (len >= buffer_size) + { + memcpy(buffer, s, buffer_size - 1); + buffer += buffer_size - 1; + break; + } + + memcpy(buffer, s, len); + buffer += len; + it++; + } + + *buffer = '\0'; +} + +void ztextbox::init() +{ + xtextbox::register_tags(new_tags, new_tags_size); + + head_active = NULL; +} + +void ztextbox::load(xBase& data, xDynAsset& asset, size_t) +{ + ((ztextbox&)data).load((asset_type&)asset); +} + +void ztextbox::update_all(xScene& s, F32 dt) +{ + ztextbox* it = head_active; + + while (it) + { + it->update(s, dt); + it = it->next; + } +} + +void ztextbox::render_all() +{ + ztextbox* it = head_active; + + while (it) + { + it->render(); + it = it->next; + } +} + +iColor_tag convert(const ztextbox::asset_type::color_type& color) +{ + iColor_tag c; + c.r = color.r; + c.g = color.g; + c.b = color.b; + c.a = color.a; + return c; +} diff --git a/src/SB/Game/zTextBox.h b/src/SB/Game/zTextBox.h new file mode 100644 index 0000000..203cd6e --- /dev/null +++ b/src/SB/Game/zTextBox.h @@ -0,0 +1,103 @@ +#ifndef ZTEXTBOX_H +#define ZTEXTBOX_H + +#include "xDynAsset.h" +#include "xFont.h" +#include "xScene.h" + +#include + +struct ztextbox : xBase +{ + struct asset_type : xDynAsset + { + struct color_type + { + U8 r; + U8 g; + U8 b; + U8 a; + }; + + U32 text; + basic_rect bounds; + U32 font; + struct + { + F32 width; + F32 height; + } size; + struct + { + F32 x; + F32 y; + } space; + color_type color; + struct + { + F32 left; + F32 top; + F32 right; + F32 bottom; + } inset; + enum + { + XJ_LEFT, + XJ_CENTER, + XJ_RIGHT + } xjustify; + enum + { + EX_UP, + EX_CENTER, + EX_DOWN, + MAX_EX + } expand; + F32 max_height; + struct + { + U32 type; + color_type color; + U32 texture; + } backdrop; + }; + + struct + { + bool active : 1; // bit 24 + bool dirty : 1; // bit 25 + bool show_backdrop : 1; // bit 26 + bool visible : 1; // bit 27 + bool hack_invisible : 1; // bit 28 + } flag; + asset_type* asset; + xtextbox tb; + const char* segments[16]; + U32 segments_size; + ztextbox* next; + ztextbox* prev; + RwRaster* bgtex; + + static void init(); + static void load(xBase& data, xDynAsset& asset, size_t); + static void update_all(xScene& s, F32 dt); + static void render_all(); + + void load(const asset_type& a); + void update(xScene&, F32); + void reset(); + void render(); + void render_backdrop(); + void activate(); + void deactivate(); + void set_text(const char* s); + void set_text(U32 id); + void add_text(const char* s); + void add_text(U32 id); + void clear_text(); + void refresh(); + void get_text(char* buffer, size_t buffer_size) const; + bool visible(); +}; + +#endif diff --git a/src/SB/Game/zWadNME.cpp b/src/SB/Game/zWadNME.cpp index 7d8fcdf..a82ce29 100644 --- a/src/SB/Game/zWadNME.cpp +++ b/src/SB/Game/zWadNME.cpp @@ -1,18 +1,19 @@ -#include "zWadNME.h" +// #include "zWadNME.h" -S32 zNMEGoalDentDamage::Exit(float, void*) -{ - return 0; // TO-DO -} +// S32 zNMEGoalDentDamage::Exit(float, void*) +// { +// return 0; // TO-DO +// } -S32 zNMEGoalDenDamage::Exit(float dt, void* ctxt) //POSSIBLY RIGHT, NEEDS DOUBLE CHECKED -{ - zNMEDennis* npc; - npc->spd_throttle = -1.0f; - return 0; -} +// S32 zNMEGoalDenDamage::Exit(float dt, void* ctxt) //POSSIBLY RIGHT, NEEDS DOUBLE CHECKED +// { +// zNMEDennis* npc; +// npc->spd_throttle = -1.0f; +// return 0; +// } + +// S32 zNMEDennis::DfltVulnFlags() +// { +// return 0xc07b0007; // HACKED TOGETHER FOR TESTING PURPOSES +// } -S32 zNMEDennis::DfltVulnFlags() -{ - return 0xc07b0007; // HACKED TOGETHER FOR TESTING PURPOSES -} diff --git a/src/SB/Game/zWadNME.h b/src/SB/Game/zWadNME.h index 1901ae0..e69de29 100644 --- a/src/SB/Game/zWadNME.h +++ b/src/SB/Game/zWadNME.h @@ -1,323 +0,0 @@ -#ifndef ZWADNME_H -#define ZWADNME_H - -#include - -#include "xNME.h" -#include "zBossCam.h" -#include "xPlayer.h" - -struct base : xEnt, xFactoryInst -{ - S16 bound_bone; - U16 sound_id_offset; - U16 global_parameters_size; - U16 local_parameters_size; - U32 type; - xModelAssetParam* global_parameters; - xModelAssetParam* local_parameters; - union - { - xMovePoint* movepoint; - U32 movepoint_asset_id; - }; - xEntNPCAssetIN* npc_asset; - xModelAssetInfo* model_asset; - F32 shadow_strength; - F32 shadow_cache_fudge_factor; - xVec3 bound_offset; -}; - -struct zNMENPCWrapper : base -{ - void (*fun_setup)(xEnt*); - void (*fun_reset)(xEnt*); - S32 colFreq; - U8 flg_colCheck; - U8 flg_penCheck; - U16 flg_unusedCollFlags; - struct - { - S32 aflg_basenme : 8; - S32 flg_upward : 8; - S32 flg_xtrarend : 1; - S32 flg_inUpdate : 1; - S32 flg_newtime : 1; - S32 flg_postproc : 1; - S32 flg_profProc : 1; - S32 flg_hudrend : 1; - S32 flg_moreUnusedSpace : 10; - }; - - void InitFromNPCMgr(xEntAsset* asset); - void Init(xEntAsset* asset); - void PostInit(); - void PostSetup(); - void Load(); - void NewTime(); - void RenderExtra(); - void RenderHud(); - void Move(); - S32 ColFreqReset(); - void init(xEntAsset* asset); - void SelfSetup(); - void setup(); - void Reset(); - void Setup(); - void reset(); - void update_npc(F32 dt); - void Process(); - void update_bound(); - void change_bounds(); - U8 system_event(); - void render_npc(); - void Render(); - void debug_render(); - void render_extra(); - void damage(); - void destroy(); - void Destroy(); - void scene_setup(); - void add_states(); - void add_transitions(); - S32 SysEvent(); - void BUpdate(); - void UpdateWrapper(F32 dt); - void NMEWrap_Init(xEntAsset* asset); - xAnimTable* CreateAnimTable(); - void SelfDestroy(); - void CollideReview(); -}; - -struct zNMECommon : zNMENPCWrapper -{ - zNMEAsset* nmeass; - S32 siz_nmeass; - xPsyche* psy_self; - NMECfgCommon* cfg_common; - NMEShadParms* cfg_shadparm; - S32 flg_vuln; - S32 flg_move; - S32 flg_misc; - S32 flg_able; - F32 spd_throttle; - NMERuntime runtimeData; - zNMEDriver* drv_data; - zNMENavNet* navnet; - union - { - F32 tmr_common[3]; - F32 tmr_invuln; - }; - F32 tmr_scary; - F32 tmr_lastAlert; - zNMECommon* npc_duplodude; - zNMESoundTable* snd_table; - iSndHandle sndID[10]; - zShrapnelAsset* shrapnelAsset; - - void Destroy(); - void Render(); - void SelfDestroy(); - void ProcessInvis(); - void PostProcess(); - S32 IsAlive(); - S32 IsHealthy(); - S32 IsPresent(); - en_nmesimp SimpleStatus(); - F32 HealthRatio(); - void Boo(); - void DuploOwner(zNMECommon* duper); - void SpeakBegin(); - void SpeakEnd(); - void SpeakStart(); - void SpeakStop(); - S32 CanRope(); - void CollideReview(); - zMovePoint* MvptFirstFollow(); - zMovePoint* MvptFirstTarget(); - xEntFrame* Gimme_xEntFrame(); - zNMEDriver* Gimme_DriveData(); - xEntShadow* Gimme_ShadowData(); - zNMENavNet* Gimme_NavNet(); - zNMEArena* Gimme_NMEArena(); - xShadowSimpleCache* Gimme_SimpShadowCache(); - void Reset(); - void PoofOfBubbles(); - S32 LaunchProjectile(en_haztyp haztyp, F32 spd_proj, F32 dst_minRange, xVec3* pos_launch, - F32 tym_predictMax, F32 hyt_offset, F32 rad_min, F32 rad_max); - void GiveReward(); - void DeathFXKick(); - void DieTheGoodDeath(); - F32 ThrottleAdjust(F32 dt, F32 spd_want, F32 accel); - xAnimTable* CreateAnimTable(xAnimTable* table); - xAnimTransition* AnimMakeSmackTran(U32 animID); - S32 AnimStart(U32 animID, S32 forceRestart); - S32 MatMoveToPos(xVec3* pos_tobe, F32 dt, F32 spd, S32 doTurn, F32 spd_turnrate); - F32 MatQRotTowards(F32 dt, xVec3* dir_face, F32 spd_turnrate); - xModelInstance* ModelAtomicFind(S32 index, S32 idx_prev, xModelInstance* mdl_prev); - S32 HaveLOSToPos(xVec3* pos, F32 dist, xScene* xscn, xBase* tgt, xCollis* colCallers); - S32 ReviewCollBounce(xEntCollis* npccol, xVec3* vel, F32 fac_elastic); - S32 ReviewCollSurfs(xEntCollis* npccol, zNMECommon* npc); - void RunCollision(F32 dt); - en_nmesimp Common_SimpStat(); - void ApplyGlowDamp(); - void ShadStufUpdate(); - void FullShadAcquire(); - void ShadowPrep(); - S32 WannaPoolShadow(); - void TellMeVisOnOff(xEnt* ent); - S32 Respawn(xVec3* pos, zMovePoint* mvptFirst, zMovePoint* mvptSpawnRef); - void Damage(en_npcdmg dmgtype, xBase* who, xVec3* vec_hit, S32 amt_dmgCaller, - en_plyrpup pup_fromCaller); - void ConvertHitEvent(NMESysEvent* sysmail); - S32 DfltSysEventMail(NMESysEvent* sysmail); - S32 SysEvent(xBase* from, xBase* to, U32 toEvent, F32* toParam, xBase* toParamWidget, - U32 toParamWidgetID, S32* handled); - S32 NMEMessage(NMEMsg* mail); - S32 TypeHandleMail(); - void CreateConfig(); - void Setup(); - void Common_Init(); - void Process(F32 dt); - void BUpdate(xVec3* pos); - void Init(xEntAsset* entasset); -}; - -struct zNMEBoss : zNMECommon -{ -}; - -struct zNMEDennis; - -struct zNMESBBat : zNMECommon -{ - zNMEDennis* npc_bossman; - void Reset(); - void Process(F32 dt); - void Setup(); - void Init(xEntAsset* asset); - void SelfSetup(); - U32 AnimPick(S32 gid); - xAnimTable* CreateAnimTable(xAnimTable* table); -}; - -struct zNMEDennis : zNMEBoss -{ - S32 pts_health; - NMECfgDennis* cfg_dennis; - F32 tmr_nextLeap; - S32 cnt_attacksTilEvade; - zMovePoint* nav_evade; - zNMESBBat* npc_sbbat; - union - { - en_denstage stageCurr; - S32 stageCurrNum; - }; - union - { - xModelBlur moveBlur; - xModelBlur moveBlurShort; - }; - xModelBlur moveBlurLong; - zStreamedSoundList oneLiners; - DennisLetMeKnow tellMeWhen; - S32 flg_firstTimestep; - zBossCam_Binary cam_boss; - en_dbcmode mod_camCurr; - en_dbcmode mod_camWant; - xGroup* grp_mvpt; - - zMovePoint* PickEvade(zMovePoint* nav_from); - S32 DenMailSys(NMESysEvent* sysmail); - S32 DenMailDamage(NMEDamageInfo* dmgmail); - S32 TypeHandleMail(NMEMsg* mail); - void BossCamSet(en_dbcmode mod_desired, U8 forceCut); - en_vis VisionTarget(); - void RenderHud(); - void PostProcess(); - void NewTime(F32 dt); - void BUpdate(xVec3* pos); - void Process(F32 dt); - S32 IsAlive(); - void Destroy(); - void Reset(); - void Setup(); - void Init(xEntAsset* asset); - xAnimTable* CreateAnimTable(xAnimTable* table); - U32 AnimPick(S32 gid, en_npcgspot gspot); - zMovePoint* MvptFirstFollow(); - void SelfSetup(); - S32 DfltVulnFlags(); - void CreateConfig(); -}; - -struct zNMEDenToo : zNMEBoss -{ - S32 pts_health; - DenTooMeter denTooMeter; - NMECfgDenToo* cfg_dentoo; - F32 tmr_nextLeap; - S32 cnt_attacksTilEvade; - zMovePoint* nav_evade; - union - { - en_dentstage stageCurr; - S32 stageCurrNum; - }; - xModelBlur blur_jumpShort; - xModelBlur blur_jumpLong; - zStreamedSoundList oneLiners; - xGroup* grp_mvpt; - S32 flg_firstTimestep; - zBossCam_Binary cam_boss; - en_dtbcmode mod_camCurr; - en_dtbcmode mod_camWant; - F32 tmr_bobCycle; - - zMovePoint* PickEvade(zMovePoint* nav_from); - S32 DenMailSys(NMESysEvent* sysmail); - S32 DenMailDamage(NMEDamageInfo* dmgmail); - S32 TypeHandleMail(NMEMsg* mail); - void BossCamRepel(); - void BossCamSet(en_dtbcmode mod_desired, U8 forceCut); - void RespondToHittingPlayer(); - en_vis VisionTarget(); - void RenderHud(); - void BUpdate(xVec3* pos); - void PostProcess(); - void Process(F32 dt); - S32 IsAlive(); - void Destroy(); - void Reset(); - void Setup(); - void Init(xEntAsset* asset); - xAnimTable* CreateAnimTable(xAnimTable* table); - U32 AnimPick(S32 gid, en_npcgspot gspot); - zMovePoint* MvptFirstFollow(); - void SelfSetup(); - S32 DfltVulnFlags(); - void CreateConfig(); - S32 WannaPoolShadow(); -}; - -struct zNMEGoalDenDamage : zNMEGoalCommon -{ - S32 GoalHandleMail(NMEMsg* mail); - S32 ChkExistence(zNMEDennis* npc, F32 dt, S32& nextgoal, en_trantype& trantype); - S32 Process(en_trantype* trantype, F32 dt, void* ctxt); - S32 Exit(float, void*); - S32 Enter(); -}; - -struct zNMEGoalDentDamage : zNMEGoalCommon -{ - S32 GoalHandleMail(NMEMsg* mail); - S32 ChkExistence(zNMEDenToo* npc, F32 dt, S32& nextgoal, en_trantype& trantype); - S32 Process(en_trantype* trantype, F32 dt, void* ctxt); - S32 Exit(float, void*); - S32 Enter(); -}; - -#endif