#include #include "common.h" #include "hybrid.h" int groundLevel; s16 specialTable[4] = { 144, 192, 48, 112 }; int numSequenceParam = 0; sequenceParamStruct sequenceParams[NUM_MAX_SEQUENCE_PARAM]; void resetRotateParam(void) { currentProcessedActorPtr->rotate.numSteps = 0; } void throwObj(int animThrow, int frameThrow, int arg_4, int objToThrowIdx, int throwRotated, int throwForce, int animNext) { if (InitAnim(animThrow, 2, animNext)) { currentProcessedActorPtr->animActionANIM = animThrow; currentProcessedActorPtr->animActionFRAME = frameThrow; currentProcessedActorPtr->animActionType = 6; currentProcessedActorPtr->hotPointID = arg_4; currentProcessedActorPtr->animActionParam = objToThrowIdx; currentProcessedActorPtr->hitForce = throwForce; if (!throwRotated) { ListWorldObjets[objToThrowIdx].gamma -= 0x100; } ListWorldObjets[objToThrowIdx].foundFlag |= 0x1000; } } void put(int x, int y, int z, int room, int stage, int alpha, int beta, int gamma, int idx) { tWorldObject* objPtr = &ListWorldObjets[idx]; objPtr->x = x; objPtr->y = y; objPtr->z = z; objPtr->room = room; objPtr->stage = stage; objPtr->alpha = alpha; objPtr->beta = beta; objPtr->gamma = gamma; DeleteInventoryObjet(idx); objPtr->foundFlag |= 0x4000; /* FlagGenereActiveList = 1; FlagRefreshAux2 = 1; */ } void drop(int worldIdx, int worldSource) { PutAtObjet(worldIdx, worldSource); } void fire(int fireAnim, int X, int Y, int Z, int hitForce, int nextAnim) { if (InitAnim(fireAnim, 2, nextAnim)) { currentProcessedActorPtr->animActionANIM = fireAnim; currentProcessedActorPtr->animActionFRAME = X; currentProcessedActorPtr->animActionType = 4; currentProcessedActorPtr->animActionParam = Z; currentProcessedActorPtr->hotPointID = Y; currentProcessedActorPtr->hitForce = hitForce; } } int randRange(int min, int max) { return((rand() % (max - min)) + min); } 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]; memcpy(localSpecialTable, specialTable, 8); tObject* currentActorPtr = ListObjets.data(); int i; for (i = 0; i < NUM_MAX_OBJECT; i++) // count the number of active actors { if (currentActorPtr->indexInWorld == -1) break; currentActorPtr++; } if (i == NUM_MAX_OBJECT) // no free actor entry, abort { return(-1); } currentActorPtr->objectType = AF_SPECIAL; currentActorPtr->indexInWorld = -2; currentActorPtr->life = -1; currentActorPtr->lifeMode = 2; // TODO: probably incorrect betweem AITD1/2 currentActorPtr->bodyNum = 0; currentActorPtr->worldX = currentActorPtr->roomX = X; currentActorPtr->worldY = currentActorPtr->roomY = Y; currentActorPtr->worldZ = currentActorPtr->roomZ = Z; currentActorPtr->stage = stage; currentActorPtr->room = room; if (currentRoom != room) { currentActorPtr->worldX -= (s16)((roomDataTable[currentRoom].worldX - roomDataTable[room].worldX) * 10); currentActorPtr->worldY += (s16)((roomDataTable[currentRoom].worldY - roomDataTable[room].worldY) * 10); currentActorPtr->worldZ += (s16)((roomDataTable[currentRoom].worldZ - roomDataTable[room].worldZ) * 10); } currentActorPtr->alpha = alpha; currentActorPtr->beta = beta; currentActorPtr->gamma = gamma; currentActorPtr->stepX = 0; currentActorPtr->stepY = 0; currentActorPtr->stepZ = 0; ZVStruct* actorZvPtr = nullptr; if (zvPtr) { actorZvPtr = ¤tActorPtr->zv; CopyZV(zvPtr, actorZvPtr); } switch (mode) { case 0: // evaporate { char* flowPtr; int j; actorZvPtr->ZVX1 -= X; actorZvPtr->ZVX2 -= X; actorZvPtr->ZVY1 -= Y; actorZvPtr->ZVY2 -= Y; actorZvPtr->ZVZ1 -= Z; actorZvPtr->ZVZ2 -= Z; currentActorPtr->frame = HQ_Malloc(HQ_Memory, 304); flowPtr = HQ_PtrMalloc(HQ_Memory, currentActorPtr->frame); if (!flowPtr) { currentActorPtr->indexInWorld = -1; return(-1); } currentActorPtr->ANIM = mode; *(s16*)flowPtr = localSpecialTable[rand() % 3]; // type ? color ? flowPtr += 2; *(s16*)flowPtr = 30; // num of points flowPtr += 2; for (j = 0; j < 30; j++) { *(s16*)flowPtr = randRange(actorZvPtr->ZVX1, actorZvPtr->ZVX2); //X flowPtr += 2; *(s16*)flowPtr = randRange(actorZvPtr->ZVY1, actorZvPtr->ZVY2); //Y flowPtr += 2; *(s16*)flowPtr = randRange(actorZvPtr->ZVZ1, actorZvPtr->ZVZ2); //Z flowPtr += 2; } for (j = 0; j < 30; j++) { *(s16*)flowPtr = randRange(150, 300); // ? flowPtr += 2; *(s16*)flowPtr = randRange(30, 80); // ? flowPtr += 2; } actorZvPtr->ZVX1 = X - 10; actorZvPtr->ZVX2 = X + 10; actorZvPtr->ZVY1 = Y; actorZvPtr->ZVY2 = Y - 1; actorZvPtr->ZVZ1 = Z - 10; actorZvPtr->ZVZ2 = Z + 10; break; } default: { printf("Unsupported case %d in createFlow\n", mode); } } FlagGenereAffList = 1; return(i); } void getHardClip() { ZVStruct* zvPtr = ¤tProcessedActorPtr->zv; char* etageData = (char*)getRoomData(currentProcessedActorPtr->room); s16 numEntry; int i; etageData += *(s16*)etageData; numEntry = *(s16*)etageData; etageData += 2; for (i = 0; i < numEntry; i++) { ZVStruct zvCol; zvCol.ZVX1 = READ_LE_S16(etageData + 0x00); zvCol.ZVX2 = READ_LE_S16(etageData + 0x02); zvCol.ZVY1 = READ_LE_S16(etageData + 0x04); zvCol.ZVY2 = READ_LE_S16(etageData + 0x06); zvCol.ZVZ1 = READ_LE_S16(etageData + 0x08); zvCol.ZVZ2 = READ_LE_S16(etageData + 0x0A); if (CubeIntersect(zvPtr, &zvCol)) { hardClip.ZVX1 = zvCol.ZVX1; hardClip.ZVX2 = zvCol.ZVX2; hardClip.ZVY1 = zvCol.ZVY1; hardClip.ZVY2 = zvCol.ZVY2; hardClip.ZVZ1 = zvCol.ZVZ1; hardClip.ZVZ2 = zvCol.ZVZ2; return; } etageData += 16; } hardClip.ZVX1 = 32000; hardClip.ZVX2 = -32000; hardClip.ZVY1 = 32000; hardClip.ZVY2 = -32000; hardClip.ZVZ1 = 32000; hardClip.ZVZ2 = -32000; } void animMove(int animStand, int animWalk, int animRun, int animStop, int animBackward, int animTurnRight, int animTurnLeft) { if (currentProcessedActorPtr->speed == 5) { InitAnim(animRun, 1, -1); } if (currentProcessedActorPtr->speed == 4) { InitAnim(animWalk, 1, -1); } if (currentProcessedActorPtr->speed == -1) // backward { if (currentProcessedActorPtr->ANIM == animWalk) { InitAnim(animStand, 0, animBackward); } else if (currentProcessedActorPtr->ANIM == animRun) { InitAnim(animStop, 0, animStand); } else { InitAnim(animBackward, 1, -1); // walk backward } } if (currentProcessedActorPtr->speed == 0) { if ((currentProcessedActorPtr->ANIM == animWalk) || (currentProcessedActorPtr->ANIM == animRun)) { InitAnim(animStop, 0, animStand); } else { if (currentProcessedActorPtr->direction == 0) { InitAnim(animStand, 1, -1); } if (currentProcessedActorPtr->direction == 1) // left { InitAnim(animTurnLeft, 0, animStand); } if (currentProcessedActorPtr->direction == -1) // right { InitAnim(animTurnRight, 0, animStand); } } } } void setStage(int newStage, int newRoomLocal, int X, int Y, int Z) { int animX; int animY; int animZ; currentProcessedActorPtr->stage = newStage; currentProcessedActorPtr->room = newRoomLocal; if (g_gameId != AITD1) { currentProcessedActorPtr->hardMat = -1; } animX = currentProcessedActorPtr->roomX + currentProcessedActorPtr->stepX; animY = currentProcessedActorPtr->roomY + currentProcessedActorPtr->stepY; animZ = currentProcessedActorPtr->roomZ + currentProcessedActorPtr->stepZ; currentProcessedActorPtr->zv.ZVX1 += X - animX; currentProcessedActorPtr->zv.ZVX2 += X - animX; currentProcessedActorPtr->zv.ZVY1 += Y - animY; currentProcessedActorPtr->zv.ZVY2 += Y - animY; currentProcessedActorPtr->zv.ZVZ1 += Z - animZ; currentProcessedActorPtr->zv.ZVZ2 += Z - animZ; currentProcessedActorPtr->roomX = X; currentProcessedActorPtr->roomY = Y; currentProcessedActorPtr->roomZ = Z; currentProcessedActorPtr->worldX = X; currentProcessedActorPtr->worldY = Y; currentProcessedActorPtr->worldZ = Z; currentProcessedActorPtr->stepX = 0; currentProcessedActorPtr->stepY = 0; currentProcessedActorPtr->stepZ = 0; if (currentCameraTargetActor == currentProcessedActorIdx) { if (newStage != g_currentFloor) { FlagChangeEtage = 1; NewNumEtage = newStage; NewNumSalle = newRoomLocal; } else { if (currentRoom != newRoomLocal) { FlagChangeSalle = 1; NewNumSalle = newRoomLocal; } } } else { if (currentRoom != newRoomLocal) { currentProcessedActorPtr->worldX -= (s16)((roomDataTable[currentRoom].worldX - roomDataTable[newRoomLocal].worldX) * 10); currentProcessedActorPtr->worldY += (s16)((roomDataTable[currentRoom].worldY - roomDataTable[newRoomLocal].worldY) * 10); currentProcessedActorPtr->worldZ += (s16)((roomDataTable[currentRoom].worldZ - roomDataTable[newRoomLocal].worldZ) * 10); } // FlagGenereActiveList = 1; } } void setupRealZv(ZVStruct* zvPtr) { zvPtr->ZVX1 = 32000; zvPtr->ZVY1 = 32000; zvPtr->ZVZ1 = 32000; zvPtr->ZVX2 = -32000; zvPtr->ZVY2 = -32000; zvPtr->ZVZ2 = -32000; for (int i = 0; i < numOfPoints; i++) { point3dStruct* ptr = &pointBuffer[i]; if (zvPtr->ZVX1 > ptr->x) { zvPtr->ZVX1 = ptr->x; } else if (zvPtr->ZVX2 < ptr->x) { zvPtr->ZVX2 = ptr->x; } if (zvPtr->ZVY1 > ptr->y) { zvPtr->ZVY1 = ptr->y; } else if (zvPtr->ZVY2 < ptr->y) { zvPtr->ZVY2 = ptr->y; } if (zvPtr->ZVZ1 > ptr->z) { zvPtr->ZVZ1 = ptr->z; } else if (zvPtr->ZVZ2 < ptr->z) { zvPtr->ZVZ2 = ptr->z; } } } void doRealZv(tObject* actorPtr) { ZVStruct* zvPtr; computeScreenBox(0, 0, 0, actorPtr->alpha, actorPtr->beta, actorPtr->gamma, HQR_Get(HQ_Bodys, actorPtr->bodyNum)); zvPtr = &actorPtr->zv; setupRealZv(zvPtr); zvPtr->ZVX1 += actorPtr->roomX; zvPtr->ZVX2 += actorPtr->roomX; zvPtr->ZVY1 += actorPtr->roomY; zvPtr->ZVY2 += actorPtr->roomY; zvPtr->ZVZ1 += actorPtr->roomZ; zvPtr->ZVZ2 += actorPtr->roomZ; } #ifdef DEBUG char currentDebugLifeLine[1024 * 1024]; void appendFormated(const char* format, ...) { va_list argList; va_start(argList, format); char buff[256]; vsprintf(buff, format, argList); va_end(argList); strcat(currentDebugLifeLine, buff); } #endif void processLife(int lifeNum, bool callFoundLife) { int exitLife = 0; //int switchVal = 0; int var_6; int switchVal = 0; currentLifeActorIdx = currentProcessedActorIdx; currentLifeActorPtr = currentProcessedActorPtr; currentLifeNum = lifeNum; currentLifePtr = HQR_Get(listLife, lifeNum); assert(currentLifePtr); while (!exitLife) { int lifeTempVar1; int lifeTempVar2; int lifeTempVar3; int lifeTempVar4; int lifeTempVar5; int lifeTempVar6; int lifeTempVar7; int lifeTempVar8; s16 currentOpcode; var_6 = -1; currentOpcode = *(s16*)(currentLifePtr); currentLifePtr += 2; #ifdef DEBUG strcpy(currentDebugLifeLine, ""); #endif appendFormated("%d:opcode: %02X: ", lifeNum, currentOpcode & 0xFFFF); if (currentOpcode & 0x8000) { var_6 = *(s16*)(currentLifePtr); currentLifePtr += 2; if (var_6 == -1) { printf("Unsupported newVar = -1\n"); assert(0); } else { currentProcessedActorIdx = ListWorldObjets[var_6].objIndex; if (currentProcessedActorIdx != -1) { currentProcessedActorPtr = &ListObjets[currentProcessedActorIdx]; goto processOpcode; } else { int opcodeLocated; if (g_gameId == AITD1) { opcodeLocated = AITD1LifeMacroTable[currentOpcode & 0x7FFF]; } else { opcodeLocated = AITD2LifeMacroTable[currentOpcode & 0x7FFF]; } switch (opcodeLocated) { //////////////////////////////////////////////////////////////////////// case LM_BODY: { ListWorldObjets[var_6].body = evalVar(); break; } case LM_BODY_RESET: { ListWorldObjets[var_6].body = evalVar(); ListWorldObjets[var_6].anim = evalVar(); break; } case LM_TYPE: { lifeTempVar1 = (*(s16*)(currentLifePtr)) & TYPE_MASK; currentLifePtr += 2; lifeTempVar2 = ListWorldObjets[var_6].flags; ListWorldObjets[var_6].flags = (ListWorldObjets[var_6].flags & (~TYPE_MASK)) + lifeTempVar1; break; } //////////////////////////////////////////////////////////////////////// case LM_ANIM_ONCE: { ListWorldObjets[var_6].anim = *(s16*)(currentLifePtr); currentLifePtr += 2; ListWorldObjets[var_6].animInfo = *(s16*)(currentLifePtr); currentLifePtr += 2; ListWorldObjets[var_6].animType = ANIM_ONCE; if (g_gameId >= JACK) ListWorldObjets[var_6].frame = 0; break; } case LM_ANIM_REPEAT: { ListWorldObjets[var_6].anim = *(s16*)(currentLifePtr); currentLifePtr += 2; ListWorldObjets[var_6].animInfo = -1; ListWorldObjets[var_6].animType = ANIM_REPEAT; if (g_gameId >= JACK) ListWorldObjets[var_6].frame = 0; break; } case LM_ANIM_ALL_ONCE: { ListWorldObjets[var_6].anim = *(s16*)(currentLifePtr); currentLifePtr += 2; ListWorldObjets[var_6].animInfo = *(s16*)(currentLifePtr); currentLifePtr += 2; ListWorldObjets[var_6].animType = ANIM_ONCE | ANIM_UNINTERRUPTABLE; if (g_gameId >= JACK) ListWorldObjets[var_6].frame = 0; break; } case LM_ANIM_RESET: { ASSERT(g_gameId >= JACK); ListWorldObjets[var_6].anim = *(s16*)(currentLifePtr); currentLifePtr += 2; ListWorldObjets[var_6].animInfo = *(s16*)(currentLifePtr); currentLifePtr += 2; ListWorldObjets[var_6].animType = ANIM_ONCE | ANIM_RESET; ListWorldObjets[var_6].frame = 0; break; } //////////////////////////////////////////////////////////////////////// case LM_MOVE: // MOVE { ListWorldObjets[var_6].trackMode = *(s16*)(currentLifePtr); currentLifePtr += 2; ListWorldObjets[var_6].trackNumber = *(s16*)(currentLifePtr); currentLifePtr += 2; ListWorldObjets[var_6].positionInTrack = 0; if (g_gameId > AITD1) { ListWorldObjets[var_6].mark = -1; } break; } case LM_ANGLE: { ListWorldObjets[var_6].alpha = *(s16*)(currentLifePtr); currentLifePtr += 2; ListWorldObjets[var_6].beta = *(s16*)(currentLifePtr); currentLifePtr += 2; ListWorldObjets[var_6].gamma = *(s16*)(currentLifePtr); currentLifePtr += 2; break; } case LM_STAGE: // stage { ListWorldObjets[var_6].stage = *(s16*)(currentLifePtr); currentLifePtr += 2; ListWorldObjets[var_6].room = *(s16*)(currentLifePtr); currentLifePtr += 2; ListWorldObjets[var_6].x = *(s16*)(currentLifePtr); currentLifePtr += 2; ListWorldObjets[var_6].y = *(s16*)(currentLifePtr); currentLifePtr += 2; ListWorldObjets[var_6].z = *(s16*)(currentLifePtr); currentLifePtr += 2; //FlagGenereActiveList = 1; break; } case LM_TEST_COL: { if (*(s16*)(currentLifePtr)) { ListWorldObjets[var_6].flags |= 0x20; } else { ListWorldObjets[var_6].flags &= 0xFFDF; } currentLifePtr += 2; break; } //////////////////////////////////////////////////////////////////////// case LM_LIFE: { ListWorldObjets[var_6].life = *(s16*)(currentLifePtr); currentLifePtr += 2; break; } case LM_LIFE_MODE: // LIFE_MODE { lifeTempVar1 = *(s16*)(currentLifePtr); currentLifePtr += 2; if (lifeTempVar1 != ListWorldObjets[var_6].lifeMode) { ListWorldObjets[var_6].lifeMode = lifeTempVar1; //FlagGenereActiveList = 1; } break; } case LM_FOUND_NAME: // FOUND_NAME { ListWorldObjets[var_6].foundName = *(s16*)(currentLifePtr); currentLifePtr += 2; break; } case LM_FOUND_BODY: // FOUND_BODY { ListWorldObjets[var_6].foundBody = *(s16*)(currentLifePtr); currentLifePtr += 2; break; } case LM_FOUND_FLAG: // FOUND_FLAG { ListWorldObjets[var_6].foundFlag &= 0xE000; ListWorldObjets[var_6].foundFlag |= *(s16*)(currentLifePtr); currentLifePtr += 2; break; } case LM_FOUND_WEIGHT: { ListWorldObjets[var_6].positionInTrack = *(s16*)(currentLifePtr); currentLifePtr += 2; break; } case LM_START_CHRONO: // arrive in original interpreter too { break; } //////////////////////////////////////////////////////////////////////// default: { printf("Unsupported opcode %X when actor isn't in floor\n", currentOpcode & 0x7FFF); assert(0); break; } } } } } else { int opcodeLocated; processOpcode: if (g_gameId == AITD1) { opcodeLocated = AITD1LifeMacroTable[currentOpcode & 0x7FFF]; } else { opcodeLocated = AITD2LifeMacroTable[currentOpcode & 0x7FFF]; } switch (opcodeLocated) { case LM_BODY: { lifeTempVar1 = evalVar(); ListWorldObjets[currentProcessedActorPtr->indexInWorld].body = lifeTempVar1; if (currentProcessedActorPtr->bodyNum != lifeTempVar1) { currentProcessedActorPtr->bodyNum = lifeTempVar1; if (currentProcessedActorPtr->objectType & AF_ANIMATED) { if ((currentProcessedActorPtr->ANIM != -1) && (currentProcessedActorPtr->bodyNum != -1)) { sAnimation* pAnim = HQR_Get(HQ_Anims, currentProcessedActorPtr->ANIM); if (g_gameId >= JACK) { /* if (bFlagDecal) gereDecal(); */ } sBody* pBody = HQR_Get(HQ_Bodys, currentProcessedActorPtr->bodyNum); /* if(gameId >= JACK) { setInterAnimObject2(currentProcessedActorPtr->FRAME, pAnim, pBody, TRUE, Objet->AnimDecal); } else */ { SetInterAnimObjet(currentProcessedActorPtr->frame, pAnim, pBody); } } } else { FlagInitView = 1; } } break; } case LM_BODY_RESET: { appendFormated("LM_BODY_RESET "); int param1 = evalVar("body"); int param2 = evalVar("anim"); ListWorldObjets[currentProcessedActorPtr->indexInWorld].body = param1; ListWorldObjets[currentProcessedActorPtr->indexInWorld].anim = param2; currentProcessedActorPtr->bodyNum = param1; if (currentProcessedActorPtr->objectType & AF_ANIMATED) { sAnimation* pAnim = HQR_Get(HQ_Anims, currentProcessedActorPtr->ANIM); if (g_gameId >= JACK) { /* if (bFlagDecal) gereDecal(); */ } sBody* pBody = HQR_Get(HQ_Bodys, currentProcessedActorPtr->bodyNum); SetAnimObjet(0, pAnim, pBody); InitAnim(param2, 4, -1); } else { FlagInitView = 1; } break; } case LM_DO_REAL_ZV: { appendFormated("LM_DO_REAL_ZV "); doRealZv(currentProcessedActorPtr); break; } case LM_DEF_ZV: // DEF_ZV { appendFormated("LM_DEF_ZV "); currentProcessedActorPtr->zv.ZVX1 = currentProcessedActorPtr->roomX + *(s16*)currentLifePtr + currentProcessedActorPtr->stepX; currentLifePtr += 2; currentProcessedActorPtr->zv.ZVX2 = currentProcessedActorPtr->roomX + *(s16*)currentLifePtr + currentProcessedActorPtr->stepX; currentLifePtr += 2; currentProcessedActorPtr->zv.ZVY1 = currentProcessedActorPtr->roomY + *(s16*)currentLifePtr + currentProcessedActorPtr->stepY; currentLifePtr += 2; currentProcessedActorPtr->zv.ZVY2 = currentProcessedActorPtr->roomY + *(s16*)currentLifePtr + currentProcessedActorPtr->stepY; currentLifePtr += 2; currentProcessedActorPtr->zv.ZVZ1 = currentProcessedActorPtr->roomZ + *(s16*)currentLifePtr + currentProcessedActorPtr->stepZ; currentLifePtr += 2; currentProcessedActorPtr->zv.ZVZ2 = currentProcessedActorPtr->roomZ + *(s16*)currentLifePtr + currentProcessedActorPtr->stepZ; currentLifePtr += 2; break; } case LM_DEF_ABS_ZV: { appendFormated("LM_DEF_ABS_ZV "); currentProcessedActorPtr->zv.ZVX1 = *(s16*)currentLifePtr; currentLifePtr += 2; currentProcessedActorPtr->zv.ZVX2 = *(s16*)currentLifePtr; currentLifePtr += 2; currentProcessedActorPtr->zv.ZVY1 = *(s16*)currentLifePtr; currentLifePtr += 2; currentProcessedActorPtr->zv.ZVY2 = *(s16*)currentLifePtr; currentLifePtr += 2; currentProcessedActorPtr->zv.ZVZ1 = *(s16*)currentLifePtr; currentLifePtr += 2; currentProcessedActorPtr->zv.ZVZ2 = *(s16*)currentLifePtr; currentLifePtr += 2; break; } case LM_DO_ROT_ZV: // DO_ROT_ZV { appendFormated("LM_DO_ROT_ZV "); getZvRot(HQR_Get(HQ_Bodys, currentProcessedActorPtr->bodyNum), ¤tProcessedActorPtr->zv, currentProcessedActorPtr->alpha, currentProcessedActorPtr->beta, currentProcessedActorPtr->gamma); currentProcessedActorPtr->zv.ZVX1 += currentProcessedActorPtr->roomX; currentProcessedActorPtr->zv.ZVX2 += currentProcessedActorPtr->roomX; currentProcessedActorPtr->zv.ZVY1 += currentProcessedActorPtr->roomY; currentProcessedActorPtr->zv.ZVY2 += currentProcessedActorPtr->roomY; currentProcessedActorPtr->zv.ZVZ1 += currentProcessedActorPtr->roomZ; currentProcessedActorPtr->zv.ZVZ2 += currentProcessedActorPtr->roomZ; break; } case LM_DO_MAX_ZV: { appendFormated("LM_DO_MAX_ZV "); getZvMax(HQR_Get(HQ_Bodys, currentProcessedActorPtr->bodyNum), ¤tProcessedActorPtr->zv); currentProcessedActorPtr->zv.ZVX1 += currentProcessedActorPtr->roomX; currentProcessedActorPtr->zv.ZVX2 += currentProcessedActorPtr->roomX; currentProcessedActorPtr->zv.ZVY1 += currentProcessedActorPtr->roomY; currentProcessedActorPtr->zv.ZVY2 += currentProcessedActorPtr->roomY; currentProcessedActorPtr->zv.ZVZ1 += currentProcessedActorPtr->roomZ; currentProcessedActorPtr->zv.ZVZ2 += currentProcessedActorPtr->roomZ; break; } case LM_DO_CARRE_ZV: // DO_CARRE_ZV { appendFormated("LM_DO_CARRE_ZV "); getZvCube(HQR_Get(HQ_Bodys, currentProcessedActorPtr->bodyNum), ¤tProcessedActorPtr->zv); currentProcessedActorPtr->zv.ZVX1 += currentProcessedActorPtr->roomX; currentProcessedActorPtr->zv.ZVX2 += currentProcessedActorPtr->roomX; currentProcessedActorPtr->zv.ZVY1 += currentProcessedActorPtr->roomY; currentProcessedActorPtr->zv.ZVY2 += currentProcessedActorPtr->roomY; currentProcessedActorPtr->zv.ZVZ1 += currentProcessedActorPtr->roomZ; currentProcessedActorPtr->zv.ZVZ2 += currentProcessedActorPtr->roomZ; break; } case LM_TYPE: // TYPE { appendFormated("LM_TYPE "); lifeTempVar1 = readNextArgument("type") & AF_MASK; lifeTempVar2 = currentProcessedActorPtr->objectType; currentProcessedActorPtr->objectType = (currentProcessedActorPtr->objectType & ~AF_MASK) + lifeTempVar1; if (g_gameId > AITD1) { if (lifeTempVar2 & 1) { if (!(lifeTempVar1 & 1)) { addActorToBgInscrust(currentProcessedActorIdx); } } if (lifeTempVar1 & 1) { if (!(lifeTempVar2 & 8)) { removeFromBGIncrust(currentProcessedActorIdx); } } } break; } case LM_GET_HARD_CLIP: //GET_HARD_CLIP { appendFormated("LM_GET_HARD_CLIP "); getHardClip(); break; } //////////////////////////////////////////////////////////////////////// case LM_ANIM_ONCE: { appendFormated("LM_ANIM_ONCE "); lifeTempVar1 = readNextArgument("Anim"); lifeTempVar2 = readNextArgument("Flags"); if (lifeTempVar1 == -1) { currentProcessedActorPtr->ANIM = -1; currentProcessedActorPtr->newAnim = -2; } else { InitAnim(lifeTempVar1, 0, lifeTempVar2); } break; } case LM_ANIM_REPEAT: { appendFormated("LM_ANIM_REPEAT "); lifeTempVar1 = readNextArgument("Anim"); InitAnim(lifeTempVar1, 1, -1); break; } case LM_ANIM_ALL_ONCE: { appendFormated("LM_ANIM_ALL_ONCE "); lifeTempVar1 = readNextArgument("Anim"); lifeTempVar2 = readNextArgument("Flags"); InitAnim(lifeTempVar1, 2, lifeTempVar2); break; } case LM_ANIM_RESET: { appendFormated("LM_ANIM_RESET "); int anim = readNextArgument("Anim"); int animFlag = readNextArgument("Flags"); if (anim == -1) { currentProcessedActorPtr->ANIM = -1; currentProcessedActorPtr->newAnim = -2; } else { InitAnim(anim, ANIM_ONCE | ANIM_RESET, animFlag); } break; } case LM_ANIM_HYBRIDE_ONCE: { appendFormated("LM_ANIM_HYBRIDE_ONCE "); 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)) { sHybrid* pHybrid = HQR_Get(HQ_Hybrides, currentProcessedActorPtr->ANIM); currentProcessedActorPtr->numOfFrames = pHybrid->animations[currentProcessedActorPtr->bodyNum].count; 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 "); 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)) { sHybrid* pHybrid = HQR_Get(HQ_Hybrides, currentProcessedActorPtr->ANIM); currentProcessedActorPtr->numOfFrames = pHybrid->animations[currentProcessedActorPtr->bodyNum].count; currentProcessedActorPtr->animInfo = -1; currentProcessedActorPtr->animType = ANIM_REPEAT; currentProcessedActorPtr->objectType |= AF_OBJ_2D; } else { currentProcessedActorPtr->numOfFrames = 0; currentProcessedActorPtr->objectType = 0; } } break; } //////////////////////////////////////////////////////////////////////// case LM_HIT: { appendFormated("LM_HIT "); lifeTempVar1 = readNextArgument("Anim"); lifeTempVar2 = readNextArgument("StartFrame"); lifeTempVar3 = readNextArgument("GroupNumber"); lifeTempVar4 = readNextArgument("HitBoxSize"); lifeTempVar5 = evalVar("HitForce"); lifeTempVar6 = readNextArgument("NextAnim"); hit(lifeTempVar1, lifeTempVar2, lifeTempVar3, lifeTempVar4, lifeTempVar5, lifeTempVar6); break; } case LM_FIRE: // FIRE { appendFormated("LM_FIRE "); if (g_gameId == AITD1) { int fireAnim; int shootFrame; int emitPoint; int zvSize; int hitForce; int nextAnim; fireAnim = readNextArgument("Anim"); shootFrame = readNextArgument("Frame"); emitPoint = readNextArgument("EmitPoint"); zvSize = readNextArgument("ZVSize"); hitForce = readNextArgument("Force"); nextAnim = readNextArgument("NextAnim"); fire(fireAnim, shootFrame, emitPoint, zvSize, hitForce, nextAnim); } else // use an emitter model { int fireAnim; int shootFrame; int emitPoint; int emitModel; int zvSize; int hitForce; int nextAnim; fireAnim = evalVar("Anim"); shootFrame = readNextArgument("Frame"); emitPoint = readNextArgument("EmitPoint"); emitModel = readNextArgument("EmitModel"); zvSize = readNextArgument("ZVSize"); hitForce = readNextArgument("Force"); nextAnim = evalVar(); fire(fireAnim, shootFrame, emitPoint, zvSize, hitForce, nextAnim); // todo: implement emit model } break; } case LM_FIRE_UP_DOWN: // TODO AITD3 only { appendFormated("LM_FIRE_UP_DOWN "); evalVar(); currentLifePtr += 12; evalVar(); break; } case LM_HIT_OBJECT: // HIT_OBJECT { appendFormated("LM_HIT_OBJECT "); lifeTempVar1 = readNextArgument("Flags"); lifeTempVar2 = readNextArgument("Force"); currentProcessedActorPtr->animActionType = 8; currentProcessedActorPtr->animActionParam = lifeTempVar1; currentProcessedActorPtr->hitForce = lifeTempVar2; currentProcessedActorPtr->hotPointID = -1; break; } case LM_STOP_HIT_OBJECT: // cancel hit obj { appendFormated("LM_STOP_HIT_OBJECT "); if (currentProcessedActorPtr->animActionType == 8) { currentProcessedActorPtr->animActionType = 0; currentProcessedActorPtr->animActionParam = 0; currentProcessedActorPtr->hitForce = 0; currentProcessedActorPtr->hotPointID = -1; } break; } case LM_THROW: // throw { appendFormated("LM_THROW "); lifeTempVar1 = *(s16*)(currentLifePtr); currentLifePtr += 2; lifeTempVar2 = *(s16*)(currentLifePtr); currentLifePtr += 2; lifeTempVar3 = *(s16*)(currentLifePtr); currentLifePtr += 2; lifeTempVar4 = *(s16*)(currentLifePtr); currentLifePtr += 2; lifeTempVar5 = *(s16*)(currentLifePtr); currentLifePtr += 2; lifeTempVar6 = *(s16*)(currentLifePtr); currentLifePtr += 2; lifeTempVar7 = *(s16*)(currentLifePtr); currentLifePtr += 2; throwObj(lifeTempVar1, lifeTempVar2, lifeTempVar3, lifeTempVar4, lifeTempVar5, lifeTempVar6, lifeTempVar7); break; } //////////////////////////////////////////////////////////////////////// case LM_MOVE: { appendFormated("LM_MOVE "); lifeTempVar1 = readNextArgument("TrackMode"); lifeTempVar2 = readNextArgument("TrackNumber"); InitDeplacement(lifeTempVar1, lifeTempVar2); break; } case LM_RESET_MOVE_MANUAL: { appendFormated("LM_RESET_MOVE_MANUAL "); resetRotateParam(); break; } case LM_CONTINUE_TRACK: { appendFormated("LM_CONTINUE_TRACK "); char* ptr; ptr = HQR_Get(listTrack, currentProcessedActorPtr->trackNumber); ptr += currentProcessedActorPtr->positionInTrack * 2; if (*(s16*)ptr == 5) { currentProcessedActorPtr->positionInTrack++; } break; } case LM_DO_MOVE: { appendFormated("LM_DO_MOVE "); processTrack(); break; } case LM_ANIM_MOVE: { appendFormated("LM_ANIM_MOVE "); int animStand = readNextArgument("animStand"); int animWalk = readNextArgument("animWalk"); int animRun = readNextArgument("animRun"); int animStop = readNextArgument("animStop"); int animWalkBackward = readNextArgument("animWalkBackward"); int animTurnRight = readNextArgument("animTurnRight"); int animTurnLeft = readNextArgument("animTurnLeft"); animMove(animStand, animWalk, animRun, animStop, animWalkBackward, animTurnRight, animTurnLeft); break; } case LM_MANUAL_ROT: // MANUAL_ROT { appendFormated("LM_MANUAL_ROT "); if (g_gameId == AITD1) { GereManualRot(240); } else { GereManualRot(90); } break; } case LM_SET_BETA: // SET_BETA { appendFormated("LM_SET_BETA "); lifeTempVar1 = readNextArgument("beta"); lifeTempVar2 = readNextArgument("speed"); if (currentProcessedActorPtr->beta != lifeTempVar1) { if (currentProcessedActorPtr->rotate.numSteps == 0 || currentProcessedActorPtr->rotate.endValue != lifeTempVar1) { InitRealValue(currentProcessedActorPtr->beta, lifeTempVar1, lifeTempVar2, ¤tProcessedActorPtr->rotate); } currentProcessedActorPtr->beta = updateActorRotation(¤tProcessedActorPtr->rotate); } break; } case LM_SET_ALPHA: // SET_ALPHA { appendFormated("LM_SET_ALPHA "); lifeTempVar1 = readNextArgument("alpha"); lifeTempVar2 = readNextArgument("speed"); if (currentProcessedActorPtr->alpha != lifeTempVar1) { if (currentProcessedActorPtr->rotate.numSteps == 0 || lifeTempVar1 != currentProcessedActorPtr->rotate.endValue) { InitRealValue(currentProcessedActorPtr->alpha, lifeTempVar1, lifeTempVar2, ¤tProcessedActorPtr->rotate); } currentProcessedActorPtr->alpha = updateActorRotation(¤tProcessedActorPtr->rotate); } break; } case LM_ANGLE: // ANGLE { appendFormated("LM_ANGLE "); currentProcessedActorPtr->alpha = readNextArgument("alpha"); currentProcessedActorPtr->beta = readNextArgument("beta"); currentProcessedActorPtr->gamma = readNextArgument("gamma"); break; } case LM_COPY_ANGLE: { appendFormated("LM_COPY_ANGLE "); int object = readNextArgument("object"); int localObjectIndex = ListWorldObjets[object].objIndex; if (localObjectIndex == -1) { currentProcessedActorPtr->alpha = ListWorldObjets[object].alpha; currentProcessedActorPtr->beta = ListWorldObjets[object].beta; currentProcessedActorPtr->gamma = ListWorldObjets[object].gamma; } else { currentProcessedActorPtr->alpha = ListObjets[localObjectIndex].alpha; currentProcessedActorPtr->beta = ListObjets[localObjectIndex].beta; currentProcessedActorPtr->gamma = ListObjets[localObjectIndex].gamma; } break; } case LM_STAGE: // STAGE { appendFormated("LM_STAGE "); lifeTempVar1 = readNextArgument("newStage"); lifeTempVar2 = readNextArgument("newRoom"); lifeTempVar3 = readNextArgument("X"); lifeTempVar4 = readNextArgument("Y"); lifeTempVar5 = readNextArgument("Z"); setStage(lifeTempVar1, lifeTempVar2, lifeTempVar3, lifeTempVar4, lifeTempVar5); break; } case LM_TEST_COL: // TEST_COL { appendFormated("LM_TEST_COL "); lifeTempVar1 = readNextArgument(); if (lifeTempVar1) { currentProcessedActorPtr->dynFlags |= 1; } else { currentProcessedActorPtr->dynFlags &= ~1; } break; } case LM_UP_COOR_Y: // UP_COOR_Y { appendFormated("LM_UP_COOR_Y "); InitRealValue(0, -2000, -1, ¤tProcessedActorPtr->YHandler); break; } //////////////////////////////////////////////////////////////////////// case LM_LIFE: // LIFE { appendFormated("LM_LIFE "); currentProcessedActorPtr->life = readNextArgument("newLife"); break; } case LM_STAGE_LIFE: { appendFormated("LM_STAGE_LIFE "); ListWorldObjets[currentProcessedActorPtr->indexInWorld].floorLife = readNextArgument("stageLife"); break; } case LM_LIFE_MODE: // LIFE_MODE { appendFormated("LM_LIFE_MODE "); lifeTempVar1 = readNextArgument("lifeMode"); if (g_gameId <= JACK) { lifeTempVar2 = currentProcessedActorPtr->lifeMode; } else { lifeTempVar2 = currentProcessedActorPtr->lifeMode & 3; } if (lifeTempVar1 != lifeTempVar2) { currentProcessedActorPtr->lifeMode = lifeTempVar1; //FlagGenereActiveList = 1; } break; } case LM_DELETE: // DELETE { appendFormated("LM_DELETE "); if (g_gameId <= JACK) { lifeTempVar1 = readNextArgument("ObjectId"); } else { lifeTempVar1 = evalVar("ObjectId"); } deleteObject(lifeTempVar1); if (ListWorldObjets[lifeTempVar1].foundBody != -1) { if (g_gameId == AITD1) // TODO: check, really useful ? { ListWorldObjets[lifeTempVar1].foundFlag &= ~0x8000; } ListWorldObjets[lifeTempVar1].foundFlag |= 0x4000; } break; } case LM_SPECIAL: // SPECIAL { appendFormated("LM_SPECIAL "); lifeTempVar1 = readNextArgument("type"); switch (lifeTempVar1) { case 0: // evaporate { InitSpecialObjet(0, currentProcessedActorPtr->roomX + currentProcessedActorPtr->stepX, currentProcessedActorPtr->roomY + currentProcessedActorPtr->stepY, currentProcessedActorPtr->roomZ + currentProcessedActorPtr->stepZ, currentProcessedActorPtr->stage, currentProcessedActorPtr->room, currentProcessedActorPtr->alpha, currentProcessedActorPtr->beta, currentProcessedActorPtr->gamma, ¤tProcessedActorPtr->zv); break; } case 1: // flow { currentProcessedActorPtr = &ListObjets[currentProcessedActorPtr->HIT_BY]; InitSpecialObjet(1, currentProcessedActorPtr->roomX + currentProcessedActorPtr->stepX + currentProcessedActorPtr->hotPoint.x, currentProcessedActorPtr->roomY + currentProcessedActorPtr->stepY + currentProcessedActorPtr->hotPoint.y, currentProcessedActorPtr->roomZ + currentProcessedActorPtr->stepZ + currentProcessedActorPtr->hotPoint.z, currentProcessedActorPtr->stage, currentProcessedActorPtr->room, 0, -currentProcessedActorPtr->beta, 0, NULL); currentProcessedActorPtr = currentLifeActorPtr; break; } case 4: // cigar smoke { InitSpecialObjet(4, currentProcessedActorPtr->roomX + currentProcessedActorPtr->stepX, currentProcessedActorPtr->roomY + currentProcessedActorPtr->stepY, currentProcessedActorPtr->roomZ + currentProcessedActorPtr->stepZ, currentProcessedActorPtr->stage, currentProcessedActorPtr->room, currentProcessedActorPtr->alpha, currentProcessedActorPtr->beta, currentProcessedActorPtr->gamma, ¤tProcessedActorPtr->zv); break; } } break; } //////////////////////////////////////////////////////////////////////// case LM_START_CHRONO: //START_CHRONO { appendFormated("LM_START_CHRONO "); startChrono(¤tProcessedActorPtr->CHRONO); break; } //////////////////////////////////////////////////////////////////////// case LM_FOUND: // FOUND { appendFormated("LM_FOUND "); lifeTempVar1 = readNextArgument("ObjectId"); if (g_gameId == AITD1) { FoundObjet(lifeTempVar1, 1); } else { if (callFoundLife) { FoundObjet(lifeTempVar1, 2); } else { FoundObjet(lifeTempVar1, 1); } } break; } case LM_TAKE: // TAKE { appendFormated("LM_TAKE "); if (g_gameId >= TIMEGATE) { int arg0 = evalVar(); int arg1 = readNextArgument(); int arg2 = readNextArgument(); int arg3 = readNextArgument(); } else { lifeTempVar1 = readNextArgument("ObjectId"); take(lifeTempVar1); } break; } case LM_IN_HAND: // IN_HAND { appendFormated("LM_IN_HAND "); if (g_gameId <= JACK) { inHandTable[currentInventory] = *(s16*)(currentLifePtr); currentLifePtr += 2; } else { inHandTable[currentInventory] = evalVar(); } break; } case LM_DROP: // DROP { appendFormated("LM_DROP "); lifeTempVar1 = evalVar(); lifeTempVar2 = *(s16*)(currentLifePtr); currentLifePtr += 2; drop(lifeTempVar1, lifeTempVar2); break; } case LM_PUT: { appendFormated("LM_PUT "); int x; int y; int z; int room; int stage; int alpha; int beta; int gamma; int idx; idx = *(s16*)(currentLifePtr); currentLifePtr += 2; x = *(s16*)(currentLifePtr); currentLifePtr += 2; y = *(s16*)(currentLifePtr); currentLifePtr += 2; z = *(s16*)(currentLifePtr); currentLifePtr += 2; room = *(s16*)(currentLifePtr); currentLifePtr += 2; stage = *(s16*)(currentLifePtr); currentLifePtr += 2; alpha = *(s16*)(currentLifePtr); currentLifePtr += 2; beta = *(s16*)(currentLifePtr); currentLifePtr += 2; gamma = *(s16*)(currentLifePtr); currentLifePtr += 2; put(x, y, z, room, stage, alpha, beta, gamma, idx); break; } case LM_PUT_AT: // PUT_AT { appendFormated("LM_PUT_AT "); int objIdx1; int objIdx2; objIdx1 = *(s16*)currentLifePtr; currentLifePtr += 2; objIdx2 = *(s16*)currentLifePtr; currentLifePtr += 2; PutAtObjet(objIdx1, objIdx2); break; } case LM_FOUND_NAME: // FOUND_NAME { appendFormated("LM_FOUND_NAME "); ListWorldObjets[currentProcessedActorPtr->indexInWorld].foundName = *(s16*)(currentLifePtr); currentLifePtr += 2; break; } case LM_FOUND_BODY: // FOUND_BODY { appendFormated("LM_FOUND_BODY "); ListWorldObjets[currentProcessedActorPtr->indexInWorld].foundBody = *(s16*)(currentLifePtr); currentLifePtr += 2; break; } case LM_FOUND_FLAG: // FOUND_FLAG { appendFormated("LM_FOUND_FLAG "); ListWorldObjets[currentProcessedActorPtr->indexInWorld].foundFlag &= 0xE000; ListWorldObjets[currentProcessedActorPtr->indexInWorld].foundFlag |= *(s16*)(currentLifePtr); currentLifePtr += 2; break; } case LM_FOUND_WEIGHT: // FOUND_WEIGHT { appendFormated("LM_FOUND_WEIGHT "); ListWorldObjets[currentProcessedActorPtr->indexInWorld].positionInTrack = *(s16*)(currentLifePtr); currentLifePtr += 2; break; } case LM_FOUND_LIFE: // FOUND_LIFE { appendFormated("LM_FOUND_LIFE "); ListWorldObjets[currentProcessedActorPtr->indexInWorld].foundLife = *(s16*)(currentLifePtr); currentLifePtr += 2; break; } case LM_READ: // READ { appendFormated("LM_READ "); lifeTempVar1 = *(s16*)(currentLifePtr); currentLifePtr += 2; lifeTempVar2 = *(s16*)(currentLifePtr); currentLifePtr += 2; if (g_gameId == AITD1) { currentLifePtr += 2;// AITD1 CD has an extra digit, related to the VOC files to play for the text? } FadeOutPhys(0x20, 0); readBook(lifeTempVar2 + 1, lifeTempVar1); if (g_gameId == AITD1) { FadeOutPhys(4, 0); } FlagInitView = 2; break; } case LM_READ_ON_PICTURE: // TODO { appendFormated("LM_READ_ON_PICTURE "); lifeTempVar1 = *(s16*)(currentLifePtr); currentLifePtr += 2; lifeTempVar2 = *(s16*)(currentLifePtr); currentLifePtr += 2; lifeTempVar3 = *(s16*)(currentLifePtr); currentLifePtr += 2; lifeTempVar4 = *(s16*)(currentLifePtr); currentLifePtr += 2; lifeTempVar5 = *(s16*)(currentLifePtr); currentLifePtr += 2; lifeTempVar6 = *(s16*)(currentLifePtr); currentLifePtr += 2; lifeTempVar7 = *(s16*)(currentLifePtr); currentLifePtr += 2; lifeTempVar8 = *(s16*)(currentLifePtr); currentLifePtr += 2; SaveTimerAnim(); FadeOutPhys(32, 0); LoadPak("ITD_RESS", lifeTempVar1, aux); palette_t lpalette; copyPalette(aux + 64000, lpalette); convertPaletteIfRequired(lpalette); copyPalette(lpalette, currentGamePalette); setPalette(lpalette); turnPageFlag = false; Lire(lifeTempVar2 + 1, lifeTempVar3, lifeTempVar4, lifeTempVar5, lifeTempVar6, 0, lifeTempVar7, lifeTempVar8); FlagInitView = 2; RestoreTimerAnim(); break; } //////////////////////////////////////////////////////////////////////// case LM_ANIM_SAMPLE: // ANIM_SAMPLE { appendFormated("LM_ANIM_SAMPLE "); lifeTempVar1 = evalVar(); if (g_gameId == TIMEGATE) { currentLifePtr += 2; } lifeTempVar2 = *(s16*)(currentLifePtr); currentLifePtr += 2; lifeTempVar3 = *(s16*)(currentLifePtr); currentLifePtr += 2; if (currentProcessedActorPtr->END_FRAME != 0) { if (currentProcessedActorPtr->ANIM == lifeTempVar2) { if (currentProcessedActorPtr->frame == lifeTempVar3) { playSound(lifeTempVar1); //setSampleFreq(0); } } } break; } case LM_2D_ANIM_SAMPLE: { appendFormated("LM_2D_ANIM_SAMPLE "); int sampleNumber; int animNumber; int frameNumber; sampleNumber = evalVar(); animNumber = *(s16*)(currentLifePtr); currentLifePtr += 2; frameNumber = *(s16*)(currentLifePtr); currentLifePtr += 2; printf("LM_2D_ANIM_SAMPLE(sampleNumber %d, animNumber %d, frameNumber %d)\n", sampleNumber, animNumber, frameNumber); break; // TODO: implement } case LM_SAMPLE: { appendFormated("LM_SAMPLE "); int sampleNumber; if (g_gameId == TIMEGATE) { sampleNumber = evalVar(); readNextArgument(); } else if (g_gameId <= JACK) { sampleNumber = evalVar(); } else { sampleNumber = *(s16*)(currentLifePtr); currentLifePtr += 2; } playSound(sampleNumber); //setSampleFreq(0); break; } case LM_REP_SAMPLE: // sample TODO! { appendFormated("LM_REP_SAMPLE "); if ((g_gameId == AITD1) || (g_gameId == TIMEGATE)) { evalVar(); currentLifePtr += 2; } else { currentLifePtr += 4; } //printf("LM_REP_SAMPLE\n"); break; } case LM_STOP_SAMPLE: // todo { appendFormated("LM_STOP_SAMPLE "); //printf("LM_STOP_SAMPLE\n"); if (g_gameId == TIMEGATE) { readNextArgument(); } break; } case LM_SAMPLE_THEN: //todo { appendFormated("LM_SAMPLE_THEN "); if (g_gameId == AITD1) { playSound(evalVar()); nextSample = evalVar(); } else { int newSample; if (g_gameId == JACK) { newSample = evalVar(); nextSample = evalVar(); } else { newSample = *(s16*)currentLifePtr; currentLifePtr += 2; nextSample = *(s16*)currentLifePtr; currentLifePtr += 2; } playSound(newSample); } printf("LM_SAMPLE_THEN\n"); // setSampleFreq(0); break; } case LM_SAMPLE_THEN_REPEAT: //todo { appendFormated("LM_SAMPLE_THEN_REPEAT "); playSound(evalVar()); nextSample = evalVar() | 0x4000; // setSampleFreq(0); //printf("LM_SAMPLE_THEN_REPEAT\n"); break; } //////////////////////////////////////////////////////////////////////// case LM_MUSIC: // MUSIC { appendFormated("LM_MUSIC "); int newMusicIdx = *(s16*)(currentLifePtr); currentLifePtr += 2; playMusic(newMusicIdx); break; } case LM_NEXT_MUSIC: // TODO { appendFormated("LM_NEXT_MUSIC "); int musicIdx = *(s16*)(currentLifePtr); currentLifePtr += 2; if (currentMusic == -1) { playMusic(musicIdx); } else { nextMusic = musicIdx; } break; } case LM_FADE_MUSIC: // ? fade out music and play another music ? { appendFormated("LM_FADE_MUSIC "); lifeTempVar1 = *(s16*)(currentLifePtr); currentLifePtr += 2; if (currentMusic != -1) { fadeMusic(0, 0, 0x8000); // fade out music startChrono(&musicChrono); // fade out music timer currentMusic = -2; // waiting next music nextMusic = lifeTempVar1; // next music to play } else { playMusic(lifeTempVar1); } break; } case LM_RND_FREQ: // TODO { appendFormated("LM_RND_FREQ "); //printf("LM_RND_FREQ\n"); currentLifePtr += 2; break; } //////////////////////////////////////////////////////////////////////// case LM_LIGHT: // LIGHT { appendFormated("LM_LIGHT "); lifeTempVar1 = 2 - ((*(s16*)(currentLifePtr)) << 1); currentLifePtr += 2; if (g_gameId >= JACK || (!CVars[getCVarsIdx((enumCVars)KILLED_SORCERER)])) { if (lightOff != lifeTempVar1) { lightOff = lifeTempVar1; lightVar2 = 1; } } break; } case LM_SHAKING: // SHAKING { appendFormated("LM_SHAKING "); printf("LM_SHAKING\n"); //shakingState = shakingAmplitude = *(s16*)(currentLifePtr); currentLifePtr += 2; /* if(shakingState==0) { stopShaking(); } */ break; } case LM_PLUIE: { appendFormated("LM_PLUIE "); //printf("LM_PLUIE\n"); // TODO currentLifePtr += 2; break; } case LM_WATER: // ? shaking related { appendFormated("LM_WATER "); // TODO: Warning, AITD1/AITD2 diff printf("LM_WATER\n"); // mainLoopVar1 = shakeVar1 = *(s16*)(currentLifePtr); currentLifePtr += 2; /* if(mainLoopVar1) { //setupShaking(-600); } else { //setupShaking(1000); } */ break; } case LM_CAMERA_TARGET: // CAMERA_TARGET { appendFormated("LM_CAMERA_TARGET "); lifeTempVar1 = readNextArgument("Target"); if (lifeTempVar1 != currentWorldTarget) // same target { lifeTempVar2 = ListWorldObjets[lifeTempVar1].objIndex; if (lifeTempVar2 != -1) { if (g_gameId == AITD1) { currentWorldTarget = lifeTempVar1; currentCameraTargetActor = lifeTempVar2; lifeTempVar3 = ListObjets[currentCameraTargetActor].room; if (lifeTempVar3 != currentRoom) { FlagChangeSalle = 1; NewNumSalle = lifeTempVar3; } } else { // security case, the target actor may be still be in list while already changed of stage // TODO: check if AITD1 could use the same code (quite probable as it's only security) if (ListObjets[lifeTempVar2].stage != g_currentFloor) { currentWorldTarget = lifeTempVar1; FlagChangeEtage = 1; NewNumEtage = ListObjets[lifeTempVar2].stage; NewNumSalle = ListObjets[lifeTempVar2].room; } else { currentWorldTarget = lifeTempVar1; currentCameraTargetActor = lifeTempVar2; lifeTempVar3 = ListObjets[currentCameraTargetActor].room; if (lifeTempVar3 != currentRoom) { FlagChangeSalle = 1; NewNumSalle = lifeTempVar3; } } } } else // different stage { currentWorldTarget = lifeTempVar1; if (ListWorldObjets[lifeTempVar1].stage != g_currentFloor) { FlagChangeEtage = 1; NewNumEtage = ListWorldObjets[lifeTempVar1].stage; NewNumSalle = ListWorldObjets[lifeTempVar1].room; } else { if (currentRoom != ListWorldObjets[lifeTempVar1].room) { FlagChangeSalle = 1; NewNumSalle = ListWorldObjets[lifeTempVar1].room; } } } } break; } case LM_PICTURE: // displayScreen { appendFormated("LM_PICTURE "); int pictureIndex = readNextArgument("pictureIndex"); int delay = readNextArgument("delay"); int sampleId; if (g_gameId == TIMEGATE) { sampleId = evalVar("sampleId"); readNextArgument(); } else { sampleId = readNextArgument("sampleId"); } SaveTimerAnim(); LoadPak("ITD_RESS", pictureIndex, aux); if (g_gameId > AITD1) { FadeOutPhys(0x10, 0); palette_t lpalette; copyPalette(aux + 64000, lpalette); convertPaletteIfRequired(lpalette); copyPalette(lpalette, currentGamePalette); setPalette(lpalette); } FastCopyScreen(aux, frontBuffer); osystem_CopyBlockPhys((unsigned char*)frontBuffer, 0, 0, 320, 200); osystem_drawBackground(); unsigned int chrono; startChrono(&chrono); playSound(sampleId); //soundFunc(0); do { unsigned int time; process_events(); time = evalChrono(&chrono); if (time > (unsigned int)delay) break; } while (!key && !Click); RestoreTimerAnim(); FlagInitView = 1; if (g_gameId > AITD1) { FadeOutPhys(0x10, 0); } break; } case LM_PLAY_SEQUENCE: // sequence { appendFormated("LM_PLAY_SEQUENCE "); u16 sequenceIdx; u16 fadeEntry; u16 fadeOut; SaveTimerAnim(); sequenceIdx = *(u16*)(currentLifePtr); currentLifePtr += 2; fadeEntry = *(u16*)(currentLifePtr); currentLifePtr += 2; fadeOut = *(u16*)(currentLifePtr); currentLifePtr += 2; playSequence(sequenceIdx, fadeEntry, fadeOut); RestoreTimerAnim(); break; } case LM_DEF_SEQUENCE_SAMPLE: { appendFormated("LM_DEF_SEQUENCE_SAMPLE "); u16 numParams; int i; numParams = *(s16*)(currentLifePtr); currentLifePtr += 2; ASSERT(numParams <= NUM_MAX_SEQUENCE_PARAM); for (i = 0; i < numParams; i++) { sequenceParams[i].frame = READ_LE_U16(currentLifePtr); currentLifePtr += 2; sequenceParams[i].sample = READ_LE_U16(currentLifePtr); currentLifePtr += 2; } numSequenceParam = numParams; break; } //////////////////////////////////////////////////////////////////////// case LM_PROTECT: // protection opcode { assert(g_gameId != TIMEGATE); appendFormated("LM_PROTECT "); printf("LM_PROTECT\n"); //protection = 1; break; } //////////////////////////////////////////////////////////////////////// case LM_INVENTORY: // INVENTORY { appendFormated("LM_INVENTORY "); statusScreenAllowed = *(s16*)currentLifePtr; currentLifePtr += 2; break; } case LM_SET_INVENTORY: { appendFormated("LM_SET_INVENTORY "); //int inventoryIndex = *(s16*)(currentLifePtr); currentLifePtr += 2; /* if(indeventoyIndex != currentInHand) { if(currentInHand<2) { int i; for(i=0;i= lifeTempVar2) { currentLifePtr += 2; } else { lifeTempVar2 = *(s16*)(currentLifePtr); currentLifePtr += lifeTempVar2 * 2; currentLifePtr += 2; } break; } case LM_IF_SUP: { appendFormated("LM_IF_SUP "); lifeTempVar1 = evalVar(); lifeTempVar2 = evalVar(); if (lifeTempVar1 > lifeTempVar2) { currentLifePtr += 2; } else { lifeTempVar2 = *(s16*)(currentLifePtr); currentLifePtr += lifeTempVar2 * 2; currentLifePtr += 2; } break; } case LM_IF_INF_EGAL: { appendFormated("LM_IF_INF_EGAL "); lifeTempVar1 = evalVar(); lifeTempVar2 = evalVar(); if (lifeTempVar1 <= lifeTempVar2) { currentLifePtr += 2; } else { lifeTempVar2 = *(s16*)(currentLifePtr); currentLifePtr += lifeTempVar2 * 2; currentLifePtr += 2; } break; } case LM_IF_INF: { appendFormated("LM_IF_INF "); lifeTempVar1 = evalVar(); lifeTempVar2 = evalVar(); if (lifeTempVar1 < lifeTempVar2) { currentLifePtr += 2; } else { lifeTempVar2 = *(s16*)(currentLifePtr); currentLifePtr += lifeTempVar2 * 2; currentLifePtr += 2; } break; } case LM_GOTO: { appendFormated("LM_GOTO "); lifeTempVar1 = readNextArgument("Offset"); currentLifePtr += lifeTempVar1 * 2; break; } //////////////////////////////////////////////////////////////////////// case LM_SWITCH: // SWITCH { appendFormated("LM_SWITCH "); switchVal = evalVar("value"); break; } case LM_CASE: // CASE { appendFormated("LM_CASE "); lifeTempVar1 = readNextArgument("Case"); if (lifeTempVar1 == switchVal) { currentLifePtr += 2; } else { lifeTempVar2 = *(s16*)(currentLifePtr); currentLifePtr += lifeTempVar2 * 2; currentLifePtr += 2; } break; } case LM_MULTI_CASE: // MULTI_CASE { appendFormated("LM_MULTI_CASE "); int i; lifeTempVar1 = *(s16*)(currentLifePtr); currentLifePtr += 2; lifeTempVar2 = 0; for (i = 0; i < lifeTempVar1; i++) { if (*(s16*)(currentLifePtr) == switchVal) { lifeTempVar2 = 1; } currentLifePtr += 2; } if (!lifeTempVar2) { lifeTempVar2 = *(s16*)(currentLifePtr); currentLifePtr += lifeTempVar2 * 2; currentLifePtr += 2; } else { currentLifePtr += 2; } break; } //////////////////////////////////////////////////////////////////////// case LM_RETURN: { appendFormated("LM_RETURN "); exitLife = 1; break; } case LM_END: { appendFormated("LM_END "); exitLife = 1; break; } case LM_GAME_OVER: { appendFormated("LM_GAME_OVER "); fadeMusic(0, 0, 0x8000); // fade out music startChrono(&musicChrono); while (evalChrono(&musicChrono) < 120) { process_events(); } FlagGameOver = 1; exitLife = 1; break; } case LM_WAIT_GAME_OVER: { appendFormated("LM_WAIT_GAME_OVER "); while (key || JoyD || Click) { process_events(); } while (!key && !JoyD && Click) { process_events(); } FlagGameOver = 1; exitLife = 1; break; } case LM_CALL_INVENTORY: { appendFormated("LM_CALL_INVENTORY "); processInventory(); break; } case LM_DO_ROT_CLUT: // DO_ROT_CLUT { appendFormated("LM_DO_ROT_CLUT "); assert(g_gameId == TIMEGATE); int arg0 = readNextArgument(); int arg1 = readNextArgument(); int arg2 = readNextArgument(); break; } case LM_START_FADE_IN_MUSIC_LOOP: { appendFormated("LM_START_FADE_IN_MUSIC_LOOP "); assert(g_gameId == TIMEGATE); int arg0 = readNextArgument(); int arg1 = readNextArgument(); int arg2 = readNextArgument(); int arg3 = readNextArgument(); int arg4 = readNextArgument(); //int arg5 = readNextArgument(); break; } default: { printf("Unknown opcode %X in processLife\n", currentOpcode & 0x7FFF); assert(0); } } } #ifdef DEBUG if (strlen(currentDebugLifeLine)) { printf("%s\n", currentDebugLifeLine); } #endif if (var_6 != -1) { currentProcessedActorIdx = currentLifeActorIdx; currentProcessedActorPtr = currentLifeActorPtr; } } currentLifeNum = -1; }