mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-02-07 00:41:26 +00:00
Merge branch 'intermission-buffer' into 'master'
Restore the last gameplay frame while on the intermission screen See merge request STJr/SRB2Internal!444
This commit is contained in:
commit
d9a54a6b61
3 changed files with 129 additions and 5 deletions
|
@ -227,7 +227,14 @@ static void D_Display(void)
|
||||||
SCR_SetMode(); // change video mode
|
SCR_SetMode(); // change video mode
|
||||||
|
|
||||||
if (vid.recalc)
|
if (vid.recalc)
|
||||||
|
{
|
||||||
SCR_Recalc(); // NOTE! setsizeneeded is set by SCR_Recalc()
|
SCR_Recalc(); // NOTE! setsizeneeded is set by SCR_Recalc()
|
||||||
|
#ifdef HWRENDER
|
||||||
|
// Shoot! The screen texture was flushed!
|
||||||
|
if ((rendermode == render_opengl) && (gamestate == GS_INTERMISSION))
|
||||||
|
usebuffer = false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// change the view size if needed
|
// change the view size if needed
|
||||||
if (setsizeneeded)
|
if (setsizeneeded)
|
||||||
|
@ -415,6 +422,7 @@ static void D_Display(void)
|
||||||
if (rendermode == render_soft)
|
if (rendermode == render_soft)
|
||||||
{
|
{
|
||||||
VID_BlitLinearScreen(screens[0], screens[1], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes);
|
VID_BlitLinearScreen(screens[0], screens[1], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes);
|
||||||
|
Y_ConsiderScreenBuffer();
|
||||||
usebuffer = true;
|
usebuffer = true;
|
||||||
}
|
}
|
||||||
lastdraw = false;
|
lastdraw = false;
|
||||||
|
|
125
src/y_inter.c
125
src/y_inter.c
|
@ -143,9 +143,21 @@ static patch_t *widebgpatch = NULL; // INTERSCW
|
||||||
static patch_t *bgtile = NULL; // SPECTILE/SRB2BACK
|
static patch_t *bgtile = NULL; // SPECTILE/SRB2BACK
|
||||||
static patch_t *interpic = NULL; // custom picture defined in map header
|
static patch_t *interpic = NULL; // custom picture defined in map header
|
||||||
static boolean usetile;
|
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;
|
boolean usebuffer = false;
|
||||||
static boolean useinterpic;
|
static boolean useinterpic;
|
||||||
static INT32 timer;
|
static y_buffer_t *y_buffer;
|
||||||
|
|
||||||
static INT32 intertic;
|
static INT32 intertic;
|
||||||
static INT32 tallydonetic = -1;
|
static INT32 tallydonetic = -1;
|
||||||
|
@ -153,6 +165,8 @@ static INT32 endtic = -1;
|
||||||
|
|
||||||
intertype_t intertype = int_none;
|
intertype_t intertype = int_none;
|
||||||
|
|
||||||
|
static void Y_RescaleScreenBuffer(void);
|
||||||
|
static void Y_CleanupScreenBuffer(void);
|
||||||
static void Y_AwardCoopBonuses(void);
|
static void Y_AwardCoopBonuses(void);
|
||||||
static void Y_AwardSpecialStageBonus(void);
|
static void Y_AwardSpecialStageBonus(void);
|
||||||
static void Y_CalculateCompetitionWinners(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);
|
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
|
// Y_IntermissionDrawer
|
||||||
//
|
//
|
||||||
|
@ -229,12 +331,23 @@ void Y_IntermissionDrawer(void)
|
||||||
else if (!usetile)
|
else if (!usetile)
|
||||||
{
|
{
|
||||||
if (rendermode == render_soft && usebuffer)
|
if (rendermode == render_soft && usebuffer)
|
||||||
VID_BlitLinearScreen(screens[1], screens[0], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes);
|
|
||||||
#ifdef HWRENDER
|
|
||||||
else if(rendermode != render_soft && usebuffer)
|
|
||||||
{
|
{
|
||||||
HWR_DrawIntermissionBG();
|
// 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
|
#endif
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2108,6 +2221,8 @@ static void Y_UnloadData(void)
|
||||||
if (rendermode != render_soft)
|
if (rendermode != render_soft)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Y_CleanupScreenBuffer();
|
||||||
|
|
||||||
// unload the background patches
|
// unload the background patches
|
||||||
UNLOAD(bgpatch);
|
UNLOAD(bgpatch);
|
||||||
UNLOAD(widebgpatch);
|
UNLOAD(widebgpatch);
|
||||||
|
|
|
@ -15,6 +15,7 @@ void Y_IntermissionDrawer(void);
|
||||||
void Y_Ticker(void);
|
void Y_Ticker(void);
|
||||||
void Y_StartIntermission(void);
|
void Y_StartIntermission(void);
|
||||||
void Y_EndIntermission(void);
|
void Y_EndIntermission(void);
|
||||||
|
void Y_ConsiderScreenBuffer(void);
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue