Page 3 of 3

Re: Daytona USA 2 High Scores

Posted: Sun Apr 06, 2025 2:38 pm
by MO-120FF
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

Posted: Mon Apr 07, 2025 6:56 am
by Bart
I believe that you have to disable Vsync in your graphics driver as well for this to work.

Re: Daytona USA 2 High Scores

Posted: Wed Apr 23, 2025 7:03 am
by MO-120FF
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?

Re: Daytona USA 2 High Scores

Posted: Thu Apr 24, 2025 1:25 am
by Bart
Yes I do. You'll need to build Supermodel with ENABLE_DEBUGGER set. On Windows, for me, this looks like:

Code: Select all

make -f Makefiles/Makefile.Win32 clean
make -f Makefiles/Makefile.Win32 ENABLE_DEBUGGER=1
Then you can run as:

Code: Select all

supermodel daytona2.zip -enter-debugger
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:

Code: Select all

g++ Src/CPU/PowerPC/PPCDisasm.cpp -o ppcd.exe -DSTANDALONE -ISrc -ISrc/OSD/SDL
Now you can disassemble the ram file:

Code: Select all

ppcd ram -l 1000000 >daytona2.txt

Re: Daytona USA 2 High Scores

Posted: Thu Apr 24, 2025 4:37 am
by Bart
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

Posted: Fri Apr 25, 2025 12:49 pm
by MO-120FF
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. 😉