Open RikkiGibson opened 4 weeks ago
Interesting and detailed information! I didn't know about this game trick.
Unfortunately I'm pretty sure people will start complaining that the gdrom emulation is too slow if load times are increased to match real hardware. Interestingly Skies of Arcadia is very sensitive to the gdrom speed and a significant delay had to be introduced for this game not hang during the intro. And some people started complaining... Also there are still delay issues with the gdrom that affects some games in serious ways so work is definitely not complete in this area.
If you want to experiment further with this, I suggest you use real BIOS mode and tweak core/hw/gdrom/gdromv3.cpp
. Try increasing the value 1100000 in getGDROMTicks()
. This is the number of sh4 cycles to transfer 10 KB of data (5 sectors). There are 200M cycles/sec so this is 5.5 ms. I'd be interested in what you fell is the "correct" value.
Thanks much for the insights! Totally understand that asking for a big slowdown in the GDROM perf would really be a downgrade for ordinary use. I am wondering if such a change could go behind a config setting? Would that be more palatable? Maybe even a 3-state between "FastGDRomLoad", "Default", and "HighFidelityGDRomLoad", or something.
In any case, I much appreciate the information and guidance.
I also had time to gather a little data today.
Time from first GDROM access to the encounter trigger visual effect (usually the screen breaking apart into triangles).
getGDROMTicks() | Time |
---|---|
1100000 | ~0.7s |
2100000 | ~1s |
3100000 | ~1.2s |
4200000 | ~1.5s |
Real console | ~1.5s |
Starting from Shrine Island outside, hold A+B+X+Y+Start and count time till title screen reappears
getGDROMTicks() | Time |
---|---|
1100000 | ~3s |
3100000 | ~8s |
4200000 | ~10s |
Real console | ~12s |
getGDROMTicks() | Time |
---|---|
1100000 | ~2s |
2100000 | ~2.8s |
3100000 | ~3.5s |
4200000 | ~4.6s |
Real console | ~3.2s |
The first table looks pretty bad (would require a massive speed reduction in order to match). The last table a smaller increase but still quite large.
I am thinking there probably isn't one correct value for these particular tests, if the goal is to match the performance of the original GDROM drive. There would probably be a need to simulate seeking, etc. and basically penalize workloads which jump back and forth across the disk versus ones that read straight through.
I made an assumption that the gdromv3.cpp does not simulate seek time. Is that right? Does the STRICT_MODE
symbol play into the behavior significantly here? If STRICT_MODE is meant to eventually become a full fledged setting, then possibly these slower, more "faithful" GDROM behaviors could be locked behind it?
Is your feature request related to a problem? Please describe. Skies of Arcadia notoriously telegraphs when a random encounter is going to happen by reading from the disk drive. This makes a pretty noticeable noise on console. You can do stuff like open the menu and heal up, then get a guaranteed encounter the instant you close the menu.
It turns out you can also use this to cancel encounters on console. In the ~1.5 seconds between hearing the disk drive and the battle starting, if you perform an action like opening a chest, climbing a ladder, etc., the battle won't start. It seems the step counter resets when you do this, so you can effectively cut the encounter rate in half in some areas when you pull this trick off.
It would be nice if this trick were also possible on emulator. For speedruns it would level the playing field more between those playing on original console and those on emulator, since obviously getting fewer random encounters saves time.
Describe the solution you'd like The solution involves 2 things:
Describe alternatives you've considered I can't think of any reasonable alternatives which would achieve the goal.
Additional context I tried to modify the emulator to accomplish this. And I kinda-sorta got something working, which can be seen in the attached video. The LOADING.. text appearing briefly in the bottom left, before climbing the ladder, indicates a canceled encounter. I was able to walk all the way back inside with no encounters, which is pretty much impossible to do without this trick.
https://github.com/user-attachments/assets/2f823335-e941-4228-aada-befdba386e35
First I modified the UI to show when a GDROM read is in progress. I did this by just exposing and reading the
gd_hle_state.status
in the UI, and showing "loading" text when the status was nonzero.This showed a loading indicator the way I wanted, but the load went by too fast. In adhoc testing there was maybe 0.7 seconds to react to the loading text and cancel the encounter, which was about half the time I have on console. Very difficult to actually pull the trick off this way.
So, secondly, I tried to adjust
read_sectors_to
to be slow enough for this trick, ideally resulting in a similar speed as console.I basically just tried inserting a 250ms access time if the requested sector is far enough away from the most recently read sector. This kinda worked, but had the effect of slowing down ordinary read workloads too much. It was just obvious when launching the game that things were now way too slow.
Also, my change was obviously only in the HLE emulation. I ended up adding the DC BIOS file later on, and tried again in gdromv3.cpp. I wasn't able to understand what would be equivalent to what I did for the HLE one. I found the getGDROMTicks function, but I wasn't sure what it meant. It looked like a constant return value was being used for large transfers, which I didn't understand. I expected larger and larger transfers to take more and more ticks to finish or something like that. I managed to show when it was reading, but the reads were generally too fast to do the trick most of the time.
I think to make this take a similar amount of time as console, without harming overall performance too much, might require a more complex simulation of the disk drive. Accounting for stuff like constant angular velocity, seek time, buffering, and so on. For example, I noticed on console that when you repeatedly open the in-game menu in Skies, you will generally only hear the disk drive crank and get a delay the first time you do it after a battle or some such. The subsequent times will have much less delay. This might be due to the disk drive buffering the read? When I did my "add 250ms" hack, the additional delay to open the menu was considerable and happened every time.
I poked around a bit to see if any other emulators tried to do more accurate simulation of the disk drive. It looks like PCSX2 does some work to do this. Possibly some of the same aspects they are simulating could be done here. It seems like a significant amount of work, though, and might be tricky to be sure whether a complex set of changes to the GDROM did not negatively impact other games.
Here is the branch. It's in a hacked up state, but may be of interest.
Thanks for reading, and for any thoughts/suggestions you may have.