Merge branch 'master' of https://git.do.srb2.org/KartKrew/Kart into conditions-cascading

This commit is contained in:
toaster 2023-03-04 20:09:48 +00:00
commit 5296ab1397
14 changed files with 237 additions and 32 deletions

View file

@ -479,6 +479,7 @@ static void COM_TokenizeString(char *ptext)
Z_Free(com_argv[i]); Z_Free(com_argv[i]);
com_argc = 0; com_argc = 0;
Z_Free(com_args);
com_args = NULL; com_args = NULL;
com_flags = 0; com_flags = 0;
@ -502,7 +503,7 @@ static void COM_TokenizeString(char *ptext)
break; break;
if (com_argc == 1) if (com_argc == 1)
com_args = ptext; com_args = COM_Purge(Z_StrDup(ptext), NULL);
ptext = COM_Parse(ptext); ptext = COM_Parse(ptext);
if (ptext == NULL) if (ptext == NULL)

View file

@ -1955,6 +1955,9 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
{ {
I_OsPolling(); I_OsPolling();
I_NewTwodeeFrame();
I_NewImguiFrame();
// Needs to be updated here for M_DrawEggaChannel // Needs to be updated here for M_DrawEggaChannel
renderdeltatics = FRACUNIT; renderdeltatics = FRACUNIT;
rendertimefrac = FRACUNIT; rendertimefrac = FRACUNIT;

View file

@ -803,8 +803,11 @@ void D_SRB2Loop(void)
HW3S_BeginFrameUpdate(); HW3S_BeginFrameUpdate();
#endif #endif
I_NewTwodeeFrame(); if (rendermode != render_none)
I_NewImguiFrame(); {
I_NewTwodeeFrame();
I_NewImguiFrame();
}
if (realtics > 0 || singletics) if (realtics > 0 || singletics)
{ {
@ -1500,8 +1503,11 @@ void D_SRB2Main(void)
CONS_Printf("I_StartupGraphics()...\n"); CONS_Printf("I_StartupGraphics()...\n");
I_StartupGraphics(); I_StartupGraphics();
I_NewTwodeeFrame(); if (rendermode != render_none)
I_NewImguiFrame(); {
I_NewTwodeeFrame();
I_NewImguiFrame();
}
#ifdef HWRENDER #ifdef HWRENDER
// Lactozilla: Add every hardware mode CVAR and CCMD. // Lactozilla: Add every hardware mode CVAR and CCMD.
@ -1642,6 +1648,10 @@ void D_SRB2Main(void)
I_Error("Bad '%s' level warp.\n" I_Error("Bad '%s' level warp.\n"
#if defined (_WIN32) #if defined (_WIN32)
"Are you using MSDOS 8.3 filenames in Zone Builder?\n" "Are you using MSDOS 8.3 filenames in Zone Builder?\n"
"\n"
"To check: edit the Ring Racers game configuration in Zone Builder.\n"
"Go to the Testing tab and make sure \"Use short paths and file names\" is turned off.\n"
"(The option is hidden by default. Check \"Customize parameters\" to show it.)\n"
#endif #endif
, word); , word);
} }
@ -1652,7 +1662,7 @@ void D_SRB2Main(void)
} }
{ {
if (!M_CheckParm("-server")) if (!M_CheckParm("-server") && !M_CheckParm("-dedicated"))
{ {
G_SetUsedCheats(); G_SetUsedCheats();

View file

@ -226,6 +226,8 @@ static void Command_Schedule_List(void);
static void Command_Automate_Set(void); static void Command_Automate_Set(void);
static void Command_Eval(void);
// ========================================================================= // =========================================================================
// CLIENT VARIABLES // CLIENT VARIABLES
// ========================================================================= // =========================================================================
@ -492,7 +494,7 @@ consvar_t cv_rollingdemos = CVAR_INIT ("rollingdemos", "On", CV_SAVE, CV_OnOff,
static CV_PossibleValue_t pointlimit_cons_t[] = {{1, "MIN"}, {MAXSCORE, "MAX"}, {0, "None"}, {-1, "Default"}, {0, NULL}}; static CV_PossibleValue_t pointlimit_cons_t[] = {{1, "MIN"}, {MAXSCORE, "MAX"}, {0, "None"}, {-1, "Default"}, {0, NULL}};
consvar_t cv_pointlimit = CVAR_INIT ("pointlimit", "Default", CV_NETVAR|CV_CALL|CV_NOINIT, pointlimit_cons_t, PointLimit_OnChange); consvar_t cv_pointlimit = CVAR_INIT ("pointlimit", "Default", CV_NETVAR|CV_CALL|CV_NOINIT, pointlimit_cons_t, PointLimit_OnChange);
static CV_PossibleValue_t timelimit_cons_t[] = {{1, "MIN"}, {30, "MAX"}, {0, "None"}, {-1, "Default"}, {0, NULL}}; static CV_PossibleValue_t timelimit_cons_t[] = {{1, "MIN"}, {30*60, "MAX"}, {0, "None"}, {-1, "Default"}, {0, NULL}};
consvar_t cv_timelimit = CVAR_INIT ("timelimit", "Default", CV_NETVAR|CV_CALL|CV_NOINIT, timelimit_cons_t, TimeLimit_OnChange); consvar_t cv_timelimit = CVAR_INIT ("timelimit", "Default", CV_NETVAR|CV_CALL|CV_NOINIT, timelimit_cons_t, TimeLimit_OnChange);
static CV_PossibleValue_t numlaps_cons_t[] = {{1, "MIN"}, {MAX_LAPS, "MAX"}, {0, "Map default"}, {0, NULL}}; static CV_PossibleValue_t numlaps_cons_t[] = {{1, "MIN"}, {MAX_LAPS, "MAX"}, {0, "Map default"}, {0, NULL}};
@ -745,6 +747,8 @@ void D_RegisterServerCommands(void)
COM_AddCommand("automate_set", Command_Automate_Set); COM_AddCommand("automate_set", Command_Automate_Set);
COM_AddCommand("eval", Command_Eval);
// for master server connection // for master server connection
AddMServCommands(); AddMServCommands();
@ -1083,6 +1087,7 @@ void D_RegisterClientCommands(void)
COM_AddCommand("god", Command_CheatGod_f); COM_AddCommand("god", Command_CheatGod_f);
COM_AddCommand("setrings", Command_Setrings_f); COM_AddCommand("setrings", Command_Setrings_f);
COM_AddCommand("setlives", Command_Setlives_f); COM_AddCommand("setlives", Command_Setlives_f);
COM_AddCommand("setscore", Command_Setscore_f);
COM_AddCommand("devmode", Command_Devmode_f); COM_AddCommand("devmode", Command_Devmode_f);
COM_AddCommand("savecheckpoint", Command_Savecheckpoint_f); COM_AddCommand("savecheckpoint", Command_Savecheckpoint_f);
COM_AddCommand("scale", Command_Scale_f); COM_AddCommand("scale", Command_Scale_f);
@ -2051,6 +2056,10 @@ void D_Cheat(INT32 playernum, INT32 cheat, ...)
COPY(WRITESINT8, int); COPY(WRITESINT8, int);
COPY(WRITEUINT8, unsigned int); COPY(WRITEUINT8, unsigned int);
break; break;
case CHEAT_SCORE:
COPY(WRITEUINT32, UINT32);
break;
} }
#undef COPY #undef COPY
@ -5029,7 +5038,7 @@ static void TimeLimit_OnChange(void)
break; break;
default: default:
CONS_Printf(M_GetText("Time limit has been set to %d minute%s.\n"), cv_timelimit.value,cv_timelimit.value == 1 ? "" : "s"); CONS_Printf(M_GetText("Time limit has been set to %d second%s.\n"), cv_timelimit.value,cv_timelimit.value == 1 ? "" : "s");
} }
timelimitintics = K_TimeLimitForGametype(); timelimitintics = K_TimeLimitForGametype();
@ -5051,7 +5060,7 @@ static void TimeLimit_OnChange(void)
break; break;
default: default:
CONS_Printf(M_GetText("Time limit will be %d minute%s next round.\n"), cv_timelimit.value,cv_timelimit.value == 1 ? "" : "s"); CONS_Printf(M_GetText("Time limit will be %d second%s next round.\n"), cv_timelimit.value,cv_timelimit.value == 1 ? "" : "s");
} }
} }
} }
@ -5739,6 +5748,15 @@ static void Got_Cheat(UINT8 **cp, INT32 playernum)
break; break;
} }
case CHEAT_SCORE: {
UINT32 score = READUINT32(*cp);
player->roundscore = score;
CV_CheaterWarning(targetPlayer, va("score = %u", score));
break;
}
case NUMBER_OF_CHEATS: case NUMBER_OF_CHEATS:
break; break;
} }
@ -6114,6 +6132,18 @@ static void Command_Automate_Set(void)
SendNetXCmd(XD_AUTOMATE, buf, buf_p - buf); SendNetXCmd(XD_AUTOMATE, buf, buf_p - buf);
} }
static void Command_Eval(void)
{
const char *args = COM_Args();
if (args)
{
const fixed_t n = LUA_EvalMath(args);
CONS_Printf("%f (%d)\n", FixedToFloat(n), n);
}
}
/** Makes a change to ::cv_forceskin take effect immediately. /** Makes a change to ::cv_forceskin take effect immediately.
* *
* \sa Command_SetForcedSkin_f, cv_forceskin, forcedskin * \sa Command_SetForcedSkin_f, cv_forceskin, forcedskin

View file

@ -1088,6 +1088,13 @@ static void G_DoAnglePrediction(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer, p
{ {
angle_t angleChange = 0; angle_t angleChange = 0;
// Chasecam stops in these situations, so local cam should stop too.
// Otherwise it'll jerk when it resumes.
if (player->playerstate == PST_DEAD)
return;
if (player->mo != NULL && !P_MobjWasRemoved(player->mo) && player->mo->hitlag > 0)
return;
while (realtics > 0) while (realtics > 0)
{ {
localsteering[ssplayer - 1] = K_UpdateSteeringValue(localsteering[ssplayer - 1], cmd->turning); localsteering[ssplayer - 1] = K_UpdateSteeringValue(localsteering[ssplayer - 1], cmd->turning);

View file

@ -11347,7 +11347,7 @@ tic_t K_TimeLimitForGametype(void)
if (cv_timelimit.value != -1) if (cv_timelimit.value != -1)
{ {
return cv_timelimit.value * (60*TICRATE); return cv_timelimit.value * TICRATE;
} }
// No time limit for Break the Capsules FREE PLAY // No time limit for Break the Capsules FREE PLAY

View file

@ -699,6 +699,10 @@ fixed_t LUA_EvalMath(const char *word)
lua_pushboolean(L, true); lua_pushboolean(L, true);
lua_call(L, 1, 0); lua_call(L, 1, 0);
lua_pushcfunction(L, LUA_MathLib);
lua_pushboolean(L, true);
lua_call(L, 1, 0);
// change ^ into ^^ for Lua. // change ^ into ^^ for Lua.
strcpy(buf, "return "); strcpy(buf, "return ");
b = buf+strlen(buf); b = buf+strlen(buf);

View file

@ -763,6 +763,14 @@ void Command_Setlives_f(void)
D_Cheat(consoleplayer, CHEAT_LIVES, atoi(COM_Argv(1))); D_Cheat(consoleplayer, CHEAT_LIVES, atoi(COM_Argv(1)));
} }
void Command_Setscore_f(void)
{
REQUIRE_CHEATS;
REQUIRE_INLEVEL;
D_Cheat(consoleplayer, CHEAT_SCORE, atoi(COM_Argv(1)));
}
void Command_Grayscale_f(void) void Command_Grayscale_f(void)
{ {
REQUIRE_CHEATS; REQUIRE_CHEATS;

View file

@ -35,6 +35,7 @@ typedef enum {
CHEAT_RELATIVE_TELEPORT, CHEAT_RELATIVE_TELEPORT,
CHEAT_DEVMODE, CHEAT_DEVMODE,
CHEAT_GIVEITEM, CHEAT_GIVEITEM,
CHEAT_SCORE,
NUMBER_OF_CHEATS NUMBER_OF_CHEATS
} cheat_t; } cheat_t;
@ -71,6 +72,7 @@ void Command_CheatGod_f(void);
void Command_Savecheckpoint_f(void); void Command_Savecheckpoint_f(void);
void Command_Setrings_f(void); void Command_Setrings_f(void);
void Command_Setlives_f(void); void Command_Setlives_f(void);
void Command_Setscore_f(void);
void Command_Devmode_f(void); void Command_Devmode_f(void);
void Command_Scale_f(void); void Command_Scale_f(void);
void Command_Gravflip_f(void); void Command_Gravflip_f(void);

View file

@ -1973,7 +1973,7 @@ static void K_HandleLapIncrement(player_t *player)
rainbowstartavailable = false; rainbowstartavailable = false;
} }
if (netgame && player->laps >= numlaps) if (netgame && player->laps > numlaps)
CON_LogMessage(va(M_GetText("%s has finished the race.\n"), player_names[player-players])); CON_LogMessage(va(M_GetText("%s has finished the race.\n"), player_names[player-players]));
player->starpostnum = 0; player->starpostnum = 0;

View file

@ -2117,6 +2117,78 @@ static void P_3dMovement(player_t *player)
} }
} }
// For turning correction in P_UpdatePlayerAngle.
// Given a range of possible steering inputs, finds a steering input that corresponds to the desired angle change.
static INT16 P_FindClosestTurningForAngle(player_t *player, INT32 targetAngle, INT16 lowBound, INT16 highBound)
{
INT16 newBound;
INT16 preferred = lowBound;
int attempts = 0;
// Only works if our low bound is actually our low bound.
if (highBound < lowBound)
{
INT16 tmp = lowBound;
lowBound = highBound;
highBound = tmp;
}
// Slightly frumpy binary search for the ideal turning input.
// We do this instead of reversing K_GetKartTurnValue so that future handling changes are automatically accounted for.
while (attempts++ < 20) // Practical calls of this function search maximum 10 times, this is solely for safety.
{
// These need to be treated as signed, or situations where boundaries straddle 0 are a mess.
INT32 lowAngle = K_GetKartTurnValue(player, lowBound) << TICCMD_REDUCE;
INT32 highAngle = K_GetKartTurnValue(player, highBound) << TICCMD_REDUCE;
// EXIT CONDITION 1: Hopeless search, target angle isn't between boundaries at all.
if (lowAngle >= targetAngle)
return lowBound;
if (highAngle <= targetAngle)
return highBound;
// Test the middle of our steering range, so we can see which side is more promising.
newBound = (lowBound + highBound) / 2;
// EXIT CONDITION 2: Boundaries converged and we're all out of precision.
if (newBound == lowBound || newBound == highBound)
break;
INT32 newAngle = K_GetKartTurnValue(player, newBound) << TICCMD_REDUCE;
angle_t lowError = abs(targetAngle - lowAngle);
angle_t highError = abs(targetAngle - highAngle);
angle_t newError = abs(targetAngle - newAngle);
// CONS_Printf("steering %d / %d / %d - angle %d / %d / %d - TA %d - error %d / %d / %d\n", lowBound, newBound, highBound, lowAngle, newAngle, highAngle, targetAngle, lowError, newError, highError);
// EXIT CONDITION 3: We got lucky!
if (lowError == 0)
return lowBound;
if (newError == 0)
return newBound;
if (highError == 0)
return highBound;
// If not, store the best estimate...
if (lowError <= newError && lowError <= highError)
preferred = lowBound;
if (highError <= newError && highError <= lowError)
preferred = highBound;
if (newError <= lowError && newError <= highError)
preferred = newBound;
// ....and adjust the bounds for another run.
if (lowAngle <= targetAngle && targetAngle <= newAngle)
highBound = newBound;
else
lowBound = newBound;
}
return preferred;
}
// //
// P_UpdatePlayerAngle // P_UpdatePlayerAngle
// //
@ -2153,6 +2225,13 @@ static void P_UpdatePlayerAngle(player_t *player)
angle_t targetAngle = (player->cmd.angle) << TICCMD_REDUCE; angle_t targetAngle = (player->cmd.angle) << TICCMD_REDUCE;
angle_t targetDelta = targetAngle - (player->mo->angle); angle_t targetDelta = targetAngle - (player->mo->angle);
// Corrections via fake turn go through easing.
// That means undoing them takes the same amount of time as doing them.
// This can lead to oscillating death spiral states on a multi-tic correction, as we swing past the target angle.
// So before we go into death-spirals, if our predicton is _almost_ right...
angle_t leniency = (2*ANG1/3) * min(player->cmd.latency, 6);
// Don't force another turning tic, just give them the desired angle!
if (targetDelta == angleChange || player->pflags & PF_DRIFTEND || (maxTurnRight == 0 && maxTurnLeft == 0)) if (targetDelta == angleChange || player->pflags & PF_DRIFTEND || (maxTurnRight == 0 && maxTurnLeft == 0))
{ {
// We are where we need to be. // We are where we need to be.
@ -2163,25 +2242,15 @@ static void P_UpdatePlayerAngle(player_t *player)
// so we momentarily ignore the camera angle and let the server trust our inputs instead. // so we momentarily ignore the camera angle and let the server trust our inputs instead.
// That way, even if you're steering blind, you get the intended "kick-out" effect. // That way, even if you're steering blind, you get the intended "kick-out" effect.
} }
else if (targetDelta >= ANGLE_180 && maxTurnLeft >= targetDelta) // Overshot, so just fudge it. else
{ {
angleChange = targetDelta; // We're off. Try to legally steer the player towards their camera.
player->steering = targetsteering; player->steering = P_FindClosestTurningForAngle(player, targetDelta, steeringLeft, steeringRight);
} angleChange = K_GetKartTurnValue(player, player->steering) << TICCMD_REDUCE;
else if (targetDelta <= ANGLE_180 && maxTurnRight <= targetDelta) // Overshot, so just fudge it.
{ // And if the resulting steering input is close enough, snap them exactly.
angleChange = targetDelta; if (min(targetDelta - angleChange, angleChange - targetDelta) <= leniency)
player->steering = targetsteering; angleChange = targetDelta;
}
else if (targetDelta >= ANGLE_180 && maxTurnLeft < targetDelta) // Undershot, slam the stick.
{
angleChange = maxTurnLeft;
player->steering = steeringLeft;
}
else if (targetDelta <= ANGLE_180 && maxTurnRight > targetDelta) // Undershot, slam the stick.
{
angleChange = maxTurnRight;
player->steering = steeringRight;
} }
} }
else else
@ -2218,6 +2287,7 @@ static void P_UpdatePlayerAngle(player_t *player)
} }
} }
// //
// P_SpectatorMovement // P_SpectatorMovement
// //

View file

@ -1065,6 +1065,25 @@ static void R_DrawVisSprite(vissprite_t *vis)
pwidth = patch->width; pwidth = patch->width;
#endif #endif
if (vis->x1test && vis->x2test)
{
INT32 x1test = vis->x1test;
INT32 x2test = vis->x2test;
if (x1test < 0)
x1test = 0;
if (x2test >= vid.width)
x2test = vid.width-1;
const INT32 t = (vis->startfrac + (vis->xiscale * (x2test - x1test))) >> FRACBITS;
if (x1test <= x2test && (t < 0 || t >= pwidth))
{
CONS_Printf("THE GAME WOULD HAVE CRASHED, %d (old) vs %d (new)\n", (x2test - x1test), (vis->x2 - vis->x1));
}
}
// Non-paper drawing loop // Non-paper drawing loop
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale, sprtopscreen += vis->shear.tan) for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale, sprtopscreen += vis->shear.tan)
{ {
@ -1452,6 +1471,9 @@ static void R_ProjectDropShadow(
shadow->x1 = x1 < portalclipstart ? portalclipstart : x1; shadow->x1 = x1 < portalclipstart ? portalclipstart : x1;
shadow->x2 = x2 >= portalclipend ? portalclipend-1 : x2; shadow->x2 = x2 >= portalclipend ? portalclipend-1 : x2;
shadow->x1test = 0;
shadow->x2test = 0;
shadow->xscale = FixedMul(xscale, shadowxscale); //SoM: 4/17/2000 shadow->xscale = FixedMul(xscale, shadowxscale); //SoM: 4/17/2000
shadow->scale = FixedMul(yscale, shadowyscale); shadow->scale = FixedMul(yscale, shadowyscale);
shadow->thingscale = interp.scale; shadow->thingscale = interp.scale;
@ -1598,6 +1620,9 @@ static void R_ProjectBoundingBox(mobj_t *thing, vissprite_t *vis)
box->sortscale = yscale; box->sortscale = yscale;
box->dispoffset = 0; box->dispoffset = 0;
} }
box->x1test = 0;
box->x2test = 0;
} }
// //
@ -1616,6 +1641,7 @@ static void R_ProjectSprite(mobj_t *thing)
fixed_t sort_x = 0, sort_y = 0, sort_z; fixed_t sort_x = 0, sort_y = 0, sort_z;
INT32 x1, x2; INT32 x1, x2;
INT32 x1test = 0, x2test = 0;
spritedef_t *sprdef; spritedef_t *sprdef;
spriteframe_t *sprframe; spriteframe_t *sprframe;
@ -2001,18 +2027,35 @@ static void R_ProjectSprite(mobj_t *thing)
scalestep = 0; scalestep = 0;
yscale = sortscale; yscale = sortscale;
tx += offset; tx += offset;
x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS; //x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS;
x1 = centerx + (FixedMul(tx,xscale) / FRACUNIT);
x1test = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS;
if (x1test > viewwidth)
x1test = 0;
// off the right side? // off the right side?
if (x1 > viewwidth) if (x1 > viewwidth)
return; return;
tx += offset2; tx += offset2;
x2 = ((centerxfrac + FixedMul(tx,xscale))>>FRACBITS); x2--; //x2 = ((centerxfrac + FixedMul(tx,xscale))>>FRACBITS); x2--;
x2 = (centerx + (FixedMul(tx,xscale) / FRACUNIT)) - 1;
x2test = ((centerxfrac + FixedMul(tx,xscale))>>FRACBITS) - 1;
if (x2test < 0)
x2test = 0;
// off the left side // off the left side
if (x2 < 0) if (x2 < 0)
return; return;
#if 0
if ((x2 - x1) != (x2test - x1test))
CONS_Printf("[%d] %d != %d\n", objectsdrawn, x2 - x1, x2test - x1test);
#endif
} }
// Adjust the sort scale if needed // Adjust the sort scale if needed
@ -2101,6 +2144,12 @@ static void R_ProjectSprite(mobj_t *thing)
if (x2 < portalclipstart || x1 >= portalclipend) if (x2 < portalclipstart || x1 >= portalclipend)
return; return;
if (x2test < portalclipstart || x1test >= portalclipend)
{
x1test = 0;
x2test = 0;
}
if (P_PointOnLineSide(interp.x, interp.y, portalclipline) != 0) if (P_PointOnLineSide(interp.x, interp.y, portalclipline) != 0)
return; return;
} }
@ -2269,6 +2318,9 @@ static void R_ProjectSprite(mobj_t *thing)
vis->x1 = x1 < portalclipstart ? portalclipstart : x1; vis->x1 = x1 < portalclipstart ? portalclipstart : x1;
vis->x2 = x2 >= portalclipend ? portalclipend-1 : x2; vis->x2 = x2 >= portalclipend ? portalclipend-1 : x2;
vis->x1test = x1test < portalclipstart ? portalclipstart : x1test;
vis->x2test = x2test >= portalclipend ? portalclipend-1 : x2test;
vis->sector = thing->subsector->sector; vis->sector = thing->subsector->sector;
vis->szt = (INT16)((centeryfrac - FixedMul(vis->gzt - viewz, sortscale))>>FRACBITS); vis->szt = (INT16)((centeryfrac - FixedMul(vis->gzt - viewz, sortscale))>>FRACBITS);
vis->sz = (INT16)((centeryfrac - FixedMul(vis->gz - viewz, sortscale))>>FRACBITS); vis->sz = (INT16)((centeryfrac - FixedMul(vis->gz - viewz, sortscale))>>FRACBITS);
@ -2290,6 +2342,12 @@ static void R_ProjectSprite(mobj_t *thing)
if (shadowdraw || shadoweffects) if (shadowdraw || shadoweffects)
{ {
if (x1test && x2test)
{
vis->xiscaletest = (patch->width<<FRACBITS)/(x2test-x1test+1); // fuck it
x1test += (x2test-x1test)/2; // reusing x1 variable
}
iscale = (patch->width<<FRACBITS)/(x2-x1+1); // fuck it iscale = (patch->width<<FRACBITS)/(x2-x1+1); // fuck it
x1 += (x2-x1)/2; // reusing x1 variable x1 += (x2-x1)/2; // reusing x1 variable
vis->shear.offset = vis->x1-x1; vis->shear.offset = vis->x1-x1;
@ -2303,6 +2361,7 @@ static void R_ProjectSprite(mobj_t *thing)
{ {
vis->startfrac = spr_width-1; vis->startfrac = spr_width-1;
vis->xiscale = -iscale; vis->xiscale = -iscale;
vis->xiscaletest = -vis->xiscaletest;
} }
else else
{ {
@ -2310,10 +2369,13 @@ static void R_ProjectSprite(mobj_t *thing)
vis->xiscale = iscale; vis->xiscale = iscale;
} }
vis->startfractest = vis->startfrac;
if (vis->x1 > x1) if (vis->x1 > x1)
{ {
vis->startfrac += FixedDiv(vis->xiscale, this_scale) * (vis->x1 - x1); vis->startfrac += FixedDiv(vis->xiscale, this_scale) * (vis->x1 - x1);
vis->scale += FixedMul(scalestep, spriteyscale) * (vis->x1 - x1); vis->scale += FixedMul(scalestep, spriteyscale) * (vis->x1 - x1);
vis->startfractest += FixedDiv(vis->xiscaletest, this_scale) * (vis->x1test - x1test);
} }
vis->transmap = R_GetBlendTable(blendmode, trans); vis->transmap = R_GetBlendTable(blendmode, trans);
@ -2525,6 +2587,9 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
vis->x1 = x1 < portalclipstart ? portalclipstart : x1; vis->x1 = x1 < portalclipstart ? portalclipstart : x1;
vis->x2 = x2 >= portalclipend ? portalclipend-1 : x2; vis->x2 = x2 >= portalclipend ? portalclipend-1 : x2;
vis->x1test = 0;
vis->x2test = 0;
vis->xscale = xscale; //SoM: 4/17/2000 vis->xscale = xscale; //SoM: 4/17/2000
vis->sector = thing->subsector->sector; vis->sector = thing->subsector->sector;
vis->szt = (INT16)((centeryfrac - FixedMul(vis->gzt - viewz, yscale))>>FRACBITS); vis->szt = (INT16)((centeryfrac - FixedMul(vis->gzt - viewz, yscale))>>FRACBITS);

View file

@ -161,6 +161,9 @@ struct vissprite_t
mobj_t *mobj; // for easy access mobj_t *mobj; // for easy access
INT32 x1, x2; INT32 x1, x2;
INT32 x1test, x2test;
fixed_t xiscaletest;
fixed_t startfractest;
fixed_t gx, gy; // for line side calculation fixed_t gx, gy; // for line side calculation
fixed_t gz, gzt; // global bottom/top for silhouette clipping and sorting with 3D floors fixed_t gz, gzt; // global bottom/top for silhouette clipping and sorting with 3D floors

View file

@ -237,7 +237,9 @@ void ST_Start(void)
ST_Stop(); ST_Stop();
ST_InitData(); ST_InitData();
st_stopped = false;
if (!dedicated)
st_stopped = false;
} }
// //