øAslickproductions.org/forum/index.php?PHPSESSID=so1iojs5ocdn0o2vf0tti7fbu6&topic=2374.0e:/My Web Sites/Slick Productions - FFIV Message Board/slickproductions.org/forum/index0b80.htmlslickproductions.org/forum/index.php?PHPSESSID=so1iojs5ocdn0o2vf0tti7fbu6&board=17.0e:/My Web Sites/Slick Productions - FFIV Message Board/slickproductions.org/forum/index0b80.html.zx4õg^ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿȰU)1OKtext/htmlISO-8859-1gzip0|Ö)1ÿÿÿÿÿÿÿÿTue, 10 Mar 2020 20:31:07 GMT0ó°° ®0®P®€§²ð®3õg^ÿÿÿÿÿÿÿÿ¯.)1 Enemy Group size/spell animation issues

Author Topic: Enemy Group size/spell animation issues  (Read 435 times)

Praetarius5018

  • Vargas
  • *
  • Posts: 88
    • View Profile
Enemy Group size/spell animation issues
« on: June 22, 2017, 04:19:35 PM »
So theoretically the game can have 8 enemies in battle at the same time.
This doesn't seem to be a good idea.
If there are 7-8 enemies alive at the same time, casting a multitarget spell will crash the game.
"Simple" animations like Bolt survive 7 enemies (at least in my test group) but 8 was too much.
Fire3 glitches the game at 7 enemies already. I had to restart the entire emulator, loading savestate didn't suffice for some reason.
Ice2 doesn't crash the game at 6 enemies, but the 6th enemy didn't display the "got hit" part of the animation.
Ice1 passed even 8 enemies but was very laggy.

The biggest "natural" enemy group I know of has 6 of those Puroboros bomb enemies and a quick search found no enemy formation that even used the 8th slot.

Also anything targetting the 8th enemy exclusively somehow lands instead on the parties first character. But only while all 8 are alive.
This is confusing, yo...


Background is:
I wanted to use the unused enemy slots for random encounters and make it really random.
Enemy slot 1-8 would all be filled and then RNG decides at battle start that enemy 2,4 and 7 stay home.
So far the theory. Reality... has crashed and needs a reboot.


So what I wanted to know is, has anyone ever used those "extra" monster formation slots successfully or just stuck to vanilla?

Squall

  • Dark Dragon
  • *
  • Posts: 486
    • View Profile
Re: Enemy Group size/spell animation issues
« Reply #1 on: June 23, 2017, 03:00:09 AM »
Quote
The biggest "natural" enemy group I know of has 6 of those Puroboros bomb enemies and a quick search found no enemy formation that even used the 8th slot.
Correct. No 8 slot battle. There are couple of 6 slot - 209, 270, 467. There are couple of 7th slot battles, but we will never see all 7 on screen at the same time - 101, 447, 495, 501; GBA only - 629, 597

I was always wonder, why they dont use all 8 slots. Maybe they have experienced similar crashes and made 'soft' lock up to 6. Your idea of having random is interesting. FF1 & 2 heavily rely on random numbers, while FF5 is strictly predetermined.

P.S. I wonder what cause the crashes ... is it software bug, is it some 'hidden' limitation of the GPU. Will the game crash if we use contemporary powerful PC? What about a different emulator?

Praetarius5018

  • Vargas
  • *
  • Posts: 88
    • View Profile
Re: Enemy Group size/spell animation issues
« Reply #2 on: June 23, 2017, 12:34:26 PM »
FF1adv is probably the final fantasy I'm most familar with. At least the one I completed more than once (or never for most games in the series)
I'm honestly not even sure if I ever finished FF5, hmmm.....

I guess 8 targets was never intended.
Kinda funny how in the NES games you can have spells hit 9 targets no problem and the FF5 code gives up at 7.


I was 99% sure it is just the GPU at its limit; the whole screen turns to garbage and music continues.
The more "parts" an animation has the less targets it can endure.

