Browse Source

♻️ Clean up `cel_header.hpp`

1. Rename `CelGetFrameStart` to `CelGetFrame`, in line with the other 2
   functions with the same name and load the `uint32_t` safely.
2. Remove redundant `FrameHeader`, simply use `LoadLE16`.
3. Document all the functions.
pull/2217/head
Gleb Mazovetskiy 5 years ago
parent
commit
8a9618aea2
  1. 58
      Source/engine/cel_header.hpp
  2. 2
      Source/missiles.cpp
  3. 4
      Source/monster.cpp
  4. 2
      Source/player.cpp
  5. 2
      Source/towners.cpp
  6. 8
      Source/utils/endian.hpp

58
Source/engine/cel_header.hpp

@ -10,46 +10,48 @@
namespace devilution {
inline byte *CelGetFrameStart(byte *pCelBuff, int nCel)
/**
* Returns the pointer to the start of the frame data (often a header).
*/
inline byte *CelGetFrame(byte *data, int frame)
{
const auto *pFrameTable = reinterpret_cast<const std::uint32_t *>(pCelBuff);
return &pCelBuff[SDL_SwapLE32(pFrameTable[nCel])];
const std::uint32_t begin = LoadLE32(&data[frame * sizeof(std::uint32_t)]);
return &data[begin];
}
inline byte *CelGetFrame(byte *pCelBuff, int nCel, int *nDataSize)
/**
* Returns the pointer to the start of the frame data (often a header) and sets `frameSize` to the size of the data in bytes.
*/
inline byte *CelGetFrame(byte *data, int frame, int *frameSize)
{
const std::uint32_t nCellStart = LoadLE32(&pCelBuff[nCel * sizeof(std::uint32_t)]);
*nDataSize = static_cast<int>(LoadLE32(&pCelBuff[(nCel + 1) * sizeof(std::uint32_t)]) - nCellStart);
return &pCelBuff[nCellStart];
const std::uint32_t begin = LoadLE32(&data[frame * sizeof(std::uint32_t)]);
*frameSize = static_cast<int>(LoadLE32(&data[(frame + 1) * sizeof(std::uint32_t)]) - begin);
return &data[begin];
}
inline const byte *CelGetFrame(const byte *pCelBuff, int nCel, int *nDataSize)
/**
* Returns the pointer to the start of the frame data (often a header) and sets `frameSize` to the size of the data in bytes.
*/
inline const byte *CelGetFrame(const byte *data, int frame, int *frameSize)
{
const std::uint32_t nCellStart = LoadLE32(&pCelBuff[nCel * sizeof(std::uint32_t)]);
*nDataSize = static_cast<int>(LoadLE32(&pCelBuff[(nCel + 1) * sizeof(std::uint32_t)]) - nCellStart);
return &pCelBuff[nCellStart];
const std::uint32_t begin = LoadLE32(&data[frame * sizeof(std::uint32_t)]);
*frameSize = static_cast<int>(LoadLE32(&data[(frame + 1) * sizeof(std::uint32_t)]) - begin);
return &data[begin];
}
struct FrameHeader {
uint16_t row0;
uint16_t row32;
uint16_t row64;
uint16_t row96;
uint16_t row128;
};
inline const byte *CelGetFrameClipped(const byte *pCelBuff, int nCel, int *nDataSize)
/**
* Returns the pointer to the start of the frame's pixel data and sets `frameSize` to the size of the data in bytes.
*/
inline const byte *CelGetFrameClipped(const byte *data, int frame, int *frameSize)
{
const byte *pRLEBytes = CelGetFrame(pCelBuff, nCel, nDataSize);
FrameHeader frameHeader;
std::memcpy(&frameHeader, pRLEBytes, sizeof(FrameHeader));
const byte *frameData = CelGetFrame(data, frame, frameSize);
std::uint16_t nDataStart = SDL_SwapLE16(frameHeader.row0);
*nDataSize -= nDataStart;
// The frame begins with a header that consists of 5 little-endian 16-bit integers
// pointing to the start of the pixel data for rows 0, 32, 64, 96, and 128.
const std::uint16_t begin = LoadLE16(frameData);
return &pRLEBytes[nDataStart];
*frameSize -= begin;
return &frameData[begin];
}
} // namespace devilution

2
Source/missiles.cpp

@ -1127,7 +1127,7 @@ void LoadMissileGFX(BYTE mi)
sprintf(pszName, "Missiles\\%s.CL2", mfd->mName);
byte *file = LoadFileInMem(pszName).release();
for (unsigned i = 0; i < mfd->mAnimFAmt; i++)
mfd->mAnimData[i] = CelGetFrameStart(file, i);
mfd->mAnimData[i] = CelGetFrame(file, i);
} else if (mfd->mAnimFAmt == 1) {
sprintf(pszName, "Missiles\\%s.CL2", mfd->mName);
mfd->mAnimData[0] = LoadFileInMem(pszName).release();

4
Source/monster.cpp

@ -159,7 +159,7 @@ void InitMonsterTRN(CMonster &monst)
for (int j = 0; j < 8; j++) {
Cl2ApplyTrans(
CelGetFrameStart(monst.Anims[i].CMem.get(), j),
CelGetFrame(monst.Anims[i].CMem.get(), j),
colorTranslations,
monst.Anims[i].Frames);
}
@ -359,7 +359,7 @@ void InitMonsterGFX(int monst)
if (Monsters[monst].mtype != MT_GOLEM || (animletter[anim] != 's' && animletter[anim] != 'd')) {
for (i = 0; i < 8; i++) {
byte *pCelStart = CelGetFrameStart(celBuf, i);
byte *pCelStart = CelGetFrame(celBuf, i);
Monsters[monst].Anims[anim].CelSpritesForDirections[i].emplace(pCelStart, width);
}
} else {

2
Source/player.cpp

@ -581,7 +581,7 @@ void SetPlayerGPtrs(const char *path, std::unique_ptr<byte[]> &data, std::array<
data = LoadFileInMem(path);
for (int i = 0; i < 8; i++) {
byte *pCelStart = CelGetFrameStart(data.get(), i);
byte *pCelStart = CelGetFrame(data.get(), i);
anim[i].emplace(pCelStart, width);
}
}

2
Source/towners.cpp

@ -238,7 +238,7 @@ void InitCows(TownerStruct &towner, const TownerInit &initData)
towner.animOrder = nullptr;
towner.animOrderSize = 0;
for (int i = 0; i < 8; i++) {
towner._tNAnim[i] = CelGetFrameStart(CowCels.get(), i);
towner._tNAnim[i] = CelGetFrame(CowCels.get(), i);
}
NewTownerAnim(towner, towner._tNAnim[initData.dir], 12, 3);
towner._tAnimFrame = GenerateRnd(11) + 1;

8
Source/utils/endian.hpp

@ -4,6 +4,14 @@
namespace devilution {
template <typename T>
constexpr std::uint16_t LoadLE16(const T *b)
{
static_assert(sizeof(T) == 1, "invalid argument");
// NOLINTNEXTLINE(readability-magic-numbers)
return (static_cast<std::uint16_t>(b[1]) << 8) | static_cast<std::uint16_t>(b[0]);
}
template <typename T>
constexpr std::uint32_t LoadLE32(const T *b)
{

Loading…
Cancel
Save