mirror of
https://git.do.srb2.org/KartKrew/Kart-Public.git
synced 2024-12-26 12:21:19 +00:00
Fix screenshot functionality in fullscreen in SDL2
This commit is contained in:
parent
77af3a8f95
commit
121fcd8369
7 changed files with 103 additions and 0 deletions
|
@ -769,6 +769,9 @@ UINT8 *HWR_GetScreenshot(void)
|
|||
if (!buf)
|
||||
return NULL;
|
||||
// returns 24bit 888 RGB
|
||||
#ifdef HAVE_SDL
|
||||
if (!HWD.pfnReadScreenTexture(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf))
|
||||
#endif
|
||||
HWD.pfnReadRect(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf);
|
||||
return buf;
|
||||
}
|
||||
|
@ -782,8 +785,19 @@ boolean HWR_Screenshot(const char *lbmname)
|
|||
return false;
|
||||
|
||||
// returns 24bit 888 RGB
|
||||
#ifdef HAVE_SDL
|
||||
// Sryder: SDL2 uses borderless fullscreen mode, and creates a screen texture to upscale to the screen size.
|
||||
// This breaks screenshots because the code here takes a screenshot of just the resolution from the bottom
|
||||
// left corner, while the "true" resolution is the monitor resolution. We can either take a screenshot of
|
||||
// the true resolution or just use the already made screen texture
|
||||
// NOTE: The SDL1.2 version should get a return of false from ReadScreenTexture as no screen texture will have
|
||||
// been made, this will also mean that if the screen texture doesn't exist for some reason it will fall
|
||||
// back to the old version
|
||||
if (!HWD.pfnReadScreenTexture(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf))
|
||||
#endif
|
||||
HWD.pfnReadRect(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf);
|
||||
|
||||
|
||||
#ifdef USE_PNG
|
||||
ret = M_SavePNG(lbmname, buf, vid.width, vid.height, NULL);
|
||||
#else
|
||||
|
|
|
@ -58,6 +58,9 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags);
|
|||
EXPORT void HWRAPI(ClearBuffer) (FBOOLEAN ColorMask, FBOOLEAN DepthMask, FRGBAFloat *ClearColor);
|
||||
EXPORT void HWRAPI(SetTexture) (FTextureInfo *TexInfo);
|
||||
EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height, INT32 dst_stride, UINT16 *dst_data);
|
||||
#ifdef HAVE_SDL
|
||||
EXPORT boolean HWRAPI(ReadScreenTexture) (INT32 x, INT32 y, INT32 width, INT32 height, INT32 dst_stride, UINT16 * dst_data);
|
||||
#endif
|
||||
EXPORT void HWRAPI(GClipRect) (INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip);
|
||||
EXPORT void HWRAPI(ClearMipMapCache) (void);
|
||||
|
||||
|
@ -104,6 +107,9 @@ struct hwdriver_s
|
|||
ClearBuffer pfnClearBuffer;
|
||||
SetTexture pfnSetTexture;
|
||||
ReadRect pfnReadRect;
|
||||
#ifdef HAVE_SDL
|
||||
ReadScreenTexture pfnReadScreenTexture;
|
||||
#endif
|
||||
GClipRect pfnGClipRect;
|
||||
ClearMipMapCache pfnClearMipMapCache;
|
||||
SetSpecialState pfnSetSpecialState;//Hurdler: added for backward compatibility
|
||||
|
|
|
@ -260,6 +260,7 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...)
|
|||
#define pglTexEnvi glTexEnvi
|
||||
#define pglTexParameteri glTexParameteri
|
||||
#define pglTexImage2D glTexImage2D
|
||||
#define pglGetTexImage glGetTexImage
|
||||
|
||||
/* Fog */
|
||||
#define pglFogf glFogf
|
||||
|
@ -381,6 +382,8 @@ typedef void (APIENTRY * PFNglTexParameteri) (GLenum target, GLenum pname, GLint
|
|||
static PFNglTexParameteri pglTexParameteri;
|
||||
typedef void (APIENTRY * PFNglTexImage2D) (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
|
||||
static PFNglTexImage2D pglTexImage2D;
|
||||
typedef void (APIENTRY * PFNglGetTexImage) (GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels);
|
||||
static PFNglGetTexImage pglGetTexImage;
|
||||
|
||||
/* Fog */
|
||||
typedef void (APIENTRY * PFNglFogf) (GLenum pname, GLfloat param);
|
||||
|
@ -507,6 +510,7 @@ boolean SetupGLfunc(void)
|
|||
GETOPENGLFUNC(pglTexEnvi , glTexEnvi)
|
||||
GETOPENGLFUNC(pglTexParameteri , glTexParameteri)
|
||||
GETOPENGLFUNC(pglTexImage2D , glTexImage2D)
|
||||
GETOPENGLFUNC(pglGetTexImage , glGetTexImage)
|
||||
|
||||
GETOPENGLFUNC(pglFogf , glFogf)
|
||||
GETOPENGLFUNC(pglFogfv , glFogfv)
|
||||
|
@ -933,6 +937,81 @@ EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height,
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_SDL
|
||||
EXPORT boolean HWRAPI(ReadScreenTexture) (INT32 x, INT32 y, INT32 width,
|
||||
INT32 height, INT32 dst_stride,
|
||||
UINT16 * dst_data)
|
||||
{
|
||||
#ifdef KOS_GL_COMPATIBILITY
|
||||
(void)x;
|
||||
(void)y;
|
||||
(void)width;
|
||||
(void)height;
|
||||
(void)dst_stride;
|
||||
(void)dst_data;
|
||||
#else
|
||||
INT32 i, j;
|
||||
INT32 texsize = 2048;
|
||||
GLubyte *image;
|
||||
// DBG_Printf ("ReadScreenTexture()\n");
|
||||
if (screentexture == 0)
|
||||
return false; // No screen texture
|
||||
|
||||
if(screen_width <= 1024)
|
||||
texsize = 1024;
|
||||
if(screen_width <= 512)
|
||||
texsize = 512;
|
||||
|
||||
if (x < 0)
|
||||
x = 0;
|
||||
if (x + width > screen_width)
|
||||
width = screen_width - x;
|
||||
if (y < 0)
|
||||
y = 0;
|
||||
if (y + height > screen_height)
|
||||
height = screen_height - y;
|
||||
|
||||
image = malloc(texsize*texsize*3*sizeof (*image));
|
||||
if (!image)
|
||||
return false;
|
||||
pglBindTexture(GL_TEXTURE_2D, finalScreenTexture);
|
||||
tex_downloaded = finalScreenTexture;
|
||||
pglGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
|
||||
|
||||
if (dst_stride == width*3)
|
||||
{
|
||||
UINT8 *dest = (void *)dst_data;
|
||||
for (i = y + height-1; i >= y; i--)
|
||||
{
|
||||
for (j = x; j < width + x; j++)
|
||||
{
|
||||
dest[((height-1-i-y)*width+j-x)*3] = image[(i*texsize+j)*3];
|
||||
dest[((height-1-i-y)*width+j-x)*3+1] = image[(i*texsize+j)*3+1];
|
||||
dest[((height-1-i-y)*width+j-x)*3+2] = image[(i*texsize+j)*3+2];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Sryder: NOTE: I'm not entirely sure this works, as far as I know nothing in the game uses it.
|
||||
for (i = y + height-1; i >= y; i--)
|
||||
{
|
||||
for (j = x; j < width + x; j++)
|
||||
{
|
||||
dst_data[(height-1-i-y)*width+j-x] =
|
||||
(UINT16)(
|
||||
((image[(i*texsize+j)*3]>>3)<<11) |
|
||||
((image[(i*texsize+j)*3+1]>>2)<<5) |
|
||||
((image[(i*texsize+j)*3+2]>>3)));
|
||||
}
|
||||
}
|
||||
}
|
||||
free(image);
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// -----------------+
|
||||
// GClipRect : Defines the 2D hardware clipping window
|
||||
|
|
|
@ -83,6 +83,7 @@ void *hwSym(const char *funcName,void *handle)
|
|||
GETFUNC(ClearBuffer);
|
||||
GETFUNC(SetTexture);
|
||||
GETFUNC(ReadRect);
|
||||
GETFUNC(ReadScreenTexture);
|
||||
GETFUNC(GClipRect);
|
||||
GETFUNC(ClearMipMapCache);
|
||||
GETFUNC(SetSpecialState);
|
||||
|
|
|
@ -1430,6 +1430,7 @@ void I_StartupGraphics(void)
|
|||
HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL);
|
||||
HWD.pfnSetTexture = hwSym("SetTexture",NULL);
|
||||
HWD.pfnReadRect = hwSym("ReadRect",NULL);
|
||||
HWD.pfnReadScreenTexture= hwSym("ReadScreenTexture",NULL);
|
||||
HWD.pfnGClipRect = hwSym("GClipRect",NULL);
|
||||
HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL);
|
||||
HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL);
|
||||
|
|
|
@ -89,6 +89,7 @@ void *hwSym(const char *funcName,void *handle)
|
|||
GETFUNC(ClearBuffer);
|
||||
GETFUNC(SetTexture);
|
||||
GETFUNC(ReadRect);
|
||||
GETFUNC(ReadScreenTexture);
|
||||
GETFUNC(GClipRect);
|
||||
GETFUNC(ClearMipMapCache);
|
||||
GETFUNC(SetSpecialState);
|
||||
|
|
|
@ -1960,6 +1960,7 @@ void I_StartupGraphics(void)
|
|||
HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL);
|
||||
HWD.pfnSetTexture = hwSym("SetTexture",NULL);
|
||||
HWD.pfnReadRect = hwSym("ReadRect",NULL);
|
||||
HWD.pfnReadScreenTexture= hwSym("ReadScreenTexture",NULL);
|
||||
HWD.pfnGClipRect = hwSym("GClipRect",NULL);
|
||||
HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL);
|
||||
HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL);
|
||||
|
|
Loading…
Reference in a new issue