From 1febc8ce298cfd09c14c1338876345c7d93aeccb Mon Sep 17 00:00:00 2001
From: cloudwalk <cloudwalk@d7cf8633-e32d-0410-b094-e92efae38249>
Date: Sat, 27 Jun 2020 02:27:19 +0000
Subject: [PATCH] Dynamically specify float precision when QC sets cvars. Fixes
 rounding errors

Fix by terencehill

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@12737 d7cf8633-e32d-0410-b094-e92efae38249
---
 prvm_edict.c | 30 +++++++++++++++++++++++++++---
 1 file changed, 27 insertions(+), 3 deletions(-)

diff --git a/prvm_edict.c b/prvm_edict.c
index 875d52c6..83d194d3 100644
--- a/prvm_edict.c
+++ b/prvm_edict.c
@@ -2391,7 +2391,9 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char * filename, unsigned char * da
 			if(!cvar)
 			{
 				const char *value;
-				char buf[64];
+				char buf[128];
+				int prec[3];
+				float f;
 				Con_DPrintf("PRVM_LoadProgs: no cvar for autocvar global %s in %s, creating...\n", name, prog->name);
 				switch(prog->globaldefs[i].type & ~DEF_SAVEGLOBAL)
 				{
@@ -2399,11 +2401,33 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char * filename, unsigned char * da
 						if((float)((int)(val->_float)) == val->_float)
 							dpsnprintf(buf, sizeof(buf), "%i", (int)(val->_float));
 						else
-							dpsnprintf(buf, sizeof(buf), "%.9g", val->_float);
+						{
+							// ftos_slow
+							f = val->_float;
+							for (int precision = 7; precision <= 9; ++precision) {
+								dpsnprintf(buf, sizeof(buf), "%.*g", precision, f);
+								if ((float)atof(buf) == f) {
+									break;
+								}
+							}
+						}
 						value = buf;
 						break;
 					case ev_vector:
-						dpsnprintf(buf, sizeof(buf), "%.9g %.9g %.9g", val->vector[0], val->vector[1], val->vector[2]); value = buf;
+						for (i = 0; i < 3; ++i)
+						{
+							prec[i] = 9;
+							f = val->vector[i];
+							for (int precision = 7; precision <= 9; ++precision) {
+								dpsnprintf(buf, sizeof(buf), "%.*g", precision, f);
+								if ((float)atof(buf) == f) {
+									prec[i] = precision;
+									break;
+								}
+							}
+						}
+						dpsnprintf(buf, sizeof(buf), "%.*g %.*g %.*g", prec[0], val->vector[0], prec[1], val->vector[1], prec[2], val->vector[2]);
+						value = buf;
 						break;
 					case ev_string:
 						value = PRVM_GetString(prog, val->string);
-- 
2.39.5