From d97131349eab2f901570c85c7200f9029651bc21 Mon Sep 17 00:00:00 2001 From: obligaron Date: Sun, 23 May 2021 14:55:24 +0200 Subject: [PATCH] Unify player_graphic memory handling --- Source/diablo.cpp | 2 +- Source/items.cpp | 9 +- Source/loadsave.cpp | 6 +- Source/msg.cpp | 8 +- Source/multi.cpp | 8 +- Source/player.cpp | 295 ++++++++++++++++--------------------------- Source/player.h | 71 +++++------ test/player_test.cpp | 1 - 8 files changed, 160 insertions(+), 240 deletions(-) diff --git a/Source/diablo.cpp b/Source/diablo.cpp index bbd9cca9c..490703e74 100644 --- a/Source/diablo.cpp +++ b/Source/diablo.cpp @@ -335,7 +335,7 @@ static void free_game() FreeStoreMem(); for (auto &player : plr) - FreePlayerGFX(player); + ResetPlayerGFX(player); FreeCursor(); #ifdef _DEBUG diff --git a/Source/items.cpp b/Source/items.cpp index a76b5b113..5280cd17a 100644 --- a/Source/items.cpp +++ b/Source/items.cpp @@ -884,13 +884,14 @@ void CalcPlrItemVals(int playerId, bool Loadgfx) if (player._pgfxnum != g && Loadgfx) { player._pgfxnum = g; - player._pGFXLoad = 0; + ResetPlayerGFX(player); SetPlrAnims(player); - LoadPlrGFX(player, static_cast(PFILE_STAND | PFILE_WALK)); if (player._pmode == PM_STAND) { - player.AnimInfo.ChangeAnimationData(&*player._pNAnim[player._pdir], player._pNFrames, 3); + LoadPlrGFX(player, player_graphic::Stand); + player.AnimInfo.ChangeAnimationData(&*player.AnimationData[static_cast(player_graphic::Stand)].CelSpritesForDirections[player._pdir], player._pNFrames, 3); } else { - player.AnimInfo.ChangeAnimationData(&*player._pWAnim[player._pdir], player._pWFrames, 0); + LoadPlrGFX(player, player_graphic::Walk); + player.AnimInfo.ChangeAnimationData(&*player.AnimationData[static_cast(player_graphic::Walk)].CelSpritesForDirections[player._pdir], player._pWFrames, 0); } } else { player._pgfxnum = g; diff --git a/Source/loadsave.cpp b/Source/loadsave.cpp index 210281722..5f11ed3a0 100644 --- a/Source/loadsave.cpp +++ b/Source/loadsave.cpp @@ -432,7 +432,8 @@ static void LoadPlayer(LoadHelper *file, int p) file->skip(2); // Alignment - pPlayer->_pGFXLoad = file->nextLE(); + // skip _pGFXLoad + file->skip(4); file->skip(4 * 8); // Skip pointers _pNAnim pPlayer->_pNFrames = file->nextLE(); // skip _pNWidth @@ -1428,7 +1429,8 @@ static void SavePlayer(SaveHelper *file, int p) file->skip(2); // Alignment - file->writeLE(pPlayer->_pGFXLoad); + // Write _pGFXLoad for vanilla compatibility + file->writeLE(0); file->skip(4 * 8); // Skip pointers _pNAnim file->writeLE(pPlayer->_pNFrames); // Skip _pNWidth diff --git a/Source/msg.cpp b/Source/msg.cpp index 1d3dbc55a..51afbf837 100644 --- a/Source/msg.cpp +++ b/Source/msg.cpp @@ -696,7 +696,7 @@ void DeltaSaveLevel() for (int i = 0; i < MAX_PLRS; i++) { if (i != myplr) - plr[i]._pGFXLoad = 0; + ResetPlayerGFX(plr[i]); } plr[myplr]._pLvlVisited[currlevel] = true; delta_leave_sync(currlevel); @@ -2225,7 +2225,7 @@ static DWORD On_PLAYER_JOINLEVEL(TCmd *pCmd, int pnum) else { plr[pnum]._pLvlChanging = false; if (plr[pnum]._pName[0] != 0 && !plr[pnum].plractive) { - InitPlrGFXMem(plr[pnum]); + ResetPlayerGFX(plr[pnum]); plr[pnum].plractive = true; gbActivePlayers++; EventPlrMsg(fmt::format(_("Player '{:s}' (level {:d}) just joined the game"), plr[pnum]._pName, plr[pnum]._pLevel).c_str()); @@ -2234,7 +2234,7 @@ static DWORD On_PLAYER_JOINLEVEL(TCmd *pCmd, int pnum) if (plr[pnum].plractive && myplr != pnum) { plr[pnum].position.tile = { p->x, p->y }; plr[pnum].plrlevel = p->wParam1; - plr[pnum]._pGFXLoad = 0; + ResetPlayerGFX(plr[pnum]); if (currlevel == plr[pnum].plrlevel) { SyncInitPlr(pnum); if ((plr[pnum]._pHitPoints >> 6) > 0) @@ -2242,7 +2242,7 @@ static DWORD On_PLAYER_JOINLEVEL(TCmd *pCmd, int pnum) else { plr[pnum]._pgfxnum = 0; plr[pnum]._pmode = PM_DEATH; - NewPlrAnim(plr[pnum], PFILE_DEATH, DIR_S, plr[pnum]._pDFrames, 1); + NewPlrAnim(plr[pnum], player_graphic::Death, DIR_S, plr[pnum]._pDFrames, 1); plr[pnum].AnimInfo.CurrentFrame = plr[pnum].AnimInfo.NumberOfFrames - 1; dFlags[plr[pnum].position.tile.x][plr[pnum].position.tile.y] |= BFLAG_DEAD_PLAYER; } diff --git a/Source/multi.cpp b/Source/multi.cpp index 322851838..06cb028bf 100644 --- a/Source/multi.cpp +++ b/Source/multi.cpp @@ -275,7 +275,7 @@ static void multi_player_left_msg(int pnum, bool left) } plr[pnum].plractive = false; plr[pnum]._pName[0] = '\0'; - FreePlayerGFX(plr[pnum]); + ResetPlayerGFX(plr[pnum]); gbActivePlayers--; } } @@ -749,7 +749,7 @@ bool NetInit(bool bSinglePlayer) SetupLocalCoords(); multi_send_pinfo(-2, CMD_SEND_PLRINFO); - InitPlrGFXMem(plr[myplr]); + ResetPlayerGFX(plr[myplr]); plr[myplr].plractive = true; gbActivePlayers = 1; @@ -855,7 +855,7 @@ void recv_plrinfo(int pnum, TCmdPlrInfoHdr *p, bool recv) return; } - InitPlrGFXMem(plr[pnum]); + ResetPlayerGFX(plr[pnum]); plr[pnum].plractive = true; gbActivePlayers++; @@ -874,7 +874,7 @@ void recv_plrinfo(int pnum, TCmdPlrInfoHdr *p, bool recv) } else { plr[pnum]._pgfxnum = 0; plr[pnum]._pmode = PM_DEATH; - NewPlrAnim(player, PFILE_DEATH, DIR_S, plr[pnum]._pDFrames, 1); + NewPlrAnim(player, player_graphic::Death, DIR_S, plr[pnum]._pDFrames, 1); plr[pnum].AnimInfo.CurrentFrame = plr[pnum].AnimInfo.NumberOfFrames - 1; dFlags[plr[pnum].position.tile.x][plr[pnum].position.tile.y] |= BFLAG_DEAD_PLAYER; } diff --git a/Source/player.cpp b/Source/player.cpp index 89d94f640..16788ee27 100644 --- a/Source/player.cpp +++ b/Source/player.cpp @@ -377,15 +377,15 @@ void PlayerStruct::Reset() int PlayerStruct::GetAnimationWidth(player_graphic graphic) { switch (graphic) { - case PFILE_STAND: + case player_graphic::Stand: if (_pClass == HeroClass::Monk) return 112; return 96; - case PFILE_WALK: + case player_graphic::Walk: if (_pClass == HeroClass::Monk) return 112; return 96; - case PFILE_ATTACK: + case player_graphic::Attack: if (_pClass == HeroClass::Monk) return 130; if (_pClass == HeroClass::Warrior || _pClass == HeroClass::Barbarian) { @@ -394,23 +394,23 @@ int PlayerStruct::GetAnimationWidth(player_graphic graphic) return 96; } return 128; - case PFILE_HIT: + case player_graphic::Hit: if (_pClass == HeroClass::Monk) return 98; return 96; - case PFILE_LIGHTNING: - case PFILE_FIRE: - case PFILE_MAGIC: + case player_graphic::Lightning: + case player_graphic::Fire: + case player_graphic::Magic: if (_pClass == HeroClass::Monk) return 114; if (_pClass == HeroClass::Sorcerer) return 128; return 96; - case PFILE_DEATH: + case player_graphic::Death: if (_pClass == HeroClass::Monk) return 160; return 128; - case PFILE_BLOCK: + case player_graphic::Block: if (_pClass == HeroClass::Monk) return 98; return 96; @@ -431,13 +431,11 @@ void SetPlayerGPtrs(const char *path, std::unique_ptr &data, std::array< } } -void LoadPlrGFX(PlayerStruct &player, player_graphic gfxflag) +void LoadPlrGFX(PlayerStruct &player, player_graphic graphic) { char prefix[16]; char pszName[256]; const char *szCel; - std::unique_ptr *pData; - std::array, 8> *pAnim; HeroClass c = player._pClass; if (c == HeroClass::Bard && hfbard_mpq == nullptr) { @@ -449,96 +447,61 @@ void LoadPlrGFX(PlayerStruct &player, player_graphic gfxflag) sprintf(prefix, "%c%c%c", CharChar[static_cast(c)], ArmourChar[player._pgfxnum >> 4], WepChar[player._pgfxnum & 0xF]); const char *cs = ClassPathTbl[static_cast(c)]; - for (unsigned i = 1; i <= PFILE_NONDEATH; i <<= 1) { - if ((i & gfxflag) == 0) { - continue; - } - - switch (i) { - case PFILE_STAND: - szCel = "AS"; - if (leveltype == DTYPE_TOWN) { - szCel = "ST"; - } - pData = &player._pNData; - pAnim = &player._pNAnim; - break; - case PFILE_WALK: - szCel = "AW"; - if (leveltype == DTYPE_TOWN) { - szCel = "WL"; - } - pData = &player._pWData; - pAnim = &player._pWAnim; - break; - case PFILE_ATTACK: - if (leveltype == DTYPE_TOWN) { - continue; - } - szCel = "AT"; - pData = &player._pAData; - pAnim = &player._pAAnim; - break; - case PFILE_HIT: - if (leveltype == DTYPE_TOWN) { - continue; - } - szCel = "HT"; - pData = &player._pHData; - pAnim = &player._pHAnim; - break; - case PFILE_LIGHTNING: - if (leveltype == DTYPE_TOWN) { - continue; - } - szCel = "LM"; - pData = &player._pLData; - pAnim = &player._pLAnim; - break; - case PFILE_FIRE: - if (leveltype == DTYPE_TOWN) { - continue; - } - szCel = "FM"; - pData = &player._pFData; - pAnim = &player._pFAnim; - break; - case PFILE_MAGIC: - if (leveltype == DTYPE_TOWN) { - continue; - } - szCel = "QM"; - pData = &player._pTData; - pAnim = &player._pTAnim; - break; - case PFILE_DEATH: - if ((player._pgfxnum & 0xF) != 0) { - continue; - } - szCel = "DT"; - pData = &player._pDData; - pAnim = &player._pDAnim; - break; - case PFILE_BLOCK: - if (leveltype == DTYPE_TOWN) { - continue; - } - if (!player._pBlockFlag) { - continue; - } - - szCel = "BL"; - pData = &player._pBData; - pAnim = &player._pBAnim; - break; - default: - app_fatal("PLR:2"); - } - - sprintf(pszName, "PlrGFX\\%s\\%s\\%s%s.CL2", cs, prefix, prefix, szCel); - SetPlayerGPtrs(pszName, *pData, *pAnim, player.GetAnimationWidth(static_cast(i))); - player._pGFXLoad |= i; + switch (graphic) { + case player_graphic::Stand: + szCel = "AS"; + if (leveltype == DTYPE_TOWN) + szCel = "ST"; + break; + case player_graphic::Walk: + szCel = "AW"; + if (leveltype == DTYPE_TOWN) + szCel = "WL"; + break; + case player_graphic::Attack: + if (leveltype == DTYPE_TOWN) + return; + szCel = "AT"; + break; + case player_graphic::Hit: + if (leveltype == DTYPE_TOWN) + return; + szCel = "HT"; + break; + case player_graphic::Lightning: + if (leveltype == DTYPE_TOWN) + return; + szCel = "LM"; + break; + case player_graphic::Fire: + if (leveltype == DTYPE_TOWN) + return; + szCel = "FM"; + break; + case player_graphic::Magic: + if (leveltype == DTYPE_TOWN) + return; + szCel = "QM"; + break; + case player_graphic::Death: + if ((player._pgfxnum & 0xF) != 0) + return; + szCel = "DT"; + break; + case player_graphic::Block: + if (leveltype == DTYPE_TOWN) + return; + if (!player._pBlockFlag) + return; + szCel = "BL"; + break; + default: + app_fatal("PLR:2"); } + + sprintf(pszName, "PlrGFX\\%s\\%s\\%s%s.CL2", cs, prefix, prefix, szCel); + auto &animationData = player.AnimationData[static_cast(graphic)]; + SetPlayerGPtrs(pszName, animationData.RawData, animationData.CelSpritesForDirections, player.GetAnimationWidth(graphic)); } void InitPlayerGFX(int pnum) @@ -550,9 +513,14 @@ void InitPlayerGFX(int pnum) if (player._pHitPoints >> 6 == 0) { player._pgfxnum = 0; - LoadPlrGFX(player, PFILE_DEATH); + LoadPlrGFX(player, player_graphic::Death); } else { - LoadPlrGFX(player, PFILE_NONDEATH); + for (int i = 0; i < enum_size::value; i++) { + auto graphic = static_cast(i); + if (graphic == player_graphic::Death) + continue; + LoadPlrGFX(player, graphic); + } } } @@ -568,67 +536,26 @@ static HeroClass GetPlrGFXClass(HeroClass c) } } -void InitPlrGFXMem(PlayerStruct &player) +void ResetPlayerGFX(PlayerStruct &player) { - FreePlayerGFX(player); -} - -void FreePlayerGFX(PlayerStruct &player) -{ - player._pNData = nullptr; - player._pWData = nullptr; - player._pAData = nullptr; - player._pHData = nullptr; - player._pLData = nullptr; - player._pFData = nullptr; - player._pTData = nullptr; - player._pDData = nullptr; - player._pBData = nullptr; - player._pGFXLoad = 0; + player.AnimInfo.pCelSprite = nullptr; + for (auto &animData : player.AnimationData) { + for (auto &celSprite : animData.CelSpritesForDirections) + celSprite = std::nullopt; + animData.RawData = nullptr; + } } void NewPlrAnim(PlayerStruct &player, player_graphic graphic, Direction dir, int numberOfFrames, int delayLen, AnimationDistributionFlags flags /*= AnimationDistributionFlags::None*/, int numSkippedFrames /*= 0*/, int distributeFramesBeforeFrame /*= 0*/) { - if ((player._pGFXLoad & graphic) != graphic) + if (player.AnimationData[static_cast(graphic)].RawData == nullptr) LoadPlrGFX(player, graphic); - std::array, 8> *pCelSprites = nullptr; - switch (graphic) { - case PFILE_STAND: - pCelSprites = &player._pNAnim; - break; - case PFILE_WALK: - pCelSprites = &player._pWAnim; - break; - case PFILE_ATTACK: - pCelSprites = &player._pAAnim; - break; - case PFILE_HIT: - pCelSprites = &player._pHAnim; - break; - case PFILE_LIGHTNING: - pCelSprites = &player._pLAnim; - break; - case PFILE_FIRE: - pCelSprites = &player._pFAnim; - break; - case PFILE_MAGIC: - pCelSprites = &player._pTAnim; - break; - case PFILE_DEATH: - pCelSprites = &player._pDAnim; - break; - case PFILE_BLOCK: - pCelSprites = &player._pBAnim; - break; - default: - Log("NewPlrAnim: Unkown graphic {}", graphic); - break; - } + auto &CelSprites = player.AnimationData[static_cast(graphic)].CelSpritesForDirections; CelSprite *pCelSprite = nullptr; - if (pCelSprites != nullptr && (*pCelSprites)[dir]) - pCelSprite = &*(*pCelSprites)[dir]; + if (CelSprites[dir]) + pCelSprite = &*CelSprites[dir]; player.AnimInfo.SetNewAnimation(pCelSprite, numberOfFrames, delayLen, flags, numSkippedFrames, distributeFramesBeforeFrame); } @@ -1120,12 +1047,12 @@ void InitPlayer(int pnum, bool FirstTime) if (player._pHitPoints >> 6 > 0) { player._pmode = PM_STAND; - NewPlrAnim(player, PFILE_STAND, DIR_S, player._pNFrames, 3); + NewPlrAnim(player, player_graphic::Stand, DIR_S, player._pNFrames, 3); player.AnimInfo.CurrentFrame = GenerateRnd(player._pNFrames - 1) + 1; player.AnimInfo.DelayCounter = GenerateRnd(3); } else { player._pmode = PM_DEATH; - NewPlrAnim(player, PFILE_DEATH, DIR_S, player._pDFrames, 1); + NewPlrAnim(player, player_graphic::Death, DIR_S, player._pDFrames, 1); player.AnimInfo.CurrentFrame = player.AnimInfo.NumberOfFrames - 1; } @@ -1299,7 +1226,7 @@ void StartStand(int pnum, Direction dir) auto &player = plr[pnum]; if (!player._pInvincible || player._pHitPoints != 0 || pnum != myplr) { - NewPlrAnim(player, PFILE_STAND, dir, player._pNFrames, 3); + NewPlrAnim(player, player_graphic::Stand, dir, player._pNFrames, 3); player._pmode = PM_STAND; FixPlayerLocation(pnum, dir); FixPlrWalkTags(pnum); @@ -1465,7 +1392,7 @@ void StartWalk(int pnum, int xvel, int yvel, int xoff, int yoff, int xadd, int y skippedFrames = 2; if (pmWillBeCalled) skippedFrames += 1; - NewPlrAnim(player, PFILE_WALK, EndDir, player._pWFrames, 0, AnimationDistributionFlags::ProcessAnimationPending, skippedFrames); + NewPlrAnim(player, player_graphic::Walk, EndDir, player._pWFrames, 0, AnimationDistributionFlags::ProcessAnimationPending, skippedFrames); player._pdir = EndDir; @@ -1512,7 +1439,7 @@ void StartAttack(int pnum, Direction d) auto animationFlags = AnimationDistributionFlags::ProcessAnimationPending; if (player._pmode == PM_ATTACK) animationFlags = static_cast(animationFlags | AnimationDistributionFlags::RepeatedAction); - NewPlrAnim(player, PFILE_ATTACK, d, player._pAFrames, 0, animationFlags, skippedAnimationFrames, player._pAFNum); + NewPlrAnim(player, player_graphic::Attack, d, player._pAFrames, 0, animationFlags, skippedAnimationFrames, player._pAFNum); player._pmode = PM_ATTACK; FixPlayerLocation(pnum, d); SetPlayerOld(player); @@ -1540,7 +1467,7 @@ void StartRangeAttack(int pnum, Direction d, int cx, int cy) auto animationFlags = AnimationDistributionFlags::ProcessAnimationPending; if (player._pmode == PM_RATTACK) animationFlags = static_cast(animationFlags | AnimationDistributionFlags::RepeatedAction); - NewPlrAnim(player, PFILE_ATTACK, d, player._pAFrames, 0, animationFlags, skippedAnimationFrames, player._pAFNum); + NewPlrAnim(player, player_graphic::Attack, d, player._pAFrames, 0, animationFlags, skippedAnimationFrames, player._pAFNum); player._pmode = PM_RATTACK; FixPlayerLocation(pnum, d); @@ -1567,7 +1494,7 @@ void StartPlrBlock(int pnum, Direction dir) skippedAnimationFrames = (player._pBFrames - 2); // ISPL_FASTBLOCK means we cancel the animation if frame 2 was shown } - NewPlrAnim(player, PFILE_BLOCK, dir, player._pBFrames, 2, AnimationDistributionFlags::SkipsDelayOfLastFrame, skippedAnimationFrames); + NewPlrAnim(player, player_graphic::Block, dir, player._pBFrames, 2, AnimationDistributionFlags::SkipsDelayOfLastFrame, skippedAnimationFrames); player._pmode = PM_BLOCK; FixPlayerLocation(pnum, dir); @@ -1592,13 +1519,13 @@ void StartSpell(int pnum, Direction d, int cx, int cy) switch (spelldata[player._pSpell].sType) { case STYPE_FIRE: - NewPlrAnim(player, PFILE_FIRE, d, player._pSFrames, 0, animationFlags, 0, player._pSFNum); + NewPlrAnim(player, player_graphic::Fire, d, player._pSFrames, 0, animationFlags, 0, player._pSFNum); break; case STYPE_LIGHTNING: - NewPlrAnim(player, PFILE_LIGHTNING, d, player._pSFrames, 0, animationFlags, 0, player._pSFNum); + NewPlrAnim(player, player_graphic::Lightning, d, player._pSFrames, 0, animationFlags, 0, player._pSFNum); break; case STYPE_MAGIC: - NewPlrAnim(player, PFILE_MAGIC, d, player._pSFrames, 0, animationFlags, 0, player._pSFNum); + NewPlrAnim(player, player_graphic::Magic, d, player._pSFrames, 0, animationFlags, 0, player._pSFNum); break; } } else { @@ -1709,7 +1636,7 @@ void StartPlrHit(int pnum, int dam, bool forcehit) skippedAnimationFrames = 0; } - NewPlrAnim(player, PFILE_HIT, pd, player._pHFrames, 0, AnimationDistributionFlags::None, skippedAnimationFrames); + NewPlrAnim(player, player_graphic::Hit, pd, player._pHFrames, 0, AnimationDistributionFlags::None, skippedAnimationFrames); player._pmode = PM_GOTHIT; FixPlayerLocation(pnum, pd); @@ -1796,11 +1723,11 @@ StartPlayerKill(int pnum, int earflag) if (player._pgfxnum) { player._pgfxnum = 0; - player._pGFXLoad = 0; + ResetPlayerGFX(player); SetPlrAnims(player); } - NewPlrAnim(player, PFILE_DEATH, player._pdir, player._pDFrames, 1); + NewPlrAnim(player, player_graphic::Death, player._pdir, player._pDFrames, 1); player._pBlockFlag = false; player._pmode = PM_DEATH; @@ -3812,24 +3739,24 @@ void SyncPlrAnim(int pnum) } auto &player = plr[pnum]; - dir = player._pdir; + player_graphic graphic; switch (player._pmode) { case PM_STAND: - player.AnimInfo.pCelSprite = &*player._pNAnim[dir]; + case PM_NEWLVL: + case PM_QUIT: + graphic = player_graphic::Stand; break; case PM_WALK: case PM_WALK2: case PM_WALK3: - player.AnimInfo.pCelSprite = &*player._pWAnim[dir]; + graphic = player_graphic::Walk; break; case PM_ATTACK: - player.AnimInfo.pCelSprite = &*player._pAAnim[dir]; - break; case PM_RATTACK: - player.AnimInfo.pCelSprite = &*player._pAAnim[dir]; + graphic = player_graphic::Attack; break; case PM_BLOCK: - player.AnimInfo.pCelSprite = &*player._pBAnim[dir]; + graphic = player_graphic::Block; break; case PM_SPELL: if (pnum == myplr) @@ -3837,27 +3764,23 @@ void SyncPlrAnim(int pnum) else sType = STYPE_FIRE; if (sType == STYPE_FIRE) - player.AnimInfo.pCelSprite = &*player._pFAnim[dir]; + graphic = player_graphic::Fire; if (sType == STYPE_LIGHTNING) - player.AnimInfo.pCelSprite = &*player._pLAnim[dir]; + graphic = player_graphic::Lightning; if (sType == STYPE_MAGIC) - player.AnimInfo.pCelSprite = &*player._pTAnim[dir]; + graphic = player_graphic::Magic; break; case PM_GOTHIT: - player.AnimInfo.pCelSprite = &*player._pHAnim[dir]; - break; - case PM_NEWLVL: - player.AnimInfo.pCelSprite = &*player._pNAnim[dir]; + graphic = player_graphic::Hit; break; case PM_DEATH: - player.AnimInfo.pCelSprite = &*player._pDAnim[dir]; - break; - case PM_QUIT: - player.AnimInfo.pCelSprite = &*player._pNAnim[dir]; + graphic = player_graphic::Death; break; default: app_fatal("SyncPlrAnim"); } + + player.AnimInfo.pCelSprite = &*player.AnimationData[static_cast(graphic)].CelSpritesForDirections[player._pdir]; } void SyncInitPlrPos(int pnum) diff --git a/Source/player.h b/Source/player.h index f84705650..249b34afe 100644 --- a/Source/player.h +++ b/Source/player.h @@ -77,21 +77,18 @@ enum inv_body_loc : uint8_t { NUM_INVLOC, }; -enum player_graphic : uint16_t { - // clang-format off - PFILE_STAND = 1 << 0, - PFILE_WALK = 1 << 1, - PFILE_ATTACK = 1 << 2, - PFILE_HIT = 1 << 3, - PFILE_LIGHTNING = 1 << 4, - PFILE_FIRE = 1 << 5, - PFILE_MAGIC = 1 << 6, - PFILE_DEATH = 1 << 7, - PFILE_BLOCK = 1 << 8, - // everything except PFILE_DEATH - // 0b1_0111_1111 - PFILE_NONDEATH = 0x17F - // clang-format on +enum class player_graphic : uint16_t { + Stand, + Walk, + Attack, + Hit, + Lightning, + Fire, + Magic, + Death, + Block, + + LAST = Block }; enum anim_weapon_id : uint8_t { @@ -149,6 +146,21 @@ enum player_weapon_type : uint8_t { WT_RANGED, }; +/* + * @brief Contains Data (CelSprites) for a player graphic (player_graphic) + */ +struct PlayerAnimationData { + /* + * @brief CelSprites for the different directions + */ + std::array, 8> CelSpritesForDirections; + /* + * @brief Raw Data (binary) of the CL2 file. + * Is referenced from CelSprite in CelSpritesForDirections + */ + std::unique_ptr RawData; +}; + struct PlayerStruct { PlayerStruct() = default; PlayerStruct(PlayerStruct &&) noexcept = default; @@ -237,25 +249,18 @@ struct PlayerStruct { int deathFrame; bool _pLvlVisited[NUMLEVELS]; bool _pSLvlVisited[NUMLEVELS]; // only 10 used - /** Using player_graphic as bitflags */ - int _pGFXLoad; - std::array, 8> _pNAnim; // Stand animations + /* + * @brief Contains Data (Sprites) for the different Animations + */ + std::array::value> AnimationData; int _pNFrames; - std::array, 8> _pWAnim; // Walk animations int _pWFrames; - std::array, 8> _pAAnim; // Attack animations int _pAFrames; int _pAFNum; - std::array, 8> _pLAnim; // Lightning spell cast animations - std::array, 8> _pFAnim; // Fire spell cast animations - std::array, 8> _pTAnim; // Generic spell cast animations int _pSFrames; int _pSFNum; - std::array, 8> _pHAnim; // Getting hit animations int _pHFrames; - std::array, 8> _pDAnim; // Death animations int _pDFrames; - std::array, 8> _pBAnim; // Block animations int _pBFrames; ItemStruct InvBody[NUM_INVLOC]; ItemStruct InvList[NUM_INV_GRID_ELEM]; @@ -294,15 +299,6 @@ struct PlayerStruct { uint8_t pDiabloKillLevel; _difficulty pDifficulty; uint32_t pDamAcFlags; - std::unique_ptr _pNData; - std::unique_ptr _pWData; - std::unique_ptr _pAData; - std::unique_ptr _pLData; - std::unique_ptr _pFData; - std::unique_ptr _pTData; - std::unique_ptr _pHData; - std::unique_ptr _pDData; - std::unique_ptr _pBData; void CalcScrolls(); @@ -408,10 +404,9 @@ extern PlayerStruct plr[MAX_PLRS]; extern bool deathflag; extern int ToBlkTbl[enum_size::value]; -void LoadPlrGFX(PlayerStruct &player, player_graphic gfxflag); +void LoadPlrGFX(PlayerStruct &player, player_graphic graphic); void InitPlayerGFX(int pnum); -void InitPlrGFXMem(PlayerStruct &player); -void FreePlayerGFX(PlayerStruct &player); +void ResetPlayerGFX(PlayerStruct &player); /** * @brief Sets the new Player Animation with all relevant information for rendering diff --git a/test/player_test.cpp b/test/player_test.cpp index 4bf8829e8..ccd2b0dc5 100644 --- a/test/player_test.cpp +++ b/test/player_test.cpp @@ -13,7 +13,6 @@ int RunBlockTest(int frames, int flags) int pnum = 0; plr[pnum]._pHFrames = frames; plr[pnum]._pIFlags = flags; - plr[pnum]._pGFXLoad = -1; StartPlrHit(pnum, 5, Direction::DIR_S); int i = 1;