diff --git a/src/m_anigif.c b/src/m_anigif.c index 56d3c87075fc7a8779e04c46a9467d5fb70df6d1..f761db143b0cb016ee0395e9f045c8cdeb49d444 100644 --- a/src/m_anigif.c +++ b/src/m_anigif.c @@ -20,6 +20,10 @@ #include "i_video.h" #include "m_misc.h" +#ifdef HWRENDER +#include "hardware/hw_main.h" +#endif + // GIFs are always little-endian #include "byteptr.h" @@ -29,6 +33,7 @@ consvar_t cv_gif_downscale = {"gif_downscale", "On", CV_SAVE, CV_OnOff, NULL, 0 #ifdef HAVE_ANIGIF static boolean gif_optimize = false; // So nobody can do something dumb static boolean gif_downscale = false; // like changing cvars mid output +static RGBA_t *gif_palette = NULL; static FILE *gif_out = NULL; static INT32 gif_frames = 0; @@ -428,10 +433,7 @@ static void GIF_headwrite(void) // write color table { - RGBA_t *pal = ((cv_screenshot_colorprofile.value) - ? pLocalPalette - : pMasterPalette); - + RGBA_t *pal = gif_palette; for (i = 0; i < 256; i++) { WRITEUINT8(p, pal[i].s.red); @@ -457,6 +459,32 @@ const UINT8 gifframe_gchead[4] = {0x21,0xF9,0x04,0x04}; // GCE, bytes, packed by static UINT8 *gifframe_data = NULL; static size_t gifframe_size = 8192; +#ifdef HWRENDER +static void hwrconvert(void) +{ + UINT8 *linear = HWR_GetScreenshot(); + UINT8 *dest = screens[2]; + UINT8 r, g, b; + INT32 x, y; + size_t i = 0; + + InitColorLUT(gif_palette); + + for (y = 0; y < vid.height; y++) + { + for (x = 0; x < vid.width; x++, i += 3) + { + r = (UINT8)linear[i]; + g = (UINT8)linear[i + 1]; + b = (UINT8)linear[i + 2]; + dest[(y * vid.width) + x] = colorlookup[r >> SHIFTCOLORBITS][g >> SHIFTCOLORBITS][b >> SHIFTCOLORBITS]; + } + } + + free(linear); +} +#endif + // // GIF_framewrite // writes a frame into the file. @@ -482,7 +510,12 @@ static void GIF_framewrite(void) GIF_optimizeregion(cur_screen, movie_screen, &blitx, &blity, &blitw, &blith); // blit to temp screen - I_ReadScreen(movie_screen); + if (rendermode == render_soft) + I_ReadScreen(movie_screen); +#ifdef HWRENDER + else if (rendermode == render_opengl) + hwrconvert(); +#endif } else { @@ -491,7 +524,18 @@ static void GIF_framewrite(void) blith = vid.height; if (gif_frames == 0) - I_ReadScreen(movie_screen); + { + if (rendermode == render_soft) + I_ReadScreen(movie_screen); +#ifdef HWRENDER + else if (rendermode == render_opengl) + { + hwrconvert(); + VID_BlitLinearScreen(screens[2], screens[0], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes); + } +#endif + } + movie_screen = screens[0]; } @@ -580,7 +624,7 @@ static void GIF_framewrite(void) // INT32 GIF_open(const char *filename) { -#ifdef HWRENDER +#if 0 if (rendermode != render_soft) { CONS_Alert(CONS_WARNING, M_GetText("GIFs cannot be taken in non-software modes!\n")); @@ -594,6 +638,16 @@ INT32 GIF_open(const char *filename) gif_optimize = (!!cv_gif_optimize.value); gif_downscale = (!!cv_gif_downscale.value); + + // GIF color table + // In hardware mode, uses the master palette + gif_palette = ((cv_screenshot_colorprofile.value +#ifdef HWRENDER + && (rendermode == render_soft) +#endif + ) ? pLocalPalette + : pMasterPalette); + GIF_headwrite(); gif_frames = 0; return 1; diff --git a/src/m_misc.c b/src/m_misc.c index d973833857a339c4aa61589348aa473c959c0d3d..c8383d3fe1d55df99cdc05bd274bc93824940029 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -1161,12 +1161,8 @@ void M_StartMovie(void) switch (cv_moviemode.value) { case MM_GIF: - if (rendermode == render_soft) - { - moviemode = M_StartMovieGIF(pathname); - break; - } - /* FALLTHRU */ + moviemode = M_StartMovieGIF(pathname); + break; case MM_APNG: moviemode = M_StartMovieAPNG(pathname); break; diff --git a/src/r_data.h b/src/r_data.h index 3dcb22ec4989e870cf72dc623f3494a902611aba..f028f2f5d16ef54da544d56780448adc84d8b858 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -171,6 +171,8 @@ const char *R_NameForColormap(extracolormap_t *extra_colormap); #define R_PutRgbaRGB(r, g, b) (R_PutRgbaR(r) + R_PutRgbaG(g) + R_PutRgbaB(b)) #define R_PutRgbaRGBA(r, g, b, a) (R_PutRgbaRGB(r, g, b) + R_PutRgbaA(a)) +UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b); + extern INT32 numtextures; #endif diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index c876a323f3fbbce1b4a716994cc92a34a09c8913..e054381eec6183cba9b46d4948dc4f0723a0b088 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1441,6 +1441,7 @@ INT32 VID_SetMode(INT32 modeNum) //Impl_SetWindowName("SRB2 "VERSIONSTRING); SDLSetMode(vid.width, vid.height, USE_FULLSCREEN); + Impl_VideoSetupBuffer(); if (rendermode == render_soft) { @@ -1449,8 +1450,6 @@ INT32 VID_SetMode(INT32 modeNum) SDL_FreeSurface(bufSurface); bufSurface = NULL; } - - Impl_VideoSetupBuffer(); } return SDL_TRUE; @@ -1573,7 +1572,7 @@ static void Impl_VideoSetupSDLBuffer(void) static void Impl_VideoSetupBuffer(void) { // Set up game's software render buffer - if (rendermode == render_soft) + //if (rendermode == render_soft) { vid.rowbytes = vid.width * vid.bpp; vid.direct = NULL; diff --git a/src/v_video.c b/src/v_video.c index c6ec22767f6f4518e7ba1ee231ac73edf800fc65..c91e5f213e8fb7ec0eca1ddc9d29176dbc2d8440 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -3244,6 +3244,29 @@ Unoptimized version #endif } +// Taken from my videos-in-SRB2 project +// Generates a color look-up table +// which has up to 64 colors at each channel +// (see the defines in v_video.h) + +UINT8 colorlookup[CLUTSIZE][CLUTSIZE][CLUTSIZE]; + +void InitColorLUT(RGBA_t *palette) +{ + UINT8 r, g, b; + static boolean clutinit = false; + static RGBA_t *lastpalette = NULL; + if ((!clutinit) || (lastpalette != palette)) + { + for (r = 0; r < CLUTSIZE; r++) + for (g = 0; g < CLUTSIZE; g++) + for (b = 0; b < CLUTSIZE; b++) + colorlookup[r][g][b] = NearestColor(r << SHIFTCOLORBITS, g << SHIFTCOLORBITS, b << SHIFTCOLORBITS); + clutinit = true; + lastpalette = palette; + } +} + // V_Init // old software stuff, buffers are allocated at video mode setup // here we set the screens[x] pointers accordingly @@ -3255,13 +3278,9 @@ void V_Init(void) const INT32 screensize = vid.rowbytes * vid.height; LoadMapPalette(); - // hardware modes do not use screens[] pointers + for (i = 0; i < NUMSCREENS; i++) screens[i] = NULL; - if (rendermode != render_soft) - { - return; // be sure to cause a NULL read/write error so we detect it, in case of.. - } // start address of NUMSCREENS * width*height vidbuffers if (base) diff --git a/src/v_video.h b/src/v_video.h index 2434fec816b002f3fa61412901ef16f39bfa5f13..36d1914af6edec7f1b9996e4c767d507dcaf8a71 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -37,6 +37,18 @@ cv_allcaps; // Allocates buffer screens, call before R_Init. void V_Init(void); +// Taken from my videos-in-SRB2 project +// Generates a color look-up table +// which has up to 64 colors at each channel + +#define COLORBITS 6 +#define SHIFTCOLORBITS (8-COLORBITS) +#define CLUTSIZE (1<<COLORBITS) + +extern UINT8 colorlookup[CLUTSIZE][CLUTSIZE][CLUTSIZE]; + +void InitColorLUT(RGBA_t *palette); + // Set the current RGB palette lookup to use for palettized graphics void V_SetPalette(INT32 palettenum);