News: 11 March 2016 - Forum Rules

Author Topic: FF1 NES TMPR/SABR bug fix for Final Fantasy Randomizer  (Read 2963 times)

EntroperZero

  • Jr. Member
  • **
  • Posts: 11
    • View Profile
FF1 NES TMPR/SABR bug fix for Final Fantasy Randomizer
« on: May 14, 2017, 01:38:38 am »
Hi all,

For those who don't know, I'm the author of FF Randomizer: https://github.com/Entroper/FF1Randomizer/releases

In addition to randomizing the game, FFR can also fix some of its bugs.  I've got several patches in, but I'm struggling mightily with fixing TMPR and SABR (and XFER, which may be related).

I've seen this awesome thread on GameFAQs, and even stolen implemented some of the patches.  But the patch for TMPR and SABR is a huge patch that makes a bunch of other changes that I don't want to include.  I'm basically trying to come up with a "minimal" patch that only fixes the bugs with these spells, and doesn't totally change the mechanics.

I can read and generally understand 6502 ASM, but writing it is an entirely different story.  I've tweaked a few small things, but it gets really iffy trying to actually move code around or add new code to the ROM.  I'd love it if someone more familiar could help out.

Disch

  • Hero Member
  • *****
  • Posts: 2814
  • NES Junkie
    • View Profile
Re: FF1 NES TMPR/SABR bug fix for Final Fantasy Randomizer
« Reply #1 on: May 14, 2017, 10:38:19 am »
XFER is a similar problem, but is unrelated to TMPR/SABR.  They'll take separate fixes.

To fix TMPR/SABR
The fix is actually very simple.  The problem is you need to add new code, which means you need to find free space for it.

In bank C, there are 2 routines you need to add code to.

You need to add these 3 lines (7 bytes) to BtlMag_LoadPlayerDefenderStats:
Code: [Select]
    LDY #btlch_dmg
    LDA (btl_entityptr_ibram), Y
    STA btlmag_defender_strength

And these 3 lines (7 bytes) need to be added to BtlMag_SavePlayerDefenderStats:
Code: [Select]
    LDY #btlch_dmg
    LDA btlmag_defender_strength
    STA (btl_entityptr_ibram), Y


To fix XFER (this will also fix AFIR/etc spells when cast on enemies)

XFER has a similar problem in that it doesn't load/save enemy elemental resistance from RAM -- but that's because it doesn't STORE elemental resistance in RAM!!!

These changes are all in bank C.  Also I didn't test them, but I'm reasonably sure they'd work:

In LoadEnemyStats, there's a '@lut_RomRamMapping' table:

Code: [Select]
;  Replace this line
;    .BYTE ENROMSTAT_HPMAX,      en_unknown12     ; <- ?  is this BUGGED?  Why is HP duplicated here?  And why just the low byte?
;  With this one:
    .BYTE ENROMSTAT_ELEMRESIST, en_unknown12    ; repurposing unknown12 to be elemental resistance


Note the above code will slightly change the behavior (but not end result) of the code that determines whether or not enemies will wake up from the Sleep ailment (see the '@Asleep' section in Battle_DoEnemyTurn) -- but that code is HORRIBLY bugged to begin with, resulting in enemies waking up immediately.  It shouldn't matter, but I bring it up in case you also are using a patch to fix that wake-up code.


In PlayerAttackEnemy_Physical:
Code: [Select]
; Replace this code:
;    LDY #ENROMSTAT_ELEMWEAK         ; elemental weakness from ROM
;    LDA ($86), Y                    ; BUGGED - it should be taking this from enemy RAM stats, not from ROM stats
;    STA btl_defender_elemweakness   ;   as a result, spells which modify this (XFER) have no effect when used on enemies.
;
; With this code:
    LDY #en_unknown12
    LDA ($84), Y        ; <- be sure to use 84, not 86
    STA btl_defender_elemweakness
Note the above code won't do anything in vanilla because elemental resistance of physical weapons is further bugged.  But it doesn't hurt to make this change, and if you are using a patch which fixes elemental weapons, you'll need this change.



In BtlMag_LoadEnemyDefenderStats:
Code: [Select]
    INY                             ; Y = ENROMSTAT_ELEMWEAK
    LDA (btl_entityptr_obrom), Y    ; elemental weakness from ROM
    STA btlmag_defender_elemweakness
   
; Replace this code:
;    INY                             ; Y = ENROMSTAT_ELEMRESIST
;    LDA (btl_entityptr_obrom), Y    ; elemental resistance from ROM
;    STA btlmag_defender_elemresist  ;   BUGGED - loaded from ROM instead of RAM.  Contributes to XFER bug
; With this code:
    LDY #en_unknown12
    LDA (btl_entityptr_ibram), Y    ; <- note:  ibram, not obrom
    STA btlmag_defender_elemresist

