Merge branch 'master' into trick-panels-changes

This commit is contained in:
SteelT 2021-06-10 23:45:35 -04:00
commit b3cee8b8fc
41 changed files with 1233 additions and 540 deletions

View file

@ -1338,7 +1338,7 @@ static void CL_ReloadReceivedSavegame(void)
neededtic = gametic;
maketic = neededtic;
for (i = 0; i <= splitscreen; i++)
for (i = 0; i <= r_splitscreen; i++)
{
P_ForceLocalAngle(&players[displayplayers[i]], players[displayplayers[i]].angleturn);
}
@ -2375,7 +2375,7 @@ void CL_RemovePlayer(INT32 playernum, kickreason_t reason)
LUAh_PlayerQuit(&players[playernum], reason); // Lua hook for player quitting
// don't look through someone's view who isn't there
if (playernum == displayplayers[0])
if (playernum == displayplayers[0] && !demo.playback)
{
// Call ViewpointSwitch hooks here.
// The viewpoint was forcibly changed.
@ -2404,9 +2404,6 @@ void CL_RemovePlayer(INT32 playernum, kickreason_t reason)
RemoveAdminPlayer(playernum); // don't stay admin after you're gone
}
if (playernum == displayplayers[0] && !demo.playback)
displayplayers[0] = consoleplayer; // don't look through someone's view who isn't there
LUA_InvalidatePlayer(&players[playernum]);
K_CheckBumpers();

View file

@ -615,16 +615,6 @@ static void D_Display(void)
{
F_WipeEndScreen();
// Funny.
if (WipeStageTitle && st_overlay)
{
lt_ticker--;
lt_lasttic = lt_ticker;
ST_preLevelTitleCardDrawer();
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol);
F_WipeStartScreen();
}
F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK && gamestate != GS_TITLESCREEN, "FADEMAP0", true, false);
}
@ -1057,15 +1047,6 @@ static void IdentifyVersion(void)
D_AddFile(startupiwads, va(pandf,srb2waddir,"patch.pk3"));
#endif
#if 0
// TODO: pk3 doesn't support music replacement IIRC
// music barely benefits from the compression anyway
// would be nice for the folders, though
D_AddFile(startupiwads, va(pandf,srb2waddir,"sounds.pk3"));
D_AddFile(startupiwads, va(pandf,srb2waddir,"music.pk3"));
#else
#if !defined (HAVE_SDL) || defined (HAVE_MIXER)
#define MUSICTEST(str) \
@ -1078,12 +1059,11 @@ static void IdentifyVersion(void)
I_Error("File "str" has been modified with non-music/sound lumps"); \
}
MUSICTEST("sounds.wad")
MUSICTEST("sounds.pk3")
MUSICTEST("music.pk3")
#undef MUSICTEST
#endif
#endif
}

View file

@ -1299,16 +1299,18 @@ void PT_FileFragment(void)
filename = va("%s", file->filename);
nameonly(filename);
if (!(strcmp(filename, "main.kart")
&& strcmp(filename, "gfx.pk3")
&& strcmp(filename, "textures.pk3")
&& strcmp(filename, "chars.pk3")
&& strcmp(filename, "maps.wad")
&& strcmp(filename, "patch.pk3")
&& strcmp(filename, "sounds.wad")
&& strcmp(filename, "music.wad")
))
if (!strcmp(filename, "main.kart")
|| !strcmp(filename, "gfx.pk3")
|| !strcmp(filename, "textures.pk3")
|| !strcmp(filename, "chars.pk3")
|| !strcmp(filename, "maps.pk3")
|| !strcmp(filename, "patch.pk3")
|| !strcmp(filename, "sounds.pk3")
|| !strcmp(filename, "music.pk3")
)
{
I_Error("Tried to download \"%s\"", filename);
}
filename = file->filename;

View file

@ -526,6 +526,8 @@ typedef struct player_s
UINT8 kickstartaccel;
UINT8 stairjank;
#ifdef HWRENDER
fixed_t fovadd; // adjust FOV for hw rendering
#endif

View file

@ -4649,6 +4649,12 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
"S_DEBTSPIKEC",
"S_DEBTSPIKED",
"S_DEBTSPIKEE",
// Sparks when driving on stairs
"S_JANKSPARK1",
"S_JANKSPARK2",
"S_JANKSPARK3",
"S_JANKSPARK4",
};
// RegEx to generate this from info.h: ^\tMT_([^,]+), --> \t"MT_\1",
@ -5452,6 +5458,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
"MT_DRIFTDUST",
"MT_DRIFTELECTRICITY",
"MT_DRIFTELECTRICSPARK",
"MT_JANKSPARK",
"MT_ROCKETSNEAKER", // Rocket sneakers

View file

@ -420,7 +420,7 @@ typedef struct
extern mapheader_t* mapheaderinfo[NUMMAPS];
// This could support more, but is that a good idea?
// Keep in mind that it may encourage people making overly long cups just because they "can", and would be a waste of memory.
// Keep in mind that it may encourage people making overly long cups just because they "can", and would be a waste of memory.
#define MAXLEVELLIST 5
typedef struct cupheader_s

View file

@ -143,7 +143,7 @@ extern INT32 lastwipetic;
// Don't know where else to place this constant
// But this file seems appropriate
#define PRELEVELTIME 24 // frames in tics
#define PRELEVELTIME TICRATE // frames in tics
void F_WipeStartScreen(void);
void F_WipeEndScreen(void);

View file

@ -415,7 +415,7 @@ void F_WipeStageTitle(void)
if ((WipeStageTitle) && G_IsTitleCardAvailable())
{
ST_runTitleCard();
ST_drawWipeTitleCard();
ST_drawTitleCard();
}
}

View file

@ -347,6 +347,7 @@ void G_ReadDemoExtraData(void)
players[p].pflags &= ~(PF_KICKSTARTACCEL);
if (extradata & 1)
players[p].pflags |= PF_KICKSTARTACCEL;
//CONS_Printf("weaponpref is %d for player %d\n", extradata, p);
}
p = READUINT8(demo_p);
@ -2656,7 +2657,7 @@ void G_DoPlayDemo(char *defdemoname)
UINT32 randseed;
char msg[1024];
boolean spectator;
boolean spectator, kickstart;
UINT8 slots[MAXPLAYERS], kartspeed[MAXPLAYERS], kartweight[MAXPLAYERS], numslots = 0;
#if defined(SKIPERRORS) && !defined(DEVELOP)
@ -2925,16 +2926,8 @@ void G_DoPlayDemo(char *defdemoname)
while (p != 0xFF)
{
players[p].pflags &= ~PF_KICKSTARTACCEL;
if (p & DEMO_KICKSTART)
if ((spectator = (p & DEMO_SPECTATOR)))
{
players[p].pflags |= PF_KICKSTARTACCEL;
p &= ~DEMO_KICKSTART;
}
spectator = false;
if (p & DEMO_SPECTATOR)
{
spectator = true;
p &= ~DEMO_SPECTATOR;
if (modeattacking)
@ -2949,6 +2942,10 @@ void G_DoPlayDemo(char *defdemoname)
return;
}
}
if ((kickstart = (p & DEMO_KICKSTART)))
p &= ~DEMO_KICKSTART;
slots[numslots] = p; numslots++;
if (modeattacking && numslots > 1)
@ -2968,6 +2965,10 @@ void G_DoPlayDemo(char *defdemoname)
playeringame[p] = true;
players[p].spectator = spectator;
if (kickstart)
players[p].pflags |= PF_KICKSTARTACCEL;
else
players[p].pflags &= ~PF_KICKSTARTACCEL;
// Name
M_Memcpy(player_names[p],demo_p,16);

View file

@ -1139,7 +1139,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
// Send leveltime when this tic was generated to the server for control lag calculations.
// Only do this when in a level. Also do this after the hook, so that it can't overwrite this.
cmd->latency = (leveltime & 0xFF);
cmd->latency = (leveltime & 0xFF);
}
if (cmd->forwardmove > MAXPLMOVE)
@ -1263,7 +1263,7 @@ void G_DoLoadLevel(boolean resetplayer)
for (i = 0; i <= r_splitscreen; i++)
{
if (camera[i].chase)
P_ResetCamera(&players[g_localplayers[i]], &camera[i]);
P_ResetCamera(&players[displayplayers[i]], &camera[i]);
}
// clear cmd building stuff
@ -1301,7 +1301,7 @@ void G_StartTitleCard(void)
ST_startTitleCard();
// start the title card
WipeStageTitle = false; //(!titlemapinaction); -- temporary until titlecards are reworked
WipeStageTitle = (!titlemapinaction);
}
//
@ -1310,26 +1310,27 @@ void G_StartTitleCard(void)
void G_PreLevelTitleCard(void)
{
#ifndef NOWIPE
tic_t strtime = I_GetTime();
tic_t endtime = strtime + (PRELEVELTIME*NEWTICRATERATIO);
tic_t nowtime = strtime;
tic_t lasttime = strtime;
while (nowtime < endtime)
{
// draw loop
while (!((nowtime = I_GetTime()) - lasttime))
I_Sleep();
lasttime = nowtime;
tic_t strtime = I_GetTime();
tic_t endtime = strtime + (PRELEVELTIME*NEWTICRATERATIO);
tic_t nowtime = strtime;
tic_t lasttime = strtime;
while (nowtime < endtime)
{
// draw loop
ST_runTitleCard();
ST_preLevelTitleCardDrawer();
I_FinishUpdate(); // page flip or blit buffer
NetKeepAlive(); // Prevent timeouts
ST_runTitleCard();
ST_preLevelTitleCardDrawer();
I_FinishUpdate(); // page flip or blit buffer
if (moviemode)
M_SaveFrame();
if (takescreenshot) // Only take screenshots after drawing.
M_DoScreenShot();
if (moviemode)
M_SaveFrame();
if (takescreenshot) // Only take screenshots after drawing.
M_DoScreenShot();
}
while (!((nowtime = I_GetTime()) - lasttime))
I_Sleep();
lasttime = nowtime;
}
#endif
}

View file

@ -50,10 +50,10 @@ G_ResetSplitscreen (INT32 playernum)
displayplayers[i] = g_localplayers[i];
P_ResetCamera(&players[displayplayers[i]], &camera[i]);
}
while (i < MAXSPLITSCREENPLAYERS)
{
displayplayers[i] = consoleplayer;
i++;
}

View file

