From b5ad92eb2cecf361bcd1c1c695dd65496ce96bc6 Mon Sep 17 00:00:00 2001 From: obligaron Date: Mon, 14 Jun 2021 20:32:49 +0200 Subject: [PATCH] Convert _mAnimData to CelSprite --- Source/dead.cpp | 6 ++++-- Source/dead.h | 2 +- Source/missiles.cpp | 11 ++++++----- Source/missiles.h | 2 +- Source/monster.cpp | 38 +++++++++++++++++++++----------------- Source/monster.h | 6 +++--- Source/scrollrt.cpp | 12 +++++++----- 7 files changed, 43 insertions(+), 34 deletions(-) diff --git a/Source/dead.cpp b/Source/dead.cpp index 007e3d34f..35842f327 100644 --- a/Source/dead.cpp +++ b/Source/dead.cpp @@ -18,9 +18,11 @@ int8_t stonendx; namespace { void InitDeadAnimationFromMonster(DeadStruct &d, const CMonster &mon) { - d._deadData = mon.Anims[MA_DEATH].Data; + int i = 0; + for (auto &celSprite : mon.Anims[MA_DEATH].CelSpritesForDirections) + d._deadData[i++] = celSprite->Data(); d._deadFrame = mon.Anims[MA_DEATH].Frames; - d._deadWidth = mon.width; + d._deadWidth = mon.Anims[MA_DEATH].CelSpritesForDirections[0]->Width(); } } diff --git a/Source/dead.h b/Source/dead.h index 71bff9e79..ebe95eb82 100644 --- a/Source/dead.h +++ b/Source/dead.h @@ -15,7 +15,7 @@ namespace devilution { static constexpr unsigned MaxDead = 31; struct DeadStruct { - std::array _deadData; + std::array _deadData; int _deadFrame; int _deadWidth; uint8_t _deadtrans; diff --git a/Source/missiles.cpp b/Source/missiles.cpp index 278192fb5..60e581c73 100644 --- a/Source/missiles.cpp +++ b/Source/missiles.cpp @@ -2497,11 +2497,12 @@ void InitMissileAnimationFromMonster(MissileStruct &mis, int midir, const Monste const AnimStruct &anim = mon.MType->Anims[graphic]; mis._mimfnum = midir; mis._miAnimFlags = 0; - mis._miAnimData = anim.Data[midir]; + auto& celSprite = *anim.CelSpritesForDirections[midir]; + mis._miAnimData = celSprite.Data(); mis._miAnimDelay = anim.Rate; mis._miAnimLen = anim.Frames; - mis._miAnimWidth = mon.MType->width; - mis._miAnimWidth2 = CalculateWidth2(mon.MType->width); + mis._miAnimWidth = celSprite.Width(); + mis._miAnimWidth2 = CalculateWidth2(celSprite.Width()); mis._miAnimAdd = 1; mis._miVar1 = 0; mis._miVar2 = 0; @@ -4646,7 +4647,7 @@ void MI_Fireman(int i) if (!PosOkMissile(0, b) || (j > 0 && !(missile[i]._miVar1 & 1))) { missile[i].position.velocity *= -1; missile[i]._mimfnum = opposite[missile[i]._mimfnum]; - missile[i]._miAnimData = monster[src].MType->Anims[MA_WALK].Data[missile[i]._mimfnum]; + missile[i]._miAnimData = monster[src].MType->Anims[MA_WALK].CelSpritesForDirections[missile[i]._mimfnum]->Data(); missile[i]._miVar2++; if (j > 0) missile[i]._miVar1 |= 1; @@ -5192,7 +5193,7 @@ void missiles_process_charge() else anim = &mon->Anims[MA_WALK]; } - missile[mi]._miAnimData = anim->Data[mis->_mimfnum]; + missile[mi]._miAnimData = anim->CelSpritesForDirections[mis->_mimfnum]->Data(); } } } diff --git a/Source/missiles.h b/Source/missiles.h index f75a30d8b..d1fa4c1d2 100644 --- a/Source/missiles.h +++ b/Source/missiles.h @@ -42,7 +42,7 @@ struct MissileStruct { bool _miDelFlag; // Indicate whether the missile should be deleted uint8_t _miAnimType; int _miAnimFlags; - byte *_miAnimData; + const byte *_miAnimData; int _miAnimDelay; // Tick length of each frame in the current animation int _miAnimLen; // Number of frames in current animation int _miAnimWidth; diff --git a/Source/monster.cpp b/Source/monster.cpp index 3521a65e9..cfe398c4c 100644 --- a/Source/monster.cpp +++ b/Source/monster.cpp @@ -157,7 +157,7 @@ void InitMonsterTRN(CMonster &monst) for (int j = 0; j < 8; j++) { Cl2ApplyTrans( - monst.Anims[i].Data[j], + CelGetFrameStart(monst.Anims[i].CMem.get(), j), colorTranslations, monst.Anims[i].Frames); } @@ -337,6 +337,7 @@ void InitMonsterGFX(int monst) char strBuff[256]; mtype = Monsters[monst].mtype; + int width = monsterdata[mtype].width; for (anim = 0; anim < 6; anim++) { int frames = monsterdata[mtype].Frames[anim]; @@ -356,11 +357,12 @@ void InitMonsterGFX(int monst) if (Monsters[monst].mtype != MT_GOLEM || (animletter[anim] != 's' && animletter[anim] != 'd')) { for (i = 0; i < 8; i++) { - Monsters[monst].Anims[anim].Data[i] = CelGetFrameStart(celBuf, i); + byte *pCelStart = CelGetFrameStart(celBuf, i); + Monsters[monst].Anims[anim].CelSpritesForDirections[i].emplace(pCelStart, width); } } else { for (i = 0; i < 8; i++) { - Monsters[monst].Anims[anim].Data[i] = celBuf; + Monsters[monst].Anims[anim].CelSpritesForDirections[i].emplace(celBuf, width); } } } @@ -369,7 +371,6 @@ void InitMonsterGFX(int monst) Monsters[monst].Anims[anim].Rate = monsterdata[mtype].Rate[anim]; } - Monsters[monst].width = monsterdata[mtype].width; Monsters[monst].mMinHP = monsterdata[mtype].mMinHP; Monsters[monst].mMaxHP = monsterdata[mtype].mMaxHP; if (!gbIsHellfire && mtype == MT_DIABLO) { @@ -481,7 +482,7 @@ void InitMonster(int i, Direction rd, int mtype, Point position) monster[i].mName = _(monst->MData->mName); monster[i].MType = monst; monster[i].MData = monst->MData; - monster[i]._mAnimData = monst->Anims[MA_STAND].Data[rd]; + monster[i]._mAnimData = monst->Anims[MA_STAND].CelSpritesForDirections[rd] ? &*monst->Anims[MA_STAND].CelSpritesForDirections[rd] : nullptr; monster[i]._mAnimDelay = monst->Anims[MA_STAND].Rate; monster[i]._mAnimCnt = GenerateRnd(monster[i]._mAnimDelay - 1); monster[i]._mAnimLen = monst->Anims[MA_STAND].Frames; @@ -531,7 +532,7 @@ void InitMonster(int i, Direction rd, int mtype, Point position) monster[i].mtalkmsg = TEXT_NONE; if (monster[i]._mAi == AI_GARG) { - monster[i]._mAnimData = monst->Anims[MA_SPECIAL].Data[rd]; + monster[i]._mAnimData = &*monst->Anims[MA_SPECIAL].CelSpritesForDirections[rd]; monster[i]._mAnimFrame = 1; monster[i]._mFlags |= MFLAG_ALLOW_SPECIAL; monster[i]._mmode = MM_SATTACK; @@ -886,7 +887,7 @@ void PlaceUniqueMonst(int uniqindex, int miniontype, int bosspacksize) } if (Monst->_mAi != AI_GARG) { - Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Data[Monst->_mdir]; + Monst->_mAnimData = &*Monst->MType->Anims[MA_STAND].CelSpritesForDirections[Monst->_mdir]; Monst->_mAnimFrame = GenerateRnd(Monst->_mAnimLen - 1) + 1; Monst->_mFlags &= ~MFLAG_ALLOW_SPECIAL; Monst->_mmode = MM_STAND; @@ -1058,7 +1059,7 @@ void PlaceGroup(int mtype, int num, int leaderf, int leader) } if (monster[nummonsters]._mAi != AI_GARG) { - monster[nummonsters]._mAnimData = monster[nummonsters].MType->Anims[MA_STAND].Data[monster[nummonsters]._mdir]; + monster[nummonsters]._mAnimData = &*monster[nummonsters].MType->Anims[MA_STAND].CelSpritesForDirections[monster[nummonsters]._mdir]; monster[nummonsters]._mAnimFrame = GenerateRnd(monster[nummonsters]._mAnimLen - 1) + 1; monster[nummonsters]._mFlags &= ~MFLAG_ALLOW_SPECIAL; monster[nummonsters]._mmode = MM_STAND; @@ -1268,7 +1269,7 @@ void monster_43C785(int i) void NewMonsterAnim(int i, AnimStruct *anim, Direction md) { MonsterStruct *Monst = &monster[i]; - Monst->_mAnimData = anim->Data[md]; + Monst->_mAnimData = &*anim->CelSpritesForDirections[md]; Monst->_mAnimLen = anim->Frames; Monst->_mAnimCnt = 0; Monst->_mAnimFrame = 1; @@ -1904,7 +1905,7 @@ void M_StartHeal(int i) assurance(monster[i].MType != nullptr, i); Monst = &monster[i]; - Monst->_mAnimData = Monst->MType->Anims[MA_SPECIAL].Data[Monst->_mdir]; + Monst->_mAnimData = &*Monst->MType->Anims[MA_SPECIAL].CelSpritesForDirections[Monst->_mdir]; Monst->_mAnimFrame = Monst->MType->Anims[MA_SPECIAL].Frames; Monst->_mFlags |= MFLAG_LOCK_ANIMATION; Monst->_mmode = MM_HEAL; @@ -1949,9 +1950,9 @@ bool M_DoStand(int i) Monst = &monster[i]; if (Monst->MType->mtype == MT_GOLEM) - Monst->_mAnimData = Monst->MType->Anims[MA_WALK].Data[Monst->_mdir]; + Monst->_mAnimData = &*Monst->MType->Anims[MA_WALK].CelSpritesForDirections[Monst->_mdir]; else - Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Data[Monst->_mdir]; + Monst->_mAnimData = &*Monst->MType->Anims[MA_STAND].CelSpritesForDirections[Monst->_mdir]; if (Monst->_mAnimFrame == Monst->_mAnimLen) M_Enemy(i); @@ -2666,7 +2667,7 @@ bool M_DoDelay(int i) commitment((DWORD)i < MAXMONSTERS, i); commitment(monster[i].MType != nullptr, i); - monster[i]._mAnimData = monster[i].MType->Anims[MA_STAND].Data[M_GetDir(i)]; + monster[i]._mAnimData = &*monster[i].MType->Anims[MA_STAND].CelSpritesForDirections[M_GetDir(i)]; if (monster[i]._mAi == AI_LAZURUS) { if (monster[i]._mVar2 > 8 || monster[i]._mVar2 < 0) monster[i]._mVar2 = 8; @@ -3244,7 +3245,7 @@ void MAI_Sneak(int i) } if (Monst->_mmode == MM_STAND) { if (abs(mx) >= 2 || abs(my) >= 2 || v >= 4 * Monst->_mint + 10) - Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Data[md]; + Monst->_mAnimData = &*Monst->MType->Anims[MA_STAND].CelSpritesForDirections[md]; else M_StartAttack(i); } @@ -3504,7 +3505,7 @@ void MAI_Ranged(int i, int missile_type, bool special) else M_StartRAttack(i, missile_type, 4); } else { - Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Data[md]; + Monst->_mAnimData = &*Monst->MType->Anims[MA_STAND].CelSpritesForDirections[md]; } } } else if (Monst->_msquelch != 0) { @@ -4855,7 +4856,10 @@ void SyncMonsterAnim(int i) break; } - monster[i]._mAnimData = monster[i].MType->Anims[graphic].Data[_mdir]; + if (monster[i].MType->Anims[graphic].CelSpritesForDirections[_mdir]) + monster[i]._mAnimData = &*monster[i].MType->Anims[graphic].CelSpritesForDirections[_mdir]; + else + monster[i]._mAnimData = nullptr; } void M_FallenFear(Point position) @@ -5431,7 +5435,7 @@ void decode_enemy(int m, int enemy) void MonsterStruct::CheckStandAnimationIsLoaded(int mdir) { if (_mmode == MM_STAND || _mmode == MM_TALK) - _mAnimData = MType->Anims[MA_STAND].Data[mdir]; + _mAnimData = &*MType->Anims[MA_STAND].CelSpritesForDirections[mdir]; } } // namespace devilution diff --git a/Source/monster.h b/Source/monster.h index 7b6ca3416..25592a82f 100644 --- a/Source/monster.h +++ b/Source/monster.h @@ -10,6 +10,7 @@ #include "engine.h" #include "miniwin/miniwin.h" +#include "utils/stdcompat/optional.hpp" #include "monstdat.h" #include "textdat.h" @@ -111,7 +112,7 @@ enum placeflag : uint8_t { struct AnimStruct { std::unique_ptr CMem; - std::array Data; + std::array, 8> CelSpritesForDirections; int Frames; int Rate; }; @@ -124,7 +125,6 @@ struct CMonster { #ifndef NOSOUND std::unique_ptr Snds[4][2]; #endif - int width; uint16_t mMinHP; uint16_t mMaxHP; bool has_special; @@ -148,7 +148,7 @@ struct MonsterStruct { // note: missing field _mAFNum int _menemy; /** Usually correspond's to the enemy's future position */ Point enemyPosition; - byte *_mAnimData; + CelSprite *_mAnimData; /** Tick length of each frame in the current animation */ int _mAnimDelay; /** Increases by one each game tick, counting how close we are to _pAnimDelay */ diff --git a/Source/scrollrt.cpp b/Source/scrollrt.cpp index 62d7b620c..06dc9a627 100644 --- a/Source/scrollrt.cpp +++ b/Source/scrollrt.cpp @@ -329,7 +329,7 @@ static void DrawMonster(const CelOutputBuffer &out, int x, int y, int mx, int my } int nCel = monster[m]._mAnimFrame; - auto frameTable = reinterpret_cast(monster[m]._mAnimData); + auto frameTable = reinterpret_cast(monster[m]._mAnimData->Data()); int frames = SDL_SwapLE32(frameTable[0]); if (nCel < 1 || frames > 50 || nCel > frames) { const char *szMode = "unknown action"; @@ -345,7 +345,7 @@ static void DrawMonster(const CelOutputBuffer &out, int x, int y, int mx, int my return; } - CelSprite cel { monster[m]._mAnimData, monster[m].MType->width }; + CelSprite &cel = *monster[m]._mAnimData; if ((dFlags[x][y] & BFLAG_LIT) == 0) { Cl2DrawLightTbl(out, mx, my, cel, monster[m]._mAnimFrame, 1); @@ -704,10 +704,12 @@ static void DrawMonsterHelper(const CelOutputBuffer &out, int x, int y, int oy, return; } - px = sx + pMonster->position.offset.x - CalculateWidth2(pMonster->MType->width); + const CelSprite &cel = *pMonster->_mAnimData; + + px = sx + pMonster->position.offset.x - CalculateWidth2(cel.Width()); py = sy + pMonster->position.offset.y; if (mi == pcursmonst) { - Cl2DrawOutline(out, 233, px, py, CelSprite(pMonster->_mAnimData, pMonster->MType->width), pMonster->_mAnimFrame); + Cl2DrawOutline(out, 233, px, py, cel, pMonster->_mAnimFrame); } DrawMonster(out, x, y, px, py, mi); } @@ -785,7 +787,7 @@ static void scrollrt_draw_dungeon(const CelOutputBuffer &out, int sx, int sy, in DeadStruct *pDeadGuy = &dead[(bDead & 0x1F) - 1]; auto dd = static_cast((bDead >> 5) & 7); int px = dx - CalculateWidth2(pDeadGuy->_deadWidth); - byte *pCelBuff = pDeadGuy->_deadData[dd]; + const byte *pCelBuff = pDeadGuy->_deadData[dd]; assert(pCelBuff != nullptr); auto frameTable = reinterpret_cast(pCelBuff); int frames = SDL_SwapLE32(frameTable[0]);