hwr2: do GIF recording in screenshot pass

This commit is contained in:
James R 2023-02-13 21:41:25 -08:00 committed by Eidolon
parent 11fecebc47
commit a19b476d3d
11 changed files with 75 additions and 15 deletions

View file

@ -2022,7 +2022,7 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
} }
I_UpdateNoVsync(); // page flip or blit buffer I_UpdateNoVsync(); // page flip or blit buffer
if (moviemode) if (moviemode)
M_SaveFrame(); M_LegacySaveFrame();
S_UpdateSounds(); S_UpdateSounds();
S_UpdateClosedCaptions(); S_UpdateClosedCaptions();
} }

View file

@ -873,7 +873,7 @@ void D_SRB2Loop(void)
// Only take screenshots after drawing. // Only take screenshots after drawing.
if (moviemode) if (moviemode)
M_SaveFrame(); M_LegacySaveFrame();
#ifdef HWRENDER #ifdef HWRENDER
if (rendermode == render_opengl && takescreenshot) if (rendermode == render_opengl && takescreenshot)
M_DoLegacyGLScreenShot(); M_DoLegacyGLScreenShot();

View file

@ -438,7 +438,7 @@ void F_IntroTicker(void)
I_FinishUpdate(); // Update the screen with the image Tails 06-19-2001 I_FinishUpdate(); // Update the screen with the image Tails 06-19-2001
if (moviemode) // make sure we save frames for the white hold too if (moviemode) // make sure we save frames for the white hold too
M_SaveFrame(); M_LegacySaveFrame();
} }
} }

View file

@ -526,7 +526,7 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu, const char *colormap, boolean r
} }
if (moviemode) if (moviemode)
M_SaveFrame(); M_LegacySaveFrame();
NetKeepAlive(); // Update the network so we don't cause timeouts NetKeepAlive(); // Update the network so we don't cause timeouts
} }

View file

@ -1602,7 +1602,7 @@ void G_PreLevelTitleCard(void)
NetKeepAlive(); // Prevent timeouts NetKeepAlive(); // Prevent timeouts
if (moviemode) if (moviemode)
M_SaveFrame(); M_LegacySaveFrame();
while (!((nowtime = I_GetTime()) - lasttime)) while (!((nowtime = I_GetTime()) - lasttime))
{ {

View file

@ -34,7 +34,7 @@ void ScreenshotPass::prepass(Rhi& rhi)
); );
} }
doing_screenshot_ = takescreenshot; doing_screenshot_ = takescreenshot || moviemode == MM_GIF;
} }
void ScreenshotPass::transfer(Rhi& rhi, Handle<TransferContext> ctx) void ScreenshotPass::transfer(Rhi& rhi, Handle<TransferContext> ctx)
@ -63,6 +63,15 @@ void ScreenshotPass::postpass(Rhi& rhi)
return; return;
} }
M_DoScreenShot(width_, height_, tcb::as_bytes(tcb::span(pixel_data_))); if (takescreenshot)
{
M_DoScreenShot(width_, height_, tcb::as_bytes(tcb::span(pixel_data_)));
}
if (moviemode == MM_GIF)
{
M_SaveFrame(width_, height_, tcb::as_bytes(tcb::span(pixel_data_)));
}
doing_screenshot_ = false; doing_screenshot_ = false;
} }

View file