@ -73,6 +73,8 @@
patch_t *pinggfx[5]; // small ping graphic
patch_t *mping[5]; // smaller ping graphic
patch_t *tc_font[2][LT_FONTSIZE]; // Special font stuff for titlecard
patch_t *framecounter;
patch_t *frameslash; // framerate stuff. Used in screen.c
@ -178,7 +180,8 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum);
void HU_LoadGraphics(void)
{
INT32 i;
char buffer[9];
INT32 i, j;
if (dedicated)
return;
@ -191,6 +194,27 @@ void HU_LoadGraphics(void)
emblemicon = HU_CachePatch("EMBLICON");
songcreditbg = HU_CachePatch("K_SONGCR");
// Cache titlecard font
j = LT_FONTSTART;
for (i = 0; i < LT_FONTSIZE; i++, j++)
{
// cache the titlecard font
// Bottom layer
sprintf(buffer, "GTOL%.3d", j);
if (W_CheckNumForName(buffer) == LUMPERROR)
tc_font[0][i] = NULL;
else
tc_font[0][i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
// Top layer
sprintf(buffer, "GTFN%.3d", j);
if (W_CheckNumForName(buffer) == LUMPERROR)
tc_font[1][i] = NULL;
else
tc_font[1][i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
}
// cache ping gfx:
for (i = 0; i < 5; i++)
{
@ -704,7 +728,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
}
else if (target == -1) // say team
{
if (players[playernum].ctfteam == 1)
if (players[playernum].ctfteam == 1)
{
// red text
cstart = textcolor = "\x85";

View file

@ -39,6 +39,11 @@
#define LT_FONTEND 'z' // the last font characters
#define LT_FONTSIZE (LT_FONTEND - LT_FONTSTART + 1)
// Under regular circumstances, we'd use the built in font stuff, however this font is a bit messy because of how we're gonna draw shit.
// tc_font[0][n] is used for the "bottom" layer
// tc_font[1][n] is used for the "top" layer
extern patch_t *tc_font[2][LT_FONTSIZE];
#define CRED_FONTSTART '!' // the first font character
#define CRED_FONTEND 'Z' // the last font character
#define CRED_FONTSIZE (CRED_FONTEND - CRED_FONTSTART + 1)

View file

@ -543,6 +543,7 @@ char sprnames[NUMSPRITES + 1][5] =
"DRWS", // Drift dust sparks
"DREL", // Drift electricity
"DRES", // Drift electric sparks
"JANK", // Stair janking sparks
// Kart Items
"RSHE", // Rocket sneaker
@ -5234,6 +5235,12 @@ state_t states[NUMSTATES] =
{SPR_DEBT, 7|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_DEBTSPIKED}, // S_DEBTSPIKEC
{SPR_DEBT, 6|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_DEBTSPIKEE}, // S_DEBTSPIKED
{SPR_DEBT, 7|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_DEBTSPIKE1}, // S_DEBTSPIKEE
// Sparks when driving on stairs
{SPR_JANK, 0, 1, {NULL}, 0, 0, S_JANKSPARK2}, // S_JANKSPARK1
{SPR_JANK, FF_PAPERSPRITE|FF_FULLBRIGHT|FF_ANIMATE, 4, {NULL}, 3, 1, S_JANKSPARK3}, // S_JANKSPARK2
{SPR_JANK, 0, 0, {A_SetCustomValue}, -1, 5, S_JANKSPARK4}, // S_JANKSPARK3
{SPR_JANK, 0, 0, {A_ChangeAngleRelative}, 180, 180, S_JANKSPARK2}, // S_JANKSPARK4
};
mobjinfo_t mobjinfo[NUMMOBJTYPES] =
@ -23534,6 +23541,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
{ // MT_JANKSPARK
-1, // doomednum
S_JANKSPARK1, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
8, // speed
8*FRACUNIT, // radius
8*FRACUNIT, // height
0, // display offset
100, // mass
0, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_FLOAT|MF_DONTENCOREMAP, // flags
S_NULL // raisestate
},
{ // MT_ROCKETSNEAKER
-1, // doomednum
S_ROCKETSNEAKER_L, // spawnstate

View file

@ -1085,6 +1085,7 @@ typedef enum sprite
SPR_DRWS, // Drift dust sparks
SPR_DREL, // Drift electricity
SPR_DRES, // Drift electric sparks
SPR_JANK, // Stair janking sparks
// Kart Items
SPR_RSHE, // Rocket sneaker
@ -5640,6 +5641,11 @@ typedef enum state
S_DEBTSPIKED,
S_DEBTSPIKEE,
S_JANKSPARK1,
S_JANKSPARK2,
S_JANKSPARK3,
S_JANKSPARK4,
S_FIRSTFREESLOT,
S_LASTFREESLOT = S_FIRSTFREESLOT + NUMSTATEFREESLOTS - 1,
NUMSTATES
@ -6462,6 +6468,7 @@ typedef enum mobj_type
MT_DRIFTDUST,
MT_DRIFTELECTRICITY,
MT_DRIFTELECTRICSPARK,
MT_JANKSPARK,
MT_ROCKETSNEAKER,

View file

@ -46,7 +46,7 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2)
{
// Player Damage
P_DamageMobj(t2, t1, t1->target, 1, DMG_WIPEOUT);
K_KartBouncing(t2, t1, false, false);
K_KartBouncing(t2, t1);
S_StartSound(t2, sfx_s3k7b);
}
@ -430,7 +430,7 @@ boolean K_KitchenSinkCollide(mobj_t *t1, mobj_t *t2)
boolean K_FallingRockCollide(mobj_t *t1, mobj_t *t2)
{
if (t2->player || t2->type == MT_FALLINGROCK)
K_KartBouncing(t2, t1, false, false);
K_KartBouncing(t2, t1);
return true;
}
@ -457,8 +457,8 @@ boolean K_SMKIceBlockCollide(mobj_t *t1, mobj_t *t2)
return true;
*/
K_KartBouncing(t2, t1, false, true);
return false;
K_KartSolidBounce(t1, t2);
return true;
}
boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
@ -537,25 +537,24 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
if (t1Condition == true)
{
P_PlayerRingBurst(t2->player, 1);
if (t2->player->rings <= 0)
{
P_DamageMobj(t2, t1, t1, 1, DMG_STING);
stung = true;
}
P_PlayerRingBurst(t2->player, 1);
stung = true;
}
if (t2Condition == true)
{
P_PlayerRingBurst(t1->player, 1);
if (t1->player->rings <= 0)
{
P_DamageMobj(t1, t2, t2, 1, DMG_STING);
stung = true;
}
P_PlayerRingBurst(t2->player, 1);
}
return stung;

View file

@ -1123,16 +1123,137 @@ fixed_t K_GetMobjWeight(mobj_t *mobj, mobj_t *against)
return FixedMul(weight, mobj->scale);
}
boolean K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid)
static void K_SpawnBumpForObjs(mobj_t *mobj1, mobj_t *mobj2)
{
mobj_t *fx;
mobj_t *fx = P_SpawnMobj(
mobj1->x/2 + mobj2->x/2,
mobj1->y/2 + mobj2->y/2,
mobj1->z/2 + mobj2->z/2,
MT_BUMP
);
fixed_t avgScale = (mobj1->scale + mobj2->scale) / 2;
if (mobj1->eflags & MFE_VERTICALFLIP)
{
fx->eflags |= MFE_VERTICALFLIP;
}
else
{
fx->eflags &= ~MFE_VERTICALFLIP;
}
P_SetScale(fx, (fx->destscale = avgScale));
if ((mobj1->player && mobj1->player->itemtype == KITEM_BUBBLESHIELD)
|| (mobj2->player && mobj2->player->itemtype == KITEM_BUBBLESHIELD))
{
S_StartSound(mobj1, sfx_s3k44);
}
else
{
S_StartSound(mobj1, sfx_s3k49);
}
}
static void K_PlayerJustBumped(player_t *player)
{
mobj_t *playerMobj = NULL;
if (player == NULL)
{
return;
}
playerMobj = player->mo;
if (playerMobj == NULL || P_MobjWasRemoved(playerMobj))
{
return;
}
if (abs(player->rmomx) < playerMobj->scale && abs(player->rmomy) < playerMobj->scale)
{
// Because this is done during collision now, rmomx and rmomy need to be recalculated
// so that friction doesn't immediately decide to stop the player if they're at a standstill
player->rmomx = playerMobj->momx - player->cmomx;
player->rmomy = playerMobj->momy - player->cmomy;
}
player->justbumped = bumptime;
player->spindash = 0;
if (player->spinouttimer)
{
player->wipeoutslow = wipeoutslowtime+1;
player->spinouttimer = max(wipeoutslowtime+1, player->spinouttimer);
//player->spinouttype = KSPIN_WIPEOUT; // Enforce type
}
}
static fixed_t K_GetBounceForce(mobj_t *mobj1, mobj_t *mobj2, fixed_t distx, fixed_t disty)
{
const fixed_t forceMul = (4 * FRACUNIT) / 10; // Multiply by this value to make it feel like old bumps.
fixed_t momdifx, momdify;
fixed_t distx, disty;
fixed_t dot, force;
fixed_t dot;
fixed_t force = 0;
momdifx = mobj1->momx - mobj2->momx;
momdify = mobj1->momy - mobj2->momy;
if (distx == 0 && disty == 0)
{
// if there's no distance between the 2, they're directly on top of each other, don't run this
return 0;
}
{ // Normalize distance to the sum of the two objects' radii, since in a perfect world that would be the distance at the point of collision...
fixed_t dist = P_AproxDistance(distx, disty);
fixed_t nx, ny;
dist = dist ? dist : 1;
nx = FixedDiv(distx, dist);
ny = FixedDiv(disty, dist);
distx = FixedMul(mobj1->radius + mobj2->radius, nx);
disty = FixedMul(mobj1->radius + mobj2->radius, ny);
if (momdifx == 0 && momdify == 0)
{
// If there's no momentum difference, they're moving at exactly the same rate. Pretend they moved into each other.
momdifx = -nx;
momdify = -ny;
}
}
dot = FixedMul(momdifx, distx) + FixedMul(momdify, disty);
if (dot >= 0)
{
// They're moving away from each other
return 0;
}
// Return the push force!
force = FixedDiv(dot, FixedMul(distx, distx) + FixedMul(disty, disty));
return FixedMul(force, forceMul);
}
boolean K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2)
{
const fixed_t minBump = 25*mapobjectscale;
mobj_t *goombaBounce = NULL;
fixed_t distx, disty, dist;
fixed_t force;
fixed_t mass1, mass2;
if (!mobj1 || !mobj2)
if ((!mobj1 || P_MobjWasRemoved(mobj1))
|| (!mobj2 || P_MobjWasRemoved(mobj2)))
{
return false;
}
// Don't bump when you're being reborn
if ((mobj1->player && mobj1->player->playerstate != PST_LIVE)
@ -1176,135 +1297,145 @@ boolean K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean sol
return false;
}
mass1 = K_GetMobjWeight(mobj1, mobj2);
// Adds the OTHER object's momentum times a bunch, for the best chance of getting the correct direction
distx = (mobj1->x + mobj2->momx) - (mobj2->x + mobj1->momx);
disty = (mobj1->y + mobj2->momy) - (mobj2->y + mobj1->momy);
if (solid == true && mass1 > 0)
mass2 = mass1;
else
mass2 = K_GetMobjWeight(mobj2, mobj1);
force = K_GetBounceForce(mobj1, mobj2, distx, disty);
momdifx = mobj1->momx - mobj2->momx;
momdify = mobj1->momy - mobj2->momy;
// Adds the OTHER player's momentum times a bunch, for the best chance of getting the correct direction
distx = (mobj1->x + mobj2->momx*3) - (mobj2->x + mobj1->momx*3);
disty = (mobj1->y + mobj2->momy*3) - (mobj2->y + mobj1->momy*3);
if (distx == 0 && disty == 0)
if (force == 0)
{
// if there's no distance between the 2, they're directly on top of each other, don't run this
return false;
}
{ // Normalize distance to the sum of the two objects' radii, since in a perfect world that would be the distance at the point of collision...
fixed_t dist = P_AproxDistance(distx, disty);
fixed_t nx, ny;
mass1 = K_GetMobjWeight(mobj1, mobj2);
mass2 = K_GetMobjWeight(mobj2, mobj1);
dist = dist ? dist : 1;
nx = FixedDiv(distx, dist);
ny = FixedDiv(disty, dist);
distx = FixedMul(mobj1->radius+mobj2->radius, nx);
disty = FixedMul(mobj1->radius+mobj2->radius, ny);
if (momdifx == 0 && momdify == 0)
{
// If there's no momentum difference, they're moving at exactly the same rate. Pretend they moved into each other.
momdifx = -nx;
momdify = -ny;
}
if ((P_IsObjectOnGround(mobj1) && mobj2->momz < 0) // Grounded
|| (mass2 == 0 && mass1 > 0)) // The other party is immovable
{
goombaBounce = mobj2;
}
else if ((P_IsObjectOnGround(mobj2) && mobj1->momz < 0) // Grounded
|| (mass1 == 0 && mass2 > 0)) // The other party is immovable
{
goombaBounce = mobj1;
}
if (goombaBounce != NULL)
{
// Perform a Goomba Bounce by reversing your z momentum.
goombaBounce->momz = -goombaBounce->momz;
}
else
{
// Trade z momentum values.
fixed_t newz = mobj1->momz;
mobj1->momz = mobj2->momz;
mobj2->momz = newz;
}
// Multiply by force
distx = FixedMul(force, distx);
disty = FixedMul(force, disty);
dist = FixedHypot(distx, disty);
// if the speed difference is less than this let's assume they're going proportionately faster from each other
if (P_AproxDistance(momdifx, momdify) < (25*mapobjectscale))
if (dist < minBump)
{
fixed_t momdiflength = P_AproxDistance(momdifx, momdify);
fixed_t normalisedx = FixedDiv(momdifx, momdiflength);
fixed_t normalisedy = FixedDiv(momdify, momdiflength);
momdifx = FixedMul((25*mapobjectscale), normalisedx);
momdify = FixedMul((25*mapobjectscale), normalisedy);
}
fixed_t normalisedx = FixedDiv(distx, dist);
fixed_t normalisedy = FixedDiv(disty, dist);
dot = FixedMul(momdifx, distx) + FixedMul(momdify, disty);
if (dot >= 0)
{
// They're moving away from each other
return false;
}
force = FixedDiv(dot, FixedMul(distx, distx)+FixedMul(disty, disty));
if (bounce == true && mass2 > 0) // Perform a Goomba Bounce.
mobj1->momz = -mobj1->momz;
else
{
fixed_t newz = mobj1->momz;
if (mass2 > 0)
mobj1->momz = mobj2->momz;
if (mass1 > 0 && solid == false)
mobj2->momz = newz;
distx = FixedMul(minBump, normalisedx);
disty = FixedMul(minBump, normalisedy);
}
if (mass2 > 0)
{
mobj1->momx = mobj1->momx - FixedMul(FixedMul(FixedDiv(2*mass2, mass1 + mass2), force), distx);
mobj1->momy = mobj1->momy - FixedMul(FixedMul(FixedDiv(2*mass2, mass1 + mass2), force), disty);
mobj1->momx = mobj1->momx - FixedMul(FixedDiv(2*mass2, mass1 + mass2), distx);
mobj1->momy = mobj1->momy - FixedMul(FixedDiv(2*mass2, mass1 + mass2), disty);
}
if (mass1 > 0 && solid == false)
if (mass1 > 0)
{
mobj2->momx = mobj2->momx - FixedMul(FixedMul(FixedDiv(2*mass1, mass1 + mass2), force), -distx);
mobj2->momy = mobj2->momy - FixedMul(FixedMul(FixedDiv(2*mass1, mass1 + mass2), force), -disty);
mobj2->momx = mobj2->momx - FixedMul(FixedDiv(2*mass1, mass1 + mass2), -distx);
mobj2->momy = mobj2->momy - FixedMul(FixedDiv(2*mass1, mass1 + mass2), -disty);
}
// Do the bump fx when we've CONFIRMED we can bump.
if ((mobj1->player && mobj1->player->itemtype == KITEM_BUBBLESHIELD) || (mobj2->player && mobj2->player->itemtype == KITEM_BUBBLESHIELD))
S_StartSound(mobj1, sfx_s3k44);
else
S_StartSound(mobj1, sfx_s3k49);
K_SpawnBumpForObjs(mobj1, mobj2);
fx = P_SpawnMobj(mobj1->x/2 + mobj2->x/2, mobj1->y/2 + mobj2->y/2, mobj1->z/2 + mobj2->z/2, MT_BUMP);
if (mobj1->eflags & MFE_VERTICALFLIP)
fx->eflags |= MFE_VERTICALFLIP;
else
fx->eflags &= ~MFE_VERTICALFLIP;
P_SetScale(fx, mobj1->scale);
K_PlayerJustBumped(mobj1->player);
K_PlayerJustBumped(mobj2->player);
// Because this is done during collision now, rmomx and rmomy need to be recalculated
// so that friction doesn't immediately decide to stop the player if they're at a standstill
// Also set justbumped here
if (mobj1->player)
return true;
}
// K_KartBouncing, but simplified to act like P_BouncePlayerMove
boolean K_KartSolidBounce(mobj_t *bounceMobj, mobj_t *solidMobj)
{
const fixed_t minBump = 25*mapobjectscale;
fixed_t distx, disty, dist;
fixed_t force;
if ((!bounceMobj || P_MobjWasRemoved(bounceMobj))
|| (!solidMobj || P_MobjWasRemoved(solidMobj)))
{
mobj1->player->rmomx = mobj1->momx - mobj1->player->cmomx;
mobj1->player->rmomy = mobj1->momy - mobj1->player->cmomy;
mobj1->player->justbumped = bumptime;
mobj1->player->spindash = 0;
if (mobj1->player->spinouttimer)
{
mobj1->player->wipeoutslow = wipeoutslowtime+1;
mobj1->player->spinouttimer = max(wipeoutslowtime+1, mobj1->player->spinouttimer);
//mobj1->player->spinouttype = KSPIN_WIPEOUT; // Enforce type
}
return false;
}
if (mobj2->player)
// Don't bump when you're being reborn
if (bounceMobj->player && bounceMobj->player->playerstate != PST_LIVE)
return false;
if (bounceMobj->player && bounceMobj->player->respawn.state != RESPAWNST_NONE)
return false;
// Don't bump if you've recently bumped
if (bounceMobj->player && bounceMobj->player->justbumped)
{
mobj2->player->rmomx = mobj2->momx - mobj2->player->cmomx;
mobj2->player->rmomy = mobj2->momy - mobj2->player->cmomy;
mobj2->player->justbumped = bumptime;
mobj2->player->spindash = 0;
if (mobj2->player->spinouttimer)
{
mobj2->player->wipeoutslow = wipeoutslowtime+1;
mobj2->player->spinouttimer = max(wipeoutslowtime+1, mobj2->player->spinouttimer);
//mobj2->player->spinouttype = KSPIN_WIPEOUT; // Enforce type
}
bounceMobj->player->justbumped = bumptime;
return false;
}
// Adds the OTHER object's momentum times a bunch, for the best chance of getting the correct direction
{
distx = (bounceMobj->x + solidMobj->momx) - (solidMobj->x + bounceMobj->momx);
disty = (bounceMobj->y + solidMobj->momy) - (solidMobj->y + bounceMobj->momy);
}
force = K_GetBounceForce(bounceMobj, solidMobj, distx, disty);
if (force == 0)
{
return false;
}
// Multiply by force
distx = FixedMul(force, distx);
disty = FixedMul(force, disty);
dist = FixedHypot(distx, disty);
{
// Normalize to the desired push value.
fixed_t normalisedx = FixedDiv(distx, dist);
fixed_t normalisedy = FixedDiv(disty, dist);
fixed_t bounceSpeed;
bounceSpeed = FixedHypot(bounceMobj->momx, bounceMobj->momy);
bounceSpeed = FixedMul(bounceSpeed, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3)));
bounceSpeed += minBump;
distx = FixedMul(bounceSpeed, normalisedx);
disty = FixedMul(bounceSpeed, normalisedy);
}
bounceMobj->momx = bounceMobj->momx - distx;
bounceMobj->momy = bounceMobj->momy - disty;
bounceMobj->momz = -bounceMobj->momz;
K_SpawnBumpForObjs(bounceMobj, solidMobj);
K_PlayerJustBumped(bounceMobj->player);
return true;
}
@ -1760,11 +1891,6 @@ static void K_SpawnBrakeDriftSparks(player_t *player) // Be sure to update the m
sparks->renderflags |= RF_DONTDRAW;
}
static fixed_t K_RandomFlip(fixed_t f)
{
return ( ( leveltime & 1 ) ? f : -f );
}
void K_SpawnDriftBoostClip(player_t *player)
{
mobj_t *clip;
@ -1789,7 +1915,7 @@ void K_SpawnDriftBoostClip(player_t *player)
clip->momz += player->mo->momz;
P_InstaThrust(clip, player->mo->angle +
K_RandomFlip(P_RandomRange(FRACUNIT/2, FRACUNIT)),
P_RandomFlip(P_RandomRange(FRACUNIT/2, FRACUNIT)),
FixedMul(scale, player->speed));
}
@ -6310,7 +6436,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
ghost->extravalue1 = player->numboosts+1;
ghost->extravalue2 = (leveltime % ghost->extravalue1);
ghost->fuse = ghost->extravalue1;
ghost->frame |= FF_FULLBRIGHT;
ghost->renderflags |= RF_FULLBRIGHT;
ghost->colorized = true;
//ghost->color = player->skincolor;
//ghost->momx = (3*player->mo->momx)/4;
@ -7870,6 +7996,11 @@ SINT8 K_Sliptiding(player_t *player)
return player->drift ? 0 : player->aizdriftstrat;
}
INT32 K_StairJankFlip(INT32 value)
{
return P_AltFlip(value, 2);
}
static void K_KartSpindashDust(mobj_t *parent)
{
fixed_t rad = FixedDiv(FixedHypot(parent->radius, parent->radius), parent->scale);

View file

@ -37,7 +37,8 @@ UINT8 K_FindUseodds(player_t *player, fixed_t mashed, UINT32 pdis, UINT8 bestbum
INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush, boolean bot, boolean rival);
INT32 K_GetShieldFromItem(INT32 item);
fixed_t K_GetMobjWeight(mobj_t *mobj, mobj_t *against);
boolean K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid);
boolean K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2);
boolean K_KartSolidBounce(mobj_t *bounceMobj, mobj_t *solidMobj);
void K_KartPainEnergyFling(player_t *player);
void K_FlipFromObject(mobj_t *mo, mobj_t *master);
void K_MatchGenericExtraFlags(mobj_t *mo, mobj_t *master);
@ -85,6 +86,7 @@ boolean K_CheckPlayersRespawnColliding(INT32 playernum, fixed_t x, fixed_t y);
void K_UpdateSteeringValue(player_t *player, INT16 destSteering);
INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue);
INT32 K_GetKartDriftSparkValue(player_t *player);
INT32 K_StairJankFlip(INT32 value);
INT32 K_GetKartDriftSparkValueForStage(player_t *player, UINT8 stage);
void K_SpawnDriftBoostExplosion(player_t *player, int stage);
void K_SpawnDriftElectricSparks(player_t *player);

View file

@ -3391,14 +3391,12 @@ static int lib_kKartBouncing(lua_State *L)
{
mobj_t *mobj1 = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
mobj_t *mobj2 = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
boolean bounce = lua_optboolean(L, 3);
boolean solid = lua_optboolean(L, 4);
NOHUD
if (!mobj1)
return LUA_ErrInvalid(L, "mobj_t");
if (!mobj2)
return LUA_ErrInvalid(L, "mobj_t");
K_KartBouncing(mobj1, mobj2, bounce, solid);
K_KartBouncing(mobj1, mobj2);
return 0;
}

View file

@ -946,6 +946,24 @@ static int libd_drawString(lua_State *L)
return 0;
}
static int libd_drawTitleCardString(lua_State *L)
{
fixed_t x = luaL_checkinteger(L, 1);
fixed_t y = luaL_checkinteger(L, 2);
const char *str = luaL_checkstring(L, 3);
INT32 flags = luaL_optinteger(L, 4, V_ALLOWLOWERCASE);
boolean rightalign = lua_optboolean(L, 5);
INT32 timer = luaL_optinteger(L, 6, 0);
INT32 threshold = luaL_optinteger(L, 7, 0);
flags &= ~V_PARAMMASK; // Don't let crashes happen.
HUDONLY
V_DrawTitleCardString(x, y, str, flags, rightalign, timer, threshold);
return 0;
}
static int libd_drawKartString(lua_State *L)
{
fixed_t x = luaL_checkinteger(L, 1);
@ -960,6 +978,15 @@ static int libd_drawKartString(lua_State *L)
return 0;
}
static int libd_titleCardStringWidth(lua_State *L)
{
const char *str = luaL_checkstring(L, 1);
HUDONLY
lua_pushinteger(L, V_TitleCardStringWidth(str));
return 1;
}
static int libd_stringWidth(lua_State *L)
{
const char *str = luaL_checkstring(L, 1);
@ -1163,9 +1190,11 @@ static luaL_Reg lib_draw[] = {
{"drawFill", libd_drawFill},
{"fadeScreen", libd_fadeScreen},
{"drawString", libd_drawString},
{"drawTitleCardString", libd_drawTitleCardString},
{"drawKartString", libd_drawKartString},
// misc
{"stringWidth", libd_stringWidth},
{"titleCardStringWidth", libd_titleCardStringWidth},
// m_random
{"RandomFixed",libd_RandomFixed},
{"RandomByte",libd_RandomByte},

View file

@ -128,7 +128,7 @@ static int lib_iterateDisplayplayers(lua_State *L)
for (i++; i < MAXSPLITSCREENPLAYERS; i++)
{
if (i > splitscreen || !playeringame[displayplayers[i]])
if (i > r_splitscreen || !playeringame[displayplayers[i]])
return 0; // Stop! There are no more players for us to go through. There will never be a player gap in displayplayers.
LUA_PushUserdata(L, &players[displayplayers[i]], META_PLAYER);
@ -147,7 +147,7 @@ static int lib_getDisplayplayers(lua_State *L)
lua_Integer i = luaL_checkinteger(L, 2);
if (i < 0 || i >= MAXSPLITSCREENPLAYERS)
return luaL_error(L, "displayplayers[] index %d out of range (0 - %d)", i, MAXSPLITSCREENPLAYERS-1);
if (i > splitscreen)
if (i > r_splitscreen)
return 0;
if (!playeringame[displayplayers[i]])
return 0;

View file

@ -178,7 +178,7 @@ int LUA_PushGlobals(lua_State *L, const char *word)
lua_pushboolean(L, modeattacking);
return 1;
} else if (fastcmp(word,"splitscreen")) {
lua_pushboolean(L, splitscreen);
lua_pushinteger(L, splitscreen);
return 1;
} else if (fastcmp(word,"gamecomplete")) {
lua_pushboolean(L, (gamecomplete != 0));

View file

@ -11044,7 +11044,7 @@ void A_FadeOverlay(mobj_t *actor)
return;
fade = P_SpawnGhostMobj(actor);
fade->frame = actor->frame;
fade->renderflags = actor->renderflags;
if (!(locvar1 & 1))
{
@ -14650,4 +14650,4 @@ void A_InvincSparkleRotate(mobj_t *actor)
actor->momz = actor->target->momz; // Give momentum for eventual interp builds idk.
actor->angle += ANG1*10*(actor->extravalue2); // Arbitrary value, change this if you want, I suppose.
}
}

View file

@ -1247,33 +1247,19 @@ static boolean PIT_CheckThing(mobj_t *thing)
return true;
}
// The bump has to happen last
if (P_IsObjectOnGround(thing) && tmthing->momz < 0 && tmthing->player->trickpanel)
{
// The bump has to happen last
mobj_t *mo1 = tmthing;
mobj_t *mo2 = thing;
boolean zbounce = false;
P_DamageMobj(thing, tmthing, tmthing, 1, DMG_WIPEOUT|DMG_STEAL);
}
else if (P_IsObjectOnGround(tmthing) && thing->momz < 0 && thing->player->trickpanel)
{
P_DamageMobj(tmthing, thing, thing, 1, DMG_WIPEOUT|DMG_STEAL);
}
if (P_IsObjectOnGround(thing) && tmthing->momz < 0)
{
zbounce = true;
mo1 = thing;
mo2 = tmthing;
if (tmthing->player->trickpanel)
P_DamageMobj(thing, tmthing, tmthing, 1, DMG_WIPEOUT|DMG_STEAL);
}
else if (P_IsObjectOnGround(tmthing) && thing->momz < 0)
{
zbounce = true;
if (thing->player->trickpanel)
P_DamageMobj(tmthing, thing, thing, 1, DMG_WIPEOUT|DMG_STEAL);
}
if (K_KartBouncing(mo1, mo2, zbounce, false))
{
K_PvPTouchDamage(mo1, mo2);
}
if (K_KartBouncing(tmthing, thing) == true)
{
K_PvPTouchDamage(tmthing, thing);
}
return true;
@ -1300,8 +1286,8 @@ static boolean PIT_CheckThing(mobj_t *thing)
}
else
{
K_KartBouncing(tmthing, thing, false, true);
return false;
K_KartSolidBounce(tmthing, thing);
return true;
}
}
else if (thing->type == MT_SMK_PIPE)
@ -1322,8 +1308,8 @@ static boolean PIT_CheckThing(mobj_t *thing)
return true; // kill
}
K_KartBouncing(tmthing, thing, false, true);
return false;
K_KartSolidBounce(tmthing, thing);
return true;
}
else if (thing->type == MT_SMK_THWOMP)
{
@ -1362,12 +1348,13 @@ static boolean PIT_CheckThing(mobj_t *thing)
P_DamageMobj(tmthing, thing, thing, 1, DMG_TUMBLE);
else
{
if (thing->flags2 & MF2_AMBUSH)
if ((K_KartSolidBounce(tmthing, thing) == true) && (thing->flags2 & MF2_AMBUSH))
{
P_DamageMobj(tmthing, thing, thing, 1, DMG_WIPEOUT);
K_KartBouncing(tmthing, thing, false, true);
}
}
return false;
return true;
}
else if (thing->type == MT_KART_LEFTOVER)
{
@ -1377,12 +1364,8 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (tmthing->z + tmthing->height < thing->z)
return true; // underneath
if (P_IsObjectOnGround(thing) && tmthing->momz < 0)
K_KartBouncing(tmthing, thing, true, false);
else
K_KartBouncing(tmthing, thing, false, false);
return false;
K_KartBouncing(tmthing, thing);
return true;
}
else if (thing->flags & MF_SOLID)
{
@ -1392,12 +1375,8 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (tmthing->z + tmthing->height < thing->z)
return true; // underneath
if (P_IsObjectOnGround(thing) && tmthing->momz < 0)
K_KartBouncing(tmthing, thing, true, true);
else
K_KartBouncing(tmthing, thing, false, true);
return false;
K_KartSolidBounce(tmthing, thing);
return true;
}
}
@ -2417,6 +2396,8 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
fixed_t radius = thing->radius;
fixed_t thingtop;
fixed_t startingonground = P_IsObjectOnGround(thing);
fixed_t stairjank = 0;
pslope_t *oldslope = thing->standingslope;
floatok = false;
// reset this to 0 at the start of each trymove call as it's only used here
@ -2488,6 +2469,9 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
if (maxstep > 0)
{
const boolean flipped =
(thing->eflags & MFE_VERTICALFLIP) != 0;
thingtop = thing->z + thing->height;
// Step up
@ -2495,6 +2479,9 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
{
if (tmfloorstep <= maxstep)
{
if (!flipped)
stairjank = tmfloorstep;
thing->z = thing->floorz = tmfloorz;
thing->floorrover = tmfloorrover;
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
@ -2508,6 +2495,9 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
{
if (tmceilingstep <= maxstep)
{
if (flipped)
stairjank = tmceilingstep;
thing->z = ( thing->ceilingz = tmceilingz ) - thing->height;
thing->ceilingrover = tmceilingrover;
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
@ -2524,6 +2514,9 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
if (thingtop == thing->ceilingz && tmceilingz > thingtop && tmceilingz - thingtop <= maxstep)
{
if (flipped)
stairjank = (tmceilingz - thingtop);
thing->z = (thing->ceilingz = tmceilingz) - thing->height;
thing->ceilingrover = tmceilingrover;
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
@ -2531,6 +2524,9 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
}
else if (thing->z == thing->floorz && tmfloorz < thing->z && thing->z - tmfloorz <= maxstep)
{
if (!flipped)
stairjank = (thing->z - tmfloorz);
thing->z = thing->floorz = tmfloorz;
thing->floorrover = tmfloorrover;
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
@ -2617,6 +2613,28 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
else // don't set standingslope if you're not going to clip against it
thing->standingslope = NULL;
/* FIXME: slope step down (even up) has some false
positives, so just ignore them entirely. */
if (stairjank && !oldslope && !thing->standingslope &&
thing->player && !thing->player->spectator)
{
/* use a shorter sound if not two tics have passed
* since the last step */
S_StartSound(thing, thing->player->stairjank
>= 16 ? sfx_s23b : sfx_s268);
if (!thing->player->stairjank)
{
mobj_t * spark = P_SpawnMobjFromMobj(thing,
0, 0, 0, MT_JANKSPARK);
spark->fuse = 9;
spark->cusval = K_StairJankFlip(ANGLE_90);
P_SetTarget(&spark->target, thing);
}
thing->player->stairjank = 17;
}
thing->x = x;
thing->y = y;

View file

@ -4284,8 +4284,8 @@ void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot)
angle_t prevfa = (prevrot + mobj->friction) & FINEMASK;
fa = (rot + mobj->friction) & FINEMASK;
if (!(prevfa > (FINEMASK/2)) && (fa > (FINEMASK/2))) // completed a full swing
dosound = true;
// completed a half-spin
dosound = ((prevfa > (FINEMASK/2)) != (fa > (FINEMASK/2)));
unit_lengthways[0] = FixedMul(FINECOSINE(fa), radius);
unit_lengthways[2] = FixedMul(FINESINE(fa), radius);
@ -6626,6 +6626,21 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
mobj->renderflags |= RF_DONTDRAW;
}
break;
case MT_JANKSPARK:
if (!mobj->target)
{
P_RemoveMobj(mobj);
return false;
}
if (mobj->fuse == 1 && mobj->target->player &&
mobj->target->player->stairjank >= 8)
{
mobj->fuse = 9;
}
P_TeleportMove(mobj, mobj->target->x,
mobj->target->y, mobj->target->z);
mobj->angle = mobj->target->angle + mobj->cusval;
break;
case MT_PLAYERRETICULE:
if (!mobj->target || !mobj->target->health)
{
@ -8477,17 +8492,29 @@ void P_MobjThinker(mobj_t *mobj)
if (mobj->type == MT_GHOST && mobj->fuse > 0) // Not guaranteed to be MF_SCENERY or not MF_SCENERY!
{
if (mobj->flags2 & MF2_BOSSNOTRAP) // "fast" flag
if (mobj->extravalue1 > 0) // Sonic Advance 2 mode
{
if ((signed)((mobj->renderflags & RF_TRANSMASK) >> RF_TRANSSHIFT) < (NUMTRANSMAPS-1) - (2*mobj->fuse)/3)
// fade out when nearing the end of fuse...
mobj->renderflags = (mobj->renderflags & ~RF_TRANSMASK) | (((NUMTRANSMAPS-1) - (2*mobj->fuse)/3) << RF_TRANSSHIFT);
if (mobj->extravalue2 >= 2)
{
if (mobj->extravalue2 == 2) // I don't know why the normal logic doesn't work for this.
mobj->renderflags ^= RF_DONTDRAW;
else
{
if (mobj->fuse == mobj->extravalue2)
mobj->renderflags &= ~RF_DONTDRAW;
else
mobj->renderflags |= RF_DONTDRAW;
}
}
}
else
{
if ((signed)((mobj->renderflags & RF_TRANSMASK) >> RF_TRANSSHIFT) < (NUMTRANSMAPS-1) - mobj->fuse / 2)
INT32 dur = (mobj->flags2 & MF2_BOSSNOTRAP)
? (2*mobj->fuse)/3
: mobj->fuse/2;
if (((mobj->renderflags & RF_TRANSMASK) >> RF_TRANSSHIFT) < ((NUMTRANSMAPS-1) - dur))
// fade out when nearing the end of fuse...
mobj->renderflags = (mobj->frame & ~RF_TRANSMASK) | (((NUMTRANSMAPS-1) - mobj->fuse / 2) << RF_TRANSSHIFT);
mobj->renderflags = (mobj->renderflags & ~RF_TRANSMASK) | (((NUMTRANSMAPS-1) - dur) << RF_TRANSSHIFT);
}
}
@ -8815,21 +8842,6 @@ void P_SceneryThinker(mobj_t *mobj)
}
}
// Sonic Advance 2 flashing afterimages
if (mobj->type == MT_GHOST && mobj->fuse > 0
&& mobj->extravalue1 > 0 && mobj->extravalue2 >= 2)
{
if (mobj->extravalue2 == 2) // I don't know why the normal logic doesn't work for this.
mobj->renderflags ^= RF_DONTDRAW;
else
{
if (mobj->fuse == mobj->extravalue2)
mobj->renderflags &= ~RF_DONTDRAW;
else
mobj->renderflags |= RF_DONTDRAW;
}
}
// momentum movement
if (mobj->momx || mobj->momy)
{

View file

@ -659,9 +659,7 @@ flatfound:
levelflat->u.flat.baselumpnum = LUMPERROR;
}
#ifndef ZDEBUG
CONS_Debug(DBG_SETUP, "flat #%03d: %s\n", atoi(sizeu1(numlevelflats)), levelflat->name);
#endif
return ( numlevelflats++ );
}
@ -3729,10 +3727,10 @@ static void P_InitCamera(void)
{
UINT8 i;
for (i = 0; i <= splitscreen; i++)
for (i = 0; i <= r_splitscreen; i++)
{
P_SetupCamera(i, &camera[i]);
displayplayers[i] = g_localplayers[i]; // Start with your OWN view, please!
//displayplayers[i] = g_localplayers[i]; // Start with your OWN view, please!
P_SetupCamera(displayplayers[i], &camera[i]);
}
}
}
@ -3981,8 +3979,8 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
F_RunWipe(wipedefs[wipe_level_toblack], false, ((levelfadecol == 0) ? "FADEMAP1" : "FADEMAP0"), false, false);
}
if (!titlemapinaction)
wipegamestate = GS_LEVEL;
/*if (!titlemapinaction)
wipegamestate = GS_LEVEL;*/
// Close text prompt before freeing the old level
F_EndTextPrompt(false, true);

View file

@ -848,6 +848,11 @@ void P_SlopeLaunch(mobj_t *mo)
//CONS_Printf("Launched off of slope.\n");
mo->standingslope = NULL;
if (mo->player)
{
mo->player->stairjank = 0; // fuck you
}
}
//

View file

@ -36,6 +36,11 @@
tic_t leveltime;
INT32 P_AltFlip(INT32 n, tic_t tics)
{
return leveltime % (2 * tics) < tics ? n : -(n);
}
//
// THINKERS
// All thinkers should be allocated by Z_Calloc

View file

@ -30,4 +30,8 @@ void P_DoTeamscrambling(void);
void P_RemoveThinkerDelayed(thinker_t *thinker); //killed
mobj_t *P_SetTarget(mobj_t **mo, mobj_t *target); // killough 11/98
// Negate the value for tics
INT32 P_AltFlip(INT32 value, tic_t tics);
#define P_RandomFlip(value) P_AltFlip(value, 1)
#endif

View file

@ -1677,12 +1677,22 @@ static void P_3dMovement(player_t *player)
// Get the old momentum; this will be needed at the end of the function! -SH
oldMagnitude = R_PointToDist2(player->mo->momx - player->cmomx, player->mo->momy - player->cmomy, 0, 0);
if (player->drift != 0)
movepushangle = player->mo->angle-(ANGLE_45/5)*player->drift;
else if (player->spinouttimer || player->wipeoutslow) // if spun out, use the boost angle
if (player->stairjank > 8 && leveltime & 3)
{
movepushangle = K_MomentumAngle(player->mo);
}
else if (player->drift != 0)
{
movepushangle = player->mo->angle - (ANGLE_45/5) * player->drift;
}
else if (player->spinouttimer || player->wipeoutslow) // if spun out, use the boost angle
{
movepushangle = (angle_t)player->boostangle;
}
else
{
movepushangle = player->mo->angle;
}
// cmomx/cmomy stands for the conveyor belt speed.
if (player->onconveyor == 2) // Wind/Current
@ -4486,14 +4496,19 @@ void P_PlayerThink(player_t *player)
player->typing_duration = 0;
}
if (player->stairjank > 0)
{
player->stairjank--;
}
K_KartPlayerThink(player, cmd); // SRB2kart
DoABarrelRoll(player);
LUAh_PlayerThink(player);
if (player->carry == CR_SLIDING)
player->carry = CR_NONE;
LUAh_PlayerThink(player);
}
//

View file

@ -15,6 +15,7 @@
#include "w_wad.h"
#include "r_main.h" // R_PointToAngle
#include "k_kart.h" // K_Sliptiding
#include "p_tick.h"
#ifdef ROTSPRITE
fixed_t rollcosang[ROTANGLES];
@ -32,16 +33,14 @@ angle_t R_GetPitchRollAngle(mobj_t *mobj)
return rollOrPitch;
}
angle_t R_SpriteRotationAngle(mobj_t *mobj)
static angle_t R_PlayerSpriteRotation(player_t *player)
{
angle_t viewingAngle = R_PointToAngle(mobj->x, mobj->y);
angle_t angleDelta = (viewingAngle - mobj->angle);
angle_t viewingAngle = R_PointToAngle(player->mo->x, player->mo->y);
angle_t angleDelta = (viewingAngle - player->mo->angle);
angle_t sliptideLift = mobj->player
? mobj->player->aizdrifttilt : 0;
angle_t sliptideLift = player->aizdrifttilt;
angle_t rollOrPitch = R_GetPitchRollAngle(mobj);
angle_t rollAngle = (rollOrPitch + mobj->rollangle);
angle_t rollAngle = 0;
if (sliptideLift)
{
@ -52,6 +51,25 @@ angle_t R_SpriteRotationAngle(mobj_t *mobj)
FixedMul(sliptideLift, FINECOSINE(angleDelta >> ANGLETOFINESHIFT));
}
if (player->stairjank)
{
rollAngle += K_StairJankFlip(ANGLE_11hh / 2 /
(17 / player->stairjank));
}
return rollAngle;
}
angle_t R_SpriteRotationAngle(mobj_t *mobj)
{
angle_t rollOrPitch = R_GetPitchRollAngle(mobj);
angle_t rollAngle = (rollOrPitch + mobj->rollangle);
if (mobj->player)
{
rollAngle += R_PlayerSpriteRotation(mobj->player);
}
return rollAngle;
}

View file

@ -1611,9 +1611,7 @@ INT32 R_CheckTextureNumForName(const char *name)
Z_Realloc(tidcache, tidcachelen * sizeof(*tidcache), PU_STATIC, &tidcache);
strncpy(tidcache[tidcachelen-1].name, name, 8);
tidcache[tidcachelen-1].name[8] = '\0';
#ifndef ZDEBUG
CONS_Debug(DBG_SETUP, "texture #%s: %s\n", sizeu1(tidcachelen), tidcache[tidcachelen-1].name);
#endif
tidcache[tidcachelen-1].id = i;
return i;
}

View file

@ -484,9 +484,7 @@ void R_AddSpriteDefs(UINT16 wadnum)
#endif
// if a new sprite was added (not just replaced)
addsprites++;
#ifndef ZDEBUG
CONS_Debug(DBG_SETUP, "sprite %s set in pwad %d\n", sprnames[i], wadnum);
#endif
}
}

View file

