Author Topic: Bugfixes and Queries  (Read 8082 times)

DLPB

  • No life
  • *
  • Posts: 8286
  • Karma: 223
  • ‘You know who I am,’ he said.
    • View Profile
Re: Bugfixes and Queries
« Reply #25 on: 2015-12-07 14:07:41 »
I am still looking at the frame limiter. The world map limiter is not the same... prob why it actually works.  Still...  It's gonna take time, if I can at all.

DLPB

  • No life
  • *
  • Posts: 8286
  • Karma: 223
  • ‘You know who I am,’ he said.
    • View Profile
Re: Bugfixes and Queries
« Reply #26 on: 2015-12-08 12:46:36 »
It looks like I am not going to have any success (I'll keep trying).  But I'll leave here what I think is going on and what Dziugo posted to me, in the hope someone else can figure this out.  I think I've found the same function that Dziugo was editing too.

As far as I can see, the reason the limiter isn't accurate and drops frames under heavier load is simply because the calculation is bad.  I remember when I programmed my own limiter for my own game using timegettime.  If it isn't done right, you'll get frame drops where there shouldn't be.  This is noticeable when trying to record games with something like Fraps. It will work perfectly if you set the frame rate of FF7 to 60 and then let fraps limit the game to 30 - but it will drop to 24-28 if you don't.   This isn't a problem with Fraps - it will happen with any high load (although game recording shows the bug up more).  For some people, attaining 30fps in normal play won't happen either.  This is also not fixed by Aali's driver - which uses timegettime / qpc.  Because it's the limiter that is broken and leading to this issue.

This is what Dziugo sent me:

How it works currently:
Quote
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).

Note that the 10000 RDTSC ticks actually mess things up further.  This is corrected when you do this >

7B7848 = 00 00 00 00 00 00 00 00 *note this part of the calculation is taken into account when going from a different module to field.  So, going from world map to field recalculates and uses this Double floating point value.

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
Quote
And then I ran out of time. I've nailed down the frame limiter for field (field is special as there are actually two framelimiters, it allows ff7 to make a little bit of frame-skipping) and most of the other modules. The rebuilt framelimiter (really simple one) works fine, although it didn't get much of testing

The function that seems to deal with the frame limiter is 6384E6.

The better news is that the world map limiter seems to work - so maybe can do a comparison?  The world map limiter is at 74C7E4. 
« Last Edit: 2015-12-08 16:38:13 by DLPB »

DLPB

  • No life
  • *
  • Posts: 8286
  • Karma: 223
  • ‘You know who I am,’ he said.
    • View Profile
Re: Bugfixes and Queries
« Reply #27 on: 2015-12-11 19:23:10 »
Ok I'm getting somewhere now.  The frame limiter above is probably not broken.  It basically keeps the game in a loop until a number of ticks has been satisfied.  It's very simple to reprogram despite how ridiculous the code looks above.

Unfortunately, that's not where the issue lies.  At least, not how I thought.  I am going to cook something up later!

NFITC1

  • No life
  • *
  • Posts: 2696
  • Karma: 59
  • I just don't know what went wrong.
    • View Profile
    • WM/PrC Blog
Re: Bugfixes and Queries
« Reply #28 on: 2015-12-11 20:15:37 »
Like I PMed you, it's got to be based on TimeGetTime to be accurate. RDTSC is unusable on modern CPUs. Instead of looping until the ticks are done, it SHOULD be pre-rendering the next frame (unless that's what it's waiting on).

obesebear

  • Administrator
  • No life
  • *
  • Posts: 3215
  • Karma: 109
    • View Profile
Re: Bugfixes and Queries
« Reply #29 on: 2015-12-11 20:16:06 »
Good luck!

DLPB

  • No life
  • *
  • Posts: 8286
  • Karma: 223
  • ‘You know who I am,’ he said.
    • View Profile
Re: Bugfixes and Queries
« Reply #30 on: 2015-12-11 20:43:28 »
Like I PMed you, it's got to be based on TimeGetTime to be accurate. RDTSC is unusable on modern CPUs. Instead of looping until the ticks are done, it SHOULD be pre-rendering the next frame (unless that's what it's waiting on).

It's a silly system...  it's not doing what a normal limiter does.  It's keeping the game in a while loop for a period of ticks before letting it carry on.  I've never seen something like that before.  If it's simply incrementing ticks in that function, then that's also a weird way of doing it.  When using TGT or QPC, there is no increment... it's done independently of the function.  I should be able to quite easily fix this up with a TGT or even QPC.  And it should work fine.

NFITC1

  • No life
  • *
  • Posts: 2696
  • Karma: 59
  • I just don't know what went wrong.
    • View Profile
    • WM/PrC Blog
Re: Bugfixes and Queries
« Reply #31 on: 2015-12-11 21:53:20 »
QPC is the "correct" way to go as TGT is OS clock dependent and QPC is more CPU cycles dependent. QPC is the more modern version of TSC and still has to be calibrated prior to use.

At best you'd want a timer with better than 16.6 ms resolution. TGT gets 1 ms precision at best and QPC is measured in μs.

Optimally there'd be a single timer thread in the background that's sending signals back to the draw thread to display what it has ready and begin processing the next frame. (V-Sync, anyone?) HOWEVER, since FFVII has THREE graphics modes (15, 30 and 60 fps) it can't rely on a fixed timer. It's always adjusting it when transitioning from one module to the next.

DLPB

  • No life
  • *
  • Posts: 8286
  • Karma: 223
  • ‘You know who I am,’ he said.
    • View Profile
Re: Bugfixes and Queries
« Reply #32 on: 2015-12-11 22:08:23 »
TGT doesn't have the same issue that the older method does - and I think the way they did this limiter was completely bollocks anyway.  You're right that TGT is close to 1ms (when timebeginperiod(1) is called), but that should be good enough when your target rate is 30fps.

QPC has issues with older  CPU but shouldn't with the massive majority out now.

QPC is already there at CFF8D8, so that's convenient (aali's driver prob adds that support).
« Last Edit: 2015-12-11 22:25:46 by DLPB »

DLPB

  • No life
  • *
  • Posts: 8286
  • Karma: 223
  • ‘You know who I am,’ he said.
    • View Profile
Re: Bugfixes and Queries
« Reply #33 on: 2015-12-12 15:56:56 »
The frame limiter is fixed - it will give a perfect 30 (or 60 in battle) recording or otherwise.  The scroll, like at Wallmarket is also now great.  And it should be v easy to export this to Steam and to all other problem areas.


 8-) 8-) 8-) 8-) 8-) 8-) 8-) 8-) 8-) 8-) 8-)

This is how you fix it:

Code: [Select]
StartQpc:= currentqpc;
DeltaQPC := StartQPC - LastQPC;

While (Deltaqpc + CurrentQPC) - startqpc < clocktarget do
begin
// do nothing.  Effectively suspend play.
end;

LastQPC:= CurrentQPC;

The delta time was not being correctly factored in with the old process.  Clocktarget is the number of Qpc ticks a second * 30, for field.  It's saved at cff890.
« Last Edit: 2015-12-12 16:54:20 by DLPB »

obesebear

  • Administrator
  • No life
  • *
  • Posts: 3215
  • Karma: 109
    • View Profile
Re: Bugfixes and Queries
« Reply #34 on: 2015-12-12 17:20:27 »
Dude.  Congrats.  I know this has been bugging you for a long time.

DLPB

  • No life
  • *
  • Posts: 8286
  • Karma: 223
  • ‘You know who I am,’ he said.
    • View Profile
Re: Bugfixes and Queries
« Reply #35 on: 2015-12-12 17:37:30 »
Dude.  Congrats.  I know this has been bugging you for a long time.

Thanks man!

And yeah, it has!!!!

it's a definite improvement, as you'll see.  Much smoother.  Even the screen fades.

Cyberman

  • No life
  • *
  • Posts: 1571
  • Karma: 8
    • View Profile
Re: Bugfixes and Queries
« Reply #36 on: 2015-12-26 15:36:09 »
The frame limiter is fixed - it will give a perfect 30 (or 60 in battle) recording or otherwise.  The scroll, like at Wallmarket is also now great.  And it should be v easy to export this to Steam and to all other problem areas.


 8-) 8-) 8-) 8-) 8-) 8-) 8-) 8-) 8-) 8-) 8-)

