dhewm / dhewm3

dhewm 3 main repository
https://dhewm3.org/
GNU General Public License v3.0
1.78k stars 346 forks source link

Concept of dhewm3 running at 144Hz refresh #250

Open dezo2 opened 5 years ago

dezo2 commented 5 years ago

I made a custom win32 build for my testing purposes aimed to 144Hz displays, including RoE and dentonmod. After some testing I decided to share it here in case anyone of you guys wants to try it. It is by no means official proper engine fix, just an experiment if it can run smoothly at such refresh. I also tried to fix some issues found on the way - see bellow. There can be more of them (mainly physics), but hopefully nothing game breaking.

dhewm3_144Hz.zip

To install this just copy the unzipped content over the stable 1.5.0 dhewm3 release, or merge the autoexec lines if you already use your own. Of course your display refresh has to be 144Hz before executing the game and in-game VSync must be active. The frame time for 144Hz is very close to 7ms, so that is the value I used in all binaries for the integer USERCMD_MSEC constant. With that and the com_fixedTic "1" plus VSync, the game speed looks alright. As for the CPU load, do NOT use r_finish "1" for input lag reduction, it tanks the CPU in some areas and may cause crashes in high refresh. Just leave it at "0", input lag will be lowered anyway with the shorter frame time.

Changes made in the binaries:

dezo2 commented 5 years ago

During testing I went through the whole base game and RoE expansion pack using i7-8700, GTX-1080 (drivers 431.60), 2560x1440 @144Hz with default dhewm3 Ultra setting. I didn't use the in-game MSAA, instead used cheap nVidia FXAA, which looks OK in this old game and is almost resources free. GPU was resting the whole time at about 10%..30% load and I didn't encountered any engine crashes. Surprisingly there also weren't any slowdowns due to com_fixedTic "1", not even once. So at least on this CPU the high refresh seems to be viable.

dezo2 commented 5 years ago

I suggest a little change in the grabber crosshair switching code for RoE. IMHO the crosshair rotation looks better unscaled in widescreen. I doubt it can be fixed to circle due to the dynamic rotation. The code is in d3xp\Player.cpp, idPlayer::DrawHUD function.

if ( weapon.GetEntity()->GetGrabberState() == 1 || weapon.GetEntity()->GetGrabberState() == 2 ) {
    cursor->SetStateString( "grabbercursor", "1" );
    cursor->SetStateString( "combatcursor", "0" );
    cursor->SetStateBool( "scaleto43", false );   // unscaled
    cursor->StateChanged( gameLocal.realClientTime );   // set state
} else {
    cursor->SetStateString( "grabbercursor", "0" );
    cursor->SetStateString( "combatcursor", "1" );
    cursor->SetStateBool("scaleto43", true);   // scaled
    cursor->StateChanged(gameLocal.realClientTime);   // set state
}
KillPixelGames commented 4 years ago

Nice, this works very well! I haven't tested it too much but it seems very solid.

Ah, it's nice to have non-BFG edition at high refresh rates...

linuxiorr commented 4 years ago

Could anyone compile the 144hz fix for Linux? I'm using dhewm3 from the repositories.

Right I have to play with com_fixedTic -1.

VipersFighting commented 3 years ago

Hey dezo2!

I am not sure why this patch as not received as much attention as it should be! It is the holy grail for D3 modification!

With the Librecoop coming along we are so close to having a better than BFG Edition type co-op experience for the first time ever.

which raised the question,

Any way to have this compatible librecoop on a client side level?

If i used your base.dll It runs but everything is in fast forward. Is there a simple way to be compatible the librecoop base.dll?

Any insight would be very welcomed!

SixelAlexiS90 commented 2 years ago

I made a custom win32 build for my testing purposes aimed to 144Hz displays, including RoE and dentonmod. After some testing I decided to share it here in case anyone of you guys wants to try it. It is by no means official proper engine fix, just an experiment if it can run smoothly at such refresh. I also tried to fix some issues found on the way - see bellow. There can be more of them (mainly physics), but hopefully nothing game breaking.

dhewm3_144Hz.zip

To install this just copy the unzipped content over the stable 1.5.0 dhewm3 release, or merge the autoexec lines if you already use your own. Of course your display refresh has to be 144Hz before executing the game and in-game VSync must be active. The frame time for 144Hz is very close to 7ms, so that is the value I used in all binaries for the integer USERCMD_MSEC constant. With that and the com_fixedTic "1" plus VSync, the game speed looks alright. As for the CPU load, do NOT use r_finish "1" for input lag reduction, it tanks the CPU in some areas and may cause crashes in high refresh. Just leave it at "0", input lag will be lowered anyway with the shorter frame time.

