100+ bugs

Talk about all aspects of the gameplay of Final Fantasy 3us/6j.

Moderators: General Moderator, Game Moderator

Re: 100+ bugs

Postby Assassin » Thu Jun 27, 2013 3:49 pm

Lenophis wrote:I think the problem, at least partially, is that it appears both C3/0F75 and C3/A991 are setting up DMA with the same channel. When DMA is to happen, a series of routines starting at C3/1463 executes. In this case, C3/14AC executes.


looking at Bank C3, it seems that only DMA Channel 0 is ever used, of the normal channels. (Is HDMA Channel N separate from DMA Channel N, or can they not both be active at once?)

maybe we could make C3/0F75 use new DMA setup variables, and have C3/1463 call a new DMA routine that uses Channel 1+. now, we might also have to mimic every place that zeroes $1B to prevent C3/14AC from executing, and adapt it to our new variable and function.

adapting C3/9E23 and/or C3/9E37 to use a new DMA channel could be trickier, as unlike C3/0F75, they're called from multiple places.

i noticed that some calls to C3/9E23 were neighbored by calls/branches to $1368 to trigger NMI. so i took inspiration, and changed the "JSR $0F75" to immediately call C3/1368 afterwards. sure enough, the MP cost is updating immediately after button presses. however, spell descriptions print out noticably slower, repeat L/R scrolling is slowed down, and repeat arrow scrolling is slowed down with display glitches.

a compromise might be to issue the NMI only in a wake of a keypress. with a free RAM variable, i should be able to do this with the Y and L/R buttons, as i know how C3/27E2 detects them. how it detects arrow presses eludes me, and issuing an NMI after each arrow "repeat" might not avoid the aforementioned glitchy slowness (it depends how many repeats per second there are).

another compromise is to not do the entire NMI after C3/0F75, but just the DMA transfer. that should be faster... do we have to wait for H-Blank, V-Blank, or what else?

------------------

EDIT: okay, i tried a version that after calling C3/0F75, waits for V-Blank, then calls C3/14AC for the DMA transfer. it still seems to fix the bug, and has far less slowdown. though there is still some slowdown when repeat arrow scrolling, albeit with no display glitchiness.

i'm hoping that this DMA transfer isn't being done too nearly before or after the usual one reached via C3/1460, and that both have time to complete.
User avatar
Assassin
Moderator
Moderator
 
Posts: 1192
Joined: Tue Sep 14, 2004 5:10 am

Re: 100+ bugs

Postby Lenophis » Thu Jun 27, 2013 8:20 pm

Assassin wrote:looking at Bank C3, it seems that only DMA Channel 0 is ever used, of the normal channels. (Is HDMA Channel N separate from DMA Channel N, or can they not both be active at once?)

The latter is correct.

a compromise might be to issue the NMI only in a wake of a keypress. with a free RAM variable, i should be able to do this with the Y and L/R buttons, as i know how C3/27E2 detects them. how it detects arrow presses eludes me, and issuing an NMI after each arrow "repeat" might not avoid the aforementioned glitchy slowness (it depends how many repeats per second there are).

Code: Select all
LDA $09
BIT #$08  ; did you press up?
BIT #$04  ; did you press down?
BIT #$02  ; did you press left?
BIT #$01  ; did you press right?

They're on the same byte as cancel, so $09/$0B/$0D/$0F are what you want to load for checking.
Image
Lenophis
Veteran
Veteran
 
Posts: 588
Joined: Sat Mar 26, 2005 5:52 am
Location: Duluth, MN

Re: 100+ bugs

Postby Assassin » Fri Jun 28, 2013 3:54 am

cool, $0B looks to be the repeat-relevant one.

for (H)DMA, am i right in concluding that Channel 4 is never used for either type in Bank C3? i was gonna attempt to do a Channel 4 transfer concurrent with a Channel 0 transfer to save time (as i suspect that's why Square would do one DMA setup or another based on frame count), until it dawned on me that both DMAs are writing to port $2118. :/ so a non-starter, but i'm curious.

Function C3/A818 actually checks for arrow and shoulder button presses, as well as the Variable $45, Bit 4 flag set by a Y button press in C3/27E2, and will skip the damned C3/A991 call if detected. the Y button issues were discussed in prior posts:

1) there's no guarantee this "skippage" will line up with C3/0F75 having been called in C3/27E2.
2) the $45 flag is set before the top right MP Cost is even updated in the video buffer, so the skippage comes too early to take advantage of.

as for the arrow/shoulder buttons, i suspect that tapping them real quickly causes a situation where they're detected in an earlier function for cursor movement/page scroll purposes, but they're released by the time C3/A818 is reached.

------------------

anyway, enough blather. here's a beta patch, which addresses only the Magic menu:

http://web.archive.org/web/*/http://hom ... tafix1.zip
http://assassin17.brinkster.net/mp-cost ... tafix1.zip

testing welcome, and i'll gladly answer any questions on it.

there's no extra DMA transfer, or NMI issuance, so it shouldn't have any slowdown issue. the lone thing i spotted is that if i move from one spell to another with a 1-frame shoulder button tap, the spell description will actually undo printing its second letter, then print it again before printing the rest of the description. some of clark gable's famous parting words are fitting here. :P
Last edited by Assassin on Thu Jul 14, 2016 3:32 pm, edited 2 times in total.
Reason: Comcast down, updating URLs. also crossing out a sentence.
User avatar
Assassin
Moderator
Moderator
 
Posts: 1192
Joined: Tue Sep 14, 2004 5:10 am

Re: 100+ bugs

Postby Assassin » Sat Jun 29, 2013 11:59 pm

use this one instead:
http://web.archive.org/web/*/http://hom ... tafix2.zip
http://assassin17.brinkster.net/mp-cost ... tafix2.zip

two changes:
1) also addresses Relic menu issue.
2) on the first beta, in response to detection of menu position movement, Variable $45, Bit 4 wouldn't get set until the *next* frame where C3/0F75 was called... even if the detection happened on such a frame. this beta reorders the code to no longer have that small lag.

what's left:
- maybe zero the new custom variable ($1443) any time the Magic or Relic menus are entered, as a precaution. arguably not necessary.
- find where to put all this added code on FF6j, which doesn't have massive free C3 block. maybe i'll just move the damn code to Bank C2. but that'll require freeing up 1 byte for each caller, unless i nest a far call within a near-called function (ugh).

anyway, i think this is the algorithm i'll be sticking with, so testing is appreciated.
Last edited by Assassin on Thu May 19, 2016 9:52 am, edited 1 time in total.
Reason: Comcast down, updating URLs. also, bolded first line.
User avatar
Assassin
Moderator
Moderator
 
Posts: 1192
Joined: Tue Sep 14, 2004 5:10 am

Re: 100+ bugs

Postby Lenophis » Sun Jun 30, 2013 9:08 am

C3 is a mess, and a bunch of code almost everywhere could be optimized to free up a significant amount of space. For instance:
Code: Select all
Move inventory to backup ram for now
C3/26B8:   7B         TDC         (Put 0 in A)
C3/26B9:   AA         TAX         (Transfer A = 0 to X)
C3/26BA:   BD6918     LDA $1869,X      (Load inventory item at position X)
C3/26BD:   9F8DAA7E   STA $7EAA8D,X   (Store in RAM location)
C3/26C1:   A9FF       LDA #$FF      (Load an "empty" value)
C3/26C3:   9D6918     STA $1869,X      (Put it in inventory location X)
C3/26C6:   E8         INX         (Increment X)
C3/26C7:   E00001     CPX #$0100      (Is X over 256?)
C3/26CA:   D0EE       BNE $26BA      (If not, branch -> Load inventory item X)
C3/26CC:   7B         TDC         (Otherwise, put a 0 in A)
C3/26CD:   AA         TAX         (Transfer A = 0 to X)
C3/26CE:   BD6919     LDA $1969,X    (Get quantity of item X)
C3/26D1:   9F8DAB7E   STA $7EAB8D,X   (Store the quantity in a RAM location)
C3/26D5:   7B         TDC         (Put 0 in A)
C3/26D6:   9D6919     STA $1969,X    (Put it in for quantity of item X)
C3/26D9:   E8         INX         (Increment X)
C3/26DA:   E00001     CPX #$0100      (Is X 256 yet?)
C3/26DD:   D0EF       BNE $26CE      (If not, branch -> Get quantity of item X)
C3/26DF:   60         RTS         (Exit)