This is how you fix it:

Code: [Select]
StartQpc:= currentqpc;
DeltaQPC := StartQPC - LastQPC;

While (Deltaqpc + CurrentQPC) - startqpc < clocktarget do
begin
// do nothing.  Effectively suspend play.
end;

LastQPC:= CurrentQPC;

The delta time was not being correctly factored in with the old process.  Clocktarget is the number of Qpc ticks a second * 30, for field.  It's saved at cff890.
I have to ask (LOL) why isn't it using the Vsync event at all?
Swaping rendered buffers is what it is for. I'm pretty sure the PS1 version does that (I could be wrong though).
That would make it asynchronous. What they are doing is consuming lots of time with looping (software timing is very poor in accuracy). And trying synchronise timing.
Most of the time you create threads that handle different sets of event processing on the PC however it may have been old enough for the PC microsoft hadn't implemented threads (win32 / win95-98 era?).
Anyhow I digress, congratulations. Remember Square I don't believe did the porting and according to halkun they didn't have the released PS1 code as their base for the port.
Many of the PC bugs didn't exist in the PS1 (likely because on the PS1 they would have used the vsync event by setting a bit in an ISR then having an event loop check it and swap the frame buffer viewed and do the next image of the frame). Swaping the buffer frame likely would take micro seconds durring the vsync interval.

Unfortunately I doubt you can do this with how the constructed the PC version of the game without some major adjustment to the original code.

Cyb

DLPB

  • No life
  • *
  • Posts: 8286
  • Karma: 223
  • ‘You know who I am,’ he said.
    • View Profile
Re: Bugfixes and Queries
« Reply #37 on: 2015-12-26 22:17:31 »
Vsync does affect delta time (if enabled, of course)...and will limit the game if the limiter does not (so if your maximum refresh rate is 60, the best fps you will get is 60.  But since no module (field etc) goes over that, most players are unaware of that limit).

In other words, if you had no code above at all, your refresh rate was 60, and vsync enabled... the whole game would run at 60 (meaning field, battle, world map would be incorrect speed without fixes... and the menu would be fine).

DLPB

  • No life
  • *
  • Posts: 8286
  • Karma: 223
  • ‘You know who I am,’ he said.
    • View Profile
Re: Bugfixes and Queries
« Reply #38 on: 2015-12-30 05:25:22 »
Anyone wanting to change texture placements on screen in chocobo minigame the function to search is call 0077A469

With that you can see the table address above it, which includes its ID and X Y pos.

DLPB

  • No life
  • *
  • Posts: 8286
  • Karma: 223
  • ‘You know who I am,’ he said.
    • View Profile
Centre the Field.
« Reply #39 on: 2016-05-17 03:18:56 »
For 1998 English game using latest Aali's driver, this is how:

#These 4 entries shift the field down (all layers).
640C77 = B8 E8 00 00 00
640FD4 = B8 E8 00 00 00
641397 = B8 E8 00 00 00
{Aali's latest driver}
10045A32 = BB E8 00 00 00

# offset screen Y by 16 pixels.
CFF1E4 = 10 00

#Shift cursor down 16 pixels.
CFF200 = F0 00

# offset FADE in/out Y by 16 pixels.
CFFAE0 = 10 00

That's not to say I am confident that this is complete.  But a few testers would go a long way.  It does look ok.  But who knows?  It's hard to tell! 

The FMV isn't centred yet - but that shouldn't be much of a problem. 

The Steam version of the game needs AF3DN.p patching. The memory addresses move, so here is the file address:

C6B2 = BB E8 00 00 00
« Last Edit: 2016-05-18 15:39:18 by DLPB »

5way

  • Crazy poster
  • *
  • Posts: 160
  • Karma: 15
    • View Profile
Re: Bugfixes and Queries
« Reply #40 on: 2016-05-18 01:47:48 »
That's awesome but is there any chance to shift the fields down in the 2012/Steam version ?

DLPB

  • No life
  • *
  • Posts: 8286
  • Karma: 223
  • ‘You know who I am,’ he said.
    • View Profile
Re: Bugfixes and Queries
« Reply #41 on: 2016-05-18 02:10:14 »
That's awesome but is there any chance to shift the fields down in the 2012/Steam version ?

It uses Aali's driver, so yeah, it's possible.  But it means having to find the correct place in it (pretty easy) - like with Aali's 1998 driver.  It is getting out of hand having to support Reunion for both, though.  Esp since it's possible to just convert.  But for now I'm willing to support both. 

DLPB

  • No life
  • *
  • Posts: 8286
  • Karma: 223
  • ‘You know who I am,’ he said.
    • View Profile
No Field Borders... almost
« Reply #42 on: 2016-05-18 03:15:25 »
We'd be far better off if we had Aali's driver source.

This isn't fully tested, but it does look like it works (I assume this is gonna fail somewhere because I can't see why there is a calculation at all, if these values were meant to be 0 and 1 originally :P.  I am testing that.) 

