Merge remote-tracking branch 'origin/master' into frey

This commit is contained in:
AJ Martinez 2024-03-05 01:29:21 -07:00
commit 01bab662c5
36 changed files with 270 additions and 165 deletions

View file

@ -579,7 +579,7 @@ target_compile_definitions(SRB2SDL2 PRIVATE -DCMAKECONFIG)
# Misc. build options from Makefiles # Misc. build options from Makefiles
if(SRB2_CONFIG_DEBUGMODE) if(SRB2_CONFIG_DEBUGMODE)
target_compile_definitions(SRB2SDL2 PRIVATE -DZDEBUG -DPARANOIA -DRANGECHECK -DPACKETDROP) target_compile_definitions(SRB2SDL2 PRIVATE -DZDEBUG -DPARANOIA -DPACKETDROP)
endif() endif()
if(SRB2_CONFIG_TESTERS) if(SRB2_CONFIG_TESTERS)
target_compile_definitions(SRB2SDL2 PRIVATE -DTESTERS) target_compile_definitions(SRB2SDL2 PRIVATE -DTESTERS)

View file

@ -301,10 +301,7 @@ consvar_t cv_addons_search_case = Player("addons_search_case", "No").yes_no();
consvar_t cv_addons_search_type = Player("addons_search_type", "Anywhere").values({{0, "Start"}, {1, "Anywhere"}}); consvar_t cv_addons_search_type = Player("addons_search_type", "Anywhere").values({{0, "Start"}, {1, "Anywhere"}});
consvar_t cv_addons_showall = Player("addons_showall", "No").yes_no(); consvar_t cv_addons_showall = Player("addons_showall", "No").yes_no();
consvar_t cv_allowguests = Player("allowguests", "On").on_off(); consvar_t cv_allowguests = Player("allowguests", "On").on_off();
consvar_t cv_alttitle = Player("alttitle", "Off").on_off();
void AltTitle_OnChange(void);
consvar_t cv_alttitle = Player("alttitle", "Off").flags(CV_NOSHOWHELP).on_off().onchange_noinit(AltTitle_OnChange);
consvar_t cv_alwaysgrabmouse = GraphicsDriver("alwaysgrabmouse", "Off").on_off(); consvar_t cv_alwaysgrabmouse = GraphicsDriver("alwaysgrabmouse", "Off").on_off();
consvar_t cv_apng_delay = Player("apng_speed", "1x").values({ consvar_t cv_apng_delay = Player("apng_speed", "1x").values({

View file

@ -5920,7 +5920,7 @@ static void Local_Maketic(INT32 realtics)
INT32 i; INT32 i;
I_OsPolling(); // I_Getevent I_OsPolling(); // I_Getevent
D_ProcessEvents(); // menu responder, cons responder, D_ProcessEvents(true); // menu responder, cons responder,
// game responder calls HU_Responder, AM_Responder, // game responder calls HU_Responder, AM_Responder,
// and G_MapEventsToControls // and G_MapEventsToControls

View file

@ -264,7 +264,7 @@ void HandleGamepadDeviceEvents(event_t *ev)
// D_ProcessEvents // D_ProcessEvents
// Send all the events of the given timestamp down the responder chain // Send all the events of the given timestamp down the responder chain
// //
void D_ProcessEvents(void) void D_ProcessEvents(boolean callresponders)
{ {
event_t *ev; event_t *ev;
int i; int i;
@ -298,6 +298,9 @@ void D_ProcessEvents(void)
// update keys current state // update keys current state
G_MapEventsToControls(ev); G_MapEventsToControls(ev);
if (!callresponders)
continue; // eat
// Menu input // Menu input
#ifdef HAVE_THREADS #ifdef HAVE_THREADS
I_lock_mutex(&k_menu_mutex); I_lock_mutex(&k_menu_mutex);

View file

@ -50,7 +50,7 @@ void D_PostEvent(const event_t *ev);
void D_PostEvent_end(void); // delimiter for locking memory void D_PostEvent_end(void); // delimiter for locking memory
#endif #endif
void D_ProcessEvents(void); void D_ProcessEvents(boolean callresponders);
const char *D_Home(void); const char *D_Home(void);

View file

@ -5195,19 +5195,6 @@ FUNCNORETURN static ATTRNORETURN void Command_Quit_f(void)
I_Quit(); I_Quit();
} }
void AltTitle_OnChange(void)
{
if (!cv_alttitle.value)
return; // it's fine.
if (!M_SecretUnlocked(SECRET_ALTTITLE, true))
{
CONS_Printf(M_GetText("You haven't earned this yet.\n"));
CV_StealthSetValue(&cv_alttitle, 0);
return;
}
}
void ItemFinder_OnChange(void) void ItemFinder_OnChange(void)
{ {
if (!cv_itemfinder.value) if (!cv_itemfinder.value)

View file

@ -110,7 +110,7 @@ typedef enum {
} capsuletest_val_t; } capsuletest_val_t;
extern consvar_t cv_capsuletest; extern consvar_t cv_capsuletest;
extern consvar_t cv_alttitle, cv_itemfinder; extern consvar_t cv_itemfinder;
extern consvar_t cv_inttime, cv_advancemap; extern consvar_t cv_inttime, cv_advancemap;
extern consvar_t cv_overtime; extern consvar_t cv_overtime;
@ -255,7 +255,6 @@ boolean IsPlayerAdmin(INT32 playernum);
void SetAdminPlayer(INT32 playernum); void SetAdminPlayer(INT32 playernum);
void ClearAdminPlayers(void); void ClearAdminPlayers(void);
void RemoveAdminPlayer(INT32 playernum); void RemoveAdminPlayer(INT32 playernum);
void AltTitle_OnChange(void);
void ItemFinder_OnChange(void); void ItemFinder_OnChange(void);
void D_SetPassword(const char *pw); void D_SetPassword(const char *pw);

View file

@ -67,12 +67,10 @@ extern "C" {
#if !defined (NDEBUG) #if !defined (NDEBUG)
#define PACKETDROP #define PACKETDROP
#define PARANOIA #define PARANOIA
//#define RANGECHECK
#define ZDEBUG #define ZDEBUG
#endif #endif
// Uncheck this to compile debugging code // Uncheck this to compile debugging code
#define RANGECHECK
//#ifndef PARANOIA //#ifndef PARANOIA
//#define PARANOIA // do some tests that never fail but maybe //#define PARANOIA // do some tests that never fail but maybe
// turn this on by make etc.. DEBUGMODE = 1 or use the Debug profile in the VC++ projects // turn this on by make etc.. DEBUGMODE = 1 or use the Debug profile in the VC++ projects

View file

@ -1145,13 +1145,8 @@ static void F_CacheTitleScreen(void)
case TTMODE_RINGRACERS: case TTMODE_RINGRACERS:
{ {
if (!M_SecretUnlocked(SECRET_ALTTITLE, true))
{
CV_StealthSetValue(&cv_alttitle, 0);
}
kts_bumper = W_CachePatchName( kts_bumper = W_CachePatchName(
(cv_alttitle.value ? "KTSJUMPR1" : "KTSBUMPR1"), (M_UseAlternateTitleScreen() ? "KTSJUMPR1" : "KTSBUMPR1"),
PU_PATCH_LOWPRIORITY); PU_PATCH_LOWPRIORITY);
kts_eggman = W_CachePatchName("KTSEGG01", PU_PATCH_LOWPRIORITY); kts_eggman = W_CachePatchName("KTSEGG01", PU_PATCH_LOWPRIORITY);
kts_tails = W_CachePatchName("KTSTAL01", PU_PATCH_LOWPRIORITY); kts_tails = W_CachePatchName("KTSTAL01", PU_PATCH_LOWPRIORITY);

View file

@ -494,11 +494,6 @@ void F_RunWipe(UINT8 wipemode, UINT8 wipetype, boolean drawMenu, const char *col
WipeInAction = true; WipeInAction = true;
wipe_scr = screens[0]; wipe_scr = screens[0];
// FIXME: Wipes SUCK and drop input events for some reason, causing stuck gamepad inputs.
// It's better to ignore an intentional hold than to turn a tap into a phantom hold.
// (If you're removing this, remove the one after the inner loop too!)
G_ResetAllDeviceGameKeyDown();
// lastwipetic should either be 0 or the tic we last wiped // lastwipetic should either be 0 or the tic we last wiped
// on for fade-to-black // on for fade-to-black
for (;;) for (;;)
@ -558,6 +553,12 @@ void F_RunWipe(UINT8 wipemode, UINT8 wipetype, boolean drawMenu, const char *col
} }
I_OsPolling(); I_OsPolling();
// The event buffer is rather small so we need to
// process these events immediately, to make sure
// inputs don't get stuck (would happen a lot with
// some controllers that send a lot of analog
// events).
D_ProcessEvents(false);
I_UpdateNoBlit(); I_UpdateNoBlit();
if (drawMenu && rendermode != render_none) if (drawMenu && rendermode != render_none)
@ -586,11 +587,6 @@ void F_RunWipe(UINT8 wipemode, UINT8 wipetype, boolean drawMenu, const char *col
WipeInAction = false; WipeInAction = false;
// FIXME: Wipes SUCK and drop input events for some reason, causing stuck gamepad inputs.
// It's better to ignore an intentional hold than to turn a tap into a phantom hold.
// (If you're removing this, remove the one before the inner loop too!)
G_ResetAllDeviceGameKeyDown();
if (fcolor) if (fcolor)
{ {
Z_Free(fcolor); Z_Free(fcolor);

View file

@ -3588,6 +3588,14 @@ void G_AddGhost(savebuffer_t *buffer, const char *defdemoname)
if ((flags & DF_GRANDPRIX)) if ((flags & DF_GRANDPRIX))
p += 3; p += 3;
// Skip unlockables
{
UINT32 unlockables = READUINT32(p);
p += std::min<UINT32>(unlockables, MAXUNLOCKABLES);
}
p++; // mapmusrng
if (*p == DEMOMARKER) if (*p == DEMOMARKER)
{ {
CONS_Alert(CONS_NOTICE, M_GetText("Failed to add ghost %s: Replay is empty.\n"), defdemoname); CONS_Alert(CONS_NOTICE, M_GetText("Failed to add ghost %s: Replay is empty.\n"), defdemoname);
@ -3803,6 +3811,14 @@ staffbrief_t *G_GetStaffGhostBrief(UINT8 *buffer)
if ((flags & DF_GRANDPRIX)) if ((flags & DF_GRANDPRIX))
p += 3; p += 3;
// Skip unlockables
{
UINT32 unlockables = READUINT32(p);
p += std::min<UINT32>(unlockables, MAXUNLOCKABLES);
}
p++; // mapmusrng
// Assert first player is in and then read name // Assert first player is in and then read name
if (READUINT8(p) != 0) if (READUINT8(p) != 0)
goto fail; goto fail;

View file

@ -1191,8 +1191,10 @@ void G_DoLoadLevelEx(boolean resetplayer, gamestate_t newstate)
} }
// clear cmd building stuff // clear cmd building stuff
G_ResetAllDeviceGameKeyDown(); // We don't clear them anymore, so you can buffer inputs
G_ResetAllDeviceResponding(); // on map change / map restart.
//G_ResetAllDeviceGameKeyDown();
//G_ResetAllDeviceResponding();
// clear hud messages remains (usually from game startup) // clear hud messages remains (usually from game startup)
CON_ClearHUD(); CON_ClearHUD();

View file

@ -4740,10 +4740,11 @@ static void HWR_ProjectSprite(mobj_t *thing)
tr_y = FIXED_TO_FLOAT(interp.y); tr_y = FIXED_TO_FLOAT(interp.y);
// decide which patch to use for sprite relative to player // decide which patch to use for sprite relative to player
#ifdef RANGECHECK
if ((unsigned)thing->sprite >= numsprites) if ((unsigned)thing->sprite >= numsprites)
I_Error("HWR_ProjectSprite: invalid sprite number %i ", thing->sprite); {
#endif CONS_Debug(DBG_RENDER, "HWR_ProjectSprite: invalid sprite number %i\n", thing->sprite);
return;
}
rot = thing->frame&FF_FRAMEMASK; rot = thing->frame&FF_FRAMEMASK;
@ -5184,22 +5185,20 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
// decide which patch to use for sprite relative to player // decide which patch to use for sprite relative to player
if ((unsigned)thing->sprite >= numsprites) if ((unsigned)thing->sprite >= numsprites)
#ifdef RANGECHECK {
I_Error("HWR_ProjectPrecipitationSprite: invalid sprite number %i ", CONS_Debug(DBG_RENDER, "HWR_ProjectPrecipitationSprite: invalid sprite number %i\n",
thing->sprite); thing->sprite);
#else
return; return;
#endif }
sprdef = &sprites[thing->sprite]; sprdef = &sprites[thing->sprite];
if ((size_t)(thing->frame&FF_FRAMEMASK) >= sprdef->numframes) if ((size_t)(thing->frame&FF_FRAMEMASK) >= sprdef->numframes)
#ifdef RANGECHECK {
I_Error("HWR_ProjectPrecipitationSprite: invalid sprite frame %i : %i for %s", CONS_Debug(DBG_RENDER, "HWR_ProjectPrecipitationSprite: invalid sprite frame %i : %i for %s\n",
thing->sprite, thing->frame, sprnames[thing->sprite]); thing->sprite, thing->frame, sprnames[thing->sprite]);
#else
return; return;
#endif }
sprframe = &sprdef->spriteframes[ thing->frame & FF_FRAMEMASK]; sprframe = &sprdef->spriteframes[ thing->frame & FF_FRAMEMASK];

View file

@ -319,6 +319,15 @@ void HU_Init(void)
PR ("PRFN"); PR ("PRFN");
REG; REG;
DIM ('0', 10);
DIG (2);
PR ("ROLNUM");
REG;
PR ("RO4NUM");
REG;
DIG (3); DIG (3);
ADIM (KART); ADIM (KART);

View file

@ -80,6 +80,8 @@ enum
X (NIGHTSNUM), X (NIGHTSNUM),
X (PINGNUM), X (PINGNUM),
X (PROFNUM), X (PROFNUM),
X (ROLNUM),
X (RO4NUM),
X (KART), X (KART),
X (TIMER), X (TIMER),

View file

@ -1023,7 +1023,7 @@ static void F_DrawCreditsTitleDrop(void)
0, -BASEVIDHEIGHT * (FRACUNIT / 2), 0, -BASEVIDHEIGHT * (FRACUNIT / 2),
FRACUNIT, 0, FRACUNIT, 0,
static_cast<patch_t *>(W_CachePatchName( static_cast<patch_t *>(W_CachePatchName(
(cv_alttitle.value ? "KTSJUMPR1" : "KTSBUMPR1"), (M_UseAlternateTitleScreen() ? "KTSJUMPR1" : "KTSBUMPR1"),
PU_CACHE PU_CACHE
)), )),
nullptr nullptr

View file

@ -1371,6 +1371,7 @@ static void K_drawKartItem(void)
// Set to 'no item' just in case. // Set to 'no item' just in case.
const UINT8 offset = ((r_splitscreen > 1) ? 1 : 0); const UINT8 offset = ((r_splitscreen > 1) ? 1 : 0);
patch_t *localpatch[3] = { kp_nodraw, kp_nodraw, kp_nodraw }; patch_t *localpatch[3] = { kp_nodraw, kp_nodraw, kp_nodraw };
UINT8 localamt[3] = {0, 0, 0};
patch_t *localbg = ((offset) ? kp_itembg[2] : kp_itembg[0]); patch_t *localbg = ((offset) ? kp_itembg[2] : kp_itembg[0]);
patch_t *localinv = ((offset) ? kp_invincibility[((leveltime % (6*3)) / 3) + 7] : kp_invincibility[(leveltime % (7*3)) / 3]); patch_t *localinv = ((offset) ? kp_invincibility[((leveltime % (6*3)) / 3) + 7] : kp_invincibility[(leveltime % (7*3)) / 3]);
INT32 fx = 0, fy = 0, fflags = 0; // final coords for hud and flags... INT32 fx = 0, fy = 0, fflags = 0; // final coords for hud and flags...
@ -1403,14 +1404,19 @@ static void K_drawKartItem(void)
{ {
case KITEM_INVINCIBILITY: case KITEM_INVINCIBILITY:
localpatch[i] = localinv; localpatch[i] = localinv;
localamt[i] = amt;
break; break;
case KITEM_ORBINAUT: case KITEM_ORBINAUT:
localpatch[i] = kp_orbinaut[(offset ? 4 : std::min(amt-1, 3))]; localpatch[i] = kp_orbinaut[(offset ? 4 : std::min(amt-1, 3))];
if (amt > 4)
localamt[i] = amt;
break; break;
default: default:
localpatch[i] = K_GetCachedItemPatch(item, offset); localpatch[i] = K_GetCachedItemPatch(item, offset);
if (item != KITEM_BALLHOG || amt != 5)
localamt[i] = amt;
break; break;
} }
} }
@ -1586,25 +1592,35 @@ static void K_drawKartItem(void)
V_SLIDEIN|fflags V_SLIDEIN|fflags
); );
auto draw_item = [&](fixed_t y, int i)
{
const UINT8 *colormap = (localcolor[i] ? R_GetTranslationColormap(colormode[i], localcolor[i], GTC_CACHE) : NULL);
V_DrawFixedPatch( V_DrawFixedPatch(
fx<<FRACBITS, (fy<<FRACBITS) + rouletteOffset + rouletteSpace, fx<<FRACBITS, (fy<<FRACBITS) + rouletteOffset + y,
FRACUNIT, V_HUDTRANS|V_SLIDEIN|fflags, FRACUNIT, V_HUDTRANS|V_SLIDEIN|fflags,
localpatch[0], (localcolor[0] ? R_GetTranslationColormap(colormode[0], localcolor[0], GTC_CACHE) : NULL) localpatch[i], colormap
);
V_DrawFixedPatch(
fx<<FRACBITS, (fy<<FRACBITS) + rouletteOffset - rouletteSpace,
FRACUNIT, V_HUDTRANS|V_SLIDEIN|fflags,
localpatch[2], (localcolor[2] ? R_GetTranslationColormap(colormode[2], localcolor[2], GTC_CACHE) : NULL)
); );
if (localamt[i] > 1)
{
using srb2::Draw;
Draw(
fx + rouletteCrop.x + FixedToFloat(rouletteSpace/2),
fy + rouletteCrop.y + FixedToFloat(rouletteOffset + y + rouletteSpace) - (r_splitscreen > 1 ? 15 : 33))
.font(r_splitscreen > 1 ? Draw::Font::kRollingNum4P : Draw::Font::kRollingNum)
.align(Draw::Align::kCenter)
.flags(V_HUDTRANS|V_SLIDEIN|fflags)
.colormap(colormap)
.text("{}", localamt[i]);
}
};
draw_item(rouletteSpace, 0);
draw_item(-rouletteSpace, 2);
if (stplyr->itemRoulette.active == true) if (stplyr->itemRoulette.active == true)
{ {
// Draw the item underneath the box. // Draw the item underneath the box.
V_DrawFixedPatch( draw_item(0, 1);
fx<<FRACBITS, (fy<<FRACBITS) + rouletteOffset,
FRACUNIT, V_HUDTRANS|V_SLIDEIN|fflags,
localpatch[1], (localcolor[1] ? R_GetTranslationColormap(colormode[1], localcolor[1], GTC_CACHE) : NULL)
);
V_ClearClipRect(); V_ClearClipRect();
} }
else else
@ -1987,8 +2003,13 @@ void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT32 splitflags, U
} }
} }
workx -= V_ThinStringWidth(stickermedalinfo.targettext, splitflags); using srb2::Draw;
V_DrawThinString(workx, worky, splitflags, stickermedalinfo.targettext); Draw::TextElement text(stickermedalinfo.targettext);
text.flags(splitflags);
text.font(Draw::Font::kZVote);
workx -= text.width();
Draw(workx, worky).text(text);
} }
workx -= (6 + (i*5)); workx -= (6 + (i*5));
@ -5953,11 +5974,19 @@ void K_drawKartHUD(void)
{ {
// Draw the timestamp // Draw the timestamp
if (LUA_HudEnabled(hud_time)) if (LUA_HudEnabled(hud_time))
K_drawKartTimestamp(stplyr->realtime, {
TIME_X, bool ta = modeattacking && !demo.playback;
TIME_Y, INT32 flags = V_HUDTRANS|V_SLIDEIN|V_SNAPTOTOP|V_SNAPTORIGHT;
V_HUDTRANS|V_SLIDEIN|V_SNAPTOTOP|V_SNAPTORIGHT, K_drawKartTimestamp(stplyr->realtime, TIME_X, TIME_Y + (ta ? 2 : 0), flags, 0);
0); if (ta)
{
using srb2::Draw;
Draw(BASEVIDWIDTH - 19, 2)
.flags(flags | V_YELLOWMAP)
.align(Draw::Align::kRight)
.text("\xBE Restart");
}
}
islonesome = K_drawKartPositionFaces(); islonesome = K_drawKartPositionFaces();
} }
@ -5998,7 +6027,7 @@ void K_drawKartHUD(void)
if (demo.attract == DEMO_ATTRACT_TITLE) // Draw logo on title screen demos if (demo.attract == DEMO_ATTRACT_TITLE) // Draw logo on title screen demos
{ {
INT32 x = BASEVIDWIDTH - 8, y = BASEVIDHEIGHT-8, snapflags = V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_SLIDEIN; INT32 x = BASEVIDWIDTH - 8, y = BASEVIDHEIGHT-8, snapflags = V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_SLIDEIN;
patch_t *pat = static_cast<patch_t*>(W_CachePatchName((cv_alttitle.value ? "MTSJUMPR1" : "MTSBUMPR1"), PU_CACHE)); patch_t *pat = static_cast<patch_t*>(W_CachePatchName((M_UseAlternateTitleScreen() ? "MTSJUMPR1" : "MTSBUMPR1"), PU_CACHE));
if (r_splitscreen == 3) if (r_splitscreen == 3)
{ {

View file

@ -232,6 +232,8 @@ private:
case MT_BATTLEUFO_SPAWNER: case MT_BATTLEUFO_SPAWNER:
case MT_WAYPOINT: case MT_WAYPOINT:
case MT_BUBBLESHIELDTRAP:
case MT_GARDENTOP:
return {}; return {};
default: default:
@ -341,11 +343,36 @@ bool is_object_tracking_target(const mobj_t* mobj)
case MT_WAYPOINT: case MT_WAYPOINT:
return cv_kartdebugwaypoints.value; return cv_kartdebugwaypoints.value;
case MT_BUBBLESHIELDTRAP:
return mobj->tracer && !P_MobjWasRemoved(mobj->tracer)
&& mobj->tracer->player && P_IsDisplayPlayer(mobj->tracer->player)
&& mobj->tracer->player == &players[displayplayers[R_GetViewNumber()]];
case MT_GARDENTOP:
return mobj->tracer && !P_MobjWasRemoved(mobj->tracer)
&& mobj->tracer->player && P_IsDisplayPlayer(mobj->tracer->player)
&& mobj->tracer->player == &players[displayplayers[R_GetViewNumber()]]
&& Obj_GardenTopPlayerNeedsHelp(mobj);
default: default:
return false; return false;
} }
} }
bool can_object_be_offscreen(const mobj_t* mobj)
{
switch (mobj->type)
{
// You can see this, you fucking liar
case MT_GARDENTOP:
case MT_BUBBLESHIELDTRAP:
return false;
default:
return true;
}
}
Visibility is_object_visible(const mobj_t* mobj) Visibility is_object_visible(const mobj_t* mobj)
{ {
switch (mobj->type) switch (mobj->type)
@ -381,7 +408,7 @@ void K_DrawTargetTracking(const TargetTracking& target)
const trackingResult_t& result = target.result; const trackingResult_t& result = target.result;
int32_t timer = 0; int32_t timer = 0;
if (result.onScreen == false) if (can_object_be_offscreen(target.mobj) && result.onScreen == false)
{ {
// Off-screen, draw alongside the borders of the screen. // Off-screen, draw alongside the borders of the screen.
// Probably the most complicated thing. // Probably the most complicated thing.
@ -578,7 +605,9 @@ void K_DrawTargetTracking(const TargetTracking& target)
.align(Draw::Align::kCenter); .align(Draw::Align::kCenter);
}; };
switch (target.mobj->type) // debug srb2::Draw::Font splitfont = (r_splitscreen > 1) ? Draw::Font::kThin : Draw::Font::kMenu;
switch (target.mobj->type)
{ {
case MT_BATTLEUFO_SPAWNER: case MT_BATTLEUFO_SPAWNER:
debug().text("BUFO ID: {}", Obj_BattleUFOSpawnerID(target.mobj)); debug().text("BUFO ID: {}", Obj_BattleUFOSpawnerID(target.mobj));
@ -592,6 +621,21 @@ void K_DrawTargetTracking(const TargetTracking& target)
} }
break; break;
case MT_BUBBLESHIELDTRAP:
Draw(FixedToFloat(result.x), FixedToFloat(result.y))
.flags(V_SPLITSCREEN)
.font(Draw::Font::kMenu)
.align(Draw::Align::kCenter)
.text(((leveltime/3)%2) ? "\xB3 " : " \xB2");
break;
case MT_GARDENTOP:
Draw(FixedToFloat(result.x), FixedToFloat(result.y))
.flags(V_SPLITSCREEN)
.font(splitfont)
.align(Draw::Align::kCenter)
.text("Try \xA7!");
default: default:
break; break;
} }

View file

@ -7014,7 +7014,7 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
{ {
x = 8; x = 8;
y = BASEVIDHEIGHT-16; y = BASEVIDHEIGHT-16;
V_DrawGamemodeString(x, y - 33, 0, R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_PLAGUE, GTC_MENUCACHE), cv_alttitle.string); V_DrawGamemodeString(x, y - 33, 0, R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_PLAGUE, GTC_MENUCACHE), M_UseAlternateTitleScreen() ? "On" : "Off");
K_drawButtonAnim(x, y, 0, kp_button_a[1], challengesmenu.ticker); K_drawButtonAnim(x, y, 0, kp_button_a[1], challengesmenu.ticker);
x += SHORT(kp_button_a[1][0]->width); x += SHORT(kp_button_a[1][0]->width);
@ -8202,7 +8202,7 @@ void M_DrawWrongWarp(void)
titleoffset += titlewidth; titleoffset += titlewidth;
} }
patch_t *bumper = W_CachePatchName((cv_alttitle.value ? "MTSJUMPR1" : "MTSBUMPR1"), PU_CACHE); patch_t *bumper = W_CachePatchName((M_UseAlternateTitleScreen() ? "MTSJUMPR1" : "MTSBUMPR1"), PU_CACHE);
V_DrawScaledPatch(x-(SHORT(bumper->width)), (BASEVIDHEIGHT-8)-(SHORT(bumper->height)), 0, bumper); V_DrawScaledPatch(x-(SHORT(bumper->width)), (BASEVIDHEIGHT-8)-(SHORT(bumper->height)), 0, bumper);
} }