This is just bad, and it's slow. If you were to optimize it...
Code: Select all
; move entire inventory to backup ram for now
C326B8:   TDC
C326B9:   TAX
C326BA:   LDA $1869,X  ; load this item
C326BD:   STA $7EAA8D,X  ; move it
C326C1:   LDA #$FF  ; no item
C326C3:   STA $1869,X  ; save in this inventory slot
   LDA $1969,X  ; load this quantity
   STA $7EAB8D,X  ; move it
   STZ $1969,X  ; zero current quantity
C326C6:   INX
C326C7:   CPX #$0100
C326CA:   BNE C326BA
C326CC:   
C326CD:   
C326CE:   
C326D1:   
C326D5:   
C326D6:   
C326D9:   
C326DA:   
C326DD:   
C326DF:   RTS

...it takes up 0x1F bytes instead of the 0x28 bytes it did originally. It's also about 68% faster than the original code. Sadly, stuff like this exists all throughout C3. Anybody using this code should notice it immediately when they go to arrange their inventory. The 1/4 of a second it takes originally should be just about instantaneous now, regardless of how much is in your inventory.

This code in FF6j is at C3/272B, if you're wondering.
Image
Lenophis
Veteran
Veteran
 
Posts: 588
Joined: Sat Mar 26, 2005 5:52 am
Location: Duluth, MN

Re: 100+ bugs

Postby Lenophis » Thu Jul 18, 2013 9:10 pm

Well, I finally managed to give this a try. Other than doing frame-perfect input to try and break this thing, I don't know what else to do. I patched a v1.0 rom with betafix2, and the magic menu updates accordingly with no hitches. Guessing ff3-10 is an anti-patch?

- maybe zero the new custom variable ($1443) any time the Magic or Relic menus are entered, as a precaution. arguably not necessary.

Since every time you enter the magic menu, it always shows the progress half, this probably isn't necessary. Not sure on the relic menu about this, though.

--Edit--
Hmm, a thought. Should the LDA #$10 TSB $45 at C3/A0E5 be commented out or otherwise replaced?
Image
Lenophis
Veteran
Veteran
 
Posts: 588
Joined: Sat Mar 26, 2005 5:52 am
Location: Duluth, MN

Re: 100+ bugs

Postby Assassin » Fri Jul 19, 2013 4:15 am

thanks for testing.

Lenophis wrote:Guessing ff3-10 is an anti-patch?

yup.

--Edit--
Hmm, a thought. Should the LDA #$10 TSB $45 at C3/A0E5 be commented out or otherwise replaced?

that's done in response to pressing the A or B button while choosing a new relic, meaning you're taken back to the choosing between the two relic slots (and the righthand column of numbers disappears). i think that code is there to skip the later part of C3/A818, as there's no description to display. i don't think it needs to be changed. Bit 4 of Variable $45 is also set when you first enter the Relic screen.

since i was hoping not to claim a new RAM byte unless truly necessary, it looks like Bit 7 of Variable $45 is free within the context of Bank C3, based off the disassembly. (though i will have to take the clearing precautions if i use this, because unlike $1443, this variable _is_ used elsewhere.) am i correct to your knowledge?
User avatar
Assassin
Moderator
Moderator
 
