From b0b51f9a619534358e4606367a52319942877628 Mon Sep 17 00:00:00 2001
From: ZTsukei <ztsukei@gmail.com>
Date: Sun, 12 Feb 2017 23:24:49 -0500
Subject: [PATCH] Some position code

---
 src/command.c         |   3 +
 src/command.h         |   1 +
 src/d_main.c          |   6 +-
 src/d_netcmd.c        |   1 +
 src/d_netcmd.h        |   4 +-
 src/d_player.h        |   1 +
 src/doomdef.h         |   8 +-
 src/k_kart.c          | 259 ++++++++++++++++++++++++++++++++----------
 src/p_mobj.c          |   4 +
 src/p_user.c          |  36 +++++-
 src/sdl/i_main.c      |   4 +-
 src/sdl/i_video.c     |   8 +-
 src/sdl12/i_main.c    |   2 +-
 src/sdl12/i_video.c   |   6 +-
 src/sounds.h          |   5 +
 src/win32/win_dbg.c   |   2 +-
 src/win32/win_main.c  |   8 +-
 src/win32/win_sys.c   |   4 +-
 src/win32ce/win_dbg.c |   2 +-
 19 files changed, 274 insertions(+), 90 deletions(-)

diff --git a/src/command.c b/src/command.c
index a96ce0436..7094a137d 100644
--- a/src/command.c
+++ b/src/command.c
@@ -66,6 +66,9 @@ CV_PossibleValue_t CV_Natural[] = {{1, "MIN"}, {999999999, "MAX"}, {0, NULL}};
 CV_PossibleValue_t karthud_cons_t[] = {
 	{0, "Off"}, {1, "Default"}, {2, "SNES"}, {3, "MK64"}, 
 	{0, NULL}};
+CV_PossibleValue_t kartcc_cons_t[] = {
+	{50, "50cc"}, {100, "100cc"}, {150, "150cc"}, {200, "200cc"}, 
+	{0, NULL}};
 
 #define COM_BUF_SIZE 8192 // command buffer size
 
diff --git a/src/command.h b/src/command.h
index 74160d3c8..cd2ead991 100644
--- a/src/command.h
+++ b/src/command.h
@@ -128,6 +128,7 @@ extern CV_PossibleValue_t CV_Natural[];
 
 // SRB2kart
 extern CV_PossibleValue_t karthud_cons_t[];
+extern CV_PossibleValue_t kartcc_cons_t[];
 
 // register a variable for use at the console
 void CV_RegisterVar(consvar_t *variable);
diff --git a/src/d_main.c b/src/d_main.c
index 6023b906b..4e6b23d9b 100644
--- a/src/d_main.c
+++ b/src/d_main.c
@@ -946,8 +946,8 @@ void D_SRB2Main(void)
 	dedicated = M_CheckParm("-dedicated") != 0;
 #endif
 
-	strcpy(title, "Sonic Robo Blast 2");
-	strcpy(srb2, "Sonic Robo Blast 2");
+	strcpy(title, "SRB2Kart");
+	strcpy(srb2, "SRB2Kart");
 	D_MakeTitleString(srb2);
 
 #ifdef PC_DOS
@@ -957,7 +957,7 @@ void D_SRB2Main(void)
 #if defined (__OS2__) && !defined (HAVE_SDL)
 	// set PM window title
 	snprintf(pmData->title, sizeof (pmData->title),
-		"Sonic Robo Blast 2" VERSIONSTRING ": %s",
+		"SRB2Kart" VERSIONSTRING ": %s",
 		title);
 	pmData->title[sizeof (pmData->title) - 1] = '\0';
 #endif
