fabiangreffrath / crispy-doom

Crispy Doom is a limit-removing enhanced-resolution Doom source port based on Chocolate Doom.
https://fabiangreffrath.github.io/crispy-homepage
GNU General Public License v2.0
802 stars 132 forks source link

FPS capping while paused / non-playable game states #324

Closed JNechaevsky closed 6 years ago

JNechaevsky commented 6 years ago

Since we have taking a good way of rejecting full uncapping, I would like to suggest yet another one, maybe a bit fanatical step - reducing fps to 35 in some non-playable game states.

Possible benefits

Less CPU usage = less noise... Oh, should I really say that again? In other words: don't need to abuse CPU in the states, where it's really not necessary. Let's take care about hardware and thermal grease.

Let's see a difference in CPU usage on simple and extreme detailed places:

Note: CPU usage value is always floating about 1%.

Approach

Please take a look at my current approach as a template (there are no gamestate conditions yet): https://github.com/JNechaevsky/russian-doom/commit/675d921963750a0057a3e9fa5f9e8d203e04165f

Switching between 35/60 fps does not seems to have a notable delay, despite of both FPS counters (IDRATE and video capturing software) are indicating it. Just try to run with full speed and pause/unpause the game, you will not see any framerate changes. Hopefully.

What should be capped?

What should not happen

Notable slow down of fuzz effect by changing 60 fps to 35 fps. It's looking aesthetically awful! But you are already taking care about fuzz, eh? :)

Also beware, Heretic and Hexen are using MenuActive instead of menuactive, that's why I have made a full replacements in commit from above.

Taking full responsibility to declare this is a suggestion №94

JNechaevsky commented 6 years ago

Game state GS_LEVEL seems to the only necessary for interpolation. Here's how I done it: https://github.com/JNechaevsky/russian-doom/commit/5ad3a7b5d875603637c2de15dd2e2d9cc2cf66ac

Not sure it will be good for Crispy, because I've made gamestate_t global. But it's same for all three (d/h/h) games, though.

SoDOOManiac commented 6 years ago

non-playable game states

Demo playback is also a non-playable game state, but it shouldn't cap the framerate.

JNechaevsky commented 6 years ago

Demos are interpolated in this approach. Have to rephrase a bit: not a "non-playable", but "where is no level running" ... should not be interpolated.

SoDOOManiac commented 6 years ago

Notable slow down of fuzz effect by changing 60 fps to 35 fps. It's looking aesthetically awful! But you are already taking care about fuzz, eh? :)

This has already been taken care of ;)

fabiangreffrath commented 6 years ago

because I've made gamestate_t global.

Sorry, but this won't happen.

JNechaevsky commented 6 years ago

Waked up with thought - if gamestate_t is an enum, there is no need to move anything. This seems to be working fine in Crispy:

void TryRunTics (void) @ d_loop.c

    int realtics;
    int availabletics;
    int counts;
+++ extern int gamestate;

...

        // [AM] If we've uncapped the framerate and there are no tics
        //      to run, return early instead of waiting around.
        if (counts == 0 && crispy->uncapped && gametic && screenvisible &&
+++         gamestate == 0) // <-- [JN] Assuming GS_LEVEL
            return;

Could you please take a try on your side?

Edit: ideally, take a try to run with fps indication software. There are couple of such stuff for Windows, but I don't any for Linux. :\

fabiangreffrath commented 6 years ago

Maybe I can convice the other Choco devs to move enum gamestate_t to the top-level src/d_mode.h header. Then, your proposed solution would be feasible.

JNechaevsky commented 6 years ago

Sounds fair, glad you liked the idea. Original Doom sources are having gamestate_t enum along with other global variables, like skill levels and etc, so it should fir to the Chocolate Phylosophy: https://github.com/id-Software/DOOM/blob/master/linuxdoom-1.10/doomdef.h#L124

fabiangreffrath commented 6 years ago

I think I have found an even better way to check for

!paused && (!menuactive || demoplayback || netgame) && gamestate == GS_LEVEL

