gameframe-msvc-crt
Parts of the Microsoft C runtime (MSVC CRT) that a game's results can depend on, rebuilt in Rust so a port gives the same numbers as the original program.
| Module | What it reproduces | Why it matters |
|---|---|---|
crt | sinf, cosf, acosf, atan2f of the x64 runtime, operation by operation | They are not correctly rounded. Rust's f32::sin can differ in the last bit, which can change a simulation |
qsort | qsort's algorithm: median-of-three quicksort with a selection sort for 8 or fewer elements | It is unstable. The order of equal elements is part of the game's behaviour |
rand | rand and srand: the linear congruential generator with RAND_MAX 32,767 | Many games use it for their random numbers, or a library they link uses it |
powf, floorf and sqrtf are correctly rounded in the runtime and in Rust, so Rust's own functions already match them.
It comes from Un-Banished. There the float functions match Banished's copies of the runtime on 200,000 calls each. The sort matches the original's order of equal elements on recorded sorts (measured with GameFrame's emulator).
Use it
[dependencies]
gameframe-msvc-crt = { git = "https://github.com/tanepiper/game-frame" }use gameframe_msvc_crt::{crt, qsort, rand::Rand};
let heading = crt::atan2f(1.0, 2.0);
let mut r = Rand::new(1);
let first = r.rand(); // 41
let mut scores = vec![(3, "a"), (1, "b"), (3, "c")];
qsort::qsort_by(&mut scores, |x, y| x.0 - y.0);
assert!(heading > 0.46 && first == 41 && scores[0].0 == 1);Check your game uses these
Different compilers and runtime versions have different maths functions. Before you rely on this crate, compare it with your game's own copy:
- Find the game's
sinf(or the others) in the decompile: the import frommsvcrt.dllorucrtbase.dll, or a statically linked copy. - Run it under GameFrame's emulator on many inputs (
re-emulate). - Compare the results with this crate bit for bit. If they differ, the game uses another version. Trace its algorithm.
The 32-bit runtime's x87 versions of these functions are different code with different results.
Tests
cargo test --release -p gameframe-msvc-crtThe tests check plain values, that each function is within one unit in the last place of the true result, the arctangent table, rand's known first values from seed 1, and that the sort sorts and is unstable.
Licence
Apache 2.0.