@ -87,7 +87,7 @@ sfxinfo_t S_sfx[NUMSFX] =
{"fire", false, 8, 32, -1, NULL, 0, -1, -1, LUMPERROR, "Flamethrower"},
{"grind", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Metallic grinding"},
{"laser", true, 16, 2, -1, NULL, 0, -1, -1, LUMPERROR, "Laser hum"},
{"mswing", false, 16, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Swinging mace"},
{"mswing", false, 16, 65, -1, NULL, 0, -1, -1, LUMPERROR, "Swinging mace"},
{"pstart", false, 100, 0, -1, NULL, 0, -1, -1, LUMPERROR, "/"},
{"pstop", false, 100, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Crusher stomp"},
{"steam1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Steam jet"}, // Tails 06-19-2001
@ -630,8 +630,8 @@ sfxinfo_t S_sfx[NUMSFX] =
{"s3kc7l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Aiming"}, // ditto
{"s3kc8s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Sliding"},
{"s3kc8l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Sliding"}, // ditto
{"s3kc9s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Swinging"},
{"s3kc9l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Swinging"}, // ditto
{"s3kc9s", false, 64, 65, -1, NULL, 0, -1, -1, LUMPERROR, "Swinging"},
{"s3kc9l", false, 64, 65, -1, NULL, 0, -1, -1, LUMPERROR, "Swinging"}, // ditto
{"s3kcas", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Energy"},
{"s3kcal", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Energy"}, // ditto
{"s3kcbs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous rumbling"},
@ -837,6 +837,77 @@ sfxinfo_t S_sfx[NUMSFX] =
{"kc6d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc6e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
// Mean Bean Machine sounds
{"mbs41", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs42", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs43", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs44", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs45", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs46", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs47", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs48", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs49", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs4a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs4b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs4c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs4d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs4e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs4f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs50", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs51", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs52", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs53", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs54", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs55", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs56", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs57", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs58", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs59", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs5a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs5b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs5c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs5d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs5e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs5f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs60", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs61", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs62", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs63", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs64", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs67", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs68", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs69", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs6a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs6b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs6d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs6e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs70", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs71", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbs72", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbv81", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbv82", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbv83", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbv84", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbv85", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbv86", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbv87", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbv88", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbv89", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbv8a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbv8b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbv8c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbv8d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbv8e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbv8f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbv90", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbv91", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbv92", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbv93", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbv94", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbv95", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbv96", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbv97", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
// SRB2kart
{"slip", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Spinout
{"screec", false, 48, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Tight turning screech

View file

@ -901,6 +901,77 @@ typedef enum
sfx_kc6d,
sfx_kc6e,
// Mean Bean Machine sounds
sfx_mbs41,
sfx_mbs42,
sfx_mbs43,
sfx_mbs44,
sfx_mbs45,
sfx_mbs46,
sfx_mbs47,
sfx_mbs48,
sfx_mbs49,
sfx_mbs4a,
sfx_mbs4b,
sfx_mbs4c,
sfx_mbs4d,
sfx_mbs4e,
sfx_mbs4f,
sfx_mbs50,
sfx_mbs51,
sfx_mbs52,
sfx_mbs53,
sfx_mbs54,
sfx_mbs55,
sfx_mbs56,
sfx_mbs57,
sfx_mbs58,
sfx_mbs59,
sfx_mbs5a,
sfx_mbs5b,
sfx_mbs5c,
sfx_mbs5d,
sfx_mbs5e,
sfx_mbs5f,
sfx_mbs60,
sfx_mbs61,
sfx_mbs62,
sfx_mbs63,
sfx_mbs64,
sfx_mbs67,
sfx_mbs68,
sfx_mbs69,
sfx_mbs6a,
sfx_mbs6b,
sfx_mbs6d,
sfx_mbs6e,
sfx_mbs70,
sfx_mbs71,
sfx_mbs72,
sfx_mbv81,
sfx_mbv82,
sfx_mbv83,
sfx_mbv84,
sfx_mbv85,
sfx_mbv86,
sfx_mbv87,
sfx_mbv88,
sfx_mbv89,
sfx_mbv8a,
sfx_mbv8b,
sfx_mbv8c,
sfx_mbv8d,
sfx_mbv8e,
sfx_mbv8f,
sfx_mbv90,
sfx_mbv91,
sfx_mbv92,
sfx_mbv93,
sfx_mbv94,
sfx_mbv95,
sfx_mbv96,
sfx_mbv97,
// SRB2kart
sfx_slip,
sfx_screec,

View file

@ -31,6 +31,7 @@
#include "m_misc.h" // moviemode
#include "m_anigif.h" // cv_gif_downscale
#include "p_setup.h" // NiGHTS grading
#include "k_grandprix.h" // we need to know grandprix status for titlecards
//random index
#include "m_random.h"
@ -622,23 +623,97 @@ static void ST_drawDebugInfo(void)
V_DrawRightAlignedString(320, height, V_MONOSPACE, va("Heap used: %7sKB", sizeu1(Z_TagsUsage(0, INT32_MAX)>>10)));
}
static patch_t *lt_patches[3];
static INT32 lt_scroll = 0;
static INT32 lt_mom = 0;
static INT32 lt_zigzag = 0;
tic_t lt_ticker = 0, lt_lasttic = 0;
tic_t lt_exitticker = 0, lt_endtime = 0;
// SRB2KART: HUD shit for new titlecards:
static patch_t *tcchev1;
static patch_t *tcchev2;
static patch_t *tcol1;
static patch_t *tcol2;
static patch_t *tcroundbar;
static patch_t *tcround;
static patch_t *tccircletop;
static patch_t *tccirclebottom;
static patch_t *tccirclebg;
static patch_t *tcbanner;
static patch_t *tcbanner2;
static patch_t *tcroundnum[10];
static patch_t *tcactnum[10];
static patch_t *tcact;
// some coordinates define to make my life easier....
#define FINAL_ROUNDX (24)
#define FINAL_EGGY (160)
#define FINAL_ROUNDY (16)
#define FINAL_BANNERY (160)
INT32 chev1x, chev1y, chev2x, chev2y, chevtflag;
INT32 roundx, roundy;
INT32 bannerx, bannery;
INT32 roundnumx, roundnumy;
INT32 eggx1, eggx2, eggy1, eggy2;
// These are all arbitrary values found by trial and error trying to align the hud lmao.
// But they'll work.
#define BASE_CHEV1X (252)
#define BASE_CHEV1Y (60)
#define BASE_CHEV2X (65)
#define BASE_CHEV2Y (135)
#define TTANIMTHRESHOLD (TICRATE)
#define TTANIMSTART (TTANIMTHRESHOLD-16)
#define TTANIMENDTHRESHOLD (TICRATE*3)
#define TTANIMEND (TICRATE*4)
//
// Load the graphics for the title card.
// Don't let LJ see this
//
static void ST_cacheLevelTitle(void)
{
lt_patches[0] = (patch_t *)W_CachePatchName("LTACTBLU", PU_HUDGFX);
lt_patches[1] = (patch_t *)W_CachePatchName("LTZIGZAG", PU_HUDGFX);
lt_patches[2] = (patch_t *)W_CachePatchName("LTZZTEXT", PU_HUDGFX);
UINT8 i;
char buf[9];
// SRB2KART
tcchev1 = (patch_t *)W_CachePatchName("TCCHEV1W", PU_HUDGFX);
tcchev2 = (patch_t *)W_CachePatchName("TCCHEV2W", PU_HUDGFX);
tcol1 = (patch_t *)W_CachePatchName("TCCHOL1", PU_HUDGFX);
tcol2 = (patch_t *)W_CachePatchName("TCCHOL2", PU_HUDGFX);
tcroundbar = (patch_t *)W_CachePatchName("TCBB0", PU_HUDGFX);
tcround = (patch_t *)W_CachePatchName("TCROUND", PU_HUDGFX);
tccircletop = (patch_t *)W_CachePatchName("TCSN1", PU_HUDGFX);
tccirclebottom =(patch_t *)W_CachePatchName("TCSN2", PU_HUDGFX);
tccirclebg = (patch_t *)W_CachePatchName("TCEG3", PU_HUDGFX);
tcbanner = (patch_t *)W_CachePatchName("TCBSKA0", PU_HUDGFX);
tcbanner2 = (patch_t *)W_CachePatchName("TCBC0", PU_HUDGFX);
tcact = (patch_t *)W_CachePatchName("TT_ACT", PU_HUDGFX);
// Cache round #
for (i=1; i < 11; i++)
{
sprintf(buf, "TT_RND%d", i);
tcroundnum[i-1] = (patch_t *)W_CachePatchName(buf, PU_HUDGFX);
}
// Cache act #
for (i=0; i < 10; i++)
{
sprintf(buf, "TT_ACT%d", i);
tcactnum[i] = (patch_t *)W_CachePatchName(buf, PU_HUDGFX);
}
}
//
@ -649,12 +724,28 @@ void ST_startTitleCard(void)
// cache every HUD patch used
ST_cacheLevelTitle();
// Set most elements to start off-screen, ST_runTitleCard will have them slide in afterwards
chev1x = BASE_CHEV1X +350; // start off-screen
chev1y = BASE_CHEV1Y;
chev2x = BASE_CHEV2X -350; // start off-screen
chev2y = BASE_CHEV2Y;
chevtflag = 0;
roundx = -999;
roundy = -999;
roundnumx = -999;
roundnumy = -999;
eggx1 = -999;
eggx2 = -999;
eggy1 = -999;
eggy2 = -999;
bannery = 300;
// initialize HUD variables
lt_ticker = lt_exitticker = lt_lasttic = 0;
lt_endtime = 2*TICRATE + (10*NEWTICRATERATIO);
lt_scroll = BASEVIDWIDTH * FRACUNIT;
lt_zigzag = -((lt_patches[1])->width * FRACUNIT);
lt_mom = 0;
lt_endtime = 4*TICRATE; // + (10*NEWTICRATERATIO);
}
//
@ -679,6 +770,8 @@ void ST_preDrawTitleCard(void)
void ST_runTitleCard(void)
{
boolean run = !(paused || P_AutoPause());
INT32 auxticker;
boolean gp = (grandprixinfo.gp && grandprixinfo.roundnum); // check whether we're in grandprix
if (!G_IsTitleCardAvailable())
return;
@ -690,35 +783,137 @@ void ST_runTitleCard(void)
{
// tick
lt_ticker++;
// SRB2KART
// side Zig-Zag positions...
// TITLECARD START
if (lt_ticker < TTANIMSTART)
{
chev1x = max(BASE_CHEV1X, (BASE_CHEV1X +350) - (INT32)(lt_ticker)*50);
chev2x = min(BASE_CHEV2X, (BASE_CHEV2X -350) + (INT32)(lt_ticker)*50);
}
// OPEN ZIG-ZAGS 1 SECOND IN
if (lt_ticker > TTANIMTHRESHOLD)
{
auxticker = (INT32)(lt_ticker) - TTANIMTHRESHOLD;
chev1x = min(320, BASE_CHEV1X + auxticker*16);
chev1y = max(0, BASE_CHEV1Y - auxticker*16);
chev2x = max(0, BASE_CHEV2X - auxticker*16);
chev2y = min(200, BASE_CHEV2Y + auxticker*16);
// translucent fade after opening up.
chevtflag = min(5, ((auxticker)/5)) << V_ALPHASHIFT;
// OPEN ZIG-ZAG: END OF ANIMATION (they leave the screen borders)
if (lt_ticker > TTANIMENDTHRESHOLD)
{
auxticker = (INT32)lt_ticker - TTANIMENDTHRESHOLD;
chev1x += auxticker*16;
chev1y -= auxticker*16;
chev2x -= auxticker*16;
chev2y += auxticker*16;
}
}
// ROUND BAR + EGG
eggy1 = FINAL_EGGY; // Make sure to reset that each call so that Y position doesn't go bonkers
// SLIDE BAR IN, SLIDE "ROUND" DOWNWARDS
if (lt_ticker <= TTANIMTHRESHOLD)
{
INT32 interptimer = (INT32)lt_ticker - TTANIMSTART;
// INT32 because tic_t is unsigned and we want this to be potentially negative
if (interptimer >= 0)
{
INT32 interpdiff = ((TTANIMTHRESHOLD-TTANIMSTART) - interptimer);
interpdiff *= interpdiff; // interpdiff^2
roundx = FINAL_ROUNDX - interpdiff;
roundy = FINAL_ROUNDY - interpdiff;
eggy1 = FINAL_EGGY + interpdiff;
}
}
// SLIDE BAR OUT, SLIDE "ROUND" DOWNWARDS FASTER
else if (lt_ticker >= TTANIMENDTHRESHOLD)
{
auxticker = (INT32)lt_ticker - TTANIMENDTHRESHOLD;
roundx = FINAL_ROUNDX - auxticker*24;
roundy = FINAL_ROUNDY + auxticker*48;
eggy1 = FINAL_EGGY + auxticker*48;
}
// follow the round bar.
eggx1 = roundx + tcroundbar->width/2;
// initially, both halves are on the same coordinates.
eggx2 = eggx1;
eggy2 = eggy1;
// same for the background (duh)
roundnumx = eggx1;
roundnumy = eggy1;
// split both halves of the egg, but only do that in grand prix!
if (gp && lt_ticker > TTANIMTHRESHOLD + TICRATE/2)
{
auxticker = (INT32)lt_ticker - (TTANIMTHRESHOLD + TICRATE/2);
eggx1 -= auxticker*12;
eggy1 -= auxticker*12;
eggx2 += auxticker*12;
eggy2 += auxticker*12;
}
// SCROLLING BOTTOM BANNER
// SLIDE BANNER UPWARDS WITH A FUNNY BOUNCE (this requires trig :death:)
if (lt_ticker < TTANIMTHRESHOLD)
{
INT32 costimer = (INT32)lt_ticker - TTANIMSTART;
// INT32 because tic_t is unsigned and we want this to be potentially negative
if (costimer > 0)
{
// For this animation, we're going to do a tiny bit of stupid trigonometry.
// Admittedly all of this is going to look like magic numbers, and honestly? They are.
// start at angle 355 (where y = ~230 with our params)
// and go to angle 131 (where y = ~160 with our params)
UINT8 basey = 190;
UINT8 amplitude = 45;
fixed_t ang = (355 - costimer*14)*FRACUNIT;
bannery = basey + (amplitude * FINECOSINE(FixedAngle(ang)>>ANGLETOFINESHIFT)) / FRACUNIT;
}
}
// SLIDE BANNER DOWNWARDS OUT OF THE SCREEN AT THE END
else if (lt_ticker >= TTANIMENDTHRESHOLD)
{
auxticker = (INT32)lt_ticker - TTANIMENDTHRESHOLD;
bannery = FINAL_BANNERY + auxticker*16;
}
// No matter the circumstances, scroll the banner...
bannerx = -(lt_ticker%(tcbanner->width));
// used for hud slidein
if (lt_ticker >= lt_endtime)
lt_exitticker++;
// scroll to screen (level title)
if (!lt_exitticker)
{
if (abs(lt_scroll) > FRACUNIT)
lt_scroll -= (lt_scroll>>2);
else
lt_scroll = 0;
}
// scroll away from screen (level title)
else
{
lt_mom -= FRACUNIT*6;
lt_scroll += lt_mom;
}
// scroll to screen (zigzag)
if (!lt_exitticker)
{
if (abs(lt_zigzag) > FRACUNIT)
lt_zigzag -= (lt_zigzag>>2);
else
lt_zigzag = 0;
}
// scroll away from screen (zigzag)
else
lt_zigzag += lt_mom;
}
}
@ -729,25 +924,17 @@ void ST_runTitleCard(void)
void ST_drawTitleCard(void)
{
char *lvlttl = mapheaderinfo[gamemap-1]->lvlttl;
char *subttl = mapheaderinfo[gamemap-1]->subttl;
char *zonttl = mapheaderinfo[gamemap-1]->zonttl; // SRB2kart
UINT8 actnum = mapheaderinfo[gamemap-1]->actnum;
INT32 lvlttlxpos, ttlnumxpos, zonexpos;
INT32 subttlxpos = BASEVIDWIDTH/2;
INT32 ttlscroll = FixedInt(lt_scroll);
#ifdef TITLEPATCHES
INT32 zzticker;
patch_t *actpat, *zigzag, *zztext;
UINT8 colornum;
const UINT8 *colormap;
boolean gp = (grandprixinfo.gp && grandprixinfo.roundnum);
if (players[g_localplayers[0]].skincolor)
colornum = players[g_localplayers[0]].skincolor;
else
colornum = cv_playercolor[0].value;
INT32 acttimer;
fixed_t actscale;
angle_t fakeangle;
colormap = R_GetTranslationColormap(TC_DEFAULT, colornum, GTC_CACHE);
#endif
INT32 bx = bannerx; // We need to make a copy of that otherwise pausing will cause problems.
UINT8 i;
if (!G_IsTitleCardAvailable())
return;
@ -761,95 +948,118 @@ void ST_drawTitleCard(void)
if ((lt_ticker-lt_lasttic) > 1)
lt_ticker = lt_lasttic+1;
ST_cacheLevelTitle();
// Avoid HOMs while drawing the start of the titlecard
if (lt_ticker < TTANIMSTART)
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol);
#ifdef TITLEPATCHES
actpat = lt_patches[0];
zigzag = lt_patches[1];
zztext = lt_patches[2];
#endif
// Background zig-zags
V_DrawFixedPatch((chev1x)*FRACUNIT, (chev1y)*FRACUNIT, FRACUNIT, chevtflag, tcchev1, NULL);
V_DrawFixedPatch((chev2x)*FRACUNIT, (chev2y)*FRACUNIT, FRACUNIT, chevtflag, tcchev2, NULL);
lvlttlxpos = ((BASEVIDWIDTH/2) - (V_LevelNameWidth(lvlttl)/2));
if (actnum > 0)
lvlttlxpos -= V_LevelNameWidth(va("%d", actnum));
// Draw ROUND bar, scroll it downwards.
V_DrawFixedPatch(roundx*FRACUNIT, ((-32) + (lt_ticker%32))*FRACUNIT, FRACUNIT, V_SNAPTOTOP|V_SNAPTOLEFT, tcroundbar, NULL);
// Draw ROUND text
if (gp)
V_DrawFixedPatch((roundx+10)*FRACUNIT, roundy*FRACUNIT, FRACUNIT, V_SNAPTOTOP|V_SNAPTOLEFT, tcround, NULL);
zonexpos = ttlnumxpos = lvlttlxpos + V_LevelNameWidth(lvlttl);
if (zonttl[0])
zonexpos -= V_LevelNameWidth(zonttl); // SRB2kart
else
zonexpos -= V_LevelNameWidth(M_GetText("Zone"));
// round num background
V_DrawFixedPatch(roundnumx*FRACUNIT, roundnumy*FRACUNIT, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTOLEFT, tccirclebg, NULL);
ttlnumxpos++;
if (lvlttlxpos < 0)
lvlttlxpos = 0;
#ifdef TITLEPATCHES
if (!splitscreen || (splitscreen && stplyr == &players[displayplayers[0]]))
// Scrolling banner, we'll draw 3 of those back to back.
for (i=0; i < 3; i++)
{
zzticker = lt_ticker;
V_DrawMappedPatch(FixedInt(lt_zigzag), (-zzticker) % zigzag->height, V_SNAPTOTOP|V_SNAPTOLEFT, zigzag, colormap);
V_DrawMappedPatch(FixedInt(lt_zigzag), (zigzag->height-zzticker) % zigzag->height, V_SNAPTOTOP|V_SNAPTOLEFT, zigzag, colormap);
V_DrawMappedPatch(FixedInt(lt_zigzag), (-zigzag->height+zzticker) % zztext->height, V_SNAPTOTOP|V_SNAPTOLEFT, zztext, colormap);
V_DrawMappedPatch(FixedInt(lt_zigzag), (zzticker) % zztext->height, V_SNAPTOTOP|V_SNAPTOLEFT, zztext, colormap);
V_DrawFixedPatch((bannerx + bx)*FRACUNIT, (bannery)*FRACUNIT, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTOLEFT, tcbanner, NULL);
bx += tcbanner->width;
}
#endif
if (actnum)
// If possible, draw round number
if (gp && grandprixinfo.roundnum > 0 && grandprixinfo.roundnum < 11) // Check boundaries JUST IN CASE.
V_DrawFixedPatch(roundnumx*FRACUNIT, roundnumy*FRACUNIT, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTOLEFT, tcroundnum[grandprixinfo.roundnum-1], NULL);
// Draw both halves of the egg
V_DrawFixedPatch(eggx1*FRACUNIT, eggy1*FRACUNIT, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTOLEFT, tccircletop, NULL);
V_DrawFixedPatch(eggx2*FRACUNIT, eggy2*FRACUNIT, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTOLEFT, tccirclebottom, NULL);
// Now the level name.
V_DrawTitleCardString((actnum) ? 265 : 280, 60, lvlttl, V_SNAPTORIGHT, true, lt_ticker, TTANIMENDTHRESHOLD);
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE))
V_DrawTitleCardString((actnum) ? 265 : 280, 60+32, strlen(zonttl) ? zonttl : "ZONE", V_SNAPTORIGHT, true, lt_ticker - strlen(lvlttl), TTANIMENDTHRESHOLD);
// the act has a similar graphic animation, but we'll handle it here since it's only like 2 graphics lmfao.
if (actnum && actnum < 10)
{
#ifdef TITLEPATCHES
if (!splitscreen)
// compute delay before the act should appear.
acttimer = lt_ticker - strlen(lvlttl);
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE))
acttimer -= strlen((strlen(zonttl)) ? (zonttl) : ("ZONE"));
actscale = 0;
fakeangle = 0;
if (acttimer >= 0)
{
if (actnum > 9) // slightly offset the act diamond for two-digit act numbers
V_DrawMappedPatch(ttlnumxpos + (V_LevelNameWidth(va("%d", actnum))/4) + ttlscroll, 104 - ttlscroll, 0, actpat, colormap);
else
V_DrawMappedPatch(ttlnumxpos + ttlscroll, 104 - ttlscroll, 0, actpat, colormap);
}
#endif
V_DrawLevelTitle(ttlnumxpos + ttlscroll, 104, 0, va("%d", actnum));
}
V_DrawLevelTitle(lvlttlxpos - ttlscroll, 80, 0, lvlttl);
if (zonttl[0])
V_DrawLevelTitle(zonexpos + ttlscroll, 104, 0, zonttl);
else if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE))
V_DrawLevelTitle(zonexpos + ttlscroll, 104, 0, M_GetText("Zone"));
V_DrawCenteredString(subttlxpos - ttlscroll, 135, 0|V_ALLOWLOWERCASE, subttl);
if (acttimer < TTANIMENDTHRESHOLD) // spin in
{
fakeangle = min(360 + 90, acttimer*41) * ANG1;
actscale = FINESINE(fakeangle>>ANGLETOFINESHIFT);
}
else // spin out
{
// Make letters disappear...
acttimer -= TTANIMENDTHRESHOLD;
fakeangle = max(0, (360+90) - acttimer*41)*ANG1;
actscale = FINESINE(fakeangle>>ANGLETOFINESHIFT);
}
if (actscale)
{
// draw the top:
V_DrawStretchyFixedPatch(286*FRACUNIT, 76*FRACUNIT, abs(actscale), FRACUNIT, V_SNAPTORIGHT|(actscale < 0 ? V_FLIP : 0), tcact, NULL);
V_DrawStretchyFixedPatch(286*FRACUNIT, 123*FRACUNIT, abs(actscale), FRACUNIT, V_SNAPTORIGHT|(actscale < 0 ? V_FLIP : 0), tcactnum[actnum], NULL);
}
}
}
lt_lasttic = lt_ticker;
luahook:
LUAh_TitleCardHUD(stplyr);
}
// Clear defined coordinates, we don't need them anymore
#undef FINAL_ROUNDX
#undef FINAL_EGGY
#undef FINAL_ROUNDY
#undef FINAL_BANNERY
#undef BASE_CHEV1X
#undef BASE_CHEV1Y
#undef BASE_CHEV2X
#undef BASE_CHEV2Y
#undef TTANIMTHRESHOLD
#undef TTANIMSTART
#undef TTANIMENDTHRESHOLD
#undef TTANIMEND
//
// Drawer for G_PreLevelTitleCard.
//
void ST_preLevelTitleCardDrawer(void)
{
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol);
ST_drawWipeTitleCard();
ST_drawTitleCard();
I_OsPolling();
I_UpdateNoBlit();
}
//
// Draw the title card while on a wipe.
// Also used in G_PreLevelTitleCard.
//
void ST_drawWipeTitleCard(void)
{
UINT8 i;
for (i = 0; i <= r_splitscreen; i++)
{
stplyr = &players[displayplayers[i]];
ST_preDrawTitleCard();
ST_drawTitleCard();
}
}
//
// Draw the status bar overlay, customisable: the user chooses which
// kind of information to overlay