And counterpoint...
at least in case of Fire2 it looks like a unintended JMP target
Code: [Select]
$C1/1186 AD 3A CD    LDA $CD3A  [$7E:CD3A]   A:0004 X:0000 Y:0040 P:envMxdIzc
$C1/1189 0A          ASL A                   A:00F0 X:0000 Y:0040 P:eNvMxdIzc
$C1/118A AA          TAX                     A:00E0 X:0000 Y:0040 P:eNvMxdIzC
$C1/118B BF 9B 11 C1 LDA $C1119B,x[$C1:127B] A:00E0 X:00E0 Y:0040 P:envMxdIzC
$C1/118F 85 88       STA $88    [$00:0088]   A:009D X:00E0 Y:0040 P:eNvMxdIzC
$C1/1191 BF 9C 11 C1 LDA $C1119C,x[$C1:127C] A:009D X:00E0 Y:0040 P:eNvMxdIzC
$C1/1195 85 89       STA $89    [$00:0089]   A:00BC X:00E0 Y:0040 P:eNvMxdIzC
$C1/1197 6C 88 00    JMP ($0088)[$C1:BC9D]   A:00BC X:00E0 Y:0040 P:eNvMxdIzC
$C1/BC9D 86 F5       STX $F5    [$00:00F5]   A:00BC X:00E0 Y:0040 P:eNvMxdIzC
$C1/BC9F 1A          INC A                   A:00BC X:00E0 Y:0040 P:eNvMxdIzC
$C1/BCA0 0A          ASL A                   A:00BD X:00E0 Y:0040 P:eNvMxdIzC
$C1/BCA1 AA          TAX                     A:007A X:00E0 Y:0040 P:envMxdIzC
$C1/BCA2 7B          TDC                     A:007A X:007A Y:0040 P:envMxdIzC
$C1/BCA3 A8          TAY                     A:0000 X:007A Y:0040 P:envMxdIZC
$C1/BCA4 BF 42 7D D9 LDA $D97D42,x[$D9:7DBC] A:0000 X:007A Y:0000 P:envMxdIZC
$C1/BCA8 99 1A D4    STA $D41A,y[$7E:D41A]   A:0094 X:007A Y:0000 P:eNvMxdIzC
$C1/BCAB 98          TYA                     A:0094 X:007A Y:0000 P:eNvMxdIzC
$C1/BCAC 18          CLC                     A:0000 X:007A Y:0000 P:envMxdIZC
$C1/BCAD 69 10       ADC #$10                A:0000 X:007A Y:0000 P:envMxdIZc
$C1/BCAF 00 A8       BRK #$A8                A:0010 X:007A Y:0000 P:envMxdIzc


all iterations before always had a 0 in 7E:CD3A
Code: [Select]
$C1/118B BF 9B 11 C1 LDA $C1119B,x[$C1:119B] A:0000 X:0000 Y:0880 P:envMxdIZc
$C1/118F 85 88       STA $88    [$00:0088]   A:009A X:0000 Y:0880 P:eNvMxdIzc
$C1/1191 BF 9C 11 C1 LDA $C1119C,x[$C1:119C] A:009A X:0000 Y:0880 P:eNvMxdIzc
$C1/1195 85 89       STA $89    [$00:0089]   A:0011 X:0000 Y:0880 P:envMxdIzc
$C1/1197 6C 88 00    JMP ($0088)[$C1:119A]   A:0011 X:0000 Y:0880 P:envMxdIzc
$C1/119A 60          RTS                     A:0011 X:0000 Y:0880 P:envMxdIzc



