Browse Source

Reindex all level cel blocks

pull/7864/head
staphen 1 year ago committed by Anders Jenbo
parent
commit
09f24ae0e8
  1. 21
      Source/levels/gendung.cpp
  2. 14
      Source/levels/reencode_dun_cels.cpp
  3. 7
      Source/levels/reencode_dun_cels.hpp

21
Source/levels/gendung.cpp

@ -524,12 +524,11 @@ void SetDungeonMicros()
uint16_t *pieces = &levelPieces[blocks * levelPieceId];
for (uint32_t block = 0; block < blocks; block++) {
const LevelCelBlock levelCelBlock { SDL_SwapLE16(pieces[blocks - 2 + (block & 1) - (block & 0xE)]) };
LevelCelBlock &mt = DPieceMicros[levelPieceId].mt[block];
mt = levelCelBlock;
DPieceMicros[levelPieceId].mt[block] = levelCelBlock;
if (levelCelBlock.hasValue()) {
if (const auto it = frameToTypeMap.find(levelCelBlock.frame()); it == frameToTypeMap.end()) {
frameToTypeMap.emplace_hint(it, levelCelBlock.frame(),
DunFrameInfo { static_cast<uint8_t>(block), levelCelBlock.type(), SOLData[levelPieceId], &mt.data });
DunFrameInfo { static_cast<uint8_t>(block), levelCelBlock.type(), SOLData[levelPieceId] });
}
}
}
@ -539,7 +538,21 @@ void SetDungeonMicros()
return a.first < b.first;
});
ReencodeDungeonCels(pDungeonCels, frameToTypeList);
ReindexCelBlocks(frameToTypeList);
std::vector<std::pair<uint16_t, uint16_t>> celBlockAdjustments = ComputeCelBlockAdjustments(frameToTypeList);
if (celBlockAdjustments.size() == 0) return;
for (size_t levelPieceId = 0; levelPieceId < tileCount / blocks; levelPieceId++) {
for (uint32_t block = 0; block < blocks; block++) {
LevelCelBlock &levelCelBlock = DPieceMicros[levelPieceId].mt[block];
const uint16_t frame = levelCelBlock.frame();
const auto pair = std::make_pair(frame, frame);
const auto it = std::upper_bound(celBlockAdjustments.begin(), celBlockAdjustments.end(), pair,
[](std::pair<uint16_t, uint16_t> p1, std::pair<uint16_t, uint16_t> p2) { return p1.first < p2.first; });
if (it != celBlockAdjustments.end()) {
levelCelBlock.data -= it->second;
}
}
}
}
void DRLG_InitTrans()

14
Source/levels/reencode_dun_cels.cpp

@ -3,9 +3,11 @@
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <limits>
#include <memory>
#include <span>
#include <utility>
#include <vector>
#include <SDL_endian.h>
@ -301,15 +303,21 @@ void ReencodeDungeonCels(std::unique_ptr<std::byte[]> &dungeonCels, std::span<st
dungeonCels = std::move(result);
}
void ReindexCelBlocks(std::span<std::pair<uint16_t, DunFrameInfo>> frames)
std::vector<std::pair<uint16_t, uint16_t>> ComputeCelBlockAdjustments(std::span<std::pair<uint16_t, DunFrameInfo>> frames)
{
std::vector<std::pair<uint16_t, uint16_t>> celBlockAdjustments;
uint16_t lastFrameIndex = 0;
uint16_t adjustment = 0;
for (auto &[frame, info] : frames) {
adjustment += frame - lastFrameIndex - 1;
uint16_t diff = frame - lastFrameIndex - 1;
if (diff > 0) celBlockAdjustments.emplace_back(frame, adjustment);
adjustment += diff;
lastFrameIndex = frame;
*info.celBlockData -= adjustment;
}
if (adjustment > 0) {
celBlockAdjustments.emplace_back(std::numeric_limits<uint16_t>::max(), adjustment);
}
return celBlockAdjustments;
}
} // namespace devilution

7
Source/levels/reencode_dun_cels.hpp

@ -5,6 +5,7 @@
#include <memory>
#include <span>
#include <utility>
#include <vector>
#include "levels/dun_tile.hpp"
@ -17,8 +18,6 @@ struct DunFrameInfo {
TileType type;
TileProperties properties;
uint16_t *celBlockData;
[[nodiscard]] bool isFloor() const
{
// The BlockMissile check is for stairs in L3 and L4, e.g. tile 46 sub-tile 141 frame 386 in L4.
@ -39,11 +38,11 @@ struct DunFrameInfo {
void ReencodeDungeonCels(std::unique_ptr<std::byte[]> &dungeonCels, std::span<std::pair<uint16_t, DunFrameInfo>> frames);
/**
* @brief Adjusts frame indexes in cel block data.
* @brief Computes adjustments to apply to frame indexes in cel block data.
*
* Re-encoding the dungeon cels removes frames that are not referenced.
* Indexes must also be adjusted to avoid errors when doing lookups.
*/
void ReindexCelBlocks(std::span<std::pair<uint16_t, DunFrameInfo>> frames);
std::vector<std::pair<uint16_t, uint16_t>> ComputeCelBlockAdjustments(std::span<std::pair<uint16_t, DunFrameInfo>> frames);
} // namespace devilution

Loading…
Cancel
Save