It isn't ideal since the FMV will never work properly with a full screen - and some fields don't have enough data to satisfy the areas where the black bars go. But....

Basically... this is what to do:

Code: [Select]
{No field borders by DLPB

#Extend layer range
640C77 = B8 F0 00 00 00
640FD4 = B8 F0 00 00 00
641397 = B8 F0 00 00 00
10045A32 = BB F0 00 00 00

#cursor
CFF200 = 00 01

# Fade in/out
CFFAE8 = E0 01

#Stop screen resolution being changed to 448 - and force 480 in Aali's driver.
This isn't a problem since World map uses 480 regardless.
100483C7 = 90 90 90 90 90 90
1008f178 = E0 01

But here's the issue.  These 2 floating point values have to be the following with field:

10085534 needs to be set to 0.93333
10085554 needs to be set to -0.066667

BUT the following with world map:

10085534 needs to be set to 1
10085554 needs to be set to 0

So the question is how to get the game to calculate 2 different values depending on WM/Field
Made more annoying by the fact Aali's driver is handling it.

The calculations are probably supposed to be this for field:

448 / 480 = 0.93333

and

-16 / 240 = -0.067

But these are becoming 480 / 480 = 1 at 100484CE

and 0 / 240 = 0 at 10048543.

Actually, the above is EXACTLY how it should be.



« Last Edit: 2016-05-18 15:27:31 by DLPB »

DLPB

  • No life
  • *
  • Posts: 8286
  • Karma: 223
  • ‘You know who I am,’ he said.
    • View Profile
Re: Bugfixes and Queries
« Reply #43 on: 2016-06-16 00:17:42 »
It seems opcode 28 - KAWAI is broken in PC game.  As a consequence there are a number of errors - including:

1. Treasure chests do not return to the correct colour after collecting them. The shine effect is stupid regardless - to turn it off they set the shine to 2. So that brightens the object - to fix this they then use the same opcode to reset the colour after stopping shine.  This is failing on treasure chests.

https://www.youtube.com/watch?v=6mEqB5_oUwE&t=54m10s  Note that the chest colour change fails, so it stays bright.

2. Materia does not shine correctly.

I can't fix it.

Unless someone out there feels up to the task of reverse engineering that opcode - the best thing to do is to just remove all shine / colour change operations completely.
« Last Edit: 2016-06-16 00:31:27 by DLPB »

DLPB

  • No life
  • *
  • Posts: 8286
  • Karma: 223
  • ‘You know who I am,’ he said.
    • View Profile
Re: Bugfixes and Queries
« Reply #44 on: 2016-06-16 00:37:57 »
Can I share my frustration here too? This game has been out since 1998 and very very little appears to have been done to fix all these issues. That's a rather sorry indictment of the modding community - that some of this hasnt been tackled at all.  Recently the music lock bug I had to fix for example.  The level of attention this game has and the modders available really should have yielded far more fixes. 

halkun

  • Global moderator
  • No life
  • *
  • Posts: 2105
  • Karma: 20
  • NicoNico :)
    • View Profile
    • Q-Gears Homepage
Re: Bugfixes and Queries
« Reply #45 on: 2016-06-19 11:08:28 »
That's a pretty silly thing to say.  We not under any obligation to fix *anything* in the game. Heck the only reason why the Wiki exists is because I got tired telling everyone to aggregate their findings in one spot.  I decided to make a PDF with everything I could find... Then I put it all in the wiki when Qhimm set it up.