we can guess where this loop is going, right?
Code: [Select]
$C1/6505 7A          PLY                     A:0050 X:0100 Y:0010 P:envMxdIZC
$C1/6506 98          TYA                     A:0050 X:0100 Y:0000 P:envMxdIZC
$C1/6507 38          SEC                     A:0000 X:0100 Y:0000 P:envMxdIZC
$C1/6508 E9 10       SBC #$10                A:0000 X:0100 Y:0000 P:envMxdIZC
$C1/650A A8          TAY                     A:00F0 X:0100 Y:0000 P:eNvMxdIzc
$C1/650B C9 F0       CMP #$F0                A:00F0 X:0100 Y:00F0 P:envMxdIzc
$C1/650D D0 ED       BNE $ED    [$64FC]      A:00F0 X:0100 Y:00F0 P:envMxdIZC
$C1/650F A5 92       LDA $92    [$00:0092]   A:00F0 X:0100 Y:00F0 P:envMxdIZC
$C1/6511 8D 3A DB    STA $DB3A  [$7E:DB3A]   A:0040 X:0100 Y:00F0 P:envMxdIzC
$C1/6514 C2 20       REP #$20                A:0040 X:0100 Y:00F0 P:envMxdIzC
$C1/6516 0A          ASL A                   A:0040 X:0100 Y:00F0 P:envmxdIzC
$C1/6517 0A          ASL A                   A:0080 X:0100 Y:00F0 P:envmxdIzc
$C1/6518 AA          TAX                     A:0100 X:0100 Y:00F0 P:envmxdIzc
$C1/6519 7B          TDC                     A:0100 X:0100 Y:00F0 P:envmxdIzc
$C1/651A E2 20       SEP #$20                A:0000 X:0100 Y:00F0 P:envmxdIZc
$C1/651C A9 F0       LDA #$F0                A:0000 X:0100 Y:00F0 P:envMxdIZc
$C1/651E 9D 0A 7D    STA $7D0A,x[$7E:7E0A]   A:00F0 X:0100 Y:00F0 P:eNvMxdIzc
$C1/6521 E8          INX                     A:00F0 X:0100 Y:00F0 P:eNvMxdIzc
$C1/6522 E8          INX                     A:00F0 X:0101 Y:00F0 P:envMxdIzc
$C1/6523 E8          INX                     A:00F0 X:0102 Y:00F0 P:envMxdIzc
$C1/6524 E8          INX                     A:00F0 X:0103 Y:00F0 P:envMxdIzc
$C1/6525 E0 00 01    CPX #$0100              A:00F0 X:0104 Y:00F0 P:envMxdIzc
$C1/6528 D0 F4       BNE $F4    [$651E]      A:00F0 X:0104 Y:00F0 P:envMxdIzC
$C1/651E 9D 0A 7D    STA $7D0A,x[$7E:7E0E]   A:00F0 X:0104 Y:00F0 P:envMxdIzC
$C1/6521 E8          INX                     A:00F0 X:0104 Y:00F0 P:envMxdIzC
$C1/6522 E8          INX                     A:00F0 X:0105 Y:00F0 P:envMxdIzC
$C1/6523 E8          INX                     A:00F0 X:0106 Y:00F0 P:envMxdIzC
$C1/6524 E8          INX                     A:00F0 X:0107 Y:00F0 P:envMxdIzC
$C1/6525 E0 00 01    CPX #$0100              A:00F0 X:0108 Y:00F0 P:envMxdIzC
$C1/6528 D0 F4       BNE $F4    [$651E]      A:00F0 X:0108 Y:00F0 P:envMxdIzC


a full loop over almost everything
Code: [Select]
$C1/651E 9D 0A 7D    STA $7D0A,x[$7E:CD3A]   A:00F0 X:5030 Y:00F0 P:envMxdIzC
$C1/6521 E8          INX                     A:00F0 X:5030 Y:00F0 P:envMxdIzC
$C1/6522 E8          INX                     A:00F0 X:5031 Y:00F0 P:envMxdIzC
$C1/6523 E8          INX                     A:00F0 X:5032 Y:00F0 P:envMxdIzC
$C1/6524 E8          INX                     A:00F0 X:5033 Y:00F0 P:envMxdIzC
$C1/6525 E0 00 01    CPX #$0100              A:00F0 X:5034 Y:00F0 P:envMxdIzC
$C1/6528 D0 F4       BNE $F4    [$651E]      A:00F0 X:5034 Y:00F0 P:envMxdIzC

$92 seems to increase with every sprite?
no real idea.

7E:7D0A to 7E:7E06 (+/- 3) seems to be reserved for the animations and 7E:7E0A is the next thing.
from there on seems to be general graphics, increasing
$C1/6525 E0 00 01    CPX #$0100
to CPX #0160 survived even ice3
...
we don't happen to have free $0200 RAM somewhere, do we?

Praetarius5018

  • Vargas
  • *
  • Posts: 88
    • View Profile
Re: Enemy Group size/spell animation issues
« Reply #3 on: June 23, 2017, 04:25:22 PM »
I'm actually disappointed that this works...

I just took the sprite counter and capped it at the last safe value. That's it.
Freezing it a low value would play no animations.

I simply replaced
Code: [Select]
$C1/6BDE E6 92       INC $92    [$00:0092]   A:0050 X:00FC Y:000E P:envMxdIzC
$C1/6BE0 E8          INX                     A:0050 X:00FC Y:000E P:envMxdIzC
$C1/6BE1 E8          INX                     A:0050 X:00FD Y:000E P:envMxdIzC

