diff --git a/source/core/binaryangle.h b/source/core/binaryangle.h
index 198abc6d7..acf5b82f2 100644
--- a/source/core/binaryangle.h
+++ b/source/core/binaryangle.h
@@ -398,6 +398,7 @@ class fixedhoriz
 	
 	friend constexpr fixedhoriz q16horiz(fixed_t v);
 	friend constexpr fixedhoriz buildhoriz(int v);
+	friend constexpr fixedhoriz buildfhoriz(double v);
 	friend fixedhoriz pitchhoriz(double v);
 	friend fixedhoriz bamhoriz(int32_t v);
 
@@ -496,6 +497,7 @@ public:
 
 inline constexpr fixedhoriz q16horiz(fixed_t v) { return fixedhoriz(v); }
 inline constexpr fixedhoriz buildhoriz(int v) { return fixedhoriz(IntToFixed(v)); }
+inline constexpr fixedhoriz buildfhoriz(double v) { return fixedhoriz(FloatToFixed(v)); }
 inline fixedhoriz pitchhoriz(double v) { return fixedhoriz(PitchToHoriz(v)); }
 inline fixedhoriz bamhoriz(int32_t v) { return pitchhoriz(BAMToPitch(v)); }
 
diff --git a/source/core/gameinput.h b/source/core/gameinput.h
index 03c41067b..652cac326 100644
--- a/source/core/gameinput.h
+++ b/source/core/gameinput.h
@@ -12,8 +12,8 @@ lookangle getincanglebam(binangle a, binangle na);
 
 struct PlayerHorizon
 {
-	fixedhoriz horiz, ohoriz, horizoff, ohorizoff;
-	double adjustment, target;
+	fixedhoriz horiz, ohoriz, horizoff, ohorizoff, target;
+	double adjustment;
 
 	void backup()
 	{
@@ -44,30 +44,58 @@ struct PlayerHorizon
 		adjustment = 0;
 	}
 
+	void settarget(int value, bool backup = false)
+	{
+		if (!SyncInput() && !backup)
+		{
+			target = buildhoriz(value);
+			if (target.asq16() == 0) target = q16horiz(1);
+		}
+		else
+		{
+			horiz = buildhoriz(value);
+			if (backup) ohoriz = horiz;
+		}
+	}
+
 	void settarget(double value, bool backup = false)
 	{
 		if (!SyncInput() && !backup)
 		{
-			target = value * FRACUNIT;
-			if (target == 0) target += 1;
+			target = buildfhoriz(value);
+			if (target.asq16() == 0) target = q16horiz(1);
 		}
 		else
 		{
-			horiz = q16horiz(FloatToFixed(value));
+			horiz = buildfhoriz(value);
+			if (backup) ohoriz = horiz;
+		}
+	}
+
+	void settarget(fixedhoriz value, bool backup = false)
+	{
+		if (!SyncInput() && !backup)
+		{
+			target = value;
+			if (target.asq16() == 0) target = q16horiz(1);
+		}
+		else
+		{
+			horiz = value;
 			if (backup) ohoriz = horiz;
 		}
 	}
 
 	void processhelpers(double const scaleAdjust)
 	{
-		if (target)
+		if (target.asq16())
 		{
-			horiz += q16horiz(xs_CRoundToInt(scaleAdjust * (target - horiz.asq16())));
+			horiz += q16horiz(xs_CRoundToInt(scaleAdjust * (target - horiz).asq16()));
 
-			if (abs(horiz.asq16() - target) < FRACUNIT)
+			if (abs((horiz - target).asq16()) < FRACUNIT)
 			{
-				horiz = q16horiz(target);
-				target = 0;
+				horiz = target;
+				target = q16horiz(0);
 			}
 		}
 		else if (adjustment)