Note the above changes will require 1 additional byte of code.  Fortunately, you can shave the code at the end of the routine to get some free space:
Code: [Select]
; At the end of BtlMag_LoadEnemyDefenderStats
; Replace this code (8 bytes)
;    ;  Lastly, do the explosion effect and exit
;    LDA #$02
;    JSR PlayBattleSFX                   ; "cha" sound effect (unnecessary, as DoExplosionEffect does this already)
;    JMP DoExplosionEffect
; With this code (7 bytes -- freeing up 1 byte for the above change)
    JMP DoExplosionEffect
    .BYTE 0, 0, 0, 0


Final change!  Note ... it's adding code, so you'll have to find free space.  In BtlMag_SaveEnemyDefenderStats:
Code: [Select]
; Add the below code (7 bytes)
LDA btlmag_defender_elemresist
LDY #en_unknown12
STA (btl_entityptr_ibram), Y
« Last Edit: May 14, 2017, 06:43:05 pm by Disch »

EntroperZero

  • Jr. Member
  • **
  • Posts: 11
    • View Profile
Re: FF1 NES TMPR/SABR bug fix for Final Fantasy Randomizer
« Reply #2 on: May 15, 2017, 02:26:01 am »
That's VERY detailed, Disch, thanks a ton.  :)  I think I can probably find ~20ish bytes in bank C somewhere.

essellejaye

  • Jr. Member
  • **
  • Posts: 28
    • View Profile
Re: FF1 NES TMPR/SABR bug fix for Final Fantasy Randomizer
« Reply #3 on: May 15, 2017, 08:48:09 am »
That's VERY detailed, Disch, thanks a ton.  :)  I think I can probably find ~20ish bytes in bank C somewhere.

The DataCrystal ROM map has been updated with free space and unused routines; it'll help you locate free space and plan how to use it.
http://datacrystal.romhacking.net/wiki/Final_Fantasy:ROM_map


EntroperZero

  • Jr. Member
  • **
  • Posts: 11
    • View Profile
Re: FF1 NES TMPR/SABR bug fix for Final Fantasy Randomizer
« Reply #4 on: May 20, 2017, 09:05:01 am »
Starting to dig into this now.  Correct me if I'm wrong, but for SABR to work as intended, I also need to load and save the defender's hit% in the respective functions, right?  And of course, put a nonzero value in the hit% field for SABR.

I've got this so far (variable definitions because I'm just pasting into an online assembler):

Code: [Select]
btlch_dmg     = $09
btlch_hitrate = $05

btlmag_defender_strength = $6882
btlmag_defender_hitrate  = $6884

btl_entityptr_ibram = $90


    LDY #btlch_dmg
    LDA (btl_entityptr_ibram), Y
    STA btlmag_defender_strength
    LDY #btlch_hitrate
    LDA (btl_entityptr_ibram), Y
    STA btlmag_defender_hitrate
    RTS

    LDY #btlch_dmg
    LDA btlmag_defender_strength
    STA (btl_entityptr_ibram), Y
    LDY #btlch_hitrate
    LDA btlmag_defender_hitrate
    STA (btl_entityptr_ibram), Y
    RTS
« Last Edit: May 20, 2017, 09:36:41 am by EntroperZero »

Disch

  • Hero Member
  • *****
  • Posts: 2814
  • NES Junkie
    • View Profile
Re: FF1 NES TMPR/SABR bug fix for Final Fantasy Randomizer
« Reply #5 on: May 21, 2017, 12:51:32 am »
Starting to dig into this now.  Correct me if I'm wrong, but for SABR to work as intended, I also need to load and save the defender's hit% in the respective functions, right?  And of course, put a nonzero value in the hit% field for SABR.

If you want the hit% boost to matter, yes.

Quote
I've got this so far (variable definitions because I'm just pasting into an online assembler):

Looks good!  Though if you're using $6884 for defender hit%, you'll have to modify PrepareEnemyMagAttack and PreparePlayerMagAttack to remove their writes to 'btlmag_attacker_unk6884' -- as they overwrite it with the caster's hit% instead of the target's hit%.

And of course, the code that save the defender's hit%.  But you already mentioned that  =P

EntroperZero

  • Jr. Member
  • **
  • Posts: 11
    • View Profile
Re: FF1 NES TMPR/SABR bug fix for Final Fantasy Randomizer
« Reply #6 on: May 21, 2017, 10:07:35 am »
Interesting.  I suppose, in the case of SABR, the caster's hit% and the target's hit% will always be the same.  But things could still get screwy if we're overwriting a value that's just been updated elsewhere.

Actually... it looks like the "free space" I found in Bank C was exactly the two functions you mentioned (thanks essellejaye for the ROM map link!).  I overwrote most of that code with the new save/load code for TMPR and SABR, since it wasn't doing anything useful.  So, handy coincidence saves the day.  :)

May 22, 2017, 01:40:42 pm - (Auto Merged - Double Posts are not allowed before 7 days.)
I love the way this has turned out.  Fixing the critical hit chance made late-game weapons much weaker, and fixing TMPR and SABR has somewhat compensated for that.  At least, it adds another option for getting through bosses with really high defense stats generated by the randomizer.  And fixing LOCK/LOK2 adds an option for getting through high evade stats.
« Last Edit: May 22, 2017, 01:40:42 pm by EntroperZero »