@ -508,7 +508,7 @@ static size_t gifframe_size = 8192;
#ifdef HWRENDER #ifdef HWRENDER
static colorlookup_t gif_colorlookup; static colorlookup_t gif_colorlookup;
static void GIF_rgbconvert(UINT8 *linear, UINT8 *scr) static void GIF_rgbconvert(const UINT8 *linear, UINT8 *scr)
{ {
UINT8 r, g, b; UINT8 r, g, b;
size_t src = 0, dest = 0; size_t src = 0, dest = 0;
@ -532,13 +532,18 @@ static void GIF_rgbconvert(UINT8 *linear, UINT8 *scr)
// GIF_framewrite // GIF_framewrite
// writes a frame into the file. // writes a frame into the file.
// //
static void GIF_framewrite(void) static void GIF_framewrite(INT32 input_width, INT32 input_height, const UINT8 *input)
{ {
UINT8 *p; UINT8 *p;
UINT8 *movie_screen = screens[2]; UINT8 *movie_screen = screens[2];
INT32 blitx, blity, blitw, blith; INT32 blitx, blity, blitw, blith;
boolean palchanged; boolean palchanged;
(void)input_width;
(void)input_height;
I_Assert(input_width == vid.width && input_height == vid.height);
if (!gifframe_data) if (!gifframe_data)
gifframe_data = Z_Malloc(gifframe_size, PU_STATIC, NULL); gifframe_data = Z_Malloc(gifframe_size, PU_STATIC, NULL);
p = gifframe_data; p = gifframe_data;
@ -565,7 +570,10 @@ static void GIF_framewrite(void)
// blit to temp screen // blit to temp screen
if (rendermode == render_soft) if (rendermode == render_soft)
I_ReadScreen(movie_screen); {
I_Assert(input != NULL);
GIF_rgbconvert(input, movie_screen);
}
#ifdef HWRENDER #ifdef HWRENDER
else if (rendermode == render_opengl) else if (rendermode == render_opengl)
{ {
@ -594,7 +602,10 @@ static void GIF_framewrite(void)
// Copy the first frame into the movie screen // Copy the first frame into the movie screen
// OpenGL already does the same above. // OpenGL already does the same above.
if (gif_frames == 0 && rendermode == render_soft) if (gif_frames == 0 && rendermode == render_soft)
I_ReadScreen(movie_screen); {
I_Assert(input != NULL);
GIF_rgbconvert(input, screens[0]);
}
movie_screen = screens[0]; movie_screen = screens[0];
} }
@ -751,7 +762,16 @@ INT32 GIF_open(const char *filename)
void GIF_frame(void) void GIF_frame(void)
{ {
// there's not much actually needed here, is there. // there's not much actually needed here, is there.
GIF_framewrite(); GIF_framewrite(vid.width, vid.height, NULL);
}
//
// GIF_frame_rgb24
// writes a frame into the output gif, with existing image data
//
void GIF_frame_rgb24(INT32 width, INT32 height, const UINT8 *buffer)
{
GIF_framewrite(width, height, buffer);
} }
// //

View file

@ -28,6 +28,7 @@ extern "C" {
#ifdef HAVE_ANIGIF #ifdef HAVE_ANIGIF
INT32 GIF_open(const char *filename); INT32 GIF_open(const char *filename);
void GIF_frame(void); void GIF_frame(void);
void GIF_frame_rgb24(INT32 width, INT32 height, const UINT8 *buffer);
INT32 GIF_close(void); INT32 GIF_close(void);
#endif #endif

View file

@ -1384,9 +1384,18 @@ void M_StartMovie(void)
#endif #endif
} }
void M_SaveFrame(void) void M_LegacySaveFrame(void)
{ {
#if NUMSCREENS > 2 #if NUMSCREENS > 2
// TODO: until HWR2 replaces legacy OpenGL renderer, this
// function still needs to called for OpenGL.
#ifdef HWRENDER
if (rendermode != render_opengl)
#endif
{
return;
}
// paranoia: should be unnecessary without singletics // paranoia: should be unnecessary without singletics
static tic_t oldtic = 0; static tic_t oldtic = 0;
@ -1463,6 +1472,26 @@ void M_SaveFrame(void)
#endif #endif
} }
void M_SaveFrame(uint32_t width, uint32_t height, tcb::span<const std::byte> data)
{
if (moviemode != MM_GIF)
{
return;
}
static tic_t oldtic = 0;
// limit the recording to TICRATE
if (oldtic == I_GetTime())
{
return;
}
oldtic = I_GetTime();
GIF_frame_rgb24(width, height, reinterpret_cast<const uint8_t*>(data.data()));
}
void M_StopMovie(void) void M_StopMovie(void)
{ {
#if NUMSCREENS > 2 #if NUMSCREENS > 2

View file

@ -28,6 +28,7 @@
#include <tcb/span.hpp> #include <tcb/span.hpp>
void M_DoScreenShot(uint32_t width, uint32_t height, tcb::span<const std::byte> data); void M_DoScreenShot(uint32_t width, uint32_t height, tcb::span<const std::byte> data);
void M_SaveFrame(uint32_t width, uint32_t height, tcb::span<const std::byte> data);
extern "C" { extern "C" {
#endif #endif
@ -48,7 +49,7 @@ extern consvar_t cv_zlib_memorya, cv_zlib_levela, cv_zlib_strategya, cv_zlib_win
extern consvar_t cv_apng_delay, cv_apng_downscale; extern consvar_t cv_apng_delay, cv_apng_downscale;
void M_StartMovie(void); void M_StartMovie(void);
void M_SaveFrame(void); void M_LegacySaveFrame(void);
void M_StopMovie(void); void M_StopMovie(void);
// the file where game vars and settings are saved // the file where game vars and settings are saved

View file

@ -7571,7 +7571,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
} \ } \
lastwipetic = nowtime; \ lastwipetic = nowtime; \
if (moviemode) \ if (moviemode) \
M_SaveFrame(); \ M_LegacySaveFrame(); \
NetKeepAlive(); \ NetKeepAlive(); \
} \ } \