View file

@ -64,7 +64,6 @@ void ST_runTitleCard(void);
void ST_drawTitleCard(void);
void ST_preDrawTitleCard(void);
void ST_preLevelTitleCardDrawer(void);
void ST_drawWipeTitleCard(void);
extern tic_t lt_ticker, lt_lasttic;
extern tic_t lt_exitticker, lt_endtime;

View file

@ -1676,6 +1676,149 @@ void V_DrawChatCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed, UI
V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, FRACUNIT/2, flags, fontv[HU_FONT].font[c], colormap);
}
// V_TitleCardStringWidth
// Get the string's width using the titlecard font.
INT32 V_TitleCardStringWidth(const char *str)
{
INT32 xoffs = 0;
const char *ch = str;
char c;
patch_t *pp;
for (;;ch++)
{
if (!*ch)
break;
if (*ch == '\n')
{
xoffs = 0;
continue;
}
c = *ch;
c = toupper(c);
c -= LT_FONTSTART;
// check if character exists, if not, it's a space.
if (c < 0 || c >= LT_FONTSIZE || !tc_font[0][(INT32)c])
{
xoffs += 10;
continue;
}
pp = tc_font[1][(INT32)c];
xoffs += pp->width-5;
}
return xoffs;
}
// V_DrawTitleCardScreen.
// see v_video.h's prototype for more information.
//
void V_DrawTitleCardString(INT32 x, INT32 y, const char *str, INT32 flags, boolean alignright, INT32 timer, INT32 threshold)
{
INT32 xoffs = 0;
INT32 yoffs = 0;
INT32 i = 0;
// per-letter variables
fixed_t scalex;
fixed_t offs;
INT32 let_time;
INT32 flipflag;
angle_t fakeang;
const char *ch = str;
char c;
patch_t *pp;
patch_t *ol;
x -= 2; // Account for patch width...
if (alignright)
x -= V_TitleCardStringWidth(str);
for (;;ch++, i++)
{
scalex = FRACUNIT;
offs = 0;
let_time = timer - i;
flipflag = 0;
if (!*ch)
break;
if (*ch == '\n')
{
xoffs = x;
yoffs += 32;
continue;
}
c = *ch;
c = toupper(c);
c -= LT_FONTSTART;
// check if character exists, if not, it's a space.
if (c < 0 || c >= LT_FONTSIZE || !tc_font[1][(INT32)c])
{
xoffs += 10;
continue;
}
ol = tc_font[0][(INT32)c];
pp = tc_font[1][(INT32)c];
if (timer)
{
// make letters appear
if (!threshold || let_time < threshold)
{
if (let_time <= 0)
return; // No reason to continue drawing, none of the next letters will be drawn either.
// otherwise; scalex must start at 0
// let's have each letter do 4 spins (360*4 + 90 = 1530 "degrees")
fakeang = min(360 + 90, let_time*41) * ANG1;
scalex = FINESINE(fakeang>>ANGLETOFINESHIFT);
}
else if (let_time > threshold)
{
// Make letters disappear...
let_time -= threshold;
fakeang = max(0, (360+90) - let_time*41)*ANG1;
scalex = FINESINE(fakeang>>ANGLETOFINESHIFT);
}
// Because of how our patches are offset, we need to counter the displacement caused by changing the scale with an offset of our own.
offs = ((FRACUNIT-scalex)*pp->width)/2;
}
// And now, we just need to draw the stuff.
flipflag = (scalex < 0) ? V_FLIP : 0;
if (scalex && ol && pp)
{
//CONS_Printf("%d\n", (INT32)c);
V_DrawStretchyFixedPatch((x + xoffs)*FRACUNIT + offs, (y+yoffs)*FRACUNIT, abs(scalex), FRACUNIT, flags|flipflag, ol, NULL);
V_DrawStretchyFixedPatch((x + xoffs)*FRACUNIT + offs, (y+yoffs)*FRACUNIT, abs(scalex), FRACUNIT, flags|flipflag, pp, NULL);
}
xoffs += pp->width -5;
}
}
// Precompile a wordwrapped string to any given width.
// This is a muuuch better method than V_WORDWRAP.
char *V_WordWrap(INT32 x, INT32 w, INT32 option, const char *string)

View file

