1
0
Fork 0
mirror of https://github.com/TerryCavanagh/VVVVVV.git synced 2024-12-22 09:39:43 +01:00

Fix screenshots in Flip Mode

One problem with internal screenshot capture is that we rely on SDL's
render subsystem to flip the screen in Flip Mode, while leaving our
actual screen untouched. Since we source the screenshot from the screen
and not what SDL renders, we need to flip the screenshot ourselves when
saving an internal capture.

To do this, we need to support 24-bit colors in DrawPixel() and
ReadPixel(). Luckily, this isn't too hard to do. A 24-bit color is just
a tuple of three bytes, and we just need to do a small amount of bitwise
math to pack/unpack them to a single integer for SDL_GetRGB() and
SDL_MapRGB().
This commit is contained in:
Misa 2023-10-31 22:52:42 -07:00 committed by Misa Elizabeth Kai
parent ae5ef9753c
commit 20f0fafa5e

View file

@ -97,18 +97,27 @@ void DrawPixel(SDL_Surface* surface, const int x, const int y, const SDL_Color c
const SDL_PixelFormat* fmt = surface->format; const SDL_PixelFormat* fmt = surface->format;
const int bpp = fmt->BytesPerPixel; const int bpp = fmt->BytesPerPixel;
Uint32* pixel = (Uint32*) ((Uint8*) surface->pixels + y * surface->pitch + x * bpp); Uint8* pixel = (Uint8*) surface->pixels + y * surface->pitch + x * bpp;
Uint32* pixel32 = (Uint32*) pixel;
switch (bpp) switch (bpp)
{ {
case 1: case 1:
case 2: case 2:
SDL_assert(0 && "Colors other than 24- or 32- bit unsupported!");
break;
case 3: case 3:
SDL_assert(0 && "Non-32-bit colors not supported!"); {
return; const Uint32 single = SDL_MapRGB(fmt, color.r, color.g, color.b);
pixel[0] = (single & 0xFF0000) >> 16;
pixel[1] = (single & 0x00FF00) >> 8;
pixel[2] = (single & 0x0000FF) >> 0;
break;
}
case 4: case 4:
*pixel = SDL_MapRGBA(fmt, color.r, color.g, color.b, color.a); *pixel32 = SDL_MapRGBA(fmt, color.r, color.g, color.b, color.a);
} }
} }
@ -131,18 +140,26 @@ SDL_Color ReadPixel(const SDL_Surface* surface, const int x, const int y)
const SDL_PixelFormat* fmt = surface->format; const SDL_PixelFormat* fmt = surface->format;
const int bpp = surface->format->BytesPerPixel; const int bpp = surface->format->BytesPerPixel;
const Uint32* pixel = (Uint32*) ((Uint8*) surface->pixels + y * surface->pitch + x * bpp); const Uint8* pixel = (Uint8*) surface->pixels + y * surface->pitch + x * bpp;
const Uint32* pixel32 = (Uint32*) pixel;
switch (bpp) switch (bpp)
{ {
case 1: case 1:
case 2: case 2:
case 3: SDL_assert(0 && "Colors other than 24- or 32- bit unsupported!");
SDL_assert(0 && "Non-32-bit colors not supported!");
break; break;
case 3:
{
const Uint32 single = (pixel[0] << 16) | (pixel[1] << 8) | (pixel[2] << 0);
SDL_GetRGB(single, fmt, &color.r, &color.g, &color.b);
color.a = 255;
break;
}
case 4: case 4:
SDL_GetRGBA(*pixel, fmt, &color.r, &color.g, &color.b, &color.a); SDL_GetRGBA(*pixel32, fmt, &color.r, &color.g, &color.b, &color.a);
} }
return color; return color;
@ -312,5 +329,20 @@ bool TakeScreenshot(SDL_Surface** surface)
return false; return false;
} }
/* Need to manually vertically reverse pixels in Flip Mode. */
if (graphics.flipmode)
{
for (int x = 0; x < (*surface)->w; x++)
{
for (int y = 0; y < (*surface)->h / 2; y++)
{
const SDL_Color upper = ReadPixel(*surface, x, y);
const SDL_Color lower = ReadPixel(*surface, x, (*surface)->h - 1 - y);
DrawPixel(*surface, x, y, lower);
DrawPixel(*surface, x, (*surface)->h - 1 - y, upper);
}
}
}
return true; return true;
} }