From 897feac6516d4702cb057bce86cd63d02af4f0c4 Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Fri, 20 Mar 2020 14:59:38 +0100 Subject: [PATCH 01/64] Make SPB spawn damaging dust and sliptides while it moves around --- src/dehacked.c | 1 + src/info.c | 27 +++++++++++++++ src/info.h | 1 + src/p_enemy.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 119 insertions(+), 1 deletion(-) diff --git a/src/dehacked.c b/src/dehacked.c index 31986e942..2e4b89d41 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7999,6 +7999,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_KARMAFIREWORK", "MT_RINGSPARKS", "MT_DRAFTDUST", + "MT_SPBDUST", "MT_TIREGREASE", "MT_OVERTIMEFOG", diff --git a/src/info.c b/src/info.c index b1d95859b..fb56abcfa 100644 --- a/src/info.c +++ b/src/info.c @@ -20293,6 +20293,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_SPBDUST + -1, // doomednum + S_DRAFTDUST1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 16<floorz; + angle_t sa = mo->angle - ANG1*60; + INT32 i; + + if (mo->eflags & MFE_VERTICALFLIP) + sz = mo->ceilingz; + + if (leveltime & 1 && abs(mo->z - sz) < FRACUNIT*32) // Only ever other frame. Also don't spawn it if we're way above the ground. + { + // Determine spawning position next to the SPB: + for (i=0; i < 2; i++) + { + sx = mo->x + FixedMul((mo->scale*96), FINECOSINE((sa)>>ANGLETOFINESHIFT)); + sy = mo->y + FixedMul((mo->scale*96), FINESINE((sa)>>ANGLETOFINESHIFT)); + + dust = P_SpawnMobj(sx, sy, sz, MT_SPBDUST); + dust->momx = mo->momx/2; + dust->momy = mo->momy/2; + dust->momz = mo->momz/2; // Give some of the momentum to the dust + P_SetScale(dust, mo->scale*2); + dust->colorized = true; + dust->color = SKINCOLOR_RED; + dust->angle = mo->angle - FixedAngle(FRACUNIT*90 - FRACUNIT*180*i); // The first one will spawn to the right of the spb, the second one to the left. + P_Thrust(dust, dust->angle, 6*dust->scale); + + K_MatchGenericExtraFlags(dust, mo); + + sa += ANG1*120; // Add 120 degrees to get to mo->angle + ANG1*60 + } + } +} + +// Spawns SPB slip tide. To be used when the SPB is turning. +// Modified version of K_SpawnAIZDust. Maybe we could merge those to be cleaner? + +// dir should be either 1 or -1 to determine where to spawn the dust. + +static void SpawnSPBAIZDust(mobj_t *mo, INT32 dir) +{ + fixed_t newx; + fixed_t newy; + mobj_t *spark; + angle_t travelangle; + + travelangle = R_PointToAngle2(0, 0, mo->momx, mo->momy); + if (leveltime & 1) + { + newx = mo->x + P_ReturnThrustX(mo, travelangle - (dir*ANGLE_45), FixedMul(24*FRACUNIT, mo->scale)); + newy = mo->y + P_ReturnThrustY(mo, travelangle - (dir*ANGLE_45), FixedMul(24*FRACUNIT, mo->scale)); + spark = P_SpawnMobj(newx, newy, mo->z, MT_AIZDRIFTSTRAT); + spark->colorized = true; + spark->color = SKINCOLOR_RED; + spark->flags = MF_NOGRAVITY|MF_PAIN; + P_SetTarget(&spark->target, mo); + + spark->angle = travelangle+(dir*ANGLE_90); + P_SetScale(spark, (spark->destscale = mo->scale*3/2)); + + spark->momx = (6*mo->momx)/5; + spark->momy = (6*mo->momy)/5; + + K_MatchGenericExtraFlags(spark, mo); + } +} + void A_SPBChase(mobj_t *actor) { player_t *player = NULL; @@ -8703,6 +8775,12 @@ void A_SPBChase(mobj_t *actor) spbplace = bestrank; dist = P_AproxDistance(P_AproxDistance(actor->x-actor->tracer->x, actor->y-actor->tracer->y), actor->z-actor->tracer->z); + /* + K_GetBestWaypointForMobj returns the waypoint closest to the object that isn't its current waypoint. While this is usually good enough, + in cases where the track overlaps, this means that the SPB will sometimes target a waypoint on an earlier/later portion of the track instead of following along. + For this reason, we're going to try and make sure to avoid these situations. + */ + // Move along the waypoints until you get close enough if (actor->cusval > -1 && actor->extravalue2 > 0) { @@ -8770,6 +8848,8 @@ void A_SPBChase(mobj_t *actor) // Smoothly rotate horz angle angle_t input = hang - actor->angle; boolean invert = (input > ANGLE_180); + INT32 turnangle; + if (invert) input = InvAngle(input); @@ -8782,6 +8862,15 @@ void A_SPBChase(mobj_t *actor) input = InvAngle(input); actor->angle += input; + // If input is small enough, spawn dust. Otherwise, spawn a slip tide! + turnangle = AngleFixed(input)/FRACUNIT; + + // The SPB is really turning if that value is >= 3 and <= 357. This looks pretty bad check-wise so feel free to change it for something that isn't as terrible. + if (turnangle >= 3 && turnangle <= 357) + SpawnSPBAIZDust(actor, turnangle < 180 ? 1 : -1); // 1 if turning left, -1 if turning right. Angles work counterclockwise, remember! + else + SpawnSPBDust(actor); // if we're mostly going straight, then spawn the V dust cone! + // Smoothly rotate vert angle input = vang - actor->movedir; invert = (input > ANGLE_180); @@ -8830,7 +8919,7 @@ void A_SPBChase(mobj_t *actor) // Spawn a trail of rings behind the SPB! SpawnSPBTrailRings(actor); - if (dist <= (1024*actor->tracer->scale)) // Close enough to target? + if (dist <= (1024*actor->tracer->scale) && !actor->reactiontime) // Close enough to target? Reactiontime is used for debug purposes. { S_StartSound(actor, actor->info->attacksound); actor->extravalue1 = 1; // TARGET ACQUIRED From 366fff9942baeb9530d474fd4784a066af467294 Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Fri, 20 Mar 2020 21:58:14 +0100 Subject: [PATCH 02/64] Red rings, fuse, and spb game speed support --- src/k_kart.c | 19 ++++++++++++++----- src/k_kart.h | 1 + src/p_enemy.c | 51 +++++++++++++++++++++++++++++++-------------------- src/p_mobj.c | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 81 insertions(+), 25 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 27a4b1e1f..fd280f86e 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2499,20 +2499,29 @@ static void K_GetKartBoostPower(player_t *player) player->kartstuff[k_numboosts] = numboosts; } -fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower) +// Returns kart speed from a stat. Boost power and scale are NOT taken into account, no player or object is necessary. +fixed_t K_GetKartSpeedFromStat(UINT8 kartspeed) { const fixed_t xspd = (3*FRACUNIT)/64; fixed_t g_cc = K_GetKartGameSpeedScalar(gamespeed) + xspd; fixed_t k_speed = 150; - UINT8 kartspeed = player->kartspeed; fixed_t finalspeed; - if (G_BattleGametype() && player->kartstuff[k_bumper] <= 0) - kartspeed = 1; - k_speed += kartspeed*3; // 153 - 177 finalspeed = FixedMul(k_speed<<14, g_cc); + return finalspeed; +} + +fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower) +{ + fixed_t finalspeed; + UINT8 kartspeed = player->kartspeed; + + if (G_BattleGametype() && player->kartstuff[k_bumper] <= 0) + kartspeed = 1; + + finalspeed = K_GetKartSpeedFromStat(kartspeed); if (player->mo && !P_MobjWasRemoved(player->mo)) finalspeed = FixedMul(finalspeed, player->mo->scale); diff --git a/src/k_kart.h b/src/k_kart.h index ff6f6fafc..988b1b8ad 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -62,6 +62,7 @@ void K_DropItems(player_t *player); void K_StripItems(player_t *player); void K_StripOther(player_t *player); void K_MomentumToFacing(player_t *player); +fixed_t K_GetKartSpeedFromStat(UINT8 kartspeed); fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower); fixed_t K_GetKartAccel(player_t *player); UINT16 K_GetKartFlashing(player_t *player); diff --git a/src/p_enemy.c b/src/p_enemy.c index 0aa6a49ac..8c33aba3e 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8449,12 +8449,14 @@ static void SpawnSPBTrailRings(mobj_t *actor) { if (actor != NULL) { - if (leveltime % 6 == 0) + if (leveltime % (actor->extravalue1 == 2 ? 6 : 3) == 0) // Extravalue1 == 2 is seeking mode. Because the SPB is about twice as fast as normal in that mode, also spawn the rings twice as often to make up for it! { mobj_t *ring = P_SpawnMobj(actor->x - actor->momx, actor->y - actor->momy, actor->z - actor->momz + (24*mapobjectscale), MT_RING); ring->threshold = 10; - ring->fuse = 120*TICRATE; + ring->fuse = 35*TICRATE; + ring->colorized = true; + ring->color = SKINCOLOR_RED; } } } @@ -8473,7 +8475,7 @@ static void SpawnSPBDust(mobj_t *mo) if (mo->eflags & MFE_VERTICALFLIP) sz = mo->ceilingz; - if (leveltime & 1 && abs(mo->z - sz) < FRACUNIT*32) // Only ever other frame. Also don't spawn it if we're way above the ground. + if (leveltime & 1 && abs(mo->z - sz) < FRACUNIT*64) // Only ever other frame. Also don't spawn it if we're way above the ground. { // Determine spawning position next to the SPB: for (i=0; i < 2; i++) @@ -8509,13 +8511,17 @@ static void SpawnSPBAIZDust(mobj_t *mo, INT32 dir) fixed_t newy; mobj_t *spark; angle_t travelangle; + fixed_t sz = mo->floorz; + + if (mo->eflags & MFE_VERTICALFLIP) + sz = mo->ceilingz; travelangle = R_PointToAngle2(0, 0, mo->momx, mo->momy); - if (leveltime & 1) + if (leveltime & 1 && abs(mo->z - sz) < FRACUNIT*64) { newx = mo->x + P_ReturnThrustX(mo, travelangle - (dir*ANGLE_45), FixedMul(24*FRACUNIT, mo->scale)); newy = mo->y + P_ReturnThrustY(mo, travelangle - (dir*ANGLE_45), FixedMul(24*FRACUNIT, mo->scale)); - spark = P_SpawnMobj(newx, newy, mo->z, MT_AIZDRIFTSTRAT); + spark = P_SpawnMobj(newx, newy, sz, MT_AIZDRIFTSTRAT); spark->colorized = true; spark->color = SKINCOLOR_RED; spark->flags = MF_NOGRAVITY|MF_PAIN; @@ -8531,6 +8537,21 @@ static void SpawnSPBAIZDust(mobj_t *mo, INT32 dir) } } +// Used for seeking and when SPB is trailing its target from way too close! +static void SpawnSPBSpeedLines(mobj_t *actor) +{ + mobj_t *fast = P_SpawnMobj(actor->x + (P_RandomRange(-24,24) * actor->scale), + actor->y + (P_RandomRange(-24,24) * actor->scale), + actor->z + (actor->height/2) + (P_RandomRange(-24,24) * actor->scale), + MT_FASTLINE); + + fast->angle = R_PointToAngle2(0, 0, actor->momx, actor->momy); + fast->color = SKINCOLOR_RED; + fast->colorized = true; + K_MatchGenericExtraFlags(fast, actor); +} + + void A_SPBChase(mobj_t *actor) { player_t *player = NULL; @@ -8549,7 +8570,7 @@ void A_SPBChase(mobj_t *actor) #endif // Default speed - wspeed = actor->movefactor; + wspeed = FixedMul(mapobjectscale, K_GetKartSpeedFromStat(5)*2); // Go at twice the average speed a player would be going at! if (actor->threshold) // Just fired, go straight. { @@ -8701,19 +8722,7 @@ void A_SPBChase(mobj_t *actor) if (R_PointToDist2(0, 0, actor->momx, actor->momy) > (actor->tracer->player ? (16*actor->tracer->player->speed)/15 : (16*R_PointToDist2(0, 0, actor->tracer->momx, actor->tracer->momy))/15) // Going faster than the target && xyspeed > K_GetKartSpeed(actor->tracer->player, false)/4) // Don't display speedup lines at pitifully low speeds - { - mobj_t *fast = P_SpawnMobj(actor->x + (P_RandomRange(-24,24) * actor->scale), - actor->y + (P_RandomRange(-24,24) * actor->scale), - actor->z + (actor->height/2) + (P_RandomRange(-24,24) * actor->scale), - MT_FASTLINE); - fast->angle = R_PointToAngle2(0, 0, actor->momx, actor->momy); - //fast->momx = (3*actor->momx)/4; - //fast->momy = (3*actor->momy)/4; - //fast->momz = (3*actor->momz)/4; - fast->color = SKINCOLOR_RED; - fast->colorized = true; - K_MatchGenericExtraFlags(fast, actor); - } + SpawnSPBSpeedLines(actor); return; } @@ -8871,6 +8880,8 @@ void A_SPBChase(mobj_t *actor) else SpawnSPBDust(actor); // if we're mostly going straight, then spawn the V dust cone! + SpawnSPBSpeedLines(actor); // Always spawn speed lines while seeking + // Smoothly rotate vert angle input = vang - actor->movedir; invert = (input > ANGLE_180); @@ -8919,7 +8930,7 @@ void A_SPBChase(mobj_t *actor) // Spawn a trail of rings behind the SPB! SpawnSPBTrailRings(actor); - if (dist <= (1024*actor->tracer->scale) && !actor->reactiontime) // Close enough to target? Reactiontime is used for debug purposes. + if (dist <= (1024*actor->tracer->scale) && !(actor->flags2 & MF2_AMBUSH)) // Close enough to target? Use Ambush flag to disable targetting so I can have an easier time testing stuff... { S_StartSound(actor, actor->info->attacksound); actor->extravalue1 = 1; // TARGET ACQUIRED diff --git a/src/p_mobj.c b/src/p_mobj.c index 4ef291c82..2fcc99a08 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3982,6 +3982,9 @@ void P_PrecipThinker(precipmobj_t *mobj) static void P_RingThinker(mobj_t *mobj) { + + mobj_t *spark; // Ring Fuse + if (mobj->momx || mobj->momy) { P_RingXYMovement(mobj); @@ -4001,6 +4004,38 @@ static void P_RingThinker(mobj_t *mobj) return; } + // This thinker splits apart before the regular fuse handling so we need to handle it here instead. + if (mobj->fuse) + { + mobj->fuse--; + + if (mobj->fuse < TICRATE*3) + { + if (leveltime & 1) + mobj->flags2 |= MF2_DONTDRAW; + else + mobj->flags2 &= ~MF2_DONTDRAW; + } + + if (!mobj->fuse) + { +#ifdef HAVE_BLUA + if (!LUAh_MobjFuse(mobj)) +#endif + { + mobj->flags2 &= ~MF2_DONTDRAW; + spark = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_SIGNSPARKLE); // Spawn a fancy sparkle + K_MatchGenericExtraFlags(spark, mobj); + spark->colorized = true; + spark->color = mobj->color ? : SKINCOLOR_YELLOW; // Use yellow if the ring doesn't use a skin color. (It should be red for SPB rings, but let normal rings look fancy too!) + P_RemoveMobj(mobj); // Adieu, monde cruel! + return; + } + + } + + } + P_CycleMobjState(mobj); } From ae3c4a0227436eb78092ce437774cafe4b97a619 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 14 Apr 2017 20:43:30 +0100 Subject: [PATCH 03/64] Removal of cv_allcaps for console stuff. (cherry picked from commit 95d89078f5bb7a9d8ce52cff129e54a7ec2e4744) --- src/console.c | 20 ++++++++++---------- src/hu_stuff.c | 20 ++++++++++---------- src/m_menu.c | 3 --- src/v_video.c | 2 -- src/v_video.h | 2 +- 5 files changed, 21 insertions(+), 26 deletions(-) diff --git a/src/console.c b/src/console.c index 1defa7e82..ec1e892ed 100644 --- a/src/console.c +++ b/src/console.c @@ -1474,32 +1474,32 @@ static void CON_DrawInput(void) if (input_sel < c) V_DrawFill(x, y, charwidth*3, (10 * con_scalefactor), 77 | V_NOSCALESTART); for (i = 0; i < 3; ++i, x += charwidth) - V_DrawCharacter(x, y, '.' | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, !cv_allcaps.value); + V_DrawCharacter(x, y, '.' | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, true); } else - V_DrawCharacter(x-charwidth, y, CON_PROMPTCHAR | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, !cv_allcaps.value); + V_DrawCharacter(x-charwidth, y, CON_PROMPTCHAR | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, true); for (cend = c + clen; c < cend; ++c, x += charwidth) { if ((input_sel > c && input_cur <= c) || (input_sel <= c && input_cur > c)) { V_DrawFill(x, y, charwidth, (10 * con_scalefactor), 77 | V_NOSCALESTART); - V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_YELLOWMAP | V_NOSCALESTART, !cv_allcaps.value); + V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_YELLOWMAP | V_NOSCALESTART, true); } else - V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); + V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_NOSCALESTART, true); if (c == input_cur && con_tick >= 4) - V_DrawCharacter(x, y + (con_scalefactor*2), '_' | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); + V_DrawCharacter(x, y + (con_scalefactor*2), '_' | cv_constextsize.value | V_NOSCALESTART, true); } if (cend == input_cur && con_tick >= 4) - V_DrawCharacter(x, y + (con_scalefactor*2), '_' | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); + V_DrawCharacter(x, y + (con_scalefactor*2), '_' | cv_constextsize.value | V_NOSCALESTART, true); if (rellip) { if (input_sel > cend) V_DrawFill(x, y, charwidth*3, (10 * con_scalefactor), 77 | V_NOSCALESTART); for (i = 0; i < 3; ++i, x += charwidth) - V_DrawCharacter(x, y, '.' | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, !cv_allcaps.value); + V_DrawCharacter(x, y, '.' | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, true); } } @@ -1545,11 +1545,11 @@ static void CON_DrawHudlines(void) else { //charwidth = SHORT(hu_font['A'-HU_FONTSTART]->width) * con_scalefactor; - V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); + V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, true); } } - //V_DrawCharacter(x, y, (p[c]&0xff) | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); + //V_DrawCharacter(x, y, (p[c]&0xff) | cv_constextsize.value | V_NOSCALESTART, true); y += charheight; } @@ -1620,7 +1620,7 @@ static void CON_DrawConsole(void) charflags = (*p & 0x7f) << V_CHARCOLORSHIFT; p++; } - V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); + V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, true); } } diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 76b85dd01..a454aaecc 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1583,7 +1583,7 @@ static void HU_drawMiniChat(void) if (cv_chatbacktint.value) // on request of wolfy V_DrawFillConsoleMap(x + dx + 2, y+dy, charwidth, charheight, 159|V_SNAPTOBOTTOM|V_SNAPTOLEFT); - V_DrawChatCharacter(x + dx + 2, y+dy, msg[j++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|transflag, !cv_allcaps.value, colormap); + V_DrawChatCharacter(x + dx + 2, y+dy, msg[j++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|transflag, true, colormap); } dx += charwidth; @@ -1677,7 +1677,7 @@ static void HU_drawChatLog(INT32 offset) else { if ((y+dy+2 >= chat_topy) && (y+dy < (chat_bottomy))) - V_DrawChatCharacter(x + dx + 2, y+dy+2, msg[j++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT, !cv_allcaps.value, colormap); + V_DrawChatCharacter(x + dx + 2, y+dy+2, msg[j++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT, true, colormap); else j++; // don't forget to increment this or we'll get stuck in the limbo. } @@ -1778,7 +1778,7 @@ static void HU_DrawChat(void) ++i; else { - V_DrawChatCharacter(chatx + c + 2, y, talk[i] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|cflag, !cv_allcaps.value, V_GetStringColormap(talk[i]|cflag)); + V_DrawChatCharacter(chatx + c + 2, y, talk[i] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|cflag, true, V_GetStringColormap(talk[i]|cflag)); i++; } @@ -1796,7 +1796,7 @@ static void HU_DrawChat(void) typelines = 1; if ((strlen(w_chat) == 0 || c_input == 0) && hu_tick < 4) - V_DrawChatCharacter(chatx + 2 + c, y+1, '_' |V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL); + V_DrawChatCharacter(chatx + 2 + c, y+1, '_' |V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, true, NULL); while (w_chat[i]) { @@ -1806,7 +1806,7 @@ static void HU_DrawChat(void) INT32 cursorx = (c+charwidth < boxw-charwidth) ? (chatx + 2 + c+charwidth) : (chatx+1); // we may have to go down. INT32 cursory = (cursorx != chatx+1) ? (y) : (y+charheight); if (hu_tick < 4) - V_DrawChatCharacter(cursorx, cursory+1, '_' |V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL); + V_DrawChatCharacter(cursorx, cursory+1, '_' |V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, true, NULL); if (cursorx == chatx+1 && saylen == i) // a weirdo hack { @@ -1819,7 +1819,7 @@ static void HU_DrawChat(void) if (w_chat[i] < HU_FONTSTART) ++i; else - V_DrawChatCharacter(chatx + c + 2, y, w_chat[i++] | V_SNAPTOBOTTOM|V_SNAPTOLEFT | t, !cv_allcaps.value, NULL); + V_DrawChatCharacter(chatx + c + 2, y, w_chat[i++] | V_SNAPTOBOTTOM|V_SNAPTOLEFT | t, true, NULL); c += charwidth; if (c > boxw-(charwidth*2) && !skippedline) @@ -1945,13 +1945,13 @@ static void HU_DrawChat_Old(void) else { //charwidth = SHORT(hu_font[talk[i]-HU_FONTSTART]->width) * con_scalefactor; - V_DrawCharacter(HU_INPUTX + c, y, talk[i++] | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); + V_DrawCharacter(HU_INPUTX + c, y, talk[i++] | cv_constextsize.value | V_NOSCALESTART, true); } c += charwidth; } if ((strlen(w_chat) == 0 || c_input == 0) && hu_tick < 4) - V_DrawCharacter(HU_INPUTX+c, y+2*con_scalefactor, '_' |cv_constextsize.value | V_NOSCALESTART|t, !cv_allcaps.value); + V_DrawCharacter(HU_INPUTX+c, y+2*con_scalefactor, '_' |cv_constextsize.value | V_NOSCALESTART|t, true); i = 0; while (w_chat[i]) @@ -1961,7 +1961,7 @@ static void HU_DrawChat_Old(void) { INT32 cursorx = (HU_INPUTX+c+charwidth < vid.width) ? (HU_INPUTX + c + charwidth) : (HU_INPUTX); // we may have to go down. INT32 cursory = (cursorx != HU_INPUTX) ? (y) : (y+charheight); - V_DrawCharacter(cursorx, cursory+2*con_scalefactor, '_' |cv_constextsize.value | V_NOSCALESTART|t, !cv_allcaps.value); + V_DrawCharacter(cursorx, cursory+2*con_scalefactor, '_' |cv_constextsize.value | V_NOSCALESTART|t, true); } //Hurdler: isn't it better like that? @@ -1973,7 +1973,7 @@ static void HU_DrawChat_Old(void) else { //charwidth = SHORT(hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor; - V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | cv_constextsize.value | V_NOSCALESTART | t, !cv_allcaps.value); + V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | cv_constextsize.value | V_NOSCALESTART | t, true); } c += charwidth; diff --git a/src/m_menu.c b/src/m_menu.c index 68aae68eb..6ac2ef5ab 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3321,9 +3321,6 @@ void M_Init(void) #ifndef NONET CV_RegisterVar(&cv_serversort); #endif - - //todo put this somewhere better... - CV_RegisterVar(&cv_allcaps); } void M_InitCharacterTables(void) diff --git a/src/v_video.c b/src/v_video.c index 297eae9c4..274c14b38 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -44,8 +44,6 @@ static void CV_usegamma_OnChange(void); consvar_t cv_ticrate = {"showfps", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_usegamma = {"gamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_usegamma_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_allcaps = {"allcaps", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; - static CV_PossibleValue_t constextsize_cons_t[] = { {V_NOSCALEPATCH, "Small"}, {V_SMALLSCALEPATCH, "Medium"}, {V_MEDSCALEPATCH, "Large"}, {0, "Huge"}, {0, NULL}}; diff --git a/src/v_video.h b/src/v_video.h index eb60690bd..d229c370f 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -28,7 +28,7 @@ extern UINT8 *screens[5]; extern const UINT8 gammatable[5][256]; -extern consvar_t cv_ticrate, cv_usegamma, cv_allcaps, cv_constextsize; +extern consvar_t cv_ticrate, cv_usegamma, cv_constextsize; // Allocates buffer screens, call before R_Init. void V_Init(void); From f5ecb1b9c90b5eac35b5c7e5f72d21b09d7d884a Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 23 Mar 2020 16:27:14 -0700 Subject: [PATCH 04/64] Introducing the Colour Cube! https://cdn.discordapp.com/attachments/293238104096112641/304015171385294850/aa.png Basically in preperation of supporting colourblindness modes I implemented the following link when loading palettes. http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter24.html This basically means I can do whatever the hell I want to the colour profile of incoming paletties, and nobody can stop me. Muahahahaha etc. Also, I added a saturation feature to show off its full potential, converted gamma from a table to a factor of the calculation, tweaked some menus and made the default value of cvars show up on sliders. Because that's how I roll. (cherry picked from commit 83e16da83bb1a2e3be7ee8a5fd4a779797294fc8) # Conflicts: # src/m_menu.c --- src/d_netcmd.c | 1 + src/v_video.c | 251 +++++++++++++++++++++++++++++++------------------ src/v_video.h | 3 +- 3 files changed, 164 insertions(+), 91 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 88621ee66..489590978 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -857,6 +857,7 @@ void D_RegisterClientCommands(void) // FIXME: not to be here.. but needs be done for config loading CV_RegisterVar(&cv_usegamma); + CV_RegisterVar(&cv_usesaturation); // m_menu.c //CV_RegisterVar(&cv_compactscoreboard); diff --git a/src/v_video.c b/src/v_video.c index 274c14b38..f380f0d99 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -38,12 +38,15 @@ UINT8 *screens[5]; // screens[3] = fade screen start // screens[4] = fade screen end, postimage tempoarary buffer -static CV_PossibleValue_t gamma_cons_t[] = {{0, "MIN"}, {4, "MAX"}, {0, NULL}}; +static CV_PossibleValue_t gamma_cons_t[] = {{-5, "MIN"}, {5, "MAX"}, {0, NULL}}; static void CV_usegamma_OnChange(void); consvar_t cv_ticrate = {"showfps", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_usegamma = {"gamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_usegamma_OnChange, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t saturation_cons_t[] = {{0, "MIN"}, {10, "MAX"}, {0, NULL}}; +consvar_t cv_usesaturation = {"saturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_usegamma_OnChange, 0, NULL, NULL, 0, 0, NULL}; + static CV_PossibleValue_t constextsize_cons_t[] = { {V_NOSCALEPATCH, "Small"}, {V_SMALLSCALEPATCH, "Medium"}, {V_MEDSCALEPATCH, "Large"}, {0, "Huge"}, {0, NULL}}; @@ -82,97 +85,123 @@ consvar_t cv_grfallbackplayermodel = {"gr_fallbackplayermodel", "Off", CV_SAVE, consvar_t cv_grspritebillboarding = {"gr_spritebillboarding", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; #endif -const UINT8 gammatable[5][256] = -{ - {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16, - 17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32, - 33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48, - 49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64, - 65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80, - 81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96, - 97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112, - 113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128, - 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, - 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, - 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, - 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, - 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, - 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, - 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, - 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255}, - - {2,4,5,7,8,10,11,12,14,15,16,18,19,20,21,23,24,25,26,27,29,30,31, - 32,33,34,36,37,38,39,40,41,42,44,45,46,47,48,49,50,51,52,54,55, - 56,57,58,59,60,61,62,63,64,65,66,67,69,70,71,72,73,74,75,76,77, - 78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98, - 99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114, - 115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,129, - 130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145, - 146,147,148,148,149,150,151,152,153,154,155,156,157,158,159,160, - 161,162,163,163,164,165,166,167,168,169,170,171,172,173,174,175, - 175,176,177,178,179,180,181,182,183,184,185,186,186,187,188,189, - 190,191,192,193,194,195,196,196,197,198,199,200,201,202,203,204, - 205,205,206,207,208,209,210,211,212,213,214,214,215,216,217,218, - 219,220,221,222,222,223,224,225,226,227,228,229,230,230,231,232, - 233,234,235,236,237,237,238,239,240,241,242,243,244,245,245,246, - 247,248,249,250,251,252,252,253,254,255}, - - {4,7,9,11,13,15,17,19,21,22,24,26,27,29,30,32,33,35,36,38,39,40,42, - 43,45,46,47,48,50,51,52,54,55,56,57,59,60,61,62,63,65,66,67,68,69, - 70,72,73,74,75,76,77,78,79,80,82,83,84,85,86,87,88,89,90,91,92,93, - 94,95,96,97,98,100,101,102,103,104,105,106,107,108,109,110,111,112, - 113,114,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128, - 129,130,131,132,133,133,134,135,136,137,138,139,140,141,142,143,144, - 144,145,146,147,148,149,150,151,152,153,153,154,155,156,157,158,159, - 160,160,161,162,163,164,165,166,166,167,168,169,170,171,172,172,173, - 174,175,176,177,178,178,179,180,181,182,183,183,184,185,186,187,188, - 188,189,190,191,192,193,193,194,195,196,197,197,198,199,200,201,201, - 202,203,204,205,206,206,207,208,209,210,210,211,212,213,213,214,215, - 216,217,217,218,219,220,221,221,222,223,224,224,225,226,227,228,228, - 229,230,231,231,232,233,234,235,235,236,237,238,238,239,240,241,241, - 242,243,244,244,245,246,247,247,248,249,250,251,251,252,253,254,254, - 255}, - - {8,12,16,19,22,24,27,29,31,34,36,38,40,41,43,45,47,49,50,52,53,55, - 57,58,60,61,63,64,65,67,68,70,71,72,74,75,76,77,79,80,81,82,84,85, - 86,87,88,90,91,92,93,94,95,96,98,99,100,101,102,103,104,105,106,107, - 108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124, - 125,126,127,128,129,130,131,132,133,134,135,135,136,137,138,139,140, - 141,142,143,143,144,145,146,147,148,149,150,150,151,152,153,154,155, - 155,156,157,158,159,160,160,161,162,163,164,165,165,166,167,168,169, - 169,170,171,172,173,173,174,175,176,176,177,178,179,180,180,181,182, - 183,183,184,185,186,186,187,188,189,189,190,191,192,192,193,194,195, - 195,196,197,197,198,199,200,200,201,202,202,203,204,205,205,206,207, - 207,208,209,210,210,211,212,212,213,214,214,215,216,216,217,218,219, - 219,220,221,221,222,223,223,224,225,225,226,227,227,228,229,229,230, - 231,231,232,233,233,234,235,235,236,237,237,238,238,239,240,240,241, - 242,242,243,244,244,245,246,246,247,247,248,249,249,250,251,251,252, - 253,253,254,254,255}, - - {16,23,28,32,36,39,42,45,48,50,53,55,57,60,62,64,66,68,69,71,73,75,76, - 78,80,81,83,84,86,87,89,90,92,93,94,96,97,98,100,101,102,103,105,106, - 107,108,109,110,112,113,114,115,116,117,118,119,120,121,122,123,124, - 125,126,128,128,129,130,131,132,133,134,135,136,137,138,139,140,141, - 142,143,143,144,145,146,147,148,149,150,150,151,152,153,154,155,155, - 156,157,158,159,159,160,161,162,163,163,164,165,166,166,167,168,169, - 169,170,171,172,172,173,174,175,175,176,177,177,178,179,180,180,181, - 182,182,183,184,184,185,186,187,187,188,189,189,190,191,191,192,193, - 193,194,195,195,196,196,197,198,198,199,200,200,201,202,202,203,203, - 204,205,205,206,207,207,208,208,209,210,210,211,211,212,213,213,214, - 214,215,216,216,217,217,218,219,219,220,220,221,221,222,223,223,224, - 224,225,225,226,227,227,228,228,229,229,230,230,231,232,232,233,233, - 234,234,235,235,236,236,237,237,238,239,239,240,240,241,241,242,242, - 243,243,244,244,245,245,246,246,247,247,248,248,249,249,250,250,251, - 251,252,252,253,254,254,255,255} -}; - // local copy of the palette for V_GetColor() RGBA_t *pLocalPalette = NULL; +/* +The following was an extremely helpful resource when developing my Colour Cube LUT. +http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter24.html +Please check it out if you're trying to maintain this. +toast 18/04/17 +*/ + +float Cubepal[2][2][2][3]; + +// returns whether to apply cube, selectively avoiding expensive operations +static boolean InitCube(void) +{ + boolean apply = false; + UINT8 q; + float working[2][2][2][3] = // the initial positions of the corners of the colour cube! + { + { + { + {0.0, 0.0, 0.0}, // black corner + {1.0, 0.0, 0.0} // red corner + }, + { + {0.0, 1.0, 0.0}, // green corner + {1.0, 1.0, 0.0} // yellow corner + } + }, + { + { + {0.0, 0.0, 1.0}, // blue corner + {1.0, 0.0, 1.0} // magenta corner + }, + { + {0.0, 1.0, 1.0}, // cyan corner + {1.0, 1.0, 1.0} // white corner + } + } + }; + + if (cv_usegamma.value) + { +#define gammascale 8 + float gammamul = (255 - (gammascale*abs(cv_usegamma.value)))/255.0; + float gammaoffs = ((cv_usegamma.value > 0) ? ((gammascale*cv_usegamma.value)/255.0) : 0.0); +#undef gammascale + + apply = true; + + #define dogamma(i, j, k, l) \ + working[i][j][k][l]*= gammamul;\ + working[i][j][k][l] += gammaoffs + for (q = 0; q < 3; q++) + { + dogamma(0, 0, 0, q); + dogamma(1, 0, 0, q); + dogamma(0, 1, 0, q); + dogamma(1, 1, 0, q); + dogamma(0, 0, 1, q); + dogamma(1, 0, 1, q); + dogamma(0, 1, 1, q); + dogamma(1, 1, 1, q); + } +#undef dogamma + } + + if (cv_usesaturation.value != 10) + { + float desatur[3] = {0.33, 0.33, 0.33}; // grey + float work = (cv_usesaturation.value/10.0); + + apply = true; + +#define dosaturation(a, e) a = ((1 - work)*e + work*a) + for (q = 0; q < 3; q++) + { + dosaturation(working[0][0][1][q], desatur[q]); + dosaturation(working[0][1][0][q], desatur[q]); + dosaturation(working[1][0][0][q], desatur[q]); + + dosaturation(working[1][1][0][q], 2*desatur[q]); + dosaturation(working[1][0][1][q], 2*desatur[q]); + dosaturation(working[0][1][1][q], 2*desatur[q]); + } +#undef dosaturation + } + + if (!apply) + return false; + +#define dowork(i, j, k, l) \ + if (working[i][j][k][l] > 1.0)\ + working[i][j][k][l] = 1.0;\ + else if (working[i][j][k][l] < 0.0)\ + working[i][j][k][l] = 0.0;\ + Cubepal[i][j][k][l] = working[i][j][k][l] + for (q = 0; q < 3; q++) + { + dowork(0, 0, 0, q); + dowork(1, 0, 0, q); + dowork(0, 1, 0, q); + dowork(1, 1, 0, q); + dowork(0, 0, 1, q); + dowork(1, 0, 1, q); + dowork(0, 1, 1, q); + dowork(1, 1, 1, q); + } +#undef dowork + + return true; +} + // keep a copy of the palette so that we can get the RGB value for a color index at any time. static void LoadPalette(const char *lumpname) { - const UINT8 *usegamma = gammatable[cv_usegamma.value]; + boolean cube = InitCube(); lumpnum_t lumpnum = W_GetNumForName(lumpname); size_t i, palsize = W_LumpLength(lumpnum)/3; UINT8 *pal; @@ -184,10 +213,54 @@ static void LoadPalette(const char *lumpname) pal = W_CacheLumpNum(lumpnum, PU_CACHE); for (i = 0; i < palsize; i++) { - pLocalPalette[i].s.red = usegamma[*pal++]; - pLocalPalette[i].s.green = usegamma[*pal++]; - pLocalPalette[i].s.blue = usegamma[*pal++]; + pLocalPalette[i].s.red = *pal++; + pLocalPalette[i].s.green = *pal++; + pLocalPalette[i].s.blue = *pal++; pLocalPalette[i].s.alpha = 0xFF; + + // lerp of colour cubing! + if (cube) + { + float working[4][3]; + float linear; + UINT8 q; + + linear = (pLocalPalette[i].s.red/255.0); +#define dolerp(e1, e2) ((1 - linear)*e1 + linear*e2) + for (q = 0; q < 3; q++) + { + working[0][q] = dolerp(Cubepal[0][0][0][q], Cubepal[1][0][0][q]); + working[1][q] = dolerp(Cubepal[0][1][0][q], Cubepal[1][1][0][q]); + working[2][q] = dolerp(Cubepal[0][0][1][q], Cubepal[1][0][1][q]); + working[3][q] = dolerp(Cubepal[0][1][1][q], Cubepal[1][1][1][q]); + } + linear = (pLocalPalette[i].s.green/255.0); + for (q = 0; q < 3; q++) + { + working[0][q] = dolerp(working[0][q], working[1][q]); + working[1][q] = dolerp(working[2][q], working[3][q]); + } + linear = (pLocalPalette[i].s.blue/255.0); + for (q = 0; q < 3; q++) + { + working[0][q] = 255*dolerp(working[0][q], working[1][q]); + if (working[0][q] > 255.0) + working[0][q] = 255.0; + else if (working[0][q] < 0.0) + working[0][q] = 0.0; + } +#undef dowork + + /* + I don't know what I messed up such that red takes index 2 and blue takes index 0. + It should be the other way around, but I've just got this working after spending + hours on it and I'm not going to look a gift ho(rse/t)fix in the mouth. + toast 18/04/17 + */ + pLocalPalette[i].s.red = (UINT8)(working[0][2]); + pLocalPalette[i].s.green = (UINT8)(working[0][1]); + pLocalPalette[i].s.blue = (UINT8)(working[0][0]); + } } } diff --git a/src/v_video.h b/src/v_video.h index d229c370f..8b35b920a 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -27,8 +27,7 @@ extern UINT8 *screens[5]; -extern const UINT8 gammatable[5][256]; -extern consvar_t cv_ticrate, cv_usegamma, cv_constextsize; +extern consvar_t cv_ticrate, cv_usegamma, cv_usesaturation, cv_constextsize; // Allocates buffer screens, call before R_Init. void V_Init(void); From a82e5ee91631057e80c32851bc77880f2980122f Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 18 Apr 2017 23:38:38 +0100 Subject: [PATCH 05/64] Figured out what was up. I didn't quite understand my original array! (cherry picked from commit c2edd6224da250d251013a10495403d3af1ed074) --- src/v_video.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/v_video.c b/src/v_video.c index f380f0d99..ffc5afc37 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -107,20 +107,20 @@ static boolean InitCube(void) { { {0.0, 0.0, 0.0}, // black corner - {1.0, 0.0, 0.0} // red corner + {0.0, 0.0, 1.0} // blue corner }, { - {0.0, 1.0, 0.0}, // green corner - {1.0, 1.0, 0.0} // yellow corner + {0.0, 1.0, 0.0}, // greem corner + {0.0, 1.0, 1.0} // cyan corner } }, { { - {0.0, 0.0, 1.0}, // blue corner + {1.0, 0.0, 0.0}, // red corner {1.0, 0.0, 1.0} // magenta corner }, { - {0.0, 1.0, 1.0}, // cyan corner + {1.0, 1.0, 0.0}, // yellow corner {1.0, 1.0, 1.0} // white corner } } @@ -251,15 +251,9 @@ static void LoadPalette(const char *lumpname) } #undef dowork - /* - I don't know what I messed up such that red takes index 2 and blue takes index 0. - It should be the other way around, but I've just got this working after spending - hours on it and I'm not going to look a gift ho(rse/t)fix in the mouth. - toast 18/04/17 - */ - pLocalPalette[i].s.red = (UINT8)(working[0][2]); + pLocalPalette[i].s.red = (UINT8)(working[0][0]); pLocalPalette[i].s.green = (UINT8)(working[0][1]); - pLocalPalette[i].s.blue = (UINT8)(working[0][0]); + pLocalPalette[i].s.blue = (UINT8)(working[0][2]); } } } From b1202b617cb49d63f3d346cb37a7c12d1555e0db Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 18 Apr 2017 23:40:57 +0100 Subject: [PATCH 06/64] greem (cherry picked from commit 9b13caccae4e298b7ee99035e679f08fec5519f2) --- src/v_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/v_video.c b/src/v_video.c index ffc5afc37..fddfa07a7 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -110,7 +110,7 @@ static boolean InitCube(void) {0.0, 0.0, 1.0} // blue corner }, { - {0.0, 1.0, 0.0}, // greem corner + {0.0, 1.0, 0.0}, // green corner {0.0, 1.0, 1.0} // cyan corner } }, From fcc80b12ad2203dd79b93dc463ebcea687688bfd Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 23 Mar 2020 16:32:11 -0700 Subject: [PATCH 07/64] Colour Cube Calibration Menu! (called "Advanced Color Settings" because No Fun Allowed...) https://cdn.discordapp.com/attachments/237798387070664724/304343382073933824/aa.png Also, a "Reset all" button for the Monitor toggle menu, a ton of new cvars to match up with the colour cube calibration, and a bunch of variable renames related to colour cube operations. (cherry picked from commit c3840ba01d866d257434b2abdad40ef3b0cb581f) # Conflicts: # src/m_menu.c # src/v_video.c --- src/d_netcmd.c | 25 ++++++- src/m_menu.c | 4 +- src/v_video.c | 181 +++++++++++++++++++++++++++++++++++++++---------- src/v_video.h | 6 +- 4 files changed, 174 insertions(+), 42 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 489590978..03096197a 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -856,8 +856,29 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_netdemosyncquality); // FIXME: not to be here.. but needs be done for config loading - CV_RegisterVar(&cv_usegamma); - CV_RegisterVar(&cv_usesaturation); + CV_RegisterVar(&cv_globalgamma); + CV_RegisterVar(&cv_globalsaturation); + + CV_RegisterVar(&cv_rhue); + CV_RegisterVar(&cv_yhue); + CV_RegisterVar(&cv_ghue); + CV_RegisterVar(&cv_chue); + CV_RegisterVar(&cv_bhue); + CV_RegisterVar(&cv_mhue); + + CV_RegisterVar(&cv_rgamma); + CV_RegisterVar(&cv_ygamma); + CV_RegisterVar(&cv_ggamma); + CV_RegisterVar(&cv_cgamma); + CV_RegisterVar(&cv_bgamma); + CV_RegisterVar(&cv_mgamma); + + CV_RegisterVar(&cv_rsaturation); + CV_RegisterVar(&cv_ysaturation); + CV_RegisterVar(&cv_gsaturation); + CV_RegisterVar(&cv_csaturation); + CV_RegisterVar(&cv_bsaturation); + CV_RegisterVar(&cv_msaturation); // m_menu.c //CV_RegisterVar(&cv_compactscoreboard); diff --git a/src/m_menu.c b/src/m_menu.c index 6ac2ef5ab..4bbaa1205 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1252,7 +1252,7 @@ static menuitem_t OP_VideoOptionsMenu[] = {IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 20}, #endif {IT_STRING | IT_CVAR | IT_CV_SLIDER, - NULL, "Gamma", &cv_usegamma, 30}, + NULL, "Gamma", &cv_globalgamma, 30}, {IT_STRING | IT_CVAR, NULL, "Draw Distance", &cv_drawdist, 45}, //{IT_STRING | IT_CVAR, NULL, "NiGHTS Draw Dist", &cv_drawdist_nights, 55}, @@ -2675,7 +2675,7 @@ boolean M_Responder(event_t *ev) return true; case KEY_F11: // Gamma Level - CV_AddValue(&cv_usegamma, 1); + CV_AddValue(&cv_globalgamma, 1); return true; // Spymode on F12 handled in game logic diff --git a/src/v_video.c b/src/v_video.c index fddfa07a7..1a7aabc82 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -38,14 +38,39 @@ UINT8 *screens[5]; // screens[3] = fade screen start // screens[4] = fade screen end, postimage tempoarary buffer -static CV_PossibleValue_t gamma_cons_t[] = {{-5, "MIN"}, {5, "MAX"}, {0, NULL}}; -static void CV_usegamma_OnChange(void); +consvar_t cv_ticrate = {"showfps", "No", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_ticrate = {"showfps", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_usegamma = {"gamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_usegamma_OnChange, 0, NULL, NULL, 0, 0, NULL}; +static void CV_palette_OnChange(void); + +static CV_PossibleValue_t gamma_cons_t[] = {{-15, "MIN"}, {5, "MAX"}, {0, NULL}}; +consvar_t cv_globalgamma = {"gamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t saturation_cons_t[] = {{0, "MIN"}, {10, "MAX"}, {0, NULL}}; -consvar_t cv_usesaturation = {"saturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_usegamma_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_globalsaturation = {"saturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; + +#define huecoloursteps 4 + +static CV_PossibleValue_t hue_cons_t[] = {{0, "MIN"}, {(huecoloursteps*6)-1, "MAX"}, {0, NULL}}; +consvar_t cv_rhue = {"rhue", "0", CV_SAVE|CV_CALL, hue_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_yhue = {"yhue", "4", CV_SAVE|CV_CALL, hue_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_ghue = {"ghue", "8", CV_SAVE|CV_CALL, hue_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_chue = {"chue", "12", CV_SAVE|CV_CALL, hue_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_bhue = {"bhue", "16", CV_SAVE|CV_CALL, hue_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_mhue = {"mhue", "20", CV_SAVE|CV_CALL, hue_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; + +consvar_t cv_rgamma = {"rgamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_ygamma = {"ygamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_ggamma = {"ggamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_cgamma = {"cgamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_bgamma = {"bgamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_mgamma = {"mgamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; + +consvar_t cv_rsaturation = {"rsaturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_ysaturation = {"ysaturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_gsaturation = {"gsaturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_csaturation = {"csaturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_bsaturation = {"bsaturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_msaturation = {"msaturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t constextsize_cons_t[] = { {V_NOSCALEPATCH, "Small"}, {V_SMALLSCALEPATCH, "Medium"}, {V_MEDSCALEPATCH, "Large"}, {0, "Huge"}, @@ -125,54 +150,136 @@ static boolean InitCube(void) } } }; + float desatur[3]; // grey + float globalgammamul, globalgammaoffs; + boolean doinggamma; + +#define diffcons(cv) (cv.value != atoi(cv.defaultvalue)) + + doinggamma = diffcons(cv_globalgamma); - if (cv_usegamma.value) - { #define gammascale 8 - float gammamul = (255 - (gammascale*abs(cv_usegamma.value)))/255.0; - float gammaoffs = ((cv_usegamma.value > 0) ? ((gammascale*cv_usegamma.value)/255.0) : 0.0); -#undef gammascale + globalgammamul = (cv_globalgamma.value ? ((255 - (gammascale*abs(cv_globalgamma.value)))/255.0) : 1.0); + globalgammaoffs = ((cv_globalgamma.value > 0) ? ((gammascale*cv_globalgamma.value)/255.0) : 0.0); + desatur[0] = desatur[1] = desatur[2] = globalgammaoffs + (0.33*globalgammamul); - apply = true; - - #define dogamma(i, j, k, l) \ - working[i][j][k][l]*= gammamul;\ - working[i][j][k][l] += gammaoffs - for (q = 0; q < 3; q++) - { - dogamma(0, 0, 0, q); - dogamma(1, 0, 0, q); - dogamma(0, 1, 0, q); - dogamma(1, 1, 0, q); - dogamma(0, 0, 1, q); - dogamma(1, 0, 1, q); - dogamma(0, 1, 1, q); - dogamma(1, 1, 1, q); - } -#undef dogamma - } - - if (cv_usesaturation.value != 10) + if (doinggamma + || diffcons(cv_rhue) + || diffcons(cv_yhue) + || diffcons(cv_ghue) + || diffcons(cv_chue) + || diffcons(cv_bhue) + || diffcons(cv_mhue) + || diffcons(cv_rgamma) + || diffcons(cv_ygamma) + || diffcons(cv_ggamma) + || diffcons(cv_cgamma) + || diffcons(cv_bgamma) + || diffcons(cv_mgamma)) { - float desatur[3] = {0.33, 0.33, 0.33}; // grey - float work = (cv_usesaturation.value/10.0); + float mod, tempgammamul, tempgammaoffs; apply = true; + working[0][0][0][0] = working[0][0][0][1] = working[0][0][0][2] = globalgammaoffs; + working[1][1][1][0] = working[1][1][1][1] = working[1][1][1][2] = globalgammaoffs+globalgammamul; + +#define dohue(hue, gamma, loc) \ + tempgammamul = (gamma ? ((255 - (gammascale*abs(gamma)))/255.0)*globalgammamul : globalgammamul);\ + tempgammaoffs = ((gamma > 0) ? ((gammascale*gamma)/255.0) + globalgammaoffs : globalgammaoffs);\ + mod = ((hue % huecoloursteps)*(tempgammamul)/huecoloursteps);\ + switch (hue/huecoloursteps)\ + {\ + case 0:\ + default:\ + loc[0] = tempgammaoffs+tempgammamul;\ + loc[1] = tempgammaoffs+mod;\ + loc[2] = tempgammaoffs;\ + break;\ + case 1:\ + loc[0] = tempgammaoffs+tempgammamul-mod;\ + loc[1] = tempgammaoffs+tempgammamul;\ + loc[2] = tempgammaoffs;\ + break;\ + case 2:\ + loc[0] = tempgammaoffs;\ + loc[1] = tempgammaoffs+tempgammamul;\ + loc[2] = tempgammaoffs+mod;\ + break;\ + case 3:\ + loc[0] = tempgammaoffs;\ + loc[1] = tempgammaoffs+tempgammamul-mod;\ + loc[2] = tempgammaoffs+tempgammamul;\ + break;\ + case 4:\ + loc[0] = tempgammaoffs+mod;\ + loc[1] = tempgammaoffs;\ + loc[2] = tempgammaoffs+tempgammamul;\ + break;\ + case 5:\ + loc[0] = tempgammaoffs+tempgammamul;\ + loc[1] = tempgammaoffs;\ + loc[2] = tempgammaoffs+tempgammamul-mod;\ + break;\ + } + dohue(cv_rhue.value, cv_rgamma.value, working[1][0][0]); + dohue(cv_yhue.value, cv_ygamma.value, working[1][1][0]); + dohue(cv_ghue.value, cv_ggamma.value, working[0][1][0]); + dohue(cv_chue.value, cv_cgamma.value, working[0][1][1]); + dohue(cv_bhue.value, cv_bgamma.value, working[0][0][1]); + dohue(cv_mhue.value, cv_mgamma.value, working[1][0][1]); +#undef dohue + } + #define dosaturation(a, e) a = ((1 - work)*e + work*a) +#define docvsat(cv_sat, hue, gamma, r, g, b) \ + if diffcons(cv_sat)\ + {\ + float work, mod, tempgammamul, tempgammaoffs;\ + apply = true;\ + work = (cv_sat.value/10.0);\ + mod = ((hue % huecoloursteps)*(1.0)/huecoloursteps);\ + if (hue & huecoloursteps)\ + mod = 2-mod;\ + else\ + mod += 1;\ + tempgammamul = (gamma ? ((255 - (gammascale*abs(gamma)))/255.0)*globalgammamul : globalgammamul);\ + tempgammaoffs = ((gamma > 0) ? ((gammascale*gamma)/255.0) + globalgammaoffs : globalgammaoffs);\ + for (q = 0; q < 3; q++)\ + dosaturation(working[r][g][b][q], (tempgammaoffs+(desatur[q]*mod*tempgammamul)));\ + } + + docvsat(cv_rsaturation, cv_rhue.value, cv_rgamma.value, 1, 0, 0); + docvsat(cv_ysaturation, cv_yhue.value, cv_ygamma.value, 1, 1, 0); + docvsat(cv_gsaturation, cv_ghue.value, cv_ggamma.value, 0, 1, 0); + docvsat(cv_csaturation, cv_chue.value, cv_cgamma.value, 0, 1, 1); + docvsat(cv_bsaturation, cv_bhue.value, cv_bgamma.value, 0, 0, 1); + docvsat(cv_msaturation, cv_mhue.value, cv_mgamma.value, 1, 0, 1); + +#undef gammascale + + if diffcons(cv_globalsaturation) + { + float work = (cv_globalsaturation.value/10.0); + + apply = true; + for (q = 0; q < 3; q++) { - dosaturation(working[0][0][1][q], desatur[q]); - dosaturation(working[0][1][0][q], desatur[q]); dosaturation(working[1][0][0][q], desatur[q]); + dosaturation(working[0][1][0][q], desatur[q]); + dosaturation(working[0][0][1][q], desatur[q]); dosaturation(working[1][1][0][q], 2*desatur[q]); - dosaturation(working[1][0][1][q], 2*desatur[q]); dosaturation(working[0][1][1][q], 2*desatur[q]); + dosaturation(working[1][0][1][q], 2*desatur[q]); } -#undef dosaturation } +#undef dosaturation + +#undef diffcons + if (!apply) return false; @@ -319,7 +426,7 @@ void V_SetPaletteLump(const char *pal) #endif } -static void CV_usegamma_OnChange(void) +static void CV_palette_OnChange(void) { // reload palette LoadMapPalette(); diff --git a/src/v_video.h b/src/v_video.h index 8b35b920a..0a360bc42 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -27,7 +27,11 @@ extern UINT8 *screens[5]; -extern consvar_t cv_ticrate, cv_usegamma, cv_usesaturation, cv_constextsize; +extern consvar_t cv_ticrate, cv_constextsize,\ +cv_globalgamma, cv_globalsaturation, \ +cv_rhue, cv_yhue, cv_ghue, cv_chue, cv_bhue, cv_mhue,\ +cv_rgamma, cv_ygamma, cv_ggamma, cv_cgamma, cv_bgamma, cv_mgamma, \ +cv_rsaturation, cv_ysaturation, cv_gsaturation, cv_csaturation, cv_bsaturation, cv_msaturation; // Allocates buffer screens, call before R_Init. void V_Init(void); From cdf8c54f2d1feae314daebbaee61f0e03e1fb929 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 20 Apr 2017 13:15:32 +0100 Subject: [PATCH 08/64] Correcting gamma to match base SRB2. (cherry picked from commit 29d5af61c1f7cff83e5e59117ff6ceef00d698c1) --- src/v_video.c | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/src/v_video.c b/src/v_video.c index 1a7aabc82..2171f94c5 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -119,7 +119,6 @@ http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter24.html Please check it out if you're trying to maintain this. toast 18/04/17 */ - float Cubepal[2][2][2][3]; // returns whether to apply cube, selectively avoiding expensive operations @@ -175,7 +174,7 @@ static boolean InitCube(void) || diffcons(cv_ggamma) || diffcons(cv_cgamma) || diffcons(cv_bgamma) - || diffcons(cv_mgamma)) + || diffcons(cv_mgamma)) // set the gamma'd/hued positions (saturation is done later) { float mod, tempgammamul, tempgammaoffs; @@ -305,6 +304,31 @@ static boolean InitCube(void) return true; } +/* +So it turns out that the way gamma was implemented previously, the default +colour profile of the game was messed up. Since this bad decision has been +around for a long time, and the intent is to keep the base game looking the +same, I'm not gonna be the one to remove this base modification. +toast 20/04/17 +*/ +const UINT8 correctiontable[256] = + {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16, + 17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32, + 33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48, + 49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64, + 65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80, + 81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96, + 97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112, + 113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128, + 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, + 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, + 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, + 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, + 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, + 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, + 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, + 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255}; + // keep a copy of the palette so that we can get the RGB value for a color index at any time. static void LoadPalette(const char *lumpname) { @@ -320,9 +344,9 @@ static void LoadPalette(const char *lumpname) pal = W_CacheLumpNum(lumpnum, PU_CACHE); for (i = 0; i < palsize; i++) { - pLocalPalette[i].s.red = *pal++; - pLocalPalette[i].s.green = *pal++; - pLocalPalette[i].s.blue = *pal++; + pLocalPalette[i].s.red = correctiontable[*pal++]; + pLocalPalette[i].s.green = correctiontable[*pal++]; + pLocalPalette[i].s.blue = correctiontable[*pal++]; pLocalPalette[i].s.alpha = 0xFF; // lerp of colour cubing! From 56ac0884436ba5bd728114f7d875334ffa830a8e Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 20 Apr 2017 13:17:11 +0100 Subject: [PATCH 09/64] Screenshots now contain the palette you're actively looking at, as opposed to the palette the game/map has! This makes sense for colorblind users being able to store their precious memories, and it matches up with how gifs palettise. (cherry picked from commit 9d46ba281fe9ddebc9613c4e2db6792eaf46dda2) --- src/hardware/hw_draw.c | 2 +- src/m_misc.c | 25 +++++++++++-------------- src/m_misc.h | 2 +- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index b39103ee4..dd21f408b 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -1208,7 +1208,7 @@ boolean HWR_Screenshot(const char *lbmname) HWD.pfnReadRect(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf); #ifdef USE_PNG - ret = M_SavePNG(lbmname, buf, vid.width, vid.height, NULL); + ret = M_SavePNG(lbmname, buf, vid.width, vid.height, false); #else ret = saveTGA(lbmname, buf, vid.width, vid.height); #endif diff --git a/src/m_misc.c b/src/m_misc.c index f4a4ec291..3600ad08d 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -654,19 +654,18 @@ static void PNG_warn(png_structp PNG, png_const_charp pngtext) CONS_Debug(DBG_RENDER, "libpng warning at %p: %s", PNG, pngtext); } -static void M_PNGhdr(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png_uint_32 width, PNG_CONST png_uint_32 height, PNG_CONST png_byte *palette) +static void M_PNGhdr(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png_uint_32 width, PNG_CONST png_uint_32 height, const boolean palette) { const png_byte png_interlace = PNG_INTERLACE_NONE; //PNG_INTERLACE_ADAM7 if (palette) { png_colorp png_PLTE = png_malloc(png_ptr, sizeof(png_color)*256); //palette - const png_byte *pal = palette; png_uint_16 i; for (i = 0; i < 256; i++) { - png_PLTE[i].red = *pal; pal++; - png_PLTE[i].green = *pal; pal++; - png_PLTE[i].blue = *pal; pal++; + png_PLTE[i].red = pLocalPalette[i].s.red; + png_PLTE[i].green = pLocalPalette[i].s.green; + png_PLTE[i].blue = pLocalPalette[i].s.blue; } png_set_IHDR(png_ptr, png_info_ptr, width, height, 8, PNG_COLOR_TYPE_PALETTE, png_interlace, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); @@ -941,7 +940,7 @@ static void M_PNGfix_acTL(png_structp png_ptr, png_infop png_info_ptr, #endif } -static boolean M_SetupaPNG(png_const_charp filename, png_bytep pal) +static boolean M_SetupaPNG(png_const_charp filename, boolean palette) { apng_FILE = fopen(filename,"wb+"); // + mode for reading if (!apng_FILE) @@ -993,7 +992,7 @@ static boolean M_SetupaPNG(png_const_charp filename, png_bytep pal) png_set_compression_strategy(apng_ptr, cv_zlib_strategya.value); png_set_compression_window_bits(apng_ptr, cv_zlib_window_bitsa.value); - M_PNGhdr(apng_ptr, apng_info_ptr, vid.width, vid.height, pal); + M_PNGhdr(apng_ptr, apng_info_ptr, vid.width, vid.height, palette); M_PNGText(apng_ptr, apng_info_ptr, true); @@ -1033,9 +1032,9 @@ static inline moviemode_t M_StartMovieAPNG(const char *pathname) } if (rendermode == render_soft) - ret = M_SetupaPNG(va(pandf,pathname,freename), W_CacheLumpName(GetPalette(), PU_CACHE)); + ret = M_SetupaPNG(va(pandf,pathname,freename), true); else - ret = M_SetupaPNG(va(pandf,pathname,freename), NULL); + ret = M_SetupaPNG(va(pandf,pathname,freename), false); if (!ret) { @@ -1241,11 +1240,10 @@ void M_StopMovie(void) * \param palette Palette of image data * \note if palette is NULL, BGR888 format */ -boolean M_SavePNG(const char *filename, void *data, int width, int height, const UINT8 *palette) +boolean M_SavePNG(const char *filename, void *data, int width, int height, const boolean palette) { png_structp png_ptr; png_infop png_info_ptr; - PNG_CONST png_byte *PLTE = (const png_byte *)palette; #ifdef PNG_SETJMP_SUPPORTED #ifdef USE_FAR_KEYWORD jmp_buf jmpbuf; @@ -1308,7 +1306,7 @@ boolean M_SavePNG(const char *filename, void *data, int width, int height, const png_set_compression_strategy(png_ptr, cv_zlib_strategy.value); png_set_compression_window_bits(png_ptr, cv_zlib_window_bits.value); - M_PNGhdr(png_ptr, png_info_ptr, width, height, PLTE); + M_PNGhdr(png_ptr, png_info_ptr, width, height, palette); M_PNGText(png_ptr, png_info_ptr, false); @@ -1471,8 +1469,7 @@ void M_DoScreenShot(void) if (rendermode != render_none) { #ifdef USE_PNG - ret = M_SavePNG(va(pandf,pathname,freename), linear, vid.width, vid.height, - W_CacheLumpName(GetPalette(), PU_CACHE)); + ret = M_SavePNG(va(pandf,pathname,freename), linear, vid.width, vid.height, true); #else ret = WritePCXfile(va(pandf,pathname,freename), linear, vid.width, vid.height, W_CacheLumpName(GetPalette(), PU_CACHE)); diff --git a/src/m_misc.h b/src/m_misc.h index 658028b44..1e780632b 100644 --- a/src/m_misc.h +++ b/src/m_misc.h @@ -64,7 +64,7 @@ void FIL_ForceExtension(char *path, const char *extension); boolean FIL_CheckExtension(const char *in); #ifdef HAVE_PNG -boolean M_SavePNG(const char *filename, void *data, int width, int height, const UINT8 *palette); +boolean M_SavePNG(const char *filename, void *data, int width, int height, const boolean palette); #endif extern boolean takescreenshot; From 7a14bbba829856668359e36e7bcd6dfc2984ef45 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 23 Mar 2020 16:35:38 -0700 Subject: [PATCH 10/64] Disable colour profile influence on screenshots and gifs if you want. (cherry picked from commit 8b46ee76ff06d600a606e23802e024416a58b5b2) # Conflicts: # src/m_menu.c --- src/d_netcmd.c | 1 + src/m_anigif.c | 24 ++++++++++++++++++------ src/m_misc.c | 23 +++++++++++++++++++---- src/m_misc.h | 2 +- 4 files changed, 39 insertions(+), 11 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 03096197a..36cb01adf 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -789,6 +789,7 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_screenshot_option); CV_RegisterVar(&cv_screenshot_folder); + CV_RegisterVar(&cv_screenshot_colorprofile); CV_RegisterVar(&cv_moviemode); // PNG variables CV_RegisterVar(&cv_zlib_level); diff --git a/src/m_anigif.c b/src/m_anigif.c index 4dfc77cb3..4746d2c19 100644 --- a/src/m_anigif.c +++ b/src/m_anigif.c @@ -18,6 +18,7 @@ #include "z_zone.h" #include "v_video.h" #include "i_video.h" +#include "m_misc.h" // GIFs are always little-endian #include "byteptr.h" @@ -396,7 +397,6 @@ static void GIF_headwrite(void) { UINT8 *gifhead = Z_Malloc(800, PU_STATIC, NULL); UINT8 *p = gifhead; - RGBA_t *c; INT32 i; UINT16 rwidth, rheight; @@ -427,12 +427,24 @@ static void GIF_headwrite(void) WRITEUINT8(p, 0x00); // write color table - for (i = 0; i < 256; ++i) + if (cv_screenshot_colorprofile.value) { - c = &pLocalPalette[i]; - WRITEUINT8(p, c->s.red); - WRITEUINT8(p, c->s.green); - WRITEUINT8(p, c->s.blue); + for (i = 0; i < 256; i++) + { + WRITEUINT8(p, pLocalPalette[i].s.red); + WRITEUINT8(p, pLocalPalette[i].s.green); + WRITEUINT8(p, pLocalPalette[i].s.blue); + } + } + else + { + const UINT8 *pal = (UINT8 *)W_CacheLumpName(GetPalette(), PU_CACHE); + for (i = 0; i < 256; i++) + { + WRITEUINT8(p, *pal); pal++; + WRITEUINT8(p, *pal); pal++; + WRITEUINT8(p, *pal); pal++; + } } // write extension block diff --git a/src/m_misc.c b/src/m_misc.c index 3600ad08d..bcf9d4d0a 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -104,6 +104,8 @@ static CV_PossibleValue_t screenshot_cons_t[] = {{0, "Default"}, {1, "HOME"}, {2 consvar_t cv_screenshot_option = {"screenshot_option", "Default", CV_SAVE|CV_CALL, screenshot_cons_t, Screenshot_option_Onchange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_screenshot_folder = {"screenshot_folder", "", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_screenshot_colorprofile = {"screenshot_colorprofile", "Yes", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + static CV_PossibleValue_t moviemode_cons_t[] = {{MM_GIF, "GIF"}, {MM_APNG, "aPNG"}, {MM_SCREENSHOT, "Screenshots"}, {0, NULL}}; consvar_t cv_moviemode = {"moviemode_mode", "GIF", CV_SAVE|CV_CALL, moviemode_cons_t, Moviemode_mode_Onchange, 0, NULL, NULL, 0, 0, NULL}; @@ -661,11 +663,24 @@ static void M_PNGhdr(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png_ { png_colorp png_PLTE = png_malloc(png_ptr, sizeof(png_color)*256); //palette png_uint_16 i; - for (i = 0; i < 256; i++) + if (cv_screenshot_colorprofile.value) { - png_PLTE[i].red = pLocalPalette[i].s.red; - png_PLTE[i].green = pLocalPalette[i].s.green; - png_PLTE[i].blue = pLocalPalette[i].s.blue; + for (i = 0; i < 256; i++) + { + png_PLTE[i].red = pLocalPalette[i].s.red; + png_PLTE[i].green = pLocalPalette[i].s.green; + png_PLTE[i].blue = pLocalPalette[i].s.blue; + } + } + else + { + const png_byte *pal = (png_byte *)W_CacheLumpName(GetPalette(), PU_CACHE); + for (i = 0; i < 256; i++) + { + png_PLTE[i].red = *pal++; + png_PLTE[i].green = *pal++; + png_PLTE[i].blue = *pal++; + } } png_set_IHDR(png_ptr, png_info_ptr, width, height, 8, PNG_COLOR_TYPE_PALETTE, png_interlace, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); diff --git a/src/m_misc.h b/src/m_misc.h index 1e780632b..df9344dd4 100644 --- a/src/m_misc.h +++ b/src/m_misc.h @@ -29,7 +29,7 @@ typedef enum { } moviemode_t; extern moviemode_t moviemode; -extern consvar_t cv_screenshot_option, cv_screenshot_folder; +extern consvar_t cv_screenshot_option, cv_screenshot_folder, cv_screenshot_colorprofile; extern consvar_t cv_moviemode; extern consvar_t cv_zlib_memory, cv_zlib_level, cv_zlib_strategy, cv_zlib_window_bits; extern consvar_t cv_zlib_memorya, cv_zlib_levela, cv_zlib_strategya, cv_zlib_window_bitsa; From e8c37067ed0ed0ad41849a277b00429f8f90a1ec Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 21 Apr 2017 20:29:06 +0100 Subject: [PATCH 11/64] Made PCX use cv_screenshot_colorprofile. Also, optimised gif headwrite's palette writing. (cherry picked from commit 3cce4956753ced4e325edc4ec61f6fe7494cc233) --- src/m_anigif.c | 4 +--- src/m_misc.c | 26 +++++++++++++++++++++----- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/m_anigif.c b/src/m_anigif.c index 4746d2c19..77d9a5463 100644 --- a/src/m_anigif.c +++ b/src/m_anigif.c @@ -439,11 +439,9 @@ static void GIF_headwrite(void) else { const UINT8 *pal = (UINT8 *)W_CacheLumpName(GetPalette(), PU_CACHE); - for (i = 0; i < 256; i++) + for (i = 0; i < 256*3; i++) { WRITEUINT8(p, *pal); pal++; - WRITEUINT8(p, *pal); pal++; - WRITEUINT8(p, *pal); pal++; } } diff --git a/src/m_misc.c b/src/m_misc.c index bcf9d4d0a..7ba949424 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -1368,7 +1368,7 @@ typedef struct * \param palette Palette of image data */ #if NUMSCREENS > 2 -static boolean WritePCXfile(const char *filename, const UINT8 *data, int width, int height, const UINT8 *palette) +static boolean WritePCXfile(const char *filename, const UINT8 *data, int width, int height) { int i; size_t length; @@ -1409,8 +1409,25 @@ static boolean WritePCXfile(const char *filename, const UINT8 *data, int width, // write the palette *pack++ = 0x0c; // palette ID byte - for (i = 0; i < 768; i++) - *pack++ = *palette++; + + // write color table + if (cv_screenshot_colorprofile.value) + { + for (i = 0; i < 256; i++) + { + *pack++ = pLocalPalette[i].s.red; + *pack++ = pLocalPalette[i].s.green; + *pack++ = pLocalPalette[i].s.blue; + } + } + else + { + const UINT8 *pal = (UINT8 *)W_CacheLumpName(GetPalette(), PU_CACHE); + for (i = 0; i < 256*3; i++) + { + *pack++ = *pal++; + } + } // write output file length = pack - (UINT8 *)pcx; @@ -1486,8 +1503,7 @@ void M_DoScreenShot(void) #ifdef USE_PNG ret = M_SavePNG(va(pandf,pathname,freename), linear, vid.width, vid.height, true); #else - ret = WritePCXfile(va(pandf,pathname,freename), linear, vid.width, vid.height, - W_CacheLumpName(GetPalette(), PU_CACHE)); + ret = WritePCXfile(va(pandf,pathname,freename), linear, vid.width, vid.height); #endif } From 2fb599661e5cd44ddf51b5441d286d61980821f8 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 29 Apr 2017 16:40:07 +0100 Subject: [PATCH 12/64] Introducing pMasterPalette. Used instead of pLocalPalette when attempting to determine objective truths, such as "the colours of this gif without color profile modification" and "what indicies should this colormap remap to". Also, made f_wipe.c's paldiv only get calculated once. (cherry picked from commit d669a4e84ac4e4292a8b95ab88f4948090282741) --- src/f_wipe.c | 2 +- src/m_anigif.c | 19 +++++++------------ src/m_misc.c | 46 +++++++++++++++++----------------------------- src/r_data.c | 43 ++++++++++++++++++++++++++++++++++--------- src/v_video.c | 11 +++++++---- src/v_video.h | 1 + 6 files changed, 67 insertions(+), 55 deletions(-) diff --git a/src/f_wipe.c b/src/f_wipe.c index e42042516..6ad565441 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -157,7 +157,7 @@ static fademask_t *F_GetFadeMask(UINT8 masknum, UINT8 scrnnum) { while (lsize--) { // Determine pixel to use from fademask - pcolor = &pLocalPalette[*lump++]; + pcolor = &pMasterPalette[*lump++]; *mask++ = FixedDiv((pcolor->s.red+1)<>FRACBITS; } diff --git a/src/m_anigif.c b/src/m_anigif.c index 77d9a5463..64254163d 100644 --- a/src/m_anigif.c +++ b/src/m_anigif.c @@ -427,21 +427,16 @@ static void GIF_headwrite(void) WRITEUINT8(p, 0x00); // write color table - if (cv_screenshot_colorprofile.value) { + RGBA_t *pal = ((cv_screenshot_colorprofile.value) + ? pLocalPalette + : pMasterPalette); + for (i = 0; i < 256; i++) { - WRITEUINT8(p, pLocalPalette[i].s.red); - WRITEUINT8(p, pLocalPalette[i].s.green); - WRITEUINT8(p, pLocalPalette[i].s.blue); - } - } - else - { - const UINT8 *pal = (UINT8 *)W_CacheLumpName(GetPalette(), PU_CACHE); - for (i = 0; i < 256*3; i++) - { - WRITEUINT8(p, *pal); pal++; + WRITEUINT8(p, pal[i].s.red); + WRITEUINT8(p, pal[i].s.green); + WRITEUINT8(p, pal[i].s.blue); } } diff --git a/src/m_misc.c b/src/m_misc.c index 7ba949424..43b78c35c 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -663,25 +663,18 @@ static void M_PNGhdr(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png_ { png_colorp png_PLTE = png_malloc(png_ptr, sizeof(png_color)*256); //palette png_uint_16 i; - if (cv_screenshot_colorprofile.value) + + RGBA_t *pal = ((cv_screenshot_colorprofile.value) + ? pLocalPalette + : pMasterPalette); + + for (i = 0; i < 256; i++) { - for (i = 0; i < 256; i++) - { - png_PLTE[i].red = pLocalPalette[i].s.red; - png_PLTE[i].green = pLocalPalette[i].s.green; - png_PLTE[i].blue = pLocalPalette[i].s.blue; - } - } - else - { - const png_byte *pal = (png_byte *)W_CacheLumpName(GetPalette(), PU_CACHE); - for (i = 0; i < 256; i++) - { - png_PLTE[i].red = *pal++; - png_PLTE[i].green = *pal++; - png_PLTE[i].blue = *pal++; - } + png_PLTE[i].red = pal[i].s.red; + png_PLTE[i].green = pal[i].s.green; + png_PLTE[i].blue = pal[i].s.blue; } + png_set_IHDR(png_ptr, png_info_ptr, width, height, 8, PNG_COLOR_TYPE_PALETTE, png_interlace, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); png_write_info_before_PLTE(png_ptr, png_info_ptr); @@ -1411,21 +1404,16 @@ static boolean WritePCXfile(const char *filename, const UINT8 *data, int width, *pack++ = 0x0c; // palette ID byte // write color table - if (cv_screenshot_colorprofile.value) { + RGBA_t *pal = ((cv_screenshot_colorprofile.value) + ? pLocalPalette + : pMasterPalette); + for (i = 0; i < 256; i++) { - *pack++ = pLocalPalette[i].s.red; - *pack++ = pLocalPalette[i].s.green; - *pack++ = pLocalPalette[i].s.blue; - } - } - else - { - const UINT8 *pal = (UINT8 *)W_CacheLumpName(GetPalette(), PU_CACHE); - for (i = 0; i < 256*3; i++) - { - *pack++ = *pal++; + *pack++ = pal[i].s.red; + *pack++ = pal[i].s.green; + *pack++ = pal[i].s.blue; } } diff --git a/src/r_data.c b/src/r_data.c index 922e907e2..843ed2acb 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -22,7 +22,7 @@ #include "w_wad.h" #include "z_zone.h" #include "p_setup.h" // levelflats -#include "v_video.h" // pLocalPalette +#include "v_video.h" // pMasterPalette #include "dehacked.h" #if defined (_WIN32) || defined (_WIN32_WCE) @@ -1192,7 +1192,7 @@ void R_MakeInvertmap(void) INT32 R_CreateColormap(char *p1, char *p2, char *p3) { double cmaskr, cmaskg, cmaskb, cdestr, cdestg, cdestb; - double maskamt = 0, othermask = 0; + double r, g, b, cbrightness, maskamt = 0, othermask = 0; int mask, fog = 0; size_t mapnum = num_extra_colormaps; size_t i; @@ -1300,6 +1300,32 @@ INT32 R_CreateColormap(char *p1, char *p2, char *p3) num_extra_colormaps++; + if (rendermode == render_soft) + { + for (i = 0; i < 256; i++) + { + r = pMasterPalette[i].s.red; + g = pMasterPalette[i].s.green; + b = pMasterPalette[i].s.blue; + cbrightness = sqrt((r*r) + (g*g) + (b*b)); + + map[i][0] = (cbrightness * cmaskr) + (r * othermask); + if (map[i][0] > 255.0l) + map[i][0] = 255.0l; + deltas[i][0] = (map[i][0] - cdestr) / (double)fadedist; + + map[i][1] = (cbrightness * cmaskg) + (g * othermask); + if (map[i][1] > 255.0l) + map[i][1] = 255.0l; + deltas[i][1] = (map[i][1] - cdestg) / (double)fadedist; + + map[i][2] = (cbrightness * cmaskb) + (b * othermask); + if (map[i][2] > 255.0l) + map[i][2] = 255.0l; + deltas[i][2] = (map[i][2] - cdestb) / (double)fadedist; + } + } + foundcolormaps[mapnum] = LUMPERROR; // aligned on 8 bit for asm code @@ -1313,7 +1339,6 @@ INT32 R_CreateColormap(char *p1, char *p2, char *p3) if (rendermode == render_soft) { - double r, g, b, cbrightness; int p; lighttable_t *colormap_p; @@ -1324,9 +1349,9 @@ INT32 R_CreateColormap(char *p1, char *p2, char *p3) // map[i]'s values are decremented by after each use for (i = 0; i < 256; i++) { - r = pLocalPalette[i].s.red; - g = pLocalPalette[i].s.green; - b = pLocalPalette[i].s.blue; + r = pMasterPalette[i].s.red; + g = pMasterPalette[i].s.green; + b = pMasterPalette[i].s.blue; cbrightness = sqrt((r*r) + (g*g) + (b*b)); map[i][0] = (cbrightness * cmaskr) + (r * othermask); @@ -1409,9 +1434,9 @@ UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b) for (i = 0; i < 256; i++) { - dr = r - pLocalPalette[i].s.red; - dg = g - pLocalPalette[i].s.green; - db = b - pLocalPalette[i].s.blue; + dr = r - pMasterPalette[i].s.red; + dg = g - pMasterPalette[i].s.green; + db = b - pMasterPalette[i].s.blue; distortion = dr*dr + dg*dg + db*db; if (distortion < bestdistortion) { diff --git a/src/v_video.c b/src/v_video.c index 2171f94c5..0efd2cdda 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -112,6 +112,7 @@ consvar_t cv_grspritebillboarding = {"gr_spritebillboarding", "On", CV_SAVE, CV_ // local copy of the palette for V_GetColor() RGBA_t *pLocalPalette = NULL; +RGBA_t *pMasterPalette = NULL; /* The following was an extremely helpful resource when developing my Colour Cube LUT. @@ -338,16 +339,18 @@ static void LoadPalette(const char *lumpname) UINT8 *pal; Z_Free(pLocalPalette); + Z_Free(pMasterPalette); pLocalPalette = Z_Malloc(sizeof (*pLocalPalette)*palsize, PU_STATIC, NULL); + pMasterPalette = Z_Malloc(sizeof (*pMasterPalette)*palsize, PU_STATIC, NULL); pal = W_CacheLumpNum(lumpnum, PU_CACHE); for (i = 0; i < palsize; i++) { - pLocalPalette[i].s.red = correctiontable[*pal++]; - pLocalPalette[i].s.green = correctiontable[*pal++]; - pLocalPalette[i].s.blue = correctiontable[*pal++]; - pLocalPalette[i].s.alpha = 0xFF; + pMasterPalette[i].s.red = pLocalPalette[i].s.red = correctiontable[*pal++]; + pMasterPalette[i].s.green = pLocalPalette[i].s.green = correctiontable[*pal++]; + pMasterPalette[i].s.blue = pLocalPalette[i].s.blue = correctiontable[*pal++]; + pMasterPalette[i].s.alpha = pLocalPalette[i].s.alpha = 0xFF; // lerp of colour cubing! if (cube) diff --git a/src/v_video.h b/src/v_video.h index 0a360bc42..7478c6903 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -45,6 +45,7 @@ const char *R_GetPalname(UINT16 num); const char *GetPalette(void); extern RGBA_t *pLocalPalette; +extern RGBA_t *pMasterPalette; extern UINT8 hudtrans; From d688ef2c901c8aeccf8448b33b38fdda327410f9 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 29 Apr 2017 16:40:07 +0100 Subject: [PATCH 13/64] Fix typo. (cherry picked from commit 5180bff05bf55132746913305ade19ee0ced5c10) --- src/v_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/v_video.c b/src/v_video.c index 0efd2cdda..c482debda 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -383,7 +383,7 @@ static void LoadPalette(const char *lumpname) else if (working[0][q] < 0.0) working[0][q] = 0.0; } -#undef dowork +#undef dolerp pLocalPalette[i].s.red = (UINT8)(working[0][0]); pLocalPalette[i].s.green = (UINT8)(working[0][1]); From 60624edc1ae7e5a5f680667a6063e070621dfee9 Mon Sep 17 00:00:00 2001 From: Jimita the Cat Date: Wed, 2 Jan 2019 00:41:52 -0300 Subject: [PATCH 14/64] Add support for flashpals in screenshots (cherry picked from commit e765b9400cf741eb8aaa72768ef677769ee5c12b) --- src/hardware/hw_draw.c | 9 ++++-- src/hardware/hw_main.h | 5 +-- src/m_misc.c | 72 ++++++++++++++++++++++++++---------------- src/m_misc.h | 2 +- src/st_stuff.c | 2 +- src/st_stuff.h | 1 + 6 files changed, 56 insertions(+), 35 deletions(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index dd21f408b..eb1db7d70 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -1196,21 +1196,24 @@ UINT8 *HWR_GetScreenshot(void) return buf; } -boolean HWR_Screenshot(const char *lbmname) +boolean HWR_Screenshot(const char *pathname, char **error) { boolean ret; UINT8 *buf = malloc(vid.width * vid.height * 3 * sizeof (*buf)); if (!buf) + { + *error = "Failed to allocate memory for HWR_Screenshot"; return false; + } // returns 24bit 888 RGB HWD.pfnReadRect(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf); #ifdef USE_PNG - ret = M_SavePNG(lbmname, buf, vid.width, vid.height, false); + ret = M_SavePNG(pathname, buf, vid.width, vid.height, NULL, &*error); // c_irl #else - ret = saveTGA(lbmname, buf, vid.width, vid.height); + ret = saveTGA(pathname, buf, vid.width, vid.height); #endif free(buf); return ret; diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 7bc361d95..109c5cb20 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -38,8 +38,6 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player); void HWR_RenderPlayerView(INT32 viewnumber, player_t *player); void HWR_DrawViewBorder(INT32 clearlines); void HWR_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum); -UINT8 *HWR_GetScreenshot(void); -boolean HWR_Screenshot(const char *lbmname); void HWR_InitTextureMapping(void); void HWR_SetViewSize(void); void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option); @@ -54,6 +52,9 @@ void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32 void HWR_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 color); void HWR_DrawPic(INT32 x,INT32 y,lumpnum_t lumpnum); +UINT8 *HWR_GetScreenshot(void); +boolean HWR_Screenshot(const char *pathname, char **error); + void HWR_AddCommands(void); void HWR_CorrectSWTricks(void); void transform(float *cx, float *cy, float *cz); diff --git a/src/m_misc.c b/src/m_misc.c index 43b78c35c..40d8c103f 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -30,6 +30,7 @@ #include "g_game.h" #include "m_misc.h" #include "hu_stuff.h" +#include "st_stuff.h" #include "v_video.h" #include "z_zone.h" #include "g_input.h" @@ -588,6 +589,21 @@ void M_SaveConfig(const char *filename) fclose(f); } +// ========================================================================== +// SCREENSHOTS +// ========================================================================== +static UINT8 screenshot_palette[768]; +static void M_CreateScreenShotPalette(void) +{ + size_t i, j; + for (i = 0, j = 0; i < 768; i += 3, j++) + { + RGBA_t locpal = pLocalPalette[(max(st_palette,0)*256)+j]; + screenshot_palette[i] = locpal.s.red; + screenshot_palette[i+1] = locpal.s.green; + screenshot_palette[i+2] = locpal.s.blue; + } +} #if NUMSCREENS > 2 static const char *Newsnapshotfile(const char *pathname, const char *ext) @@ -1024,6 +1040,7 @@ static boolean M_SetupaPNG(png_const_charp filename, boolean palette) static inline moviemode_t M_StartMovieAPNG(const char *pathname) { #ifdef USE_APNG + UINT8 *palette; const char *freename = NULL; boolean ret = false; @@ -1039,10 +1056,8 @@ static inline moviemode_t M_StartMovieAPNG(const char *pathname) return MM_OFF; } - if (rendermode == render_soft) - ret = M_SetupaPNG(va(pandf,pathname,freename), true); - else - ret = M_SetupaPNG(va(pandf,pathname,freename), false); + if (rendermode == render_soft) M_CreateScreenShotPalette(); + ret = M_SetupaPNG(va(pandf,pathname,freename), (palette = screenshot_palette)); if (!ret) { @@ -1245,10 +1260,11 @@ void M_StopMovie(void) * \param data The image data. * \param width Width of the picture. * \param height Height of the picture. - * \param palette Palette of image data + * \param palette Palette of image data. * \note if palette is NULL, BGR888 format + * \param error Error string to return, if screenshot failed. */ -boolean M_SavePNG(const char *filename, void *data, int width, int height, const boolean palette) +boolean M_SavePNG(const char *filename, void *data, int width, int height, const UINT8 *palette, char **error) { png_structp png_ptr; png_infop png_info_ptr; @@ -1262,15 +1278,14 @@ boolean M_SavePNG(const char *filename, void *data, int width, int height, const png_FILE = fopen(filename,"wb"); if (!png_FILE) { - CONS_Debug(DBG_RENDER, "M_SavePNG: Error on opening %s for write\n", filename); + *error = "Failed to open file for write"; return false; } - png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, - PNG_error, PNG_warn); + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, PNG_error, PNG_warn); if (!png_ptr) { - CONS_Debug(DBG_RENDER, "M_SavePNG: Error on initialize libpng\n"); + *error = "Failed to initialize libpng"; fclose(png_FILE); remove(filename); return false; @@ -1279,7 +1294,7 @@ boolean M_SavePNG(const char *filename, void *data, int width, int height, const png_info_ptr = png_create_info_struct(png_ptr); if (!png_info_ptr) { - CONS_Debug(DBG_RENDER, "M_SavePNG: Error on allocate for libpng\n"); + *error = "Failed to allocate memory for libpng"; png_destroy_write_struct(&png_ptr, NULL); fclose(png_FILE); remove(filename); @@ -1292,7 +1307,7 @@ boolean M_SavePNG(const char *filename, void *data, int width, int height, const if (setjmp(png_jmpbuf(png_ptr))) #endif { - //CONS_Debug(DBG_RENDER, "libpng write error on %s\n", filename); + *error = "libpng write error"; png_destroy_write_struct(&png_ptr, &png_info_ptr); fclose(png_FILE); remove(filename); @@ -1433,9 +1448,8 @@ void M_ScreenShot(void) } /** Takes a screenshot. - * The screenshot is saved as "kartxxxx.pcx" (or "kartxxxx.tga" in hardware - * rendermode) where xxxx is the lowest four-digit number for which a file - * does not already exist. + * The screenshot is saved as "srb2xxxx.png" where xxxx is the lowest + * four-digit number for which a file does not already exist. * * \sa HWR_ScreenShot */ @@ -1444,11 +1458,16 @@ void M_DoScreenShot(void) #if NUMSCREENS > 2 const char *freename = NULL, *pathname = "."; boolean ret = false; + char *error = "Unknown error"; UINT8 *linear = NULL; // Don't take multiple screenshots, obviously takescreenshot = false; + // how does one take a screenshot without a render system? + if (rendermode == render_none) + return; + if (cv_screenshot_option.value == 0) pathname = usehome ? srb2home : srb2path; else if (cv_screenshot_option.value == 1) @@ -1459,16 +1478,13 @@ void M_DoScreenShot(void) pathname = cv_screenshot_folder.string; #ifdef USE_PNG - if (rendermode != render_none) - freename = Newsnapshotfile(pathname,"png"); + freename = Newsnapshotfile(pathname,"png"); #else if (rendermode == render_soft) freename = Newsnapshotfile(pathname,"pcx"); - else if (rendermode != render_none) + else if (rendermode == render_opengl) freename = Newsnapshotfile(pathname,"tga"); #endif - else - I_Error("Can't take a screenshot without a render system"); if (rendermode == render_soft) { @@ -1482,16 +1498,16 @@ void M_DoScreenShot(void) // save the pcx file #ifdef HWRENDER - if (rendermode != render_soft) - ret = HWR_Screenshot(va(pandf,pathname,freename)); + if (rendermode == render_opengl) + ret = HWR_Screenshot(va(pandf,pathname,freename), &error); else #endif - if (rendermode != render_none) { + M_CreateScreenShotPalette(); #ifdef USE_PNG - ret = M_SavePNG(va(pandf,pathname,freename), linear, vid.width, vid.height, true); + ret = M_SavePNG(va(pandf,pathname,freename), linear, vid.width, vid.height, screenshot_palette, &error); #else - ret = WritePCXfile(va(pandf,pathname,freename), linear, vid.width, vid.height); + ret = WritePCXfile(va(pandf,pathname,freename), linear, vid.width, vid.height, screenshot_palette); #endif } @@ -1499,14 +1515,14 @@ failure: if (ret) { if (moviemode != MM_SCREENSHOT) - CONS_Printf(M_GetText("screen shot %s saved in %s\n"), freename, pathname); + CONS_Printf(M_GetText("Screen shot %s saved in %s\n"), freename, pathname); } else { if (freename) - CONS_Printf(M_GetText("Couldn't create screen shot %s in %s\n"), freename, pathname); + CONS_Alert(CONS_ERROR, M_GetText("Couldn't create screen shot %s in %s (%s)\n"), freename, pathname, error); else - CONS_Printf(M_GetText("Couldn't create screen shot (all 10000 slots used!) in %s\n"), pathname); + CONS_Alert(CONS_ERROR, M_GetText("Couldn't create screen shot in %s (all 10000 slots used!)\n"), pathname); if (moviemode == MM_SCREENSHOT) M_StopMovie(); diff --git a/src/m_misc.h b/src/m_misc.h index df9344dd4..990e15b3c 100644 --- a/src/m_misc.h +++ b/src/m_misc.h @@ -64,7 +64,7 @@ void FIL_ForceExtension(char *path, const char *extension); boolean FIL_CheckExtension(const char *in); #ifdef HAVE_PNG -boolean M_SavePNG(const char *filename, void *data, int width, int height, const boolean palette); +boolean M_SavePNG(const char *filename, void *data, int width, int height, const UINT8 *palette, char **error); #endif extern boolean takescreenshot; diff --git a/src/st_stuff.c b/src/st_stuff.c index 2a2ede350..8ac6e89a0 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -203,7 +203,7 @@ void ST_Ticker(void) } // 0 is default, any others are special palettes. -static INT32 st_palette = 0; +INT32 st_palette = 0; void ST_doPaletteStuff(void) { diff --git a/src/st_stuff.h b/src/st_stuff.h index 16f7b8811..5ed5dd1c6 100644 --- a/src/st_stuff.h +++ b/src/st_stuff.h @@ -61,6 +61,7 @@ boolean ST_SameTeam(player_t *a, player_t *b); //-------------------- extern boolean st_overlay; // sb overlay on or off when fullscreen +extern INT32 st_palette; // 0 is default, any others are special palettes. extern lumpnum_t st_borderpatchnum; // patches, also used in intermission From d6493c9101bb29d1a02a577cce3260a75b434886 Mon Sep 17 00:00:00 2001 From: Jimita the Cat Date: Wed, 2 Jan 2019 01:01:57 -0300 Subject: [PATCH 15/64] dumb (cherry picked from commit 892e65071281e1aa2bd6158748120cf4b7cd81c2) --- src/hardware/hw_draw.c | 6 +++--- src/hardware/hw_main.h | 2 +- src/m_misc.c | 18 ++++++++---------- src/m_misc.h | 2 +- 4 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index eb1db7d70..eca6edfc1 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -1196,14 +1196,14 @@ UINT8 *HWR_GetScreenshot(void) return buf; } -boolean HWR_Screenshot(const char *pathname, char **error) +boolean HWR_Screenshot(const char *pathname) { boolean ret; UINT8 *buf = malloc(vid.width * vid.height * 3 * sizeof (*buf)); if (!buf) { - *error = "Failed to allocate memory for HWR_Screenshot"; + CONS_Debug(DBG_RENDER, "HWR_Screenshot: Failed to allocate memory\n"); return false; } @@ -1211,7 +1211,7 @@ boolean HWR_Screenshot(const char *pathname, char **error) HWD.pfnReadRect(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf); #ifdef USE_PNG - ret = M_SavePNG(pathname, buf, vid.width, vid.height, NULL, &*error); // c_irl + ret = M_SavePNG(pathname, buf, vid.width, vid.height, NULL); #else ret = saveTGA(pathname, buf, vid.width, vid.height); #endif diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 109c5cb20..67c2f5430 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -53,7 +53,7 @@ void HWR_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 color); void HWR_DrawPic(INT32 x,INT32 y,lumpnum_t lumpnum); UINT8 *HWR_GetScreenshot(void); -boolean HWR_Screenshot(const char *pathname, char **error); +boolean HWR_Screenshot(const char *pathname); void HWR_AddCommands(void); void HWR_CorrectSWTricks(void); diff --git a/src/m_misc.c b/src/m_misc.c index 40d8c103f..a63c31ce1 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -1262,9 +1262,8 @@ void M_StopMovie(void) * \param height Height of the picture. * \param palette Palette of image data. * \note if palette is NULL, BGR888 format - * \param error Error string to return, if screenshot failed. */ -boolean M_SavePNG(const char *filename, void *data, int width, int height, const UINT8 *palette, char **error) +boolean M_SavePNG(const char *filename, void *data, int width, int height, const UINT8 *palette) { png_structp png_ptr; png_infop png_info_ptr; @@ -1278,14 +1277,14 @@ boolean M_SavePNG(const char *filename, void *data, int width, int height, const png_FILE = fopen(filename,"wb"); if (!png_FILE) { - *error = "Failed to open file for write"; + CONS_Debug(DBG_RENDER, "M_SavePNG: Error on opening %s for write\n", filename); return false; } png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, PNG_error, PNG_warn); if (!png_ptr) { - *error = "Failed to initialize libpng"; + CONS_Debug(DBG_RENDER, "M_SavePNG: Error on initialize libpng\n"); fclose(png_FILE); remove(filename); return false; @@ -1294,7 +1293,7 @@ boolean M_SavePNG(const char *filename, void *data, int width, int height, const png_info_ptr = png_create_info_struct(png_ptr); if (!png_info_ptr) { - *error = "Failed to allocate memory for libpng"; + CONS_Debug(DBG_RENDER, "M_SavePNG: Error on allocate for libpng\n"); png_destroy_write_struct(&png_ptr, NULL); fclose(png_FILE); remove(filename); @@ -1307,7 +1306,7 @@ boolean M_SavePNG(const char *filename, void *data, int width, int height, const if (setjmp(png_jmpbuf(png_ptr))) #endif { - *error = "libpng write error"; + //CONS_Debug(DBG_RENDER, "libpng write error on %s\n", filename); png_destroy_write_struct(&png_ptr, &png_info_ptr); fclose(png_FILE); remove(filename); @@ -1458,7 +1457,6 @@ void M_DoScreenShot(void) #if NUMSCREENS > 2 const char *freename = NULL, *pathname = "."; boolean ret = false; - char *error = "Unknown error"; UINT8 *linear = NULL; // Don't take multiple screenshots, obviously @@ -1499,13 +1497,13 @@ void M_DoScreenShot(void) // save the pcx file #ifdef HWRENDER if (rendermode == render_opengl) - ret = HWR_Screenshot(va(pandf,pathname,freename), &error); + ret = HWR_Screenshot(va(pandf,pathname,freename)); else #endif { M_CreateScreenShotPalette(); #ifdef USE_PNG - ret = M_SavePNG(va(pandf,pathname,freename), linear, vid.width, vid.height, screenshot_palette, &error); + ret = M_SavePNG(va(pandf,pathname,freename), linear, vid.width, vid.height, screenshot_palette); #else ret = WritePCXfile(va(pandf,pathname,freename), linear, vid.width, vid.height, screenshot_palette); #endif @@ -1520,7 +1518,7 @@ failure: else { if (freename) - CONS_Alert(CONS_ERROR, M_GetText("Couldn't create screen shot %s in %s (%s)\n"), freename, pathname, error); + CONS_Alert(CONS_ERROR, M_GetText("Couldn't create screen shot %s in %s\n"), freename, pathname); else CONS_Alert(CONS_ERROR, M_GetText("Couldn't create screen shot in %s (all 10000 slots used!)\n"), pathname); diff --git a/src/m_misc.h b/src/m_misc.h index 990e15b3c..3d42b4244 100644 --- a/src/m_misc.h +++ b/src/m_misc.h @@ -64,7 +64,7 @@ void FIL_ForceExtension(char *path, const char *extension); boolean FIL_CheckExtension(const char *in); #ifdef HAVE_PNG -boolean M_SavePNG(const char *filename, void *data, int width, int height, const UINT8 *palette, char **error); +boolean M_SavePNG(const char *filename, void *data, int width, int height, const UINT8 *palette); #endif extern boolean takescreenshot; From a3732678e06c7c4e89276e8f19f3b72f7bb7ca41 Mon Sep 17 00:00:00 2001 From: Jimita the Cat Date: Wed, 2 Jan 2019 00:41:52 -0300 Subject: [PATCH 16/64] Add support for flashpals in screenshots (cherry picked from commit e765b9400cf741eb8aaa72768ef677769ee5c12b) --- src/hardware/hw_draw.c | 6 +++--- src/hardware/hw_main.h | 2 +- src/m_misc.c | 18 ++++++++++-------- src/m_misc.h | 2 +- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index eca6edfc1..eb1db7d70 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -1196,14 +1196,14 @@ UINT8 *HWR_GetScreenshot(void) return buf; } -boolean HWR_Screenshot(const char *pathname) +boolean HWR_Screenshot(const char *pathname, char **error) { boolean ret; UINT8 *buf = malloc(vid.width * vid.height * 3 * sizeof (*buf)); if (!buf) { - CONS_Debug(DBG_RENDER, "HWR_Screenshot: Failed to allocate memory\n"); + *error = "Failed to allocate memory for HWR_Screenshot"; return false; } @@ -1211,7 +1211,7 @@ boolean HWR_Screenshot(const char *pathname) HWD.pfnReadRect(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf); #ifdef USE_PNG - ret = M_SavePNG(pathname, buf, vid.width, vid.height, NULL); + ret = M_SavePNG(pathname, buf, vid.width, vid.height, NULL, &*error); // c_irl #else ret = saveTGA(pathname, buf, vid.width, vid.height); #endif diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 67c2f5430..109c5cb20 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -53,7 +53,7 @@ void HWR_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 color); void HWR_DrawPic(INT32 x,INT32 y,lumpnum_t lumpnum); UINT8 *HWR_GetScreenshot(void); -boolean HWR_Screenshot(const char *pathname); +boolean HWR_Screenshot(const char *pathname, char **error); void HWR_AddCommands(void); void HWR_CorrectSWTricks(void); diff --git a/src/m_misc.c b/src/m_misc.c index a63c31ce1..40d8c103f 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -1262,8 +1262,9 @@ void M_StopMovie(void) * \param height Height of the picture. * \param palette Palette of image data. * \note if palette is NULL, BGR888 format + * \param error Error string to return, if screenshot failed. */ -boolean M_SavePNG(const char *filename, void *data, int width, int height, const UINT8 *palette) +boolean M_SavePNG(const char *filename, void *data, int width, int height, const UINT8 *palette, char **error) { png_structp png_ptr; png_infop png_info_ptr; @@ -1277,14 +1278,14 @@ boolean M_SavePNG(const char *filename, void *data, int width, int height, const png_FILE = fopen(filename,"wb"); if (!png_FILE) { - CONS_Debug(DBG_RENDER, "M_SavePNG: Error on opening %s for write\n", filename); + *error = "Failed to open file for write"; return false; } png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, PNG_error, PNG_warn); if (!png_ptr) { - CONS_Debug(DBG_RENDER, "M_SavePNG: Error on initialize libpng\n"); + *error = "Failed to initialize libpng"; fclose(png_FILE); remove(filename); return false; @@ -1293,7 +1294,7 @@ boolean M_SavePNG(const char *filename, void *data, int width, int height, const png_info_ptr = png_create_info_struct(png_ptr); if (!png_info_ptr) { - CONS_Debug(DBG_RENDER, "M_SavePNG: Error on allocate for libpng\n"); + *error = "Failed to allocate memory for libpng"; png_destroy_write_struct(&png_ptr, NULL); fclose(png_FILE); remove(filename); @@ -1306,7 +1307,7 @@ boolean M_SavePNG(const char *filename, void *data, int width, int height, const if (setjmp(png_jmpbuf(png_ptr))) #endif { - //CONS_Debug(DBG_RENDER, "libpng write error on %s\n", filename); + *error = "libpng write error"; png_destroy_write_struct(&png_ptr, &png_info_ptr); fclose(png_FILE); remove(filename); @@ -1457,6 +1458,7 @@ void M_DoScreenShot(void) #if NUMSCREENS > 2 const char *freename = NULL, *pathname = "."; boolean ret = false; + char *error = "Unknown error"; UINT8 *linear = NULL; // Don't take multiple screenshots, obviously @@ -1497,13 +1499,13 @@ void M_DoScreenShot(void) // save the pcx file #ifdef HWRENDER if (rendermode == render_opengl) - ret = HWR_Screenshot(va(pandf,pathname,freename)); + ret = HWR_Screenshot(va(pandf,pathname,freename), &error); else #endif { M_CreateScreenShotPalette(); #ifdef USE_PNG - ret = M_SavePNG(va(pandf,pathname,freename), linear, vid.width, vid.height, screenshot_palette); + ret = M_SavePNG(va(pandf,pathname,freename), linear, vid.width, vid.height, screenshot_palette, &error); #else ret = WritePCXfile(va(pandf,pathname,freename), linear, vid.width, vid.height, screenshot_palette); #endif @@ -1518,7 +1520,7 @@ failure: else { if (freename) - CONS_Alert(CONS_ERROR, M_GetText("Couldn't create screen shot %s in %s\n"), freename, pathname); + CONS_Alert(CONS_ERROR, M_GetText("Couldn't create screen shot %s in %s (%s)\n"), freename, pathname, error); else CONS_Alert(CONS_ERROR, M_GetText("Couldn't create screen shot in %s (all 10000 slots used!)\n"), pathname); diff --git a/src/m_misc.h b/src/m_misc.h index 3d42b4244..990e15b3c 100644 --- a/src/m_misc.h +++ b/src/m_misc.h @@ -64,7 +64,7 @@ void FIL_ForceExtension(char *path, const char *extension); boolean FIL_CheckExtension(const char *in); #ifdef HAVE_PNG -boolean M_SavePNG(const char *filename, void *data, int width, int height, const UINT8 *palette); +boolean M_SavePNG(const char *filename, void *data, int width, int height, const UINT8 *palette, char **error); #endif extern boolean takescreenshot; From 9ded0d1770c8dd071d1d7fd7ade73504f4db2c6d Mon Sep 17 00:00:00 2001 From: Jimita the Cat Date: Wed, 2 Jan 2019 01:01:57 -0300 Subject: [PATCH 17/64] dumb (cherry picked from commit 892e65071281e1aa2bd6158748120cf4b7cd81c2) --- src/hardware/hw_draw.c | 6 +++--- src/hardware/hw_main.h | 2 +- src/m_misc.c | 18 ++++++++---------- src/m_misc.h | 2 +- 4 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index eb1db7d70..eca6edfc1 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -1196,14 +1196,14 @@ UINT8 *HWR_GetScreenshot(void) return buf; } -boolean HWR_Screenshot(const char *pathname, char **error) +boolean HWR_Screenshot(const char *pathname) { boolean ret; UINT8 *buf = malloc(vid.width * vid.height * 3 * sizeof (*buf)); if (!buf) { - *error = "Failed to allocate memory for HWR_Screenshot"; + CONS_Debug(DBG_RENDER, "HWR_Screenshot: Failed to allocate memory\n"); return false; } @@ -1211,7 +1211,7 @@ boolean HWR_Screenshot(const char *pathname, char **error) HWD.pfnReadRect(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf); #ifdef USE_PNG - ret = M_SavePNG(pathname, buf, vid.width, vid.height, NULL, &*error); // c_irl + ret = M_SavePNG(pathname, buf, vid.width, vid.height, NULL); #else ret = saveTGA(pathname, buf, vid.width, vid.height); #endif diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 109c5cb20..67c2f5430 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -53,7 +53,7 @@ void HWR_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 color); void HWR_DrawPic(INT32 x,INT32 y,lumpnum_t lumpnum); UINT8 *HWR_GetScreenshot(void); -boolean HWR_Screenshot(const char *pathname, char **error); +boolean HWR_Screenshot(const char *pathname); void HWR_AddCommands(void); void HWR_CorrectSWTricks(void); diff --git a/src/m_misc.c b/src/m_misc.c index 40d8c103f..a63c31ce1 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -1262,9 +1262,8 @@ void M_StopMovie(void) * \param height Height of the picture. * \param palette Palette of image data. * \note if palette is NULL, BGR888 format - * \param error Error string to return, if screenshot failed. */ -boolean M_SavePNG(const char *filename, void *data, int width, int height, const UINT8 *palette, char **error) +boolean M_SavePNG(const char *filename, void *data, int width, int height, const UINT8 *palette) { png_structp png_ptr; png_infop png_info_ptr; @@ -1278,14 +1277,14 @@ boolean M_SavePNG(const char *filename, void *data, int width, int height, const png_FILE = fopen(filename,"wb"); if (!png_FILE) { - *error = "Failed to open file for write"; + CONS_Debug(DBG_RENDER, "M_SavePNG: Error on opening %s for write\n", filename); return false; } png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, PNG_error, PNG_warn); if (!png_ptr) { - *error = "Failed to initialize libpng"; + CONS_Debug(DBG_RENDER, "M_SavePNG: Error on initialize libpng\n"); fclose(png_FILE); remove(filename); return false; @@ -1294,7 +1293,7 @@ boolean M_SavePNG(const char *filename, void *data, int width, int height, const png_info_ptr = png_create_info_struct(png_ptr); if (!png_info_ptr) { - *error = "Failed to allocate memory for libpng"; + CONS_Debug(DBG_RENDER, "M_SavePNG: Error on allocate for libpng\n"); png_destroy_write_struct(&png_ptr, NULL); fclose(png_FILE); remove(filename); @@ -1307,7 +1306,7 @@ boolean M_SavePNG(const char *filename, void *data, int width, int height, const if (setjmp(png_jmpbuf(png_ptr))) #endif { - *error = "libpng write error"; + //CONS_Debug(DBG_RENDER, "libpng write error on %s\n", filename); png_destroy_write_struct(&png_ptr, &png_info_ptr); fclose(png_FILE); remove(filename); @@ -1458,7 +1457,6 @@ void M_DoScreenShot(void) #if NUMSCREENS > 2 const char *freename = NULL, *pathname = "."; boolean ret = false; - char *error = "Unknown error"; UINT8 *linear = NULL; // Don't take multiple screenshots, obviously @@ -1499,13 +1497,13 @@ void M_DoScreenShot(void) // save the pcx file #ifdef HWRENDER if (rendermode == render_opengl) - ret = HWR_Screenshot(va(pandf,pathname,freename), &error); + ret = HWR_Screenshot(va(pandf,pathname,freename)); else #endif { M_CreateScreenShotPalette(); #ifdef USE_PNG - ret = M_SavePNG(va(pandf,pathname,freename), linear, vid.width, vid.height, screenshot_palette, &error); + ret = M_SavePNG(va(pandf,pathname,freename), linear, vid.width, vid.height, screenshot_palette); #else ret = WritePCXfile(va(pandf,pathname,freename), linear, vid.width, vid.height, screenshot_palette); #endif @@ -1520,7 +1518,7 @@ failure: else { if (freename) - CONS_Alert(CONS_ERROR, M_GetText("Couldn't create screen shot %s in %s (%s)\n"), freename, pathname, error); + CONS_Alert(CONS_ERROR, M_GetText("Couldn't create screen shot %s in %s\n"), freename, pathname); else CONS_Alert(CONS_ERROR, M_GetText("Couldn't create screen shot in %s (all 10000 slots used!)\n"), pathname); diff --git a/src/m_misc.h b/src/m_misc.h index 990e15b3c..3d42b4244 100644 --- a/src/m_misc.h +++ b/src/m_misc.h @@ -64,7 +64,7 @@ void FIL_ForceExtension(char *path, const char *extension); boolean FIL_CheckExtension(const char *in); #ifdef HAVE_PNG -boolean M_SavePNG(const char *filename, void *data, int width, int height, const UINT8 *palette, char **error); +boolean M_SavePNG(const char *filename, void *data, int width, int height, const UINT8 *palette); #endif extern boolean takescreenshot; From 3c2adbb7d187d6a77b2b45762bd29e150ed2bc4c Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 23 Mar 2020 17:08:44 -0700 Subject: [PATCH 18/64] Fix whacky history --- src/m_misc.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/m_misc.c b/src/m_misc.c index a63c31ce1..acd150169 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -672,7 +672,7 @@ static void PNG_warn(png_structp PNG, png_const_charp pngtext) CONS_Debug(DBG_RENDER, "libpng warning at %p: %s", PNG, pngtext); } -static void M_PNGhdr(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png_uint_32 width, PNG_CONST png_uint_32 height, const boolean palette) +static void M_PNGhdr(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png_uint_32 width, PNG_CONST png_uint_32 height, PNG_CONST png_byte *palette) { const png_byte png_interlace = PNG_INTERLACE_NONE; //PNG_INTERLACE_ADAM7 if (palette) @@ -680,15 +680,13 @@ static void M_PNGhdr(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png_ png_colorp png_PLTE = png_malloc(png_ptr, sizeof(png_color)*256); //palette png_uint_16 i; - RGBA_t *pal = ((cv_screenshot_colorprofile.value) - ? pLocalPalette - : pMasterPalette); + const png_byte *pal = palette; for (i = 0; i < 256; i++) { - png_PLTE[i].red = pal[i].s.red; - png_PLTE[i].green = pal[i].s.green; - png_PLTE[i].blue = pal[i].s.blue; + png_PLTE[i].red = *pal; pal++; + png_PLTE[i].green = *pal; pal++; + png_PLTE[i].blue = *pal; pal++; } png_set_IHDR(png_ptr, png_info_ptr, width, height, 8, PNG_COLOR_TYPE_PALETTE, @@ -964,7 +962,7 @@ static void M_PNGfix_acTL(png_structp png_ptr, png_infop png_info_ptr, #endif } -static boolean M_SetupaPNG(png_const_charp filename, boolean palette) +static boolean M_SetupaPNG(png_const_charp filename, png_bytep pal) { apng_FILE = fopen(filename,"wb+"); // + mode for reading if (!apng_FILE) @@ -1016,7 +1014,7 @@ static boolean M_SetupaPNG(png_const_charp filename, boolean palette) png_set_compression_strategy(apng_ptr, cv_zlib_strategya.value); png_set_compression_window_bits(apng_ptr, cv_zlib_window_bitsa.value); - M_PNGhdr(apng_ptr, apng_info_ptr, vid.width, vid.height, palette); + M_PNGhdr(apng_ptr, apng_info_ptr, vid.width, vid.height, pal); M_PNGText(apng_ptr, apng_info_ptr, true); From 1a759a49049d72a0d0352459ffa0ec767427abef Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 10 Nov 2019 00:04:11 -0300 Subject: [PATCH 19/64] GIF recording (cherry picked from commit d467d2b2295a9660631774b9edb29555cc5c30fe) --- src/hardware/hw_main.c | 4 ++-- src/m_anigif.c | 52 +++++++++++++++++++++++++++++++++++++++--- src/m_misc.c | 8 ++----- src/r_data.h | 2 ++ src/sdl/i_video.c | 5 ++-- src/v_video.c | 27 ++++++++++++++++++---- src/v_video.h | 12 ++++++++++ 7 files changed, 91 insertions(+), 19 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 73e65cceb..a22e5b586 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -582,7 +582,7 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is if (nrPlaneVerts < 3) //not even a triangle ? return; - if ((UINT32)nrPlaneVerts > UINT16_MAX) // FIXME: exceeds plVerts size + if (nrPlaneVerts > INT16_MAX) // FIXME: exceeds plVerts size { CONS_Debug(DBG_RENDER, "polygon size of %d exceeds max value of %d vertices\n", nrPlaneVerts, UINT16_MAX); return; @@ -3229,7 +3229,7 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, if (nrPlaneVerts < 3) //not even a triangle ? return; - if (nrPlaneVerts > UINT16_MAX) // FIXME: exceeds plVerts size + if (nrPlaneVerts > INT16_MAX) // FIXME: exceeds plVerts size { CONS_Debug(DBG_RENDER, "polygon size of %s exceeds max value of %d vertices\n", sizeu1(nrPlaneVerts), UINT16_MAX); return; diff --git a/src/m_anigif.c b/src/m_anigif.c index 64254163d..1e5ece33b 100644 --- a/src/m_anigif.c +++ b/src/m_anigif.c @@ -20,6 +20,10 @@ #include "i_video.h" #include "m_misc.h" +#ifdef HWRENDER +#include "hardware/hw_main.h" +#endif + // GIFs are always little-endian #include "byteptr.h" @@ -457,6 +461,32 @@ const UINT8 gifframe_gchead[4] = {0x21,0xF9,0x04,0x04}; // GCE, bytes, packed by static UINT8 *gifframe_data = NULL; static size_t gifframe_size = 8192; +#ifdef HWRENDER +static void hwrconvert(void) +{ + UINT8 *linear = HWR_GetScreenshot(); + UINT8 *dest = screens[2]; + UINT8 r, g, b; + INT32 x, y; + size_t i = 0; + + InitColorLUT(); + + for (y = 0; y < vid.height; y++) + { + for (x = 0; x < vid.width; x++, i += 3) + { + r = (UINT8)linear[i]; + g = (UINT8)linear[i + 1]; + b = (UINT8)linear[i + 2]; + dest[(y * vid.width) + x] = colorlookup[r >> SHIFTCOLORBITS][g >> SHIFTCOLORBITS][b >> SHIFTCOLORBITS]; + } + } + + free(linear); +} +#endif + // // GIF_framewrite // writes a frame into the file. @@ -482,7 +512,12 @@ static void GIF_framewrite(void) GIF_optimizeregion(cur_screen, movie_screen, &blitx, &blity, &blitw, &blith); // blit to temp screen - I_ReadScreen(movie_screen); + if (rendermode == render_soft) + I_ReadScreen(movie_screen); +#ifdef HWRENDER + else if (rendermode == render_opengl) + hwrconvert(); +#endif } else { @@ -491,7 +526,18 @@ static void GIF_framewrite(void) blith = vid.height; if (gif_frames == 0) - I_ReadScreen(movie_screen); + { + if (rendermode == render_soft) + I_ReadScreen(movie_screen); +#ifdef HWRENDER + else if (rendermode == render_opengl) + { + hwrconvert(); + VID_BlitLinearScreen(screens[2], screens[0], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes); + } +#endif + } + movie_screen = screens[0]; } @@ -580,7 +626,7 @@ static void GIF_framewrite(void) // INT32 GIF_open(const char *filename) { -#ifdef HWRENDER +#if 0 if (rendermode != render_soft) { CONS_Alert(CONS_WARNING, M_GetText("GIFs cannot be taken in non-software modes!\n")); diff --git a/src/m_misc.c b/src/m_misc.c index acd150169..800d34e79 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -1120,12 +1120,8 @@ void M_StartMovie(void) switch (cv_moviemode.value) { case MM_GIF: - if (rendermode == render_soft) - { - moviemode = M_StartMovieGIF(pathname); - break; - } - /* FALLTHRU */ + moviemode = M_StartMovieGIF(pathname); + break; case MM_APNG: moviemode = M_StartMovieAPNG(pathname); break; diff --git a/src/r_data.h b/src/r_data.h index cd61bbaac..e5dd3764a 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -99,6 +99,8 @@ void R_MakeInvertmap(void); #endif const char *R_ColormapNameForNum(INT32 num); +UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b); + extern INT32 numtextures; #endif diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index c900417ab..1a8175dc3 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1647,6 +1647,7 @@ INT32 VID_SetMode(INT32 modeNum) //Impl_SetWindowName("SRB2Kart "VERSIONSTRING); SDLSetMode(vid.width, vid.height, USE_FULLSCREEN); + Impl_VideoSetupBuffer(); if (rendermode == render_soft) { @@ -1655,8 +1656,6 @@ INT32 VID_SetMode(INT32 modeNum) SDL_FreeSurface(bufSurface); bufSurface = NULL; } - - Impl_VideoSetupBuffer(); } return SDL_TRUE; @@ -1779,7 +1778,7 @@ static void Impl_VideoSetupSDLBuffer(void) static void Impl_VideoSetupBuffer(void) { // Set up game's software render buffer - if (rendermode == render_soft) + //if (rendermode == render_soft) { vid.rowbytes = vid.width * vid.bpp; vid.direct = NULL; diff --git a/src/v_video.c b/src/v_video.c index c482debda..2fbdbb1f9 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -2867,6 +2867,27 @@ Unoptimized version #endif } +// Taken from my videos-in-SRB2 project +// Generates a color look-up table +// which has up to 64 colors at each channel +// (see the defines in v_video.h) + +UINT8 colorlookup[CLUTSIZE][CLUTSIZE][CLUTSIZE]; + +void InitColorLUT(void) +{ + UINT8 r, g, b; + static boolean clutinit = false; + if (!clutinit) + { + for (r = 0; r < CLUTSIZE; r++) + for (g = 0; g < CLUTSIZE; g++) + for (b = 0; b < CLUTSIZE; b++) + colorlookup[r][g][b] = NearestColor(r << SHIFTCOLORBITS, g << SHIFTCOLORBITS, b << SHIFTCOLORBITS); + clutinit = true; + } +} + // V_Init // old software stuff, buffers are allocated at video mode setup // here we set the screens[x] pointers accordingly @@ -2878,13 +2899,9 @@ void V_Init(void) const INT32 screensize = vid.rowbytes * vid.height; LoadMapPalette(); - // hardware modes do not use screens[] pointers + for (i = 0; i < NUMSCREENS; i++) screens[i] = NULL; - if (rendermode != render_soft) - { - return; // be sure to cause a NULL read/write error so we detect it, in case of.. - } // start address of NUMSCREENS * width*height vidbuffers if (base) diff --git a/src/v_video.h b/src/v_video.h index 7478c6903..c9751a34a 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -36,6 +36,18 @@ cv_rsaturation, cv_ysaturation, cv_gsaturation, cv_csaturation, cv_bsaturation, // Allocates buffer screens, call before R_Init. void V_Init(void); +// Taken from my videos-in-SRB2 project +// Generates a color look-up table +// which has up to 64 colors at each channel + +#define COLORBITS 6 +#define SHIFTCOLORBITS (8-COLORBITS) +#define CLUTSIZE (1< Date: Mon, 11 Nov 2019 00:02:22 -0300 Subject: [PATCH 20/64] Recreate the CLUT when the palette changes (cherry picked from commit 6e0ff4a4a40306a59c8b18d03ae86560e6a52a4a) --- src/v_video.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/v_video.c b/src/v_video.c index 2fbdbb1f9..41505eef3 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -2878,13 +2878,15 @@ void InitColorLUT(void) { UINT8 r, g, b; static boolean clutinit = false; - if (!clutinit) + static RGBA_t *lastpalette = NULL; + if ((!clutinit) || (lastpalette != pLocalPalette)) { for (r = 0; r < CLUTSIZE; r++) for (g = 0; g < CLUTSIZE; g++) for (b = 0; b < CLUTSIZE; b++) colorlookup[r][g][b] = NearestColor(r << SHIFTCOLORBITS, g << SHIFTCOLORBITS, b << SHIFTCOLORBITS); clutinit = true; + lastpalette = pLocalPalette; } } From 2e62f5c793355b9b566eae4f5c77bdedb444a528 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 17 Dec 2019 15:20:22 -0300 Subject: [PATCH 21/64] Don't use the local palette, because OpenGL mixes it into the textures themselves (cherry picked from commit 0af71fafc57fb842a8c7a9a4853d8c7fbb2bf7fc) --- src/m_anigif.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/m_anigif.c b/src/m_anigif.c index 1e5ece33b..fb9ebaffd 100644 --- a/src/m_anigif.c +++ b/src/m_anigif.c @@ -432,8 +432,11 @@ static void GIF_headwrite(void) // write color table { - RGBA_t *pal = ((cv_screenshot_colorprofile.value) - ? pLocalPalette + RGBA_t *pal = ((cv_screenshot_colorprofile.value +#ifdef HWRENDER + && (rendermode == render_soft) +#endif + ) ? pLocalPalette : pMasterPalette); for (i = 0; i < 256; i++) From b8f5166d8e08b237d5fc993b9465725faa156218 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 17 Dec 2019 15:37:43 -0300 Subject: [PATCH 22/64] Avoid recreating the color LUT mid-recording-frame (cherry picked from commit c3f0e6aa4472f0754a7f392759b9f93cb3c7651b) --- src/m_anigif.c | 21 +++++++++++++-------- src/v_video.c | 6 +++--- src/v_video.h | 2 +- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/m_anigif.c b/src/m_anigif.c index fb9ebaffd..c298ad705 100644 --- a/src/m_anigif.c +++ b/src/m_anigif.c @@ -33,6 +33,7 @@ consvar_t cv_gif_downscale = {"gif_downscale", "On", CV_SAVE, CV_OnOff, NULL, 0 #ifdef HAVE_ANIGIF static boolean gif_optimize = false; // So nobody can do something dumb static boolean gif_downscale = false; // like changing cvars mid output +static RGBA_t *gif_palette = NULL; static FILE *gif_out = NULL; static INT32 gif_frames = 0; @@ -432,13 +433,7 @@ static void GIF_headwrite(void) // write color table { - RGBA_t *pal = ((cv_screenshot_colorprofile.value -#ifdef HWRENDER - && (rendermode == render_soft) -#endif - ) ? pLocalPalette - : pMasterPalette); - + RGBA_t *pal = gif_palette; for (i = 0; i < 256; i++) { WRITEUINT8(p, pal[i].s.red); @@ -473,7 +468,7 @@ static void hwrconvert(void) INT32 x, y; size_t i = 0; - InitColorLUT(); + InitColorLUT(gif_palette); for (y = 0; y < vid.height; y++) { @@ -643,6 +638,16 @@ INT32 GIF_open(const char *filename) gif_optimize = (!!cv_gif_optimize.value); gif_downscale = (!!cv_gif_downscale.value); + + // GIF color table + // In hardware mode, uses the master palette + gif_palette = ((cv_screenshot_colorprofile.value +#ifdef HWRENDER + && (rendermode == render_soft) +#endif + ) ? pLocalPalette + : pMasterPalette); + GIF_headwrite(); gif_frames = 0; return 1; diff --git a/src/v_video.c b/src/v_video.c index 41505eef3..3300e16bc 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -2874,19 +2874,19 @@ Unoptimized version UINT8 colorlookup[CLUTSIZE][CLUTSIZE][CLUTSIZE]; -void InitColorLUT(void) +void InitColorLUT(RGBA_t *palette) { UINT8 r, g, b; static boolean clutinit = false; static RGBA_t *lastpalette = NULL; - if ((!clutinit) || (lastpalette != pLocalPalette)) + if ((!clutinit) || (lastpalette != palette)) { for (r = 0; r < CLUTSIZE; r++) for (g = 0; g < CLUTSIZE; g++) for (b = 0; b < CLUTSIZE; b++) colorlookup[r][g][b] = NearestColor(r << SHIFTCOLORBITS, g << SHIFTCOLORBITS, b << SHIFTCOLORBITS); clutinit = true; - lastpalette = pLocalPalette; + lastpalette = palette; } } diff --git a/src/v_video.h b/src/v_video.h index c9751a34a..4e78e9f9e 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -46,7 +46,7 @@ void V_Init(void); extern UINT8 colorlookup[CLUTSIZE][CLUTSIZE][CLUTSIZE]; -void InitColorLUT(void); +void InitColorLUT(RGBA_t *palette); // Set the current RGB palette lookup to use for palettized graphics void V_SetPalette(INT32 palettenum); From f106ba7ac4913618574c5392caa639a20648c18f Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 27 Jan 2020 13:55:13 -0300 Subject: [PATCH 23/64] Fix color LUT using the wrong palette (cherry picked from commit 636093a59ddd95b25d79c4ebff51dc6412de1956) --- src/m_anigif.c | 18 +++++------------- src/r_data.c | 12 ++++++++---- src/r_data.h | 3 ++- src/v_video.c | 3 +-- src/v_video.h | 5 +---- 5 files changed, 17 insertions(+), 24 deletions(-) diff --git a/src/m_anigif.c b/src/m_anigif.c index c298ad705..08b0903de 100644 --- a/src/m_anigif.c +++ b/src/m_anigif.c @@ -624,14 +624,6 @@ static void GIF_framewrite(void) // INT32 GIF_open(const char *filename) { -#if 0 - if (rendermode != render_soft) - { - CONS_Alert(CONS_WARNING, M_GetText("GIFs cannot be taken in non-software modes!\n")); - return 0; - } -#endif - gif_out = fopen(filename, "wb"); if (!gif_out) return 0; @@ -640,13 +632,13 @@ INT32 GIF_open(const char *filename) gif_downscale = (!!cv_gif_downscale.value); // GIF color table - // In hardware mode, uses the master palette - gif_palette = ((cv_screenshot_colorprofile.value + // In hardware mode, forces the local palette #ifdef HWRENDER - && (rendermode == render_soft) + if (rendermode == render_opengl) + gif_palette = pLocalPalette; + else #endif - ) ? pLocalPalette - : pMasterPalette); + gif_palette = ((cv_screenshot_colorprofile.value) ? pLocalPalette : pMasterPalette); GIF_headwrite(); gif_frames = 0; diff --git a/src/r_data.c b/src/r_data.c index 843ed2acb..b37431870 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -1427,16 +1427,20 @@ INT32 R_CreateColormap(char *p1, char *p2, char *p3) // Thanks to quake2 source! // utils3/qdata/images.c -UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b) +UINT8 NearestPaletteColor(UINT8 r, UINT8 g, UINT8 b, RGBA_t *palette) { int dr, dg, db; int distortion, bestdistortion = 256 * 256 * 4, bestcolor = 0, i; + // Use master palette if none specified + if (palette == NULL) + palette = pMasterPalette; + for (i = 0; i < 256; i++) { - dr = r - pMasterPalette[i].s.red; - dg = g - pMasterPalette[i].s.green; - db = b - pMasterPalette[i].s.blue; + dr = r - palette[i].s.red; + dg = g - palette[i].s.green; + db = b - palette[i].s.blue; distortion = dr*dr + dg*dg + db*db; if (distortion < bestdistortion) { diff --git a/src/r_data.h b/src/r_data.h index e5dd3764a..86ba0885b 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -99,7 +99,8 @@ void R_MakeInvertmap(void); #endif const char *R_ColormapNameForNum(INT32 num); -UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b); +UINT8 NearestPaletteColor(UINT8 r, UINT8 g, UINT8 b, RGBA_t *palette); +#define NearestColor(r, g, b) NearestPaletteColor(r, g, b, NULL) extern INT32 numtextures; diff --git a/src/v_video.c b/src/v_video.c index 3300e16bc..517cae719 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -2867,7 +2867,6 @@ Unoptimized version #endif } -// Taken from my videos-in-SRB2 project // Generates a color look-up table // which has up to 64 colors at each channel // (see the defines in v_video.h) @@ -2884,7 +2883,7 @@ void InitColorLUT(RGBA_t *palette) for (r = 0; r < CLUTSIZE; r++) for (g = 0; g < CLUTSIZE; g++) for (b = 0; b < CLUTSIZE; b++) - colorlookup[r][g][b] = NearestColor(r << SHIFTCOLORBITS, g << SHIFTCOLORBITS, b << SHIFTCOLORBITS); + colorlookup[r][g][b] = NearestPaletteColor(r << SHIFTCOLORBITS, g << SHIFTCOLORBITS, b << SHIFTCOLORBITS, palette); clutinit = true; lastpalette = palette; } diff --git a/src/v_video.h b/src/v_video.h index 4e78e9f9e..ee7a681d8 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -36,10 +36,7 @@ cv_rsaturation, cv_ysaturation, cv_gsaturation, cv_csaturation, cv_bsaturation, // Allocates buffer screens, call before R_Init. void V_Init(void); -// Taken from my videos-in-SRB2 project -// Generates a color look-up table -// which has up to 64 colors at each channel - +// Color look-up table #define COLORBITS 6 #define SHIFTCOLORBITS (8-COLORBITS) #define CLUTSIZE (1< Date: Wed, 29 Jan 2020 13:47:55 -0300 Subject: [PATCH 24/64] Local Color Table for GIF movie mode (cherry picked from commit 5a330803ec5bea2ca7b6b30bf7972b11753b571d) --- src/d_netcmd.c | 1 + src/m_anigif.c | 89 ++++++++++++++++++++++++++++++++++++++------------ src/m_anigif.h | 2 +- 3 files changed, 71 insertions(+), 21 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 36cb01adf..21bdd033e 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -805,6 +805,7 @@ void D_RegisterClientCommands(void) // GIF variables CV_RegisterVar(&cv_gif_optimize); CV_RegisterVar(&cv_gif_downscale); + CV_RegisterVar(&cv_gif_localcolortable); #ifdef WALLSPLATS CV_RegisterVar(&cv_splats); diff --git a/src/m_anigif.c b/src/m_anigif.c index 08b0903de..31bc11070 100644 --- a/src/m_anigif.c +++ b/src/m_anigif.c @@ -19,6 +19,7 @@ #include "v_video.h" #include "i_video.h" #include "m_misc.h" +#include "st_stuff.h" // st_palette #ifdef HWRENDER #include "hardware/hw_main.h" @@ -29,10 +30,12 @@ consvar_t cv_gif_optimize = {"gif_optimize", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_gif_downscale = {"gif_downscale", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_gif_localcolortable = {"gif_localcolortable", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; #ifdef HAVE_ANIGIF static boolean gif_optimize = false; // So nobody can do something dumb static boolean gif_downscale = false; // like changing cvars mid output +static boolean gif_localcolortable = false; static RGBA_t *gif_palette = NULL; static FILE *gif_out = NULL; @@ -393,6 +396,41 @@ const UINT8 gifhead_nsid[19] = {0x21,0xFF,0x0B, // extension block + size 0x4E,0x45,0x54,0x53,0x43,0x41,0x50,0x45,0x32,0x2E,0x30, // NETSCAPE2.0 0x03,0x01,0xFF,0xFF,0x00}; // sub-block, repetitions + +// +// GIF_setpalette +// determine the gif palette. +// +static void GIF_setpalette(void) +{ + // In hardware mode, uses the master palette + size_t palnum = (rendermode == render_soft) ? ((gif_localcolortable) ? max(st_palette, 0) : 0) : 0; + gif_palette = ((cv_screenshot_colorprofile.value +#ifdef HWRENDER + && (rendermode == render_soft) +#endif + ) ? &pLocalPalette[palnum*256] + : &pMasterPalette[palnum*256]); +} + +// +// GIF_palwrite +// writes the gif palette. +// used both for the header and the local color table. +// +static UINT8 *GIF_palwrite(UINT8 *p) +{ + INT32 i; + RGBA_t *pal = gif_palette; + for (i = 0; i < 256; i++) + { + WRITEUINT8(p, pal[i].s.red); + WRITEUINT8(p, pal[i].s.green); + WRITEUINT8(p, pal[i].s.blue); + } + return p; +} + // // GIF_headwrite // writes the gif header to the currently open output file. @@ -402,8 +440,10 @@ static void GIF_headwrite(void) { UINT8 *gifhead = Z_Malloc(800, PU_STATIC, NULL); UINT8 *p = gifhead; - INT32 i; + UINT8 *last_p; UINT16 rwidth, rheight; + size_t totalbytes; + INT32 i; if (!gif_out) return; @@ -423,30 +463,37 @@ static void GIF_headwrite(void) rwidth = vid.width; rheight = vid.height; } + + last_p = p; WRITEUINT16(p, rwidth); WRITEUINT16(p, rheight); // colors, aspect, etc - WRITEUINT8(p, 0xFF); // TRANSPARENTPIXEL + WRITEUINT8(p, (gif_localcolortable ? 0xF0 : 0xF7)); // (0xF7 = 1111 0111) WRITEUINT8(p, 0x00); WRITEUINT8(p, 0x00); + // Lactozilla: should be 800 without a local color table + totalbytes = sizeof(gifhead_base) + sizeof(gifhead_nsid) + (p - last_p); + // write color table + if (!gif_localcolortable) { - RGBA_t *pal = gif_palette; - for (i = 0; i < 256; i++) - { - WRITEUINT8(p, pal[i].s.red); - WRITEUINT8(p, pal[i].s.green); - WRITEUINT8(p, pal[i].s.blue); - } + p = GIF_palwrite(p); + totalbytes += (256 * 3); + } + else + { + // write a dummy palette + for (i = 0; i < 6; i++, totalbytes++) + WRITEUINT8(p, 0); } // write extension block WRITEMEM(p, gifhead_nsid, sizeof(gifhead_nsid)); // write to file and be done with it! - fwrite(gifhead, 1, 800, gif_out); + fwrite(gifhead, 1, totalbytes, gif_out); Z_Free(gifhead); } @@ -566,7 +613,15 @@ static void GIF_framewrite(void) WRITEUINT16(p, (UINT16)(blity / scrbuf_downscaleamt)); WRITEUINT16(p, (UINT16)(blitw / scrbuf_downscaleamt)); WRITEUINT16(p, (UINT16)(blith / scrbuf_downscaleamt)); - WRITEUINT8(p, 0); // no local table of colors + + if (!gif_localcolortable) + WRITEUINT8(p, 0); // no local table of colors + else + { + WRITEUINT8(p, 0x87); // (0x87 = 1000 0111) + GIF_setpalette(); + p = GIF_palwrite(p); + } scrbuf_pos = movie_screen + blitx + (blity * vid.width); scrbuf_writeend = scrbuf_pos + (blitw - 1) + ((blith - 1) * vid.width); @@ -630,15 +685,9 @@ INT32 GIF_open(const char *filename) gif_optimize = (!!cv_gif_optimize.value); gif_downscale = (!!cv_gif_downscale.value); - - // GIF color table - // In hardware mode, forces the local palette -#ifdef HWRENDER - if (rendermode == render_opengl) - gif_palette = pLocalPalette; - else -#endif - gif_palette = ((cv_screenshot_colorprofile.value) ? pLocalPalette : pMasterPalette); + gif_localcolortable = (!!cv_gif_localcolortable.value); + if (!gif_localcolortable) + GIF_setpalette(); GIF_headwrite(); gif_frames = 0; diff --git a/src/m_anigif.h b/src/m_anigif.h index 6d94ecf8c..bec481d59 100644 --- a/src/m_anigif.h +++ b/src/m_anigif.h @@ -27,6 +27,6 @@ void GIF_frame(void); INT32 GIF_close(void); #endif -extern consvar_t cv_gif_optimize, cv_gif_downscale; +extern consvar_t cv_gif_optimize, cv_gif_downscale, cv_gif_localcolortable; #endif From e75baf70b0bd6ebee402c0b22b15df154fecde4f Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 29 Jan 2020 13:56:39 -0300 Subject: [PATCH 25/64] Uh (cherry picked from commit 999e72ab325301d248837f5337eb8f90143231ef) --- src/m_anigif.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/m_anigif.c b/src/m_anigif.c index 31bc11070..c10d70229 100644 --- a/src/m_anigif.c +++ b/src/m_anigif.c @@ -434,7 +434,6 @@ static UINT8 *GIF_palwrite(UINT8 *p) // // GIF_headwrite // writes the gif header to the currently open output file. -// NOTE that this code does not accomodate for palette changes. // static void GIF_headwrite(void) { From 6f5416954e14fa3f8895624dbf87715760813bd7 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 29 Jan 2020 17:31:27 -0300 Subject: [PATCH 26/64] Only write a Local Color Table if the frame's palette differs from the header's palette (cherry picked from commit 85211dcc09c922e0d42b4eeea387dcecc8e989ae) --- src/m_anigif.c | 73 +++++++++++++++++++++++++------------------------- 1 file changed, 37 insertions(+), 36 deletions(-) diff --git a/src/m_anigif.c b/src/m_anigif.c index c10d70229..b914cb14c 100644 --- a/src/m_anigif.c +++ b/src/m_anigif.c @@ -35,8 +35,12 @@ consvar_t cv_gif_localcolortable = {"gif_localcolortable", "On", CV_SAVE, CV_On #ifdef HAVE_ANIGIF static boolean gif_optimize = false; // So nobody can do something dumb static boolean gif_downscale = false; // like changing cvars mid output + +// Palette handling static boolean gif_localcolortable = false; -static RGBA_t *gif_palette = NULL; +static boolean gif_colorprofile = false; +static RGBA_t *gif_headerpalette = NULL; +static RGBA_t *gif_framepalette = NULL; static FILE *gif_out = NULL; static INT32 gif_frames = 0; @@ -398,14 +402,13 @@ const UINT8 gifhead_nsid[19] = {0x21,0xFF,0x0B, // extension block + size // -// GIF_setpalette -// determine the gif palette. +// GIF_getpalette +// determine the palette for the current frame. // -static void GIF_setpalette(void) +static RGBA_t *GIF_getpalette(size_t palnum) { // In hardware mode, uses the master palette - size_t palnum = (rendermode == render_soft) ? ((gif_localcolortable) ? max(st_palette, 0) : 0) : 0; - gif_palette = ((cv_screenshot_colorprofile.value + return ((gif_colorprofile #ifdef HWRENDER && (rendermode == render_soft) #endif @@ -416,12 +419,11 @@ static void GIF_setpalette(void) // // GIF_palwrite // writes the gif palette. -// used both for the header and the local color table. +// used both for the header and local color tables. // -static UINT8 *GIF_palwrite(UINT8 *p) +static UINT8 *GIF_palwrite(UINT8 *p, RGBA_t *pal) { INT32 i; - RGBA_t *pal = gif_palette; for (i = 0; i < 256; i++) { WRITEUINT8(p, pal[i].s.red); @@ -439,10 +441,7 @@ static void GIF_headwrite(void) { UINT8 *gifhead = Z_Malloc(800, PU_STATIC, NULL); UINT8 *p = gifhead; - UINT8 *last_p; UINT16 rwidth, rheight; - size_t totalbytes; - INT32 i; if (!gif_out) return; @@ -463,36 +462,22 @@ static void GIF_headwrite(void) rheight = vid.height; } - last_p = p; WRITEUINT16(p, rwidth); WRITEUINT16(p, rheight); // colors, aspect, etc - WRITEUINT8(p, (gif_localcolortable ? 0xF0 : 0xF7)); // (0xF7 = 1111 0111) + WRITEUINT8(p, 0xF7); // (0xF7 = 1111 0111) WRITEUINT8(p, 0x00); WRITEUINT8(p, 0x00); - // Lactozilla: should be 800 without a local color table - totalbytes = sizeof(gifhead_base) + sizeof(gifhead_nsid) + (p - last_p); - // write color table - if (!gif_localcolortable) - { - p = GIF_palwrite(p); - totalbytes += (256 * 3); - } - else - { - // write a dummy palette - for (i = 0; i < 6; i++, totalbytes++) - WRITEUINT8(p, 0); - } + p = GIF_palwrite(p, gif_headerpalette); // write extension block WRITEMEM(p, gifhead_nsid, sizeof(gifhead_nsid)); // write to file and be done with it! - fwrite(gifhead, 1, totalbytes, gif_out); + fwrite(gifhead, 1, 800, gif_out); Z_Free(gifhead); } @@ -514,7 +499,7 @@ static void hwrconvert(void) INT32 x, y; size_t i = 0; - InitColorLUT(gif_palette); + InitColorLUT(gif_framepalette); for (y = 0; y < vid.height; y++) { @@ -540,6 +525,7 @@ static void GIF_framewrite(void) UINT8 *p; UINT8 *movie_screen = screens[2]; INT32 blitx, blity, blitw, blith; + boolean palchanged; if (!gifframe_data) gifframe_data = Z_Malloc(gifframe_size, PU_STATIC, NULL); @@ -548,8 +534,18 @@ static void GIF_framewrite(void) if (!gif_out) return; + // Lactozilla: Compare the header's palette with the current frame's palette and see if it changed. + if (gif_localcolortable) + { + gif_framepalette = GIF_getpalette((rendermode == render_soft) ? ((gif_localcolortable) ? max(st_palette, 0) : 0) : 0); + palchanged = memcmp(gif_headerpalette, gif_framepalette, sizeof(RGBA_t) * 256); + } + else + palchanged = false; + // Compare image data (for optimizing GIF) - if (gif_optimize && gif_frames > 0) + // If the palette has changed, the entire frame is considered to be different. + if (gif_optimize && gif_frames > 0 && (!palchanged)) { // before blit movie_screen points to last frame, cur_screen points to this frame UINT8 *cur_screen = screens[0]; @@ -617,9 +613,14 @@ static void GIF_framewrite(void) WRITEUINT8(p, 0); // no local table of colors else { - WRITEUINT8(p, 0x87); // (0x87 = 1000 0111) - GIF_setpalette(); - p = GIF_palwrite(p); + if (palchanged) + { + // The palettes are different, so write the Local Color Table! + WRITEUINT8(p, 0x87); // (0x87 = 1000 0111) + p = GIF_palwrite(p, gif_framepalette); + } + else + WRITEUINT8(p, 0); // They are equal, no Local Color Table needed. } scrbuf_pos = movie_screen + blitx + (blity * vid.width); @@ -685,8 +686,8 @@ INT32 GIF_open(const char *filename) gif_optimize = (!!cv_gif_optimize.value); gif_downscale = (!!cv_gif_downscale.value); gif_localcolortable = (!!cv_gif_localcolortable.value); - if (!gif_localcolortable) - GIF_setpalette(); + gif_colorprofile = (!!cv_screenshot_colorprofile.value); + gif_headerpalette = GIF_getpalette(0); GIF_headwrite(); gif_frames = 0; From 21a168d41013445e90093c7c5428cec37cb2ab0e Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 3 Feb 2020 02:24:22 -0300 Subject: [PATCH 27/64] What (cherry picked from commit d1e8744583b9a868665b4b3a5e4803a29829f7a0) --- src/m_anigif.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_anigif.c b/src/m_anigif.c index b914cb14c..15528599b 100644 --- a/src/m_anigif.c +++ b/src/m_anigif.c @@ -537,7 +537,7 @@ static void GIF_framewrite(void) // Lactozilla: Compare the header's palette with the current frame's palette and see if it changed. if (gif_localcolortable) { - gif_framepalette = GIF_getpalette((rendermode == render_soft) ? ((gif_localcolortable) ? max(st_palette, 0) : 0) : 0); + gif_framepalette = GIF_getpalette(max(st_palette, 0)); palchanged = memcmp(gif_headerpalette, gif_framepalette, sizeof(RGBA_t) * 256); } else From ef028e5822c4c1f19f81ec5aa4d9505dc087b818 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 23 Mar 2020 17:50:51 -0700 Subject: [PATCH 28/64] Add a comment because this is confusing --- src/m_anigif.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/m_anigif.c b/src/m_anigif.c index 15528599b..eef94a522 100644 --- a/src/m_anigif.c +++ b/src/m_anigif.c @@ -466,6 +466,10 @@ static void GIF_headwrite(void) WRITEUINT16(p, rheight); // colors, aspect, etc + /* + also these are magical values, check out + https://tronche.com/computer-graphics/gif/gif89a.html#screen-descriptor + */ WRITEUINT8(p, 0xF7); // (0xF7 = 1111 0111) WRITEUINT8(p, 0x00); WRITEUINT8(p, 0x00); From 0a0dede69e509ec5905b04222387bba1fe84e3b2 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 24 Mar 2020 15:13:07 -0700 Subject: [PATCH 29/64] Revert "Correcting gamma to match base SRB2." This reverts commit cdf8c54f2d1feae314daebbaee61f0e03e1fb929. --- src/v_video.c | 32 ++++---------------------------- 1 file changed, 4 insertions(+), 28 deletions(-) diff --git a/src/v_video.c b/src/v_video.c index 517cae719..d7e8b64c1 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -120,6 +120,7 @@ http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter24.html Please check it out if you're trying to maintain this. toast 18/04/17 */ + float Cubepal[2][2][2][3]; // returns whether to apply cube, selectively avoiding expensive operations @@ -305,31 +306,6 @@ static boolean InitCube(void) return true; } -/* -So it turns out that the way gamma was implemented previously, the default -colour profile of the game was messed up. Since this bad decision has been -around for a long time, and the intent is to keep the base game looking the -same, I'm not gonna be the one to remove this base modification. -toast 20/04/17 -*/ -const UINT8 correctiontable[256] = - {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16, - 17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32, - 33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48, - 49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64, - 65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80, - 81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96, - 97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112, - 113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128, - 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, - 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, - 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, - 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, - 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, - 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, - 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, - 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255}; - // keep a copy of the palette so that we can get the RGB value for a color index at any time. static void LoadPalette(const char *lumpname) { @@ -347,9 +323,9 @@ static void LoadPalette(const char *lumpname) pal = W_CacheLumpNum(lumpnum, PU_CACHE); for (i = 0; i < palsize; i++) { - pMasterPalette[i].s.red = pLocalPalette[i].s.red = correctiontable[*pal++]; - pMasterPalette[i].s.green = pLocalPalette[i].s.green = correctiontable[*pal++]; - pMasterPalette[i].s.blue = pLocalPalette[i].s.blue = correctiontable[*pal++]; + pMasterPalette[i].s.red = pLocalPalette[i].s.red = *pal++; + pMasterPalette[i].s.green = pLocalPalette[i].s.green = *pal++; + pMasterPalette[i].s.blue = pLocalPalette[i].s.blue = *pal++; pMasterPalette[i].s.alpha = pLocalPalette[i].s.alpha = 0xFF; // lerp of colour cubing! From 1b6256bd89a4d7c1214ecd25ea92f5b6e201bb51 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 28 Mar 2020 20:57:27 -0700 Subject: [PATCH 30/64] Use the 2.2 frame characters --- src/r_things.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/r_things.h b/src/r_things.h index a50e0803d..470e32fb2 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -219,7 +219,7 @@ char *GetPlayerFacePic(INT32 skinnum); // Future: [[ ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!@ ]] FUNCMATH FUNCINLINE static ATTRINLINE char R_Frame2Char(UINT8 frame) { -#if 1 // 2.1 compat +#if 0 // 2.1 compat return 'A' + frame; #else if (frame < 26) return 'A' + frame; @@ -233,7 +233,7 @@ FUNCMATH FUNCINLINE static ATTRINLINE char R_Frame2Char(UINT8 frame) FUNCMATH FUNCINLINE static ATTRINLINE UINT8 R_Char2Frame(char cn) { -#if 1 // 2.1 compat +#if 0 // 2.1 compat if (cn == '+') return '\\' - 'A'; // PK3 can't use backslash, so use + instead return cn - 'A'; #else From 896f752d94498c45565513f0332f03558a11c5eb Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Sun, 29 Mar 2020 08:39:15 -0400 Subject: [PATCH 31/64] Fix the compile errors I got - void out link variable in non-unix to prevent unused variable error - change n's type to size_t from int to prevent unsigned signed comparison --- src/sdl/i_main.c | 1 + src/sdl/i_system.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sdl/i_main.c b/src/sdl/i_main.c index 816142d72..841997165 100644 --- a/src/sdl/i_main.c +++ b/src/sdl/i_main.c @@ -213,6 +213,7 @@ int main(int argc, char **argv) I_OutputMsg("Error symlinking latest-log.txt: %s\n", strerror(errno)); } #else/*__unix__*/ + (void)link; logstream = fopen("latest-log.txt", "wt+"); #endif/*__unix__*/ } diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 2ccdec5c4..73292d8e1 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -3282,7 +3282,7 @@ static void Shittylogcopy(void) { char buf[8192]; FILE *fp; - int n; + size_t n; if (fseek(logstream, 0, SEEK_SET) == -1) { Shittycopyerror("fseek"); From 266ad99374570a96c8346626fa7e00219e29b4cc Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Mon, 30 Mar 2020 06:57:42 -0400 Subject: [PATCH 32/64] Add new item sprites --- src/dehacked.c | 52 +++++++++++------------ src/info.c | 111 ++++++++++++++++++++++++------------------------- src/info.h | 52 +++++++++++------------ src/k_kart.c | 40 ++++++++++++++++++ src/k_kart.h | 1 + src/p_mobj.c | 23 +++++++++- 6 files changed, 169 insertions(+), 110 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 34092a5ec..60d61903a 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6305,18 +6305,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_RANDOMITEM10", "S_RANDOMITEM11", "S_RANDOMITEM12", - "S_RANDOMITEM13", - "S_RANDOMITEM14", - "S_RANDOMITEM15", - "S_RANDOMITEM16", - "S_RANDOMITEM17", - "S_RANDOMITEM18", - "S_RANDOMITEM19", - "S_RANDOMITEM20", - "S_RANDOMITEM21", - "S_RANDOMITEM22", - "S_RANDOMITEM23", - "S_RANDOMITEM24", "S_DEADRANDOMITEM", // Random Item Pop @@ -6456,18 +6444,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_EGGMANITEM10", "S_EGGMANITEM11", "S_EGGMANITEM12", - "S_EGGMANITEM13", - "S_EGGMANITEM14", - "S_EGGMANITEM15", - "S_EGGMANITEM16", - "S_EGGMANITEM17", - "S_EGGMANITEM18", - "S_EGGMANITEM19", - "S_EGGMANITEM20", - "S_EGGMANITEM21", - "S_EGGMANITEM22", - "S_EGGMANITEM23", - "S_EGGMANITEM24", "S_EGGMANITEM_DEAD", //} @@ -6931,8 +6907,32 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_PLAYERBOMB18", "S_PLAYERBOMB19", "S_PLAYERBOMB20", - "S_PLAYERITEM", // Player item overlay - "S_PLAYERFAKE", // Player fake overlay + + "S_PLAYERITEM1", // Player item overlay + "S_PLAYERITEM2", + "S_PLAYERITEM3", + "S_PLAYERITEM4", + "S_PLAYERITEM5", + "S_PLAYERITEM6", + "S_PLAYERITEM7", + "S_PLAYERITEM8", + "S_PLAYERITEM9", + "S_PLAYERITEM10", + "S_PLAYERITEM11", + "S_PLAYERITEM12", + + "S_PLAYERFAKE1", // Player fake overlay + "S_PLAYERFAKE2", + "S_PLAYERFAKE3", + "S_PLAYERFAKE4", + "S_PLAYERFAKE5", + "S_PLAYERFAKE6", + "S_PLAYERFAKE7", + "S_PLAYERFAKE8", + "S_PLAYERFAKE9", + "S_PLAYERFAKE10", + "S_PLAYERFAKE11", + "S_PLAYERFAKE12", "S_KARMAWHEEL", // Karma player wheels diff --git a/src/info.c b/src/info.c index 26c7f973d..9c9759f31 100644 --- a/src/info.c +++ b/src/info.c @@ -2534,38 +2534,25 @@ state_t states[NUMSTATES] = {SPR_SRBO, 0, 2, {A_BuzzFly}, 0, 0, S_SRB1_GENREX2}, // S_SRB1_GENREX2 // SRB2kart - {SPR_RNDM, 0|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM2}, // S_RANDOMITEM1 - {SPR_RNDM, 1|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM3}, // S_RANDOMITEM2 - {SPR_RNDM, 2|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM4}, // S_RANDOMITEM3 - {SPR_RNDM, 3|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM5}, // S_RANDOMITEM4 - {SPR_RNDM, 4|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM6}, // S_RANDOMITEM5 - {SPR_RNDM, 5|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM7}, // S_RANDOMITEM6 - {SPR_RNDM, 6|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM8}, // S_RANDOMITEM7 - {SPR_RNDM, 7|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM9}, // S_RANDOMITEM8 - {SPR_RNDM, 8|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM10}, // S_RANDOMITEM9 - {SPR_RNDM, 9|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM11}, // S_RANDOMITEM10 - {SPR_RNDM, 10|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM12}, // S_RANDOMITEM11 - {SPR_RNDM, 11|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM13}, // S_RANDOMITEM12 - {SPR_RNDM, 12|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM14}, // S_RANDOMITEM13 - {SPR_RNDM, 13|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM15}, // S_RANDOMITEM14 - {SPR_RNDM, 14|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM16}, // S_RANDOMITEM15 - {SPR_RNDM, 15|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM17}, // S_RANDOMITEM16 - {SPR_RNDM, 16|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM18}, // S_RANDOMITEM17 - {SPR_RNDM, 17|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM19}, // S_RANDOMITEM18 - {SPR_RNDM, 18|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM20}, // S_RANDOMITEM19 - {SPR_RNDM, 19|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM21}, // S_RANDOMITEM20 - {SPR_RNDM, 20|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM22}, // S_RANDOMITEM21 - {SPR_RNDM, 21|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM23}, // S_RANDOMITEM22 - {SPR_RNDM, 22|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM24}, // S_RANDOMITEM23 - {SPR_RNDM, 23|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM1}, // S_RANDOMITEM24 - {SPR_RNDM, 0|FF_FULLBRIGHT, 1, {A_ItemPop}, 0, 0, S_NULL}, // S_DEADRANDOMITEM + {SPR_RNDM, FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_RANDOMITEM2}, // S_RANDOMITEM1 + {SPR_RNDM, 2|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_RANDOMITEM3}, // S_RANDOMITEM2 + {SPR_RNDM, 4|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_RANDOMITEM4}, // S_RANDOMITEM3 + {SPR_RNDM, 6|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_RANDOMITEM5}, // S_RANDOMITEM4 + {SPR_RNDM, 8|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_RANDOMITEM6}, // S_RANDOMITEM5 + {SPR_RNDM, 10|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_RANDOMITEM7}, // S_RANDOMITEM6 + {SPR_RNDM, 12|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_RANDOMITEM8}, // S_RANDOMITEM7 + {SPR_RNDM, 14|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_RANDOMITEM9}, // S_RANDOMITEM8 + {SPR_RNDM, 16|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_RANDOMITEM10}, // S_RANDOMITEM9 + {SPR_RNDM, 18|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_RANDOMITEM11}, // S_RANDOMITEM10 + {SPR_RNDM, 20|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_RANDOMITEM12}, // S_RANDOMITEM11 + {SPR_RNDM, 22|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_RANDOMITEM1}, // S_RANDOMITEM12 + {SPR_NULL, 0, 0, {A_ItemPop}, 0, 0, S_NULL}, // S_DEADRANDOMITEM {SPR_RPOP, FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_RANDOMITEMPOP2}, // S_RANDOMITEMPOP1 {SPR_RPOP, FF_FULLBRIGHT|1, 5, {NULL}, 0, 0, S_RANDOMITEMPOP3}, // S_RANDOMITEMPOP2 {SPR_RPOP, FF_FULLBRIGHT|2, 5, {NULL}, 0, 0, S_RANDOMITEMPOP4}, // S_RANDOMITEMPOP3 {SPR_RPOP, FF_FULLBRIGHT|3, 5, {NULL}, 0, 0, S_NULL}, // S_RANDOMITEMPOP4 - {SPR_NULL, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMICON {SPR_SGNS, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_SIGNSPARK2}, // S_SIGNSPARK1 @@ -2672,31 +2659,19 @@ state_t states[NUMSTATES] = {SPR_RSHE, 2, -1, {NULL}, 0, 0, S_NULL}, // S_ROCKETSNEAKER_LVIBRATE {SPR_RSHE, 3, -1, {NULL}, 0, 0, S_NULL}, // S_ROCKETSNEAKER_RVIBRATE - {SPR_FITM, FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM2}, // S_EGGMANITEM1 - {SPR_FITM, 1|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM3}, // S_EGGMANITEM2 - {SPR_FITM, 2|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM4}, // S_EGGMANITEM3 - {SPR_FITM, 3|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM5}, // S_EGGMANITEM4 - {SPR_FITM, 4|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM6}, // S_EGGMANITEM5 - {SPR_FITM, 5|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM7}, // S_EGGMANITEM6 - {SPR_FITM, 6|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM8}, // S_EGGMANITEM7 - {SPR_FITM, 7|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM9}, // S_EGGMANITEM8 - {SPR_FITM, 8|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM10}, // S_EGGMANITEM9 - {SPR_FITM, 9|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM11}, // S_EGGMANITEM10 - {SPR_FITM, 10|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM12}, // S_EGGMANITEM11 - {SPR_FITM, 11|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM13}, // S_EGGMANITEM12 - {SPR_FITM, 12|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM14}, // S_EGGMANITEM13 - {SPR_FITM, 13|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM15}, // S_EGGMANITEM14 - {SPR_FITM, 14|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM16}, // S_EGGMANITEM15 - {SPR_FITM, 15|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM17}, // S_EGGMANITEM16 - {SPR_FITM, 16|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM18}, // S_EGGMANITEM17 - {SPR_FITM, 17|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM19}, // S_EGGMANITEM18 - {SPR_FITM, 18|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM20}, // S_EGGMANITEM19 - {SPR_FITM, 19|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM21}, // S_EGGMANITEM20 - {SPR_FITM, 20|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM22}, // S_EGGMANITEM21 - {SPR_FITM, 21|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM23}, // S_EGGMANITEM22 // ***** - {SPR_FITM, 22|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM24}, // S_EGGMANITEM23 // ***** - {SPR_FITM, 23|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_EGGMANITEM1}, // S_EGGMANITEM24 // ***** - {SPR_FITM, FF_FULLBRIGHT, 175, {NULL}, 0, 0, S_EGGMANITEM1}, // S_EGGMANITEM_DEAD + {SPR_FITM, FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_EGGMANITEM2}, // S_EGGMANITEM1 + {SPR_FITM, 2|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_EGGMANITEM3}, // S_EGGMANITEM2 + {SPR_FITM, 4|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_EGGMANITEM4}, // S_EGGMANITEM3 + {SPR_FITM, 6|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_EGGMANITEM5}, // S_EGGMANITEM4 + {SPR_FITM, 8|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_EGGMANITEM6}, // S_EGGMANITEM5 + {SPR_FITM, 10|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_EGGMANITEM7}, // S_EGGMANITEM6 + {SPR_FITM, 12|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_EGGMANITEM8}, // S_EGGMANITEM7 + {SPR_FITM, 14|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_EGGMANITEM9}, // S_EGGMANITEM8 + {SPR_FITM, 16|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_EGGMANITEM10}, // S_EGGMANITEM9 + {SPR_FITM, 18|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_EGGMANITEM11}, // S_EGGMANITEM10 + {SPR_FITM, 20|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_EGGMANITEM12}, // S_EGGMANITEM11 + {SPR_FITM, 22|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_EGGMANITEM1}, // S_EGGMANITEM12 + {SPR_FITM, 24|FF_FULLBRIGHT, 175, {NULL}, 0, 0, S_NULL}, // S_EGGMANITEM_DEAD {SPR_BANA, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BANANA {SPR_BANA, 0, 175, {NULL}, 0, 0, S_NULL}, // S_BANANA_DEAD @@ -3143,8 +3118,32 @@ state_t states[NUMSTATES] = {SPR_SPBM, 8, 1, {NULL}, 0, 0, S_PLAYERBOMB19}, // S_PLAYERBOMB18 {SPR_SPBM, 0, 1, {NULL}, 0, 0, S_PLAYERBOMB20}, // S_PLAYERBOMB19 {SPR_SPBM, 8, 1, {NULL}, 0, 0, S_PLAYERBOMB1}, // S_PLAYERBOMB20 - {SPR_RNDM, FF_ANIMATE, -1, {NULL}, 23, 3, S_NULL}, // S_PLAYERITEM - {SPR_FITM, FF_ANIMATE, -1, {NULL}, 23, 3, S_NULL}, // S_PLAYERFAKE + + {SPR_RNDM, FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_PLAYERITEM2}, // S_PLAYERITEM1 + {SPR_RNDM, 2|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_PLAYERITEM3}, // S_PLAYERITEM2 + {SPR_RNDM, 4|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_PLAYERITEM4}, // S_PLAYERITEM3 + {SPR_RNDM, 6|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_PLAYERITEM5}, // S_PLAYERITEM4 + {SPR_RNDM, 8|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_PLAYERITEM6}, // S_PLAYERITEM5 + {SPR_RNDM, 10|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_PLAYERITEM7}, // S_PLAYERITEM6 + {SPR_RNDM, 12|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_PLAYERITEM8}, // S_PLAYERITEM7 + {SPR_RNDM, 14|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_PLAYERITEM9}, // S_PLAYERITEM8 + {SPR_RNDM, 16|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_PLAYERITEM10}, // S_PLAYERITEM9 + {SPR_RNDM, 18|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_PLAYERITEM11}, // S_PLAYERITEM10 + {SPR_RNDM, 20|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_PLAYERITEM12}, // S_PLAYERITEM11 + {SPR_RNDM, 22|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_PLAYERITEM1}, // S_PLAYERITEM12 + + {SPR_FITM, FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_PLAYERFAKE2}, // S_PLAYERFAKE1 + {SPR_FITM, 2|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_PLAYERFAKE3}, // S_PLAYERFAKE2 + {SPR_FITM, 4|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_PLAYERFAKE4}, // S_PLAYERFAKE3 + {SPR_FITM, 6|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_PLAYERFAKE5}, // S_PLAYERFAKE4 + {SPR_FITM, 8|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_PLAYERFAKE6}, // S_PLAYERFAKE5 + {SPR_FITM, 10|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_PLAYERFAKE7}, // S_PLAYERFAKE6 + {SPR_FITM, 12|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_PLAYERFAKE8}, // S_PLAYERFAKE7 + {SPR_FITM, 14|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_PLAYERFAKE9}, // S_PLAYERFAKE8 + {SPR_FITM, 16|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_PLAYERFAKE10}, // S_PLAYERFAKE9 + {SPR_FITM, 18|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_PLAYERFAKE11}, // S_PLAYERFAKE10 + {SPR_FITM, 20|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_PLAYERFAKE12}, // S_PLAYERFAKE11 + {SPR_FITM, 22|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_PLAYERFAKE1}, // S_PLAYERFAKE12 {SPR_PBOM, 0, -1, {NULL}, 0, 0, S_NULL}, // S_KARMAWHEEL @@ -15640,7 +15639,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_EGGMANITEM -1, // doomednum - S_EGGMANITEM1, // spawnstate + S_EGGMANITEM1, // spawnstate 2, // spawnhealth S_NULL, // seestate sfx_tossed, // seesound @@ -17775,11 +17774,11 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = -1, // doomednum S_PLAYERBOMB1, // spawnstate 1000, // spawnhealth - S_PLAYERITEM, // seestate + S_PLAYERITEM1, // seestate sfx_kc2e, // seesound 8, // reactiontime sfx_s3k4e, // attacksound - S_PLAYERFAKE, // painstate + S_PLAYERFAKE1, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate diff --git a/src/info.h b/src/info.h index 1468f51dd..ca2f71def 100644 --- a/src/info.h +++ b/src/info.h @@ -3204,18 +3204,6 @@ typedef enum state S_RANDOMITEM10, S_RANDOMITEM11, S_RANDOMITEM12, - S_RANDOMITEM13, - S_RANDOMITEM14, - S_RANDOMITEM15, - S_RANDOMITEM16, - S_RANDOMITEM17, - S_RANDOMITEM18, - S_RANDOMITEM19, - S_RANDOMITEM20, - S_RANDOMITEM21, - S_RANDOMITEM22, - S_RANDOMITEM23, - S_RANDOMITEM24, S_DEADRANDOMITEM, // Random Item Pop @@ -3355,18 +3343,6 @@ typedef enum state S_EGGMANITEM10, S_EGGMANITEM11, S_EGGMANITEM12, - S_EGGMANITEM13, - S_EGGMANITEM14, - S_EGGMANITEM15, - S_EGGMANITEM16, - S_EGGMANITEM17, - S_EGGMANITEM18, - S_EGGMANITEM19, - S_EGGMANITEM20, - S_EGGMANITEM21, - S_EGGMANITEM22, - S_EGGMANITEM23, - S_EGGMANITEM24, S_EGGMANITEM_DEAD, //} @@ -3830,8 +3806,32 @@ typedef enum state S_PLAYERBOMB18, S_PLAYERBOMB19, S_PLAYERBOMB20, - S_PLAYERITEM, - S_PLAYERFAKE, + + S_PLAYERITEM1, + S_PLAYERITEM2, + S_PLAYERITEM3, + S_PLAYERITEM4, + S_PLAYERITEM5, + S_PLAYERITEM6, + S_PLAYERITEM7, + S_PLAYERITEM8, + S_PLAYERITEM9, + S_PLAYERITEM10, + S_PLAYERITEM11, + S_PLAYERITEM12, + + S_PLAYERFAKE1, + S_PLAYERFAKE2, + S_PLAYERFAKE3, + S_PLAYERFAKE4, + S_PLAYERFAKE5, + S_PLAYERFAKE6, + S_PLAYERFAKE7, + S_PLAYERFAKE8, + S_PLAYERFAKE9, + S_PLAYERFAKE10, + S_PLAYERFAKE11, + S_PLAYERFAKE12, S_KARMAWHEEL, diff --git a/src/k_kart.c b/src/k_kart.c index 4065cb0c2..e5eb6346d 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -542,6 +542,39 @@ UINT8 K_GetKartColorByName(const char *name) //} +UINT8 K_GetClosestPlayersColor(mobj_t *mobj) +{ + fixed_t closest = INT32_MAX; + UINT8 color = SKINCOLOR_NONE; + UINT8 i; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo) + && !players[i].spectator && !players[i].exiting) + { + fixed_t dist = P_AproxDistance(P_AproxDistance( + players[i].mo->x - mobj->x, + players[i].mo->y - mobj->y), + players[i].mo->z - mobj->z + ); + + if (dist > 8192*mobj->scale) + { + continue; + } + + if (dist < closest) + { + color = players[i].skincolor; + closest = dist; + } + } + } + + return color; +} + //{ SRB2kart Net Variables void K_RegisterKartStuff(void) @@ -5185,6 +5218,13 @@ static void K_MoveHeldObjects(player_t *player) fixed_t targx, targy, targz; fixed_t speed, dist; + if (cur->type == MT_EGGMANITEM_SHIELD) + { + // K_GetClosestPlayersColor will practically always get our player anyway + // so we might as well save the effort + cur->color = player->skincolor; + } + cur->flags &= ~MF_NOCLIPTHING; if (!cur->health) diff --git a/src/k_kart.h b/src/k_kart.h index edec02685..14cb242bf 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -18,6 +18,7 @@ extern const UINT8 KartColor_Opposite[MAXSKINCOLORS*2]; void K_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor); void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color); UINT8 K_GetKartColorByName(const char *name); +UINT8 K_GetClosestPlayersColor(mobj_t *mobj); void K_RegisterKartStuff(void); diff --git a/src/p_mobj.c b/src/p_mobj.c index c27f8e118..4f5b0b1aa 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8107,8 +8107,20 @@ void P_MobjThinker(mobj_t *mobj) break; } - case MT_BANANA: case MT_EGGMANITEM: + { + UINT8 color = K_GetClosestPlayersColor(mobj); + + if (color == SKINCOLOR_NONE) + { + color = SKINCOLOR_BLACK; + } + + mobj->color = color; + mobj->colorized = false; + } + /* FALLTHRU */ + case MT_BANANA: mobj->friction = ORIG_FRICTION/4; if (P_MobjTouchingSectorSpecial(mobj, 4, 7, true)) @@ -9957,7 +9969,14 @@ void P_MobjThinker(mobj_t *mobj) } else { - mobj->color = SKINCOLOR_NONE; + UINT8 color = K_GetClosestPlayersColor(mobj); + + if (color == SKINCOLOR_NONE) + { + color = SKINCOLOR_BLACK; + } + + mobj->color = color; mobj->colorized = false; } break; From 69a67376b385cf20b7d80cd6a71760fe9b73d894 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Mon, 30 Mar 2020 07:43:22 -0400 Subject: [PATCH 33/64] Oni's suggestions - Only look for players who can pick up the item. Serves as a subtle tell for other players holding onto items, and lets you see the canon color more often - Held eggman item uses black instead of player color - Fix karma items not animating --- src/k_kart.c | 22 +++++++++++++--------- src/k_kart.h | 2 +- src/p_mobj.c | 30 ++++++++++++++++-------------- 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index e5eb6346d..3342b809b 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -542,16 +542,21 @@ UINT8 K_GetKartColorByName(const char *name) //} -UINT8 K_GetClosestPlayersColor(mobj_t *mobj) +player_t *K_GetItemBoxPlayer(mobj_t *mobj) { fixed_t closest = INT32_MAX; - UINT8 color = SKINCOLOR_NONE; + player_t *player = NULL; UINT8 i; for (i = 0; i < MAXPLAYERS; i++) { - if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo) - && !players[i].spectator && !players[i].exiting) + if (!(playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo) && !players[i].spectator)) + { + continue; + } + + // Always use normal item box rules -- could pass in "2" for fakes but they blend in better like this + if (P_CanPickupItem(&players[i], 1)) { fixed_t dist = P_AproxDistance(P_AproxDistance( players[i].mo->x - mobj->x, @@ -566,13 +571,13 @@ UINT8 K_GetClosestPlayersColor(mobj_t *mobj) if (dist < closest) { - color = players[i].skincolor; + player = &players[i]; closest = dist; } } } - return color; + return player; } //{ SRB2kart Net Variables @@ -5220,9 +5225,8 @@ static void K_MoveHeldObjects(player_t *player) if (cur->type == MT_EGGMANITEM_SHIELD) { - // K_GetClosestPlayersColor will practically always get our player anyway - // so we might as well save the effort - cur->color = player->skincolor; + // Decided that this should use their "canon" color. + cur->color = SKINCOLOR_BLACK; } cur->flags &= ~MF_NOCLIPTHING; diff --git a/src/k_kart.h b/src/k_kart.h index 14cb242bf..8dc5604b8 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -18,7 +18,7 @@ extern const UINT8 KartColor_Opposite[MAXSKINCOLORS*2]; void K_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor); void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color); UINT8 K_GetKartColorByName(const char *name); -UINT8 K_GetClosestPlayersColor(mobj_t *mobj); +player_t *K_GetItemBoxPlayer(mobj_t *mobj); void K_RegisterKartStuff(void); diff --git a/src/p_mobj.c b/src/p_mobj.c index 4f5b0b1aa..2a12dcc7a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8109,11 +8109,12 @@ void P_MobjThinker(mobj_t *mobj) } case MT_EGGMANITEM: { - UINT8 color = K_GetClosestPlayersColor(mobj); + player_t *player = K_GetItemBoxPlayer(mobj); + UINT8 color = SKINCOLOR_BLACK; - if (color == SKINCOLOR_NONE) + if (player != NULL) { - color = SKINCOLOR_BLACK; + color = player->skincolor; } mobj->color = color; @@ -8872,8 +8873,8 @@ void P_MobjThinker(mobj_t *mobj) if (mobj->target->player->kartstuff[k_comebacktimer] > 0) { - if (state < mobj->info->spawnstate || state > mobj->info->spawnstate+19) - P_SetMobjState(mobj, mobj->info->spawnstate); + if (state < S_PLAYERBOMB1 || state > S_PLAYERBOMB20) + P_SetMobjState(mobj, S_PLAYERBOMB1); if (mobj->target->player->kartstuff[k_comebacktimer] < TICRATE && (leveltime & 1)) mobj->flags2 &= ~MF2_DONTDRAW; else @@ -8882,14 +8883,14 @@ void P_MobjThinker(mobj_t *mobj) else { if (!mobj->target->player->kartstuff[k_comebackmode] - && (state < mobj->info->spawnstate || state > mobj->info->spawnstate+19)) - P_SetMobjState(mobj, mobj->info->spawnstate); + && (state < S_PLAYERBOMB1 || state > S_PLAYERBOMB20)) + P_SetMobjState(mobj, S_PLAYERBOMB1); else if (mobj->target->player->kartstuff[k_comebackmode] == 1 - && state != mobj->info->seestate) - P_SetMobjState(mobj, mobj->info->seestate); + && (state < S_PLAYERITEM1 || state > S_PLAYERITEM12)) + P_SetMobjState(mobj, S_PLAYERITEM1); else if (mobj->target->player->kartstuff[k_comebackmode] == 2 - && state != mobj->info->painstate) - P_SetMobjState(mobj, mobj->info->painstate); + && (state < S_PLAYERFAKE1 || state > S_PLAYERFAKE12)) + P_SetMobjState(mobj, S_PLAYERFAKE1); if (mobj->target->player->powers[pw_flashing] && (leveltime & 1)) mobj->flags2 |= MF2_DONTDRAW; @@ -9969,11 +9970,12 @@ void P_MobjThinker(mobj_t *mobj) } else { - UINT8 color = K_GetClosestPlayersColor(mobj); + player_t *player = K_GetItemBoxPlayer(mobj); + UINT8 color = SKINCOLOR_BLACK; - if (color == SKINCOLOR_NONE) + if (player != NULL) { - color = SKINCOLOR_BLACK; + color = player->skincolor; } mobj->color = color; From 956222ad86718cd425ab313997d269e3f15e56e4 Mon Sep 17 00:00:00 2001 From: Sryder Date: Mon, 30 Mar 2020 20:43:01 +0100 Subject: [PATCH 34/64] Fix joining netgames not loading up waypoints correctly. Mobjs get deleted and loaded from net save. The mobjs in the waypoints need to load into the correct waypoints again. This doesn't save/load the entire waypoints, so they still cannot be edited/added/removed mid-game. --- src/k_waypoint.c | 6 +++++- src/k_waypoint.h | 10 ++++++++++ src/p_saveg.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/src/k_waypoint.c b/src/k_waypoint.c index f77e6d62f..807dfe6a5 100644 --- a/src/k_waypoint.c +++ b/src/k_waypoint.c @@ -318,6 +318,11 @@ size_t K_GetWaypointHeapIndex(waypoint_t *waypoint) return waypointindex; } +size_t K_GetNumWaypoints(void) +{ + return numwaypoints; +} + /*-------------------------------------------------- waypoint_t *K_GetWaypointFromIndex(size_t waypointindex) @@ -1478,7 +1483,6 @@ static waypoint_t *K_MakeWaypoint(mobj_t *const mobj) I_Assert(waypointcap != NULL); // No waypoint mobjs in map load I_Assert(numwaypoints < numwaypointmobjs); // waypoint array reached max capacity - // numwaypoints is incremented later in K_SetupWaypoint madewaypoint = &waypointheap[numwaypoints]; numwaypoints++; diff --git a/src/k_waypoint.h b/src/k_waypoint.h index fb8d37f20..f1a678603 100644 --- a/src/k_waypoint.h +++ b/src/k_waypoint.h @@ -287,6 +287,16 @@ waypoint_t *K_SearchWaypointHeapForMobj(mobj_t * const mobj); --------------------------------------------------*/ size_t K_GetWaypointHeapIndex(waypoint_t *waypoint); +/*-------------------------------------------------- + size_t K_GetNumWaypoints(void) + + Returns the number of waypoints that are in the heap. + Intended for Net Archiving/Unarchiving + + Return:- + The number of waypoints in the heap +--------------------------------------------------*/ +size_t K_GetNumWaypoints(void); /*-------------------------------------------------- waypoint_t *K_GetWaypointFromIndex(size_t waypointindex) diff --git a/src/p_saveg.c b/src/p_saveg.c index ccae035ee..b65c0f17a 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -49,6 +49,7 @@ UINT8 *save_p; #define ARCHIVEBLOCK_POBJS 0x7F928546 #define ARCHIVEBLOCK_THINKERS 0x7F37037C #define ARCHIVEBLOCK_SPECIALS 0x7F228378 +#define ARCHIVEBLOCK_WAYPOINTS 0x7F46498F // Note: This cannot be bigger // than an UINT16 @@ -1908,6 +1909,49 @@ static void P_NetArchiveThinkers(void) WRITEUINT8(save_p, tc_end); } +static void P_NetArchiveWaypoints(void) +{ + waypoint_t *waypoint; + size_t i; + size_t numWaypoints = K_GetNumWaypoints(); + + WRITEUINT32(save_p, ARCHIVEBLOCK_WAYPOINTS); + WRITEUINT32(save_p, numWaypoints); + + for (i = 0U; i < numWaypoints; i++) { + waypoint = K_GetWaypointFromIndex(i); + + // The only thing we save for each waypoint is the mobj. + // Waypoints should NEVER be completely created or destroyed mid-race as a result of this + WRITEUINT32(save_p, waypoint->mobj->mobjnum); + } +} + +static void P_NetUnArchiveWaypoints(void) +{ + if (READUINT32(save_p) != ARCHIVEBLOCK_WAYPOINTS) + I_Error("Bad $$$.sav at archive block Waypoints!"); + else { + UINT32 numArchiveWaypoints = READUINT32(save_p); + size_t numSpawnedWaypoints = K_GetNumWaypoints(); + + if (numArchiveWaypoints != numSpawnedWaypoints) { + I_Error("Bad $$$.sav: More saved waypoints than created!"); + } else { + waypoint_t *waypoint; + UINT32 i; + UINT32 temp; + for (i = 0U; i < numArchiveWaypoints; i++) { + waypoint = K_GetWaypointFromIndex(i); + temp = READUINT32(save_p); + if (!P_SetTarget(&waypoint->mobj, P_FindNewPosition(temp))) { + CONS_Debug(DBG_GAMELOGIC, "waypoint mobj not found for %d\n", i); + } + } + } + } +} + // Now save the pointers, tracer and target, but at load time we must // relink to this; the savegame contains the old position in the pointer // field copyed in the info field temporarily, but finally we just search @@ -3526,6 +3570,7 @@ void P_SaveNetGame(void) #endif P_NetArchiveThinkers(); P_NetArchiveSpecials(); + P_NetArchiveWaypoints(); } #ifdef HAVE_BLUA LUA_Archive(); @@ -3570,6 +3615,7 @@ boolean P_LoadNetGame(void) #endif P_NetUnArchiveThinkers(); P_NetUnArchiveSpecials(); + P_NetUnArchiveWaypoints(); P_RelinkPointers(); P_FinishMobjs(); } From 3fa22c508b36e62b8c264dda3dde874e652c6254 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 30 Mar 2020 17:41:48 -0700 Subject: [PATCH 35/64] Put screenshots, movies and replays under a "media" directory --- src/m_menu.c | 15 ++++++++------- src/m_misc.c | 8 ++++---- src/p_setup.c | 12 +++++++----- src/y_inter.c | 9 +++++---- 4 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 267dbe07f..3abf64476 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2101,14 +2101,14 @@ static void Nextmap_OnChange(void) if (currentMenu == &SP_TimeAttackDef) { // see also p_setup.c's P_LoadRecordGhosts - const size_t glen = strlen(srb2home)+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1; + const size_t glen = strlen(srb2home)+1+strlen("media")+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1; char *gpath = malloc(glen); INT32 i; if (!gpath) return; - sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)); + sprintf(gpath,"%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)); CV_StealthSetValue(&cv_dummystaff, 0); @@ -5142,7 +5142,7 @@ void M_ReplayHut(INT32 choice) if (!demo.inreplayhut) { - snprintf(menupath, 1024, "%s"PATHSEP"replay"PATHSEP"online"PATHSEP, srb2home); + snprintf(menupath, 1024, "%s"PATHSEP"media"PATHSEP"replay"PATHSEP"online"PATHSEP, srb2home); menupathindex[(menudepthleft = menudepth-1)] = strlen(menupath); } if (!preparefilemenu(false, true)) @@ -7876,20 +7876,21 @@ static boolean M_QuitTimeAttackMenu(void) static void M_ChooseTimeAttack(INT32 choice) { char *gpath; - const size_t glen = strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1; + const size_t glen = strlen("media")+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1; char nameofdemo[256]; (void)choice; emeralds = 0; M_ClearMenus(true); modeattacking = (levellistmode == LLM_BREAKTHECAPSULES ? ATTACKING_CAPSULES : ATTACKING_RECORD); - I_mkdir(va("%s"PATHSEP"replay", srb2home), 0755); - I_mkdir(va("%s"PATHSEP"replay"PATHSEP"%s", srb2home, timeattackfolder), 0755); + gpath = va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s", + srb2home, timeattackfolder); + M_MkdirEach(gpath, M_PathParts(gpath) - 3, 0755); if ((gpath = malloc(glen)) == NULL) I_Error("Out of memory for replay filepath\n"); - sprintf(gpath,"replay"PATHSEP"%s"PATHSEP"%s", timeattackfolder, G_BuildMapName(cv_nextmap.value)); + sprintf(gpath,"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", timeattackfolder, G_BuildMapName(cv_nextmap.value)); snprintf(nameofdemo, sizeof nameofdemo, "%s-%s-last", gpath, cv_chooseskin.string); if (!cv_autorecord.value) diff --git a/src/m_misc.c b/src/m_misc.c index 2de64d589..34cfb200a 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -1121,8 +1121,8 @@ void M_StartMovie(void) if (cv_movie_option.value != 3) { - strcat(pathname, PATHSEP"movies"PATHSEP); - I_mkdir(pathname, 0755); + strcat(pathname, PATHSEP"media"PATHSEP"movies"PATHSEP); + M_MkdirEach(pathname, M_PathParts(pathname) - 2, 0755); } if (rendermode == render_none) @@ -1483,8 +1483,8 @@ void M_DoScreenShot(void) if (cv_screenshot_option.value != 3) { - strcat(pathname, PATHSEP"screenshots"PATHSEP); - I_mkdir(pathname, 0755); + strcat(pathname, PATHSEP"media"PATHSEP"screenshots"PATHSEP); + M_MkdirEach(pathname, M_PathParts(pathname) - 2, 0755); } #ifdef USE_PNG diff --git a/src/p_setup.c b/src/p_setup.c index 40ea643b7..d569c6452 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2621,14 +2621,14 @@ static void P_ForceCharacter(const char *forcecharskin) static void P_LoadRecordGhosts(void) { // see also m_menu.c's Nextmap_OnChange - const size_t glen = strlen(srb2home)+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1; + const size_t glen = strlen(srb2home)+1+strlen("media")+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1; char *gpath = malloc(glen); INT32 i; if (!gpath) return; - sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(gamemap)); + sprintf(gpath,"%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(gamemap)); // Best Time ghost if (cv_ghost_besttime.value) @@ -3203,10 +3203,12 @@ boolean P_SetupLevel(boolean skipprecip) //@TODO I'd like to fix dedis crashing when recording replays for the future too... if (!demo.playback && multiplayer && !dedicated) { static char buf[256]; - sprintf(buf, "replay"PATHSEP"online"PATHSEP"%d-%s", (int) (time(NULL)), G_BuildMapName(gamemap)); + char *path; + sprintf(buf, "media"PATHSEP"replay"PATHSEP"online"PATHSEP"%d-%s", (int) (time(NULL)), G_BuildMapName(gamemap)); + + path = va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"online", srb2home); + M_MkdirEach(path, M_PathParts(path) - 4, 0755); - I_mkdir(va("%s"PATHSEP"replay", srb2home), 0755); - I_mkdir(va("%s"PATHSEP"replay"PATHSEP"online", srb2home), 0755); G_RecordDemo(buf); } diff --git a/src/y_inter.c b/src/y_inter.c index e9e243b04..93771be5c 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -787,7 +787,7 @@ void Y_Ticker(void) // static void Y_UpdateRecordReplays(void) { - const size_t glen = strlen(srb2home)+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1; + const size_t glen = strlen(srb2home)+1+strlen("media")+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1; char *gpath; char lastdemo[256], bestdemo[256]; UINT8 earnedEmblems; @@ -823,13 +823,14 @@ static void Y_UpdateRecordReplays(void) G_SetDemoTime(players[consoleplayer].realtime, bestlap); G_CheckDemoStatus(); - I_mkdir(va("%s"PATHSEP"replay", srb2home), 0755); - I_mkdir(va("%s"PATHSEP"replay"PATHSEP"%s", srb2home, timeattackfolder), 0755); + gpath = va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s", + srb2home, timeattackfolder); + M_MkdirEach(gpath, M_PathParts(gpath) - 3, 0755); if ((gpath = malloc(glen)) == NULL) I_Error("Out of memory for replay filepath\n"); - sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(gamemap)); + sprintf(gpath,"%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(gamemap)); snprintf(lastdemo, 255, "%s-%s-last.lmp", gpath, cv_chooseskin.string); if (FIL_FileExists(lastdemo)) From 902bbb447f1ff28e39e3d1827e41bba45db1046e Mon Sep 17 00:00:00 2001 From: Sryder Date: Tue, 31 Mar 2020 16:31:01 +0100 Subject: [PATCH 36/64] Missed a function header comment in k_waypoint.c --- src/k_waypoint.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/k_waypoint.c b/src/k_waypoint.c index 807dfe6a5..a70e3a249 100644 --- a/src/k_waypoint.c +++ b/src/k_waypoint.c @@ -318,6 +318,11 @@ size_t K_GetWaypointHeapIndex(waypoint_t *waypoint) return waypointindex; } +/*-------------------------------------------------- + size_t K_GetNumWaypoints(void) + + See header file for description. +--------------------------------------------------*/ size_t K_GetNumWaypoints(void) { return numwaypoints; From 735dd26dc64ff0d0e1207fcec327486ea22793f0 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 31 Mar 2020 15:23:24 -0700 Subject: [PATCH 37/64] Put downloads in addons/downloads instead of DOWNLOAD --- src/d_main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index aed861e7d..8f42fc918 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1083,7 +1083,6 @@ void D_SRB2Main(void) // use user specific config file #ifdef DEFAULTDIR snprintf(srb2home, sizeof srb2home, "%s" PATHSEP DEFAULTDIR, userhome); - snprintf(downloaddir, sizeof downloaddir, "%s" PATHSEP "DOWNLOAD", srb2home); if (dedicated) snprintf(configfile, sizeof configfile, "%s" PATHSEP "d"CONFIGFILENAME, srb2home); else @@ -1094,7 +1093,6 @@ void D_SRB2Main(void) #else snprintf(srb2home, sizeof srb2home, "%s", userhome); - snprintf(downloaddir, sizeof downloaddir, "%s", userhome); if (dedicated) snprintf(configfile, sizeof configfile, "%s" PATHSEP "d"CONFIGFILENAME, userhome); else @@ -1116,6 +1114,10 @@ void D_SRB2Main(void) snprintf(addonsdir, sizeof addonsdir, "%s%s%s", srb2home, PATHSEP, "addons"); I_mkdir(addonsdir, 0755); + /* and downloads in a subdirectory */ + snprintf(downloaddir, sizeof downloaddir, "%.255s%.1s%.255s",/* fuck!! */ + addonsdir, PATHSEP, "downloads"); + // rand() needs seeded regardless of password srand((unsigned int)time(NULL)); From e4094bc2a92bdfd742c5de2af2fc9c2a88379682 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 31 Mar 2020 15:26:22 -0700 Subject: [PATCH 38/64] Remove some redundant code --- src/d_main.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 8f42fc918..1f2eafb3a 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1083,6 +1083,10 @@ void D_SRB2Main(void) // use user specific config file #ifdef DEFAULTDIR snprintf(srb2home, sizeof srb2home, "%s" PATHSEP DEFAULTDIR, userhome); +#else + snprintf(srb2home, sizeof srb2home, "%s", userhome); +#endif + if (dedicated) snprintf(configfile, sizeof configfile, "%s" PATHSEP "d"CONFIGFILENAME, srb2home); else @@ -1090,17 +1094,6 @@ void D_SRB2Main(void) // can't use sprintf since there is %u in savegamename strcatbf(savegamename, srb2home, PATHSEP); - -#else - snprintf(srb2home, sizeof srb2home, "%s", userhome); - if (dedicated) - snprintf(configfile, sizeof configfile, "%s" PATHSEP "d"CONFIGFILENAME, userhome); - else - snprintf(configfile, sizeof configfile, "%s" PATHSEP CONFIGFILENAME, userhome); - - // can't use sprintf since there is %u in savegamename - strcatbf(savegamename, userhome, PATHSEP); -#endif } configfile[sizeof configfile - 1] = '\0'; From 4a3a4c0801c258dbb7e68a8c5cbcdd3990ad3466 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 31 Mar 2020 15:50:39 -0700 Subject: [PATCH 39/64] This won't be needed --- src/d_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_main.c b/src/d_main.c index 1f2eafb3a..a67c8addd 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1108,7 +1108,7 @@ void D_SRB2Main(void) I_mkdir(addonsdir, 0755); /* and downloads in a subdirectory */ - snprintf(downloaddir, sizeof downloaddir, "%.255s%.1s%.255s",/* fuck!! */ + snprintf(downloaddir, sizeof downloaddir, "%s%s%s", addonsdir, PATHSEP, "downloads"); // rand() needs seeded regardless of password From 593003b0f7a1159f5ca5c82029275979b533927e Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 3 Apr 2020 20:53:00 -0700 Subject: [PATCH 40/64] Line special 80, raise tagged things by type to this FOF Thing type is the front texture x offset. Tag here refers to the thing's angle. For example, you have two sectors tagged to one FOF. Put a ring in each sector, give it angle 0. Then give a line in the FOF control sector special 80 front texture x offset 300. Those rings will spawn on the FOF instead of on the sector floor. Also works for object flip and slopes. --- src/p_spec.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/src/p_spec.c b/src/p_spec.c index 425d1c779..0e182fa18 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -5350,6 +5350,72 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f return ffloor; } +static fixed_t +Floor_height (sector_t *s, fixed_t x, fixed_t y) +{ +#ifdef ESLOPE + return s->f_slope ? P_GetZAt(s->f_slope, x, y) : s->floorheight; +#else + (void)x; + (void)y; + return s->floorheight; +#endif +} + +static fixed_t +Ceiling_height (sector_t *s, fixed_t x, fixed_t y) +{ +#ifdef ESLOPE + return s->c_slope ? P_GetZAt(s->c_slope, x, y) : s->ceilingheight; +#else + (void)x; + (void)y; + return s->ceilingheight; +#endif +} + +static void +P_RaiseTaggedThingsToFakeFloor ( + UINT16 type, + INT16 tag, + sector_t *control +){ + sector_t *target; + + mobj_t *mo; + mapthing_t *mthing; + + fixed_t offset; + + size_t i; + + for (i = 0; i < control->numattached; ++i) + { + target = §ors[control->attached[i]]; + + for (mo = target->thinglist; mo; mo = mo->snext) + { + mthing = mo->spawnpoint; + + if ( + mthing->type == type && + mthing->angle == tag + ){ + if (( mo->flags2 & MF2_OBJECTFLIP )) + { + offset = ( mo->ceilingz - mo->info->height ) - mo->z; + mo->z = ( Floor_height(control, mo->x, mo->y) - mo->info->height ) - offset; + } + else + { + offset = mo->z - mo->floorz; + mo->z = Ceiling_height(control, mo->x, mo->y) + offset; + } + } + } + } +} + // // SPECIAL SPAWNING // @@ -6813,6 +6879,22 @@ void P_SpawnSpecials(INT32 fromnetsave) } } + /* some things have to be done after FOF spawn */ + + for (i = 0; i < numlines; ++i) + { + switch (lines[i].special) + { + case 80: // Raise tagged things by type to this FOF + P_RaiseTaggedThingsToFakeFloor( + ( sides[lines[i].sidenum[0]].textureoffset >> FRACBITS ), + lines[i].tag, + lines[i].frontsector + ); + break; + } + } + // Allocate each list for (i = 0; i < numsectors; i++) if(secthinkers[i].thinkers) From 89a2f8ec8d4746c5f836228a6ca4ce29d0f9d26f Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 4 Apr 2020 01:20:38 -0700 Subject: [PATCH 41/64] Thing type 2002, MT_WAYPOINT_RISER - Raise tagged waypoints in sector to FOF sorted by height Thing height refers to the index of FOF. FOF are sorted by top height, lowest to highest. Set Object Flip to sort highest to lowest. If the waypoint thing set Object Flip, it will be placed on the bottom of the FOF. The sorting remains the same though. Set Ambush to raise the waypoint to the same z position. --- src/dehacked.c | 1 + src/info.c | 27 +++++++++++++++ src/info.h | 1 + src/k_waypoint.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++ src/k_waypoint.h | 12 ++++++- src/p_local.h | 6 ++++ src/p_map.c | 48 +++++++++++++++++++++++++++ src/p_mobj.c | 5 +++ src/p_setup.c | 6 ++++ src/p_slopes.c | 1 - src/p_spec.c | 37 +++++++++++++++++++++ src/r_defs.h | 8 +++++ 12 files changed, 236 insertions(+), 2 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 60d61903a..ab3340ed1 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7898,6 +7898,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_DEZLASER", "MT_WAYPOINT", + "MT_WAYPOINT_RISER", "MT_RANDOMAUDIENCE", diff --git a/src/info.c b/src/info.c index 9c9759f31..298ca2c8c 100644 --- a/src/info.c +++ b/src/info.c @@ -16528,6 +16528,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_WAYPOINT_RISER + 2002, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 100, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 1*FRACUNIT, // radius + 2*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags + S_NULL // raisestate + }, + { // MT_RANDOMAUDIENCE 1488, // doomednum S_RANDOMAUDIENCE, // spawnstate diff --git a/src/info.h b/src/info.h index ca2f71def..5cb0a8a45 100644 --- a/src/info.h +++ b/src/info.h @@ -4829,6 +4829,7 @@ typedef enum mobj_type MT_DEZLASER, MT_WAYPOINT, + MT_WAYPOINT_RISER, MT_RANDOMAUDIENCE, diff --git a/src/k_waypoint.c b/src/k_waypoint.c index a70e3a249..fc9a7ce1d 100644 --- a/src/k_waypoint.c +++ b/src/k_waypoint.c @@ -16,6 +16,7 @@ #include "d_netcmd.h" #include "p_local.h" #include "p_tick.h" +#include "r_state.h" #include "z_zone.h" #include "g_game.h" @@ -1770,3 +1771,88 @@ void K_ClearWaypoints(void) numwaypointmobjs = 0U; circuitlength = 0U; } + +/*-------------------------------------------------- + void K_AdjustWaypointsParameters(void) + + See header file for description. +--------------------------------------------------*/ + +void K_AdjustWaypointsParameters (void) +{ + mobj_t *waypointmobj; + mobj_t *riser; + + fixed_t x; + fixed_t y; + + sector_t *sector; + ffloor_t *rover; + + boolean descending; + + UINT16 fof_no; + + for ( + waypointmobj = waypointcap; + waypointmobj; + waypointmobj = waypointmobj->tracer + ){ + sector = waypointmobj->subsector->sector; + + for ( + riser = sector->thinglist; + riser; + riser = riser->snext + ){ + if ( + riser->type == MT_WAYPOINT_RISER && + riser->spawnpoint->angle == waypointmobj->spawnpoint->angle + ){ + if (( riser->spawnpoint->options & MTF_AMBUSH )) + { + waypointmobj->z = riser->z; + } + else + { + descending = ( riser->spawnpoint->options & MTF_OBJECTFLIP ); + + fof_no = ( riser->spawnpoint->options >> ZSHIFT ); + + if (descending) + rover = sector->highest_ffloor; + else + rover = sector->lowest_ffloor; + + while (rover) + { + if (fof_no > 0) + { + if (descending) + rover = rover->lower; + else + rover = rover->higher; + + fof_no--; + } + else + { + x = waypointmobj->x; + y = waypointmobj->y; + + if (( waypointmobj->flags2 & MF2_OBJECTFLIP )) + { + waypointmobj->z = P_GetFOFBottomZAt(rover, x, y) - + waypointmobj->info->height; + } + else + waypointmobj->z = P_GetFOFTopZAt(rover, x, y); + + break; + } + } + } + } + } + } +} diff --git a/src/k_waypoint.h b/src/k_waypoint.h index f1a678603..0017c443e 100644 --- a/src/k_waypoint.h +++ b/src/k_waypoint.h @@ -345,4 +345,14 @@ boolean K_SetupWaypointList(void); void K_ClearWaypoints(void); -#endif \ No newline at end of file +/*-------------------------------------------------- + void K_AdjustWaypointsParameters(void) + + Adjusts waypoint parameters after P_SpawnSpecials. This is for + raising waypoints to an FOF, which requires that the FOF is + already spawned. +--------------------------------------------------*/ + +void K_AdjustWaypointsParameters (void); + +#endif diff --git a/src/p_local.h b/src/p_local.h index 0d7d3ec3e..a45119a18 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -355,6 +355,12 @@ boolean PIT_PushableMoved(mobj_t *thing); boolean P_DoSpring(mobj_t *spring, mobj_t *object); +fixed_t P_GetFOFTopZAt (ffloor_t *rover, fixed_t x, fixed_t y); +fixed_t P_GetFOFBottomZAt (ffloor_t *rover, fixed_t x, fixed_t y); + +fixed_t P_VeryTopOfFOF (ffloor_t *rover); +fixed_t P_VeryBottomOfFOF (ffloor_t *rover); + // // P_SETUP // diff --git a/src/p_map.c b/src/p_map.c index 9a3864f2c..a6306bb19 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -4749,3 +4749,51 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height) return floorz; } + +fixed_t +P_GetFOFTopZAt (ffloor_t *rover, fixed_t x, fixed_t y) +{ + (void)x; + (void)y; +#ifdef ESLOPE + if (*rover->t_slope) + return P_GetZAt(*rover->t_slope, x, y); + else +#endif + return *rover->topheight; +} + +fixed_t +P_GetFOFBottomZAt (ffloor_t *rover, fixed_t x, fixed_t y) +{ + (void)x; + (void)y; +#ifdef ESLOPE + if (*rover->b_slope) + return P_GetZAt(*rover->b_slope, x, y); + else +#endif + return *rover->bottomheight; +} + +fixed_t +P_VeryTopOfFOF (ffloor_t *rover) +{ +#ifdef ESLOPE + if (*rover->t_slope) + return (*rover->t_slope)->highz; + else +#endif + return *rover->topheight; +} + +fixed_t +P_VeryBottomOfFOF (ffloor_t *rover) +{ +#ifdef ESLOPE + if (*rover->b_slope) + return (*rover->b_slope)->lowz; + else +#endif + return *rover->bottomheight; +} diff --git a/src/p_mobj.c b/src/p_mobj.c index 2a12dcc7a..a989b0019 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -12324,6 +12324,11 @@ void P_SpawnMapThing(mapthing_t *mthing) y = mthing->y << FRACBITS; ss = R_PointInSubsector(x, y); + if (i == MT_WAYPOINT_RISER) + { + ss->sector->ffloor_sorting = true; + } + if (i == MT_NIGHTSBUMPER) z = ( #ifdef ESLOPE diff --git a/src/p_setup.c b/src/p_setup.c index 40ea643b7..0eb4abc5c 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -741,6 +741,10 @@ static void P_LoadRawSectors(UINT8 *data, size_t i) ss->maxattached = 1; ss->moved = true; + ss->ffloor_sorting = false; + ss->lowest_ffloor = NULL; + ss->highest_ffloor = NULL; + ss->extra_colormap = NULL; ss->floor_xoffs = ss->ceiling_xoffs = ss->floor_yoffs = ss->ceiling_yoffs = 0; @@ -3126,6 +3130,8 @@ boolean P_SetupLevel(boolean skipprecip) // set up world state P_SpawnSpecials(fromnetsave); + K_AdjustWaypointsParameters(); + if (loadprecip) // ugly hack for P_NetUnArchiveMisc (and P_LoadNetGame) P_SpawnPrecipitation(); diff --git a/src/p_slopes.c b/src/p_slopes.c index e623b6f19..6c6842458 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -757,7 +757,6 @@ fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y) return slope->o.z + FixedMul(dist, slope->zdelta); } - // // P_QuantizeMomentumToSlope // diff --git a/src/p_spec.c b/src/p_spec.c index 0e182fa18..158f44dda 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -5150,14 +5150,51 @@ static inline void P_AddFFloorToList(sector_t *sec, ffloor_t *ffloor) { ffloor_t *rover; + fixed_t top; + if (!sec->ffloors) { sec->ffloors = ffloor; + if (sec->ffloor_sorting) + { + sec->lowest_ffloor = ffloor; + sec->highest_ffloor = ffloor; + } ffloor->next = 0; ffloor->prev = 0; return; } + if (sec->ffloor_sorting) + { + top = P_VeryTopOfFOF(ffloor); + + for (rover = sec->lowest_ffloor; rover; rover = rover->higher) + { + if (top < P_VeryTopOfFOF(rover)) + break; + } + + if (rover) + { + if (rover->lower) + rover->lower->higher = ffloor; + else + sec->lowest_ffloor = ffloor; + + ffloor->lower = rover->lower; + ffloor->higher = rover; + + rover->lower = ffloor; + } + else + { + sec->highest_ffloor->higher = ffloor; + ffloor->lower = sec->highest_ffloor; + sec->highest_ffloor = ffloor; + } + } + for (rover = sec->ffloors; rover->next; rover = rover->next); rover->next = ffloor; diff --git a/src/r_defs.h b/src/r_defs.h index c8a72044d..399dec087 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -170,6 +170,10 @@ typedef struct ffloor_s struct ffloor_s *next; struct ffloor_s *prev; + /* if sector->ffloor_sorting */ + struct ffloor_s *higher;/* by top height */ + struct ffloor_s *lower;/* by bottom height */ + INT32 lastlight; INT32 alpha; tic_t norender; // for culling @@ -347,6 +351,10 @@ typedef struct sector_s INT32 numlights; boolean moved; + boolean ffloor_sorting; + ffloor_t *lowest_ffloor; + ffloor_t *highest_ffloor; + // per-sector colormaps! extracolormap_t *extra_colormap; From 77e01f61e6a6fa79090773f635a69da1369c1a2c Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 4 Apr 2020 01:28:53 -0700 Subject: [PATCH 42/64] Waypoint Riser: Require Object Special for discrimination by tag So the default is to affect all waypoints in the sector. --- src/k_waypoint.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/k_waypoint.c b/src/k_waypoint.c index fc9a7ce1d..1bc48b2a5 100644 --- a/src/k_waypoint.c +++ b/src/k_waypoint.c @@ -1807,7 +1807,10 @@ void K_AdjustWaypointsParameters (void) ){ if ( riser->type == MT_WAYPOINT_RISER && - riser->spawnpoint->angle == waypointmobj->spawnpoint->angle + ( + !( riser->spawnpoint->options & MTF_OBJECTSPECIAL ) || + riser->spawnpoint->angle == waypointmobj->spawnpoint->angle + ) ){ if (( riser->spawnpoint->options & MTF_AMBUSH )) { From ccc746fbf40dd81d12a16a37410940311dd02d3e Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 9 Apr 2020 17:21:30 -0700 Subject: [PATCH 43/64] Change netvars in replays --- src/command.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/command.c b/src/command.c index 625065120..6f3ccd7f6 100644 --- a/src/command.c +++ b/src/command.c @@ -1543,7 +1543,7 @@ static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth) } // Only add to netcmd buffer if in a netgame, otherwise, just change it. - if (netgame || multiplayer) + if (netgame) { WRITEUINT16(p, var->netid); WRITESTRING(p, value); From 1618d61bfcc925bf5249fb2843556f051f4b6388 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Thu, 9 Apr 2020 20:56:15 -0400 Subject: [PATCH 44/64] Fix potential overflow --- src/k_kart.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 3342b809b..7ad459ad1 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -796,6 +796,7 @@ static void K_KartGetItemResult(player_t *player, SINT8 getitem) { if (getitem == KITEM_SPB || getitem == KITEM_SHRINK) // Indirect items indirectitemcooldown = 20*TICRATE; + if (getitem == KITEM_HYUDORO) // Hyudoro cooldown hyubgone = 5*TICRATE; @@ -1167,7 +1168,17 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) && players[i].kartstuff[k_position] == 1) { // This player is first! Yay! - pdis = player->distancetofinish - players[i].distancetofinish; + + if (player->distancetofinish <= players[i].distancetofinish) + { + // Guess you're in first / tied for first? + pdis = 0; + } + else + { + // Subtract 1st's distance from your distance, to get your distance from 1st! + pdis = player->distancetofinish - players[i].distancetofinish; + } break; } } @@ -1281,7 +1292,7 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) player->kartstuff[k_itemroulette] = 0; player->kartstuff[k_roulettetype] = 0; if (P_IsDisplayPlayer(player)) - S_StartSound(NULL, (mashed ? sfx_itrolm : sfx_itrolf)); + S_StartSound(NULL, sfx_itrolm); return; } } From 43732b386d65619d4a2b259093c35e2bc03abaf9 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Thu, 9 Apr 2020 20:57:21 -0400 Subject: [PATCH 45/64] Fix being able to hold items to get them as early as possible (Doesn't matter in v2 because it'd waste your rings to do it, but y'know how it is. Maybe port for v1.2 if it works?) --- src/k_kart.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 7ad459ad1..1f0eb3462 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1150,17 +1150,21 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) // If the roulette finishes or the player presses BT_ATTACK, stop the roulette and calculate the item. // I'm returning via the exact opposite, however, to forgo having another bracket embed. Same result either way, I think. // Finally, if you get past this check, now you can actually start calculating what item you get. - if ((cmd->buttons & BT_ATTACK) && (player->kartstuff[k_itemroulette] >= roulettestop) + if (((cmd->buttons & BT_ATTACK) && !(player->pflags & PF_ATTACKDOWN)) + && (player->kartstuff[k_itemroulette] >= roulettestop) && !(player->kartstuff[k_eggmanheld] || player->kartstuff[k_itemheld] || player->kartstuff[k_userings])) { // Mashing reduces your chances for the good items mashed = FixedDiv((player->kartstuff[k_itemroulette])*FRACUNIT, ((TICRATE*3)+roulettestop)*FRACUNIT) - FRACUNIT; } - else if (!(player->kartstuff[k_itemroulette] >= (TICRATE*3))) - return; + else + { + if (cmd->buttons & BT_ATTACK) + player->pflags |= PF_ATTACKDOWN; - if (cmd->buttons & BT_ATTACK) - player->pflags |= PF_ATTACKDOWN; + if (!(player->kartstuff[k_itemroulette] >= (TICRATE*3))) + return; + } for (i = 0; i < MAXPLAYERS; i++) { From c8da95cbda0cf59f7f99c2d8c2f5f42d2e999ed8 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Thu, 9 Apr 2020 21:05:46 -0400 Subject: [PATCH 46/64] Revert "Fix being able to hold items to get them as early as possible" This reverts commit 43732b386d65619d4a2b259093c35e2bc03abaf9. --- src/k_kart.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 1f0eb3462..7ad459ad1 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1150,21 +1150,17 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) // If the roulette finishes or the player presses BT_ATTACK, stop the roulette and calculate the item. // I'm returning via the exact opposite, however, to forgo having another bracket embed. Same result either way, I think. // Finally, if you get past this check, now you can actually start calculating what item you get. - if (((cmd->buttons & BT_ATTACK) && !(player->pflags & PF_ATTACKDOWN)) - && (player->kartstuff[k_itemroulette] >= roulettestop) + if ((cmd->buttons & BT_ATTACK) && (player->kartstuff[k_itemroulette] >= roulettestop) && !(player->kartstuff[k_eggmanheld] || player->kartstuff[k_itemheld] || player->kartstuff[k_userings])) { // Mashing reduces your chances for the good items mashed = FixedDiv((player->kartstuff[k_itemroulette])*FRACUNIT, ((TICRATE*3)+roulettestop)*FRACUNIT) - FRACUNIT; } - else - { - if (cmd->buttons & BT_ATTACK) - player->pflags |= PF_ATTACKDOWN; + else if (!(player->kartstuff[k_itemroulette] >= (TICRATE*3))) + return; - if (!(player->kartstuff[k_itemroulette] >= (TICRATE*3))) - return; - } + if (cmd->buttons & BT_ATTACK) + player->pflags |= PF_ATTACKDOWN; for (i = 0; i < MAXPLAYERS; i++) { From 9b4e10d5d77d4695513fa33a811eafe08d092762 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Thu, 9 Apr 2020 22:56:31 -0400 Subject: [PATCH 47/64] Item dropping code cleanup --- src/k_kart.c | 111 ++++++++++++++++++++++++-------------------------- src/k_kart.h | 2 +- src/p_inter.c | 2 +- 3 files changed, 55 insertions(+), 60 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 3342b809b..4cddcee1d 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1434,7 +1434,7 @@ static void K_DebtStingPlayer(player_t *player, INT32 length) if (player->mo->state != &states[S_KART_SPIN]) P_SetPlayerMobjState(player->mo, S_KART_SPIN); - K_DropHnextList(player); + K_DropHnextList(player, false); return; } @@ -2875,7 +2875,7 @@ void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, mobj_t *inflicto if (cv_kartdebughuddrop.value && !modeattacking) K_DropItems(player); else - K_DropHnextList(player); + K_DropHnextList(player, false); return; } @@ -3020,7 +3020,7 @@ void K_SquishPlayer(player_t *player, mobj_t *source, mobj_t *inflictor) if (cv_kartdebughuddrop.value && !modeattacking) K_DropItems(player); else - K_DropHnextList(player); + K_DropHnextList(player, false); return; } @@ -3226,7 +3226,7 @@ void K_StealBumper(player_t *player, player_t *victim, boolean force) if (cv_kartdebughuddrop.value && !modeattacking) K_DropItems(victim); else - K_DropHnextList(victim); + K_DropHnextList(victim, false); return; } @@ -4689,54 +4689,51 @@ void K_UpdateHnextList(player_t *player, boolean clean) nextwork = work->hnext; - while ((work = nextwork) && !P_MobjWasRemoved(work)) + while ((work = nextwork) && !(work == NULL || P_MobjWasRemoved(work))) { nextwork = work->hnext; if (!clean && (!work->movedir || work->movedir <= (UINT16)player->kartstuff[k_itemamount])) + { continue; + } P_RemoveMobj(work); } } // For getting hit! -void K_DropHnextList(player_t *player) +void K_DropHnextList(player_t *player, boolean keepshields) { mobj_t *work = player->mo, *nextwork, *dropwork; INT32 flip; mobjtype_t type; boolean orbit, ponground, dropall = true; + INT32 shield = K_GetShieldFromItem(player->kartstuff[k_itemtype]); - if (!work || P_MobjWasRemoved(work)) + if (work == NULL || P_MobjWasRemoved(work)) + { return; + } flip = P_MobjFlip(player->mo); ponground = P_IsObjectOnGround(player->mo); - if (player->kartstuff[k_itemtype] == KITEM_THUNDERSHIELD) + if (shield != KSHIELD_NONE && !keepshields) { - K_DoThunderShield(player); - player->kartstuff[k_itemtype] = KITEM_NONE; - player->kartstuff[k_itemamount] = 0; + if (shield == KSHIELD_THUNDER) + { + K_DoThunderShield(player); + } + player->kartstuff[k_curshield] = KSHIELD_NONE; - } - else if (player->kartstuff[k_itemtype] == KITEM_BUBBLESHIELD) - { player->kartstuff[k_itemtype] = KITEM_NONE; - player->kartstuff[k_itemamount] = 0; - player->kartstuff[k_curshield] = KSHIELD_NONE; - } - else if (player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD) - { - player->kartstuff[k_itemtype] = KITEM_NONE; - player->kartstuff[k_itemamount] = 0; - player->kartstuff[k_curshield] = KSHIELD_NONE; + player->kartstuff[k_itemamount] = player->kartstuff[k_itemheld] = 0; } nextwork = work->hnext; - while ((work = nextwork) && !P_MobjWasRemoved(work)) + while ((work = nextwork) && !(work == NULL || P_MobjWasRemoved(work))) { nextwork = work->hnext; @@ -4765,20 +4762,20 @@ void K_DropHnextList(player_t *player) orbit = false; type = MT_EGGMANITEM; break; - // intentionally do nothing - case MT_SINK_SHIELD: - case MT_ROCKETSNEAKER: - return; default: continue; } dropwork = P_SpawnMobj(work->x, work->y, work->z, type); + P_SetTarget(&dropwork->target, player->mo); - P_AddKartItem(dropwork); // needs to be called here so shrink can bust items off players in front of the user. + P_AddKartItem(dropwork); // needs to be called here so shrink can bust items off players in front of the user. + dropwork->angle = work->angle; - dropwork->flags2 = work->flags2; + dropwork->flags |= MF_NOCLIPTHING; + dropwork->flags2 = work->flags2; + dropwork->floorz = work->floorz; dropwork->ceilingz = work->ceilingz; @@ -4807,19 +4804,29 @@ void K_DropHnextList(player_t *player) if (orbit) // splay out { dropwork->flags2 |= MF2_AMBUSH; + dropwork->z += flip; + dropwork->momx = player->mo->momx>>1; dropwork->momy = player->mo->momy>>1; dropwork->momz = 3*flip*mapobjectscale; + if (dropwork->eflags & MFE_UNDERWATER) dropwork->momz = (117 * dropwork->momz) / 200; + P_Thrust(dropwork, work->angle - ANGLE_90, 6*mapobjectscale); + dropwork->movecount = 2; dropwork->movedir = work->angle - ANGLE_90; + P_SetMobjState(dropwork, dropwork->info->deathstate); + dropwork->tics = -1; + if (type == MT_JAWZ_DUD) + { dropwork->z += 20*flip*dropwork->scale; + } else { dropwork->color = work->color; @@ -4835,39 +4842,33 @@ void K_DropHnextList(player_t *player) P_RemoveMobj(work); } + // we need this here too because this is done in afterthink - pointers are cleaned up at the START of each tic... + P_SetTarget(&player->mo->hnext, NULL); + + player->kartstuff[k_bananadrag] = 0; + + if (player->kartstuff[k_eggmanheld]) { - // we need this here too because this is done in afterthink - pointers are cleaned up at the START of each tic... - P_SetTarget(&player->mo->hnext, NULL); - player->kartstuff[k_bananadrag] = 0; - if (player->kartstuff[k_eggmanheld]) - player->kartstuff[k_eggmanheld] = 0; - else if (player->kartstuff[k_itemheld] - && (dropall || (--player->kartstuff[k_itemamount] <= 0))) - { - player->kartstuff[k_itemamount] = player->kartstuff[k_itemheld] = 0; - player->kartstuff[k_itemtype] = KITEM_NONE; - } + player->kartstuff[k_eggmanheld] = 0; + } + else if (player->kartstuff[k_itemheld] + && (dropall || (--player->kartstuff[k_itemamount] <= 0))) + { + player->kartstuff[k_itemamount] = player->kartstuff[k_itemheld] = 0; + player->kartstuff[k_itemtype] = KITEM_NONE; } } // For getting EXTRA hit! void K_DropItems(player_t *player) { - INT32 shieldhack = 0; + K_DropHnextList(player, true); - if (player->kartstuff[k_curshield]) - shieldhack = K_GetShieldFromItem(player->kartstuff[k_itemtype]); - - if (shieldhack) - player->kartstuff[k_itemtype] = KITEM_NONE; - - K_DropHnextList(player); - - if (player->mo && !P_MobjWasRemoved(player->mo) && player->kartstuff[k_itemamount]) + if (player->mo && !P_MobjWasRemoved(player->mo) && player->kartstuff[k_itemamount] > 0) { mobj_t *drop = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + player->mo->height/2, MT_FLOATINGITEM); P_SetScale(drop, drop->scale>>4); - drop->destscale = (3*drop->destscale)/2;; + drop->destscale = (3*drop->destscale)/2; drop->angle = player->mo->angle + ANGLE_90; P_Thrust(drop, @@ -4877,13 +4878,7 @@ void K_DropItems(player_t *player) if (drop->eflags & MFE_UNDERWATER) drop->momz = (117 * drop->momz) / 200; - switch (shieldhack) - { - case KSHIELD_THUNDER: drop->threshold = KITEM_THUNDERSHIELD; break; - case KSHIELD_BUBBLE: drop->threshold = KITEM_BUBBLESHIELD; break; - case KSHIELD_FLAME: drop->threshold = KITEM_FLAMESHIELD; break; - default: drop->threshold = player->kartstuff[k_itemtype]; break; - } + drop->threshold = player->kartstuff[k_itemtype]; drop->movecount = player->kartstuff[k_itemamount]; drop->flags |= MF_NOCLIPTHING; diff --git a/src/k_kart.h b/src/k_kart.h index 8dc5604b8..4053e687c 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -56,7 +56,7 @@ void K_DoSneaker(player_t *player, INT32 type); void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound); void K_KillBananaChain(mobj_t *banana, mobj_t *inflictor, mobj_t *source); void K_UpdateHnextList(player_t *player, boolean clean); -void K_DropHnextList(player_t *player); +void K_DropHnextList(player_t *player, boolean keepshields); void K_RepairOrbitChain(mobj_t *orbit); player_t *K_FindJawzTarget(mobj_t *actor, player_t *source); boolean K_CheckPlayersRespawnColliding(INT32 playernum, fixed_t x, fixed_t y); diff --git a/src/p_inter.c b/src/p_inter.c index 8cc307571..1451e4b6d 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -542,7 +542,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (player->kartstuff[k_bubbleblowup] > 0) { - K_DropHnextList(player); + K_DropHnextList(player, false); special->extravalue1 = 2; // WAIT... special->extravalue2 = 52; // Slightly over the respawn timer length return; From 8b5bd645ca5d8ef9269aa6ccf4375337bd0c1672 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Thu, 9 Apr 2020 22:57:05 -0400 Subject: [PATCH 48/64] See if cleaning the pointer here fixes shrink/eggbox syncbombs --- src/k_kart.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/k_kart.c b/src/k_kart.c index 4cddcee1d..865ee11cb 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4700,6 +4700,13 @@ void K_UpdateHnextList(player_t *player, boolean clean) P_RemoveMobj(work); } + + if (player->mo->hnext == NULL || P_MobjWasRemoved(player->mo->hnext)) + { + // Like below, try to clean up the pointer if it's NULL. + // Maybe this was a cause of the shrink/eggbox fails? + P_SetTarget(&player->mo->hnext, NULL); + } } // For getting hit! From 371cc18bf68dc194a2f74b18f4c26e9a9165962f Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Sun, 12 Apr 2020 21:04:07 -0400 Subject: [PATCH 49/64] Update ALL finish line distances & positions, separately, before player thinkers happen, ensuring it's never inaccurate --- src/k_kart.c | 9 ++------- src/k_kart.h | 1 + src/p_tick.c | 22 ++++++++++++++++++++++ 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 7ad459ad1..dab36aaf9 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -6287,10 +6287,6 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) void K_KartPlayerAfterThink(player_t *player) { - // Moved to afterthink, as at this point the players have had their distances to the finish line updated - // and this will correctly account for all players - K_KartUpdatePosition(player); - if (player->kartstuff[k_curshield] || player->kartstuff[k_invincibilitytimer] || (player->kartstuff[k_growshrinktimer] != 0 && player->kartstuff[k_growshrinktimer] % 5 == 4)) // 4 instead of 0 because this is afterthink! @@ -6607,7 +6603,7 @@ static boolean K_PlayerCloserToNextWaypoints(waypoint_t *const waypoint, player_ } /*-------------------------------------------------- - static void K_UpdateDistanceFromFinishLine(player_t *const player) + void K_UpdateDistanceFromFinishLine(player_t *const player) Updates the distance a player has to the finish line. @@ -6617,7 +6613,7 @@ static boolean K_PlayerCloserToNextWaypoints(waypoint_t *const waypoint, player_ Return:- None --------------------------------------------------*/ -static void K_UpdateDistanceFromFinishLine(player_t *const player) +void K_UpdateDistanceFromFinishLine(player_t *const player) { if ((player != NULL) && (player->mo != NULL)) { @@ -7167,7 +7163,6 @@ void K_MoveKartPlayer(player_t *player, boolean onground) boolean HOLDING_ITEM = (player->kartstuff[k_itemheld] || player->kartstuff[k_eggmanheld]); boolean NO_HYUDORO = (player->kartstuff[k_stolentimer] == 0 && player->kartstuff[k_stealingtimer] == 0); - K_UpdateDistanceFromFinishLine(player); player->pflags &= ~PF_HITFINISHLINE; if (!player->exiting) diff --git a/src/k_kart.h b/src/k_kart.h index 8dc5604b8..8f47b9780 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -59,6 +59,7 @@ void K_UpdateHnextList(player_t *player, boolean clean); void K_DropHnextList(player_t *player); void K_RepairOrbitChain(mobj_t *orbit); player_t *K_FindJawzTarget(mobj_t *actor, player_t *source); +void K_UpdateDistanceFromFinishLine(player_t *const player); boolean K_CheckPlayersRespawnColliding(INT32 playernum, fixed_t x, fixed_t y); INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue); INT32 K_GetKartDriftSparkValue(player_t *player); diff --git a/src/p_tick.c b/src/p_tick.c index d7359b307..43ca98416 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -616,6 +616,17 @@ void P_Ticker(boolean run) G_ReadDemoTiccmd(&players[i].cmd, i); } + // First loop: Ensure all players' distance to the finish line are all accurate + for (i = 0; i < MAXPLAYERS; i++) + if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) + K_UpdateDistanceFromFinishLine(&players[i]); + + // Second loop: Ensure all player positions reflect everyone's distances + for (i = 0; i < MAXPLAYERS; i++) + if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) + K_KartUpdatePosition(&players[i]); + + // OK! Now that we got all of that sorted, players can think! for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) P_PlayerThink(&players[i]); @@ -778,6 +789,17 @@ void P_PreTicker(INT32 frames) { P_MapStart(); + // First loop: Ensure all players' distance to the finish line are all accurate + for (i = 0; i < MAXPLAYERS; i++) + if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) + K_UpdateDistanceFromFinishLine(&players[i]); + + // Second loop: Ensure all player positions reflect everyone's distances + for (i = 0; i < MAXPLAYERS; i++) + if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) + K_KartUpdatePosition(&players[i]); + + // OK! Now that we got all of that sorted, players can think! for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) { From da953c9dae05fae848e2e61e4f81b993852bea94 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Sun, 12 Apr 2020 23:51:00 -0400 Subject: [PATCH 50/64] No more modulo bullshit in VERSION VERSION is the first number, SUBVERSION is the second number, and the third number burns in hell; we really don't need that precision --- src/d_clisrv.c | 12 ++++++------ src/doomdef.h | 2 +- src/mserv.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 084a6fd81..3347091a3 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1880,7 +1880,7 @@ void CL_UpdateServerList(boolean internetsearch, INT32 room) { char version[8] = ""; #if VERSION > 0 || SUBVERSION > 0 - snprintf(version, sizeof (version), "%d.%d.%d", VERSION/100, VERSION%100, SUBVERSION); + snprintf(version, sizeof (version), "%d.%d", VERSION, SUBVERSION); #else strcpy(version, GetRevisionString()); #endif @@ -2355,8 +2355,8 @@ static void CL_ConnectToServer(boolean viams) gametypestr = Gametype_Names[num]; if (gametypestr) CONS_Printf(M_GetText("Gametype: %s\n"), gametypestr); - CONS_Printf(M_GetText("Version: %d.%d.%u\n"), serverlist[i].info.version/100, - serverlist[i].info.version%100, serverlist[i].info.subversion); + CONS_Printf(M_GetText("Version: %d.%d\n"), + serverlist[i].info.version, serverlist[i].info.subversion); } SL_ClearServerList(servernode); #endif @@ -3296,8 +3296,8 @@ static void Got_RemovePlayer(UINT8 **p, INT32 playernum); // called one time at init void D_ClientServerInit(void) { - DEBFILE(va("- - -== SRB2Kart v%d.%.2d.%d "VERSIONSTRING" debugfile ==- - -\n", - VERSION/100, VERSION%100, SUBVERSION)); + DEBFILE(va("- - -== SRB2Kart v%d.%d "VERSIONSTRING" debugfile ==- - -\n", + VERSION, SUBVERSION)); #ifndef NONET COM_AddCommand("getplayernum", Command_GetPlayerNum); @@ -3822,7 +3822,7 @@ static void HandleConnect(SINT8 node) SV_SendRefuse(node, M_GetText("You have been banned\nfrom the server")); else if (netbuffer->u.clientcfg.version != VERSION || netbuffer->u.clientcfg.subversion != SUBVERSION) - SV_SendRefuse(node, va(M_GetText("Different SRB2Kart versions cannot\nplay a netgame!\n(server version %d.%d.%d)"), VERSION/100, VERSION%100, SUBVERSION)); + SV_SendRefuse(node, va(M_GetText("Different SRB2Kart versions cannot\nplay a netgame!\n(server version %d.%d)"), VERSION, SUBVERSION)); else if (!cv_allownewplayer.value && node) SV_SendRefuse(node, M_GetText("The server is not accepting\njoins for the moment")); else if (D_NumPlayers() >= maxplayers) diff --git a/src/doomdef.h b/src/doomdef.h index ef7a2f8cb..2a67ce0e2 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -150,7 +150,7 @@ extern char logfilename[1024]; // most interface strings are ignored in development mode. // we use comprevision and compbranch instead. #else -#define VERSION 200 // Game version +#define VERSION 2 // Game version #define SUBVERSION 0 // more precise version number #define VERSIONSTRING "v2.0" #define VERSIONSTRINGW L"v2.0" diff --git a/src/mserv.c b/src/mserv.c index c7344b16a..12469928d 100644 --- a/src/mserv.c +++ b/src/mserv.c @@ -751,7 +751,7 @@ static INT32 AddToMasterServer(boolean firstadd) strcpy(info->name, cv_servername.string); M_Memcpy(&info->room, & room, sizeof (INT32)); #if VERSION > 0 || SUBVERSION > 0 - sprintf(info->version, "%d.%d.%d", VERSION/100, VERSION%100, SUBVERSION); + sprintf(info->version, "%d.%d", VERSION, SUBVERSION); #else // Trunk build, send revision info strcpy(info->version, GetRevisionString()); #endif @@ -789,7 +789,7 @@ static INT32 RemoveFromMasterSever(void) strcpy(info->ip, ""); strcpy(info->port, int2str(current_port)); strcpy(info->name, registered_server.name); - sprintf(info->version, "%d.%d.%d", VERSION/100, VERSION%100, SUBVERSION); + sprintf(info->version, "%d.%d", VERSION, SUBVERSION); msg.type = REMOVE_SERVER_MSG; msg.length = (UINT32)sizeof (msg_server_t); From ab40ede95508b7dc55c87facb001a92e67ce6653 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 15 Apr 2020 18:45:23 -0700 Subject: [PATCH 51/64] Line special 507, scroll tagged lines' front and back textures by front and back texture offsets --- src/p_spec.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 425d1c779..2d80dce5c 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -7205,9 +7205,15 @@ static void P_SpawnScrollers(void) { fixed_t dx = l->dx >> SCROLL_SHIFT; // direction and speed of scrolling fixed_t dy = l->dy >> SCROLL_SHIFT; + + fixed_t bx = 0;/* backside variants */ + fixed_t by = 0; + INT32 control = -1, accel = 0; // no control sector or acceleration INT32 special = l->special; + INT32 s; + // These types are same as the ones they get set to except that the // first side's sector's heights cause scrolling when they change, and // this linedef controls the direction and speed of the scrolling. The @@ -7236,10 +7242,21 @@ static void P_SpawnScrollers(void) control = (INT32)(sides[*l->sidenum].sector - sectors); } + if (special == 507) // front and back scrollers + { + s = l->sidenum[0]; + + dx = -(sides[s].textureoffset); + dy = sides[s].rowoffset; + + s = l->sidenum[1]; + + bx = -(sides[s].textureoffset); + by = sides[s].rowoffset; + } + switch (special) { - register INT32 s; - case 513: // scroll effect ceiling case 533: // scroll and carry objects on ceiling for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) @@ -7292,6 +7309,17 @@ static void P_SpawnScrollers(void) CONS_Debug(DBG_GAMELOGIC, "Line special 506 (line #%s) missing 2nd side!\n", sizeu1(i)); break; + case 507: // scroll front and backside of tagged lines + for (s = -1; (s = P_FindLineFromLineTag(l, s)) >= 0 ;) + { + if (s != (INT32)i) + { + Add_Scroller(sc_side, dx, dy, control, lines[s].sidenum[0], accel, 0); + Add_Scroller(sc_side, bx, by, control, lines[s].sidenum[1], accel, 0); + } + } + break; + case 500: // scroll first side Add_Scroller(sc_side, FRACUNIT, 0, -1, lines[i].sidenum[0], accel, 0); break; From 190fc271216627510ddec597a72fcd0ac1a8cdbb Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 15 Apr 2020 18:48:23 -0700 Subject: [PATCH 52/64] Check that a back side exists --- src/p_spec.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 2d80dce5c..ee3e4851f 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -7251,8 +7251,11 @@ static void P_SpawnScrollers(void) s = l->sidenum[1]; - bx = -(sides[s].textureoffset); - by = sides[s].rowoffset; + if (s != 0xffff) + { + bx = -(sides[s].textureoffset); + by = sides[s].rowoffset; + } } switch (special) @@ -7315,7 +7318,8 @@ static void P_SpawnScrollers(void) if (s != (INT32)i) { Add_Scroller(sc_side, dx, dy, control, lines[s].sidenum[0], accel, 0); - Add_Scroller(sc_side, bx, by, control, lines[s].sidenum[1], accel, 0); + if (lines[s].sidenum[1] != 0xffff) + Add_Scroller(sc_side, bx, by, control, lines[s].sidenum[1], accel, 0); } } break; From 0b3b13b3b59ada7533edd16aa9b83c97d4b10314 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 15 Apr 2020 19:16:49 -0700 Subject: [PATCH 53/64] Remove FOF height sorting --- src/p_mobj.c | 5 ----- src/p_setup.c | 4 ---- src/p_spec.c | 35 ----------------------------------- src/r_defs.h | 8 -------- 4 files changed, 52 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index a989b0019..2a12dcc7a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -12324,11 +12324,6 @@ void P_SpawnMapThing(mapthing_t *mthing) y = mthing->y << FRACBITS; ss = R_PointInSubsector(x, y); - if (i == MT_WAYPOINT_RISER) - { - ss->sector->ffloor_sorting = true; - } - if (i == MT_NIGHTSBUMPER) z = ( #ifdef ESLOPE diff --git a/src/p_setup.c b/src/p_setup.c index 0eb4abc5c..4ddc3c2a9 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -741,10 +741,6 @@ static void P_LoadRawSectors(UINT8 *data, size_t i) ss->maxattached = 1; ss->moved = true; - ss->ffloor_sorting = false; - ss->lowest_ffloor = NULL; - ss->highest_ffloor = NULL; - ss->extra_colormap = NULL; ss->floor_xoffs = ss->ceiling_xoffs = ss->floor_yoffs = ss->ceiling_yoffs = 0; diff --git a/src/p_spec.c b/src/p_spec.c index 158f44dda..f6c975d9b 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -5155,46 +5155,11 @@ static inline void P_AddFFloorToList(sector_t *sec, ffloor_t *ffloor) if (!sec->ffloors) { sec->ffloors = ffloor; - if (sec->ffloor_sorting) - { - sec->lowest_ffloor = ffloor; - sec->highest_ffloor = ffloor; - } ffloor->next = 0; ffloor->prev = 0; return; } - if (sec->ffloor_sorting) - { - top = P_VeryTopOfFOF(ffloor); - - for (rover = sec->lowest_ffloor; rover; rover = rover->higher) - { - if (top < P_VeryTopOfFOF(rover)) - break; - } - - if (rover) - { - if (rover->lower) - rover->lower->higher = ffloor; - else - sec->lowest_ffloor = ffloor; - - ffloor->lower = rover->lower; - ffloor->higher = rover; - - rover->lower = ffloor; - } - else - { - sec->highest_ffloor->higher = ffloor; - ffloor->lower = sec->highest_ffloor; - sec->highest_ffloor = ffloor; - } - } - for (rover = sec->ffloors; rover->next; rover = rover->next); rover->next = ffloor; diff --git a/src/r_defs.h b/src/r_defs.h index 399dec087..c8a72044d 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -170,10 +170,6 @@ typedef struct ffloor_s struct ffloor_s *next; struct ffloor_s *prev; - /* if sector->ffloor_sorting */ - struct ffloor_s *higher;/* by top height */ - struct ffloor_s *lower;/* by bottom height */ - INT32 lastlight; INT32 alpha; tic_t norender; // for culling @@ -351,10 +347,6 @@ typedef struct sector_s INT32 numlights; boolean moved; - boolean ffloor_sorting; - ffloor_t *lowest_ffloor; - ffloor_t *highest_ffloor; - // per-sector colormaps! extracolormap_t *extra_colormap; From 62143d32b372f4332a618c314b90cf0c87c8fe1e Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 15 Apr 2020 19:31:23 -0700 Subject: [PATCH 54/64] Rise waypoint to highest FOF below riser, or lowest above --- src/k_waypoint.c | 45 +++++++++++++++++++++------------------------ 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/src/k_waypoint.c b/src/k_waypoint.c index 1bc48b2a5..07ea34dbe 100644 --- a/src/k_waypoint.c +++ b/src/k_waypoint.c @@ -1791,7 +1791,8 @@ void K_AdjustWaypointsParameters (void) boolean descending; - UINT16 fof_no; + fixed_t sort; + fixed_t z; for ( waypointmobj = waypointcap; @@ -1818,42 +1819,38 @@ void K_AdjustWaypointsParameters (void) } else { + x = waypointmobj->x; + y = waypointmobj->y; + descending = ( riser->spawnpoint->options & MTF_OBJECTFLIP ); - fof_no = ( riser->spawnpoint->options >> ZSHIFT ); - if (descending) - rover = sector->highest_ffloor; + sort = sector->ceilingheight; else - rover = sector->lowest_ffloor; + sort = sector->floorheight; - while (rover) - { - if (fof_no > 0) + for ( + rover = sector->ffloors; + rover; + rover = rover->next + ){ + if (descending) { - if (descending) - rover = rover->lower; - else - rover = rover->higher; + z = P_GetFOFBottomZAt(rover, x, y); - fof_no--; + if (z > riser->z && z < sort) + sort = z; } else { - x = waypointmobj->x; - y = waypointmobj->y; + z = P_GetFOFTopZAt(rover, x, y); - if (( waypointmobj->flags2 & MF2_OBJECTFLIP )) - { - waypointmobj->z = P_GetFOFBottomZAt(rover, x, y) - - waypointmobj->info->height; - } - else - waypointmobj->z = P_GetFOFTopZAt(rover, x, y); - - break; + if (z < riser->z && z > sort) + sort = z; } } + + waypointmobj->z = sort; } } } From e941749f4c96026912b3945d376187c1b26f2f4e Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Wed, 15 Apr 2020 22:45:03 -0400 Subject: [PATCH 55/64] Move all of the item destroy sector code to one place --- src/p_mobj.c | 73 ++++++++++++++++++++++++++-------------------------- 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 2a12dcc7a..2838e9388 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6153,7 +6153,7 @@ boolean P_IsKartItem(INT32 type) type == MT_JAWZ || type == MT_JAWZ_DUD || type == MT_JAWZ_SHIELD || type == MT_SSMINE || type == MT_SSMINE_SHIELD || type == MT_SINK || type == MT_SINK_SHIELD || - type == MT_SPB) + type == MT_SPB || type == MT_BALLHOG || type == MT_BUBBLESHIELDTRAP) return true; else return false; @@ -7175,6 +7175,41 @@ void P_MobjThinker(mobj_t *mobj) return; } #endif + + // Destroy items sector special + if (mobj->type == MT_BANANA || mobj->type == MT_EGGMANITEM + || mobj->type == MT_ORBINAUT || mobj->type == MT_BALLHOG + || mobj->type == MT_JAWZ || mobj->type == MT_JAWZ_DUD + || mobj->type == MT_SSMINE || mobj->type == MT_BUBBLESHIELDTRAP) + { + if (mobj->health > 0 && P_MobjTouchingSectorSpecial(mobj, 4, 7, true)) + { + if (mobj->type == MT_SSMINE + || mobj->type == MT_BUBBLESHIELDTRAP + || mobj->type == MT_BALLHOG) + { + S_StartSound(mobj, mobj->info->deathsound); + P_KillMobj(mobj, NULL, NULL); + } + else + { + // This Item Damage + if (mobj->eflags & MFE_VERTICALFLIP) + mobj->z -= mobj->height; + else + mobj->z += mobj->height; + + S_StartSound(mobj, mobj->info->deathsound); + P_KillMobj(mobj, NULL, NULL); + + P_SetObjectMomZ(mobj, 8*FRACUNIT, false); + P_InstaThrust(mobj, R_PointToAngle2(0, 0, mobj->momx, mobj->momy) + ANGLE_90, 16*FRACUNIT); + } + + return; + } + } + // if it's pushable, or if it would be pushable other than temporary disablement, use the // separate thinker if (mobj->flags & MF_PUSHABLE || (mobj->info->flags & MF_PUSHABLE && mobj->fuse)) @@ -7939,12 +7974,6 @@ void P_MobjThinker(mobj_t *mobj) { boolean grounded = P_IsObjectOnGround(mobj); - if (P_MobjTouchingSectorSpecial(mobj, 4, 7, true)) - { - P_RemoveMobj(mobj); - return; - } - if (mobj->flags2 & MF2_AMBUSH) { if (grounded && (mobj->flags & MF_NOCLIPTHING)) @@ -8015,12 +8044,6 @@ void P_MobjThinker(mobj_t *mobj) { mobj_t *ghost = P_SpawnGhostMobj(mobj); - if (P_MobjTouchingSectorSpecial(mobj, 4, 7, true)) - { - P_RemoveMobj(mobj); - return; - } - if (mobj->target && !P_MobjWasRemoved(mobj->target) && mobj->target->player) { ghost->color = mobj->target->player->skincolor; @@ -8045,12 +8068,6 @@ void P_MobjThinker(mobj_t *mobj) { boolean grounded = P_IsObjectOnGround(mobj); - if (P_MobjTouchingSectorSpecial(mobj, 4, 7, true)) - { - P_RemoveMobj(mobj); - return; - } - if (mobj->flags2 & MF2_AMBUSH) { if (grounded && (mobj->flags & MF_NOCLIPTHING)) @@ -8124,12 +8141,6 @@ void P_MobjThinker(mobj_t *mobj) case MT_BANANA: mobj->friction = ORIG_FRICTION/4; - if (P_MobjTouchingSectorSpecial(mobj, 4, 7, true)) - { - P_RemoveMobj(mobj); - return; - } - if (mobj->momx || mobj->momy) { mobj_t *ghost = P_SpawnGhostMobj(mobj); @@ -8159,12 +8170,6 @@ void P_MobjThinker(mobj_t *mobj) mobj_t *ghost = P_SpawnGhostMobj(mobj); ghost->fuse = 3; - if (P_MobjTouchingSectorSpecial(mobj, 4, 7, true)) - { - P_RemoveMobj(mobj); - return; - } - if (mobj->target && !P_MobjWasRemoved(mobj->target) && mobj->target->player) { ghost->color = mobj->target->player->skincolor; @@ -8197,12 +8202,6 @@ void P_MobjThinker(mobj_t *mobj) mobj->threshold--; break; case MT_SSMINE: - if (P_MobjTouchingSectorSpecial(mobj, 4, 7, true)) - { - P_RemoveMobj(mobj); - return; - } - if (mobj->target && mobj->target->player) mobj->color = mobj->target->player->skincolor; else From 263c31f5df8f4a47c233d7fa4687f1917b4688a5 Mon Sep 17 00:00:00 2001 From: lachwright Date: Tue, 21 Apr 2020 02:38:08 +0800 Subject: [PATCH 56/64] Improve camera tilt --- src/p_user.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 16038fade..3a5300f42 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -7411,7 +7411,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall if (mo->standingslope) { - pitch = (angle_t)FixedMul(P_ReturnThrustX(mo, player->frameangle - mo->standingslope->xydirection, FRACUNIT), (fixed_t)mo->standingslope->zangle); + pitch = (angle_t)FixedMul(P_ReturnThrustX(mo, thiscam->angle - mo->standingslope->xydirection, FRACUNIT), (fixed_t)mo->standingslope->zangle); if (mo->eflags & MFE_VERTICALFLIP) { if (pitch >= ANGLE_180) @@ -7476,9 +7476,15 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall pviewheight = FixedMul(32<scale); if (mo->eflags & MFE_VERTICALFLIP) - z = mo->z + mo->height - pviewheight - camheight + distz; + { + distz = min(-height, distz); + z = mo->z + mo->height - pviewheight + distz; + } else - z = mo->z + pviewheight + camheight + distz; + { + distz = max(height, distz); + z = mo->z + pviewheight + distz; + } #ifndef NOCLIPCAM // Disable all z-clipping for noclip cam // move camera down to move under lower ceilings @@ -7724,13 +7730,13 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall { angle = R_PointToAngle2(0, thiscam->z + thiscam->height, dist, mo->z + mo->height - P_GetPlayerHeight(player)); if (thiscam->pitch < ANGLE_180 && thiscam->pitch > angle) - angle = thiscam->pitch; + angle += (thiscam->pitch - angle)/2; } else { angle = R_PointToAngle2(0, thiscam->z, dist, mo->z + P_GetPlayerHeight(player)); if (thiscam->pitch >= ANGLE_180 && thiscam->pitch < angle) - angle = thiscam->pitch; + angle -= (angle - thiscam->pitch)/2; } if (player->playerstate != PST_DEAD && !((player->pflags & PF_NIGHTSMODE) && player->exiting)) From 6905cfb0643df798cd53649ef40b49153378ced8 Mon Sep 17 00:00:00 2001 From: lachwright Date: Tue, 21 Apr 2020 03:30:45 +0800 Subject: [PATCH 57/64] Revert camtilt splitscreen hacks --- src/p_user.c | 4 ++-- src/r_main.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 3a5300f42..46b0a4f26 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -7434,8 +7434,8 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall else distxy = dist; distz = -FixedMul(dist, FINESINE((pitch>>ANGLETOFINESHIFT) & FINEMASK)); - if (r_splitscreen == 1) // 2 player is weird, this helps keep players on screen - distz = 3*distz/5; + //if (r_splitscreen == 1) // 2 player is weird, this helps keep players on screen + //distz = 3*distz/5; x = mo->x - FixedMul(FINECOSINE((angle>>ANGLETOFINESHIFT) & FINEMASK), distxy); y = mo->y - FixedMul(FINESINE((angle>>ANGLETOFINESHIFT) & FINEMASK), distxy); diff --git a/src/r_main.c b/src/r_main.c index 5afda93f7..10ba4d6a8 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -841,7 +841,7 @@ static void R_SetupFreelook(void) // clip it in the case we are looking a hardware 90 degrees full aiming // (lmps, network and use F12...) G_SoftwareClipAimingPitch((INT32 *)&aimingangle); - dy = AIMINGTODY(aimingangle) * viewheight/BASEVIDHEIGHT; + dy = AIMINGTODY(aimingangle) * viewwidth/BASEVIDWIDTH; yslope = &yslopetab[viewheight*8 - (viewheight/2 + dy)]; } centery = (viewheight/2) + dy; From c92634c71e4bba4c00301c909292175c2050b23a Mon Sep 17 00:00:00 2001 From: lachwright Date: Tue, 21 Apr 2020 05:24:48 +0800 Subject: [PATCH 58/64] Make lookback instantaneous --- src/p_user.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 46b0a4f26..fe7082990 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -7157,13 +7157,14 @@ void P_ResetCamera(player_t *player, camera_t *thiscam) boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcalled) { - static UINT8 lookbackdelay[4] = {0,0,0,0}; + static boolean lookbackactive[MAXSPLITSCREENPLAYERS]; + static UINT8 lookbackdelay[MAXSPLITSCREENPLAYERS]; UINT8 num; angle_t angle = 0, focusangle = 0, focusaiming = 0, pitch = 0; fixed_t x, y, z, dist, distxy, distz, height, viewpointx, viewpointy, camspeed, camdist, camheight, pviewheight; fixed_t pan, xpan, ypan; INT32 camrotate; - boolean camstill, lookback; + boolean camstill, lookback, lookbackdown; UINT8 timeover; mobj_t *mo; fixed_t f1, f2; @@ -7343,15 +7344,19 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall camstill = true; else if (lookback || lookbackdelay[num]) // SRB2kart - Camera flipper { +#define MAXLOOKBACKDELAY 2 camspeed = FRACUNIT; if (lookback) { camrotate += 180; - lookbackdelay[num] = 2; + lookbackdelay[num] = MAXLOOKBACKDELAY; } else lookbackdelay[num]--; } + lookbackdown = (lookbackdelay[num] == MAXLOOKBACKDELAY) != lookbackactive[num]; + lookbackactive[num] = (lookbackdelay[num] == MAXLOOKBACKDELAY); +#undef MAXLOOKBACKDELAY if (mo->eflags & MFE_VERTICALFLIP) camheight += thiscam->height; @@ -7434,8 +7439,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall else distxy = dist; distz = -FixedMul(dist, FINESINE((pitch>>ANGLETOFINESHIFT) & FINEMASK)); - //if (r_splitscreen == 1) // 2 player is weird, this helps keep players on screen - //distz = 3*distz/5; x = mo->x - FixedMul(FINECOSINE((angle>>ANGLETOFINESHIFT) & FINEMASK), distxy); y = mo->y - FixedMul(FINESINE((angle>>ANGLETOFINESHIFT) & FINEMASK), distxy); @@ -7779,6 +7782,9 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall thiscam->aiming = ANGLE_22h; } + if (lookbackdown) + P_MoveChaseCamera(player, thiscam, false); + return (x == thiscam->x && y == thiscam->y && z == thiscam->z && angle == thiscam->aiming); } From 02f30814eb276e302ab7b0ff1fdd3f8d7762999f Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 21 Apr 2020 00:21:41 -0700 Subject: [PATCH 59/64] Do some cleanup --- src/k_waypoint.c | 145 ++++++++++++++++++++++++++++------------------- 1 file changed, 88 insertions(+), 57 deletions(-) diff --git a/src/k_waypoint.c b/src/k_waypoint.c index 07ea34dbe..0cc52fd89 100644 --- a/src/k_waypoint.c +++ b/src/k_waypoint.c @@ -1772,6 +1772,88 @@ void K_ClearWaypoints(void) circuitlength = 0U; } +/*-------------------------------------------------- + static boolean K_RaiseWaypoint( + mobj_t *const waypointmobj, + const mobj_t *const riser) + + Raise a waypoint according a waypoint riser thing. + + Input Arguments:- + waypointmobj - The mobj of the waypoint to raise + riser - The waypoint riser mobj + + Return:- + True if the waypoint was risen, false if not. +--------------------------------------------------*/ + +static boolean K_RaiseWaypoint( + mobj_t *const waypointmobj, + const mobj_t *const riser) +{ + fixed_t x; + fixed_t y; + + const sector_t *sector; + ffloor_t *rover; + + boolean descending; + + fixed_t sort; + fixed_t z; + + if ( + !( riser->spawnpoint->options & MTF_OBJECTSPECIAL ) || + riser->spawnpoint->angle == waypointmobj->spawnpoint->angle + ){ + if (( riser->spawnpoint->options & MTF_AMBUSH )) + { + waypointmobj->z = riser->z; + } + else + { + x = waypointmobj->x; + y = waypointmobj->y; + + descending = ( riser->spawnpoint->options & MTF_OBJECTFLIP ); + + sector = waypointmobj->subsector->sector; + + if (descending) + sort = sector->ceilingheight; + else + sort = sector->floorheight; + + for ( + rover = sector->ffloors; + rover; + rover = rover->next + ){ + if (descending) + { + z = P_GetFOFBottomZAt(rover, x, y); + + if (z > riser->z && z < sort) + sort = z; + } + else + { + z = P_GetFOFTopZAt(rover, x, y); + + if (z < riser->z && z > sort) + sort = z; + } + } + + waypointmobj->z = sort; + } + + return true; + } + else + return false; +} + /*-------------------------------------------------- void K_AdjustWaypointsParameters(void) @@ -1781,18 +1863,9 @@ void K_ClearWaypoints(void) void K_AdjustWaypointsParameters (void) { mobj_t *waypointmobj; - mobj_t *riser; + const mobj_t *riser; - fixed_t x; - fixed_t y; - - sector_t *sector; - ffloor_t *rover; - - boolean descending; - - fixed_t sort; - fixed_t z; + const sector_t *sector; for ( waypointmobj = waypointcap; @@ -1806,52 +1879,10 @@ void K_AdjustWaypointsParameters (void) riser; riser = riser->snext ){ - if ( - riser->type == MT_WAYPOINT_RISER && - ( - !( riser->spawnpoint->options & MTF_OBJECTSPECIAL ) || - riser->spawnpoint->angle == waypointmobj->spawnpoint->angle - ) - ){ - if (( riser->spawnpoint->options & MTF_AMBUSH )) - { - waypointmobj->z = riser->z; - } - else - { - x = waypointmobj->x; - y = waypointmobj->y; - - descending = ( riser->spawnpoint->options & MTF_OBJECTFLIP ); - - if (descending) - sort = sector->ceilingheight; - else - sort = sector->floorheight; - - for ( - rover = sector->ffloors; - rover; - rover = rover->next - ){ - if (descending) - { - z = P_GetFOFBottomZAt(rover, x, y); - - if (z > riser->z && z < sort) - sort = z; - } - else - { - z = P_GetFOFTopZAt(rover, x, y); - - if (z < riser->z && z > sort) - sort = z; - } - } - - waypointmobj->z = sort; - } + if (riser->type == MT_WAYPOINT_RISER) + { + if (K_RaiseWaypoint(waypointmobj, riser)) + break; } } } From fd51bf10b060a1b290318d9b00acb6e2782e8788 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 21 Apr 2020 00:30:56 -0700 Subject: [PATCH 60/64] Thing type 2003, MT_WAYPOINT_ANCHOR - Adjust waypoint's radius The distance from the waypoint to the anchor will be the new radius. --- src/dehacked.c | 1 + src/info.c | 27 ++++++++++++++++++++++ src/info.h | 1 + src/k_waypoint.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 87 insertions(+), 1 deletion(-) diff --git a/src/dehacked.c b/src/dehacked.c index ab3340ed1..8507a1b03 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7899,6 +7899,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_WAYPOINT", "MT_WAYPOINT_RISER", + "MT_WAYPOINT_ANCHOR", "MT_RANDOMAUDIENCE", diff --git a/src/info.c b/src/info.c index 298ca2c8c..7bed0a78d 100644 --- a/src/info.c +++ b/src/info.c @@ -16555,6 +16555,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_WAYPOINT_ANCHOR + 2003, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 100, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 1*FRACUNIT, // radius + 2*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags + S_NULL // raisestate + }, + { // MT_RANDOMAUDIENCE 1488, // doomednum S_RANDOMAUDIENCE, // spawnstate diff --git a/src/info.h b/src/info.h index 5cb0a8a45..f86fed973 100644 --- a/src/info.h +++ b/src/info.h @@ -4830,6 +4830,7 @@ typedef enum mobj_type MT_WAYPOINT, MT_WAYPOINT_RISER, + MT_WAYPOINT_ANCHOR, MT_RANDOMAUDIENCE, diff --git a/src/k_waypoint.c b/src/k_waypoint.c index 0cc52fd89..f32cf68b0 100644 --- a/src/k_waypoint.c +++ b/src/k_waypoint.c @@ -16,7 +16,7 @@ #include "d_netcmd.h" #include "p_local.h" #include "p_tick.h" -#include "r_state.h" +#include "r_local.h" #include "z_zone.h" #include "g_game.h" @@ -1854,6 +1854,37 @@ static boolean K_RaiseWaypoint( return false; } +/*-------------------------------------------------- + static boolean K_AnchorWaypointRadius( + mobj_t *const waypointmobj, + const mobj_t *const anchor) + + Adjust a waypoint's radius by distance from an "anchor". + + Input Arguments:- + waypointmobj - The mobj of the waypoint whose radius to adjust + riser - The waypoint anchor mobj + + Return:- + True if the waypoint's radius was adjusted, false if not. +--------------------------------------------------*/ + +static boolean K_AnchorWaypointRadius( + mobj_t *const waypointmobj, + const mobj_t *const anchor) +{ + if (anchor->spawnpoint->angle == waypointmobj->spawnpoint->angle) + { + waypointmobj->radius = R_PointToDist2( + waypointmobj->x, waypointmobj->y, + anchor->x, anchor->y); + + return true; + } + else + return false; +} + /*-------------------------------------------------- void K_AdjustWaypointsParameters(void) @@ -1865,6 +1896,9 @@ void K_AdjustWaypointsParameters (void) mobj_t *waypointmobj; const mobj_t *riser; + const thinker_t *th; + const mobj_t *anchor; + const sector_t *sector; for ( @@ -1886,4 +1920,27 @@ void K_AdjustWaypointsParameters (void) } } } + + for ( + th = thinkercap.next; + th != &thinkercap; + th = th->next + ){ + if (th->function.acp1 == (actionf_p1)P_MobjThinker) + { + anchor = (const mobj_t *)th; + + if (anchor->type == MT_WAYPOINT_ANCHOR) + { + for ( + waypointmobj = waypointcap; + waypointmobj; + waypointmobj = waypointmobj->tracer + ){ + if (K_AnchorWaypointRadius(waypointmobj, anchor)) + break; + } + } + } + } } From dd126494b3b7bfc74bca904c2a9ec16743f13de6 Mon Sep 17 00:00:00 2001 From: lachwright Date: Wed, 22 Apr 2020 22:59:57 +0800 Subject: [PATCH 61/64] [Everyone disliked that.] (revert camera zoom) --- src/p_user.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index fe7082990..5358df1fe 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -7161,7 +7161,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall static UINT8 lookbackdelay[MAXSPLITSCREENPLAYERS]; UINT8 num; angle_t angle = 0, focusangle = 0, focusaiming = 0, pitch = 0; - fixed_t x, y, z, dist, distxy, distz, height, viewpointx, viewpointy, camspeed, camdist, camheight, pviewheight; + fixed_t x, y, z, dist, distxy, distz, viewpointx, viewpointy, camspeed, camdist, camheight, pviewheight; fixed_t pan, xpan, ypan; INT32 camrotate; boolean camstill, lookback, lookbackdown; @@ -7399,8 +7399,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall thiscam->angle = angle; } - height = camheight; - // sets ideal cam pos dist = camdist; @@ -7409,10 +7407,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall dist += abs(thiscam->momz)/4; if (player->karthud[khud_boostcam]) - { dist -= FixedMul(11*dist/16, player->karthud[khud_boostcam]); - height -= FixedMul(height, player->karthud[khud_boostcam]); - } if (mo->standingslope) { @@ -7480,12 +7475,12 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall if (mo->eflags & MFE_VERTICALFLIP) { - distz = min(-height, distz); + distz = min(-camheight, distz); z = mo->z + mo->height - pviewheight + distz; } else { - distz = max(height, distz); + distz = max(camheight, distz); z = mo->z + pviewheight + distz; } From 4040698e2403fd7bb912d959491ce447a06d6b33 Mon Sep 17 00:00:00 2001 From: lachwright Date: Wed, 22 Apr 2020 23:24:13 +0800 Subject: [PATCH 62/64] Add new files to src/CMakeLists.txt --- src/CMakeLists.txt | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2f97c173c..4447614d3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -18,6 +18,7 @@ set(SRB2_CORE_SOURCES filesrch.c g_game.c g_input.c + g_splitscreen.c hu_stuff.c i_tcp.c info.c @@ -156,7 +157,13 @@ set(SRB2_CORE_GAME_SOURCES p_telept.c p_tick.c p_user.c + k_battle.c + k_bheap.c + k_collide.c k_kart.c + k_pathfind.c + k_pwrlv.c + k_waypoint.c p_local.h p_maputl.h @@ -168,7 +175,13 @@ set(SRB2_CORE_GAME_SOURCES p_slopes.h p_spec.h p_tick.h + k_battle.h + k_bheap.h + k_collide.h k_kart.h + k_pathfind.h + k_pwrlv.h + k_waypoint.h ) if(NOT (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) From e26bb897d661535554b72cb3ca4f0f407aa4d5aa Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Thu, 23 Apr 2020 14:18:43 -0400 Subject: [PATCH 63/64] Prevent divide by zero in slopes code Not exactly sure why this happens, or if this is the correct way to fix it --- src/p_slopes.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/p_slopes.c b/src/p_slopes.c index e623b6f19..03c1205f6 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -54,6 +54,13 @@ static void P_ReconfigureVertexSlope(pslope_t *slope) max(max(abs(vec1.x), abs(vec1.y)), abs(vec1.z)), max(max(abs(vec2.x), abs(vec2.y)), abs(vec2.z)) ) >> (FRACBITS+5); + + if (slope->extent == 0) + { + // Prevent divide by zero + slope->extent = 1; + } + vec1.x /= slope->extent; vec1.y /= slope->extent; vec1.z /= slope->extent; From 48b7c75e477c871276381fc321f7b0a2cd6ebf9a Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 24 Apr 2020 20:39:54 -0700 Subject: [PATCH 64/64] Why is this still here --- src/p_spec.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index fd3b717bf..ad711fb8b 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -5150,8 +5150,6 @@ static inline void P_AddFFloorToList(sector_t *sec, ffloor_t *ffloor) { ffloor_t *rover; - fixed_t top; - if (!sec->ffloors) { sec->ffloors = ffloor;