View file

@ -27,6 +27,7 @@ void Obj_GardenTopThink(mobj_t *top);
void Obj_GardenTopSparkThink(mobj_t *spark); void Obj_GardenTopSparkThink(mobj_t *spark);
void Obj_GardenTopArrowThink(mobj_t *arrow); void Obj_GardenTopArrowThink(mobj_t *arrow);
boolean Obj_GardenTopPlayerIsGrinding(const player_t *player); boolean Obj_GardenTopPlayerIsGrinding(const player_t *player);
boolean Obj_GardenTopPlayerNeedsHelp(const mobj_t *top);
/* Shrink */ /* Shrink */
void Obj_PohbeeThinker(mobj_t *pohbee); void Obj_PohbeeThinker(mobj_t *pohbee);

View file

@ -3758,3 +3758,9 @@ const char *M_GetEmblemPatch(emblem_t *em, boolean big)
return pnamebuf; return pnamebuf;
} }
boolean M_UseAlternateTitleScreen(void)
{
extern consvar_t cv_alttitle;
return cv_alttitle.value && M_SecretUnlocked(SECRET_ALTTITLE, true);
}

View file

@ -494,6 +494,8 @@ UINT16 M_EmblemMapNum(emblem_t *emblem);
#define M_Achieved(a) ((a) >= MAXCONDITIONSETS || gamedata->achieved[a]) #define M_Achieved(a) ((a) >= MAXCONDITIONSETS || gamedata->achieved[a])
boolean M_UseAlternateTitleScreen(void);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
#endif #endif

