From 316c300fd606ca73f9a2dcddbad355aba545e880 Mon Sep 17 00:00:00 2001 From: roblabla <1069318+roblabla@users.noreply.github.com> Date: Mon, 18 Nov 2024 20:11:10 +0000 Subject: [PATCH 01/14] Update mapping to latest ghidra changes --- config/mapping.csv | 58 +++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/config/mapping.csv b/config/mapping.csv index af2e6895..c4dc18ec 100644 --- a/config/mapping.csv +++ b/config/mapping.csv @@ -47,36 +47,36 @@ th06::EclManager::Load,0x407340,0xb2,__thiscall,,ZunResult,EclManager*,char* th06::EclManager::Unload,0x407400,0x32,__thiscall,,void,EclManager* th06::EclManager::CallEclSub,0x407440,0x54,__thiscall,,ZunResult,EclManager*,EnemyEclContext*,i16 th06::EclManager::RunEcl,0x4074a0,0x3504,__thiscall,,ZunResult,EclManager*,Enemy* -th06::Enemy::MoveDirTime,0x40abe0,0x123,default,,void,Enemy*,EclRawInstr* -th06::Enemy::MovePosTime,0x40ad10,0x166,default,,void,Enemy*,EclRawInstr* -th06::Enemy::MoveTime,0x40ae80,0x12c,default,,void,Enemy*,EclRawInstr* -th06::Enemy::GetVar,0x40afb0,0x36c,default,,i32*,Enemy*,EclVarId*,EclValueType* -th06::Enemy::GetVarFloat,0x40b380,0x40,default,,f32*,Enemy*,f32*,EclValueType* -th06::Enemy::SetVar,0x40b3c0,0x58,default,,void,Enemy*,EclVarId,void* -th06::Enemy::MathAdd,0x40b420,0xa1,default,,void,Enemy*,EclVarId,EclVarId*,EclVarId* -th06::Enemy::MathSub,0x40b4d0,0xa1,default,,void,Enemy*,EclVarId,EclVarId*,EclVarId* -th06::Enemy::MathMul,0x40b580,0xcc,default,,void,Enemy*,EclVarId,EclVarId*,EclVarId* -th06::Enemy::MathDiv,0x40b650,0xa4,default,,void,Enemy*,EclVarId,EclVarId*,EclVarId* -th06::Enemy::MathMod,0x40b700,0xca,default,,void,Enemy*,EclVarId,EclVarId*,EclVarId* -th06::Enemy::MathAtan2,0x40b7d0,0xbe,default,,void,Enemy*,EclVarId,f32*,f32*,f32*,f32* +th06::EnemyEclInstr::MoveDirTime,0x40abe0,0x123,default,,void,Enemy*,EclRawInstr* +th06::EnemyEclInstr::MovePosTime,0x40ad10,0x166,default,,void,Enemy*,EclRawInstr* +th06::EnemyEclInstr::MoveTime,0x40ae80,0x12c,default,,void,Enemy*,EclRawInstr* +th06::EnemyEclInstr::GetVar,0x40afb0,0x36c,default,,i32*,Enemy*,EclVarId*,EclValueType* +th06::EnemyEclInstr::GetVarFloat,0x40b380,0x40,default,,f32*,Enemy*,f32*,EclValueType* +th06::EnemyEclInstr::SetVar,0x40b3c0,0x58,default,,void,Enemy*,EclVarId,void* +th06::EnemyEclInstr::MathAdd,0x40b420,0xa1,default,,void,Enemy*,EclVarId,EclVarId*,EclVarId* +th06::EnemyEclInstr::MathSub,0x40b4d0,0xa1,default,,void,Enemy*,EclVarId,EclVarId*,EclVarId* +th06::EnemyEclInstr::MathMul,0x40b580,0xcc,default,,void,Enemy*,EclVarId,EclVarId*,EclVarId* +th06::EnemyEclInstr::MathDiv,0x40b650,0xa4,default,,void,Enemy*,EclVarId,EclVarId*,EclVarId* +th06::EnemyEclInstr::MathMod,0x40b700,0xca,default,,void,Enemy*,EclVarId,EclVarId*,EclVarId* +th06::EnemyEclInstr::MathAtan2,0x40b7d0,0xbe,default,,void,Enemy*,EclVarId,f32*,f32*,f32*,f32* D3DXVec3Length,0x40b890,0x4a,__stdcall,,f32,D3DXVECTOR3* -th06::Enemy::ExInsCirnoRainbowBallJank,0x40b8e0,0x19e,default,,void,Enemy*,EclRawInstr* -th06::Enemy::ExInsShootAtRandomArea,0x40ba80,0xf4,default,,void,Enemy*,EclRawInstr* -th06::Enemy::ExInsShootStarPattern,0x40bb80,0x574,default,,void,Enemy*,EclRawInstr* -th06::Enemy::ExInsPatchouliShottypeSetVars,0x40c100,0x75,default,,void,Enemy*,EclRawInstr* -th06::Enemy::ExInsStage56Func4,0x40c180,0x42a,default,,void,Enemy*,EclRawInstr* -th06::Enemy::ExInsStage5Func5,0x40c5b0,0x533,default,,void,Enemy*,EclRawInstr* -th06::Enemy::ExInsStage6XFunc6,0x40caf0,0x550,default,,void,Enemy*,EclRawInstr* -th06::Enemy::ExInsStage6Func7,0x40d040,0x3bb,default,,void,Enemy*,EclRawInstr* -th06::Enemy::ExInsStage6Func8,0x40d400,0x125,default,,void,Enemy*,EclRawInstr* -th06::Enemy::ExInsStage6Func9,0x40d530,0x238,default,,void,Enemy*,EclRawInstr* -th06::Enemy::ExInsStage6Func11,0x40d770,0x1b6,default,,void,Enemy*,EclRawInstr* -th06::Enemy::ExInsStage6XFunc10,0x40d930,0x164,default,,void,Enemy*,EclRawInstr* -th06::Enemy::ExInsStage4Func12,0x40daa0,0x114,default,,void,Enemy*,EclRawInstr* -th06::Enemy::ExInsStageXFunc13,0x40dbc0,0xf2,default,,void,Enemy*,EclRawInstr* -th06::Enemy::ExInsStageXFunc14,0x40dcc0,0x139,default,,void,Enemy*,EclRawInstr* -th06::Enemy::ExInsStageXFunc15,0x40de00,0x3ae,default,,void,Enemy*,EclRawInstr* -th06::Enemy::ExInsStageXFunc16,0x40e1b0,0x114,default,,void,Enemy*,EclRawInstr* +th06::EnemyEclInstr::ExInsCirnoRainbowBallJank,0x40b8e0,0x19e,default,,void,Enemy*,EclRawInstr* +th06::EnemyEclInstr::ExInsShootAtRandomArea,0x40ba80,0xf4,default,,void,Enemy*,EclRawInstr* +th06::EnemyEclInstr::ExInsShootStarPattern,0x40bb80,0x574,default,,void,Enemy*,EclRawInstr* +th06::EnemyEclInstr::ExInsPatchouliShottypeSetVars,0x40c100,0x75,default,,void,Enemy*,EclRawInstr* +th06::EnemyEclInstr::ExInsStage56Func4,0x40c180,0x42a,default,,void,Enemy*,EclRawInstr* +th06::EnemyEclInstr::ExInsStage5Func5,0x40c5b0,0x533,default,,void,Enemy*,EclRawInstr* +th06::EnemyEclInstr::ExInsStage6XFunc6,0x40caf0,0x550,default,,void,Enemy*,EclRawInstr* +th06::EnemyEclInstr::ExInsStage6Func7,0x40d040,0x3bb,default,,void,Enemy*,EclRawInstr* +th06::EnemyEclInstr::ExInsStage6Func8,0x40d400,0x125,default,,void,Enemy*,EclRawInstr* +th06::EnemyEclInstr::ExInsStage6Func9,0x40d530,0x238,default,,void,Enemy*,EclRawInstr* +th06::EnemyEclInstr::ExInsStage6Func11,0x40d770,0x1b6,default,,void,Enemy*,EclRawInstr* +th06::EnemyEclInstr::ExInsStage6XFunc10,0x40d930,0x164,default,,void,Enemy*,EclRawInstr* +th06::EnemyEclInstr::ExInsStage4Func12,0x40daa0,0x114,default,,void,Enemy*,EclRawInstr* +th06::EnemyEclInstr::ExInsStageXFunc13,0x40dbc0,0xf2,default,,void,Enemy*,EclRawInstr* +th06::EnemyEclInstr::ExInsStageXFunc14,0x40dcc0,0x139,default,,void,Enemy*,EclRawInstr* +th06::EnemyEclInstr::ExInsStageXFunc15,0x40de00,0x3ae,default,,void,Enemy*,EclRawInstr* +th06::EnemyEclInstr::ExInsStageXFunc16,0x40e1b0,0x114,default,,void,Enemy*,EclRawInstr* th06::EffectManager::EffectManager,0x40e2d0,0x65,__thiscall,,u32*,EffectManager* th06::EffectManager::Reset,0x40e340,0x19,__thiscall,,void,EffectManager* th06::EffectManager::EffectCallbackRandomSplash,0x40e360,0x24d,default,,i32,Effect* From 960da5d50299a3835beb884c09e12037638d6b81 Mon Sep 17 00:00:00 2001 From: roblabla Date: Sun, 17 Nov 2024 19:09:08 +0100 Subject: [PATCH 02/14] Reorder functions in Enemy --- src/Enemy.cpp | 118 +++++++++++++++++++++++++------------------------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/src/Enemy.cpp b/src/Enemy.cpp index d16827dd..a478c852 100644 --- a/src/Enemy.cpp +++ b/src/Enemy.cpp @@ -35,6 +35,65 @@ DIFFABLE_STATIC_ARRAY(f32, 6, g_StarAngleTable); DIFFABLE_STATIC(D3DXVECTOR3, g_EnemyPosVector); DIFFABLE_STATIC(D3DXVECTOR3, g_PlayerPosVector); +void Enemy::MoveDirTime(Enemy *enemy, EclRawInstr *instr) +{ + EclRawInstrAluArgs *alu; + f32 angle; + + alu = &instr->args.alu; + angle = *Enemy::GetVarFloat(enemy, &alu->arg1.f32, NULL); + + enemy->moveInterp.x = sinf(angle) * alu->arg2.f32 * alu->res / 2.0f; + enemy->moveInterp.y = cosf(angle) * alu->arg2.f32 * alu->res / 2.0f; + enemy->moveInterp.z = 0.0f; + + enemy->moveInterpStartPos = enemy->position; + enemy->moveInterpStartTime = alu->res; + + enemy->moveInterpTimer.SetCurrent(enemy->moveInterpStartTime); + + enemy->flags.unk1 = 2; +} + +void Enemy::MovePosTime(Enemy *enemy, EclRawInstr *instr) +{ + D3DXVECTOR3 newPos; + EclRawInstrAluArgs *alu = &instr->args.alu; + + newPos.x = *Enemy::GetVarFloat(enemy, &alu->arg1.f32, NULL); + newPos.y = *Enemy::GetVarFloat(enemy, &alu->arg2.f32, NULL); + newPos.z = *Enemy::GetVarFloat(enemy, &alu->arg3.f32, NULL); + + enemy->moveInterp = newPos - enemy->position; + enemy->moveInterpStartPos = enemy->position; + enemy->moveInterpStartTime = alu->res; + + enemy->moveInterpTimer.SetCurrent(enemy->moveInterpStartTime); + + enemy->flags.unk1 = 2; + enemy->axisSpeed = D3DXVECTOR3(0.0f, 0.0f, 0.0f); +} + +void Enemy::MoveTime(Enemy *enemy, EclRawInstr *instr) +{ + EclRawInstrAluArgs *alu; + f32 angle; + + alu = &instr->args.alu; + angle = *Enemy::GetVarFloat(enemy, &enemy->angle, NULL); + + enemy->moveInterp.x = sinf(angle) * enemy->speed * alu->res / 2.0f; + enemy->moveInterp.y = cosf(angle) * enemy->speed * alu->res / 2.0f; + enemy->moveInterp.z = 0.0f; + + enemy->moveInterpStartPos = enemy->position; + enemy->moveInterpStartTime = alu->res; + + enemy->moveInterpTimer.SetCurrent(enemy->moveInterpStartTime); + + enemy->flags.unk1 = 2; +} + i32 *Enemy::GetVar(Enemy *enemy, EclVarId *eclVarId, EclValueType *valueType) { if (valueType != NULL) @@ -349,65 +408,6 @@ void Enemy::MathAtan2(Enemy *enemy, EclVarId outVarId, f32 *x1, f32 *y1, f32 *y2 return; } -void Enemy::MoveTime(Enemy *enemy, EclRawInstr *instr) -{ - EclRawInstrAluArgs *alu; - f32 angle; - - alu = &instr->args.alu; - angle = *Enemy::GetVarFloat(enemy, &enemy->angle, NULL); - - enemy->moveInterp.x = sinf(angle) * enemy->speed * alu->res / 2.0f; - enemy->moveInterp.y = cosf(angle) * enemy->speed * alu->res / 2.0f; - enemy->moveInterp.z = 0.0f; - - enemy->moveInterpStartPos = enemy->position; - enemy->moveInterpStartTime = alu->res; - - enemy->moveInterpTimer.SetCurrent(enemy->moveInterpStartTime); - - enemy->flags.unk1 = 2; -} - -void Enemy::MovePosTime(Enemy *enemy, EclRawInstr *instr) -{ - D3DXVECTOR3 newPos; - EclRawInstrAluArgs *alu = &instr->args.alu; - - newPos.x = *Enemy::GetVarFloat(enemy, &alu->arg1.f32, NULL); - newPos.y = *Enemy::GetVarFloat(enemy, &alu->arg2.f32, NULL); - newPos.z = *Enemy::GetVarFloat(enemy, &alu->arg3.f32, NULL); - - enemy->moveInterp = newPos - enemy->position; - enemy->moveInterpStartPos = enemy->position; - enemy->moveInterpStartTime = alu->res; - - enemy->moveInterpTimer.SetCurrent(enemy->moveInterpStartTime); - - enemy->flags.unk1 = 2; - enemy->axisSpeed = D3DXVECTOR3(0.0f, 0.0f, 0.0f); -} - -void Enemy::MoveDirTime(Enemy *enemy, EclRawInstr *instr) -{ - EclRawInstrAluArgs *alu; - f32 angle; - - alu = &instr->args.alu; - angle = *Enemy::GetVarFloat(enemy, &alu->arg1.f32, NULL); - - enemy->moveInterp.x = sinf(angle) * alu->arg2.f32 * alu->res / 2.0f; - enemy->moveInterp.y = cosf(angle) * alu->arg2.f32 * alu->res / 2.0f; - enemy->moveInterp.z = 0.0f; - - enemy->moveInterpStartPos = enemy->position; - enemy->moveInterpStartTime = alu->res; - - enemy->moveInterpTimer.SetCurrent(enemy->moveInterpStartTime); - - enemy->flags.unk1 = 2; -} - void Enemy::Move() { if (!this->flags.unk4) From 9606c66d1cdd5259e943048fb8bc799fee8e8696 Mon Sep 17 00:00:00 2001 From: roblabla Date: Sun, 17 Nov 2024 23:08:33 +0100 Subject: [PATCH 03/14] Implement EffectManager::EffectManager --- config/implemented.csv | 1 + src/EffectManager.cpp | 15 ++++++++++----- src/EffectManager.hpp | 5 +++-- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/config/implemented.csv b/config/implemented.csv index 07b123ec..30e03425 100644 --- a/config/implemented.csv +++ b/config/implemented.csv @@ -101,6 +101,7 @@ th06::Ending::FadingEffect th06::Ending::LoadEnding th06::Ending::ReadEndFileParameter th06::Ending::ParseEndFile +th06::EffectManager::EffectManager th06::EffectManager::Reset th06::EffectManager::AddedCallback th06::EffectManager::DeletedCallback diff --git a/src/EffectManager.cpp b/src/EffectManager.cpp index a92b8983..b2af9921 100644 --- a/src/EffectManager.cpp +++ b/src/EffectManager.cpp @@ -38,6 +38,11 @@ DIFFABLE_STATIC_ARRAY_ASSIGN(EffectInfo, 20, g_Effects) = { {ANM_SCRIPT_BULLET4_SCRIPT_19, EffectManager::EffectCallbackStill}, }; +EffectManager::EffectManager() +{ + this->Reset(); +} + ZunResult EffectManager::RegisterChain() { EffectManager *mgr = &g_EffectManager; @@ -141,7 +146,7 @@ ChainCallbackResult EffectManager::OnUpdate(EffectManager *mgr) effect = &mgr->effects[0]; mgr->activeEffects = 0; - for (effectIdx = 0; effectIdx < ARRAY_SIZE_SIGNED(mgr->effects); effectIdx++, effect++) + for (effectIdx = 0; effectIdx < ARRAY_SIZE_SIGNED(mgr->effects) - 1; effectIdx++, effect++) { if (effect->inUseFlag == 0) { @@ -171,7 +176,7 @@ ChainCallbackResult EffectManager::OnDraw(EffectManager *mgr) Effect *effect; effect = &mgr->effects[0]; - for (effectIdx = 0; effectIdx < ARRAY_SIZE_SIGNED(mgr->effects); effectIdx++, effect++) + for (effectIdx = 0; effectIdx < ARRAY_SIZE_SIGNED(mgr->effects) - 1; effectIdx++, effect++) { if (effect->inUseFlag == 0) { @@ -192,10 +197,10 @@ Effect *EffectManager::SpawnParticles(i32 effectIdx, D3DXVECTOR3 *pos, i32 count Effect *effect; effect = &this->effects[this->nextIndex]; - for (idx = 0; idx < ARRAY_SIZE_SIGNED(this->effects); idx++) + for (idx = 0; idx < ARRAY_SIZE_SIGNED(this->effects) - 1; idx++) { this->nextIndex++; - if (this->nextIndex >= ARRAY_SIZE_SIGNED(this->effects)) + if (this->nextIndex >= ARRAY_SIZE_SIGNED(this->effects) - 1) { this->nextIndex = 0; } @@ -238,7 +243,7 @@ Effect *EffectManager::SpawnParticles(i32 effectIdx, D3DXVECTOR3 *pos, i32 count } } - return idx >= ARRAY_SIZE_SIGNED(this->effects) ? &this->dummyEffect : effect; + return idx >= ARRAY_SIZE_SIGNED(this->effects) - 1 ? &this->effects[512] : effect; } i32 EffectManager::EffectCallbackRandomSplash(Effect *effect) diff --git a/src/EffectManager.hpp b/src/EffectManager.hpp index 60c85497..9f673239 100644 --- a/src/EffectManager.hpp +++ b/src/EffectManager.hpp @@ -36,8 +36,9 @@ struct EffectManager { i32 nextIndex; i32 activeEffects; - Effect effects[512]; - Effect dummyEffect; + Effect effects[513]; + + EffectManager(); static ZunResult RegisterChain(); static void CutChain(); From 7b298ec78c7414b75812cd205eb7922d7063113d Mon Sep 17 00:00:00 2001 From: roblabla Date: Sun, 17 Nov 2024 23:08:56 +0100 Subject: [PATCH 04/14] Shuffle around Enemy/EnemyManager functions to match original --- src/Enemy.cpp | 208 ------------- src/EnemyManager.cpp | 726 ++++++++++++++++++++++++++++--------------- 2 files changed, 467 insertions(+), 467 deletions(-) diff --git a/src/Enemy.cpp b/src/Enemy.cpp index a478c852..e68a2b17 100644 --- a/src/Enemy.cpp +++ b/src/Enemy.cpp @@ -408,214 +408,6 @@ void Enemy::MathAtan2(Enemy *enemy, EclVarId outVarId, f32 *x1, f32 *y1, f32 *y2 return; } -void Enemy::Move() -{ - if (!this->flags.unk4) - { - this->position.x += g_Supervisor.effectiveFramerateMultiplier * this->axisSpeed.x; - } - else - { - this->position.x -= g_Supervisor.effectiveFramerateMultiplier * this->axisSpeed.x; - } - this->position.y += g_Supervisor.effectiveFramerateMultiplier * this->axisSpeed.y; - this->position.z += g_Supervisor.effectiveFramerateMultiplier * this->axisSpeed.z; -} - -void Enemy::ClampPos() -{ - if (this->flags.shouldClampPos) - { - if (this->position.x < this->lowerMoveLimit.x) - { - this->position.x = this->lowerMoveLimit.x; - } - else if (this->position.x > this->upperMoveLimit.x) - { - this->position.x = this->upperMoveLimit.x; - } - - if (this->position.y < this->lowerMoveLimit.y) - { - this->position.y = this->lowerMoveLimit.y; - } - else if (this->position.y > this->upperMoveLimit.y) - { - this->position.y = this->upperMoveLimit.y; - } - } -} - -#pragma var_order(curEnemy, i) -ZunBool Enemy::HandleLifeCallback() -{ - - i32 i; - Enemy *curEnemy; - - if (this->life < this->lifeCallbackThreshold) - { - this->life = this->lifeCallbackThreshold; - g_EclManager.CallEclSub(&this->currentContext, this->lifeCallbackSub); - this->lifeCallbackThreshold = -1; - this->timerCallbackSub = this->deathCallbackSub; - this->bulletRankSpeedLow = -0.5f; - this->bulletRankSpeedHigh = 0.5f; - this->bulletRankAmount1Low = 0; - this->bulletRankAmount1High = 0; - this->bulletRankAmount2Low = 0; - this->bulletRankAmount2High = 0; - this->stackDepth = 0; - - curEnemy = g_EnemyManager.enemies; - for (i = 0; i < ARRAY_SIZE_SIGNED(g_EnemyManager.enemies); i++, curEnemy++) - { - if (!curEnemy->flags.unk5) - { - continue; - } - if (curEnemy->flags.isBoss) - { - continue; - } - curEnemy->life = 0; - - if (!curEnemy->flags.unk6 && curEnemy->deathCallbackSub >= 0) - { - g_EclManager.CallEclSub(&curEnemy->currentContext, curEnemy->deathCallbackSub); - curEnemy->deathCallbackSub = -1; - } - } - return true; - } - - return false; -} - -#pragma var_order(curEnemy, i) -ZunBool Enemy::HandleTimerCallback() -{ - - Enemy *curEnemy; - i32 i; - - if (this->flags.isBoss) - { - g_Gui.SetSpellcardSeconds((this->timerCallbackThreshold - this->bossTimer.AsFrames()) / 60); - } - - if (this->HasBossTimerFinished()) - { - if (this->lifeCallbackThreshold > 0) - { - this->life = this->lifeCallbackThreshold; - this->lifeCallbackThreshold = -1; - } - g_EclManager.CallEclSub(&this->currentContext, this->timerCallbackSub); - this->timerCallbackThreshold = -1; - this->timerCallbackSub = this->deathCallbackSub; - this->bossTimer.InitializeForPopup(); - if (!this->flags.unk16) - { - g_EnemyManager.spellcardInfo.isCapturing = false; - if (g_EnemyManager.spellcardInfo.isActive) - { - g_EnemyManager.spellcardInfo.isActive++; - } - g_BulletManager.RemoveAllBullets(0); - } - - curEnemy = g_EnemyManager.enemies; - for (i = 0; i < ARRAY_SIZE_SIGNED(g_EnemyManager.enemies); i++, curEnemy++) - { - if (!curEnemy->flags.unk5) - { - continue; - } - if (curEnemy->flags.isBoss) - { - continue; - } - curEnemy->life = 0; - - if (!curEnemy->flags.unk6 && curEnemy->deathCallbackSub >= 0) - { - g_EclManager.CallEclSub(&curEnemy->currentContext, curEnemy->deathCallbackSub); - curEnemy->deathCallbackSub = -1; - } - } - this->bulletRankSpeedLow = -0.5f; - this->bulletRankSpeedHigh = 0.5f; - this->bulletRankAmount1Low = 0; - this->bulletRankAmount1High = 0; - this->bulletRankAmount2Low = 0; - this->bulletRankAmount2High = 0; - this->stackDepth = 0; - return true; - } - return false; -} - -void Enemy::Despawn() -{ - if (!this->flags.unk11) - { - this->flags.unk5 = 0; - } - else - { - this->flags.unk6 = 0; - } - if (this->flags.isBoss) - { - g_Gui.bossPresent = false; - } - if (this->effectIdx != 0) - { - this->ResetEffectArray(this); - } -} - -void Enemy::ResetEffectArray(Enemy *enemy) -{ - i32 idx; - - for (idx = 0; idx < enemy->effectIdx; idx++) - { - if (!enemy->effectArray[idx]) - { - continue; - } - enemy->effectArray[idx]->unk_17a = 1; - enemy->effectArray[idx] = NULL; - } - enemy->effectIdx = 0; -} - -#pragma var_order(effect, i) -void Enemy::UpdateEffects(Enemy *enemy) -{ - Effect *effect; - i32 i; - - for (i = 0; i < enemy->effectIdx; i++) - { - effect = enemy->effectArray[i]; - if (!effect) - { - continue; - } - - effect->position = enemy->position; - if (effect->unk_15c < enemy->effectDistance) - { - effect->unk_15c += 0.3f; - } - - effect->angleRelated = utils::AddNormalizeAngle(effect->angleRelated, ZUN_PI / 100); - } -} - #pragma var_order(i, currentBullet, effectIndex, velocityVector, bulletTimer, accelerationMultiplier, accelerationAngle) void Enemy::ExInsCirnoRainbowBallJank(Enemy *enemy, EclRawInstr *instr) { diff --git a/src/EnemyManager.cpp b/src/EnemyManager.cpp index 5cb91940..b89a821e 100644 --- a/src/EnemyManager.cpp +++ b/src/EnemyManager.cpp @@ -83,6 +83,407 @@ void EnemyManager::Initialize() enemy->bulletRankSpeedHigh = 0.5f; } +Enemy *EnemyManager::SpawnEnemy(i32 eclSubId, D3DXVECTOR3 *pos, i16 life, i16 itemDrop, i32 score) +{ + Enemy *newEnemy; + i32 idx; + + newEnemy = this->enemies; + idx = 0; + for (; idx < ARRAY_SIZE_SIGNED(this->enemies); idx++, newEnemy++) + { + if (newEnemy->flags.unk5) + continue; + + *newEnemy = this->enemyTemplate; + + if (0 <= life) + newEnemy->life = life; + + newEnemy->position = *pos; + g_EclManager.CallEclSub(&newEnemy->currentContext, eclSubId); + g_EclManager.RunEcl(newEnemy); + newEnemy->color = newEnemy->primaryVm.color; + newEnemy->itemDrop = itemDrop; + + if (0 <= life) + newEnemy->life = life; + + if (0 <= score) + newEnemy->score = score; + + newEnemy->maxLife = newEnemy->life; + break; + } + return newEnemy; +} + +void Enemy::ResetEffectArray(Enemy *enemy) +{ + i32 idx; + + for (idx = 0; idx < enemy->effectIdx; idx++) + { + if (!enemy->effectArray[idx]) + { + continue; + } + enemy->effectArray[idx]->unk_17a = 1; + enemy->effectArray[idx] = NULL; + } + enemy->effectIdx = 0; +} + +#pragma var_order(spawnedEnemy, subrankIncreaseFrame, args1, args2, args3, pos1, pos2, args4, pos3, pos4) +void EnemyManager::RunEclTimeline() +{ + D3DXVECTOR3 pos4; + D3DXVECTOR3 pos3; + D3DXVECTOR3 pos2; + D3DXVECTOR3 pos1; + EclTimelineInstrArgs *args4; + EclTimelineInstrArgs *args3; + EclTimelineInstrArgs *args2; + EclTimelineInstrArgs *args1; + i32 subrankIncreaseFrame; + Enemy *spawnedEnemy; + + if (this->timelineInstr == NULL) + { + this->timelineInstr = g_EclManager.timeline; + } + if (g_Gui.HasCurrentMsgIdx() == 0) + { + // Unclear what this is? It looks like it increases the subrank at + // regular intervals, where the interval is made shorter based on the + // number of lives lost? + subrankIncreaseFrame = 10 * 4 * 60; + subrankIncreaseFrame -= g_GameManager.livesRemaining * 4 * 60; + if (this->timelineTime.HasTicked() && this->timelineTime.AsFrames() % subrankIncreaseFrame == 0) + { + g_GameManager.IncreaseSubrank(100); + } + } + while (0 <= this->timelineInstr->time) + { + if ((ZunBool)(this->timelineTime.current == this->timelineInstr->time)) + { + switch (this->timelineInstr->opCode) + { + case 0: + if (!g_Gui.BossPresent()) + { + args1 = &this->timelineInstr->args; + this->SpawnEnemy(this->timelineInstr->arg0, args1->Var1AsVec(), args1->ushortVar1, + args1->ushortVar2, args1->uintVar4); + } + break; + case 1: + if (!g_Gui.BossPresent()) + { + this->SpawnEnemy(this->timelineInstr->arg0, this->timelineInstr->args.Var1AsVec(), -1, ITEM_NO_ITEM, + -1); + } + break; + case 2: + if (!g_Gui.BossPresent()) + { + args2 = &this->timelineInstr->args; + spawnedEnemy = this->SpawnEnemy(this->timelineInstr->arg0, args2->Var1AsVec(), args2->ushortVar1, + args2->ushortVar2, args2->uintVar4); + spawnedEnemy->flags.unk4 = 1; + } + break; + case 3: + if (!g_Gui.BossPresent()) + { + spawnedEnemy = this->SpawnEnemy(this->timelineInstr->arg0, this->timelineInstr->args.Var1AsVec(), + -1, ITEM_NO_ITEM, -1); + spawnedEnemy->flags.unk4 = 1; + } + break; + case 4: + if (!g_Gui.BossPresent()) + { + args3 = &this->timelineInstr->args; + pos1 = *args3->Var1AsVec(); + if (args3->Var1AsVec()->x <= -990.0f) + { + pos1.x = g_Rng.GetRandomF32InRange(g_GameManager.playerMovementAreaSize.x); + } + if (args3->Var1AsVec()->y <= -990.0f) + { + pos1.y = g_Rng.GetRandomF32InRange(g_GameManager.playerMovementAreaSize.y); + } + if (args3->Var1AsVec()->z <= -990.0f) + { + pos1.z = g_Rng.GetRandomF32InRange(800.0f); + } + this->SpawnEnemy(this->timelineInstr->arg0, &pos1, args3->ushortVar1, args3->ushortVar2, + args3->uintVar4); + } + break; + case 5: + if (!g_Gui.BossPresent()) + { + pos2 = *this->timelineInstr->args.Var1AsVec(); + if (pos2.x <= -990.0f) + { + pos2.x = g_Rng.GetRandomF32InRange(g_GameManager.playerMovementAreaSize.x); + } + if (pos2.y <= -990.0f) + { + pos2.y = g_Rng.GetRandomF32InRange(g_GameManager.playerMovementAreaSize.y); + } + if (pos2.z <= -990.0f) + { + pos2.z = g_Rng.GetRandomF32InRange(800.0f); + } + this->SpawnEnemy(this->timelineInstr->arg0, &pos2, -1, ITEM_NO_ITEM, -1); + } + break; + case 6: + if (!g_Gui.BossPresent()) + { + args4 = &this->timelineInstr->args; + pos3 = *args4->Var1AsVec(); + if (args4->Var1AsVec()->x <= -990.0f) + { + pos3.x = g_Rng.GetRandomF32InRange(g_GameManager.playerMovementAreaSize.x); + } + if (args4->Var1AsVec()->y <= -990.0f) + { + pos3.y = g_Rng.GetRandomF32InRange(g_GameManager.playerMovementAreaSize.y); + } + if (args4->Var1AsVec()->z <= -990.0f) + { + pos3.z = g_Rng.GetRandomF32InRange(800.0f); + } + spawnedEnemy = this->SpawnEnemy(this->timelineInstr->arg0, &pos3, args4->ushortVar1, + args4->ushortVar2, args4->uintVar4); + spawnedEnemy->flags.unk4 = 1; + } + break; + case 7: + if (!g_Gui.BossPresent()) + { + pos4 = *this->timelineInstr->args.Var1AsVec(); + if (pos4.x <= -990.0f) + { + pos4.x = g_Rng.GetRandomF32InRange(g_GameManager.playerMovementAreaSize.x); + } + if (pos4.y <= -990.0f) + { + pos4.y = g_Rng.GetRandomF32InRange(g_GameManager.playerMovementAreaSize.y); + } + if (pos4.z <= -990.0f) + { + pos4.z = g_Rng.GetRandomF32InRange(800.0f); + } + spawnedEnemy = this->SpawnEnemy(this->timelineInstr->arg0, &pos4, -1, ITEM_NO_ITEM, -1); + spawnedEnemy->flags.unk4 = 1; + } + break; + case 8: + if (g_GameManager.difficulty == EASY && g_GameManager.currentStage == 5 && + this->timelineInstr->arg0 == 1) + { + g_Gui.MsgRead(g_GameManager.character * 10 + 3); + } + else + { + g_Gui.MsgRead(this->timelineInstr->arg0 + g_GameManager.character * 10); + } + break; + case 9: + if (g_Gui.MsgWait()) + { + this->timelineTime.Decrement(1); + return; + } + break; + case 10: + this->bosses[this->timelineInstr->args.uintVar1]->runInterrupt = this->timelineInstr->args.uintVar2; + break; + case 0xb: + g_GameManager.currentPower = this->timelineInstr->arg0; + break; + case 0xc: + if (this->bosses[this->timelineInstr->arg0] != NULL && + this->bosses[this->timelineInstr->arg0]->flags.unk5) + { + this->timelineTime.Decrement(1); + return; + } + } + } + else if ((ZunBool)(this->timelineTime.current < this->timelineInstr->time)) + { + break; + } + this->timelineInstr = (EclTimelineInstr *)((i32)this->timelineInstr + this->timelineInstr->size); + } + if (!g_Gui.HasCurrentMsgIdx()) + { + g_GameManager.counat++; + } + return; +} + +#pragma var_order(curEnemy, i) +ZunBool Enemy::HandleLifeCallback() +{ + + i32 i; + Enemy *curEnemy; + + if (this->life < this->lifeCallbackThreshold) + { + this->life = this->lifeCallbackThreshold; + g_EclManager.CallEclSub(&this->currentContext, this->lifeCallbackSub); + this->lifeCallbackThreshold = -1; + this->timerCallbackSub = this->deathCallbackSub; + this->bulletRankSpeedLow = -0.5f; + this->bulletRankSpeedHigh = 0.5f; + this->bulletRankAmount1Low = 0; + this->bulletRankAmount1High = 0; + this->bulletRankAmount2Low = 0; + this->bulletRankAmount2High = 0; + this->stackDepth = 0; + + curEnemy = g_EnemyManager.enemies; + for (i = 0; i < ARRAY_SIZE_SIGNED(g_EnemyManager.enemies); i++, curEnemy++) + { + if (!curEnemy->flags.unk5) + { + continue; + } + if (curEnemy->flags.isBoss) + { + continue; + } + curEnemy->life = 0; + + if (!curEnemy->flags.unk6 && curEnemy->deathCallbackSub >= 0) + { + g_EclManager.CallEclSub(&curEnemy->currentContext, curEnemy->deathCallbackSub); + curEnemy->deathCallbackSub = -1; + } + } + return true; + } + + return false; +} + +#pragma var_order(curEnemy, i) +ZunBool Enemy::HandleTimerCallback() +{ + + Enemy *curEnemy; + i32 i; + + if (this->flags.isBoss) + { + g_Gui.SetSpellcardSeconds((this->timerCallbackThreshold - this->bossTimer.AsFrames()) / 60); + } + + if (this->HasBossTimerFinished()) + { + if (this->lifeCallbackThreshold > 0) + { + this->life = this->lifeCallbackThreshold; + this->lifeCallbackThreshold = -1; + } + g_EclManager.CallEclSub(&this->currentContext, this->timerCallbackSub); + this->timerCallbackThreshold = -1; + this->timerCallbackSub = this->deathCallbackSub; + this->bossTimer.InitializeForPopup(); + if (!this->flags.unk16) + { + g_EnemyManager.spellcardInfo.isCapturing = false; + if (g_EnemyManager.spellcardInfo.isActive) + { + g_EnemyManager.spellcardInfo.isActive++; + } + g_BulletManager.RemoveAllBullets(0); + } + + curEnemy = g_EnemyManager.enemies; + for (i = 0; i < ARRAY_SIZE_SIGNED(g_EnemyManager.enemies); i++, curEnemy++) + { + if (!curEnemy->flags.unk5) + { + continue; + } + if (curEnemy->flags.isBoss) + { + continue; + } + curEnemy->life = 0; + + if (!curEnemy->flags.unk6 && curEnemy->deathCallbackSub >= 0) + { + g_EclManager.CallEclSub(&curEnemy->currentContext, curEnemy->deathCallbackSub); + curEnemy->deathCallbackSub = -1; + } + } + this->bulletRankSpeedLow = -0.5f; + this->bulletRankSpeedHigh = 0.5f; + this->bulletRankAmount1Low = 0; + this->bulletRankAmount1High = 0; + this->bulletRankAmount2Low = 0; + this->bulletRankAmount2High = 0; + this->stackDepth = 0; + return true; + } + return false; +} + +void Enemy::Despawn() +{ + if (!this->flags.unk11) + { + this->flags.unk5 = 0; + } + else + { + this->flags.unk6 = 0; + } + if (this->flags.isBoss) + { + g_Gui.bossPresent = false; + } + if (this->effectIdx != 0) + { + this->ResetEffectArray(this); + } +} + +void Enemy::ClampPos() +{ + if (this->flags.shouldClampPos) + { + if (this->position.x < this->lowerMoveLimit.x) + { + this->position.x = this->lowerMoveLimit.x; + } + else if (this->position.x > this->upperMoveLimit.x) + { + this->position.x = this->upperMoveLimit.x; + } + + if (this->position.y < this->lowerMoveLimit.y) + { + this->position.y = this->lowerMoveLimit.y; + } + else if (this->position.y > this->upperMoveLimit.y) + { + this->position.y = this->upperMoveLimit.y; + } + } +} + ZunResult EnemyManager::RegisterChain(char *stgEnm1, char *stgEnm2) { EnemyManager *mgr = &g_EnemyManager; @@ -110,44 +511,6 @@ ZunResult EnemyManager::RegisterChain(char *stgEnm1, char *stgEnm2) return ZUN_SUCCESS; } -void EnemyManager::CutChain() -{ - g_Chain.Cut(&g_EnemyManagerCalcChain); - g_Chain.Cut(&g_EnemyManagerDrawChain); - return; -} - -ZunResult EnemyManager::AddedCallback(EnemyManager *enemyManager) -{ - Enemy *enemies = enemyManager->enemies; - - if (enemyManager->stgEnmAnmFilename && - g_AnmManager->LoadAnm(ANM_FILE_ENEMY, enemyManager->stgEnmAnmFilename, ANM_OFFSET_ENEMY) != ZUN_SUCCESS) - { - return ZUN_ERROR; - } - if (enemyManager->stgEnm2AnmFilename && - g_AnmManager->LoadAnm(ANM_FILE_ENEMY2, enemyManager->stgEnm2AnmFilename, ANM_OFFSET_ENEMY) != ZUN_SUCCESS) - { - return ZUN_ERROR; - } - - enemyManager->randomItemSpawnIndex = g_Rng.GetRandomU16InRange(ITEM_SPAWNS); - enemyManager->randomItemTableIndex = g_Rng.GetRandomU16InRange(ITEM_TABLES); - - enemyManager->spellcardInfo.isActive = 0; - enemyManager->timelineInstr = NULL; - - return ZUN_SUCCESS; -} - -ZunResult EnemyManager::DeletedCallback(EnemyManager *mgr) -{ - g_AnmManager->ReleaseAnm(ANM_FILE_ENEMY2); - g_AnmManager->ReleaseAnm(ANM_FILE_ENEMY); - return ZUN_SUCCESS; -} - #pragma var_order(local_8, damage, enemyIdx, enemyHitbox, enemyVmIdx, enemyLifeBeforeDmg, curEnemy) ChainCallbackResult EnemyManager::OnUpdate(EnemyManager *mgr) { @@ -363,14 +726,38 @@ ChainCallbackResult EnemyManager::OnUpdate(EnemyManager *mgr) curEnemy->primaryVm.flags.colorOp = AnmVmColorOp_Modulate; } } - Enemy::UpdateEffects(curEnemy); - if (g_GameManager.isTimeStopped == 0) + Enemy::UpdateEffects(curEnemy); + if (g_GameManager.isTimeStopped == 0) + { + curEnemy->bossTimer.Tick(); + } + } + mgr->timelineTime.Tick(); + return CHAIN_CALLBACK_RESULT_CONTINUE; +} + +#pragma var_order(effect, i) +void Enemy::UpdateEffects(Enemy *enemy) +{ + Effect *effect; + i32 i; + + for (i = 0; i < enemy->effectIdx; i++) + { + effect = enemy->effectArray[i]; + if (!effect) + { + continue; + } + + effect->position = enemy->position; + if (effect->unk_15c < enemy->effectDistance) { - curEnemy->bossTimer.Tick(); + effect->unk_15c += 0.3f; } + + effect->angleRelated = utils::AddNormalizeAngle(effect->angleRelated, ZUN_PI / 100); } - mgr->timelineTime.Tick(); - return CHAIN_CALLBACK_RESULT_CONTINUE; } #pragma var_order(curEnemyIdx, curEnemyVm, curEnemyVmIdx, curEnemy) @@ -430,234 +817,55 @@ ChainCallbackResult EnemyManager::OnDraw(EnemyManager *mgr) return CHAIN_CALLBACK_RESULT_CONTINUE; } -#pragma var_order(spawnedEnemy, subrankIncreaseFrame, args1, args2, args3, pos1, pos2, args4, pos3, pos4) -void EnemyManager::RunEclTimeline() +ZunResult EnemyManager::AddedCallback(EnemyManager *enemyManager) { - D3DXVECTOR3 pos4; - D3DXVECTOR3 pos3; - D3DXVECTOR3 pos2; - D3DXVECTOR3 pos1; - EclTimelineInstrArgs *args4; - EclTimelineInstrArgs *args3; - EclTimelineInstrArgs *args2; - EclTimelineInstrArgs *args1; - i32 subrankIncreaseFrame; - Enemy *spawnedEnemy; + Enemy *enemies = enemyManager->enemies; - if (this->timelineInstr == NULL) - { - this->timelineInstr = g_EclManager.timeline; - } - if (g_Gui.HasCurrentMsgIdx() == 0) - { - // Unclear what this is? It looks like it increases the subrank at - // regular intervals, where the interval is made shorter based on the - // number of lives lost? - subrankIncreaseFrame = 10 * 4 * 60; - subrankIncreaseFrame -= g_GameManager.livesRemaining * 4 * 60; - if (this->timelineTime.HasTicked() && this->timelineTime.AsFrames() % subrankIncreaseFrame == 0) - { - g_GameManager.IncreaseSubrank(100); - } - } - while (0 <= this->timelineInstr->time) + if (enemyManager->stgEnmAnmFilename && + g_AnmManager->LoadAnm(ANM_FILE_ENEMY, enemyManager->stgEnmAnmFilename, ANM_OFFSET_ENEMY) != ZUN_SUCCESS) { - if ((ZunBool)(this->timelineTime.current == this->timelineInstr->time)) - { - switch (this->timelineInstr->opCode) - { - case 0: - if (!g_Gui.BossPresent()) - { - args1 = &this->timelineInstr->args; - this->SpawnEnemy(this->timelineInstr->arg0, args1->Var1AsVec(), args1->ushortVar1, - args1->ushortVar2, args1->uintVar4); - } - break; - case 1: - if (!g_Gui.BossPresent()) - { - this->SpawnEnemy(this->timelineInstr->arg0, this->timelineInstr->args.Var1AsVec(), -1, ITEM_NO_ITEM, - -1); - } - break; - case 2: - if (!g_Gui.BossPresent()) - { - args2 = &this->timelineInstr->args; - spawnedEnemy = this->SpawnEnemy(this->timelineInstr->arg0, args2->Var1AsVec(), args2->ushortVar1, - args2->ushortVar2, args2->uintVar4); - spawnedEnemy->flags.unk4 = 1; - } - break; - case 3: - if (!g_Gui.BossPresent()) - { - spawnedEnemy = this->SpawnEnemy(this->timelineInstr->arg0, this->timelineInstr->args.Var1AsVec(), - -1, ITEM_NO_ITEM, -1); - spawnedEnemy->flags.unk4 = 1; - } - break; - case 4: - if (!g_Gui.BossPresent()) - { - args3 = &this->timelineInstr->args; - pos1 = *args3->Var1AsVec(); - if (args3->Var1AsVec()->x <= -990.0f) - { - pos1.x = g_Rng.GetRandomF32InRange(g_GameManager.playerMovementAreaSize.x); - } - if (args3->Var1AsVec()->y <= -990.0f) - { - pos1.y = g_Rng.GetRandomF32InRange(g_GameManager.playerMovementAreaSize.y); - } - if (args3->Var1AsVec()->z <= -990.0f) - { - pos1.z = g_Rng.GetRandomF32InRange(800.0f); - } - this->SpawnEnemy(this->timelineInstr->arg0, &pos1, args3->ushortVar1, args3->ushortVar2, - args3->uintVar4); - } - break; - case 5: - if (!g_Gui.BossPresent()) - { - pos2 = *this->timelineInstr->args.Var1AsVec(); - if (pos2.x <= -990.0f) - { - pos2.x = g_Rng.GetRandomF32InRange(g_GameManager.playerMovementAreaSize.x); - } - if (pos2.y <= -990.0f) - { - pos2.y = g_Rng.GetRandomF32InRange(g_GameManager.playerMovementAreaSize.y); - } - if (pos2.z <= -990.0f) - { - pos2.z = g_Rng.GetRandomF32InRange(800.0f); - } - this->SpawnEnemy(this->timelineInstr->arg0, &pos2, -1, ITEM_NO_ITEM, -1); - } - break; - case 6: - if (!g_Gui.BossPresent()) - { - args4 = &this->timelineInstr->args; - pos3 = *args4->Var1AsVec(); - if (args4->Var1AsVec()->x <= -990.0f) - { - pos3.x = g_Rng.GetRandomF32InRange(g_GameManager.playerMovementAreaSize.x); - } - if (args4->Var1AsVec()->y <= -990.0f) - { - pos3.y = g_Rng.GetRandomF32InRange(g_GameManager.playerMovementAreaSize.y); - } - if (args4->Var1AsVec()->z <= -990.0f) - { - pos3.z = g_Rng.GetRandomF32InRange(800.0f); - } - spawnedEnemy = this->SpawnEnemy(this->timelineInstr->arg0, &pos3, args4->ushortVar1, - args4->ushortVar2, args4->uintVar4); - spawnedEnemy->flags.unk4 = 1; - } - break; - case 7: - if (!g_Gui.BossPresent()) - { - pos4 = *this->timelineInstr->args.Var1AsVec(); - if (pos4.x <= -990.0f) - { - pos4.x = g_Rng.GetRandomF32InRange(g_GameManager.playerMovementAreaSize.x); - } - if (pos4.y <= -990.0f) - { - pos4.y = g_Rng.GetRandomF32InRange(g_GameManager.playerMovementAreaSize.y); - } - if (pos4.z <= -990.0f) - { - pos4.z = g_Rng.GetRandomF32InRange(800.0f); - } - spawnedEnemy = this->SpawnEnemy(this->timelineInstr->arg0, &pos4, -1, ITEM_NO_ITEM, -1); - spawnedEnemy->flags.unk4 = 1; - } - break; - case 8: - if (g_GameManager.difficulty == EASY && g_GameManager.currentStage == 5 && - this->timelineInstr->arg0 == 1) - { - g_Gui.MsgRead(g_GameManager.character * 10 + 3); - } - else - { - g_Gui.MsgRead(this->timelineInstr->arg0 + g_GameManager.character * 10); - } - break; - case 9: - if (g_Gui.MsgWait()) - { - this->timelineTime.Decrement(1); - return; - } - break; - case 10: - this->bosses[this->timelineInstr->args.uintVar1]->runInterrupt = this->timelineInstr->args.uintVar2; - break; - case 0xb: - g_GameManager.currentPower = this->timelineInstr->arg0; - break; - case 0xc: - if (this->bosses[this->timelineInstr->arg0] != NULL && - this->bosses[this->timelineInstr->arg0]->flags.unk5) - { - this->timelineTime.Decrement(1); - return; - } - } - } - else if ((ZunBool)(this->timelineTime.current < this->timelineInstr->time)) - { - break; - } - this->timelineInstr = (EclTimelineInstr *)((i32)this->timelineInstr + this->timelineInstr->size); + return ZUN_ERROR; } - if (!g_Gui.HasCurrentMsgIdx()) + if (enemyManager->stgEnm2AnmFilename && + g_AnmManager->LoadAnm(ANM_FILE_ENEMY2, enemyManager->stgEnm2AnmFilename, ANM_OFFSET_ENEMY) != ZUN_SUCCESS) { - g_GameManager.counat++; + return ZUN_ERROR; } - return; -} - -Enemy *EnemyManager::SpawnEnemy(i32 eclSubId, D3DXVECTOR3 *pos, i16 life, i16 itemDrop, i32 score) -{ - Enemy *newEnemy; - i32 idx; - - newEnemy = this->enemies; - idx = 0; - for (; idx < ARRAY_SIZE_SIGNED(this->enemies); idx++, newEnemy++) - { - if (newEnemy->flags.unk5) - continue; - *newEnemy = this->enemyTemplate; + enemyManager->randomItemSpawnIndex = g_Rng.GetRandomU16InRange(ITEM_SPAWNS); + enemyManager->randomItemTableIndex = g_Rng.GetRandomU16InRange(ITEM_TABLES); - if (0 <= life) - newEnemy->life = life; + enemyManager->spellcardInfo.isActive = 0; + enemyManager->timelineInstr = NULL; - newEnemy->position = *pos; - g_EclManager.CallEclSub(&newEnemy->currentContext, eclSubId); - g_EclManager.RunEcl(newEnemy); - newEnemy->color = newEnemy->primaryVm.color; - newEnemy->itemDrop = itemDrop; + return ZUN_SUCCESS; +} - if (0 <= life) - newEnemy->life = life; +ZunResult EnemyManager::DeletedCallback(EnemyManager *mgr) +{ + g_AnmManager->ReleaseAnm(ANM_FILE_ENEMY2); + g_AnmManager->ReleaseAnm(ANM_FILE_ENEMY); + return ZUN_SUCCESS; +} - if (0 <= score) - newEnemy->score = score; +void EnemyManager::CutChain() +{ + g_Chain.Cut(&g_EnemyManagerCalcChain); + g_Chain.Cut(&g_EnemyManagerDrawChain); + return; +} - newEnemy->maxLife = newEnemy->life; - break; +void Enemy::Move() +{ + if (!this->flags.unk4) + { + this->position.x += g_Supervisor.effectiveFramerateMultiplier * this->axisSpeed.x; } - return newEnemy; + else + { + this->position.x -= g_Supervisor.effectiveFramerateMultiplier * this->axisSpeed.x; + } + this->position.y += g_Supervisor.effectiveFramerateMultiplier * this->axisSpeed.y; + this->position.z += g_Supervisor.effectiveFramerateMultiplier * this->axisSpeed.z; } }; // namespace th06 From fedc0ddc5a447092d60eae96f64088e9d1115941 Mon Sep 17 00:00:00 2001 From: roblabla Date: Sun, 17 Nov 2024 23:13:52 +0100 Subject: [PATCH 05/14] Fix effectmanager calling wrong function in deletedCallback --- src/EffectManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EffectManager.cpp b/src/EffectManager.cpp index b2af9921..8ca69a19 100644 --- a/src/EffectManager.cpp +++ b/src/EffectManager.cpp @@ -52,7 +52,7 @@ ZunResult EffectManager::RegisterChain() g_EffectManagerCalcChain.addedCallback = NULL; g_EffectManagerCalcChain.deletedCallback = NULL; g_EffectManagerCalcChain.addedCallback = (ChainAddedCallback)mgr->AddedCallback; - g_EffectManagerCalcChain.deletedCallback = (ChainAddedCallback)mgr->AddedCallback; + g_EffectManagerCalcChain.deletedCallback = (ChainAddedCallback)mgr->DeletedCallback; g_EffectManagerCalcChain.arg = mgr; if (g_Chain.AddToCalcChain(&g_EffectManagerCalcChain, TH_CHAIN_PRIO_CALC_EFFECTMANAGER)) From 8ca9218630bfb168efb10401cb8c6a78999ceb4b Mon Sep 17 00:00:00 2001 From: roblabla Date: Sun, 17 Nov 2024 23:14:58 +0100 Subject: [PATCH 06/14] Reorder EffectManager functions --- src/EffectManager.cpp | 395 +++++++++++++++++++++--------------------- 1 file changed, 197 insertions(+), 198 deletions(-) diff --git a/src/EffectManager.cpp b/src/EffectManager.cpp index 8ca69a19..9017ac3a 100644 --- a/src/EffectManager.cpp +++ b/src/EffectManager.cpp @@ -43,209 +43,11 @@ EffectManager::EffectManager() this->Reset(); } -ZunResult EffectManager::RegisterChain() -{ - EffectManager *mgr = &g_EffectManager; - mgr->Reset(); - - g_EffectManagerCalcChain.callback = (ChainCallback)mgr->OnUpdate; - g_EffectManagerCalcChain.addedCallback = NULL; - g_EffectManagerCalcChain.deletedCallback = NULL; - g_EffectManagerCalcChain.addedCallback = (ChainAddedCallback)mgr->AddedCallback; - g_EffectManagerCalcChain.deletedCallback = (ChainAddedCallback)mgr->DeletedCallback; - g_EffectManagerCalcChain.arg = mgr; - - if (g_Chain.AddToCalcChain(&g_EffectManagerCalcChain, TH_CHAIN_PRIO_CALC_EFFECTMANAGER)) - { - return ZUN_ERROR; - } - - g_EffectManagerDrawChain.callback = (ChainCallback)mgr->OnDraw; - g_EffectManagerDrawChain.addedCallback = NULL; - g_EffectManagerDrawChain.deletedCallback = NULL; - g_EffectManagerDrawChain.arg = mgr; - g_Chain.AddToDrawChain(&g_EffectManagerDrawChain, TH_CHAIN_PRIO_DRAW_EFFECTMANAGER); - - return ZUN_SUCCESS; -} - -void EffectManager::CutChain() -{ - g_Chain.Cut(&g_EffectManagerCalcChain); - g_Chain.Cut(&g_EffectManagerDrawChain); -} - -ZunResult EffectManager::AddedCallback(EffectManager *mgr) -{ - mgr->Reset(); - switch (g_GameManager.currentStage) - { - case 0: - case 1: - if (g_AnmManager->LoadAnm(ANM_FILE_EFFECTS, "data/eff01.anm", ANM_OFFSET_EFFECTS) != ZUN_SUCCESS) - { - return ZUN_ERROR; - } - break; - case 2: - if (g_AnmManager->LoadAnm(ANM_FILE_EFFECTS, "data/eff02.anm", ANM_OFFSET_EFFECTS) != ZUN_SUCCESS) - { - return ZUN_ERROR; - } - break; - case 3: - if (g_AnmManager->LoadAnm(ANM_FILE_EFFECTS, "data/eff03.anm", ANM_OFFSET_EFFECTS) != ZUN_SUCCESS) - { - return ZUN_ERROR; - } - break; - case 4: - if (g_AnmManager->LoadAnm(ANM_FILE_EFFECTS, "data/eff04.anm", ANM_OFFSET_EFFECTS) != ZUN_SUCCESS) - { - return ZUN_ERROR; - } - break; - case 5: - if (g_AnmManager->LoadAnm(ANM_FILE_EFFECTS, "data/eff05.anm", ANM_OFFSET_EFFECTS) != ZUN_SUCCESS) - { - return ZUN_ERROR; - } - break; - case 6: - if (g_AnmManager->LoadAnm(ANM_FILE_EFFECTS, "data/eff06.anm", ANM_OFFSET_EFFECTS) != ZUN_SUCCESS) - { - return ZUN_ERROR; - } - break; - case 7: - if (g_AnmManager->LoadAnm(ANM_FILE_EFFECTS, "data/eff07.anm", ANM_OFFSET_EFFECTS) != ZUN_SUCCESS) - { - return ZUN_ERROR; - } - break; - } - return ZUN_SUCCESS; -} - -ZunResult EffectManager::DeletedCallback(EffectManager *p) -{ - g_AnmManager->ReleaseAnm(ANM_FILE_EFFECTS); - - return ZUN_SUCCESS; -} - void EffectManager::Reset() { memset(this, 0, sizeof(*this)); } -ChainCallbackResult EffectManager::OnUpdate(EffectManager *mgr) -{ - i32 effectIdx; - Effect *effect; - - effect = &mgr->effects[0]; - mgr->activeEffects = 0; - for (effectIdx = 0; effectIdx < ARRAY_SIZE_SIGNED(mgr->effects) - 1; effectIdx++, effect++) - { - if (effect->inUseFlag == 0) - { - continue; - } - - mgr->activeEffects++; - if (effect->updateCallback != NULL && (effect->updateCallback)(effect) != EFFECT_CALLBACK_RESULT_DONE) - { - effect->inUseFlag = 0; - } - - if (g_AnmManager->ExecuteScript(&effect->vm) != 0) - { - effect->inUseFlag = 0; - } - - effect->timer.Tick(); - } - - return CHAIN_CALLBACK_RESULT_CONTINUE; -} - -ChainCallbackResult EffectManager::OnDraw(EffectManager *mgr) -{ - int effectIdx; - Effect *effect; - - effect = &mgr->effects[0]; - for (effectIdx = 0; effectIdx < ARRAY_SIZE_SIGNED(mgr->effects) - 1; effectIdx++, effect++) - { - if (effect->inUseFlag == 0) - { - continue; - } - - effect->vm.pos = effect->pos1; - g_AnmManager->Draw3(&effect->vm); - } - - return CHAIN_CALLBACK_RESULT_CONTINUE; -} - -#pragma var_order(effect, idx) -Effect *EffectManager::SpawnParticles(i32 effectIdx, D3DXVECTOR3 *pos, i32 count, ZunColor color) -{ - i32 idx; - Effect *effect; - - effect = &this->effects[this->nextIndex]; - for (idx = 0; idx < ARRAY_SIZE_SIGNED(this->effects) - 1; idx++) - { - this->nextIndex++; - if (this->nextIndex >= ARRAY_SIZE_SIGNED(this->effects) - 1) - { - this->nextIndex = 0; - } - if (effect->inUseFlag) - { - if (this->nextIndex == 0) - { - effect = &this->effects[0]; - } - else - { - effect++; - } - continue; - } - - effect->inUseFlag = 1; - effect->effectId = effectIdx; - effect->pos1 = *pos; - - g_AnmManager->SetAndExecuteScriptIdx(&effect->vm, g_Effects[effectIdx].anmIdx); - - effect->vm.color = color; - effect->updateCallback = g_Effects[effectIdx].updateCallback; - effect->timer.InitializeForPopup(); - effect->unk_17a = 0; - effect->unk_17b = 0; - count--; - - if (count == 0) - break; - - if (this->nextIndex == 0) - { - effect = &this->effects[0]; - } - else - { - effect++; - } - } - - return idx >= ARRAY_SIZE_SIGNED(this->effects) - 1 ? &this->effects[512] : effect; -} - i32 EffectManager::EffectCallbackRandomSplash(Effect *effect) { if (effect->timer == 0 && effect->timer.HasTicked()) @@ -389,4 +191,201 @@ i32 EffectManager::EffectCallbackAttractSlow(Effect *effect) return EFFECT_CALLBACK_RESULT_DONE; } +#pragma var_order(effect, idx) +Effect *EffectManager::SpawnParticles(i32 effectIdx, D3DXVECTOR3 *pos, i32 count, ZunColor color) +{ + i32 idx; + Effect *effect; + + effect = &this->effects[this->nextIndex]; + for (idx = 0; idx < ARRAY_SIZE_SIGNED(this->effects) - 1; idx++) + { + this->nextIndex++; + if (this->nextIndex >= ARRAY_SIZE_SIGNED(this->effects) - 1) + { + this->nextIndex = 0; + } + if (effect->inUseFlag) + { + if (this->nextIndex == 0) + { + effect = &this->effects[0]; + } + else + { + effect++; + } + continue; + } + + effect->inUseFlag = 1; + effect->effectId = effectIdx; + effect->pos1 = *pos; + + g_AnmManager->SetAndExecuteScriptIdx(&effect->vm, g_Effects[effectIdx].anmIdx); + + effect->vm.color = color; + effect->updateCallback = g_Effects[effectIdx].updateCallback; + effect->timer.InitializeForPopup(); + effect->unk_17a = 0; + effect->unk_17b = 0; + count--; + + if (count == 0) + break; + + if (this->nextIndex == 0) + { + effect = &this->effects[0]; + } + else + { + effect++; + } + } + + return idx >= ARRAY_SIZE_SIGNED(this->effects) - 1 ? &this->effects[512] : effect; +} + +ChainCallbackResult EffectManager::OnUpdate(EffectManager *mgr) +{ + i32 effectIdx; + Effect *effect; + + effect = &mgr->effects[0]; + mgr->activeEffects = 0; + for (effectIdx = 0; effectIdx < ARRAY_SIZE_SIGNED(mgr->effects) - 1; effectIdx++, effect++) + { + if (effect->inUseFlag == 0) + { + continue; + } + + mgr->activeEffects++; + if (effect->updateCallback != NULL && (effect->updateCallback)(effect) != EFFECT_CALLBACK_RESULT_DONE) + { + effect->inUseFlag = 0; + } + + if (g_AnmManager->ExecuteScript(&effect->vm) != 0) + { + effect->inUseFlag = 0; + } + + effect->timer.Tick(); + } + + return CHAIN_CALLBACK_RESULT_CONTINUE; +} + +ChainCallbackResult EffectManager::OnDraw(EffectManager *mgr) +{ + int effectIdx; + Effect *effect; + + effect = &mgr->effects[0]; + for (effectIdx = 0; effectIdx < ARRAY_SIZE_SIGNED(mgr->effects) - 1; effectIdx++, effect++) + { + if (effect->inUseFlag == 0) + { + continue; + } + + effect->vm.pos = effect->pos1; + g_AnmManager->Draw3(&effect->vm); + } + + return CHAIN_CALLBACK_RESULT_CONTINUE; +} + +ZunResult EffectManager::AddedCallback(EffectManager *mgr) +{ + mgr->Reset(); + switch (g_GameManager.currentStage) + { + case 0: + case 1: + if (g_AnmManager->LoadAnm(ANM_FILE_EFFECTS, "data/eff01.anm", ANM_OFFSET_EFFECTS) != ZUN_SUCCESS) + { + return ZUN_ERROR; + } + break; + case 2: + if (g_AnmManager->LoadAnm(ANM_FILE_EFFECTS, "data/eff02.anm", ANM_OFFSET_EFFECTS) != ZUN_SUCCESS) + { + return ZUN_ERROR; + } + break; + case 3: + if (g_AnmManager->LoadAnm(ANM_FILE_EFFECTS, "data/eff03.anm", ANM_OFFSET_EFFECTS) != ZUN_SUCCESS) + { + return ZUN_ERROR; + } + break; + case 4: + if (g_AnmManager->LoadAnm(ANM_FILE_EFFECTS, "data/eff04.anm", ANM_OFFSET_EFFECTS) != ZUN_SUCCESS) + { + return ZUN_ERROR; + } + break; + case 5: + if (g_AnmManager->LoadAnm(ANM_FILE_EFFECTS, "data/eff05.anm", ANM_OFFSET_EFFECTS) != ZUN_SUCCESS) + { + return ZUN_ERROR; + } + break; + case 6: + if (g_AnmManager->LoadAnm(ANM_FILE_EFFECTS, "data/eff06.anm", ANM_OFFSET_EFFECTS) != ZUN_SUCCESS) + { + return ZUN_ERROR; + } + break; + case 7: + if (g_AnmManager->LoadAnm(ANM_FILE_EFFECTS, "data/eff07.anm", ANM_OFFSET_EFFECTS) != ZUN_SUCCESS) + { + return ZUN_ERROR; + } + break; + } + return ZUN_SUCCESS; +} + +ZunResult EffectManager::DeletedCallback(EffectManager *p) +{ + g_AnmManager->ReleaseAnm(ANM_FILE_EFFECTS); + + return ZUN_SUCCESS; +} + +ZunResult EffectManager::RegisterChain() +{ + EffectManager *mgr = &g_EffectManager; + mgr->Reset(); + + g_EffectManagerCalcChain.callback = (ChainCallback)mgr->OnUpdate; + g_EffectManagerCalcChain.addedCallback = NULL; + g_EffectManagerCalcChain.deletedCallback = NULL; + g_EffectManagerCalcChain.addedCallback = (ChainAddedCallback)mgr->AddedCallback; + g_EffectManagerCalcChain.deletedCallback = (ChainAddedCallback)mgr->DeletedCallback; + g_EffectManagerCalcChain.arg = mgr; + + if (g_Chain.AddToCalcChain(&g_EffectManagerCalcChain, TH_CHAIN_PRIO_CALC_EFFECTMANAGER)) + { + return ZUN_ERROR; + } + + g_EffectManagerDrawChain.callback = (ChainCallback)mgr->OnDraw; + g_EffectManagerDrawChain.addedCallback = NULL; + g_EffectManagerDrawChain.deletedCallback = NULL; + g_EffectManagerDrawChain.arg = mgr; + g_Chain.AddToDrawChain(&g_EffectManagerDrawChain, TH_CHAIN_PRIO_DRAW_EFFECTMANAGER); + + return ZUN_SUCCESS; +} + +void EffectManager::CutChain() +{ + g_Chain.Cut(&g_EffectManagerCalcChain); + g_Chain.Cut(&g_EffectManagerDrawChain); +} }; // namespace th06 From b627857b6dc46b5487a0439838ad27c027cc3418 Mon Sep 17 00:00:00 2001 From: roblabla Date: Sun, 17 Nov 2024 23:21:46 +0100 Subject: [PATCH 07/14] Fix function ordering in EclManager --- src/EclManager.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/EclManager.cpp b/src/EclManager.cpp index b692681e..1d49a2e0 100644 --- a/src/EclManager.cpp +++ b/src/EclManager.cpp @@ -54,6 +54,16 @@ ZunResult EclManager::Load(char *eclPath) return ZUN_SUCCESS; } +void EclManager::Unload() +{ + if (eclFile != NULL) + { + free(eclFile); + } + eclFile = NULL; + return; +} + ZunResult EclManager::CallEclSub(EnemyEclContext *ctx, i16 subId) { ctx->currentInstr = this->subTable[subId]; @@ -1021,14 +1031,4 @@ ZunResult EclManager::RunEcl(Enemy *enemy) } } } - -void EclManager::Unload() -{ - if (eclFile != NULL) - { - free(eclFile); - } - eclFile = NULL; - return; -} }; // namespace th06 From a12236dce05a384c36928b4283e74e90cf8f5e0f Mon Sep 17 00:00:00 2001 From: roblabla Date: Sun, 17 Nov 2024 23:26:08 +0100 Subject: [PATCH 08/14] Improve accuracy of EclManager::Unload --- src/EclManager.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/EclManager.cpp b/src/EclManager.cpp index 1d49a2e0..02851094 100644 --- a/src/EclManager.cpp +++ b/src/EclManager.cpp @@ -56,11 +56,14 @@ ZunResult EclManager::Load(char *eclPath) void EclManager::Unload() { - if (eclFile != NULL) + EclRawHeader *file; + + if (this->eclFile != NULL) { - free(eclFile); + file = this->eclFile; + free(file); } - eclFile = NULL; + this->eclFile = NULL; return; } From 4d8e7324c1e953518f0dea3495048894a3cabc45 Mon Sep 17 00:00:00 2001 From: roblabla Date: Sun, 17 Nov 2024 23:32:43 +0100 Subject: [PATCH 09/14] Reorder ending functions --- src/Ending.cpp | 478 ++++++++++++++++++++++++------------------------- 1 file changed, 238 insertions(+), 240 deletions(-) diff --git a/src/Ending.cpp b/src/Ending.cpp index 0927351e..a9319b5f 100644 --- a/src/Ending.cpp +++ b/src/Ending.cpp @@ -14,206 +14,20 @@ namespace th06 { - -Ending::Ending() -{ - i32 unused[4]; - - memset(this, 0, sizeof(Ending)); - this->line2Delay = 8; - this->timer2.InitializeForPopup(); - this->timer1.InitializeForPopup(); - this->backgroundPos.x = 0.0f; - this->backgroundPos.y = 0.0f; - this->backgroundScrollSpeed = 0.0f; -} - -ZunResult Ending::RegisterChain() -{ - Ending *ending; - - ending = new Ending(); - ending->calcChain = g_Chain.CreateElem((ChainCallback)Ending::OnUpdate); - ending->calcChain->arg = ending; - ending->calcChain->addedCallback = (ChainAddedCallback)Ending::AddedCallback; - ending->calcChain->deletedCallback = (ChainDeletedCallback)Ending::DeletedCallback; - if (g_Chain.AddToCalcChain(ending->calcChain, TH_CHAIN_PRIO_CALC_ENDING)) - { - return ZUN_ERROR; - } - - ending->drawChain = g_Chain.CreateElem((ChainCallback)Ending::OnDraw); - ending->drawChain->arg = ending; - g_Chain.AddToDrawChain(ending->drawChain, TH_CHAIN_PRIO_DRAW_ENDING); - - return ZUN_SUCCESS; -} - -#pragma var_order(unused, shotTypeAndCharacter) -ZunResult Ending::AddedCallback(Ending *ending) -{ - i32 shotTypeAndCharacter; - i32 unused; - - unused = g_GameManager.character * 2 + g_GameManager.shotType; - - g_GameManager.isGameCompleted = true; - g_Supervisor.isInEnding = true; - g_Supervisor.LoadPbg3(ED_PBG3_INDEX, TH_ED_DAT_FILE); - g_AnmManager->LoadAnm(ANM_FILE_STAFF01, "data/staff01.anm", ANM_OFFSET_STAFF01); - g_AnmManager->LoadAnm(ANM_FILE_STAFF02, "data/staff02.anm", ANM_OFFSET_STAFF02); - g_AnmManager->LoadAnm(ANM_FILE_STAFF03, "data/staff03.anm", ANM_OFFSET_STAFF03); - - g_AnmManager->SetCurrentTexture(NULL); - g_AnmManager->SetCurrentSprite(NULL); - g_AnmManager->SetCurrentBlendMode(0xff); - g_AnmManager->SetCurrentVertexShader(0xff); - - shotTypeAndCharacter = g_GameManager.character * 2 + g_GameManager.shotType; - ending->hasSeenEnding = false; - if (g_GameManager.numRetries == 0) - { - if (g_GameManager.clrd[shotTypeAndCharacter].difficultyClearedWithRetries[g_GameManager.difficulty] == 99) - { - ending->hasSeenEnding = true; - } - - g_GameManager.clrd[shotTypeAndCharacter].difficultyClearedWithRetries[g_GameManager.difficulty] = 99; - } - else - { - if (g_GameManager.clrd[shotTypeAndCharacter].difficultyClearedWithoutRetries[g_GameManager.difficulty] == 99) - { - ending->hasSeenEnding = true; - } - } - g_GameManager.clrd[shotTypeAndCharacter].difficultyClearedWithoutRetries[g_GameManager.difficulty] = 99; - if (g_GameManager.difficulty == EASY || g_GameManager.numRetries != 0) - { - switch (g_GameManager.character) - { - case CHARA_REIMU: - if (ending->LoadEnding("data/end00b.end") != ZUN_SUCCESS) - { - return ZUN_ERROR; - } - break; - case CHARA_MARISA: - if (ending->LoadEnding("data/end10b.end") != ZUN_SUCCESS) - { - return ZUN_ERROR; - } - break; - } - } - else - { - switch (g_GameManager.character) - { - case CHARA_REIMU: - if (g_GameManager.shotType == SHOT_TYPE_A) - { - if (ending->LoadEnding("data/end00.end") != ZUN_SUCCESS) - { - return ZUN_ERROR; - } - } - else - { - if (ending->LoadEnding("data/end01.end") != ZUN_SUCCESS) - { - return ZUN_ERROR; - } - } - break; - case CHARA_MARISA: - if (g_GameManager.shotType == SHOT_TYPE_A) - { - if (ending->LoadEnding("data/end10.end") != ZUN_SUCCESS) - { - return ZUN_ERROR; - } - } - else - { - if (ending->LoadEnding("data/end11.end") != ZUN_SUCCESS) - { - return ZUN_ERROR; - } - } - break; - } - } - return ZUN_SUCCESS; -} - -ZunResult Ending::DeletedCallback(Ending *ending) -{ - g_AnmManager->ReleaseAnm(ANM_FILE_STAFF01); - g_AnmManager->ReleaseAnm(ANM_FILE_STAFF02); - g_AnmManager->ReleaseAnm(ANM_FILE_STAFF03); - - g_Supervisor.curState = SUPERVISOR_STATE_RESULTSCREEN_FROMGAME; - - g_AnmManager->ReleaseSurface(0); - - // This has the same effect as doing "delete ending->endFileData" since delete just calls free, but for some reason, - // in both ways, the stack doesn't match with the other variable used in delete ending, in theory this should should - // be correct since ending->endFileData was allocated with malloc. One way to solve it, would be to do the same with - // ending, and align both variables with var_order, but that would be "incorrect", weird... - char *endfiledata = ending->endFileData; - free(endfiledata); - - g_Chain.Cut(ending->drawChain); - ending->drawChain = NULL; - - delete ending; - ending = NULL; - - g_Supervisor.isInEnding = false; - g_Supervisor.ReleasePbg3(ED_PBG3_INDEX); - return ZUN_SUCCESS; -} - -ZunResult Ending::LoadEnding(char *endFilePath) +i32 Ending::ReadEndFileParameter() { - char *endFileDat; + i32 readResult; - endFileDat = this->endFileData; - this->endFileData = (char *)FileSystem::OpenPath(endFilePath, false); - if (this->endFileData == NULL) - { - GameErrorContext::Log(&g_GameErrorContext, TH_ERR_ENDING_END_FILE_CORRUPTED); - return ZUN_ERROR; - } - else + readResult = atol(this->endFileDataPtr); + while (this->endFileDataPtr[0] != '\0') { - this->endFileDataPtr = this->endFileData; - this->line2Delay = 8; - this->timer2.InitializeForPopup(); - this->timer1.InitializeForPopup(); - if (endFileDat != NULL) - { - free(endFileDat); - } - return ZUN_SUCCESS; + this->endFileDataPtr++; } -} - -ChainCallbackResult Ending::OnDraw(Ending *ending) -{ - i32 idx; - - g_AnmManager->DrawEndingRect(0, 0, 0, ending->backgroundPos.x, ending->backgroundPos.y, 640, 480); - for (idx = 0; idx < ARRAY_SIZE_SIGNED(ending->sprites); idx++) + while (this->endFileDataPtr[0] == '\0') { - if (ending->sprites[idx].anmFileIndex != 0) - { - g_AnmManager->DrawNoRotation(&ending->sprites[idx]); - } + this->endFileDataPtr++; } - ending->FadingEffect(); - return CHAIN_CALLBACK_RESULT_CONTINUE; + return readResult; } #pragma var_order(endingRect, color) @@ -293,51 +107,6 @@ void Ending::FadingEffect() } } -#pragma var_order(framesPressed, idx) -ChainCallbackResult Ending::OnUpdate(Ending *ending) -{ - i32 idx; - i32 framesPressed; - - for (framesPressed = 0;;) - { - if (ending->ParseEndFile() != ZUN_SUCCESS) - { - return CHAIN_CALLBACK_RESULT_CONTINUE_AND_REMOVE_JOB; - } - for (idx = 0; idx < ARRAY_SIZE_SIGNED(ending->sprites); idx++) - { - if (ending->sprites[idx].anmFileIndex != 0) - { - g_AnmManager->ExecuteScript(&ending->sprites[idx]); - } - } - if (ending->hasSeenEnding && IS_PRESSED(TH_BUTTON_SKIP) && framesPressed < 4) - { - framesPressed++; - continue; - } - break; - }; - return CHAIN_CALLBACK_RESULT_CONTINUE; -} - -i32 Ending::ReadEndFileParameter() -{ - i32 readResult; - - readResult = atol(this->endFileDataPtr); - while (this->endFileDataPtr[0] != '\0') - { - this->endFileDataPtr++; - } - while (this->endFileDataPtr[0] == '\0') - { - this->endFileDataPtr++; - } - return readResult; -} - #pragma var_order(lineDisplayed, textBuffer, charactersReaded, anmScriptIdx, vmIndex, anmSpriteIdx, scrollBGDistance, \ scrollBGDuration, characterIdx, diffIdx, spriteIdx, musicFadeFrames, fill) ZunResult Ending::ParseEndFile() @@ -657,4 +426,233 @@ ZunResult Ending::ParseEndFile() return ZUN_SUCCESS; } -}; // namespace th06 \ No newline at end of file +ZunResult Ending::LoadEnding(char *endFilePath) +{ + char *endFileDat; + + endFileDat = this->endFileData; + this->endFileData = (char *)FileSystem::OpenPath(endFilePath, false); + if (this->endFileData == NULL) + { + GameErrorContext::Log(&g_GameErrorContext, TH_ERR_ENDING_END_FILE_CORRUPTED); + return ZUN_ERROR; + } + else + { + this->endFileDataPtr = this->endFileData; + this->line2Delay = 8; + this->timer2.InitializeForPopup(); + this->timer1.InitializeForPopup(); + if (endFileDat != NULL) + { + free(endFileDat); + } + return ZUN_SUCCESS; + } +} + +ZunResult Ending::RegisterChain() +{ + Ending *ending; + + ending = new Ending(); + ending->calcChain = g_Chain.CreateElem((ChainCallback)Ending::OnUpdate); + ending->calcChain->arg = ending; + ending->calcChain->addedCallback = (ChainAddedCallback)Ending::AddedCallback; + ending->calcChain->deletedCallback = (ChainDeletedCallback)Ending::DeletedCallback; + if (g_Chain.AddToCalcChain(ending->calcChain, TH_CHAIN_PRIO_CALC_ENDING)) + { + return ZUN_ERROR; + } + + ending->drawChain = g_Chain.CreateElem((ChainCallback)Ending::OnDraw); + ending->drawChain->arg = ending; + g_Chain.AddToDrawChain(ending->drawChain, TH_CHAIN_PRIO_DRAW_ENDING); + + return ZUN_SUCCESS; +} + +Ending::Ending() +{ + i32 unused[4]; + + memset(this, 0, sizeof(Ending)); + this->line2Delay = 8; + this->timer2.InitializeForPopup(); + this->timer1.InitializeForPopup(); + this->backgroundPos.x = 0.0f; + this->backgroundPos.y = 0.0f; + this->backgroundScrollSpeed = 0.0f; +} + +#pragma var_order(framesPressed, idx) +ChainCallbackResult Ending::OnUpdate(Ending *ending) +{ + i32 idx; + i32 framesPressed; + + for (framesPressed = 0;;) + { + if (ending->ParseEndFile() != ZUN_SUCCESS) + { + return CHAIN_CALLBACK_RESULT_CONTINUE_AND_REMOVE_JOB; + } + for (idx = 0; idx < ARRAY_SIZE_SIGNED(ending->sprites); idx++) + { + if (ending->sprites[idx].anmFileIndex != 0) + { + g_AnmManager->ExecuteScript(&ending->sprites[idx]); + } + } + if (ending->hasSeenEnding && IS_PRESSED(TH_BUTTON_SKIP) && framesPressed < 4) + { + framesPressed++; + continue; + } + break; + }; + return CHAIN_CALLBACK_RESULT_CONTINUE; +} + +ChainCallbackResult Ending::OnDraw(Ending *ending) +{ + i32 idx; + + g_AnmManager->DrawEndingRect(0, 0, 0, ending->backgroundPos.x, ending->backgroundPos.y, 640, 480); + for (idx = 0; idx < ARRAY_SIZE_SIGNED(ending->sprites); idx++) + { + if (ending->sprites[idx].anmFileIndex != 0) + { + g_AnmManager->DrawNoRotation(&ending->sprites[idx]); + } + } + ending->FadingEffect(); + return CHAIN_CALLBACK_RESULT_CONTINUE; +} + +#pragma var_order(unused, shotTypeAndCharacter) +ZunResult Ending::AddedCallback(Ending *ending) +{ + i32 shotTypeAndCharacter; + i32 unused; + + unused = g_GameManager.character * 2 + g_GameManager.shotType; + + g_GameManager.isGameCompleted = true; + g_Supervisor.isInEnding = true; + g_Supervisor.LoadPbg3(ED_PBG3_INDEX, TH_ED_DAT_FILE); + g_AnmManager->LoadAnm(ANM_FILE_STAFF01, "data/staff01.anm", ANM_OFFSET_STAFF01); + g_AnmManager->LoadAnm(ANM_FILE_STAFF02, "data/staff02.anm", ANM_OFFSET_STAFF02); + g_AnmManager->LoadAnm(ANM_FILE_STAFF03, "data/staff03.anm", ANM_OFFSET_STAFF03); + + g_AnmManager->SetCurrentTexture(NULL); + g_AnmManager->SetCurrentSprite(NULL); + g_AnmManager->SetCurrentBlendMode(0xff); + g_AnmManager->SetCurrentVertexShader(0xff); + + shotTypeAndCharacter = g_GameManager.character * 2 + g_GameManager.shotType; + ending->hasSeenEnding = false; + if (g_GameManager.numRetries == 0) + { + if (g_GameManager.clrd[shotTypeAndCharacter].difficultyClearedWithRetries[g_GameManager.difficulty] == 99) + { + ending->hasSeenEnding = true; + } + + g_GameManager.clrd[shotTypeAndCharacter].difficultyClearedWithRetries[g_GameManager.difficulty] = 99; + } + else + { + if (g_GameManager.clrd[shotTypeAndCharacter].difficultyClearedWithoutRetries[g_GameManager.difficulty] == 99) + { + ending->hasSeenEnding = true; + } + } + g_GameManager.clrd[shotTypeAndCharacter].difficultyClearedWithoutRetries[g_GameManager.difficulty] = 99; + if (g_GameManager.difficulty == EASY || g_GameManager.numRetries != 0) + { + switch (g_GameManager.character) + { + case CHARA_REIMU: + if (ending->LoadEnding("data/end00b.end") != ZUN_SUCCESS) + { + return ZUN_ERROR; + } + break; + case CHARA_MARISA: + if (ending->LoadEnding("data/end10b.end") != ZUN_SUCCESS) + { + return ZUN_ERROR; + } + break; + } + } + else + { + switch (g_GameManager.character) + { + case CHARA_REIMU: + if (g_GameManager.shotType == SHOT_TYPE_A) + { + if (ending->LoadEnding("data/end00.end") != ZUN_SUCCESS) + { + return ZUN_ERROR; + } + } + else + { + if (ending->LoadEnding("data/end01.end") != ZUN_SUCCESS) + { + return ZUN_ERROR; + } + } + break; + case CHARA_MARISA: + if (g_GameManager.shotType == SHOT_TYPE_A) + { + if (ending->LoadEnding("data/end10.end") != ZUN_SUCCESS) + { + return ZUN_ERROR; + } + } + else + { + if (ending->LoadEnding("data/end11.end") != ZUN_SUCCESS) + { + return ZUN_ERROR; + } + } + break; + } + } + return ZUN_SUCCESS; +} + +ZunResult Ending::DeletedCallback(Ending *ending) +{ + g_AnmManager->ReleaseAnm(ANM_FILE_STAFF01); + g_AnmManager->ReleaseAnm(ANM_FILE_STAFF02); + g_AnmManager->ReleaseAnm(ANM_FILE_STAFF03); + + g_Supervisor.curState = SUPERVISOR_STATE_RESULTSCREEN_FROMGAME; + + g_AnmManager->ReleaseSurface(0); + + // This has the same effect as doing "delete ending->endFileData" since delete just calls free, but for some reason, + // in both ways, the stack doesn't match with the other variable used in delete ending, in theory this should should + // be correct since ending->endFileData was allocated with malloc. One way to solve it, would be to do the same with + // ending, and align both variables with var_order, but that would be "incorrect", weird... + char *endfiledata = ending->endFileData; + free(endfiledata); + + g_Chain.Cut(ending->drawChain); + ending->drawChain = NULL; + + delete ending; + ending = NULL; + + g_Supervisor.isInEnding = false; + g_Supervisor.ReleasePbg3(ED_PBG3_INDEX); + return ZUN_SUCCESS; +} +}; // namespace th06 From d3cab0f00631a9414d8aceb3e87f9c5773beb4d1 Mon Sep 17 00:00:00 2001 From: roblabla Date: Sun, 17 Nov 2024 23:33:03 +0100 Subject: [PATCH 10/14] Remove unnecessary padding in Ending ctor This was likely the padding that was caused by the AnmVm inlining. Since AnmVm is properly set as inline now, the manual padding is unnecessary. --- src/Ending.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Ending.cpp b/src/Ending.cpp index a9319b5f..90412027 100644 --- a/src/Ending.cpp +++ b/src/Ending.cpp @@ -474,8 +474,6 @@ ZunResult Ending::RegisterChain() Ending::Ending() { - i32 unused[4]; - memset(this, 0, sizeof(Ending)); this->line2Delay = 8; this->timer2.InitializeForPopup(); From 91118615e58fa2bbd856d182c2de0aab3ee74ee6 Mon Sep 17 00:00:00 2001 From: roblabla Date: Sun, 17 Nov 2024 23:35:24 +0100 Subject: [PATCH 11/14] Define Ending ctor in class This improves the RegisterChain accuracy, fixing the weird stack slots we were seeing. --- src/Ending.cpp | 11 ----------- src/Ending.hpp | 12 +++++++++++- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/Ending.cpp b/src/Ending.cpp index 90412027..95b66e77 100644 --- a/src/Ending.cpp +++ b/src/Ending.cpp @@ -472,17 +472,6 @@ ZunResult Ending::RegisterChain() return ZUN_SUCCESS; } -Ending::Ending() -{ - memset(this, 0, sizeof(Ending)); - this->line2Delay = 8; - this->timer2.InitializeForPopup(); - this->timer1.InitializeForPopup(); - this->backgroundPos.x = 0.0f; - this->backgroundPos.y = 0.0f; - this->backgroundScrollSpeed = 0.0f; -} - #pragma var_order(framesPressed, idx) ChainCallbackResult Ending::OnUpdate(Ending *ending) { diff --git a/src/Ending.hpp b/src/Ending.hpp index 33238fe4..27332ed2 100644 --- a/src/Ending.hpp +++ b/src/Ending.hpp @@ -42,7 +42,17 @@ enum EndOpcode struct Ending { - Ending(); + Ending() + { + memset(this, 0, sizeof(Ending)); + this->line2Delay = 8; + this->timer2.InitializeForPopup(); + this->timer1.InitializeForPopup(); + this->backgroundPos.x = 0.0f; + this->backgroundPos.y = 0.0f; + this->backgroundScrollSpeed = 0.0f; + } + static ZunResult RegisterChain(); static ChainCallbackResult OnUpdate(Ending *ending); static ChainCallbackResult OnDraw(Ending *ending); From ed41801fc15849c8023969d37138880cc55acf9c Mon Sep 17 00:00:00 2001 From: roblabla Date: Mon, 18 Nov 2024 00:19:28 +0100 Subject: [PATCH 12/14] Implement Enemy::Enemy --- config/ghidra_ns_to_obj.csv | 2 +- config/implemented.csv | 1 + src/Enemy.hpp | 12 ++++++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/config/ghidra_ns_to_obj.csv b/config/ghidra_ns_to_obj.csv index e2470659..ad9c119e 100644 --- a/config/ghidra_ns_to_obj.csv +++ b/config/ghidra_ns_to_obj.csv @@ -7,7 +7,7 @@ EclManager,th06::EclManager EffectManager,th06::EffectManager Ending,th06::Ending Enemy,th06::Enemy -EnemyManager,th06::EnemyManager +EnemyManager,th06::EnemyManager,th06::Enemy FileAbstraction,th06::FileAbstraction FileSystem,th06::FileSystem GameErrorContext,th06::GameErrorContext diff --git a/config/implemented.csv b/config/implemented.csv index 30e03425..fdd30f72 100644 --- a/config/implemented.csv +++ b/config/implemented.csv @@ -125,6 +125,7 @@ th06::EnemyManager::OnUpdate th06::EnemyManager::OnDraw th06::EnemyManager::RunEclTimeline th06::EnemyManager::SpawnEnemy +th06::Enemy::Enemy th06::Enemy::GetVar th06::Enemy::GetVarFloat th06::Enemy::SetVar diff --git a/src/Enemy.hpp b/src/Enemy.hpp index d20f3580..78ea59a0 100644 --- a/src/Enemy.hpp +++ b/src/Enemy.hpp @@ -21,6 +21,10 @@ struct Enemy; struct EnemyBulletShooter { + EnemyBulletShooter() + { + memset(this, 0, sizeof(EnemyBulletShooter)); + } i16 sprite; i16 spriteOffset; D3DXVECTOR3 position; @@ -42,6 +46,10 @@ C_ASSERT(sizeof(EnemyBulletShooter) == 0x54); struct EnemyLaserShooter { + EnemyLaserShooter() + { + memset(this, 0, sizeof(EnemyLaserShooter)); + } i16 sprite; i16 spriteOffset; D3DXVECTOR3 position; @@ -124,6 +132,10 @@ enum EclValueType struct Enemy { + Enemy() + { + } + void Move(); void ClampPos(); ZunBool HandleLifeCallback(); From 93b0857a3b4b2c999a883eef46bdf0e2ab2c6462 Mon Sep 17 00:00:00 2001 From: roblabla Date: Mon, 18 Nov 2024 00:20:05 +0100 Subject: [PATCH 13/14] Implement EnemyManager::EnemyManager --- config/implemented.csv | 1 + src/EclManager.cpp | 2 +- src/EnemyManager.cpp | 15 ++++++++++----- src/EnemyManager.hpp | 4 ++-- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/config/implemented.csv b/config/implemented.csv index fdd30f72..3fe4097c 100644 --- a/config/implemented.csv +++ b/config/implemented.csv @@ -117,6 +117,7 @@ th06::EffectManager::EffectUpdateCallback4 th06::EffectManager::EffectCallbackAttract th06::EffectManager::EffectCallbackAttractSlow th06::EnemyManager::Initialize +th06::EnemyManager::EnemyManager th06::EnemyManager::RegisterChain th06::EnemyManager::CutChain th06::EnemyManager::AddedCallback diff --git a/src/EclManager.cpp b/src/EclManager.cpp index 02851094..fbdf81e8 100644 --- a/src/EclManager.cpp +++ b/src/EclManager.cpp @@ -855,7 +855,7 @@ ZunResult EclManager::RunEcl(Enemy *enemy) break; case ECL_OPCODE_ENEMYKILLALL: for (local_b4 = &g_EnemyManager.enemies[0], local_b8 = 0; - local_b8 < ARRAY_SIZE_SIGNED(g_EnemyManager.enemies); local_b8++, local_b4++) + local_b8 < ARRAY_SIZE_SIGNED(g_EnemyManager.enemies) - 1; local_b8++, local_b4++) { if (!local_b4->flags.unk5) { diff --git a/src/EnemyManager.cpp b/src/EnemyManager.cpp index b89a821e..54a328bd 100644 --- a/src/EnemyManager.cpp +++ b/src/EnemyManager.cpp @@ -83,6 +83,11 @@ void EnemyManager::Initialize() enemy->bulletRankSpeedHigh = 0.5f; } +EnemyManager::EnemyManager() +{ + this->Initialize(); +} + Enemy *EnemyManager::SpawnEnemy(i32 eclSubId, D3DXVECTOR3 *pos, i16 life, i16 itemDrop, i32 score) { Enemy *newEnemy; @@ -90,7 +95,7 @@ Enemy *EnemyManager::SpawnEnemy(i32 eclSubId, D3DXVECTOR3 *pos, i16 life, i16 it newEnemy = this->enemies; idx = 0; - for (; idx < ARRAY_SIZE_SIGNED(this->enemies); idx++, newEnemy++) + for (; idx < ARRAY_SIZE_SIGNED(this->enemies) - 1; idx++, newEnemy++) { if (newEnemy->flags.unk5) continue; @@ -352,7 +357,7 @@ ZunBool Enemy::HandleLifeCallback() this->stackDepth = 0; curEnemy = g_EnemyManager.enemies; - for (i = 0; i < ARRAY_SIZE_SIGNED(g_EnemyManager.enemies); i++, curEnemy++) + for (i = 0; i < ARRAY_SIZE_SIGNED(g_EnemyManager.enemies) - 1; i++, curEnemy++) { if (!curEnemy->flags.unk5) { @@ -410,7 +415,7 @@ ZunBool Enemy::HandleTimerCallback() } curEnemy = g_EnemyManager.enemies; - for (i = 0; i < ARRAY_SIZE_SIGNED(g_EnemyManager.enemies); i++, curEnemy++) + for (i = 0; i < ARRAY_SIZE_SIGNED(g_EnemyManager.enemies) - 1; i++, curEnemy++) { if (!curEnemy->flags.unk5) { @@ -524,7 +529,7 @@ ChainCallbackResult EnemyManager::OnUpdate(EnemyManager *mgr) local_8 = 0; mgr->RunEclTimeline(); - for (curEnemy = &mgr->enemies[0], mgr->enemyCount = 0, enemyIdx = 0; enemyIdx < ARRAY_SIZE_SIGNED(mgr->enemies); + for (curEnemy = &mgr->enemies[0], mgr->enemyCount = 0, enemyIdx = 0; enemyIdx < ARRAY_SIZE_SIGNED(mgr->enemies) - 1; enemyIdx++, curEnemy++) { if (!curEnemy->flags.unk5) @@ -768,7 +773,7 @@ ChainCallbackResult EnemyManager::OnDraw(EnemyManager *mgr) i32 curEnemyVmIdx; i32 curEnemyIdx; - for (curEnemy = &mgr->enemies[0], curEnemyIdx = 0; curEnemyIdx < ARRAY_SIZE_SIGNED(mgr->enemies); + for (curEnemy = &mgr->enemies[0], curEnemyIdx = 0; curEnemyIdx < ARRAY_SIZE_SIGNED(mgr->enemies) - 1; curEnemyIdx++, curEnemy++) { if (!curEnemy->flags.unk5) diff --git a/src/EnemyManager.hpp b/src/EnemyManager.hpp index 6aa3d3d0..cebf52a5 100644 --- a/src/EnemyManager.hpp +++ b/src/EnemyManager.hpp @@ -22,6 +22,7 @@ C_ASSERT(sizeof(RunningSpellcardInfo) == 0x14); struct EnemyManager { void Initialize(); + EnemyManager(); static ZunResult RegisterChain(char *stgEnm1, char *stgEnm2); static void CutChain(); static ChainCallbackResult OnUpdate(EnemyManager *enemyManager); @@ -35,8 +36,7 @@ struct EnemyManager char *stgEnmAnmFilename; char *stgEnm2AnmFilename; Enemy enemyTemplate; - Enemy enemies[256]; - Enemy dummyEnemyForFailedSpawns; + Enemy enemies[257]; Enemy *bosses[8]; u16 randomItemSpawnIndex; u16 randomItemTableIndex; From cc54d21d6f8d6cd73f10b55635f3a404fa1a6508 Mon Sep 17 00:00:00 2001 From: roblabla Date: Mon, 18 Nov 2024 21:19:09 +0100 Subject: [PATCH 14/14] Move Enemy ECL instructions to EnemyEclInstr.cpp --- config/ghidra_ns_to_obj.csv | 2 +- config/implemented.csv | 58 ++++---- objdiff.json | 6 +- scripts/configure.py | 2 +- src/EclManager.cpp | 205 ++++++++++++++------------- src/Enemy.hpp | 33 ----- src/{Enemy.cpp => EnemyEclInstr.cpp} | 145 +++++++++---------- src/EnemyEclInstr.hpp | 42 ++++++ 8 files changed, 253 insertions(+), 240 deletions(-) rename src/{Enemy.cpp => EnemyEclInstr.cpp} (89%) create mode 100644 src/EnemyEclInstr.hpp diff --git a/config/ghidra_ns_to_obj.csv b/config/ghidra_ns_to_obj.csv index ad9c119e..ba3f383d 100644 --- a/config/ghidra_ns_to_obj.csv +++ b/config/ghidra_ns_to_obj.csv @@ -6,7 +6,7 @@ Chain,th06::Chain,th06::ChainElem EclManager,th06::EclManager EffectManager,th06::EffectManager Ending,th06::Ending -Enemy,th06::Enemy +EnemyEclInstr,th06::EnemyEclInstr EnemyManager,th06::EnemyManager,th06::Enemy FileAbstraction,th06::FileAbstraction FileSystem,th06::FileSystem diff --git a/config/implemented.csv b/config/implemented.csv index 3fe4097c..5ec9761c 100644 --- a/config/implemented.csv +++ b/config/implemented.csv @@ -126,43 +126,43 @@ th06::EnemyManager::OnUpdate th06::EnemyManager::OnDraw th06::EnemyManager::RunEclTimeline th06::EnemyManager::SpawnEnemy +th06::EnemyEclInstr::GetVar +th06::EnemyEclInstr::GetVarFloat +th06::EnemyEclInstr::SetVar +th06::EnemyEclInstr::MathAdd +th06::EnemyEclInstr::MathSub +th06::EnemyEclInstr::MathMul +th06::EnemyEclInstr::MathDiv +th06::EnemyEclInstr::MathMod +th06::EnemyEclInstr::MathAtan2 +th06::EnemyEclInstr::MoveTime +th06::EnemyEclInstr::MoveDirTime +th06::EnemyEclInstr::MovePosTime +th06::EnemyEclInstr::ExInsCirnoRainbowBallJank +th06::EnemyEclInstr::ExInsShootAtRandomArea +th06::EnemyEclInstr::ExInsShootStarPattern +th06::EnemyEclInstr::ExInsPatchouliShottypeSetVars +th06::EnemyEclInstr::ExInsStage56Func4 +th06::EnemyEclInstr::ExInsStage5Func5 +th06::EnemyEclInstr::ExInsStage6XFunc6 +th06::EnemyEclInstr::ExInsStage6Func7 +th06::EnemyEclInstr::ExInsStage6Func8 +th06::EnemyEclInstr::ExInsStage6Func9 +th06::EnemyEclInstr::ExInsStage6Func11 +th06::EnemyEclInstr::ExInsStage6XFunc10 +th06::EnemyEclInstr::ExInsStage4Func12 +th06::EnemyEclInstr::ExInsStageXFunc13 +th06::EnemyEclInstr::ExInsStageXFunc14 +th06::EnemyEclInstr::ExInsStageXFunc15 +th06::EnemyEclInstr::ExInsStageXFunc16 th06::Enemy::Enemy -th06::Enemy::GetVar -th06::Enemy::GetVarFloat -th06::Enemy::SetVar -th06::Enemy::MathAdd -th06::Enemy::MathSub -th06::Enemy::MathMul -th06::Enemy::MathDiv -th06::Enemy::MathMod -th06::Enemy::MathAtan2 th06::Enemy::Move -th06::Enemy::MoveTime -th06::Enemy::MoveDirTime -th06::Enemy::MovePosTime th06::Enemy::ClampPos th06::Enemy::HandleLifeCallback th06::Enemy::HandleTimerCallback th06::Enemy::Despawn th06::Enemy::ResetEffectArray th06::Enemy::UpdateEffects -th06::Enemy::ExInsCirnoRainbowBallJank -th06::Enemy::ExInsShootAtRandomArea -th06::Enemy::ExInsShootStarPattern -th06::Enemy::ExInsPatchouliShottypeSetVars -th06::Enemy::ExInsStage56Func4 -th06::Enemy::ExInsStage5Func5 -th06::Enemy::ExInsStage6XFunc6 -th06::Enemy::ExInsStage6Func7 -th06::Enemy::ExInsStage6Func8 -th06::Enemy::ExInsStage6Func9 -th06::Enemy::ExInsStage6Func11 -th06::Enemy::ExInsStage6XFunc10 -th06::Enemy::ExInsStage4Func12 -th06::Enemy::ExInsStageXFunc13 -th06::Enemy::ExInsStageXFunc14 -th06::Enemy::ExInsStageXFunc15 -th06::Enemy::ExInsStageXFunc16 th06::GameErrorContext::Fatal th06::GameErrorContext::Log th06::GameErrorContext::Flush diff --git a/objdiff.json b/objdiff.json index fd719c71..efc28c99 100644 --- a/objdiff.json +++ b/objdiff.json @@ -83,10 +83,10 @@ "reverse_fn_order": false }, { - "name": "Enemy", + "name": "EnemyEclInstr", - "target_path": "build/objdiff/orig/Enemy.obj", - "base_path": "build/objdiff/reimpl/Enemy.obj", + "target_path": "build/objdiff/orig/EnemyEclInstr.obj", + "base_path": "build/objdiff/reimpl/EnemyEclInstr.obj", "reverse_fn_order": false }, diff --git a/scripts/configure.py b/scripts/configure.py index 61bc390a..4fcd1a96 100644 --- a/scripts/configure.py +++ b/scripts/configure.py @@ -95,7 +95,7 @@ def configure(build_type): "Stage", "BombData", "EclManager", - "Enemy", # ECL instructions. + "EnemyEclInstr", "EffectManager", "Ending", "EnemyManager", diff --git a/src/EclManager.cpp b/src/EclManager.cpp index fbdf81e8..f81d017b 100644 --- a/src/EclManager.cpp +++ b/src/EclManager.cpp @@ -2,6 +2,7 @@ #include "AnmManager.hpp" #include "EffectManager.hpp" #include "Enemy.hpp" +#include "EnemyEclInstr.hpp" #include "EnemyManager.hpp" #include "FileSystem.hpp" #include "GameErrorContext.hpp" @@ -22,16 +23,16 @@ DIFFABLE_STATIC_ARRAY_ASSIGN(i32, 64, g_SpellcardScore) = { 700000, 700000, 700000, 700000, 700000, 700000, 700000, 700000, 700000, 700000, 700000, 700000}; DIFFABLE_STATIC(EclManager, g_EclManager); typedef void (*ExInsn)(Enemy *, EclRawInstr *); -DIFFABLE_STATIC_ARRAY_ASSIGN(ExInsn, 17, - g_EclExInsn) = {Enemy::ExInsCirnoRainbowBallJank, Enemy::ExInsShootAtRandomArea, - Enemy::ExInsShootStarPattern, Enemy::ExInsPatchouliShottypeSetVars, - Enemy::ExInsStage56Func4, Enemy::ExInsStage5Func5, - Enemy::ExInsStage6XFunc6, Enemy::ExInsStage6Func7, - Enemy::ExInsStage6Func8, Enemy::ExInsStage6Func9, - Enemy::ExInsStage6XFunc10, Enemy::ExInsStage6Func11, - Enemy::ExInsStage4Func12, Enemy::ExInsStageXFunc13, - Enemy::ExInsStageXFunc14, Enemy::ExInsStageXFunc15, - Enemy::ExInsStageXFunc16}; +DIFFABLE_STATIC_ARRAY_ASSIGN(ExInsn, 17, g_EclExInsn) = { + EnemyEclInstr::ExInsCirnoRainbowBallJank, EnemyEclInstr::ExInsShootAtRandomArea, + EnemyEclInstr::ExInsShootStarPattern, EnemyEclInstr::ExInsPatchouliShottypeSetVars, + EnemyEclInstr::ExInsStage56Func4, EnemyEclInstr::ExInsStage5Func5, + EnemyEclInstr::ExInsStage6XFunc6, EnemyEclInstr::ExInsStage6Func7, + EnemyEclInstr::ExInsStage6Func8, EnemyEclInstr::ExInsStage6Func9, + EnemyEclInstr::ExInsStage6XFunc10, EnemyEclInstr::ExInsStage6Func11, + EnemyEclInstr::ExInsStage4Func12, EnemyEclInstr::ExInsStageXFunc13, + EnemyEclInstr::ExInsStageXFunc14, EnemyEclInstr::ExInsStageXFunc15, + EnemyEclInstr::ExInsStageXFunc16}; ZunResult EclManager::Load(char *eclPath) { @@ -120,9 +121,9 @@ ZunResult EclManager::RunEcl(Enemy *enemy) case ECL_OPCODE_UNIMP: return ZUN_ERROR; case ECL_OPCODE_JUMPDEC: - local_14 = *Enemy::GetVar(enemy, &args->jump.var, NULL); + local_14 = *EnemyEclInstr::GetVar(enemy, &args->jump.var, NULL); local_14--; - Enemy::SetVar(enemy, args->jump.var, &local_14); + EnemyEclInstr::SetVar(enemy, args->jump.var, &local_14); if (local_14 <= 0) break; case ECL_OPCODE_JUMP: @@ -132,86 +133,86 @@ ZunResult EclManager::RunEcl(Enemy *enemy) goto YOLO; case ECL_OPCODE_SETINT: case ECL_OPCODE_SETFLOAT: - Enemy::SetVar(enemy, instruction->args.alu.res, &args->alu.arg1.i32); + EnemyEclInstr::SetVar(enemy, instruction->args.alu.res, &args->alu.arg1.i32); break; case ECL_OPCODE_MATHNORMANGLE: - local_18 = *(f32 *)Enemy::GetVar(enemy, &instruction->args.alu.res, NULL); + local_18 = *(f32 *)EnemyEclInstr::GetVar(enemy, &instruction->args.alu.res, NULL); local_18 = utils::AddNormalizeAngle(local_18, 0.0f); - Enemy::SetVar(enemy, instruction->args.alu.res, &local_18); + EnemyEclInstr::SetVar(enemy, instruction->args.alu.res, &local_18); break; case ECL_OPCODE_SETINTRAND: - local_24 = *Enemy::GetVar(enemy, &args->alu.arg1.id, NULL); + local_24 = *EnemyEclInstr::GetVar(enemy, &args->alu.arg1.id, NULL); local_14 = g_Rng.GetRandomU32InRange(local_24); - Enemy::SetVar(enemy, instruction->args.alu.res, &local_14); + EnemyEclInstr::SetVar(enemy, instruction->args.alu.res, &local_14); break; case ECL_OPCODE_SETINTRANDMIN: - local_28 = *Enemy::GetVar(enemy, &args->alu.arg1.id, NULL); - local_2c = *Enemy::GetVar(enemy, &args->alu.arg2.id, NULL); + local_28 = *EnemyEclInstr::GetVar(enemy, &args->alu.arg1.id, NULL); + local_2c = *EnemyEclInstr::GetVar(enemy, &args->alu.arg2.id, NULL); local_14 = g_Rng.GetRandomU32InRange(local_28); local_14 += local_2c; - Enemy::SetVar(enemy, instruction->args.alu.res, &local_14); + EnemyEclInstr::SetVar(enemy, instruction->args.alu.res, &local_14); break; case ECL_OPCODE_SETFLOATRAND: - local_30 = *Enemy::GetVarFloat(enemy, &args->alu.arg1.f32, NULL); + local_30 = *EnemyEclInstr::GetVarFloat(enemy, &args->alu.arg1.f32, NULL); local_18 = g_Rng.GetRandomF32InRange(local_30); - Enemy::SetVar(enemy, instruction->args.alu.res, &local_18); + EnemyEclInstr::SetVar(enemy, instruction->args.alu.res, &local_18); break; case ECL_OPCODE_SETFLOATRANDMIN: - local_34 = *Enemy::GetVarFloat(enemy, &args->alu.arg1.f32, NULL); - local_38 = *Enemy::GetVarFloat(enemy, &args->alu.arg2.f32, NULL); + local_34 = *EnemyEclInstr::GetVarFloat(enemy, &args->alu.arg1.f32, NULL); + local_38 = *EnemyEclInstr::GetVarFloat(enemy, &args->alu.arg2.f32, NULL); local_18 = g_Rng.GetRandomF32InRange(local_34); local_18 += local_38; - Enemy::SetVar(enemy, instruction->args.alu.res, &local_18); + EnemyEclInstr::SetVar(enemy, instruction->args.alu.res, &local_18); break; case ECL_OPCODE_SETVARSELFX: - Enemy::SetVar(enemy, instruction->args.alu.res, &enemy->position.x); + EnemyEclInstr::SetVar(enemy, instruction->args.alu.res, &enemy->position.x); break; case ECL_OPCODE_SETVARSELFY: - Enemy::SetVar(enemy, instruction->args.alu.res, &enemy->position.y); + EnemyEclInstr::SetVar(enemy, instruction->args.alu.res, &enemy->position.y); break; case ECL_OPCODE_SETVARSELFZ: - Enemy::SetVar(enemy, instruction->args.alu.res, &enemy->position.z); + EnemyEclInstr::SetVar(enemy, instruction->args.alu.res, &enemy->position.z); break; case ECL_OPCODE_MATHINTADD: case ECL_OPCODE_MATHFLOATADD: - Enemy::MathAdd(enemy, instruction->args.alu.res, &args->alu.arg1.id, &args->alu.arg2.id); + EnemyEclInstr::MathAdd(enemy, instruction->args.alu.res, &args->alu.arg1.id, &args->alu.arg2.id); break; case ECL_OPCODE_MATHINC: - local_3c = Enemy::GetVar(enemy, &instruction->args.alu.res, NULL); + local_3c = EnemyEclInstr::GetVar(enemy, &instruction->args.alu.res, NULL); *local_3c += 1; break; case ECL_OPCODE_MATHDEC: - local_40 = Enemy::GetVar(enemy, &instruction->args.alu.res, NULL); + local_40 = EnemyEclInstr::GetVar(enemy, &instruction->args.alu.res, NULL); *local_40 -= 1; break; case ECL_OPCODE_MATHINTSUB: case ECL_OPCODE_MATHFLOATSUB: - Enemy::MathSub(enemy, instruction->args.alu.res, &args->alu.arg1.id, &args->alu.arg2.id); + EnemyEclInstr::MathSub(enemy, instruction->args.alu.res, &args->alu.arg1.id, &args->alu.arg2.id); break; case ECL_OPCODE_MATHINTMUL: case ECL_OPCODE_MATHFLOATMUL: - Enemy::MathMul(enemy, instruction->args.alu.res, &args->alu.arg1.id, &args->alu.arg2.id); + EnemyEclInstr::MathMul(enemy, instruction->args.alu.res, &args->alu.arg1.id, &args->alu.arg2.id); break; case ECL_OPCODE_MATHINTDIV: case ECL_OPCODE_MATHFLOATDIV: - Enemy::MathDiv(enemy, instruction->args.alu.res, &args->alu.arg1.id, &args->alu.arg2.id); + EnemyEclInstr::MathDiv(enemy, instruction->args.alu.res, &args->alu.arg1.id, &args->alu.arg2.id); break; case ECL_OPCODE_MATHINTMOD: case ECL_OPCODE_MATHFLOATMOD: - Enemy::MathMod(enemy, instruction->args.alu.res, &args->alu.arg1.id, &args->alu.arg2.id); + EnemyEclInstr::MathMod(enemy, instruction->args.alu.res, &args->alu.arg1.id, &args->alu.arg2.id); break; case ECL_OPCODE_MATHATAN2: - Enemy::MathAtan2(enemy, instruction->args.alu.res, &args->alu.arg1.f32, &args->alu.arg2.f32, - &args->alu.arg3.f32, &args->alu.arg4.f32); + EnemyEclInstr::MathAtan2(enemy, instruction->args.alu.res, &args->alu.arg1.f32, &args->alu.arg2.f32, + &args->alu.arg3.f32, &args->alu.arg4.f32); break; case ECL_OPCODE_CMPINT: - local_48 = *Enemy::GetVar(enemy, &instruction->args.cmp.lhs.id, NULL); - local_44 = *Enemy::GetVar(enemy, &instruction->args.cmp.rhs.id, NULL); + local_48 = *EnemyEclInstr::GetVar(enemy, &instruction->args.cmp.lhs.id, NULL); + local_44 = *EnemyEclInstr::GetVar(enemy, &instruction->args.cmp.rhs.id, NULL); enemy->currentContext.compareRegister = local_48 == local_44 ? 0 : local_48 < local_44 ? -1 : 1; break; case ECL_OPCODE_CMPFLOAT: - local_4c = *Enemy::GetVarFloat(enemy, &instruction->args.cmp.lhs.f32, NULL); - local_50 = *Enemy::GetVarFloat(enemy, &instruction->args.cmp.rhs.f32, NULL); + local_4c = *EnemyEclInstr::GetVarFloat(enemy, &instruction->args.cmp.lhs.f32, NULL); + local_50 = *EnemyEclInstr::GetVarFloat(enemy, &instruction->args.cmp.rhs.f32, NULL); enemy->currentContext.compareRegister = local_4c == local_50 ? 0 : (local_4c < local_50 ? -1 : 1); break; case ECL_OPCODE_JUMPLSS: @@ -264,32 +265,32 @@ ZunResult EclManager::RunEcl(Enemy *enemy) memcpy(&enemy->currentContext, &enemy->savedContextStack[enemy->stackDepth], sizeof(EnemyEclContext)); continue; case ECL_OPCODE_CALLLSS: - local_14 = *Enemy::GetVar(enemy, &args->call.cmpLhs, NULL); + local_14 = *EnemyEclInstr::GetVar(enemy, &args->call.cmpLhs, NULL); if (local_14 < args->call.cmpRhs) goto HANDLE_CALL; break; case ECL_OPCODE_CALLLEQ: - local_14 = *Enemy::GetVar(enemy, &args->call.cmpLhs, NULL); + local_14 = *EnemyEclInstr::GetVar(enemy, &args->call.cmpLhs, NULL); if (local_14 <= args->call.cmpRhs) goto HANDLE_CALL; break; case ECL_OPCODE_CALLEQU: - local_14 = *Enemy::GetVar(enemy, &args->call.cmpLhs, NULL); + local_14 = *EnemyEclInstr::GetVar(enemy, &args->call.cmpLhs, NULL); if (local_14 == args->call.cmpRhs) goto HANDLE_CALL; break; case ECL_OPCODE_CALLGRE: - local_14 = *Enemy::GetVar(enemy, &args->call.cmpLhs, NULL); + local_14 = *EnemyEclInstr::GetVar(enemy, &args->call.cmpLhs, NULL); if (local_14 > args->call.cmpRhs) goto HANDLE_CALL; break; case ECL_OPCODE_CALLGEQ: - local_14 = *Enemy::GetVar(enemy, &args->call.cmpLhs, NULL); + local_14 = *EnemyEclInstr::GetVar(enemy, &args->call.cmpLhs, NULL); if (local_14 >= args->call.cmpRhs) goto HANDLE_CALL; break; case ECL_OPCODE_CALLNEQ: - local_14 = *Enemy::GetVar(enemy, &args->call.cmpLhs, NULL); + local_14 = *EnemyEclInstr::GetVar(enemy, &args->call.cmpLhs, NULL); if (local_14 != args->call.cmpRhs) goto HANDLE_CALL; break; @@ -307,43 +308,43 @@ ZunResult EclManager::RunEcl(Enemy *enemy) break; case ECL_OPCODE_MOVEPOSITION: enemy->position = *instruction->args.move.pos.AsD3dXVec(); - enemy->position.x = *Enemy::GetVarFloat(enemy, &enemy->position.x, NULL); - enemy->position.y = *Enemy::GetVarFloat(enemy, &enemy->position.y, NULL); - enemy->position.z = *Enemy::GetVarFloat(enemy, &enemy->position.z, NULL); + enemy->position.x = *EnemyEclInstr::GetVarFloat(enemy, &enemy->position.x, NULL); + enemy->position.y = *EnemyEclInstr::GetVarFloat(enemy, &enemy->position.y, NULL); + enemy->position.z = *EnemyEclInstr::GetVarFloat(enemy, &enemy->position.z, NULL); enemy->ClampPos(); break; case ECL_OPCODE_MOVEAXISVELOCITY: enemy->axisSpeed = *instruction->args.move.pos.AsD3dXVec(); - enemy->axisSpeed.x = *Enemy::GetVarFloat(enemy, &enemy->axisSpeed.x, NULL); - enemy->axisSpeed.y = *Enemy::GetVarFloat(enemy, &enemy->axisSpeed.y, NULL); - enemy->axisSpeed.z = *Enemy::GetVarFloat(enemy, &enemy->axisSpeed.z, NULL); + enemy->axisSpeed.x = *EnemyEclInstr::GetVarFloat(enemy, &enemy->axisSpeed.x, NULL); + enemy->axisSpeed.y = *EnemyEclInstr::GetVarFloat(enemy, &enemy->axisSpeed.y, NULL); + enemy->axisSpeed.z = *EnemyEclInstr::GetVarFloat(enemy, &enemy->axisSpeed.z, NULL); enemy->flags.unk1 = 0; break; case ECL_OPCODE_MOVEVELOCITY: local_8 = instruction->args.move.pos; - enemy->angle = *Enemy::GetVarFloat(enemy, &local_8.x, NULL); - enemy->speed = *Enemy::GetVarFloat(enemy, &local_8.y, NULL); + enemy->angle = *EnemyEclInstr::GetVarFloat(enemy, &local_8.x, NULL); + enemy->speed = *EnemyEclInstr::GetVarFloat(enemy, &local_8.y, NULL); enemy->flags.unk1 = 1; break; case ECL_OPCODE_MOVEANGULARVELOCITY: local_8 = instruction->args.move.pos; - enemy->angularVelocity = *Enemy::GetVarFloat(enemy, &local_8.x, NULL); + enemy->angularVelocity = *EnemyEclInstr::GetVarFloat(enemy, &local_8.x, NULL); enemy->flags.unk1 = 1; break; case ECL_OPCODE_MOVEATPLAYER: local_8 = instruction->args.move.pos; enemy->angle = g_Player.AngleToPlayer(&enemy->position) + local_8.x; - enemy->speed = *Enemy::GetVarFloat(enemy, &local_8.y, NULL); + enemy->speed = *EnemyEclInstr::GetVarFloat(enemy, &local_8.y, NULL); enemy->flags.unk1 = 1; break; case ECL_OPCODE_MOVESPEED: local_8 = instruction->args.move.pos; - enemy->speed = *Enemy::GetVarFloat(enemy, &local_8.x, NULL); + enemy->speed = *EnemyEclInstr::GetVarFloat(enemy, &local_8.x, NULL); enemy->flags.unk1 = 1; break; case ECL_OPCODE_MOVEACCELERATION: local_8 = instruction->args.move.pos; - enemy->acceleration = *Enemy::GetVarFloat(enemy, &local_8.x, NULL); + enemy->acceleration = *EnemyEclInstr::GetVarFloat(enemy, &local_8.x, NULL); enemy->flags.unk1 = 1; break; case ECL_OPCODE_BULLETFANAIMED: @@ -359,23 +360,23 @@ ZunResult EclManager::RunEcl(Enemy *enemy) local_58 = &enemy->bulletProps; local_58->sprite = local_54->sprite; local_58->aimMode = instruction->opCode - ECL_OPCODE_BULLETFANAIMED; - local_58->count1 = *Enemy::GetVar(enemy, &local_54->count1, NULL); + local_58->count1 = *EnemyEclInstr::GetVar(enemy, &local_54->count1, NULL); local_58->count1 += enemy->BulletRankAmount1(g_GameManager.rank); if (local_58->count1 <= 0) { local_58->count1 = 1; } - local_58->count2 = *Enemy::GetVar(enemy, &local_54->count2, NULL); + local_58->count2 = *EnemyEclInstr::GetVar(enemy, &local_54->count2, NULL); local_58->count2 += enemy->BulletRankAmount2(g_GameManager.rank); if (local_58->count2 <= 0) { local_58->count2 = 1; } local_58->position = enemy->position + enemy->shootOffset; - local_58->angle1 = *Enemy::GetVarFloat(enemy, &local_54->angle1, NULL); + local_58->angle1 = *EnemyEclInstr::GetVarFloat(enemy, &local_54->angle1, NULL); local_58->angle1 = utils::AddNormalizeAngle(local_58->angle1, 0.0f); - local_58->speed1 = *Enemy::GetVarFloat(enemy, &local_54->speed1, NULL); + local_58->speed1 = *EnemyEclInstr::GetVarFloat(enemy, &local_54->speed1, NULL); if (local_58->speed1 != 0.0f) { local_58->speed1 += enemy->BulletRankSpeed(g_GameManager.rank); @@ -384,8 +385,8 @@ ZunResult EclManager::RunEcl(Enemy *enemy) local_58->speed1 = 0.3; } } - local_58->angle2 = *Enemy::GetVarFloat(enemy, &local_54->angle2, NULL); - local_58->speed2 = *Enemy::GetVarFloat(enemy, &local_54->speed2, NULL); + local_58->angle2 = *EnemyEclInstr::GetVarFloat(enemy, &local_54->angle2, NULL); + local_58->speed2 = *EnemyEclInstr::GetVarFloat(enemy, &local_54->speed2, NULL); local_58->speed2 += enemy->BulletRankSpeed(g_GameManager.rank) / 2.0f; if (local_58->speed2 < 0.3f) { @@ -395,21 +396,21 @@ ZunResult EclManager::RunEcl(Enemy *enemy) local_58->flags = local_54->flags; local_14 = local_54->color; // TODO: Strict aliasing rule be like. - local_58->spriteOffset = *Enemy::GetVar(enemy, (EclVarId *)&local_14, NULL); + local_58->spriteOffset = *EnemyEclInstr::GetVar(enemy, (EclVarId *)&local_14, NULL); if (enemy->flags.unk3 == 0) { g_BulletManager.SpawnBulletPattern(local_58); } break; case ECL_OPCODE_BULLETEFFECTS: - enemy->bulletProps.exInts[0] = *Enemy::GetVar(enemy, &args->bulletEffects.ivar1, NULL); - enemy->bulletProps.exInts[1] = *Enemy::GetVar(enemy, &args->bulletEffects.ivar2, NULL); - enemy->bulletProps.exInts[2] = *Enemy::GetVar(enemy, &args->bulletEffects.ivar3, NULL); - enemy->bulletProps.exInts[3] = *Enemy::GetVar(enemy, &args->bulletEffects.ivar4, NULL); - enemy->bulletProps.exFloats[0] = *Enemy::GetVarFloat(enemy, &args->bulletEffects.fvar1, NULL); - enemy->bulletProps.exFloats[1] = *Enemy::GetVarFloat(enemy, &args->bulletEffects.fvar2, NULL); - enemy->bulletProps.exFloats[2] = *Enemy::GetVarFloat(enemy, &args->bulletEffects.fvar3, NULL); - enemy->bulletProps.exFloats[3] = *Enemy::GetVarFloat(enemy, &args->bulletEffects.fvar4, NULL); + enemy->bulletProps.exInts[0] = *EnemyEclInstr::GetVar(enemy, &args->bulletEffects.ivar1, NULL); + enemy->bulletProps.exInts[1] = *EnemyEclInstr::GetVar(enemy, &args->bulletEffects.ivar2, NULL); + enemy->bulletProps.exInts[2] = *EnemyEclInstr::GetVar(enemy, &args->bulletEffects.ivar3, NULL); + enemy->bulletProps.exInts[3] = *EnemyEclInstr::GetVar(enemy, &args->bulletEffects.ivar4, NULL); + enemy->bulletProps.exFloats[0] = *EnemyEclInstr::GetVarFloat(enemy, &args->bulletEffects.fvar1, NULL); + enemy->bulletProps.exFloats[1] = *EnemyEclInstr::GetVarFloat(enemy, &args->bulletEffects.fvar2, NULL); + enemy->bulletProps.exFloats[2] = *EnemyEclInstr::GetVarFloat(enemy, &args->bulletEffects.fvar3, NULL); + enemy->bulletProps.exFloats[3] = *EnemyEclInstr::GetVarFloat(enemy, &args->bulletEffects.fvar4, NULL); break; case ECL_OPCODE_ANMSETDEATH: local_5c = &instruction->args.anmSetDeath; @@ -441,9 +442,9 @@ ZunResult EclManager::RunEcl(Enemy *enemy) g_BulletManager.SpawnBulletPattern(&enemy->bulletProps); break; case ECL_OPCODE_SHOOTOFFSET: - enemy->shootOffset.x = *Enemy::GetVarFloat(enemy, &args->move.pos.x, NULL); - enemy->shootOffset.y = *Enemy::GetVarFloat(enemy, &args->move.pos.y, NULL); - enemy->shootOffset.z = *Enemy::GetVarFloat(enemy, &args->move.pos.z, NULL); + enemy->shootOffset.x = *EnemyEclInstr::GetVarFloat(enemy, &args->move.pos.x, NULL); + enemy->shootOffset.y = *EnemyEclInstr::GetVarFloat(enemy, &args->move.pos.y, NULL); + enemy->shootOffset.z = *EnemyEclInstr::GetVarFloat(enemy, &args->move.pos.z, NULL); break; case ECL_OPCODE_LASERCREATE: case ECL_OPCODE_LASERCREATEAIMED: @@ -452,11 +453,11 @@ ZunResult EclManager::RunEcl(Enemy *enemy) local_60->position = enemy->position + enemy->shootOffset; local_60->sprite = local_64->sprite; local_60->spriteOffset = local_64->color; - local_60->angle = *Enemy::GetVarFloat(enemy, &local_64->angle, NULL); - local_60->speed = *Enemy::GetVarFloat(enemy, &local_64->speed, NULL); - local_60->startOffset = *Enemy::GetVarFloat(enemy, &local_64->startOffset, NULL); - local_60->endOffset = *Enemy::GetVarFloat(enemy, &local_64->endOffset, NULL); - local_60->startLength = *Enemy::GetVarFloat(enemy, &local_64->startLength, NULL); + local_60->angle = *EnemyEclInstr::GetVarFloat(enemy, &local_64->angle, NULL); + local_60->speed = *EnemyEclInstr::GetVarFloat(enemy, &local_64->speed, NULL); + local_60->startOffset = *EnemyEclInstr::GetVarFloat(enemy, &local_64->startOffset, NULL); + local_60->endOffset = *EnemyEclInstr::GetVarFloat(enemy, &local_64->endOffset, NULL); + local_60->startLength = *EnemyEclInstr::GetVarFloat(enemy, &local_64->startLength, NULL); local_60->width = local_64->width; local_60->startTime = local_64->startTime; local_60->duration = local_64->duration; @@ -475,13 +476,13 @@ ZunResult EclManager::RunEcl(Enemy *enemy) enemy->lasers[enemy->laserStore] = g_BulletManager.SpawnLaserPattern(local_60); break; case ECL_OPCODE_LASERINDEX: - enemy->laserStore = *Enemy::GetVar(enemy, &instruction->args.alu.res, NULL); + enemy->laserStore = *EnemyEclInstr::GetVar(enemy, &instruction->args.alu.res, NULL); break; case ECL_OPCODE_LASERROTATE: if (enemy->lasers[instruction->args.laserOp.laserIdx] != NULL) { enemy->lasers[instruction->args.laserOp.laserIdx]->angle += - *Enemy::GetVarFloat(enemy, &instruction->args.laserOp.arg1.x, NULL); + *EnemyEclInstr::GetVarFloat(enemy, &instruction->args.laserOp.arg1.x, NULL); } break; case ECL_OPCODE_LASERROTATEFROMPLAYER: @@ -489,7 +490,7 @@ ZunResult EclManager::RunEcl(Enemy *enemy) { enemy->lasers[instruction->args.laserOp.laserIdx]->angle = g_Player.AngleToPlayer(&enemy->lasers[instruction->args.laserOp.laserIdx]->pos) + - *Enemy::GetVarFloat(enemy, &instruction->args.laserOp.arg1.x, NULL); + *EnemyEclInstr::GetVarFloat(enemy, &instruction->args.laserOp.arg1.x, NULL); } break; case ECL_OPCODE_LASEROFFSET: @@ -550,55 +551,55 @@ ZunResult EclManager::RunEcl(Enemy *enemy) enemy->effectIdx++; break; case ECL_OPCODE_MOVEDIRTIMEDECELERATE: - Enemy::MoveDirTime(enemy, instruction); + EnemyEclInstr::MoveDirTime(enemy, instruction); enemy->flags.unk2 = 1; break; case ECL_OPCODE_MOVEDIRTIMEDECELERATEFAST: - Enemy::MoveDirTime(enemy, instruction); + EnemyEclInstr::MoveDirTime(enemy, instruction); enemy->flags.unk2 = 2; break; case ECL_OPCODE_MOVEDIRTIMEACCELERATE: - Enemy::MoveDirTime(enemy, instruction); + EnemyEclInstr::MoveDirTime(enemy, instruction); enemy->flags.unk2 = 3; break; case ECL_OPCODE_MOVEDIRTIMEACCELERATEFAST: - Enemy::MoveDirTime(enemy, instruction); + EnemyEclInstr::MoveDirTime(enemy, instruction); enemy->flags.unk2 = 4; break; case ECL_OPCODE_MOVEPOSITIONTIMELINEAR: - Enemy::MovePosTime(enemy, instruction); + EnemyEclInstr::MovePosTime(enemy, instruction); enemy->flags.unk2 = 0; break; case ECL_OPCODE_MOVEPOSITIONTIMEDECELERATE: - Enemy::MovePosTime(enemy, instruction); + EnemyEclInstr::MovePosTime(enemy, instruction); enemy->flags.unk2 = 1; break; case ECL_OPCODE_MOVEPOSITIONTIMEDECELERATEFAST: - Enemy::MovePosTime(enemy, instruction); + EnemyEclInstr::MovePosTime(enemy, instruction); enemy->flags.unk2 = 2; break; case ECL_OPCODE_MOVEPOSITIONTIMEACCELERATE: - Enemy::MovePosTime(enemy, instruction); + EnemyEclInstr::MovePosTime(enemy, instruction); enemy->flags.unk2 = 3; break; case ECL_OPCODE_MOVEPOSITIONTIMEACCELERATEFAST: - Enemy::MovePosTime(enemy, instruction); + EnemyEclInstr::MovePosTime(enemy, instruction); enemy->flags.unk2 = 4; break; case ECL_OPCODE_MOVETIMEDECELERATE: - Enemy::MoveTime(enemy, instruction); + EnemyEclInstr::MoveTime(enemy, instruction); enemy->flags.unk2 = 1; break; case ECL_OPCODE_MOVETIMEDECELERATEFAST: - Enemy::MoveTime(enemy, instruction); + EnemyEclInstr::MoveTime(enemy, instruction); enemy->flags.unk2 = 2; break; case ECL_OPCODE_MOVETIMEACCELERATE: - Enemy::MoveTime(enemy, instruction); + EnemyEclInstr::MoveTime(enemy, instruction); enemy->flags.unk2 = 3; break; case ECL_OPCODE_MOVETIMEACCELERATEFAST: - Enemy::MoveTime(enemy, instruction); + EnemyEclInstr::MoveTime(enemy, instruction); enemy->flags.unk2 = 4; break; case ECL_OPCODE_MOVEBOUNDSSET: @@ -833,7 +834,7 @@ ZunResult EclManager::RunEcl(Enemy *enemy) break; case ECL_OPCODE_TIMESET: enemy->currentContext.time.IncrementInline( - *Enemy::GetVar(enemy, &instruction->args.timeSet.timeToSet, NULL)); + *EnemyEclInstr::GetVar(enemy, &instruction->args.timeSet.timeToSet, NULL)); break; case ECL_OPCODE_DROPITEMID: g_ItemManager.SpawnItem(&enemy->position, instruction->args.dropItem.itemId, 0); @@ -847,9 +848,9 @@ ZunResult EclManager::RunEcl(Enemy *enemy) break; case ECL_OPCODE_ENEMYCREATE: local_b0 = instruction->args.enemyCreate; - local_b0.pos.x = *Enemy::GetVarFloat(enemy, &local_b0.pos.x, NULL); - local_b0.pos.y = *Enemy::GetVarFloat(enemy, &local_b0.pos.y, NULL); - local_b0.pos.z = *Enemy::GetVarFloat(enemy, &local_b0.pos.z, NULL); + local_b0.pos.x = *EnemyEclInstr::GetVarFloat(enemy, &local_b0.pos.x, NULL); + local_b0.pos.y = *EnemyEclInstr::GetVarFloat(enemy, &local_b0.pos.y, NULL); + local_b0.pos.z = *EnemyEclInstr::GetVarFloat(enemy, &local_b0.pos.z, NULL); g_EnemyManager.SpawnEnemy(local_b0.subId, local_b0.pos.AsD3dXVec(), local_b0.life, local_b0.itemDrop, local_b0.score); break; diff --git a/src/Enemy.hpp b/src/Enemy.hpp index 78ea59a0..d28f84d0 100644 --- a/src/Enemy.hpp +++ b/src/Enemy.hpp @@ -145,39 +145,6 @@ struct Enemy static void ResetEffectArray(Enemy *enemy); static void UpdateEffects(Enemy *enemy); - static i32 *GetVar(Enemy *enemy, EclVarId *varId, EclValueType *valueType); - static f32 *GetVarFloat(Enemy *enemy, f32 *varId, EclValueType *valueType); - static void SetVar(Enemy *enemy, EclVarId lhs, void *rhs); - - static void MathAdd(Enemy *enemy, EclVarId out, EclVarId *lhs, EclVarId *rhs); - static void MathSub(Enemy *enemy, EclVarId out, EclVarId *lhs, EclVarId *rhs); - static void MathMul(Enemy *enemy, EclVarId out, EclVarId *lhs, EclVarId *rhs); - static void MathDiv(Enemy *enemy, EclVarId out, EclVarId *lhs, EclVarId *rhs); - static void MathMod(Enemy *enemy, EclVarId out, EclVarId *lhs, EclVarId *rhs); - static void MathAtan2(Enemy *enemy, EclVarId out, f32 *a1, f32 *a2, f32 *b1, f32 *b2); - - static void MoveDirTime(Enemy *enemy, EclRawInstr *instr); - static void MovePosTime(Enemy *enemy, EclRawInstr *instr); - static void MoveTime(Enemy *enemy, EclRawInstr *instr); - - static void ExInsCirnoRainbowBallJank(Enemy *enemy, EclRawInstr *instr); - static void ExInsShootAtRandomArea(Enemy *enemy, EclRawInstr *instr); - static void ExInsShootStarPattern(Enemy *enemy, EclRawInstr *instr); - static void ExInsPatchouliShottypeSetVars(Enemy *enemy, EclRawInstr *instr); - static void ExInsStage56Func4(Enemy *enemy, EclRawInstr *instr); - static void ExInsStage5Func5(Enemy *enemy, EclRawInstr *instr); - static void ExInsStage6XFunc6(Enemy *enemy, EclRawInstr *instr); - static void ExInsStage6Func7(Enemy *enemy, EclRawInstr *instr); - static void ExInsStage6Func8(Enemy *enemy, EclRawInstr *instr); - static void ExInsStage6Func9(Enemy *enemy, EclRawInstr *instr); - static void ExInsStage6Func11(Enemy *enemy, EclRawInstr *instr); - static void ExInsStage6XFunc10(Enemy *enemy, EclRawInstr *instr); - static void ExInsStage4Func12(Enemy *enemy, EclRawInstr *instr); - static void ExInsStageXFunc13(Enemy *enemy, EclRawInstr *instr); - static void ExInsStageXFunc14(Enemy *enemy, EclRawInstr *instr); - static void ExInsStageXFunc15(Enemy *enemy, EclRawInstr *instr); - static void ExInsStageXFunc16(Enemy *enemy, EclRawInstr *instr); - f32 LifePercent() { return (f32)this->life / (f32)this->maxLife; diff --git a/src/Enemy.cpp b/src/EnemyEclInstr.cpp similarity index 89% rename from src/Enemy.cpp rename to src/EnemyEclInstr.cpp index e68a2b17..2fb8b051 100644 --- a/src/Enemy.cpp +++ b/src/EnemyEclInstr.cpp @@ -1,7 +1,8 @@ -#include "Enemy.hpp" +#include "EnemyEclInstr.hpp" #include "BulletManager.hpp" #include "EclManager.hpp" #include "EffectManager.hpp" +#include "Enemy.hpp" #include "EnemyManager.hpp" #include "GameManager.hpp" #include "Gui.hpp" @@ -12,7 +13,8 @@ namespace th06 { - +namespace EnemyEclInstr +{ #define MAX_BOSS_TIME 7200 struct PatchouliShottypeVars @@ -35,13 +37,13 @@ DIFFABLE_STATIC_ARRAY(f32, 6, g_StarAngleTable); DIFFABLE_STATIC(D3DXVECTOR3, g_EnemyPosVector); DIFFABLE_STATIC(D3DXVECTOR3, g_PlayerPosVector); -void Enemy::MoveDirTime(Enemy *enemy, EclRawInstr *instr) +void MoveDirTime(Enemy *enemy, EclRawInstr *instr) { EclRawInstrAluArgs *alu; f32 angle; alu = &instr->args.alu; - angle = *Enemy::GetVarFloat(enemy, &alu->arg1.f32, NULL); + angle = *GetVarFloat(enemy, &alu->arg1.f32, NULL); enemy->moveInterp.x = sinf(angle) * alu->arg2.f32 * alu->res / 2.0f; enemy->moveInterp.y = cosf(angle) * alu->arg2.f32 * alu->res / 2.0f; @@ -55,14 +57,14 @@ void Enemy::MoveDirTime(Enemy *enemy, EclRawInstr *instr) enemy->flags.unk1 = 2; } -void Enemy::MovePosTime(Enemy *enemy, EclRawInstr *instr) +void MovePosTime(Enemy *enemy, EclRawInstr *instr) { D3DXVECTOR3 newPos; EclRawInstrAluArgs *alu = &instr->args.alu; - newPos.x = *Enemy::GetVarFloat(enemy, &alu->arg1.f32, NULL); - newPos.y = *Enemy::GetVarFloat(enemy, &alu->arg2.f32, NULL); - newPos.z = *Enemy::GetVarFloat(enemy, &alu->arg3.f32, NULL); + newPos.x = *GetVarFloat(enemy, &alu->arg1.f32, NULL); + newPos.y = *GetVarFloat(enemy, &alu->arg2.f32, NULL); + newPos.z = *GetVarFloat(enemy, &alu->arg3.f32, NULL); enemy->moveInterp = newPos - enemy->position; enemy->moveInterpStartPos = enemy->position; @@ -74,13 +76,13 @@ void Enemy::MovePosTime(Enemy *enemy, EclRawInstr *instr) enemy->axisSpeed = D3DXVECTOR3(0.0f, 0.0f, 0.0f); } -void Enemy::MoveTime(Enemy *enemy, EclRawInstr *instr) +void MoveTime(Enemy *enemy, EclRawInstr *instr) { EclRawInstrAluArgs *alu; f32 angle; alu = &instr->args.alu; - angle = *Enemy::GetVarFloat(enemy, &enemy->angle, NULL); + angle = *GetVarFloat(enemy, &enemy->angle, NULL); enemy->moveInterp.x = sinf(angle) * enemy->speed * alu->res / 2.0f; enemy->moveInterp.y = cosf(angle) * enemy->speed * alu->res / 2.0f; @@ -94,7 +96,7 @@ void Enemy::MoveTime(Enemy *enemy, EclRawInstr *instr) enemy->flags.unk1 = 2; } -i32 *Enemy::GetVar(Enemy *enemy, EclVarId *eclVarId, EclValueType *valueType) +i32 *GetVar(Enemy *enemy, EclVarId *eclVarId, EclValueType *valueType) { if (valueType != NULL) *valueType = ECL_VALUE_TYPE_UNDEFINED; @@ -232,10 +234,10 @@ i32 *Enemy::GetVar(Enemy *enemy, EclVarId *eclVarId, EclValueType *valueType) return (i32 *)eclVarId; } -f32 *Enemy::GetVarFloat(Enemy *enemy, f32 *eclVarId, EclValueType *valueType) +f32 *GetVarFloat(Enemy *enemy, f32 *eclVarId, EclValueType *valueType) { i32 varId = *eclVarId; - i32 *res = Enemy::GetVar(enemy, (EclVarId *)&varId, valueType); + i32 *res = GetVar(enemy, (EclVarId *)&varId, valueType); if (res == &varId) { return eclVarId; @@ -247,13 +249,13 @@ f32 *Enemy::GetVarFloat(Enemy *enemy, f32 *eclVarId, EclValueType *valueType) } #pragma var_order(lhsPtr, rhsPtr, lhsType) -void Enemy::SetVar(Enemy *enemy, EclVarId lhs, void *rhs) +void SetVar(Enemy *enemy, EclVarId lhs, void *rhs) { i32 *lhsPtr; EclValueType lhsType; i32 *rhsPtr; - rhsPtr = Enemy::GetVar(enemy, (EclVarId *)rhs, NULL); + rhsPtr = GetVar(enemy, (EclVarId *)rhs, NULL); lhsPtr = GetVar(enemy, &lhs, &lhsType); if (lhsType == ECL_VALUE_TYPE_INT) { @@ -267,7 +269,7 @@ void Enemy::SetVar(Enemy *enemy, EclVarId lhs, void *rhs) } #pragma var_order(outPtr, rhsPtr, lhsPtr, outType) -void Enemy::MathAdd(Enemy *enemy, EclVarId outVarId, EclVarId *lhsVarId, EclVarId *rhsVarId) +void MathAdd(Enemy *enemy, EclVarId outVarId, EclVarId *lhsVarId, EclVarId *rhsVarId) { EclValueType outType; i32 *outPtr; @@ -275,141 +277,141 @@ void Enemy::MathAdd(Enemy *enemy, EclVarId outVarId, EclVarId *lhsVarId, EclVarI i32 *rhsPtr; // Get output variable. - outPtr = Enemy::GetVar(enemy, &outVarId, &outType); + outPtr = GetVar(enemy, &outVarId, &outType); if (outType == ECL_VALUE_TYPE_INT) { - lhsPtr = Enemy::GetVar(enemy, lhsVarId, NULL); - rhsPtr = Enemy::GetVar(enemy, rhsVarId, NULL); + lhsPtr = GetVar(enemy, lhsVarId, NULL); + rhsPtr = GetVar(enemy, rhsVarId, NULL); *outPtr = *lhsPtr + *rhsPtr; } else if (outType == ECL_VALUE_TYPE_FLOAT) { - lhsPtr = (i32 *)Enemy::GetVarFloat(enemy, (f32 *)lhsVarId, NULL); - rhsPtr = (i32 *)Enemy::GetVarFloat(enemy, (f32 *)rhsVarId, NULL); + lhsPtr = (i32 *)GetVarFloat(enemy, (f32 *)lhsVarId, NULL); + rhsPtr = (i32 *)GetVarFloat(enemy, (f32 *)rhsVarId, NULL); *(f32 *)outPtr = *(f32 *)lhsPtr + *(f32 *)rhsPtr; } return; } #pragma var_order(outPtr, rhsPtr, lhsPtr, outType) -void Enemy::MathSub(Enemy *enemy, EclVarId outVarId, EclVarId *lhsVarId, EclVarId *rhsVarId) +void MathSub(Enemy *enemy, EclVarId outVarId, EclVarId *lhsVarId, EclVarId *rhsVarId) { EclValueType outType; i32 *outPtr; i32 *lhsPtr; i32 *rhsPtr; - outPtr = Enemy::GetVar(enemy, &outVarId, &outType); + outPtr = GetVar(enemy, &outVarId, &outType); if (outType == ECL_VALUE_TYPE_INT) { - lhsPtr = Enemy::GetVar(enemy, lhsVarId, NULL); - rhsPtr = Enemy::GetVar(enemy, rhsVarId, NULL); + lhsPtr = GetVar(enemy, lhsVarId, NULL); + rhsPtr = GetVar(enemy, rhsVarId, NULL); *outPtr = *lhsPtr - *rhsPtr; } else if (outType == ECL_VALUE_TYPE_FLOAT) { - lhsPtr = (i32 *)Enemy::GetVarFloat(enemy, (f32 *)lhsVarId, NULL); - rhsPtr = (i32 *)Enemy::GetVarFloat(enemy, (f32 *)rhsVarId, NULL); + lhsPtr = (i32 *)GetVarFloat(enemy, (f32 *)lhsVarId, NULL); + rhsPtr = (i32 *)GetVarFloat(enemy, (f32 *)rhsVarId, NULL); *(f32 *)outPtr = *(f32 *)lhsPtr - *(f32 *)rhsPtr; } return; } #pragma var_order(outPtr, rhsPtr, lhsPtr, outType) -void Enemy::MathMul(Enemy *enemy, EclVarId outVarId, EclVarId *lhsVarId, EclVarId *rhsVarId) +void MathMul(Enemy *enemy, EclVarId outVarId, EclVarId *lhsVarId, EclVarId *rhsVarId) { EclValueType outType; i32 *outPtr; i32 *lhsPtr; i32 *rhsPtr; - lhsPtr = Enemy::GetVar(enemy, lhsVarId, NULL); - rhsPtr = Enemy::GetVar(enemy, rhsVarId, NULL); - outPtr = Enemy::GetVar(enemy, &outVarId, &outType); + lhsPtr = GetVar(enemy, lhsVarId, NULL); + rhsPtr = GetVar(enemy, rhsVarId, NULL); + outPtr = GetVar(enemy, &outVarId, &outType); if (outType == ECL_VALUE_TYPE_INT) { - lhsPtr = Enemy::GetVar(enemy, lhsVarId, NULL); - rhsPtr = Enemy::GetVar(enemy, rhsVarId, NULL); + lhsPtr = GetVar(enemy, lhsVarId, NULL); + rhsPtr = GetVar(enemy, rhsVarId, NULL); *outPtr = *lhsPtr * *rhsPtr; } else if (outType == ECL_VALUE_TYPE_FLOAT) { - lhsPtr = (i32 *)Enemy::GetVarFloat(enemy, (f32 *)lhsVarId, NULL); - rhsPtr = (i32 *)Enemy::GetVarFloat(enemy, (f32 *)rhsVarId, NULL); + lhsPtr = (i32 *)GetVarFloat(enemy, (f32 *)lhsVarId, NULL); + rhsPtr = (i32 *)GetVarFloat(enemy, (f32 *)rhsVarId, NULL); *(f32 *)outPtr = *(f32 *)lhsPtr * *(f32 *)rhsPtr; } return; } #pragma var_order(outPtr, rhsPtr, lhsPtr, outType) -void Enemy::MathDiv(Enemy *enemy, EclVarId outVarId, EclVarId *lhsVarId, EclVarId *rhsVarId) +void MathDiv(Enemy *enemy, EclVarId outVarId, EclVarId *lhsVarId, EclVarId *rhsVarId) { EclValueType outType; i32 *outPtr; i32 *lhsPtr; i32 *rhsPtr; - outPtr = Enemy::GetVar(enemy, &outVarId, &outType); + outPtr = GetVar(enemy, &outVarId, &outType); if (outType == ECL_VALUE_TYPE_INT) { - lhsPtr = Enemy::GetVar(enemy, lhsVarId, NULL); - rhsPtr = Enemy::GetVar(enemy, rhsVarId, NULL); + lhsPtr = GetVar(enemy, lhsVarId, NULL); + rhsPtr = GetVar(enemy, rhsVarId, NULL); *outPtr = *lhsPtr / *rhsPtr; } else if (outType == ECL_VALUE_TYPE_FLOAT) { - lhsPtr = (i32 *)Enemy::GetVarFloat(enemy, (f32 *)lhsVarId, NULL); - rhsPtr = (i32 *)Enemy::GetVarFloat(enemy, (f32 *)rhsVarId, NULL); + lhsPtr = (i32 *)GetVarFloat(enemy, (f32 *)lhsVarId, NULL); + rhsPtr = (i32 *)GetVarFloat(enemy, (f32 *)rhsVarId, NULL); *(f32 *)outPtr = *(f32 *)lhsPtr / *(f32 *)rhsPtr; } return; } #pragma var_order(outPtr, rhsPtr, lhsPtr, outType) -void Enemy::MathMod(Enemy *enemy, EclVarId outVarId, EclVarId *lhsVarId, EclVarId *rhsVarId) +void MathMod(Enemy *enemy, EclVarId outVarId, EclVarId *lhsVarId, EclVarId *rhsVarId) { EclValueType outType; i32 *outPtr; i32 *lhsPtr; i32 *rhsPtr; - outPtr = Enemy::GetVar(enemy, &outVarId, &outType); + outPtr = GetVar(enemy, &outVarId, &outType); if (outType == ECL_VALUE_TYPE_INT) { - lhsPtr = Enemy::GetVar(enemy, lhsVarId, NULL); - rhsPtr = Enemy::GetVar(enemy, rhsVarId, NULL); + lhsPtr = GetVar(enemy, lhsVarId, NULL); + rhsPtr = GetVar(enemy, rhsVarId, NULL); *outPtr = *lhsPtr % *rhsPtr; } else if (outType == ECL_VALUE_TYPE_FLOAT) { - lhsPtr = (i32 *)Enemy::GetVarFloat(enemy, (f32 *)lhsVarId, NULL); - rhsPtr = (i32 *)Enemy::GetVarFloat(enemy, (f32 *)rhsVarId, NULL); + lhsPtr = (i32 *)GetVarFloat(enemy, (f32 *)lhsVarId, NULL); + rhsPtr = (i32 *)GetVarFloat(enemy, (f32 *)rhsVarId, NULL); *(f32 *)outPtr = fmodf(*(f32 *)lhsPtr, *(f32 *)rhsPtr); } return; } #pragma var_order(y2Ptr, outPtr, x1Ptr, y1Ptr, outType, x2Ptr) -void Enemy::MathAtan2(Enemy *enemy, EclVarId outVarId, f32 *x1, f32 *y1, f32 *y2, f32 *x2) +void MathAtan2(Enemy *enemy, EclVarId outVarId, f32 *x1, f32 *y1, f32 *y2, f32 *x2) { EclValueType outType; f32 *outPtr; f32 *y1Ptr, *x1Ptr, *x2Ptr, *y2Ptr; - outPtr = (f32 *)Enemy::GetVar(enemy, &outVarId, &outType); + outPtr = (f32 *)GetVar(enemy, &outVarId, &outType); if (outType == ECL_VALUE_TYPE_FLOAT) { - y1Ptr = Enemy::GetVarFloat(enemy, x1, NULL); - x1Ptr = Enemy::GetVarFloat(enemy, y1, NULL); - y2Ptr = Enemy::GetVarFloat(enemy, y2, NULL); - x2Ptr = Enemy::GetVarFloat(enemy, x2, NULL); + y1Ptr = GetVarFloat(enemy, x1, NULL); + x1Ptr = GetVarFloat(enemy, y1, NULL); + y2Ptr = GetVarFloat(enemy, y2, NULL); + x2Ptr = GetVarFloat(enemy, x2, NULL); *outPtr = atan2f(*x2Ptr - *x1Ptr, *y2Ptr - *y1Ptr); } return; } #pragma var_order(i, currentBullet, effectIndex, velocityVector, bulletTimer, accelerationMultiplier, accelerationAngle) -void Enemy::ExInsCirnoRainbowBallJank(Enemy *enemy, EclRawInstr *instr) +void ExInsCirnoRainbowBallJank(Enemy *enemy, EclRawInstr *instr) { f32 accelerationAngle; f32 accelerationMultiplier; @@ -458,7 +460,7 @@ void Enemy::ExInsCirnoRainbowBallJank(Enemy *enemy, EclRawInstr *instr) } } -void Enemy::ExInsShootAtRandomArea(Enemy *enemy, EclRawInstr *instr) +void ExInsShootAtRandomArea(Enemy *enemy, EclRawInstr *instr) { f32 bulletSpeed; @@ -474,7 +476,7 @@ void Enemy::ExInsShootAtRandomArea(Enemy *enemy, EclRawInstr *instr) #pragma var_order(i, propsSpeedBackup, starPatterTarget1, targetDistance, starPatternTarget0, patternPosition, \ baseTargetPosition) -void Enemy::ExInsShootStarPattern(Enemy *enemy, EclRawInstr *instr) +void ExInsShootStarPattern(Enemy *enemy, EclRawInstr *instr) { // Variable names are more quick guesses at functionality than anything else, they should not be trusted D3DXVECTOR3 baseTargetPosition; @@ -538,7 +540,7 @@ void Enemy::ExInsShootStarPattern(Enemy *enemy, EclRawInstr *instr) enemy->currentContext.var2++; } -void Enemy::ExInsPatchouliShottypeSetVars(Enemy *enemy, EclRawInstr *instr) +void ExInsPatchouliShottypeSetVars(Enemy *enemy, EclRawInstr *instr) { enemy->currentContext.var1 = g_PatchouliShottypeVars[g_GameManager.character].shotVars[g_GameManager.shotType].var1; enemy->currentContext.var2 = g_PatchouliShottypeVars[g_GameManager.character].shotVars[g_GameManager.shotType].var2; @@ -546,7 +548,7 @@ void Enemy::ExInsPatchouliShottypeSetVars(Enemy *enemy, EclRawInstr *instr) } #pragma var_order(playerBulletOffset, bulletsLeft, i, currentBullet) -void Enemy::ExInsStage56Func4(Enemy *enemy, EclRawInstr *instr) +void ExInsStage56Func4(Enemy *enemy, EclRawInstr *instr) { i32 bulletsLeft; Bullet *currentBullet; @@ -649,7 +651,7 @@ void Enemy::ExInsStage56Func4(Enemy *enemy, EclRawInstr *instr) #pragma var_order(patternPosition, i, bulletProps, sinOut, bpPositionOffset, matrixOutSeed, matrixIn, bulletAngle, \ cosOut, matrixInSeed, matrixOut) -void Enemy::ExInsStage5Func5(Enemy *enemy, EclRawInstr *instr) +void ExInsStage5Func5(Enemy *enemy, EclRawInstr *instr) { D3DXVECTOR3 bpPositionOffset; f32 bulletAngle; @@ -732,7 +734,7 @@ void Enemy::ExInsStage5Func5(Enemy *enemy, EclRawInstr *instr) } #pragma var_order(effect, baseAngleModifier, distanceModifier, finalAngle, particlePos) -void Enemy::ExInsStage6XFunc6(Enemy *enemy, EclRawInstr *instr) +void ExInsStage6XFunc6(Enemy *enemy, EclRawInstr *instr) { i32 baseAngleModifier; f32 distanceModifier; @@ -742,7 +744,7 @@ void Enemy::ExInsStage6XFunc6(Enemy *enemy, EclRawInstr *instr) if (enemy->flags.unk15 != 0) { - ResetEffectArray(enemy); + Enemy::ResetEffectArray(enemy); return; } enemy->exInsFunc6Angle += RADIANS(1.0f); @@ -790,7 +792,7 @@ void Enemy::ExInsStage6XFunc6(Enemy *enemy, EclRawInstr *instr) #pragma var_order(laserProps, i, lengthMultiplier, attackType, innerLoopCount, angleDiff, outerLoopCount, laserAngle, \ randomAngleModifier, positionVectors) -void Enemy::ExInsStage6Func7(Enemy *enemy, EclRawInstr *instr) +void ExInsStage6Func7(Enemy *enemy, EclRawInstr *instr) { f32 angleDiff; i32 attackType; @@ -909,7 +911,7 @@ void Enemy::ExInsStage6Func7(Enemy *enemy, EclRawInstr *instr) } #pragma var_order(bulletProps, changedBullets, i, currentBullet) -void Enemy::ExInsStage6Func8(Enemy *enemy, EclRawInstr *instr) +void ExInsStage6Func8(Enemy *enemy, EclRawInstr *instr) { EnemyBulletShooter bulletProps; i32 changedBullets; @@ -948,7 +950,7 @@ void Enemy::ExInsStage6Func8(Enemy *enemy, EclRawInstr *instr) } #pragma var_order(unusedBulletProps, i, local64, currentBullet, randomAngleModifier) -void Enemy::ExInsStage6Func9(Enemy *enemy, EclRawInstr *instr) +void ExInsStage6Func9(Enemy *enemy, EclRawInstr *instr) { Bullet *currentBullet; f32 distance; @@ -996,7 +998,7 @@ void Enemy::ExInsStage6Func9(Enemy *enemy, EclRawInstr *instr) } #pragma var_order(unusedBulletProps, i, currentBullet, unusedRandomNumber) -void Enemy::ExInsStage6Func11(Enemy *enemy, EclRawInstr *instr) +void ExInsStage6Func11(Enemy *enemy, EclRawInstr *instr) { Bullet *currentBullet; i32 i; @@ -1032,7 +1034,7 @@ void Enemy::ExInsStage6Func11(Enemy *enemy, EclRawInstr *instr) } } -void Enemy::ExInsStage6XFunc10(Enemy *enemy, EclRawInstr *instr) +void ExInsStage6XFunc10(Enemy *enemy, EclRawInstr *instr) { if (enemy->life <= 0) { @@ -1066,7 +1068,7 @@ void Enemy::ExInsStage6XFunc10(Enemy *enemy, EclRawInstr *instr) } } -void Enemy::ExInsStage4Func12(Enemy *enemy, EclRawInstr *instr) +void ExInsStage4Func12(Enemy *enemy, EclRawInstr *instr) { i32 i; @@ -1083,7 +1085,7 @@ void Enemy::ExInsStage4Func12(Enemy *enemy, EclRawInstr *instr) } #pragma var_order(i, bulletProps, basePatternAngle, numPatterns) -void Enemy::ExInsStageXFunc13(Enemy *enemy, EclRawInstr *instr) +void ExInsStageXFunc13(Enemy *enemy, EclRawInstr *instr) { f32 basePatternAngle; EnemyBulletShooter bulletProps; @@ -1108,7 +1110,7 @@ void Enemy::ExInsStageXFunc13(Enemy *enemy, EclRawInstr *instr) } #pragma var_order(bulletPosition, i, angleSin, currentLaser, angleCos, positionMultiplier) -void Enemy::ExInsStageXFunc14(Enemy *enemy, EclRawInstr *instr) +void ExInsStageXFunc14(Enemy *enemy, EclRawInstr *instr) { f32 angleCos; f32 angleSin; @@ -1143,7 +1145,7 @@ void Enemy::ExInsStageXFunc14(Enemy *enemy, EclRawInstr *instr) #pragma var_order(unusedBulletProps, totalIterations, i, innerBullet, enemyAngle, distance, currentBullet, \ bulletsAngle, j) -void Enemy::ExInsStageXFunc15(Enemy *enemy, EclRawInstr *instr) +void ExInsStageXFunc15(Enemy *enemy, EclRawInstr *instr) { f32 bulletsAngle; Bullet *currentBullet; @@ -1209,7 +1211,7 @@ void Enemy::ExInsStageXFunc15(Enemy *enemy, EclRawInstr *instr) } #pragma var_order(remainingLife, rangeModifier) -void Enemy::ExInsStageXFunc16(Enemy *enemy, EclRawInstr *instr) +void ExInsStageXFunc16(Enemy *enemy, EclRawInstr *instr) { f32 rangeModifier; i32 remainingLife; @@ -1233,4 +1235,5 @@ void Enemy::ExInsStageXFunc16(Enemy *enemy, EclRawInstr *instr) enemy->currentContext.float3 = g_Rng.GetRandomF32InRange(rangeModifier) + (96.0f - rangeModifier / 2.0f); } } +}; // namespace EnemyEclInstr }; // namespace th06 diff --git a/src/EnemyEclInstr.hpp b/src/EnemyEclInstr.hpp new file mode 100644 index 00000000..ec543a87 --- /dev/null +++ b/src/EnemyEclInstr.hpp @@ -0,0 +1,42 @@ +#pragma once + +#include "Enemy.hpp" + +namespace th06 +{ +namespace EnemyEclInstr +{ +i32 *GetVar(Enemy *enemy, EclVarId *varId, EclValueType *valueType); +f32 *GetVarFloat(Enemy *enemy, f32 *varId, EclValueType *valueType); +void SetVar(Enemy *enemy, EclVarId lhs, void *rhs); + +void MathAdd(Enemy *enemy, EclVarId out, EclVarId *lhs, EclVarId *rhs); +void MathSub(Enemy *enemy, EclVarId out, EclVarId *lhs, EclVarId *rhs); +void MathMul(Enemy *enemy, EclVarId out, EclVarId *lhs, EclVarId *rhs); +void MathDiv(Enemy *enemy, EclVarId out, EclVarId *lhs, EclVarId *rhs); +void MathMod(Enemy *enemy, EclVarId out, EclVarId *lhs, EclVarId *rhs); +void MathAtan2(Enemy *enemy, EclVarId out, f32 *a1, f32 *a2, f32 *b1, f32 *b2); + +void MoveDirTime(Enemy *enemy, EclRawInstr *instr); +void MovePosTime(Enemy *enemy, EclRawInstr *instr); +void MoveTime(Enemy *enemy, EclRawInstr *instr); + +void ExInsCirnoRainbowBallJank(Enemy *enemy, EclRawInstr *instr); +void ExInsShootAtRandomArea(Enemy *enemy, EclRawInstr *instr); +void ExInsShootStarPattern(Enemy *enemy, EclRawInstr *instr); +void ExInsPatchouliShottypeSetVars(Enemy *enemy, EclRawInstr *instr); +void ExInsStage56Func4(Enemy *enemy, EclRawInstr *instr); +void ExInsStage5Func5(Enemy *enemy, EclRawInstr *instr); +void ExInsStage6XFunc6(Enemy *enemy, EclRawInstr *instr); +void ExInsStage6Func7(Enemy *enemy, EclRawInstr *instr); +void ExInsStage6Func8(Enemy *enemy, EclRawInstr *instr); +void ExInsStage6Func9(Enemy *enemy, EclRawInstr *instr); +void ExInsStage6Func11(Enemy *enemy, EclRawInstr *instr); +void ExInsStage6XFunc10(Enemy *enemy, EclRawInstr *instr); +void ExInsStage4Func12(Enemy *enemy, EclRawInstr *instr); +void ExInsStageXFunc13(Enemy *enemy, EclRawInstr *instr); +void ExInsStageXFunc14(Enemy *enemy, EclRawInstr *instr); +void ExInsStageXFunc15(Enemy *enemy, EclRawInstr *instr); +void ExInsStageXFunc16(Enemy *enemy, EclRawInstr *instr); +}; // namespace EnemyEclInstr +}; // namespace th06