Daytona USA 2 High Scores
Forum rules
Keep it classy!
Keep it classy!
- No ROM requests or links.
- Do not ask to be a play tester.
- Do not ask about release dates.
- No drama!
Re: Daytona USA 2 High Scores
Regarding the settings, I would just like to disable throttling (Alt + T), but it doesn't work for me. Supermodel always throttles to 60fps. Are there any settings that allow me to disable throttling using Alt + T? (The command line option -no-throttle also doesn't work for me.)
Re: Daytona USA 2 High Scores
I believe that you have to disable Vsync in your graphics driver as well for this to work.
Re: Daytona USA 2 High Scores
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.
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?
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
- Attachments
-
- daytona_20250421_nv.jpg (90.26 KiB) Viewed 28152 times
Re: Daytona USA 2 High Scores
Yes I do. You'll need to build Supermodel with ENABLE_DEBUGGER set. On Windows, for me, this looks like:
Then you can run as:
There is a help command. "c" will continue execution and Alt+B breaks back into the debugger. Note that you will not easily find the game accessing NVRAM. It doesn't access it directly as far as I can tell. Rather, it keeps a score table in memory with an entirely different format and (I presume), writes it to NVRAM only when something has changed.
You can set breakpoints in the debugger but I don't think we have watches (for memory access or other conditions). I disassembled the entire Daytona 2 program code and looked through it manually, searching for relevant magic numbers. I think I also looked at the RAM dump directly searching for the high score strings.
In Model3.cpp, near the bottom of the file, there is code to dump RAM and other memory. Uncomment that. On exit, you'll get a file called "ram", which is the lower 8MB of the PowerPC address space. This is where game code is copied to and executed from. You can open it in a hex editor. To disassemble it, build Src/CPU/PowerPC/PPCDisasm.cpp as a standalone application, like so:
Now you can disassemble the ram file:
Code: Select all
make -f Makefiles/Makefile.Win32 clean
make -f Makefiles/Makefile.Win32 ENABLE_DEBUGGER=1
Code: Select all
supermodel daytona2.zip -enter-debugger
You can set breakpoints in the debugger but I don't think we have watches (for memory access or other conditions). I disassembled the entire Daytona 2 program code and looked through it manually, searching for relevant magic numbers. I think I also looked at the RAM dump directly searching for the high score strings.
In Model3.cpp, near the bottom of the file, there is code to dump RAM and other memory. Uncomment that. On exit, you'll get a file called "ram", which is the lower 8MB of the PowerPC address space. This is where game code is copied to and executed from. You can open it in a hex editor. To disassemble it, build Src/CPU/PowerPC/PPCDisasm.cpp as a standalone application, like so:
Code: Select all
g++ Src/CPU/PowerPC/PPCDisasm.cpp -o ppcd.exe -DSTANDALONE -ISrc -ISrc/OSD/SDL
Code: Select all
ppcd ram -l 1000000 >daytona2.txt
Re: Daytona USA 2 High Scores
I just pushed a change to master that builds ppcd.exe automatically in the bin64 directory (alongside supermodel.exe), so if you build Supermodel as normal, you should now also get a ppcd.exe.
Re: Daytona USA 2 High Scores
I've tried the MAME debugger so far - it's pretty extensive, and you can set memory watches. The ROM set is compatible, i.e. the 0x4D4B4 function is at the same address, as is the in-memory high score list at 0x00106F50. The game runs, but unfortunately isn't playable. Also the NV dump is in a different format (though the two "time bytes" for each entry are the same).
Thanks for your detailed instructions on compiling the source and using the debugger. I need to set up a build environment first - that might take some time.
Actually, I play this game just for fun and only wanted a quick way to compare top times with friends. Didn't expect to end up disassembling and debugging the source code for that.
Thanks for your detailed instructions on compiling the source and using the debugger. I need to set up a build environment first - that might take some time.
Actually, I play this game just for fun and only wanted a quick way to compare top times with friends. Didn't expect to end up disassembling and debugging the source code for that.