View file

@ -1027,11 +1027,13 @@ boolean M_ChallengesInputs(INT32 ch)
{ {
switch (unlockables[challengesmenu.currentunlock].type) switch (unlockables[challengesmenu.currentunlock].type)
{ {
case SECRET_ALTTITLE: case SECRET_ALTTITLE: {
extern consvar_t cv_alttitle;
CV_AddValue(&cv_alttitle, 1); CV_AddValue(&cv_alttitle, 1);
S_StartSound(NULL, sfx_s3kc3s); S_StartSound(NULL, sfx_s3kc3s);
M_SetMenuDelay(pid); M_SetMenuDelay(pid);
break; break;
}
default: default:
break; break;
} }

View file

@ -19,6 +19,22 @@ menuitem_t OPTIONS_Server[] =
NULL, {.cvar = &cv_advertise}, 0, 0}, NULL, {.cvar = &cv_advertise}, 0, 0},
{IT_HEADER, "Players...", NULL,
NULL, {NULL}, 0, 0},
{IT_STRING | IT_CVAR, "Maximum Players", "How many players can play at once.",
NULL, {.cvar = &cv_maxplayers}, 0, 0},
{IT_STRING | IT_CVAR, "Maximum Connections", "How many players & spectators can connect to the server.",
NULL, {.cvar = &cv_maxconnections}, 0, 0},
{IT_STRING | IT_CVAR, "CPU Difficulty", "Bots can fill unused slots. How strong should they be?",
NULL, {.cvar = &cv_kartbot}, 0, 0},
{IT_STRING | IT_CVAR, "Use PWR.LV", "Set whether players should be rated on their performance.",
NULL, {.cvar = &cv_kartusepwrlv}, 0, 0},
{IT_HEADER, "Progression...", NULL, {IT_HEADER, "Progression...", NULL,
NULL, {NULL}, 0, 0}, NULL, {NULL}, 0, 0},
@ -32,15 +48,9 @@ menuitem_t OPTIONS_Server[] =
NULL, {.cvar = &cv_votetime}, 0, 0}, NULL, {.cvar = &cv_votetime}, 0, 0},
{IT_HEADER, "Joining...", NULL, {IT_HEADER, "Permissions...", NULL,
NULL, {NULL}, 0, 0}, NULL, {NULL}, 0, 0},
{IT_STRING | IT_CVAR, "Maximum Players", "How many players can play at once.",
NULL, {.cvar = &cv_maxplayers}, 0, 0},
{IT_STRING | IT_CVAR, "Maximum Connections", "How many players & spectators can connect to the server.",
NULL, {.cvar = &cv_maxconnections}, 0, 0},
{IT_STRING | IT_CVAR, "Allow Joining", "Sets whether players can connect to your server.", {IT_STRING | IT_CVAR, "Allow Joining", "Sets whether players can connect to your server.",
NULL, {.cvar = &cv_allownewplayer}, 0, 0}, NULL, {.cvar = &cv_allownewplayer}, 0, 0},
@ -60,8 +70,7 @@ menuitem_t OPTIONS_Server[] =
{IT_STRING | IT_CVAR, "Chat Spam Protection", "Prevents too many message from a single player.", {IT_STRING | IT_CVAR, "Chat Spam Protection", "Prevents too many message from a single player.",
NULL, {.cvar = &cv_chatspamprotection}, 0, 0}, NULL, {.cvar = &cv_chatspamprotection}, 0, 0},
{IT_HEADER, "Advanced...", NULL,
{IT_SPACE | IT_DYBIGSPACE, NULL, NULL,
NULL, {NULL}, 0, 0}, NULL, {NULL}, 0, 0},
{IT_STRING | IT_SUBMENU, "Advanced...", "Advanced options. Be careful when messing with these!", {IT_STRING | IT_SUBMENU, "Advanced...", "Advanced options. Be careful when messing with these!",

View file

@ -747,7 +747,9 @@ void M_LevelSelected(INT16 add, boolean menuupdate)
SV_StartSinglePlayerServer(levellist.newgametype, levellist.netgame); SV_StartSinglePlayerServer(levellist.newgametype, levellist.netgame);
if (!levellist.netgame)
CV_StealthSet(&cv_kartbot, cv_dummymatchbots.string); CV_StealthSet(&cv_kartbot, cv_dummymatchbots.string);
CV_StealthSet(&cv_kartencore, (cv_dummygpencore.value == 1) ? "On" : "Auto"); CV_StealthSet(&cv_kartencore, (cv_dummygpencore.value == 1) ? "On" : "Auto");
CV_StealthSet(&cv_kartspeed, (cv_dummykartspeed.value == KARTSPEED_NORMAL) ? "Auto" : cv_dummykartspeed.string); CV_StealthSet(&cv_kartspeed, (cv_dummykartspeed.value == KARTSPEED_NORMAL) ? "Auto" : cv_dummykartspeed.string);

View file

@ -47,6 +47,8 @@ enum {
#define top_waveangle(o) ((o)->movedir) #define top_waveangle(o) ((o)->movedir)
/* wavepause will take mobjinfo reactiontime automatically */ /* wavepause will take mobjinfo reactiontime automatically */
#define top_wavepause(o) ((o)->reactiontime) #define top_wavepause(o) ((o)->reactiontime)
#define top_helpme(o) ((o)->cusval)
#define top_lifetime(o) ((o)->cvmem)
#define spark_top(o) ((o)->target) #define spark_top(o) ((o)->target)
#define spark_angle(o) ((o)->movedir) #define spark_angle(o) ((o)->movedir)
@ -133,6 +135,8 @@ init_top
top_float(top) = 0; top_float(top) = 0;
top_sound(top) = sfx_None; top_sound(top) = sfx_None;
top_waveangle(top) = 0; top_waveangle(top) = 0;
top_helpme(top) = (mode == TOP_ANCHORED) ? 1 : 0;
top_lifetime(top) = 0;
} }
static void static void
@ -191,6 +195,8 @@ spawn_grind_spark (mobj_t *top)
player = get_rider_player(rider); player = get_rider_player(rider);
} }
top_helpme(top) = 0;
spark = P_SpawnMobjFromMobj( spark = P_SpawnMobjFromMobj(
top, x, y, 0, MT_DRIFTSPARK); top, x, y, 0, MT_DRIFTSPARK);
@ -432,6 +438,8 @@ anchor_top (mobj_t *top)
top->momy = 0; top->momy = 0;
top->momz = rider->momz; top->momz = rider->momz;
top_lifetime(top)++;
/* The Z momentum can put the Top slightly ahead of the /* The Z momentum can put the Top slightly ahead of the
player in that axis too. It looks cool if the Top player in that axis too. It looks cool if the Top
falls below you but not if it bounces up. */ falls below you but not if it bounces up. */
@ -687,3 +695,11 @@ Obj_GardenTopPlayerIsGrinding (const player_t *player)
return top ? is_top_grinding(top) : false; return top ? is_top_grinding(top) : false;
} }
boolean
Obj_GardenTopPlayerNeedsHelp (const mobj_t *top)
{
if (top && top_mode(top) != TOP_ANCHORED)
return false;
return top ? (top_helpme(top) || top_lifetime(top) < 3*TICRATE) : false;
}