Posts: 1192
Joined: Tue Sep 14, 2004 5:10 am

Re: 100+ bugs

Postby Lenophis » Fri Jul 19, 2013 3:35 pm

Yeah, looks like it. Looks like $45 gets used in C0 and C1.
Image
Lenophis
Veteran
Veteran
 
Posts: 588
Joined: Sat Mar 26, 2005 5:52 am
Location: Duluth, MN

Re: 100+ bugs

Postby Assassin » Wed Jul 31, 2013 11:49 pm

#133

Summon Palidor, and have someone cast Quick before everyone could drop down; have that person use a Smoke Bomb on his first of two turns. Those in mid-air won't escape, and Quick won't be broken, which situation results in a game hang.


a test shows this bug isn't dependent on using Palidor; it also happens if I simply have one character use Jump. figured it's worth noting, given that Palidor has its own cans of worms (dicking with the action queue, toggling all sorts of flags) that normal Jump doesn't.
User avatar
Assassin
Moderator
Moderator
 
Posts: 1192
Joined: Tue Sep 14, 2004 5:10 am

Re: 100+ bugs

Postby Assassin » Wed Sep 25, 2013 11:15 am

Novalia Spirit wrote:2. The jumping animation for the bodyguard only applies to the first strike of a multihit attack (this was tested with Genji Glove); it seems as if the attacker is deliberately targeting the bodyguard directly out of anger.

[...]

1. If the bodyguard is in a Near Fatal condition after the initial strike, it may receive protection from another candidate on the second strike. (This is just an addendum to one of the bugs I mentioned earlier.)


another addendum is that if you use Fight on a low-HP character, and a True Knight character protects them, Mimic will target the bodyguard rather than the initial character.
User avatar
Assassin
Moderator
Moderator
 
Posts: 1192
Joined: Tue Sep 14, 2004 5:10 am

Re: 100+ bugs

Postby Assassin » Tue Oct 29, 2013 7:23 pm

1. Characters acting as enemies are treated like normal characters when it comes to True Knight, so they can both protect a vulnerable target or receive protection when weak. This includes Kefka, but it requires a multistrike attack to bypass a certain bug that causes the battle to end after any attack instead of when Kefka has no HP left.


inspired by this, i noticed a more general issue a couple months ago: when interpreting the "abort on characters" property (better known as "exclude characters from targets"), Function C2/58FA does not differentiate characters acting as enemies from normal characters.

one manifestation of this, as pointed out by Novalia, is that Sealed Gate Kefka can't be hit by Bio Blaster or Flash: two Tools that utilize spells, which both have the "exclude characters from targets" property set.
User avatar
Assassin
Moderator
Moderator
 
Posts: 1192
Joined: Tue Sep 14, 2004 5:10 am

Re: 100+ bugs

Postby Assassin » Sat Dec 21, 2013 11:28 pm

to keep things in one place:

http://novaliaspirit.99k.org/ff6/patches.html#1.38
http://www.gamefaqs.com/boards/554041-f ... i/68023017

The lore known as Rippler is infamous for its ability to deprive Shadow of his dog. Alas, the lore is not unique in this regard. Cherub Down, an accessory that bestows the Float status, falls in the same category.

...


definitely a consequential bug, and a speedy patch creation.
User avatar
Assassin
Moderator
Moderator
 
Posts: 1192
Joined: Tue Sep 14, 2004 5:10 am

Re: 100+ bugs

Postby Djibriel » Fri Apr 18, 2014 7:29 am

To continue putting things in one place, a noble endeavor:

The Soul Sabre targets MDef. This can be easily observed in the Ancient Castle, where you'd think the Soul Sabre would be superior to Osmose. For what it's worth, it targets MDef in the Android/IOS game as well, so you could label this a maybe.

