Jump to content

Lamia's FE4 stuff


Lamia
 Share

Recommended Posts

I figure I'd drop this here in case anybody needs it, since I was looking through FE4 ASM earlier for the Yune randomizer. Maybe it's already out there and I just didn't look hard enough.

Removing the Pursuit requirement for follow-up attacks

All ROM addresses are headered and based off of the original (though I've tested it with the Naga patch).

0x4E567

Old Values:

90 12 BD 24 00 89 00 40 F0 0A B9 30 00 DD 30 00 10 02 38 60 18 60

New Values (the 00s don't matter, I just stubbed them out so that it's clear they do nothing)

20 10 FF 60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

0x50110

Old Values: All 00s.

New Values:

90 2C B9 30 00 DD 30 00 10 24 BD 24 00 89 00 40 F0 0E BD 30 00 38 F9 30 00 C9 03 00 90 10 80 0C BD 30 00 38 F9 30 00 C9 06 00 90 02 38 60 18 60

In that set of new values, there are two values that can be tweaked. The two 0xC9 bytes are each followed by a value for the AS threshold needed to double with and without Pursuit. In the above example, this is 6 AS to double without Pursuit and 3 AS to double with Pursuit.

Technical Explanation

The first change replaces the routine that checks for Pursuit to determine doubling. Originally, this ASM looked like this:

$84/E367 90 12       BCC $12    [$E37B]      A:0000 X:4EB5 Y:4F15 P:envmxdizc <-- Some kind of check that bypasses this entire sequence if the result of the previous function (see above) has the carry flag cleared.
$84/E369 BD 24 00    LDA $0024,x[$7E:4ED9]   A:0000 X:4EB5 Y:4F15 P:envmxdizc <-- Loads Attacker Skills into Accumulator.
$84/E36C 89 00 40    BIT #$4000              A:0000 X:4EB5 Y:4F15 P:envmxdizc <-- Check if the Pursuit bit is set. If it is, clears the zero flag.
$84/E36F F0 0A       BEQ $0A    [$E37B]      A:0000 X:4EB5 Y:4F15 P:envmxdizc <-- Branches if zero flag was set.
$84/E371 B9 30 00    LDA $0030,y[$7E:4F45]   A:0000 X:4EB5 Y:4F15 P:envmxdizc <-- Loads the defender's AS into the Accumulator
$84/E374 DD 30 00    CMP $0030,x[$7E:4EE5]   A:0000 X:4EB5 Y:4F15 P:envmxdizc <-- Compares it with the attacker's AS. Sets the negative flag if necessary (i.e. Defender AS - Attacker AS)
$84/E377 10 02       BPL $02    [$E37B]      A:0000 X:4EB5 Y:4F15 P:envmxdizc <-- Branches to skip the double attack if the negative flag was not set. (i.e. Defender AS > Attacker AS)
$84/E379 38          SEC                     A:0000 X:4EB5 Y:4F15 P:envmxdizc <-- Sets the Carry to indicate a follow up attack is needed.
$84/E37A 60          RTS                     A:0000 X:4EB5 Y:4F15 P:envmxdizc <-- Return
$84/E37B 18          CLC                     A:0000 X:4EB5 Y:4F15 P:envmxdizc <-- The Branch Destination if there is no double attack. Clears the Carry flag to indicate no double attack.
$84/E37C 60          RTS                     A:0000 X:4EB5 Y:4F15 P:envmxdizc <-- Return

Since the check is bit more complex, I opted to jump to my own subroutine and do calculations there for more space. Thankfully Jump and Return instructions don't mess with any flags, which is what we need to preserve for returning to the original caller.

The ASM for the jump is just:

$84/E367 20 10 FF    JSR $FF10  [$84:FF10]   A:0000 X:4EB5 Y:4F15 P:envmxdiZC <-- Jump to our new subroutine.
$84/E36A 60          RTS                     A:0000 X:4EB5 Y:4F15 P:envmxdiZC <-- Return the result from our new subroutine.
$84/E36B 00 00       BRK #$00                A:0000 X:4EB5 Y:4F15 P:envmxdiZC <-- Stubbed out to 00s.
$84/E36D 00 00       BRK #$00                A:0000 X:4EB5 Y:4F15 P:envmxdiZC
$84/E36F 00 00       BRK #$00                A:0000 X:4EB5 Y:4F15 P:envmxdiZC
$84/E371 00 00       BRK #$00                A:0000 X:4EB5 Y:4F15 P:envmxdiZC
$84/E373 00 00       BRK #$00                A:0000 X:4EB5 Y:4F15 P:envmxdiZC
$84/E375 00 00       BRK #$00                A:0000 X:4EB5 Y:4F15 P:envmxdiZC
$84/E377 00 00       BRK #$00                A:0000 X:4EB5 Y:4F15 P:envmxdiZC
$84/E379 00 00       BRK #$00                A:0000 X:4EB5 Y:4F15 P:envmxdiZC
$84/E37B 00 00       BRK #$00                A:0000 X:4EB5 Y:4F15 P:envmxdiZC

The new code we wrote is in the same data bank, but uses empty space at the end of the bank. The ASM looks like this:

$84/FF10 90 2C       BCC $2C    [$FF3E]      A:0000 X:4EB5 Y:4F15 P:envmxdiZC
$84/FF12 B9 30 00    LDA $0030,y[$7E:4F45]   A:0000 X:4EB5 Y:4F15 P:envmxdiZC <-- Loads the defender's AS.
$84/FF15 DD 30 00    CMP $0030,x[$7E:4EE5]   A:0000 X:4EB5 Y:4F15 P:envmxdiZC <-- Compares the defender AS with the attacker AS.
$84/FF18 10 24       BPL $24    [$FF3E]      A:0000 X:4EB5 Y:4F15 P:envmxdiZC <-- If the defender is faster, skip the rest and return no follow-up.

$84/FF1A BD 24 00    LDA $0024,x[$7E:4ED9]   A:0000 X:4EB5 Y:4F15 P:envmxdiZC <-- Load the attacker's skills.
$84/FF1D 89 00 40    BIT #$4000              A:0000 X:4EB5 Y:4F15 P:envmxdiZC <-- Does the attacker have Pursuit?
$84/FF20 F0 0E       BEQ $0E    [$FF30]      A:0000 X:4EB5 Y:4F15 P:envmxdiZC <-- If he doesn't, skip to the logic for checking doubling threshold without Pursuit.

$84/FF22 BD 30 00    LDA $0030,x[$7E:4EE5]   A:0000 X:4EB5 Y:4F15 P:envmxdiZC <-- If we get here, the attacker has Pursuit. Load the attacker AS.
$84/FF25 38          SEC                     A:0000 X:4EB5 Y:4F15 P:envmxdiZC <-- 65816 CPU quirk for subtraction.
$84/FF26 F9 30 00    SBC $0030,y[$7E:4F45]   A:0000 X:4EB5 Y:4F15 P:envmxdiZC <-- Subtract the defender's AS from the attacker's.
$84/FF29 C9 03 00    CMP #$0003              A:0000 X:4EB5 Y:4F15 P:envmxdiZC <-- Compare it to the Pursuit threshold (3 in this case). Sets the carry flag if AS difference > threshold.
$84/FF2C 90 10       BCC $10    [$FF3E]      A:0000 X:4EB5 Y:4F15 P:envmxdiZC <-- If carry flag is not set, skip to the end. No follow-up needed.
$84/FF2E 80 0C       BRA $0C    [$FF3C]      A:0000 X:4EB5 Y:4F15 P:envmxdiZC <-- Otherwise, we have a follow-up. Always jump to the follow-up routine.

$84/FF30 BD 30 00    LDA $0030,x[$7E:4EE5]   A:0000 X:4EB5 Y:4F15 P:envmxdiZC <-- If we get here, the attacker does not have Pursuit. Same as above, load the attacker AS.
$84/FF33 38          SEC                     A:0000 X:4EB5 Y:4F15 P:envmxdiZC <-- 65816 CPU quirk for subtraction.
$84/FF34 F9 30 00    SBC $0030,y[$7E:4F45]   A:0000 X:4EB5 Y:4F15 P:envmxdiZC <-- Subtract the defender's AS from the attacker's.
$84/FF37 C9 06 00    CMP #$0006              A:0000 X:4EB5 Y:4F15 P:envmxdiZC <-- Compare it to the non-Pursuit threshold (6 in this case). Sets the carry flag if AS difference > threshold.
$84/FF3A 90 02       BCC $02    [$FF3E]      A:0000 X:4EB5 Y:4F15 P:envmxdiZC <-- If carry flag is not set, skip to the end. No follow-up needed.

$84/FF3C 38          SEC                     A:0000 X:4EB5 Y:4F15 P:envmxdiZC <-- If we get here, we have a follow-up attack. Set the carry flag to indicate this.
$84/FF3D 60          RTS                     A:0000 X:4EB5 Y:4F15 P:envmxdiZC <-- Return.
$84/FF3E 18          CLC                     A:0000 X:4EB5 Y:4F15 P:envmxdiZC <-- If we get here, we don't have a follow-up attack. Clear the carry flag to indicate this.
$84/FF3F 60          RTS                     A:0000 X:4EB5 Y:4F15 P:envmxdiZC <-- Return.

Note: I use "Attacker" and "Defender", but that really just refers to the values in the X and Y registers. The routine is called twice if necessary, swapping X and Y in the second case. I suspect this only happens if the initial call does not result in a follow-up attack, since only one side can have a follow-up.

Link to comment
Share on other sites

  • 4 weeks later...
  • Replies 278
  • Created
  • Last Reply

Top Posters In This Topic

On 4/14/2021 at 12:35 AM, windypanda1 said:

I had to do hecking 2 hours of digging around the Char Portrait Editor to find the Young Arvis Sprite. Here are some pointers I've recorded to save others some trouble.

89 00 = Old Arvis
8A 00 = Julius
8C 00 = Ishtar
56 00 = Eltshan
5D 00 = Langobalt

51 = Andrey
52 = Blume
53 = Dannan
54 = Lamia
55 = Arvis
5A = Dithorba    
5B = Mahnya
59 = Pamela
5C = Donovan
54 = Hilda
9B = Slayder
 

Know it's an old post, but to save anyone else time in the future here is a complete visual list of all the portraits in the game and their pointers. I didn't make it, just consolidated them, whoever made it seems to have ordered them by family. I just added the generic portraits to complete it. (Oddly a FE3 one makes it in, the only FE3 hold over I have found in FE4)

https://imgur.com/a/0Gg4aHi

Edited by Camus The Dark Knight
Link to comment
Share on other sites

  • 8 months later...

Is it possible to make it so that weapons never gain crit regardless of the number of kills? 

Edit: I don't know if anyone but me cares about this but I at least found an action replay code that stops weapon kill counters from incrementing

87E17B 80

87E17C 03

Edited by Slig
Link to comment
Share on other sites

  • 3 months later...

i tried to dump many times using fe4dump (i follow the command prompt via the instructions and it just kills itself) and fedump2000(i run the .exe and it pops up for maybe .5 seconds then closes.)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...