From 29e11a03782edd17634fdaf8a09b209c0a13d85d Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Thu, 22 Apr 2021 15:11:15 +0200 Subject: [PATCH 01/26] changes to the delay, boost when doing upwards trick --- src/d_player.h | 6 ++++++ src/k_kart.c | 39 +++++++++++++++++++++++++++++++++++---- src/p_mobj.c | 2 +- src/p_saveg.c | 8 ++++++++ src/p_user.c | 2 +- 5 files changed, 51 insertions(+), 6 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index afa232991..8f1481499 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -241,6 +241,7 @@ typedef enum // CONSTANTS FOR TRICK PANELS #define TRICKMOMZRAMP (30) #define TRICKLAG (9) +#define TRICKDELAY (TICRATE/2) #define TUMBLEBOUNCES 3 @@ -450,9 +451,14 @@ typedef struct player_s UINT8 jawztargetdelay; // (0 to 5) - Delay for Jawz target switching, to make it less twitchy UINT8 trickpanel; // Trick panel state + tic_t tricktime; // Increases while you're tricking. You can't input any trick until it's reached a certain threshold fixed_t trickmomx; fixed_t trickmomy; fixed_t trickmomz; + fixed_t trickboostpower; // Save the rough speed multiplier. Used for upwards tricks. + tic_t trickboostdecay; // used to know how long you've waited + tic_t trickboost; // Trick boost. This one is weird and has variable speed. Dear god. + UINT32 roundscore; // battle score this round UINT8 emeralds; diff --git a/src/k_kart.c b/src/k_kart.c index dedf9dddc..9a5bd8b05 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2546,6 +2546,11 @@ static void K_GetKartBoostPower(player_t *player) } } + if (player->trickboost) // Trick pannel up-boost + { + ADDBOOST(player->trickboostpower, 5*FRACUNIT, 0); // % speed, 500% accel, 0% handling + } + if (player->ringboost) // Ring Boost { ADDBOOST(FRACUNIT/5, 4*FRACUNIT, 0); // + 20% top speed, + 400% acceleration, +0% handling @@ -4868,7 +4873,10 @@ void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound) thrust = FixedMul(thrust, 9*FRACUNIT/8); } - mo->player->trickmomx = mo->player->trickmomy = mo->player->trickmomz = 0; // Reset post-hitlag momentums. + mo->player->trickmomx = mo->player->trickmomy = mo->player->trickmomz = mo->player->tricktime = 0; // Reset post-hitlag momentums and timer + // Setup the boost for potential upwards trick, at worse, make it your regular max speed. + mo->player->trickboostpower = max(FixedDiv(mo->player->speed, K_GetKartSpeed(mo->player, false)) - FRACUNIT, 0); + //CONS_Printf("Got boost: %d%\n", mo->player->trickboostpower*100 / FRACUNIT); } mo->momz = FixedMul(thrust, vscale); @@ -6284,7 +6292,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) // Speed lines if (player->sneakertimer || player->ringboost || player->driftboost || player->startboost - || player->eggmanexplode) + || player->eggmanexplode || player->trickboost) { if (player->invincibilitytimer) K_SpawnInvincibilitySpeedLines(player->mo); @@ -6525,6 +6533,9 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) } } + if (player->trickboost) + player->trickboost--; + if (player->flamedash) player->flamedash--; @@ -8787,6 +8798,9 @@ void K_MoveKartPlayer(player_t *player, boolean onground) fixed_t basespeed = P_AproxDistance(player->mo->momx, player->mo->momy); // at WORSE, keep your normal speed when tricking. fixed_t speed = FixedMul(speedmult, P_AproxDistance(player->mo->momx, player->mo->momy)); + if (!cmd->turning && !player->throwdir) // increment this counter while your inputs are neutral + player->tricktime++; + // debug shit //CONS_Printf("%d\n", player->mo->momz / mapobjectscale); if (momz < -10*FRACUNIT) // :youfuckedup: @@ -8858,6 +8872,12 @@ void K_MoveKartPlayer(player_t *player, boolean onground) relative = false; } + // Calculate speed boost decay: + // Base speed boost duration is 35 tics. + // At most, lose 3/4th of your boost. + player->trickboostdecay = min(TICRATE*3/4, abs(momz/FRACUNIT)); + //CONS_Printf("decay: %d\n", player->trickboostdecay); + P_SetObjectMomZ(player->mo, 48*FRACUNIT, relative); player->trickmomx = player->mo->momx; @@ -8866,7 +8886,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) P_InstaThrust(player->mo, 0, 0); // Sike, you have no speed :) player->mo->momz = 0; - player->trickpanel = 3; + player->trickpanel = 4; player->mo->hitlag = TRICKLAG; } } @@ -8882,8 +8902,19 @@ void K_MoveKartPlayer(player_t *player, boolean onground) } + else if (player->trickpanel == 4 && P_IsObjectOnGround(player->mo)) // Upwards trick landed! + { + //CONS_Printf("apply boost\n"); + S_StartSound(player->mo, sfx_s23c); + K_SpawnDashDustRelease(player); + player->trickboost = TICRATE - player->trickboostdecay; + + player->trickpanel = player->trickboostdecay = 0; + } + // Wait until we let go off the control stick to remove the delay - if ((player->pflags & PF_TRICKDELAY) && !player->throwdir && !cmd->turning) + // buttons must be neutral after the initial trick delay. This prevents weirdness where slight nudges after blast off would send you flying. + if ((player->pflags & PF_TRICKDELAY) && !player->throwdir && !cmd->turning && (player->tricktime >= TRICKDELAY)) { player->pflags &= ~PF_TRICKDELAY; } diff --git a/src/p_mobj.c b/src/p_mobj.c index f3711f819..8cccc7963 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1109,7 +1109,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo) gravityadd = (4*gravityadd)/3; } - if (mo->player->trickpanel == 2 || mo->player->trickpanel == 3) + if (mo->player->trickpanel >= 2) { gravityadd = (5*gravityadd)/2; } diff --git a/src/p_saveg.c b/src/p_saveg.c index 35f68be29..9f2d182fb 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -305,9 +305,13 @@ static void P_NetArchivePlayers(void) WRITEUINT8(save_p, players[i].jawztargetdelay); WRITEUINT8(save_p, players[i].trickpanel); + WRITEUINT32(save_p, players[i].tricktime); WRITEUINT32(save_p, players[i].trickmomx); WRITEUINT32(save_p, players[i].trickmomy); WRITEUINT32(save_p, players[i].trickmomz); + WRITEUINT32(save_p, players[i].trickboostpower); + WRITEUINT32(save_p, players[i].trickboostdecay); + WRITEUINT32(save_p, players[i].trickboost); WRITEUINT32(save_p, players[i].roundscore); WRITEUINT8(save_p, players[i].emeralds); @@ -557,9 +561,13 @@ static void P_NetUnArchivePlayers(void) players[i].jawztargetdelay = READUINT8(save_p); players[i].trickpanel = READUINT8(save_p); + players[i].tricktime = (tic_t)READUINT32(save_p); players[i].trickmomx = READUINT32(save_p); players[i].trickmomy = READUINT32(save_p); players[i].trickmomz = READUINT32(save_p); + players[i].trickboostpower = READUINT32(save_p); + players[i].trickboostdecay = (tic_t)READUINT32(save_p); + players[i].trickboost = (tic_t)READUINT32(save_p); players[i].roundscore = READUINT32(save_p); players[i].emeralds = READUINT8(save_p); diff --git a/src/p_user.c b/src/p_user.c index 3cd0bba5c..18afb0337 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2030,7 +2030,7 @@ void P_MovePlayer(player_t *player) { player->drawangle += ANGLE_22h; } - else if (player->trickpanel == 3) + else if (player->trickpanel >= 3) { player->drawangle -= ANGLE_22h; } From a25b79885d805721946e9ec29f371c08638c4b08 Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Thu, 22 Apr 2021 19:33:01 +0200 Subject: [PATCH 02/26] 1/4s delay w/o input checks instead of 1/2 w/ input checks --- src/d_player.h | 2 +- src/k_kart.c | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 8f1481499..84165192b 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -241,7 +241,7 @@ typedef enum // CONSTANTS FOR TRICK PANELS #define TRICKMOMZRAMP (30) #define TRICKLAG (9) -#define TRICKDELAY (TICRATE/2) +#define TRICKDELAY (TICRATE/4) #define TUMBLEBOUNCES 3 diff --git a/src/k_kart.c b/src/k_kart.c index 9a5bd8b05..5848f5b09 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -8798,8 +8798,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) fixed_t basespeed = P_AproxDistance(player->mo->momx, player->mo->momy); // at WORSE, keep your normal speed when tricking. fixed_t speed = FixedMul(speedmult, P_AproxDistance(player->mo->momx, player->mo->momy)); - if (!cmd->turning && !player->throwdir) // increment this counter while your inputs are neutral - player->tricktime++; + player->tricktime++; // debug shit //CONS_Printf("%d\n", player->mo->momz / mapobjectscale); From 8b50b0ddd76b0500bae355a778177d24e634806f Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Thu, 22 Apr 2021 21:26:00 +0200 Subject: [PATCH 03/26] boost is now 125%, allow turning after upwards trick --- src/k_kart.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 5848f5b09..c714a68c2 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4874,8 +4874,8 @@ void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound) } mo->player->trickmomx = mo->player->trickmomy = mo->player->trickmomz = mo->player->tricktime = 0; // Reset post-hitlag momentums and timer - // Setup the boost for potential upwards trick, at worse, make it your regular max speed. - mo->player->trickboostpower = max(FixedDiv(mo->player->speed, K_GetKartSpeed(mo->player, false)) - FRACUNIT, 0); + // Setup the boost for potential upwards trick, at worse, make it your regular max speed. (boost = curr speed*1.25) + mo->player->trickboostpower = max(FixedDiv(mo->player->speed, K_GetKartSpeed(mo->player, false)) - FRACUNIT, 0)*125/100; //CONS_Printf("Got boost: %d%\n", mo->player->trickboostpower*100 / FRACUNIT); } @@ -7279,9 +7279,9 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue) return 0; } - if (player->trickpanel != 0) + if (player->trickpanel != 0 && player->trickpanel < 4) { - // No turning during trick panel + // No turning during trick panel unless you did the upwards trick (4) return 0; } From d10f4ea1281059ca4b549386babfe9316c979ae2 Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Fri, 23 Apr 2021 00:14:36 +0200 Subject: [PATCH 04/26] More suitable data types + lua push --- src/d_player.h | 6 +++--- src/k_kart.c | 6 ++++-- src/lua_playerlib.c | 16 ++++++++++++++++ src/p_saveg.c | 12 ++++++------ 4 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 84165192b..445c1148d 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -451,13 +451,13 @@ typedef struct player_s UINT8 jawztargetdelay; // (0 to 5) - Delay for Jawz target switching, to make it less twitchy UINT8 trickpanel; // Trick panel state - tic_t tricktime; // Increases while you're tricking. You can't input any trick until it's reached a certain threshold + UINT8 tricktime; // Increases while you're tricking. You can't input any trick until it's reached a certain threshold fixed_t trickmomx; fixed_t trickmomy; fixed_t trickmomz; fixed_t trickboostpower; // Save the rough speed multiplier. Used for upwards tricks. - tic_t trickboostdecay; // used to know how long you've waited - tic_t trickboost; // Trick boost. This one is weird and has variable speed. Dear god. + UINT8 trickboostdecay; // used to know how long you've waited + UINT8 trickboost; // Trick boost. This one is weird and has variable speed. Dear god. UINT32 roundscore; // battle score this round diff --git a/src/k_kart.c b/src/k_kart.c index c714a68c2..915d3cd32 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -8797,8 +8797,10 @@ void K_MoveKartPlayer(player_t *player, boolean onground) fixed_t speedmult = max(0, FRACUNIT - abs(momz)/TRICKMOMZRAMP); // TRICKMOMZRAMP momz is minimum speed (Should be 20) fixed_t basespeed = P_AproxDistance(player->mo->momx, player->mo->momy); // at WORSE, keep your normal speed when tricking. fixed_t speed = FixedMul(speedmult, P_AproxDistance(player->mo->momx, player->mo->momy)); - - player->tricktime++; + + // We'll never need to go above that. + if (player->tricktime <= TRICKDELAY) + player->tricktime++; // debug shit //CONS_Printf("%d\n", player->mo->momz / mapobjectscale); diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index a76eb1990..a9e193543 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -354,12 +354,20 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->glanceDir); else if (fastcmp(field,"trickpanel")) lua_pushinteger(L, plr->trickpanel); + else if (fastcmp(field,"tricktime")) + lua_pushinteger(L, plr->tricktime); else if (fastcmp(field,"trickmomx")) lua_pushfixed(L, plr->trickmomx); else if (fastcmp(field,"trickmomy")) lua_pushfixed(L, plr->trickmomy); else if (fastcmp(field,"trickmomz")) lua_pushfixed(L, plr->trickmomz); + else if (fastcmp(field,"trickboostpower")) + lua_pushfixed(L, plr->trickboostpower); + else if (fastcmp(field,"trickboostdecay")) + lua_pushinteger(L, plr->trickboostdecay); + else if (fastcmp(field,"trickboost")) + lua_pushinteger(L, plr->trickboost); else if (fastcmp(field,"roundscore")) plr->roundscore = luaL_checkinteger(L, 3); else if (fastcmp(field,"emeralds")) @@ -697,12 +705,20 @@ static int player_set(lua_State *L) plr->glanceDir = luaL_checkinteger(L, 3); else if (fastcmp(field,"trickpanel")) plr->trickpanel = luaL_checkinteger(L, 3); + else if (fastcmp(field,"tricktime")) + plr->tricktime = luaL_checkinteger(L, 3); else if (fastcmp(field,"trickmomx")) plr->trickmomx = luaL_checkfixed(L, 3); else if (fastcmp(field,"trickmomy")) plr->trickmomy = luaL_checkfixed(L, 3); else if (fastcmp(field,"trickmomz")) plr->trickmomz = luaL_checkfixed(L, 3); + else if (fastcmp(field,"trickboostpower")) + plr->trickboostpower = luaL_checkfixed(L, 3); + else if (fastcmp(field,"trickboostdecay")) + plr->trickboostdecay = luaL_checkinteger(L, 3); + else if (fastcmp(field,"trickboost")) + plr->trickboost = luaL_checkinteger(L, 3); else if (fastcmp(field,"roundscore")) lua_pushinteger(L, plr->roundscore); else if (fastcmp(field,"emeralds")) diff --git a/src/p_saveg.c b/src/p_saveg.c index 9f2d182fb..e8e992fcc 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -305,13 +305,13 @@ static void P_NetArchivePlayers(void) WRITEUINT8(save_p, players[i].jawztargetdelay); WRITEUINT8(save_p, players[i].trickpanel); - WRITEUINT32(save_p, players[i].tricktime); + WRITEUINT8(save_p, players[i].tricktime); WRITEUINT32(save_p, players[i].trickmomx); WRITEUINT32(save_p, players[i].trickmomy); WRITEUINT32(save_p, players[i].trickmomz); WRITEUINT32(save_p, players[i].trickboostpower); - WRITEUINT32(save_p, players[i].trickboostdecay); - WRITEUINT32(save_p, players[i].trickboost); + WRITEUINT8(save_p, players[i].trickboostdecay); + WRITEUINT8(save_p, players[i].trickboost); WRITEUINT32(save_p, players[i].roundscore); WRITEUINT8(save_p, players[i].emeralds); @@ -561,13 +561,13 @@ static void P_NetUnArchivePlayers(void) players[i].jawztargetdelay = READUINT8(save_p); players[i].trickpanel = READUINT8(save_p); - players[i].tricktime = (tic_t)READUINT32(save_p); + players[i].tricktime = READUINT8(save_p); players[i].trickmomx = READUINT32(save_p); players[i].trickmomy = READUINT32(save_p); players[i].trickmomz = READUINT32(save_p); players[i].trickboostpower = READUINT32(save_p); - players[i].trickboostdecay = (tic_t)READUINT32(save_p); - players[i].trickboost = (tic_t)READUINT32(save_p); + players[i].trickboostdecay = READUINT8(save_p); + players[i].trickboost = READUINT8(save_p); players[i].roundscore = READUINT32(save_p); players[i].emeralds = READUINT8(save_p); From f935b3b6f496f480253a4cb18940ebcbaa1c0093 Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Fri, 23 Apr 2021 02:10:20 +0200 Subject: [PATCH 05/26] wip: starting on visuals --- src/k_kart.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/src/k_kart.c b/src/k_kart.c index 915d3cd32..593d46409 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -8135,6 +8135,53 @@ void K_AdjustPlayerFriction(player_t *player) } } +// +// K_trickPanelTimingVisual +// Spawns the timing visual for trick panels depending on the given player's momz. +// + +#define RADIUSSCALING 6 +#define MINRADIUS 24 + +static void K_trickPanelTimingVisual(player_t *player, fixed_t momz) +{ + + fixed_t pos, tx, ty, tz; + mobj_t *flame; + + angle_t hang = R_PointToAngle(player->mo->x, player->mo->y) + ANG1*90; // horizontal angle + angle_t vang = -leveltime*ANG1*12; // vertical angle... arbitrary rotation speed for now. + fixed_t dist = FixedMul(max(MINRADIUS<mo->scale); // distance. + + UINT8 i; + + //CONS_Printf("a\n"); + + // Do you like trig? cool, me neither. + for (i=0; i < 2; i++) + { + //CONS_Printf("%d\n", i); + pos = FixedMul(dist, FINESINE(vang>>ANGLETOFINESHIFT)); + tx = player->mo->x + FixedMul(pos, FINECOSINE(hang>>ANGLETOFINESHIFT)); + ty = player->mo->y + FixedMul(pos, FINESINE(hang>>ANGLETOFINESHIFT)); + tz = player->mo->z + FixedMul(dist, FINECOSINE(vang>>ANGLETOFINESHIFT)); + + // All coordinates set, spawn our fire, now. + flame = P_SpawnMobj(tx, ty, tz, MT_THOK); // @TODO: Make this into its own object. Duh. + flame->frame = 0; + flame->tics = 2; + + // make sure this is only drawn for our local player + // @TODO + + vang += FixedAngle(180<mo->momx, player->mo->momy); // at WORSE, keep your normal speed when tricking. fixed_t speed = FixedMul(speedmult, P_AproxDistance(player->mo->momx, player->mo->momy)); - + + K_trickPanelTimingVisual(player, abs(momz)); + + // streaks: + if (momz*P_MobjFlip(player->mo) > 0) // only spawn those while you're going upwards relative to your current gravity + { + // these are all admittedly arbitrary numbers... + INT32 n; + INT32 maxlines = max(1, (momz/FRACUNIT)/8); + INT32 frequency = max(1, 5-(momz/FRACUNIT)/4); + fixed_t sx, sy, sz; + mobj_t *spdl; + + if (!(leveltime % frequency)) + { + for (n=0; n < maxlines; n++) + { + sx = player->mo->x + P_RandomRange(-24, 24)*player->mo->scale; + sy = player->mo->y + P_RandomRange(-24, 24)*player->mo->scale; + sz = player->mo->z + P_RandomRange(0, 48)*player->mo->scale; + + spdl = P_SpawnMobj(sx, sy, sz, MT_FASTLINE); + P_SetTarget(&spdl->target, player->mo); + spdl->angle = R_PointToAngle2(spdl->x, spdl->y, player->mo->x, player->mo->y); + spdl->rollangle = -ANG1*90*P_MobjFlip(player->mo); // angle them downwards relative to the player's gravity... + spdl->spriteyscale = player->trickboostpower+FRACUNIT; + } + + } + + } + // We'll never need to go above that. if (player->tricktime <= TRICKDELAY) player->tricktime++; From a27b825d3c078260d3f7826dcab53cc761519083 Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Fri, 23 Apr 2021 12:56:46 +0200 Subject: [PATCH 06/26] horiz. lines keep momentum, slightly better visuals --- src/k_kart.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 593d46409..3f1cdebb9 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -8168,11 +8168,27 @@ static void K_trickPanelTimingVisual(player_t *player, fixed_t momz) // All coordinates set, spawn our fire, now. flame = P_SpawnMobj(tx, ty, tz, MT_THOK); // @TODO: Make this into its own object. Duh. - flame->frame = 0; + + // PLACEHOLDER VISUALS + // @TODO: SPRITES + flame->sprite = SPR_FLAM; + flame->frame = ((leveltime%16) /2)|FF_FULLBRIGHT; flame->tics = 2; + flame->rollangle = vang + ANG1*90; // make sure this is only drawn for our local player - // @TODO + flame->renderflags &= ~K_GetPlayerDontDrawFlag(player); + + // second flame for visuals... + flame = P_SpawnMobj(tx, ty, tz, MT_THOK); // @TODO: Make this into its own object. Duh. + + flame->sprite = SPR_FLAM; + flame->frame = ((leveltime%16) /2)|FF_FULLBRIGHT|FF_TRANS60; + flame->tics = 10; + flame->rollangle = vang + ANG1*90; + + // make sure this is only drawn for our local player + flame->renderflags &= ~K_GetPlayerDontDrawFlag(player); vang += FixedAngle(180<angle = R_PointToAngle2(spdl->x, spdl->y, player->mo->x, player->mo->y); spdl->rollangle = -ANG1*90*P_MobjFlip(player->mo); // angle them downwards relative to the player's gravity... spdl->spriteyscale = player->trickboostpower+FRACUNIT; + spdl->momx = player->mo->momx; + spdl->momy = player->mo->momy; } } From 8958ebd293ddb754483aa47ac25d69662b783bf3 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 23 Apr 2021 17:38:38 -0400 Subject: [PATCH 07/26] Sound refactor - Fix splitscreen volume being too low after james volume fix - Use loops instead of horrid code duplication Unfortunately seems to break sounds in menus and I dunno what to look at :pensive: --- src/s_sound.c | 668 +++++++++++++++----------------------------------- 1 file changed, 201 insertions(+), 467 deletions(-) diff --git a/src/s_sound.c b/src/s_sound.c index 3c7957624..8979d1fc9 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -35,7 +35,7 @@ // 3D Sound Interface #include "hardware/hw3sound.h" #else -static INT32 S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *vol, INT32 *sep, INT32 *pitch, sfxinfo_t *sfxinfo); +static boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *vol, INT32 *sep, INT32 *pitch, sfxinfo_t *sfxinfo); #endif CV_PossibleValue_t soundvolume_cons_t[] = {{0, "MIN"}, {MAX_VOLUME, "MAX"}, {0, NULL}}; @@ -196,7 +196,6 @@ static INT32 S_getChannel(const void *origin, sfxinfo_t *sfxinfo) else if (sfxinfo == channels[cnum].sfxinfo && (sfxinfo->pitch & SF_NOMULTIPLESOUND)) { return -1; - break; } else if (sfxinfo == channels[cnum].sfxinfo && sfxinfo->singularity == true) { @@ -501,24 +500,37 @@ void S_StartCaption(sfxenum_t sfx_id, INT32 cnum, UINT16 lifespan) closedcaptions[set].b = 2; // bob } +static INT32 S_ScaleVolumeWithSplitscreen(INT32 volume) +{ + fixed_t root = INT32_MAX; + + if (r_splitscreen == 0) + { + return volume; + } + + root = FixedSqrt((r_splitscreen + 1) * (FRACUNIT/3)); + + return FixedDiv( + volume * FRACUNIT, + root + ) / FRACUNIT; +} + void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) { - const INT32 initial_volume = volume; - INT32 sep, pitch, priority, cnum; - const sfxenum_t actual_id = sfx_id; - sfxinfo_t *sfx; - const boolean reverse = (stereoreverse.value ^ encoremode); const mobj_t *origin = (const mobj_t *)origin_p; + const sfxenum_t actual_id = sfx_id; + const boolean reverse = (stereoreverse.value ^ encoremode); + const INT32 initial_volume = (origin ? S_ScaleVolumeWithSplitscreen(volume) : volume); - listener_t listener = {0,0,0,0}; - listener_t listener2 = {0,0,0,0}; - listener_t listener3 = {0,0,0,0}; - listener_t listener4 = {0,0,0,0}; + sfxinfo_t *sfx; + INT32 sep, pitch, priority, cnum; + boolean anyListeners = false; + INT32 i; - mobj_t *listenmobj = democam.soundmobj ? : players[displayplayers[0]].mo; - mobj_t *listenmobj2 = NULL; - mobj_t *listenmobj3 = NULL; - mobj_t *listenmobj4 = NULL; + listener_t listener[MAXSPLITSCREENPLAYERS]; + mobj_t *listenmobj[MAXSPLITSCREENPLAYERS]; if (S_SoundDisabled() || !sound_started) return; @@ -527,27 +539,30 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) if (sfx_id == sfx_None) return; - if (players[displayplayers[0]].awayviewtics) - listenmobj = players[displayplayers[0]].awayviewmobj; - - if (r_splitscreen) + for (i = 0; i <= r_splitscreen; i++) { - listenmobj2 = players[displayplayers[1]].mo; - if (players[displayplayers[1]].awayviewtics) - listenmobj2 = players[displayplayers[1]].awayviewmobj; + player_t *player = &players[displayplayers[i]]; - if (r_splitscreen > 1) + memset(&listener[i], 0, sizeof (listener[i])); + listenmobj[i] = NULL; + + if (!player) { - listenmobj3 = players[displayplayers[2]].mo; - if (players[displayplayers[2]].awayviewtics) - listenmobj3 = players[displayplayers[2]].awayviewmobj; + continue; + } - if (r_splitscreen > 2) - { - listenmobj4 = players[displayplayers[3]].mo; - if (players[displayplayers[3]].awayviewtics) - listenmobj4 = players[displayplayers[3]].awayviewmobj; - } + if (i == 0 && democam.soundmobj) + { + continue; + } + + if (player->awayviewtics) + { + listenmobj[i] = player->awayviewmobj; + } + else + { + listenmobj[i] = player->mo; } } @@ -559,75 +574,37 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) }; #endif - if (camera[0].chase && !players[displayplayers[0]].awayviewtics) + for (i = 0; i <= r_splitscreen; i++) { - listener.x = camera[0].x; - listener.y = camera[0].y; - listener.z = camera[0].z; - listener.angle = camera[0].angle; + player_t *player = &players[displayplayers[i]]; + + if (!player) + { + continue; + } + + if (camera[i].chase && !player->awayviewtics) + { + listener[i].x = camera[i].x; + listener[i].y = camera[i].y; + listener[i].z = camera[i].z; + listener[i].angle = camera[i].angle; + anyListeners = true; + } + else if (listenmobj[i]) + { + listener[i].x = listenmobj[i]->x; + listener[i].y = listenmobj[i]->y; + listener[i].z = listenmobj[i]->z; + listener[i].angle = listenmobj[i]->angle; + anyListeners = true; + } } - else if (listenmobj) + + if (origin && anyListeners == false) { - listener.x = listenmobj->x; - listener.y = listenmobj->y; - listener.z = listenmobj->z; - listener.angle = listenmobj->angle; - } - else if (origin) + // If a mobj is trying to make a noise, and no one is around to hear it, does it make a sound? return; - - if (listenmobj2) - { - if (camera[1].chase && !players[displayplayers[1]].awayviewtics) - { - listener2.x = camera[1].x; - listener2.y = camera[1].y; - listener2.z = camera[1].z; - listener2.angle = camera[1].angle; - } - else - { - listener2.x = listenmobj2->x; - listener2.y = listenmobj2->y; - listener2.z = listenmobj2->z; - listener2.angle = listenmobj2->angle; - } - } - - if (listenmobj3) - { - if (camera[2].chase && !players[displayplayers[2]].awayviewtics) - { - listener3.x = camera[2].x; - listener3.y = camera[2].y; - listener3.z = camera[2].z; - listener3.angle = camera[2].angle; - } - else - { - listener3.x = listenmobj3->x; - listener3.y = listenmobj3->y; - listener3.z = listenmobj3->z; - listener3.angle = listenmobj3->angle; - } - } - - if (listenmobj4) - { - if (camera[3].chase && !players[displayplayers[3]].awayviewtics) - { - listener4.x = camera[3].x; - listener4.y = camera[3].y; - listener4.z = camera[3].z; - listener4.angle = camera[3].angle; - } - else - { - listener4.x = listenmobj4->x; - listener4.y = listenmobj4->y; - listener4.z = listenmobj4->z; - listener4.angle = listenmobj4->angle; - } } // check for bogus sound # @@ -647,92 +624,48 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) pitch = NORM_PITCH; priority = NORM_PRIORITY; - if (r_splitscreen && origin) - volume = FixedDiv(volume<>FRACBITS; + // try to find a channel + cnum = S_getChannel(origin, sfx); - if (r_splitscreen && listenmobj2) // Copy the sound for the split player + if (cnum < 0) { - // Check to see if it is audible, and if not, modify the params - if (origin && origin != listenmobj2) - { - INT32 rc; - rc = S_AdjustSoundParams(listenmobj2, origin, &volume, &sep, &pitch, sfx); - - if (!rc) - goto dontplay; // Maybe the other player can hear it... - - if (origin->x == listener2.x && origin->y == listener2.y) - sep = NORM_SEP; - } - else if (!origin) - // Do not play origin-less sounds for the second player. - // The first player will be able to hear it just fine, - // we really don't want it playing twice. - goto dontplay; - else - sep = NORM_SEP; - - // try to find a channel - cnum = S_getChannel(origin, sfx); - - if (cnum < 0) - return; // If there's no free channels, it's not gonna be free for player 1, either. - - // This is supposed to handle the loading/caching. - // For some odd reason, the caching is done nearly - // each time the sound is needed? - - // cache data if necessary - // NOTE: set sfx->data NULL sfx->lump -1 to force a reload - if (!sfx->data) - sfx->data = I_GetSfx(sfx); - - // increase the usefulness - if (sfx->usefulness++ < 0) - sfx->usefulness = -1; - - // Avoid channel reverse if surround - if (reverse -#ifdef SURROUND - && sep != SURROUND_SEP -#endif - ) - sep = (~sep) & 255; - - // Assigns the handle to one of the channels in the - // mix/output buffer. - channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum); + return; // If there's no free channels, it's not gonna be free for anyone. } -dontplay: - - if (r_splitscreen > 1 && listenmobj3) // Copy the sound for the third player + for (i = r_splitscreen; i >= 0; i--) { - // Check to see if it is audible, and if not, modify the params - if (origin && origin != listenmobj3) + // Copy the sound for the splitscreen players! + if (!listenmobj[i]) { - INT32 rc; - rc = S_AdjustSoundParams(listenmobj3, origin, &volume, &sep, &pitch, sfx); + continue; + } + + // Check to see if it is audible, and if not, modify the params + if (origin && origin != listenmobj[i]) + { + boolean rc = S_AdjustSoundParams(listenmobj[i], origin, &volume, &sep, &pitch, sfx); if (!rc) - goto dontplay3; // Maybe the other player can hear it... + { + continue; // Maybe the other player can hear it... + } - if (origin->x == listener3.x && origin->y == listener3.y) + if (origin->x == listener[i].x && origin->y == listener[i].y) + { sep = NORM_SEP; + } } - else if (!origin) - // Do not play origin-less sounds for the second player. + else if (i > 0 && !origin) + { + // Do not play origin-less sounds for the splitscreen players. // The first player will be able to hear it just fine, // we really don't want it playing twice. - goto dontplay3; + continue; + } else + { sep = NORM_SEP; - - // try to find a channel - cnum = S_getChannel(origin, sfx); - - if (cnum < 0) - return; // If there's no free channels, it's not gonna be free for player 1, either. + } // This is supposed to handle the loading/caching. // For some odd reason, the caching is done nearly @@ -741,135 +674,35 @@ dontplay: // cache data if necessary // NOTE: set sfx->data NULL sfx->lump -1 to force a reload if (!sfx->data) - sfx->data = I_GetSfx(sfx); - - // increase the usefulness - if (sfx->usefulness++ < 0) - sfx->usefulness = -1; - - // Avoid channel reverse if surround - if (reverse -#ifdef SURROUND - && sep != SURROUND_SEP -#endif - ) - sep = (~sep) & 255; - - // Assigns the handle to one of the channels in the - // mix/output buffer. - channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum); - } - -dontplay3: - - if (r_splitscreen > 2 && listenmobj4) // Copy the sound for the split player - { - // Check to see if it is audible, and if not, modify the params - if (origin && origin != listenmobj4) { - INT32 rc; - rc = S_AdjustSoundParams(listenmobj4, origin, &volume, &sep, &pitch, sfx); - - if (!rc) - goto dontplay4; // Maybe the other player can hear it... - - if (origin->x == listener4.x && origin->y == listener4.y) - sep = NORM_SEP; - } - else if (!origin) - // Do not play origin-less sounds for the second player. - // The first player will be able to hear it just fine, - // we really don't want it playing twice. - goto dontplay4; - else - sep = NORM_SEP; - - // try to find a channel - cnum = S_getChannel(origin, sfx); - - if (cnum < 0) - return; // If there's no free channels, it's not gonna be free for player 1, either. - - // This is supposed to handle the loading/caching. - // For some odd reason, the caching is done nearly - // each time the sound is needed? - - // cache data if necessary - // NOTE: set sfx->data NULL sfx->lump -1 to force a reload - if (!sfx->data) sfx->data = I_GetSfx(sfx); + } // increase the usefulness if (sfx->usefulness++ < 0) + { sfx->usefulness = -1; + } // Avoid channel reverse if surround if (reverse #ifdef SURROUND && sep != SURROUND_SEP #endif - ) + ) + { sep = (~sep) & 255; + } // Handle closed caption input. S_StartCaption(actual_id, cnum, MAXCAPTIONTICS); // Assigns the handle to one of the channels in the // mix/output buffer. + channels[cnum].volume = initial_volume; channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum); + return; // We're done here! } - -dontplay4: - - // Check to see if it is audible, and if not, modify the params - if (origin && origin != listenmobj) - { - INT32 rc; - rc = S_AdjustSoundParams(listenmobj, origin, &volume, &sep, &pitch, sfx); - - if (!rc) - return; - - if (origin->x == listener.x && origin->y == listener.y) - sep = NORM_SEP; - } - else - sep = NORM_SEP; - - // try to find a channel - cnum = S_getChannel(origin, sfx); - - if (cnum < 0) - return; - - // This is supposed to handle the loading/caching. - // For some odd reason, the caching is done nearly - // each time the sound is needed? - - // cache data if necessary - // NOTE: set sfx->data NULL sfx->lump -1 to force a reload - if (!sfx->data) - sfx->data = I_GetSfx(sfx); - - // increase the usefulness - if (sfx->usefulness++ < 0) - sfx->usefulness = -1; - - // Avoid channel reverse if surround - if (reverse -#ifdef SURROUND - && sep != SURROUND_SEP -#endif - ) - sep = (~sep) & 255; - - // Handle closed caption input. - S_StartCaption(actual_id, cnum, MAXCAPTIONTICS); - - // Assigns the handle to one of the channels in the - // mix/output buffer. - channels[cnum].volume = initial_volume; - channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum); } void S_StartSound(const void *origin, sfxenum_t sfx_id) @@ -920,23 +753,13 @@ static INT32 actualdigmusicvolume; void S_UpdateSounds(void) { - INT32 audible, cnum, volume, sep, pitch; + INT32 cnum, volume, sep, pitch; + boolean audible = false; channel_t *c; + INT32 i; - listener_t listener; - listener_t listener2; - listener_t listener3; - listener_t listener4; - - mobj_t *listenmobj = democam.soundmobj ? : players[displayplayers[0]].mo; - mobj_t *listenmobj2 = NULL; - mobj_t *listenmobj3 = NULL; - mobj_t *listenmobj4 = NULL; - - memset(&listener, 0, sizeof(listener_t)); - memset(&listener2, 0, sizeof(listener_t)); - memset(&listener3, 0, sizeof(listener_t)); - memset(&listener4, 0, sizeof(listener_t)); + listener_t listener[MAXSPLITSCREENPLAYERS]; + mobj_t *listenmobj[MAXSPLITSCREENPLAYERS]; // Update sound/music volumes, if changed manually at console if (actualsfxvolume != cv_soundvolume.value * USER_VOLUME_SCALE) @@ -949,7 +772,7 @@ void S_UpdateSounds(void) { #ifndef NOMUMBLE // Stop Mumble cutting out. I'm sick of it. - I_UpdateMumble(NULL, listener); + I_UpdateMumble(NULL, listener[0]); #endif goto notinlevel; @@ -958,47 +781,35 @@ void S_UpdateSounds(void) if (dedicated || sound_disabled) return; - if (players[displayplayers[0]].awayviewtics) - listenmobj = players[displayplayers[0]].awayviewmobj; - - if (r_splitscreen) + for (i = 0; i <= r_splitscreen; i++) { - listenmobj2 = players[displayplayers[1]].mo; - if (players[displayplayers[1]].awayviewtics) - listenmobj2 = players[displayplayers[1]].awayviewmobj; + player_t *player = &players[displayplayers[i]]; - if (r_splitscreen > 1) + memset(&listener[i], 0, sizeof (listener[i])); + listenmobj[i] = NULL; + + if (!player) { - listenmobj3 = players[displayplayers[2]].mo; - if (players[displayplayers[2]].awayviewtics) - listenmobj3 = players[displayplayers[2]].awayviewmobj; + continue; + } - if (r_splitscreen > 2) - { - listenmobj4 = players[displayplayers[3]].mo; - if (players[displayplayers[3]].awayviewtics) - listenmobj4 = players[displayplayers[3]].awayviewmobj; - } + if (i == 0 && democam.soundmobj) + { + continue; + } + + if (player->awayviewtics) + { + listenmobj[i] = player->awayviewmobj; + } + else + { + listenmobj[i] = player->mo; } } - if (camera[0].chase && !players[displayplayers[0]].awayviewtics) - { - listener.x = camera[0].x; - listener.y = camera[0].y; - listener.z = camera[0].z; - listener.angle = camera[0].angle; - } - else if (listenmobj) - { - listener.x = listenmobj->x; - listener.y = listenmobj->y; - listener.z = listenmobj->z; - listener.angle = listenmobj->angle; - } - #ifndef NOMUMBLE - I_UpdateMumble(players[consoleplayer].mo, listener); + I_UpdateMumble(players[consoleplayer].mo, listener[0]); #endif #ifdef HW3SOUND @@ -1009,57 +820,28 @@ void S_UpdateSounds(void) } #endif - if (listenmobj2) + for (i = 0; i <= r_splitscreen; i++) { - if (camera[1].chase && !players[displayplayers[1]].awayviewtics) - { - listener2.x = camera[1].x; - listener2.y = camera[1].y; - listener2.z = camera[1].z; - listener2.angle = camera[1].angle; - } - else - { - listener2.x = listenmobj2->x; - listener2.y = listenmobj2->y; - listener2.z = listenmobj2->z; - listener2.angle = listenmobj2->angle; - } - } + player_t *player = &players[displayplayers[i]]; - if (listenmobj3) - { - if (camera[2].chase && !players[displayplayers[2]].awayviewtics) + if (!player) { - listener3.x = camera[2].x; - listener3.y = camera[2].y; - listener3.z = camera[2].z; - listener3.angle = camera[2].angle; + continue; } - else - { - listener3.x = listenmobj3->x; - listener3.y = listenmobj3->y; - listener3.z = listenmobj3->z; - listener3.angle = listenmobj3->angle; - } - } - if (listenmobj4) - { - if (camera[3].chase && !players[displayplayers[3]].awayviewtics) + if (camera[i].chase && !player->awayviewtics) { - listener4.x = camera[3].x; - listener4.y = camera[3].y; - listener4.z = camera[3].z; - listener4.angle = camera[3].angle; + listener[i].x = camera[i].x; + listener[i].y = camera[i].y; + listener[i].z = camera[i].z; + listener[i].angle = camera[i].angle; } - else + else if (listenmobj[i]) { - listener4.x = listenmobj4->x; - listener4.y = listenmobj4->y; - listener4.z = listenmobj4->z; - listener4.angle = listenmobj4->angle; + listener[i].x = listenmobj[i]->x; + listener[i].y = listenmobj[i]->y; + listener[i].z = listenmobj[i]->z; + listener[i].angle = listenmobj[i]->angle; } } @@ -1076,84 +858,54 @@ void S_UpdateSounds(void) pitch = NORM_PITCH; sep = NORM_SEP; - if (r_splitscreen && c->origin) - volume = FixedDiv(volume<>FRACBITS; - // check non-local sounds for distance clipping // or modify their params - if (c->origin && ((c->origin != players[displayplayers[0]].mo) - || (r_splitscreen && c->origin != players[displayplayers[1]].mo) - || (r_splitscreen > 1 && c->origin != players[displayplayers[2]].mo) - || (r_splitscreen > 2 && c->origin != players[displayplayers[3]].mo))) + if (c->origin) { - // Whomever is closer gets the sound, but only in splitscreen. - if (r_splitscreen) + boolean itsUs = false; + + for (i = 0; i <= r_splitscreen; i++) + { + if (c->origin == players[displayplayers[i]].mo) + { + itsUs = true; + break; + } + } + + if (itsUs == false) { const mobj_t *soundmobj = c->origin; - fixed_t recdist = -1; - INT32 i, p = -1; + fixed_t recdist = INT32_MAX; + UINT8 p = 0; for (i = 0; i <= r_splitscreen; i++) { - fixed_t thisdist = -1; + fixed_t thisdist = INT32_MAX; - if (i == 0 && listenmobj) - thisdist = P_AproxDistance(listener.x-soundmobj->x, listener.y-soundmobj->y); - else if (i == 1 && listenmobj2) - thisdist = P_AproxDistance(listener2.x-soundmobj->x, listener2.y-soundmobj->y); - else if (i == 2 && listenmobj3) - thisdist = P_AproxDistance(listener3.x-soundmobj->x, listener3.y-soundmobj->y); - else if (i == 3 && listenmobj4) - thisdist = P_AproxDistance(listener4.x-soundmobj->x, listener4.y-soundmobj->y); - else + if (!listenmobj[i]) + { continue; + } - if (recdist == -1 || (thisdist != -1 && thisdist < recdist)) + thisdist = P_AproxDistance(listener[i].x - soundmobj->x, listener[i].y - soundmobj->y); + + if (thisdist < recdist) { recdist = thisdist; p = i; } } - if (p != -1) + if (listenmobj[p]) { - if (p == 1) - { - // Player 2 gets the sound - audible = S_AdjustSoundParams(listenmobj2, c->origin, &volume, &sep, &pitch, - c->sfxinfo); - } - else if (p == 2) - { - // Player 3 gets the sound - audible = S_AdjustSoundParams(listenmobj3, c->origin, &volume, &sep, &pitch, - c->sfxinfo); - } - else if (p == 3) - { - // Player 4 gets the sound - audible = S_AdjustSoundParams(listenmobj4, c->origin, &volume, &sep, &pitch, - c->sfxinfo); - } - else - { - // Player 1 gets the sound - audible = S_AdjustSoundParams(listenmobj, c->origin, &volume, &sep, &pitch, - c->sfxinfo); - } - - if (audible) - I_UpdateSoundParams(c->handle, volume, sep, pitch); - else - S_StopChannel(cnum); + audible = S_AdjustSoundParams( + listenmobj[p], c->origin, + &volume, &sep, &pitch, + c->sfxinfo + ); } - } - else if (listenmobj && !r_splitscreen) - { - // In the case of a single player, he or she always should get updated sound. - audible = S_AdjustSoundParams(listenmobj, c->origin, &volume, &sep, &pitch, - c->sfxinfo); - + if (audible) I_UpdateSoundParams(c->handle, volume, sep, pitch); else @@ -1273,54 +1025,39 @@ fixed_t S_CalculateSoundDistance(fixed_t sx1, fixed_t sy1, fixed_t sz1, fixed_t // If the sound is not audible, returns a 0. // Otherwise, modifies parameters and returns 1. // -INT32 S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *vol, INT32 *sep, INT32 *pitch, +boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *vol, INT32 *sep, INT32 *pitch, sfxinfo_t *sfxinfo) { + const boolean reverse = (stereoreverse.value ^ encoremode); + fixed_t approx_dist; angle_t angle; listener_t listensource; - - const boolean reverse = (stereoreverse.value ^ encoremode); + INT32 i; (void)pitch; + if (!listener) return false; - if (listener == players[displayplayers[0]].mo && camera[0].chase) + // Init listensource with default listener + listensource.x = listener->x; + listensource.y = listener->y; + listensource.z = listener->z; + listensource.angle = listener->angle; + + for (i = 0; i <= r_splitscreen; i++) { - listensource.x = camera[0].x; - listensource.y = camera[0].y; - listensource.z = camera[0].z; - listensource.angle = camera[0].angle; - } - else if (r_splitscreen && listener == players[displayplayers[1]].mo && camera[1].chase) - { - listensource.x = camera[1].x; - listensource.y = camera[1].y; - listensource.z = camera[1].z; - listensource.angle = camera[1].angle; - } - else if (r_splitscreen > 1 && listener == players[displayplayers[2]].mo && camera[2].chase) - { - listensource.x = camera[2].x; - listensource.y = camera[2].y; - listensource.z = camera[2].z; - listensource.angle = camera[2].angle; - } - else if (r_splitscreen > 2 && listener == players[displayplayers[3]].mo && camera[3].chase) - { - listensource.x = camera[3].x; - listensource.y = camera[3].y; - listensource.z = camera[3].z; - listensource.angle = camera[3].angle; - } - else - { - listensource.x = listener->x; - listensource.y = listener->y; - listensource.z = listener->z; - listensource.angle = listener->angle; + // If listener is a chasecam player, use the camera instead + if (listener == players[displayplayers[i]].mo && camera[i].chase) + { + listensource.x = camera[i].x; + listensource.y = camera[i].y; + listensource.z = camera[i].z; + listensource.angle = camera[i].angle; + break; + } } if (sfxinfo->pitch & SF_OUTSIDESOUND) // Rain special case @@ -1370,7 +1107,7 @@ INT32 S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *v approx_dist = FixedDiv(approx_dist,2*FRACUNIT); if (approx_dist > S_CLIPPING_DIST) - return 0; + return false; // angle of source to listener angle = R_PointToAngle2(listensource.x, listensource.y, source->x, source->y); @@ -1405,9 +1142,6 @@ INT32 S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *v *vol = FixedMul(*vol * FRACUNIT / 255, n) / S_ATTENUATOR; } - if (r_splitscreen) - *vol = FixedDiv((*vol)<>FRACBITS; - return (*vol > 0); } From 0bc19152caf5d94c208dd876355165d75ac86caa Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 23 Apr 2021 19:17:29 -0400 Subject: [PATCH 08/26] Fix Advance 2 afterimages conflicting with fade-out afterimages --- src/p_mobj.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 694accbd3..1013d8521 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8492,7 +8492,22 @@ 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 (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 (mobj->flags2 & MF2_BOSSNOTRAP) // "fast" flag { if ((signed)((mobj->renderflags & RF_TRANSMASK) >> RF_TRANSSHIFT) < (NUMTRANSMAPS-1) - (2*mobj->fuse)/3) // fade out when nearing the end of fuse... @@ -8830,21 +8845,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) { From e632e1d70ee4491c2e3085026249c6a2522e0d84 Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Sat, 24 Apr 2021 01:26:39 +0200 Subject: [PATCH 09/26] Final (?) visuals for trick panel timing --- src/d_player.h | 3 ++ src/info.c | 2 ++ src/info.h | 2 ++ src/k_hud.c | 34 ++++++++++++++++++++ src/k_kart.c | 85 ++++++++++++++++++++++++++++++++++++-------------- 5 files changed, 102 insertions(+), 24 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 445c1148d..8bd2f3fa8 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -232,6 +232,9 @@ typedef enum khud_cardanimation, // Used to determine the position of some full-screen Battle Mode graphics khud_yougotem, // "You Got Em" gfx when hitting someone as a karma player via a method that gets you back in the game instantly + // Tricks + khud_trickcool, + NUMKARTHUD } karthudtype_t; diff --git a/src/info.c b/src/info.c index eaa800ebc..ff982d6de 100644 --- a/src/info.c +++ b/src/info.c @@ -747,6 +747,8 @@ char sprnames[NUMSPRITES + 1][5] = "SDDS", // Spindash dust "SDWN", // Spindash wind + "TRCK", + "FLBM", // First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw later diff --git a/src/info.h b/src/info.h index 697d206c6..f012df8a0 100644 --- a/src/info.h +++ b/src/info.h @@ -1289,6 +1289,8 @@ typedef enum sprite SPR_SDDS, // Spindash dust SPR_SDWN, // Spindash wind + SPR_TRCK, + SPR_FLBM, // Finish line beam // First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw later diff --git a/src/k_hud.c b/src/k_hud.c index c2b29fe3d..e03172ae4 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -162,6 +162,8 @@ static patch_t *kp_cpu; static patch_t *kp_nametagstem; +static patch_t *kp_trickcool[2]; + void K_LoadKartHUDGraphics(void) { INT32 i, j; @@ -601,6 +603,9 @@ void K_LoadKartHUDGraphics(void) kp_cpu = (patch_t *) W_CachePatchName("K_CPU", PU_HUDGFX); kp_nametagstem = (patch_t *) W_CachePatchName("K_NAMEST", PU_HUDGFX); + + kp_trickcool[0] = W_CachePatchName("K_COOL1", PU_HUDGFX); + kp_trickcool[1] = W_CachePatchName("K_COOL2", PU_HUDGFX); } // For the item toggle menu @@ -3951,6 +3956,31 @@ static void K_drawLapStartAnim(void) } } +// stretch for "COOOOOL" popup. +// I can't be fucked to find out any math behind this so have a table lmao +static fixed_t stretch[6][2] = { + {FRACUNIT/4, FRACUNIT*4}, + {FRACUNIT/2, FRACUNIT*2}, + {FRACUNIT, FRACUNIT}, + {FRACUNIT*2, FRACUNIT/2}, + {FRACUNIT*4, FRACUNIT/4}, + {FRACUNIT*2, FRACUNIT/2}, +}; + +static void K_drawTrickCool(void) +{ + + tic_t timer = TICRATE - stplyr->karthud[khud_trickcool]; + if (timer <= 6) + { + V_DrawStretchyFixedPatch(160<karthud[khud_trickcool]) + K_drawTrickCool(); + if (modeattacking || freecam) // everything after here is MP and debug only return; diff --git a/src/k_kart.c b/src/k_kart.c index 3f1cdebb9..938f4a5d0 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -6099,6 +6099,9 @@ void K_KartPlayerHUDUpdate(player_t *player) if (player->karthud[khud_tauntvoices]) player->karthud[khud_tauntvoices]--; + if (player->karthud[khud_trickcool]) + player->karthud[khud_trickcool]--; + if (!(player->pflags & PF_FAULT)) player->karthud[khud_fault] = 0; else if (player->karthud[khud_fault] > 0 && player->karthud[khud_fault] < 2*TICRATE) @@ -8138,10 +8141,12 @@ void K_AdjustPlayerFriction(player_t *player) // // K_trickPanelTimingVisual // Spawns the timing visual for trick panels depending on the given player's momz. +// If the player has tricked and is not in hitlag, this will send the half circles flying out. +// if you tumble, they'll fall off instead. // #define RADIUSSCALING 6 -#define MINRADIUS 24 +#define MINRADIUS 12 static void K_trickPanelTimingVisual(player_t *player, fixed_t momz) { @@ -8150,8 +8155,8 @@ static void K_trickPanelTimingVisual(player_t *player, fixed_t momz) mobj_t *flame; angle_t hang = R_PointToAngle(player->mo->x, player->mo->y) + ANG1*90; // horizontal angle - angle_t vang = -leveltime*ANG1*12; // vertical angle... arbitrary rotation speed for now. - fixed_t dist = FixedMul(max(MINRADIUS<mo->scale); // distance. + angle_t vang = -FixedAngle(momz)*12 + (ANG1*45); // vertical angle... arbitrary rotation speed for now. + fixed_t dist = FixedMul(max(MINRADIUS<mo->scale); // distance. UINT8 i; @@ -8164,31 +8169,48 @@ static void K_trickPanelTimingVisual(player_t *player, fixed_t momz) pos = FixedMul(dist, FINESINE(vang>>ANGLETOFINESHIFT)); tx = player->mo->x + FixedMul(pos, FINECOSINE(hang>>ANGLETOFINESHIFT)); ty = player->mo->y + FixedMul(pos, FINESINE(hang>>ANGLETOFINESHIFT)); - tz = player->mo->z + FixedMul(dist, FINECOSINE(vang>>ANGLETOFINESHIFT)); + tz = player->mo->z + player->mo->height/2 + FixedMul(dist, FINECOSINE(vang>>ANGLETOFINESHIFT)); // All coordinates set, spawn our fire, now. - flame = P_SpawnMobj(tx, ty, tz, MT_THOK); // @TODO: Make this into its own object. Duh. + flame = P_SpawnMobj(tx, ty, tz, MT_THOK); - // PLACEHOLDER VISUALS - // @TODO: SPRITES - flame->sprite = SPR_FLAM; - flame->frame = ((leveltime%16) /2)|FF_FULLBRIGHT; - flame->tics = 2; - flame->rollangle = vang + ANG1*90; + P_SetScale(flame, player->mo->scale); + + // Visuals + flame->sprite = SPR_TRCK; + flame->frame = i|FF_FULLBRIGHT; + + if (player->trickpanel <= 1 && !player->tumbleBounces) + flame->tics = 2; + else + { + flame->tics = TICRATE; + + if (player->trickpanel > 1) // we tricked + { + // Send the thing outwards via ghetto maths + pos = FixedMul(48*player->mo->scale, FINESINE((vang +ANG1*90)>>ANGLETOFINESHIFT)); + tx = player->mo->x + FixedMul(pos, FINECOSINE(hang>>ANGLETOFINESHIFT)); + ty = player->mo->y + FixedMul(pos, FINESINE(hang>>ANGLETOFINESHIFT)); + tz = player->mo->z + player->mo->height/2 + FixedMul(48*player->mo->scale, FINECOSINE((vang +ANG1*90)>>ANGLETOFINESHIFT)); + + flame->momx = tx -player->mo->x; + flame->momy = ty -player->mo->y; + flame->momz = tz -(player->mo->z+player->mo->height/2); + } + else // we failed the trick. + { + flame->flags &= ~MF_NOGRAVITY; + P_SetObjectMomZ(flame, 4<mo->x, player->mo->y, flame->x, flame->y), 8*mapobjectscale); + flame->momx += player->mo->momx; + flame->momy += player->mo->momy; + flame->momz += player->mo->momz; + } + } // make sure this is only drawn for our local player - flame->renderflags &= ~K_GetPlayerDontDrawFlag(player); - - // second flame for visuals... - flame = P_SpawnMobj(tx, ty, tz, MT_THOK); // @TODO: Make this into its own object. Duh. - - flame->sprite = SPR_FLAM; - flame->frame = ((leveltime%16) /2)|FF_FULLBRIGHT|FF_TRANS60; - flame->tics = 10; - flame->rollangle = vang + ANG1*90; - - // make sure this is only drawn for our local player - flame->renderflags &= ~K_GetPlayerDontDrawFlag(player); + flame->renderflags |= (RF_DONTDRAW & ~K_GetPlayerDontDrawFlag(player)); vang += FixedAngle(180<mo->momx, player->mo->momy); // at WORSE, keep your normal speed when tricking. fixed_t speed = FixedMul(speedmult, P_AproxDistance(player->mo->momx, player->mo->momy)); - K_trickPanelTimingVisual(player, abs(momz)); + K_trickPanelTimingVisual(player, momz); // streaks: if (momz*P_MobjFlip(player->mo) > 0) // only spawn those while you're going upwards relative to your current gravity @@ -8907,11 +8929,22 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->pflags &= ~PF_TUMBLESOUND; player->tumbleHeight = 30; // Base tumble bounce height player->trickpanel = 0; + K_trickPanelTimingVisual(player, momz); // fail trick visual P_SetPlayerMobjState(player->mo, S_KART_SPINOUT); } else if (!(player->pflags & PF_TRICKDELAY)) // don't allow tricking at the same frame you tumble obv { + + // "COOL" timing n shit. + if (cmd->turning || player->throwdir) + { + if (abs(momz) < FRACUNIT*99) // Let's use that as baseline for PERFECT trick. + { + player->karthud[khud_trickcool] = TICRATE; + } + } + // Uses cmd->turning over steering intentionally. if (cmd->turning > 0) { @@ -8925,6 +8958,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->trickpanel = 2; player->mo->hitlag = TRICKLAG; + K_trickPanelTimingVisual(player, momz); } else if (cmd->turning < 0) { @@ -8938,6 +8972,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->trickpanel = 3; player->mo->hitlag = TRICKLAG; + K_trickPanelTimingVisual(player, momz); } else if (player->throwdir == 1) { @@ -8956,6 +8991,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->trickpanel = 2; player->mo->hitlag = TRICKLAG; + K_trickPanelTimingVisual(player, momz); } else if (player->throwdir == -1) { @@ -8985,6 +9021,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->trickpanel = 4; player->mo->hitlag = TRICKLAG; + K_trickPanelTimingVisual(player, momz); } } } From e980be69ef40d6c42b0e9947ce0556bbf08f4b75 Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Sat, 24 Apr 2021 01:56:34 +0200 Subject: [PATCH 10/26] wip splitscreen garbage. DOES NOT WORK. --- src/k_hud.c | 22 ++++++++++++++++++++-- src/k_kart.c | 2 ++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index e03172ae4..18809ae6f 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -3971,13 +3971,31 @@ static void K_drawTrickCool(void) { tic_t timer = TICRATE - stplyr->karthud[khud_trickcool]; + INT32 x = (BASEVIDWIDTH/2); + INT32 y = ((BASEVIDHEIGHT)/2)-10; + + // @TODO: fix this shit + /*if (r_splitscreen > 2) // 4p split + { + if (stplyr == &players[displayplayers[0]] || stplyr == &players[displayplayers[2]]) + { + x /= 2; + y /= 2; + } + else + { + x /= 2 + BASEVIDWIDTH/2; + y /= 2 + BASEVIDHEIGHT/2; + } + }*/ + if (timer <= 6) { - V_DrawStretchyFixedPatch(160< Date: Sat, 24 Apr 2021 14:46:39 +0200 Subject: [PATCH 11/26] Fix effects in splitscreen --- src/k_hud.c | 36 ++++++++++++++---------------------- src/k_kart.c | 16 ++++++---------- src/r_main.c | 35 +++++++++++++++++++++++++++++++++++ src/r_main.h | 1 + 4 files changed, 56 insertions(+), 32 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index 18809ae6f..d023653a2 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -684,6 +684,9 @@ INT32 ITEM2_X, ITEM2_Y; INT32 LAPS2_X, LAPS2_Y; INT32 POSI2_X, POSI2_Y; +// trick "cool" +INT32 TCOOL_X, TCOOL_Y; + void K_AdjustXYWithSnap(INT32 *x, INT32 *y, UINT32 options, INT32 dupx, INT32 dupy) { @@ -987,6 +990,10 @@ static void K_initKartHUD(void) WANT_X = BASEVIDWIDTH - 55; // 270 WANT_Y = BASEVIDHEIGHT- 71; // 176 + // trick COOL + TCOOL_X = (BASEVIDWIDTH)/2; + TCOOL_Y = (BASEVIDHEIGHT)/2 -10; + if (r_splitscreen) // Splitscreen { ITEM_X = 5; @@ -1029,6 +1036,8 @@ static void K_initKartHUD(void) MINI_X = (3*BASEVIDWIDTH/4); MINI_Y = (3*BASEVIDHEIGHT/4); + TCOOL_X = (BASEVIDWIDTH)/4; + if (r_splitscreen > 2) // 4P-only { MINI_X = (BASEVIDWIDTH/2); @@ -3962,40 +3971,23 @@ static fixed_t stretch[6][2] = { {FRACUNIT/4, FRACUNIT*4}, {FRACUNIT/2, FRACUNIT*2}, {FRACUNIT, FRACUNIT}, - {FRACUNIT*2, FRACUNIT/2}, - {FRACUNIT*4, FRACUNIT/4}, - {FRACUNIT*2, FRACUNIT/2}, + {FRACUNIT*4, FRACUNIT/2}, + {FRACUNIT*8, FRACUNIT/4}, + {FRACUNIT*4, FRACUNIT/2}, }; static void K_drawTrickCool(void) { tic_t timer = TICRATE - stplyr->karthud[khud_trickcool]; - INT32 x = (BASEVIDWIDTH/2); - INT32 y = ((BASEVIDHEIGHT)/2)-10; - - // @TODO: fix this shit - /*if (r_splitscreen > 2) // 4p split - { - if (stplyr == &players[displayplayers[0]] || stplyr == &players[displayplayers[2]]) - { - x /= 2; - y /= 2; - } - else - { - x /= 2 + BASEVIDWIDTH/2; - y /= 2 + BASEVIDHEIGHT/2; - } - }*/ if (timer <= 6) { - V_DrawStretchyFixedPatch(x<mo->x, player->mo->y) + ANG1*90; // horizontal angle - angle_t vang = -FixedAngle(momz)*12 + (ANG1*45); // vertical angle... arbitrary rotation speed for now. - fixed_t dist = FixedMul(max(MINRADIUS<mo->scale); // distance. + angle_t hang = R_PointToAnglePlayer(player, player->mo->x, player->mo->y) + ANG1*90; // horizontal angle + angle_t vang = -FixedAngle(momz)*12 + (ANG1*45); // vertical angle dependant on momz, we want it to line up at 45 degrees at the perfect frame to trick at + fixed_t dist = FixedMul(max(MINRADIUS<mo->scale); // distance. UINT8 i; - //CONS_Printf("a\n"); - // Do you like trig? cool, me neither. for (i=0; i < 2; i++) { - //CONS_Printf("%d\n", i); pos = FixedMul(dist, FINESINE(vang>>ANGLETOFINESHIFT)); tx = player->mo->x + FixedMul(pos, FINECOSINE(hang>>ANGLETOFINESHIFT)); ty = player->mo->y + FixedMul(pos, FINESINE(hang>>ANGLETOFINESHIFT)); @@ -8190,7 +8185,8 @@ static void K_trickPanelTimingVisual(player_t *player, fixed_t momz) if (player->trickpanel > 1) // we tricked { - // Send the thing outwards via ghetto maths + // Send the thing outwards via ghetto maths which involves redoing the whole 3d sphere again, witht the "vertical" angle shifted by 90 degrees. + // There's probably a simplier way to do this the way I want to but this works. pos = FixedMul(48*player->mo->scale, FINESINE((vang +ANG1*90)>>ANGLETOFINESHIFT)); tx = player->mo->x + FixedMul(pos, FINECOSINE(hang>>ANGLETOFINESHIFT)); ty = player->mo->y + FixedMul(pos, FINESINE(hang>>ANGLETOFINESHIFT)); @@ -8200,7 +8196,7 @@ static void K_trickPanelTimingVisual(player_t *player, fixed_t momz) flame->momy = ty -player->mo->y; flame->momz = tz -(player->mo->z+player->mo->height/2); } - else // we failed the trick. + else // we failed the trick, drop the half circles, it'll be funny I promise. { flame->flags &= ~MF_NOGRAVITY; P_SetObjectMomZ(flame, 4<x; + refy = cam->y; + + // Now do whatever tehe fuck is this hellish maths from R_PointToAngle while swapping viewx/viewy for our refx/refy + return (y -= refy, (x -= refx) || y) ? + x >= 0 ? + y >= 0 ? + (x > y) ? tantoangle[SlopeDiv(y,x)] : // octant 0 + ANGLE_90-tantoangle[SlopeDiv(x,y)] : // octant 1 + x > (y = -y) ? 0-tantoangle[SlopeDiv(y,x)] : // octant 8 + ANGLE_270+tantoangle[SlopeDiv(x,y)] : // octant 7 + y >= 0 ? (x = -x) > y ? ANGLE_180-tantoangle[SlopeDiv(y,x)] : // octant 3 + ANGLE_90 + tantoangle[SlopeDiv(x,y)] : // octant 2 + (x = -x) > (y = -y) ? ANGLE_180+tantoangle[SlopeDiv(y,x)] : // octant 4 + ANGLE_270-tantoangle[SlopeDiv(x,y)] : // octant 5 + 0; +} + // This version uses 64-bit variables to avoid overflows with large values. // Currently used only by OpenGL rendering. angle_t R_PointToAngle64(INT64 x, INT64 y) diff --git a/src/r_main.h b/src/r_main.h index 49e028149..5208b52a3 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -63,6 +63,7 @@ extern lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ]; INT32 R_PointOnSide(fixed_t x, fixed_t y, node_t *node); INT32 R_PointOnSegSide(fixed_t x, fixed_t y, seg_t *line); angle_t R_PointToAngle(fixed_t x, fixed_t y); +angle_t R_PointToAnglePlayer(player_t *player, fixed_t x, fixed_t y); angle_t R_PointToAngle64(INT64 x, INT64 y); angle_t R_PointToAngle2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1); angle_t R_PointToAngleEx(INT32 x2, INT32 y2, INT32 x1, INT32 y1); From 47a95efa6b6d1ea0e65abc7a07875b08f6e1324e Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Sat, 24 Apr 2021 14:49:41 +0200 Subject: [PATCH 12/26] push R_PointToAnlePlayer to Lua, might be super useful for it. --- src/lua_baselib.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index abf0224d2..9e1c909f5 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2098,6 +2098,16 @@ static int lib_rPointToAngle(lua_State *L) return 1; } +static int lib_rPointToAnglePlayer(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + fixed_t x = luaL_checkfixed(L, 2); + fixed_t y = luaL_checkfixed(L, 3); + //HUDSAFE + lua_pushangle(L, R_PointToAnglePlayer(player, x, y)); + return 1; +} + static int lib_rPointToAngle2(lua_State *L) { fixed_t px2 = luaL_checkfixed(L, 1); @@ -3876,6 +3886,7 @@ static luaL_Reg lib[] = { // r_defs {"R_PointToAngle",lib_rPointToAngle}, + {"R_PointToAnglePlayer", lib_rPointToAnglePlayer}, {"R_PointToAngle2",lib_rPointToAngle2}, {"R_PointToDist",lib_rPointToDist}, {"R_PointToDist2",lib_rPointToDist2}, From c0ba14a752e2c98e00317b2764bbe42f6bae6743 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 25 Apr 2021 20:42:25 -0400 Subject: [PATCH 13/26] Use sounds.pk3 instead of sounds.wad --- src/d_main.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 57dcdefea..c806e4354 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1057,15 +1057,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 +1069,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 } From 9ba424a6c40fd4b33cf8ea8edc8af74307425846 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 25 Apr 2021 20:49:43 -0400 Subject: [PATCH 14/26] Mean Bean Machine sound effects --- src/sounds.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/src/sounds.c b/src/sounds.c index fa0229aa2..f090a33a6 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -837,6 +837,78 @@ 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, ""}, + {"mbv80", 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 From 340c948c71e0febf1ee8ad16cb31020cc2c99d23 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 25 Apr 2021 20:49:52 -0400 Subject: [PATCH 15/26] Fix being able to download our data files --- src/d_netfil.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/d_netfil.c b/src/d_netfil.c index d3058681b..5714c39cd 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -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; From 078ffa8914ee2c4a96149b28e780c33e45fc9f7c Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 25 Apr 2021 21:31:09 -0400 Subject: [PATCH 16/26] Accidentally included one non-existent sound --- src/sounds.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sounds.c b/src/sounds.c index f090a33a6..636b53a8c 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -884,7 +884,6 @@ sfxinfo_t S_sfx[NUMSFX] = {"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, ""}, - {"mbv80", 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, ""}, From 0f14f0cec1d42dea9aa49562c0910598347b4b8a Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 26 Apr 2021 04:09:23 -0400 Subject: [PATCH 17/26] Only check for listenmobj for the splitscreen players Steel's comment is what hinted me to compare the code again -- P1 was the only one who didn't care about their listenmobj existing first. --- src/s_sound.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/s_sound.c b/src/s_sound.c index 8979d1fc9..c4d27e479 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -635,7 +635,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) for (i = r_splitscreen; i >= 0; i--) { // Copy the sound for the splitscreen players! - if (!listenmobj[i]) + if (listenmobj[i] == NULL && i != 0) { continue; } From 44ed9fcd4c30d1f2a1b99fd54507f0cd9305bf06 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 26 Apr 2021 14:49:45 -0400 Subject: [PATCH 18/26] ZDEBUG is default - ZDEBUG2 is now ZDEBUG ... although admittedly, it doesn't seem that useful, it just enables some CONS_Debug's ... but now there's a convenient way to enable them now I suppose - Mostly just means the I_Errors give __FILE__ and __LINE__. - Also enables a "memdump" command that just prints a bunch of zone memory info. I don't think any of this should be guarded, so I went ahead and did this. --- src/p_setup.c | 2 - src/r_textures.c | 2 - src/r_things.c | 2 - src/z_zone.c | 145 +++++++++-------------------------------------- src/z_zone.h | 12 +--- 5 files changed, 28 insertions(+), 135 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 1c2d46e9f..44c53a303 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -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++ ); } diff --git a/src/r_textures.c b/src/r_textures.c index e8d79981a..9716724b5 100644 --- a/src/r_textures.c +++ b/src/r_textures.c @@ -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; } diff --git a/src/r_things.c b/src/r_things.c index bb848a679..ce62b0ad6 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -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 } } diff --git a/src/z_zone.c b/src/z_zone.c index d7da17e51..3a541f3a6 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -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<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. * diff --git a/src/z_zone.h b/src/z_zone.h index 049a39475..94cf244cf 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -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); From 53806d41e09f31aa4aa829cfbed23a60146c541a Mon Sep 17 00:00:00 2001 From: toaster Date: Tue, 27 Apr 2021 20:29:30 +0100 Subject: [PATCH 19/26] Orbfterimages. Fixes mistakes made in !408 and !418, resolving #173. --- src/k_kart.c | 2 +- src/p_enemy.c | 2 +- src/p_mobj.c | 13 +++++-------- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index e8cc80d7c..e4f3972bc 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -6425,7 +6425,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; diff --git a/src/p_enemy.c b/src/p_enemy.c index c9ba95245..9dbeb8f5b 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -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)) { diff --git a/src/p_mobj.c b/src/p_mobj.c index 1013d8521..1bc2c7761 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8507,17 +8507,14 @@ void P_MobjThinker(mobj_t *mobj) } } } - else if (mobj->flags2 & MF2_BOSSNOTRAP) // "fast" flag - { - 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); - } 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); } } From 710abf68206767c84fa63beef80f798bf0c9d8fe Mon Sep 17 00:00:00 2001 From: Sryder Date: Tue, 27 Apr 2021 21:27:42 +0100 Subject: [PATCH 20/26] Fix sound crash, let a sound be played for multiple players again too. S_getChannel now doesn't do any alterations to the channel, it *only* returns the number of the free channel. --- src/s_sound.c | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/src/s_sound.c b/src/s_sound.c index c4d27e479..71e97c27b 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -183,8 +183,6 @@ static INT32 S_getChannel(const void *origin, sfxinfo_t *sfxinfo) // channel number to use INT32 cnum; - channel_t *c; - // Find an open channel for (cnum = 0; cnum < numofchannels; cnum++) { @@ -239,12 +237,6 @@ static INT32 S_getChannel(const void *origin, sfxinfo_t *sfxinfo) } } - c = &channels[cnum]; - - // channel is decided to be cnum. - c->sfxinfo = sfxinfo; - c->origin = origin; - return cnum; } @@ -624,14 +616,6 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) pitch = NORM_PITCH; priority = NORM_PRIORITY; - // try to find a channel - cnum = S_getChannel(origin, sfx); - - if (cnum < 0) - { - return; // If there's no free channels, it's not gonna be free for anyone. - } - for (i = r_splitscreen; i >= 0; i--) { // Copy the sound for the splitscreen players! @@ -697,11 +681,19 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) // Handle closed caption input. S_StartCaption(actual_id, cnum, MAXCAPTIONTICS); - // Assigns the handle to one of the channels in the - // mix/output buffer. + // At this point it is determined that a sound can and should be played, so find a free channel to play it on + cnum = S_getChannel(origin, sfx); + + if (cnum < 0) + { + return; // If there's no free channels, there won't be any for anymore players either + } + + // Now that we know we are going to play a sound, fill out this info + channels[cnum].sfxinfo = sfx; + channels[cnum].origin = origin; channels[cnum].volume = initial_volume; channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum); - return; // We're done here! } } @@ -905,7 +897,7 @@ void S_UpdateSounds(void) c->sfxinfo ); } - + if (audible) I_UpdateSoundParams(c->handle, volume, sep, pitch); else From 5b0b29dbdc305ac9bc354ec7e61f8e61a87019ba Mon Sep 17 00:00:00 2001 From: SteelT Date: Thu, 29 Apr 2021 12:55:35 -0400 Subject: [PATCH 21/26] Add missing mean bean machine sound enums to list of sounds --- src/sounds.h | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/src/sounds.h b/src/sounds.h index 51155c7c3..ac7d5b9cf 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -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, From f2f0a6cbe280e1010b0b7ca07b5bb0ee1438c31b Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Fri, 30 Apr 2021 18:11:36 +0200 Subject: [PATCH 22/26] New titlecards --- src/d_main.c | 10 -- src/doomstat.h | 2 +- src/f_finale.h | 2 +- src/g_game.c | 6 +- src/hu_stuff.c | 28 ++- src/hu_stuff.h | 5 + src/lua_hudlib.c | 29 ++++ src/p_setup.c | 4 +- src/st_stuff.c | 430 +++++++++++++++++++++++++++++++++++------------ src/v_video.c | 143 ++++++++++++++++ src/v_video.h | 10 ++ 11 files changed, 544 insertions(+), 125 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index c806e4354..5ded2bf14 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -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); } diff --git a/src/doomstat.h b/src/doomstat.h index d44ec24b0..19359df3b 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -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 diff --git a/src/f_finale.h b/src/f_finale.h index cc731f7f3..a45de5734 100644 --- a/src/f_finale.h +++ b/src/f_finale.h @@ -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); diff --git a/src/g_game.c b/src/g_game.c index ed21c30f1..df2fbb931 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -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) @@ -1301,7 +1301,7 @@ void G_StartTitleCard(void) ST_startTitleCard(); // start the title card - WipeStageTitle = false; //(!titlemapinaction); -- temporary until titlecards are reworked + WipeStageTitle = (!titlemapinaction); } // @@ -1322,7 +1322,7 @@ void G_PreLevelTitleCard(void) lasttime = nowtime; ST_runTitleCard(); - ST_preLevelTitleCardDrawer(); + ST_drawTitleCard(); I_FinishUpdate(); // page flip or blit buffer if (moviemode) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 3358f2fd3..7afc7d531 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -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"; diff --git a/src/hu_stuff.h b/src/hu_stuff.h index 6a425926b..4d686516e 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -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) diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 926df78ca..75a84ed18 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -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}, diff --git a/src/p_setup.c b/src/p_setup.c index 1c2d46e9f..7ec44eb71 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3981,8 +3981,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); diff --git a/src/st_stuff.c b/src/st_stuff.c index 16118cbee..43d1821ec 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -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()); + tic_t auxticker; + boolean gp = (grandprixinfo.gp && grandprixinfo.roundnum); // check whether we're in grandprix if (!G_IsTitleCardAvailable()) return; @@ -690,35 +783,152 @@ void ST_runTitleCard(void) { // tick lt_ticker++; + + // SRB2KART + // side Zig-Zag positions... + + // TITLECARD START + if (lt_ticker < TTANIMSTART) + { + chev1x = (BASE_CHEV1X + 350) - lt_ticker*50; + if (chev1x < BASE_CHEV1X) + chev1x = BASE_CHEV1X; // min/max macros don't work well with signed, it seems + + chev2x = (BASE_CHEV2X - 350) + lt_ticker*50; + if (chev2x > BASE_CHEV2X) + chev2x = BASE_CHEV2X; // ditto + } + + // OPEN ZIG-ZAGS 1 SECOND IN + if (lt_ticker > TTANIMTHRESHOLD) + { + auxticker = lt_ticker - TTANIMTHRESHOLD; + + chev1x = BASE_CHEV1X + auxticker*16; + if (chev1x > 320) + chev1x = 320; + + chev1y = BASE_CHEV1Y - auxticker*16; + if (chev1y < 0) + chev1y = 0; + + chev2x = BASE_CHEV2X - auxticker*16; + if (chev2x < 0) + chev2x = 0; + + chev2y = BASE_CHEV2Y + auxticker*16; + if (chev2y > 200) + chev2y = 200; + + // 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 = 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 = 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 = 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 = 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 +939,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,66 +963,88 @@ 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, 31); -#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); + } // @@ -829,6 +1053,7 @@ luahook: void ST_preLevelTitleCardDrawer(void) { V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol); + ST_drawWipeTitleCard(); I_OsPolling(); I_UpdateNoBlit(); @@ -840,14 +1065,7 @@ void ST_preLevelTitleCardDrawer(void) // void ST_drawWipeTitleCard(void) { - UINT8 i; - - for (i = 0; i <= r_splitscreen; i++) - { - stplyr = &players[displayplayers[i]]; - ST_preDrawTitleCard(); - ST_drawTitleCard(); - } + ST_drawTitleCard(); } // diff --git a/src/v_video.c b/src/v_video.c index 85adeb4eb..5bd7ba733 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -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) diff --git a/src/v_video.h b/src/v_video.h index 08a279fd0..da4506c9a 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -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); From 66740e96dc025e8d76ab49008dbb143bdf9d294f Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Sat, 1 May 2021 12:01:00 +0200 Subject: [PATCH 23/26] slight optimizations + undefs --- src/st_stuff.c | 55 +++++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 43d1821ec..493d1b128 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -770,7 +770,7 @@ void ST_preDrawTitleCard(void) void ST_runTitleCard(void) { boolean run = !(paused || P_AutoPause()); - tic_t auxticker; + INT32 auxticker; boolean gp = (grandprixinfo.gp && grandprixinfo.roundnum); // check whether we're in grandprix if (!G_IsTitleCardAvailable()) @@ -790,35 +790,20 @@ void ST_runTitleCard(void) // TITLECARD START if (lt_ticker < TTANIMSTART) { - chev1x = (BASE_CHEV1X + 350) - lt_ticker*50; - if (chev1x < BASE_CHEV1X) - chev1x = BASE_CHEV1X; // min/max macros don't work well with signed, it seems - - chev2x = (BASE_CHEV2X - 350) + lt_ticker*50; - if (chev2x > BASE_CHEV2X) - chev2x = BASE_CHEV2X; // ditto + 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 = lt_ticker - TTANIMTHRESHOLD; + auxticker = (INT32)(lt_ticker) - TTANIMTHRESHOLD; - chev1x = BASE_CHEV1X + auxticker*16; - if (chev1x > 320) - chev1x = 320; + chev1x = min(320, BASE_CHEV1X + auxticker*16); + chev1y = max(0, BASE_CHEV1Y - auxticker*16); - chev1y = BASE_CHEV1Y - auxticker*16; - if (chev1y < 0) - chev1y = 0; - - chev2x = BASE_CHEV2X - auxticker*16; - if (chev2x < 0) - chev2x = 0; - - chev2y = BASE_CHEV2Y + auxticker*16; - if (chev2y > 200) - chev2y = 200; + 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; @@ -827,7 +812,7 @@ void ST_runTitleCard(void) // OPEN ZIG-ZAG: END OF ANIMATION (they leave the screen borders) if (lt_ticker > TTANIMENDTHRESHOLD) { - auxticker = lt_ticker - TTANIMENDTHRESHOLD; + auxticker = (INT32)lt_ticker - TTANIMENDTHRESHOLD; chev1x += auxticker*16; chev1y -= auxticker*16; @@ -861,7 +846,7 @@ void ST_runTitleCard(void) // SLIDE BAR OUT, SLIDE "ROUND" DOWNWARDS FASTER else if (lt_ticker >= TTANIMENDTHRESHOLD) { - auxticker = lt_ticker - TTANIMENDTHRESHOLD; + auxticker = (INT32)lt_ticker - TTANIMENDTHRESHOLD; roundx = FINAL_ROUNDX - auxticker*24; roundy = FINAL_ROUNDY + auxticker*48; @@ -881,7 +866,7 @@ void ST_runTitleCard(void) // split both halves of the egg, but only do that in grand prix! if (gp && lt_ticker > TTANIMTHRESHOLD + TICRATE/2) { - auxticker = lt_ticker - (TTANIMTHRESHOLD + TICRATE/2); + auxticker = (INT32)lt_ticker - (TTANIMTHRESHOLD + TICRATE/2); eggx1 -= auxticker*12; eggy1 -= auxticker*12; @@ -918,7 +903,7 @@ void ST_runTitleCard(void) // SLIDE BANNER DOWNWARDS OUT OF THE SCREEN AT THE END else if (lt_ticker >= TTANIMENDTHRESHOLD) { - auxticker = lt_ticker - TTANIMENDTHRESHOLD; + auxticker = (INT32)lt_ticker - TTANIMENDTHRESHOLD; bannery = FINAL_BANNERY + auxticker*16; } @@ -1047,6 +1032,22 @@ luahook: } +// 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. // From f559f24c0779966e78f0ebe7105dd23b3097e634 Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Sun, 2 May 2021 11:38:33 +0200 Subject: [PATCH 24/26] Encore support, gif fix and slight optimization --- src/f_wipe.c | 2 +- src/g_game.c | 37 +++++++++++++++++++------------------ src/st_stuff.c | 13 ++----------- src/st_stuff.h | 1 - 4 files changed, 22 insertions(+), 31 deletions(-) diff --git a/src/f_wipe.c b/src/f_wipe.c index 9399598f5..ddc719e6d 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -415,7 +415,7 @@ void F_WipeStageTitle(void) if ((WipeStageTitle) && G_IsTitleCardAvailable()) { ST_runTitleCard(); - ST_drawWipeTitleCard(); + ST_drawTitleCard(); } } diff --git a/src/g_game.c b/src/g_game.c index df2fbb931..580b3bf0d 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -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_drawTitleCard(); - 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 } diff --git a/src/st_stuff.c b/src/st_stuff.c index 493d1b128..ee03a07a4 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -950,7 +950,7 @@ void ST_drawTitleCard(void) // Avoid HOMs while drawing the start of the titlecard if (lt_ticker < TTANIMSTART) - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol); // Background zig-zags V_DrawFixedPatch((chev1x)*FRACUNIT, (chev1y)*FRACUNIT, FRACUNIT, chevtflag, tcchev1, NULL); @@ -1055,20 +1055,11 @@ 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) -{ - ST_drawTitleCard(); -} - // // Draw the status bar overlay, customisable: the user chooses which // kind of information to overlay diff --git a/src/st_stuff.h b/src/st_stuff.h index cc771c053..a17f72c1f 100644 --- a/src/st_stuff.h +++ b/src/st_stuff.h @@ -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; From 7fab92d73b6bfe40f3e3e5b59ac7add3ae3f89a0 Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 10 May 2021 14:21:13 +0100 Subject: [PATCH 25/26] Kickstartaccel demo fix An absolute dogshit clown-level code blunder from me, now corrected. --- src/g_demo.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/g_demo.c b/src/g_demo.c index 56f98cf73..a30d78878 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -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); From 82fa8755027ff3a6485740909b207ecb5c2fe5c7 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 12 Jun 2021 00:56:55 -0400 Subject: [PATCH 26/26] Refactor R_PointToAnglePlayer --- src/r_main.c | 58 ++++++++++++++++++---------------------------------- 1 file changed, 20 insertions(+), 38 deletions(-) diff --git a/src/r_main.c b/src/r_main.c index 97d946876..dfc11ab4a 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -318,18 +318,7 @@ INT32 R_PointOnSegSide(fixed_t x, fixed_t y, seg_t *line) angle_t R_PointToAngle(fixed_t x, fixed_t y) { - return (y -= viewy, (x -= viewx) || y) ? - x >= 0 ? - y >= 0 ? - (x > y) ? tantoangle[SlopeDiv(y,x)] : // octant 0 - ANGLE_90-tantoangle[SlopeDiv(x,y)] : // octant 1 - x > (y = -y) ? 0-tantoangle[SlopeDiv(y,x)] : // octant 8 - ANGLE_270+tantoangle[SlopeDiv(x,y)] : // octant 7 - y >= 0 ? (x = -x) > y ? ANGLE_180-tantoangle[SlopeDiv(y,x)] : // octant 3 - ANGLE_90 + tantoangle[SlopeDiv(x,y)] : // octant 2 - (x = -x) > (y = -y) ? ANGLE_180+tantoangle[SlopeDiv(y,x)] : // octant 4 - ANGLE_270-tantoangle[SlopeDiv(x,y)] : // octant 5 - 0; + return R_PointToAngle2(viewx, viewy, x, y); } // Similar to R_PointToAngle, but requires an additional player_t argument. @@ -338,33 +327,26 @@ angle_t R_PointToAngle(fixed_t x, fixed_t y) angle_t R_PointToAnglePlayer(player_t *player, fixed_t x, fixed_t y) { fixed_t refx = viewx, refy = viewy; - camera_t *cam = &camera[0]; - - // Check for splitscreen players and get their cam if possible. - if (player == &players[displayplayers[1]]) - cam = &camera[1]; - else if (player == &players[displayplayers[2]]) - cam = &camera[2]; - else if (player == &players[displayplayers[3]]) - cam = &camera[3]; - + camera_t *cam = NULL; + UINT8 i; + + for (i = 0; i < r_splitscreen; i++) + { + if (player == &players[displayplayers[i]]) + { + cam = &camera[i]; + break; + } + } + // use whatever cam we found's coordinates. - refx = cam->x; - refy = cam->y; - - // Now do whatever tehe fuck is this hellish maths from R_PointToAngle while swapping viewx/viewy for our refx/refy - return (y -= refy, (x -= refx) || y) ? - x >= 0 ? - y >= 0 ? - (x > y) ? tantoangle[SlopeDiv(y,x)] : // octant 0 - ANGLE_90-tantoangle[SlopeDiv(x,y)] : // octant 1 - x > (y = -y) ? 0-tantoangle[SlopeDiv(y,x)] : // octant 8 - ANGLE_270+tantoangle[SlopeDiv(x,y)] : // octant 7 - y >= 0 ? (x = -x) > y ? ANGLE_180-tantoangle[SlopeDiv(y,x)] : // octant 3 - ANGLE_90 + tantoangle[SlopeDiv(x,y)] : // octant 2 - (x = -x) > (y = -y) ? ANGLE_180+tantoangle[SlopeDiv(y,x)] : // octant 4 - ANGLE_270-tantoangle[SlopeDiv(x,y)] : // octant 5 - 0; + if (cam != NULL) + { + refx = cam->x; + refy = cam->y; + } + + return R_PointToAngle2(refx, refy, x, y); } // This version uses 64-bit variables to avoid overflows with large values.