For the record: that Android/IOS release is godawful. I was anxious to play it and I was sure I was going to update my walkthrough for the new release... until I played it. I could not have liked this remake less if it had been coded by the Westboro Baptist Church. Playing it feels like playing the violin with boxing gloves on, and it looks like it's been stitched together from dead dog parts. I feel like I have to finish it, but whenever I want to get started I start doing my taxes because I lack the willpower.
"The population in Iraq is over 80% Shi'ite. Couldn't the same be said about your music, Mr. Durst? "
User avatar
Djibriel
Regular User
Regular User
 
Posts: 354
Joined: Wed Sep 08, 2004 3:45 pm
Location: Outsider!

Re: 100+ bugs

Postby Assassin » Wed Sep 02, 2015 1:45 pm

re #148:
viewtopic.php?p=3439#p3439

it turns out this also skips the updating of the "Can't Escape" and "Can't Run" flags, and re-calculation of Run Difficulty, because those are handled by C2/5C73 as well.

a fix should be simple. Function C2/00F9 sets Bit 5 of $B0 after the C2/13D3 call, to tell the game a turn has been performed since the last update. Function C2/4B7B (which handles counterattacks -- both the initial "Run Monster Script" command and the actual payloads -- and periodic damage/healing) needs to do this, too.

due to the order of how various things get executed, i don't think setting the bit is actually necessary in the counterattack (payload) case. however, for the same reasons, setting it in this case should be harmless (i.e. it'll already be on); no need to waste code to limit it to periodic damage/healing.
User avatar
Assassin
Moderator
Moderator
 
Posts: 1192
Joined: Tue Sep 14, 2004 5:10 am

Re: 100+ bugs

Postby Assassin » Thu Jul 13, 2017 3:47 pm

to flesh out some fixes mentioned back on October 13, 2012:
me wrote:
Novalia Spirit wrote:Some additions concerning True Knight and Genji Glove:
1. If the bodyguard is in a Near Fatal condition after the initial strike, it may receive protection from another candidate on the second strike. (This is just an addendum to one of the bugs I mentioned earlier.)

whoa.. when i first read that bug, i just figured that somehow the game was failing to draw the bodyguard in front of the initial target for the remaining strikes, but that the protection of the initial target was still happening mechanically. now, you've convinced me that the actual target has changed.