View file

@ -634,6 +634,14 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
P_SetTarget(&special->tracer, toucher); P_SetTarget(&special->tracer, toucher);
toucher->flags |= MF_NOGRAVITY; toucher->flags |= MF_NOGRAVITY;
toucher->momz = (8*toucher->scale) * P_MobjFlip(toucher); toucher->momz = (8*toucher->scale) * P_MobjFlip(toucher);
// Snap to the unfortunate player and quit moving laterally, or we can end up quite far away
special->momx = 0;
special->momy = 0;
special->x = toucher->x;
special->y = toucher->y;
special->z = toucher->z;
S_StartSound(toucher, sfx_s1b2); S_StartSound(toucher, sfx_s1b2);
return; return;
@ -3114,8 +3122,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
source->player->invincibilityextensions++; source->player->invincibilityextensions++;
source->player->invincibilitytimer += kinvextend; source->player->invincibilitytimer += kinvextend;
// This has a scaling boost type now, don't let it get too crazy
source->player->invincibilitytimer = min(source->player->invincibilitytimer, 20*TICRATE);
if (P_IsDisplayPlayer(source->player)) if (P_IsDisplayPlayer(source->player))
S_StartSound(NULL, sfx_gsha7); S_StartSound(NULL, sfx_gsha7);

View file

