Author Topic: FF7's Broken FPS Limiter Part 10  (Read 2819 times)

DLPB_

  • Banned
  • *
  • Posts: 11006
    • View Profile
FF7's Broken FPS Limiter Part 10
« on: 2015-02-20 14:24:22 »
Yup, it's been well over 2 years since this issue was first discussed at any length and we still sit here with a broken limiter.  The Battle fps issue is usually disguised because it's only 15fps, but once you make it 60, you soon see that it is dropping to around 57.  The only fix so far is to set the limiter to 63 so that it achieves ~60.  Not good.

The world map does not seem to suffer from these issues.

The field does.  The field also has an extra subtraction in its code that further affects the fps.  But even removing that will still mean you don't really get a true 30fps.

And these issues are made worse when recording using dxtory/fraps... where you will never achieve the target fps (unless you set the limiter of FF7 to say 120, and let fraps dxtory do the limiting).

This is not an issue of cpu power... it's broken limiter code.  I've had a look and it's well beyond me.  But such a fundamental problem with the game needs some sort of response. Dziugo's last message to me on this before he went awol was that he was fixing it up.  The only thing that has been said about the limiter (for field) is this:

Ok, I might know what's going on. First of all, this is how the original frame limiting (mostly) works: info about frame limiting. It's from old times, but should still be (mostly) valid.

Read it? Good. Now about the subtraction - look how (theoretically) a main loop could be constructed:
Code: [Select]
while (notEnd) {
   doStuff1();
   doStuff2 { // dynamic function, calling address changes depending on the module we're in
      startTheRDTSCTimer();                                 A
      doStuff2a(); // here the actual processing work
      idleUntilRDTSCReachesTheDesiredValue();               B
      doStuff2b(); // here some other work
   }
   doStuff3();
}
So, the game makes sure that the time between A and B is at least the time it calculated the frame processing should take... Wait a minute! What about the time it takes to get from B to A again? That's assumed to be exactly 10000 RDTSC ticks (for field).

This could affect the FPS slightly (now I see what you mean). One could correct it (slightly ;p) by moving the B just before A, or actually modding the limiter to take into account at least the last frame processing time (each additional frame will add precision, but with exponentially lowering results - something like 4-5 frames should be enough).

Quote
Ok, got it to run at exactly 30.0 FPS (average of last 3 frames). I've merged A+B into one point, and made it CPU frequency independent, all that with just timeGetTime. Now, time to make it actually usable... ;p

Side note (probably knew this already), Aali's FPS counter is not that accurate. It displays 30 even if the true FPS is 29.4.




The submarine battle may be sharing the same code as field / duplicating field code... as it suffers from the exact same issues.
« Last Edit: 2015-02-20 14:35:23 by DLPB »

halkun

  • Global moderator
  • *
  • Posts: 2097
  • NicoNico :)
    • View Profile
    • Q-Gears Homepage
Re: FF7's Broken FPS Limiter Part 10
« Reply #1 on: 2015-02-21 03:53:54 »
PS1 bases it's timing on root counters which are timers that fire very pixel clock, Hsync, and Vsync (Every dot, line and frame). We've tripped up on root counter code before that caused us grief.

DLPB_

  • Banned
  • *
  • Posts: 11006
    • View Profile
Re: FF7's Broken FPS Limiter Part 10
« Reply #2 on: 2015-02-22 16:04:38 »
How hard is it to fix this issue for PC so that it runs correctly?

halkun

  • Global moderator
  • *
  • Posts: 2097
  • NicoNico :)
    • View Profile
    • Q-Gears Homepage
Re: FF7's Broken FPS Limiter Part 10
« Reply #3 on: 2015-02-22 18:55:45 »
If I remember correctly the PC version does some wacky vsync stuff along with an internal timer that was impossible to decouple. Look back in the 60fps thread near the beginning and some info may be there if I remember.