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 {
|
struct [[gnu::packed]] YatfHeader {
|
||||||
enum class TextureFormat : u8 {
|
enum class TextureFormat : u8 {
|
||||||
|
// V1 formats.
|
||||||
kTextureFormatV1_8Bpp = 0,
|
kTextureFormatV1_8Bpp = 0,
|
||||||
kTextureFormatV1_24Bpp = 2,
|
kTextureFormatV1_24Bpp = 2,
|
||||||
kTextureFormatV1_32Bpp = 3,
|
kTextureFormatV1_32Bpp = 3,
|
||||||
|
@ -34,11 +35,11 @@ namespace europa::structs {
|
||||||
|
|
||||||
u32 magic;
|
u32 magic;
|
||||||
|
|
||||||
u16 version; // 0x1 for starfighter, 0x2 for jsf
|
u16 version; // 0x1 for starfighter, 0x2 for new jsf files
|
||||||
|
|
||||||
TextureFormat format;
|
TextureFormat format;
|
||||||
|
|
||||||
u8 unkThing2; // flags? some palbpp?
|
u8 unkThing2; // flags? some palbpp? V2 seems to end up usually matching
|
||||||
|
|
||||||
// Always zeroed.
|
// Always zeroed.
|
||||||
u32 zero;
|
u32 zero;
|
||||||
|
|
|
@ -78,6 +78,21 @@ namespace europa::util {
|
||||||
|
|
||||||
void Resize(Size newSize);
|
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:
|
private:
|
||||||
UniqueArray<std::uint32_t> imageBuffer;
|
UniqueArray<std::uint32_t> imageBuffer;
|
||||||
Size size;
|
Size size;
|
||||||
|
|
|
@ -46,16 +46,7 @@ namespace europa::io::yatf {
|
||||||
|
|
||||||
stream.read(reinterpret_cast<char*>(&palette[0]), sizeof(palette));
|
stream.read(reinterpret_cast<char*>(&palette[0]), sizeof(palette));
|
||||||
stream.read(reinterpret_cast<char*>(&palettizedData[0]), imageSize.Linear());
|
stream.read(reinterpret_cast<char*>(&palettizedData[0]), imageSize.Linear());
|
||||||
|
surface.PaintFromSource_8bpp(&palettizedData[0], &palette[0]);
|
||||||
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)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case kTextureFormatV1_24Bpp: {
|
case kTextureFormatV1_24Bpp: {
|
||||||
|
@ -90,20 +81,9 @@ namespace europa::io::yatf {
|
||||||
case kTextureFormatV2_4Bpp: {
|
case kTextureFormatV2_4Bpp: {
|
||||||
util::Pixel palette[16] {};
|
util::Pixel palette[16] {};
|
||||||
util::UniqueArray<std::uint8_t> palettizedData(imageSize.Linear() / 2);
|
util::UniqueArray<std::uint8_t> palettizedData(imageSize.Linear() / 2);
|
||||||
|
|
||||||
stream.read(reinterpret_cast<char*>(&palette[0]), sizeof(palette));
|
stream.read(reinterpret_cast<char*>(&palette[0]), sizeof(palette));
|
||||||
stream.read(reinterpret_cast<char*>(&palettizedData[0]), imageSize.Linear() / 2);
|
stream.read(reinterpret_cast<char*>(&palettizedData[0]), imageSize.Linear() / 2);
|
||||||
|
surface.PaintFromSource_4bpp(&palettizedData[0], &palette[0]);
|
||||||
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)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case kTextureFormatV2_8Bpp: {
|
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*>(&palette[0]), sizeof(palette));
|
||||||
stream.read(reinterpret_cast<char*>(&palettizedData[0]), imageSize.Linear());
|
stream.read(reinterpret_cast<char*>(&palettizedData[0]), imageSize.Linear());
|
||||||
|
|
||||||
auto* pDestBuffer = reinterpret_cast<util::Pixel*>(surface.GetBuffer());
|
surface.PaintFromSource_8bpp(&palettizedData[0], &palette[0]);
|
||||||
|
|
||||||
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)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case kTextureFormatV2_24Bpp: {
|
case kTextureFormatV2_24Bpp: {
|
||||||
|
|
|
@ -26,4 +26,29 @@ namespace europa::util {
|
||||||
return imageBuffer.Data();
|
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
|
} // namespace europa::util
|
Loading…
Reference in a new issue