@ -5359,6 +5359,12 @@ static boolean P_IsTrackerType(INT32 type)
case MT_WAYPOINT: // debug case MT_WAYPOINT: // debug
return true; return true;
case MT_BUBBLESHIELDTRAP: // Mash prompt
return true;
case MT_GARDENTOP: // Frey
return true;
default: default:
return false; return false;
} }

View file

@ -1427,15 +1427,11 @@ void T_PolyObjRotate(polyrotate_t *th)
polyobj_t *po = Polyobj_GetForNum(th->polyObjNum); polyobj_t *po = Polyobj_GetForNum(th->polyObjNum);
if (!po) if (!po)
#ifdef RANGECHECK
I_Error("T_PolyObjRotate: thinker has invalid id %d\n", th->polyObjNum);
#else
{ {
CONS_Debug(DBG_POLYOBJ, "T_PolyObjRotate: thinker with invalid id %d removed.\n", th->polyObjNum); CONS_Debug(DBG_POLYOBJ, "T_PolyObjRotate: thinker with invalid id %d removed.\n", th->polyObjNum);
P_RemoveThinker(&th->thinker); P_RemoveThinker(&th->thinker);
return; return;
} }
#endif
// check for displacement due to override and reattach when possible // check for displacement due to override and reattach when possible
if (po->thinker == NULL) if (po->thinker == NULL)
@ -1508,15 +1504,11 @@ void T_PolyObjMove(polymove_t *th)
polyobj_t *po = Polyobj_GetForNum(th->polyObjNum); polyobj_t *po = Polyobj_GetForNum(th->polyObjNum);
if (!po) if (!po)
#ifdef RANGECHECK
I_Error("T_PolyObjMove: thinker has invalid id %d\n", th->polyObjNum);
#else
{ {
CONS_Debug(DBG_POLYOBJ, "T_PolyObjMove: thinker with invalid id %d removed.\n", th->polyObjNum); CONS_Debug(DBG_POLYOBJ, "T_PolyObjMove: thinker with invalid id %d removed.\n", th->polyObjNum);
P_RemoveThinker(&th->thinker); P_RemoveThinker(&th->thinker);
return; return;
} }
#endif
// check for displacement due to override and reattach when possible // check for displacement due to override and reattach when possible
if (po->thinker == NULL) if (po->thinker == NULL)
@ -1598,15 +1590,11 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
fixed_t speed = th->speed; fixed_t speed = th->speed;
if (!po) if (!po)
#ifdef RANGECHECK
I_Error("T_PolyObjWaypoint: thinker has invalid id %d\n", th->polyObjNum);
#else
{ {
CONS_Debug(DBG_POLYOBJ, "T_PolyObjWaypoint: thinker with invalid id %d removed.", th->polyObjNum); CONS_Debug(DBG_POLYOBJ, "T_PolyObjWaypoint: thinker with invalid id %d removed.", th->polyObjNum);
P_RemoveThinker(&th->thinker); P_RemoveThinker(&th->thinker);
return; return;
} }
#endif
// check for displacement due to override and reattach when possible // check for displacement due to override and reattach when possible
if (!po->thinker) if (!po->thinker)
@ -1714,15 +1702,11 @@ void T_PolyDoorSlide(polyslidedoor_t *th)
polyobj_t *po = Polyobj_GetForNum(th->polyObjNum); polyobj_t *po = Polyobj_GetForNum(th->polyObjNum);
if (!po) if (!po)
#ifdef RANGECHECK
I_Error("T_PolyDoorSlide: thinker has invalid id %d\n", th->polyObjNum);
#else
{ {
CONS_Debug(DBG_POLYOBJ, "T_PolyDoorSlide: thinker with invalid id %d removed.\n", th->polyObjNum); CONS_Debug(DBG_POLYOBJ, "T_PolyDoorSlide: thinker with invalid id %d removed.\n", th->polyObjNum);
P_RemoveThinker(&th->thinker); P_RemoveThinker(&th->thinker);
return; return;
} }
#endif
// check for displacement due to override and reattach when possible // check for displacement due to override and reattach when possible
if (po->thinker == NULL) if (po->thinker == NULL)
@ -1819,15 +1803,11 @@ void T_PolyDoorSwing(polyswingdoor_t *th)
polyobj_t *po = Polyobj_GetForNum(th->polyObjNum); polyobj_t *po = Polyobj_GetForNum(th->polyObjNum);
if (!po) if (!po)
#ifdef RANGECHECK
I_Error("T_PolyDoorSwing: thinker has invalid id %d\n", th->polyObjNum);
#else
{ {
CONS_Debug(DBG_POLYOBJ, "T_PolyDoorSwing: thinker with invalid id %d removed.\n", th->polyObjNum); CONS_Debug(DBG_POLYOBJ, "T_PolyDoorSwing: thinker with invalid id %d removed.\n", th->polyObjNum);
P_RemoveThinker(&th->thinker); P_RemoveThinker(&th->thinker);
return; return;
} }
#endif
// check for displacement due to override and reattach when possible // check for displacement due to override and reattach when possible
if (po->thinker == NULL) if (po->thinker == NULL)
@ -1918,15 +1898,11 @@ void T_PolyObjDisplace(polydisplace_t *th)
fixed_t dx, dy; fixed_t dx, dy;
if (!po) if (!po)
#ifdef RANGECHECK
I_Error("T_PolyObjDisplace: thinker has invalid id %d\n", th->polyObjNum);
#else
{ {
CONS_Debug(DBG_POLYOBJ, "T_PolyObjDisplace: thinker with invalid id %d removed.\n", th->polyObjNum); CONS_Debug(DBG_POLYOBJ, "T_PolyObjDisplace: thinker with invalid id %d removed.\n", th->polyObjNum);
P_RemoveThinker(&th->thinker); P_RemoveThinker(&th->thinker);
return; return;
} }
#endif
// check for displacement due to override and reattach when possible // check for displacement due to override and reattach when possible
if (po->thinker == NULL) if (po->thinker == NULL)
@ -1958,15 +1934,11 @@ void T_PolyObjRotDisplace(polyrotdisplace_t *th)
fixed_t rotangle; fixed_t rotangle;
if (!po) if (!po)
#ifdef RANGECHECK
I_Error("T_PolyObjRotDisplace: thinker has invalid id %d\n", th->polyObjNum);
#else
{ {
CONS_Debug(DBG_POLYOBJ, "T_PolyObjRotDisplace: thinker with invalid id %d removed.\n", th->polyObjNum); CONS_Debug(DBG_POLYOBJ, "T_PolyObjRotDisplace: thinker with invalid id %d removed.\n", th->polyObjNum);
P_RemoveThinker(&th->thinker); P_RemoveThinker(&th->thinker);
return; return;
} }
#endif
// check for displacement due to override and reattach when possible // check for displacement due to override and reattach when possible
if (po->thinker == NULL) if (po->thinker == NULL)
@ -2442,15 +2414,11 @@ void T_PolyObjFlag(polymove_t *th)
size_t i; size_t i;
if (!po) if (!po)
#ifdef RANGECHECK
I_Error("T_PolyObjFlag: thinker has invalid id %d\n", th->polyObjNum);
#else
{ {
CONS_Debug(DBG_POLYOBJ, "T_PolyObjFlag: thinker with invalid id %d removed.\n", th->polyObjNum); CONS_Debug(DBG_POLYOBJ, "T_PolyObjFlag: thinker with invalid id %d removed.\n", th->polyObjNum);
P_RemoveThinker(&th->thinker); P_RemoveThinker(&th->thinker);
return; return;
} }
#endif
// check for displacement due to override and reattach when possible // check for displacement due to override and reattach when possible
if (po->thinker == NULL) if (po->thinker == NULL)
@ -2549,15 +2517,11 @@ void T_PolyObjFade(polyfade_t *th)
polyobj_t *po = Polyobj_GetForNum(th->polyObjNum); polyobj_t *po = Polyobj_GetForNum(th->polyObjNum);
if (!po) if (!po)
#ifdef RANGECHECK
I_Error("T_PolyObjFade: thinker has invalid id %d\n", th->polyObjNum);
#else
{ {
CONS_Debug(DBG_POLYOBJ, "T_PolyObjFade: thinker with invalid id %d removed.\n", th->polyObjNum); CONS_Debug(DBG_POLYOBJ, "T_PolyObjFade: thinker with invalid id %d removed.\n", th->polyObjNum);
P_RemoveThinker(&th->thinker); P_RemoveThinker(&th->thinker);
return; return;
} }
#endif
// check for displacement due to override and reattach when possible // check for displacement due to override and reattach when possible
if (po->thinker == NULL) if (po->thinker == NULL)