diff --git a/src/d_netcmd.c b/src/d_netcmd.c
index e949358d2..8eca528ac 100644
--- a/src/d_netcmd.c
+++ b/src/d_netcmd.c
@@ -314,6 +314,7 @@ consvar_t cv_tripleredshell = 	{"tripleredshells", 	"On", CV_NETVAR|CV_CHEAT, CV
 consvar_t cv_lightning = 		{"lightning", 			"On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
 
 consvar_t cv_karthud = {"karthud", "Default", CV_SAVE|CV_CALL, karthud_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
+consvar_t cv_kartcc = {"kartcc", "100cc", CV_NETVAR, kartcc_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
 //
 
 consvar_t cv_ringslinger = {"ringslinger", "No", CV_NETVAR|CV_NOSHOWHELP|CV_CALL|CV_CHEAT, CV_YesNo,
diff --git a/src/d_netcmd.h b/src/d_netcmd.h
index 55865d9ee..df8776acb 100644
--- a/src/d_netcmd.h
+++ b/src/d_netcmd.h
@@ -103,8 +103,10 @@ extern consvar_t cv_magnet, cv_boo, cv_mushroom, cv_triplemushroom, cv_megashroo
 extern consvar_t cv_goldshroom, cv_star, cv_triplebanana, cv_fakeitem, cv_banana;
 extern consvar_t cv_greenshell, cv_redshell, cv_laserwisp, cv_triplegreenshell, cv_bobomb;
 extern consvar_t cv_blueshell, cv_jaws, cv_fireflower, cv_tripleredshell, cv_lightning;
-extern consvar_t cv_karthud;
 
+extern consvar_t cv_karthud;
+extern consvar_t cv_kartcc;
+//
 
 extern consvar_t cv_itemfinder;
 
diff --git a/src/d_player.h b/src/d_player.h
index d33947376..fc9865f5e 100644
--- a/src/d_player.h
+++ b/src/d_player.h
@@ -237,6 +237,7 @@ typedef enum
 	k_position,			// Used for Kart positions, mostly for deterministic stuff
 	k_playerahead,		// Is someone ahead of me or not?
 	k_oldposition,		// Used for taunting when you pass someone
+	k_positiondelay,	// Prevents player from taunting continuously if two people were neck-and-neck
 	k_prevcheck,		// Previous checkpoint distance; for p_user.c (was "pw_pcd")
 	k_nextcheck,		// Next checkpoint distance; for p_user.c (was "pw_ncd")
 	k_waypoint,			// Waypoints.
diff --git a/src/doomdef.h b/src/doomdef.h
index 06958eb88..a07fdb6cb 100644
--- a/src/doomdef.h
+++ b/src/doomdef.h
@@ -148,10 +148,10 @@ extern FILE *logstream;
 // most interface strings are ignored in development mode.
 // we use comprevision and compbranch instead.
 #else
-#define VERSION    201 // Game version
-#define SUBVERSION 15  // more precise version number
-#define VERSIONSTRING "v2.1.15"
-#define VERSIONSTRINGW L"v2.1.15"
+#define VERSION    100 // Game version
+#define SUBVERSION 0  // more precise version number
+#define VERSIONSTRING "v1.0.00"
+#define VERSIONSTRINGW L"v1.0.00"
 // Hey! If you change this, add 1 to the MODVERSION below!
 // Otherwise we can't force updates!
 #endif
diff --git a/src/k_kart.c b/src/k_kart.c
index c87b4cb07..8a4e974ff 100644
--- a/src/k_kart.c
+++ b/src/k_kart.c
@@ -290,6 +290,8 @@ void K_RegisterKartStuff(void)
 	CV_RegisterVar(&cv_fireflower);
 	CV_RegisterVar(&cv_tripleredshell);
 	CV_RegisterVar(&cv_lightning);
+
+	CV_RegisterVar(&cv_kartcc);
 }
 
 //}
@@ -889,6 +891,39 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd)
 
 //{ SRB2kart p_user.c Stuff
 
+/**	\brief	Updates the Player's offroad value once per frame
+
+	\param	player	player object passed from K_KartPlayerThink
+
+	\return	void
+*/
+void K_UpdateOffroad(player_t *player)
+{
+	fixed_t kartweight = player->kartweight;
+	sector_t *nextsector = R_PointInSubsector(
+		player->mo->x + player->mo->momx*2, player->mo->y + player->mo->momy*2)->sector;
+
+	// If you are offroad, a timer starts. Depending on your weight value, the timer increments differently.
+	if (nextsector->special & 256 && nextsector->special != 768 && (nextsector->special != 1024 || nextsector->special != 4864))
+	{
+		if (P_IsObjectOnGround(player->mo) && player->kartstuff[k_offroad] == 0)
+			player->kartstuff[k_offroad] = 16;
+		if (player->kartstuff[k_offroad] > 0)
+		{
+			if (kartweight < 1) kartweight = 1; if (kartweight > 9) kartweight = 9; // Safety Net
+
+			// 1872 is the magic number - 35 frames adds up to approximately 65536. 1872/4 = 468/3 = 156
+			// A higher kart weight means you can stay offroad for longer without losing speed
+			player->kartstuff[k_offroad] += (1872 + 5*156 - kartweight*156);
+		}
+
+		if (player->kartstuff[k_offroad] > FRACUNIT)
+			player->kartstuff[k_offroad] = FRACUNIT;
+	}
+	else
+		player->kartstuff[k_offroad] = 0;
+}
+
 /**	\brief	Decreases various kart timers and powers per frame. Called in P_PlayerThink in p_user.c
 
 	\param	player	player object passed from P_PlayerThink
@@ -898,6 +933,8 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd)
 */
 void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
 {
+	K_UpdateOffroad(player);
+
 	// This spawns the drift sparks when k_driftcharge hits 30. Its own AI handles life/death and color
 	if ((player->kartstuff[k_drift] >= 1 || player->kartstuff[k_drift] <= -1) 
 		&& player->kartstuff[k_driftcharge] == 30)
@@ -1033,6 +1070,62 @@ void K_PlayTauntSound(mobj_t *source)
 		S_StartSound(source, sfx_taunt4);
 }
 
+fixed_t K_GetKartBoostPower(player_t *player)
+{
+	fixed_t boostpower = FRACUNIT;
+
+	if (!(player->kartstuff[k_startimer] || player->kartstuff[k_bootaketimer] || player->kartstuff[k_mushroomtimer] || player->kartstuff[k_growshrinktimer] > 1) 
+		&& player->kartstuff[k_offroad] >= 0)
+			boostpower = FixedDiv(boostpower, player->kartstuff[k_offroad] + FRACUNIT);
+	if (player->kartstuff[k_growshrinktimer] < -1) 
+		boostpower = FixedMul(boostpower, 6*FRACUNIT/8);	// Shrink
+	if (player->kartstuff[k_squishedtimer] > 0) 
+		boostpower = FixedMul(boostpower, 7*FRACUNIT/8);	// Squished
+	if (player->powers[pw_sneakers]) 
+		boostpower = FixedMul(boostpower, 10*FRACUNIT/8);	// Slide Boost
+	if (player->kartstuff[k_growshrinktimer] > 1) 
+		boostpower = FixedMul(boostpower, 10*FRACUNIT/8);	// Mega Mushroom
+	if (player->kartstuff[k_startimer]) 
+		boostpower = FixedMul(boostpower, 11*FRACUNIT/8);	// Star
+	if (player->kartstuff[k_mushroomtimer]) 
+		boostpower = FixedMul(boostpower, 12*FRACUNIT/8);	// Mushroom
+
+	return boostpower;
+}
+fixed_t K_GetKartSpeed(player_t *player)
+{
+	fixed_t k_speed = 151;
+	fixed_t g_cc = (cv_kartcc.value/50 + 6)*FRACUNIT/8; // Game CC - 50cc = 0, 100cc = 1, etc.
+
+	k_speed += player->kartspeed; // 152 - 160
+
+	return FixedMul(FixedMul(k_speed<<14, g_cc), K_GetKartBoostPower(player));
+}
+fixed_t K_GetKartAccel(player_t *player)
+{
+	fixed_t k_accel = 36;
+
+	k_accel += 3 * (9 - player->kartspeed); // 36 - 60
+
+	return k_accel;
+}
+fixed_t K_3dKartMovement(player_t *player, boolean onground)
+{
+	if (!onground) return 0; // If the player isn't on the ground, there is no change in speed
+
+	fixed_t accelmax = 4000;
+	fixed_t newspeed, oldspeed, finalspeed;
+	fixed_t p_speed = K_GetKartSpeed(player);
+	fixed_t p_accel = K_GetKartAccel(player);
+
+	// ACCELCODE!!!1!11!
+	oldspeed = FixedMul(P_AproxDistance(player->rmomx, player->rmomy), player->mo->scale);
+	newspeed = FixedDiv(FixedDiv(FixedMul(oldspeed, accelmax - p_accel) + FixedMul(p_speed, p_accel), accelmax), ORIG_FRICTION);
+	finalspeed = newspeed - oldspeed;
+
+	return finalspeed;
+}
+
 void K_SpinPlayer(player_t *player, mobj_t *source)
 {
 	if (player->health <= 0)
@@ -1721,74 +1814,93 @@ void K_KartDrift(player_t *player, ticcmd_t *cmd, boolean onground)
 		player->kartstuff[k_driftcharge] = 0;
 	}
 }
-
-// Game CC - This will become a netgame variable, just here for testing now
-fixed_t g_cc = ((2) + 6)*FRACUNIT/8;
-
-fixed_t K_GetKartSpeed(player_t *player)
+//
+// K_KartUpdatePosition
+//
+static void K_KartUpdatePosition(player_t *player)
 {
-	fixed_t k_speed = 151;
+	fixed_t position = 1;
+	fixed_t i, ppcd, pncd, ipcd, incd;
+	fixed_t pmo, imo;
+	thinker_t *th;
+	mobj_t *mo;	
 
-	k_speed += player->kartspeed; // 152 - 160
+	for (i = 0; i < MAXPLAYERS; i++)
+	{
+		if (!playeringame[i] || players[i].spectator)	// If you don't exist, you aren't in the race.
+			continue;
 
-	return FixedMul(k_speed<<14, g_cc);
-}
+		if (((players[i].starpostnum) + (numstarposts + 1) * players[i].laps) > 
+			((player->starpostnum) + (numstarposts + 1) * player->laps))
+			position++;
 
-fixed_t K_GetKartAccel(player_t *player)
-{
-	fixed_t k_accel = 36;
+		ppcd = pncd = ipcd = incd = 0;
 
-	k_accel += 3 * (9 - player->kartspeed); // 36 - 60
+		player->kartstuff[k_prevcheck] = players[i].kartstuff[k_prevcheck] = 0;
+		player->kartstuff[k_nextcheck] = players[i].kartstuff[k_nextcheck] = 0;
+		
+		// This checks every thing on the map, and looks for MT_BOSS3WAYPOINT (the thing we're using for checkpoint wp's, for now)
+		for (th = thinkercap.next; th != &thinkercap; th = th->next) 
+		{
+			if (th->function.acp1 != (actionf_p1)P_MobjThinker)	// Not a mobj at all, shoo
+				continue;
 
-	return k_accel;
-}
+			mo = (mobj_t *)th;
 
-fixed_t K_3dKartMovement(player_t *player, boolean onground)
-{
-	// If the player isn't on the ground, there is no change in speed
-	if (!onground) return 0;
+			pmo = P_AproxDistance(P_AproxDistance(mo->x - player->mo->x, mo->y - player->mo->y), mo->z - player->mo->z) / FRACUNIT;
+			imo = P_AproxDistance(P_AproxDistance(mo->x - players[i].mo->x, mo->y - players[i].mo->y), mo->z - players[i].mo->z) / FRACUNIT;
 
-	fixed_t accelmax = 4000;					// AccelMax
-	fixed_t newspeed, oldspeed, finalspeed;
-	fixed_t boostpower = 1*FRACUNIT;
-	fixed_t p_speed = K_GetKartSpeed(player);
-	fixed_t p_accel = K_GetKartAccel(player);
+			if (mo->type != MT_BOSS3WAYPOINT)
+				continue;
 
-	sector_t *nextsector = R_PointInSubsector(player->mo->x + player->mo->momx*2, player->mo->y + player->mo->momy*2)->sector;
-
-	// Determine boostpower by checking every power. There's probably a cleaner way to do this, but eh whatever.
-	if (!(player->kartstuff[k_startimer] || player->kartstuff[k_bootaketimer] || player->powers[pw_sneakers] || 
-		  player->kartstuff[k_mushroomtimer] || player->kartstuff[k_growshrinktimer] > 1) && P_IsObjectOnGround(player->mo) &&
-		  nextsector->special & 256 && nextsector->special != 768 && (nextsector->special != 1024 || nextsector->special != 4864))
-													boostpower = FixedMul(boostpower, FRACUNIT/4);	// Off-road, unless you're ignoring off-road.
-	if (player->kartstuff[k_growshrinktimer] < -1) 	boostpower = FixedMul(boostpower, FRACUNIT/3);	// Shrink
-	if (player->kartstuff[k_squishedtimer] > 0) 	boostpower = FixedMul(boostpower, FRACUNIT/2);	// Squished
-	if (player->powers[pw_sneakers]) 				boostpower = FixedMul(boostpower, FRACUNIT+FRACUNIT/4);	// Slide Boost
-	if (player->kartstuff[k_growshrinktimer] > 1) 	boostpower = FixedMul(boostpower, FRACUNIT+FRACUNIT/3);	// Mega Mushroom
-	if (player->kartstuff[k_startimer]) 			boostpower = FixedMul(boostpower, FRACUNIT+FRACUNIT/2);	// Star
-	if (player->kartstuff[k_mushroomtimer]) 		boostpower = FixedMul(boostpower, FRACUNIT+FRACUNIT/1);	// Mushroom
-
-	// Boostpower is applied to each stat individually, and NOT the calculation.
-	// Applying to the calculation fails due to friction never getting beaten, or getting overshot really far.
-	// It's easier this way.
-	p_speed  = FixedMul(p_speed,  boostpower);
-	p_accel  = FixedMul(p_accel,  boostpower);
-	accelmax = FixedMul(accelmax, boostpower);
-
-	// Now, the code that made Iceman's eyes rub erotically against a toaster.
-	oldspeed = FixedMul(P_AproxDistance(player->rmomx, player->rmomy), player->mo->scale);
-	newspeed = FixedDiv(FixedDiv(FixedMul(oldspeed, accelmax - p_accel) + FixedMul(p_speed, p_accel), accelmax), ORIG_FRICTION);
-	finalspeed = newspeed - oldspeed;
+			if (mo->health == player->starpostnum)
+			{
+				player->kartstuff[k_prevcheck] += pmo;
+				ppcd++;
+			}
+			if (mo->health == (player->starpostnum + 1))
+			{
+				player->kartstuff[k_nextcheck] += pmo;
+				pncd++;
+			}
+			if (mo->health == players[i].starpostnum)
+			{
+				players[i].kartstuff[k_prevcheck] += imo;
+				ipcd++;
+			}
+			if (mo->health == (players[i].starpostnum + 1))
+			{
+				players[i].kartstuff[k_nextcheck] += imo;
+				incd++;
+			}
+		}
 
-	CONS_Printf("Game CC    = %d\n", g_cc);
-	CONS_Printf("finalspeed = %d\n", finalspeed);
-	
-	// 245498
-	// 498024
+		if (ppcd > 1) player->kartstuff[k_prevcheck] /= ppcd;
+		if (pncd > 1) player->kartstuff[k_nextcheck] /= pncd;
+		if (ipcd > 1) players[i].kartstuff[k_prevcheck] /= ipcd;
+		if (incd > 1) players[i].kartstuff[k_nextcheck] /= incd;
 
-	return finalspeed;
+		if ((players[i].kartstuff[k_nextcheck] > 0 || player->kartstuff[k_nextcheck] > 0) && !player->exiting)
+		{
+			if ((players[i].kartstuff[k_nextcheck] - players[i].kartstuff[k_prevcheck]) < (player->kartstuff[k_nextcheck] - player->kartstuff[k_prevcheck]))
+				position++;
+		}
+		else if (!player->exiting)
+		{
+			if (players[i].kartstuff[k_prevcheck] > player->kartstuff[k_prevcheck])
+				position++;
+		}
+		else
+		{
+			if (players[i].starposttime < player->starposttime)
+				position++;
+		}
+	}
+	player->kartstuff[k_position] = position;
 }
-
+//
+// K_MoveKartPlayer
+//
 void K_MoveKartPlayer(player_t *player, ticcmd_t *cmd, boolean onground)
 {
 	boolean ATTACK_IS_DOWN = ((cmd->buttons & BT_ATTACK) && !(player->pflags & PF_ATTACKDOWN));
@@ -1799,6 +1911,32 @@ void K_MoveKartPlayer(player_t *player, ticcmd_t *cmd, boolean onground)
 		|| player->kartstuff[k_triplebanana] & 1 || player->kartstuff[k_triplebanana] & 2 || player->kartstuff[k_triplebanana] & 4);
 	boolean NO_BOO = (player->kartstuff[k_boostolentimer] == 0 && player->kartstuff[k_bootaketimer] == 0);
 
+	K_KartUpdatePosition(player);
+
+	// Position Taunt
+	// If you were behind someone but just passed them, taunt at them!
+	if (!player->kartstuff[k_positiondelay] && !player->exiting)
+	{
+		if (player->kartstuff[k_oldposition] <= player->kartstuff[k_position]) // But first, if you lost a place,
+			player->kartstuff[k_oldposition] = player->kartstuff[k_position]; // then the other player taunts.
+		else if (player->kartstuff[k_oldposition] > player->kartstuff[k_position]) // Otherwise,
+		{
+			//S_StartSound(player->mo, sfx_slow); // Say "YOU'RE TOO SLOW!"
+			player->kartstuff[k_oldposition] = player->kartstuff[k_position]; // Restore the old position,
+			player->kartstuff[k_positiondelay] = 5*TICRATE; // and set up a timer.
+		}
+	}
+	if (player->kartstuff[k_positiondelay])
+		player->kartstuff[k_positiondelay]--;
+
+	// Race Spectator
+	if (netgame && player->jointime < 1
+	&& gametype == GT_RACE && countdown)
+	{
+		player->spectator = true;
+		player->powers[pw_nocontrol] = 5;
+	}
+
 	if ((player->pflags & PF_ATTACKDOWN) && !(cmd->buttons & BT_ATTACK))
 		player->pflags &= ~PF_ATTACKDOWN;
 	else if (cmd->buttons & BT_ATTACK)
@@ -2925,7 +3063,7 @@ static void K_drawKartNeoItem(void)
 }
 */
 
-static void K_drawKartTripleItem(void)
+static void K_DrawKartTripleItem(void)
 {
 	// TRIP_X = 143;				// 143
 	// TRIP_Y = BASEVIDHEIGHT-34;	// 166
@@ -3155,7 +3293,7 @@ static void K_DrawKartPositionFaces(void)
 				V_DrawSmallMappedPatch(FACE_X, Y, 0, faceprefix[players[rankplayer[i]].skin], colormap);
 		}
 		// Draws the little number over the face
-		switch (ranklines)
+		switch (players[rankplayer[i]].kartstuff[k_position])
 		{
 			case 1: localpatch = kp_facefirst; break;
 			case 2: localpatch = kp_facesecond; break;
@@ -3193,7 +3331,7 @@ void K_drawKartHUD(void)
 	// Draw the little triple-item icons at the bottom
 	if (!splitscreen)
 	{
-		K_drawKartTripleItem();
+		K_DrawKartTripleItem();
 		K_DrawKartPositionFaces();
 	}
 	
@@ -3208,8 +3346,7 @@ void K_drawKartHUD(void)
 		V_DrawKartString(LAPS_X+33, STRINGY(LAPS_Y+3), 0, va("%d/%d", stplyr->laps+1, cv_numlaps.value));
 	
 	// Draw the numerical position
-	K_DrawKartPositionNum(stplyr->kartstuff[k_spinout]);
-	//K_DrawKartPositionNum(stplyr->kartstuff[k_position]);
+	K_DrawKartPositionNum(stplyr->kartstuff[k_position]);
 	
 	// Plays the music after the starting countdown. This is here since it checks every frame regularly.
 	if (leveltime > 157 && leveltime < (TICRATE+1)*7)
diff --git a/src/p_mobj.c b/src/p_mobj.c
index 66adc5741..0a2e3208a 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -9466,6 +9466,10 @@ ML_NOCLIMB : Direction not controllable
 		if (!foundanother)
 			numstarposts++;
 	}
+	else if (i == MT_BOSS3WAYPOINT) // SRB2kart 120217 - Used to store checkpoint num
+	{
+		mobj->health = mthing->angle;
+	}
 	else if (i == MT_SPIKE)
 	{
 		// Pop up spikes!
diff --git a/src/p_user.c b/src/p_user.c
index d72c632a3..175ae00d1 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -1581,12 +1581,42 @@ void P_DoPlayerExit(player_t *player)
 		return;
 	else if (gametype == GT_RACE || gametype == GT_COMPETITION) // If in Race Mode, allow
 	{
-		if (!countdown) // a 60-second wait ala Sonic 2.
+		// SRB2kart 120217
+		if (!countdown && !(netgame || multiplayer))
+			countdown = 60*TICRATE + 1; // 60 seconds to finish, get going!
+		else if (!countdown)
 			countdown = cv_countdowntime.value*TICRATE + 1; // Use cv_countdowntime
 
+/*
+		if (circuitmap)
+		{
+			if (player->kartstuff[k_position] <= 3)
+				S_StartSound(player->mo, sfx_kwin);
+			else
+				S_StartSound(player->mo, sfx_klose);
+		}*/
+
+		if (P_IsLocalPlayer(player) && cv_inttime.value > 0)
+		{
+			if (!splitscreen)
+			{
+				if (player->kartstuff[k_position] == 1)
+					S_ChangeMusicInternal("karwin", true);
+				else if (player->kartstuff[k_position] == 2 || player->kartstuff[k_position] == 3)
+					S_ChangeMusicInternal("karok", true);
+				else if (player->kartstuff[k_position] >= 4)
+					S_ChangeMusicInternal("karlos", true);
+			}
+			else
+				S_ChangeMusicInternal("karwin", true);
+		}
+
 		player->exiting = 3*TICRATE;
 
-		if (!countdown2)
+		// SRB2kart 120217
+		if (!countdown2 && !(netgame || multiplayer))
+			countdown2 = (66)*TICRATE + 1; // 6 seconds past the time over
+		else if (!countdown2)
 			countdown2 = (8 + cv_countdowntime.value)*TICRATE + 1; // 8 sec more than countdowntime -- 11 is too much
 
 		if (P_CheckRacers())
@@ -4819,7 +4849,7 @@ static void P_3dMovement(player_t *player)
 			movepushside >>= 2;
 
 			// Reduce movepushslide even more if over "max" flight speed
-			if (player->powers[pw_tailsfly] && player->speed > topspeed)
+			if (player->powers[pw_tailsfly] && player->speed > K_GetKartSpeed(player)) //topspeed)
 				movepushside >>= 2;
 		}
 
diff --git a/src/sdl/i_main.c b/src/sdl/i_main.c
index 25fccb9f9..d299a867c 100644
--- a/src/sdl/i_main.c
+++ b/src/sdl/i_main.c
@@ -44,7 +44,7 @@ static char netmask[16] = {0};
 #include <pspthreadman.h>
 PSP_HEAP_SIZE_KB(24*1024);
 PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER | PSP_THREAD_ATTR_VFPU);
-PSP_MAIN_THREAD_NAME("SRB2");
+PSP_MAIN_THREAD_NAME("SRB2Kart");
 PSP_MAIN_THREAD_STACK_SIZE_KB(256);
 #endif
 
@@ -233,7 +233,7 @@ int main(int argc, char **argv)
 #endif
 #endif
 	// startup SRB2
-	CONS_Printf("Setting up SRB2...\n");
+	CONS_Printf("Setting up SRB2Kart...\n");
 	D_SRB2Main();
 	CONS_Printf("Entering main game loop...\n");
 	// never return
diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c
index b5168dad5..6caec1ef1 100644
--- a/src/sdl/i_video.c
+++ b/src/sdl/i_video.c
@@ -1529,7 +1529,7 @@ INT32 VID_SetMode(INT32 modeNum)
 		}
 		vid.modenum = -1;
 	}