Sisyphus rolls his own boulder.

DLPB

  • No life
  • *
  • Posts: 8286
  • Karma: 223
  • ‘You know who I am,’ he said.
    • View Profile
Re: Bugfixes and Queries
« Reply #46 on: 2016-06-19 11:14:59 »
Never said anyone was under any obligation ;)  I said it was a sorry indictment of the modding community - mostly that it seems to have the body but no head.  But I do like the wiki.  Needs more people adding to it really - but it's easier I just place what I know here for time being.  I haven't got the skill to reverse engineer entire graphic based functions.  But what I can do - I will :)

The priority from the beginning should have been to fix the biggest bugs in the game - and a lot of them still remain.  I don't know if the graphic function for field Kawai 28 can be fixed.  If I knew how, I'd certainly try.  But there appears to be no information on its bugs or why it is bugged - for example.
« Last Edit: 2016-06-22 21:33:20 by DLPB »

DLPB

  • No life
  • *
  • Posts: 8286
  • Karma: 223
  • ‘You know who I am,’ he said.
    • View Profile
World Map Sky Fix
« Reply #47 on: 2016-07-09 22:16:29 »
As many of you will know, when the Highwind does a sharp turn (while holding Circle), you can see the edge of the sky / cloud texture.  You can even see past the end of the viewable area.  Since the graphics cannot support the sharper turn, the best way to fix this issue is to disable that operation entirely.

To Fix:
74F3B2 = 90 90 90 90 90 90

L1 and R1 can still be used for a full turn and do not affect the background.
« Last Edit: 2016-07-09 22:32:23 by DLPB »

DLPB

  • No life
  • *
  • Posts: 8286
  • Karma: 223
  • ‘You know who I am,’ he said.
    • View Profile
Re: Bugfixes and Queries
« Reply #48 on: 2016-08-03 19:46:48 »
I just added Otyugh encounter to the Ancient Forest on one of the maps. At first, the game just loaded the pyramids with error message. I knew there was nothing wrong with the code, so it had to be a bug.  Checked Terrence's guide, and it turns out that you should never use a battle chance greater than 31 in the field encounter list. 32-64 are bugged because the signed number is not calculated correctly. You'll get weird effects, like the pyramid battle if you do. 

So if you ever need a battle to have 50% + chance of being seen, use two encounter slots (same battle ID) with maximum value of 31 for each.

DynamixDJ

  • Crazy poster
  • *
  • Posts: 156
  • Karma: 18
  • 1111 1111 0111
    • View Profile
Re: Bugfixes and Queries
« Reply #49 on: 2016-08-04 20:37:36 »
Quote
it turns out that you should never use a battle chance greater than 31 in the field encounter list. 32-64 are bugged because the signed number is not calculated correctly.
There are 5 examples of this glitch occurring in the Vanilla Game. The effect isn't that the battle will play out incorrectly, but rather, the battle check will cease to continue, and every formation placed after the formation with >31 enc rate will be ignored. This is why we will never encounter: (formation IDs are in dec)

mtcrl_4 - #505 2x Cokatolis (Mt. Corel Rollercoaster screen)
mtcrl_9 - #514 1x Bagnadrana (Mt. Corel Bridge)
mtnvl3 - #585 2x Sonic Speed (Mt. Nibel Bridge)
junsbd1 - #762 2x SOLDIER:2nd (Red Submarine Dock past barking dog)
junin2 - #945 2x SOLDIER:2nd (Outside press conference room, during escape).

I have written up on this glitch, along with several other similar glitches within the Bug Report section of my Enemy Formation Charts. Look in Section E - Final Notes, although I believe White Wind may have tracked them all in the bug tracker. It's still worth checking.

In regards to the battle with the pyramids, are you sure that you didn't have encounter "0" set with an encounter rate of >0? I've done it myself in the past, the likely culprit is when editing the four "special battle" slots.

One other thing worth mentioning for those that didn't know, the total encounter rate for all 6 "normal battle" slots must total 64, otherwise the game will just freeze as soon as you try to traverse on it.