View file

@ -469,10 +469,11 @@ static boolean P_CrossSubsector(size_t num, register los_t *los, register los_fu
seg_t *seg; seg_t *seg;
INT32 count; INT32 count;
#ifdef RANGECHECK
if (num >= numsubsectors) if (num >= numsubsectors)
I_Error("P_CrossSubsector: ss %s with numss = %s\n", sizeu1(num), sizeu2(numsubsectors)); {
#endif CONS_Debug(DBG_RENDER, "P_CrossSubsector: ss %s with numss = %s\n", sizeu1(num), sizeu2(numsubsectors));
return true;
}
// haleyjd 02/23/06: this assignment should be after the above check // haleyjd 02/23/06: this assignment should be after the above check
seg = segs + subsectors[num].firstline; seg = segs + subsectors[num].firstline;

View file

@ -909,14 +909,12 @@ static void R_Subsector(size_t num)
ZoneScoped; ZoneScoped;
#ifdef RANGECHECK
if (num >= numsubsectors)
I_Error("R_Subsector: ss %s with numss = %s\n", sizeu1(num), sizeu2(numsubsectors));
#endif
// subsectors added at run-time // subsectors added at run-time
if (num >= numsubsectors) if (num >= numsubsectors)
{
CONS_Debug(DBG_RENDER, "R_Subsector: ss %s with numss = %s\n", sizeu1(num), sizeu2(numsubsectors));
return; return;
}
sub = &subsectors[num]; sub = &subsectors[num];
frontsector = sub->sector; frontsector = sub->sector;

View file

@ -105,12 +105,10 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc)
return; return;
} }
#ifdef RANGECHECK
if ((unsigned)dc->x >= (unsigned)vid.width || dc->yl < 0 || dc->yh >= vid.height) if ((unsigned)dc->x >= (unsigned)vid.width || dc->yl < 0 || dc->yh >= vid.height)
{ {
return; return;
} }
#endif
if constexpr (Type & DrawColumnType::DC_LIGHTLIST) if constexpr (Type & DrawColumnType::DC_LIGHTLIST)
{ {
@ -341,10 +339,8 @@ void R_DrawFogColumn(drawcolumndata_t *dc)
if (count < 0) if (count < 0)
return; return;
#ifdef RANGECHECK
if ((unsigned)dc->x >= (unsigned)vid.width || dc->yl < 0 || dc->yh >= vid.height) if ((unsigned)dc->x >= (unsigned)vid.width || dc->yl < 0 || dc->yh >= vid.height)
return; return;
#endif
// Framebuffer destination address. // Framebuffer destination address.
// Use ylookup LUT to avoid multiply with ScreenWidth. // Use ylookup LUT to avoid multiply with ScreenWidth.
@ -408,10 +404,8 @@ void R_DrawColumn_Flat(drawcolumndata_t *dc)
if (count < 0) // Zero length, column does not exceed a pixel. if (count < 0) // Zero length, column does not exceed a pixel.
return; return;
#ifdef RANGECHECK
if ((unsigned)dc->x >= (unsigned)vid.width || dc->yl < 0 || dc->yh >= vid.height) if ((unsigned)dc->x >= (unsigned)vid.width || dc->yl < 0 || dc->yh >= vid.height)
return; return;
#endif
// Framebuffer destination address. // Framebuffer destination address.
// Use ylookup LUT to avoid multiply with ScreenWidth. // Use ylookup LUT to avoid multiply with ScreenWidth.

View file

@ -1073,9 +1073,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
} }
else if (vis->cut & SC_SHEAR) else if (vis->cut & SC_SHEAR)
{ {
#ifdef RANGECHECK
pwidth = patch->width; pwidth = patch->width;
#endif
// Vertically sheared sprite // Vertically sheared sprite
for (dc.x = vis->x1; dc.x <= vis->x2; dc.x++, frac += vis->xiscale, dc.texturemid -= vis->shear.tan) for (dc.x = vis->x1; dc.x <= vis->x2; dc.x++, frac += vis->xiscale, dc.texturemid -= vis->shear.tan)
@ -1093,7 +1091,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
else else
{ {
#ifdef RANGECHECK #if 0
if (vis->x1test && vis->x2test) if (vis->x1test && vis->x2test)
{ {
INT32 x1test = vis->x1test; INT32 x1test = vis->x1test;
@ -1112,7 +1110,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
CONS_Printf("THE GAME WOULD HAVE CRASHED, %d (old) vs %d (new)\n", (x2test - x1test), (vis->x2 - vis->x1)); CONS_Printf("THE GAME WOULD HAVE CRASHED, %d (old) vs %d (new)\n", (x2test - x1test), (vis->x2 - vis->x1));
} }
} }
#endif // RANGECHECK #endif
// Non-paper drawing loop // Non-paper drawing loop
for (dc.x = vis->x1; dc.x <= vis->x2; dc.x++, frac += vis->xiscale, sprtopscreen += vis->shear.tan) for (dc.x = vis->x1; dc.x <= vis->x2; dc.x++, frac += vis->xiscale, sprtopscreen += vis->shear.tan)
@ -1191,10 +1189,11 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis)
{ {
texturecolumn = frac>>FRACBITS; texturecolumn = frac>>FRACBITS;
#ifdef RANGECHECK
if (texturecolumn < 0 || texturecolumn >= patch->width) if (texturecolumn < 0 || texturecolumn >= patch->width)
I_Error("R_DrawPrecipitationSpriteRange: bad texturecolumn"); {
#endif CONS_Debug(DBG_RENDER, "R_DrawPrecipitationSpriteRange: bad texturecolumn\n");
break;
}
column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[texturecolumn])); column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[texturecolumn]));
@ -1832,10 +1831,11 @@ static void R_ProjectSprite(mobj_t *thing)
sortscale = FixedDiv(projectiony[viewssnum], tz); sortscale = FixedDiv(projectiony[viewssnum], tz);
// decide which patch to use for sprite relative to player // decide which patch to use for sprite relative to player
#ifdef RANGECHECK
if ((size_t)(thing->sprite) >= numsprites) if ((size_t)(thing->sprite) >= numsprites)
I_Error("R_ProjectSprite: invalid sprite number %d ", thing->sprite); {
#endif CONS_Debug(DBG_RENDER, "R_ProjectSprite: invalid sprite number %d\n", thing->sprite);
return;
}
frame = thing->frame&FF_FRAMEMASK; frame = thing->frame&FF_FRAMEMASK;
@ -2634,19 +2634,21 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
yscale = FixedDiv(projectiony[viewssnum], tz); yscale = FixedDiv(projectiony[viewssnum], tz);
// decide which patch to use for sprite relative to player // decide which patch to use for sprite relative to player
#ifdef RANGECHECK
if ((unsigned)thing->sprite >= numsprites) if ((unsigned)thing->sprite >= numsprites)
I_Error("R_ProjectPrecipitationSprite: invalid sprite number %d ", {
CONS_Debug(DBG_RENDER, "R_ProjectPrecipitationSprite: invalid sprite number %d\n",
thing->sprite); thing->sprite);
#endif return;
}
sprdef = &sprites[thing->sprite]; sprdef = &sprites[thing->sprite];
#ifdef RANGECHECK
if ((UINT8)(thing->frame&FF_FRAMEMASK) >= sprdef->numframes) if ((UINT8)(thing->frame&FF_FRAMEMASK) >= sprdef->numframes)
I_Error("R_ProjectPrecipitationSprite: invalid sprite frame %d : %d for %s", {
CONS_Debug(DBG_RENDER, "R_ProjectPrecipitationSprite: invalid sprite frame %d : %d for %s\n",
thing->sprite, thing->frame, sprnames[thing->sprite]); thing->sprite, thing->frame, sprnames[thing->sprite]);
#endif return;
}
sprframe = &sprdef->spriteframes[thing->frame & FF_FRAMEMASK]; sprframe = &sprdef->spriteframes[thing->frame & FF_FRAMEMASK];

