Add support for flashpals in screenshots

This commit is contained in:
Jimita the Cat 2019-01-02 00:41:52 -03:00
parent 5278d1ca20
commit e765b9400c
6 changed files with 56 additions and 37 deletions

View file

@ -1082,21 +1082,24 @@ UINT8 *HWR_GetScreenshot(void)
return buf; return buf;
} }
boolean HWR_Screenshot(const char *lbmname) boolean HWR_Screenshot(const char *pathname, char **error)
{ {
boolean ret; boolean ret;
UINT8 *buf = malloc(vid.width * vid.height * 3 * sizeof (*buf)); UINT8 *buf = malloc(vid.width * vid.height * 3 * sizeof (*buf));
if (!buf) if (!buf)
{
*error = "Failed to allocate memory for HWR_Screenshot";
return false; return false;
}
// returns 24bit 888 RGB // returns 24bit 888 RGB
HWD.pfnReadRect(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf); HWD.pfnReadRect(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf);
#ifdef USE_PNG #ifdef USE_PNG
ret = M_SavePNG(lbmname, buf, vid.width, vid.height, NULL); ret = M_SavePNG(pathname, buf, vid.width, vid.height, NULL, &*error); // c_irl
#else #else
ret = saveTGA(lbmname, buf, vid.width, vid.height); ret = saveTGA(pathname, buf, vid.width, vid.height);
#endif #endif
free(buf); free(buf);
return ret; return ret;

View file

@ -38,8 +38,6 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player);
void HWR_RenderPlayerView(INT32 viewnumber, player_t *player); void HWR_RenderPlayerView(INT32 viewnumber, player_t *player);
void HWR_DrawViewBorder(INT32 clearlines); void HWR_DrawViewBorder(INT32 clearlines);
void HWR_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum); void HWR_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum);
UINT8 *HWR_GetScreenshot(void);
boolean HWR_Screenshot(const char *lbmname);
void HWR_InitTextureMapping(void); void HWR_InitTextureMapping(void);
void HWR_SetViewSize(void); void HWR_SetViewSize(void);
void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option); void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option);
@ -54,6 +52,9 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color);
void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32 options); // Lat: separate flags from color since color needs to be an uint to work right. void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32 options); // Lat: separate flags from color since color needs to be an uint to work right.
void HWR_DrawPic(INT32 x,INT32 y,lumpnum_t lumpnum); void HWR_DrawPic(INT32 x,INT32 y,lumpnum_t lumpnum);
UINT8 *HWR_GetScreenshot(void);
boolean HWR_Screenshot(const char *pathname, char **error);
void HWR_AddCommands(void); void HWR_AddCommands(void);
void HWR_CorrectSWTricks(void); void HWR_CorrectSWTricks(void);
void transform(float *cx, float *cy, float *cz); void transform(float *cx, float *cy, float *cz);

View file

