Port Saturn's VoteBG scaling code

Thanks to Alug and Indev as per usual
This commit is contained in:
NepDisk 2025-06-26 11:13:32 -04:00
parent 7226fd120e
commit 11e29d5afa
8 changed files with 173 additions and 55 deletions

View file

@ -1172,6 +1172,7 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_renderview);
CV_RegisterVar(&cv_vhseffect);
CV_RegisterVar(&cv_shittyscreen);
CV_RegisterVar(&cv_votebgscaling);
CV_RegisterVar(&cv_renderer);
CV_RegisterVar(&cv_scr_depth);
CV_RegisterVar(&cv_scr_width);

View file

@ -9246,6 +9246,12 @@ boolean P_AddWadFile(const char *wadfilename, wadcompat_t compat)
return true;
}
// check for replacement votescreen backgrounds
boolean wideracereplaced = false;
boolean racereplaced = false;
boolean widebattlereplaced = false;
boolean battlereplaced = false;
//
// Add a WAD file and do the per-WAD setup stages.
// Call P_MultiSetupWadFiles as soon as possible after any number of these.
@ -9411,6 +9417,44 @@ UINT16 P_PartialAddWadFile(const char *wadfilename, wadcompat_t compat)
//
R_LoadSpriteInfoLumps(wadnum, numlumps);
//
// check for votescreen replacements
//
if (!wideracereplaced && !racereplaced && !widebattlereplaced && !battlereplaced)
{
lumpinfo = wadfiles[wadnum]->lumpinfo;
for (i = 0; i < numlumps; i++, lumpinfo++)
{
name = lumpinfo->name;
// widescreen patch Race
if (!wideracereplaced && !strncmp(name, "INTERSCW", 8))
{
wideracereplaced = true;
continue;
}
if (!racereplaced && !strncmp(name, "INTERSCR", 8))
{
racereplaced = true;
continue;
}
// widescreen patch Battle
if (!widebattlereplaced && !strncmp(name, "BATTLSCW", 8))
{
widebattlereplaced = true;
continue;
}
if (!battlereplaced && !strncmp(name, "BATTLSCR", 8))
{
battlereplaced = true;
continue;
}
}
}
refreshdirmenu &= ~REFRESHDIR_GAMEDATA; // Under usual circumstances we'd wait for REFRESHDIR_ flags to disappear the next frame, but this one's a bit too dangerous for that...
partadd_stage = 0;
return wadnum;

View file

@ -87,6 +87,11 @@ void HWR_LoadLevel(void);
#endif
boolean P_AddWadFile(const char *wadfilename, wadcompat_t compat);
extern boolean wideracereplaced;
extern boolean racereplaced;
extern boolean widebattlereplaced;
extern boolean battlereplaced;
#define MAPRET_ADDED (1)
#define MAPRET_CURRENTREPLACED (1<<1)
UINT8 P_InitMapData(boolean existingmapheaders);

View file

