From 0ffbc021e2bc930bf05a1c4544d704ca1c48b9c8 Mon Sep 17 00:00:00 2001 From: yaz0r <363511+yaz0r@users.noreply.github.com> Date: Sat, 14 Jun 2025 02:08:20 -0700 Subject: [PATCH] Implement reset animations, cleanups and fix a few sanitizer issues --- FitdLib/aitdBox.cpp | 6 ++ FitdLib/anim.cpp | 163 +++++++++++++++++++++++------------------ FitdLib/anim.h | 3 +- FitdLib/animAction.cpp | 12 +-- FitdLib/debugger.cpp | 4 +- FitdLib/evalVar.cpp | 13 ++-- FitdLib/life.cpp | 84 +++++++++++++++------ FitdLib/main.cpp | 124 +++++++++++++++++-------------- FitdLib/mainLoop.cpp | 14 ++-- FitdLib/object.cpp | 16 ++-- FitdLib/save.cpp | 28 +++---- FitdLib/track.cpp | 8 +- FitdLib/vars.cpp | 13 ++-- FitdLib/vars.h | 16 ++-- 14 files changed, 298 insertions(+), 206 deletions(-) diff --git a/FitdLib/aitdBox.cpp b/FitdLib/aitdBox.cpp index e33fe4d..e1a855a 100644 --- a/FitdLib/aitdBox.cpp +++ b/FitdLib/aitdBox.cpp @@ -28,6 +28,12 @@ void afficheSprite(int left, int top, int index, char* gfxData) offset = 320 - width; + // Prevent overflow + if(height + top > 200) + { + height = top - 200; + } + for(i=0;i g_bodyBufferMap; int SetAnimObjet(int frame, char* anim, char* body) -{ - sAnimation* pAnimation = getAnimationFromPtr(anim); +{ + sAnimation* pAnimation = getAnimationFromPtr(anim); s16 temp; s16 ax; @@ -129,23 +129,23 @@ int InitAnim(int animNum,int animType, int animInfo) { if(animNum == currentProcessedActorPtr->ANIM) { - if(!(currentProcessedActorPtr->_flags & AF_ANIMATED)) + if(!(currentProcessedActorPtr->objectType & AF_ANIMATED)) { - if(currentProcessedActorPtr->_flags & AF_BOXIFY) + if(currentProcessedActorPtr->objectType & AF_BOXIFY) { removeFromBGIncrust(currentProcessedActorIdx); } - currentProcessedActorPtr->_flags |= AF_ANIMATED; + currentProcessedActorPtr->objectType |= AF_ANIMATED; - SetAnimObjet(currentProcessedActorPtr->FRAME, HQR_Get(listAnim,animNum), HQR_Get(listBody, currentProcessedActorPtr->bodyNum)); + SetAnimObjet(currentProcessedActorPtr->frame, HQR_Get(listAnim,animNum), HQR_Get(listBody, currentProcessedActorPtr->bodyNum)); currentProcessedActorPtr->animType = animType; currentProcessedActorPtr->animInfo = animInfo; if(g_gameId > AITD1) { - currentProcessedActorPtr->FRAME = 0; + currentProcessedActorPtr->frame = 0; } return 1; @@ -164,11 +164,11 @@ int InitAnim(int animNum,int animType, int animInfo) return(1); } - if(!(currentProcessedActorPtr->_flags & AF_ANIMATED)) + if(!(currentProcessedActorPtr->objectType & AF_ANIMATED)) { - currentProcessedActorPtr->_flags |= AF_ANIMATED; + currentProcessedActorPtr->objectType |= AF_ANIMATED; - if(currentProcessedActorPtr->_flags & AF_BOXIFY) + if(currentProcessedActorPtr->objectType & AF_BOXIFY) { removeFromBGIncrust(currentProcessedActorIdx); } @@ -180,7 +180,7 @@ int InitAnim(int animNum,int animType, int animInfo) currentProcessedActorPtr->newAnimInfo = animInfo; if(g_gameId > AITD1) { - currentProcessedActorPtr->FRAME = 0; + currentProcessedActorPtr->frame = 0; } return 1; } @@ -215,7 +215,7 @@ int InitAnim(int animNum,int animType, int animInfo) if(g_gameId != AITD1) { - currentProcessedActorPtr->FRAME = 0; + currentProcessedActorPtr->frame = 0; } return(1); @@ -293,52 +293,64 @@ void updateAnimation(void) int newAnim = currentProcessedActorPtr->newAnim; - if(newAnim != -1) // next anim ? - { - if(newAnim == -2) // completely stop anim and add actor to background - { - addActorToBgInscrust(currentProcessedActorIdx); - currentProcessedActorPtr->newAnim = -1; - currentProcessedActorPtr->newAnimType = 0; - currentProcessedActorPtr->newAnimInfo = -1; - currentProcessedActorPtr->END_ANIM = 1; + if (newAnim != -1) // next anim ? + { + if (newAnim == -2) // completely stop anim and add actor to background + { + addActorToBgInscrust(currentProcessedActorIdx); + currentProcessedActorPtr->newAnim = -1; + currentProcessedActorPtr->newAnimType = 0; + currentProcessedActorPtr->newAnimInfo = -1; + currentProcessedActorPtr->flagEndAnim = 1; - return; - } + return; + } + else { + if (!(currentProcessedActorPtr->newAnimType & ANIM_RESET)) // Reset + { + if (currentProcessedActorPtr->END_FRAME == 0) + { + currentProcessedActorPtr->worldX += currentProcessedActorPtr->stepX; + currentProcessedActorPtr->roomX += currentProcessedActorPtr->stepX; - if(currentProcessedActorPtr->END_FRAME == 0) - { - currentProcessedActorPtr->worldX += currentProcessedActorPtr->stepX; - currentProcessedActorPtr->roomX += currentProcessedActorPtr->stepX; + currentProcessedActorPtr->worldZ += currentProcessedActorPtr->stepZ; + currentProcessedActorPtr->roomZ += currentProcessedActorPtr->stepZ; - currentProcessedActorPtr->worldZ += currentProcessedActorPtr->stepZ; - currentProcessedActorPtr->roomZ += currentProcessedActorPtr->stepZ; + currentProcessedActorPtr->stepX = 0; + currentProcessedActorPtr->stepZ = 0; - currentProcessedActorPtr->stepX = 0; - currentProcessedActorPtr->stepZ = 0; + currentProcessedActorPtr->animNegX = 0; + currentProcessedActorPtr->animNegY = 0; + currentProcessedActorPtr->animNegZ = 0; + } - currentProcessedActorPtr->animNegX = 0; - currentProcessedActorPtr->animNegY = 0; - currentProcessedActorPtr->animNegZ = 0; - } + // TODO: AITD3 has some extra code here to handle bufferAnimCounter - initBufferAnim(BufferAnim[bufferAnimCounter], HQR_Get(listBody,currentProcessedActorPtr->bodyNum)); + StockInterAnim(BufferAnim[bufferAnimCounter], HQR_Get(listBody, currentProcessedActorPtr->bodyNum)); - bufferAnimCounter++; - if(bufferAnimCounter == NB_BUFFER_ANIM) - bufferAnimCounter = 0; + bufferAnimCounter++; + if (bufferAnimCounter == NB_BUFFER_ANIM) + bufferAnimCounter = 0; - currentProcessedActorPtr->ANIM = newAnim; - currentProcessedActorPtr->animType = currentProcessedActorPtr->newAnimType; - currentProcessedActorPtr->animInfo = currentProcessedActorPtr->newAnimInfo; - currentProcessedActorPtr->newAnim = -1; - currentProcessedActorPtr->newAnimType = 0; - currentProcessedActorPtr->newAnimInfo = -1; - currentProcessedActorPtr->END_ANIM = 0; - currentProcessedActorPtr->FRAME = 0; + } + else { + ResetStartAnim(HQR_Get(listBody, currentProcessedActorPtr->bodyNum)); + currentProcessedActorPtr->newAnimType &= ~ANIM_RESET; + } + currentProcessedActorPtr->ANIM = newAnim; + currentProcessedActorPtr->animType = currentProcessedActorPtr->newAnimType; + currentProcessedActorPtr->animInfo = currentProcessedActorPtr->newAnimInfo; - currentProcessedActorPtr->numOfFrames = GetNbFramesAnim(HQR_Get(listAnim,newAnim)); - } + currentProcessedActorPtr->newAnim = -1; + currentProcessedActorPtr->newAnimType = 0; + currentProcessedActorPtr->newAnimInfo = -1; + + currentProcessedActorPtr->flagEndAnim = 0; + currentProcessedActorPtr->frame = 0; + + currentProcessedActorPtr->numOfFrames = GetNbFramesAnim(HQR_Get(listAnim, newAnim)); + } + } if(currentProcessedActorPtr->ANIM == -1) // no animation { @@ -382,7 +394,7 @@ void updateAnimation(void) oldStepY = currentProcessedActorPtr->stepY; oldStepZ = currentProcessedActorPtr->stepZ; - currentProcessedActorPtr->END_FRAME = SetInterAnimObjet(currentProcessedActorPtr->FRAME, HQR_Get(listAnim, currentProcessedActorPtr->ANIM), HQR_Get(listBody, currentProcessedActorPtr->bodyNum)); + currentProcessedActorPtr->END_FRAME = SetInterAnimObjet(currentProcessedActorPtr->frame, HQR_Get(listAnim, currentProcessedActorPtr->ANIM), HQR_Get(listBody, currentProcessedActorPtr->bodyNum)); walkStep(animStepX,animStepZ,currentProcessedActorPtr->beta); @@ -499,7 +511,7 @@ void updateAnimation(void) ZVStruct* touchedZv = &actorTouchedPtr->zv; - if(actorTouchedPtr->_flags & AF_FOUNDABLE) // takable + if(actorTouchedPtr->objectType & AF_FOUNDABLE) // takable { if(currentProcessedActorPtr->trackMode == 1 /*&& ((gameId == AITD1 && defines.field_1E == 0) || (gameId >= JACK && defines.field_6 == 0))*/) // TODO: check if character isn't dead... { @@ -508,7 +520,7 @@ void updateAnimation(void) } else { - if(actorTouchedPtr->_flags & AF_MOVABLE) // can be pushed ? + if(actorTouchedPtr->objectType & AF_MOVABLE) // can be pushed ? { ZVStruct localZv2; @@ -568,12 +580,12 @@ void updateAnimation(void) } else // push succeed { - if(actorTouchedPtr->_flags & AF_BOXIFY) + if(actorTouchedPtr->objectType & AF_BOXIFY) { removeFromBGIncrust(collisionIndex); } - actorTouchedPtr->_flags |= AF_ANIMATED; + actorTouchedPtr->objectType |= AF_ANIMATED; actorTouchedPtr->worldX += stepX; // apply push to object actorTouchedPtr->worldZ += stepZ; @@ -645,7 +657,7 @@ void updateAnimation(void) currentProcessedActorPtr->stepY = 0; - if(currentProcessedActorPtr->_flags & AF_FALLABLE) + if(currentProcessedActorPtr->objectType & AF_FALLABLE) { zvPtr = ¤tProcessedActorPtr->zv; @@ -665,7 +677,7 @@ void updateAnimation(void) } else { - if((currentProcessedActorPtr->YHandler.numSteps != -1) && (currentProcessedActorPtr->_flags & AF_FALLABLE)) + if((currentProcessedActorPtr->YHandler.numSteps != -1) && (currentProcessedActorPtr->objectType & AF_FALLABLE)) { currentProcessedActorPtr->falling = 1; } @@ -679,7 +691,7 @@ void updateAnimation(void) { tObject* actorTouchedPtr = &objectTable[collisionIndex]; - if(actorTouchedPtr->_flags & AF_MOVABLE) + if(actorTouchedPtr->objectType & AF_MOVABLE) { int i; @@ -691,7 +703,7 @@ void updateAnimation(void) if(i == 3) { - actorTouchedPtr->_flags &= ~AF_ANIMATED; + actorTouchedPtr->objectType &= ~AF_ANIMATED; addActorToBgInscrust(collisionIndex); } } @@ -700,12 +712,12 @@ void updateAnimation(void) if(currentProcessedActorPtr->END_FRAME) // key frame change { - currentProcessedActorPtr->FRAME++; + currentProcessedActorPtr->frame++; - if(currentProcessedActorPtr->FRAME >= currentProcessedActorPtr->numOfFrames) // end of anim ? + if(currentProcessedActorPtr->frame >= currentProcessedActorPtr->numOfFrames) // end of anim ? { - currentProcessedActorPtr->END_ANIM = 1; // end of anim - currentProcessedActorPtr->FRAME = 0; // restart anim + currentProcessedActorPtr->flagEndAnim = 1; // end of anim + currentProcessedActorPtr->frame = 0; // restart anim if(!(currentProcessedActorPtr->animType & 1) && (currentProcessedActorPtr->newAnim == -1)) // is another anim waiting ? { @@ -743,14 +755,14 @@ void updateAnimation(void) InitRealValue(0,currentProcessedActorPtr->speed,60,¤tProcessedActorPtr->speedChange); } - currentProcessedActorPtr->END_ANIM = 0; + currentProcessedActorPtr->flagEndAnim = 0; } } -void initBufferAnim(std::vector& buffer, char* bodyPtr) -{ - std::vector::iterator bufferIt = buffer.begin(); +void StockInterAnim(std::vector& buffer, char* bodyPtr) +{ + std::vector::iterator bufferIt = buffer.begin(); int flag = *(s16*)bodyPtr; if(flag & 2) @@ -780,7 +792,7 @@ void initBufferAnim(std::vector& buffer, char* bodyPtr) source+= 10; for(i=0;i& buffer, char* bodyPtr) bufferIt[0] = *(s16*)(source); bufferIt[1] = *(s16*)(source + 2); bufferIt[2] = *(s16*)(source + 4); - bufferIt[3] = *(s16*)(source + 6); + bufferIt[3] = *(s16*)(source + 6); bufferIt +=4; source+=8; @@ -803,7 +815,14 @@ void initBufferAnim(std::vector& buffer, char* bodyPtr) source+=8; } - } + } +} + +void ResetStartAnim(char* bodyPtr) { + bodyPtr += 16; + *(u16*)(bodyPtr + 4) = 0; // reset timer + *(s16*)(bodyPtr) = 0; + *(s16*)(bodyPtr + 2) = 0; } s16 GetNbFramesAnim(char* animPtr) @@ -892,7 +911,7 @@ void PatchInterStep(char** bodyPtr, int bp, int bx) // local } s16 SetInterAnimObjet(int frame, char* animPtr, char* bodyPtr) -{ +{ int numOfBonesInAnim = *(s16*)(animPtr+2); u16 keyframeLength; u16 timeOfKeyframeStart; @@ -901,8 +920,8 @@ s16 SetInterAnimObjet(int frame, char* animPtr, char* bodyPtr) u16 time; int bp; int flag; - - sBody* pBody = getBodyFromPtr(bodyPtr); + + sBody* pBody = getBodyFromPtr(bodyPtr); flag = pBody->m_flags; diff --git a/FitdLib/anim.h b/FitdLib/anim.h index 43f5b23..a6249b0 100644 --- a/FitdLib/anim.h +++ b/FitdLib/anim.h @@ -7,7 +7,8 @@ int InitAnim(int animNum,int animType, int animInfo); int SetAnimObjet(int frame, char* anim, char* body); s16 SetInterAnimObjet(int frame, char* animPtr, char* bodyPtr); s16 GetNbFramesAnim(char* animPtr); -void initBufferAnim(std::vector& animBuffer, char* bodyPtr); +void StockInterAnim(std::vector& animBuffer, char* bodyPtr); +void ResetStartAnim(char* bodyPtr); void updateAnimation(void); void InitCopyBox(char* var0, char* var1); diff --git a/FitdLib/animAction.cpp b/FitdLib/animAction.cpp index 5c11711..eefe7c5 100644 --- a/FitdLib/animAction.cpp +++ b/FitdLib/animAction.cpp @@ -29,7 +29,7 @@ void GereFrappe(void) return; } - if (currentProcessedActorPtr->FRAME == currentProcessedActorPtr->animActionFRAME) + if (currentProcessedActorPtr->frame == currentProcessedActorPtr->animActionFRAME) { currentProcessedActorPtr->animActionType = FRAPPE_OK; } @@ -77,7 +77,7 @@ void GereFrappe(void) actorPtr2->HIT_BY = currentProcessedActorIdx; actorPtr2->hitForce = currentProcessedActorPtr->hitForce; - if(actorPtr2->_flags & AF_ANIMATED) + if(actorPtr2->objectType & AF_ANIMATED) { currentProcessedActorPtr->animActionType = 0; return; @@ -90,7 +90,7 @@ void GereFrappe(void) if(currentProcessedActorPtr->ANIM != currentProcessedActorPtr->animActionANIM) return; - if(currentProcessedActorPtr->FRAME != currentProcessedActorPtr->animActionFRAME) + if(currentProcessedActorPtr->frame != currentProcessedActorPtr->animActionFRAME) return; currentProcessedActorPtr->animActionType = 5; @@ -174,7 +174,7 @@ void GereFrappe(void) } else { - if(currentProcessedActorPtr->FRAME == currentProcessedActorPtr->animActionFRAME) + if(currentProcessedActorPtr->frame == currentProcessedActorPtr->animActionFRAME) { currentProcessedActorPtr->animActionType = 7; @@ -240,8 +240,8 @@ void GereFrappe(void) actorPtr->zv.ZVZ1 += z; actorPtr->zv.ZVZ2 += z; - actorPtr->_flags |= AF_ANIMATED; - actorPtr->_flags &= ~AF_BOXIFY; + actorPtr->objectType |= AF_ANIMATED; + actorPtr->objectType &= ~AF_BOXIFY; ListWorldObjets[objIdx].x = x; ListWorldObjets[objIdx].y = y; diff --git a/FitdLib/debugger.cpp b/FitdLib/debugger.cpp index 2e0996f..852bb51 100644 --- a/FitdLib/debugger.cpp +++ b/FitdLib/debugger.cpp @@ -270,10 +270,10 @@ void debugger_draw(void) InputS16("newAnim", &pObject->newAnim); InputS16("newAnimType", &pObject->newAnimType); InputS16("newAnimInfo", &pObject->newAnimInfo); - InputS16("FRAME", &pObject->FRAME); + InputS16("FRAME", &pObject->frame); InputS16("numOfFrames", &pObject->numOfFrames); InputS16("END_FRAME", &pObject->END_FRAME); - InputS16("END_ANIM", &pObject->END_ANIM); + InputS16("END_ANIM", &pObject->flagEndAnim); InputS16("trackMode", &pObject->trackMode); InputS16("trackNumber", &pObject->trackNumber); InputS16("MARK", &pObject->MARK); diff --git a/FitdLib/evalVar.cpp b/FitdLib/evalVar.cpp index 084e1d7..2d7a3d7 100644 --- a/FitdLib/evalVar.cpp +++ b/FitdLib/evalVar.cpp @@ -298,12 +298,12 @@ int evalVar(const char* name) } case 0x6: { - return(actorPtr->END_ANIM); + return(actorPtr->flagEndAnim); break; } case 0x7: { - return(actorPtr->FRAME); + return(actorPtr->frame); break; } case 0x8: @@ -608,7 +608,7 @@ int evalVar2(const char* name) actorIdx = ListWorldObjets[objectNumber].objIndex; currentLifePtr+=2; - actorPtr = &objectTable[actorIdx]; + actorPtr = nullptr; if(actorIdx==-1) { @@ -640,6 +640,9 @@ int evalVar2(const char* name) } } } + else { + actorPtr = &objectTable[actorIdx]; + } } { @@ -724,12 +727,12 @@ int evalVar2(const char* name) } case 0x6: { - return(actorPtr->END_ANIM); + return(actorPtr->flagEndAnim); break; } case 0x7: { - return(actorPtr->FRAME); + return(actorPtr->frame); break; } case 0x8: diff --git a/FitdLib/life.cpp b/FitdLib/life.cpp index 8a2f3d3..eef44aa 100644 --- a/FitdLib/life.cpp +++ b/FitdLib/life.cpp @@ -84,14 +84,11 @@ int randRange(int min, int max) int InitSpecialObjet(int mode, int X, int Y, int Z, int stage, int room, int alpha, int beta, int gamma, ZVStruct* zvPtr) { s16 localSpecialTable[4]; - tObject* currentActorPtr; - int i; - ZVStruct* actorZvPtr; - memcpy(localSpecialTable, specialTable, 8); - currentActorPtr = objectTable; + tObject* currentActorPtr = objectTable.data(); + int i; for (i = 0; i < NUM_MAX_OBJECT; i++) // count the number of active actors { if (currentActorPtr->indexInWorld == -1) @@ -104,7 +101,7 @@ int InitSpecialObjet(int mode, int X, int Y, int Z, int stage, int room, int alp return(-1); } - currentActorPtr->_flags = AF_SPECIAL; + currentActorPtr->objectType = AF_SPECIAL; currentActorPtr->indexInWorld = -2; currentActorPtr->life = -1; currentActorPtr->lifeMode = 2; @@ -129,6 +126,7 @@ int InitSpecialObjet(int mode, int X, int Y, int Z, int stage, int room, int alp currentActorPtr->stepY = 0; currentActorPtr->stepZ = 0; + ZVStruct* actorZvPtr = nullptr; if (zvPtr) { actorZvPtr = ¤tActorPtr->zv; @@ -149,9 +147,9 @@ int InitSpecialObjet(int mode, int X, int Y, int Z, int stage, int room, int alp actorZvPtr->ZVZ1 -= Z; actorZvPtr->ZVZ2 -= Z; - currentActorPtr->FRAME = HQ_Malloc(HQ_Memory, 304); + currentActorPtr->frame = HQ_Malloc(HQ_Memory, 304); - flowPtr = HQ_PtrMalloc(HQ_Memory, currentActorPtr->FRAME); + flowPtr = HQ_PtrMalloc(HQ_Memory, currentActorPtr->frame); if (!flowPtr) { @@ -758,7 +756,7 @@ void processLife(int lifeNum, bool callFoundLife) { currentProcessedActorPtr->bodyNum = lifeTempVar1; - if (currentProcessedActorPtr->_flags & AF_ANIMATED) + if (currentProcessedActorPtr->objectType & AF_ANIMATED) { if ((currentProcessedActorPtr->ANIM != -1) && (currentProcessedActorPtr->bodyNum != -1)) { @@ -779,7 +777,7 @@ void processLife(int lifeNum, bool callFoundLife) } else */ { - SetInterAnimObjet(currentProcessedActorPtr->FRAME, pAnim, pBody); + SetInterAnimObjet(currentProcessedActorPtr->frame, pAnim, pBody); } } } @@ -802,7 +800,7 @@ void processLife(int lifeNum, bool callFoundLife) currentProcessedActorPtr->bodyNum = param1; - if (currentProcessedActorPtr->_flags & AF_ANIMATED) + if (currentProcessedActorPtr->objectType & AF_ANIMATED) { char* pAnim = HQR_Get(listAnim, currentProcessedActorPtr->ANIM); char* pBody; @@ -920,9 +918,9 @@ void processLife(int lifeNum, bool callFoundLife) appendFormated("LM_TYPE "); lifeTempVar1 = readNextArgument("type") & AF_MASK; - lifeTempVar2 = currentProcessedActorPtr->_flags; + lifeTempVar2 = currentProcessedActorPtr->objectType; - currentProcessedActorPtr->_flags = (currentProcessedActorPtr->_flags & ~AF_MASK) + lifeTempVar1; + currentProcessedActorPtr->objectType = (currentProcessedActorPtr->objectType & ~AF_MASK) + lifeTempVar1; if (g_gameId > AITD1) { @@ -1003,7 +1001,7 @@ void processLife(int lifeNum, bool callFoundLife) } else { - InitAnim(anim, 4, animFlag); + InitAnim(anim, ANIM_ONCE | ANIM_RESET, animFlag); } break; @@ -1011,21 +1009,61 @@ void processLife(int lifeNum, bool callFoundLife) case LM_ANIM_HYBRIDE_ONCE: { appendFormated("LM_ANIM_HYBRIDE_ONCE "); - // TODO - int anim = readNextArgument("Anim"); - int body = readNextArgument("Body?"); - //printf("LM_ANIM_HYBRIDE_ONCE(anim:%d, body:%d)\n", anim, body); + int anim = readNextArgument("Anim"); + int body = readNextArgument("Body"); + + if ((currentProcessedActorPtr->ANIM != anim) || (currentProcessedActorPtr->bodyNum != body)) { + currentProcessedActorPtr->ANIM = anim; + currentProcessedActorPtr->bodyNum = body; + currentProcessedActorPtr->memoTicks = timer; + currentProcessedActorPtr->frame = 0; + + if ((currentProcessedActorPtr->ANIM != -1) && (currentProcessedActorPtr->bodyNum != -1)) { + char* pHybrid = HQR_Get(listHybrides, currentProcessedActorPtr->ANIM); + pHybrid += READ_LE_U32(pHybrid + 8); + pHybrid += READ_LE_U32(pHybrid + currentProcessedActorPtr->bodyNum * 4); + + currentProcessedActorPtr->numOfFrames = pHybrid[1]; + currentProcessedActorPtr->animInfo = -1; + currentProcessedActorPtr->animType = ANIM_ONCE; + currentProcessedActorPtr->objectType |= AF_OBJ_2D; + } + else { + currentProcessedActorPtr->numOfFrames = 0; + currentProcessedActorPtr->objectType = 0; + } + } break; } case LM_ANIM_HYBRIDE_REPEAT: { appendFormated("LM_ANIM_HYBRIDE_REPEAT "); - // TODO - int anim = readNextArgument("Anim"); - int body = readNextArgument("Body?"); - //printf("LM_ANIM_HYBRIDE_REPEAT(anim:%d, body:%d)\n", anim, body); + int anim = readNextArgument("Anim"); + int body = readNextArgument("Body"); + + if ((currentProcessedActorPtr->ANIM != anim) || (currentProcessedActorPtr->bodyNum != body)) { + currentProcessedActorPtr->ANIM = anim; + currentProcessedActorPtr->bodyNum = body; + currentProcessedActorPtr->memoTicks = timer; + currentProcessedActorPtr->frame = 0; + + if ((currentProcessedActorPtr->ANIM != -1) && (currentProcessedActorPtr->bodyNum != -1)) { + char* pHybrid = HQR_Get(listHybrides, currentProcessedActorPtr->ANIM); + pHybrid += READ_LE_U32(pHybrid + 8); + pHybrid += READ_LE_U32(pHybrid + currentProcessedActorPtr->bodyNum * 4); + + currentProcessedActorPtr->numOfFrames = pHybrid[1]; + currentProcessedActorPtr->animInfo = -1; + currentProcessedActorPtr->animType = ANIM_REPEAT; + currentProcessedActorPtr->objectType |= AF_OBJ_2D; + } + else { + currentProcessedActorPtr->numOfFrames = 0; + currentProcessedActorPtr->objectType = 0; + } + } break; } //////////////////////////////////////////////////////////////////////// @@ -1691,7 +1729,7 @@ void processLife(int lifeNum, bool callFoundLife) { if (currentProcessedActorPtr->ANIM == lifeTempVar2) { - if (currentProcessedActorPtr->FRAME == lifeTempVar3) + if (currentProcessedActorPtr->frame == lifeTempVar3) { playSound(lifeTempVar1); //setSampleFreq(0); diff --git a/FitdLib/main.cpp b/FitdLib/main.cpp index daef974..e2718ba 100644 --- a/FitdLib/main.cpp +++ b/FitdLib/main.cpp @@ -223,7 +223,7 @@ void executeFoundLife(int objIdx) currentProcessedActorPtr->indexInWorld = objIdx; currentProcessedActorPtr->life = -1; currentProcessedActorPtr->bodyNum = -1; - currentProcessedActorPtr->_flags = 0; + currentProcessedActorPtr->objectType = 0; currentProcessedActorPtr->trackMode = -1; currentProcessedActorPtr->room = -1; currentProcessedActorPtr->lifeMode = -1; @@ -1162,7 +1162,10 @@ void LoadWorld(void) } listLife = HQR_InitRessource("LISTLIFE", 65000, 100); - listTrack = HQR_InitRessource("LISTTRAK", 20000, 100); + listTrack = HQR_InitRessource("LISTTRAK", 20000, 100); + if (g_gameId >= JACK) { + listHybrides = HQR_InitRessource("LISTHYB", 20000, 10); // TODO: recheck size for other games + } // TODO: missing dos memory check here @@ -1671,7 +1674,7 @@ void DeleteObjet(int index) // remove actor CVars[getCVarsIdx(FOG_FLAG)] = 0; } - HQ_Free_Malloc(HQ_Memory,actorPtr->FRAME); + HQ_Free_Malloc(HQ_Memory,actorPtr->frame); } else { @@ -1684,10 +1687,10 @@ void DeleteObjet(int index) // remove actor objectPtr->body = actorPtr->bodyNum; objectPtr->anim = actorPtr->ANIM; - objectPtr->frame = actorPtr->FRAME; + objectPtr->frame = actorPtr->frame; objectPtr->animType = actorPtr->animType; objectPtr->animInfo = actorPtr->animInfo; - objectPtr->flags = actorPtr->_flags & ~AF_BOXIFY; + objectPtr->flags = actorPtr->objectType & ~AF_BOXIFY; objectPtr->flags |= AF_SPECIAL * actorPtr->dynFlags; // ugly hack, need rewrite objectPtr->life = actorPtr->life; objectPtr->lifeMode = actorPtr->lifeMode; @@ -2163,7 +2166,7 @@ addObject: void updateAllActorAndObjects() { int i; - tObject *currentActor = objectTable; + tObject *currentActor = objectTable.data(); tWorldObject* currentObject; if(g_gameId > JACK) @@ -2340,30 +2343,24 @@ int checkActorInRoom(int room) void createActorList() { - int i; - tObject* actorPtr; - numActorInList = 0; - actorPtr = objectTable; - - for(i=0;iindexInWorld != -1 && actorPtr->bodyNum != -1) { if(checkActorInRoom(actorPtr->room)) { sortedActorTable[numActorInList] = i; - if(!(actorPtr->_flags & (AF_SPECIAL & AF_ANIMATED))) + if(!(actorPtr->objectType & (AF_SPECIAL & AF_ANIMATED))) { - actorPtr->_flags |= AF_BOXIFY; + actorPtr->objectType |= AF_BOXIFY; // FlagRefreshAux2 = 1; } numActorInList++; } } - - actorPtr++; } } @@ -2391,6 +2388,10 @@ void InitView() } cameraBackgroundChanged = true; + if (g_gameId >= JACK) { + printf("Load 2d animations"); + } + pCamera = cameraDataTable[NumCamera]; SetAngleCamera(pCamera->alpha,pCamera->beta,pCamera->gamma); @@ -2522,7 +2523,7 @@ void removeFromBGIncrust(int actorIdx) { tObject* actorPtr = &objectTable[actorIdx]; - actorPtr->_flags &= ~AF_BOXIFY; + actorPtr->objectType &= ~AF_BOXIFY; // FlagRefreshAux2 = 1; @@ -2585,7 +2586,7 @@ void deleteObject(int objIdx) // FlagGenereActiveList = 1; - if(actorPtr->_flags & AF_BOXIFY) + if(actorPtr->objectType & AF_BOXIFY) { removeFromBGIncrust(actorIdx); } @@ -3294,43 +3295,59 @@ void mainDraw(int flagFlip) // this is commented out to draw actors incrusted in background //if(actorPtr->_flags & (AF_ANIMATED + AF_DRAWABLE + AF_SPECIAL)) { - actorPtr->_flags &= ~AF_DRAWABLE; + actorPtr->objectType &= ~AF_DRAWABLE; - if(actorPtr->_flags & AF_SPECIAL) + if(actorPtr->objectType & AF_SPECIAL) { mainDrawSub2(currentDrawActor); } else { - char* bodyPtr = HQR_Get(listBody,actorPtr->bodyNum); + if (actorPtr->objectType & AF_OBJ_2D) { + char* pHybrid = HQR_Get(listHybrides, actorPtr->ANIM); + char* pData = pHybrid + READ_LE_U32(pHybrid + 8); + pData += READ_LE_U32(pData + actorPtr->bodyNum * 4); - if(HQ_Load) - { - // initAnimInBody(actorPtr->FRAME, HQR_Get(listAnim, actorPtr->ANIM), bodyPtr); - } + char* pAnim = pData + 2; + pAnim += 8 * actorPtr->frame; + s16 numHybrid = READ_LE_U16(pAnim); - AffObjet(actorPtr->worldX + actorPtr->stepX, actorPtr->worldY + actorPtr->stepY, actorPtr->worldZ + actorPtr->stepZ, actorPtr->alpha, actorPtr->beta, actorPtr->gamma, bodyPtr); + //AffHyb(numHybrid, 0, 0, pHybrid); + + // TODO: bounding volume + } + else + { + char* bodyPtr = HQR_Get(listBody, actorPtr->bodyNum); + + if (HQ_Load) + { + // initAnimInBody(actorPtr->FRAME, HQR_Get(listAnim, actorPtr->ANIM), bodyPtr); + } + + AffObjet(actorPtr->worldX + actorPtr->stepX, actorPtr->worldY + actorPtr->stepY, actorPtr->worldZ + actorPtr->stepZ, actorPtr->alpha, actorPtr->beta, actorPtr->gamma, bodyPtr); - if(actorPtr->animActionType != 0) - { - if(actorPtr->hotPointID != -1) - { - getHotPoint(actorPtr->hotPointID, bodyPtr, &actorPtr->hotPoint); - } - } + if (actorPtr->animActionType != 0) + { + if (actorPtr->hotPointID != -1) + { + getHotPoint(actorPtr->hotPointID, bodyPtr, &actorPtr->hotPoint); + } + } - ///////////////////////////////////// DEBUG + ///////////////////////////////////// DEBUG #ifdef FITD_DEBUGGER - // if(debuggerVar_drawModelZv) - { - if(backgroundMode == backgroundModeEnum_3D) - { - drawZv(actorPtr); - } - } + // if(debuggerVar_drawModelZv) + { + if (backgroundMode == backgroundModeEnum_3D) + { + drawZv(actorPtr); + } + } #endif - ///////////////////////////////////// + ///////////////////////////////////// + } } if(BBox3D1 < 0) @@ -3418,8 +3435,8 @@ void walkStep(int angle1, int angle2, int angle3) void addActorToBgInscrust(int actorIdx) { - objectTable[actorIdx]._flags |= AF_BOXIFY + AF_DRAWABLE; - objectTable[actorIdx]._flags &= ~AF_ANIMATED; + objectTable[actorIdx].objectType |= AF_BOXIFY + AF_DRAWABLE; + objectTable[actorIdx].objectType &= ~AF_ANIMATED; //FlagRefreshAux2 = 1; } @@ -3464,7 +3481,7 @@ void getZvRelativePosition(ZVStruct* zvPtr, int startRoom, int destRoom) int checkObjectCollisions(int actorIdx, ZVStruct* zvPtr) { int currentCollisionSlot = 0; - tObject* currentActor = objectTable; + tObject* currentActor = objectTable.data(); int actorRoom = objectTable[actorIdx].room; for(int i=0;i<3;i++) @@ -4078,6 +4095,12 @@ void checkIfCameraChangeIsRequired(void) if(NumCamera!=-1) { + if (currentCameraTargetActor == -1) + { + // TODO: Happens at the start of AITD3, likely a bug + return; + } + tObject* actorPtr; int zvx1; int zvx2; @@ -4317,13 +4340,10 @@ int checkLineProjectionWithActors( int actorIdx, int X, int Y, int Z, int beta, } else { - tObject* currentActorPtr = objectTable; - - int i; - - for(i=0;iindexInWorld != -1 && i != actorIdx && !(currentActorPtr->_flags & AF_SPECIAL)) + tObject* currentActorPtr = &objectTable[i]; + if(currentActorPtr->indexInWorld != -1 && i != actorIdx && !(currentActorPtr->objectType & AF_SPECIAL)) { ZVStruct* zvPtr = ¤tActorPtr->zv; @@ -4352,8 +4372,6 @@ int checkLineProjectionWithActors( int actorIdx, int X, int Y, int Z, int beta, foundFlag = i; break; } - - currentActorPtr++; } } } diff --git a/FitdLib/mainLoop.cpp b/FitdLib/mainLoop.cpp index dbb6354..311a6cb 100644 --- a/FitdLib/mainLoop.cpp +++ b/FitdLib/mainLoop.cpp @@ -110,7 +110,7 @@ void PlayWorld(int allowSystemMenu, int deltaTime) } } - currentProcessedActorPtr = objectTable; + currentProcessedActorPtr = objectTable.data(); for(currentProcessedActorIdx = 0; currentProcessedActorIdx < NUM_MAX_OBJECT; currentProcessedActorIdx++) { @@ -126,12 +126,12 @@ void PlayWorld(int allowSystemMenu, int deltaTime) currentProcessedActorPtr++; } - currentProcessedActorPtr = objectTable; + currentProcessedActorPtr = objectTable.data(); for(currentProcessedActorIdx = 0; currentProcessedActorIdx < NUM_MAX_OBJECT; currentProcessedActorIdx++) { if(currentProcessedActorPtr->indexInWorld >= 0) { - int flag = currentProcessedActorPtr->_flags; + int flag = currentProcessedActorPtr->objectType; if((flag & AF_ANIMATED) || (g_gameId >= AITD2 && flag & 0x200)) { @@ -151,7 +151,7 @@ void PlayWorld(int allowSystemMenu, int deltaTime) currentProcessedActorPtr++; } - currentProcessedActorPtr = objectTable; + currentProcessedActorPtr = objectTable.data(); for(currentProcessedActorIdx = 0; currentProcessedActorIdx < NUM_MAX_OBJECT; currentProcessedActorIdx++) { if(currentProcessedActorPtr->indexInWorld >= 0) @@ -212,14 +212,14 @@ void PlayWorld(int allowSystemMenu, int deltaTime) NumCamera = NewNumCamera; - currentProcessedActorPtr = objectTable; - for(currentProcessedActorIdx = 0; currentProcessedActorIdx < NUM_MAX_OBJECT; currentProcessedActorIdx++) + for (currentProcessedActorIdx = 0; currentProcessedActorIdx < NUM_MAX_OBJECT; currentProcessedActorIdx++) { + currentProcessedActorPtr = &objectTable[currentProcessedActorIdx]; if(currentProcessedActorPtr->indexInWorld >= 0) { if(currentProcessedActorPtr->life != -1) { - if(currentProcessedActorPtr->_flags & 0x200) + if(currentProcessedActorPtr->objectType & 0x200) { if(currentProcessedActorPtr->lifeMode&3) if(!(currentProcessedActorPtr->lifeMode&4)) diff --git a/FitdLib/object.cpp b/FitdLib/object.cpp index 4a92aab..b111ab1 100644 --- a/FitdLib/object.cpp +++ b/FitdLib/object.cpp @@ -4,7 +4,7 @@ int copyObjectToActor(int body, int typeZv, int hardZvIdx, s16 objectType, int x { int i; int j; - tObject* actorPtr = objectTable; + tObject* actorPtr = objectTable.data(); char* bodyPtr; ZVStruct* zvPtr; @@ -23,7 +23,7 @@ int copyObjectToActor(int body, int typeZv, int hardZvIdx, s16 objectType, int x currentProcessedActorIdx = i; actorPtr->bodyNum = body; - actorPtr->_flags = objectType; + actorPtr->objectType = objectType; actorPtr->stage = stage; actorPtr->room = room; actorPtr->worldX = actorPtr->roomX = x; @@ -44,13 +44,13 @@ int copyObjectToActor(int body, int typeZv, int hardZvIdx, s16 objectType, int x actorPtr->dynFlags = 1; actorPtr->ANIM = anim; - actorPtr->FRAME = frame; + actorPtr->frame = frame; actorPtr->animType = animtype; actorPtr->animInfo = animInfo; actorPtr->END_FRAME = 1; - actorPtr->END_ANIM = 1; + actorPtr->flagEndAnim = 1; actorPtr->newAnim = -1; actorPtr->newAnimType = 0; actorPtr->newAnimInfo = -1; @@ -105,8 +105,8 @@ int copyObjectToActor(int body, int typeZv, int hardZvIdx, s16 objectType, int x SetAnimObjet(frame,animPtr,bodyPtr); actorPtr->numOfFrames = GetNbFramesAnim(animPtr); - actorPtr->END_ANIM = 0; - actorPtr->_flags |= AF_ANIMATED; + actorPtr->flagEndAnim = 0; + actorPtr->objectType |= AF_ANIMATED; // computeScreenBox(actorPtr->field_22 + actorPtr->field_5A, actorPtr->field_24 + actorPtr->field_5C, actorPtr->anim + actorPtr->field_5E, actorPtr->alpha, actorPtr->beta, actorPtr->gamma, bodyPtr); @@ -129,9 +129,9 @@ int copyObjectToActor(int body, int typeZv, int hardZvIdx, s16 objectType, int x } else { - if(!(actorPtr->_flags & AF_DRAWABLE)) + if(!(actorPtr->objectType & AF_DRAWABLE)) { - actorPtr->_flags &= ~AF_ANIMATED; // do not animate an object that is invisible + actorPtr->objectType &= ~AF_ANIMATED; // do not animate an object that is invisible } } } diff --git a/FitdLib/save.cpp b/FitdLib/save.cpp index 02d4ebb..58492f9 100644 --- a/FitdLib/save.cpp +++ b/FitdLib/save.cpp @@ -284,8 +284,8 @@ int loadSave(int saveNumber) ASSERT(sizeof(objectTable[i].bodyNum) == 2); fread(&objectTable[i].bodyNum,2,1,fHandle); - ASSERT(sizeof(objectTable[i]._flags) == 2); - fread(&objectTable[i]._flags,2,1,fHandle); + ASSERT(sizeof(objectTable[i].objectType) == 2); + fread(&objectTable[i].objectType,2,1,fHandle); ASSERT(sizeof(objectTable[i].dynFlags) == 2); fread(&objectTable[i].dynFlags,2,1,fHandle); @@ -389,8 +389,8 @@ int loadSave(int saveNumber) ASSERT(sizeof(objectTable[i].newAnimInfo) == 2); fread(&objectTable[i].newAnimInfo,2,1,fHandle); - ASSERT(sizeof(objectTable[i].FRAME) == 2); - fread(&objectTable[i].FRAME,2,1,fHandle); + ASSERT(sizeof(objectTable[i].frame) == 2); + fread(&objectTable[i].frame,2,1,fHandle); ASSERT(sizeof(objectTable[i].numOfFrames) == 2); fread(&objectTable[i].numOfFrames,2,1,fHandle); @@ -398,8 +398,8 @@ int loadSave(int saveNumber) ASSERT(sizeof(objectTable[i].END_FRAME) == 2); fread(&objectTable[i].END_FRAME,2,1,fHandle); - ASSERT(sizeof(objectTable[i].END_ANIM) == 2); - fread(&objectTable[i].END_ANIM,2,1,fHandle); + ASSERT(sizeof(objectTable[i].flagEndAnim) == 2); + fread(&objectTable[i].flagEndAnim,2,1,fHandle); ASSERT(sizeof(objectTable[i].trackMode) == 2); fread(&objectTable[i].trackMode,2,1,fHandle); @@ -499,7 +499,7 @@ int loadSave(int saveNumber) if(objectTable[i].ANIM != -1) { char* animPtr = HQR_Get(listAnim,objectTable[i].ANIM); - SetAnimObjet(objectTable[i].FRAME,animPtr,bodyPtr); + SetAnimObjet(objectTable[i].frame,animPtr,bodyPtr); } } } @@ -562,7 +562,7 @@ int makeSaveFile(int entry) if (objectTable[i].ANIM == 4) { CVars[getCVarsIdx(FOG_FLAG)] = 0; - HQ_Free_Malloc(HQ_Memory, objectTable[i].FRAME); + HQ_Free_Malloc(HQ_Memory, objectTable[i].frame); } } } @@ -778,8 +778,8 @@ int makeSaveFile(int entry) ASSERT(sizeof(objectTable[i].bodyNum) == 2); fwrite(&objectTable[i].bodyNum,2,1,fHandle); - ASSERT(sizeof(objectTable[i]._flags) == 2); - fwrite(&objectTable[i]._flags,2,1,fHandle); + ASSERT(sizeof(objectTable[i].objectType) == 2); + fwrite(&objectTable[i].objectType,2,1,fHandle); ASSERT(sizeof(objectTable[i].dynFlags) == 2); fwrite(&objectTable[i].dynFlags,2,1,fHandle); @@ -879,8 +879,8 @@ int makeSaveFile(int entry) ASSERT(sizeof(objectTable[i].newAnimInfo) == 2); fwrite(&objectTable[i].newAnimInfo,2,1,fHandle); - ASSERT(sizeof(objectTable[i].FRAME) == 2); - fwrite(&objectTable[i].FRAME,2,1,fHandle); + ASSERT(sizeof(objectTable[i].frame) == 2); + fwrite(&objectTable[i].frame,2,1,fHandle); ASSERT(sizeof(objectTable[i].numOfFrames) == 2); fwrite(&objectTable[i].numOfFrames,2,1,fHandle); @@ -888,8 +888,8 @@ int makeSaveFile(int entry) ASSERT(sizeof(objectTable[i].END_FRAME) == 2); fwrite(&objectTable[i].END_FRAME,2,1,fHandle); - ASSERT(sizeof(objectTable[i].END_ANIM) == 2); - fwrite(&objectTable[i].END_ANIM,2,1,fHandle); + ASSERT(sizeof(objectTable[i].flagEndAnim) == 2); + fwrite(&objectTable[i].flagEndAnim,2,1,fHandle); ASSERT(sizeof(objectTable[i].trackMode) == 2); fwrite(&objectTable[i].trackMode,2,1,fHandle); diff --git a/FitdLib/track.cpp b/FitdLib/track.cpp index 3f566c2..d3b87e5 100644 --- a/FitdLib/track.cpp +++ b/FitdLib/track.cpp @@ -537,13 +537,13 @@ void processTrack(void) } case TL_DEC_OFF: // background collision off { - currentProcessedActorPtr->_flags &= ~AF_TRIGGER; + currentProcessedActorPtr->objectType &= ~AF_TRIGGER; currentProcessedActorPtr->positionInTrack++; break; } case TL_DEC_ON: // background collision on { - currentProcessedActorPtr->_flags |= AF_TRIGGER; + currentProcessedActorPtr->objectType |= AF_TRIGGER; currentProcessedActorPtr->positionInTrack++; break; } @@ -1013,13 +1013,13 @@ void processTrack2(void) } case 0xA: { - currentProcessedActorPtr->_flags &= 0xFFBF; + currentProcessedActorPtr->objectType &= 0xFFBF; currentProcessedActorPtr->positionInTrack++; break; } case 0xB: { - currentProcessedActorPtr->_flags |= 0x40; + currentProcessedActorPtr->objectType |= 0x40; currentProcessedActorPtr->positionInTrack++; break; }/* diff --git a/FitdLib/vars.cpp b/FitdLib/vars.cpp index ca3c7d1..5b39c70 100644 --- a/FitdLib/vars.cpp +++ b/FitdLib/vars.cpp @@ -78,17 +78,18 @@ char* screenSm3; char* screenSm4; char* screenSm5; -tObject objectTable[NUM_MAX_OBJECT]; +std::array objectTable; s16 currentWorldTarget; int fileSize; -hqrEntryStruct* listBody; -hqrEntryStruct* listAnim; -hqrEntryStruct* listLife; -hqrEntryStruct* listTrack; -hqrEntryStruct* listMatrix; +hqrEntryStruct* listBody = nullptr; +hqrEntryStruct* listAnim = nullptr; +hqrEntryStruct* listLife = nullptr; +hqrEntryStruct* listTrack = nullptr; +hqrEntryStruct* listHybrides = nullptr; +hqrEntryStruct* listMatrix = nullptr; s16 maxObjects; diff --git a/FitdLib/vars.h b/FitdLib/vars.h index cf1b9d4..43a5e25 100644 --- a/FitdLib/vars.h +++ b/FitdLib/vars.h @@ -115,14 +115,18 @@ enum actorFlags AF_FOUNDABLE = 0x0080, AF_FALLABLE = 0x0100, - AF_MASK = AF_ANIMATED + AF_MOVABLE + AF_TRIGGER + AF_FOUNDABLE + AF_FALLABLE, + // >= JACK + AF_OBJ_2D = 0x0200, + AF_WATER = 0x0400, + + AF_MASK = AF_ANIMATED + AF_MOVABLE + AF_TRIGGER + AF_FOUNDABLE + AF_FALLABLE + AF_WATER, }; struct tObject // used to read data from file too { s16 indexInWorld; s16 bodyNum; - u16 _flags; + u16 objectType; s16 dynFlags; ZVStruct zv; s16 screenXMin; @@ -150,10 +154,11 @@ struct tObject // used to read data from file too s16 newAnim; s16 newAnimType; s16 newAnimInfo; - s16 FRAME; + s16 frame; s16 numOfFrames; s16 END_FRAME; - s16 END_ANIM; + s16 flagEndAnim; + u32 memoTicks; // for 2d objects s16 trackMode; s16 trackNumber; s16 MARK; @@ -323,7 +328,7 @@ extern char* screenSm3; extern char* screenSm4; extern char* screenSm5; -extern tObject objectTable[NUM_MAX_OBJECT]; +extern std::array objectTable; extern s16 currentWorldTarget; @@ -333,6 +338,7 @@ extern hqrEntryStruct* listBody; extern hqrEntryStruct* listAnim; extern hqrEntryStruct* listLife; extern hqrEntryStruct* listTrack; +extern hqrEntryStruct* listHybrides; extern hqrEntryStruct* listMatrix; extern s16 maxObjects;