From 0b22e8eb003c320e9f555c98f18ace8073b8a03d Mon Sep 17 00:00:00 2001
From: Sally Coolatta <tehrealsalt@gmail.com>
Date: Wed, 22 Nov 2023 18:50:13 -0500
Subject: [PATCH] Fix visuals on roulette latency compensation

- Latency is based on D0 instead of D2.
- Confirm offset is now adjusted for latency, so it should feel more correct when stopping it.
- Slot machine offset is properly set up to use the slot machine offset instead of the item roulette offset.
---
 src/k_hud.c      |  4 ++--
 src/k_roulette.c | 38 +++++++++++++++++++++++++++-----------
 src/k_roulette.h | 11 +++++++----
 3 files changed, 36 insertions(+), 17 deletions(-)

diff --git a/src/k_hud.c b/src/k_hud.c
index 15c2f02313..cc6b05bb35 100644
--- a/src/k_hud.c
+++ b/src/k_hud.c
@@ -1358,7 +1358,7 @@ static void K_drawKartItem(void)
 
 	if (stplyr->itemRoulette.active == true)
 	{
-		rouletteOffset = K_GetRouletteOffset(&stplyr->itemRoulette, rendertimefrac);
+		rouletteOffset = K_GetRouletteOffset(&stplyr->itemRoulette, rendertimefrac, 0);
 	}
 	else
 	{
@@ -1712,7 +1712,7 @@ static void K_drawKartSlotMachine(void)
 
 	if (stplyr->itemRoulette.active == true)
 	{
-		rouletteOffset = K_GetSlotOffset(&stplyr->itemRoulette, rendertimefrac);
+		rouletteOffset = K_GetSlotOffset(&stplyr->itemRoulette, rendertimefrac, 0);
 	}
 	else
 	{
diff --git a/src/k_roulette.c b/src/k_roulette.c
index faa6f0e921..b66754c258 100644
--- a/src/k_roulette.c
+++ b/src/k_roulette.c
@@ -1513,16 +1513,23 @@ void K_StopRoulette(itemroulette_t *const roulette)
 }
 
 /*--------------------------------------------------
-	fixed_t K_GetRouletteOffset(itemroulette_t *const roulette, fixed_t renderDelta)
+	fixed_t K_GetRouletteOffset(itemroulette_t *const roulette, fixed_t renderDelta, UINT8 fudge)
 
 		See header file for description.
 --------------------------------------------------*/
-fixed_t K_GetRouletteOffset(itemroulette_t *const roulette, fixed_t renderDelta)
+fixed_t K_GetRouletteOffset(itemroulette_t *const roulette, fixed_t renderDelta, UINT8 fudge)
 {
 	const fixed_t curTic = (roulette->tics << FRACBITS) - renderDelta;
 	const fixed_t midTic = roulette->speed * (FRACUNIT >> 1);
 
-	return FixedMul(FixedDiv(midTic - curTic, ((roulette->speed + 1) << FRACBITS)), ROULETTE_SPACING);
+	fixed_t result = FixedMul(FixedDiv(midTic - curTic, ((roulette->speed + 1) << FRACBITS)), ROULETTE_SPACING);
+
+	if (fudge > 0)
+	{
+		result += (roulette->speed + 1) * fudge;
+	}
+
+	return result;
 }
 
 /*--------------------------------------------------
@@ -1530,12 +1537,19 @@ fixed_t K_GetRouletteOffset(itemroulette_t *const roulette, fixed_t renderDelta)
 
 		See header file for description.
 --------------------------------------------------*/
-fixed_t K_GetSlotOffset(itemroulette_t *const roulette, fixed_t renderDelta)
+fixed_t K_GetSlotOffset(itemroulette_t *const roulette, fixed_t renderDelta, UINT8 fudge)
 {
 	const fixed_t curTic = (roulette->tics << FRACBITS) - renderDelta;
 	const fixed_t midTic = roulette->speed * (FRACUNIT >> 1);
 
-	return FixedMul(FixedDiv(midTic - curTic, ((roulette->speed + 1) << FRACBITS)), SLOT_SPACING);
+	fixed_t result = FixedMul(FixedDiv(midTic - curTic, ((roulette->speed + 1) << FRACBITS)), SLOT_SPACING);
+
+	if (fudge > 0)
+	{
+		result += (roulette->speed + 1) * fudge;
+	}
+
+	return result;
 }
 
 /*--------------------------------------------------
@@ -1631,7 +1645,7 @@ void K_KartItemRoulette(player_t *const player, ticcmd_t *const cmd)
 
 			//player->karthud[khud_itemblink] = TICRATE;
 			//player->karthud[khud_itemblinkmode] = 1;
-			//player->karthud[khud_rouletteoffset] = K_GetRouletteOffset(roulette, FRACUNIT);
+			//player->karthud[khud_rouletteoffset] = K_GetRouletteOffset(roulette, FRACUNIT, 0);
 
 			if (K_IsPlayingDisplayPlayer(player))
 			{
@@ -1640,12 +1654,13 @@ void K_KartItemRoulette(player_t *const player, ticcmd_t *const cmd)
 		}
 		else
 		{
-			// D2 fudge factor. Roulette was originally designed and tested with this delay.
-			UINT8 fudgedDelay = (player->cmd.latency <= 2) ? 0 : player->cmd.latency - 2;
-
+			UINT8 baseFudge = player->cmd.latency; // max(0, player->cmd.latency - 2);
 			if (roulette->autoroulette)
-				fudgedDelay = 0; // We didn't manually stop this, you jackwagon
+			{
+				baseFudge = 0; // We didn't manually stop this, you jackwagon
+			}
 
+			UINT8 fudgedDelay = baseFudge;
 			while (fudgedDelay > 0)
 			{
 				UINT8 gap = (roulette->speed - roulette->tics); // How long has the roulette been on this entry?
@@ -1670,15 +1685,16 @@ void K_KartItemRoulette(player_t *const player, ticcmd_t *const cmd)
 			{
 				player->ringboxdelay = TICRATE;
 				player->ringboxaward = finalItem;
+				player->karthud[khud_rouletteoffset] = K_GetSlotOffset(roulette, FRACUNIT, baseFudge);
 			}
 			else
 			{
 				K_KartGetItemResult(player, finalItem);
+				player->karthud[khud_rouletteoffset] = K_GetRouletteOffset(roulette, FRACUNIT, baseFudge);
 			}
 
 			player->karthud[khud_itemblink] = TICRATE;
 			player->karthud[khud_itemblinkmode] = 0;
-			player->karthud[khud_rouletteoffset] = K_GetRouletteOffset(roulette, FRACUNIT);
 
 			if (K_IsPlayingDisplayPlayer(player))
 			{
diff --git a/src/k_roulette.h b/src/k_roulette.h
index 7c1eb6c803..9eba345d4d 100644
--- a/src/k_roulette.h
+++ b/src/k_roulette.h
@@ -173,7 +173,7 @@ void K_StopRoulette(itemroulette_t *const roulette);
 
 
 /*--------------------------------------------------
-	fixed_t K_GetRouletteOffset(itemroulette_t *const roulette, fixed_t renderDelta);
+	fixed_t K_GetRouletteOffset(itemroulette_t *const roulette, fixed_t renderDelta, UINT8 fudge);
 
 		Gets the Y offset, for use in the roulette HUD.
 		A separate function since it is used both by the
@@ -182,15 +182,17 @@ void K_StopRoulette(itemroulette_t *const roulette);
 	Input Arguments:-
 		roulette - The roulette we are drawing for.
 		renderDelta - Fractional tic delta, when used for HUD.
+		fudge - Input latency fudge factor, when used for gameplay.
 
 	Return:-
 		The Y offset when drawing the item.
 --------------------------------------------------*/
 
-fixed_t K_GetRouletteOffset(itemroulette_t *const roulette, fixed_t renderDelta);
+fixed_t K_GetRouletteOffset(itemroulette_t *const roulette, fixed_t renderDelta, UINT8 fudge);
+
 
 /*--------------------------------------------------
-	fixed_t K_GetSlotOffset(itemroulette_t *const roulette, fixed_t renderDelta);
+	fixed_t K_GetSlotOffset(itemroulette_t *const roulette, fixed_t renderDelta, UINT8 fudge);
 
 		Gets the Y offset, for use in the slot HUD.
 		A separate function since it is used both by the
@@ -199,12 +201,13 @@ fixed_t K_GetRouletteOffset(itemroulette_t *const roulette, fixed_t renderDelta)
 	Input Arguments:-
 		roulette - The roulette we are drawing for.
 		renderDelta - Fractional tic delta, when used for HUD.
+		fudge - Input latency fudge factor, when used for gameplay.
 
 	Return:-
 		The Y offset when drawing the item.
 --------------------------------------------------*/
 
-fixed_t K_GetSlotOffset(itemroulette_t *const roulette, fixed_t renderDelta);
+fixed_t K_GetSlotOffset(itemroulette_t *const roulette, fixed_t renderDelta, UINT8 fudge);
 
 
 /*--------------------------------------------------
-- 
GitLab