@ -65,6 +65,9 @@ consvar_t cv_vhseffect = CVAR_INIT ("vhspause", "On", CV_SAVE, CV_OnOff, NULL);
static CV_PossibleValue_t shittyscreen_cons_t[] = {{0, "Okay"}, {1, "Shitty"}, {2, "Extra Shitty"}, {0, NULL}};
consvar_t cv_shittyscreen = CVAR_INIT ("televisionsignal", "Okay", 0, shittyscreen_cons_t, NULL);
static CV_PossibleValue_t votescale_cons_t[] = {{0, "Vanilla"}, {1, "Adaptive"}, {2, "VerticalFill"}, {3, "HorizontalFill"}, {0, NULL}};
consvar_t cv_votebgscaling = CVAR_INIT ("votebgscaling", "Adaptive", 0, votescale_cons_t, NULL);
CV_PossibleValue_t cv_renderer_t[] = {
{1, "Software"},
#ifdef HWRENDER

View file

@ -133,7 +133,7 @@ extern INT32 scr_bpp;
extern UINT8 *scr_borderpatch; // patch used to fill the view borders
extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_renderer, cv_renderhitbox, cv_fullscreen;
extern consvar_t cv_vhseffect, cv_shittyscreen;
extern consvar_t cv_vhseffect, cv_shittyscreen, cv_votebgscaling;
extern consvar_t cv_parallelsoftware;
// wait for page flipping to end or not

View file

@ -1539,6 +1539,51 @@ void V_DrawPatchFill(patch_t *pat)
}
}
// Draws a patch and tries to always fill the screen with the patch
void V_DrawAdaptiveScaledFullScreenPatch(patch_t *patch)
{
fixed_t x = 0, y = 0;
fixed_t scale = ((vid.width * FRACUNIT) / patch->width); // fit the screen horizontally
fixed_t scaled_height = FixedMul(patch->height << FRACBITS, scale);
// however, if this means the patch doesent fill out the screen vertically then
if (scaled_height < (vid.height << FRACBITS))
{
scale = ((vid.height * FRACUNIT) / patch->height); // scale it to fit the screen vertically
x = ((vid.width << FRACBITS) - FixedMul(patch->width << FRACBITS, scale)) / 2;
}
else
y = (vid.height << FRACBITS) - scaled_height;
V_DrawFixedPatch(x, y, scale, V_NOSCALEPATCH, patch, NULL);
}
// Draws a patch and scales it to fill out the screen vertically while remaining centered
void V_DrawVerticallyScaledFullScreenPatch(patch_t *patch)
{
fixed_t scale = ((vid.height * FRACUNIT) / patch->height);
fixed_t x = ((vid.width << FRACBITS) - FixedMul(patch->width << FRACBITS, scale)) / 2; // i fucking hate maths
V_DrawFixedPatch(x, 0, scale, V_NOSCALEPATCH, patch, NULL);
}
// Draws a patch and scales it to fill out the screen horizontally
// centers the patch when its too small to fit the screen vertically
void V_DrawHorizontallyScaledFullScreenPatch(patch_t *patch)
{
fixed_t scale = ((vid.width * FRACUNIT) / patch->width);
fixed_t scaled_height = FixedMul(patch->height << FRACBITS, scale);
fixed_t y = (vid.height << FRACBITS) - scaled_height;
// center it if it does not fit the screen vertically
if (scaled_height < (vid.height << FRACBITS))
{
y /= 2;
}
V_DrawFixedPatch(0, y, scale, V_NOSCALEPATCH, patch, NULL);
}
void V_DrawVhsEffect(boolean rewind)
{
static fixed_t upbary = 100*FRACUNIT, downbary = 150*FRACUNIT;

View file

@ -341,6 +341,10 @@ void V_DoPostProcessor(INT32 view, INT32 param);
void V_DrawPatchFill(patch_t *pat);
void V_DrawAdaptiveScaledFullScreenPatch(patch_t *patch);
void V_DrawVerticallyScaledFullScreenPatch(patch_t *patch);
void V_DrawHorizontallyScaledFullScreenPatch(patch_t *patch);
void VID_BlitLinearScreen(const UINT8 *srcptr, UINT8 *destptr, INT32 width, INT32 height, size_t srcrowbytes,
size_t destrowbytes);

View file

@ -367,27 +367,22 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32))
static void Y_AnimatedVoteScreenCheck(void)
{
char tmpPrefix[] = "INTS";
boolean stopSearching = false;
if (luaVoteScreen)
strncpy(tmpPrefix, luaVoteScreen, 4);
else
{
if(gametype == GT_BATTLE)
strcpy(tmpPrefix, "BTLS");
}
else if(gametype == GT_BATTLE)
strcpy(tmpPrefix, "BTLS");
strncpy(animPrefix, tmpPrefix, 4);
animPrefix[4] = 'C';
strncpy(animWidePrefix, tmpPrefix, 4);
animWidePrefix[4] = 'W';
foundAnimVoteFrames = 0;
foundAnimVoteWideFrames = 0;
foundAnimVoteFrames = foundAnimVoteWideFrames = 0;
currentAnimFrame = 0;
INT32 i = 1;
while(!stopSearching)
for (;;)
{
boolean normalLumpExists = W_LumpExists(va("%sC%d", tmpPrefix, i));
boolean wideLumpExists = W_LumpExists(va("%sW%d", tmpPrefix, i));
@ -401,7 +396,7 @@ static void Y_AnimatedVoteScreenCheck(void)
foundAnimVoteWideFrames++;
}
else // If we don't find at least frame 1 (e.g VEXTRN1), let's just stop looking
stopSearching = true;
break;
i++;
}
@ -1132,35 +1127,53 @@ static void Y_UnloadData(void)
// SRB2Kart: Voting!
static void Y_DrawVoteBackground(patch_t *patch)
{
switch (cv_votebgscaling.value)
{
case 1: // adaptive
V_DrawAdaptiveScaledFullScreenPatch(patch);
break;
case 2: // vertical-fill
V_DrawVerticallyScaledFullScreenPatch(patch);
break;
case 3: // horizontal-fill
V_DrawHorizontallyScaledFullScreenPatch(patch);
break;
case 0: // vanilla
default:
V_DrawScaledPatch(((vid.width/2) / vid.dupx) - (patch->width/2),
(vid.height / vid.dupy) - patch->height,
V_SNAPTOTOP|V_SNAPTOLEFT, patch);
break;
}
}
// Y_DrawAnimatedVoteScreenPatch
//
// Draw animated patch based on frame counter on vote screen
//
static inline void Y_DrawAnimatedVoteScreenPatch(boolean widePatch)
static void Y_DrawAnimatedVoteScreenPatch(boolean widePatch)
{
INT32 nextframe = 0;
patch_t *votebg = NULL;
char tempAnimPrefix[7];
(widePatch) ? strcpy(tempAnimPrefix, animWidePrefix) : strcpy(tempAnimPrefix, animPrefix);
INT32 tempFoundAnimVoteFrames = (widePatch) ? foundAnimVoteWideFrames : foundAnimVoteFrames;
const INT32 tempFoundAnimVoteFrames = ((widePatch ? foundAnimVoteWideFrames : foundAnimVoteFrames) - 1);
strcpy(tempAnimPrefix, (widePatch ? animWidePrefix : animPrefix));
// Just in case someone provides LESS widescreen frames than normal frames or vice versa, reset the frame counter to 0
if (widePatch)
{
if (currentAnimFrame > foundAnimVoteWideFrames-1)
currentAnimFrame = 0;
}
else
{
if (currentAnimFrame > foundAnimVoteFrames-1)
currentAnimFrame = 0;
}
if (currentAnimFrame > tempFoundAnimVoteFrames)
currentAnimFrame = 0;
patch_t *background = W_CachePatchName(va("%s%d", tempAnimPrefix, currentAnimFrame + 1), PU_CACHE);
V_DrawScaledPatch(((vid.width/2) / vid.dupx) - (SHORT(background->width)/2), // Keep the width/height adjustments, for screens that are less wide than 320(?)
(vid.height / vid.dupy) - SHORT(background->height),
V_SNAPTOTOP|V_SNAPTOLEFT, background);
nextframe = (currentAnimFrame + 1);
if (renderisnewtic && votetic % 2 == 0 && !paused)
currentAnimFrame = (currentAnimFrame + 1 > tempFoundAnimVoteFrames - 1) ? 0 : currentAnimFrame + 1;
votebg = W_CachePatchName(va("%s%d", (widePatch ? animWidePrefix : animPrefix), nextframe), PU_PATCH);
Y_DrawVoteBackground(votebg);
if (renderisnewtic && (votetic % 2 == 0) && !paused)
currentAnimFrame = (nextframe > tempFoundAnimVoteFrames) ? 0 : nextframe;
}
static fixed_t Y_CalculatePicScale(fixed_t picscale, INT32 hypoti)
@ -1179,6 +1192,32 @@ static fixed_t Y_CalculatePicScale(fixed_t picscale, INT32 hypoti)
return picscale;
}
static void Y_DrawVoteScreenPatch(void)
{
patch_t *votebg = NULL;
const boolean widescreen = (vid.width / vid.dupx > 320);
if (foundAnimVoteWideFrames || foundAnimVoteFrames)
{
Y_DrawAnimatedVoteScreenPatch((foundAnimVoteWideFrames && widescreen));
return;
}
votebg = bgpatch; // non widescreen patch
UINT8 prefgametype = (votelevels[0][1] & ~0x80);
const boolean widebgreplaced = (prefgametype == GT_BATTLE) ? widebattlereplaced : wideracereplaced;
const boolean bgreplaced = (prefgametype == GT_BATTLE) ? battlereplaced : racereplaced;
if ((widescreen && (widebgreplaced || !bgreplaced))
|| (!widescreen && (widebgreplaced && !bgreplaced)))
{
votebg = widebgpatch;
}
Y_DrawVoteBackground(votebg);
}
//
// Y_VoteDrawer
//
@ -1236,31 +1275,8 @@ void Y_VoteDrawer(void)
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
if (widebgpatch && vid.width / vid.dupx > 320) {
if(foundAnimVoteWideFrames == 0){
V_DrawScaledPatch(((vid.width/2) / vid.dupx) - (SHORT(widebgpatch->width)/2),
(vid.height / vid.dupy) - SHORT(widebgpatch->height),
V_SNAPTOTOP|V_SNAPTOLEFT, widebgpatch);
} else {
// patch_t *currPatch = W_CachePatchName(va("%s%d", animPrefix, currentAnimFrame+1), PU_CACHE);
// V_DrawScaledPatch(((vid.width/2) / vid.dupx) - (SHORT(currPatch->width)/2), // Keep the width/height adjustments, for screens that are less wide than 320(?)
// (vid.height / vid.dupy) - SHORT(currPatch->height),
// V_SNAPTOTOP|V_SNAPTOLEFT, currPatch);
// if(votetic % 4 == 0 && !paused){
// currentAnimFrame = (currentAnimFrame+1 > foundAnimVoteFrames-1) ? 0 : currentAnimFrame + 1;
// }
Y_DrawAnimatedVoteScreenPatch(true);
}
} else {
if(foundAnimVoteFrames == 0) {
V_DrawScaledPatch(((vid.width/2) / vid.dupx) - (SHORT(bgpatch->width)/2), // Keep the width/height adjustments, for screens that are less wide than 320(?)
(vid.height / vid.dupy) - SHORT(bgpatch->height),
V_SNAPTOTOP|V_SNAPTOLEFT, bgpatch);
} else {
Y_DrawAnimatedVoteScreenPatch(false);
}
}
// decides which votebg to draw and draws it
Y_DrawVoteScreenPatch();
rowval = (votemax*3)+((votemax > 1) ? (votemax - 1) : 0);
for (i = 0; i < (rowval+1); i++) // First, we need to figure out the height of this thing...