Skip to content

Commit c66a8cc

Browse files
committed
Replace game's CRT function call in floating point number INI parser
1 parent fcda09f commit c66a8cc

File tree

2 files changed

+26
-16
lines changed

2 files changed

+26
-16
lines changed

docs/Whats-New.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,7 @@ Phobos fixes:
554554
- Fixed an issue with `Powered`/`PoweredSpecial` building animation ownership change fix (by Trsdy)
555555
- Fixed `DisplayIncome`, `Transact.Money` etc. display strings showing through shroud and for objects that are supposed to be hidden such as cloaked, undetected enemies (by Starkku)
556556
- Fixed an issue that could cause crashes when `FeedbackWeapon` was used to convert the firer to another TechnoType with less or no weapons (by Starkku)
557+
- Fixed an issue with parsing floating point numbers from INI that may have in some cases contributed to desyncs (by Starkku)
557558
```
558559

559560
### 0.4

src/Utilities/Parser.h

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
#include <type_traits>
3636
#include <Windows.h>
3737
#include <stdio.h>
38-
#include <CRT.h>
3938

4039
//! Parses strings into one or more elements of another type.
4140
/*!
@@ -261,35 +260,45 @@ inline bool Parser<int>::TryParse(const char* pValue, OutType* outValue)
261260
template<>
262261
inline bool Parser<double>::TryParse(const char* pValue, OutType* outValue)
263262
{
263+
errno = 0;
264+
char* end;
264265

265-
// Game doesn't use double precision when parsing, using double here would create inconsistency.
266-
float buffer = 0.0;
266+
// Nov 23, 2025 - Starkku: strtod() + cast result to float produces results
267+
// more similar to game's CRT functions than using sscanf_s.
268+
double value = strtod(pValue, &end);
267269

268-
// Use game's sscanf function, the C library one has different precision/rounding.
269-
if (CRT::sscanf(pValue, "%f", &buffer) == 1)
270+
if (pValue == end || errno == ERANGE)
271+
return false;
272+
273+
float floatValue = static_cast<float>(value);
274+
275+
if (strchr(pValue, '%'))
270276
{
271-
if (strchr(pValue, '%'))
272-
{
273-
buffer *= 0.01f;
274-
}
275-
if (outValue)
276-
{
277-
*outValue = buffer;
278-
}
279-
return true;
277+
floatValue *= 0.01f;
280278
}
281-
return false;
279+
if (outValue)
280+
{
281+
*outValue = floatValue;
282+
}
283+
return true;
282284
};
283285

284286
template<>
285287
inline bool Parser<float>::TryParse(const char* pValue, OutType* outValue)
286288
{
287289
double buffer = 0.0;
290+
288291
if (Parser<double>::TryParse(pValue, &buffer))
289292
{
293+
float floatValue = static_cast<float>(buffer);
294+
295+
if (strchr(pValue, '%'))
296+
{
297+
floatValue *= 0.01f;
298+
}
290299
if (outValue)
291300
{
292-
*outValue = static_cast<float>(buffer);
301+
*outValue = floatValue;
293302
}
294303
return true;
295304
}

0 commit comments

Comments
 (0)