From d42189664753a378b92573a9da2f0655397f8c88 Mon Sep 17 00:00:00 2001 From: Colin Miller Date: Mon, 23 Jun 2025 23:18:20 -0400 Subject: [PATCH 1/2] Implemented RWSDK --- configure.py | 2 + include/rwsdk/rphanim.h | 46 +- include/rwsdk/rpmatfx.h | 7 +- include/rwsdk/rpskin.h | 9 +- include/rwsdk/rpworld.h | 35 +- include/rwsdk/rtanim.h | 8 +- include/rwsdk/rtquat.h | 80 +- include/rwsdk/rwcore.h | 80 +- include/rwsdk/rwplcore.h | 98 +- src/rwsdk/driver/common/palquant.c | 53 + src/rwsdk/driver/gcn/dl2drend.c | 0 src/rwsdk/driver/gcn/dlconvrt.c | 0 src/rwsdk/driver/gcn/dldevice.c | 0 src/rwsdk/driver/gcn/dlraster.c | 0 src/rwsdk/driver/gcn/dlrendst.c | 0 src/rwsdk/driver/gcn/dlsprite.c | 0 src/rwsdk/driver/gcn/dltexdic.c | 0 src/rwsdk/driver/gcn/dltextur.c | 0 src/rwsdk/driver/gcn/dltoken.c | 0 src/rwsdk/os/gcn/osintf.c | 6 + src/rwsdk/plugin/collis/ctbsp.c | 55 +- src/rwsdk/plugin/collis/ctgeom.c | 0 src/rwsdk/plugin/collis/ctworld.c | 0 src/rwsdk/plugin/collis/rpcollis.c | 60 + src/rwsdk/plugin/hanim/rphanim.c | 231 +++ src/rwsdk/plugin/hanim/stdkey.c | 95 ++ src/rwsdk/plugin/matfx/gcn/effectPipesGcn.c | 24 + src/rwsdk/plugin/matfx/gcn/multiTexGcn.c | 0 src/rwsdk/plugin/matfx/gcn/multiTexGcnData.c | 0 src/rwsdk/plugin/matfx/gcn/multiTexGcnPipe.c | 0 src/rwsdk/plugin/matfx/matfx.h | 106 ++ src/rwsdk/plugin/matfx/multiTex.c | 230 +++ src/rwsdk/plugin/matfx/multiTex.h | 88 ++ src/rwsdk/plugin/matfx/multiTexEffect.c | 164 +++ src/rwsdk/plugin/matfx/multiTexEffect.h | 125 ++ src/rwsdk/plugin/matfx/rpmatfx.c | 1303 +++++++++++++++++ src/rwsdk/plugin/ptank/gcn/ptankgcn.c | 13 + .../plugin/ptank/gcn/ptankgcn_cc_cs_nr.c | 0 .../plugin/ptank/gcn/ptankgcn_cc_cs_ppr.c | 0 src/rwsdk/plugin/ptank/gcn/ptankgcn_cc_ppm.c | 0 .../plugin/ptank/gcn/ptankgcn_cc_pps_nr.c | 0 .../plugin/ptank/gcn/ptankgcn_cc_pps_ppr.c | 0 .../plugin/ptank/gcn/ptankgcn_nc_cs_nr.c | 0 .../plugin/ptank/gcn/ptankgcn_nc_cs_ppr.c | 0 src/rwsdk/plugin/ptank/gcn/ptankgcn_nc_ppm.c | 0 .../plugin/ptank/gcn/ptankgcn_nc_pps_nr.c | 0 .../plugin/ptank/gcn/ptankgcn_nc_pps_ppr.c | 0 .../plugin/ptank/gcn/ptankgcncallbacks.c | 7 + src/rwsdk/plugin/ptank/gcn/ptankgcnrender.c | 0 .../plugin/ptank/gcn/ptankgcntransforms.c | 0 src/rwsdk/plugin/ptank/rpptank.c | 37 + src/rwsdk/plugin/skin2/bsplit.c | 118 ++ .../plugin/skin2/gcn/instance/instanceskin.c | 0 src/rwsdk/plugin/skin2/gcn/skingcn.c | 0 src/rwsdk/plugin/skin2/gcn/skingcnasm.c | 0 src/rwsdk/plugin/skin2/gcn/skingcng.c | 0 src/rwsdk/plugin/skin2/gcn/skinmatrixblend.c | 0 src/rwsdk/plugin/skin2/gcn/skinstream.c | 0 src/rwsdk/plugin/skin2/rpskin.c | 284 ++++ src/rwsdk/plugin/skin2/skin.h | 184 +++ src/rwsdk/plugin/userdata/rpusrdat.c | 181 +++ src/rwsdk/plugin/userdata/rpusrdat.h | 93 ++ src/rwsdk/src/babbox.c | 14 + src/rwsdk/src/babincam.c | 65 + src/rwsdk/src/babinfrm.c | 34 + src/rwsdk/src/babintex.c | 0 src/rwsdk/src/bacamera.c | 0 src/rwsdk/src/badevice.c | 28 + src/rwsdk/src/baframe.c | 0 src/rwsdk/src/baimage.c | 0 src/rwsdk/src/baimras.c | 0 src/rwsdk/src/baraster.c | 0 src/rwsdk/src/baresamp.c | 0 src/rwsdk/src/basync.c | 0 src/rwsdk/src/batextur.c | 0 src/rwsdk/src/batypehf.c | 27 + src/rwsdk/src/pipe/p2/baim3d.c | 0 src/rwsdk/src/pipe/p2/bapipe.c | 0 src/rwsdk/src/pipe/p2/gcn/im3dpipe.c | 0 .../pipe/p2/gcn/nodeDolphinSubmitNoLight.c | 0 src/rwsdk/src/pipe/p2/p2altmdl.c | 0 src/rwsdk/src/pipe/p2/p2core.c | 0 src/rwsdk/src/pipe/p2/p2define.c | 0 src/rwsdk/src/pipe/p2/p2dep.c | 0 src/rwsdk/src/pipe/p2/p2heap.c | 0 src/rwsdk/src/pipe/p2/p2renderstate.c | 0 src/rwsdk/src/pipe/p2/p2resort.c | 0 src/rwsdk/src/plcore/babinary.c | 0 src/rwsdk/src/plcore/bacolor.c | 0 src/rwsdk/src/plcore/baerr.c | 0 src/rwsdk/src/plcore/bafsys.c | 0 src/rwsdk/src/plcore/baimmedi.c | 0 src/rwsdk/src/plcore/bamatrix.c | 0 src/rwsdk/src/plcore/bamemory.c | 0 src/rwsdk/src/plcore/baresour.c | 0 src/rwsdk/src/plcore/bastream.c | 0 src/rwsdk/src/plcore/batkbin.c | 0 src/rwsdk/src/plcore/batkreg.c | 0 src/rwsdk/src/plcore/bavector.c | 0 src/rwsdk/src/plcore/resmem.c | 0 src/rwsdk/src/plcore/rwstring.c | 0 src/rwsdk/tool/anim/rtanim.c | 0 src/rwsdk/tool/intsec/rtintsec.c | 0 src/rwsdk/world/babinwor.c | 67 + src/rwsdk/world/babinwor.h | 119 ++ src/rwsdk/world/baclump.c | 0 src/rwsdk/world/bageomet.c | 0 src/rwsdk/world/balight.c | 0 src/rwsdk/world/bamateri.c | 0 src/rwsdk/world/bamatlst.c | 0 src/rwsdk/world/bamesh.c | 0 src/rwsdk/world/bameshop.c | 0 src/rwsdk/world/basector.c | 0 src/rwsdk/world/baworld.c | 0 src/rwsdk/world/baworobj.c | 0 src/rwsdk/world/pipe/p2/bapipew.c | 0 src/rwsdk/world/pipe/p2/gcn/gclights.c | 0 src/rwsdk/world/pipe/p2/gcn/gcmorph.c | 0 src/rwsdk/world/pipe/p2/gcn/gcpipe.c | 0 .../world/pipe/p2/gcn/instance/geomcond.c | 0 .../world/pipe/p2/gcn/instance/geominst.c | 0 .../world/pipe/p2/gcn/instance/ibuffer.c | 0 .../world/pipe/p2/gcn/instance/instancegeom.c | 0 .../pipe/p2/gcn/instance/instanceworld.c | 0 src/rwsdk/world/pipe/p2/gcn/instance/itools.c | 0 .../world/pipe/p2/gcn/instance/vbuffer.c | 0 src/rwsdk/world/pipe/p2/gcn/instance/vtools.c | 0 .../world/pipe/p2/gcn/instance/vtxdesc.c | 0 src/rwsdk/world/pipe/p2/gcn/native.c | 0 .../pipe/p2/gcn/nodeGameCubeAtomicAllInOne.c | 0 .../p2/gcn/nodeGameCubeWorldSectorAllInOne.c | 0 src/rwsdk/world/pipe/p2/gcn/setup.c | 0 src/rwsdk/world/pipe/p2/gcn/vtxfmt.c | 0 src/rwsdk/world/pipe/p2/gcn/wrldpipe.c | 0 134 files changed, 4087 insertions(+), 89 deletions(-) create mode 100644 src/rwsdk/driver/common/palquant.c create mode 100644 src/rwsdk/driver/gcn/dl2drend.c create mode 100644 src/rwsdk/driver/gcn/dlconvrt.c create mode 100644 src/rwsdk/driver/gcn/dldevice.c create mode 100644 src/rwsdk/driver/gcn/dlraster.c create mode 100644 src/rwsdk/driver/gcn/dlrendst.c create mode 100644 src/rwsdk/driver/gcn/dlsprite.c create mode 100644 src/rwsdk/driver/gcn/dltexdic.c create mode 100644 src/rwsdk/driver/gcn/dltextur.c create mode 100644 src/rwsdk/driver/gcn/dltoken.c create mode 100644 src/rwsdk/os/gcn/osintf.c create mode 100644 src/rwsdk/plugin/collis/ctgeom.c create mode 100644 src/rwsdk/plugin/collis/ctworld.c create mode 100644 src/rwsdk/plugin/collis/rpcollis.c create mode 100644 src/rwsdk/plugin/hanim/rphanim.c create mode 100644 src/rwsdk/plugin/hanim/stdkey.c create mode 100644 src/rwsdk/plugin/matfx/gcn/effectPipesGcn.c create mode 100644 src/rwsdk/plugin/matfx/gcn/multiTexGcn.c create mode 100644 src/rwsdk/plugin/matfx/gcn/multiTexGcnData.c create mode 100644 src/rwsdk/plugin/matfx/gcn/multiTexGcnPipe.c create mode 100644 src/rwsdk/plugin/matfx/matfx.h create mode 100644 src/rwsdk/plugin/matfx/multiTex.c create mode 100644 src/rwsdk/plugin/matfx/multiTex.h create mode 100644 src/rwsdk/plugin/matfx/multiTexEffect.c create mode 100644 src/rwsdk/plugin/matfx/multiTexEffect.h create mode 100644 src/rwsdk/plugin/matfx/rpmatfx.c create mode 100644 src/rwsdk/plugin/ptank/gcn/ptankgcn.c create mode 100644 src/rwsdk/plugin/ptank/gcn/ptankgcn_cc_cs_nr.c create mode 100644 src/rwsdk/plugin/ptank/gcn/ptankgcn_cc_cs_ppr.c create mode 100644 src/rwsdk/plugin/ptank/gcn/ptankgcn_cc_ppm.c create mode 100644 src/rwsdk/plugin/ptank/gcn/ptankgcn_cc_pps_nr.c create mode 100644 src/rwsdk/plugin/ptank/gcn/ptankgcn_cc_pps_ppr.c create mode 100644 src/rwsdk/plugin/ptank/gcn/ptankgcn_nc_cs_nr.c create mode 100644 src/rwsdk/plugin/ptank/gcn/ptankgcn_nc_cs_ppr.c create mode 100644 src/rwsdk/plugin/ptank/gcn/ptankgcn_nc_ppm.c create mode 100644 src/rwsdk/plugin/ptank/gcn/ptankgcn_nc_pps_nr.c create mode 100644 src/rwsdk/plugin/ptank/gcn/ptankgcn_nc_pps_ppr.c create mode 100644 src/rwsdk/plugin/ptank/gcn/ptankgcncallbacks.c create mode 100644 src/rwsdk/plugin/ptank/gcn/ptankgcnrender.c create mode 100644 src/rwsdk/plugin/ptank/gcn/ptankgcntransforms.c create mode 100644 src/rwsdk/plugin/ptank/rpptank.c create mode 100644 src/rwsdk/plugin/skin2/bsplit.c create mode 100644 src/rwsdk/plugin/skin2/gcn/instance/instanceskin.c create mode 100644 src/rwsdk/plugin/skin2/gcn/skingcn.c create mode 100644 src/rwsdk/plugin/skin2/gcn/skingcnasm.c create mode 100644 src/rwsdk/plugin/skin2/gcn/skingcng.c create mode 100644 src/rwsdk/plugin/skin2/gcn/skinmatrixblend.c create mode 100644 src/rwsdk/plugin/skin2/gcn/skinstream.c create mode 100644 src/rwsdk/plugin/skin2/rpskin.c create mode 100644 src/rwsdk/plugin/skin2/skin.h create mode 100644 src/rwsdk/plugin/userdata/rpusrdat.c create mode 100644 src/rwsdk/plugin/userdata/rpusrdat.h create mode 100644 src/rwsdk/src/babbox.c create mode 100644 src/rwsdk/src/babincam.c create mode 100644 src/rwsdk/src/babinfrm.c create mode 100644 src/rwsdk/src/babintex.c create mode 100644 src/rwsdk/src/bacamera.c create mode 100644 src/rwsdk/src/badevice.c create mode 100644 src/rwsdk/src/baframe.c create mode 100644 src/rwsdk/src/baimage.c create mode 100644 src/rwsdk/src/baimras.c create mode 100644 src/rwsdk/src/baraster.c create mode 100644 src/rwsdk/src/baresamp.c create mode 100644 src/rwsdk/src/basync.c create mode 100644 src/rwsdk/src/batextur.c create mode 100644 src/rwsdk/src/batypehf.c create mode 100644 src/rwsdk/src/pipe/p2/baim3d.c create mode 100644 src/rwsdk/src/pipe/p2/bapipe.c create mode 100644 src/rwsdk/src/pipe/p2/gcn/im3dpipe.c create mode 100644 src/rwsdk/src/pipe/p2/gcn/nodeDolphinSubmitNoLight.c create mode 100644 src/rwsdk/src/pipe/p2/p2altmdl.c create mode 100644 src/rwsdk/src/pipe/p2/p2core.c create mode 100644 src/rwsdk/src/pipe/p2/p2define.c create mode 100644 src/rwsdk/src/pipe/p2/p2dep.c create mode 100644 src/rwsdk/src/pipe/p2/p2heap.c create mode 100644 src/rwsdk/src/pipe/p2/p2renderstate.c create mode 100644 src/rwsdk/src/pipe/p2/p2resort.c create mode 100644 src/rwsdk/src/plcore/babinary.c create mode 100644 src/rwsdk/src/plcore/bacolor.c create mode 100644 src/rwsdk/src/plcore/baerr.c create mode 100644 src/rwsdk/src/plcore/bafsys.c create mode 100644 src/rwsdk/src/plcore/baimmedi.c create mode 100644 src/rwsdk/src/plcore/bamatrix.c create mode 100644 src/rwsdk/src/plcore/bamemory.c create mode 100644 src/rwsdk/src/plcore/baresour.c create mode 100644 src/rwsdk/src/plcore/bastream.c create mode 100644 src/rwsdk/src/plcore/batkbin.c create mode 100644 src/rwsdk/src/plcore/batkreg.c create mode 100644 src/rwsdk/src/plcore/bavector.c create mode 100644 src/rwsdk/src/plcore/resmem.c create mode 100644 src/rwsdk/src/plcore/rwstring.c create mode 100644 src/rwsdk/tool/anim/rtanim.c create mode 100644 src/rwsdk/tool/intsec/rtintsec.c create mode 100644 src/rwsdk/world/babinwor.c create mode 100644 src/rwsdk/world/babinwor.h create mode 100644 src/rwsdk/world/baclump.c create mode 100644 src/rwsdk/world/bageomet.c create mode 100644 src/rwsdk/world/balight.c create mode 100644 src/rwsdk/world/bamateri.c create mode 100644 src/rwsdk/world/bamatlst.c create mode 100644 src/rwsdk/world/bamesh.c create mode 100644 src/rwsdk/world/bameshop.c create mode 100644 src/rwsdk/world/basector.c create mode 100644 src/rwsdk/world/baworld.c create mode 100644 src/rwsdk/world/baworobj.c create mode 100644 src/rwsdk/world/pipe/p2/bapipew.c create mode 100644 src/rwsdk/world/pipe/p2/gcn/gclights.c create mode 100644 src/rwsdk/world/pipe/p2/gcn/gcmorph.c create mode 100644 src/rwsdk/world/pipe/p2/gcn/gcpipe.c create mode 100644 src/rwsdk/world/pipe/p2/gcn/instance/geomcond.c create mode 100644 src/rwsdk/world/pipe/p2/gcn/instance/geominst.c create mode 100644 src/rwsdk/world/pipe/p2/gcn/instance/ibuffer.c create mode 100644 src/rwsdk/world/pipe/p2/gcn/instance/instancegeom.c create mode 100644 src/rwsdk/world/pipe/p2/gcn/instance/instanceworld.c create mode 100644 src/rwsdk/world/pipe/p2/gcn/instance/itools.c create mode 100644 src/rwsdk/world/pipe/p2/gcn/instance/vbuffer.c create mode 100644 src/rwsdk/world/pipe/p2/gcn/instance/vtools.c create mode 100644 src/rwsdk/world/pipe/p2/gcn/instance/vtxdesc.c create mode 100644 src/rwsdk/world/pipe/p2/gcn/native.c create mode 100644 src/rwsdk/world/pipe/p2/gcn/nodeGameCubeAtomicAllInOne.c create mode 100644 src/rwsdk/world/pipe/p2/gcn/nodeGameCubeWorldSectorAllInOne.c create mode 100644 src/rwsdk/world/pipe/p2/gcn/setup.c create mode 100644 src/rwsdk/world/pipe/p2/gcn/vtxfmt.c create mode 100644 src/rwsdk/world/pipe/p2/gcn/wrldpipe.c diff --git a/configure.py b/configure.py index c385f046f..0b1cf79d4 100644 --- a/configure.py +++ b/configure.py @@ -204,6 +204,8 @@ "-i src/dolphin/include", "-i src/dolphin/src", "-i src", + "-i src/rwsdk", + "-i include/rwsdk", f"-i build/{config.version}/include", f"-DBUILD_VERSION={version_num}", f"-DVERSION_{config.version}", diff --git a/include/rwsdk/rphanim.h b/include/rwsdk/rphanim.h index 320605f7d..5a2ad3951 100644 --- a/include/rwsdk/rphanim.h +++ b/include/rwsdk/rphanim.h @@ -3,6 +3,10 @@ #include "rwcore.h" #include "rtanim.h" +#include "rtquat.h" + +#define rpHANIMDEFAULTFRAMEID -1 +#define rpHANIMSTREAMCURRENTVERSION 0x100 struct RpHAnimNodeInfo { @@ -12,6 +16,9 @@ struct RpHAnimNodeInfo RwFrame* pFrame; }; +typedef struct RpHAnimNodeInfo RpHAnimNodeInfo; +typedef struct RpHAnimHierarchy RpHAnimHierarchy; + struct RpHAnimHierarchy { RwInt32 flags; @@ -34,6 +41,43 @@ enum RpHAnimHierarchyFlag rpHANIMHIERARCHYLOCALSPACEMATRICES = 0x4000, rpHANIMHIERARCHYFLAGFORCEENUMSIZEINT = RWFORCEENUMSIZEINT }; +typedef enum RpHAnimHierarchyFlag RpHAnimHierarchyFlag; + +typedef struct RpHAnimAtomicGlobalVars RpHAnimAtomicGlobalVars; + +struct RpHAnimAtomicGlobalVars +{ + RwInt32 engineOffset; + RwFreeList* HAnimFreeList; +}; + +typedef struct RpHAnimFrameExtension RpHAnimFrameExtension; + +struct RpHAnimFrameExtension +{ + RwInt32 id; + RpHAnimHierarchy* hierarchy; +}; + +typedef struct RpHAnimInterpFrame RpHAnimInterpFrame; + +typedef struct RpHAnimKeyFrame RpHAnimKeyFrame; + +struct RpHAnimKeyFrame +{ + RpHAnimKeyFrame* prevFrame; + RwReal time; + RtQuat q; + RwV3d t; +}; + +struct RpHAnimInterpFrame +{ + RpHAnimKeyFrame* keyFrame1; + RpHAnimKeyFrame* keyFrame2; + RtQuat q; + RwV3d t; +}; #ifdef __cplusplus extern "C" { @@ -60,4 +104,4 @@ extern RpHAnimHierarchy* RpHAnimFrameGetHierarchy(RwFrame* frame); } #endif -#endif \ No newline at end of file +#endif diff --git a/include/rwsdk/rpmatfx.h b/include/rwsdk/rpmatfx.h index f9601fba3..92bd684c7 100644 --- a/include/rwsdk/rpmatfx.h +++ b/include/rwsdk/rpmatfx.h @@ -31,10 +31,15 @@ enum RpMatFXMaterialFlags extern "C" { #endif +typedef struct RxPipeline RxPipeline; +typedef enum RpMatFXGameCubePipeline RpMatFXGameCubePipeline; + extern RxPipeline* RpMatFXGetGameCubePipeline(RpMatFXGameCubePipeline gamecubePipeline); extern RwBool RpMatFXPluginAttach(void); extern RpAtomic* RpMatFXAtomicEnableEffects(RpAtomic* atomic); extern RpWorldSector* RpMatFXWorldSectorEnableEffects(RpWorldSector* worldSector); +typedef enum RpMatFXMaterialFlags RpMatFXMaterialFlags; + extern RpMaterial* RpMatFXMaterialSetEffects(RpMaterial* material, RpMatFXMaterialFlags flags); extern RpMaterial* RpMatFXMaterialSetupBumpMap(RpMaterial* material, RwTexture* texture, RwFrame* frame, RwReal coef); @@ -75,4 +80,4 @@ extern const RpMaterial* RpMatFXMaterialGetUVTransformMatrices(const RpMaterial* } #endif -#endif \ No newline at end of file +#endif diff --git a/include/rwsdk/rpskin.h b/include/rwsdk/rpskin.h index 68eb7623e..3d2051aa5 100644 --- a/include/rwsdk/rpskin.h +++ b/include/rwsdk/rpskin.h @@ -5,7 +5,7 @@ #include "rpworld.h" #include "rphanim.h" -typedef struct RpSkin; +typedef struct RpSkin RpSkin; struct RwMatrixWeights { @@ -34,13 +34,18 @@ extern RpSkin* RpSkinGeometryGetSkin(RpGeometry* geometry); extern RpGeometry* RpSkinGeometrySetSkin(RpGeometry* geometry, RpSkin* skin); extern RpSkin* RpSkinDestroy(RpSkin* skin); extern RwUInt32 RpSkinGetNumBones(RpSkin* skin); +typedef struct RwMatrixWeights RwMatrixWeights; + extern const RwMatrixWeights* RpSkinGetVertexBoneWeights(RpSkin* skin); extern const RwUInt32* RpSkinGetVertexBoneIndices(RpSkin* skin); extern const RwMatrix* RpSkinGetSkinToBoneMatrices(RpSkin* skin); +typedef struct RpAtomic RpAtomic; +typedef enum RpSkinType RpSkinType; + extern RpAtomic* RpSkinAtomicSetType(RpAtomic* atomic, RpSkinType type); #ifdef __cplusplus } #endif -#endif \ No newline at end of file +#endif diff --git a/include/rwsdk/rpworld.h b/include/rwsdk/rpworld.h index b621b4b25..b6fc8c3df 100644 --- a/include/rwsdk/rpworld.h +++ b/include/rwsdk/rpworld.h @@ -2,8 +2,11 @@ #define RPWORLD_H #include +#include "rpworld.h" -typedef struct RpLight; +typedef struct RpLight RpLight; +typedef struct RwSurfaceProperties RwSurfaceProperties; +typedef struct RpMaterial RpMaterial; struct RpMaterial { @@ -81,6 +84,8 @@ struct RpBuildMeshTriangle RwUInt16 pipelineIndex; }; +typedef struct RpBuildMeshTriangle RpBuildMeshTriangle; + struct RpBuildMesh { RwUInt32 triangleBufferSize; @@ -88,6 +93,8 @@ struct RpBuildMesh RpBuildMeshTriangle* meshTriangles; }; +typedef struct RpMesh RpMesh; + struct RpMesh { RxVertexIndex* indices; @@ -95,6 +102,7 @@ struct RpMesh RpMaterial* material; }; +typedef struct RpMeshHeader RpMeshHeader; struct RpMeshHeader { RwUInt32 flags; @@ -106,7 +114,7 @@ struct RpMeshHeader typedef RpMesh* (*RpMeshCallBack)(RpMesh* mesh, RpMeshHeader* meshHeader, void* pData); -typedef struct RpGeometry; +typedef struct RpGeometry RpGeometry; struct RpMorphTarget { @@ -116,6 +124,11 @@ struct RpMorphTarget RwV3d* normals; }; +typedef struct RpMaterialList RpMaterialList; +typedef struct RpTriangle RpTriangle; +typedef struct RwTexCoords RwTexCoords; +typedef struct RpMorphTarget RpMorphTarget; + struct RpGeometry { RwObject object; @@ -150,7 +163,7 @@ enum RpAtomicFlag rpATOMICFLAGFORCEENUMSIZEINT = RWFORCEENUMSIZEINT }; -typedef struct RpClump; +typedef struct RpClump RpClump; typedef RpClump* (*RpClumpCallBack)(RpClump* clump, void* data); @@ -174,7 +187,7 @@ struct RpInterpolator RwReal position; }; -typedef struct RpAtomic; +typedef struct RpAtomic RpAtomic; typedef RpAtomic* (*RpAtomicCallBackRender)(RpAtomic* atomic); @@ -318,6 +331,8 @@ typedef RpAtomic* (*RpAtomicCallBackRender)(RpAtomic* atomic); #define RpAtomicSetPipeline RpAtomicSetPipelineMacro #define RpAtomicGetPipeline RpAtomicGetPipelineMacro +typedef struct RpInterpolator RpInterpolator; + struct RpAtomic { RwObjectHasFrame object; @@ -351,6 +366,10 @@ struct RpPolygon RwUInt16 vertIndex[3]; }; +typedef struct RpPolygon RpPolygon; +typedef struct RpVertexNormal RpVertexNormal; +typedef struct RpWorldSector RpWorldSector; + struct RpWorldSector { RwInt32 type; @@ -453,6 +472,9 @@ enum RpWorldRenderOrder typedef RpWorldSector* (*RpWorldSectorCallBackRender)(RpWorldSector* worldSector); +typedef enum RpWorldRenderOrder RpWorldRenderOrder; +typedef struct RpSector RpSector; + struct RpWorld { RwObject object; @@ -542,6 +564,8 @@ typedef RpLight* (*RpLightCallBack)(RpLight* light, void* data); extern "C" { #endif +typedef struct RpWorld RpWorld; + extern RpWorld* RpWorldStreamRead(RwStream* stream); extern RpAtomic* AtomicDefaultRenderCallBack(RpAtomic* atomic); extern void _rpAtomicResyncInterpolatedSphere(RpAtomic* atomic); @@ -654,6 +678,7 @@ extern RpMaterialList* _rpMaterialListStreamRead(RwStream* stream, RpMaterialLis extern RpMeshHeader* _rpMeshHeaderCreate(RwUInt32 size); extern void* _rpMeshClose(void* instance, RwInt32 offset, RwInt32 size); extern void* _rpMeshOpen(void* instance, RwInt32 offset, RwInt32 size); +typedef struct RpBuildMesh RpBuildMesh; extern RpBuildMesh* _rpBuildMeshCreate(RwUInt32 bufferSize); extern RwBool _rpBuildMeshDestroy(RpBuildMesh* mesh); extern RwBool _rpMeshDestroy(RpMeshHeader* mesh); @@ -725,4 +750,4 @@ extern RxNodeDefinition* RxNodeDefinitionGetGameCubeWorldSectorAllInOne(void); } #endif -#endif \ No newline at end of file +#endif diff --git a/include/rwsdk/rtanim.h b/include/rwsdk/rtanim.h index bca0b2e20..13c13f8de 100644 --- a/include/rwsdk/rtanim.h +++ b/include/rwsdk/rtanim.h @@ -3,7 +3,7 @@ #include "rwcore.h" -typedef struct RtAnimAnimation; +typedef struct RtAnimAnimation RtAnimAnimation; typedef void (*RtAnimKeyFrameApplyCallBack)(void* result, void* voidIFrame); typedef void (*RtAnimKeyFrameBlendCallBack)(void* voidOut, void* voidIn1, void* voidIn2, @@ -17,6 +17,8 @@ typedef RtAnimAnimation* (*RtAnimKeyFrameStreamReadCallBack)(RwStream* stream, typedef RwBool (*RtAnimKeyFrameStreamWriteCallBack)(RtAnimAnimation* animation, RwStream* stream); typedef RwInt32 (*RtAnimKeyFrameStreamGetSizeCallBack)(RtAnimAnimation* animation); +typedef struct RtAnimInterpolatorInfo RtAnimInterpolatorInfo; + struct RtAnimInterpolatorInfo { RwInt32 typeID; @@ -43,7 +45,7 @@ struct RtAnimAnimation void* customData; }; -typedef struct RtAnimInterpolator; +typedef struct RtAnimInterpolator RtAnimInterpolator; typedef RtAnimInterpolator* (*RtAnimCallBack)(RtAnimInterpolator* animInstance, void* data); @@ -83,4 +85,4 @@ extern void RtAnimInterpolatorDestroy(RtAnimInterpolator* anim); } #endif -#endif \ No newline at end of file +#endif diff --git a/include/rwsdk/rtquat.h b/include/rwsdk/rtquat.h index ff402d361..e92fdf4df 100644 --- a/include/rwsdk/rtquat.h +++ b/include/rwsdk/rtquat.h @@ -1,64 +1,18 @@ #ifndef RTQUAT_H #define RTQUAT_H -/** - * \defgroup rtquat RtQuat - * \ingroup mathtools - * - * Quaternion Toolkit for RenderWare. - * - * See also http://www.gamasutra.com/features/19980703/quaternions_01.htm - */ - -/* - * See http://www-groups.dcs.st-and.ac.uk/~history/Mathematicians/Hamilton.html - * On 16 October 1843 (a Monday) Hamilton was walking in along the Royal - * Canal with his wife to preside at a Council meeting of the Royal Irish - * Academy. - * - * Although his wife talked to him now and again Hamilton hardly - * heard, for the discovery of the quaternions, the first noncommutative - * algebra to be studied, was taking shape in his mind:- - * - * "And here there dawned on me the notion that we must admit, in - * some sense, a fourth dimension of space for the purpose of calculating - * with triples ... An electric circuit seemed to close, and a spark - * flashed forth." - */ - -/**************************************************************************** - Includes - */ - #include -/* renderware */ -//#include "rwplcore.h" - -//#include "rtquat.rpe" /* automatically generated header file */ +#include "rwcore.h" #define RW_TOL_ORTHONORMAL ((RwReal)0.01) -/**************************************************************************** - Global Types - */ - typedef struct RtQuat RtQuat; -/** - * \ingroup rtquat - * \struct RtQuat - * A structure describing a Quaternion - * -*/ struct RtQuat { - RwV3d imag; /**< The imaginary part(s) */ - RwReal real; /**< The real part */ + RwV3d imag; + RwReal real; }; -/**************************************************************************** - Defines - */ - #define RtQuatInitMacro(result, _x, _y, _z, _w) \ MACRO_START \ { \ @@ -71,7 +25,7 @@ struct RtQuat #if (!defined(RtQuatAssignMacro)) #define RtQuatAssignMacro(_target, _source) (*(_target) = *(_source)) -#endif /* (!defined(RtQuatAssignMacro)) */ +#endif #define RtQuatAddMacro(result, q1, q2) \ MACRO_START \ @@ -159,9 +113,6 @@ struct RtQuat #define RtQuatMultiplyMacro(result, q1, q2) \ MACRO_START \ { \ - /* \ - * Assumes q1 != result != q2 \ - */ \ (result)->real = (q1)->real * (q2)->real - RwV3dDotProductMacro(&(q1)->imag, &(q2)->imag); \ RwV3dCrossProductMacro(&(result)->imag, &(q1)->imag, &(q2)->imag); \ RwV3dIncrementScaledMacro(&(result)->imag, &(q2)->imag, (q1)->real); \ @@ -172,9 +123,6 @@ struct RtQuat #define RtQuatReciprocalMacro(result, q) \ MACRO_START \ { \ - /* \ - * Assumes result != q \ - */ \ RwReal val = RtQuatModulusSquaredMacro(q); \ \ if (val > (RwReal)0) \ @@ -190,9 +138,6 @@ struct RtQuat #define RtQuatSquareMacro(result, q) \ MACRO_START \ { \ - /* \ - * Assumes result != q \ - */ \ RwReal val = ((RwReal)2) * (q)->real; \ \ (result)->real = (q)->real * (q)->real - RwV3dDotProductMacro(&(q)->imag, &(q)->imag); \ @@ -467,14 +412,11 @@ struct RtQuat #define RtQuatUnitConvertToMatrix(qpQuat, mpMatrix) RtQuatUnitConvertToMatrixMacro(qpQuat, mpMatrix) -#endif /* (! ( defined(RWDEBUG) || defined(RWSUPPRESSINLINE) )) */ +#endif -/**************************************************************************** - Function prototypes - */ #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif extern RwBool RtQuatConvertFromMatrix(RtQuat* const qpQuat, const RwMatrix* const mpMatrix); @@ -536,15 +478,11 @@ extern void RtQuatConvertToMatrix(const RtQuat* const qpQuat, RwMatrix* const mp extern void RtQuatUnitConvertToMatrix(const RtQuat* const qpQuat, RwMatrix* const mpMatrix); -#endif /* ( defined(RWDEBUG) || defined(RWSUPPRESSINLINE) ) */ +#endif #ifdef __cplusplus } -#endif /* __cplusplus */ - -/* - * Backwards compatibility code - */ +#endif typedef RtQuat RpQuat; @@ -552,4 +490,4 @@ typedef RtQuat RpQuat; #define RpAnimQuatConvertToMatrix(qpQuat, mpMatrix) RtQuatUnitConvertToMatrix(qpQuat, mpMatrix) -#endif /* RTQUAT_H */ +#endif diff --git a/include/rwsdk/rwcore.h b/include/rwsdk/rwcore.h index 311d8bfc1..025d83f93 100644 --- a/include/rwsdk/rwcore.h +++ b/include/rwsdk/rwcore.h @@ -16,6 +16,9 @@ union RxColorUnion // However, currently decomped functions seem to pack the struct // in this particular way so it's like this for now. // See: zActionLIne.cpp + +typedef union RxColorUnion RxColorUnion; + struct _RxObjSpace3DVertex { RwV3d objVertex; @@ -33,12 +36,16 @@ typedef struct rxHeapSuperBlockDescriptor; typedef struct RxHeap; typedef struct rxHeapBlockHeader; +typedef struct rxHeapBlockHeader rxHeapBlockHeader; + struct rxHeapFreeBlock { RwUInt32 size; rxHeapBlockHeader* ptr; }; +typedef struct rxHeapSuperBlockDescriptor rxHeapSuperBlockDescriptor; + struct rxHeapSuperBlockDescriptor { void* start; @@ -46,6 +53,8 @@ struct rxHeapSuperBlockDescriptor rxHeapSuperBlockDescriptor* next; }; +typedef struct rxHeapFreeBlock rxHeapFreeBlock; + struct RxHeap { RwUInt32 superBlockSize; @@ -57,6 +66,8 @@ struct RxHeap RwBool dirty; }; +typedef struct rxHeapFreeBlock rxHeapFreeBlock; + struct rxHeapBlockHeader { rxHeapBlockHeader *prev, *next; @@ -95,6 +106,8 @@ struct RxClusterDefinition const RwChar* attributeSet; }; +typedef enum RxClusterValid RxClusterValid; + struct RxOutputSpec { RwChar* name; @@ -109,6 +122,9 @@ enum RxClusterForcePresent rxCLUSTERFORCEPRESENTFORCEENUMSIZEINT = RWFORCEENUMSIZEINT }; +typedef struct RxClusterDefinition RxClusterDefinition; +typedef enum RxClusterForcePresent RxClusterForcePresent; + struct RxClusterRef { RxClusterDefinition* clusterDef; @@ -116,6 +132,10 @@ struct RxClusterRef RwUInt32 reserved; }; +typedef struct RxClusterRef RxClusterRef; +typedef enum RxClusterValidityReq RxClusterValidityReq; +typedef struct RxOutputSpec RxOutputSpec; + struct RxIoSpec { RwUInt32 numClustersOfInterest; @@ -125,6 +145,11 @@ struct RxIoSpec RxOutputSpec* outputs; }; +typedef struct RxPipelineNode RxPipelineNode; +typedef struct RxPipelineNodeParam RxPipelineNodeParam; +typedef struct RxNodeDefinition RxNodeDefinition; +typedef struct RxPipeline RxPipeline; + typedef RwBool (*RxNodeBodyFn)(RxPipelineNode* self, const RxPipelineNodeParam* params); typedef RwBool (*RxNodeInitFn)(RxNodeDefinition* self); typedef void (*RxNodeTermFn)(RxNodeDefinition* self); @@ -152,6 +177,10 @@ enum RxNodeDefEditable rxNODEDEFEDITABLEFORCEENUMSIZEINT = RWFORCEENUMSIZEINT }; +typedef struct RxNodeMethods RxNodeMethods; +typedef struct RxIoSpec RxIoSpec; +typedef enum RxNodeDefEditable RxNodeDefEditable; + struct RxNodeDefinition { RwChar* name; @@ -168,6 +197,8 @@ struct RxPipelineCluster RwUInt32 creationAttributes; }; +typedef struct RxPipelineCluster RxPipelineCluster; + struct RxCluster { RwUInt16 flags; @@ -180,6 +211,9 @@ struct RxCluster RwUInt32 attributes; }; +typedef struct RxPipelineCluster RxPipelineCluster; +typedef struct RxCluster RxCluster; + struct RxPacket { RwUInt16 flags; @@ -191,6 +225,8 @@ struct RxPacket RxCluster clusters[1]; }; +typedef struct RxPipelineNodeTopSortData RxPipelineNodeTopSortData; + struct RxPipelineNode { RxNodeDefinition* nodeDef; @@ -205,7 +241,7 @@ struct RxPipelineNode RwUInt32 initializationDataSize; }; -typedef struct rxReq; +typedef struct rxReq rxReq; struct RxPipelineNodeTopSortData { @@ -214,6 +250,8 @@ struct RxPipelineNodeTopSortData rxReq* req; }; +typedef struct RxHeap RxHeap; + struct RxPipelineNodeParam { void* dataParam; @@ -236,6 +274,10 @@ struct RxPipelineRequiresCluster RwUInt32 slotIndex; }; +typedef enum rxEmbeddedPacketState rxEmbeddedPacketState; +typedef struct RxPacket RxPacket; +typedef struct RxPipelineRequiresCluster RxPipelineRequiresCluster; + struct RxPipeline { RwBool locked; @@ -324,6 +366,8 @@ enum RwRasterPrivateFlag #define rwRASTERPALETTELOCKED (rwRASTERPALETTELOCKEDREAD | rwRASTERPALETTELOCKEDWRITE) #define rwRASTERLOCKED (rwRASTERPIXELLOCKED | rwRASTERPALETTELOCKED) +typedef struct RwRaster RwRaster; + struct RwRaster { RwRaster* parent; @@ -356,6 +400,12 @@ struct RwRaster #define RwRasterGetParent(_raster) ((_raster)->parent) +typedef enum RwShadeMode RwShadeMode; +typedef enum RwBlendFunction RwBlendFunction; +typedef enum RwTextureAddressMode RwTextureAddressMode; +typedef enum RwTextureFilterMode RwTextureFilterMode; +typedef enum RwFogType RwFogType; + struct RxRenderStateVector { RwUInt32 Flags; @@ -425,6 +475,8 @@ struct RwTexDictionary RwLLLink lInInstance; }; +typedef struct RwTexDictionary RwTexDictionary; + struct RwTexture { RwRaster* raster; @@ -436,6 +488,8 @@ struct RwTexture RwInt32 refCount; }; +typedef struct RwTexture RwTexture; + typedef RwTexture* (*RwTextureCallBackRead)(const RwChar* name, const RwChar* maskName); typedef RwTexture* (*RwTextureCallBack)(RwTexture* texture, void* pData); @@ -531,12 +585,16 @@ struct RwFrame struct RwFrame* root; }; +typedef struct RwFrame RwFrame; + typedef RwFrame* (*RwFrameCallBack)(RwFrame* frame, void* data); #define RwFrameGetParent(_f) ((RwFrame*)rwObjectGetParent(_f)) #define RwFrameGetMatrix(_f) (&(_f)->modelling) +typedef struct RwObjectHasFrame RwObjectHasFrame; + typedef struct RwObjectHasFrame; typedef RwObjectHasFrame* (*RwObjectHasFrameSyncFunction)(RwObjectHasFrame* object); @@ -586,6 +644,8 @@ enum RwFrustumTestResult rwFRUSTUMTESTRESULTFORCEENUMSIZEINT = RWFORCEENUMSIZEINT }; +typedef struct RwPlane RwPlane; + struct RwFrustumPlane { RwPlane plane; @@ -597,9 +657,16 @@ struct RwFrustumPlane typedef struct RwCamera; +typedef struct RwCamera RwCamera; + typedef RwCamera* (*RwCameraBeginUpdateFunc)(RwCamera* camera); typedef RwCamera* (*RwCameraEndUpdateFunc)(RwCamera* camera); +typedef enum RwCameraProjection RwCameraProjection; +typedef struct RwV2d RwV2d; +typedef struct RwFrustumPlane RwFrustumPlane; +typedef struct RwBBox RwBBox; + struct RwCamera { RwObjectHasFrame object; @@ -668,6 +735,8 @@ extern RwCamera* RwCameraStreamRead(RwStream* stream); extern RwInt32 RwFrameRegisterPluginStream(RwUInt32 pluginID, RwPluginDataChunkReadCallBack readCB, RwPluginDataChunkWriteCallBack writeCB, RwPluginDataChunkGetSizeCallBack getSizeCB); +typedef struct rwFrameList rwFrameList; + extern RwBool _rwFrameListFindFrame(const rwFrameList* frameList, const RwFrame* frame, RwInt32* npIndex); extern rwFrameList* _rwFrameListDeinitialize(rwFrameList* frameList); @@ -685,6 +754,9 @@ extern RwCamera* RwCameraBeginUpdate(RwCamera* camera); extern RwCamera* RwCameraSetViewOffset(RwCamera* camera, const RwV2d* offset); extern RwCamera* RwCameraSetNearClipPlane(RwCamera* camera, RwReal nearClip); extern RwCamera* RwCameraSetFarClipPlane(RwCamera* camera, RwReal farClip); +typedef enum RwFrustumTestResult RwFrustumTestResult; +typedef struct RwSphere RwSphere; + extern RwFrustumTestResult RwCameraFrustumTestSphere(const RwCamera* camera, const RwSphere* sphere); extern RwCamera* RwCameraClear(RwCamera* camera, RwRGBA* colour, RwInt32 clearMode); @@ -716,6 +788,8 @@ extern RwInt32 RwFrameRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor constructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB); +typedef struct RwImage RwImage; + extern RwImage* RwImageCreate(RwInt32 width, RwInt32 height, RwInt32 depth); extern RwBool RwImageDestroy(RwImage* image); extern RwImage* RwImageAllocatePixels(RwImage* image); @@ -802,6 +876,8 @@ extern void RxHeapFree(RxHeap* heap, void* block); extern RwBool _rxHeapReset(RxHeap* heap); extern void RxHeapDestroy(RxHeap* heap); extern RxHeap* RxHeapCreate(RwUInt32 size); +typedef struct RxRenderStateVector RxRenderStateVector; + extern RxRenderStateVector* RxRenderStateVectorSetDefaultRenderStateVector(RxRenderStateVector* rsvp); extern RxRenderStateVector* RxRenderStateVectorLoadDriverState(RxRenderStateVector* rsvp); @@ -811,4 +887,4 @@ extern void RwGameCubeCameraTextureFlush(RwRaster* ras, RwUInt32 param); } #endif -#endif \ No newline at end of file +#endif diff --git a/include/rwsdk/rwplcore.h b/include/rwsdk/rwplcore.h index 80c5eba6d..5501bb1dc 100644 --- a/include/rwsdk/rwplcore.h +++ b/include/rwsdk/rwplcore.h @@ -31,12 +31,14 @@ struct RwInt64 RwUInt32 bottom; }; +typedef struct RwUInt64 RwUInt64; struct RwUInt128 { RwUInt64 top; RwUInt64 bottom; }; +typedef struct RwInt64 RwInt64; struct RwInt128 { RwInt64 top; @@ -54,6 +56,16 @@ struct RwInt128 #define RwUInt16MAXVAL 0xFFFF #define RwUInt16MINVAL 0x0000 +#define RWALIGN(type, x) type __attribute__((aligned(x))) +#define rwMATRIXALIGNMENT sizeof(RwUInt32) +#define rwFRAMEALIGNMENT sizeof(RwUInt32) +#define rwV4DALIGNMENT sizeof(RwUInt32) + +#define rwMALLOCALIGNMENT 32 + +/* We define texture names to be a maximum of 16 ISO chars */ +#define rwTEXTUREBASENAMELENGTH 32 + #include #define _RW_C1 ((float)4.1666667908e-02) @@ -140,6 +152,8 @@ union RwSplitBits volatile RwUInt32 nUInt; }; +typedef struct RwSplitFixed RwSplitFixed; + struct RwSplitFixed { RwInt16 integral; @@ -183,6 +197,8 @@ struct RwRect RwInt32 h; }; +typedef struct RwV3d RwV3d; + struct RwSphere { RwV3d center; @@ -213,12 +229,16 @@ enum RwTextureCoordinateIndex rwTEXTURECOORDINATEINDEXFORCEENUMSIZEINT = RWFORCEENUMSIZEINT }; +typedef struct RwTexCoords RwTexCoords; + struct RwTexCoords { RwReal u; RwReal v; }; +typedef struct RwSLLink RwSLLink; + struct RwSLLink { RwSLLink* next; @@ -242,6 +262,8 @@ struct RwSingleList #define rwSingleListGetFirstSLLink(list) ((list)->link.next) #define rwSingleListGetTerminator(list) (NULL) +typedef struct RwLLLink RwLLLink; + struct RwLLLink { RwLLLink* next; @@ -378,6 +400,7 @@ enum RwPlatformID rwID_GAMECUBE, rwID_SOFTRAS, rwID_PCD3D8, + rwID_PCD3D9, rwPLATFROMIDFORCEENUMSIZEINT = RWFORCEENUMSIZEINT }; @@ -389,6 +412,7 @@ struct RwObject RwUInt8 privateFlags; void* parent; }; +typedef struct RwObject RwObject; typedef RwObject* (*RwObjectCallBack)(RwObject* object, void* data); @@ -497,6 +521,8 @@ struct RwMemoryFunctions void* (*rwcalloc)(size_t numObj, size_t sizeObj); }; +typedef struct RwLinkList RwLinkList; + struct RwFreeList { RwUInt32 entrySize; @@ -508,6 +534,8 @@ struct RwFreeList RwLLLink link; }; +typedef struct RwFreeList RwFreeList; + typedef void (*RwFreeListCallBack)(void* pMem, void* pData); typedef void* (*RwMemoryAllocFn)(RwFreeList* fl); typedef RwFreeList* (*RwMemoryFreeFn)(RwFreeList* fl, void* pData); @@ -558,6 +586,10 @@ struct RwStreamCustom void* data; }; +typedef struct RwStreamMemory RwStreamMemory; +typedef union RwStreamFile RwStreamFile; +typedef struct RwStreamCustom RwStreamCustom; + union RwStreamUnion { RwStreamMemory memory; @@ -565,6 +597,10 @@ union RwStreamUnion RwStreamCustom custom; }; +typedef enum RwStreamType RwStreamType; +typedef enum RwStreamAccessType RwStreamAccessType; +typedef union RwStreamUnion RwStreamUnion; + struct RwStream { RwStreamType type; @@ -580,6 +616,8 @@ typedef void* (*RwPluginObjectDestructor)(void* object, RwInt32 offsetInObject, RwInt32 sizeInObject); typedef void* (*RwPluginObjectCopy)(void* dstObject, const void* srcObject, RwInt32 offsetInObject, RwInt32 sizeInObject); +typedef struct RwStream RwStream; + typedef RwStream* (*RwPluginDataChunkReadCallBack)(RwStream* stream, RwInt32 binaryLength, void* object, RwInt32 offsetInObject, RwInt32 sizeInObject); @@ -595,6 +633,8 @@ typedef RwBool (*RwPluginDataChunkRightsCallBack)(void* object, RwInt32 offsetIn typedef struct RwPluginRegEntry; +typedef struct RwPluginRegEntry RwPluginRegEntry; + struct RwPluginRegistry { RwInt32 sizeOfStruct; @@ -607,6 +647,8 @@ struct RwPluginRegistry typedef void* (*RwPluginErrorStrCallBack)(void*); +typedef struct RwPluginRegistry RwPluginRegistry; + struct RwPluginRegEntry { RwInt32 offset; @@ -781,6 +823,8 @@ struct RwRGBA #define RwRGBAAssign(_target, _source) (*(_target) = *(_source)) +typedef struct RwRGBA RwRGBA; + struct rwGameCube2DVertex { RwReal x; @@ -790,6 +834,7 @@ struct rwGameCube2DVertex RwReal u; RwReal v; }; +typedef struct rwGameCube2DVertex rwGameCube2DVertex; typedef rwGameCube2DVertex RwIm2DVertex; typedef RwUInt16 RxVertexIndex; @@ -1080,11 +1125,14 @@ struct RwEngineOpenParams void* displayID; }; +typedef struct RwGameCubeDeviceConfig RwGameCubeDeviceConfig; struct RwGameCubeDeviceConfig { - /* unknown */ + s32 temppad; // stops a compiler issue }; +typedef enum RwRenderState RwRenderState; + typedef RwBool (*RwSystemFunc)(RwInt32 nOption, void* pOut, void* pInOut, RwInt32 nIn); typedef RwBool (*RwRenderStateSetFunction)(RwRenderState nState, void* pParam); typedef RwBool (*RwRenderStateGetFunction)(RwRenderState nState, void* pParam); @@ -1092,6 +1140,8 @@ typedef RwBool (*RwIm2DRenderLineFunction)(RwIm2DVertex* vertices, RwInt32 numVe RwInt32 vert1, RwInt32 vert2); typedef RwBool (*RwIm2DRenderTriangleFunction)(RwIm2DVertex* vertices, RwInt32 numVertices, RwInt32 vert1, RwInt32 vert2, RwInt32 vert3); +typedef enum RwPrimitiveType RwPrimitiveType; + typedef RwBool (*RwIm2DRenderPrimitiveFunction)(RwPrimitiveType primType, RwIm2DVertex* vertices, RwInt32 numVertices); typedef RwBool (*RwIm2DRenderIndexedPrimitiveFunction)(RwPrimitiveType primType, @@ -1148,6 +1198,8 @@ enum RwVideoModeFlag rwVIDEOMODEFLAGFORCEENUMSIZEINT = RWFORCEENUMSIZEINT }; +typedef enum RwVideoModeFlag RwVideoModeFlag; + struct RwVideoMode { RwInt32 width; @@ -1176,6 +1228,13 @@ enum RwEngineStatus rwENGINESTATUSFORCEENUMSIZEINT = RWFORCEENUMSIZEINT }; +typedef struct RwDevice RwDevice; +typedef struct RwFileFunctions RwFileFunctions; +typedef struct RwStringFunctions RwStringFunctions; +typedef struct RwMemoryFunctions RwMemoryFunctions; +typedef struct RwMetrics RwMetrics; +typedef enum RwEngineStatus RwEngineStatus; + struct RwGlobals { void* curCamera; @@ -1198,8 +1257,10 @@ struct RwGlobals typedef struct RwResEntry; +typedef struct RwResEntry RwResEntry; typedef void (*RwResEntryDestroyNotify)(RwResEntry* resEntry); +typedef struct RwResEntry RwResEntry; struct RwResEntry { RwLLLink link; @@ -1220,6 +1281,8 @@ struct RwChunkHeaderInfo RwBool isComplex; /**< Internal Use */ }; +typedef struct RwRGBAReal RwRGBAReal; + struct RwSky2DVertexFields { RwV3d scrVertex; @@ -1233,6 +1296,8 @@ struct RwSky2DVertexFields RwReal pad2; }; +typedef struct RwSky2DVertexFields RwSky2DVertexFields; + struct RwSky2DVertexAlignmentOverlay { union @@ -1242,15 +1307,38 @@ struct RwSky2DVertexAlignmentOverlay }; }; +typedef struct RwSky2DVertexAlignmentOverlay RwSky2DVertexAlignmentOverlay; + struct RwSky2DVertex { RwSky2DVertexAlignmentOverlay u; }; +typedef struct RwModuleInfo RwModuleInfo; +struct RwModuleInfo +{ + RwInt32 globalsOffset; + RwInt32 numInstances; +}; + +enum RwMemoryHintDuration +{ + rwMEMHINTDUR_NADURATION = 0x00000000, + rwMEMHINTDUR_FUNCTION = 0x00010000, + rwMEMHINTDUR_FRAME = 0x00020000, + rwMEMHINTDUR_EVENT = 0x00030000, + rwMEMHINTDUR_GLOBAL = 0x00040000, + rwMEMHINTDUR_MASK = 0x00FF0000, + rwMEMHINTDURFORCEENUMSIZEINT = RWFORCEENUMSIZEINT +}; +typedef enum RwMemoryHintDuration RwMemoryHintDuration; + #ifdef __cplusplus extern "C" { #endif +typedef struct RwGlobals RwGlobals; + extern RwGlobals* RwEngineInstance; extern RwStream* _rwStreamWriteVersionedChunkHeader(RwStream* stream, RwInt32 type, RwInt32 size, @@ -1265,6 +1353,9 @@ extern RwStream* RwStreamWriteReal(RwStream* stream, const RwReal* reals, RwUInt extern RwStream* RwStreamWriteInt32(RwStream* stream, const RwInt32* ints, RwUInt32 numBytes); extern RwStream* RwStreamReadReal(RwStream* stream, RwReal* reals, RwUInt32 numBytes); extern RwStream* RwStreamReadInt32(RwStream* stream, RwInt32* ints, RwUInt32 numBytes); +typedef struct RwChunkHeaderInfo RwChunkHeaderInfo; +typedef struct RwError RwError; + extern RwStream* RwStreamReadChunkHeaderInfo(RwStream* stream, RwChunkHeaderInfo* chunkHeaderInfo); extern RwError* RwErrorSet(RwError* code); extern RwError* RwErrorGet(RwError* code); @@ -1290,6 +1381,8 @@ extern RwMatrix* RwMatrixUpdate(RwMatrix* matrix); extern RwMatrix* RwMatrixMultiply(RwMatrix* matrixOut, const RwMatrix* MatrixIn1, const RwMatrix* matrixIn2); extern RwMatrix* RwMatrixOrthoNormalize(RwMatrix* matrixOut, const RwMatrix* matrixIn); +typedef enum RwOpCombineType RwOpCombineType; + extern RwMatrix* RwMatrixRotateOneMinusCosineSine(RwMatrix* matrix, const RwV3d* unitAxis, RwReal oneMinusCosine, RwReal sine, RwOpCombineType combineOp); @@ -1360,6 +1453,9 @@ extern RwInt32 RwEngineRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor initCB, RwPluginObjectDestructor termCB); extern RwInt32 RwEngineGetPluginOffset(RwUInt32 pluginID); +typedef struct RwVideoMode RwVideoMode; +typedef struct RwEngineOpenParams RwEngineOpenParams; + extern RwVideoMode* RwEngineGetVideoModeInfo(RwVideoMode* modeinfo, RwInt32 modeIndex); extern RwInt32 RwEngineGetCurrentVideoMode(void); extern RwBool RwEngineStop(void); diff --git a/src/rwsdk/driver/common/palquant.c b/src/rwsdk/driver/common/palquant.c new file mode 100644 index 000000000..319b542b6 --- /dev/null +++ b/src/rwsdk/driver/common/palquant.c @@ -0,0 +1,53 @@ +#include "rwplcore.h" +#include "rwcore.h" + +typedef struct _rwPalQuantRGBABox _rwPalQuantRGBABox; +typedef struct _rwPalQuantOctNode _rwPalQuantOctNode; +typedef struct _rwPalQuantLeafNode _rwPalQuantLeafNode; +typedef struct _rwPalQuantBranchNode _rwPalQuantBranchNode; + +extern RwGlobals* RwEngineInstance; + +struct _rwPalQuantLeafNode +{ + RwReal weight; + RwRGBAReal ac; + RwReal var; + RwUInt8 palIndex; +}; + +struct _rwPalQuantBranchNode +{ + _rwPalQuantOctNode* dir[16]; +}; + +struct _rwPalQuantOctNode +{ + _rwPalQuantLeafNode Leaf; + _rwPalQuantBranchNode Branch; +}; + +void InitLeaf(_rwPalQuantLeafNode* Leaf) +{ + // What the hell is going on here? + Leaf->palIndex = 0xff; + Leaf->weight = 0; + Leaf->ac.red = 0; + Leaf->ac.green = 0; + Leaf->ac.blue = 0; + Leaf->ac.alpha = 0; + Leaf->var = 0; +} + +void InitBranch(_rwPalQuantBranchNode* Branch) +{ + int x; + for (x = 0; x < 16; ++x) + { + Branch->dir[x] = (_rwPalQuantOctNode*)NULL; + } +} + +void CreateCube() +{ +} diff --git a/src/rwsdk/driver/gcn/dl2drend.c b/src/rwsdk/driver/gcn/dl2drend.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/driver/gcn/dlconvrt.c b/src/rwsdk/driver/gcn/dlconvrt.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/driver/gcn/dldevice.c b/src/rwsdk/driver/gcn/dldevice.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/driver/gcn/dlraster.c b/src/rwsdk/driver/gcn/dlraster.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/driver/gcn/dlrendst.c b/src/rwsdk/driver/gcn/dlrendst.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/driver/gcn/dlsprite.c b/src/rwsdk/driver/gcn/dlsprite.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/driver/gcn/dltexdic.c b/src/rwsdk/driver/gcn/dltexdic.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/driver/gcn/dltextur.c b/src/rwsdk/driver/gcn/dltextur.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/driver/gcn/dltoken.c b/src/rwsdk/driver/gcn/dltoken.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/os/gcn/osintf.c b/src/rwsdk/os/gcn/osintf.c new file mode 100644 index 000000000..519afb04d --- /dev/null +++ b/src/rwsdk/os/gcn/osintf.c @@ -0,0 +1,6 @@ +#include "rwplcore.h" +#include "rwcore.h" + +RwInt32 _rwpathisabsolute() +{ +} diff --git a/src/rwsdk/plugin/collis/ctbsp.c b/src/rwsdk/plugin/collis/ctbsp.c index ef70eb772..c344b8e8a 100644 --- a/src/rwsdk/plugin/collis/ctbsp.c +++ b/src/rwsdk/plugin/collis/ctbsp.c @@ -1,8 +1,57 @@ -// #include +#include "rwplcore.h" +#include "rwcore.h" // #include // #include // #include -void _rpCollBSPTreeInit() +struct nodeInfo { -} \ No newline at end of file + u32 type; + u32 index; +}; + +typedef struct RpCollBSPTree RpCollBSPTree; + +struct RpCollBSPTree +// Blocks +/* anonymous block */ { + // Range: 0x1C9BE0 -> 0x1CA540 + s32 nStack; // r20 + struct nodeInfo nodeStack[33]; // r29+0x420 + struct RwLine lineStack[33]; // r29+0x100 + struct RwLine currLine; // r29+0xE0 + struct RpCollBSPLeafNode* leaf; // r2 + struct RpCollBSPBranchNode* branch; // r9 + u32 branch_type; // r5 + u32 branch_leftType; // r6 + u32 branch_rightType; // r4 + u32 branch_leftNode; // r3 + u32 branch_rightNode; // r2 + union RwSplitBits lStart; // r29+0x53C + union RwSplitBits lEnd; // r29+0x538 + union RwSplitBits rStart; // r29+0x534 + union RwSplitBits rEnd; // r29+0x530 + f32 delta; // r5 + //f32 delta; // r5 + //f32 delta; // r6 + //f32 delta; // r5 +}; + +RpCollBSPTree* _rpCollBSPTreeInit(RpCollBSPTree* tree, s32 numLeafNodes) +{ + // Something similar to this? + // Not quite sure yet + tree = (RpCollBSPTree*)numLeafNodes; + if (numLeafNodes + -1 > 0) + { + tree = (tree + 4); + tree = tree + (numLeafNodes + -1) * 0x10; + return; + } + tree = 0; + tree = (tree + 4); +} + +s32 _rpCollBSPTreeMemGetSize(s32 numLeafNodes) +{ +} diff --git a/src/rwsdk/plugin/collis/ctgeom.c b/src/rwsdk/plugin/collis/ctgeom.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/plugin/collis/ctworld.c b/src/rwsdk/plugin/collis/ctworld.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/plugin/collis/rpcollis.c b/src/rwsdk/plugin/collis/rpcollis.c new file mode 100644 index 000000000..b0b3086a6 --- /dev/null +++ b/src/rwsdk/plugin/collis/rpcollis.c @@ -0,0 +1,60 @@ +#include "rwplcore.h" +#include "rwcore.h" + +RwInt32 _rpCollisionNumInstances = 0; +RwInt32 _rpCollisionGlobalsOffset = 0; +RwInt32 _rpCollisionAtomicDataOffset = 0; +RwInt32 _rpCollisionGeometryDataOffset = 0; +RwInt32 _rpCollisionWorldSectorDataOffset = 0; + +struct RpCollisionData +{ + struct RpCollTree* tree; +}; + +typedef struct RpCollisionData RpCollisionData; + +// Not the correct params? +static void* CollisionOpen(void* instance, RwInt32 offset, RwInt32 size) +{ + _rpCollisionNumInstances++; +} + +// Not the correct params? +static void* CollisionClose(void* instance, RwInt32 offset, RwInt32 size) +{ + _rpCollisionNumInstances--; +} + +void* CollisionDataDestroy(void* object, s32 offset) +{ + RpCollisionData** extData; +} + +// params unknown, probably offset and size tho +void CollisionDataCreate(RwInt32 offset, RwInt32 size) +{ + *(RwInt32*)(offset + size) = 0; +} + +// param could be wrong +void CollisionAtomicInit(RwInt32 size) +{ + *(RwInt32*)(size + _rpCollisionAtomicDataOffset) = 0; +} + +static RwStream* CollisionDataStreamWrite(RwStream* stream, const void* object, RwInt32 offset) +{ +} + +RwStream* CollisionDataStreamRead(RwStream* stream, s32 binaryLength, void* object, s32 offset) +{ +} + +s32 CollisionDataStreamGetSize(void* object, s32 offsetInObject) +{ +} + +RwBool RpCollisionPluginAttach() +{ +} diff --git a/src/rwsdk/plugin/hanim/rphanim.c b/src/rwsdk/plugin/hanim/rphanim.c new file mode 100644 index 000000000..c08e47315 --- /dev/null +++ b/src/rwsdk/plugin/hanim/rphanim.c @@ -0,0 +1,231 @@ +#include "rwplcore.h" +#include "rwcore.h" +#include "rphanim.h" + +extern RpHAnimAtomicGlobalVars RpHAnimAtomicGlobals; + +static void* HAnimClose(void* instance, RwInt32 offset, RwInt32 size) +{ + if (NULL != RpHAnimAtomicGlobals.HAnimFreeList) + { + RwFreeListDestroy(RpHAnimAtomicGlobals.HAnimFreeList); + RpHAnimAtomicGlobals.HAnimFreeList = (RwFreeList*)NULL; + } + return instance; +} + +static void* HAnimConstructor(void* object, RwInt32 offset, RwInt32 size) +{ + RpHAnimFrameExtension* frameExt = 0; + + frameExt = (object); + frameExt->hierarchy = (RpHAnimHierarchy*)NULL; + frameExt->id = rpHANIMDEFAULTFRAMEID; + + return (object); +} + +static void* HAnimDestructor(void* object, RwInt32 offset, RwInt32 size) +{ + RpHAnimFrameExtension* frameExt; + + frameExt = (RpHAnimFrameExtension*)RPHANIMFRAMEGETDATA(object); + if (frameExt->hierarchy) + { + RpHAnimHierarchy* pHierarchy = frameExt->hierarchy; + RwInt32 frameNum; + /* run through all the frames this hierarchy + points at since they also point back at the + hierarchy. Set the pointers to NULL and then + destroy the hierarchy */ + for (frameNum = 0; frameNum < pHierarchy->numNodes; frameNum++) + { + if (pHierarchy->pNodeInfo[frameNum].pFrame) + { + /* TODO: + In here we ultimately check if this pointer is a sub-hierarchy + root, if so destroy the sub-hierarchy */ + } + + pHierarchy->pNodeInfo[frameNum].pFrame = (RwFrame*)NULL; + } + + if (pHierarchy->parentFrame == (RwFrame*)object) + { + RpHAnimHierarchyDestroy(pHierarchy); + } + + frameExt->hierarchy = (RpHAnimHierarchy*)NULL; + } + frameExt->id = rpHANIMDEFAULTFRAMEID; + + return object; +} + +static void* HAnimCopy(void* dstObject, const void* srcObject, RwInt32 offset, RwInt32 size) +{ + const RpHAnimFrameExtension* srcFrameExt; + RpHAnimFrameExtension* dstFrameExt; + + srcFrameExt = (const RpHAnimFrameExtension*)RPHANIMFRAMEGETCONSTDATA(srcObject); + dstFrameExt = (RpHAnimFrameExtension*)RPHANIMFRAMEGETDATA(dstObject); + + dstFrameExt->id = srcFrameExt->id; + if (srcFrameExt->hierarchy) + { + RpHAnimHierarchy* srcHierarchy = srcFrameExt->hierarchy; + if (!(srcHierarchy->flags & rpHANIMHIERARCHYSUBHIERARCHY)) + { + RpHAnimHierarchy* dstHierarchy; + RwInt32 i; + + dstHierarchy = + RpHAnimHierarchyCreate(srcHierarchy->numNodes, (RwUInt32*)NULL, (RwInt32*)NULL, + (RpHAnimHierarchyFlag)srcHierarchy->flags, + srcHierarchy->currentAnim->maxInterpKeyFrameSize); + + for (i = 0; i < dstHierarchy->numNodes; i++) + { + dstHierarchy->pNodeInfo[i].pFrame = (RwFrame*)NULL; + dstHierarchy->pNodeInfo[i].flags = srcHierarchy->pNodeInfo[i].flags; + dstHierarchy->pNodeInfo[i].nodeIndex = srcHierarchy->pNodeInfo[i].nodeIndex; + dstHierarchy->pNodeInfo[i].nodeID = srcHierarchy->pNodeInfo[i].nodeID; + } + + dstFrameExt->hierarchy = dstHierarchy; + dstHierarchy->parentFrame = (RwFrame*)dstObject; + } + } + + return dstObject; +} + +static RwStream* HAnimWrite(RwStream* stream, RwInt32 binaryLength, const void* object, + RwInt32 offsetInObject, RwInt32 sizeInObject) +{ + RwInt32 i; + const RpHAnimFrameExtension* frameExt; + RpHAnimNodeInfo* pNodeInfo; + RpHAnimHierarchy* animHierarchy; + RwInt32 streamVersion = rpHANIMSTREAMCURRENTVERSION; + + if (!RwStreamWriteInt32(stream, (RwInt32*)&streamVersion, sizeof(RwInt32))) + { + return NULL; + } + + frameExt = (const RpHAnimFrameExtension*)RPHANIMFRAMEGETCONSTDATA(object); + + if (!RwStreamWriteInt32(stream, (const RwInt32*)&frameExt->id, sizeof(RwInt32))) + { + return NULL; + } + + animHierarchy = frameExt->hierarchy; + + if (animHierarchy && !(animHierarchy->flags & rpHANIMHIERARCHYSUBHIERARCHY)) + { + if (!RwStreamWriteInt32(stream, (const RwInt32*)&animHierarchy->numNodes, sizeof(RwInt32))) + { + return NULL; + } + if (!RwStreamWriteInt32(stream, (const RwInt32*)&animHierarchy->flags, sizeof(RwInt32))) + { + return NULL; + } + if (!RwStreamWriteInt32(stream, + (const RwInt32*)&animHierarchy->currentAnim->maxInterpKeyFrameSize, + sizeof(RwInt32))) + { + return NULL; + } + + pNodeInfo = animHierarchy->pNodeInfo; + + for (i = 0; i < animHierarchy->numNodes; i++) + { + if (!RwStreamWriteInt32(stream, (RwInt32*)&pNodeInfo->nodeID, sizeof(RwInt32))) + { + return NULL; + } + + if (!RwStreamWriteInt32(stream, (RwInt32*)&pNodeInfo->nodeIndex, sizeof(RwInt32))) + { + return NULL; + } + + if (!RwStreamWriteInt32(stream, (RwInt32*)&pNodeInfo->flags, sizeof(RwInt32))) + { + return NULL; + } + + pNodeInfo++; + } + } + else + { + RwInt32 numNodes = 0; + + if (!RwStreamWriteInt32(stream, (const RwInt32*)&numNodes, sizeof(RwInt32))) + { + return NULL; + } + } + + return stream; +} + +static RwInt32 HAnimSize(const void* object, RwInt32 offsetInObject, RwInt32 sizeInObject) +{ + RwBool needToStream; + + const RpHAnimFrameExtension* frameExt = + (const RpHAnimFrameExtension*)RPHANIMFRAMEGETCONSTDATA(object); + + needToStream = (rpHANIMDEFAULTFRAMEID != frameExt->id) || (frameExt->hierarchy); + + if (needToStream) + { + RwInt32 size; + + size = sizeof(RwInt32); + size += sizeof(RwInt32); + size += sizeof(RwInt32); + + if (frameExt->hierarchy && !(frameExt->hierarchy->flags & rpHANIMHIERARCHYSUBHIERARCHY)) + { + size += sizeof(RwInt32); + size += sizeof(RwInt32); + size += frameExt->hierarchy->numNodes * (sizeof(RwInt32) * 3); + } + + return size; + } + + return 0; +} + +RwBool RpHAnimFrameSetHierarchy(RwFrame* frame, RpHAnimHierarchy* hierarchy) +{ + // Seems to be the correct idea but the RPHANIMFRAMEGETDATA call + // adds in too much to the asm. Needs re-written + RpHAnimFrameExtension* frameExt; + + frameExt = (RpHAnimFrameExtension*)RPHANIMFRAMEGETDATA(frame); + + if (frameExt->hierarchy) + { + frameExt->hierarchy->parentFrame = (RwFrame*)NULL; + } + frameExt->hierarchy = hierarchy; + if (hierarchy) + { + hierarchy->parentFrame = frame; + } + + return TRUE; +} + +RpHAnimHierarchy* RpHAnimFrameGetHierarchy(RwFrame* frame) +{ +} diff --git a/src/rwsdk/plugin/hanim/stdkey.c b/src/rwsdk/plugin/hanim/stdkey.c new file mode 100644 index 000000000..f81dca3d9 --- /dev/null +++ b/src/rwsdk/plugin/hanim/stdkey.c @@ -0,0 +1,95 @@ +#include "rwplcore.h" +#include "rwcore.h" +#include "rphanim.h" + +#define RpHAnimKeyFrameToMatrixMacro(_matrix, _voidIFrame) \ + MACRO_START \ + { \ + RpHAnimInterpFrame* iFrame = (RpHAnimInterpFrame*)(_voidIFrame); \ + \ + RtQuatUnitConvertToMatrix(&iFrame->q, (_matrix)); \ + \ + (_matrix)->pos.x = iFrame->t.x; \ + (_matrix)->pos.y = iFrame->t.y; \ + (_matrix)->pos.z = iFrame->t.z; \ + } \ + MACRO_STOP + +#define _EPSILON ((RwReal)(0.001)) +#define _TOL_COS_ZERO (((RwReal)1) - _EPSILON) + +void RpHAnimKeyFrameApply(void* pMatrix, void* pVoidIFrame) +{ + // Correct idea, but executed wwrong? + RpHAnimKeyFrameToMatrixMacro((RwMatrix*)pMatrix, pVoidIFrame); + return; +} + +void RpHAnimKeyFrameInterpolate(void* pVoidOut, void* pVoidIn1, void* pVoidIn2, RwReal time, + void* customData) +{ + // End of the function is correct, first 80% is horribly wrong. + RpHAnimInterpFrame* pOut = (RpHAnimInterpFrame*)pVoidOut; + RpHAnimKeyFrame* pIn1 = (RpHAnimKeyFrame*)pVoidIn1; + RpHAnimKeyFrame* pIn2 = (RpHAnimKeyFrame*)pVoidIn2; + + RwReal fCosTheta = + (RwV3dDotProduct(&pIn1->q.imag, &pIn2->q.imag) + pIn1->q.real * pIn2->q.real); + RwReal fAlpha = ((time - pIn1->time) / + + (pIn2->time - pIn1->time)); + RwReal fBeta; + RwBool bObtuseTheta; + RwBool bNearlyZeroTheta = 0; + + RpHAnimKeyFrameTransInterpolate(&pOut->t, &pIn1->t, fAlpha, &pIn2->t); + + bObtuseTheta = (fCosTheta < ((RwReal)0)); + + if (bObtuseTheta) + { + fCosTheta = -fCosTheta; + RwV3dNegate(&pIn2->q.imag, &pIn2->q.imag); + pIn2->q.real = -pIn2->q.real; + } + + fBeta = ((RwReal)1) - fAlpha; + + bNearlyZeroTheta = (fCosTheta >= _TOL_COS_ZERO); + + if (!bNearlyZeroTheta) + { + RwReal fTheta = 0; + RwReal fCosecTheta = 0; + + RwIEEEACosfMacro(fTheta, fCosTheta); + RwCosecMinusPiToPiMacro(fCosecTheta, fTheta); + + fBeta *= fTheta; + RwSinMinusPiToPiMacro(fBeta, fBeta); + fBeta *= fCosecTheta; + + fAlpha *= fTheta; + RwSinMinusPiToPiMacro(fAlpha, fAlpha); + fAlpha *= fCosecTheta; + } + + pOut->q.imag.x = fBeta * pIn1->q.imag.x + fAlpha * pIn2->q.imag.x; + pOut->q.imag.y = fBeta * pIn1->q.imag.y + fAlpha * pIn2->q.imag.y; + pOut->q.imag.z = fBeta * pIn1->q.imag.z + fAlpha * pIn2->q.imag.z; + pOut->q.real = fBeta * pIn1->q.real + fAlpha * pIn2->q.real; + +#if (0) + /* Assert no worse than 5% error in length^2 of + * spherically interpolated quaternion */ + + RWASSERT(bNearlyZeroTheta || (((0.95) < RtQuatModulusSquaredMacro(&pOut->q)) && + (RtQuatModulusSquaredMacro(&pOut->q) < (1 / 0.95)))); +#endif + + return; +} + +// Not continuing with this file for now +// Seems to need the macros rewritten, along with a good portion of the functions +// -Colin diff --git a/src/rwsdk/plugin/matfx/gcn/effectPipesGcn.c b/src/rwsdk/plugin/matfx/gcn/effectPipesGcn.c new file mode 100644 index 000000000..16f1dece5 --- /dev/null +++ b/src/rwsdk/plugin/matfx/gcn/effectPipesGcn.c @@ -0,0 +1,24 @@ +#include "rwplcore.h" +#include "rwcore.h" +#include "rpmatfx.h" + +RwTexture* _rpMatFXTextureMaskCreate(); +RpWorldSector* _RpMatFXWorldSectorPipe; + +typedef struct MatFXDualData MatFXDualData; + +extern RpWorldSector* _rpMatFXPipelineWorldSectorSetup(RpWorldSector* worldSector) +{ + _RpMatFXWorldSectorPipe = worldSector; +} + +extern RwBool _rpMatFXSetupDualRenderState(MatFXDualData* dualData, RwRenderState nState) +{ + return TRUE; +} + +extern RwTexture* _rpMatFXSetupBumpMapTexture(const RwTexture* baseTexture, + const RwTexture* effectTexture) +{ + _rpMatFXTextureMaskCreate(); +} diff --git a/src/rwsdk/plugin/matfx/gcn/multiTexGcn.c b/src/rwsdk/plugin/matfx/gcn/multiTexGcn.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/plugin/matfx/gcn/multiTexGcnData.c b/src/rwsdk/plugin/matfx/gcn/multiTexGcnData.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/plugin/matfx/gcn/multiTexGcnPipe.c b/src/rwsdk/plugin/matfx/gcn/multiTexGcnPipe.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/plugin/matfx/matfx.h b/src/rwsdk/plugin/matfx/matfx.h new file mode 100644 index 000000000..62aa25244 --- /dev/null +++ b/src/rwsdk/plugin/matfx/matfx.h @@ -0,0 +1,106 @@ +#ifndef RPMATFX_MATFX_H +#define RPMATFX_MATFX_H + +#include "rwcore.h" +#include "rpworld.h" + +typedef enum RpMatFXMaterialFlags RpMatFXMaterialFlags; +typedef struct RwMatFXInfo RwMatFXInfo; +typedef struct RwModuleInfo RwModuleInfo; + +struct RwMatFXInfo +{ + RwModuleInfo Module; + RwFreeList* MaterialData; +}; + +extern RwMatFXInfo MatFXInfo; + +#ifdef __cplusplus +extern "C" { +#endif + +extern void RpMatFXMaterialDataSetFreeListCreateParams(RwInt32 blockSize, + RwInt32 numBlocksToPrealloc); + +extern RwBool RpMatFXPluginAttach(void); +extern RpAtomic* RpMatFXAtomicEnableEffects(RpAtomic* atomic); +extern RwBool RpMatFXAtomicQueryEffects(RpAtomic* atomic); +extern RpWorldSector* RpMatFXWorldSectorEnableEffects(RpWorldSector* worldSector); +extern RwBool RpMatFXWorldSectorQueryEffects(RpWorldSector* worldSector); +extern RpMaterial* RpMatFXMaterialSetEffects(RpMaterial* material, RpMatFXMaterialFlags flags); + +extern RpMaterial* RpMatFXMaterialSetupBumpMap(RpMaterial* material, RwTexture* texture, + RwFrame* frame, RwReal coef); + +extern RpMaterial* RpMatFXMaterialSetupEnvMap(RpMaterial* material, RwTexture* texture, + RwFrame* frame, RwBool useFrameBufferAlpha, + RwReal coef); + +extern RpMaterial* RpMatFXMaterialSetupDualTexture(RpMaterial* material, RwTexture* texture, + RwBlendFunction srcBlendMode, + RwBlendFunction dstBlendMode); + +extern RpMatFXMaterialFlags RpMatFXMaterialGetEffects(const RpMaterial* material); + +extern RpMaterial* RpMatFXMaterialSetBumpMapTexture(RpMaterial* material, RwTexture* texture); + +extern RpMaterial* RpMatFXMaterialSetBumpMapFrame(RpMaterial* material, RwFrame* frame); + +extern RpMaterial* RpMatFXMaterialSetBumpMapCoefficient(RpMaterial* material, RwReal coef); +extern RwTexture* RpMatFXMaterialGetBumpMapTexture(const RpMaterial* material); + +extern RwTexture* RpMatFXMaterialGetBumpMapBumpedTexture(const RpMaterial* material); + +extern RwFrame* RpMatFXMaterialGetBumpMapFrame(const RpMaterial* material); + +extern RwReal RpMatFXMaterialGetBumpMapCoefficient(const RpMaterial* material); + +extern RpMaterial* RpMatFXMaterialSetEnvMapTexture(RpMaterial* material, RwTexture* texture); + +extern RpMaterial* RpMatFXMaterialSetEnvMapFrame(RpMaterial* material, RwFrame* frame); + +extern RpMaterial* RpMatFXMaterialSetEnvMapFrameBufferAlpha(RpMaterial* material, + RwBool useFrameBufferAlpha); + +extern RpMaterial* RpMatFXMaterialSetEnvMapCoefficient(RpMaterial* material, RwReal coef); + +extern RwTexture* RpMatFXMaterialGetEnvMapTexture(const RpMaterial* material); + +extern RwFrame* RpMatFXMaterialGetEnvMapFrame(const RpMaterial* material); + +extern RwBool RpMatFXMaterialGetEnvMapFrameBufferAlpha(const RpMaterial* material); + +extern RwReal RpMatFXMaterialGetEnvMapCoefficient(const RpMaterial* material); + +extern RpMaterial* RpMatFXMaterialSetDualTexture(RpMaterial* material, RwTexture* texture); + +extern RpMaterial* RpMatFXMaterialSetDualBlendModes(RpMaterial* material, + RwBlendFunction srcBlendMode, + RwBlendFunction dstBlendMode); + +extern RwTexture* RpMatFXMaterialGetDualTexture(const RpMaterial* material); + +extern const RpMaterial* RpMatFXMaterialGetDualBlendModes(const RpMaterial* material, + RwBlendFunction* srcBlendMode, + RwBlendFunction* dstBlendMode); + +extern RpMaterial* RpMatFXMaterialSetUVTransformMatrices(RpMaterial* material, + RwMatrix* baseTransform, + RwMatrix* dualTransform); + +extern const RpMaterial* RpMatFXMaterialGetUVTransformMatrices(const RpMaterial* material, + RwMatrix** baseTransform, + RwMatrix** dualTransform); + +#ifdef __cplusplus +} +#endif + +extern RwStream* _rpMatFXStreamWriteTexture(RwStream* stream, const RwTexture* texture); + +extern RwStream* _rpMatFXStreamReadTexture(RwStream* stream, RwTexture** texture); + +extern RwUInt32 _rpMatFXStreamSizeTexture(const RwTexture* texture); + +#endif diff --git a/src/rwsdk/plugin/matfx/multiTex.c b/src/rwsdk/plugin/matfx/multiTex.c new file mode 100644 index 000000000..3ff67142d --- /dev/null +++ b/src/rwsdk/plugin/matfx/multiTex.c @@ -0,0 +1,230 @@ +#include "rwplcore.h" +#include "rwcore.h" +#include "rpmatfx.h" +#include + +#define MAXPLATFORMID (rwID_PCD3D9) + +#ifndef rwCHUNKHEADERSIZE +#define rwCHUNKHEADERSIZE (sizeof(RwUInt32) * 3) +#endif + +#define rwMAXTEXTURECOORDS 8 + +#define rwID_MULTITEXPLUGIN MAKECHUNKID(rwVENDORID_CRITERIONTK, 0x2c) +#define rwID_CHAINPLUGIN MAKECHUNKID(rwVENDORID_CRITERIONTK, 0x2d) + +typedef struct _MultiTextureExt +{ + RpMultiTexture* multiTexture; + +} MultiTextureExt; + +typedef enum _MultiTextureStreamFlag +{ + MULTITEXTURESTREAMEFFECT = 0x01 + +} MultiTextureStreamFlag; + +typedef struct _MultiTextureStreamHdr +{ + RwUInt8 platformID; + RwUInt8 numTextures; + RwUInt8 flags; + RwUInt8 pad; + +} MultiTextureStreamHdr; + +rpMultiTextureRegEntry RegEntries[MAXPLATFORMID + 1]; + +RwModuleInfo _rpMultiTextureModule = { 0, 0 }; + +static void* MultiTextureOpen(void* object, RwInt32 offsetInObject, RwInt32 sizeInObject) +{ + _rpMultiTextureModule.numInstances++; + _rpMTEffectOpen(); + return object; +} + +static void* MultiTextureClose(void* object, RwInt32 offsetInObject, RwInt32 sizeInObject) +{ + _rpMTEffectClose(); + _rpMultiTextureModule.numInstances--; + return object; +} + +static void* MultiTextureConstructor(void* object, RwInt32 offset, RwInt32 size) +{ + *(RwInt32*)((RwInt32)object + offset) = 0; +} + +static void* MultiTextureDestructor(void* object, RwInt32 offset, RwInt32 size) +{ + MultiTextureExt* ext = (MultiTextureExt*)GetMultiTextureExtMacro(object, offset); + + if (ext->multiTexture) + { + MultiTextureDestroy(ext->multiTexture); + ext->multiTexture = (RpMultiTexture*)NULL; + } + + return object; +} + +static void* MultiTextureCopy(void* dstObject, const void* srcObject, RwInt32 offset, RwInt32 size) +{ + RpMultiTexture const* srcMT; + RpMultiTexture* dstMT; + RwUInt32 i; + + srcMT = 0; + if (!srcMT) + { + RWRETURN(dstObject); + } + + dstMT = (RpMultiTexture*)MultiTextureCreate(srcMT->regEntry, srcMT->numTextures); + if (!dstMT) + { + return NULL; + } + + for (i = 0; i < srcMT->numTextures; i++) + { + RpMultiTextureSetTexture(dstMT, i, RpMultiTextureGetTexture(srcMT, i)); + RpMultiTextureSetCoords(dstMT, i, RpMultiTextureGetCoords(srcMT, i)); + } + + RpMultiTextureSetEffect(dstMT, RpMultiTextureGetEffect(srcMT)); + + return dstObject; +} + +static RwInt32 MultiTextureStreamGetSize(const void* object, RwInt32 offset, RwInt32 sizeInObj) +{ +} + +static RwStream* MultiTextureStreamWrite(RwStream* stream, RwInt32 length, const void* object, + RwInt32 offset, RwInt32 sizeInObj) +{ +} + +static RwStream* MultiTextureStreamRead(RwStream* stream, RwInt32 length, void* object, + RwInt32 offset, RwInt32 sizeInObj) +{ +} + +RwBool _rpMultiTexturePluginAttach() +{ + if (!_rpMTEffectSystemInit()) + { + return FALSE; + } + + memset(RegEntries, 0, sizeof(RegEntries)); + + _rpMultiTextureModule.globalsOffset = RwEngineRegisterPlugin( + sizeof(rpMultiTextureGlobals), rwID_MULTITEXPLUGIN, MultiTextureOpen, MultiTextureClose); + + if (_rpMultiTextureModule.globalsOffset < 0) + { + return (FALSE); + } + + return TRUE; +} + +RwBool _rpMaterialRegisterMultiTexturePlugin(RwPlatformID platformID, RwUInt32 pluginID, + RwUInt32 extensionSize) +{ + RwInt32 offset; + rpMultiTextureRegEntry* regEntry; + + offset = RpMaterialRegisterPlugin(sizeof(MultiTextureExt), pluginID, MultiTextureConstructor, + MultiTextureDestructor, MultiTextureCopy); + if (offset < 0) + { + return FALSE; + } + regEntry = &RegEntries[platformID]; + regEntry->materialOffset = offset; + offset = RpMaterialRegisterPluginStream(pluginID, MultiTextureStreamRead, + MultiTextureStreamWrite, MultiTextureStreamGetSize); + if (offset < 0) + { + return FALSE; + } + + regEntry->platformID = platformID; + regEntry->pluginID = pluginID; + regEntry->extensionSize = extensionSize; + + return TRUE; +} + +RpMultiTexture* RpMultiTextureSetEffect(RpMultiTexture* multiTexture, RpMTEffect* effect) +{ + if (multiTexture->effect) + { + RpMTEffectDestroy(multiTexture->effect); + } + multiTexture->effect = effect; + if (effect) + { + RpMTEffectAddRef(multiTexture->effect); + } + return multiTexture; +} + +RpMTEffect* RpMultiTextureGetEffect(const RpMultiTexture* multiTexture) +{ + return multiTexture->effect; +} + +RpMultiTexture* RpMultiTextureSetTexture(RpMultiTexture* multiTexture, RwUInt32 index, + RwTexture* texture) +{ + if (multiTexture->textures[index]) + { + RwTextureDestroy(multiTexture->textures[index]); + } + + multiTexture->textures[index] = texture; + if (texture) + { + RwTextureAddRef(texture); + } + + return multiTexture; +} + +RwTexture* RpMultiTextureGetTexture(const RpMultiTexture* multiTexture, RwUInt32 index) +{ + return multiTexture->textures[index]; +} + +RpMultiTexture* RpMultiTextureSetCoords(RpMultiTexture* multiTexture, RwUInt32 index, + RwUInt32 texCoordIndex) +{ + multiTexture->coordMap[index] = (RwUInt8)texCoordIndex; + return multiTexture; +} + +RwUInt32 RpMultiTextureGetCoords(const RpMultiTexture* multiTexture, RwUInt32 index) +{ + return multiTexture->coordMap[index]; +} + +RpMultiTexture* RpMaterialGetMultiTexture(const RpMaterial* material, RwPlatformID platformID) +{ + rpMultiTextureRegEntry* regEntry; + + regEntry = &RegEntries[platformID]; + if (regEntry->pluginID) + { + const MultiTextureExt* ext; + ext = 0; + return (ext->multiTexture); + } + return (RpMultiTexture*)NULL; +} diff --git a/src/rwsdk/plugin/matfx/multiTex.h b/src/rwsdk/plugin/matfx/multiTex.h new file mode 100644 index 000000000..f5d2dc339 --- /dev/null +++ b/src/rwsdk/plugin/matfx/multiTex.h @@ -0,0 +1,88 @@ +#ifndef RPMATFX_MULTITEX_H +#define RPMATFX_MULTITEX_H + +#include "rwcore.h" +#include "rpworld.h" + +#include + +#define rpMAXMULTITEXTURES 8 + +struct rpMultiTextureRegEntry +{ + RwPlatformID platformID; + RwUInt32 pluginID; + RwUInt32 materialOffset; + RwUInt32 extensionSize; +}; +typedef struct rpMultiTextureRegEntry rpMultiTextureRegEntry; + +struct RpMultiTexture +{ + rpMultiTextureRegEntry* regEntry; + + RwUInt32 numTextures; + RwTexture* textures[rpMAXMULTITEXTURES]; + RwUInt8 coordMap[rpMAXMULTITEXTURES]; + + RpMTEffect* effect; + + void* extension; +}; + +typedef struct RpMultiTexture RpMultiTexture; + +typedef struct _rpMultiTextureGlobals +{ + rpMTEffectGlobals effect; + +} rpMultiTextureGlobals; + +extern RwModuleInfo _rpMultiTextureModule; + +#define RPMULTITEXTUREGLOBAL(var) \ + (RWPLUGINOFFSET(rpMultiTextureGlobals, RwEngineInstance, _rpMultiTextureModule.globalsOffset) \ + ->var) + +#ifdef __cplusplus +extern "C" { +#endif + +extern RwUInt32 RpMultiTextureGetNumTextures(const RpMultiTexture* multiTexture); + +extern RpMultiTexture* RpMultiTextureSetTexture(RpMultiTexture* multiTexture, RwUInt32 index, + RwTexture* texture); + +extern RwTexture* RpMultiTextureGetTexture(const RpMultiTexture* multiTexture, RwUInt32 index); + +extern RpMultiTexture* RpMultiTextureSetCoords(RpMultiTexture* multiTexture, RwUInt32 index, + RwUInt32 texCoordIndex); + +extern RwUInt32 RpMultiTextureGetCoords(const RpMultiTexture* multiTexture, RwUInt32 index); + +extern RpMultiTexture* RpMultiTextureSetEffect(RpMultiTexture* multiTexture, RpMTEffect* effect); + +extern RpMTEffect* RpMultiTextureGetEffect(const RpMultiTexture* multiTexture); + +extern RpMaterial* RpMaterialCreateMultiTexture(RpMaterial* material, RwPlatformID platformID, + RwUInt32 numTextures); + +extern RpMaterial* RpMaterialDestroyMultiTexture(RpMaterial* material, RwPlatformID platformID); + +extern RpMultiTexture* RpMaterialGetMultiTexture(const RpMaterial* material, + RwPlatformID platformID); + +extern RwBool RpMaterialQueryMultiTexturePlatform(RwPlatformID platformID); + +extern RwBool _rpMultiTexturePluginAttach(void); + +extern RwBool _rpMaterialRegisterMultiTexturePlugin(RwPlatformID platformID, RwUInt32 pluginID, + RwUInt32 extensionSize); + +extern RwBool _rpMultiTexturePlatformPluginsAttach(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/rwsdk/plugin/matfx/multiTexEffect.c b/src/rwsdk/plugin/matfx/multiTexEffect.c new file mode 100644 index 000000000..e5a965502 --- /dev/null +++ b/src/rwsdk/plugin/matfx/multiTexEffect.c @@ -0,0 +1,164 @@ +#include "rwplcore.h" +#include "rwcore.h" +#include "rpmatfx.h" +#include + +#define MAXPLATFORMID (rwID_PCD3D9) +#define DEFAULTPATHSIZE 256 +#define rwID_MULTITEXPLUGIN MAKECHUNKID(rwVENDORID_CRITERIONTK, 0x2c) + +typedef union RpPtrMTEffect RpPtrMTEffect; +union RpPtrMTEffect +{ + RpMTEffect* ptrMTEffect; + const RpMTEffect* constptrMTEffect; +}; + +typedef union RpPtrMTEffectDict RpPtrMTEffectDict; +union RpPtrMTEffectDict +{ + RpMTEffectDict* ptrMTEffectDict; + const RpMTEffectDict* constptrMTEffectDict; +}; + +typedef struct EffectRegEntry EffectRegEntry; +struct EffectRegEntry +{ + RwPlatformID platformID; + + rpMTEffectDestroyCallBack destroy; + rpMTEffectStreamReadCallBack streamRead; + rpMTEffectStreamWriteCallBack streamWrite; + rpMTEffectStreamGetSizeCallBack streamGetSize; +}; + +typedef struct BinaryEffectDict BinaryEffectDict; +struct BinaryEffectDict +{ + RwUInt32 numEffects; +}; + +typedef struct BinaryEffect BinaryEffect; +struct BinaryEffect +{ + RwUInt32 platformID; +}; + +typedef struct Iterator Iterator; +struct Iterator +{ + const RwLLLink* cur; + const RwLLLink* end; +}; + +static EffectRegEntry EffectRegEntries[MAXPLATFORMID + 1]; + +static RpMTEffectDict* DummyDict = (RpMTEffectDict*)NULL; + +RwBool _rpMTEffectSystemInit() +{ + memset(EffectRegEntries, 0, sizeof(EffectRegEntries)); + return TRUE; +} + +RwBool _rpMTEffectRegisterPlatform(RwPlatformID platformID, rpMTEffectStreamReadCallBack streamRead, + rpMTEffectStreamWriteCallBack streamWrite, + rpMTEffectStreamGetSizeCallBack streamGetSize, + rpMTEffectDestroyCallBack destroy) +{ + EffectRegEntry* regEntry; + + regEntry = &EffectRegEntries[platformID]; + regEntry->platformID = platformID; + regEntry->streamRead = streamRead; + regEntry->streamWrite = streamWrite; + regEntry->streamGetSize = streamGetSize; + regEntry->destroy = destroy; + + return TRUE; +} + +RwBool _rpMTEffectOpen() +{ +} + +RwBool _rpMTEffectClose() +{ +} + +RpMTEffect* _rpMTEffectInit(RpMTEffect* effect, RwPlatformID platformID) +{ + memset(effect, 0, sizeof(RpMTEffect)); + + effect->platformID = platformID; + effect->refCount = 1; + rwLLLinkInitialize(&effect->dictLink); + + // if (platformID && RPMULTITEXTUREGLOBAL(effect.currentDict)) + // { + // RpMTEffectDictAddEffect(RPMULTITEXTUREGLOBAL(effect.currentDict), effect); + // } + + return (effect); +} + +RpMTEffectDict* RpMTEffectDictCreate(void) +{ + // What? + RpMTEffectDict* dict; + RwUInt32 size; + + size = sizeof(RpMTEffectDict); + dict = (RpMTEffectDict*)RwMalloc(size); + if (!dict) + { + RwErrorSet(NULL); + return ((RpMTEffectDict*)NULL); + } + + rwLinkListInitialize(&dict->effectList); + + return dict; +} + +RpMTEffectDict* RpMTEffectDictAddEffect(RpMTEffectDict* dict, RpMTEffect* effect) +{ + if (effect->dictLink.next) + { + rwLinkListRemoveLLLink(&effect->dictLink); + RpMTEffectDestroy(effect); + } + rwLinkListAddLLLink(&dict->effectList, &effect->dictLink); + RpMTEffectAddRef(effect); + + return dict; +} + +RpMTEffect* RpMTEffectDictRemoveEffect(RpMTEffect* effect) +{ + if (effect->dictLink.next) + { + rwLinkListRemoveLLLink(&effect->dictLink); + RpMTEffectDestroy(effect); + } + + return effect; +} + +RpMTEffect* RpMTEffectCreateDummy(void) +{ +} + +RpMTEffect* RpMTEffectSetName(RpMTEffect* effect, RwChar* name) +{ + rwstrncpy(effect->name, name, rpMTEFFECTNAMELENGTH - 1); + + return effect; +} + +RpMTEffect* RpMTEffectAddRef(RpMTEffect* effect) +{ + effect->refCount++; + + return effect; +} diff --git a/src/rwsdk/plugin/matfx/multiTexEffect.h b/src/rwsdk/plugin/matfx/multiTexEffect.h new file mode 100644 index 000000000..b2a5ba24a --- /dev/null +++ b/src/rwsdk/plugin/matfx/multiTexEffect.h @@ -0,0 +1,125 @@ +#ifndef RPMATFX_MULTITEXEFFECT_H +#define RPMATFX_MULTITEXEFFECT_H + +#include "rwcore.h" +#include "rpworld.h" + +#define rpMTEFFECTNAMELENGTH 32 + +typedef struct RpMTEffect RpMTEffect; + +typedef struct RpMTEffectDict RpMTEffectDict; + +typedef RpMTEffect* (*RpMTEffectCallBack)(RpMTEffect* effect, void* data); + +typedef RpMTEffectDict* (*RpMTEffectDictCallBack)(RpMTEffectDict* dict, void* data); + +struct RpMTEffectDict +{ + RwLinkList effectList; + RwLLLink dictListLink; +}; + +typedef struct rpMTEffectGlobals rpMTEffectGlobals; +struct rpMTEffectGlobals +{ + RwLinkList dictList; + RpMTEffectDict* currentDict; + RwInt32 pathSize; + RwChar* path; + RwChar* scratchMem; +}; + +#if (!defined(DOXYGEN)) + +typedef enum RwPlatformID RwPlatformID; + +struct RpMTEffect +{ + RwPlatformID platformID; + RwUInt32 refCount; + RwChar name[rpMTEFFECTNAMELENGTH]; + RwLLLink dictLink; +}; +#endif + +typedef void (*rpMTEffectDestroyCallBack)(RpMTEffect* effect); +typedef RwInt32 (*rpMTEffectStreamGetSizeCallBack)(const RpMTEffect* effect); +typedef RpMTEffect* (*rpMTEffectStreamReadCallBack)(RwStream* stream, RwPlatformID platformID, + RwUInt32 version, RwUInt32 length); +typedef const RpMTEffect* (*rpMTEffectStreamWriteCallBack)(const RpMTEffect* effect, + RwStream* stream); + +#ifdef __cplusplus +extern "C" { +#endif + +extern RpMTEffectDict* RpMTEffectDictCreate(void); + +extern void RpMTEffectDictDestroy(RpMTEffectDict* dict); + +extern RpMTEffectDict* RpMTEffectDictAddEffect(RpMTEffectDict* dict, RpMTEffect* effect); + +extern RpMTEffect* RpMTEffectDictRemoveEffect(RpMTEffect* effect); + +extern RpMTEffect* RpMTEffectDictFindNamedEffect(const RpMTEffectDict* dict, const RwChar* name); + +extern RpMTEffectDict* RpMTEffectDictSetCurrent(RpMTEffectDict* dict); + +extern RpMTEffectDict* RpMTEffectDictGetCurrent(void); + +extern RwUInt32 RpMTEffectDictStreamGetSize(const RpMTEffectDict* dict); + +extern const RpMTEffectDict* RpMTEffectDictStreamWrite(const RpMTEffectDict* dict, + RwStream* stream); + +extern RpMTEffectDict* RpMTEffectDictStreamRead(RwStream* stream); + +extern RwBool RpMTEffectDictForAllDictionaries(RpMTEffectDictCallBack callBack, void* data); + +extern const RpMTEffectDict* RpMTEffectDictForAllEffects(const RpMTEffectDict* dict, + RpMTEffectCallBack callBack, void* data); + +extern const RwChar* RpMTEffectSetPath(const RwChar* path); + +extern RwChar* RpMTEffectGetPath(void); + +extern RpMTEffect* RpMTEffectCreateDummy(void); + +extern void RpMTEffectDestroy(RpMTEffect* effect); + +extern RwUInt32 RpMTEffectStreamGetSize(const RpMTEffect* effect); + +extern const RpMTEffect* RpMTEffectStreamWrite(const RpMTEffect* effect, RwStream* stream); + +extern RpMTEffect* RpMTEffectStreamRead(RwStream* stream); + +extern RpMTEffect* RpMTEffectFind(RwChar* name); + +extern const RpMTEffect* RpMTEffectWrite(const RpMTEffect* effect); + +extern RpMTEffect* RpMTEffectSetName(RpMTEffect* effect, RwChar* name); + +extern RwChar* RpMTEffectGetName(RpMTEffect* effect); + +extern RpMTEffect* RpMTEffectAddRef(RpMTEffect* effect); + +extern RwBool _rpMTEffectSystemInit(void); + +extern RwBool _rpMTEffectRegisterPlatform(RwPlatformID platformID, + rpMTEffectStreamReadCallBack streamRead, + rpMTEffectStreamWriteCallBack streamWrite, + rpMTEffectStreamGetSizeCallBack streamGetSize, + rpMTEffectDestroyCallBack destroy); + +extern RwBool _rpMTEffectOpen(void); + +extern RwBool _rpMTEffectClose(void); + +extern RpMTEffect* _rpMTEffectInit(RpMTEffect* effect, RwPlatformID platformID); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/rwsdk/plugin/matfx/rpmatfx.c b/src/rwsdk/plugin/matfx/rpmatfx.c new file mode 100644 index 000000000..be261e8ad --- /dev/null +++ b/src/rwsdk/plugin/matfx/rpmatfx.c @@ -0,0 +1,1303 @@ +#include "rwplcore.h" +#include "rwcore.h" +#include "rpmatfx.h" +#include + +#define MATFXBUMPTEXTURENAMEEXTENSION "_B" + +#ifndef _rpMatFXMaterialPlatformInitialize +#define _rpMatFXMaterialPlatformInitialize(material) +#endif +#ifndef _rpMatFXMaterialPlatformEnvMapSetBlend +#define _rpMatFXMaterialPlatformEnvMapSetBlend(material) +#endif +#ifndef _rpMatFXMaterialPlatformDualSetBlend +#define _rpMatFXMaterialPlatformDualSetBlend(material) +#endif + +#define rpMATFXENTRIESPERBLOCK 128 + +#define rpMATFXALIGNMENT rwFRAMEALIGNMENT + +#define RPMATFXALIGNMENT(_x) (!(((rpMATFXALIGNMENT)-1) & ((RwUInt32)(_x)))) + +#define MATFXMATERIALGETDATA(material) \ + ((rpMatFXMaterialData**)(((RwUInt8*)material) + MatFXMaterialDataOffset)) + +#define MATFXMATERIALGETCONSTDATA(material) \ + ((const rpMatFXMaterialData* const*)(((const RwUInt8*)material) + MatFXMaterialDataOffset)) + +#define MATFXATOMICGETDATA(atomic) ((MatFXAtomicData*)(((RwUInt8*)atomic) + MatFXAtomicDataOffset)) + +#define MATFXATOMICGETCONSTDATA(atomic) \ + ((const MatFXAtomicData*)(((const RwUInt8*)atomic) + MatFXAtomicDataOffset)) + +#define MATFXWORLDSECTORGETDATA(worldSector) \ + ((MatFXWorldSectorData*)(((RwUInt8*)worldSector) + MatFXWorldSectorDataOffset)) + +#define MATFXWORLDSECTORGETCONSTDATA(worldSector) \ + ((const MatFXWorldSectorData*)(((const RwUInt8*)worldSector) + MatFXWorldSectorDataOffset)) + +#define MATFXMATERIALGETDATA(material) \ + ((rpMatFXMaterialData**)(((RwUInt8*)material) + MatFXMaterialDataOffset)) + +#define MATFXMATERIALGETCONSTDATA(material) \ + ((const rpMatFXMaterialData* const*)(((const RwUInt8*)material) + MatFXMaterialDataOffset)) + +typedef struct MatFXWorldSectorData MatFXWorldSectorData; +struct MatFXWorldSectorData +{ + RwBool enabled; +}; + +typedef struct MatFXAtomicData MatFXAtomicData; +struct MatFXAtomicData +{ + RwBool enabled; +}; + +#if (defined(RWDEBUG)) +long rpMatFXStackDepth = 0; +#endif /* (defined(RWDEBUG)) */ + +RwInt32 MatFXMaterialDataOffset = 0; + +RwMatFXInfo MatFXInfo = { { 0, 0 }, (RwFreeList*)NULL }; + +static RwInt32 MatFXAtomicDataOffset = 0; +static RwInt32 MatFXWorldSectorDataOffset = 0; + +RwTexture* _rpMatFXTextureMaskCreate(); + +static void* MatFXClose(void* instance, RwInt32 offset, RwInt32 size) +{ + MatFXInfo.Module.numInstances--; + if (MatFXInfo.Module.numInstances == 0) + { + _rpMatFXPipelinesDestroy(); + } + if (MatFXInfo.MaterialData) + { + RwFreeListDestroy(MatFXInfo.MaterialData); + MatFXInfo.MaterialData = (RwFreeList*)NULL; + } + + return instance; +} + +static RwInt32 _rpMatFXMaterialDataFreeListBlockSize = rpMATFXENTRIESPERBLOCK, + _rpMatFXMaterialDataFreeListPreallocBlocks = 1; +static RwFreeList _rpMatFXMaterialDataFreeList; + +static void* MatFXOpen(void* instance, RwInt32 offset, RwInt32 size) +{ + if (MatFXInfo.Module.numInstances == 0) + { + // Instruction below this is kinda fucked. + + // MatFXInfo.MaterialData = RwFreeListCreateAndPreallocateSpace( + // sizeof(rpMatFXMaterialData), _rpMatFXMaterialDataFreeListBlockSize, rpMATFXALIGNMENT, + // _rpMatFXMaterialDataFreeListPreallocBlocks, &_rpMatFXMaterialDataFreeList, + // rwID_MATERIALEFFECTSPLUGIN | rwMEMHINTDUR_GLOBAL); + + if (MatFXInfo.MaterialData == NULL) + { + instance = NULL; + return instance; + } + + if (FALSE == _rpMatFXPipelinesCreate()) + { + instance = NULL; + return instance; + } + } + MatFXInfo.Module.numInstances++; + + return instance; +} +typedef struct rpMatFXMaterialData rpMatFXMaterialData; +static void* MatFXMaterialConstructor(void* object, RwInt32 offset, RwInt32 size) +{ + *MATFXMATERIALGETDATA(object) = (rpMatFXMaterialData*)NULL; + + return object; +} + +enum MatFXPass +{ + rpSECONDPASS = 0, + rpTHIRDPASS = 1, + rpMAXPASS = 2 +}; + +typedef enum MatFXPass MatFXPass; +// typedef struct MatFXUVAnimData RWALIGN(MatFXUVAnimData, rpMATFXALIGNMENT); +// typedef struct MatFXBumpMapData RWALIGN(MatFXBumpMapData, rpMATFXALIGNMENT); +// typedef struct MatFXDualData RWALIGN(MatFXDualData, rpMATFXALIGNMENT); +// typedef union MatFXEffectUnion RWALIGN(MatFXEffectUnion, rpMATFXALIGNMENT); + +typedef struct MatFXBumpMapData MatFXBumpMapData; + +struct MatFXBumpMapData +{ + RwFrame* frame; + RwTexture* texture; + RwTexture* bumpTexture; + RwReal coef; + RwReal invBumpWidth; +}; +typedef struct MatFXDualData MatFXDualData; + +struct MatFXDualData +{ + RwTexture* texture; + RwBlendFunction srcBlendMode; + RwBlendFunction dstBlendMode; + + // device specific +}; +typedef struct MatFXEnvMapData RWALIGN(MatFXEnvMapData, rpMATFXALIGNMENT); +struct MatFXEnvMapData +{ + RwFrame* frame; + RwTexture* texture; + RwReal coef; + RwBool useFrameBufferAlpha; +}; + +typedef struct MatFXUVAnimData MatFXUVAnimData; + +struct MatFXUVAnimData +{ + RwMatrix* baseTransform; + RwMatrix* dualTransform; +}; + +typedef union MatFXEffectUnion MatFXEffectUnion; + +union MatFXEffectUnion +{ + MatFXBumpMapData bumpMap; + MatFXEnvMapData envMap; + MatFXDualData dual; + MatFXUVAnimData uvAnim; + +#if (defined(MULTITEXD3D8_H)) + MatFXD3D8Material d3d8Mat; +#endif +}; + +typedef struct MatFXEffectData RWALIGN(MatFXEffectData, rpMATFXALIGNMENT); +struct MatFXEffectData +{ + MatFXEffectUnion data; + RpMatFXMaterialFlags flag; + +#if (defined(SKY2_DRVMODEL_H)) + MatFXSkyMaterial skyMat; +#endif +}; +struct rpMatFXMaterialData +{ + MatFXEffectData data[rpMAXPASS]; + RpMatFXMaterialFlags flags; +}; + +static void* MatFXMaterialCopy(void* dstObject, const void* srcObject, RwInt32 offset, RwInt32 size) +{ + const RpMaterial* srcMaterial; + const rpMatFXMaterialData* srcMaterialData; + + RpMaterial* dstMaterial; + rpMatFXMaterialData* dstMaterialData; + + RpMaterial* ret; + + RwUInt8 pass; + + srcMaterial = (const RpMaterial*)srcObject; + dstMaterial = (RpMaterial*)dstObject; + + srcMaterialData = (const rpMatFXMaterialData*)*MATFXMATERIALGETCONSTDATA(srcMaterial); + + if ((rpMatFXMaterialData*)NULL == srcMaterialData) + { + return NULL; + } + + dstMaterialData = (rpMatFXMaterialData*)MatFXMaterialGetData(dstMaterial); + + if (NULL == dstMaterialData) + { + return NULL; + } + ret = RpMatFXMaterialSetEffects(dstMaterial, srcMaterialData->flags); + for (pass = 0; pass < rpMAXPASS; pass++) + { + RpMatFXMaterialFlags effect; + effect = srcMaterialData->data[pass].flag; + + switch (effect) + { + case rpMATFXEFFECTNULL: + { + break; + } + case rpMATFXEFFECTBUMPMAP: + { + const MatFXBumpMapData* srcBumpMapData; + MatFXBumpMapData* dstBumpMapData; + + RwFrame* frame; + RwReal coef; + + srcBumpMapData = &(srcMaterialData->data[pass].data.bumpMap); + dstBumpMapData = &(dstMaterialData->data[pass].data.bumpMap); + + frame = RpMatFXMaterialGetBumpMapFrame(srcMaterial); + coef = RpMatFXMaterialGetBumpMapCoefficient(srcMaterial); + ret = RpMatFXMaterialSetBumpMapFrame(dstMaterial, frame); + ret = RpMatFXMaterialSetBumpMapCoefficient(dstMaterial, coef); + + dstBumpMapData->texture = srcBumpMapData->texture; + dstBumpMapData->bumpTexture = srcBumpMapData->bumpTexture; + + if (NULL != dstBumpMapData->texture) + { + (void)RwTextureAddRef(dstBumpMapData->texture); + } + + if (NULL != dstBumpMapData->bumpTexture) + { + (void)RwTextureAddRef(dstBumpMapData->bumpTexture); + } + + break; + } + case rpMATFXEFFECTENVMAP: + { + RwTexture* texture; + RwFrame* frame; + RwReal coef; + RwBool useFrameBufferAlpha; + + texture = RpMatFXMaterialGetEnvMapTexture(srcMaterial); + frame = RpMatFXMaterialGetEnvMapFrame(srcMaterial); + coef = RpMatFXMaterialGetEnvMapCoefficient(srcMaterial); + useFrameBufferAlpha = RpMatFXMaterialGetEnvMapFrameBufferAlpha(srcMaterial); + + if (NULL != texture) + { + ret = RpMatFXMaterialSetEnvMapTexture(dstMaterial, texture); + } + ret = RpMatFXMaterialSetEnvMapFrame(dstMaterial, frame); + ret = RpMatFXMaterialSetEnvMapFrameBufferAlpha(dstMaterial, useFrameBufferAlpha); + ret = RpMatFXMaterialSetEnvMapCoefficient(dstMaterial, coef); + + break; + } + case rpMATFXEFFECTDUAL: + { + RwTexture* texture; + RwBlendFunction srcBlendMode; + RwBlendFunction dstBlendMode; + + texture = RpMatFXMaterialGetDualTexture(srcMaterial); + RpMatFXMaterialGetDualBlendModes(srcMaterial, &srcBlendMode, &dstBlendMode); + + if (NULL != texture) + { + ret = RpMatFXMaterialSetDualTexture(dstMaterial, texture); + } + ret = RpMatFXMaterialSetDualBlendModes(dstMaterial, srcBlendMode, dstBlendMode); + + break; + } + case rpMATFXEFFECTUVTRANSFORM: + { + RwMatrix* baseTransform; + RwMatrix* dualTransform; + + srcMaterial = + RpMatFXMaterialGetUVTransformMatrices(srcMaterial, &baseTransform, &dualTransform); + + dstMaterial = + RpMatFXMaterialSetUVTransformMatrices(dstMaterial, baseTransform, dualTransform); + + break; + } + default: + { + /* We shouldn't get here. */ + + break; + } + } + } + + return dstObject; +} + +RwStream* _rpMatFXStreamWriteTexture(RwStream* stream, const RwTexture* texture) +{ + RwBool present; + + present = (NULL != texture); + + if (!RwStreamWriteInt32(stream, (RwInt32*)&present, sizeof(RwBool))) + { + return ((RwStream*)NULL); + } + if (present) + { + if (!RwTextureStreamWrite(texture, stream)) + { + return ((RwStream*)NULL); + } + } + + return stream; +} + +RwUInt32 _rpMatFXStreamSizeTexture(const RwTexture* texture) +{ + RwUInt32 size; + + size = sizeof(RwBool); + + if (texture) + { + size += RwTextureStreamGetSize(texture); + } + + return (size); +} + +static RwStream* MatFXMaterialStreamWrite(RwStream* stream, RwInt32 binaryLength, + const void* object, RwInt32 offsetInObject, + RwInt32 sizeInObject) +{ + const RpMaterial* material = (const RpMaterial*)object; + const rpMatFXMaterialData* materialData; + RwUInt8 pass; + RwInt32 temp; + + materialData = (const rpMatFXMaterialData*)*MATFXMATERIALGETCONSTDATA(material); + + temp = materialData->flags; + if (!RwStreamWriteInt32(stream, &temp, sizeof(RwInt32))) + { + return NULL; + } + + for (pass = 0; pass < rpMAXPASS; pass++) + { + RpMatFXMaterialFlags effect; + + effect = materialData->data[pass].flag; + if (!RwStreamWriteInt32(stream, (RwInt32*)&effect, sizeof(RwInt32))) + { + return NULL; + } + + switch (effect) + { + case rpMATFXEFFECTNULL: + case rpMATFXEFFECTUVTRANSFORM: + { + break; + } + case rpMATFXEFFECTBUMPMAP: + { + const MatFXBumpMapData* bumpData; + RwReal coef; + + bumpData = &(materialData->data[pass].data.bumpMap); + coef = -bumpData->coef; + + if (!RwStreamWriteReal(stream, &coef, sizeof(RwReal))) + { + return NULL; + } + if (!_rpMatFXStreamWriteTexture(stream, bumpData->texture)) + { + return NULL; + } + if (!_rpMatFXStreamWriteTexture(stream, bumpData->bumpTexture)) + { + return NULL; + } + + break; + } + case rpMATFXEFFECTENVMAP: + { + const MatFXEnvMapData* envData; + envData = &(materialData->data[pass].data.envMap); + if (!RwStreamWriteReal(stream, &(envData->coef), sizeof(RwReal))) + { + return NULL; + } + temp = envData->useFrameBufferAlpha; + if (!RwStreamWriteInt32(stream, &temp, sizeof(RwInt32))) + { + return NULL; + } + if (!_rpMatFXStreamWriteTexture(stream, envData->texture)) + { + return NULL; + } + + break; + } + case rpMATFXEFFECTDUAL: + { + const MatFXDualData* dualData; + dualData = &(materialData->data[pass].data.dual); + + temp = dualData->srcBlendMode; + if (!RwStreamWriteInt32(stream, &temp, sizeof(RwInt32))) + { + return NULL; + } + + temp = dualData->dstBlendMode; + if (!RwStreamWriteInt32(stream, &temp, sizeof(RwInt32))) + { + return NULL; + } + + if (!_rpMatFXStreamWriteTexture(stream, dualData->texture)) + { + return NULL; + } + + break; + } + default: + { + break; + } + } + } + return stream; +} + +static RwStream* MatFXMaterialStreamRead(RwStream* stream, RwInt32 binaryLength, void* object, + RwInt32 offsetInObject, RwInt32 sizeInObject) +{ + RpMaterial* material; + rpMatFXMaterialData* materialData; + RpMatFXMaterialFlags flags; + RwUInt8 pass; + + material = (RpMaterial*)object; + materialData = (rpMatFXMaterialData*)MatFXMaterialGetData(material); + if (NULL == materialData) + { + return NULL; + } + + if (!RwStreamReadInt32(stream, (RwInt32*)&flags, sizeof(RwInt32))) + { + return NULL; + } + + RpMatFXMaterialSetEffects(material, flags); + + for (pass = 0; pass < rpMAXPASS; pass++) + { + RpMatFXMaterialFlags effect; + + if (!RwStreamReadInt32(stream, (RwInt32*)&effect, sizeof(RwInt32))) + { + return NULL; + } + switch (effect) + { + case rpMATFXEFFECTNULL: + case rpMATFXEFFECTUVTRANSFORM: + { + break; + } + case rpMATFXEFFECTBUMPMAP: + { + RwReal coef; + RwTexture* texture = NULL; + RwTexture* bumpTexture = NULL; + MatFXBumpMapData* bumpMapData; + + bumpMapData = &(materialData->data[pass].data.bumpMap); + if (!RwStreamReadReal(stream, &coef, sizeof(RwReal))) + { + return NULL; + } + if (!_rpMatFXStreamReadTexture(stream, &texture)) + { + return NULL; + } + if (!_rpMatFXStreamReadTexture(stream, &bumpTexture)) + { + if (texture) + { + RwTextureDestroy(texture); + } + + return NULL; + } + if (texture != NULL) + { + RwRaster* raster; + RwInt32 nWidth; + RwReal width; + + bumpMapData->texture = texture; + bumpMapData->bumpTexture = bumpTexture; + raster = RwTextureGetRaster(bumpMapData->texture); + nWidth = RwRasterGetWidth(raster); + width = (RwReal)nWidth; + bumpMapData->invBumpWidth = 1.0f / width; + } + else if (bumpTexture != NULL) + { + RpMatFXMaterialSetBumpMapTexture(material, bumpTexture); + RwTextureDestroy(bumpTexture); + } + else + { + bumpMapData->texture = (RwTexture*)NULL; + bumpMapData->bumpTexture = (RwTexture*)NULL; + } + + RpMatFXMaterialSetBumpMapCoefficient(material, coef); + + break; + } + case rpMATFXEFFECTENVMAP: + { + RwReal coef; + RwBool useFrameBufferAlpha; + RwTexture* texture = 0; + + if (!RwStreamReadReal(stream, &coef, sizeof(RwReal))) + { + return NULL; + } + if (!RwStreamReadInt32(stream, (RwInt32*)&useFrameBufferAlpha, sizeof(RwInt32))) + { + return NULL; + } + if (!_rpMatFXStreamReadTexture(stream, &texture)) + { + return NULL; + } + if (texture != NULL) + { + RpMatFXMaterialSetEnvMapTexture(material, texture); + RwTextureDestroy(texture); + } + + RpMatFXMaterialSetEnvMapCoefficient(material, coef); + RpMatFXMaterialSetEnvMapFrameBufferAlpha(material, useFrameBufferAlpha); + + break; + } + case rpMATFXEFFECTDUAL: + { + RwBlendFunction blendFuncs[2]; + RwTexture* texture = 0; + + if (!RwStreamReadInt32(stream, (RwInt32*)blendFuncs, sizeof(blendFuncs))) + { + return NULL; + } + if (!_rpMatFXStreamReadTexture(stream, &texture)) + { + return NULL; + } + if (texture != NULL) + { + RpMatFXMaterialSetDualTexture(material, texture); + RwTextureDestroy(texture); + } + + RpMatFXMaterialSetDualBlendModes(material, blendFuncs[0], blendFuncs[1]); + + break; + } + default: + { + break; + } + } + } + return stream; +} + +static RwInt32 MatFXMaterialStreamGetSize(const void* object, RwInt32 offsetInObject, + RwInt32 sizeInObject) +{ + const RpMaterial* material; + const rpMatFXMaterialData* materialData; + + RwInt32 size; + RwUInt8 pass; + + material = (const RpMaterial*)object; + materialData = (const rpMatFXMaterialData*)*MATFXMATERIALGETCONSTDATA(material); + + if (NULL == materialData || rpMATFXEFFECTNULL == materialData->flags) + { + return FALSE; + } + + size = sizeof(RpMatFXMaterialFlags); + + for (pass = 0; pass < rpMAXPASS; pass++) + { + RpMatFXMaterialFlags effect; + + effect = materialData->data[pass].flag; + size += sizeof(RpMatFXMaterialFlags); + switch (effect) + { + case rpMATFXEFFECTNULL: + case rpMATFXEFFECTUVTRANSFORM: + { + break; + } + case rpMATFXEFFECTBUMPMAP: + { + size += sizeof(RwReal); + size += _rpMatFXStreamSizeTexture(materialData->data[pass].data.bumpMap.texture); + size += _rpMatFXStreamSizeTexture(materialData->data[pass].data.bumpMap.bumpTexture); + break; + } + case rpMATFXEFFECTENVMAP: + { + size += sizeof(RwReal); + size += sizeof(RwBool); + size += _rpMatFXStreamSizeTexture(materialData->data[pass].data.envMap.texture); + break; + } + case rpMATFXEFFECTDUAL: + { + size += 2 * sizeof(RwBlendFunction); + size += _rpMatFXStreamSizeTexture(materialData->data[pass].data.dual.texture); + + break; + } + default: + { + break; + } + } + } + + return size; +} + +static void* MatFXAtomicConstructor(void* object, RwInt32 offset, RwInt32 size) +{ + MatFXAtomicData* atomicData; + + atomicData = (MatFXAtomicData*)MATFXATOMICGETDATA((RpAtomic*)object); + atomicData->enabled = FALSE; + + return object; +} + +static void* MatFXAtomicDestructor(void* object, RwInt32 offset, RwInt32 size) +{ + MatFXAtomicData* atomicData; + + atomicData = (MatFXAtomicData*)MATFXATOMICGETDATA((RpAtomic*)object); + atomicData->enabled = FALSE; + + return object; +} + +static void* MatFXAtomicCopy(void* dstObject, const void* srcObject, RwInt32 offset, RwInt32 size) +{ + const RpAtomic* srcAtomic; + const MatFXAtomicData* srcAtomicData; + + RpAtomic* dstAtomic; + MatFXAtomicData* dstAtomicData; + + srcAtomic = (const RpAtomic*)srcObject; + dstAtomic = (RpAtomic*)dstObject; + + srcAtomicData = (const MatFXAtomicData*)MATFXATOMICGETCONSTDATA(srcAtomic); + dstAtomicData = (MatFXAtomicData*)MATFXATOMICGETDATA(dstAtomic); + + if (srcAtomicData->enabled) + { + dstAtomicData->enabled = TRUE; + } + + return dstObject; +} + +static RwStream* MatFXAtomicStreamWrite(RwStream* stream, RwInt32 binaryLength, const void* object, + RwInt32 offsetInObject, RwInt32 sizeInObject) +{ + const MatFXAtomicData* atomicData = MATFXATOMICGETCONSTDATA(object); + RwStream* streamOut; + RwInt32 temp; + + temp = atomicData->enabled; + streamOut = RwStreamWriteInt32(stream, &temp, sizeof(RwInt32)); + + return streamOut; +} + +static RwStream* MatFXAtomicStreamRead(RwStream* stream, RwInt32 binaryLength, void* object, + RwInt32 offsetInObject, RwInt32 sizeInObject) +{ + RpAtomic* atomic = (RpAtomic*)object; + RwBool enabled; + + if (!RwStreamReadInt32(stream, (RwInt32*)&enabled, sizeof(RwInt32))) + { + return NULL; + } + if (enabled) + { + RpMatFXAtomicEnableEffects(atomic); + } + + return stream; +} + +static RwInt32 MatFXAtomicStreamGetSize(const void* object, RwInt32 offsetInObject, + RwInt32 sizeInObject) +{ + const MatFXAtomicData* atomicData = MATFXATOMICGETCONSTDATA(object); + + if (FALSE == atomicData->enabled) + { + return FALSE; + } + + return (sizeof(RwBool)); +} + +static void* MatFXWorldSectorConstructor(void* object, RwInt32 offset, RwInt32 size) +{ + MatFXWorldSectorData* worldSectorData; + + worldSectorData = (MatFXWorldSectorData*)MATFXWORLDSECTORGETDATA((RpWorldSector*)object); + worldSectorData->enabled = FALSE; + + return object; +} + +static void* MatFXWorldSectorDestructor(void* object, RwInt32 offset, RwInt32 size) +{ + MatFXWorldSectorData* worldSectorData; + + worldSectorData = (MatFXWorldSectorData*)MATFXWORLDSECTORGETDATA((RpWorldSector*)object); + worldSectorData->enabled = FALSE; + + return object; +} + +static void* MatFXWorldSectorCopy(void* dstObject, const void* srcObject, RwInt32 offset, + RwInt32 size) +{ + const RpWorldSector* srcWorldSector; + const MatFXWorldSectorData* srcWorldSectorData; + + RpWorldSector* dstWorldSector; + MatFXWorldSectorData* dstWorldSectorData; + + srcWorldSector = (const RpWorldSector*)srcObject; + dstWorldSector = (RpWorldSector*)dstObject; + + srcWorldSectorData = (const MatFXWorldSectorData*)MATFXWORLDSECTORGETCONSTDATA(srcWorldSector); + dstWorldSectorData = (MatFXWorldSectorData*)MATFXWORLDSECTORGETDATA(dstWorldSector); + + if (srcWorldSectorData->enabled) + { + dstWorldSectorData->enabled = TRUE; + } + + return dstObject; +} + +static RwStream* MatFXWorldSectorStreamWrite(RwStream* stream, RwInt32 binaryLength, + const void* object, RwInt32 offsetInObject, + RwInt32 sizeInObject) +{ + RwStream* streamOut; + RwInt32 temp; + const MatFXWorldSectorData* sectorData = MATFXWORLDSECTORGETCONSTDATA(object); + + temp = sectorData->enabled; + streamOut = RwStreamWriteInt32(stream, &temp, sizeof(RwInt32)); + + return streamOut; +} + +static RwStream* MatFXWorldSectorStreamRead(RwStream* stream, RwInt32 binaryLength, void* object, + RwInt32 offsetInObject, RwInt32 sizeInObject) +{ + RpWorldSector* worldSector = (RpWorldSector*)object; + RwBool enabled; + + if (!RwStreamReadInt32(stream, (RwInt32*)&enabled, sizeof(RwInt32))) + { + return NULL; + } + + if (enabled) + { + RpMatFXWorldSectorEnableEffects(worldSector); + } + + return stream; +} + +static RwInt32 MatFXWorldSectorStreamGetSize(const void* object, RwInt32 offsetInObject, + RwInt32 sizeInObject) +{ + const MatFXWorldSectorData* sectorData = MATFXWORLDSECTORGETCONSTDATA(object); + + if (FALSE == sectorData->enabled) + { + return FALSE; + } + + return (sizeof(RwBool)); +} + +RwTexture* _rpMatFXTextureMaskCreate(const RwTexture* baseTexture, const RwTexture* maskTexture) +{ + RwRaster* baseRaster = (RwRaster*)NULL; + RwRaster* maskRaster; + RwRaster* newRaster; + + RwInt32 maskX, maskY; + RwInt32 baseX, baseY; + + RwImage* maskImage; + RwImage* baseImage; + + RwTexture* result; + + RwTextureFilterMode filterMode; + RwTextureAddressMode addrsMode; + + maskRaster = RwTextureGetRaster(maskTexture); + maskX = RwRasterGetWidth(maskRaster); + maskY = RwRasterGetHeight(maskRaster); + maskImage = RwImageCreate(maskX, maskY, 32); + + RwImageAllocatePixels(maskImage); + RwImageSetFromRaster(maskImage, maskRaster); + + if (baseTexture) + { + baseRaster = RwTextureGetRaster(baseTexture); + baseX = RwRasterGetWidth(baseRaster); + baseY = RwRasterGetHeight(baseRaster); + baseImage = RwImageCreate(baseX, baseY, 32); + + RwImageAllocatePixels(baseImage); + RwImageSetFromRaster(baseImage, baseRaster); + } + else + { + RwInt32 x, y; + + baseX = RwRasterGetWidth(maskRaster); + baseY = RwRasterGetHeight(maskRaster); + baseImage = RwImageCreate(baseX, baseY, 32); + RwImageAllocatePixels(baseImage); + + for (y = 0; y < baseY; y++) + { + for (x = 0; x < baseX; x++) + { + *(RwUInt32*)(RwImageGetPixels(baseImage) + RwImageGetStride(baseImage) * y + + x * 4) = 0xFfFfFfFf; + } + } + } + + if ((baseX != maskX) || (baseY != maskY)) + { + RwImage* resampleImage; + + resampleImage = RwImageCreate(baseX, baseY, 32); + + RwImageAllocatePixels(resampleImage); + RwImageResample(resampleImage, maskImage); + RwImageDestroy(maskImage); + + maskImage = resampleImage; + } + + RwImageMakeMask(maskImage); + RwImageApplyMask(baseImage, maskImage); + + { + RwInt32 rasterWidth, rasterHeight; + RwInt32 rasterDepth, rasterFlags, rasterBaseFlags; + + RwImageFindRasterFormat(baseImage, rwRASTERTYPETEXTURE, &rasterWidth, &rasterHeight, + &rasterDepth, &rasterFlags); + + if (baseTexture) + { + rasterBaseFlags = RwRasterGetFormat(baseRaster); + } + else + { + rasterBaseFlags = RwRasterGetFormat(maskRaster); + } + + if (rasterBaseFlags & rwRASTERFORMATMIPMAP) + { + rasterFlags |= (rwRASTERFORMATAUTOMIPMAP | rwRASTERFORMATMIPMAP); + } + + newRaster = RwRasterCreate(rasterWidth, rasterHeight, rasterDepth, rasterFlags); + RwRasterSetFromImage(newRaster, baseImage); + } + + result = RwTextureCreate(newRaster); + + if (baseTexture) + { + filterMode = RwTextureGetFilterMode(baseTexture); + addrsMode = RwTextureGetAddressing(baseTexture); + } + else + { + filterMode = RwTextureGetFilterMode(maskTexture); + addrsMode = RwTextureGetAddressing(maskTexture); + } + + RwTextureSetAddressing(result, addrsMode); + RwTextureSetFilterMode(result, filterMode); + + RwImageDestroy(baseImage); + RwImageDestroy(maskImage); + + { + RwChar newName[rwTEXTUREBASENAMELENGTH] = { 0 }; + + GenBumpedTextureName(newName, baseTexture, maskTexture); + RwTextureSetName(result, newName); + } + + return result; +} + +RpAtomic* RpMatFXAtomicEnableEffects(RpAtomic* atomic) +{ + MatFXAtomicData* atomicData; + + atomicData = (MatFXAtomicData*)MATFXATOMICGETDATA(atomic); + + if (atomicData->enabled == FALSE) + { + if (NULL == _rpMatFXPipelineAtomicSetup(atomic)) + { + return NULL; + } + + atomicData->enabled = TRUE; + } + + return atomic; +} + +RpWorldSector* RpMatFXWorldSectorEnableEffects(RpWorldSector* worldSector) +{ + MatFXWorldSectorData* worldSectorData; + + worldSectorData = (MatFXWorldSectorData*)MATFXWORLDSECTORGETDATA(worldSector); + + if (worldSectorData->enabled == FALSE) + { + if (NULL == _rpMatFXPipelineWorldSectorSetup(worldSector)) + { + return NULL; + } + + worldSectorData->enabled = TRUE; + } + + return worldSector; +} + +RpMaterial* RpMatFXMaterialSetEffects(RpMaterial* material, RpMatFXMaterialFlags flags) +{ + rpMatFXMaterialData* materialData; + + materialData = (rpMatFXMaterialData*)MatFXMaterialGetData(material); + if (NULL == materialData) + { + return NULL; + } + + if ((flags == rpMATFXEFFECTNULL) || + ((materialData->flags != rpMATFXEFFECTNULL) && (materialData->flags != flags))) + { + MatFXMaterialDataClean(materialData); + } + + materialData->flags = flags; + + switch (materialData->flags) + { + case rpMATFXEFFECTBUMPMAP: + { + materialData->data[rpSECONDPASS].flag = rpMATFXEFFECTBUMPMAP; + + break; + } + case rpMATFXEFFECTENVMAP: + { + materialData->data[rpSECONDPASS].flag = rpMATFXEFFECTENVMAP; + + break; + } + case rpMATFXEFFECTBUMPENVMAP: + { + materialData->data[rpSECONDPASS].flag = rpMATFXEFFECTBUMPMAP; + materialData->data[rpTHIRDPASS].flag = rpMATFXEFFECTENVMAP; + + break; + } + case rpMATFXEFFECTDUAL: + { + materialData->data[rpSECONDPASS].flag = rpMATFXEFFECTDUAL; + + RpMatFXMaterialSetDualBlendModes(material, rwBLENDSRCALPHA, rwBLENDINVSRCALPHA); + + break; + } + case rpMATFXEFFECTUVTRANSFORM: + { + materialData->data[rpSECONDPASS].flag = rpMATFXEFFECTUVTRANSFORM; + + break; + } + case rpMATFXEFFECTDUALUVTRANSFORM: + { + materialData->data[rpSECONDPASS].flag = rpMATFXEFFECTUVTRANSFORM; + materialData->data[rpTHIRDPASS].flag = rpMATFXEFFECTDUAL; + + RpMatFXMaterialSetDualBlendModes(material, rwBLENDSRCALPHA, rwBLENDINVSRCALPHA); + + break; + } + case rpMATFXEFFECTNULL: + { + break; + } + default: + { + break; + } + } + + _rpMatFXMaterialPlatformInitialize(material); + + return material; +} + +RpMaterial* RpMatFXMaterialSetupBumpMap(RpMaterial* material, RwTexture* texture, RwFrame* frame, + RwReal coef) +{ + if (NULL == RpMatFXMaterialSetBumpMapTexture(material, texture)) + { + return NULL; + } + + if (NULL == RpMatFXMaterialSetBumpMapFrame(material, frame)) + { + return NULL; + } + + if (NULL == RpMatFXMaterialSetBumpMapCoefficient(material, coef)) + { + return NULL; + } + + return material; +} + +RpMaterial* RpMatFXMaterialSetupEnvMap(RpMaterial* material, RwTexture* texture, RwFrame* frame, + RwBool useFrameBufferAlpha, RwReal coef) +{ + if (NULL == RpMatFXMaterialSetEnvMapTexture(material, texture)) + { + return NULL; + } + + if (NULL == RpMatFXMaterialSetEnvMapFrame(material, frame)) + { + return NULL; + } + + if (NULL == RpMatFXMaterialSetEnvMapFrameBufferAlpha(material, useFrameBufferAlpha)) + { + return NULL; + } + + if (NULL == RpMatFXMaterialSetEnvMapCoefficient(material, coef)) + { + return NULL; + } + + return material; +} + +RpMatFXMaterialFlags RpMatFXMaterialGetEffects(const RpMaterial* material) +{ + const rpMatFXMaterialData* materialData; + + materialData = (const rpMatFXMaterialData*)*MATFXMATERIALGETCONSTDATA(material); + + if (NULL == materialData) + { + return (rpMATFXEFFECTNULL); + } + + return (materialData->flags); +} + +RpMaterial* RpMatFXMaterialSetBumpMapTexture(RpMaterial* material, RwTexture* bumpTexture) +{ + MatFXBumpMapData* bumpMapData; + + bumpMapData = (MatFXBumpMapData*)MATFXBUMPMAPGETDATA(material); + + if (NULL != bumpMapData->bumpTexture) + { + RwTextureDestroy(bumpMapData->bumpTexture); + bumpMapData->bumpTexture = (RwTexture*)NULL; + } + + if (NULL != bumpMapData->texture) + { + RwTextureDestroy(bumpMapData->texture); + + bumpMapData->texture = (RwTexture*)NULL; + bumpMapData->invBumpWidth = 0; + } + + if (bumpTexture) + { + RwBool dummyTextures; + RwRaster* bumpRaster; + RwTexture* baseTexture; + + bumpMapData->bumpTexture = bumpTexture; + (void)RwTextureAddRef(bumpMapData->bumpTexture); + bumpRaster = RwTextureGetRaster(bumpTexture); + dummyTextures = (0 == RwRasterGetWidth(bumpRaster)); + + baseTexture = RpMaterialGetTexture(material); + if (!dummyTextures && baseTexture) + { + RwRaster* baseRaster; + baseRaster = RwTextureGetRaster(baseTexture); + dummyTextures = (0 == RwRasterGetWidth(baseRaster)); + } + + if (!dummyTextures) + { + RwChar bumpedName[rwTEXTUREBASENAMELENGTH] = { 0 }; + RwTexDictionary* dict; + RwRaster* bumpedRaster; + + GenBumpedTextureName(bumpedName, baseTexture, bumpTexture); + + dict = RwTexDictionaryGetCurrent(); + bumpMapData->texture = (RwTexture*)NULL; + if (dict) + { + bumpMapData->texture = RwTexDictionaryFindNamedTexture(dict, bumpedName); + } + + if (!bumpMapData->texture) + { + bumpMapData->texture = + (RwTexture*)_rpMatFXSetupBumpMapTexture(baseTexture, bumpTexture); + if (!bumpMapData->texture) + { + return NULL; + } + + if (dict) + { + RwTexDictionaryAddTexture(dict, bumpMapData->texture); + } + } + else + { + (void)RwTextureAddRef(bumpMapData->texture); + } + + bumpedRaster = RwTextureGetRaster(bumpMapData->texture); + bumpMapData->invBumpWidth = 1.0f / ((RwReal)RwRasterGetWidth(bumpedRaster)); + } + } + else + { + RwTexture* baseTexture; + RwRaster* raster; + + baseTexture = RpMaterialGetTexture(material); + raster = RwTextureGetRaster(baseTexture); + + bumpMapData->invBumpWidth = 1.0f / ((RwReal)RwRasterGetWidth(raster)); + } + + return material; +} + +RpMaterial* RpMatFXMaterialSetBumpMapFrame(RpMaterial* material, RwFrame* frame) +{ +} + +RpMaterial* RpMatFXMaterialSetBumpMapCoefficient(RpMaterial* material, RwReal coef) +{ +} + +RwFrame* RpMatFXMaterialGetBumpMapFrame(const RpMaterial* material) +{ +} + +RwReal RpMatFXMaterialGetBumpMapCoefficient(const RpMaterial* material) +{ +} + +RpMaterial* RpMatFXMaterialSetEnvMapTexture(RpMaterial* material, RwTexture* texture) +{ + MatFXEnvMapData* envMapData; + + envMapData = (MatFXEnvMapData*)MATFXENVMAPGETDATA(material); + RwTextureAddRef(texture); + + if (NULL != envMapData->texture) + { + RwTextureDestroy(envMapData->texture); + envMapData->texture = (RwTexture*)NULL; + } + + envMapData->texture = texture; + + return material; +} + +RpMaterial* RpMatFXMaterialSetEnvMapFrame(RpMaterial* material, RwFrame* frame) +{ +} diff --git a/src/rwsdk/plugin/ptank/gcn/ptankgcn.c b/src/rwsdk/plugin/ptank/gcn/ptankgcn.c new file mode 100644 index 000000000..e29e6c088 --- /dev/null +++ b/src/rwsdk/plugin/ptank/gcn/ptankgcn.c @@ -0,0 +1,13 @@ +#include "rwplcore.h" +#include "rwcore.h" + +s32 _rxPTankGameCubeRenderPipeline; + +void PTankClose() +{ + if (_rxPTankGameCubeRenderPipeline != 0) + { + _rxPipelineDestroy((RxPipeline*)_rxPTankGameCubeRenderPipeline); + _rxPTankGameCubeRenderPipeline = 0; + } +} diff --git a/src/rwsdk/plugin/ptank/gcn/ptankgcn_cc_cs_nr.c b/src/rwsdk/plugin/ptank/gcn/ptankgcn_cc_cs_nr.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/plugin/ptank/gcn/ptankgcn_cc_cs_ppr.c b/src/rwsdk/plugin/ptank/gcn/ptankgcn_cc_cs_ppr.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/plugin/ptank/gcn/ptankgcn_cc_ppm.c b/src/rwsdk/plugin/ptank/gcn/ptankgcn_cc_ppm.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/plugin/ptank/gcn/ptankgcn_cc_pps_nr.c b/src/rwsdk/plugin/ptank/gcn/ptankgcn_cc_pps_nr.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/plugin/ptank/gcn/ptankgcn_cc_pps_ppr.c b/src/rwsdk/plugin/ptank/gcn/ptankgcn_cc_pps_ppr.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/plugin/ptank/gcn/ptankgcn_nc_cs_nr.c b/src/rwsdk/plugin/ptank/gcn/ptankgcn_nc_cs_nr.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/plugin/ptank/gcn/ptankgcn_nc_cs_ppr.c b/src/rwsdk/plugin/ptank/gcn/ptankgcn_nc_cs_ppr.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/plugin/ptank/gcn/ptankgcn_nc_ppm.c b/src/rwsdk/plugin/ptank/gcn/ptankgcn_nc_ppm.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/plugin/ptank/gcn/ptankgcn_nc_pps_nr.c b/src/rwsdk/plugin/ptank/gcn/ptankgcn_nc_pps_nr.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/plugin/ptank/gcn/ptankgcn_nc_pps_ppr.c b/src/rwsdk/plugin/ptank/gcn/ptankgcn_nc_pps_ppr.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/plugin/ptank/gcn/ptankgcncallbacks.c b/src/rwsdk/plugin/ptank/gcn/ptankgcncallbacks.c new file mode 100644 index 000000000..d7864bd6f --- /dev/null +++ b/src/rwsdk/plugin/ptank/gcn/ptankgcncallbacks.c @@ -0,0 +1,7 @@ +#include "rwplcore.h" +#include "rwcore.h" + +s32 _rpPTankGameCubeInstanceCallBack() +{ + return 1; +} diff --git a/src/rwsdk/plugin/ptank/gcn/ptankgcnrender.c b/src/rwsdk/plugin/ptank/gcn/ptankgcnrender.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/plugin/ptank/gcn/ptankgcntransforms.c b/src/rwsdk/plugin/ptank/gcn/ptankgcntransforms.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/plugin/ptank/rpptank.c b/src/rwsdk/plugin/ptank/rpptank.c new file mode 100644 index 000000000..1a377cd63 --- /dev/null +++ b/src/rwsdk/plugin/ptank/rpptank.c @@ -0,0 +1,37 @@ +#include "rwcore.h" +#include "rtanim.h" +#include "rtquat.h" + +RwInt32 _rpPTankAtomicDataOffset = 0; /* Offset in RpAtomic */ +RwInt32 _rpPTankGlobalsOffset = 0; /* Offset in Rwengine */ + +typedef struct RwTexCoords RxTexCoords; + +const RwInt32 datasize[] = { + sizeof(RwV3d), /*rpPTANKDFLAGPOSITION*/ + sizeof(RwMatrix), /*rpPTANKDFLAGMATRIX*/ + sizeof(RwV3d), /*rpPTANKDFLAGNORMAL*/ + sizeof(RwV2d), /*rpPTANKDFLAGSIZE*/ + sizeof(RwRGBA), /*rpPTANKDFLAGCOLOR*/ + 4 * sizeof(RwRGBA), /*rpPTANKDFLAGVTXCOLOR*/ + sizeof(RwReal), /*rpPTANKDFLAG2DROTATE*/ + 2 * sizeof(RwTexCoords), /*rpPTANKDFLAGVTX2TEXCOORDS*/ + 4 * sizeof(RwTexCoords) /*rpPTANKDFLAGVTX4TEXCOORDS*/ +}; + +#if (defined(GCN_DRVMODEL_H)) + +#define FAVORITEORGANISATIONMODE (rpPTANKDFLAGSTRUCTURE) + +#elif (defined(D3D8_DRVMODEL_H) || defined(D3D9_DRVMODEL_H) || defined(XBOX_DRVMODEL_H) || \ + defined(NULL_DRVMODEL_H) || defined(NULLGCN_DRVMODEL_H) || defined(NULLSKY_DRVMODEL_H) || \ + defined(SKY2_DRVMODEL_H) || defined(OPENGL_DRVMODEL_H) || defined(SOFTRAS_DRVMODEL_H) || \ + defined(NULLXBOX_DRVMODEL_H)) + +#define FAVORITEORGANISATIONMODE (rpPTANKDFLAGARRAY) + +#endif + +static void* PTankAtomicInit(void* object, RwInt32 offset, RwInt32 size) +{ +} diff --git a/src/rwsdk/plugin/skin2/bsplit.c b/src/rwsdk/plugin/skin2/bsplit.c new file mode 100644 index 000000000..1305637be --- /dev/null +++ b/src/rwsdk/plugin/skin2/bsplit.c @@ -0,0 +1,118 @@ +#include "rwplcore.h" +#include "rwcore.h" +#include + +RwBool _rpSkinSplitDataDestroy(RpSkin* skin) +{ + SkinSplitData* skinSplitData; + + skinSplitData = &skin->skinSplitData; + + if (skinSplitData->matrixRemapIndices != NULL) + { + RwFree(skinSplitData->matrixRemapIndices); + } + + skinSplitData->boneLimit = 0; + skinSplitData->numMeshes = 0; + skinSplitData->numRLE = 0; + + skinSplitData->matrixRemapIndices = NULL; + skinSplitData->meshRLECount = NULL; + skinSplitData->meshRLE = NULL; + + return TRUE; +} + +RwStream* _rpSkinSplitDataStreamWrite(RwStream* stream, const RpSkin* skin) +{ + RwInt32 streamSize; + const SkinSplitData* skinSplitData; + + skinSplitData = &skin->skinSplitData; + + /* Write out the counters */ + if (!RwStreamWriteInt32(stream, (const RwInt32*)&skinSplitData->boneLimit, sizeof(RwInt32))) + { + return NULL; + } + + if (!RwStreamWriteInt32(stream, (const RwInt32*)&skinSplitData->numMeshes, sizeof(RwInt32))) + { + return NULL; + } + + if (!RwStreamWriteInt32(stream, (const RwInt32*)&skinSplitData->numRLE, sizeof(RwInt32))) + { + return NULL; + } + + if (0 < skin->skinSplitData.numMeshes) + { + streamSize = SkinSplitDataSize(skin, skinSplitData); + + if (!RwStreamWrite(stream, skinSplitData->matrixRemapIndices, streamSize)) + { + return NULL; + } + } + + return stream; +} + +RwStream* _rpSkinSplitDataStreamRead(RwStream* stream, RpSkin* skin) +{ + RwInt32 numMeshes, numRLE, boneLimit, streamSize; + SkinSplitData* skinSplitData; + + skinSplitData = &skin->skinSplitData; + + if (!RwStreamReadInt32(stream, (RwInt32*)&boneLimit, sizeof(RwInt32))) + { + return NULL; + } + + if (!RwStreamReadInt32(stream, (RwInt32*)&numMeshes, sizeof(RwInt32))) + { + return NULL; + } + + if (!RwStreamReadInt32(stream, (RwInt32*)&numRLE, sizeof(RwInt32))) + { + return NULL; + } + + if (numMeshes > 0) + { + if (!_rpSkinSplitDataCreate(skin, boneLimit, skin->boneData.numBones, numMeshes, numRLE)) + { + return NULL; + } + + streamSize = SkinSplitDataSize(skin, skinSplitData); + + /* Read in the index array */ + if (!RwStreamRead(stream, skinSplitData->matrixRemapIndices, streamSize)) + { + RwFree(skinSplitData); + + return NULL; + } + } + + return stream; +} + +RwInt32 _rpSkinSplitDataStreamGetSize(const RpSkin* skin) +{ + RwUInt32 streamSize; + + streamSize = sizeof(RwUInt32) * 3; + + if (0 < skin->skinSplitData.numMeshes) + { + streamSize += SkinSplitDataSize(skin, &skin->skinSplitData); + } + + return streamSize; +} diff --git a/src/rwsdk/plugin/skin2/gcn/instance/instanceskin.c b/src/rwsdk/plugin/skin2/gcn/instance/instanceskin.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/plugin/skin2/gcn/skingcn.c b/src/rwsdk/plugin/skin2/gcn/skingcn.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/plugin/skin2/gcn/skingcnasm.c b/src/rwsdk/plugin/skin2/gcn/skingcnasm.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/plugin/skin2/gcn/skingcng.c b/src/rwsdk/plugin/skin2/gcn/skingcng.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/plugin/skin2/gcn/skinmatrixblend.c b/src/rwsdk/plugin/skin2/gcn/skinmatrixblend.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/plugin/skin2/gcn/skinstream.c b/src/rwsdk/plugin/skin2/gcn/skinstream.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/plugin/skin2/rpskin.c b/src/rwsdk/plugin/skin2/rpskin.c new file mode 100644 index 000000000..8ed1f7bbc --- /dev/null +++ b/src/rwsdk/plugin/skin2/rpskin.c @@ -0,0 +1,284 @@ +#include "rwplcore.h" +#include "rwcore.h" +#include + +#if (defined(RWDEBUG)) +long _rpSkinStackDepth = 0; +#endif /* (defined(RWDEBUG)) */ + +#define rpSKINENTRIESPERBLOCK 20 +#define rpSKINALIGNMENT sizeof(RwUInt32) + +#define ROUNDUP16(x) (((RwUInt32)(x) + 16 - 1) & ~(16 - 1)) + +#define CHECKSTREAMANDRETURN(success) \ + MACRO_START \ + { \ + if (NULL == (success)) \ + { \ + RWRETURN((RwStream*)NULL); \ + } \ + } \ + MACRO_STOP + +#define rwID_SKINPLUGIN MAKECHUNKID(rwVENDORID_CRITERIONTK, 0x16) + +static RwInt32 _rpSkinFreeListBlockSize = rpSKINENTRIESPERBLOCK, _rpSkinFreeListPreallocBlocks = 1; +static RwFreeList _rpSkinFreeList; + +static RpSkin* SkinCreate(RwUInt32 numVertices, RwUInt32 numBones, RwUInt32 numBonesUsed, + RwUInt32 maxWeights, RwMatrixWeights* vertexWeights, + RwUInt32* vertexIndices, RwMatrix* inverseMatrices) +{ + RwUInt8 usedBoneList[256]; + RpSkin* skin; + + RWFUNCTION(RWSTRING("SkinCreate")); + RWASSERT(0 < numVertices); + RWASSERT(0 < numBones); + + /* Get a new skin */ + skin = (RpSkin*)RwFreeListAlloc(_rpSkinGlobals.freeList, rwID_SKINPLUGIN | rwMEMHINTDUR_EVENT); + RWASSERT(NULL != skin); + + /* Clean the skin */ + memset(skin, 0, sizeof(RpSkin)); + + /* Find the maximum number of weights used */ + if (0 == maxWeights) + { + SkinFindMaxWeights(skin, vertexWeights, numVertices); + } + + /* Find the number of used bones */ + if (0 == numBonesUsed) + { + SkinFindNumUsedBones(skin, vertexIndices, vertexWeights, usedBoneList, &numBonesUsed, + numVertices); + } + + /* Setup the skin's bones */ + if (!SkinCreateSkinData(skin, numBones, numBonesUsed, numVertices, usedBoneList, vertexWeights, + vertexIndices, inverseMatrices)) + { + RwFreeListFree(_rpSkinGlobals.freeList, skin); + RWRETURN((RpSkin*)NULL); + } + + RWRETURN(skin); +} + +static void* SkinOpen(void* instance, RwInt32 offset, RwInt32 size) +{ +} + +static void* SkinClose(void* instance, RwInt32 offset, RwInt32 size) +{ + _rpSkinGlobals.module.numInstances--; + + if (0 == _rpSkinGlobals.module.numInstances) + { + RwBool success; + + success = _rpSkinPipelinesDestroy(); + RwFreeListDestroy(_rpSkinGlobals.freeList); + _rpSkinGlobals.freeList = (RwFreeList*)NULL; + RwFree(_rpSkinGlobals.matrixCache.unaligned); + _rpSkinGlobals.matrixCache.unaligned = NULL; + } + + return instance; +} + +static void* SkinGeometryConstructor(void* object, RwInt32 offset, RwInt32 size) +{ + *RPSKINGEOMETRYGETDATA(object) = (RpSkin*)NULL; + + return object; +} + +static void* SkinGeometryDestructor(void* object, RwInt32 offset, RwInt32 size) +{ + RpGeometry* geometry; + RpSkin* skin; + + geometry = (RpGeometry*)object; + skin = *RPSKINGEOMETRYGETDATA(geometry); + + if (NULL != skin) + { + _rpSkinDeinitialize(geometry); + *RPSKINGEOMETRYGETDATA(geometry) = RpSkinDestroy(skin); + } + + return object; +} + +static void* SkinGeometryCopy(void* dstObject, const void* srcObject, RwInt32 offset, RwInt32 size) +{ +} + +static void* SkinAtomicConstructor(void* object, RwInt32 offset, RwInt32 size) +{ + // use same var as the Destructor counterpart? +} + +static void* SkinAtomicDestructor(void* object, RwInt32 offset, RwInt32 size) +{ + RpAtomic* atomic; + SkinAtomicData* atomicData; + + atomic = (RpAtomic*)object; + atomicData = RPSKINATOMICGETDATA(atomic); + + if (NULL != atomicData->hierarchy) + { + atomicData->hierarchy = (RpHAnimHierarchy*)NULL; + } + + return object; +} + +static void* SkinAtomicCopy(void* dstObject, const void* srcObject, RwInt32 offset, RwInt32 size) +{ + // odd way to write it but ok + const RpAtomic* srcAtomic; + const SkinAtomicData* srcAtomicData; + + RpAtomic* dstAtomic; + SkinAtomicData* dstAtomicData; + + srcAtomic = (const RpAtomic*)srcObject; + dstAtomic = (RpAtomic*)dstObject; + + srcAtomicData = RPSKINATOMICGETCONSTDATA(srcAtomic); + dstAtomicData = RPSKINATOMICGETDATA(dstAtomic); + + dstAtomicData->hierarchy = srcAtomicData->hierarchy; + + return dstObject; +} + +static RwBool SkinAtomicAlways(void* object, RwInt32 offset, RwInt32 size) +{ +} + +static RwBool SkinAtomicRights(void* object, RwInt32 offset, RwInt32 size, RwUInt32 extraData) +{ +} + +static RwInt32 SkinGeometrySize(const void* object, RwInt32 offset, RwInt32 bytes) +{ +} + +static RwStream* SkinGeometryWrite(RwStream* stream, RwInt32 binaryLength, const void* object, + RwInt32 offsetInObject, RwInt32 sizeInObject) +{ +} + +static RwStream* SkinGeometryRead(RwStream* stream, RwInt32 binaryLength, void* object, + RwInt32 offsetInObject, RwInt32 sizeInObject) +{ +} + +static RwStream* SkinAtomicRead(RwStream* stream, RwInt32 binaryLength, void* object, + RwInt32 offsetInObject, RwInt32 sizeInObject) +{ +} + +static RwStream* SkinAtomicWrite(RwStream* stream, RwInt32 binaryLength, const void* object, + RwInt32 offsetInObject, RwInt32 sizeInObject) +{ + return; +} + +static RwInt32 SkinAtomicGetSize(const void* object, RwInt32 offsetInObject, RwInt32 sizeInObject) +{ + return 0; +} + +RwBool RpSkinPluginAttach(void) +{ +} + +RpAtomic* RpSkinAtomicSetHAnimHierarchy(RpAtomic* atomic, RpHAnimHierarchy* hierarchy) +{ + SkinAtomicData* atomicData; + + atomicData = RPSKINATOMICGETDATA(atomic); + atomicData->hierarchy = hierarchy; + + return atomic; +} + +RpSkin* RpSkinGeometryGetSkin(RpGeometry* geometry) +{ + RpSkin* skin; + + skin = *RPSKINGEOMETRYGETDATA(geometry); + + return skin; +} + +RpGeometry* RpSkinGeometrySetSkin(RpGeometry* geometry, RpSkin* skin) +{ + RpSkin* oldSkin; + + oldSkin = *RPSKINGEOMETRYGETDATA(geometry); + if (skin != oldSkin) + { + if (NULL != oldSkin) + { + _rpSkinDeinitialize(geometry); + } + + *RPSKINGEOMETRYGETDATA(geometry) = skin; + + if (NULL != skin) + { + if (!_rpSkinInitialize(geometry)) + { + return NULL; + } + } + } + + return geometry; +} + +RpSkin* RpSkinDestroy(RpSkin* skin) +{ + if (skin->unaligned) + { + RwFree(skin->unaligned); + } + + _rpSkinSplitDataDestroy(skin); + skin = (RpSkin*)NULL; + + return skin; +} + +RwUInt32 RpSkinGetNumBones(RpSkin* skin) +{ + return (skin->boneData.numBones); +} + +const RwMatrixWeights* RpSkinGetVertexBoneWeights(RpSkin* skin) +{ + return (skin->vertexMaps.matrixWeights); +} + +const RwUInt32* RpSkinGetVertexBoneIndices(RpSkin* skin) +{ + return (skin->vertexMaps.matrixIndices); +} + +const RwMatrix* RpSkinGetSkinToBoneMatrices(RpSkin* skin) +{ + return (skin->boneData.invBoneToSkinMat); +} + +RpAtomic* RpSkinAtomicSetType(RpAtomic* atomic, RpSkinType type) +{ +} diff --git a/src/rwsdk/plugin/skin2/skin.h b/src/rwsdk/plugin/skin2/skin.h new file mode 100644 index 000000000..dc1639345 --- /dev/null +++ b/src/rwsdk/plugin/skin2/skin.h @@ -0,0 +1,184 @@ +#ifndef _SKIN_H +#define _SKIN_H + +#include "rwcore.h" +#include "rpworld.h" + +//#include "rpplugin.h" +//#include "rpdbgerr.h" + +#include "rphanim.h" +#include "rpskin.h" + +#if (defined(SKY2_DRVMODEL_H)) +#include "sky2/skinsky.h" +#elif (defined(XBOX_DRVMODEL_H)) +#include "xbox/skinxbox.h" +#elif (defined(GCN_DRVMODEL_H)) +#include "gcn/skingcn.h" +#elif (defined(NULLGCN_DRVMODEL_H)) +#include "gcn/skingcn.h" +#elif (defined(D3D8_DRVMODEL_H)) +#include "d3d8/skind3d8.h" +#elif (defined(D3D9_DRVMODEL_H)) +#include "d3d9/skind3d9.h" +#elif (defined(OPENGL_DRVMODEL_H)) +#include "opengl/skinopengl.h" +#elif (defined(SOFTRAS_DRVMODEL_H)) +#include "softras/skinsoftras.h" +#elif (defined(NULL_DRVMODEL_H) || defined(NULLSKY_DRVMODEL_H) || defined(NULLXBOX_DRVMODEL_H)) +#include "null/skinnull.h" +#else +//#include "generic/skingeneric.h" +#endif + +enum SkinPipeline +{ + rpNASKINPIPELINE = 0, + rpSKINPIPELINESKINGENERIC = 0x01, + rpSKINPIPELINESKINMATFX = 0x02, + rpSKINPIPELINESKINTOON = 0x04, + rpSKINPIPELINEFORCEENUMSIZEINT = RWFORCEENUMSIZEINT +}; +typedef enum SkinPipeline SkinPipeline; + +typedef void* SkinUnaligned; + +typedef struct SkinPlatformData SkinPlatformData; +struct SkinPlatformData +{ + void* vertices; + void* normals; + RwUInt8* weights; + RwUInt8* indices; + RwUInt32 skinType; +}; +#if defined(SKIN_ATOMIC_PLATFORM_DATA) +typedef struct SkinAtomicPlatformData SkinAtomicPlatformData; +#endif +typedef struct SkinGlobalPlatform SkinGlobalPlatform; +struct SkinGlobalPlatform +{ + RxPipeline* pipelines[5]; +}; + +typedef struct SkinSplitData SkinSplitData; +struct SkinSplitData +{ + RwUInt32 boneLimit; + RwUInt32 numMeshes; + RwUInt32 numRLE; + RwUInt8* matrixRemapIndices; + RwUInt8* meshRLECount; + RwUInt8* meshRLE; +}; + +typedef struct SkinBoneData SkinBoneData; +struct SkinBoneData +{ + RwUInt32 numBones; + RwUInt32 numUsedBones; + RwUInt8* usedBoneList; + RwMatrix* invBoneToSkinMat; +}; + +typedef struct SkinVertexMaps SkinVertexMaps; +struct SkinVertexMaps +{ + RwUInt32 maxWeights; + RwUInt32* matrixIndices; + RwMatrixWeights* matrixWeights; +}; + +struct RpSkin +{ + SkinBoneData boneData; + SkinVertexMaps vertexMaps; + SkinPlatformData platformData; + SkinSplitData skinSplitData; + SkinUnaligned* unaligned; +}; + +typedef struct SkinAtomicData SkinAtomicData; +struct SkinAtomicData +{ + RpHAnimHierarchy* hierarchy; +#if defined(SKIN_ATOMIC_PLATFORM_DATA) + SkinAtomicPlatformData platformData; +#endif +}; + +typedef struct SkinMatrixCache SkinMatrixCache; +struct SkinMatrixCache +{ + RwMatrix* aligned; + SkinUnaligned unaligned; +}; + +typedef struct SkinGlobals SkinGlobals; +typedef struct RwModuleInfo RwModuleInfo; + +struct SkinGlobals +{ + RwInt32 engineOffset; + RwInt32 atomicOffset; + RwInt32 geometryOffset; + + SkinMatrixCache matrixCache; + RwUInt32 numMatrices; + + RwFreeList* freeList; + RwModuleInfo module; + + SkinGlobalPlatform platform; + + SkinSplitData* skinSplitData; +}; + +extern SkinGlobals _rpSkinGlobals; + +#define RPSKINENGINEGETDATA(engineInstance) \ + ((_rpSkinLinkCallBack*)(((RwUInt8*)engineInstance) + _rpSkinGlobals.engineOffset)) + +#define RPSKINENGINEGETCONSTDATA(engineInstance) \ + ((const _rpSkinLinkCallBack*)(((const RwUInt8*)engineInstance) + _rpSkinGlobals.engineOffset)) + +#define RPSKINATOMICGETDATA(atomicInstance) \ + ((SkinAtomicData*)(((RwUInt8*)atomicInstance) + _rpSkinGlobals.atomicOffset)) + +#define RPSKINATOMICGETCONSTDATA(atomicInstance) \ + ((const SkinAtomicData*)(((const RwUInt8*)atomicInstance) + _rpSkinGlobals.atomicOffset)) + +#define RPSKINGEOMETRYGETDATA(geometryInstance) \ + ((RpSkin**)(((RwUInt8*)geometryInstance) + _rpSkinGlobals.geometryOffset)) + +#define RPSKINGEOMETRYGETCONSTDATA(geometryInstance) \ + ((const RpSkin* const*)(((const RwUInt8*)geometryInstance) + _rpSkinGlobals.geometryOffset)) + +#ifdef __cplusplus +extern "C" { +#endif + +extern RwBool _rpSkinPipelinesCreate(RwUInt32 pipes); + +extern RwBool _rpSkinPipelinesDestroy(void); + +extern RpAtomic* _rpSkinPipelinesAttach(RpAtomic* atomic, RpSkinType type); + +extern RwMatrix* _rpSkinGetAlignedMatrixCache(void); + +extern RwInt32 _rpSkinGeometryNativeSize(const RpGeometry* geometry); + +extern RwStream* _rpSkinGeometryNativeWrite(RwStream* stream, const RpGeometry* geometry); + +extern RwStream* _rpSkinGeometryNativeRead(RwStream* stream, RpGeometry* geometry); + +#ifdef SKIN_ATOMIC_PLATFORM_STREAM_SIZE +extern RwInt32 _rpSkinAtomicNativeSize(const RpAtomic* atomic); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/rwsdk/plugin/userdata/rpusrdat.c b/src/rwsdk/plugin/userdata/rpusrdat.c new file mode 100644 index 000000000..0fc97b112 --- /dev/null +++ b/src/rwsdk/plugin/userdata/rpusrdat.c @@ -0,0 +1,181 @@ +#include + +static RwInt32 userDataGeometryOffset = 0; +static RwInt32 userDataGeometryStreamOffset = 0; +static RwInt32 userDataWorldSectorOffset = 0; +static RwInt32 userDataWorldSectorStreamOffset = 0; +static RwInt32 userDataFrameOffset = 0; +static RwInt32 userDataFrameStreamOffset = 0; +static RwInt32 userDataCameraOffset = 0; +static RwInt32 userDataCameraStreamOffset = 0; +static RwInt32 userDataLightOffset = 0; +static RwInt32 userDataLightStreamOffset = 0; +static RwInt32 userDataMaterialOffset = 0; +static RwInt32 userDataMaterialStreamOffset = 0; +static RwInt32 userDataTextureOffset = 0; +static RwInt32 userDataTextureStreamOffset = 0; + +RwModuleInfo userDataModule; + +#define rwPLUGIN_ID rwID_USERDATAPLUGIN +#define rwPLUGIN_ERRFUNC _rwdb_CriterionUserData +#define rwPLUGIN_ERRENUM e_rwdb_CriterionUserData +#define rwPLUGIN_ERRENUMLAST e_rwdb_CriterionUserDataLAST + +typedef struct RpUserDataList RpUserDataList; + +struct RpUserDataList +{ + RwInt32 numElements; + RpUserDataArray* userData; +}; + +// Not continuing this file because RwMalloc could be wrong +// Will return when more info is available + +static void* UserDataOpen(void* instance, RwInt32 offset, RwInt32 size) +{ + userDataModule.numInstances++; + + return instance; +} + +static void* UserDataClose(void* instance, RwInt32 offset, RwInt32 size) +{ + userDataModule.numInstances--; + + return instance; +} + +static RwStream* UserDataStreamRead(RpUserDataArray* userData, RwStream* stream) +{ + RwInt32 i, length; + RwInt32* intData; + RwReal* realData; + RwChar** charData; + + if (!RwStreamReadInt32(stream, &length, sizeof(RwInt32))) + { + return NULL; + } + + if (length > 0) + { + if (userData->name == NULL) + { + return NULL; + } + + if (!RwStreamRead(stream, userData->name, sizeof(RwChar) * length)) + { + return NULL; + } + } + + if (!RwStreamReadInt32(stream, (RwInt32*)&userData->format, sizeof(RwInt32))) + { + return NULL; + } + + if (!RwStreamReadInt32(stream, &userData->numElements, sizeof(RwInt32))) + { + return NULL; + } + + switch (userData->format) + { + case rpINTUSERDATA: + + if (userData->data == NULL) + { + return NULL; + } + + intData = (RwInt32*)userData->data; + + if (!RwStreamReadInt32(stream, intData, sizeof(RwInt32) * userData->numElements)) + { + return NULL; + } + break; + case rpREALUSERDATA: + + if (userData->data == NULL) + { + return NULL; + } + + realData = (RwReal*)userData->data; + + if (!RwStreamReadReal(stream, realData, sizeof(RwReal) * userData->numElements)) + { + return NULL; + } + break; + case rpSTRINGUSERDATA: + + if (userData->data == NULL) + { + return NULL; + } + + charData = (RwChar**)userData->data; + + for (i = 0; i < userData->numElements; i++) + { + if (!RwStreamReadInt32(stream, &length, sizeof(RwInt32))) + { + return NULL; + } + + if (length > 0) + { + if (charData[i] == NULL) + { + return NULL; + } + + if (!RwStreamRead(stream, charData[i], sizeof(RwChar) * length)) + { + return NULL; + } + } + else + { + charData[i] = (RwChar*)NULL; + } + } + break; + default: + return NULL; + break; + } + + return stream; +} + +static void* UserDataObjectConstruct(void* object, RwInt32 offset, RwInt32 size) +{ +} + +static void* UserDataObjectCopy(void* destinationObject, const void* sourceObject, RwInt32 offset, + RwInt32 size) +{ + RpUserDataList* dstUserDataList = 0; + const RpUserDataList* srcUserDataList = 0; + + UserDataListCopy(dstUserDataList, srcUserDataList); + + return destinationObject; +} + +RwInt32 RpGeometryAddUserDataArray(RpGeometry* geometry, RwChar* name, RpUserDataFormat format, + RwInt32 numElements) +{ + RwInt32 index; + RpUserDataList* userDataList = 0; + + index = UserDataListAddElement(userDataList, name, format, numElements); + + return index; +} diff --git a/src/rwsdk/plugin/userdata/rpusrdat.h b/src/rwsdk/plugin/userdata/rpusrdat.h new file mode 100644 index 000000000..ecf0bed79 --- /dev/null +++ b/src/rwsdk/plugin/userdata/rpusrdat.h @@ -0,0 +1,93 @@ +#ifndef RPUSERDATAPLUGIN_H +#define RPUSERDATAPLUGIN_H + +#include +#include + +enum RpUserDataFormat +{ + rpNAUSERDATAFORMAT = 0, + rpINTUSERDATA, + rpREALUSERDATA, + rpSTRINGUSERDATA, + rpUSERDATAFORCEENUMSIZEINT = RWFORCEENUMSIZEINT +}; +typedef enum RpUserDataFormat RpUserDataFormat; + +typedef struct RpUserDataArray RpUserDataArray; + +struct RpUserDataArray +{ + RwChar* name; + RpUserDataFormat format; + RwInt32 numElements; + void* data; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +extern RwBool RpUserDataPluginAttach(void); + +extern RwInt32 RpGeometryAddUserDataArray(RpGeometry* geometry, RwChar* name, + RpUserDataFormat format, RwInt32 numElements); +extern RpGeometry* RpGeometryRemoveUserDataArray(RpGeometry* geometry, RwInt32 index); +extern RpUserDataArray* RpGeometryGetUserDataArray(const RpGeometry* geometry, RwInt32 data); +extern RwInt32 RpGeometryGetUserDataArrayCount(const RpGeometry* geometry); + +extern RwInt32 RpWorldSectorAddUserDataArray(RpWorldSector* sector, RwChar* name, + RpUserDataFormat format, RwInt32 numElements); +extern RpWorldSector* RpWorldSectorRemoveUserDataArray(RpWorldSector* sector, RwInt32 index); +extern RpUserDataArray* RpWorldSectorGetUserDataArray(const RpWorldSector* sector, RwInt32 data); +extern RwInt32 RpWorldSectorGetUserDataArrayCount(const RpWorldSector* sector); + +extern RwInt32 RwFrameAddUserDataArray(RwFrame* frame, RwChar* name, RpUserDataFormat format, + RwInt32 numElements); +extern RwFrame* RwFrameRemoveUserDataArray(RwFrame* frame, RwInt32 index); +extern RpUserDataArray* RwFrameGetUserDataArray(const RwFrame* frame, RwInt32 data); +extern RwInt32 RwFrameGetUserDataArrayCount(const RwFrame* frame); + +extern RwInt32 RwCameraAddUserDataArray(RwCamera* camera, RwChar* name, RpUserDataFormat format, + RwInt32 numElements); +extern RwCamera* RwCameraRemoveUserDataArray(RwCamera* camera, RwInt32 index); +extern RpUserDataArray* RwCameraGetUserDataArray(const RwCamera* camera, RwInt32 data); +extern RwInt32 RwCameraGetUserDataArrayCount(const RwCamera* camera); + +extern RwInt32 RpLightAddUserDataArray(RpLight* light, RwChar* name, RpUserDataFormat format, + RwInt32 numElements); +extern RpLight* RpLightRemoveUserDataArray(RpLight* light, RwInt32 index); +extern RpUserDataArray* RpLightGetUserDataArray(const RpLight* light, RwInt32 data); +extern RwInt32 RpLightGetUserDataArrayCount(const RpLight* light); + +extern RwInt32 RpMaterialAddUserDataArray(RpMaterial* material, RwChar* name, + RpUserDataFormat format, RwInt32 numElements); +extern RpMaterial* RpMaterialRemoveUserDataArray(RpMaterial* material, RwInt32 index); +extern RpUserDataArray* RpMaterialGetUserDataArray(const RpMaterial* material, RwInt32 data); +extern RwInt32 RpMaterialGetUserDataArrayCount(const RpMaterial* material); + +extern RwInt32 RwTextureAddUserDataArray(RwTexture* texture, RwChar* name, RpUserDataFormat format, + RwInt32 numElements); +extern RwTexture* RwTextureRemoveUserDataArray(RwTexture* texture, RwInt32 index); +extern RpUserDataArray* RwTextureGetUserDataArray(const RwTexture* texture, RwInt32 data); +extern RwInt32 RwTextureGetUserDataArrayCount(const RwTexture* texture); + +extern RwChar* RpUserDataArrayGetName(RpUserDataArray* userData); +extern RpUserDataFormat RpUserDataArrayGetFormat(RpUserDataArray* userData); +extern RwInt32 RpUserDataArrayGetNumElements(RpUserDataArray* userData); + +extern RwInt32 RpUserDataArrayGetInt(RpUserDataArray* userData, RwInt32 index); +extern RwReal RpUserDataArrayGetReal(RpUserDataArray* userData, RwInt32 index); +extern RwChar* RpUserDataArrayGetString(RpUserDataArray* userData, RwInt32 index); + +extern void RpUserDataArraySetInt(RpUserDataArray* userData, RwInt32 index, RwInt32 value); +extern void RpUserDataArraySetReal(RpUserDataArray* userData, RwInt32 index, RwReal value); +extern void RpUserDataArraySetString(RpUserDataArray* userData, RwInt32 index, RwChar* value); + +extern RwInt32 RpUserDataGetFormatSize(RpUserDataFormat format); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/rwsdk/src/babbox.c b/src/rwsdk/src/babbox.c new file mode 100644 index 000000000..a924ad78c --- /dev/null +++ b/src/rwsdk/src/babbox.c @@ -0,0 +1,14 @@ +#include "rwplcore.h" +#include "rwcore.h" + +RwBBox* RwBBoxCalculate(RwBBox* boundBox, const RwV3d* verts, RwInt32 numVerts) +{ +} + +RwBBox* RwBBoxInitialize(RwBBox* boundBox, const RwV3d* vertex) +{ +} + +RwBBox* RwBBoxAddPoint(RwBBox* boundBox, const RwV3d* vertex) +{ +} diff --git a/src/rwsdk/src/babincam.c b/src/rwsdk/src/babincam.c new file mode 100644 index 000000000..ee38944ef --- /dev/null +++ b/src/rwsdk/src/babincam.c @@ -0,0 +1,65 @@ +#include "rwplcore.h" +#include "rwcore.h" + +typedef struct rwStreamCamera RwCameraChunkInfo; +typedef struct rwStreamCamera rwStreamCamera; + +extern RwPluginRegistry cameraTKList; + +struct rwStreamCamera +{ + RwV2d viewWindow; + RwV2d viewOffset; + RwReal nearPlane, farPlane; + RwReal fogPlane; + RwUInt32 projection; +}; + +RwInt32 RwCameraRegisterPluginStream(RwUInt32 pluginID, RwPluginDataChunkReadCallBack readCB, + RwPluginDataChunkWriteCallBack writeCB, + RwPluginDataChunkGetSizeCallBack getSizeCB) +{ + _rwPluginRegistryAddPluginStream(&cameraTKList, pluginID, readCB, writeCB, getSizeCB); +} + +RwCamera* RwCameraStreamRead(RwStream* stream) +{ + RwCamera* camera; + rwStreamCamera cam; + RwUInt32 size, version; + + if (!RwStreamFindChunk(stream, rwID_STRUCT, &size, &version)) + { + RWRETURN((RwCamera*)NULL); + } + + if ((version >= rwLIBRARYBASEVERSION) && (version <= rwLIBRARYCURRENTVERSION)) + { + memset(&cam, 0, sizeof(cam)); + if (RwStreamRead(stream, &cam, size) != size) + { + RWRETURN((RwCamera*)NULL); + } + camera = RwCameraCreate(); + if (!camera) + { + RWRETURN((RwCamera*)NULL); + } + if (!_rwPluginRegistryReadDataChunks(&cameraTKList, stream, camera)) + { + RWRETURN((RwCamera*)NULL); + } + RwCameraSetViewWindow(camera, &cam.viewWindow); + RwCameraSetViewOffset(camera, &cam.viewOffset); + RwCameraSetNearClipPlane(camera, ((RwReal)cam.nearPlane)); + RwCameraSetFarClipPlane(camera, ((RwReal)cam.farPlane)); + RwCameraSetFogDistance(camera, ((RwReal)cam.fogPlane)); + RwCameraSetProjection(camera, (RwCameraProjection)cam.projection); + + RWRETURN(camera); + } + else + { + RWRETURN((RwCamera*)NULL); + } +} diff --git a/src/rwsdk/src/babinfrm.c b/src/rwsdk/src/babinfrm.c new file mode 100644 index 000000000..60c1170f0 --- /dev/null +++ b/src/rwsdk/src/babinfrm.c @@ -0,0 +1,34 @@ +#include "rwplcore.h" +#include "rwcore.h" + +extern RwPluginRegistry frameTKList; + +RwInt32 RwFrameRegisterPluginStream(RwUInt32 pluginID, RwPluginDataChunkReadCallBack readCB, + RwPluginDataChunkWriteCallBack writeCB, + RwPluginDataChunkGetSizeCallBack getSizeCB) +{ + _rwPluginRegistryAddPluginStream(&frameTKList, pluginID, readCB, writeCB, getSizeCB); +} + +RwBool _rwFrameListFindFrame(const rwFrameList* frameList, const RwFrame* frame, RwInt32* npIndex) +{ + // Something like this? + + int i; + for (i = 0; i < frameList->numFrames; i++) + { + if (frameList->frames[i] == frame) + { + (*npIndex) = i; + } + } +} + +rwFrameList* _rwFrameListDeinitialize(rwFrameList* frameList) +{ + if (frameList->numFrames) + { + RwFree(frameList->frames); + } + return frameList; +} diff --git a/src/rwsdk/src/babintex.c b/src/rwsdk/src/babintex.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/src/bacamera.c b/src/rwsdk/src/bacamera.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/src/badevice.c b/src/rwsdk/src/badevice.c new file mode 100644 index 000000000..3c3fe0012 --- /dev/null +++ b/src/rwsdk/src/badevice.c @@ -0,0 +1,28 @@ +#include "rwplcore.h" +#include "rwcore.h" + +extern RwPluginRegistry engineTKList; + +RwGlobals* RwEngineInstance; +RwInt32 engineInstancesOpened; + +RwInt32 _rwGetNumEngineInstances() +{ + return engineInstancesOpened; +} + +RwUInt32 RwEngineGetVersion() +{ + return 0x35000; +} + +RwInt32 RwEngineRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor initCB, + RwPluginObjectDestructor termCB) +{ + _rwPluginRegistryAddPlugin(&engineTKList, size, pluginID, initCB, termCB, 0x0); +} + +RwInt32 RwEngineGetPluginOffset(RwUInt32 pluginID) +{ + _rwPluginRegistryGetPluginOffset(&engineTKList, pluginID); +} diff --git a/src/rwsdk/src/baframe.c b/src/rwsdk/src/baframe.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/src/baimage.c b/src/rwsdk/src/baimage.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/src/baimras.c b/src/rwsdk/src/baimras.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/src/baraster.c b/src/rwsdk/src/baraster.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/src/baresamp.c b/src/rwsdk/src/baresamp.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/src/basync.c b/src/rwsdk/src/basync.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/src/batextur.c b/src/rwsdk/src/batextur.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/src/batypehf.c b/src/rwsdk/src/batypehf.c new file mode 100644 index 000000000..e3d38e5f9 --- /dev/null +++ b/src/rwsdk/src/batypehf.c @@ -0,0 +1,27 @@ +#include "rwplcore.h" +#include "rwcore.h" + +void _rwObjectHasFrameSetFrame(void* object, RwFrame* frame) +{ + RwObjectHasFrame* ohf = (RwObjectHasFrame*)object; + if (rwObjectGetParent(ohf)) + { + rwLinkListRemoveLLLink(&ohf->lFrame); + } + rwObjectSetParent(object, frame); + if (frame) + { + rwLinkListAddLLLink(&frame->objectList, &ohf->lFrame); + + RwFrameUpdateObjects(frame); + } +} + +void _rwObjectHasFrameReleaseFrame(void* object) +{ + RwObjectHasFrame* ohf = (RwObjectHasFrame*)object; + if (rwObjectGetParent(ohf)) + { + rwLinkListRemoveLLLink(&ohf->lFrame); + } +} diff --git a/src/rwsdk/src/pipe/p2/baim3d.c b/src/rwsdk/src/pipe/p2/baim3d.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/src/pipe/p2/bapipe.c b/src/rwsdk/src/pipe/p2/bapipe.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/src/pipe/p2/gcn/im3dpipe.c b/src/rwsdk/src/pipe/p2/gcn/im3dpipe.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/src/pipe/p2/gcn/nodeDolphinSubmitNoLight.c b/src/rwsdk/src/pipe/p2/gcn/nodeDolphinSubmitNoLight.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/src/pipe/p2/p2altmdl.c b/src/rwsdk/src/pipe/p2/p2altmdl.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/src/pipe/p2/p2core.c b/src/rwsdk/src/pipe/p2/p2core.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/src/pipe/p2/p2define.c b/src/rwsdk/src/pipe/p2/p2define.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/src/pipe/p2/p2dep.c b/src/rwsdk/src/pipe/p2/p2dep.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/src/pipe/p2/p2heap.c b/src/rwsdk/src/pipe/p2/p2heap.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/src/pipe/p2/p2renderstate.c b/src/rwsdk/src/pipe/p2/p2renderstate.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/src/pipe/p2/p2resort.c b/src/rwsdk/src/pipe/p2/p2resort.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/src/plcore/babinary.c b/src/rwsdk/src/plcore/babinary.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/src/plcore/bacolor.c b/src/rwsdk/src/plcore/bacolor.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/src/plcore/baerr.c b/src/rwsdk/src/plcore/baerr.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/src/plcore/bafsys.c b/src/rwsdk/src/plcore/bafsys.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/src/plcore/baimmedi.c b/src/rwsdk/src/plcore/baimmedi.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/src/plcore/bamatrix.c b/src/rwsdk/src/plcore/bamatrix.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/src/plcore/bamemory.c b/src/rwsdk/src/plcore/bamemory.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/src/plcore/baresour.c b/src/rwsdk/src/plcore/baresour.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/src/plcore/bastream.c b/src/rwsdk/src/plcore/bastream.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/src/plcore/batkbin.c b/src/rwsdk/src/plcore/batkbin.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/src/plcore/batkreg.c b/src/rwsdk/src/plcore/batkreg.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/src/plcore/bavector.c b/src/rwsdk/src/plcore/bavector.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/src/plcore/resmem.c b/src/rwsdk/src/plcore/resmem.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/src/plcore/rwstring.c b/src/rwsdk/src/plcore/rwstring.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/tool/anim/rtanim.c b/src/rwsdk/tool/anim/rtanim.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/tool/intsec/rtintsec.c b/src/rwsdk/tool/intsec/rtintsec.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/world/babinwor.c b/src/rwsdk/world/babinwor.c new file mode 100644 index 000000000..8712086cd --- /dev/null +++ b/src/rwsdk/world/babinwor.c @@ -0,0 +1,67 @@ +#include + +#if !(rwLIBRARYVERSION36002 < rwLIBRARYBASEVERSION) +typedef struct rpPolygon rpPolygon; +struct rpPolygon +{ + RwUInt16 matIndex; + RwUInt16 vertIndex[3]; +}; +#endif + +#define RWSTREAMTYPE(_type) \ + ((rwNASTREAM == (_type)) ? \ + "rwNASTREAM" : \ + ((rwSTREAMFILE == (_type)) ? \ + "rwSTREAMFILE" : \ + ((rwSTREAMFILENAME == (_type)) ? \ + "rwSTREAMFILENAME" : \ + ((rwSTREAMMEMORY == (_type)) ? "rwSTREAMMEMORY" : "Unknown")))) + +#define WorldFormatGetNumTexCoordSetsMacro(_fmt) \ + (((_fmt)&0xff0000) ? \ + (((_fmt)&0xff0000) >> 16) : \ + (((_fmt)&rpGEOMETRYTEXTURED2) ? 2 : (((_fmt)&rpGEOMETRYTEXTURED) ? 1 : 0))) + +#define WorldFormatGetFlagsMacro(_fmt) ((_fmt)&0xff) + +static RwModuleInfo binWorldModule; + +static RwUInt32 lastSeenWorldRightsPluginId; +static RwUInt32 lastSeenWorldExtraData; + +RwStream* _rpReadWorldRights(RwStream* s, RwInt32 len, void* obj, RwInt32 off, RwInt32 size) +{ + if (!RwStreamReadInt32(s, (RwInt32*)&(lastSeenWorldRightsPluginId), sizeof(RwInt32))) + { + return NULL; + } + if (len == 8) + { + if (!RwStreamReadInt32(s, (RwInt32*)&(lastSeenWorldExtraData), sizeof(RwInt32))) + { + return NULL; + } + } + return s; +} + +RwStream* _rpWriteWorldRights(RwStream* s, RwInt32 len, const void* obj, RwInt32 off, RwInt32 size) +{ + // How does this instruction order even + // become out of order like this? + const RpWorld* wrl; + + wrl = (const RpWorld*)obj; + + if (!RwStreamWriteInt32(s, (RwInt32*)&(wrl->pipeline->pluginId), sizeof(RwInt32))) + { + return NULL; + } + if (!RwStreamWriteInt32(s, (RwInt32*)&(wrl->pipeline->pluginData), sizeof(RwInt32))) + { + return NULL; + } + + return s; +} diff --git a/src/rwsdk/world/babinwor.h b/src/rwsdk/world/babinwor.h new file mode 100644 index 000000000..e2a339130 --- /dev/null +++ b/src/rwsdk/world/babinwor.h @@ -0,0 +1,119 @@ + + +#ifndef RWBINWOR_H +#define RWBINWOR_H + +#include +#include + +typedef struct RpWorldChunkInfoSector RpWorldSectorChunkInfo; +typedef struct RpWorldChunkInfoSector _rpWorldSector; + +#if (!defined(DOXYGEN)) +struct RpWorldChunkInfoSector +{ + RwInt32 matListWindowBase; + RwInt32 numTriangles; + RwInt32 numVertices; + RwV3d inf; + RwV3d sup; + RwBool collSectorPresent; + RwBool unused; +}; + +typedef struct RpPlaneSectorChunkInfo RpPlaneSectorChunkInfo; +typedef struct RpPlaneSectorChunkInfo _rpPlaneSector; + +struct RpPlaneSectorChunkInfo +{ + RwInt32 type; + RwReal value; + RwBool leftIsWorldSector; + RwBool rightIsWorldSector; + RwReal leftValue; + RwReal rightValue; +}; + +typedef struct RpWorldChunkInfo RpWorldChunkInfo; +typedef struct RpWorldChunkInfo _rpWorld; + +struct RpWorldChunkInfo +{ + RwBool rootIsWorldSector; + + RwV3d invWorldOrigin; + + RwInt32 numTriangles; + RwInt32 numVertices; + RwInt32 numPlaneSectors; + RwInt32 numWorldSectors; + RwInt32 colSectorSize; + + RwInt32 format; + + RwBBox boundingBox; +}; + +typedef struct rpWorldChunkInfo34000 rpWorldChunkInfo34000; + +struct rpWorldChunkInfo34000 +{ + RwBool rootIsWorldSector; + + RwV3d invWorldOrigin; + + RwSurfaceProperties surfaceProps; + + RwInt32 numTriangles; + RwInt32 numVertices; + RwInt32 numPlaneSectors; + RwInt32 numWorldSectors; + RwInt32 colSectorSize; + + RwInt32 format; +}; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +extern void* _rpBinaryWorldOpen(void* instance, RwInt32 offset, RwInt32 size); +extern void* _rpBinaryWorldClose(void* instance, RwInt32 offset, RwInt32 size); + +extern RwStream* _rpReadWorldRights(RwStream* s, RwInt32 len, void* obj, RwInt32 off, RwInt32 size); +extern RwStream* _rpWriteWorldRights(RwStream* s, RwInt32 len, const void* obj, RwInt32 off, + RwInt32 size); +extern RwInt32 _rpSizeWorldRights(const void* obj, RwInt32 off, RwInt32 size); + +extern RwStream* _rpReadSectRights(RwStream* s, RwInt32 len, void* obj, RwInt32 off, RwInt32 size); +extern RwStream* _rpWriteSectRights(RwStream* s, RwInt32 len, const void* obj, RwInt32 off, + RwInt32 size); +extern RwInt32 _rpSizeSectRights(const void* obj, RwInt32 off, RwInt32 size); + +extern RwUInt32 RpWorldStreamGetSize(const RpWorld* world); +extern RpWorld* RpWorldStreamRead(RwStream* stream); +extern const RpWorld* RpWorldStreamWrite(const RpWorld* world, RwStream* stream); +extern RpWorldSectorChunkInfo* +_rpWorldSectorChunkInfoRead(RwStream* stream, RpWorldSectorChunkInfo* worldSectorChunkInfo, + RwInt32* bytesRead); +extern RpPlaneSectorChunkInfo* +_rpPlaneSectorChunkInfoRead(RwStream* stream, RpPlaneSectorChunkInfo* planeSectorChunkInfo, + RwInt32* bytesRead); +extern RpWorldChunkInfo* _rpWorldChunkInfoRead(RwStream* stream, RpWorldChunkInfo* worldChunkInfo, + RwInt32* bytesRead); + +#ifdef __cplusplus +} +#endif + +#define RpWorldSectorChunkInfoRead(stream, worldSectorChunkInfo, bytesRead) \ + _rpWorldSectorChunkInfoRead(stream, worldSectorChunkInfo, bytesRead) + +#define RpPlaneSectorChunkInfoRead(stream, planeSectorChunkInfo, bytesRead) \ + _rpPlaneSectorChunkInfoRead(stream, planeSectorChunkInfo, bytesRead) + +#define RpWorldChunkInfoRead(stream, worldChunkInfo, bytesRead) \ + _rpWorldChunkInfoRead(stream, worldChunkInfo, bytesRead) + +#endif diff --git a/src/rwsdk/world/baclump.c b/src/rwsdk/world/baclump.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/world/bageomet.c b/src/rwsdk/world/bageomet.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/world/balight.c b/src/rwsdk/world/balight.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/world/bamateri.c b/src/rwsdk/world/bamateri.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/world/bamatlst.c b/src/rwsdk/world/bamatlst.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/world/bamesh.c b/src/rwsdk/world/bamesh.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/world/bameshop.c b/src/rwsdk/world/bameshop.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/world/basector.c b/src/rwsdk/world/basector.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/world/baworld.c b/src/rwsdk/world/baworld.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/world/baworobj.c b/src/rwsdk/world/baworobj.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/world/pipe/p2/bapipew.c b/src/rwsdk/world/pipe/p2/bapipew.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/world/pipe/p2/gcn/gclights.c b/src/rwsdk/world/pipe/p2/gcn/gclights.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/world/pipe/p2/gcn/gcmorph.c b/src/rwsdk/world/pipe/p2/gcn/gcmorph.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/world/pipe/p2/gcn/gcpipe.c b/src/rwsdk/world/pipe/p2/gcn/gcpipe.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/world/pipe/p2/gcn/instance/geomcond.c b/src/rwsdk/world/pipe/p2/gcn/instance/geomcond.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/world/pipe/p2/gcn/instance/geominst.c b/src/rwsdk/world/pipe/p2/gcn/instance/geominst.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/world/pipe/p2/gcn/instance/ibuffer.c b/src/rwsdk/world/pipe/p2/gcn/instance/ibuffer.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/world/pipe/p2/gcn/instance/instancegeom.c b/src/rwsdk/world/pipe/p2/gcn/instance/instancegeom.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/world/pipe/p2/gcn/instance/instanceworld.c b/src/rwsdk/world/pipe/p2/gcn/instance/instanceworld.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/world/pipe/p2/gcn/instance/itools.c b/src/rwsdk/world/pipe/p2/gcn/instance/itools.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/world/pipe/p2/gcn/instance/vbuffer.c b/src/rwsdk/world/pipe/p2/gcn/instance/vbuffer.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/world/pipe/p2/gcn/instance/vtools.c b/src/rwsdk/world/pipe/p2/gcn/instance/vtools.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/world/pipe/p2/gcn/instance/vtxdesc.c b/src/rwsdk/world/pipe/p2/gcn/instance/vtxdesc.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/world/pipe/p2/gcn/native.c b/src/rwsdk/world/pipe/p2/gcn/native.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/world/pipe/p2/gcn/nodeGameCubeAtomicAllInOne.c b/src/rwsdk/world/pipe/p2/gcn/nodeGameCubeAtomicAllInOne.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/world/pipe/p2/gcn/nodeGameCubeWorldSectorAllInOne.c b/src/rwsdk/world/pipe/p2/gcn/nodeGameCubeWorldSectorAllInOne.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/world/pipe/p2/gcn/setup.c b/src/rwsdk/world/pipe/p2/gcn/setup.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/world/pipe/p2/gcn/vtxfmt.c b/src/rwsdk/world/pipe/p2/gcn/vtxfmt.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/rwsdk/world/pipe/p2/gcn/wrldpipe.c b/src/rwsdk/world/pipe/p2/gcn/wrldpipe.c new file mode 100644 index 000000000..e69de29bb From cd95dce8f6fd39a64d2a03bdf53962fc28e2e494 Mon Sep 17 00:00:00 2001 From: Colin Miller Date: Tue, 24 Jun 2025 12:56:39 -0400 Subject: [PATCH 2/2] Ported Seil's code from the bfbbpc repo --- include/types.h | 5 +- src/SB/Core/gc/iCollide.h | 4 +- src/SB/Core/x/xBase.h | 10 + src/SB/Core/x/xBehaviour.h | 1 + src/SB/Core/x/xBound.h | 9 + src/SB/Core/x/xCollide.h | 14 + src/SB/Core/x/xDraw.h | 3 + src/SB/Core/x/xEnt.h | 19 + src/SB/Core/x/xEntMotion.cpp | 5 - src/SB/Core/x/xMath.h | 1 + src/SB/Core/x/xMath3.h | 3 + src/SB/Core/x/xRumble.h | 4 +- src/SB/Core/x/xSpline.h | 8 +- src/SB/Core/x/xutil.h | 37 + src/SB/Game/zMovePoint.h | 4 + src/SB/Game/zNPCGoalVillager.h | 7 - src/SB/Game/zNPCGoals.h | 7 +- src/SB/Game/zNPCMessenger.h | 4 + src/SB/Game/zNPCSndTable.h | 14 + src/SB/Game/zNPCSupplement.h | 25 +- src/SB/Game/zNPCSupport.cpp | 823 +++++++- src/SB/Game/zNPCSupport.h | 22 +- src/SB/Game/zNPCTypeCommon.cpp | 3260 +++++++++++++++++++++++++++++++- src/SB/Game/zNPCTypeCommon.h | 46 +- 24 files changed, 4162 insertions(+), 173 deletions(-) diff --git a/include/types.h b/include/types.h index 84a3b6ec0..65125f04a 100644 --- a/include/types.h +++ b/include/types.h @@ -90,6 +90,9 @@ typedef wchar_t wint_t; #define NULL 0 #endif +#define FORCEENUMSIZEINT ((S32)((~((U32)0)) >> 1)) +#define ARRAY_LENGTH(a) (sizeof(a) / sizeof(a[0])) + #define UINT32_MAX 0xffffffff -#endif // !TYPES_H \ No newline at end of file +#endif // !TYPES_H diff --git a/src/SB/Core/gc/iCollide.h b/src/SB/Core/gc/iCollide.h index 41f9af95b..ad3c6e73f 100644 --- a/src/SB/Core/gc/iCollide.h +++ b/src/SB/Core/gc/iCollide.h @@ -8,9 +8,11 @@ void iBoxForModelLocal(xBox* o, const xModelInstance* m); void iBoxForModel(xBox* o, const xModelInstance* m); +void iSphereForModel(xSphere* 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); + F32 sth); U32 iRayHitsModel(const xRay3* r, const xModelInstance* m, xCollis* coll); void iCollideInit(xScene* sc); diff --git a/src/SB/Core/x/xBase.h b/src/SB/Core/x/xBase.h index a6f326912..b444832a7 100644 --- a/src/SB/Core/x/xBase.h +++ b/src/SB/Core/x/xBase.h @@ -28,6 +28,16 @@ struct xBase xBaseEventCB eventFunc; // 0xC }; +#define k_XBASE_IS_ENABLED ((U16)(1 << 0)) +#define k_XBASE_IS_PERSISTENT ((U16)(1 << 1)) +#define k_XBASE_IS_VALID ((U16)(1 << 2)) +#define k_XBASE_IS_VISIBLE_IN_CUTSCENES ((U16)(1 << 3)) +#define k_XBASE_RECEIVES_SHADOWS ((U16)(1 << 4)) +#define k_XBASE_IS_ENTITY ((U16)(1 << 5)) +#define k_XBASE_0x40 ((U16)(1 << 6)) +#define k_XBASE_0x80 ((U16)(1 << 7)) +#define k_XBASE_IS_NPC ((U16)(1 << 8)) + void xBaseInit(xBase* xb, xBaseAsset* asset); void xBaseSetup(xBase* xb); void xBaseSave(xBase* ent, xSerial* s); diff --git a/src/SB/Core/x/xBehaviour.h b/src/SB/Core/x/xBehaviour.h index 0db2b7249..1b723b8bf 100644 --- a/src/SB/Core/x/xBehaviour.h +++ b/src/SB/Core/x/xBehaviour.h @@ -115,6 +115,7 @@ struct xPsyche : RyzMemData S32 GoalSet(S32 gid, S32 r5); S32 GoalPop(S32 gid_popto, S32 r5); S32 GoalNone(S32 denyExplicit); + S32 GoalNone(S32, S32 denyExplicit); S32 GoalSwap(S32 gid, S32 r5); S32 GoalPopRecover(S32 overpend); S32 GoalPopToBase(S32 overpend); diff --git a/src/SB/Core/x/xBound.h b/src/SB/Core/x/xBound.h index e6a3416f3..c02376115 100644 --- a/src/SB/Core/x/xBound.h +++ b/src/SB/Core/x/xBound.h @@ -21,6 +21,15 @@ struct xBound xMat4x3* mat; }; +enum +{ + k_XBOUNDTYPE_NONE = 0, + k_XBOUNDTYPE_SPHERE = 1, + k_XBOUNDTYPE_BOX = 2, + k_XBOUNDTYPE_CYL = 3, + k_XBOUNDTYPE_OBB = 4 +}; + #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 diff --git a/src/SB/Core/x/xCollide.h b/src/SB/Core/x/xCollide.h index 331393247..17655cd6c 100644 --- a/src/SB/Core/x/xCollide.h +++ b/src/SB/Core/x/xCollide.h @@ -6,6 +6,20 @@ #include "xQuickCull.h" #include "iMath3.h" +#define k_HIT_IT ((U32)(1 << 0)) +#define k_HIT_0x2 ((U32)(1 << 1)) +#define k_HIT_0x4 ((U32)(1 << 2)) +#define k_HIT_0x8 ((U32)(1 << 3)) +#define k_HIT_0x10 ((U32)(1 << 4)) +#define k_HIT_0x100 ((U32)(1 << 8)) +#define k_HIT_0x200 ((U32)(1 << 9)) +#define k_HIT_0x400 ((U32)(1 << 10)) +#define k_HIT_0x800 ((U32)(1 << 11)) +#define k_HIT_0xF00 (k_HIT_0x100 | k_HIT_0x200 | k_HIT_0x400 | k_HIT_0x800) +#define k_HIT_CALC_HDNG ((U32)(1 << 12)) +#define k_HIT_CALC_TRI ((U32)(1 << 13)) +#define k_HIT_0x20000 ((U32)(1 << 17)) + struct xModelInstance; struct xCollis diff --git a/src/SB/Core/x/xDraw.h b/src/SB/Core/x/xDraw.h index 6e91c87c5..cf9c604bd 100644 --- a/src/SB/Core/x/xDraw.h +++ b/src/SB/Core/x/xDraw.h @@ -8,5 +8,8 @@ void xDrawSetColor(iColor_tag); void xDrawSphere2(const xSphere*, U32); void xDrawOBB(const xBox*, const xMat4x3*); void xDrawBox(const xBox*); +inline void xDrawLine(const xVec3* a, const xVec3* b) +{ +} #endif diff --git a/src/SB/Core/x/xEnt.h b/src/SB/Core/x/xEnt.h index e0977846d..9cb27569e 100644 --- a/src/SB/Core/x/xEnt.h +++ b/src/SB/Core/x/xEnt.h @@ -184,6 +184,25 @@ struct xEnt : xBase void* user_data; // 0xCC }; +// Ent flags (xEnt::flags) +#define k_XENT_IS_VISIBLE ((U8)(1 << 0)) +#define k_XENT_IS_STACKED ((U8)(1 << 1)) +#define k_XENT_0x10 ((U8)(1 << 4)) +#define k_XENT_0x40 ((U8)(1 << 6)) +#define k_XENT_0x80 ((U8)(1 << 7)) + +// Physics flags (xEnt::pflags) +#define k_XENT_IS_MOVING ((U8)(1 << 0)) +#define k_XENT_HAS_VELOCITY ((U8)(1 << 1)) +#define k_XENT_HAS_GRAVITY ((U8)(1 << 2)) +#define k_XENT_HAS_DRAG ((U8)(1 << 3)) +#define k_XENT_HAS_FRICTION ((U8)(1 << 4)) + +// More ent flags (xEnt::moreFlags) +#define k_MORE_FLAGS_0x8 ((U8)1 << 3) +#define k_MORE_FLAGS_HITTABLE ((U8)1 << 4) +#define k_MORE_FLAGS_ANIM_COLL ((U8)1 << 5) + // collision types #define XENT_COLLTYPE_NONE 0x0 #define XENT_COLLTYPE_TRIG 0x1 // trigger (TRIG) diff --git a/src/SB/Core/x/xEntMotion.cpp b/src/SB/Core/x/xEntMotion.cpp index 39a84b177..c294f14c4 100644 --- a/src/SB/Core/x/xEntMotion.cpp +++ b/src/SB/Core/x/xEntMotion.cpp @@ -284,11 +284,6 @@ void xEntMotionMove(xEntMotion*, xScene*, F32, xEntFrame*) { } -F32 xSpline3_ArcTotal(xSpline3*) -{ - return 0.0f; -} - void xQuatCopy(xQuat* a, const xQuat* b) { a->s = b->s; diff --git a/src/SB/Core/x/xMath.h b/src/SB/Core/x/xMath.h index 8f1ca7f21..4156b6d26 100644 --- a/src/SB/Core/x/xMath.h +++ b/src/SB/Core/x/xMath.h @@ -8,6 +8,7 @@ #define MAX(a, b) (((a) > (b)) ? (a) : (b)) #define MIN(a, b) (((a) < (b)) ? (a) : (b)) #define xabs(x) iabs(x) +#define xeq(a, b, e) (xabs((a) - (b)) <= (e)) #define CLAMP(x, a, b) (MAX((a), MIN((x), (b)))) diff --git a/src/SB/Core/x/xMath3.h b/src/SB/Core/x/xMath3.h index c7cc0d56c..959416f5b 100644 --- a/src/SB/Core/x/xMath3.h +++ b/src/SB/Core/x/xMath3.h @@ -6,6 +6,9 @@ #include "xVec3.h" #include "xVec3Inlines.h" +#define XRAY3_USE_MIN (1 << 10) +#define XRAY3_USE_MAX (1 << 11) + // Size: 0x30 struct xMat3x3 { diff --git a/src/SB/Core/x/xRumble.h b/src/SB/Core/x/xRumble.h index f161cf139..12323f7b2 100644 --- a/src/SB/Core/x/xRumble.h +++ b/src/SB/Core/x/xRumble.h @@ -3,7 +3,7 @@ #include -enum _tagRumbleType +typedef enum _tagRumbleType { eRumble_Off, eRumble_Hi, @@ -19,7 +19,7 @@ enum _tagRumbleType eRumble_VeryHeavy, eRumble_Total, eRumbleForceU32 = 0x7fffffff -}; +} xRumbleType; struct _tagxRumble { diff --git a/src/SB/Core/x/xSpline.h b/src/SB/Core/x/xSpline.h index 50a103e4a..df4d6acb1 100644 --- a/src/SB/Core/x/xSpline.h +++ b/src/SB/Core/x/xSpline.h @@ -32,6 +32,12 @@ struct xSpline3 }; void xSpline3_ArcInit(xSpline3* spl, U32 sample); -xSpline3* xSpline3_Bezier(xVec3* points, F32* time, U32 numpoints, U32 numalloc, xVec3* p1, xVec3* p2); +xSpline3* xSpline3_Bezier(xVec3* points, F32* time, U32 numpoints, U32 numalloc, xVec3* p1, + xVec3* p2); + +inline F32 xSpline3_ArcTotal(xSpline3* spl) +{ + return spl->arcLength[spl->N * spl->arcSample - 1]; +} #endif diff --git a/src/SB/Core/x/xutil.h b/src/SB/Core/x/xutil.h index 313356b01..ca66fb0b3 100644 --- a/src/SB/Core/x/xutil.h +++ b/src/SB/Core/x/xutil.h @@ -11,6 +11,43 @@ 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 static inline T xUtil_choose(const T* list, S32 cnt, const F32* wts) +{ + if (!list) + return 0; + if (cnt < 1) + return 0; + + S32 idx = 0; + F32 pt = xurand(); + + if (!wts) + { + idx = (S32)(pt * cnt); + } + else + { + F32 hi = 0.0f; + for (S32 i = 0; i < cnt; i++) + { + F32 lo = hi; + hi += wts[i]; + if (pt >= lo && pt <= hi) + { + idx = i; + break; + } + } + } + + if (idx >= cnt) + idx = cnt - 1; + if (idx < 0) + idx = 0; + + return list[idx]; +} + template static T* xUtil_select(T** arg0, S32 arg1, const F32* arg3); #endif diff --git a/src/SB/Game/zMovePoint.h b/src/SB/Game/zMovePoint.h index 3b45bd91e..f684de81d 100644 --- a/src/SB/Game/zMovePoint.h +++ b/src/SB/Game/zMovePoint.h @@ -23,6 +23,10 @@ struct zMovePoint : xMovePoint } U32 NumNodes(); S32 IsOn(); + S32 HasSpline() + { + return spl != NULL; + } }; zMovePoint* zMovePoint_GetMemPool(S32 cnt); diff --git a/src/SB/Game/zNPCGoalVillager.h b/src/SB/Game/zNPCGoalVillager.h index e37fb6573..bbb0da4c8 100644 --- a/src/SB/Game/zNPCGoalVillager.h +++ b/src/SB/Game/zNPCGoalVillager.h @@ -167,13 +167,6 @@ struct zNPCGoalBoySwim : zNPCGoalCommon } }; -struct NPCSndProp -{ - en_NPC_SOUND sndtype; - int flg_snd; - float tym_delayNext; -}; - xFactoryInst* GOALCreate_Villager(S32 who, RyzMemGrow* grow, void*); #endif diff --git a/src/SB/Game/zNPCGoals.h b/src/SB/Game/zNPCGoals.h index f5d081df3..8aafc912a 100644 --- a/src/SB/Game/zNPCGoals.h +++ b/src/SB/Game/zNPCGoals.h @@ -182,7 +182,12 @@ enum en_NPCGOALS NPC_GOAL_TIKIHIDE, NPC_GOAL_TIKICOUNT, NPC_GOAL_TIKIDYING, - NPC_GOAL_TIKIDEAD + NPC_GOAL_TIKIDEAD, + // I don't remember why i added these tbh + // - Colin + NPC_GOAL_DEV_ANIMCYCLE = 'NGX0', + NPC_GOAL_DEV_ANIMSPIN, + NPC_GOAL_DEV_HERO, }; struct xFactory; diff --git a/src/SB/Game/zNPCMessenger.h b/src/SB/Game/zNPCMessenger.h index 9f73d480e..9a0a011e5 100644 --- a/src/SB/Game/zNPCMessenger.h +++ b/src/SB/Game/zNPCMessenger.h @@ -32,4 +32,8 @@ struct NPCPSData st_XORDEREDARRAY quelist; // offset 0x20, size 0x10 }; +void zNPCMsg_SendMsg(en_NPC_MSG_ID msgevent, zNPCCommon* npc_sendto); +void zNPCMsg_SendMsg(NPCMsg* inmsg, zNPCCommon* npc_sendto); +void zNPCMsg_SendMsg(NPCMsg* inmsg, F32 delay, zNPCCommon* npc_sendto); + #endif diff --git a/src/SB/Game/zNPCSndTable.h b/src/SB/Game/zNPCSndTable.h index 717d41611..b290ff7a1 100644 --- a/src/SB/Game/zNPCSndTable.h +++ b/src/SB/Game/zNPCSndTable.h @@ -52,10 +52,24 @@ struct NPCSndQueue //0x14 F32 radius; //0x10 }; +struct NPCSndProp +{ + en_NPC_SOUND sndtype; + int flg_snd; + float tym_delayNext; +}; + void NPCS_Startup(); void NPCS_SndTimersReset(); void NPCS_SndTimersUpdate(F32 dt); void NPCS_SndTablePrepare(NPCSndTrax* trax); +void NPCS_SndTypePlayed(en_NPC_SOUND sndtype, F32 delayNext); + void NPCS_Shutdown(); +S32 NPCS_SndOkToPlay(en_NPC_SOUND sndtype); + +NPCSndProp* NPCS_SndFindProps(en_NPC_SOUND sndtype); +en_NPC_SOUND NPCS_SndTypeFromHash(U32 aid_snd, NPCSndTrax* cust, NPCSndTrax* share); +U32 NPCS_SndPickSimilar(en_NPC_SOUND sndtype, NPCSndTrax* cust, NPCSndTrax* share); #endif diff --git a/src/SB/Game/zNPCSupplement.h b/src/SB/Game/zNPCSupplement.h index efb1a8eb9..a56fb1e26 100644 --- a/src/SB/Game/zNPCSupplement.h +++ b/src/SB/Game/zNPCSupplement.h @@ -43,7 +43,8 @@ enum en_npcstreak NPC_STRK_FORCE = 0x7fffffff }; -enum en_nparmode { +enum en_nparmode +{ NPAR_MODE_STD = 0, NPAR_MODE_ALT_A = 1, NPAR_MODE_ALT_B = 2, @@ -97,7 +98,8 @@ struct NPARXtraData { }; -class NPARParmVisSplash { +class NPARParmVisSplash +{ // total size: 0x20 public: F32 tym_lifespan; // offset 0x0, size 0x4 @@ -109,7 +111,8 @@ class NPARParmVisSplash { void ConfigPar(NPARData* par, en_nparmode pmod, const xVec3* pos, const xVec3* vel) const; }; -class NPARParmTarTarGunk { +class NPARParmTarTarGunk +{ // total size: 0x28 public: F32 tym_lifespan; // offset 0x0, size 0x4 @@ -124,7 +127,8 @@ class NPARParmTarTarGunk { void ConfigPar(NPARData*, en_nparmode, const xVec3*, const xVec3*) const; }; -class NPARParmFahrwerkz { +class NPARParmFahrwerkz +{ // total size: 0x28 public: F32 tym_lifespan; // offset 0x0, size 0x4 @@ -139,7 +143,8 @@ class NPARParmFahrwerkz { void ConfigPar(NPARData*, en_nparmode, const xVec3*, const xVec3*) const; }; -class NPARParmSleepyZeez { +class NPARParmSleepyZeez +{ // total size: 0x28 public: F32 tym_lifespan; // offset 0x0, size 0x4 @@ -154,7 +159,8 @@ class NPARParmSleepyZeez { void ConfigPar(NPARData*, en_nparmode, const xVec3*, const xVec3*) const; }; -class NPARParmDogBreath { +class NPARParmDogBreath +{ // total size: 0x20 public: F32 tym_lifespan; // offset 0x0, size 0x4 @@ -167,7 +173,8 @@ class NPARParmDogBreath { void ConfigPar(NPARData* par, en_nparmode pmod, const xVec3* pos, const xVec3* vel) const; }; -class NPARParmGloveDust { +class NPARParmGloveDust +{ // total size: 0x1C public: F32 tym_lifespan; // offset 0x0, size 0x4 @@ -216,7 +223,8 @@ class NPARParmTubeSpiral void ConfigPar(NPARData*, en_nparmode, const xVec3*, const xVec3*, F32 dt) const; }; -class NPARParmChuckSplash { +class NPARParmChuckSplash +{ // total size: 0x20 public: F32 tym_lifespan; // offset 0x0, size 0x4 @@ -282,6 +290,7 @@ void NPAR_ScenePrepare(); void NPAR_SceneFinish(); void NPAR_EmitTarTarTrail(const xVec3*, const xVec3*); NPARMgmt* NPAR_PartySetup(en_nparptyp parType, void** userData, NPARXtraData* xtraData); +void NPAR_EmitFWExhaust(const xVec3* pos, const xVec3* vel); void NPAR_SceneReset(); static void NPCC_ShadowCacheReset(); void NPAR_Timestep(F32 dt); diff --git a/src/SB/Game/zNPCSupport.cpp b/src/SB/Game/zNPCSupport.cpp index 0c04cd95e..1a8925bd1 100644 --- a/src/SB/Game/zNPCSupport.cpp +++ b/src/SB/Game/zNPCSupport.cpp @@ -8,17 +8,33 @@ #include "zNPCHazard.h" #include "zNPCGlyph.h" #include "zNPCSupplement.h" +#include "zNPCMgr.h" +#include "zNPCTypeRobot.h" +#include "zNPCFXCinematic.h" #include "xMathInlines.h" #include "xMath3.h" #include "xUtil.h" #include "xBound.h" +#include "xQuickCull.h" +#include "xCollide.h" + +#define MAX_FIREWORK 32 + +static NPCWidget g_npc_widgets[NPC_WIDGE_NOMORE]; +static U32 g_hash_uiwidgets[NPC_WIDGE_NOMORE] = {}; +static const char* g_strz_uiwidgets[NPC_WIDGE_NOMORE] = { "MNU4 NPCTALK" }; + +static U32 sNPCSndFx[eNPCSnd_Total] = {}; +static U32 sNPCSndID[eNPCSnd_Total] = {}; +static F32 sNPCSndFxVolume[eNPCSnd_Total] = {}; + +static Firework g_fireworks[MAX_FIREWORK]; + +F32 Firework::acc_thrust = 15.0f; +F32 Firework::acc_gravity = -10.0f; -NPCWidget g_npc_widgets[1] = {}; -static U32 g_hash_uiwidgets[1] = { 0 }; -static char* g_strz_uiwidgets[1] = { "MNU4 NPCTALK" }; S32 g_pc_playerInvisible; -static Firework g_fireworks[32]; void NPCSupport_Startup() { @@ -83,7 +99,10 @@ void NPCSupport_Timestep(F32 dt) void NPCWidget_Startup() { - g_hash_uiwidgets[0] = xStrHash((const char*)g_strz_uiwidgets); + for (S32 i = 0; i < NPC_WIDGE_NOMORE; i++) + { + g_hash_uiwidgets[i] = xStrHash(g_strz_uiwidgets[i]); + } } void NPCWidget_Shutdown() @@ -108,9 +127,9 @@ void NPCWidget::Reset() { } -U32 NPCWidget::On(const zNPCCommon* npc, int theman) +S32 NPCWidget::On(const zNPCCommon* npc, S32 theman) { - if ((!theman && !NPCIsTheLocker(npc)) && (((S32)IsLocked()) || (!Lock(npc)))) + if ((!theman && !NPCIsTheLocker(npc)) && ((IsLocked()) || (!Lock(npc)))) { return 0; } @@ -128,6 +147,23 @@ U32 NPCWidget::On(const zNPCCommon* npc, int theman) return 1; } +S32 NPCWidget::Off(const zNPCCommon* npc, S32 theman) +{ + if (!theman && !this->NPCIsTheLocker(npc)) + { + return 0; + } + + if (npc) + { + this->Unlock(npc); + } + + zEntEvent(this->base_widge, eEventInvisible); + zEntEvent(this->base_widge, eEventUIFocusOff_Unselect); + return 1; +} + S32 NPCWidget::Unlock(const zNPCCommon* npc) { if (npc_ownerlock == NULL) @@ -192,7 +228,8 @@ NPCWidget* NPCWidget_Find(en_NPC_UI_WIDGETS which) void NPCWidget::Init(en_NPC_UI_WIDGETS which) { - base_widge = zSceneFindObject(g_hash_uiwidgets[idxID = which]); + this->idxID = which; + this->base_widge = zSceneFindObject(g_hash_uiwidgets[this->idxID]); } void NPCTarget::TargetSet(xEnt* ent, int b) @@ -217,6 +254,322 @@ void NPCTarget::TargetClear() typ_target = NPC_TGT_NONE; } +S32 NPCTarget::FindNearest(S32 flg_consider, xBase* skipme, xVec3* from, F32 dst_max) +//NONMATCH("https://decomp.me/scratch/wWBRW") +{ + S32 found = 0; + st_XORDEREDARRAY* npclist; + F32 ds2_best; + zNPCCommon *npc, *npc_best; + xVec3 vec = {}; + F32 fv; + S32 i, ntyp; + + npc_best = NULL; + ds2_best = (dst_max < 0.0f) ? HUGE : SQ(dst_max); + + if (flg_consider & 0x1) + { + this->TargetSet(&globals.player.ent, 1); + + if (from) + { + xVec3Sub(&vec, xEntGetPos(&globals.player.ent), from); + ds2_best = xVec3Length2(&vec); + } + } + + if (from && (flg_consider & 0x1E)) + { + npclist = zNPCMgr_GetNPCList(); + + for (i = 0; i < npclist->cnt; i++) + { + npc = (zNPCCommon*)npclist->list[i]; + ntyp = npc->SelfType(); + + if (npc == skipme) + continue; + + if (((ntyp & 0xFFFFFF00) != 'NTT\0' || (flg_consider & 0x4)) && + ((ntyp & 0xFFFFFF00) != 'NTR\0' || (flg_consider & 0x2)) && + ((ntyp & 0xFFFFFF00) != 'NTF\0' || (flg_consider & 0x8)) && + ((ntyp & 0xFFFFFF00) != 'NTA\0' || (flg_consider & 0x10))) + { + if (npc->IsAlive()) + { + xVec3Sub(&vec, xEntGetPos(npc), from); + if (flg_consider & 0x80) + { + vec.y = 0.0f; + } + + fv = xVec3Length2(&vec); + if (fv > ds2_best) + continue; + + ds2_best = fv; + npc_best = npc; + found = 1; + } + } + } + + if (found) + { + this->TargetSet(npc_best, 0); + } + } + + return found; +} + +S32 NPCTarget::InCylinder(xVec3* from, F32 rad, F32 hyt, F32 off) +{ + S32 inrange = 1; + + xVec3 vec = {}; + this->PosGet(&vec); + xVec3SubFrom(&vec, from); + + F32 upper = hyt + off; + F32 lower = upper - hyt; + + if (vec.y > upper) + { + inrange = 0; + } + else if (vec.y < lower) + { + inrange = 0; + } + else if (xVec3Length2(&vec) > SQ(rad)) + { + inrange = 0; + } + + return inrange; +} + +S32 NPCTarget::IsDead() +{ + S32 dead = 0; + + switch (this->typ_target) + { + case NPC_TGT_PLYR: + if (globals.player.Health < 1) + { + dead = 1; + } + break; + case NPC_TGT_ENT: + if (this->ent_target->baseType == eBaseTypeNPC) + { + if (!((zNPCCommon*)this->ent_target)->IsAlive()) + { + dead = 1; + } + } + break; + case NPC_TGT_BASE: + break; + } + + return dead; +} + +// void NPCLaser::Render(xVec3* pos_src, xVec3* pos_tgt) +// //NONMATCH("https://decomp.me/scratch/lNgTd") +// { +// xVec3 var_70; +// xVec3Copy(&var_70, pos_src); + +// xVec3 var_7C; +// xVec3Copy(&var_7C, pos_tgt); + +// xVec3 var_88; +// xVec3Sub(&var_88, &var_7C, &var_70); +// xVec3Normalize(&var_88, &var_88); + +// xVec3 var_94; +// xVec3Cross(&var_94, &globals.camera.mat.at, &var_88); + +// F32 f1 = xVec3Length2(&var_94); +// if (f1 < 0.00001f) +// { +// xVec3Copy(&var_94, &g_X3); +// } +// else +// { +// xVec3SMulBy(&var_94, 1.0f / xsqrt(f1)); +// } + +// xVec3 var_A0; +// xVec3Cross(&var_A0, &var_94, &var_88); + +// S32 i; + +// static RwIm3DVertex laser_vtxbuf[2][14]; +// RwIm3DVertex* vtx_horz = laser_vtxbuf[0]; +// RwIm3DVertex* vtx_vert = laser_vtxbuf[1]; + +// for (i = 0; i <= 6; i++) +// { +// F32 rat = (F32)i / 6.0f; +// F32 f29 = LERP(rat, this->radius[0], this->radius[1]); + +// xVec3 var_AC; +// var_AC.x = LERP(rat, var_70.x, var_7C.x); +// var_AC.y = LERP(rat, var_70.y, var_7C.y); +// var_AC.z = LERP(rat, var_70.z, var_7C.z); + +// U8 r22 = LERP(rat, this->rgba[0].red, this->rgba[1].red); +// U8 r23 = LERP(rat, this->rgba[0].green, this->rgba[1].green); +// U8 r24 = LERP(rat, this->rgba[0].blue, this->rgba[1].blue); +// U8 r25 = LERP(rat, this->rgba[0].alpha, this->rgba[1].alpha); + +// F32 u = 1.0f - rat + this->uv_base[0]; +// F32 v = 1.0f - rat + this->uv_base[1]; + +// while (u > 1.0f) +// u -= 1.0f; +// while (v > 1.0f) +// v -= 1.0f; + +// xVec3 var_B8; + +// xVec3SMul(&var_B8, &var_94, f29); +// xVec3AddTo(&var_B8, &var_AC); +// RwIm3DVertexSetPos(&vtx_horz[0], var_B8.x, var_B8.y, var_B8.z); +// RwIm3DVertexSetRGBA(&vtx_horz[0], r22, r23, r24, r25); +// RwIm3DVertexSetU(&vtx_horz[0], 0.0f); +// RwIm3DVertexSetV(&vtx_horz[0], v); + +// xVec3SMul(&var_B8, &var_94, -f29); +// xVec3AddTo(&var_B8, &var_AC); +// RwIm3DVertexSetPos(&vtx_horz[1], var_B8.x, var_B8.y, var_B8.z); +// RwIm3DVertexSetRGBA(&vtx_horz[1], r22, r23, r24, r25); +// RwIm3DVertexSetU(&vtx_horz[1], 1.0f); +// RwIm3DVertexSetV(&vtx_horz[1], v); + +// vtx_horz += 2; + +// xVec3SMul(&var_B8, &var_A0, f29); +// xVec3AddTo(&var_B8, &var_AC); +// RwIm3DVertexSetPos(&vtx_vert[0], var_B8.x, var_B8.y, var_B8.z); +// RwIm3DVertexSetRGBA(&vtx_vert[0], r22, r23, r24, r25); +// RwIm3DVertexSetU(&vtx_vert[0], 0.0f); +// RwIm3DVertexSetV(&vtx_vert[0], v); + +// xVec3SMul(&var_B8, &var_A0, -f29); +// xVec3AddTo(&var_B8, &var_AC); +// RwIm3DVertexSetPos(&vtx_vert[1], var_B8.x, var_B8.y, var_B8.z); +// RwIm3DVertexSetRGBA(&vtx_vert[1], r22, r23, r24, r25); +// RwIm3DVertexSetU(&vtx_vert[1], 1.0f); +// RwIm3DVertexSetV(&vtx_vert[1], v); + +// vtx_vert += 2; +// } + +// SDRenderState old_rendstat = zRenderStateCurrent(); +// if (old_rendstat == SDRS_Unknown) +// { +// old_rendstat = SDRS_Default; +// } + +// zRenderState(SDRS_NPCVisual); + +// RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void*)this->rast_laser); +// RwIm3DTransform(laser_vtxbuf[0], 14, NULL, +// rwIM3D_VERTEXXYZ | rwIM3D_VERTEXRGBA | rwIM3D_VERTEXUV); +// RwIm3DRenderPrimitive(rwPRIMTYPETRISTRIP); +// RwIm3DEnd(); + +// RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void*)this->rast_laser); +// RwIm3DTransform(laser_vtxbuf[1], 14, NULL, +// rwIM3D_VERTEXXYZ | rwIM3D_VERTEXRGBA | rwIM3D_VERTEXUV); +// RwIm3DRenderPrimitive(rwPRIMTYPETRISTRIP); +// RwIm3DEnd(); + +// zRenderState(old_rendstat); +// } + +// void NPCCone::RenderCone(xVec3* pos_tiptop, xVec3* pos_botcenter) +// //NONMATCH("https://decomp.me/scratch/G9pbs") +// { +// RwRGBA rgba_top = this->rgba_top; +// RwRGBA rgba_bot = this->rgba_bot; +// xVec3 pos_top = *pos_tiptop; +// xVec3 pos_bot = *pos_botcenter; +// F32 f29 = this->uv_tip[0] + 0.5f * this->uv_slice[0]; +// F32 f28 = this->uv_tip[1]; +// F32 f31 = this->uv_tip[0] + this->uv_slice[0]; +// F32 f30 = this->uv_tip[1] + this->uv_slice[1]; + +// void* mem = xMemPushTemp(10 * sizeof(RwIm3DVertex)); +// if (!mem) +// { +// return; +// } + +// memset(mem, 0, 10 * sizeof(RwIm3DVertex)); + +// RwIm3DVertex* vert_list = (RwIm3DVertex*)mem; +// RwIm3DVertex* vtx = vert_list + 1; + +// RwIm3DVertexSetPos(&vert_list[0], pos_top.x, pos_top.y, pos_top.z); +// RwIm3DVertexSetRGBA(&vert_list[0], rgba_top.red, rgba_top.green, rgba_top.blue, rgba_top.alpha); +// RwIm3DVertexSetU(&vert_list[0], f29); +// RwIm3DVertexSetV(&vert_list[0], f28); + +// for (S32 i = 0; i < 8; i++) +// { +// F32 ang_seg = i * PI / 4; +// F32 f29 = isin(ang_seg); +// F32 f1 = icos(ang_seg); + +// xVec3 var_A0; +// var_A0.x = f29; +// var_A0.y = 0.0f; +// var_A0.z = f1; +// var_A0 *= this->rad_cone; +// var_A0 += pos_bot; + +// RwIm3DVertexSetPos(vtx, var_A0.x, var_A0.y, var_A0.z); +// RwIm3DVertexSetRGBA(vtx, rgba_bot.red, rgba_bot.green, rgba_bot.blue, rgba_bot.alpha); + +// F32 f0 = 1 / 8.0f * i; + +// RwIm3DVertexSetU(vtx, f31 + f0); +// RwIm3DVertexSetV(vtx, f30); + +// vtx++; +// } + +// *vtx = vert_list[1]; +// RwIm3DVertexSetU(vtx, f31 + this->uv_slice[0]); +// RwIm3DVertexSetV(vtx, f30); + +// SDRenderState old_rendstat = zRenderStateCurrent(); +// if (old_rendstat == SDRS_Unknown) +// { +// old_rendstat = SDRS_Default; +// } + +// zRenderState(SDRS_NPCVisual); + +// RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); +// RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void*)this->rast_cone); +// RwIm3DTransform(vert_list, 10, NULL, rwIM3D_VERTEXXYZ | rwIM3D_VERTEXRGBA | rwIM3D_VERTEXUV); +// RwIm3DRenderPrimitive(rwPRIMTYPETRIFAN); +// RwIm3DEnd(); + +// zRenderState(old_rendstat); + +// xMemPopTemp(mem); +// } + void NPCBlinker::Reset() { tmr_uvcell = -1.0f; @@ -270,6 +623,44 @@ void Firework::Cleanup() { } +void Firework::Update(F32 dt) +{ + switch (this->fwstate) + { + case FW_STAT_FLIGHT: + this->FlyFlyFly(dt); + if (this->tmr_remain < 0.0f) + { + this->fwstate = FW_STAT_BOOM; + } + break; + case FW_STAT_BOOM: + this->Detonate(); + this->fwstate = FW_STAT_DONE; + break; + case FW_STAT_DONE: + break; + } + + this->tmr_remain = MAX(-1.0f, this->tmr_remain - dt); +} + +void Firework::FlyFlyFly(F32 dt) //NONMATCH("https://decomp.me/scratch/6hPC3") +{ + F32 pam_life = 1.0f - CLAMP(this->tmr_remain / this->tym_lifespan, 0.0f, 1.0f); + if (pam_life < 0.75f) + { + xVec3 dir_trav = this->vel; + dir_trav.normalize(); + + this->vel += dir_trav * (Firework::acc_thrust * dt); + } + + this->vel += g_NY3 * (Firework::acc_gravity * dt); + + NPAR_EmitFWExhaust(&this->pos, &g_O3); +} + void NPAR_EmitFWExhaust(xVec3* pos, xVec3* vel); void Firework::Detonate() @@ -284,14 +675,136 @@ void NPCC_ang_toXZDir(F32 angle, xVec3* dir) dir->z = icos(angle); } -void NPCC_dir_toXZAng(const xVec3* vec) +F32 NPCC_dir_toXZAng(const xVec3* dir) { - xatan2(vec->x, vec->z); + return xatan2(dir->x, dir->z); } void NPCC_aimMiss(xVec3* dir_aim, xVec3* pos_src, xVec3* pos_tgt, F32 dst_miss, xVec3* pos_miss) { - NPCC_aimVary(dir_aim, pos_src, pos_tgt, dst_miss, 8, pos_miss); + NPCC_aimVary(dir_aim, pos_src, pos_tgt, dst_miss, 8, pos_miss); +} + +F32 NPCC_aimVary(xVec3* dir_aim, xVec3* pos_src, xVec3* pos_tgt, F32 dst_vary, S32 flg_vary, + xVec3* pos_aimPoint) //NONMATCH("https://decomp.me/scratch/D1gIj") +{ + F32 dst_toFake = 0.0f; + xVec3 dir_left = {}; + xVec3 dir_toFake = {}; + xVec3 dir_toReal = {}; + xVec3 vec_offset = {}; + xVec3 pos_tgtFake = {}; + + xVec3Sub(&dir_toReal, pos_tgt, pos_src); + + if (flg_vary & 0x10) + { + dir_toReal.y = 0.0f; + } + + F32 mag_vary = xVec3Length(&dir_toReal); + if (mag_vary < 0.001f) + { + if (mag_vary > 0.0f) + { + xVec3SMulBy(&dir_toReal, 100000.0f); + xVec3Normalize(&dir_toReal, &dir_toReal); + } + else + { + xVec3Copy(dir_aim, &g_X3); + } + + if (pos_aimPoint) + { + xVec3Copy(pos_aimPoint, pos_tgt); + } + + return mag_vary; + } + + xVec3SMulBy(&dir_toReal, 1.0f / mag_vary); + xVec3Cross(&dir_left, &g_Y3, &dir_toReal); + + F32 mag_updown; + if (flg_vary & 0x8) + { + mag_updown = dst_vary; + } + else + { + mag_updown = 2.0f * (xurand() - 0.5f) * dst_vary; + + F32 fv; + if ((flg_vary & 0x1) && (flg_vary & 0x2)) + { + fv = 2.0f * (xurand() - 0.5f); + } + else if (flg_vary == 0x1) + { + fv = xurand(); + } + else if (flg_vary == 0x2) + { + fv = -xurand(); + } + else + { + fv = 0.0f; + } + + dst_toFake = fv * dst_vary; + } + + xVec3AddScaled(&vec_offset, &dir_left, mag_updown); + xVec3AddScaled(&vec_offset, &g_Y3, dst_toFake); + xVec3Add(&pos_tgtFake, pos_tgt, &vec_offset); + xVec3Sub(&dir_toFake, &pos_tgtFake, pos_src); + + F32 f31 = xVec3Normalize(&dir_toFake, dir_aim); + + if (pos_aimPoint) + { + xVec3Copy(pos_aimPoint, &pos_tgtFake); + } + + return (flg_vary & 0x4) ? f31 : mag_vary; +} + +S32 NPCC_chk_hitPlyr(xBound* bnd, xCollis* collide) +{ + return NPCC_chk_hitEnt(&globals.player.ent, bnd, collide); +} + +S32 NPCC_chk_hitEnt(xEnt* tgt, xBound* bnd, + xCollis* collide) //NONMATCH("https://decomp.me/scratch/Bf1rk") +{ + S32 hittgt = 0; + xCollis* colrec; + xCollis lcl_collide = {}; + + colrec = collide ? collide : &lcl_collide; + colrec->optr = tgt; + colrec->oid = tgt->id; + + if (collide) + { + colrec->flags = k_HIT_0xF00 | k_HIT_CALC_HDNG; + } + else + { + colrec->flags = 0; + } + + xQuickCullForEverything(&bnd->qcd); + xBoundHitsBound(bnd, &tgt->bound, colrec); + + if (colrec->flags & k_HIT_IT) + { + hittgt = 1; + } + + return hittgt; } void Firework_SceneReset(int param_1) @@ -370,8 +883,82 @@ RwRaster* NPCC_FindRWRaster(RwTexture* txtr) return NULL; } -void zNPC_SNDInit() +void NPCC_GenSmooth(xVec3** pos_base, + xVec3** pos_mid) //WIP NONMATCH("https://decomp.me/scratch/1MplX") { + static F32 prepute[4][4]; + static const F32 yews[4] = { 0.25f, 0.5f, 0.75f, 1.0f }; + static S32 init = 0; + + S32 i; + + if (!init) + { + init = 1; + + for (i = 0; i < 4; i++) + { + F32 u = yews[i]; + F32 u2 = u * u; + F32 u3 = u * u2; + + prepute[i][0] = u2 + -0.5f * u3 + -0.5f * u; + prepute[i][1] = -2.5f * u2 + 1.5f * u3 + 1.0f; + prepute[i][2] = 2.0f * u2 + -1.5f * u3 + 0.5f * u; + prepute[i][3] = -0.5f * u2 + 0.5f * u3; + } + } + + for (i = 0; i < 4; i++) + { + xVec3SMul(pos_mid[i], pos_base[0], prepute[i][0]); + xVec3AddScaled(pos_mid[i], pos_base[1], prepute[i][1]); + xVec3AddScaled(pos_mid[i], pos_base[2], prepute[i][2]); + xVec3AddScaled(pos_mid[i], pos_base[3], prepute[i][3]); + } +} + +void zNPC_SNDInit() //NONMATCH("https://decomp.me/scratch/VlDh8") +{ + sNPCSndID[eNPCSnd_GloveAttack] = 0; + sNPCSndID[eNPCSnd_SleepyAttack] = 0; + sNPCSndID[eNPCSnd_TubeAttack] = 0; + sNPCSndID[eNPCSnd_FodBzztAttack] = 0; + sNPCSndID[eNPCSnd_JellyfishAttack] = 0; + + sNPCSndFxVolume[eNPCSnd_GloveAttack] = 0.77f; + sNPCSndFxVolume[eNPCSnd_SleepyAttack] = 0.77f; + sNPCSndFxVolume[eNPCSnd_TubeAttack] = 0.77f; + sNPCSndFxVolume[eNPCSnd_FodBzztAttack] = 0.77f; + sNPCSndFxVolume[eNPCSnd_JellyfishAttack] = 0.77f; + + sNPCSndFx[eNPCSnd_GloveAttack] = xStrHash("Glove_hover_loop"); + sNPCSndFx[eNPCSnd_SleepyAttack] = xStrHash("ST_hit2_loop"); + sNPCSndFx[eNPCSnd_TubeAttack] = xStrHash("Tube_attack21_loop"); + sNPCSndFx[eNPCSnd_FodBzztAttack] = xStrHash("FodBzzt_attack_loop"); + sNPCSndFx[eNPCSnd_JellyfishAttack] = xStrHash("Jellyfish_zap_loop"); +} + +void zNPC_SNDPlay3D(eNPCSnd snd, xEnt* ent) +{ + if (globals.cmgr) + return; + if (sNPCSndID[snd] != 0) + return; + if (sNPCSndFx[snd] == 0) + return; + + sNPCSndID[snd] = xSndPlay3D(sNPCSndFx[snd], sNPCSndFxVolume[snd], 0.0f, 0x80, 0, ent, 2.0f, + 15.0f, SND_CAT_GAME, 0.0f); +} + +void zNPC_SNDStop(eNPCSnd snd) +{ + if (sNPCSndFx[snd] == 0) + return; + + xSndStop(sNPCSndID[snd]); + sNPCSndID[snd] = 0; } U32 NPCC_LineHitsBound(xVec3* param_1, xVec3* param_2, xBound* param_3, xCollis* param_4) @@ -384,7 +971,7 @@ U32 NPCC_LineHitsBound(xVec3* param_1, xVec3* param_2, xBound* param_3, xCollis* if (param_4 != NULL) { - colrec = (xCollis *)param_4; + colrec = (xCollis*)param_4; } xVec3Sub(&vec, param_2, param_1); len = xVec3Length(&vec); @@ -407,74 +994,74 @@ S32 NPCC_bnd_ofBase(xBase* tgt, xBound* bnd) { S32 retval = 1; - switch(tgt->baseType) - { - case eBaseTypeCamera: - case eBaseTypeDoor: - case eBaseTypeVolume: - case eBaseTypeEGenerator: - retval = 0; - break; - case eBaseTypePlayer: - case eBaseTypePickup: - case eBaseTypePlatform: - case eBaseTypeStatic: - case eBaseTypeDynamic: - case eBaseTypeBubble: - case eBaseTypePendulum: - case eBaseTypeHangable: - case eBaseTypeButton: - case eBaseTypeProjectile: - case eBaseTypeDestructObj: - case eBaseTypeNPC: - case eBaseTypeBoulder: - *bnd = *(xBound*)((int)tgt + 0x64); - break; - default: - retval = 0; - break; - case eBaseTypeCruiseBubble: - break; + switch (tgt->baseType) + { + case eBaseTypeCamera: + case eBaseTypeDoor: + case eBaseTypeVolume: + case eBaseTypeEGenerator: + retval = 0; + break; + case eBaseTypePlayer: + case eBaseTypePickup: + case eBaseTypePlatform: + case eBaseTypeStatic: + case eBaseTypeDynamic: + case eBaseTypeBubble: + case eBaseTypePendulum: + case eBaseTypeHangable: + case eBaseTypeButton: + case eBaseTypeProjectile: + case eBaseTypeDestructObj: + case eBaseTypeNPC: + case eBaseTypeBoulder: + *bnd = *(xBound*)((int)tgt + 0x64); + break; + default: + retval = 0; + break; + case eBaseTypeCruiseBubble: + break; } return retval; } S32 NPCC_pos_ofBase(xBase* tgt, xVec3* pos) { - xVec3 *pxVar1; + xVec3* pxVar1; S32 retval = 1; - switch(tgt->baseType) - { - case eBaseTypeCamera: - xVec3Copy(pos, &globals.camera.mat.pos); - break; - case eBaseTypeCruiseBubble: - retval = 0; - break; - case eBaseTypePlayer: - case eBaseTypePickup: - case eBaseTypePlatform: - case eBaseTypeStatic: - case eBaseTypeDynamic: - case eBaseTypeBubble: - case eBaseTypePendulum: - case eBaseTypeHangable: - case eBaseTypeButton: - case eBaseTypeProjectile: - case eBaseTypeDestructObj: - case eBaseTypeNPC: - case eBaseTypeBoulder: - xVec3Copy(pos, xEntGetPos((xEnt *)tgt)); - break; - case eBaseTypeDoor: - case eBaseTypeVolume: - case eBaseTypeEGenerator: - retval = 0; - break; - default: - retval = 0; - break; + switch (tgt->baseType) + { + case eBaseTypeCamera: + xVec3Copy(pos, &globals.camera.mat.pos); + break; + case eBaseTypeCruiseBubble: + retval = 0; + break; + case eBaseTypePlayer: + case eBaseTypePickup: + case eBaseTypePlatform: + case eBaseTypeStatic: + case eBaseTypeDynamic: + case eBaseTypeBubble: + case eBaseTypePendulum: + case eBaseTypeHangable: + case eBaseTypeButton: + case eBaseTypeProjectile: + case eBaseTypeDestructObj: + case eBaseTypeNPC: + case eBaseTypeBoulder: + xVec3Copy(pos, xEntGetPos((xEnt*)tgt)); + break; + case eBaseTypeDoor: + case eBaseTypeVolume: + case eBaseTypeEGenerator: + retval = 0; + break; + default: + retval = 0; + break; } return retval; } @@ -483,19 +1070,19 @@ void NPCTarget::PosGet(xVec3* pos) { switch (typ_target) { - case NPC_TGT_NONE: - break; - case NPC_TGT_PLYR: - case NPC_TGT_ENT: - case NPC_TGT_BASE: - NPCC_pos_ofBase(bas_target, pos); - break; - case NPC_TGT_POS: - xVec3Copy(pos, &pos_target); - break; - case NPC_TGT_MVPT: - xVec3Copy(pos, zMovePointGetPos(nav_target)); - break; + case NPC_TGT_NONE: + break; + case NPC_TGT_PLYR: + case NPC_TGT_ENT: + case NPC_TGT_BASE: + NPCC_pos_ofBase(bas_target, pos); + break; + case NPC_TGT_POS: + xVec3Copy(pos, &pos_target); + break; + case NPC_TGT_MVPT: + xVec3Copy(pos, zMovePointGetPos(nav_target)); + break; } } @@ -523,6 +1110,66 @@ void NPCC_xBoundBack(xBound* bnd) } } +S32 NPCC_HaveLOSToPos(xVec3* pos_src, xVec3* pos_tgt, F32 dst_max, xBase* tgt, xCollis* colCallers) +//NONMATCH("https://decomp.me/scratch/LyDtk") +{ + S32 result; + xRay3 ray = {}; + xScene* xscn = globals.sceneCur; + xCollis* colrec; + + if (colCallers) + { + colrec = colCallers; + } + else + { + static xCollis localCollis = { k_HIT_0xF00 | k_HIT_CALC_HDNG }; + + memset(&localCollis, 0, sizeof(xCollis)); + localCollis.flags = k_HIT_0xF00 | k_HIT_CALC_HDNG; + + colrec = &localCollis; + } + + ray.min_t = 0.0f; + ray.max_t = dst_max; + + xVec3Sub(&ray.dir, pos_tgt, pos_src); + xVec3Normalize(&ray.dir, &ray.dir); + xVec3Copy(&ray.origin, pos_src); + + ray.flags = XRAY3_USE_MIN | XRAY3_USE_MAX; + + xRayHitsScene(xscn, &ray, colrec); + + if (!(colrec->flags & k_HIT_IT)) + { + result = 1; + } + else if (colrec->dist > dst_max) + { + result = 1; + } + else if (tgt && colrec->oid != 0) + { + if (tgt->id == colrec->oid) + { + result = 1; + } + else + { + result = 0; + } + } + else + { + result = 0; + } + + return result; +} + void NPCC_DstSq(const xVec3*, const xVec3*, xVec3*); void NPCC_DstSqPlyrToPos(const xVec3* pos) @@ -535,7 +1182,7 @@ F32 NPCC_ds2_toCam(const xVec3* pos_from, xVec3* delta) xVec3 delt = {}; xVec3Sub(&delt, &globals.camera.mat.pos, pos_from); F32 retval = xVec3Length2(&delt); - if (delta != (xVec3 *)0) + if (delta != (xVec3*)0) { xVec3Copy(delta, &delt); } @@ -606,4 +1253,4 @@ void NPCC_MakeArbPlane(const xVec3* dir_norm, xVec3* at, xVec3* rt) { NPCC_MakePerp(at, dir_norm); xVec3Cross(rt, at, dir_norm); -} \ No newline at end of file +} diff --git a/src/SB/Game/zNPCSupport.h b/src/SB/Game/zNPCSupport.h index b69007b43..4a878ff06 100644 --- a/src/SB/Game/zNPCSupport.h +++ b/src/SB/Game/zNPCSupport.h @@ -15,7 +15,7 @@ enum en_npctgt NPC_TGT_FORCEINT = 0x7fffffff }; -enum _tageNPCSnd +typedef enum _tageNPCSnd { eNPCSnd_GloveAttack, eNPCSnd_SleepyAttack, @@ -23,7 +23,7 @@ enum _tageNPCSnd eNPCSnd_FodBzztAttack, eNPCSnd_JellyfishAttack, eNPCSnd_Total -}; +} eNPCSnd; enum en_NPC_UI_WIDGETS { @@ -67,7 +67,9 @@ struct NPCTarget zNPCCommon* npc_owner; void TargetClear(); + S32 FindNearest(S32 flg_consider, xBase* skipme, xVec3* from, F32 dst_max); void PosGet(xVec3* pos); + S32 InCylinder(xVec3* from, F32 rad, F32 hyt, F32 off); void TargetSet(xEnt* ent, int b); S32 IsDead(); }; @@ -89,10 +91,10 @@ struct NPCWidget zNPCCommon* npc_ownerlock; S32 NPCIsTheLocker(const zNPCCommon* npc_lock); - U32 IsLocked(); + S32 IsLocked(); S32 IsVisible(); - U32 Off(zNPCCommon* npc, U32 theman); - U32 On(const zNPCCommon* npc, S32 theman); + S32 Off(const zNPCCommon* npc, S32 theman); + S32 On(const zNPCCommon* npc, S32 theman); void Reset(); void Init(en_NPC_UI_WIDGETS); S32 Lock(const zNPCCommon*); @@ -135,6 +137,7 @@ void NPCSupport_Timestep(F32 dt); void NPCSupport_SceneReset(); void NPCSupport_Shutdown(); void NPCSupport_ScenePostInit(); +NPCWidget* NPCWidget_Find(en_NPC_UI_WIDGETS which); void Firework_SceneReset(S32); void Firework_ScenePrepare(); void Firework_SceneFinish(); @@ -150,14 +153,23 @@ F32 NPCC_TmrCycle(F32* tmr, F32 dt, F32 interval); xVec3* NPCC_rightDir(xEnt* ent); xVec3* NPCC_faceDir(xEnt* ent); void NPCC_ang_toXZDir(F32 angle, xVec3* dir); +F32 NPCC_dir_toXZAng(const xVec3* dir); F32 NPCC_aimVary(xVec3* dir_aim, xVec3* pos_src, xVec3* pos_tgt, F32 dst_vary, S32 flg_vary, xVec3* pos_aimPoint); void NPCC_aimMiss(xVec3*, xVec3*, xVec3*, float, xVec3*); S32 NPCC_chk_hitPlyr(xBound* bnd, xCollis* collide); +S32 NPCC_chk_hitEnt(xEnt* tgt, xBound* bnd, xCollis* collide); S32 NPCC_pos_ofBase(xBase* tgt, xVec3* pos); +void NPCC_xBoundAway(xBound* bnd); +void NPCC_xBoundBack(xBound* bnd); F32 NPCC_ds2_toCam(const xVec3* pos_from, xVec3* delta); void zNPC_SNDStop(_tageNPCSnd snd); void zNPC_SNDPlay3D(_tageNPCSnd snd, xEnt*); RwRaster* NPCC_FindRWRaster(char*); +inline F32 SQ(F32 x) +{ + return x * x; +} + #endif diff --git a/src/SB/Game/zNPCTypeCommon.cpp b/src/SB/Game/zNPCTypeCommon.cpp index 3eb5e7a37..a4acd3714 100644 --- a/src/SB/Game/zNPCTypeCommon.cpp +++ b/src/SB/Game/zNPCTypeCommon.cpp @@ -3,19 +3,33 @@ #include #include +#include "zCombo.h" #include "zEntCruiseBubble.h" #include "zEntTeleportBox.h" +#include "zEntButton.h" #include "zGlobals.h" +#include "zMovePoint.h" #include "zNPCTypes.h" #include "zNPCSndTable.h" #include "zNPCSupport.h" #include "zNPCFXCinematic.h" +#include "zNPCMessenger.h" +#include "zNPCGoals.h" +#include "zNPCGoalVillager.h" +#include "zGrid.h" +#include "zLasso.h" +#include "zGame.h" #include "iModel.h" #include "iSnd.h" +#include "iCollide.h" #include "xString.h" +#include "xSpline.h" #include "xDebug.h" +#include "xBound.h" +#include "xDraw.h" +#include "xPad.h" #define Unknown 0 #define LassoGuide_Grab01 1 @@ -23,9 +37,88 @@ extern char zNPCTypeCommon_strings[]; static char* g_strz_lassanim[3] = { "Unknown", "LassoGuide_Grab01", "LassoGuide_Hold01" }; +static char* g_strz_params[NPC_PARM_NOMORE] = { + "Empty", + "MoveSpeed", + "TurnSpeed", + "FactorAccel", + "FactorDrift", + "FactorMass", + "FactorGravKnock", + "FactorElasticity", + "BoundMainIsBox", + "BoundMainCenter", + "BoundMainExtent", + "HitPoints", + "ScaleModel", + "DetectRadius", + "DetectHeight", + "DetectOffset", + "AttackRadius", + "AttackFOV", + "SoundRadius", + "DelayFidget", + "AttackPeriod", + "StunTime", + "AlertTime", + "VtxAttackBase", + "VtxAttack", + "VtxAttack1", + "VtxAttack2", + "VtxAttack3", + "VtxAttack4", + "VtxEyeball", + "VtxDmgSmokeA", + "VtxDmgSmokeB", + "VtxDmgSmokeC", + "VtxDmgFlameA", + "VtxDmgFlameB", + "VtxDmgFlameC", + "VtxPropel", + "VtxExhaust", + "VtxGen01", + "VtxGen02", + "VtxGen03", + "VtxGen04", + "VtxGen05", + "AttackSize01", + "AttackFrames01", + "AttackFrames01a", + "AttackFrames01b", + "AttackFrames02", + "AttackFrames02a", + "AttackFrames02b", + "AttackFrames03", + "AttackFrames03a", + "AttackFrames03b", + "EsteemSlotA", + "EsteemSlotB", + "EsteemSlotC", + "EsteemSlotD", + "EsteemSlotE", + "DistShadowCast", + "ShadowCacheRadius", + "ShadowRasterRadius", + "TestCount", + "EndTag_INIOnly", + "FirstMovepoint", + "EndTag_PropsOnly", + "Bogus_Share", + "EndTag_Shared", +}; + +static en_npcparm mdlVertToParm[NPC_MDLVERT_NOMORE] = { + 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, +}; + extern S32 g_hash_lassanim[3]; extern volatile S32 g_skipDescent; extern NPCConfig* g_ncfghead; +static zNPCSettings* g_dflt_npcsettings; extern NPCSndTrax g_sndTrax_General[]; extern F32 lbl_803CE4C0; extern S32 g_flg_wonder; @@ -116,106 +209,2631 @@ void zNPCCommon_Timestep(xScene* scene, F32 dt) } } -void zNPCCommon::Destroy() +void zNPCCommon::Init(xEntAsset* entass) { - SelfDestroy(); -} + xSceneID2Name(globals.sceneCur, entass->id); -void zNPCCommon::Process(xScene* xscn, F32 dt) -{ - if ((flg_misc & 4) != 0) + xNPCBasic::Init(entass); + + this->entass = entass; + this->npcass = (xEntNPCAsset*)(entass + 1); + + xLinkAsset* npclinx = (xLinkAsset*)(this->npcass + 1); + if (linkCount) { - ModelScaleSet(&cfg_npc->scl_model); + this->link = npclinx; } - flags1.flg_upward = flags1.flg_upward & ~0x2; - xNPCBasic::Process(xscn, dt); + else + { + this->link = NULL; + } + + this->parmdata = zEntGetModelParams(this->entass->modelInfoID, &this->pdatsize); + + this->cfg_npc = this->ConfigFind(this->entass->modelInfoID); + if (!this->cfg_npc) + { + this->cfg_npc = this->ConfigCreate(this->entass->modelInfoID); + this->ParseINI(); + } + + if (this->cfg_npc && xVec3Length2(&this->cfg_npc->scl_model) > 0.0f) + { + this->flg_misc |= 0x4; + } + + this->InitBounds(); } -void zNPCCommon::ParseProps() +void zNPCCommon::InitBounds() //NONMATCH("https://decomp.me/scratch/JPhdS") { - for (S32 i = 0x3f; i < 0x42; i++) + NPCConfig* cfg = this->cfg_npc; + xVec3 half = {}; + xSphere* sph = &this->bound.sph; + xBBox* box = &this->bound.box; + + if (cfg->useBoxBound) { - switch (i) + this->bound.type = k_XBOUNDTYPE_BOX; + } + else + { + this->bound.type = k_XBOUNDTYPE_SPHERE; + } + + S32 r28; + if (xVec3Length2(&cfg->off_bound) > 0.0f) + { + r28 = 1; + } + else + { + r28 = 0; + } + + if (xVec3Length2(&cfg->dim_bound) > 0.0f) + { + xSceneID2Name(globals.sceneCur, this->id); + this->DBG_Name(); + + if (this->bound.type == k_XBOUNDTYPE_SPHERE) { - case 0x3f: - MvptReset(NULL); + sph->r = cfg->dim_bound.x; + xVec3Copy(&sph->center, xEntGetPos(this)); + xVec3AddTo(&sph->center, &cfg->off_bound); + } + else + { + xVec3SMul(&half, &cfg->dim_bound, 0.5f); + xVec3Copy(&box->center, xEntGetPos(this)); + xVec3AddTo(&box->center, &cfg->off_bound); + xVec3Add(&box->box.upper, &box->center, &half); + xVec3Sub(&box->box.lower, &box->center, &half); + } + } + else + { + xSceneID2Name(globals.sceneCur, this->id); + this->DBG_Name(); + + switch (this->bound.type) + { + case k_XBOUNDTYPE_SPHERE: + iSphereForModel(sph, this->model); + cfg->dim_bound.x = sph->r; + cfg->dim_bound.y = 0.0f; + cfg->dim_bound.z = 0.0f; + if (!r28) + { + xVec3Copy(&cfg->off_bound, &sph->center); + cfg->off_bound.y = MAX(cfg->off_bound.y, sph->r); + } + sph->r = cfg->dim_bound.x; + xVec3Copy(&sph->center, xEntGetPos(this)); + xVec3AddTo(&sph->center, &cfg->off_bound); break; - default: + case k_XBOUNDTYPE_BOX: + case k_XBOUNDTYPE_OBB: + iBoxForModel(&box->box, this->model); + xVec3Sub(&cfg->dim_bound, &box->box.upper, &box->box.lower); + if (!r28) + { + xVec3SMul(&cfg->off_bound, &cfg->dim_bound, 0.5f); + } + xVec3SMul(&half, &cfg->dim_bound, 0.5f); + xVec3Copy(&box->center, xEntGetPos(this)); + xVec3AddTo(&box->center, &cfg->off_bound); + xVec3Add(&box->box.upper, &box->center, &half); + xVec3Sub(&box->box.lower, &box->center, &half); break; } } } -bool zNPCCommon::IsMountableType(en_ZBASETYPE type) +void zNPCCommon::Setup() { - switch (type) + xSceneID2Name(globals.sceneCur, this->id); + + xNPCBasic::Setup(); + + this->DBG_InstName(); + this->DBG_RptDataSize(); + + this->npcsetass = zNPCSettings_Find(this->npcass->npcProps); + + this->ParseLinks(); + + if (this->LassoInit()) { - case eBaseTypePlatform: - return true; + this->LassoSetup(); + } + + this->SelfSetup(); + this->DBG_AddTweakers(); + + switch (this->SelfType()) + { + case NPC_TYPE_HAMMER: + case NPC_TYPE_HAMSPIN: + this->explosion = (zShrapnelAsset*)xSTFindAsset(xStrHash("hammer_shrapnel"), NULL); + break; + case NPC_TYPE_TARTAR: + this->explosion = (zShrapnelAsset*)xSTFindAsset(xStrHash("tartar_shrapnel"), NULL); + break; + case NPC_TYPE_FODDER: + this->explosion = (zShrapnelAsset*)xSTFindAsset(xStrHash("fodder_shrapnel"), NULL); + break; + case NPC_TYPE_FODBZZT: + this->explosion = (zShrapnelAsset*)xSTFindAsset(xStrHash("robot_0a_bzzt_shrapnel"), NULL); + break; + case NPC_TYPE_CHOMPER: + this->explosion = + (zShrapnelAsset*)xSTFindAsset(xStrHash("robot_0a_chomper_shrapnel"), NULL); + break; + case NPC_TYPE_GLOVE: + this->explosion = (zShrapnelAsset*)xSTFindAsset(xStrHash("g-love_shrapnel"), NULL); + break; + case NPC_TYPE_MONSOON: + this->explosion = + (zShrapnelAsset*)xSTFindAsset(xStrHash("robot_4a_monsoon_shrapnel"), NULL); + break; + case NPC_TYPE_SLEEPY: + this->explosion = + (zShrapnelAsset*)xSTFindAsset(xStrHash("robot_sleepy-time_shrapnel"), NULL); + break; + case NPC_TYPE_ARFARF: + this->explosion = (zShrapnelAsset*)xSTFindAsset(xStrHash("robot_arf_shrapnel"), NULL); + break; + case NPC_TYPE_CHUCK: + this->explosion = (zShrapnelAsset*)xSTFindAsset(xStrHash("robot_chuck_shrapnel"), NULL); + break; + case NPC_TYPE_SLICK: + this->explosion = (zShrapnelAsset*)xSTFindAsset(xStrHash("robot_9a_shrapnel"), NULL); + break; + case NPC_TYPE_DUPLOTRON: + this->explosion = + (zShrapnelAsset*)xSTFindAsset(xStrHash("duplicatotron1000_shrapnel"), NULL); + break; + case NPC_TYPE_TIKI_WOOD: + this->explosion = (zShrapnelAsset*)xSTFindAsset(xStrHash("tiki_wooden_shrapnel"), NULL); + break; + case NPC_TYPE_TIKI_QUIET: + this->explosion = (zShrapnelAsset*)xSTFindAsset(xStrHash("tiki_shhhh_shrapnel"), NULL); + break; + case NPC_TYPE_TIKI_THUNDER: + this->explosion = (zShrapnelAsset*)xSTFindAsset(xStrHash("tiki_thunder_shrapnel"), NULL); + break; + case NPC_TYPE_TIKI_LOVEY: + this->explosion = + (zShrapnelAsset*)xSTFindAsset(xStrHash("tiki_lovey_dovey_shrapnel"), NULL); + break; + case NPC_TYPE_TIKI_STONE: + this->explosion = (zShrapnelAsset*)xSTFindAsset(xStrHash("tiki_stone_shrapnel"), NULL); break; default: - return false; + this->explosion = NULL; break; } -} -void zNPCCommon::SelfDestroy() -{ - xBehaveMgr* bmgr = xBehaveMgr_GetSelf(); - if (psy_instinct != NULL) + S32 wason = 0; + xPsyche* psy = this->psy_instinct; + + if (psy) { - bmgr->UnSubscribe(psy_instinct); + if (psy->ImmTranIsOn()) + { + wason = 1; + } + psy->ImmTranOff(); + } + + this->Reset(); + + if (psy && wason) + { + psy->ImmTranOn(); } - psy_instinct = NULL; } -S32 zNPCCommon::GetVertPos(en_mdlvert vid, xVec3* pos) +void zNPCCommon::Reset() //NONMATCH("https://decomp.me/scratch/cl84A") { - NPCConfig* cfg = cfg_npc; - if (!(cfg->flg_vert & 1 << vid)) + xSceneID2Name(globals.sceneCur, this->id); + + xNPCBasic::Reset(); + + this->entShadow->dst_cast = this->cfg_npc->dst_castShadow; + this->entShadow->radius[0] = this->cfg_npc->rad_shadowCache; + this->entShadow->radius[1] = this->cfg_npc->rad_shadowRaster; + + this->ParseProps(); + + this->npcset = *this->npcsetass; + + if (this->entass->flags & k_XENT_IS_VISIBLE) { - return 0; + xEntShow(this); + } + else + { + xEntHide(this); + } + + if (this->flg_move & 0x2) + { + this->pflags |= k_XENT_HAS_GRAVITY; + } + else if (this->flg_move & 0x4) + { + this->pflags &= (U8)~k_XENT_HAS_GRAVITY; + } + else + { + this->pflags &= (U8)~k_XENT_HAS_GRAVITY; + } + + if (this->model->Anim) + { + xAnimPlaySetState(this->model->Anim->Single, &this->model->Anim->Table->StateList[0], 0.0f); + } + + this->drv_data = this->PRIV_GetDriverData(); + if (this->drv_data) + { + xEntDriveInit(this->drv_data, this); + this->drv_data->flags |= 0x1; + } + + if (this->lassdata) + { + this->lassdata->stage = LASS_STAT_PENDING; } - iModelTagEval(model->Data, &cfg->tag_vert[vid], model->Mat, pos); - return 1; } -void zNPCPlyrSnd_Reset() +void zNPCCommon::Destroy() { - g_tmr_talkless = 10.0f; + SelfDestroy(); } -void zNPCPlyrSnd_Update(F32 dt) +void zNPCCommon::Damage(en_NPC_DAMAGE_TYPE damtype, xBase* who, const xVec3* vec_hit) { - g_tmr_talkless = MAX(-1.0f, g_tmr_talkless - dt); + static NPCMsg msg; + NPCDamageInfo* dmg = &msg.dmgdata; + + if (!(this->flg_vuln & 0x1)) + return; + if (who && who->baseType == eBaseTypePlayer && !(this->flg_vuln & 0xFFFF0000)) + return; + + switch (damtype) + { + case DMGTYP_ABOVE: + if (!(this->flg_vuln & 0x40000)) + return; + break; + case DMGTYP_BELOW: + if (!(this->flg_vuln & 0x20000)) + return; + break; + case DMGTYP_SIDE: + if (gCurrentPlayer == eCurrentPlayerSpongeBob) + { + if (!(this->flg_vuln & 0x10000)) + return; + } + else if (gCurrentPlayer == eCurrentPlayerPatrick) + { + if (!(this->flg_vuln & 0x80000000)) + return; + } + else if (gCurrentPlayer == eCurrentPlayerSandy) + { + if (!(this->flg_vuln & 0x2000000)) + return; + } + else + { + if (!(this->flg_vuln & 0x10000)) + return; + } + break; + case DMGTYP_INSTAKILL: + this->tmr_invuln = -1.0f; + break; + case DMGTYP_HITBYTOSS: + if (!(this->flg_vuln & 0x4)) + return; + break; + case DMGTYP_NPCATTACK: + if (!(this->flg_vuln & 0x8)) + return; + break; + case DMGTYP_ROPE: + if (!(this->flg_vuln & 0x1000000)) + return; + break; + case DMGTYP_CRUISEBUBBLE: + if (!(this->flg_vuln & 0x80000)) + return; + break; + case DMGTYP_PROJECTILE: + if (!(this->flg_vuln & 0x8)) + return; + break; + case DMGTYP_BUBBOWL: + if (!(this->flg_vuln & 0x100000)) + return; + break; + case DMGTYP_BOULDER: + if (!(this->flg_vuln & 0x200000)) + return; + break; + case DMGTYP_THUNDER_TIKI_EXPLOSION: + if (!(this->flg_vuln & 0x2)) + return; + break; + case DMGTYP_DAMAGE_SURFACE: + case DMGTYP_SURFACE: + if (!(this->flg_vuln & 0x10)) + return; + break; + case DMGTYP_BUNGEED: + if (!(this->flg_vuln & 0x400000)) + return; + break; + } + + if (this->tmr_invuln < 0.0f) + { + this->tmr_invuln = 0.5f; + + memset(&msg, 0, sizeof(msg)); + + msg.from = this->id; + msg.sendto = this->id; + msg.msgid = NPC_MID_DAMAGE; + msg.infotype = NPC_MDAT_DAMAGE; + + dmg->dmg_type = damtype; + dmg->dmg_from = who; + + if (vec_hit) + { + xVec3Copy(&dmg->vec_dmghit, vec_hit); + } + else + { + xVec3Copy(&dmg->vec_dmghit, &g_O3); + } + + zNPCMsg_SendMsg(&msg, this); + } } -void zNPCCommon::ConfigSceneDone() +S32 zNPCCommon::Respawn(const xVec3* pos, zMovePoint* mvptFirst, zMovePoint* mvptSpawnRef) { - g_ncfghead = 0; + static NPCMsg msg; + + memset(&msg, 0, sizeof(msg)); + + msg.msgid = NPC_MID_RESPAWN; + msg.from = this->id; + msg.sendto = this->id; + msg.infotype = NPC_MDAT_SPAWN; + + if (pos) + { + xVec3Copy(&msg.spawning.pos_spawn, pos); + } + else + { + xVec3Copy(&msg.spawning.pos_spawn, &this->entass->pos); + } + + if (mvptFirst) + { + msg.spawning.nav_firstMovepoint = mvptFirst; + } + else + { + msg.spawning.nav_firstMovepoint = NULL; + } + + msg.spawning.nav_spawnReference = mvptSpawnRef; + msg.spawning.spawnSuccess = 0; + + zNPCMsg_SendMsg(&msg, this); + + return msg.spawning.spawnSuccess; } -void zNPCCommon_WonderReset() +S32 zNPCCommon::NPCMessage(NPCMsg* mail) { - g_isConversation = 0; - g_flg_wonder = 0; + S32 handled = 1; + + switch (mail->msgid) + { + case NPC_MID_SYSEVENT: + { + xPsyche* psy = this->psy_instinct; + + switch (mail->sysevent.toEvent) + { + case eEventNPCPatrolOn: + this->npcset.allowPatrol = 1; + break; + case eEventNPCPatrolOff: + this->npcset.allowPatrol = 0; + break; + case eEventNPCWanderOn: + this->npcset.allowDetect = 1; + break; + case eEventNPCWanderOff: + this->npcset.allowDetect = 0; + break; + case eEventNPCDetectOn: + this->npcset.allowDetect = 1; + break; + case eEventNPCDetectOff: + this->npcset.allowDetect = 0; + break; + case eEventNPCChaseOn: + this->npcset.allowChase = 1; + break; + case eEventNPCChaseOff: + this->npcset.allowChase = 0; + break; + case eEventNPCSplineOKOn: + this->npcset.useNavSplines = 1; + break; + case eEventNPCSplineOKOff: + this->npcset.useNavSplines = 0; + break; + case eEventNPCSetActiveOff: + if (psy && psy->HasGoal(NPC_GOAL_LIMBO)) + { + psy->GoalSet(NPC_GOAL_LIMBO, 1); + } + break; + case eEventNPCSetActiveOn: + if (psy) + { + psy->GIDOfPending(); + + S32 r4 = psy->GIDOfSafety(); + if (r4) + { + psy->GoalSet(r4, 1); + } + } + break; + default: + handled = 0; + break; + } + break; + } + case NPC_MID_RESPAWN: + { + xVec3Copy(xEntGetPos(this), &mail->spawning.pos_spawn); + + zMovePoint* mvpt = mail->spawning.nav_spawnReference; + if (!mvpt) + mvpt = mail->spawning.nav_firstMovepoint; + + this->nav_past = mvpt; + this->nav_curr = mvpt; + this->nav_dest = mvpt; + this->nav_lead = mvpt; + + mail->spawning.spawnSuccess = 1; + break; + } + case NPC_MID_DAMAGE: + break; + case NPC_MID_DEV_ANIMCYCLE: + if (this->psy_instinct && this->psy_instinct->HasGoal(NPC_GOAL_DEV_ANIMSPIN)) + { + this->psy_instinct->GoalSet(NPC_GOAL_DEV_ANIMSPIN, 0); + } + break; + case NPC_MID_DEV_ANIMSPIN: + if (this->psy_instinct && this->psy_instinct->HasGoal(NPC_GOAL_DEV_ANIMCYCLE)) + { + this->psy_instinct->GoalSet(NPC_GOAL_DEV_ANIMCYCLE, 0); + } + break; + case NPC_MID_DEV_HEROMODE: + if (this->psy_instinct && this->psy_instinct->HasGoal(NPC_GOAL_DEV_HERO)) + { + this->psy_instinct->GoalSet(NPC_GOAL_DEV_HERO, 0); + } + break; + case NPC_MID_DEV_DONE: + break; + default: + handled = 1; + break; + } + + return handled; } -U32 zNPCCommon::CanDoSplines() +void zNPCCommon::Move(xScene* xscn, F32 dt, xEntFrame* frm) { - bool retval = false; - if ((npcset.useNavSplines) && ((flg_move) & 8)) + if (this->drv_data && (this->drv_data->driver || this->drv_data->odriver)) { - retval = true; + S32 backit = 0; + xVec3 var_28; + + if (this->frame->mode & 0x2) + { + backit = 1; + var_28 = this->frame->dpos; + } + + xEntDriveUpdate(this->drv_data, xscn, dt, NULL); + + if (backit) + { + this->frame->mode |= 0x2; + this->frame->dpos = var_28; + } + } + + xNPCBasic::Move(xscn, dt, frm); +} + +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::BUpdate(xVec3* pos) //NONMATCH("https://decomp.me/scratch/zpv2r") +{ + NPCConfig* cfg = this->cfg_npc; + + if (cfg->useBoxBound) + { + this->bound.type = k_XBOUNDTYPE_BOX; + + xBBox* box = &this->bound.box; + xVec3 half = cfg->dim_bound * 0.5f; + + box->center = *pos + cfg->off_bound; + box->box.upper = box->center + half; + box->box.lower = box->center - half; + } + else + { + this->bound.type = k_XBOUNDTYPE_SPHERE; + + xSphere* sph = &this->bound.sph; + + sph->center = *pos + cfg->off_bound; + sph->r = cfg->dim_bound.x; + } + + if (this->bound.type != k_XBOUNDTYPE_NONE) + { + xQuickCullForBound(&this->bound.qcd, &this->bound); + } + + zGridUpdateEnt(this); +} + +F32 zNPCCommon::BoundAsRadius(S32 useCfg) const //NONMATCH("https://decomp.me/scratch/rCFqE") +{ + F32 rad = 1.0f; + + if (useCfg) + { + NPCConfig* cfg = this->cfg_npc; + + if (cfg->useBoxBound) + { + xVec3 dim = cfg->dim_bound; + rad = (dim.x + dim.y + dim.z) * (1 / 6.f); + } + else + { + rad = cfg->dim_bound.x; + } + } + else + { + if (this->bound.type == k_XBOUNDTYPE_BOX) + { + const xBBox* box = &this->bound.box; + const xVec3* le = &box->box.lower; + const xVec3* ue = &box->box.upper; + rad = ((ue->x + ue->y + ue->z) - (le->x + le->y - le->z)) * (1 / 6.f); + } + else if (this->bound.type == k_XBOUNDTYPE_SPHERE) + { + rad = this->bound.sph.r; + } + } + + return rad; +} + +void zNPCCommon::NewTime(xScene* xscn, F32 dt) +{ + if (this->flg_misc & 0x2) + { + this->SndQueUpdate(dt); + } + + this->tmr_invuln = MAX(-1.0f, this->tmr_invuln - dt); + + xNPCBasic::NewTime(xscn, dt); +} + +S32 zNPCCommon::SysEvent(xBase* from, xBase* to, U32 toEvent, const F32* toParam, + xBase* toParamWidget, S32* handled) +{ + static NPCMsg npcmsg; + + S32 doOtherEvents = 1; + zNPCCommon* npc = (zNPCCommon*)to; + xVec3 pos = {}; + xVec3 dir = {}; + + *handled = 1; + + switch (toEvent) + { + case eEventSceneEnd: + { + xPsyche* psy = this->psy_instinct; + if (psy) + { + psy->GoalNone(1, 1); + } + break; + } + case eEventNPCSpecial_PlatformSnap: + case eEventNPCSpecial_PlatformFall: + { + memset(&npcmsg, 0, sizeof(npcmsg)); + + npcmsg.msgid = NPC_MID_SYSEVENT; + npcmsg.infotype = NPC_MDAT_SYSEVENT; + npcmsg.from = this->id; + npcmsg.sendto = this->id; + + NPCSysEvent* se = &npcmsg.sysevent; + se->doLinkEvents = 1; + se->handled = 0; + se->to = to; + se->from = from; + se->toEvent = toEvent; + se->toParamWidget = toParamWidget; + + if (!toParam) + { + se->toParam[0] = 0.0f; + se->toParam[1] = 0.0f; + se->toParam[2] = 0.0f; + se->toParam[3] = 0.0f; + } + else + { + se->toParam[0] = toParam[0]; + se->toParam[1] = toParam[1]; + se->toParam[2] = toParam[2]; + se->toParam[3] = toParam[3]; + } + + zNPCMsg_SendMsg(&npcmsg, -1.0f, NULL); + + *handled = npcmsg.sysevent.handled; + doOtherEvents = se->doLinkEvents; + break; + } + case eEventHit: + this->ConvertHitEvent(from, to, toEvent, toParam, toParamWidget, handled); + break; + case eEventReset: + this->Reset(); + break; + case eEventVisible: + xEntShow(npc); + break; + case eEventInvisible: + xEntHide(npc); + break; + case eEventSetUpdateDistance: + if (globals.updateMgr) + { + if (toParam[0] <= 0.0f) + { + xUpdateCull_SetCB(globals.updateMgr, npc, xUpdateCull_AlwaysTrueCB, NULL); + } + else + { + FloatAndVoid dist; + dist.f = SQR(toParam[0]); + xUpdateCull_SetCB(globals.updateMgr, npc, xUpdateCull_DistanceSquaredCB, dist.v); + } + } + break; + case eEventLaunchShrapnel: + { + zShrapnelAsset* shrap = (zShrapnelAsset*)toParamWidget; + if (shrap && shrap->initCB) + { + xVec3 currVel; + xVec3Sub(&currVel, &npc->frame->mat.pos, &npc->frame->oldmat.pos); + xVec3SMulBy(&currVel, 1.0f / globals.update_dt); + + shrap->initCB(shrap, this->model, &currVel, NULL); + } + break; + } + case eEventNPCKillQuietly: + this->Damage(DMGTYP_KILLEVENT, from, NULL); + break; + case eEventKill: + this->Damage(DMGTYP_INSTAKILL, from, NULL); + break; + case eEventNPCRespawn: + this->Respawn(NULL, NULL, NULL); + break; + case eEventNPCPatrolOn: + case eEventNPCPatrolOff: + case eEventNPCWanderOn: + case eEventNPCWanderOff: + case eEventNPCDetectOn: + case eEventNPCDetectOff: + case eEventNPCChaseOn: + case eEventNPCChaseOff: + case eEventNPCFightOn: + case eEventNPCFightOff: + { + memset(&npcmsg, 0, sizeof(npcmsg)); + + npcmsg.msgid = NPC_MID_SYSEVENT; + npcmsg.infotype = NPC_MDAT_SYSEVENT; + npcmsg.from = this->id; + npcmsg.sendto = this->id; + + NPCSysEvent* se = &npcmsg.sysevent; + se->doLinkEvents = 1; + se->handled = 0; + se->to = to; + se->from = from; + se->toEvent = toEvent; + se->toParamWidget = toParamWidget; + + if (!toParam) + { + se->toParam[0] = 0.0f; + se->toParam[1] = 0.0f; + se->toParam[2] = 0.0f; + se->toParam[3] = 0.0f; + } + else + { + se->toParam[0] = toParam[0]; + se->toParam[1] = toParam[1]; + se->toParam[2] = toParam[2]; + se->toParam[3] = toParam[3]; + } + + zNPCMsg_SendMsg(&npcmsg, -1.0f, NULL); + + *handled = npcmsg.sysevent.handled; + doOtherEvents = se->doLinkEvents; + break; + } + case eEventNPCForceConverseStart: + if (NPCC_ForceTalkOk()) + { + memset(&npcmsg, 0, sizeof(npcmsg)); + + npcmsg.msgid = NPC_MID_SYSEVENT; + npcmsg.infotype = NPC_MDAT_SYSEVENT; + npcmsg.from = this->id; + npcmsg.sendto = this->id; + + NPCSysEvent* se = &npcmsg.sysevent; + se->doLinkEvents = 1; + se->handled = 0; + se->to = to; + se->from = from; + se->toEvent = toEvent; + se->toParamWidget = toParamWidget; + + if (!toParam) + { + se->toParam[0] = 0.0f; + se->toParam[1] = 0.0f; + se->toParam[2] = 0.0f; + se->toParam[3] = 0.0f; + } + else + { + se->toParam[0] = toParam[0]; + se->toParam[1] = toParam[1]; + se->toParam[2] = toParam[2]; + se->toParam[3] = toParam[3]; + } + + zNPCMsg_SendMsg(&npcmsg, -1.0f, NULL); + + *handled = npcmsg.sysevent.handled; + doOtherEvents = se->doLinkEvents; + } + + break; + case eEventNPCCheerForMe: + zNPCMsg_SendMsg(NPC_MID_CELEBRATE, this); + break; + case eEventNPCGoToSleep: + case eEventNPCWakeUp: + { + memset(&npcmsg, 0, sizeof(npcmsg)); + + npcmsg.msgid = NPC_MID_SYSEVENT; + npcmsg.infotype = NPC_MDAT_SYSEVENT; + npcmsg.from = this->id; + npcmsg.sendto = this->id; + + NPCSysEvent* se = &npcmsg.sysevent; + se->doLinkEvents = 1; + se->handled = 0; + se->to = to; + se->from = from; + se->toEvent = toEvent; + se->toParamWidget = toParamWidget; + + if (!toParam) + { + se->toParam[0] = 0.0f; + se->toParam[1] = 0.0f; + se->toParam[2] = 0.0f; + se->toParam[3] = 0.0f; + } + else + { + se->toParam[0] = toParam[0]; + se->toParam[1] = toParam[1]; + se->toParam[2] = toParam[2]; + se->toParam[3] = toParam[3]; + } + + zNPCMsg_SendMsg(&npcmsg, -1.0f, NULL); + + *handled = npcmsg.sysevent.handled; + doOtherEvents = se->doLinkEvents; + break; + } + case eEventNPCSetActiveOn: + case eEventNPCSetActiveOff: + this->SelfType(); + + if (this->psy_instinct) + { + memset(&npcmsg, 0, sizeof(npcmsg)); + + npcmsg.msgid = NPC_MID_SYSEVENT; + npcmsg.infotype = NPC_MDAT_SYSEVENT; + npcmsg.from = this->id; + npcmsg.sendto = this->id; + + NPCSysEvent* se = &npcmsg.sysevent; + se->doLinkEvents = 1; + se->handled = 0; + se->to = to; + se->from = from; + se->toEvent = toEvent; + se->toParamWidget = toParamWidget; + + if (!toParam) + { + se->toParam[0] = 0.0f; + se->toParam[1] = 0.0f; + se->toParam[2] = 0.0f; + se->toParam[3] = 0.0f; + } + else + { + se->toParam[0] = toParam[0]; + se->toParam[1] = toParam[1]; + se->toParam[2] = toParam[2]; + se->toParam[3] = toParam[3]; + } + + zNPCMsg_SendMsg(&npcmsg, -1.0f, NULL); + + *handled = npcmsg.sysevent.handled; + doOtherEvents = se->doLinkEvents; + } + + break; + case eEventDuploWaveBegin: + case eEventDuploWaveComplete: + case eEventDuploNPCBorn: + case eEventDuploNPCKilled: + case eEventDuploExpiredMaxNPC: + case eEventDuploPause: + case eEventDuploResume: + case eEventDuploKillKids: + { + memset(&npcmsg, 0, sizeof(npcmsg)); + + npcmsg.msgid = NPC_MID_SYSEVENT; + npcmsg.infotype = NPC_MDAT_SYSEVENT; + npcmsg.from = this->id; + npcmsg.sendto = this->id; + + NPCSysEvent* se = &npcmsg.sysevent; + se->doLinkEvents = 1; + se->handled = 0; + se->to = to; + se->from = from; + se->toEvent = toEvent; + se->toParamWidget = toParamWidget; + + if (!toParam) + { + se->toParam[0] = 0.0f; + se->toParam[1] = 0.0f; + se->toParam[2] = 0.0f; + se->toParam[3] = 0.0f; + } + else + { + se->toParam[0] = toParam[0]; + se->toParam[1] = toParam[1]; + se->toParam[2] = toParam[2]; + se->toParam[3] = toParam[3]; + } + + zNPCMsg_SendMsg(&npcmsg, -1.0f, NULL); + + *handled = npcmsg.sysevent.handled; + doOtherEvents = se->doLinkEvents; + break; + } + case eEventNPCScript_ScriptBegin: + zNPCMsg_SendMsg(NPC_MID_SCRIPTBEGIN, this); + break; + case eEventNPCScript_ScriptEnd: + zNPCMsg_SendMsg(NPC_MID_SCRIPTEND, this); + break; + case eEventNPCScript_SetPos: + if (toParamWidget) + { + NPCC_pos_ofBase(toParamWidget, &pos); + this->MatPosSet(&pos); + } + break; + case eEventNPCScript_SetDir: + if (toParamWidget) + { + NPCC_pos_ofBase(toParamWidget, &dir); + xVec3SubFrom(&dir, xEntGetPos(this)); + dir.y = 0.0f; + + if (xVec3Length2(&dir) > 0.001f) + { + xVec3Normalize(&dir, &dir); + xVec3Copy((xVec3*)&this->model->Mat->at, &dir); + xVec3Copy((xVec3*)&this->model->Mat->up, &g_Y3); + xVec3Cross((xVec3*)&this->model->Mat->right, &dir, &g_Y3); + } + } + break; + case eEventNPCScript_LookNormal: + case eEventNPCScript_LookAlert: + case eEventNPCScript_FaceWidget: + case eEventNPCScript_GotoWidget: + case eEventNPCScript_AttackWidget: + case eEventNPCScript_FollowWidget: + case eEventNPCScript_PlayAnim: + case eEventNPCScript_LeadPlayer: + zEventName(toEvent); + break; + case eEventUnknown: + case eEventMount: + case eEventDismount: + case eEventDeath: + case eEventSceneBegin: + case eEventRoomBegin: + case eEventRoomEnd: + case eEventNPCScript_ScriptReady: + case eEventNPCScript_Halt: + case eEventNPCScript_FaceWidgetDone: + case eEventNPCScript_GotoWidgetDone: + case eEventNPCScript_AttackWidgetDone: + case eEventNPCScript_PlayAnimDone: + break; + default: + *handled = 0; + doOtherEvents = xNPCBasic::SysEvent(from, to, toEvent, toParam, toParamWidget, handled); + break; + } + + return doOtherEvents; +} + +void zNPCCommon::ConvertHitEvent(xBase* from, xBase* to, U32 toEvent, const F32* toParam, + xBase* toParamWidget, S32* handled) +{ + xVec3 pos_cruiser = {}; + xVec3* vec_hit = NULL; + F32 mag; + en_NPC_DAMAGE_TYPE what = DMGTYP_UNDECIDED; + + if (from) + { + switch (from->baseType) + { + case eBaseTypePlayer: + { + U32 mvinf = zEntPlayer_MoveInfo(); + if (mvinf & 0x8) + { + what = DMGTYP_BELOW; + } + else if (mvinf & 0x10) + { + what = DMGTYP_ABOVE; + } + else if (mvinf & 0x20) + { + what = DMGTYP_SIDE; + } + else + { + what = DMGTYP_SIDE; + } + + xVec3Sub(&pos_cruiser, xEntGetPos(&globals.player.ent), xEntGetPos(this)); + vec_hit = &pos_cruiser; + break; + } + case eBaseTypeCruiseBubble: + what = DMGTYP_CRUISEBUBBLE; + + if (toParam) + { + pos_cruiser.x = toParam[0]; + pos_cruiser.y = toParam[1]; + pos_cruiser.z = toParam[2]; + + mag = xVec3Length(&pos_cruiser); + if (mag > 0.001f) + { + xVec3SubFrom(&pos_cruiser, xEntGetPos(this)); + xVec3SMulBy(&pos_cruiser, 2.0f / mag); + + vec_hit = &pos_cruiser; + } + } + + break; + case eBaseTypeProjectile: + what = DMGTYP_PROJECTILE; + break; + case eBaseTypeBoulder: + if (globals.player.bubblebowl && globals.player.bubblebowl == (xEntBoulder*)from) + { + what = DMGTYP_BUBBOWL; + } + else + { + what = DMGTYP_BOULDER; + } + break; + } + } + + this->Damage(what, from, vec_hit); +} + +void zNPCCommon::VelStop() //NONMATCH("https://decomp.me/scratch/YizcX") +{ + this->spd_throttle = 0.0f; + this->frame->dvel.x = 0.0f; + this->frame->dvel.y = 0.0f; + this->frame->dvel.z = 0.0f; + this->frame->vel.x = 0.0f; + this->frame->vel.y = 0.0f; + this->frame->vel.z = 0.0f; + this->frame->mode |= 0xC; + + if (!this->drv_data) + { + this->frame->dpos.x = 0.0f; + this->frame->dpos.y = 0.0f; + this->frame->dpos.z = 0.0f; + this->frame->mode |= 0x2; + } + else if (!this->drv_data->driver) + { + this->frame->dpos.x = 0.0f; + this->frame->dpos.y = 0.0f; + this->frame->dpos.z = 0.0f; + this->frame->mode |= 0x2; + } +} + +F32 zNPCCommon::ThrottleAdjust(F32 dt, F32 spd_want, F32 accel) +{ + NPCConfig* cfg = this->cfg_npc; + F32 acc; + S32 speedup = (spd_want > this->spd_throttle); + + acc = (accel < 0.0f) ? (dt * cfg->fac_accelMax) : (dt * accel); + + if (xeq(spd_want, this->spd_throttle, acc)) + { + this->spd_throttle = spd_want; + return this->spd_throttle; + } + + if (speedup) + { + this->spd_throttle += acc; + this->spd_throttle = CLAMP(this->spd_throttle, 0.0f, spd_want); + } + else + { + this->spd_throttle -= acc; + this->spd_throttle = MAX(spd_want, this->spd_throttle); + } + + return this->spd_throttle; +} + +F32 zNPCCommon::ThrottleAccel(F32 dt, S32 speedup, F32 pct_max) +{ + NPCConfig* cfg = this->cfg_npc; + F32 acc = dt * cfg->fac_accelMax; + F32 spd_top = pct_max * cfg->spd_moveMax; + + if (speedup) + { + this->spd_throttle += acc; + } + else + { + this->spd_throttle -= acc; + } + + this->spd_throttle = CLAMP(this->spd_throttle, 0.0f, spd_top); + + return this->spd_throttle; +} + +F32 zNPCCommon::ThrottleApply(F32 dt, const xVec3* dir, S32 force3D) +{ + xVec3 var_30; + if (xVec3Length2(dir) < 0.00001f) + { + var_30 = *NPCC_faceDir(this) * this->spd_throttle; + } + else + { + var_30 = *dir * this->spd_throttle; + } + + var_30 *= dt; + + if ((this->flg_move & 0x2) && !force3D) + { + this->frame->dpos.x = var_30.x; + this->frame->dpos.z = var_30.z; + } + else + { + this->frame->dpos = var_30; + } + + this->frame->mode |= 0x2; + + return this->spd_throttle; +} + +F32 zNPCCommon::TurnToFace(F32 dt, const xVec3* dir_want, F32 useTurnRate) +//NONMATCH("https://decomp.me/scratch/KRonE") +{ + F32 f29 = (useTurnRate < 0.0f) ? (dt * this->cfg_npc->spd_turnMax) : (dt * useTurnRate); + F32 f30 = NPCC_dir_toXZAng(dir_want); + F32 f31 = NPCC_dir_toXZAng(NPCC_faceDir(this)); + + F32 f28 = this->frame->rot.angle; + if (this->frame->mode & 0x20) + { + f28 += this->frame->drot.angle; + } + + F32 f1_ = xDangleClamp(f30 - f28); + F32 f2_ = CLAMP(f1_, -f29, f29); + F32 f2 = CLAMP(f28 + f2_, f31 - f29, f31 + f29); + F32 f1 = f2 - f28; + + this->frame->drot.angle = f1; + this->frame->mode |= 0x20; + + return f1; + + /* + F32 ang_caller; + F32 ang_wouldbe; + F32 rot_lim; + F32 ang_true; + F32 ang_past; + F32 ang_diff; + */ +} + +void zNPCCommon::ParseLinks() +{ + for (S32 i = 0; i < this->linkCount; i++) + { + switch (this->link[i].srcEvent) + { + case eEventNPCScript_ScriptBegin: + case eEventNPCScript_ScriptEnd: + case eEventNPCScript_ScriptReady: + case eEventNPCScript_Halt: + case eEventNPCScript_SetPos: + case eEventNPCScript_SetDir: + case eEventNPCScript_LookNormal: + case eEventNPCScript_LookAlert: + case eEventNPCScript_FaceWidget: + case eEventNPCScript_FaceWidgetDone: + case eEventNPCScript_GotoWidget: + case eEventNPCScript_GotoWidgetDone: + case eEventNPCScript_AttackWidget: + case eEventNPCScript_AttackWidgetDone: + case eEventNPCScript_FollowWidget: + case eEventNPCScript_PlayAnim: + case eEventNPCScript_PlayAnimDone: + case eEventNPCScript_LeadPlayer: + xSceneID2Name(globals.sceneCur, this->id); + this->flg_misc |= 0x1; + break; + } + } +} + +void zNPCCommon::ParseINI() +{ + NPCConfig* cfg = this->cfg_npc; + + this->TagVerts(); + + for (S32 i = NPC_PARM_MOVERATE; i < NPC_PARM_ENDTAG_INI; i++) + { + en_npcparm pid = (en_npcparm)i; + + switch (pid) + { + case NPC_PARM_ACCEL: + this->GetParm(pid, &cfg->fac_accelMax); + break; + case NPC_PARM_DRIFT: + this->GetParm(pid, &cfg->fac_driftMax); + break; + case NPC_PARM_MASS: + this->GetParm(pid, &cfg->npcMass); + if (cfg->npcMass < 0.5f) + { + cfg->npcMass = 0.5f; + } + cfg->npcMassInv = 1.0f / cfg->npcMass; + break; + case NPC_PARM_TOSSELASTIC: + this->GetParm(pid, &cfg->fac_elastic); + break; + case NPC_PARM_TOSSGRAV: + this->GetParm(pid, &cfg->fac_gravKnock); + break; + case NPC_PARM_HITPOINTS: + this->GetParm(pid, &cfg->pts_damage); + break; + case NPC_PARM_BND_ISBOX: + this->GetParm(pid, &cfg->useBoxBound); + break; + case NPC_PARM_BND_CENTER: + this->GetParm(pid, &cfg->off_bound); + break; + case NPC_PARM_BND_EXTENT: + this->GetParm(pid, &cfg->dim_bound); + break; + case NPC_PARM_MOVERATE: + this->GetParm(pid, &cfg->spd_moveMax); + break; + case NPC_PARM_TURNRATE: + { + F32 fv = RAD2DEG(cfg->spd_turnMax); + this->GetParm(pid, &fv); + cfg->spd_turnMax = DEG2RAD(fv); + break; + } + case NPC_PARM_MODELSCALE: + this->GetParm(pid, &cfg->scl_model); + break; + case NPC_PARM_DETECT_RAD: + this->GetParm(pid, &cfg->rad_detect); + break; + case NPC_PARM_DETECT_HYT: + this->GetParm(pid, &cfg->hyt_detect); + break; + case NPC_PARM_DETECT_OFF: + this->GetParm(pid, &cfg->off_detect); + break; + case NPC_PARM_TIMEFIDGET: + this->GetParm(pid, &cfg->tym_fidget); + break; + case NPC_PARM_TIMEATTACK: + this->GetParm(pid, &cfg->tym_attack); + break; + case NPC_PARM_TIMESTUN: + this->GetParm(pid, &cfg->tym_stun); + break; + case NPC_PARM_TIMEALERT: + this->GetParm(pid, &cfg->tym_alert); + break; + case NPC_PARM_ATTACK_RAD: + this->GetParm(pid, &cfg->rad_attack); + break; + case NPC_PARM_ATTACK_FOV: + { + F32 fv = RAD2DEG(cfg->fov_attack); + this->GetParm(pid, &fv); + cfg->fov_attack = DEG2RAD(fv); + break; + } + case NPC_PARM_SND_RAD: + this->GetParm(pid, &cfg->rad_sound); + break; + case NPC_PARM_ATK_SIZE01: + this->GetParm(pid, &cfg->rad_dmgSize); + break; + case NPC_PARM_ATK_FRAMES01: + case NPC_PARM_ATK_FRAMES01A: + case NPC_PARM_ATK_FRAMES01B: + case NPC_PARM_ATK_FRAMES02: + case NPC_PARM_ATK_FRAMES02A: + case NPC_PARM_ATK_FRAMES02B: + case NPC_PARM_ATK_FRAMES03: + case NPC_PARM_ATK_FRAMES03A: + case NPC_PARM_ATK_FRAMES03B: + this->GetParm(pid, &cfg->animFrameRange[pid - NPC_PARM_ATK_FRAMES01]); + break; + case NPC_PARM_ESTEEM_A: + case NPC_PARM_ESTEEM_B: + case NPC_PARM_ESTEEM_C: + case NPC_PARM_ESTEEM_D: + case NPC_PARM_ESTEEM_E: + this->GetParm(pid, &cfg->cnt_esteem[pid - NPC_PARM_ESTEEM_A]); + break; + case NPC_PARM_SHADOW_CASTDIST: + this->GetParm(pid, &cfg->dst_castShadow); + break; + case NPC_PARM_SHADOW_RADCACHE: + this->GetParm(pid, &cfg->rad_shadowCache); + break; + case NPC_PARM_SHADOW_RADRASTER: + this->GetParm(pid, &cfg->rad_shadowRaster); + break; + case NPC_PARAM_TEST_COUNT: + this->GetParm(pid, &cfg->test_count); + break; + } + } +} + +void zNPCCommon::ParseProps() +{ + for (S32 i = 0x3f; i < 0x42; i++) + { + switch (i) + { + case 0x3f: + MvptReset(NULL); + break; + default: + break; + } + } +} + +void zNPCCommon::CollideReview() +{ + xEntCollis* npccol = this->collis; + xCollis* colrec = &npccol->colls[0]; + S32 i; + S32 hitthings = 0; + + if (!(colrec->flags & k_HIT_IT) && (this->flg_move & 0x2)) + { + this->colFreq = 0; + } + + if (this->drv_data) + { + if ((colrec->flags & k_HIT_IT) && colrec->optr) + { + xEnt* flent = (xEnt*)colrec->optr; + if (this->IsMountableType((en_ZBASETYPE)flent->baseType)) + { + if (!this->drv_data->driver) + { + xEntDriveMount(this->drv_data, flent, 1.0f, colrec); + } + else if (flent != this->drv_data->driver) + { + xEntDriveDismount(this->drv_data, 0.3f); + xEntDriveMount(this->drv_data, flent, 1.0f, colrec); + } + } + } + else if (this->drv_data->driver) + { + xEntDriveDismount(this->drv_data, 0.3f); + } + } + + for (i = npccol->env_sidx; i < npccol->env_eidx; i++) + { + if (!(npccol->colls[i].flags & k_HIT_0x4)) + { + hitthings++; + } + } + + for (i = npccol->stat_sidx; i < npccol->stat_eidx; i++) + { + if (!(npccol->colls[i].flags & k_HIT_0x4)) + { + hitthings++; + } + } + + for (i = npccol->dyn_sidx; i < npccol->dyn_eidx; i++) + { + if (npccol->colls[i].flags & k_HIT_0x4) + { + xBase* base = (xBase*)npccol->colls[i].optr; + if (base->baseType == eBaseTypeButton) + { + zEntButton_Hold((_zEntButton*)base, 0x800); + } + } + hitthings++; + } + + for (i = npccol->npc_sidx; i < npccol->npc_eidx; i++) + { + if (!(npccol->colls[i].flags & k_HIT_0x4)) + { + hitthings++; + } + } + + if (hitthings) + { + S32 cf = (S32)(8.0f * xurand() + 2.0); + colFreq = MIN(colFreq, cf); + } +} + +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; +} + +void zNPCCommon::TagVerts() +{ + NPCConfig* cfg = this->cfg_npc; + S32 i; + xVec3 tmp_pos = {}; + F32 vertinfo[4] = {}; + + for (i = 0; i < 20; i++) + { + if (mdlVertToParm[i] != NPC_PARM_NONE) + { + this->GetParm(mdlVertToParm[i], vertinfo); + + tmp_pos.x = vertinfo[0]; + tmp_pos.y = vertinfo[1]; + tmp_pos.z = vertinfo[2]; + + if (xVec3Dot(&tmp_pos, &tmp_pos) > 0.001f) + { + xModelInstance* mdl; + S32 idx_atmoic = (S32)vertinfo[3]; + + if (idx_atmoic < 1) + { + mdl = this->model; + } + else + { + mdl = this->ModelAtomicFind(idx_atmoic, -1, NULL); + } + + if (mdl) + { + iModelTagSetup(&cfg->tag_vert[i], mdl->Data, tmp_pos.x, tmp_pos.y, tmp_pos.z); + + if (xVec3Length2(&tmp_pos)) + { + cfg->flg_vert |= (1 << i); + } + + xSceneID2Name(globals.sceneCur, this->id); + } + } + } + } +} + +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; +} + +S32 zNPCCommon::IsAttackFrame(F32 tym_anim, S32 series) +{ + S32 result = 0; + NPCConfig* cfg = this->cfg_npc; + + if (!cfg) + return 0; + + xVec3 var_30, var_3C, var_48; + + switch (series) + { + case 0: + case 1: + var_30 = cfg->animFrameRange[0]; + var_3C = cfg->animFrameRange[1]; + var_48 = cfg->animFrameRange[2]; + break; + case 2: + var_30 = cfg->animFrameRange[3]; + var_3C = cfg->animFrameRange[4]; + var_48 = cfg->animFrameRange[5]; + break; + default: + var_30 = cfg->animFrameRange[6]; + var_3C = cfg->animFrameRange[7]; + var_48 = cfg->animFrameRange[8]; + break; + } + + F32 tym = (tym_anim < 0.0f) ? this->AnimTimeCurrent() : tym_anim; + + if (tym >= var_30.x && tym <= var_30.y) + { + result = 1; + } + else if (tym >= var_3C.x && tym <= var_3C.y) + { + result = 2; + } + else if (tym >= var_48.x && tym <= var_48.y) + { + result = 3; + } + + return result; +} + +void zNPCCommon::GiveReward() +{ + S32 i; + U32 s; + NPCConfig* cfg = this->cfg_npc; + U32 shinies[5]; + S32 esteem; + + if (this->SelfType() != NPC_TYPE_ARFDOG) + { + if ((this->SelfType() & 0xFFFFFF00) == 'NTT\0') + { + zCombo_Add(1); + } + else + { + zCombo_Add(3); + } + } + + for (i = 0, s = 0; i < 5; i++) + { + esteem = cfg->cnt_esteem[i]; + if (esteem >= 1) + { + if (esteem == globals.player.g.ShinyValuePurple) + { + shinies[s] = 0; + s++; + } + else if (esteem == globals.player.g.ShinyValueBlue) + { + shinies[s] = 1; + s++; + } + else if (esteem == globals.player.g.ShinyValueGreen) + { + shinies[s] = 2; + s++; + } + else if (esteem == globals.player.g.ShinyValueYellow) + { + shinies[s] = 3; + s++; + } + else if (esteem == globals.player.g.ShinyValueRed) + { + shinies[s] = 4; + s++; + } + else + { + shinies[i] = 4; + s++; + break; + } + } + } + + if (s) + { + zEntPickup_SpawnNRewards(shinies, s, *this->Pos()); + } + + this->PlayerKiltMe(); +} + +void zNPCPlyrSnd_Reset() +{ + g_tmr_talkless = 10.0f; +} + +void zNPCPlyrSnd_Update(F32 dt) +{ + g_tmr_talkless = MAX(-1.0f, g_tmr_talkless - dt); +} + +void zNPCCommon::PlayerKiltMe() +{ + en_xEventTags r30 = eEventUnknown; + S32 r31 = this->SelfType(); + + if (!SomethingWonderful() && g_tmr_talkless < 0.0f) + { + g_tmr_talkless = 3.0f + (xurand() - 0.5f) * 0.25f * 3.0f; + + if ((r31 & 0xFFFFFF00) == 'NTR\0') + { + r30 = eEventSituationDestroyedRobot; + } + else if ((r31 & 0xFFFFFF00) == 'NTT\0') + { + r30 = eEventSituationDestroyedTiki; + } + + if (r30 != eEventUnknown) + { + zEntEvent(this, &globals.player.ent, r30); + } + } +} + +void zNPCCommon::ISeePlayer() //NONMATCH("https://decomp.me/scratch/M08oY") +{ + en_xEventTags ven = eEventUnknown; + + if (!SomethingWonderful() && g_tmr_talkless < 0.0f) + { + g_tmr_talkless = 3.0f + (xurand() - 0.5f) * 0.25f * 3.0f; + + switch (this->SelfType()) + { + //case NPC_TYPE_UNKNOWN: + //case NPC_TYPE_BASIC: + //case NPC_TYPE_COMMON: + case NPC_TYPE_AMBIENT: + case NPC_TYPE_VILLAGER: + case NPC_TYPE_ROBOT: + case NPC_TYPE_BOSS: + case NPC_TYPE_TEST: + case NPC_TYPE_BADGUY: + case NPC_TYPE_JELLYPINK: + case NPC_TYPE_JELLYBLUE: + case NPC_TYPE_KINGNEPTUNE: + case NPC_TYPE_MIMEFISH: + //case NPC_TYPE_COW: + break; + case NPC_TYPE_TIKI_WOOD: + ven = eEventSituationSeeWoodTiki; + break; + case NPC_TYPE_TIKI_LOVEY: + ven = eEventSituationSeeLoveyTiki; + break; + case NPC_TYPE_TIKI_QUIET: + ven = eEventSituationSeeShhhTiki; + break; + case NPC_TYPE_TIKI_THUNDER: + ven = eEventSituationSeeThunderTiki; + break; + case NPC_TYPE_TIKI_STONE: + ven = eEventSituationSeeStoneTiki; + break; + case NPC_TYPE_FISH: + //case NPC_TYPE_FISH_MALE: + //case NPC_TYPE_FISH_FEMALE: + //case NPC_TYPE_FISH_ELDER: + //case NPC_TYPE_FISH_ELDESS: + //case NPC_TYPE_FISH_BOY: + //case NPC_TYPE_FISH_GIRL: + //case NPC_TYPE_BALLOONBOY: + //case NPC_TYPE_GARY: + //case NPC_TYPE_SQUIDWARD: + case NPC_TYPE_SQUIDWARD_MUSIC: + case NPC_TYPE_SQUIDWARD_BANDAID: + //case NPC_TYPE_DUTCHMAN_NSB: + //case NPC_TYPE_SANDYBIKINI: + //case NPC_TYPE_SANDYNPC: + //case NPC_TYPE_PATNPC: + //case NPC_TYPE_BOBNPC: + //case NPC_TYPE_PLANKNPC: + //case NPC_TYPE_MRKRABS: + //case NPC_TYPE_MSPUFFS: + //case NPC_TYPE_LARRY: + //case NPC_TYPE_BUBBUDDY: + //case NPC_TYPE_NEWSFISH: + case NPC_TYPE_NEWSFISHTV: + //case NPC_TYPE_MOTORIST: + //case NPC_TYPE_MERMANCHAIR: + //case NPC_TYPE_MERMAN: + case NPC_TYPE_BARNACLEBOY: + //case NPC_TYPE_WORM: + break; + case NPC_TYPE_HAMMER: + case NPC_TYPE_HAMSPIN: + ven = eEventSituationSeeHammer; + break; + case NPC_TYPE_TARTAR: + ven = eEventSituationSeeTarTar; + break; + case NPC_TYPE_GLOVE: + ven = eEventSituationSeeGLove; + break; + case NPC_TYPE_MONSOON: + ven = eEventSituationSeeMonsoon; + break; + case NPC_TYPE_SLEEPY: + ven = eEventSituationSeeSleepyTime; + break; + case NPC_TYPE_ARFDOG: + break; + case NPC_TYPE_ARFARF: + ven = eEventSituationSeeArf; + break; + case NPC_TYPE_CHUCK: + break; + case NPC_TYPE_TUBELET: + case NPC_TYPE_TUBESLAVE: + ven = eEventSituationSeeTubelets; + break; + case NPC_TYPE_SLICK: + ven = eEventSituationSeeSlick; + break; + case NPC_TYPE_FODDER: + case NPC_TYPE_FODBOMB: + case NPC_TYPE_FODBZZT: + case NPC_TYPE_CHOMPER: + case NPC_TYPE_CRITTER: + ven = eEventSituationSeeFodder; + break; + case NPC_TYPE_DUPLOTRON: + break; + case NPC_TYPE_KINGJELLY: + ven = eEventSituationSeeKingJellyfish; + break; + case NPC_TYPE_DUTCHMAN: + ven = eEventSituationSeeDutchman; + break; + case NPC_TYPE_PRAWN: + ven = eEventSituationSeePrawn; + break; + case NPC_TYPE_BOSSSANDY: + ven = eEventSituationSeeSandyBoss; + break; + case NPC_TYPE_BOSSPAT: + ven = eEventSituationSeePatrickBoss; + break; + case NPC_TYPE_BOSS_SB1: + case NPC_TYPE_BOSSBOBBY: + ven = eEventSituationSeeSpongeBobBoss; + break; + case NPC_TYPE_BOSSPLANKTON: + ven = eEventSituationSeeRobotPlankton; + break; + //case NPC_TYPE_BADGUYMEDIUM: + // break; + } + + if (ven != eEventUnknown) + { + zEntEvent(this, &globals.player.ent, ven); + } + } +} + +void zNPCCommon::ConfigSceneDone() +{ + g_ncfghead = 0; +} + +NPCConfig* zNPCCommon::ConfigCreate(U32 modelID) +{ + NPCConfig* cfg = (NPCConfig*)xMemAllocSize(sizeof(NPCConfig)); + memset(cfg, 0, sizeof(NPCConfig)); + + cfg->modelID = modelID; + + if (!g_ncfghead) + { + g_ncfghead = cfg; + } + else + { + cfg->Insert(g_ncfghead); + } + + return cfg; +} + +NPCConfig* zNPCCommon::ConfigFind(U32 modelID) +{ + NPCConfig* cfg = NULL; + + for (NPCConfig* r3 = g_ncfghead; r3 != NULL; r3 = r3->Next()) + { + if (r3->modelID == modelID) + { + cfg = r3; + break; + } + } + + return cfg; +} + +void zNPCCommon::GetParm(en_npcparm pid, S32* val) +{ + this->GetParm(pid, (void*)val); +} + +void zNPCCommon::GetParm(en_npcparm pid, F32* val) +{ + this->GetParm(pid, (void*)val); +} + +void zNPCCommon::GetParm(en_npcparm pid, xVec3* val) +{ + this->GetParm(pid, (void*)val); +} + +void zNPCCommon::GetParm(en_npcparm pid, zMovePoint** val) +{ + this->GetParm(pid, (void*)val); +} + +void zNPCCommon::GetParm(en_npcparm pid, void* val) //NONMATCH("https://decomp.me/scratch/dg7eV") +{ + char** names = g_strz_params; + xModelAssetParam* pmdata = this->parmdata; + U32 pmsize = this->pdatsize; + + this->GetParmDefault(pid, val); + + switch (pid) + { + case NPC_PARM_BND_ISBOX: + case NPC_PARM_HITPOINTS: + case NPC_PARM_ESTEEM_A: + case NPC_PARM_ESTEEM_B: + case NPC_PARM_ESTEEM_C: + case NPC_PARM_ESTEEM_D: + case NPC_PARM_ESTEEM_E: + case NPC_PARAM_TEST_COUNT: + if (pmdata && pmsize) + { + *(S32*)val = zParamGetInt(pmdata, pmsize, names[pid], *(S32*)val); + } + break; + case NPC_PARM_MOVERATE: + case NPC_PARM_TURNRATE: + case NPC_PARM_ACCEL: + case NPC_PARM_DRIFT: + case NPC_PARM_MASS: + case NPC_PARM_TOSSGRAV: + case NPC_PARM_TOSSELASTIC: + case NPC_PARM_DETECT_RAD: + case NPC_PARM_DETECT_HYT: + case NPC_PARM_DETECT_OFF: + case NPC_PARM_ATTACK_RAD: + case NPC_PARM_ATTACK_FOV: + case NPC_PARM_SND_RAD: + case NPC_PARM_TIMEFIDGET: + case NPC_PARM_TIMEATTACK: + case NPC_PARM_TIMESTUN: + case NPC_PARM_TIMEALERT: + case NPC_PARM_ATK_SIZE01: + case NPC_PARM_SHADOW_CASTDIST: + case NPC_PARM_SHADOW_RADCACHE: + case NPC_PARM_SHADOW_RADRASTER: + if (pmdata && pmsize) + { + *(F32*)val = zParamGetFloat(pmdata, pmsize, names[pid], *(F32*)val); + } + break; + case NPC_PARM_BND_CENTER: + case NPC_PARM_BND_EXTENT: + case NPC_PARM_MODELSCALE: + case NPC_PARM_ATK_FRAMES01: + case NPC_PARM_ATK_FRAMES01A: + case NPC_PARM_ATK_FRAMES01B: + case NPC_PARM_ATK_FRAMES02: + case NPC_PARM_ATK_FRAMES02A: + case NPC_PARM_ATK_FRAMES02B: + case NPC_PARM_ATK_FRAMES03: + case NPC_PARM_ATK_FRAMES03A: + case NPC_PARM_ATK_FRAMES03B: + if (pmdata && pmsize) + { + zParamGetVector(pmdata, pmsize, names[pid], *(xVec3*)val, (xVec3*)val); + } + break; + case NPC_PARM_VTX_ATTACKBASE: + case NPC_PARM_VTX_ATTACK: + case NPC_PARM_VTX_ATTACK1: + case NPC_PARM_VTX_ATTACK2: + case NPC_PARM_VTX_ATTACK3: + case NPC_PARM_VTX_ATTACK4: + case NPC_PARM_VTX_EYEBALL: + case NPC_PARM_VTX_DMGSMOKEA: + case NPC_PARM_VTX_DMGSMOKEB: + case NPC_PARM_VTX_DMGSMOKEC: + case NPC_PARM_VTX_DMGFLAMEA: + case NPC_PARM_VTX_DMGFLAMEB: + case NPC_PARM_VTX_DMGFLAMEC: + case NPC_PARM_VTX_PROPEL: + case NPC_PARM_VTX_EXHAUST: + case NPC_PARM_VTX_GEN01: + case NPC_PARM_VTX_GEN02: + case NPC_PARM_VTX_GEN03: + case NPC_PARM_VTX_GEN04: + case NPC_PARM_VTX_GEN05: + zParamGetFloatList(pmdata, pmsize, names[pid], 4, NULL, (F32*)val); + break; + case NPC_PARM_FIRSTMVPT: + if (this->npcass->movepoint) + { + zMovePoint* mvpt = zMovePoint_From_xAssetID(this->npcass->movepoint); + if (mvpt) + { + *(zMovePoint**)val = mvpt; + } + } + break; + case NPC_PARM_BOGUSSHARE: + if (pmdata && pmsize) + { + *(S32*)val = zParamGetInt(pmdata, pmsize, names[pid], *(S32*)val); + } + break; + case NPC_PARM_NONE: + case NPC_PARM_ENDTAG_INI: + case NPC_PARM_ENDTAG_PROPS: + case NPC_PARM_ENDTAG_SHARE: + break; + } +} + +void zNPCCommon::GetParmDefault(en_npcparm pid, void* val) +//NONMATCH("https://decomp.me/scratch/mNHLS") +{ + // Should be a S32? + S32 result = 1; + S32* ivp = (S32*)val; + F32* fvp = (F32*)val; + F32* fvlist = (F32*)val; + xVec3* vec = (xVec3*)val; + zMovePoint** mvpt = (zMovePoint**)val; + + switch (pid) + { + case NPC_PARM_HITPOINTS: + *ivp = 1; + break; + case NPC_PARM_MOVERATE: + *fvp = 2.0f; + break; + case NPC_PARM_TURNRATE: + *fvp = 90.0f; + break; + case NPC_PARM_ACCEL: + *fvp = 1.0f; + break; + case NPC_PARM_DRIFT: + *fvp = 0.0f; + break; + case NPC_PARM_MASS: + *fvp = 1.0f; + break; + case NPC_PARM_TOSSGRAV: + *fvp = 25.0f; + break; + case NPC_PARM_TOSSELASTIC: + *fvp = 0.5f; + break; + case NPC_PARM_BND_ISBOX: + *ivp = 0; + break; + case NPC_PARM_BND_CENTER: + xVec3Copy(vec, &g_O3); + break; + case NPC_PARM_BND_EXTENT: + xVec3Copy(vec, &g_O3); + break; + case NPC_PARM_DETECT_RAD: + *fvp = 3.0f; + break; + case NPC_PARM_DETECT_HYT: + *fvp = 6.0f; + break; + case NPC_PARM_DETECT_OFF: + *fvp = -2.0f; + break; + case NPC_PARM_ATTACK_RAD: + *fvp = 5.0f; + break; + case NPC_PARM_ATTACK_FOV: + *fvp = 60.0f; + break; + case NPC_PARM_SND_RAD: + *fvp = 30.0f; + break; + case NPC_PARM_ESTEEM_A: + case NPC_PARM_ESTEEM_B: + case NPC_PARM_ESTEEM_C: + case NPC_PARM_ESTEEM_D: + case NPC_PARM_ESTEEM_E: + *ivp = 0; + break; + case NPC_PARM_SHADOW_CASTDIST: + case NPC_PARM_SHADOW_RADCACHE: + case NPC_PARM_SHADOW_RADRASTER: + *fvp = -1.0f; + break; + case NPC_PARM_ATK_SIZE01: + *fvp = 0.5f; + break; + case NPC_PARM_ATK_FRAMES01: + vec->x = -1.0f; + vec->y = 100.0f; + vec->z = 0.0f; + break; + case NPC_PARM_ATK_FRAMES01A: + case NPC_PARM_ATK_FRAMES01B: + case NPC_PARM_ATK_FRAMES02: + case NPC_PARM_ATK_FRAMES02A: + case NPC_PARM_ATK_FRAMES02B: + case NPC_PARM_ATK_FRAMES03: + case NPC_PARM_ATK_FRAMES03A: + case NPC_PARM_ATK_FRAMES03B: + vec->x = -1.0f; + vec->y = -2.0f; + vec->z = 0.0f; + break; + case NPC_PARM_MODELSCALE: + xVec3Copy(vec, &g_O3); + break; + case NPC_PARM_TIMEFIDGET: + *fvp = 15.0f; + break; + case NPC_PARM_TIMEATTACK: + *fvp = 15.0f; + break; + case NPC_PARM_TIMESTUN: + *fvp = 5.0f; + break; + case NPC_PARM_TIMEALERT: + *fvp = 5.0f; + break; + case NPC_PARAM_TEST_COUNT: + *ivp = 1; + break; + case NPC_PARM_VTX_ATTACKBASE: + case NPC_PARM_VTX_ATTACK: + case NPC_PARM_VTX_ATTACK1: + case NPC_PARM_VTX_ATTACK2: + case NPC_PARM_VTX_ATTACK3: + case NPC_PARM_VTX_ATTACK4: + case NPC_PARM_VTX_EYEBALL: + case NPC_PARM_VTX_DMGSMOKEA: + case NPC_PARM_VTX_DMGSMOKEB: + case NPC_PARM_VTX_DMGSMOKEC: + case NPC_PARM_VTX_DMGFLAMEA: + case NPC_PARM_VTX_DMGFLAMEB: + case NPC_PARM_VTX_DMGFLAMEC: + case NPC_PARM_VTX_PROPEL: + case NPC_PARM_VTX_EXHAUST: + case NPC_PARM_VTX_GEN01: + case NPC_PARM_VTX_GEN02: + case NPC_PARM_VTX_GEN03: + case NPC_PARM_VTX_GEN04: + case NPC_PARM_VTX_GEN05: + fvlist[0] = 0.0f; + fvlist[1] = 0.0f; + fvlist[2] = 0.0f; + fvlist[3] = 0.0f; + break; + case NPC_PARM_FIRSTMVPT: + *mvpt = NULL; + break; + case NPC_PARM_ENDTAG_INI: + case NPC_PARM_ENDTAG_PROPS: + case NPC_PARM_ENDTAG_SHARE: + result = 0; + break; + default: + result = 0; + break; + } + + //return result; +} + +void zNPCCommon_WonderReset() +{ + g_isConversation = 0; + g_flg_wonder = 0; +} + +U32 zNPCCommon::CanDoSplines() +{ + bool retval = false; + if ((npcset.useNavSplines) && ((flg_move)&8)) + { + retval = true; + } + return retval; +} + +zMovePoint* zNPCCommon::FirstAssigned() +{ + zMovePoint* nav_first = NULL; + zNPCCommon::GetParm(NPC_PARM_FIRSTMVPT, &nav_first); + return nav_first; +} + +void zNPCCommon::MvptReset(zMovePoint* nav_goto) //NONMATCH("https://decomp.me/scratch/lhUW9") +{ + if (nav_goto) + { + this->nav_dest = nav_goto; + } + else + { + this->GetParm(NPC_PARM_FIRSTMVPT, &this->nav_dest); + } + + this->nav_past = this->nav_dest; + this->nav_curr = this->nav_dest; + this->nav_lead = this->nav_dest; + this->spl_mvptspline = NULL; + this->len_mvptspline = 0.0f; + this->dst_curspline = 0.0f; +} + +S32 zNPCCommon::MvptCycle() //NONMATCH("https://decomp.me/scratch/CGooj") +{ + zMovePoint* nav_tmp = NULL; + + this->spl_mvptspline = NULL; + this->len_mvptspline = 0.0f; + this->dst_curspline = 0.0f; + + if (!this->nav_curr) + { + this->GetParm(NPC_PARM_FIRSTMVPT, &this->nav_curr); + nav_tmp = this->nav_curr; + } + else if (this->nav_curr && this->nav_dest) + { + zMovePointGetNext(this->nav_dest, this->nav_curr, &nav_tmp, NULL); + } + else if (this->nav_curr) + { + zMovePointGetNext(this->nav_curr, NULL, &nav_tmp, NULL); + } + + if (this->nav_curr) + { + this->nav_past = this->nav_curr; + } + + if (this->nav_dest) + { + this->nav_curr = this->nav_dest; + } + + this->nav_dest = nav_tmp; + + if (this->CanDoSplines() && this->nav_dest && this->nav_dest->HasSpline()) + { + this->spl_mvptspline = this->nav_dest->spl; + + while (this->nav_dest->asset->bezIndex != 0) + { + this->nav_dest = (zMovePoint*)this->nav_dest->nodes[0]; + } + + this->len_mvptspline = xSpline3_ArcTotal(this->spl_mvptspline); + } + + if (this->nav_dest) + { + zMovePointGetNext(this->nav_dest, this->nav_curr, &this->nav_lead, NULL); + } + + return (this->nav_dest != NULL); +} + +S32 zNPCCommon::HaveLOSToPos(xVec3* pos, F32 dist, xScene* xscn, xBase* tgt, xCollis* colCallers) +//NONMATCH("https://decomp.me/scratch/wxm2S") +{ + S32 result; + xRay3 ray = {}; + xVec3 mypos = {}; + + xCollis* colrec; + if (colCallers) + { + colrec = colCallers; + } + else + { + static xCollis localCollis = { k_HIT_0xF00 | k_HIT_CALC_HDNG }; + memset(&localCollis, 0, sizeof(localCollis)); + localCollis.flags = k_HIT_0xF00 | k_HIT_CALC_HDNG; + + colrec = &localCollis; + } + + this->DBG_PStatCont((en_npcperf)1); + this->DBG_PStatOn((en_npcperf)2); + + if (!this->GetVertPos(NPC_MDLVERT_LOSEYEBALL, &mypos)) + { + xVec3Copy(&mypos, xEntGetCenter(this)); + } + + NPCC_xBoundAway(&this->bound); + + ray.min_t = 0.0f; + ray.max_t = dist; + xVec3Sub(&ray.dir, pos, &mypos); + xVec3Normalize(&ray.dir, &ray.dir); + xVec3Copy(&ray.origin, &mypos); + ray.flags = XRAY3_USE_MIN | XRAY3_USE_MAX; + xRayHitsScene(xscn, &ray, colrec); + + NPCC_xBoundBack(&this->bound); + + if (!(colrec->flags & k_HIT_IT)) + { + result = 1; + } + else if (colrec->dist > dist) + { + result = 1; + } + else if (tgt && colrec->oid) + { + if (tgt->id == colrec->oid) + { + result = 1; + } + else + { + result = 0; + } + } + else + { + result = 0; + } + + if (this->DBG_IsNormLog((en_npcdcat)13, 2)) + { + if (result) + { + xDrawSetColor(g_GREEN); + } + else + { + xDrawSetColor(g_NEON_BLUE); + } + + xDrawLine(&mypos, pos); + } + + this->DBG_PStatCont((en_npcperf)2); + this->DBG_PStatOn((en_npcperf)1); + + return result; +} + +xModelInstance* zNPCCommon::ModelAtomicHide(S32 index, xModelInstance* mdl) +{ + xModelInstance* minst = mdl ? mdl : this->ModelAtomicFind(index, -1, NULL); + if (!minst) + return minst; + + minst->Flags &= ~0x1; + + return minst; +} + +xModelInstance* zNPCCommon::ModelAtomicShow(S32 index, xModelInstance* mdl) +{ + xModelInstance* minst = mdl ? mdl : this->ModelAtomicFind(index, -1, NULL); + if (!minst) + return minst; + + minst->Flags |= 0x2; + minst->Flags |= 0x1; + + return minst; +} + +xModelInstance* zNPCCommon::ModelAtomicFind(S32 index, S32 idx_prev, xModelInstance* mdl_prev) +{ + xModelInstance* da_atomic = NULL; + xModelInstance* minst = mdl_prev; + S32 midx = 0; + + if (minst && idx_prev >= 0) + { + midx = idx_prev; + } + else + { + minst = this->model; + } + + while (minst) + { + if (midx == index) + { + da_atomic = minst; + break; + } + minst = minst->Next; + midx++; + } + + return da_atomic; +} + +void zNPCCommon::ModelScaleSet(F32 x, F32 y, F32 z) +{ + xModelInstance* minst = this->model; + + while (minst) + { + minst->Scale.x = x; + minst->Scale.y = y; + minst->Scale.z = z; + minst = minst->Next; + } +} + +S32 zNPCCommon::AnimStart(U32 animID, S32 forceRestart) +{ + static S32 dumptable = 0; + if (dumptable) + { + dumptable = 0; + this->AnimGetTable(); + } + + xAnimState* r3_ = this->AnimCurState(); + if (r3_ && r3_->ID == animID && !forceRestart) + { + return r3_->ID; + } + + xAnimTable* r3 = this->AnimGetTable(); + xAnimTransition* da_tran = r3->TransitionList; + + while (da_tran) + { + if (da_tran->Dest->ID == animID) + { + break; + } + da_tran = da_tran->Next; + } + + if (da_tran) + { + xAnimPlayStartTransition(this->model->Anim, da_tran); + } + else + { + xSceneID2Name(globals.sceneCur, this->id); + } + + if (da_tran) + { + return da_tran->Dest->ID; + } + + return 0; +} + +void zNPCCommon::AnimSetState(U32 animID, F32 time) +{ + xAnimTable* r3 = this->AnimGetTable(); + xAnimState* state = xAnimTableGetStateID(r3, animID); + + xAnimPlaySetState(this->model->Anim->Single, state, time); +} + +xAnimState* zNPCCommon::AnimFindState(U32 animID) +{ + xAnimTable* r3 = this->AnimGetTable(); + return xAnimTableGetStateID(r3, animID); +} + +xAnimSingle* zNPCCommon::AnimCurSingle() +{ + if (!this->model->Anim && (this->SelfType() & 0xFFFFFF00) == 'NTT\0') + { + return NULL; + } + + return this->model->Anim->Single; +} + +xAnimState* zNPCCommon::AnimCurState() +{ + if (!this->model->Anim && (this->SelfType() & 0xFFFFFF00) == 'NTT\0') + { + return NULL; + } + + return this->model->Anim->Single->State; +} + +zNPCSettings* zNPCSettings_Find(U32 id) +{ + zNPCSettings* set = NULL; + U32 size = 0; + + if (id) + { + set = (zNPCSettings*)xSTFindAsset(id, &size); + } + + if (!set) + { + set = g_dflt_npcsettings; + } + + return set; +} + +void zNPCCommon::Vibrate(F32 ds2_cur, F32 ds2_max) //NONMATCH("https://decomp.me/scratch/A5HIP") +{ + F32 rat = ds2_cur / MAX(ds2_max, 1.0f); + + if (rat < 0.4f) + { + this->Vibrate(NPC_VIBE_HARD, -1.0f); + } + else if (rat < 0.7f) + { + this->Vibrate(NPC_VIBE_NORM, -1.0f); + } + else if (rat < 1.0f) + { + this->Vibrate(NPC_VIBE_SOFT, -1.0f); + } +} + +void zNPCCommon::Vibrate(en_npcvibe vibe, F32 duration) +{ + xRumbleType typ_rum; + F32 tym_rum; + + switch (vibe) + { + case NPC_VIBE_BUILD_A: + tym_rum = 0.05f; + typ_rum = eRumble_Light; + break; + case NPC_VIBE_BUILD_B: + tym_rum = 0.05f; + typ_rum = eRumble_Medium; + break; + case NPC_VIBE_BUILD_C: + tym_rum = 0.05f; + typ_rum = eRumble_Heavy; + break; + case NPC_VIBE_SOFT: + tym_rum = 0.1f; + typ_rum = eRumble_Light; + break; + case NPC_VIBE_NORM: + tym_rum = 0.25f; + typ_rum = eRumble_Medium; + break; + case NPC_VIBE_HARD: + tym_rum = 0.45f; + typ_rum = eRumble_Heavy; + break; + default: + tym_rum = 0.0f; + typ_rum = eRumble_Medium; + zPadAddRumble(eRumble_Medium, 0.4f, 0, 0); + break; + } + + if (duration > 0.0f) + { + tym_rum = duration; } - return retval; -} -zMovePoint* zNPCCommon::FirstAssigned() -{ - zMovePoint* nav_first = NULL; - zNPCCommon::GetParm(NPC_PARM_FIRSTMVPT, &nav_first); - return nav_first; + zPadAddRumble(typ_rum, tym_rum, 0, 0); } U32 zNPCCommon::AnimCurStateID() @@ -250,6 +2868,33 @@ F32 zNPCCommon::AnimTimeCurrent() return model->Anim->Single->Time; } +void zNPCSettings_MakeDummy() //NONMATCH("https://decomp.me/scratch/amPtL") +{ + static zNPCSettings dum; + dum.id = 0xFEEDCAFE; + dum.baseType = eBaseTypeNPCSettings; + dum.linkCount = 0; + dum.baseFlags = k_XBASE_IS_ENABLED; + dum.type = 0xBAD0CACA; + dum.version = 2; + dum.handle = 0; + dum.basisType = NPCP_BASIS_NONE; + dum.allowDetect = 1; + dum.allowWander = 1; + dum.allowPatrol = 1; + dum.reduceCollide = 0; + dum.useNavSplines = 1; + dum.allowChase = 1; + dum.allowAttack = 1; + dum.assumeLOS = 0; + dum.assumeFOV = 0; + dum.duploWaveMode = NPCP_DUPOWAVE_CONTINUOUS; + dum.duploSpawnLifeMax = -1; + dum.duploSpawnDelay = 5.0f; + + g_dflt_npcsettings = &dum; +} + xVec3* zNPCCommon::MatPosSet(xVec3* pos) { if (pos != NULL) @@ -328,6 +2973,185 @@ S32 zNPCCommon::SomethingWonderful() return flg_wonder; } +S32 zNPCCommon::SndPlayFromAFX(zAnimFxSound* afxsnd, U32* sid_played) +{ + en_NPC_SOUND sndtype; + F32 radius; + U32 aidToPlay; + U32 xsid; + NPCSndProp* sprop; + + sndtype = + NPCS_SndTypeFromHash(afxsnd->ID, this->cfg_npc->snd_trax, this->cfg_npc->snd_traxShare); + if (!NPCS_SndOkToPlay(sndtype)) + { + return -1; + } + + sprop = NPCS_SndFindProps(sndtype); + radius = this->cfg_npc->rad_sound; + + if (sndtype == NPC_STYP_BOGUS) + { + aidToPlay = afxsnd->ID; + } + else + { + aidToPlay = + NPCS_SndPickSimilar(sndtype, this->cfg_npc->snd_trax, this->cfg_npc->snd_traxShare); + } + + xsid = this->SndStart(aidToPlay, sprop, radius); + + if (sid_played) + { + *sid_played = xsid; + } + + return 1; +} +S32 zNPCCommon::SndPlayFromSFX(xSFX* sfx, U32* sid_played) +{ + U32 aidToPlay; + U32 xsid; + NPCSndProp* sprop; + + this->SndKillSounds(2, 0); + + sprop = NPCS_SndFindProps(NPC_STYP_XSFXTALK); + aidToPlay = sfx->asset->soundAssetID; + xsid = this->SndStart(aidToPlay, sprop, MIN(sfx->asset->outerRadius, this->cfg_npc->rad_sound)); + + if (sid_played) + { + *sid_played = xsid; + } + + if (xsid) + { + return 1; + } + + return 0; +} + +S32 zNPCCommon::SndPlayRandom(en_NPC_SOUND sndtype) //NONMATCH("https://decomp.me/scratch/Y5Wfo") +{ + U32 xsid = 0; + NPCConfig* cfg = this->cfg_npc; + + if (NPCS_SndOkToPlay(sndtype)) + { + NPCSndProp* sprop = NPCS_SndFindProps(sndtype); + U32 aidToPlay = NPCS_SndPickSimilar(sndtype, cfg->snd_trax, cfg->snd_traxShare); + + if (aidToPlay) + { + xsid = this->SndStart(aidToPlay, sprop, cfg->rad_sound); + } + } + + if (xsid) + { + return 1; + } + + return 0; +} + +U32 zNPCCommon::SndStart(U32 aid_toplay, NPCSndProp* sprop, F32 radius) +{ + F32 pvary = 0.0f; + U32 priority; + U32 owner; + U32 xsid = 0; + F32 vol; + S32 flg_snd; + U32 xsndflags; + + if (!sprop) + { + sprop = NPCS_SndFindProps(NPC_STYP_BOGUS); + } + + flg_snd = sprop->flg_snd & 0xFFFFFF; + vol = NPCC_ds2_toCam(this->Pos(), NULL); + + if (SQ(radius) < vol) + { + return 0; + } + + if ((flg_snd & 0x20000) && this->SndChanIsBusy(1)) + { + return 0; + } + + if ((flg_snd & 0x8000) && this->SndChanIsBusy(3)) + { + return 0; + } + + static S32 idx_seq = 0; + + if (flg_snd & 0x100) + { + vol = 1.0f; + priority = 130; + } + else if (flg_snd & 0x200) + { + vol = 0.85f; + priority = 125; + } + else if (flg_snd & 0x400) + { + vol = 0.7f; + priority = 121; + } + else + { + vol = 0.85f; + priority = 125; + } + + if (flg_snd & 0x800) + { + static const F32 pitchChoices[] = { -5, -4, -3, -2, -1, 0, 1 }; + pvary = xUtil_choose(pitchChoices, ARRAY_LENGTH(pitchChoices), NULL); + } + + owner = (U32)this + (flg_snd & 0x3); // weird... + + xsndflags = 0x10000; + if (flg_snd & 0x1000) + { + xsndflags &= ~0x10000; + } + + if (aid_toplay && (flg_snd & 0x10000)) + { + xsid = xSndPlay(aid_toplay, vol, pvary, priority, xsndflags, owner, SND_CAT_GAME, 0.0f); + } + else if (aid_toplay) + { + if (flg_snd & 0x2000) + { + xsid = xSndPlay3D(aid_toplay, 0.77f * vol, pvary, priority, xsndflags, this->Pos(), + 2.0f, radius, SND_CAT_GAME, 0.0f); + } + else + { + xsid = xSndPlay3D(aid_toplay, 0.77f * vol, pvary, priority, xsndflags, (xEnt*)owner, + 2.0f, radius, SND_CAT_GAME, 0.0f); + } + } + + NPCS_SndTypePlayed(sprop->sndtype, sprop->tym_delayNext); + + return xsid; +} + S32 zNPCCommon::SndIsAnyPlaying() { S32 iVar1 = 0; @@ -344,6 +3168,69 @@ S32 zNPCCommon::SndIsAnyPlaying() return iVar1; } +S32 zNPCCommon::SndChanIsBusy(S32 flg_chan) +{ + return xSndIsPlaying(0, (U32)this + (flg_chan & 0x3)); +} + +void zNPCCommon::SndKillSounds(S32 flg_chan, S32 all) +{ + S32 owner = (S32)this; + + if (all) + { + for (S32 i = 0; i < 4; i++) + { + xSndStopChildren(owner + i); + } + } + else + { + xSndStopChildren(owner + (flg_chan & 0x3)); + } +} + +S32 zNPCCommon::SndQueUpdate(F32 dt) //NONMATCH("https://decomp.me/scratch/5SMYN") +{ + NPCSndQueue* que; + NPCSndProp* sprop; + S32 i; + S32 cnt = 0; + + for (i = 0; i < 4; i++) + { + que = &this->snd_queue[i]; + if (que->sndtype == NPC_STYP_BOGUS) + continue; + + cnt++; + + que->tmr_delay -= dt; + if (que->tmr_delay > 0.0f) + continue; + + cnt--; + + sprop = NPCS_SndFindProps(que->sndtype); + + this->SndStart(que->sndDirect, sprop, que->radius); + + que->sndtype = NPC_STYP_BOGUS; + que->sndDirect = 0; + } + + if (cnt > 0) + { + this->flg_misc |= 0x2; + } + else + { + this->flg_misc &= ~0x2; + } + + return cnt; +} + U32 zNPCCommon::LassoInit() { lassdata = PRIV_GetLassoData(); @@ -360,6 +3247,156 @@ U32 zNPCCommon::LassoInit() return 0; } +S32 zNPCCommon::LassoSetup() +{ + zNPCLassoInfo* lass = this->lassdata; + + if (lass && lass->grabGuideModel && lass->grabGuideAnim && lass->holdGuideModel && + lass->holdGuideAnim) + { + // TODO , FIXME , Causes compiler error + // zLasso_AddGuide(this, lass->grabGuideAnim, lass->grabGuideModel); + // zLasso_AddGuide(this, lass->holdGuideAnim, lass->holdGuideModel); + + lass->holdGuideModel->Flags &= ~0x1; + lass->grabGuideModel->Flags &= ~0x1; + lass->holdGuideModel->Flags |= 0x2; + lass->grabGuideModel->Flags |= 0x2; + + this->flg_vuln |= 0x1000000; + } + else + { + this->flg_vuln &= ~0x1000000; + } + + return (this->flg_vuln & 0x1000000); +} + +S32 zNPCCommon::LassoUseGuides(S32 idx_grabmdl, S32 idx_holdmdl) +{ + xModelInstance* minst; + xModelInstance* mod_grab = NULL; + xModelInstance* mod_hold = NULL; + zNPCLassoInfo* lass = this->lassdata; + S32 midx = 0; + S32 haveAnims = 0; + + for (minst = this->model; minst; minst = minst->Next) + { + if (midx == idx_grabmdl) + { + mod_grab = minst; + } + if (midx == idx_holdmdl) + { + mod_hold = minst; + } + if (mod_grab && mod_hold) + { + break; + } + + midx++; + } + + lass->grabGuideModel = mod_grab; + lass->holdGuideModel = mod_hold; + + if (mod_grab && mod_hold) + { + haveAnims = this->LassoGetAnims(mod_grab, mod_hold); + } + + return haveAnims; +} + +S32 zNPCCommon::LassoGetAnims(xModelInstance* modgrab, xModelInstance* modhold) +{ + xAnimState* ast; + xAnimState* ast_grab = NULL; + xAnimState* ast_hold = NULL; + zNPCLassoInfo* lass = this->lassdata; + + if (modgrab->Anim && !modhold->Anim) + { + modhold->Anim = modgrab->Anim; + } + + if (!modgrab->Anim && modhold->Anim) + { + modgrab->Anim = modhold->Anim; + } + + if (!modgrab->Anim || !modhold->Anim) + { + xAnimPlay* play = this->model->Anim; + while (play) + { + xAnimTable* tab = play->Table; + if (tab && !strcmp(tab->Name, "LassoGuides")) + { + modgrab->Anim = play; + modhold->Anim = play; + break; + } + play = play->Next; + } + } + + if (modhold->Anim && modhold->Anim) + { // BUG: modgrab->Anim not checked + ast = modgrab->Anim->Table ? modgrab->Anim->Table->StateList : NULL; + + while (ast) + { + if (ast->ID == g_hash_lassanim[LASS_ANIM_GRAB]) + { + ast_grab = ast; + } + if (ast->ID == g_hash_lassanim[LASS_ANIM_HOLD]) + { + ast_hold = ast; + } + if (ast_grab && ast_hold) + { + break; + } + ast = ast->Next; + } + + lass->grabGuideAnim = ast_grab; + lass->holdGuideAnim = ast_hold; + } + + return ast_grab && ast_hold; +} + +void zNPCCommon::LassoSyncAnims(en_lassanim lassanim) +{ + xAnimState* lass_ast = NULL; + xModelInstance* lass_mdl = NULL; + + switch (lassanim) + { + case LASS_ANIM_GRAB: + lass_ast = this->lassdata->grabGuideAnim; + lass_mdl = this->lassdata->grabGuideModel; + break; + case LASS_ANIM_HOLD: + lass_ast = this->lassdata->holdGuideAnim; + lass_mdl = this->lassdata->holdGuideModel; + break; + } + + if (lass_ast && lass_mdl) + { + xAnimPlaySetState(lass_mdl->Anim->Single, lass_ast, this->AnimTimeCurrent()); + } + + this->DBG_IsNormLog((en_npcdcat)14, -1); +} + zNPCLassoInfo* zNPCCommon::GimmeLassInfo() { return flg_vuln & 0x1000000 ? lassdata : NULL; @@ -404,6 +3441,67 @@ void zNPCCommon::LassoNotify(en_LASSO_EVENT event) } } +void zNPCCommon::AddBaseline(xPsyche* psy, xGoalProcessCallback eval_idle, + xGoalProcessCallback eval_patrol, xGoalProcessCallback eval_wander, + xGoalProcessCallback eval_waiting, xGoalProcessCallback eval_fidget) +{ + xGoal* goal; + + goal = psy->AddGoal(NPC_GOAL_IDLE, NULL); + goal->SetCallbacks(eval_idle, NULL, NULL, NULL); + + goal = psy->AddGoal(NPC_GOAL_WANDER, NULL); + goal->SetCallbacks(eval_wander, NULL, NULL, NULL); + + goal = psy->AddGoal(NPC_GOAL_PATROL, NULL); + goal->SetCallbacks(eval_patrol, NULL, NULL, NULL); + + goal = psy->AddGoal(NPC_GOAL_WAITING, NULL); + goal->SetCallbacks(eval_waiting, NULL, NULL, NULL); + + goal = psy->AddGoal(NPC_GOAL_FIDGET, NULL); + goal->SetCallbacks(eval_fidget, NULL, NULL, NULL); + + goal = psy->AddGoal(NPC_GOAL_LIMBO, NULL); + + this->AddDEVGoals(psy); +} + +void zNPCCommon::AddScripting(xPsyche* psy, xGoalProcessCallback eval_script, + xGoalProcessCallback eval_playanim, xGoalProcessCallback eval_attack, + xGoalProcessCallback eval_move, xGoalProcessCallback eval_follow, + xGoalProcessCallback eval_lead, xGoalProcessCallback eval_wait) +//NONMATCH("https://decomp.me/scratch/xuZpV") +{ + xGoal* goal; + + this->DBG_Name(); + + if (this->flg_misc & 0x1) + { + goal = psy->AddGoal(NPC_GOAL_SCRIPT, NULL); + goal->SetCallbacks(eval_script, NULL, NULL, NULL); + + goal = psy->AddGoal(NPC_GOAL_SCRIPTANIM, NULL); + goal->SetCallbacks(eval_playanim, NULL, NULL, NULL); + + goal = psy->AddGoal(NPC_GOAL_SCRIPTATTACK, NULL); + goal->SetCallbacks(eval_attack, NULL, NULL, NULL); + + goal = psy->AddGoal(NPC_GOAL_SCRIPTMOVE, NULL); + goal->SetCallbacks(eval_move, NULL, NULL, NULL); + + goal = psy->AddGoal(NPC_GOAL_SCRIPTFOLLOW, NULL); + goal->SetCallbacks(eval_follow, NULL, NULL, NULL); + + goal = psy->AddGoal(NPC_GOAL_SCRIPTLEAD, NULL); + goal->SetCallbacks(eval_lead, NULL, NULL, NULL); + + goal = psy->AddGoal(NPC_GOAL_SCRIPTWAIT, NULL); + goal->SetCallbacks(eval_wait, NULL, NULL, NULL); + } +} + void zNPCCommon::AddDEVGoals(xPsyche*) { } @@ -434,6 +3532,62 @@ xAnimTable* ZNPC_AnimTable_LassoGuide() return table; } +void NPCC_BuildStandardAnimTran(xAnimTable* table, char** namelist, S32* ourAnims, S32 idx_dflt, + F32 blend) //NONMATCH("https://decomp.me/scratch/iKxSo") +{ + xAnimTransition* def = NULL; + char** names = namelist; + S32 i; + + for (i = 0; ourAnims[i];) + { + if (idx_dflt == ourAnims[i]) + { + i++; + continue; + } + + if (!def) + { + def = xAnimTableNewTransition(table, names[ourAnims[i]], names[idx_dflt], NULL, NULL, + 0x10, 0, 0.0f, 0.0f, 0, 0, blend, NULL); + continue; + } + + xAnimTableAddTransition(table, def, names[ourAnims[i]]); + i++; + } + + for (i = 0; ourAnims[i];) + { + if (idx_dflt == ourAnims[i]) + { + i++; + continue; + } + + xAnimTableNewTransition(table, names[ourAnims[i]], names[idx_dflt], NULL, NULL, 0, 0, 0.0f, + 0.0f, 0, 0, blend, NULL); + xAnimTableNewTransition(table, names[idx_dflt], names[ourAnims[i]], NULL, NULL, 0, 0, 0.0f, + 0.0f, 0, 0, blend, NULL); + i++; + } +} + +void zNPCCommon_EjectPhlemOnPawz() +{ + zGameIsPaused(); + + if (globals.sceneCur->pendingPortal) + { + NPCWidget* talk_font = NPCWidget_Find(NPC_WIDGE_TALK); + if (talk_font && talk_font->IsVisible()) + { + talk_font->Off(NULL, 1); + } + } +} + U32 zNPCCommon::DBG_Name() { return 0; diff --git a/src/SB/Game/zNPCTypeCommon.h b/src/SB/Game/zNPCTypeCommon.h index 9ce4342c6..df402ac46 100644 --- a/src/SB/Game/zNPCTypeCommon.h +++ b/src/SB/Game/zNPCTypeCommon.h @@ -8,6 +8,8 @@ #include "xBehaveMgr.h" #include "xEnt.h" #include "xSFX.h" +#include "xstransvc.h" +#include "xutil.h" #include "zNPCSndTable.h" #include "zMovePoint.h" @@ -15,6 +17,17 @@ typedef struct NPCMsg; +// Will need to be moved +struct zAnimFxSound +{ + U32 ID; + F32 vol; + F32 pitch; + U32 priority; + U32 flags; + F32 radius; +}; + enum en_npcparm { NPC_PARM_NONE, @@ -353,6 +366,15 @@ enum en_SM_NOTICES SM_NOTE_FORCE = 0x7fffffff }; +enum en_lassanim +{ + LASS_ANIM_UNKNOWN, + LASS_ANIM_GRAB, + LASS_ANIM_HOLD, + LASS_ANIM_NOMORE, + LASS_ANIM_FORCEINT = FORCEENUMSIZEINT +}; + struct zNPCLassoInfo { en_LASSO_STATUS stage; @@ -401,9 +423,20 @@ struct zNPCCommon : xNPCBasic //Size of zNPCCommon: 0x2A0 F32 ThrottleAccel(F32 dt, S32 speedup, F32 pct_max); F32 ThrottleAdjust(F32 dt, F32 spd_want, F32 accel); - F32 BoundAsRadius(int useCfg); + void InitBounds(); + F32 BoundAsRadius(int useCfg) const; + void ConvertHitEvent(xBase* from, xBase* to, U32 toEvent, const F32* toParam, + xBase* toParamWidget, S32* handled); void VelStop(); + void TagVerts(); + S32 IsAttackFrame(F32 tym_anim, S32 series); static void ConfigSceneDone(); + NPCConfig* ConfigCreate(U32 modelID); + NPCConfig* ConfigFind(U32 modelID); + void GetParm(en_npcparm pid, S32* val); + void GetParm(en_npcparm pid, F32* val); + void GetParm(en_npcparm pid, xVec3* val); + void GetParm(en_npcparm pid, zMovePoint** val); U32 LassoInit(); zNPCLassoInfo* GimmeLassInfo(); void AddDEVGoals(xPsyche*); @@ -426,17 +459,27 @@ struct zNPCCommon : xNPCBasic //Size of zNPCCommon: 0x2A0 xModelInstance* ModelAtomicHide(int index, xModelInstance* mdl); xModelInstance* ModelAtomicShow(int index, xModelInstance* mdl); S32 AnimStart(U32 animID, S32 forceRestart); + void AnimSetState(U32 animID, F32 time); xAnimState* AnimFindState(U32 animID); xAnimState* AnimCurState(); xAnimSingle* AnimCurSingle(); U32 AnimCurStateID(); U32 CanDoSplines(); void GiveReward(); + void PlayerKiltMe(); + void ISeePlayer(); + S32 SndPlayFromAFX(zAnimFxSound* afxsnd, U32* sid_played); S32 SndPlayFromSFX(xSFX* sfx, U32* sid_played); S32 SndPlayRandom(en_NPC_SOUND sndtype); + U32 SndStart(U32 aid_toplay, NPCSndProp* sprop, F32 radius); S32 SndChanIsBusy(S32 flg_chan); + void SndKillSounds(S32 flg_chan, S32 all); + S32 SndQueUpdate(F32 dt); S32 LassoUseGuides(S32 idx_grabmdl, S32 idx_holdmdl); + S32 LassoGetAnims(xModelInstance* modgrab, xModelInstance* modhold); + void LassoSyncAnims(en_lassanim lassanim); S32 GetVertPos(en_mdlvert vid, xVec3* pos); + void Vibrate(F32 ds2_cur, F32 ds2_max); 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*), @@ -639,6 +682,7 @@ static void zNPCPlyrSnd_Update(F32 dt); void zNPCCommon_SceneReset(); void ZNPC_Destroy_Common(xFactoryInst* inst); void zNPCSettings_MakeDummy(); +zNPCSettings* zNPCSettings_Find(U32); void ZNPC_Common_Startup(); void zNPCCommon_WonderReset(); void ZNPC_Common_Shutdown();