@ -262,6 +262,16 @@ void V_DrawRightAlignedThinString(INT32 x, INT32 y, INT32 option, const char *st
#define V_DrawThinStringAtFixed( x,y,option,string ) \
V__DrawOneScaleString (x,y,FRACUNIT,option,TINY_FONT,string)
// Draws a titlecard font string.
// timer: when the letters start appearing (leave to 0 to disable)
// threshold: when the letters start disappearing (leave to 0 to disable) (both are INT32 in case you supply negative values...)
// NOTE: This function ignores most conventional string flags (V_RETURN8, V_ALLOWLOWERCASE ...)
// NOTE: This font only works with uppercase letters.
void V_DrawTitleCardString(INT32 x, INT32 y, const char *str, INT32 flags, boolean alignright, INT32 timer, INT32 threshold);
// returns thr width of a string drawn using the above function.
INT32 V_TitleCardStringWidth(const char *str);
// Draw tall nums, used for menu, HUD, intermission
void V_DrawTallNum(INT32 x, INT32 y, INT32 flags, INT32 num);
void V_DrawPaddedTallNum(INT32 x, INT32 y, INT32 flags, INT32 num, INT32 digits);

View file

@ -47,10 +47,6 @@ static boolean Z_calloc = false;
#define ZONEID 0xa441d13d
#ifdef ZDEBUG
//#define ZDEBUG2
#endif
struct memblock_s;
typedef struct
@ -76,10 +72,8 @@ typedef struct memblock_s
size_t size; // including the header and blocks
size_t realsize; // size of real data only
#ifdef ZDEBUG
const char *ownerfile;
INT32 ownerline;
#endif
struct memblock_s *next, *prev;
} ATTRPACK memblock_t;
@ -91,9 +85,7 @@ static memblock_t head;
// Function prototypes
//
static void Command_Memfree_f(void);
#ifdef ZDEBUG
static void Command_Memdump_f(void);
#endif
// --------------------------
// Zone memory initialisation
@ -117,10 +109,7 @@ void Z_Init(void)
// Note: This allocates memory. Watch out.
COM_AddCommand("memfree", Command_Memfree_f);
#ifdef ZDEBUG
COM_AddCommand("memdump", Command_Memdump_f);
#endif
}
@ -137,12 +126,8 @@ void Z_Init(void)
* \return A pointer to the memblock_t for the given memory.
* \sa Z_Free, Z_ReallocAlign
*/
#ifdef ZDEBUG
#define Ptr2Memblock(s, f) Ptr2Memblock2(s, f, __FILE__, __LINE__)
static memblock_t *Ptr2Memblock2(void *ptr, const char* func, const char *file, INT32 line)
#else
static memblock_t *Ptr2Memblock(void *ptr, const char* func)
#endif
{
memhdr_t *hdr;
memblock_t *block;
@ -150,8 +135,8 @@ static memblock_t *Ptr2Memblock(void *ptr, const char* func)
if (ptr == NULL)
return NULL;
#ifdef ZDEBUG2
CONS_Printf("%s %s:%d\n", func, file, line);
#ifdef ZDEBUG
CONS_Debug(DBG_MEMORY, "%s %s:%d\n", func, file, line);
#endif
hdr = (memhdr_t *)((UINT8 *)ptr - sizeof *hdr);
@ -163,20 +148,12 @@ static memblock_t *Ptr2Memblock(void *ptr, const char* func)
#ifdef VALGRIND_MEMPOOL_EXISTS
if (!VALGRIND_MEMPOOL_EXISTS(hdr->block))
{
#ifdef ZDEBUG
I_Error("%s: bad memblock from %s:%d", func, file, line);
#else
I_Error("%s: bad memblock", func);
#endif
}
#endif
if (hdr->id != ZONEID)
{
#ifdef ZDEBUG
I_Error("%s: wrong id from %s:%d", func, file, line);
#else
I_Error("%s: wrong id", func);
#endif
}
block = hdr->block;
#ifdef VALGRIND_MAKE_MEM_NOACCESS
@ -192,31 +169,24 @@ static memblock_t *Ptr2Memblock(void *ptr, const char* func)
* assumed to have been allocated with Z_Malloc/Z_Calloc.
* \sa Z_FreeTags
*/
#ifdef ZDEBUG
void Z_Free2(void *ptr, const char *file, INT32 line)
#else
void Z_Free(void *ptr)
#endif
{
memblock_t *block;
if (ptr == NULL)
return;
#ifdef ZDEBUG2
/*
// Sal: There's a print exactly like this just below?
#ifdef ZDEBUG
CONS_Debug(DBG_MEMORY, "Z_Free %s:%d\n", file, line);
#endif
*/
#ifdef ZDEBUG
block = Ptr2Memblock2(ptr, "Z_Free", file, line);
#else
block = Ptr2Memblock(ptr, "Z_Free");
#endif
#ifdef ZDEBUG
// Write every Z_Free call to a debug file.
CONS_Debug(DBG_MEMORY, "Z_Free at %s:%d\n", file, line);
#endif
// anything that isn't by lua gets passed to lua just in case.
if (block->tag != PU_LUA)
@ -280,12 +250,8 @@ static void *xm(size_t size)
* \note You can pass Z_Malloc() a NULL user if the tag is less than PU_PURGELEVEL.
* \sa Z_CallocAlign, Z_ReallocAlign
*/
#ifdef ZDEBUG
void *Z_Malloc2(size_t size, INT32 tag, void *user, INT32 alignbits,
const char *file, INT32 line)
#else
void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits)
#endif
{
size_t extrabytes = (1<<alignbits) - 1;
size_t padsize = 0;
@ -295,7 +261,7 @@ void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits)
void *given;
size_t blocksize = extrabytes + sizeof *hdr + size;
#ifdef ZDEBUG2
#ifdef ZDEBUG
CONS_Debug(DBG_MEMORY, "Z_Malloc %s:%d\n", file, line);
#endif
@ -329,10 +295,8 @@ void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits)
block->hdr = hdr;
block->tag = tag;
block->user = NULL;
#ifdef ZDEBUG
block->ownerline = line;
block->ownerfile = file;
#endif
block->size = blocksize;
block->realsize = size;
@ -375,20 +339,12 @@ void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits)
* \note You can pass Z_Calloc() a NULL user if the tag is less than PU_PURGELEVEL.
* \sa Z_MallocAlign, Z_ReallocAlign
*/
#ifdef ZDEBUG
void *Z_Calloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line)
#else
void *Z_CallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits)
#endif
{
#ifdef VALGRIND_MEMPOOL_ALLOC
Z_calloc = true;
#endif
#ifdef ZDEBUG
return memset(Z_Malloc2 (size, tag, user, alignbits, file, line), 0, size);
#else
return memset(Z_MallocAlign(size, tag, user, alignbits ), 0, size);
#endif
}
/** The Z_ReallocAlign function.
@ -407,17 +363,13 @@ void *Z_CallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits)
* \note You can pass Z_Realloc() a NULL user if the tag is less than PU_PURGELEVEL.
* \sa Z_MallocAlign, Z_CallocAlign
*/
#ifdef ZDEBUG
void *Z_Realloc2(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line)
#else
void *Z_ReallocAlign(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits)
#endif
{
void *rez;
memblock_t *block;
size_t copysize;
#ifdef ZDEBUG2
#ifdef ZDEBUG
CONS_Debug(DBG_MEMORY, "Z_Realloc %s:%d\n", file, line);
#endif
@ -429,29 +381,17 @@ void *Z_ReallocAlign(void *ptr, size_t size, INT32 tag, void *user, INT32 alignb
if (!ptr)
{
#ifdef ZDEBUG
return Z_Calloc2(size, tag, user, alignbits, file , line);
#else
return Z_CallocAlign(size, tag, user, alignbits);
#endif
}
#ifdef ZDEBUG
block = Ptr2Memblock2(ptr, "Z_Realloc", file, line);
#else
block = Ptr2Memblock(ptr, "Z_Realloc");
#endif
if (block == NULL)
return NULL;
#ifdef ZDEBUG
// Write every Z_Realloc call to a debug file.
DEBFILE(va("Z_Realloc at %s:%d\n", file, line));
rez = Z_Malloc2(size, tag, user, alignbits, file, line);
#else
rez = Z_MallocAlign(size, tag, user, alignbits);
#endif
if (size < block->realsize)
copysize = size;
@ -460,11 +400,7 @@ void *Z_ReallocAlign(void *ptr, size_t size, INT32 tag, void *user, INT32 alignb
M_Memcpy(rez, ptr, copysize);
#ifdef ZDEBUG
Z_Free2(ptr, file, line);
#else
Z_Free(ptr);
#endif
// Need to set the user in case the old block had the same one, in
// which case the Z_Free will just have NULLed it out.
@ -569,7 +505,7 @@ void Z_CheckHeap(INT32 i)
blocknumon++;
hdr = block->hdr;
given = (UINT8 *)hdr + sizeof *hdr;
#ifdef ZDEBUG2
#ifdef ZDEBUG
CONS_Debug(DBG_MEMORY, "block %u owned by %s:%d\n",
blocknumon, block->ownerfile, block->ownerline);
#endif
@ -577,51 +513,35 @@ void Z_CheckHeap(INT32 i)
if (!VALGRIND_MEMPOOL_EXISTS(block))
{
I_Error("Z_CheckHeap %d: block %u"
#ifdef ZDEBUG
"(owned by %s:%d)"
#endif
" should not exist", i, blocknumon
#ifdef ZDEBUG
, block->ownerfile, block->ownerline
#endif
);
" should not exist", i, blocknumon,
block->ownerfile, block->ownerline
);
}
#endif
if (block->user != NULL && *(block->user) != given)
{
I_Error("Z_CheckHeap %d: block %u"
#ifdef ZDEBUG
"(owned by %s:%d)"
#endif
" doesn't have a proper user", i, blocknumon
#ifdef ZDEBUG
, block->ownerfile, block->ownerline
#endif
);
" doesn't have a proper user", i, blocknumon,
block->ownerfile, block->ownerline
);
}
if (block->next->prev != block)
{
I_Error("Z_CheckHeap %d: block %u"
#ifdef ZDEBUG
"(owned by %s:%d)"
#endif
" lacks proper backlink", i, blocknumon
#ifdef ZDEBUG
, block->ownerfile, block->ownerline
#endif
);
" lacks proper backlink", i, blocknumon,
block->ownerfile, block->ownerline
);
}
if (block->prev->next != block)
{
I_Error("Z_CheckHeap %d: block %u"
#ifdef ZDEBUG
"(owned by %s:%d)"
#endif
" lacks proper forward link", i, blocknumon
#ifdef ZDEBUG
, block->ownerfile, block->ownerline
#endif
);
" lacks proper forward link", i, blocknumon,
block->ownerfile, block->ownerline
);
}
#ifdef VALGRIND_MAKE_MEM_DEFINED
VALGRIND_MAKE_MEM_DEFINED(hdr, sizeof *hdr);
@ -629,27 +549,19 @@ void Z_CheckHeap(INT32 i)
if (hdr->block != block)
{
I_Error("Z_CheckHeap %d: block %u"
#ifdef ZDEBUG
"(owned by %s:%d)"
#endif
" doesn't have linkback from allocated memory",
i, blocknumon
#ifdef ZDEBUG
, block->ownerfile, block->ownerline
#endif
);
i, blocknumon,
block->ownerfile, block->ownerline
);
}
if (hdr->id != ZONEID)
{
I_Error("Z_CheckHeap %d: block %u"
#ifdef ZDEBUG
"(owned by %s:%d)"
#endif
" have the wrong ID", i, blocknumon
#ifdef ZDEBUG
, block->ownerfile, block->ownerline
#endif
);
" have the wrong ID", i, blocknumon,
block->ownerfile, block->ownerline
);
}
#ifdef VALGRIND_MAKE_MEM_NOACCESS
VALGRIND_MAKE_MEM_NOACCESS(hdr, sizeof *hdr);
@ -828,11 +740,9 @@ static void Command_Memfree_f(void)
CONS_Printf(M_GetText("Available physical memory: %7u KB\n"), freebytes>>10);
}
#ifdef ZDEBUG
/** The function called by the "memdump" console command.
* Prints zone memory debugging information (i.e. tag, size, location in code allocated).
* Can be all memory allocated in game, or between a set of tags (if -min/-max args used).
* This command is available only if ZDEBUG is enabled.
*/
static void Command_Memdump_f(void)
{
@ -853,7 +763,6 @@ static void Command_Memdump_f(void)
CONS_Printf("[%3d] %s (%s) bytes @ %s:%d\n", block->tag, sizeu1(block->size), sizeu2(block->realsize), filename ? filename + 1 : block->ownerfile, block->ownerline);
}
}
#endif
/** Creates a copy of a string.
*

View file

@ -79,12 +79,8 @@ void Z_Init(void);
//
// Zone memory allocation
//
// enable ZDEBUG to get the file + line the functions were called from
// for ZZ_Alloc, see doomdef.h
//
// Z_Free and alloc with alignment
#ifdef ZDEBUG
#define Z_Free(p) Z_Free2(p, __FILE__, __LINE__)
#define Z_MallocAlign(s,t,u,a) Z_Malloc2(s, t, u, a, __FILE__, __LINE__)
#define Z_CallocAlign(s,t,u,a) Z_Calloc2(s, t, u, a, __FILE__, __LINE__)
@ -93,12 +89,6 @@ void Z_Free2(void *ptr, const char *file, INT32 line);
void *Z_Malloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) FUNCALLOC(1);
void *Z_Calloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) FUNCALLOC(1);
void *Z_Realloc2(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) FUNCALLOC(2);
#else
void Z_Free(void *ptr);
void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) FUNCALLOC(1);
void *Z_CallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) FUNCALLOC(1);
void *Z_ReallocAlign(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits) FUNCALLOC(2);
#endif
// Alloc with no alignment
#define Z_Malloc(s,t,u) Z_MallocAlign(s, t, u, 0)
@ -106,7 +96,7 @@ void *Z_ReallocAlign(void *ptr, size_t size, INT32 tag, void *user, INT32 alignb
#define Z_Realloc(p,s,t,u) Z_ReallocAlign(p, s, t, u, 0)
// Free all memory by tag
// these don't give line numbers for ZDEBUG currently though
// these don't give line numbers currently though
// (perhaps this should be changed in future?)
#define Z_FreeTag(tagnum) Z_FreeTags(tagnum, tagnum)
void Z_FreeTags(INT32 lowtag, INT32 hightag);