Skip to content

Commit

Permalink
some changes for alpha channel support (still doesn't work :( )
Browse files Browse the repository at this point in the history
  • Loading branch information
thrust26 committed Aug 17, 2023
1 parent 9e268dd commit 88e737c
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 13 deletions.
5 changes: 5 additions & 0 deletions src/common/FBBackendSDL2.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,11 @@ class FBBackendSDL2 : public FBBackend
inline uInt32 mapRGB(uInt8 r, uInt8 g, uInt8 b) const override
{ 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
viewable FrameBuffer area. Note that this isn't the same as any
Expand Down
24 changes: 15 additions & 9 deletions src/common/PNGLibrary.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ void PNGLibrary::loadImage(const string& filename, FBSurface& surface, VariantLi
png_infop info_ptr{nullptr};
png_uint_32 iwidth{0}, iheight{0};
int bit_depth{0}, color_type{0}, interlace_type{0};
bool hasAlpha = false;

const auto loadImageERROR = [&](string_view s) {
if(png_ptr)
Expand Down Expand Up @@ -80,7 +81,8 @@ void PNGLibrary::loadImage(const string& filename, FBSurface& surface, VariantLi
// Only normal RBG(A) images are supported (without the alpha channel)
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)
{
Expand All @@ -96,7 +98,7 @@ void PNGLibrary::loadImage(const string& filename, FBSurface& surface, VariantLi
}

// 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");

// The PNG read function expects an array of rows, not a single 1-D array
Expand All @@ -113,7 +115,7 @@ void PNGLibrary::loadImage(const string& filename, FBSurface& surface, VariantLi
readMetaData(png_ptr, info_ptr, metaData);

// Load image into the surface, setting the correct dimensions
loadImagetoSurface(surface);
loadImagetoSurface(surface, hasAlpha);

// Cleanup
if(png_ptr)
Expand Down Expand Up @@ -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)
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())
ReadInfo.buffer.reserve(req_buffer_size * 1.5);

Expand All @@ -394,13 +396,13 @@ bool PNGLibrary::allocateStorage(size_t width, size_t height)

ReadInfo.width = static_cast<png_uint_32>(width);
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;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PNGLibrary::loadImagetoSurface(FBSurface& surface)
void PNGLibrary::loadImagetoSurface(FBSurface& surface, bool hasAlpha)
{
// First determine if we need to resize the surface
const uInt32 iw = ReadInfo.width, ih = ReadInfo.height;
Expand All @@ -423,8 +425,12 @@ void PNGLibrary::loadImagetoSurface(FBSurface& surface)
{
const uInt8* i_ptr = i_buf;
uInt32* s_ptr = s_buf;
for(uInt32 icol = 0; icol < ReadInfo.width; ++icol, i_ptr += 3)
*s_ptr++ = fb.mapRGB(*i_ptr, *(i_ptr+1), *(i_ptr+2));
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)
*s_ptr++ = fb.mapRGB(*i_ptr, *(i_ptr+1), *(i_ptr+2));
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/common/PNGLibrary.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ class PNGLibrary
@param width The width 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.
Expand All @@ -173,7 +173,7 @@ class PNGLibrary
@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.
Expand Down
9 changes: 9 additions & 0 deletions src/emucore/FBBackend.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,15 @@ class FBBackend
*/
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
FrameBuffer area. Note that this isn't the same as any internal
Expand Down
4 changes: 2 additions & 2 deletions src/emucore/FrameBuffer.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -1320,8 +1320,8 @@ FBInitStatus FrameBuffer::applyVideoMode()
const string& path = myOSystem.snapshotLoadDir().getPath();

//loadBezel(path + "Atari-2600.png");
//loadBezel(path + "Combat.png");
loadBezel(path + "Asteroids (USA).png");
loadBezel(path + "Combat (USA).png");
//loadBezel(path + "Asteroids (USA).png");
}

resetSurfaces();
Expand Down
11 changes: 11 additions & 0 deletions src/emucore/FrameBuffer.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,17 @@ class FrameBuffer
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
FrameBuffer area. Note that this isn't the same as any internal
Expand Down

0 comments on commit 88e737c

Please sign in to comment.