Changes made in the binaries:

  • all: physics workarounds to fix some machinery and moved/pushed items
  • all: too fast air decreasing when outside
  • RoE: replaced hard-coded 16/4 speeds in artifact slowmo ramps
  • dentonmod: new weapon not selected (when switch to new is active)
  • dentonmod: hud drawed on top of white or red screen overlays
  • dentonmod: copied the widescreen crosshair fix from the base game And this was adjusted in the scripts:
  • all: too fast fire rate of the chaingun
  • dentonmod: lost souls sometimes keep screaming after death

Hi dezo! Is there any chance of having this fantastic mod compatible with dhewm3 1.5.1? Your mod is amazing and surely deserve more attention as @VipersFighting already said.

I've already played the game with it some years ago but wanted to give another go. Thank you!

dezo2 commented 2 years ago

Hi Alexi, last build I have is 1.5.2pre (without the Denton's mod) - I made it for myself last year when Daniel was fixing audio bugs and adding some new EAX cvars. Feel free to try it, I don't have much time for Doom 3 lately. dhewm3_144Hz_152pre.zip

KillPixelGames commented 2 years ago

Feel free to try it

seems to be working just fine with 1.5.1

markanini commented 2 years ago

Did a quick test with dezo2's build two replies before mine. Moving and jumping slows down when fps goes below 144Hz. No issues other than that.

SixelAlexiS90 commented 2 years ago

Hi Alexi, last build I have is 1.5.2pre (without the Denton's mod) - I made it for myself last year when Daniel was fixing audio bugs and adding some new EAX cvars. Feel free to try it, I don't have much time for Doom 3 lately. dhewm3_144Hz_152pre.zip

Hi dezo! Sorry to bother you again, but do you know if there is a similar 144Hz mod for Prey (2006) as well? I know it use the same engine of Doom 3 and it's capped at 62.5FPS, maybe you tried to work on something for that game as well. Thank you again for your time and for your effort <3

doom-guy-1993 commented 1 year ago

I beat the base game on Nightmare. Not a single issue at 1920x1080. It was on my previous build with an i5-9600K @5.0GHz, GTX 1660 Super and 16GB DDR4 @3000MHz.

nr1995 commented 3 months ago

Has there been any progress made on this in the last 13 months?

DanielGibson commented 3 months ago

There's was (is?) a fork based on Stradex' branch from #297: https://github.com/simonedibilio/dhewm3

DanielGibson commented 3 months ago

By the way, @dezo2, where is the source of the binaries you posted here?

dezo2 commented 3 months ago

Sources of modified 1.5.2 are in the "neo.zip", two modified scripts that should go into the base folder are in "base.zip". I am not really a cpp/github guy, so I thought the changes I made are not up to standard here (it was just a test). I am sure there is a better way to do it instead of recompiling the whole thing with different values for USERCMD_HZ and USERCMD_MSEC in UsercmdGen.h and updating the two scripts. It will break compatibility with mods for sure. Anyway I marked every change with comment "// dezo2" to easy find them. Most of them are simple replaces of original hardcoded values. There was not much to do, the engine really had no problem with higher framerates, especially with todays CPUs with fast single core performance. I tested this last year with i5-13600 at 200 FPS no problem. Its just they decided at some point to screw it with hardcoded values, not sure why - maybe the weird physics. neo.zip base.zip

DanielGibson commented 3 months ago

thank you! :)

SixelAlexiS90 commented 3 months ago

There's was (is?) a fork based on Stradex' branch from #297: https://github.com/simonedibilio/dhewm3

Hi! Do you know if there is something similar in the work for Prey (2006)?

DanielGibson commented 2 months ago

Hi! Do you know if there is something similar in the work for Prey (2006)?

I don't think so, and as Prey's source code wasn't released it would be pretty hard to do. Also note that dhewm3 is about Doom3 and not Prey.

DanielGibson commented 2 months ago

I put your code changes into a git branch which is based on the latest dhewm3 code: https://github.com/DanielGibson/dhewm3/tree/dezo-144hz

Are there any known bugs with this code?

dezo2 commented 2 months ago

I saw maybe 2 or 3 physics related glitches where imp couldn't jump out of his hole due to a moving part in the path. Other than that I was able to finish both the base game and RoE without anything game breaking. BUT the two adjusted script files from base.zip above are mandatory, otherwise the game will crash in Alpha Labs 3 (the crane section) and chaingun will fire too fast.

DanielGibson commented 2 months ago

Do you remember where those physics glitches happened?

Why is com_fixedTic 1 (instead the default of 0) needed, what does it do?

With Stradex' approach there were reports about oxygen running out too slow (in the base game) or too fast (in d3xp), did you notice anything like that in your branch?

(Stradex also modifies GAME_FPS and GAME_FRAMETIME in the scripts, so I would expect it to behave similar in many regards)

EDIT: Oh, and I understand correctly that all that was needed to fix that crane (I saw that mentioned in #297 as well) was to adjust GAME_FPS and GAME_FRAMETIME in the scripts, not the crane script itself?

dezo2 commented 2 months ago

IIRC the glitches were in map recycling1/2 somewhere (can't remember) and in RoE map erebus4 in the beginning where that new imp couldn't leap down from the ceiling. I could't figure out what to adjust in the physics code to make it work.

Almost every high refresh monitor nowadays has variable refresh so the com_fixedTic can be ignored (left at default 0) as these monitors can handle anything in VRR range including the default 62.5 FPS hardcoded into the engine without any stutter/judder. It was an ancient fix to eliminate microstutter for fixed refresh rate monitors. It bypasses the ingame timer based FPS cap so it can be handled by VSync or external limiter instead. Because the engine uses integer value for frametime, ideal fixed refresh rates in Hz would be 50 (20ms), 100 (10ms), 125 (8ms), 200 (5ms) etc. Everything else causes microstutter as it is not aligned with integer frametimes. For example 60Hz does not match the default integer 16ms ingame constant because 1000/16=62.5 (not 60), so the game skips a frame every one second or so. That cvar removed those skips and made the game smoother but also caused slow downs when CPU/GPU is too slow to reach the target FPS. And obviously caused a bit of audio desync in cutscenes due to the wrong timing.

For the oxygen tank I made fixes in the code - that was the first thing I noticed wrong with >60FPS. It is the "airTics" adjustment in Player.cpp source code.

As for the scripts - yes, this was the fix for the crane and also the chaingun. Ideal approach would be to adjust it in the code somehow, so the users don't need to fiddle with it manually. It would be great to control all this with a simple cvar (for example "com_engineHz") and use that to overwrite the values when the engine reads and parses original scripts and also everywhere else in the code instead of the dreaded USERCMD_HZ constant.

DanielGibson commented 2 months ago

Thank you very much for the explanation! :)

It would be great to control all this with a simple cvar (for example "com_engineHz") and use that to overwrite the values when the engine reads and parses original scripts and also everywhere else in the code instead of the dreaded USERCMD_HZ constant.

Yeah, that's pretty much what Stradex' branch does - and it even patches the scripts to modify GAME_FPS and GAME_FRAMETIME (and whatever the chaingun uses) on load, so the files on the disk don't have to be modified.

He also turned some times from integers into floats, so 8.333ms or whatever can be handled without losing too much precision. I haven't looked at that too closely yet, but it is potentially helpful.

I hope that I can create something that works properly (and with all kinds of framerates) based on Stradex branch and your patch (but no promises yet, esp. the physics issues might end up as a dealbreaker that's too hard for me to fix, we'll see..)

DanielGibson commented 2 months ago

Oh, two more bugs that were reported with Stradex approach (from https://github.com/simonedibilio/dhewm3/issues/2):

Does any of that sound familiar?

dezo2 commented 2 months ago

Tried the mod switching multiple times now without problems. Can't trigger it.

As for the second one I tried the 1st level in RoE and the grabber works normally right after I get it (after the cutscene). Also played trough the whole expansion at least once and this one I would remember.

DanielGibson commented 2 months ago

My branch based on Stradex' work and your fixes: https://github.com/dhewm/dhewm3/pull/584

DanielGibson commented 2 months ago

Another try, this time not using not that much of Stradex' work: #585

By the way, I think the mod switching issues are related to one mod using a different com_gameHz value than the other, so code like

    unsigned int now = SDL_GetTicks();
    unsigned int tick = com_ticNumber * USERCMD_MSEC;
    // now compare both values..

doesn't work that well, esp. if USERCMD_MSEC has been reduced in between and tick might suddenly be a lot smaller than now.

With your patches this isn't a problem because USERCMD_* was fixed to the same value for all mods.