exoscoriae / eXoDOS

eXoDOS
69 stars 3 forks source link

Privateer 2 The Darkening (Special Edition) (1996) #2494

Open Python-Exoproject opened 3 years ago

Python-Exoproject commented 3 years ago

There is a speed problem with this game. Here is the conversation so far:

Been looking into the speed issue with Privateer 2 (Gameplay runs normal at 15000 cycles, but when a planet is in front of you in space it needs 175000 cycles.). I was thinking of it as the planets slow the game down but krc pointed out that for the era of the game (1996) its more likely that the game should be 175000 cycles and the majority of the gameplay is running too fast. He had a look and discovered that its a game issue, not a dosbox issue and that it has been patched previously by two different fan patches. The problem is that the fan-patches are for the windows version only.

The better of the two patches by HCL does a number of other things as well like deinterlace, fix mouse etc. In regards to DOS version he has said:

"Adapting these fixes to the DOS version would be possible, but technically would be more complicated due to DOS extender issues. It might be easier to tie the DOS EXE hacks to a specially modified DOSBox (been entertaining a few ideas on that regard).

So, short answer, right now these fixes are specific to the Windows version, but maybe there will be port to the DOS EXE sometime in the future."

The other patch is focused on the speed issue and gives some info on the problem:

"To all you hackers out there, this is how P2 works. It ran fine on my Pentium 200MHz back in '97, but is way to fast on any modern computer, so slowing down each frame is needed to make it playable. Hacking in a call to Sleep() at the end of each frame does the trick.

It uses DirectDraw, but only copies directly to the front buffer. There are three functions that do this: one for movies, one for the UI, and one for space combat. Movies already work because of the strict timing required. The rest of the game is typical of a DOS program...

The UI function copies the whole screen at once, so adding a call to the end of this function fixes it perfectly (the sound is fixed too!)

Space combat is different. The function only copies a small part of the screen, so the call to Sleep() had to be added to the main loop.

If it is too fast or too slow, try tweaking the values at 87D79h (UI, default 20ms) and 87D8Dh (space, default 30ms)."

Do you think kudgel that its something you could adapt to the DOS exe? Or maybe we can pass this off to ripsaw eXo and see what he thinks?

Heres HCL patch: p2_patch_test3.zip

Heres the other one: priv2_slowdownpatch.zip

This is probably something not too hard to fix If you guys think it can't be fixed with a cycle patch I can probably dig into some ways to make it frame-lock

My guess is there's a bunch of math-intensive code that's activated when the planet is in view; and it needs to run for every frame.

Also, the closer you are to the planet, the slower the frame-rate, so it's likely that the math code does even more work the closer you are: they probably have for-loops that fill in the textures.. and the closer you are, the bigger the area to fill in. The patch author tackled it from the angle assuming you're running on modern hardware (ie: who care about that slow math - you've got a faster modern system), as opposed to actually speeding up that math (which would be much harder to solve). On modern hardware, it rips through that bloated planet math - so the slow down isn't as apparent (which is similar to what we see in DOSBox going from 17k -> 175k cycles).

However, the game itself seems to run unthrottled (or somewhat unthrottled?), so that's why the patch author inserted the 30ms wait per frame. It throttles all aspects of game-play down to ~30 FPS. I suspect the delay has to be inserted inside the game's code itself.

I think if you can frame-lock the game itself (to 30 FPS or so), that would solve it. We would then be able to crank up the game's cycles on the dosbox side so the heavy planet code can also run at ~30 FPS, without any fear of other parts of game play going too fast (because they're locked at 30 FPS). Kind of like running an engine at 7000 RPM.. and riding the clutch and brakes as needed to never exceed 100 km/hr. Not the most efficient, but gets the job done!

exoscoriae commented 3 years ago

ok... so, I'm not seeing anything currently actionable here. should this be low priority? @Python-Exoproject

Python-Exoproject commented 3 years ago

Yeah, waiting to see if kudgel can do anything with it. Unless you want to try ripsaw?

Python-Exoproject commented 3 years ago

@exoscoriae In the meantime as a separate potential enhancement give staging using output=overlay a go. The interlacing looks much better with that to me

exoscoriae commented 3 years ago

does pixel perfect accomplish this as well? We found with hardline, PP was the cleanest method of presenting interlacing.

exoscoriae commented 3 years ago

switched to pixel perfect and interlacing looked great to me.

exoscoriae commented 3 years ago

moving to low priority until we have some sort of path forward on this

exoscoriae commented 3 years ago

fixed general midi using a patched mpu401/mdi file (same fix as Shellshock and Hi-Octane)

exoscoriae commented 2 years ago

with kudgel no longer active, it seems @kcgen is our primary path forward on this. Any new news since then?

Python-Exoproject commented 2 years ago

Moved back to High Priority for TSR integration.

Ripsaw wrote this TSR which helps but does not completely fix the issue: priv2wfr.zip

His notes:

It's not enough to really fix the speed issue. The program waits for retrace at the beginning of each frame, which effectively caps framerate at the refresh rate. AFAICT, it helps the game's UI to be nice and smooth at high (or max) cycles. In flight, the framerate cap may help with the difference between when a planet is visible or not, but there is a bit of overall jerkiness that is... suboptimal. I'm sure the jerkiness is caused by the TSR "wasting CPU cycles" while waiting for retrace instead of calling some part of the game's main loop, which directly relates to the difficulties I mentioned before about trying to externally manipulate framerate. So, I think maybe something can still be done, but it will involve hacking on the game code, which is no easy thing.

In 3D flight the framerate varies considerably between empty space and a planet in view. From what I can tell, the irregular framerate is caused by the absence of any form of stable limiting. For example, the 2D interface would have virtually perfect speed if the game simply waited for retrace before flipping the display page, but there is no such limiting. It seems that frames are always displayed as quickly as possible, with the only limit being the speed of the system, which is of course not a stable limiter. Unfortunately, framerate limiting has to be baked into the 3D engine and cannot be imposed externally with satisfactory results.

This real-mode VBE function is used by some games for page flipping: http://www.delorie.com/djgpp/doc/rbinter/id/83/2.html The TSR watches for "top of window A" calls, waiting for retrace before letting them proceed -- a feature that VBE does not provide.

In theory it would work for any game that uses the specific function (SkyNET, Tie Fighter CD-ROM, et al.) However, there are other VBE functions that can be used for page flipping, and they have a built-in feature to wait for retrace.


Another user has also noted that another path to fixing this is Dosbox X as it has a setting "vmemdelay" that can help a bit when set to 1000, but it also isnt a complete fix.

Lastly RealNC has noted that PCEM with an emulated Pentium 133 works flawless.

If its working properly in PCEM this gives me hope that someone working on dosbox might be able to come up with a fix!

exoscoriae commented 2 years ago

added the TSR. good notes above. Guess we will keep this open in hopes of a more complete fix.