We just need to check if leveltime keeps tickin'. So, I'll introduce a new variable oldleveltime and set this to the value of leveltime, before the latter gets increased in G_Ticker() by calling P_Ticker() if gamestate == GS_LEVEL. The point is, if the game is paused or in a different gamestate, P_Ticker() will return early and the two values will remain the same.

fabiangreffrath commented 6 years ago

crispy-oldleveltime2.zip

JNechaevsky commented 6 years ago

Ah, leveltime > oldleveltime looks likes an interesting technical approach and idea, but a bit complicated for me. Okay, I'll check it in the evening with OSD fps indicator. States to check (some of them are same game states, but I still want to make a 100% proper checking):

JNechaevsky commented 6 years ago

Finished all my tests - well done, it's working fine! While applying your patch, I've starting to get the idea, and now it seems very proper. :thumbsup:

Hovewer, while testing, I have noticed one odd bug. Please try to do following:

:heavy_exclamation_mark: Both projectiles and missiles are seems to be flying through the head, and needles to say it's a not a vanilla behavior. Reverting oldleveltime changed does not fix this case, and I'm not sure why this is happening.

fabiangreffrath commented 6 years ago

Finished all my tests - well done, it's working fine! While applying your patch, I've starting to get the idea, and now it seems very proper.

Thank you very much for testing! I'll apply this later today with some subtle changes.

Hovewer, while testing, I have noticed one odd bug

Crap! What is this and when did it start?!

JNechaevsky commented 6 years ago

Crap! What is this and when did it start?!

Absolutelly no idea, just noticied it yesterday. Could it be because of introduced flipping flag? Maybe something got messed up with thing/flag bits?

fabiangreffrath commented 6 years ago

I am also puzzled. Need to find out the latest release without this glitch so I can do a git-bisect.

fabiangreffrath commented 6 years ago

Erm, does this also happen if you use the teleport instead of no-clipping through the walls?

JNechaevsky commented 6 years ago

Will check in three hours on dinner break. Additionaly, I'll need to do this:

SoDOOManiac commented 5 years ago

Additionaly, I'll need to do this: Walk with noclip to the room with Icon Save and load game Check Icon's clipping

@JNechaevsky After commit https://github.com/fabiangreffrath/crispy-doom/commit/6cfe557765cf1e7afdd02e6fa8f937ed6d1acf9a, when I did this, I discovered that 1) upon loading game the Romero alert sound is played again, even though I alerted him before while noclipping and 2) the head becomes invulnerable to bullets!

fabiangreffrath commented 5 years ago

1) upon loading game the Romero alert sound is played again, even though I alerted him before while noclipping and

That's expected. We need to re-awake the brain after loading a game, so it can re-evaluate its numbraintargets value to prevent a division by zero error later on.

2) the head becomes invulnerable to bullets!

This should be the old behaviour with direct aiming on. After the commit you point to, the bullets should hit!

SoDOOManiac commented 5 years ago

This should be the old behaviour with direct aiming on. After the commit you point to, the bullets should hit!

After loading the savegame it's actually even worse than old behavior: the old behavior is that you can hit the base of the stick to hurt the head, but here you cannot hurt it with bullets at all! Here's the savegame. doomsav0.zip

JNechaevsky commented 5 years ago

Hm. Can't confirm with permanent mouse look + direct aiming with current compiled sources, everything is fine for me in @Zodomaniac's attached saved game.

SoDOOManiac commented 5 years ago

@JNechaevsky because there had been a fixing commit since then, I guess. Could you pls send me your build?

JNechaevsky commented 5 years ago

Here you go: crispy-16.01.2019.zip

fabiangreffrath commented 5 years ago

because there had been a fixing commit since then, I guess.

Yep, this is the commit that is supposed to fix this issue: https://github.com/fabiangreffrath/crispy-doom/commit/8b8296a14700aeefa9ed7bb3b5b59cb808471112

I could have added something similar to the savegame loading code, but this seemed cleaner to me.