with (via JSL of course)
Code: [Select]
A5 92 LDA $92
1A INC
C9 3E CMP #$3E
90 02 BCC $02
A9 3E LDA #$3E
85 92 STA $92
C2 20 REP #$20
0A ASL A
0A ASL A
AA TAX
7B TDC
E2 20 SEP #$20
CA DEX
CA DEX
6B RTL

even Ice3 - which so far had the highest problem rate - worked against 8 enemies, not even glitchy color changes. has a bit slow down/sprite flicker, but what'cha gonna do.


just for security, also replace:
Code: [Select]
$C1/6528 D0 F4       BNE $F4    [$651E]with BCC $F4

in case it overlaps somewhere else...


that leaves only one mistery - why does a single target move vs the 8th enemy target the 1st player

edit:
ah no, that bug is better!
it does not target the 1st player, but the one "before" the current user; except in 1st player case it just does whatever because of index underflow

edit2:
just put EA at $C2/9517 and that's it... what.
« Last Edit: June 23, 2017, 05:19:13 PM by Praetarius5018 »

Praetarius5018

  • Vargas
  • *
  • Posts: 88
    • View Profile
Re: Enemy Group size/spell animation issues
« Reply #4 on: July 02, 2017, 06:13:06 AM »
I simply replaced
Code: [Select]
$C1/6BDE E6 92       INC $92    [$00:0092]   A:0050 X:00FC Y:000E P:envMxdIzC
$C1/6BE0 E8          INX                     A:0050 X:00FC Y:000E P:envMxdIzC
$C1/6BE1 E8          INX                     A:0050 X:00FD Y:000E P:envMxdIzC

with (via JSL of course)
Code: [Select]
A5 92 LDA $92
1A INC
C9 3E CMP #$3E
90 02 BCC $02
A9 3E LDA #$3E
85 92 STA $92
C2 20 REP #$20
0A ASL A
0A ASL A
AA TAX
7B TDC
E2 20 SEP #$20
CA DEX
CA DEX
6B RTL

well, I found at least one case where it doesn't work properly - axes.

They skip a lot of indexes and go straight from 9 to $50 and that obviously works.

praying...
Code: [Select]
A5 92 LDA $92
1A INC
C9 50 CMP #$50
B0 06 BCS $06
C9 3C CMP #$3C
90 02 BCC $02
A9 3B LDA #$3B //3C already leads to some graphic glitches for Flare
85 92 STA $92
C2 20 REP #$20
0A ASL A
0A ASL A
AA TAX
7B TDC
E2 20 SEP #$20
CA DEX
CA DEX
6B RTL


edit:
had to lower limit from #$3E to #$3C
« Last Edit: April 16, 2018, 11:13:13 AM by Praetarius5018 »

Shinryuu

  • Ymir
  • *
  • Posts: 16
    • View Profile
Re: Enemy Group size/spell animation issues
« Reply #5 on: April 17, 2018, 11:35:56 AM »
Wow, amazing work, Praetarius5018! Do you by any chance have your fixes available as an ips patch?
Because I'm unsure of how you replaced the original code of 4 bytes with a much longer code... What is JSL?

Praetarius5018

  • Vargas
  • *
  • Posts: 88
    • View Profile
Re: Enemy Group size/spell animation issues
« Reply #6 on: April 17, 2018, 02:57:27 PM »
Only in the most literal sense, yes, I have my fixes in an ips patch. Meaning all in the same ips.

Extremely simplified, JSL would be the asm equivalent of a function call.
Not so simplified, it can also be used like eval.
And even more simplified, it is even worse.

Basically, it pauses code execution where you currently are, jumps to a different spot, executes there until it hits a "return" (RTL in this case) and then unpauses.

It happens roughly like so.
Code: [Select]
$C1/6BDE 22 34 12 D8       JSL $D8/1234
$D8/1234 <do some stuff here>
...
$D8/12FF 6B                       RTL //returns to where you stopped
$C1/6BE2 <continue here like normal>

There is also a "small" counterpart JSR that functions the same but can't leave the current bank.
The target area of JSL doesn't have to be in the ROM, you can also move to the RAM and execute that (for your own sanity, don't), which is basically like a regular language's eval.
Now here's the thing that separates JSL from a regular function call: you do not have to move to the start of a function, you can go wherever you want.
Start of a "function", middle of it or heck execute a data table if you want, asm doesn't stop you, only the crashes will.

Lenophis

  • Forum Overlord
  • *
  • Posts: 1,688
  • Gender: Male
  • I sad
    • View Profile
    • Slick Productions
