some changes for alpha channel support (still doesn't work :( )

This commit is contained in:
thrust26 2023-08-17 20:31:42 +02:00
parent 9e268dda0c
commit 88e737c6f4
6 changed files with 44 additions and 13 deletions

View File

@ -111,6 +111,11 @@ class FBBackendSDL2 : public FBBackend
inline uInt32 mapRGB(uInt8 r, uInt8 g, uInt8 b) const override inline uInt32 mapRGB(uInt8 r, uInt8 g, uInt8 b) const override
{ return SDL_MapRGB(myPixelFormat, r, g, b); } { return SDL_MapRGB(myPixelFormat, r, g, b); }
inline uInt32 mapRGBA(uInt8 r, uInt8 g, uInt8 b, uInt8 a) const override
{
return SDL_MapRGBA(myPixelFormat, r, g, b, a);
}
/** /**
This method is called to get a copy of the specified ARGB data from the This method is called to get a copy of the specified ARGB data from the
viewable FrameBuffer area. Note that this isn't the same as any viewable FrameBuffer area. Note that this isn't the same as any

View File

@ -40,6 +40,7 @@ void PNGLibrary::loadImage(const string& filename, FBSurface& surface, VariantLi
png_infop info_ptr{nullptr}; png_infop info_ptr{nullptr};
png_uint_32 iwidth{0}, iheight{0}; png_uint_32 iwidth{0}, iheight{0};
int bit_depth{0}, color_type{0}, interlace_type{0}; int bit_depth{0}, color_type{0}, interlace_type{0};
bool hasAlpha = false;
const auto loadImageERROR = [&](string_view s) { const auto loadImageERROR = [&](string_view s) {
if(png_ptr) if(png_ptr)
@ -80,7 +81,8 @@ void PNGLibrary::loadImage(const string& filename, FBSurface& surface, VariantLi
// Only normal RBG(A) images are supported (without the alpha channel) // Only normal RBG(A) images are supported (without the alpha channel)
if(color_type == PNG_COLOR_TYPE_RGBA) if(color_type == PNG_COLOR_TYPE_RGBA)
{ {
png_set_strip_alpha(png_ptr); hasAlpha = true;
//png_set_strip_alpha(png_ptr);
} }
else if(color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) else if(color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
{ {
@ -96,7 +98,7 @@ void PNGLibrary::loadImage(const string& filename, FBSurface& surface, VariantLi
} }
// Create/initialize storage area for the current image // Create/initialize storage area for the current image
if(!allocateStorage(iwidth, iheight)) if(!allocateStorage(iwidth, iheight, hasAlpha))
loadImageERROR("Not enough memory to read PNG image"); loadImageERROR("Not enough memory to read PNG image");
// The PNG read function expects an array of rows, not a single 1-D array // The PNG read function expects an array of rows, not a single 1-D array
@ -113,7 +115,7 @@ void PNGLibrary::loadImage(const string& filename, FBSurface& surface, VariantLi
readMetaData(png_ptr, info_ptr, metaData); readMetaData(png_ptr, info_ptr, metaData);
// Load image into the surface, setting the correct dimensions // Load image into the surface, setting the correct dimensions
loadImagetoSurface(surface); loadImagetoSurface(surface, hasAlpha);
// Cleanup // Cleanup
if(png_ptr) if(png_ptr)
@ -381,10 +383,10 @@ void PNGLibrary::takeSnapshot(uInt32 number)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool PNGLibrary::allocateStorage(size_t width, size_t height) bool PNGLibrary::allocateStorage(size_t width, size_t height, bool hasAlpha)
{ {
// Create space for the entire image (3 bytes per pixel in RGB format) // Create space for the entire image (3 bytes per pixel in RGB format)
const size_t req_buffer_size = width * height * 3; const size_t req_buffer_size = width * height * (hasAlpha ? 4 : 3);
if(req_buffer_size > ReadInfo.buffer.capacity()) if(req_buffer_size > ReadInfo.buffer.capacity())
ReadInfo.buffer.reserve(req_buffer_size * 1.5); ReadInfo.buffer.reserve(req_buffer_size * 1.5);
@ -394,13 +396,13 @@ bool PNGLibrary::allocateStorage(size_t width, size_t height)
ReadInfo.width = static_cast<png_uint_32>(width); ReadInfo.width = static_cast<png_uint_32>(width);
ReadInfo.height = static_cast<png_uint_32>(height); ReadInfo.height = static_cast<png_uint_32>(height);
ReadInfo.pitch = static_cast<png_uint_32>(width * 3); ReadInfo.pitch = static_cast<png_uint_32>(width * (hasAlpha ? 4 : 3));
return true; return true;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PNGLibrary::loadImagetoSurface(FBSurface& surface) void PNGLibrary::loadImagetoSurface(FBSurface& surface, bool hasAlpha)
{ {
// First determine if we need to resize the surface // First determine if we need to resize the surface
const uInt32 iw = ReadInfo.width, ih = ReadInfo.height; const uInt32 iw = ReadInfo.width, ih = ReadInfo.height;
@ -423,6 +425,10 @@ void PNGLibrary::loadImagetoSurface(FBSurface& surface)
{ {
const uInt8* i_ptr = i_buf; const uInt8* i_ptr = i_buf;
uInt32* s_ptr = s_buf; uInt32* s_ptr = s_buf;
if(hasAlpha)
for(uInt32 icol = 0; icol < ReadInfo.width; ++icol, i_ptr += 4)
*s_ptr++ = fb.mapRGBA(*i_ptr, *(i_ptr+1), *(i_ptr+2), 85/* *(i_ptr+3)*/);
else
for(uInt32 icol = 0; icol < ReadInfo.width; ++icol, i_ptr += 3) for(uInt32 icol = 0; icol < ReadInfo.width; ++icol, i_ptr += 3)
*s_ptr++ = fb.mapRGB(*i_ptr, *(i_ptr+1), *(i_ptr+2)); *s_ptr++ = fb.mapRGB(*i_ptr, *(i_ptr+1), *(i_ptr+2));
} }