View file

@ -308,6 +308,12 @@ int Draw::font_to_fontno(Font font)
case Font::kMedium: case Font::kMedium:
return MED_FONT; return MED_FONT;
case Font::kRollingNum:
return ROLNUM_FONT;
case Font::kRollingNum4P:
return RO4NUM_FONT;
} }
return TINY_FONT; return TINY_FONT;

View file

@ -41,6 +41,8 @@ public:
kThinTimer, kThinTimer,
kMenu, kMenu,
kMedium, kMedium,
kRollingNum,
kRollingNum4P,
}; };
enum class Align enum class Align

View file

@ -987,10 +987,8 @@ void V_DrawBlock(INT32 x, INT32 y, INT32 scrn, INT32 width, INT32 height, const
UINT8 *dest; UINT8 *dest;
const UINT8 *deststop; const UINT8 *deststop;
#ifdef RANGECHECK
if (x < 0 || x + width > vid.width || y < 0 || y + height > vid.height || (unsigned)scrn > 4) if (x < 0 || x + width > vid.width || y < 0 || y + height > vid.height || (unsigned)scrn > 4)
I_Error("Bad V_DrawBlock"); I_Error("Bad V_DrawBlock");
#endif
dest = screens[scrn] + y*vid.width + x; dest = screens[scrn] + y*vid.width + x;
deststop = screens[scrn] + vid.rowbytes * vid.height; deststop = screens[scrn] + vid.rowbytes * vid.height;
@ -2342,6 +2340,12 @@ static void V_GetFontSpecification(int fontno, INT32 flags, fontspec_t *result)
case PINGF_FONT: case PINGF_FONT:
result->spacew = 3; result->spacew = 3;
break; break;
case ROLNUM_FONT:
result->spacew = 17;
break;
case RO4NUM_FONT:
result->spacew = 9;
break;
} }
switch (fontno) switch (fontno)
@ -2373,6 +2377,12 @@ static void V_GetFontSpecification(int fontno, INT32 flags, fontspec_t *result)
case PINGF_FONT: case PINGF_FONT:
result->lfh = 10; result->lfh = 10;
break; break;
case ROLNUM_FONT:
result->lfh = 33;
break;
case RO4NUM_FONT:
result->lfh = 15;
break;
} }
switch (fontno) switch (fontno)
@ -2432,6 +2442,8 @@ static void V_GetFontSpecification(int fontno, INT32 flags, fontspec_t *result)
break; break;
case OPPRF_FONT: case OPPRF_FONT:
case PINGF_FONT: case PINGF_FONT:
case ROLNUM_FONT:
case RO4NUM_FONT:
if (result->chw) if (result->chw)
result->dim_fn = FixedCharacterDim; result->dim_fn = FixedCharacterDim;
else else