-
Notifications
You must be signed in to change notification settings - Fork 351
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add com_gameHz to play with higher HZ/FPS #297
base: master
Are you sure you want to change the base?
Conversation
Also, if someone have a mod with custom game logic for dhewm3 and it is worried that after this pull request that mod is not going to work anymore. This is the necessary code I used to update librecoop to make it work with this pull request. (Also keeping compatibility with original dhewm3 usign a preprocessor directive by now) For base: Forr d3xp: |
Thanks for the PR, it will most probably take a while till I merge it because, as you said, it might break existing mods. Also I'll have to review (and ideally test) this thoroughly, and I'm not sure when I have enough time for that.. (unfortunately, I can't even test it properly because all my current screens are 60Hz) Don't get me wrong, this looks great on first glance and it's a often-requested feature, but as it's a quite invasive change I want to make sure we get it right and minimize breakage :) BTW: Attaching zips containing .exe and .dll to github comments should be no problem, I do that all the time. |
Hello! No problem!, I understand that this can be a huge change and can break compatibility with older mods. And that is a problem yes, I will try to find a way to do some kind of "hack" in order to avoid needing to modify the scripts and add a new .pk4 file. I suppose that if I achieve that then we can smooth a bit the merge of this feature :). Also, if you use r_swapInterval 0 then you can test even with a screen limited to only 60hz, you are going to notice the difference no matter what. Edit: I share to everyone here the compiled files for Windows 32 bits (including the pak009.pk4) , so anyone who wants to help with testing can do it. For people with screens that doesn't support more than 60hz, use r_swapInterval 0 (need to close and open the game again after doing it) |
This seems great, hope we can have it in dhewm 3. |
entering I just remembered that there already was some discussion about >60fps at #230 and also #15 (comment) - revelator says he has a timing-related fix from DarkMod, so it might be worth checking out what they did (unfortunately, his modified dhewm3 doesn't seem to be on Github). In the discussions there was something about Doom3 not properly running at 60fps, but 62.5, and it seemed that this was due to time being measured in integer(!) milliseconds. const int USERCMD_HZ = 60; // 60 frames per second
const int USERCMD_MSEC = 1000 / USERCMD_HZ; // 16 A frame should be 16.666.. ms, but the code uses 16 everywhere - and 1000/16 = 62.5 (instead of the desired 60) - that (combined with vsync) might lead to micro stuttering, I guess? I wonder if your changes here are affected by these problems? I'm not sure if that makes sense or is even possible in Doom3, but do you think we could continue to run the game logic at 60Hz, so scripts and (most of?) the code in the game DLL don't have to be changed, but render at a different rate (and probably update at least the camera so looking around feels smooth)? It sounds like it should work at multiples of 60Hz (like 120Hz), but what if someone tries running the game at 90Hz or 144Hz or 165Hz - will stuttering get even worse then? |
… order to avoid having to use custom pak content
I have good news, I added a new commit that lets us use this feature without having to add a new pak file. Build for windows 32bits (This one does not require the extra pak009.pk4 anymore) |
I did a new commit based on that problem, I believe with the new framerate being float instead of int the improvement should be important. In my end I notice some improvement but I would prefer more people to test it before coming to conlusions too fast. |
This is the last build of this pull request. (Win32 binaries), This is for anyone who wants to test the feature. |
I looked at TheDarkMod very briefly and while it seems like they did some timing changes (using microseconds instead of milliseconds in a few places, apparently to get real 60fps instead of 62.5), it seems like it's still limited to 60Hz so it's not super helpful for >60Hz support. I'll also look at D3BFG and I'll also try to understand how exactly a frame in Doom3 works, esp. what part of it happens in the game DLL. (If all else fails we could just run at 60Hz and display 120 in the framecounter :-D) For testing your current solution it might make sense check if the stuff that was broken with
It probably also makes sense to grep the whole engine and gamecode for "60" and "16", in case hardcoded values (instead of USERCMD_HZ and USERCMD_MSEC) are used somewhere (of course not every "60" or "16" in the code should really be one of those constants, we'd have to check every occurrence) |
Ok, looks like TDM supports 120Hz after all, you gotta search for "uncapped framerate" or "uncapped fps" apparently. I created a git mirror of their SVN repo in case anyone is interested in looking at single commits mentioned in the bugreports: https://github.com/DanielGibson/thedarkmod-mirror |
Thank you for the mirror! If you wanna see the bleeding edge TDM stuff, go here: https://github.com/fholger/thedarkmod We're (TDM) mostly out of the woods with regard to high-FPS bugs but we probably could have saved ourselves a lot of hassle by simply modifying the core HZ attributes as our new developer Cabalistic did in his branch prior to joining (same dev who maintains the above repo). Duzenko ( the developer who began uncapped FPS work ) was impatient to start because he was trying to solve a different timing issue for low FPS scenes and capped FPS was impeding that work. (Eg. That initial implementation had lots of problems.) We have been fortunate that a few outside (and very skilled) contributors mysteriously arrive to fix some of the physics and game bugs (then return to the shadows). |
…ysics with player not working correctly
Thank you all for the talk and info, and also thanks to someone who was testing the build and giving me feedback I added a new commit that should fix a problem related to game physics running a bit more faster than the original game. Also this build is supposed to remove the original mircostutter problem present in vanilla doom 3. |
@@ -604,6 +605,8 @@ void idGameLocal::SaveGame( idFile *f ) { | |||
savegame.WriteBool( isMultiplayer ); | |||
savegame.WriteInt( gameType ); | |||
|
|||
savegame.WriteFloat(preciseTime); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this breaks savegame compatibility :-(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for letting me know this. I will try to find a way to avoid that, in fact I was looking at the BFG Edition code like a lot, and there are many things that I don't like about this pull request after looking at that. So I will try to find a way to improve this or actually try this again but most similar to the BFG Edition approach.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the best way to do this is to bump BUILD_NUMBER
and in idGameLocal::InitFromSaveGame()
you can check savegame.GetBuildNumber()
and only if it's the new number you read preciseTime, otherwise you set preciseTime to some sane default value.
@@ -334,6 +334,7 @@ void idGameLocal::Init( void ) { | |||
//Update MSEC and gameFps | |||
gameFps = cvarSystem->GetCVarInteger("com_gameHz"); | |||
msec = 1000.0f / cvarSystem->GetCVarFloat("com_gameHz"); | |||
msec *= 0.96f*0.96f; //HACK to emulate OG D3 msec error, in order to have exactly the same game logic speed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why 0.96f*0.96f
?
I get that 16 / 16.666 == 0.96
, but why square it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That was a mistake from me. I thought that I needed to do that twice because common frame was already working at 16.666 hz, but multiplying by 0.96f twice was a mistake.
In fact that product for 0.96f is something I don't like at all. It is some kind of "duct-tape" ugly code. I will look at this feature in some days or weeks in order to see if with a fresh mind I can actually figure out something better.
@@ -309,6 +310,10 @@ void idGameLocal::Init( void ) { | |||
const idDict *dict; | |||
idAAS *aas; | |||
|
|||
msec = 16.0; //60fps |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please put a space after "//", e.g. // 60fps
(yes, always, not just here), like it's done in the existing code
(it also just looks better)
Thanks for reviewing the code, but tbh with you there are some physics and game logic strange bugs that still I need to fix and I believe that is mainly because my approach probably is not the best at all. Sadly I must admit when what I am doing is not quite right and this is one of these times. Hopefully maybe this failed attempt will encourage others to actually try this. I am no saying to close this but I am saying that this is not quite right, not even close, to consider a pull request. There is stuff to fix and probably when I have more free time I will try to look for another approach. |
Hey, sorry to hear it doesn't work as well as we hoped! Can you write down what bugs you ran into? I think that'd be super-useful to know in case someone else would like to try to fix your approach, or to make sure that other approaches don't have the same issues - or just for yourself when you get back to this later and maybe forgot about the specific bugs :) I turned this pull request into a draft so it's clear that it's not done yet, but I'd otherwise leave it open as I think this contains good information - even if it turns out that indeed a different approach is needed I imagine that some of your changes are still useful - and if it's just to see what things in the code need to be changed for this. I'm sure we'll come up with a working solution eventually, when we have some more time! :-) |
Seems that I've founded a way to solve this crash (temporal fix). The idtech4 (dhewm3) engine have a lot of instability when you play in 144Hz/144FPS mode (or another Hz/FPS different to 60Hz/FPS). Until now, I've played a lot in 120Hz/120FPS mode and right now I'm in the Alpha Labs Sector 4 with no issues. I hope this help to contribute a little more to find a better way to reach the unlocked FPS feature. |
If CPU affinity helps it then it could be related to #169. |
I'm just a random passerby but I'm completely missing on the sense of this PR. If you want v-sync then (putting aside all the fancy nuances that has today), that should be a completely separate matter until the user decides they want it. |
The point is that Doom 3 (and thus also dhewm3) assumes a max framerate of 60hz throughout the code and within the scripts. Rendering more frames breaks things badly. There are several approaches to solve that problem, however none of them is easy to implement. This PR is one of them. Being able to render more frames would be nice, because these days 60hz is the lower end of the spectrum. Even if we can reach only 120hz, it would be a big improvement. VR probably needs 240hz or even more... |
Hello and thanks for your work! Is there a way to implement this functionality in dhewm 1.5.2? 1.5.1 has severe visual bugs when playing with D3HDP |
I second Zhnigo's comment, I too was trying to get your patch working on 1.5.2 cause of D3HDPv2 (best graphical overhaul out there imo), but - alas - to no avail.. com_fixedTic -1 doesn't really do much for smoothness like "unlockedFPS" does, unfortunately :') |
What's the perceivable difference? |
I think it's a frame pacing issue, 'cause fixedTic -1 feels like 60hz (or worse!), no matter what: I tried with the game running unlocked at a thousand FPS, or with it limited at various FPS stages (90, 120, 144, 175, 240 - depending on the set monitor's refresh rate) through nvidia's control panel, or nvidia's inspector (which should be the same..), or RTSS (again, should be the same as the control panel). .. whereas with Stradex's patch, it feels exactly like BFG's 120hz mode: perfectly sync'd, smooth and responsive, like in a competitive FPS. I recently replayed through the whole game on 1.5.1 with this patch and - apart from the memory leak (?) issue that requires you to restart the game every now and then to avoid it getting locked at 25 FPS and the oxygen getting depleted faster on a couple of outside segments of the game (not even all of them) - it was amazing. |
I decided to take matters into my own hands and ported Stradex's source into dhewm3 1.5.2 . To anyone landing here from pcgamingwiki or wherever, just check out my repo: https://github.com/simonedibilio/dhewm3/tree/unlocked-fps-rw-dhewm3-1.5.2 Peace ✌️ |
Thanks. After comparing it's clear how Stradex's patches are much smoother than com_fixedTic -1. And you made RoE work too! |
And - as of saturday - The Lost Mission too! :) |
Hi! Thanks a lot for doing it. I've been really busy lately sadly and I am not finding time to work with Doom 3 stuff anymore :( But it makes me happy to see that some of the stuff I did still serve some purpose, I am sorry for not porting it to Dhewm3-1.5.2 myself but I am glad you did. |
Sir, you are doing God's work, much appreciated for this contribution. However, there are two major bugs:
|
hey! thank you for taking the time to report these issues; I'd ask - if you don't mind - to move the discussion to the "issues" section on my repo, so that we can keep track of these problems there :) |
No problem! |
I am really glad to see that there is still interest in making DOOM 3 run with a high refresh rate, just like in BFG Edition! Running TDM with a high refresh rate and FPS is a dream come true, so I'm looking forward to having that implemented in dhewm3! |
Since 1.5.3 is out, can this be ported to the newest version as well? |
I created a pull request based on this with additional fixes: #584 |
Note: A simpler approach would be replacing "#define GAME_FPS 60" and the similar defines for GAME_FRAMETIME and CHAINGUN_FIRE_SKIPFRAMES in the scripts with other values based on com_gameHz, for example to "#define GAME_FPS 144". However, that would have two disadvantages: 1. When changing com_gameHz, you'll have to reload the scripts 2. This changes the checksum of the scripts, so each time you change com_gameHz the checksum changes and your old savegames stop working. Luckily the scripts already have functions (that are implemented in the gamecode) that expose the FPS and FrameTime: sys.getTicksPerSecond() and sys.getFrameTime() So now we modify the #defines to call those functions instead. That will still break *old* savegames, but at least savegames made from now on will still work no matter what you set com_gameHz to. TODO: A problem with this approach is that the time sys.getFrameTime() returns is scaled when in slow motion, so I'll probably have to add another function for that This code is partly based on code from Stradex' "Add com_gameHz to play with higher HZ/FPS" PR: dhewm#297
Note: A simpler approach would be replacing "#define GAME_FPS 60" and the similar defines for GAME_FRAMETIME and CHAINGUN_FIRE_SKIPFRAMES in the scripts with other values based on com_gameHz, for example to "#define GAME_FPS 144". However, that would have two disadvantages: 1. When changing com_gameHz, you'll have to reload the scripts 2. This changes the checksum of the scripts, so each time you change com_gameHz the checksum changes and your old savegames stop working. Luckily the scripts already have functions (that are implemented in the gamecode) that expose the FPS and FrameTime: sys.getTicksPerSecond() and sys.getFrameTime() So now we modify the #defines to call those functions instead. That will still break *old* savegames, but at least savegames made from now on will still work no matter what you set com_gameHz to. TODO: A problem with this approach is that the time sys.getFrameTime() returns is scaled when in slow motion, so I'll probably have to add another function for that This code is partly based on code from Stradex' "Add com_gameHz to play with higher HZ/FPS" PR: dhewm#297
Note: A simpler approach would be replacing "#define GAME_FPS 60" and the similar defines for GAME_FRAMETIME and CHAINGUN_FIRE_SKIPFRAMES in the scripts with other values based on com_gameHz, for example to "#define GAME_FPS 144". However, that would have two disadvantages: 1. When changing com_gameHz, you'll have to reload the scripts 2. This changes the checksum of the scripts, so each time you change com_gameHz the checksum changes and your old savegames stop working. Luckily the scripts already have functions (that are implemented in the gamecode) that expose the FPS and FrameTime: sys.getTicksPerSecond() and sys.getFrameTime() So now we modify the #defines to call those functions instead. That will still break *old* savegames, but at least savegames made from now on will still work no matter what you set com_gameHz to. TODO: A problem with this approach is that the time sys.getFrameTime() returns is scaled when in slow motion, so I'll probably have to add another function for that This code is partly based on code from Stradex' "Add com_gameHz to play with higher HZ/FPS" PR: dhewm#297
Note: A simpler approach would be replacing "#define GAME_FPS 60" and the similar defines for GAME_FRAMETIME and CHAINGUN_FIRE_SKIPFRAMES in the scripts with other values based on com_gameHz, for example to "#define GAME_FPS 144". However, that would have two disadvantages: 1. When changing com_gameHz, you'll have to reload the scripts 2. This changes the checksum of the scripts, so each time you change com_gameHz the checksum changes and your old savegames stop working. Luckily the scripts already have functions (that are implemented in the gamecode) that expose the FPS and FrameTime: sys.getTicksPerSecond() and sys.getFrameTime() So now we modify the #defines to call those functions instead. That will still break *old* savegames, but at least savegames made from now on will still work no matter what you set com_gameHz to. TODO: A problem with this approach is that the time sys.getFrameTime() returns is scaled when in slow motion, so I'll probably have to add another function for that This code is partly based on code from Stradex' "Add com_gameHz to play with higher HZ/FPS" PR: dhewm#297
Note: A simpler approach would be replacing "#define GAME_FPS 60" and the similar defines for GAME_FRAMETIME and CHAINGUN_FIRE_SKIPFRAMES in the scripts with other values based on com_gameHz, for example to "#define GAME_FPS 144". However, that would have two disadvantages: 1. When changing com_gameHz, you'll have to reload the scripts 2. This changes the checksum of the scripts, so each time you change com_gameHz the checksum changes and your old savegames stop working. Luckily the scripts already have functions (that are implemented in the gamecode) that expose the FPS and FrameTime: sys.getTicksPerSecond() and sys.getFrameTime() So now we modify the #defines to call those functions instead. That will still break *old* savegames, but at least savegames made from now on will still work no matter what you set com_gameHz to. TODO: A problem with this approach is that the time sys.getFrameTime() returns is scaled when in slow motion, so I'll probably have to add another function for that This code is partly based on code from Stradex' "Add com_gameHz to play with higher HZ/FPS" PR: dhewm#297
Note: A simpler approach would be replacing "#define GAME_FPS 60" and the similar defines for GAME_FRAMETIME and CHAINGUN_FIRE_SKIPFRAMES in the scripts with other values based on com_gameHz, for example to "#define GAME_FPS 144". However, that would have two disadvantages: 1. When changing com_gameHz, you'll have to reload the scripts 2. This changes the checksum of the scripts, so each time you change com_gameHz the checksum changes and your old savegames stop working. Luckily the scripts already have functions (that are implemented in the gamecode) that expose the FPS and FrameTime: sys.getTicksPerSecond() and sys.getFrameTime() So now we modify the #defines to call those functions instead. That will still break *old* savegames, but at least savegames made from now on will still work no matter what you set com_gameHz to. TODO: A problem with this approach is that the time sys.getFrameTime() returns is scaled when in slow motion, so I'll probably have to add another function for that This code is partly based on code from Stradex' "Add com_gameHz to play with higher HZ/FPS" PR: dhewm#297
This basically allows the player to set the amount of HZ/FPS they want the game to run. Making it a bit like BFG Edition in that aspect.
The cvar to use is com_gameHz. by default it is 60 (original), but you can change the values, but after you change the value you actually need to close and open the game again in order to see it working.
BTW this requires a new custom pak that should be put at base folder in order to play it. Because it requires to update the GAME_FPS and GAME_FRAMETIME from the scripts def in order to match the com_gameHz values dinamically.
I can upload the binaries for Windows 32 bits if someone actually wants to test it. (idk if github allows me to drag zips with .dll and .exe files)
pak009.zip