mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-15 09:11:48 +00:00
Restore the last gameplay frame while on the intermission screen
This commit is contained in:
parent
96aa11c825
commit
ed967f077c
3 changed files with 121 additions and 4 deletions
|
@ -415,6 +415,7 @@ static void D_Display(void)
|
|||
if (rendermode == render_soft)
|
||||
{
|
||||
VID_BlitLinearScreen(screens[0], screens[1], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes);
|
||||
Y_ConsiderScreenBuffer();
|
||||
usebuffer = true;
|
||||
}
|
||||
lastdraw = false;
|
||||
|
|
123
src/y_inter.c
123
src/y_inter.c
|
@ -143,9 +143,21 @@ static patch_t *widebgpatch = NULL; // INTERSCW
|
|||
static patch_t *bgtile = NULL; // SPECTILE/SRB2BACK
|
||||
static patch_t *interpic = NULL; // custom picture defined in map header
|
||||
static boolean usetile;
|
||||
static INT32 timer;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
INT32 source_width, source_height;
|
||||
INT32 source_bpp, source_rowbytes;
|
||||
UINT8 *source_picture;
|
||||
INT32 target_width, target_height;
|
||||
INT32 target_bpp, target_rowbytes;
|
||||
UINT8 *target_picture;
|
||||
} y_buffer_t;
|
||||
|
||||
boolean usebuffer = false;
|
||||
static boolean useinterpic;
|
||||
static INT32 timer;
|
||||
static y_buffer_t *y_buffer;
|
||||
|
||||
static INT32 intertic;
|
||||
static INT32 tallydonetic = -1;
|
||||
|
@ -153,6 +165,8 @@ static INT32 endtic = -1;
|
|||
|
||||
intertype_t intertype = int_none;
|
||||
|
||||
static void Y_RescaleScreenBuffer(void);
|
||||
static void Y_CleanupScreenBuffer(void);
|
||||
static void Y_AwardCoopBonuses(void);
|
||||
static void Y_AwardSpecialStageBonus(void);
|
||||
static void Y_CalculateCompetitionWinners(void);
|
||||
|
@ -207,6 +221,94 @@ static void Y_IntermissionTokenDrawer(void)
|
|||
V_DrawCroppedPatch(32<<FRACBITS, y<<FRACBITS, FRACUNIT/2, 0, tokenicon, 0, 0, SHORT(tokenicon->width), calc);
|
||||
}
|
||||
|
||||
//
|
||||
// Y_ConsiderScreenBuffer
|
||||
//
|
||||
// Can we copy the current screen
|
||||
// to a buffer?
|
||||
//
|
||||
void Y_ConsiderScreenBuffer(void)
|
||||
{
|
||||
if (gameaction != ga_completed)
|
||||
return;
|
||||
|
||||
if (y_buffer == NULL)
|
||||
y_buffer = Z_Calloc(sizeof(y_buffer_t), PU_STATIC, NULL);
|
||||
else
|
||||
return;
|
||||
|
||||
y_buffer->source_width = vid.width;
|
||||
y_buffer->source_height = vid.height;
|
||||
y_buffer->source_bpp = vid.bpp;
|
||||
y_buffer->source_rowbytes = vid.rowbytes;
|
||||
y_buffer->source_picture = ZZ_Alloc(y_buffer->source_width*vid.bpp * y_buffer->source_height);
|
||||
VID_BlitLinearScreen(screens[1], y_buffer->source_picture, vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes);
|
||||
|
||||
// Make the rescaled screen buffer
|
||||
Y_RescaleScreenBuffer();
|
||||
}
|
||||
|
||||
//
|
||||
// Y_RescaleScreenBuffer
|
||||
//
|
||||
// Write the rescaled source picture,
|
||||
// to the destination picture that
|
||||
// has the current screen's resolutions.
|
||||
//
|
||||
static void Y_RescaleScreenBuffer(void)
|
||||
{
|
||||
INT32 sx, sy; // source
|
||||
INT32 dx, dy; // dest
|
||||
fixed_t scalefac, yscalefac;
|
||||
fixed_t rowfrac, colfrac;
|
||||
UINT8 *dest;
|
||||
|
||||
// Who knows?
|
||||
if (y_buffer == NULL)
|
||||
return;
|
||||
|
||||
if (y_buffer->target_picture)
|
||||
Z_Free(y_buffer->target_picture);
|
||||
|
||||
y_buffer->target_width = vid.width;
|
||||
y_buffer->target_height = vid.height;
|
||||
y_buffer->target_rowbytes = vid.rowbytes;
|
||||
y_buffer->target_bpp = vid.bpp;
|
||||
y_buffer->target_picture = ZZ_Alloc(y_buffer->target_width*vid.bpp * y_buffer->target_height);
|
||||
dest = y_buffer->target_picture;
|
||||
|
||||
scalefac = FixedDiv(y_buffer->target_width*FRACUNIT, y_buffer->source_width*FRACUNIT);
|
||||
yscalefac = FixedDiv(y_buffer->target_height*FRACUNIT, y_buffer->source_height*FRACUNIT);
|
||||
|
||||
rowfrac = FixedDiv(FRACUNIT, yscalefac);
|
||||
colfrac = FixedDiv(FRACUNIT, scalefac);
|
||||
|
||||
for (sy = 0, dy = 0; sy < (y_buffer->source_height << FRACBITS) && dy < y_buffer->target_height; sy += rowfrac, dy++)
|
||||
for (sx = 0, dx = 0; sx < (y_buffer->source_width << FRACBITS) && dx < y_buffer->target_width; sx += colfrac, dx += y_buffer->target_bpp)
|
||||
dest[(dy * y_buffer->target_rowbytes) + dx] = y_buffer->source_picture[((sy>>FRACBITS) * y_buffer->source_width) + (sx>>FRACBITS)];
|
||||
}
|
||||
|
||||
//
|
||||
// Y_CleanupScreenBuffer
|
||||
//
|
||||
// Free all related memory.
|
||||
//
|
||||
static void Y_CleanupScreenBuffer(void)
|
||||
{
|
||||
// Who knows?
|
||||
if (y_buffer == NULL)
|
||||
return;
|
||||
|
||||
if (y_buffer->target_picture)
|
||||
Z_Free(y_buffer->target_picture);
|
||||
|
||||
if (y_buffer->source_picture)
|
||||
Z_Free(y_buffer->source_picture);
|
||||
|
||||
Z_Free(y_buffer);
|
||||
y_buffer = NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Y_IntermissionDrawer
|
||||
//
|
||||
|
@ -229,12 +331,23 @@ void Y_IntermissionDrawer(void)
|
|||
else if (!usetile)
|
||||
{
|
||||
if (rendermode == render_soft && usebuffer)
|
||||
VID_BlitLinearScreen(screens[1], screens[0], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes);
|
||||
{
|
||||
// no y_buffer
|
||||
if (y_buffer == NULL)
|
||||
VID_BlitLinearScreen(screens[1], screens[0], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes);
|
||||
else
|
||||
{
|
||||
// Maybe the resolution changed?
|
||||
if ((y_buffer->target_width != vid.width) || (y_buffer->target_height != vid.height))
|
||||
Y_RescaleScreenBuffer();
|
||||
|
||||
// Blit the already-scaled screen buffer to the current screen
|
||||
VID_BlitLinearScreen(y_buffer->target_picture, screens[0], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes);
|
||||
}
|
||||
}
|
||||
#ifdef HWRENDER
|
||||
else if(rendermode != render_soft && usebuffer)
|
||||
{
|
||||
HWR_DrawIntermissionBG();
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
|
@ -2096,6 +2209,8 @@ static void Y_UnloadData(void)
|
|||
if (rendermode != render_soft)
|
||||
return;
|
||||
|
||||
Y_CleanupScreenBuffer();
|
||||
|
||||
// unload the background patches
|
||||
UNLOAD(bgpatch);
|
||||
UNLOAD(widebgpatch);
|
||||
|
|
|
@ -15,6 +15,7 @@ void Y_IntermissionDrawer(void);
|
|||
void Y_Ticker(void);
|
||||
void Y_StartIntermission(void);
|
||||
void Y_EndIntermission(void);
|
||||
void Y_ConsiderScreenBuffer(void);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue