From 61ba5009ac7e4248704b745e62a137ac7aebfbc2 Mon Sep 17 00:00:00 2001 From: obligaron Date: Sun, 23 May 2021 10:23:55 +0200 Subject: [PATCH] Convert to CelSprite --- Source/engine/animationinfo.cpp | 8 +- Source/engine/animationinfo.h | 12 +- Source/items.cpp | 6 +- Source/loadsave.cpp | 9 +- Source/player.cpp | 187 ++++++++++---------------------- Source/player.h | 38 +++---- Source/scrollrt.cpp | 23 ++-- test/writehero_test.cpp | 1 - 8 files changed, 103 insertions(+), 181 deletions(-) diff --git a/Source/engine/animationinfo.cpp b/Source/engine/animationinfo.cpp index bf1993d4e..233873731 100644 --- a/Source/engine/animationinfo.cpp +++ b/Source/engine/animationinfo.cpp @@ -69,7 +69,7 @@ float AnimationInfo::GetAnimationProgress() const return fAnimationFraction; } -void AnimationInfo::SetNewAnimation(byte *pData, int numberOfFrames, int delayLen, AnimationDistributionFlags flags /*= AnimationDistributionFlags::None*/, int numSkippedFrames /*= 0*/, int distributeFramesBeforeFrame /*= 0*/) +void AnimationInfo::SetNewAnimation(CelSprite *pCelSprite, int numberOfFrames, int delayLen, AnimationDistributionFlags flags /*= AnimationDistributionFlags::None*/, int numSkippedFrames /*= 0*/, int distributeFramesBeforeFrame /*= 0*/) { if ((flags & AnimationDistributionFlags::RepeatedAction) == AnimationDistributionFlags::RepeatedAction && distributeFramesBeforeFrame != 0 && NumberOfFrames == numberOfFrames && CurrentFrame >= distributeFramesBeforeFrame && CurrentFrame != NumberOfFrames) { // We showed the same Animation (for example a melee attack) before but truncated the Animation. @@ -79,7 +79,7 @@ void AnimationInfo::SetNewAnimation(byte *pData, int numberOfFrames, int delayLe SkippedFramesFromPreviousAnimation = 0; } - this->pData = pData; + this->pCelSprite = pCelSprite; NumberOfFrames = numberOfFrames; CurrentFrame = 1 + numSkippedFrames; DelayCounter = 0; @@ -154,7 +154,7 @@ void AnimationInfo::SetNewAnimation(byte *pData, int numberOfFrames, int delayLe } } -void AnimationInfo::ChangeAnimationData(byte *pData, int numberOfFrames, int delayLen) +void AnimationInfo::ChangeAnimationData(CelSprite *pCelSprite, int numberOfFrames, int delayLen) { if (numberOfFrames != NumberOfFrames || delayLen != DelayLen) { // Ensure that the CurrentFrame is still valid and that we disable ADL cause the calculcated values (for example TickModifier) could be wrong @@ -166,7 +166,7 @@ void AnimationInfo::ChangeAnimationData(byte *pData, int numberOfFrames, int del RelevantFramesForDistributing = 0; TickModifier = 0.0f; } - this->pData = pData; + this->pCelSprite = pCelSprite; DelayLen = delayLen; } diff --git a/Source/engine/animationinfo.h b/Source/engine/animationinfo.h index dd61f9c50..873b20cdb 100644 --- a/Source/engine/animationinfo.h +++ b/Source/engine/animationinfo.h @@ -37,9 +37,9 @@ enum AnimationDistributionFlags : uint8_t { class AnimationInfo { public: /** - * @brief Pointer to Animation Data + * @brief Pointer to Animation Sprite */ - byte *pData; + CelSprite *pCelSprite; /** * @brief Additional delay of each animation in the current animation */ @@ -70,22 +70,22 @@ public: /** * @brief Sets the new Animation with all relevant information for rendering - * @param pData Pointer to Animation Data + * @param pCelSprite Pointer to Animation Sprite * @param numberOfFrames Number of Frames in Animation * @param delayLen Delay after each Animation sequence * @param flags Specifies what special logics are applied to this Animation * @param numSkippedFrames Number of Frames that will be skipped (for example with modifier "faster attack") * @param distributeFramesBeforeFrame Distribute the numSkippedFrames only before this frame */ - void SetNewAnimation(byte *pData, int numberOfFrames, int delayLen, AnimationDistributionFlags flags = AnimationDistributionFlags::None, int numSkippedFrames = 0, int distributeFramesBeforeFrame = 0); + void SetNewAnimation(CelSprite *pCelSprite, int numberOfFrames, int delayLen, AnimationDistributionFlags flags = AnimationDistributionFlags::None, int numSkippedFrames = 0, int distributeFramesBeforeFrame = 0); /** * @brief Changes the Animation Data on-the-fly. This is needed if a animation is currently in progress and the player changes his gear. - * @param pData Pointer to Animation Data + * @param pCelSprite Pointer to Animation Sprite * @param numberOfFrames Number of Frames in Animation * @param delayLen Delay after each Animation sequence */ - void ChangeAnimationData(byte *pData, int numberOfFrames, int delayLen); + void ChangeAnimationData(CelSprite *pCelSprite, int numberOfFrames, int delayLen); /* * @brief Process the Animation for a game tick (for example advances the frame) diff --git a/Source/items.cpp b/Source/items.cpp index f18564ce9..a76b5b113 100644 --- a/Source/items.cpp +++ b/Source/items.cpp @@ -888,11 +888,9 @@ void CalcPlrItemVals(int playerId, bool Loadgfx) SetPlrAnims(player); LoadPlrGFX(player, static_cast(PFILE_STAND | PFILE_WALK)); if (player._pmode == PM_STAND) { - player._pAnimWidth = player.GetAnimationWidth(PFILE_STAND); - player.AnimInfo.ChangeAnimationData(player._pNAnim[player._pdir], player._pNFrames, 3); + player.AnimInfo.ChangeAnimationData(&*player._pNAnim[player._pdir], player._pNFrames, 3); } else { - player._pAnimWidth = player.GetAnimationWidth(PFILE_WALK); - player.AnimInfo.ChangeAnimationData(player._pWAnim[player._pdir], player._pWFrames, 0); + player.AnimInfo.ChangeAnimationData(&*player._pWAnim[player._pdir], player._pWFrames, 0); } } else { player._pgfxnum = g; diff --git a/Source/loadsave.cpp b/Source/loadsave.cpp index a3fb32776..210281722 100644 --- a/Source/loadsave.cpp +++ b/Source/loadsave.cpp @@ -338,7 +338,8 @@ static void LoadPlayer(LoadHelper *file, int p) pPlayer->AnimInfo.DelayCounter = file->nextLE(); pPlayer->AnimInfo.NumberOfFrames = file->nextLE(); pPlayer->AnimInfo.CurrentFrame = file->nextLE(); - pPlayer->_pAnimWidth = file->nextLE(); + // Skip _pAnimWidth + file->skip(4); // Skip _pAnimWidth2 file->skip(4); file->skip(4); // Skip _peflag @@ -1333,9 +1334,11 @@ static void SavePlayer(SaveHelper *file, int p) file->writeLE(pPlayer->AnimInfo.DelayCounter); file->writeLE(pPlayer->AnimInfo.NumberOfFrames); file->writeLE(pPlayer->AnimInfo.CurrentFrame); - file->writeLE(pPlayer->_pAnimWidth); + // write _pAnimWidth for vanilla compatibility + int animWidth = pPlayer->AnimInfo.pCelSprite == nullptr ? 96 : pPlayer->AnimInfo.pCelSprite->Width(); + file->writeLE(animWidth); // write _pAnimWidth2 for vanilla compatibility - file->writeLE(CalculateWidth2(pPlayer->_pAnimWidth)); + file->writeLE(CalculateWidth2(animWidth)); file->skip(4); // Skip _peflag file->writeLE(pPlayer->_plid); file->writeLE(pPlayer->_pvid); diff --git a/Source/player.cpp b/Source/player.cpp index 10aa995f8..89d94f640 100644 --- a/Source/player.cpp +++ b/Source/player.cpp @@ -420,12 +420,14 @@ int PlayerStruct::GetAnimationWidth(player_graphic graphic) } } -void SetPlayerGPtrs(byte *pData, byte **pAnim) +void SetPlayerGPtrs(const char *path, std::unique_ptr &data, std::array, 8> &anim, int width) { - int i; + data = nullptr; + data = LoadFileInMem(path); - for (i = 0; i < 8; i++) { - pAnim[i] = CelGetFrameStart(pData, i); + for (int i = 0; i < 8; i++) { + byte *pCelStart = CelGetFrameStart(data.get(), i); + anim[i].emplace(pCelStart, width); } } @@ -434,8 +436,8 @@ void LoadPlrGFX(PlayerStruct &player, player_graphic gfxflag) char prefix[16]; char pszName[256]; const char *szCel; - byte *pData; - byte **pAnim; + std::unique_ptr *pData; + std::array, 8> *pAnim; HeroClass c = player._pClass; if (c == HeroClass::Bard && hfbard_mpq == nullptr) { @@ -458,64 +460,64 @@ void LoadPlrGFX(PlayerStruct &player, player_graphic gfxflag) if (leveltype == DTYPE_TOWN) { szCel = "ST"; } - pData = player._pNData; - pAnim = player._pNAnim; + pData = &player._pNData; + pAnim = &player._pNAnim; break; case PFILE_WALK: szCel = "AW"; if (leveltype == DTYPE_TOWN) { szCel = "WL"; } - pData = player._pWData; - pAnim = player._pWAnim; + pData = &player._pWData; + pAnim = &player._pWAnim; break; case PFILE_ATTACK: if (leveltype == DTYPE_TOWN) { continue; } szCel = "AT"; - pData = player._pAData; - pAnim = player._pAAnim; + pData = &player._pAData; + pAnim = &player._pAAnim; break; case PFILE_HIT: if (leveltype == DTYPE_TOWN) { continue; } szCel = "HT"; - pData = player._pHData; - pAnim = player._pHAnim; + pData = &player._pHData; + pAnim = &player._pHAnim; break; case PFILE_LIGHTNING: if (leveltype == DTYPE_TOWN) { continue; } szCel = "LM"; - pData = player._pLData; - pAnim = player._pLAnim; + pData = &player._pLData; + pAnim = &player._pLAnim; break; case PFILE_FIRE: if (leveltype == DTYPE_TOWN) { continue; } szCel = "FM"; - pData = player._pFData; - pAnim = player._pFAnim; + pData = &player._pFData; + pAnim = &player._pFAnim; break; case PFILE_MAGIC: if (leveltype == DTYPE_TOWN) { continue; } szCel = "QM"; - pData = player._pTData; - pAnim = player._pTAnim; + pData = &player._pTData; + pAnim = &player._pTAnim; break; case PFILE_DEATH: if ((player._pgfxnum & 0xF) != 0) { continue; } szCel = "DT"; - pData = player._pDData; - pAnim = player._pDAnim; + pData = &player._pDData; + pAnim = &player._pDAnim; break; case PFILE_BLOCK: if (leveltype == DTYPE_TOWN) { @@ -526,16 +528,15 @@ void LoadPlrGFX(PlayerStruct &player, player_graphic gfxflag) } szCel = "BL"; - pData = player._pBData; - pAnim = player._pBAnim; + pData = &player._pBData; + pAnim = &player._pBAnim; break; default: app_fatal("PLR:2"); } sprintf(pszName, "PlrGFX\\%s\\%s\\%s%s.CL2", cs, prefix, prefix, szCel); - LoadFileInMem(pszName, pData); - SetPlayerGPtrs(pData, pAnim); + SetPlayerGPtrs(pszName, *pData, *pAnim, player.GetAnimationWidth(static_cast(i))); player._pGFXLoad |= i; } } @@ -567,101 +568,21 @@ static HeroClass GetPlrGFXClass(HeroClass c) } } -static DWORD GetPlrGFXSize(HeroClass c, const char *szCel) -{ - const char *a, *w; - DWORD dwSize, dwMaxSize; - HANDLE hsFile; - char pszName[256]; - char Type[16]; - - c = GetPlrGFXClass(c); - dwMaxSize = 0; - - const auto hasBlockAnimation = [c](char w) { - return w == 'D' || w == 'U' || w == 'H' - || (c == HeroClass::Monk && (w == 'S' || w == 'M' || w == 'N' || w == 'T')); - }; - - for (a = &ArmourChar[0]; *a; a++) { - if (gbIsSpawn && a != &ArmourChar[0]) - break; - for (w = &WepChar[0]; *w; w++) { - if (szCel[0] == 'D' && szCel[1] == 'T' && *w != 'N') { - continue; //Death has no weapon - } - if (szCel[0] == 'B' && szCel[1] == 'L' && !hasBlockAnimation(*w)) { - continue; // No block animation - } - sprintf(Type, "%c%c%c", CharChar[static_cast(c)], *a, *w); - sprintf(pszName, "PlrGFX\\%s\\%s\\%s%s.CL2", ClassPathTbl[static_cast(c)], Type, Type, szCel); - if (SFileOpenFile(pszName, &hsFile)) { - assert(hsFile); - dwSize = SFileGetFileSize(hsFile); - SFileCloseFileThreadSafe(hsFile); - if (dwMaxSize <= dwSize) { - dwMaxSize = dwSize; - } - } - } - } - - return dwMaxSize; -} - void InitPlrGFXMem(PlayerStruct &player) { - const HeroClass c = player._pClass; - - // STAND (ST: TOWN, AS: DUNGEON) - player._pNData = new byte[std::max(GetPlrGFXSize(c, "ST"), GetPlrGFXSize(c, "AS"))]; - - // WALK (WL: TOWN, AW: DUNGEON) - player._pWData = new byte[std::max(GetPlrGFXSize(c, "WL"), GetPlrGFXSize(c, "AW"))]; - - // ATTACK - player._pAData = new byte[GetPlrGFXSize(c, "AT")]; - - // HIT - player._pHData = new byte[GetPlrGFXSize(c, "HT")]; - - // LIGHTNING - player._pLData = new byte[GetPlrGFXSize(c, "LM")]; - - // FIRE - player._pFData = new byte[GetPlrGFXSize(c, "FM")]; - - // MAGIC - player._pTData = new byte[GetPlrGFXSize(c, "QM")]; - - // DEATH - player._pDData = new byte[GetPlrGFXSize(c, "DT")]; - - // BLOCK - player._pBData = new byte[GetPlrGFXSize(c, "BL")]; - - player._pGFXLoad = 0; + FreePlayerGFX(player); } void FreePlayerGFX(PlayerStruct &player) { - delete[] player._pNData; player._pNData = nullptr; - delete[] player._pWData; player._pWData = nullptr; - delete[] player._pAData; player._pAData = nullptr; - delete[] player._pHData; player._pHData = nullptr; - delete[] player._pLData; player._pLData = nullptr; - delete[] player._pFData; player._pFData = nullptr; - delete[] player._pTData; player._pTData = nullptr; - delete[] player._pDData; player._pDData = nullptr; - delete[] player._pBData; player._pBData = nullptr; player._pGFXLoad = 0; } @@ -671,43 +592,45 @@ void NewPlrAnim(PlayerStruct &player, player_graphic graphic, Direction dir, int if ((player._pGFXLoad & graphic) != graphic) LoadPlrGFX(player, graphic); - int width = player.GetAnimationWidth(graphic); - byte *pData = nullptr; + std::array, 8> *pCelSprites = nullptr; switch (graphic) { case PFILE_STAND: - pData = player._pNAnim[dir]; + pCelSprites = &player._pNAnim; break; case PFILE_WALK: - pData = player._pWAnim[dir]; + pCelSprites = &player._pWAnim; break; case PFILE_ATTACK: - pData = player._pAAnim[dir]; + pCelSprites = &player._pAAnim; break; case PFILE_HIT: - pData = player._pHAnim[dir]; + pCelSprites = &player._pHAnim; break; case PFILE_LIGHTNING: - pData = player._pLAnim[dir]; + pCelSprites = &player._pLAnim; break; case PFILE_FIRE: - pData = player._pFAnim[dir]; + pCelSprites = &player._pFAnim; break; case PFILE_MAGIC: - pData = player._pTAnim[dir]; + pCelSprites = &player._pTAnim; break; case PFILE_DEATH: - pData = player._pDAnim[dir]; + pCelSprites = &player._pDAnim; break; case PFILE_BLOCK: - pData = player._pBAnim[dir]; + pCelSprites = &player._pBAnim; break; default: Log("NewPlrAnim: Unkown graphic {}", graphic); break; } - player._pAnimWidth = width; - player.AnimInfo.SetNewAnimation(pData, numberOfFrames, delayLen, flags, numSkippedFrames, distributeFramesBeforeFrame); + CelSprite *pCelSprite = nullptr; + if (pCelSprites != nullptr && (*pCelSprites)[dir]) + pCelSprite = &*(*pCelSprites)[dir]; + + player.AnimInfo.SetNewAnimation(pCelSprite, numberOfFrames, delayLen, flags, numSkippedFrames, distributeFramesBeforeFrame); } static void ClearPlrPVars(PlayerStruct &player) @@ -3892,21 +3815,21 @@ void SyncPlrAnim(int pnum) dir = player._pdir; switch (player._pmode) { case PM_STAND: - player.AnimInfo.pData = player._pNAnim[dir]; + player.AnimInfo.pCelSprite = &*player._pNAnim[dir]; break; case PM_WALK: case PM_WALK2: case PM_WALK3: - player.AnimInfo.pData = player._pWAnim[dir]; + player.AnimInfo.pCelSprite = &*player._pWAnim[dir]; break; case PM_ATTACK: - player.AnimInfo.pData = player._pAAnim[dir]; + player.AnimInfo.pCelSprite = &*player._pAAnim[dir]; break; case PM_RATTACK: - player.AnimInfo.pData = player._pAAnim[dir]; + player.AnimInfo.pCelSprite = &*player._pAAnim[dir]; break; case PM_BLOCK: - player.AnimInfo.pData = player._pBAnim[dir]; + player.AnimInfo.pCelSprite = &*player._pBAnim[dir]; break; case PM_SPELL: if (pnum == myplr) @@ -3914,23 +3837,23 @@ void SyncPlrAnim(int pnum) else sType = STYPE_FIRE; if (sType == STYPE_FIRE) - player.AnimInfo.pData = player._pFAnim[dir]; + player.AnimInfo.pCelSprite = &*player._pFAnim[dir]; if (sType == STYPE_LIGHTNING) - player.AnimInfo.pData = player._pLAnim[dir]; + player.AnimInfo.pCelSprite = &*player._pLAnim[dir]; if (sType == STYPE_MAGIC) - player.AnimInfo.pData = player._pTAnim[dir]; + player.AnimInfo.pCelSprite = &*player._pTAnim[dir]; break; case PM_GOTHIT: - player.AnimInfo.pData = player._pHAnim[dir]; + player.AnimInfo.pCelSprite = &*player._pHAnim[dir]; break; case PM_NEWLVL: - player.AnimInfo.pData = player._pNAnim[dir]; + player.AnimInfo.pCelSprite = &*player._pNAnim[dir]; break; case PM_DEATH: - player.AnimInfo.pData = player._pDAnim[dir]; + player.AnimInfo.pCelSprite = &*player._pDAnim[dir]; break; case PM_QUIT: - player.AnimInfo.pData = player._pNAnim[dir]; + player.AnimInfo.pCelSprite = &*player._pNAnim[dir]; break; default: app_fatal("SyncPlrAnim"); diff --git a/Source/player.h b/Source/player.h index 6fb841357..f84705650 100644 --- a/Source/player.h +++ b/Source/player.h @@ -5,6 +5,7 @@ */ #pragma once +#include #include #include "diablo.h" @@ -169,7 +170,6 @@ struct PlayerStruct { * @brief Contains Information for current Animation */ AnimationInfo AnimInfo; - int _pAnimWidth; int _plid; int _pvid; spell_id _pSpell; @@ -239,23 +239,23 @@ struct PlayerStruct { bool _pSLvlVisited[NUMLEVELS]; // only 10 used /** Using player_graphic as bitflags */ int _pGFXLoad; - byte *_pNAnim[8]; // Stand animations + std::array, 8> _pNAnim; // Stand animations int _pNFrames; - byte *_pWAnim[8]; // Walk animations + std::array, 8> _pWAnim; // Walk animations int _pWFrames; - byte *_pAAnim[8]; // Attack animations + std::array, 8> _pAAnim; // Attack animations int _pAFrames; int _pAFNum; - byte *_pLAnim[8]; // Lightning spell cast animations - byte *_pFAnim[8]; // Fire spell cast animations - byte *_pTAnim[8]; // Generic spell cast animations + 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; - byte *_pHAnim[8]; // Getting hit animations + std::array, 8> _pHAnim; // Getting hit animations int _pHFrames; - byte *_pDAnim[8]; // Death animations + std::array, 8> _pDAnim; // Death animations int _pDFrames; - byte *_pBAnim[8]; // Block animations + std::array, 8> _pBAnim; // Block animations int _pBFrames; ItemStruct InvBody[NUM_INVLOC]; ItemStruct InvList[NUM_INV_GRID_ELEM]; @@ -294,15 +294,15 @@ struct PlayerStruct { uint8_t pDiabloKillLevel; _difficulty pDifficulty; uint32_t pDamAcFlags; - byte *_pNData; - byte *_pWData; - byte *_pAData; - byte *_pLData; - byte *_pFData; - byte *_pTData; - byte *_pHData; - byte *_pDData; - byte *_pBData; + 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(); diff --git a/Source/scrollrt.cpp b/Source/scrollrt.cpp index c298b29c6..f6927da27 100644 --- a/Source/scrollrt.cpp +++ b/Source/scrollrt.cpp @@ -354,7 +354,7 @@ static void DrawMonster(const CelOutputBuffer &out, int x, int y, int mx, int my */ static void DrawPlayerIconHelper(const CelOutputBuffer &out, int pnum, missile_graphic_id missileGraphicId, int x, int y, bool lighting) { - x += CalculateWidth2(plr[pnum]._pAnimWidth) - misfiledata[missileGraphicId].mAnimWidth2[0]; + x += CalculateWidth2(plr[pnum].AnimInfo.pCelSprite->Width()) - misfiledata[missileGraphicId].mAnimWidth2[0]; int width = misfiledata[missileGraphicId].mAnimWidth[0]; byte *pCelBuff = misfiledata[missileGraphicId].mAnimData[0]; @@ -410,16 +410,15 @@ static void DrawPlayer(const CelOutputBuffer &out, int pnum, int x, int y, int p PlayerStruct *pPlayer = &plr[pnum]; - byte *pCelBuff = pPlayer->AnimInfo.pData; + auto *pCelSprite = pPlayer->AnimInfo.pCelSprite; int nCel = pPlayer->AnimInfo.GetFrameToUseForRendering(); - if (pCelBuff == nullptr) { - Log("Drawing player {} \"{}\": NULL Cel Buffer", pnum, plr[pnum]._pName); + if (pCelSprite == nullptr) { + Log("Drawing player {} \"{}\": NULL CelSprite", pnum, plr[pnum]._pName); return; } - CelSprite cel { pCelBuff, pPlayer->_pAnimWidth }; - int frames = SDL_SwapLE32(*reinterpret_cast(cel.Data())); + int frames = SDL_SwapLE32(*reinterpret_cast(pCelSprite->Data())); if (nCel < 1 || frames > 50 || nCel > frames) { const char *szMode = "unknown action"; if (plr[pnum]._pmode <= PM_QUIT) @@ -436,16 +435,16 @@ static void DrawPlayer(const CelOutputBuffer &out, int pnum, int x, int y, int p } if (pnum == pcursplr) - Cl2DrawOutline(out, 165, px, py, cel, nCel); + Cl2DrawOutline(out, 165, px, py, *pCelSprite, nCel); if (pnum == myplr) { - Cl2Draw(out, px, py, cel, nCel); + Cl2Draw(out, px, py, *pCelSprite, nCel); DrawPlayerIcons(out, pnum, px, py, true); return; } if (!(dFlags[x][y] & BFLAG_LIT) || (plr[myplr]._pInfraFlag && light_table_index > 8)) { - Cl2DrawLightTbl(out, px, py, cel, nCel, 1); + Cl2DrawLightTbl(out, px, py, *pCelSprite, nCel, 1); DrawPlayerIcons(out, pnum, px, py, true); return; } @@ -456,7 +455,7 @@ static void DrawPlayer(const CelOutputBuffer &out, int pnum, int x, int y, int p else light_table_index -= 5; - Cl2DrawLight(out, px, py, cel, nCel); + Cl2DrawLight(out, px, py, *pCelSprite, nCel); DrawPlayerIcons(out, pnum, px, py, false); light_table_index = l; @@ -481,7 +480,7 @@ void DrawDeadPlayer(const CelOutputBuffer &out, int x, int y, int sx, int sy) p = &plr[i]; if (p->plractive && p->_pHitPoints == 0 && p->plrlevel == (BYTE)currlevel && p->position.tile.x == x && p->position.tile.y == y) { dFlags[x][y] |= BFLAG_DEAD_PLAYER; - px = sx + p->position.offset.x - CalculateWidth2(p->_pAnimWidth); + px = sx + p->position.offset.x - CalculateWidth2(p->AnimInfo.pCelSprite == nullptr ? 96 : p->AnimInfo.pCelSprite->Width()); py = sy + p->position.offset.y; DrawPlayer(out, i, x, y, px, py); } @@ -718,7 +717,7 @@ static void DrawPlayerHelper(const CelOutputBuffer &out, int x, int y, int sx, i if (pPlayer->IsWalking()) { offset = GetOffsetForWalking(pPlayer->AnimInfo, pPlayer->_pdir); } - int px = sx + offset.x - CalculateWidth2(pPlayer->_pAnimWidth); + int px = sx + offset.x - CalculateWidth2(pPlayer->AnimInfo.pCelSprite == nullptr ? 96 : pPlayer->AnimInfo.pCelSprite->Width()); int py = sy + offset.y; DrawPlayer(out, p, x, y, px, py); diff --git a/test/writehero_test.cpp b/test/writehero_test.cpp index e6cfca49e..16398eddd 100644 --- a/test/writehero_test.cpp +++ b/test/writehero_test.cpp @@ -296,7 +296,6 @@ static void AssertPlayer(PlayerStruct *pPlayer) ASSERT_EQ(pPlayer->AnimInfo.DelayCounter, 1); ASSERT_EQ(pPlayer->AnimInfo.NumberOfFrames, 20); ASSERT_EQ(pPlayer->AnimInfo.CurrentFrame, 1); - ASSERT_EQ(pPlayer->_pAnimWidth, 96); ASSERT_EQ(pPlayer->_pSpell, -1); ASSERT_EQ(pPlayer->_pSplType, 4); ASSERT_EQ(pPlayer->_pSplFrom, 0);