I've put together a webpage that reads the NV file and displays the high scores using both of the calculation methods you found in the source:
function calculateTime1(nFrameCount) {
const nSeconds = Math.floor(nFrameCount / FPS);
const nFrameCount_subSecond = nFrameCount - (nSeconds * FPS);
const nCentiSeconds = Math.floor( (nFrameCount_subSecond * 100) / FPS);
const nMinutes = Math.floor(nSeconds / 60);
const nRemainingSeconds = nSeconds - (nMinutes * 60);
return `${nMinutes}:${nRemainingSeconds.toString().padStart(2, '0')}:${nCentiSeconds.toString().padStart(2, '0')}`;
}
function calculateTime2(nFrameCount) {
const nTotalCentiseconds = Math.floor((nFrameCount * 100.0) / FPS);
const nWholeSeconds = Math.floor(nTotalCentiseconds / 100);
const nCentiseconds = nTotalCentiseconds - (nWholeSeconds * 100);
const nWholeMinutes = Math.floor(nWholeSeconds / 60);
const nSeconds = nWholeSeconds - (60 * nWholeMinutes);
const nWholeHours = Math.floor(nWholeMinutes / 60);
const nMinutes = nWholeMinutes - (60 * nWholeHours);
return `${nMinutes}:${nSeconds.toString().padStart(2, '0')}:${nCentiseconds.toString().padStart(2, '0')}`;
}
As you expected, the results of both functions are the same. Some times match the game-displayed times exactly; others differ by a ms. This also happens with new entries in the high-score list.
But I noticed something interesting while trying to zero out some bytes in the high-score list:
- Zeroing 0x22E6/E7 (and the same bytes at 0x22EC/ED) - no change in game-displayed times
- Zeroing 0x22E8/E9 (and the same bytes at 0x22EA/EB) - some displayed times change
Zeroing the yellow-marked bytes in the attached screenshot caused the game to add 1ms to some times. Now the previously mismatched times match the calculation, but the ones that matched before are now too high.
Code: Select all
Rank |Initials |Frame Count |Time (Calc) |Actual Time / time with zeroed bytes
---- |-------- |----------- |------------ |-----------
1 |ZER |0x1E60 |2:16:42 |2:16:41 / 2:16:42
2 |ZER |0x1E73 |2:16:75 |2:16:74 / 2:16:75
3 |ZER |0x1E76 |2:16:80 |2:16:80 / 2:16:81
4 |ZER |0x1E78 |2:16:84 |2:16:84 / 2:16:84
5 |ZER |0x1E87 |2:17:10 |2:17:10 / 2:17:11
CR |ZER |0x03BB |0:16:75 |0:16:74 / 0:16:75
It seems those 4 bytes might have some influence on the time calculation. Guess requires again to take a closer look at the memory region around 0x00106F50 in the debugger to see how they are accessed. I noticed the sources include debugger files — do you use the internal one?