@ -30,6 +30,7 @@
#include "g_game.h" #include "g_game.h"
#include "m_misc.h" #include "m_misc.h"
#include "hu_stuff.h" #include "hu_stuff.h"
#include "st_stuff.h"
#include "v_video.h" #include "v_video.h"
#include "z_zone.h" #include "z_zone.h"
#include "g_input.h" #include "g_input.h"
@ -585,6 +586,21 @@ void M_SaveConfig(const char *filename)
fclose(f); fclose(f);
} }
// ==========================================================================
// SCREENSHOTS
// ==========================================================================
static UINT8 screenshot_palette[768];
static void M_CreateScreenShotPalette(void)
{
size_t i, j;
for (i = 0, j = 0; i < 768; i += 3, j++)
{
RGBA_t locpal = pLocalPalette[(max(st_palette,0)*256)+j];
screenshot_palette[i] = locpal.s.red;
screenshot_palette[i+1] = locpal.s.green;
screenshot_palette[i+2] = locpal.s.blue;
}
}
#if NUMSCREENS > 2 #if NUMSCREENS > 2
static const char *Newsnapshotfile(const char *pathname, const char *ext) static const char *Newsnapshotfile(const char *pathname, const char *ext)
@ -1047,6 +1063,7 @@ static boolean M_SetupaPNG(png_const_charp filename, png_bytep pal)
static inline moviemode_t M_StartMovieAPNG(const char *pathname) static inline moviemode_t M_StartMovieAPNG(const char *pathname)
{ {
#ifdef USE_APNG #ifdef USE_APNG
UINT8 *palette;
const char *freename = NULL; const char *freename = NULL;
boolean ret = false; boolean ret = false;
@ -1062,10 +1079,8 @@ static inline moviemode_t M_StartMovieAPNG(const char *pathname)
return MM_OFF; return MM_OFF;
} }
if (rendermode == render_soft) if (rendermode == render_soft) M_CreateScreenShotPalette();
ret = M_SetupaPNG(va(pandf,pathname,freename), W_CacheLumpName(GetPalette(), PU_CACHE)); ret = M_SetupaPNG(va(pandf,pathname,freename), (palette = screenshot_palette));
else
ret = M_SetupaPNG(va(pandf,pathname,freename), NULL);
if (!ret) if (!ret)
{ {
@ -1268,10 +1283,11 @@ void M_StopMovie(void)
* \param data The image data. * \param data The image data.
* \param width Width of the picture. * \param width Width of the picture.
* \param height Height of the picture. * \param height Height of the picture.
* \param palette Palette of image data * \param palette Palette of image data.
* \note if palette is NULL, BGR888 format * \note if palette is NULL, BGR888 format
* \param error Error string to return, if screenshot failed.
*/ */
boolean M_SavePNG(const char *filename, void *data, int width, int height, const UINT8 *palette) boolean M_SavePNG(const char *filename, void *data, int width, int height, const UINT8 *palette, char **error)
{ {
png_structp png_ptr; png_structp png_ptr;
png_infop png_info_ptr; png_infop png_info_ptr;
@ -1286,15 +1302,14 @@ boolean M_SavePNG(const char *filename, void *data, int width, int height, const
png_FILE = fopen(filename,"wb"); png_FILE = fopen(filename,"wb");
if (!png_FILE) if (!png_FILE)
{ {
CONS_Debug(DBG_RENDER, "M_SavePNG: Error on opening %s for write\n", filename); *error = "Failed to open file for write";
return false; return false;
} }
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, PNG_error, PNG_warn);
PNG_error, PNG_warn);
if (!png_ptr) if (!png_ptr)
{ {
CONS_Debug(DBG_RENDER, "M_SavePNG: Error on initialize libpng\n"); *error = "Failed to initialize libpng";
fclose(png_FILE); fclose(png_FILE);
remove(filename); remove(filename);
return false; return false;
@ -1303,7 +1318,7 @@ boolean M_SavePNG(const char *filename, void *data, int width, int height, const
png_info_ptr = png_create_info_struct(png_ptr); png_info_ptr = png_create_info_struct(png_ptr);
if (!png_info_ptr) if (!png_info_ptr)
{ {
CONS_Debug(DBG_RENDER, "M_SavePNG: Error on allocate for libpng\n"); *error = "Failed to allocate memory for libpng";
png_destroy_write_struct(&png_ptr, NULL); png_destroy_write_struct(&png_ptr, NULL);
fclose(png_FILE); fclose(png_FILE);
remove(filename); remove(filename);
@ -1316,7 +1331,7 @@ boolean M_SavePNG(const char *filename, void *data, int width, int height, const
if (setjmp(png_jmpbuf(png_ptr))) if (setjmp(png_jmpbuf(png_ptr)))
#endif #endif
{ {
//CONS_Debug(DBG_RENDER, "libpng write error on %s\n", filename); *error = "libpng write error";
png_destroy_write_struct(&png_ptr, &png_info_ptr); png_destroy_write_struct(&png_ptr, &png_info_ptr);
fclose(png_FILE); fclose(png_FILE);
remove(filename); remove(filename);
@ -1445,9 +1460,8 @@ void M_ScreenShot(void)
} }
/** Takes a screenshot. /** Takes a screenshot.
* The screenshot is saved as "srb2xxxx.pcx" (or "srb2xxxx.tga" in hardware * The screenshot is saved as "srb2xxxx.png" where xxxx is the lowest
* rendermode) where xxxx is the lowest four-digit number for which a file * four-digit number for which a file does not already exist.
* does not already exist.
* *
* \sa HWR_ScreenShot * \sa HWR_ScreenShot
*/ */
@ -1456,11 +1470,16 @@ void M_DoScreenShot(void)
#if NUMSCREENS > 2 #if NUMSCREENS > 2
const char *freename = NULL, *pathname = "."; const char *freename = NULL, *pathname = ".";
boolean ret = false; boolean ret = false;
char *error = "Unknown error";
UINT8 *linear = NULL; UINT8 *linear = NULL;
// Don't take multiple screenshots, obviously // Don't take multiple screenshots, obviously
takescreenshot = false; takescreenshot = false;
// how does one take a screenshot without a render system?
if (rendermode == render_none)
return;
if (cv_screenshot_option.value == 0) if (cv_screenshot_option.value == 0)
pathname = usehome ? srb2home : srb2path; pathname = usehome ? srb2home : srb2path;
else if (cv_screenshot_option.value == 1) else if (cv_screenshot_option.value == 1)
@ -1471,16 +1490,13 @@ void M_DoScreenShot(void)
pathname = cv_screenshot_folder.string; pathname = cv_screenshot_folder.string;
#ifdef USE_PNG #ifdef USE_PNG
if (rendermode != render_none)
freename = Newsnapshotfile(pathname,"png"); freename = Newsnapshotfile(pathname,"png");
#else #else
if (rendermode == render_soft) if (rendermode == render_soft)
freename = Newsnapshotfile(pathname,"pcx"); freename = Newsnapshotfile(pathname,"pcx");
else if (rendermode != render_none) else if (rendermode == render_opengl)
freename = Newsnapshotfile(pathname,"tga"); freename = Newsnapshotfile(pathname,"tga");
#endif #endif
else
I_Error("Can't take a screenshot without a render system");
if (rendermode == render_soft) if (rendermode == render_soft)
{ {
@ -1494,18 +1510,16 @@ void M_DoScreenShot(void)
// save the pcx file // save the pcx file
#ifdef HWRENDER #ifdef HWRENDER
if (rendermode != render_soft) if (rendermode == render_opengl)
ret = HWR_Screenshot(va(pandf,pathname,freename)); ret = HWR_Screenshot(va(pandf,pathname,freename), &error);
else else
#endif #endif
if (rendermode != render_none)
{ {
M_CreateScreenShotPalette();
#ifdef USE_PNG #ifdef USE_PNG
ret = M_SavePNG(va(pandf,pathname,freename), linear, vid.width, vid.height, ret = M_SavePNG(va(pandf,pathname,freename), linear, vid.width, vid.height, screenshot_palette, &error);
W_CacheLumpName(GetPalette(), PU_CACHE));
#else #else
ret = WritePCXfile(va(pandf,pathname,freename), linear, vid.width, vid.height, ret = WritePCXfile(va(pandf,pathname,freename), linear, vid.width, vid.height, screenshot_palette);
W_CacheLumpName(GetPalette(), PU_CACHE));
#endif #endif
} }
@ -1513,14 +1527,14 @@ failure:
if (ret) if (ret)
{ {
if (moviemode != MM_SCREENSHOT) if (moviemode != MM_SCREENSHOT)
CONS_Printf(M_GetText("screen shot %s saved in %s\n"), freename, pathname); CONS_Printf(M_GetText("Screen shot %s saved in %s\n"), freename, pathname);
} }
else else
{ {
if (freename) if (freename)
CONS_Printf(M_GetText("Couldn't create screen shot %s in %s\n"), freename, pathname); CONS_Alert(CONS_ERROR, M_GetText("Couldn't create screen shot %s in %s (%s)\n"), freename, pathname, error);
else else
CONS_Printf(M_GetText("Couldn't create screen shot (all 10000 slots used!) in %s\n"), pathname); CONS_Alert(CONS_ERROR, M_GetText("Couldn't create screen shot in %s (all 10000 slots used!)\n"), pathname);
if (moviemode == MM_SCREENSHOT) if (moviemode == MM_SCREENSHOT)
M_StopMovie(); M_StopMovie();

View file

@ -64,7 +64,7 @@ void FIL_ForceExtension(char *path, const char *extension);
boolean FIL_CheckExtension(const char *in); boolean FIL_CheckExtension(const char *in);
#ifdef HAVE_PNG #ifdef HAVE_PNG
boolean M_SavePNG(const char *filename, void *data, int width, int height, const UINT8 *palette); boolean M_SavePNG(const char *filename, void *data, int width, int height, const UINT8 *palette, char **error);
#endif #endif
extern boolean takescreenshot; extern boolean takescreenshot;

View file

@ -197,7 +197,7 @@ void ST_Ticker(void)
} }
// 0 is default, any others are special palettes. // 0 is default, any others are special palettes.
static INT32 st_palette = 0; INT32 st_palette = 0;
void ST_doPaletteStuff(void) void ST_doPaletteStuff(void)
{ {

View file

@ -58,6 +58,7 @@ boolean ST_SameTeam(player_t *a, player_t *b);
//-------------------- //--------------------
extern boolean st_overlay; // sb overlay on or off when fullscreen extern boolean st_overlay; // sb overlay on or off when fullscreen
extern INT32 st_palette; // 0 is default, any others are special palettes.
extern lumpnum_t st_borderpatchnum; extern lumpnum_t st_borderpatchnum;
// patches, also used in intermission // patches, also used in intermission