Users browsing this thread: 1 Guest(s)
Good Lord Send Us An Esper Level Up Bonus Patch

#3
Posts: 61
Threads: 18
Thanks Received: 1
Thanks Given: 47
Joined: May 2014
Status
None
I think what's really confusing to me is that I can't follow everything from the beginning.  I understand that it's using Y then transferring to X, but why not just increment X?  My biggest roadblock was not being able to track what happens to X throughout the whole code.  Here is the very beginning code again, which starts before my original post:

Code:
C2/60DD: BD 1E 16     LDA $161E,X    (get equipped Esper)
C2/60E0: 30 14        BMI $60F6      (if it's null, don't try to calculate bonuses)
C2/60E2: 5A           PHY
C2/60E3: DA           PHX
C2/60E4: 9B           TXY            (Y will be used to index stats that are boosted
                                     by the $614E call.  i believe it currently points
                                     to offset of character block from $1600)

C2/60E5: 20 93 62     JSR $6293      (X = A * 11d)
C2/60E8: 7B           TDC            (Clear 16-bit A)
C2/60E9: BF 0A 6E D8  LDA $D86E0A,X  (end of data block for Esper..  probably
                                     has level-up bonus)
C2/60ED: 30 05        BMI $60F4      (if null, don't try to calculate bonus)
C2/60EF: 0A           ASL
C2/60F0: AA           TAX            (multiply bonus index by 2)
C2/60F1: FC 4E 61     JSR ($614E,X)  (calculate bonus.  note that [Stat]+1 jumps to the
                                     same place as [Stat]+2.  what distinguishes them?
                                     Bit 1 of X.  if X is 20, 24, 28, 32, you'll get +1
                                     to a stat.. if it's 18, 22, 26, 30, you get +2.

                                     for HP/MP boosts, X of 0/2/4 means HP, and
                                     6/8/10 means MP)
                      
C2/60F4: FA           PLX
C2/60F5: 7A           PLY

The TDC is what signals to me that the A register is cleared so the new esper function is probably starting.  However, note that the new function starts by loading data at $D86E0A,X which is some esper information that most likely has our esper bonus.  What is in X already, and how did it get there?  I surely don't know.  We take whatever was loaded into A and multiply it by 2 via ASL, which is then copied in X via TAX.  We multiplied by two because of the next jump (JSR) which is indexed by X so the jump lands farther based on the X value.  We want it to land on a string of code pointers that each have 2 bytes, so any jump must land on the first byte of each pair in order to land on the correct section of each pointer.  The jump takes us to the range of 614E plus the X and will return when the subroutine is done.

The Code Pointers
Code:
(Code Pointers)

C2/614E: 70 61  (~10% HP bonus)  (HP due to X)
C2/6150: 74 61  (~30% HP bonus)  (HP due to X)
C2/6152: 78 61  (50% HP bonus)   (HP due to X)
C2/6154: 70 61  (~10% MP bonus)  (MP due to X)
C2/6156: 74 61  (~30% MP bonus)  (MP due to X)
C2/6158: 78 61  (50% MP bonus)   (MP due to X)  
C2/615A: B0 61  (Double natural HP gain for level.  Curious...)
C2/615C: 97 61  (No bonus)
C2/615E: 97 61  (No bonus)
C2/6160: 9B 61  (Vigor bonus)    (+1 due to X value in caller)
C2/6162: 9B 61  (Vigor bonus)    (+2 due to X)
C2/6164: 9A 61  (Speed bonus)    (+1 due to X)
C2/6166: 9A 61  (Speed bonus)    (+2 due to X.  No Esper currently uses)
C2/6168: 99 61  (Stamina bonus)  (+1 due to X)
C2/616A: 99 61  (Stamina bonus)  (+2 due to X)
C2/616C: 98 61  (MagPwr bonus)   (+1 due to X)
C2/616E: 98 61  (MagPwr bonus)   (+2 due to X)
These are pointers, but I'm not sure how the computer knows they're pointers.  The only thing we have here are a string of byte pairs that represent addresses to immediately use.  We landed here based on the X value, so whichever esper we had was copied into X and then that value influenced our jump value to bring us to these new pointers which tell us to immediately look at new addresses, based on these byte pairs.


Now for the real calculations:

First is the HP/MP
Code:
(Esper HP or MP bonus at level-up)

C2/6170: A9 1A        LDA #$1A     (26 => 10.12625% bonus)  
C2/6172: 80 06        BRA $617A
C2/6174: A9 4E        LDA #$4E     (78 => 30.46875% bonus)    
C2/6176: 80 02        BRA $617A
C2/6178: A9 80        LDA #$80     (128 ==> 50% bonus)
C2/617A: E0 06 00     CPX #$0006   (are we boosting MP rather than HP?)
C2/617D: A2 00 00     LDX #$0000   (start pointing to $FC, which holds normal HP to raise)
C2/6180: 90 02        BCC $6184    (if X was less than 6, we're just boosting HP,
                                   so branch)
C2/6182: E8           INX
C2/6183: E8           INX          (point to $FE, which holds normal MP to raise)
C2/6184: EB           XBA          (put boost numerator in top of A)
C2/6185: B5 FC        LDA $FC,X    (get current HP or MP to add)
C2/6187: 20 81 47     JSR $4781    
C2/618A: EB           XBA          (get (boost number * current HP or MP) / 256.
                                   after all, the boost IS a percentage..)
C2/618B: D0 01        BNE $618E    (if the HP/MP bonus is nonzero, branch)
C2/618D: 1A           INC          (if it was zero, be nice and give the chump one..)
C2/618E: 18           CLC
C2/618F: 75 FC        ADC $FC,X
C2/6191: 95 FC        STA $FC,X    (add boost to natural HP/MP gain)
C2/6193: 90 02        BCC $6197    
C2/6195: F6 FD        INC $FD,X    (if bottom byte overflowed from add, boost top byte)
C2/6197: 60           RTS
These are percentages and branches and some maneuvering which I haven't fully cared to figure out.  It's easy enough to change the percentages by changing the LDA values.

Now we have the stat bonuses:
Code:
(Esper stat bonus at level-up.  Vigor, Speed, Stamina, or MagPwr.
If Bit 1 of X is set, give +1 bonus.  If not, give +2.)

C2/6198: C8           INY          (enter here = 3 INYs = point to MagPwr)
C2/6199: C8           INY          (enter here = 2 INYs = point to Stamina)
C2/619A: C8           INY          (enter here = 1 INY  = point to Speed)
C2/619B: 8A           TXA          (enter here = 0 INYs = point to Vigor)

C2/619C: 4A           LSR
C2/619D: 4A           LSR          (Carry holds bit 1 of X)

C2/619E: BB           TYX          (0 to 3 value.  determines which stat will be altered)
C2/619F: BD 1A 16     LDA $161A,X  (at $161A,X we have Vigor, Speed, Stamina, and MagPwr,
                                   respectively)
C2/61A2: 1A           INC
C2/61A3: B0 01        BCS $61A6    (If carry set, just give +1)
C2/61A5: 1A           INC
C2/61A6: C9 81        CMP #$81     (is stat >= 129?)
C2/61A8: 90 02        BCC $61AC
C2/61AA: A9 80        LDA #$80     (if so, make it 128)
C2/61AC: 9D 1A 16     STA $161A,X  (save updated stat)
C2/61AF: 60           RTS
We're going to load $161A,X into A.  Apparently $161A = Vigor, $161B = Speed, $161C = Stamina, and $161D = Magic Power, because we load these indexed by X which will be from 0 to 3.  First we increment Y by 1 via INY and do this as many times (based on where our code pointers take us) as we need until we have the value 0 to 3 desired for X.  We copy X to A then shift A to the right twice, which, I believe, pushes the entire value out of the accumulator.  This puts the value of bit 1 of X into the Carry (which I don't know anything about), or at least sets the carry flag.  Then we copy Y to X, so we now have that 0 to 3 value finally in X.  C2/619F is where we load $161A,X to get our vigor, speed, stamina, or magic power statistic.  The INC increases A by 1, so we're increasing the stat.  Then we branch if the carry flag was set, which hops over another increase of the stat.  So the carry flag is set by a double logical shift right (LSR) of whatever was in bit 1 of X (which I still don't know what it is) and that is what determines if you get +1 or +2 to the stat.

