From 001e4e11ca1dfd0ded1bbc29e26f71be50c86aac Mon Sep 17 00:00:00 2001
From: Tasos Sahanidis <tasos@tasossah.com>
Date: Thu, 17 May 2018 17:55:38 +0300
Subject: [PATCH] Correct C FixedMul() off-by-one errors

The FixedMul() C implementation would produce off by one results,
causing constant desyncs on 64 bit builds and builds without an
ASM implementation of the function.

This is fixed by shifting instead of dividing, possibly avoiding
rounding errors.
---
 src/m_fixed.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/m_fixed.c b/src/m_fixed.c
index ce7471a28..014457386 100644
--- a/src/m_fixed.c
+++ b/src/m_fixed.c
@@ -33,7 +33,9 @@
 */
 fixed_t FixedMul(fixed_t a, fixed_t b)
 {
-	return (fixed_t)((((INT64)a * b) ) / FRACUNIT);
+	// Need to cast to unsigned before shifting to avoid undefined behaviour
+	// for negative integers
+	return (fixed_t)(((UINT64)((INT64)a * b)) >> FRACBITS);
 }
 
 #endif //__USE_C_FIXEDMUL__