View File

@ -153,7 +153,7 @@ class PNGLibrary
@param width The width of the PNG image @param width The width of the PNG image
@param height The height of the PNG image @param height The height of the PNG image
*/ */
static bool allocateStorage(size_t width, size_t height); static bool allocateStorage(size_t width, size_t height, bool hasAlpha);
/** The actual method which saves a PNG image. /** The actual method which saves a PNG image.
@ -173,7 +173,7 @@ class PNGLibrary
@param surface The FBSurface into which to place the PNG data @param surface The FBSurface into which to place the PNG data
*/ */
void loadImagetoSurface(FBSurface& surface); void loadImagetoSurface(FBSurface& surface, bool hasAlpha);
/** /**
Write PNG tEXt chunks to the image. Write PNG tEXt chunks to the image.

View File

@ -137,6 +137,15 @@ class FBBackend
*/ */
virtual uInt32 mapRGB(uInt8 r, uInt8 g, uInt8 b) const = 0; virtual uInt32 mapRGB(uInt8 r, uInt8 g, uInt8 b) const = 0;
/**
This method is called to map a given R/G/B triple to the screen palette.
@param r The red component of the color.
@param g The green component of the color.
@param b The blue component of the color.
*/
virtual uInt32 mapRGBA(uInt8 r, uInt8 g, uInt8 b, uInt8 a) const = 0;
/** /**
This method is called to get the specified ARGB data from the viewable This method is called to get the specified ARGB data from the viewable
FrameBuffer area. Note that this isn't the same as any internal FrameBuffer area. Note that this isn't the same as any internal

View File

@ -1320,8 +1320,8 @@ FBInitStatus FrameBuffer::applyVideoMode()
const string& path = myOSystem.snapshotLoadDir().getPath(); const string& path = myOSystem.snapshotLoadDir().getPath();
//loadBezel(path + "Atari-2600.png"); //loadBezel(path + "Atari-2600.png");
//loadBezel(path + "Combat.png"); loadBezel(path + "Combat (USA).png");
loadBezel(path + "Asteroids (USA).png"); //loadBezel(path + "Asteroids (USA).png");
} }
resetSurfaces(); resetSurfaces();

View File

@ -360,6 +360,17 @@ class FrameBuffer
return myBackend->mapRGB(r, g, b); return myBackend->mapRGB(r, g, b);
} }
/**
This method is called to map a given R/G/B triple to the screen palette.
@param r The red component of the color.
@param g The green component of the color.
@param b The blue component of the color.
*/
uInt32 mapRGBA(uInt8 r, uInt8 g, uInt8 b, uInt8 a) const {
return myBackend->mapRGBA(r, g, b, a);
}
/** /**
This method is called to get the specified ARGB data from the viewable This method is called to get the specified ARGB data from the viewable
FrameBuffer area. Note that this isn't the same as any internal FrameBuffer area. Note that this isn't the same as any internal