-	Impl_SetWindowName("SRB2 "VERSIONSTRING);
+	Impl_SetWindowName("SRB2Kart "VERSIONSTRING);
 
 	SDLSetMode(windowedModes[modeNum][0], windowedModes[modeNum][1], USE_FULLSCREEN);
 
@@ -1568,7 +1568,7 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen)
 #ifdef HWRENDER
 	if (rendermode == render_opengl)
 	{
-		window = SDL_CreateWindow("SRB2 "VERSIONSTRING, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
+		window = SDL_CreateWindow("SRB2Kart "VERSIONSTRING, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
 				realwidth, realheight, flags | SDL_WINDOW_OPENGL);
 		if (window != NULL)
 		{
@@ -1588,7 +1588,7 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen)
 #endif
 	if (rendermode == render_soft)
 	{
-		window = SDL_CreateWindow("SRB2 "VERSIONSTRING, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
+		window = SDL_CreateWindow("SRB2Kart "VERSIONSTRING, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
 				realwidth, realheight, flags);
 		if (window != NULL)
 		{
@@ -1766,7 +1766,7 @@ void I_StartupGraphics(void)
 
 	// Create window
 	//Impl_CreateWindow(USE_FULLSCREEN);
-	//Impl_SetWindowName("SRB2 "VERSIONSTRING);
+	//Impl_SetWindowName("SRB2Kart "VERSIONSTRING);
 	VID_SetMode(VID_GetModeForSize(BASEVIDWIDTH, BASEVIDHEIGHT));
 
 	vid.width = BASEVIDWIDTH; // Default size for startup
diff --git a/src/sdl12/i_main.c b/src/sdl12/i_main.c
index 1c438e083..adcaae2fd 100644
--- a/src/sdl12/i_main.c
+++ b/src/sdl12/i_main.c
@@ -44,7 +44,7 @@ static char netmask[16] = {0};
 #include <pspthreadman.h>
 PSP_HEAP_SIZE_KB(24*1024);
 PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER | PSP_THREAD_ATTR_VFPU);
-PSP_MAIN_THREAD_NAME("SRB2");
+PSP_MAIN_THREAD_NAME("SRB2Kart");
 PSP_MAIN_THREAD_STACK_SIZE_KB(256);
 #endif
 
diff --git a/src/sdl12/i_video.c b/src/sdl12/i_video.c
index 197924eda..8754587af 100644
--- a/src/sdl12/i_video.c
+++ b/src/sdl12/i_video.c
@@ -1745,7 +1745,7 @@ INT32 VID_SetMode(INT32 modeNum)
 	BitsPerPixel = (Uint8)cv_scr_depth.value;
 	//vid.bpp = BitsPerPixel==8?1:2;
 	// Window title
-	SDL_WM_SetCaption("SRB2 "VERSIONSTRING, "SRB2");
+	SDL_WM_SetCaption("SRB2Kart "VERSIONSTRING, "SRB2Kart");
 
 	if (render_soft == rendermode)
 	{
@@ -1933,9 +1933,9 @@ void I_StartupGraphics(void)
 
 	// Window title
 #ifdef _WIN32_WCE
-	SDL_WM_SetCaption("SRB2 "VERSIONSTRING, "SRB2");
+	SDL_WM_SetCaption("SRB2Kart "VERSIONSTRING, "SRB2Kart");
 #else
-	SDL_WM_SetCaption("SRB2: Starting up", "SRB2");
+	SDL_WM_SetCaption("SRB2Kart: Starting up", "SRB2Kart");
 #endif
 
 	// Window icon
diff --git a/src/sounds.h b/src/sounds.h
index 4c49a0f53..3ba30bce6 100644
--- a/src/sounds.h
+++ b/src/sounds.h
@@ -529,6 +529,7 @@ typedef enum
 	sfx_s3kdbs,
 	sfx_s3kdbl,
 
+	// SRB2kart
 	sfx_lkt1,
 	sfx_lkt2,
 	sfx_lkt3,
@@ -559,6 +560,10 @@ typedef enum
 	sfx_mkitm7,
 	sfx_mkitm8,
 	sfx_mkitmF,
+	sfx_kwin,
+	sfx_klose,
+	sfx_slow,
+	//
 
 	sfx_taunt1,
 	sfx_taunt2,
diff --git a/src/win32/win_dbg.c b/src/win32/win_dbg.c
index 23416af1b..4cc063bfc 100644
--- a/src/win32/win_dbg.c
+++ b/src/win32/win_dbg.c
@@ -452,7 +452,7 @@ LONG WINAPI RecordExceptionInfo(PEXCEPTION_POINTERS data/*, LPCSTR Message, LPST
 	FPrintf(fileHandle, "Email Sonic Team Junior so we can fix the bugs\r\n"); // Tails
 	FPrintf(fileHandle, "Make sure you tell us what you were doing to cause the crash, and if possible, record a demo!\r\n"); // Tails
 	FPrintf(fileHandle, "\r\n\r\n\r\n\r\n");
-	FPrintf(fileHandle, "SRB2 %s -ERROR LOG-\r\n\r\n", VERSIONSTRING);
+	FPrintf(fileHandle, "SRB2Kart %s -ERROR LOG-\r\n\r\n", VERSIONSTRING);
 	FPrintf(fileHandle, "\r\n");
 	// VirtualQuery can be used to get the allocation base associated with a
 	// code address, which is the same as the ModuleHandle. This can be used
diff --git a/src/win32/win_main.c b/src/win32/win_main.c
index 663eddbd4..eed276e50 100644
--- a/src/win32/win_main.c
+++ b/src/win32/win_main.c
@@ -325,8 +325,8 @@ static inline VOID OpenTextConsole(VOID)
 	{
 		if (AllocConsole()) //Let get the real console HANDLEs, because Mingw's Bash is bad!
 		{
-			SetConsoleTitleA("SRB2 Console");
-			CONS_Printf(M_GetText("Hello, it's me, SRB2's Console Window\n"));
+			SetConsoleTitleA("SRB2Kart Console");
+			CONS_Printf(M_GetText("Hello, it's me, SRB2Kart's Console Window\n"));
 		}
 		else
 		{
@@ -612,7 +612,7 @@ static int WINAPI HandledWinMain(HINSTANCE hInstance)
 #endif
 
 	// open a dummy window, both OpenGL and DirectX need one.
-	if ((hWndMain = OpenMainWindow(hInstance, va("SRB2 "VERSIONSTRING))) == INVALID_HANDLE_VALUE)
+	if ((hWndMain = OpenMainWindow(hInstance, va("SRB2Kart "VERSIONSTRING))) == INVALID_HANDLE_VALUE)
 	{
 		tlErrorMessage(TEXT("Couldn't open window"));
 		return FALSE;
@@ -624,7 +624,7 @@ static int WINAPI HandledWinMain(HINSTANCE hInstance)
 	MakeCodeWritable();
 
 	// startup SRB2
-	CONS_Printf("Setting up SRB2...\n");
+	CONS_Printf("Setting up SRB2Kart...\n");
 	D_SRB2Main();
 	CONS_Printf("Entering main game loop...\n");
 	// never return
diff --git a/src/win32/win_sys.c b/src/win32/win_sys.c
index 0331080c8..f43625ed0 100644
--- a/src/win32/win_sys.c
+++ b/src/win32/win_sys.c
@@ -3077,8 +3077,8 @@ void I_UpdateMumble(const mobj_t *mobj, const listener_t listener)
 		return;
 
 	if(mumble->uiVersion != 2) {
-		wcsncpy(mumble->name, L"SRB2 "VERSIONSTRINGW, 256);
-		wcsncpy(mumble->description, L"Sonic Robo Blast 2 with integrated Mumble Link support.", 2048);
+		wcsncpy(mumble->name, L"SRB2Kart "VERSIONSTRINGW, 256);
+		wcsncpy(mumble->description, L"SRB2Kart with integrated Mumble Link support.", 2048);
 		mumble->uiVersion = 2;
 	}
 	mumble->uiTick++;
diff --git a/src/win32ce/win_dbg.c b/src/win32ce/win_dbg.c
index 9cfe77636..45b2fc322 100644
--- a/src/win32ce/win_dbg.c
+++ b/src/win32ce/win_dbg.c
@@ -357,7 +357,7 @@ int __cdecl RecordExceptionInfo (PEXCEPTION_POINTERS data/*, LPCSTR Message, LPS
 	FPrintf (fileHandle, "Email Sonic Team Junior so we can fix the bugs\r\n"); // Tails
 	FPrintf (fileHandle, "Make sure you tell us what you were doing to cause the crash, and if possible, record a demo!\r\n"); // Tails
 	FPrintf (fileHandle, "\r\n\r\n\r\n\r\n");
-	FPrintf (fileHandle, "SRB2 %s -ERROR LOG-\r\n\r\n", VERSIONSTRING);
+	FPrintf (fileHandle, "SRB2Kart %s -ERROR LOG-\r\n\r\n", VERSIONSTRING);
 	FPrintf (fileHandle, "\r\n");
 	// VirtualQuery can be used to get the allocation base associated with a
 	// code address, which is the same as the ModuleHandle. This can be used
-- 
GitLab