libeuropa/util: Move 4bpp/8bpp paint support
This commit is contained in:
parent
69e9ecd35c
commit
6a565e3244
4 changed files with 46 additions and 33 deletions
|
@ -17,6 +17,7 @@ namespace europa::structs {
|
|||
|
||||
struct [[gnu::packed]] YatfHeader {
|
||||
enum class TextureFormat : u8 {
|
||||
// V1 formats.
|
||||
kTextureFormatV1_8Bpp = 0,
|
||||
kTextureFormatV1_24Bpp = 2,
|
||||
kTextureFormatV1_32Bpp = 3,
|
||||
|
@ -34,11 +35,11 @@ namespace europa::structs {
|
|||
|
||||
u32 magic;
|
||||
|
||||
u16 version; // 0x1 for starfighter, 0x2 for jsf
|
||||
u16 version; // 0x1 for starfighter, 0x2 for new jsf files
|
||||
|
||||
TextureFormat format;
|
||||
|
||||
u8 unkThing2; // flags? some palbpp?
|
||||
u8 unkThing2; // flags? some palbpp? V2 seems to end up usually matching
|
||||
|
||||
// Always zeroed.
|
||||
u32 zero;
|
||||
|
|
|
@ -78,6 +78,21 @@ namespace europa::util {
|
|||
|
||||
void Resize(Size newSize);
|
||||
|
||||
// FIXME: For now, these APIs will work. It may actually make sense
|
||||
// to have a ImageSurface hold a Unique<IPixelBuffer>, that knows about
|
||||
// format and can optionally output pixels or provide raw buffer access
|
||||
// if desired.
|
||||
//
|
||||
// basically support other than RGBA8888 out of the box and deal with it nicely
|
||||
|
||||
/// Paint from a 4bpp source.
|
||||
/// Assumes this image has been initalized to the proper size already.
|
||||
void PaintFromSource_4bpp(std::uint8_t const* pSrc, Pixel const* pPalette);
|
||||
|
||||
/// Paint from a 8bpp source.
|
||||
/// Assumes this image has been initalized to the proper size already.
|
||||
void PaintFromSource_8bpp(std::uint8_t const* pSrc, Pixel const* pPalette);
|
||||
|
||||
private:
|
||||
UniqueArray<std::uint32_t> imageBuffer;
|
||||
Size size;
|
||||
|
|
|
@ -46,16 +46,7 @@ namespace europa::io::yatf {
|
|||
|
||||
stream.read(reinterpret_cast<char*>(&palette[0]), sizeof(palette));
|
||||
stream.read(reinterpret_cast<char*>(&palettizedData[0]), imageSize.Linear());
|
||||
|
||||
auto* pDestBuffer = reinterpret_cast<util::Pixel*>(surface.GetBuffer());
|
||||
|
||||
for(std::size_t y = 0; y < imageSize.height; ++y) {
|
||||
for(std::size_t x = 0; x < imageSize.width; ++x) {
|
||||
auto& pp = palettizedData[y * imageSize.width + x];
|
||||
auto& dst = pDestBuffer[y * imageSize.width + x];
|
||||
dst = palette[static_cast<std::size_t>(pp)];
|
||||
}
|
||||
}
|
||||
surface.PaintFromSource_8bpp(&palettizedData[0], &palette[0]);
|
||||
} break;
|
||||
|
||||
case kTextureFormatV1_24Bpp: {
|
||||
|
@ -90,20 +81,9 @@ namespace europa::io::yatf {
|
|||
case kTextureFormatV2_4Bpp: {
|
||||
util::Pixel palette[16] {};
|
||||
util::UniqueArray<std::uint8_t> palettizedData(imageSize.Linear() / 2);
|
||||
|
||||
stream.read(reinterpret_cast<char*>(&palette[0]), sizeof(palette));
|
||||
stream.read(reinterpret_cast<char*>(&palettizedData[0]), imageSize.Linear() / 2);
|
||||
|
||||
auto* pDestBuffer = reinterpret_cast<util::Pixel*>(surface.GetBuffer());
|
||||
|
||||
// can't really get a better loop to work, so i guess this has to do
|
||||
for(std::size_t y = 0; y < (imageSize.width * imageSize.height) / 2; ++y) {
|
||||
auto& pp = palettizedData[y];
|
||||
for(std::size_t b = 0; b < 2; ++b) {
|
||||
auto col = ((pp & (0x0F << (b * 4))) >> (b * 4));
|
||||
(*pDestBuffer++) = palette[static_cast<std::size_t>(col)];
|
||||
}
|
||||
}
|
||||
surface.PaintFromSource_4bpp(&palettizedData[0], &palette[0]);
|
||||
} break;
|
||||
|
||||
case kTextureFormatV2_8Bpp: {
|
||||
|
@ -113,15 +93,7 @@ namespace europa::io::yatf {
|
|||
stream.read(reinterpret_cast<char*>(&palette[0]), sizeof(palette));
|
||||
stream.read(reinterpret_cast<char*>(&palettizedData[0]), imageSize.Linear());
|
||||
|
||||
auto* pDestBuffer = reinterpret_cast<util::Pixel*>(surface.GetBuffer());
|
||||
|
||||
for(std::size_t y = 0; y < imageSize.height; ++y) {
|
||||
for(std::size_t x = 0; x < imageSize.width; ++x) {
|
||||
auto& pp = palettizedData[y * imageSize.width + x];
|
||||
auto& dst = pDestBuffer[y * imageSize.width + x];
|
||||
dst = palette[static_cast<std::size_t>(pp)];
|
||||
}
|
||||
}
|
||||
surface.PaintFromSource_8bpp(&palettizedData[0], &palette[0]);
|
||||
} break;
|
||||
|
||||
case kTextureFormatV2_24Bpp: {
|
||||
|
|
|
@ -26,4 +26,29 @@ namespace europa::util {
|
|||
return imageBuffer.Data();
|
||||
}
|
||||
|
||||
void ImageSurface::PaintFromSource_4bpp(std::uint8_t const* pSrc, Pixel const* pPalette) {
|
||||
auto* pDestBuffer = reinterpret_cast<util::Pixel*>(imageBuffer.Data());
|
||||
|
||||
// can't really get a better loop to work, so i guess this has to do
|
||||
for(std::size_t y = 0; y < size.Linear() / 2; ++y) {
|
||||
auto& pp = pSrc[y];
|
||||
for(std::size_t b = 0; b < 2; ++b) {
|
||||
auto col = ((pp & (0x0F << (b * 4))) >> (b * 4));
|
||||
(*pDestBuffer++) = pPalette[static_cast<std::size_t>(col)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ImageSurface::PaintFromSource_8bpp(std::uint8_t const* pSrc, Pixel const* pPalette) {
|
||||
auto* pDestBuffer = reinterpret_cast<Pixel*>(imageBuffer.Data());
|
||||
|
||||
for(std::size_t y = 0; y < size.height; ++y) {
|
||||
for(std::size_t x = 0; x < size.width; ++x) {
|
||||
auto& pp = pSrc[y * size.width + x];
|
||||
auto& dst = pDestBuffer[y * size.width + x];
|
||||
dst = pPalette[static_cast<std::size_t>(pp)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace europa::util
|
Loading…
Reference in a new issue