https://bugs.winehq.org/show_bug.cgi?id=49564
--- Comment #4 from qsniyg qsniyg@mail.com --- (In reply to Arek Hiler from comment #3)
So I have tried: -static const int user_shared_data_timeout = 16; +static const int user_shared_data_timeout = 15;
Sadly, the game sill crashes. My current guess is that dosbox.exe doesn't like very unstable deltas between ticks, which we have now because we update timestamps at "random" intervals - on each server request. I am yet to verify that
The issue with dosbox is that it sleeps for one millisecond, then expects that GetTickCount will be incremented. I submitted a test for this here: https://github.com/wine-mirror/wine/commit/4617f83fcf0a34fe41b0e38dde1567195...
It's supposed to have a near-100% increment rate, but now it has a 6% increment rate instead (which makes sense, 100/16 = 6.25). So it seems like Sleep()ing somehow signals to windows that it should update the tick count, even if it's below the 15-16ms resolution?
I'm not sure about Doom II, but Tomb Raider has the source code for its patched dosbox included with the release. This is the relevant section (in dosbox.cpp):
static Bitu Normal_Loop(void) { --- snip --- Bit32u ticksNew; ticksNew=GetTicks(); ticksScheduled += ticksAdded; if (ticksNew > ticksLast) { ticksRemain = ticksNew-ticksLast; ticksLast = ticksNew; ticksDone += ticksRemain; if ( ticksRemain > 20 ) { ticksRemain = 20; } ticksAdded = ticksRemain; --- snip --- } else { ticksAdded = 0; SDL_Delay(1); // <-- ticksDone -= GetTicks() - ticksNew; // <-- if (ticksDone < 0) ticksDone = 0; }
This means ticksDone will very rarely decrement in the else block. From a quick glance at the surrounding code, I wasn't able to really figure out what the result of this meant, but it works properly when GetTicks() is incremented after sleeping for a millisecond.