After that we just have some comparison to 129 which leads to the stat being turned into 128, and the stat is then stored back into $161A,X, which is probably where the stats for all heroes are stored.

And with this knowledge, we have enough to change those measly Stamina and Vigor bonuses into +6.....

Now we're going to add an extra equation that's just like the last one for boosting stats, but instead it only boosts vigor and speed by +6.
To do this, we need free space.  This means space that is probably FFFF all over.  I checked the handy Izmogelmo's "Patch Allocation Free Space Usage" document that locates the code spaces used by other author's patches, and notes where free space still resides.

I found 110 bytes free at C2/6760, so I started the journey there.

But first! We change the pointers to point to our new code:

Code:
C2/6164: 61 67  (Speed bonus)    (+6 due to X)
C2/6166: 61 67  (Speed bonus)    (+6 due to X.  No Esper currently uses)
C2/6168: 60 67  (Stamina bonus)  (+6 due to X)
C2/616A: 60 67  (Stamina bonus)  (+6 due to X)

So the speed and stamina bonus pointers are now at the first and second spots of the new code.

Code:
C2/6760: C8           INY          (enter here = 2 INYs = point to Stamina)
C2/6161: C8           INY          (enter here = 1 INY  = point to Speed)
C2/6162: 8A           TXA          (enter here = 0 INYs = point to Vigor)

C2/6163: BB           TYX          (0 to 3 value.  determines which stat will be altered)
C2/6164: BD 1A 16     LDA $161A,X  (at $161A,X we have Vigor, Speed, Stamina, and MagPwr,
                                    respectively)
C2/6167: 1A           INC
C2/6168: 1A           INC
C2/6169: 1A           INC
C2/616A: 1A           INC
C2/616B: 1A           INC
C2/616C: 1A           INC
C2/616D: C9 81        CMP #$E7     (is stat >= 231?)
C2/616F: 90 02        BCC $6172
C2/6170: A9 80        LDA #$E6     (if so, make it 230)
C2/6172: 9D 1A 16     STA $161A,X  (save updated stat)
C2/6175: 60           RTS

So this is our new code, where we have the same process but instead of worrying about the carry flag, we just increase A six times.  Because Speed has problems around 231 and more (I believe it's actually 236), we've changed the ceilings for the stamina and speed stats to be 230.

Now changing esper bonuses is finally within our grasp. All you have to do is go into FF3USME and give espers any of the speed+ or stamina+ bonuses, and our heroes will get 6 points at level up!  The speed and stamina statistics can now grow at a rate that makes them a bit more worthwhile, reducing their stature as a deadweight stat.
  Find
Quote  



Messages In This Thread
RE: Good Lord Send Us An Esper Level Up Bonus Patch - by ReturnerScum - 02-11-2016, 06:09 PM

Forum Jump:

Users browsing this thread: 1 Guest(s)


Theme by Madsiur2017Custom Graphics by JamesWhite