maybe this can be solved by moving the "JSR $3865" ahead of the "JSR $123B". but that could cause issues with Battle/Special done via Sketch (i don't know of any other zeroers of $3415 that are True Knight-able). better yet, around C2/329F, push A (which holds 16-bit $B8) on the stack, and right before C2/3865 is called, we should restore $B8. i think this'll work, because afaik, nothing on the remainder of the strike reads from $B8-$B9; they operate on $A2-$A5 instead. (some special effects will overwrite $B8-$B9, but they don't read from it first.)

if i'm wrong, then maybe C2/123B should check if $3415 is FFh, and if so, call C2/3865, and set some flag in a scratch variable (or the stack). then we skip the latter call to $3865 if the flag is set.

regardless, i really need to comment Function C2/3865...


as mentioned back then, 'moving the "JSR $3865" ahead of the "JSR $123B"' is a non-starter due to Sketch. so of the other 2 ideas:

the first way, smallest and probably safe (yet still bugging me) (9 added bytes):
http://assassin17.brinkster.net/forum-p ... st-way.asm

the second way, safeguards for later $B8 reads are built in to different algorithm (24 or 25 added bytes, depending on contiguity):
http://assassin17.brinkster.net/forum-p ... nd-way.asm

the first way, but with safeguards added on (17 bytes):
http://assassin17.brinkster.net/forum-p ... utious.asm

i had put the last one off a bit, because the way i needed to preserve two values put me in a non-functioning situation like:
Code: Select all
A = value1
push A
...
A = value2
push A
pull A (want value1)
variable = A
...
pull A (want value2)


where i'd have to do "lda $03,s" and "lda $01,s" ugliness and bigness, or make Y 16-bit and preserve in there (less ugly, but still big).

the recent insight that C2/57C2 backs up $B8 on an $A2 silver platter for me allowed this fairly small method. also, having all additions/relocations in a single function (and thus no second JSR+RTS) helps make it smaller than the second way.

am interested in hearing your preferred method. (is anything beyond the first way paranoid space wasting? how unseemly is the inter-function scratch variable usage of second method? etc.) as well as further optimizations and thoughts.
User avatar
Assassin
Moderator
Moderator
 
Posts: 1192
Joined: Tue Sep 14, 2004 5:10 am

Re: 100+ bugs

Postby Drakkhen » Fri Jul 21, 2017 2:25 pm

Assassin wrote:... further optimizations ...

Code: Select all
True Knight and Love Token

C2/123B: 48            PHA
C2/123C: DA            PHX
C2/123D: 20 0E 52      JSR $520E     (Number of bits set in A)
C2/1240: 8E C9 3E      STX $3EC9     (# of targets)
C2/1243: A5 B2         LDA $B2       (Is "No critical and Ignore True Knight" set?)
C2/1245: 4A            LSR
C2/1246: 4A            LSR
C2/1247: B0 5E         BCS $12A7     (Exit if so)
C2/1249: A5 B8         LDA $B8       (intended target(s).   to my knowledge, there's only one
                                     intended target set if we call this function..)
C2/124B: F0 5A         BEQ $12A7     (Exit if none)
C2/124D: A0 FF         LDY #$FF
C2/124F: 84 F4         STY $F4       (default to no bodyguards.)
C2/1251: 20 F9 51      JSR $51F9     (Y = index of our highest intended target.
                                     0, 2, 4, or 6 for characters.  8, 10, 12, 14, 16, or 18
                                     for monsters.)
C2/1254: 84 F8         STY $F8       (save target index)
C2/1256: 64 F2         STZ $F2       (Highest Bodyguard HP So Far = 0.  this makes
                                     the first eligible bodyguard we check get accepted.
                                     later ones may replace him/her if they have more HP.)
C2/1258: BE 6C 33      LDX $336C,y   (Love Token - which target takes damage for you)
C2/125B: 30 06         BMI $1263     (Branch if none do)
C2/125D: 20 C4 12      JSR $12C4     (consider this target as a bodyguard)
C2/1260: 20 B0 12      JSR $12B0     (if it was valid, make it intercept the attack)
C2/1263: FA            PLX
C2/1264: B9 E4 3E      LDA $3EE4,y
C2/1267: 49 10 00      EOR #$0200
C2/126A: 89 10 02      BIT #$0210
C2/126D: D0 39         BNE $12A8     (Branch if target Clear or not Near Fatal)
C2/126F: B9 58 33      LDA $3358,y
C2/1272: 10 34         BPL $12A8     (Branch if target is seized)
C2/1274: A9 0F 00      LDA #$000F    (Load all characters as potential bodyguards)
C2/1277: C0 08         CPY #$08
C2/1279: 90 03         BCC $127E     (Branch if target is character)
C2/127B: A9 00 3F      LDA #$3F00    (Load all monsters as potential bodyguards instead)
C2/127E: 85 F0         STA $F0       (Save potential bodyguards)
C2/1280: B9 18 30      LDA $3018,y
C2/1283: 1D 18 30      ORA $3018,x
C2/1286: 14 F0         TRB $F0       (Clear attacker from potential bodyguards)
C2/1288: DA            PHX
C2/1289: A2 12         LDX #$12
C2/128B: BD 57 3C      LDA $3C57,x
C2/128E: 0A            ASL
C2/128F: 0A            ASL
C2/1290: 90 0A         BCC $129C     (Branch if no True Knight effect)
C2/1292: BD 18 30      LDA $3018,x
C2/1295: 24 F0         BIT $F0
C2/1297: F0 03         BEQ $129C     (Branch if this candidate isn't on the same
                                     team as the target)
C2/1299: 20 C4 12      JSR $12C4     (consider them as candidate bodyguard.  if they're
                                     valid and their HP is >= past valid candidates,
                                     they become the new frontrunner.)
C2/129C: CA            DEX
C2/129D: CA            DEX
C2/129E: 10 EB         BPL $128B     (Do for all characters and monsters)
C2/12A0: A5 F2         LDA $F2
C2/12A2: F0 03         BEQ $12A7     (Exit if no bodyguard found [or if the selfless
                                     soul has 0 HP, which shouldn't be possible outside
                                     of bugs].)
C2/12A4: 20 B0 12      JSR $12B0     (make chosen bodyguard -- provided there was one --
                                     intercept attack.  if somebody's already been slated
                                     to intercept it [i.e. due to Love Token], the True Knight
                                     will sensibly defer to them.)
C2/12A7: FA            PLX
C2/12A8: 20 C2 57      JSR $57C2     (Copies targets in $B8-$B9 to $A2-$A3 and $A4-$A5, and
                                     set up a couple attack properties and animation flags.)
C2/12AB: 68            PLA
C2/12AC: EA            NOP
C2/12AD: EA            NOP
C2/12AE: EA            NOP
C2/12AF: 60            RTS

(Make chosen bodyguard intercept attack, provided one hasn't been
marked to do so already.)

C2/12B0: A6 F4         LDX $F4
C2/12B2: 30 0F         BMI $12C3     (exit if no bodyguard found)
C2/12B4: C4 F8         CPY $F8
C2/12B6: D0 0B         BNE $12C3     (exit if $F8 no longer points to the original target,
                                     which means we've already assigned a bodyguard with
                                     this function.)
C2/12B8: 86 F8         STX $F8       (save bodyguard's index)
C2/12BA: 84 A8         STY $A8       (save intended target's index)
C2/12BC: 46 A8         LSR $A8       (.. but for the latter, use 0,1,2,etc rather
                                     than 0,2,4,etc)
C2/12BE: BD 18 30      LDA $3018,x
C2/12C1: 85 B8         STA $B8       (save bodyguard as the new target of attack)
C2/12C3: 60            RTS

(Consider candidate bodyguard)

C2/12C4: BD A0 3A      LDA $3AA0,x
C2/12C7: 4A            LSR
C2/12C8: 90 2A         BCC $12F4     (Exit function)
C2/12CA: BD B8 32      LDA $32B8,x   (Which target you control)
C2/12CD: 10 25         BPL $12F4     (Exit if control a target)?
C2/12CF: BD 58 33      LDA $3358,x   (Which target you have seized)
C2/12D2: 10 20         BPL $12F4     (Exit if you have a target seized)?
C2/12D4: BD E4 3E      LDA $3EE4,x
C2/12D7: 89 D2 A0      BIT #$A0D2    (Death, Petrify, Clear, Zombie, Sleep, Muddled)
C2/12DA: D0 18         BNE $12F4     (Exit if any set)
C2/12DC: BD F8 3E      LDA $3EF8,x
C2/12DF: 89 10 32      BIT #$3210    (Stop, Freeze, Spell, Hide)
C2/12E2: D0 10         BNE $12F4     (Exit if any set)
C2/12E4: BD 18 30      LDA $3018,x
C2/12E7: 04 A6         TSB $A6       (make this potential guard jump in front of the
                                     target?)
C2/12E9: BD F4 3B      LDA $3BF4,x   (HP of this potential bodyguard)
C2/12EC: C5 F2         CMP $F2
C2/12EE: 90 04         BCC $12F4     (branch if it's not >= the highest HP of the
                                     other bodyguards considered so far for this attack.)
C2/12F0: 85 F2         STA $F2       (if it is, save this entity's HP as the highest
                                     HP so far.)
C2/12F2: 86 F4         STX $F4       (and this entity becomes the new bodyguard.)
C2/12F4: 60            RTS


C2/329E: A5 B8         LDA $B8
C2/32A0: 20 3B 12      JSR $123B
C2/32A3: 85 B8         STA $B8       (restore pre- True Knight and Love Token targets, as we
                                     want those backed up for next strike (and Mimic))
C2/32A5: 20 65 38      JSR $3865     (depending on $3415, copy targets into backup targets
                                     and add to "already hit targets" list, or copy backup
                                     targets into targets.)
C2/32A8: AD 14 34      LDA $3414
C2/32AB: F0 04         BPL $32AD     (now Assassin wants me to undo HIS changes to $B8, but NOT any Square
                                     changes done by C2/3865.
C2/32AB: A5 A2         LDA $A2       (conveniently holds our post- True Knight targets (from C2/57C2))
C2/32AB: 85 B8         STA $B8       (restore them to be safe, as Assassin doesn't want patch-altered targets
                                     for anything but the C2/3865 call ... even though he doesn't think
                                     $B8 or $B9 ever gets read again without being overwritten first.)
Drakkhen
Active User
Active User
 
Posts: 71
Joined: Thu Sep 09, 2004 9:06 am
Location: Dry Land, Earth

Re: 100+ bugs

Postby Assassin » Sat Jul 22, 2017 9:12 pm

thanks for that.

weird; Square is a bit oddly tentative with the flags. like they forgot those helper functions would be called in 16-bit mode, or thought they'd also be called from elsewhere.

one thing that makes me wonder about their intent is the "STY $A8 / LSR $A8" mixing and matching 8- and 16- bit accesses. are we sure that the animation code for True Knight / Love Token will ignore whatever junk might be put in Bit 7 of $A8? hey, some bugs in this game are elusive.

also, nice optimizations in the big function.

normally, i'd be hesitant to change function starting addresses, or to push C2/3292 functionality elsewhere. but i can't fathom where else a hack would call the helper routines, so the concern doesn't really apply here. i'm a little more hesitant about a hypothetical second caller of the main True Knight / Love Token routine having more happen than expected, but it's probably not worth the worry either. the alternative of consuming 17 bytes free space for a fairly simple patch is a bit silly.

does the fact that you chose my third approach to optimize mean you favor it over the other two, or are you agnostic?

Drakkhen wrote:
Code: Select all
C2/128B: BD 57 3C      LDA $3C57,x
C2/128E: 0A            ASL
C2/128F: 0A            ASL
C2/1290: 90 0A         BCC $129C     (Branch if no True Knight effect)

or "ASL / BPL", not that another byte is needed.

shame i can't find anything to change in C2/3292, or we could have a conversation in the comments, possibly with me referring to myself in the eighth person.
User avatar
Assassin
Moderator
Moderator
 
Posts: 1192
Joined: Tue Sep 14, 2004 5:10 am

Re: 100+ bugs

Postby Drakkhen » Tue Jul 25, 2017 11:48 am

Assassin wrote:weird; Square is a bit oddly tentative with the flags. like they forgot those helper functions would be called in 16-bit mode, or thought they'd also be called from elsewhere.

C2/12A8 in particular looks like it's expecting to be called in 8-bit mode.

Assassin wrote:one thing that makes me wonder about their intent is the "STY $A8 / LSR $A8" mixing and matching 8- and 16- bit accesses. are we sure that the animation code for True Knight / Love Token will ignore whatever junk might be put in Bit 7 of $A8? hey, some bugs in this game are elusive.

Unless I'm mistaken, $A9 should be zero at this point:
Code: Select all
C2/3298: 20 00 64     JSR $6400   (Zero $A0 through $AF)


Assassin wrote:does the fact that you chose my third approach to optimize mean you favor it over the other two, or are you agnostic?

I have no idea what I'm even doing, I just work here.
Drakkhen
Active User
Active User
 
Posts: 71
Joined: Thu Sep 09, 2004 9:06 am
Location: Dry Land, Earth

Previous

Return to FF3 Gameplay Discussion

Who is online

Users browsing this forum: No registered users and 1 guest

cron