mirror of
https://github.com/libretro/devilutionX.git
synced 2026-11-12 13:05:17 -10:00
Remove PCX->CEL conversion
It is no longer used as we render all assets directly as PCX.
This commit is contained in:
1 parent
7e582a5840
commit
010dda42cf
5 files changed
-245
No files matched your search
@@ -101,7 +101,6 @@ set(libdevilutionx_SRCS
|
||||
engine/direction.cpp
|
||||
engine/dx.cpp
|
||||
engine/load_cel.cpp
|
||||
engine/load_pcx_as_cel.cpp
|
||||
engine/load_pcx.cpp
|
||||
engine/palette.cpp
|
||||
engine/path.cpp
|
||||
@@ -161,7 +160,6 @@ set(libdevilutionx_SRCS
|
||||
utils/logged_fstream.cpp
|
||||
utils/paths.cpp
|
||||
utils/pcx.cpp
|
||||
utils/pcx_to_cel.cpp
|
||||
utils/sdl_bilinear_scale.cpp
|
||||
utils/sdl_thread.cpp
|
||||
utils/utf8.cpp)
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
#include "engine/load_pcx_as_cel.hpp"
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include "engine/assets.hpp"
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/pcx_to_cel.hpp"
|
||||
|
||||
namespace devilution {
|
||||
|
||||
std::optional<OwnedCelSpriteWithFrameHeight> LoadPcxAssetAsCel(const char *filename, unsigned numFrames, bool generateFrameHeaders, uint8_t transparentColorIndex)
|
||||
{
|
||||
SDL_RWops *handle = OpenAsset(filename);
|
||||
if (handle == nullptr) {
|
||||
LogError("Missing file: {}", filename);
|
||||
return std::nullopt;
|
||||
}
|
||||
return LoadPcxAsCel(handle, numFrames, generateFrameHeaders, transparentColorIndex);
|
||||
}
|
||||
|
||||
} // namespace devilution
|
||||
@@ -1,12 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "engine/cel_sprite.hpp"
|
||||
#include "utils/stdcompat/optional.hpp"
|
||||
|
||||
namespace devilution {
|
||||
|
||||
std::optional<OwnedCelSpriteWithFrameHeight> LoadPcxAssetAsCel(const char *filename, unsigned numFrames, bool generateFrameHeaders = false, uint8_t transparentColorIndex = 1);
|
||||
|
||||
} // namespace devilution
|
||||
@@ -1,186 +0,0 @@
|
||||
#include "utils/pcx_to_cel.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "appfat.h"
|
||||
#include "utils/pcx.hpp"
|
||||
#include "utils/stdcompat/cstddef.hpp"
|
||||
|
||||
#ifdef USE_SDL1
|
||||
#include "utils/sdl2_to_1_2_backports.h"
|
||||
#endif
|
||||
|
||||
namespace devilution {
|
||||
|
||||
namespace {
|
||||
|
||||
void WriteLE32(uint8_t *out, uint32_t val)
|
||||
{
|
||||
const uint32_t littleEndian = SDL_SwapLE32(val);
|
||||
memcpy(out, &littleEndian, 4);
|
||||
}
|
||||
|
||||
void WriteLE16(uint8_t *out, uint16_t val)
|
||||
{
|
||||
const uint16_t littleEndian = SDL_SwapLE16(val);
|
||||
memcpy(out, &littleEndian, 2);
|
||||
}
|
||||
|
||||
void AppendCelTransparentRun(unsigned width, std::vector<uint8_t> &out)
|
||||
{
|
||||
while (width >= 128) {
|
||||
out.push_back(0x80);
|
||||
width -= 128;
|
||||
}
|
||||
if (width == 0)
|
||||
return;
|
||||
out.push_back(0xFF - (width - 1));
|
||||
}
|
||||
|
||||
void AppendCelSolidRun(const uint8_t *src, unsigned width, std::vector<uint8_t> &out)
|
||||
{
|
||||
while (width >= 127) {
|
||||
out.push_back(127);
|
||||
for (size_t i = 0; i < 127; ++i)
|
||||
out.push_back(src[i]);
|
||||
width -= 127;
|
||||
src += 127;
|
||||
}
|
||||
if (width == 0)
|
||||
return;
|
||||
out.push_back(width);
|
||||
for (size_t i = 0; i < width; ++i)
|
||||
out.push_back(src[i]);
|
||||
}
|
||||
|
||||
void AppendCelLine(const uint8_t *src, unsigned width, uint8_t transparentColorIndex, std::vector<uint8_t> &out)
|
||||
{
|
||||
unsigned runBegin = 0;
|
||||
bool transparentRun = false;
|
||||
for (unsigned i = 0; i < width; ++i) {
|
||||
const uint8_t pixel = src[i];
|
||||
if (pixel == transparentColorIndex) {
|
||||
if (transparentRun)
|
||||
continue;
|
||||
if (runBegin != i)
|
||||
AppendCelSolidRun(src + runBegin, i - runBegin, out);
|
||||
transparentRun = true;
|
||||
runBegin = i;
|
||||
} else if (transparentRun) {
|
||||
AppendCelTransparentRun(i - runBegin, out);
|
||||
transparentRun = false;
|
||||
runBegin = i;
|
||||
}
|
||||
}
|
||||
if (transparentRun) {
|
||||
AppendCelTransparentRun(width - runBegin, out);
|
||||
} else {
|
||||
AppendCelSolidRun(src + runBegin, width - runBegin, out);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
std::optional<OwnedCelSpriteWithFrameHeight> LoadPcxAsCel(SDL_RWops *handle, unsigned numFrames, bool generateFrameHeaders, uint8_t transparentColorIndex)
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
uint8_t bpp;
|
||||
if (!LoadPcxMeta(handle, width, height, bpp)) {
|
||||
SDL_RWclose(handle);
|
||||
return std::nullopt;
|
||||
}
|
||||
assert(bpp == 8);
|
||||
|
||||
ptrdiff_t pixelDataSize = SDL_RWsize(handle);
|
||||
if (pixelDataSize < 0) {
|
||||
SDL_RWclose(handle);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
pixelDataSize -= PcxHeaderSize;
|
||||
|
||||
std::unique_ptr<uint8_t[]> fileBuffer { new uint8_t[pixelDataSize] };
|
||||
if (SDL_RWread(handle, fileBuffer.get(), pixelDataSize, 1) == 0) {
|
||||
SDL_RWclose(handle);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// CEL header: frame count, frame offset for each frame, file size
|
||||
std::vector<uint8_t> celData(4 * (2 + static_cast<size_t>(numFrames)));
|
||||
WriteLE32(&celData[0], numFrames);
|
||||
|
||||
// We process the PCX a whole frame at a time because the lines are reversed in CEL.
|
||||
const unsigned frameHeight = height / numFrames;
|
||||
auto frameBuffer = std::unique_ptr<uint8_t[]>(new uint8_t[static_cast<size_t>(frameHeight) * width]);
|
||||
|
||||
const unsigned srcSkip = width % 2;
|
||||
uint8_t *dataPtr = fileBuffer.get();
|
||||
for (unsigned frame = 1; frame <= numFrames; ++frame) {
|
||||
WriteLE32(&celData[4 * static_cast<size_t>(frame)], static_cast<uint32_t>(celData.size()));
|
||||
|
||||
// Frame header: 5 16-bit offsets to 32-pixel height blocks.
|
||||
const size_t frameHeaderPos = celData.size();
|
||||
if (generateFrameHeaders) {
|
||||
constexpr size_t FrameHeaderSize = 10;
|
||||
celData.resize(celData.size() + FrameHeaderSize);
|
||||
WriteLE16(&celData[frameHeaderPos], FrameHeaderSize);
|
||||
}
|
||||
|
||||
for (unsigned j = 0; j < frameHeight; ++j) {
|
||||
uint8_t *buffer = &frameBuffer[static_cast<size_t>(j) * width];
|
||||
for (unsigned x = 0; x < static_cast<unsigned>(width);) {
|
||||
constexpr uint8_t PcxMaxSinglePixel = 0xBF;
|
||||
const uint8_t byte = *dataPtr++;
|
||||
if (byte <= PcxMaxSinglePixel) {
|
||||
*buffer++ = byte;
|
||||
++x;
|
||||
continue;
|
||||
}
|
||||
constexpr uint8_t PcxRunLengthMask = 0x3F;
|
||||
const uint8_t runLength = (byte & PcxRunLengthMask);
|
||||
std::memset(buffer, *dataPtr++, runLength);
|
||||
buffer += runLength;
|
||||
x += runLength;
|
||||
}
|
||||
dataPtr += srcSkip;
|
||||
}
|
||||
|
||||
size_t line = frameHeight;
|
||||
while (line-- != 0) {
|
||||
AppendCelLine(&frameBuffer[line * width], width, transparentColorIndex, celData);
|
||||
if (generateFrameHeaders) {
|
||||
switch (line) {
|
||||
case 32:
|
||||
WriteLE16(&celData[frameHeaderPos + 2], static_cast<uint16_t>(celData.size() - frameHeaderPos));
|
||||
break;
|
||||
case 64:
|
||||
WriteLE16(&celData[frameHeaderPos + 4], static_cast<uint16_t>(celData.size() - frameHeaderPos));
|
||||
break;
|
||||
case 96:
|
||||
WriteLE16(&celData[frameHeaderPos + 6], static_cast<uint16_t>(celData.size() - frameHeaderPos));
|
||||
break;
|
||||
case 128:
|
||||
WriteLE16(&celData[frameHeaderPos + 8], static_cast<uint16_t>(celData.size() - frameHeaderPos));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
WriteLE32(&celData[4 * (1 + static_cast<size_t>(numFrames))], static_cast<uint32_t>(celData.size()));
|
||||
|
||||
SDL_RWclose(handle);
|
||||
|
||||
auto out = std::unique_ptr<byte[]>(new byte[celData.size()]);
|
||||
memcpy(&out[0], celData.data(), celData.size());
|
||||
return OwnedCelSpriteWithFrameHeight {
|
||||
OwnedCelSprite { std::move(out), static_cast<uint16_t>(width) },
|
||||
frameHeight
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace devilution
|
||||
@@ -1,24 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include "engine/cel_sprite.hpp"
|
||||
#include "utils/stdcompat/optional.hpp"
|
||||
|
||||
namespace devilution {
|
||||
|
||||
/** @brief Loads a PCX file as CEL.
|
||||
*
|
||||
* Assumes that the PCX file does not have a palette.
|
||||
*
|
||||
* @param handle A non-null SDL_RWops handle. Closed by this function.
|
||||
* @param numFrames The number of vertically stacked frames in the PCX file.
|
||||
* @param generateFrameHeaders Whether to generate frame headers in the CEL sprite.
|
||||
* @param transparentColorIndex The PCX palette index of the transparent color.
|
||||
*/
|
||||
std::optional<OwnedCelSpriteWithFrameHeight> LoadPcxAsCel(SDL_RWops *handle, unsigned numFrames, bool generateFrameHeaders,
|
||||
uint8_t transparentColorIndex = 1);
|
||||
|
||||
} // namespace devilution
|
||||
Reference in new issue
Block a user