From d2c5d922387fc7648f1d4c1ef64e02cca9428cd8 Mon Sep 17 00:00:00 2001 From: Steven Casper Date: Sat, 9 Aug 2025 21:56:00 -0700 Subject: [PATCH 1/3] Progress --- src/SB/Game/zAssetTypes.cpp | 148 ++++++++++++++++++++++++++++++++++- src/SB/Game/zAssetTypes.h | 53 +++++++++++++ src/SB/Game/zNPCTypeCommon.h | 3 + 3 files changed, 202 insertions(+), 2 deletions(-) diff --git a/src/SB/Game/zAssetTypes.cpp b/src/SB/Game/zAssetTypes.cpp index c4ff20f4e..581e93f26 100644 --- a/src/SB/Game/zAssetTypes.cpp +++ b/src/SB/Game/zAssetTypes.cpp @@ -1,15 +1,16 @@ #include "zAssetTypes.h" +#include "xAnim.h" #include "xstransvc.h" #include "xDebug.h" #include "xEnv.h" #include "xJSP.h" +#include "xMorph.h" #include #include #include #include -#include static void* Curve_Read(void* param_1, U32 param_2, void* indata, U32 insize, U32* outsize); static void* ATBL_Read(void* param_1, U32 param_2, void* indata, U32 insize, U32* outsize); @@ -509,8 +510,151 @@ static U8 dummyEffectCB(U32, xAnimActiveEffect*, xAnimSingle*, void*) return 0; } -static void* ATBL_Read(void*, unsigned int, void*, unsigned int, unsigned int*) +static U32 soundEffectCB(U32 cbenum, xAnimActiveEffect* acteffect, xAnimSingle* single, + void* object) { + U32 sndhandle = 0; + U32 vil_SID = 0; + S32 vil_result; + + if (cbenum == 1) + { + xEnt* ent_tmp = (xEnt*)object; + zAnimFxSound* snd = (zAnimFxSound*)(acteffect->Effect + 1); + if (ent_tmp == NULL) + { + vil_result = 0; + } + else if (ent_tmp->baseType == eBaseTypeNPC) + { + vil_result = ((zNPCCommon*)ent_tmp)->SndPlayFromAFX(snd, &vil_SID); + } + else + { + vil_result = 0; + } + + if (vil_result > 0) + { + sndhandle = vil_SID; + } + else if (vil_result < 0) + { + sndhandle = 0; + } + else + { + U32 id = snd->ID; + U32 newId; + F32 volFactor; + + static U32 footSelector = 0; + footSelector++; + if (id == 0x42B584CB || id == 0x56E1F71E || id == 0x331BDF8F) + { + newId = 0; + volFactor = 1.0f; + + switch (id) + { + case 0x42B584CB: + { + newId = footSelector % 2 ? s_sbFootSoundA : s_sbFootSoundB; + volFactor = 0.6f; + break; + } + case 0x56E1F71E: + { + newId = footSelector % 2 ? s_scFootSoundA : s_scFootSoundB; + volFactor = 0.4f; + break; + } + case 0x331BDF8F: + { + newId = footSelector % 2 ? s_patFootSoundA : s_patFootSoundB; + volFactor = 0.6f; + break; + } + } + volFactor *= 0.65f; + sndhandle = xSndPlay(newId, snd->vol * 0.77f * volFactor, snd->pitch, snd->priority, + snd->flags, 0, SND_CAT_GAME, 0.0f); + } + else + { + sndhandle = xSndPlay3D(snd->ID, snd->vol * 0.77f, snd->pitch, snd->priority, + snd->flags, (xEnt*)object, snd->radius, SND_CAT_GAME, 0.0f); + } + } + } + if (cbenum == 3) + { + xSndStop(acteffect->Handle); + } + + return sndhandle; +} + +static void* FindAssetCB(U32 ID, char*) +{ + U32 size; + return xSTFindAsset(ID, &size); +} + +static void* ATBL_Read(void*, U32, void* indata, U32, U32* outsize) +{ + U32 i; + U32 j; + U32 debugNum; + U32 tmpsize; + + xAnimTable* table; + xAnimState* astate; + xAnimTransition* atran; + U8* zaBytes; + xAnimAssetTable* zaTbl = (xAnimAssetTable*)indata; + void** zaRaw = (void**)(zaTbl + 1); + + for (i = 0; i < zaTbl->NumRaw; ++i) + { + zaRaw[i] = xSTFindAsset(*(U32*)&zaRaw[i], &tmpsize); + } + + for (i = 0; i < zaTbl->NumRaw; ++i) + { + if (zaRaw[i] == NULL) + { + continue; + } + + for (j = 0; j < zaTbl->NumRaw; ++j) + { + if (zaRaw[j] == NULL) + { + continue; + } + zaRaw[j] = zaRaw[i]; + } + } + + for (i = 0; i < zaTbl->NumRaw; ++i) + { + if (*(U32*)zaRaw[i] == 'QSPM') + { + xMorphSeqSetup(zaRaw[i], FindAssetCB); + } + } + xAnimAssetFile* zaFile; + xAnimAssetState* zaState; + S32 k; + xAnimFile** fList; + xAnimTable* (*constructor)(); + // S32 i; + char tmpstr[32]; + xAnimFile* foundFile; + xAnimState* state; + xAnimAssetEffect* zaEffect; + xAnimEffect* effect; return NULL; } diff --git a/src/SB/Game/zAssetTypes.h b/src/SB/Game/zAssetTypes.h index b47b18573..c7fe6d565 100644 --- a/src/SB/Game/zAssetTypes.h +++ b/src/SB/Game/zAssetTypes.h @@ -40,6 +40,59 @@ class HackModelRadius F32 radius; }; +// Note (Square): I'm not sure if this should be in this header but it looks to only be used in one other place +struct zAnimFxSound +{ + U32 ID; + F32 vol; + F32 pitch; + U32 priority; + U32 flags; + F32 radius; +}; + +struct xAnimAssetTable +{ + U32 Magic; + U32 NumRaw; + U32 NumFiles; + U32 NumStates; + U32 ConstructFunc; +}; + +struct xAnimAssetFile +{ + U32 FileFlags; + F32 Duration; + F32 TimeOffset; + U16 NumAnims[2]; + void** RawData; + S32 Physics; + S32 StartPose; + S32 EndPose; +}; + +struct xAnimAssetState +{ + U32 StateID; + U32 FileIndex; + U32 EffectCount; + U32 EffectOffset; + F32 Speed; + U32 SubStateID; + U32 SubStateCount; +}; + +struct xAnimAssetEffect +{ + U32 StateID; + F32 StartTime; + F32 EndTime; + U32 Flags; + U32 EffectType; + U32 UserDataSize; +}; + void zAssetStartup(); void zAssetShutdown(); void FootstepHackSceneEnter(); diff --git a/src/SB/Game/zNPCTypeCommon.h b/src/SB/Game/zNPCTypeCommon.h index 3cbb0481d..80233c0ce 100644 --- a/src/SB/Game/zNPCTypeCommon.h +++ b/src/SB/Game/zNPCTypeCommon.h @@ -27,6 +27,8 @@ typedef struct NPCMsg; +class zAnimFxSound; + enum en_npcparm { NPC_PARM_NONE, @@ -460,6 +462,7 @@ struct zNPCCommon : xNPCBasic //Size of zNPCCommon: 0x2A0 void GiveReward(); void PlayerKiltMe(); S32 SndPlayFromSFX(xSFX* sfx, U32* sid_played); + S32 SndPlayFromAFX(zAnimFxSound* afx, U32* sid_played); S32 SndPlayRandom(en_NPC_SOUND sndtype); //U32 SndStart(U32 aid_toplay, NPCSndProp* sprop, F32 radius); S32 SndChanIsBusy(S32 flg_chan); From da2f9ee0e257e9495ba9559c0edb6dfa99668695 Mon Sep 17 00:00:00 2001 From: Steven Casper Date: Sun, 10 Aug 2025 03:46:49 -0700 Subject: [PATCH 2/3] zAssetTypes done for now --- configure.py | 2 +- src/SB/Core/x/xAnim.h | 15 ++-- src/SB/Core/x/xSnd.h | 6 ++ src/SB/Game/zAssetTypes.cpp | 158 ++++++++++++++++++++++++++------- src/SB/Game/zEntCruiseBubble.h | 4 +- 5 files changed, 144 insertions(+), 41 deletions(-) diff --git a/configure.py b/configure.py index c385f046f..390788af6 100644 --- a/configure.py +++ b/configure.py @@ -421,7 +421,7 @@ def MatchingFor(*versions): Object(Matching, "SB/Core/x/xVec3.cpp"), Object(NonMatching, "SB/Game/zActionLine.cpp"), Object(Equivalent, "SB/Game/zAnimList.cpp"), - Object(NonMatching, "SB/Game/zAssetTypes.cpp"), + Object(NonMatching, "SB/Game/zAssetTypes.cpp", extra_cflags=["-sym on"]), Object(NonMatching, "SB/Game/zCamera.cpp"), Object(Matching, "SB/Game/zConditional.cpp"), Object(NonMatching, "SB/Game/zCutsceneMgr.cpp"), diff --git a/src/SB/Core/x/xAnim.h b/src/SB/Core/x/xAnim.h index d9a5823f6..93d8a429c 100644 --- a/src/SB/Core/x/xAnim.h +++ b/src/SB/Core/x/xAnim.h @@ -65,7 +65,7 @@ struct xAnimState F32 Speed; xAnimFile* Data; xAnimEffect* Effects; - + // 0x20 xAnimTransitionList* Default; xAnimTransitionList* List; @@ -177,10 +177,11 @@ struct xAnimPlay void (*BeforeAnimMatrices)(xAnimPlay*, xQuat*, xVec3*, S32); }; -class AnimTableList { // size: 0xC +class AnimTableList +{ // size: 0xC public: - char * name; // offset 0x0, size 0x4 - class xAnimTable * (* constructor)(); // offset 0x4, size 0x4 + char* name; // offset 0x0, size 0x4 + class xAnimTable* (*constructor)(); // offset 0x4, size 0x4 unsigned int id; // offset 0x8, size 0x4 }; @@ -188,6 +189,9 @@ void xAnimInit(); void xAnimTempTransitionInit(U32 count); xAnimFile* xAnimFileNew(void* rawData, const char* name, U32 flags, xAnimFile** linkedList); xAnimTable* xAnimTableNew(const char* name, xAnimTable** linkedList, U32 userFlags); +xAnimFile* xAnimFileNewBilinear(void** rawData, const char* name, U32 flags, xAnimFile** linkedList, + U32 numX, U32 numY); +void xAnimFileSetTime(xAnimFile* data, float duration, float timeOffset); xAnimState* xAnimTableNewState(xAnimTable* table, const char* name, U32 flags, U32 userFlags, F32 speed, F32* boneBlend, F32* timeSnap, F32 fadeRecip, U16* fadeOffset, void* callbackData, @@ -199,6 +203,8 @@ xAnimTransition* xAnimTableNewTransition(xAnimTable* table, const char* source, xAnimTransitionCallback callback, U32 flags, U32 userFlags, F32 srcTime, F32 destTime, U16 priority, U16 queuePriority, F32 blendRecip, U16* blendOffset); +xAnimEffect* xAnimStateNewEffect(xAnimState* state, U32 flags, F32 startTime, F32 endTime, + xAnimEffectCallback callback, U32 userDataSize); void xAnimDefaultBeforeEnter(xAnimPlay* play, xAnimState* state); void xAnimPoolInit(xMemPool* pool, U32 count, U32 singles, U32 blendFlags, U32 effectMax); xAnimPlay* xAnimPoolAlloc(xMemPool* pool, void* object, xAnimTable* table, @@ -225,5 +231,4 @@ inline F32 xAnimFileRawTime(xAnimFile* data, float time) return data->TimeOffset + time; } - #endif diff --git a/src/SB/Core/x/xSnd.h b/src/SB/Core/x/xSnd.h index 771ef4b0d..295823de8 100644 --- a/src/SB/Core/x/xSnd.h +++ b/src/SB/Core/x/xSnd.h @@ -155,4 +155,10 @@ void xSndSetPitch(U32 snd, F32 pitch); void xSndSetCategoryVol(sound_category category, F32 vol); void xSndSetExternalCallback(void (*callback)(U32)); +inline U32 xSndPlay3D(U32 id, F32 vol, F32 pitch, U32 priority, U32 flags, xEnt* ent, F32 radius, + sound_category category, F32 delay) +{ + return xSndPlay3D(id, vol, pitch, priority, flags, ent, radius / 4.0f, radius, category, delay); +} + #endif diff --git a/src/SB/Game/zAssetTypes.cpp b/src/SB/Game/zAssetTypes.cpp index 581e93f26..e93daee27 100644 --- a/src/SB/Game/zAssetTypes.cpp +++ b/src/SB/Game/zAssetTypes.cpp @@ -220,7 +220,7 @@ static char* jsp_shadow_hack_textures[] = { "glass_broken", "ground_path_alpha", }; -static char** jsp_shadow_hack_end_textures = &jsp_shadow_hack_textures[4]; +static char** jsp_shadow_hack_end_textures = &jsp_shadow_hack_textures[5]; struct AnimTableList animTable[33] = { { "ZNPC_AnimTable_Test", ZNPC_AnimTable_Test, 0 }, @@ -345,7 +345,7 @@ static void jsp_shadow_hack(xJSPHeader* header) RpClumpForAllAtomics(header->clump, jsp_shadow_hack_atomic_cb, &context); } -static xAnimTable* (*tableFuncList[48])() = { +static xAnimTable* (*tableFuncList[])() = { zEntPlayer_AnimTable, ZNPC_AnimTable_Common, zPatrick_AnimTable, @@ -390,7 +390,7 @@ static xAnimTable* (*tableFuncList[48])() = { ZNPC_AnimTable_NightLight, ZNPC_AnimTable_HazardStd, ZNPC_AnimTable_FloatDevice, - anim_table, // Cruise Bubble anim table based on PS2 DWARF data + cruise_bubble::anim_table, // Cruise Bubble anim table based on PS2 DWARF data ZNPC_AnimTable_BossSandyScoreboard, zEntPlayer_TreeDomeSBAnimTable, NULL, @@ -505,7 +505,7 @@ void FootstepHackSceneEnter() s_patFootSoundB = xStrHash("Pat_run_rock_dryR"); } -static U8 dummyEffectCB(U32, xAnimActiveEffect*, xAnimSingle*, void*) +static U32 dummyEffectCB(U32, xAnimActiveEffect*, xAnimSingle*, void*) { return 0; } @@ -595,25 +595,33 @@ static U32 soundEffectCB(U32 cbenum, xAnimActiveEffect* acteffect, xAnimSingle* return sndhandle; } +static U32 (*effectFuncList[])(U32, xAnimActiveEffect*, xAnimSingle*, void*) = { dummyEffectCB, + soundEffectCB }; + static void* FindAssetCB(U32 ID, char*) { U32 size; return xSTFindAsset(ID, &size); } -static void* ATBL_Read(void*, U32, void* indata, U32, U32* outsize) +static xAnimTable* Anim_ATBL_getTable(xAnimTable* (*constructor)()); +static void* ATBL_Read(void*, U32, void* indata, U32 param_4, U32* outsize) { U32 i; U32 j; - U32 debugNum; + U32 debugNum = 0; U32 tmpsize; xAnimTable* table; xAnimState* astate; xAnimTransition* atran; U8* zaBytes; + xAnimAssetTable* zaTbl = (xAnimAssetTable*)indata; void** zaRaw = (void**)(zaTbl + 1); + xAnimAssetFile* zaFile = (xAnimAssetFile*)(zaRaw + zaTbl->NumRaw); + xAnimAssetState* zaState = + (xAnimAssetState*)((U32)zaFile + zaTbl->NumFiles * sizeof(xAnimAssetFile)); for (i = 0; i < zaTbl->NumRaw; ++i) { @@ -624,16 +632,14 @@ static void* ATBL_Read(void*, U32, void* indata, U32, U32* outsize) { if (zaRaw[i] == NULL) { - continue; - } - - for (j = 0; j < zaTbl->NumRaw; ++j) - { - if (zaRaw[j] == NULL) + for (j = 0; j < zaTbl->NumRaw; ++j) { - continue; + if (zaRaw[j] != NULL) + { + zaRaw[i] = zaRaw[j]; + break; + } } - zaRaw[j] = zaRaw[i]; } } @@ -644,18 +650,110 @@ static void* ATBL_Read(void*, U32, void* indata, U32, U32* outsize) xMorphSeqSetup(zaRaw[i], FindAssetCB); } } - xAnimAssetFile* zaFile; - xAnimAssetState* zaState; - S32 k; - xAnimFile** fList; - xAnimTable* (*constructor)(); - // S32 i; + + for (i = 0; i < zaTbl->NumFiles; ++i) + { + zaFile[i].RawData = (void**)((U32)zaFile[i].RawData + (U32)zaTbl); + for (S32 k = 0; k < zaFile[i].NumAnims[0] * zaFile[i].NumAnims[1]; ++k) + { + zaFile[i].RawData[k] = zaRaw[(U32)zaFile[i].RawData[k]]; + } + } + + xAnimFile** fList = (xAnimFile**)zaFile; + for (i = 0; i < zaTbl->NumFiles; ++i) + { + fList[i] = xAnimFileNewBilinear(zaFile[i].RawData, "", zaFile[i].FileFlags, NULL, + zaFile[i].NumAnims[0], zaFile[i].NumAnims[1]); + if (zaFile[i].TimeOffset >= 0.0f) + { + xAnimFileSetTime(fList[i], zaFile[i].Duration, zaFile[i].TimeOffset); + } + } + + xAnimTable* (*constructor)() = NULL; + if (zaTbl->ConstructFunc < sizeof(tableFuncList) / sizeof(xAnimTable * (*)())) + { + constructor = tableFuncList[zaTbl->ConstructFunc]; + } + else + { + for (S32 i = 0; i < sizeof(animTable) / sizeof(AnimTableList); ++i) + { + if (zaTbl->ConstructFunc == animTable[i].id) + { + constructor = animTable[i].constructor; + break; + } + } + } + + gxAnimUseGrowAlloc = true; + + table = Anim_ATBL_getTable(constructor); + char tmpstr[32]; - xAnimFile* foundFile; - xAnimState* state; - xAnimAssetEffect* zaEffect; - xAnimEffect* effect; - return NULL; + for (i = 0; i < zaTbl->NumStates; ++i) + { + astate = xAnimTableAddFileID(table, fList[zaState[i].FileIndex], zaState[i].StateID, + zaState[i].SubStateID, zaState[i].SubStateCount); + + if (astate == NULL) + { + sprintf(tmpstr, "Debug%02d", debugNum++); + astate = xAnimTableNewState(table, tmpstr, 0x20, 0x80000000, 1.0f, NULL, NULL, 0.0f, + NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + atran = xAnimTableNewTransition(table, tmpstr, NULL, NULL, NULL, 0x10, 0, 0.0f, 0.0f, 0, + 0, 0.2f, NULL); + atran->Dest = table->StateList; + xAnimTableAddFileID(table, fList[zaState[i].FileIndex], astate->ID, 0, 0); + } + astate->Speed = zaState[i].Speed; + } + + xAnimFile* foundFile = NULL; + for (astate = table->StateList; astate != NULL; astate = astate->Next) + { + if (foundFile == NULL && astate->Data != NULL) + { + foundFile = astate->Data; + } + } + for (astate = table->StateList; astate != NULL; astate = astate->Next) + { + if (astate->Data == NULL) + { + astate->Data = foundFile; + astate->UserFlags |= 0x40000000; + } + } + + for (i = 0; i < zaTbl->NumStates; ++i) + { + if (zaState[i].EffectCount != 0) + { + xAnimState* state = xAnimTableGetStateID(table, zaState[i].StateID); + xAnimAssetEffect* zaEffect = (xAnimAssetEffect*)((U32)zaTbl + zaState[i].EffectOffset); + + if (state != NULL) + { + for (j = 0; j < zaState[i].EffectCount; ++j) + { + xAnimEffect* effect = + xAnimStateNewEffect(state, zaEffect->Flags, zaEffect->StartTime, + zaEffect->EndTime, effectFuncList[zaEffect->EffectType], + zaEffect->UserDataSize); + memcpy(effect + 1, zaEffect + 1, zaEffect->UserDataSize); + + zaEffect = (xAnimAssetEffect*)(U32(zaEffect) + zaEffect->UserDataSize) + 1; + } + } + } + } + + gxAnimUseGrowAlloc = false; + *outsize = sizeof(xAnimTable); + return table; } static void Anim_Unload(void*, U32) @@ -667,9 +765,9 @@ static void LightKit_Unload(void* userdata, U32 b) xLightKit_Destroy((xLightKit*)userdata); } -static void Anim_ATBL_getTable(xAnimTable* (*param)(void)) +static xAnimTable* Anim_ATBL_getTable(xAnimTable* (*constructor)()) { - *param(); + return constructor(); } static void MovePoint_Unload(void* userdata, U32 b) @@ -700,9 +798,3 @@ static void* SndInfoRead(void* param_1, U32 param_2, void* indata, U32 insize, U return __dest; } - -U32 xSndPlay3D(U32 id, F32 vol, F32 pitch, U32 priority, U32 flags, xEnt* ent, F32 radius, - sound_category category, F32 delay) -{ - return xSndPlay3D(id, vol, pitch, priority, flags, ent, radius / 4.0f, radius, category, delay); -} diff --git a/src/SB/Game/zEntCruiseBubble.h b/src/SB/Game/zEntCruiseBubble.h index 19ded2cc5..7a9c62b2a 100644 --- a/src/SB/Game/zEntCruiseBubble.h +++ b/src/SB/Game/zEntCruiseBubble.h @@ -648,8 +648,8 @@ namespace cruise_bubble bool event_handler(xBase* from, U32 event, const F32* fparam, xBase* to); xMat4x3* get_player_mat(); xMat4x3* get_missle_mat(); -} // namespace cruise_bubble + xAnimTable* anim_table(); -xAnimTable* anim_table(); +} // namespace cruise_bubble #endif From c6d8fde1ddc5b3ed3957056526623663782a756b Mon Sep 17 00:00:00 2001 From: Steven Casper Date: Sat, 30 Aug 2025 22:51:59 -0700 Subject: [PATCH 3/3] Mark zAssetTypes equivalent --- configure.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.py b/configure.py index 390788af6..60438f4ee 100644 --- a/configure.py +++ b/configure.py @@ -421,7 +421,7 @@ def MatchingFor(*versions): Object(Matching, "SB/Core/x/xVec3.cpp"), Object(NonMatching, "SB/Game/zActionLine.cpp"), Object(Equivalent, "SB/Game/zAnimList.cpp"), - Object(NonMatching, "SB/Game/zAssetTypes.cpp", extra_cflags=["-sym on"]), + Object(Equivalent, "SB/Game/zAssetTypes.cpp", extra_cflags=["-sym on"]), Object(NonMatching, "SB/Game/zCamera.cpp"), Object(Matching, "SB/Game/zConditional.cpp"), Object(NonMatching, "SB/Game/zCutsceneMgr.cpp"),