viti95 / FastDoom

Doom port for DOS, optimized to be as fast as possible!
527 stars 33 forks source link

Use high precision timer for FPS #209

Closed tigrouind closed 2 months ago

tigrouind commented 2 months ago

Use high resolution timer (560 Hz) from @dougvj for counting FPS (when available). This considerably reduce wiggling, especially at high FPS.

I have also renamed the flag HIGH_PRECISION_FPS to SUB_FRAME_FPS at it was misleading. Accuracy is linked to timer resolution not the method used. That flag should only be used to get FPS measurement with one decimal or more. Method currently used for no decimal is better suited.

viti95 commented 2 months ago

A small bug I've found, the FPS counter can get stuck:

https://github.com/user-attachments/assets/d6c60840-1045-4297-ba04-02243cbc8638

tigrouind commented 2 months ago

No matter how hard I try, I can't reproduce this issue. Is this on real hardware (I guess it's made with DOSBOX). How much CPU cycles did you set ? I also don't understand how it can happen. Would it be possible for tick variable to overflow ?

viti95 commented 2 months ago

This is on DosBox-X and SUB_FRAME_FPS enabled, cycles are set to max. I have yet to try on real hardware.

tigrouind commented 2 months ago

OK, I see. I did not made any tests with SUB_FRAME_FPS enabled and high res timer. I will try to see what's wrong.

Note : It's not advised to use SUB_FRAME_FPS if no FPS decimals are required. I made some tests few weeks ago and it does not follow smooth curve (which is using FIR filter) as precisely as the other method.

viti95 commented 2 months ago

Aahhh ook, now I understand. The code without SUB_FRAME_FPS enabled is working perfectly fine.

tigrouind commented 2 months ago

I have fixed it. The reason why it fail it that we should start removing items once queue size is MAX_FPS-1 not MAX_FPS. Otherwise we cannot calculate the delta between frames properly. One consequence is that fps will be max 255 and no more 256 when SUB_FRAME_FPS is unused (it could use 2 code paths to prevent that but let's keep it simple).

Here is a chart that I made some weeks ago, red is SUB_FRAME_FPS off, blue is on, both with the 35 Hz timer. It might be subjective but I think red one is better. There is less wiggling.

SUB_FRAME_FPS is there because you initially calculated FPS with one decimal, something removed here.