Re: Enemy Group size/spell animation issues
« Reply #7 on: April 18, 2018, 01:06:38 AM »
P.S. I wonder what cause the crashes ... is it software bug, is it some 'hidden' limitation of the GPU. Will the game crash if we use contemporary powerful PC? What about a different emulator?
Without even looking at it, I'm fairly confident that the OAM data overflowed into whatever else (maybe the stack), which caused the crash. This is probably why FF6's engine only used 6 slots for monsters, and probably why it had two separate routines for displaying damage with different numbers of targets hit at once. Although, I haven't really looked at FF5 enough to know if it has something similar or not.

The only way to make it not crash, is to hack the engine to put in a safety mechanism that will detect the number of targets and them being hit at once.

*reads other posts*

Oh... Looks like what I said wasn't it at all then. Nevermind!

119 bugs fixed and counting.

Shinryuu

  • Ymir
  • *
  • Posts: 16
    • View Profile
Re: Enemy Group size/spell animation issues
« Reply #8 on: April 18, 2018, 11:51:49 AM »
Basically, it pauses code execution where you currently are, jumps to a different spot, executes there until it hits a "return" (RTL in this case) and then unpauses.

It happens roughly like so.
Code: [Select]
$C1/6BDE 22 34 12 D8       JSL $D8/1234
$D8/1234 <do some stuff here>
...
$D8/12FF 6B                       RTL //returns to where you stopped
$C1/6BE2 <continue here like normal>

There is also a "small" counterpart JSR that functions the same but can't leave the current bank.
The target area of JSL doesn't have to be in the ROM, you can also move to the RAM and execute that (for your own sanity, don't), which is basically like a regular language's eval.
Now here's the thing that separates JSL from a regular function call: you do not have to move to the start of a function, you can go wherever you want.
Start of a "function", middle of it or heck execute a data table if you want, asm doesn't stop you, only the crashes will.

Thanks, I'll try it right away. One more question, though; is the space at D8/1234 really unused (it doesn't seem like that)? Can I just replace the code there with the one you posted without screwing up anything else?

Praetarius5018

  • Vargas
  • *
  • Posts: 88
    • View Profile
Re: Enemy Group size/spell animation issues
« Reply #9 on: April 18, 2018, 12:45:49 PM »
No, that was just an example of how the flow would look like.
I thought "1234" would be a dead give away for an example number...

Shinryuu

  • Ymir
  • *
  • Posts: 16
    • View Profile
Re: Enemy Group size/spell animation issues
« Reply #10 on: April 18, 2018, 01:55:35 PM »
Oh, sorry my bad, lol. I'll try to find some free space in the rom then. Thanks again.

13375K31C43R

  • Ultros
  • *
  • Posts: 675
  • Gender: Male
    • View Profile
    • Leet Sketcher's Final Fantasy III Patches
Re: Enemy Group size/spell animation issues
« Reply #11 on: April 20, 2018, 03:11:09 AM »
This looks cool, but given that there are no formations in the game with more than six monsters, are there any actual benefits to applying this to a vanilla ROM? As an example, you mentioned an issue with Ice2 on six enemies...

Ice2 doesn't crash the game at 6 enemies, but the 6th enemy didn't display the "got hit" part of the animation.

Is this for real? And are there any other examples?

Also, are any of these issues possibly contingent on your choice of emulator?
"Do not meddle in the affairs of wizards, for they are subtle and quick to anger." -Gildor from The Lord of the Rings

Praetarius5018

  • Vargas
  • *
  • Posts: 88
    • View Profile
Re: Enemy Group size/spell animation issues
« Reply #12 on: April 20, 2018, 11:26:01 AM »
This looks cool, but given that there are no formations in the game with more than six monsters, are there any actual benefits to applying this to a vanilla ROM? As an example, you mentioned an issue with Ice2 on six enemies...
No, my fix doesn't address Ice2 (Ice2 doesn't exist in my hack so I didn't have to bother with it)
It is only useful if you create a hack that makes actual use of 7-8 enemy formations.

Ice2 doesn't crash the game at 6 enemies, but the 6th enemy didn't display the "got hit" part of the animation.

Is this for real? And are there any other examples?

Also, are any of these issues possibly contingent on your choice of emulator?
I didn't try every animation so there might be more.
I'm 90% sure it is emulator independant - most of the relevant issues are caused by writing animation related data to an area intended for other graphical stuff resulting in garbage or even outright crashes.