øAslickproductions.org/forum/index.php?PHPSESSID=5f0fck550j2m4m2fpbtkj2vkm1&action=profile;u=339;area=showposts;start=105e:/My Web Sites/Slick Productions - FFIV Message Board/slickproductions.org/forum/index89bd-2.htmlslickproductions.org/forum/index.php?PHPSESSID=5f0fck550j2m4m2fpbtkj2vkm1&action=profile;area=showposts;u=339e:/My Web Sites/Slick Productions - FFIV Message Board/slickproductions.org/forum/index89bd-2.html.zxÝ›h^ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÈ@>ìâOKtext/htmlISO-8859-1gzip8:ÖìâÿÿÿÿÿÿÿÿWed, 11 Mar 2020 08:22:13 GMT0ó°° ®0®P®€§²ð®Ü›h^ÿÿÿÿÿÿÿÿj1ìâ Show Posts - avalanche

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - avalanche

Pages: « 1 2 3 4 5 6 7 8 9 »
106
Final Fantasy IV Research & Development / Spell Visual Effects
« on: December 27, 2014, 03:41:16 PM »
Here is some information about how spell visuals are coded and animations stored in the ROM.  This would be pretty long for one post, so I will make a few, and link to them from this first as a little table of contents.

Table of Contents
1. Spell Visual Table
2. Sprites
3. Keyframe Animations
4. Frames for Animations
5. Master Routines

107
Here are a few bits I deciphered from the battle/encounter/formation/arrangement data.  I think Yousei called this "Enemy Combination Data".  Boy we have a few names for things, don't we?

Encounter Table
At 70200 in the ROM.
  byte 4:
        bits 0-1: indicate which of the 3 monster types are initially hidden (eg Shadow dragon, what Alert summons, etc)
              00: normal, all 3 appear
              01: monster type 2 initially hidden
              10: monster types 2 and 3 initially hidden
              11: monster type 3 initially hidden

The 3 bottom bits in byte 0 are still unknown to me.  Bit 0 is on some but not all of the boss battles, bit 1 is on most of the non-boss battles but a few boss ones as well, bit 2 is only on Calbrena and the final Zeromus battles.

Monster Positions:
Indexed by byte 5 in the above table, into the ROM at 71200.  Each entry is 8 bytes, one for each monster in the order they appear (all monster type 1's, then 2's etc).  The high nibble is X, low is Y, in 8-pixel units, with a small additional offset for X:
     xxxxyyyy
            - Final screen X position is (x * 8) + 16
            - Final screen Y position is (y * 8).


To show my work, attached are some images I made using the data above.  They're missing the +16 in X, for those with a detailed eye.  The large bands of color in the background were what I used to look for patterns for the bits.  You can see in the Calbrena image both of the byte 4 bits on (green and dark blue), which means "monster type 3 initially hidden", so the big Calbrena is hidden but the Cal and Brena are present.  For completeness, the byte 0 colors are 0=red, 1=yellow, 2=cyan.


108
Thanks!  My purposes were just to figure out the fundamentals of the ATB system, including how long between each turn and how long each status timer typically lasts.  I hadn't come across discussion that quite satisfied my need for something more formulaic.  The most interesting thing to me is that the ATB ticks are paused almost all the time.  Any time a character or monster is performing an action, showing a spell animation, showing a message on the top of the screen, the timers all wait.  This can be witnessed with a very short casting period for a spell when nothing else is happening vs a very long casting period if any other players or monsters are "doing" something.

109
Whew!  That was going to be a lot of staring at assembly to figure out.  I'll have to find another challenge to earn that giant "like" icon.

110
This poison post reminds me about some ATB status timer notes I made.  I don't want to hijack your post, but maybe you'll find it relevant with the disassembly analysis you do.  Sorry if this stuff is already well-known, just tell me to hush.  : )

First an area of RAM that the ToB docs didn't have full info for.
$29EB: 2-byte entries for each PC/monster slot in battle
  byte 0:  bits to enable each status timer for this PC/monster
      80: Stop
      40: "Main control timer" - used by normal player/AI control, also by impairment statuses like Sleep, Paralyze
      20: HP Leak
      10: Poison
      08: Gradual Petrification
      04: Wall/Reflect
      02: Count/Doom
      01: unknown
   byte 1:  Unknown

The bank 3 address you mentioned, at 03:A005 (ROM 1A205) is a table with at least 10 pointers to assembly routines that are used to calculate the duration for timers.  I don't have these fully figured out, but here's what I scribbled down.  BaseSpeed and SpeedModifier are the two speed elements in the ToB character record doc.

   0: (BaseSpeed * SpeedModifier) / 16 
        (aka normal time to next turn)
   1: 0 if player, SpeedModifier / 16 if monster
   2: duplicate pointer of #1
   3: ?
   4: MinOf1(300 - 4 * [ModifiedWill or unknown byte for monster]) * SpeedModifier / 16 / 6
        used by immobilizing status
   5: duplicate pointer of #4
   6: ([ModifiedVitality or unknown byte for monster] + 20) * SpeedModifier / 16
        used by poison, damage+poison, etc
   7: duplicate pointer of #6
        used by gradual petrification
   8: (SpellPowerByte? * 2 + 30) * SpeedModifier / 16
        used by Wall/Reflect
   9: ?
        used by HP Leak
   A: (SpellPowerByte? * 3) * SpeedModifier / 16
        Used by Stop, Magnet. I think Stop passes 10 decimal, Magnet 50 decimal.

   Not sure that the table stops there, but that is where I stopped.


Then at $2A04 are where the timers are stored for each slot.  As I think the ToB docs mentioned, they are $15 (hex) bytes long for each PC/monster which corresponds to 7 timer entries at 3 bytes each.  The order for these is the same as the enabling bits above:  Stop, "Main", HP Leak, Poison, Petrification, Wall, Count.

   bytes 0,1:  16-bit timer value.  This is decremented each ATB tick (if enabled with bits above)
                      and does something at zero.  Most of these are assigned by calling one of the assembly routines
                      listed above.  Count/Doom, for example, just copies the 10 from the spell power into it directly
                      (which to me is damning evidence that fast/slow does not affect Count, because the
                      SpeedModifier is not used in the formula)

   byte 2:       some flag bits.  I know when the main control timer's has 00 here, it means the player
                     or AI gets to choose what to do for the next turn.  I saw a lot of the others use 40 hex here frequently.
                     In short, it tells the code what to do when the timer reaches zero, but I didn't get many details.
                     I remember seeing another post here relating to values used here for queueing up actions, etc.


Happy Holidays everyone.

111
Another update: animated tiles now actually animate!!

Congrats! I'm glad my first post was of some help! (I have to enjoy that one as much as I can because the overworld map graphics might not work out so well)

112
World map tile graphics are still a big mystery.

Challenge Accepted.

113
Quote
Not much has been documented. I delved into it a bit once for myself trying to make some custom spell animations, but I kept very few notes. Furthermore, I'm not really very well versed in how SNES actually interprets graphical data, so whereas I can look at the ASM and notice patterns and pointers, a lot of the finer points of it all elude me.
Any notes you have would definitely be useful and appreciated (but in a new thread).

Will do.  It will have to wait until after the holidays, but I'll post what I have found about them.  Pretty interesting stuff.

Quote
On a tangential note - do you happen to know anything at all about world map graphics? Like, where the graphical data and/or tile assembly data are?

Are you referring to the 16x16 graphics themselves?  I'm afraid not, I just made a tileset PNG manually from some other sources at some point.  All I could point out is what ye olde FF4.txt says:
Code: [Select]
A0200-A07FF (148000-1485FF) World Map Tile Formation Data
A0800-A0AFF (148600-1488FF) World Map Tile Palette Pointers
A0B00-A0C7F (148900-148A7F) World Map Palette Data
A0C80-A0F7F (148A80-148D7F) World Map Tile Properties Data
...
E8200-ED5BF (1D8000-1DD3BF) World Map Tile Graphic Data (also used to construct pointers to town gfx)
I just scanned through the entire ROM in 3 bpp format and didn't see them.  FF4.txt lists it at E8200 but that looks pretty tabular to me.  Are they 4 bpp?


114
That looks correct, it's exactly what I am doing for the handful of tilesets for which I found a base address.  The animation base address I listed is in the ROM with the header.  Perhaps too obvious, but was the major index shifted right 2 bits?

An example.  In the House (5) tileset, tile 17 (hex) is the clock tile.  Its top left corner subtile bytes are 24 15.
15 => 001(0 01)(00)
So its major index is 1, and minor is 0, so the address of the first frame for it is FC4C0 + ( 24dec * (major * 16dec + minor) ) = FC640 (which overlaps with the Castle tileset by the way so it can share the clock).

Oh, maybe I wasn't clear that the 16 was in decimal not hex?


I should take a stab with Geiger's to find whether the game uses a table or some other math formula to locate those base addresses so we can find the others.


Unrelated question, is the way spell animations are stored well known?  I have done a bit of deciphering on them, and want to know if it would be new useful information to post what I have.  It might be lengthy..

115
Quote
Though what is this separate list and how do you differentiate it from mine?

The one I looked at when I said that is from my list of commands the monster AI uses in the attack sequences.  I *think* I got that from http://slickproductions.org/forum/index.php?topic=1713.330 in the post by Dragonsbrethren.  The list from C0-D9 is what I mapped back to 00.  Perhaps this is a totally different list?


116
I see.  Definitely a deeper challenge than my "have you tried these obvious bits?" suggestion.  : )

Quote
Ah... now I'm confused. What are the other action routines then? This may be the first time I've heard of a numeric order given to the Action Routines. Maybe there's some different terminology going on here...?

Probably terminology.  You called them Commands here: http://slickproductions.org/forum/index.php?topic=1883.0  00=Fight, etc.  Although now that I check the list I have, they pretty much only have 00=Fight in common...  In any case, it is what you listed as "02 White/Black/Call/Ninja/Spell Item Routines - 03CC46"

117
This is some impressive and useful documentation! With this I might be able to think of some way to make my Item Lord command properly differentiate between a Single Targeted Battle Item and an All-Targeted Battle Item.

Are the items the spell-like ones (index B0+)?  For those, there are bits in the item entry.  Come to think of it, the weapon-as-spell has them too via the spell they invoke, I think.


That this bit would cause Magic Defense Multiplier to always be 1 is strange. What this bit does when activated is it also seems to kill Magic Multipliers if not other multipliers, you should try it out for yourself to see the weirdness in it.

What it does from my experience...

It has a decent chance of missing, even at 127% Accuracy and lowers damage to very low amounts ranging from 40's to mid 1000's depending on the amount of the Power of the spell.

You are right, I will have to try it.  I have only looked at the assembly for my assessment, and as you know, the assembly can give quite a keyhole view into what's happening.

I would expect the defense_multiplier being lowered from a higher number to 1 ought to make it more likely to hit, and result in higher damage.  Unless the other bits were set, of course.  The one on the hitrate byte, at $289E in the spell code, has some pretty strange behavior too.  I very possibly got one or more things wrong with the analysis of the routine, for sure.


This documentation is on the 02 Routine which is the Damaging Spell Routine (as I'm sure you're aware) but it also screws up damage all around, whether that damage come from HP Sap, Draining HP, and Attack Based on Physical Attack Power, the only damage it seems to deal with properly are fractions of damage or damage based upon the caster's current HP.

It's the 02 Action routine for all spells, not the 02 spell routine.  So it would affect all the individual spell statistical routines.  Would make sense for the HP-based to not use any multipliers.  The assembly for caster's-HP-based for example explicitly overwrites what I called the net_multiplier to 1 at [03:D9B0].  Anyway, I will have to check out some spells and toggle the bits to see the actual in-game behavior.

118
Okay here we go.  First for some due credit: I based this heavily on your work, Grimoire.  I tried to fill in some of the missing pieces where (presumably) Geiger's live disassembly naturally jumped over some sections, but I probably missed some. And there were some sections I omitted, but I tried to indicate that below.

The bit in question is used a little over halfway down, after the label for address 03:D0A9.

Code: [Select]

[03:CC46]  Spell Routine (Command 0x02)
           Note: Item (0x1D) routine jumps into this too for most of the work.
----------------------------------------------

Sorry, I did not analyze the first chunk of the routine.
I believe part of it is looping targets to check for valid ones so that
it can calculate the divider used to split damage or healing.

The subroutine called at [03:CD33] for player Summon spells basically maps
to the Enemy Summon equivalent.
It replaces the caster's next subaction at $26D2, and sets $3584 to 1 as a flag.
To be honest, I did not know it overwrote $26D2 when I analyzed most of this,
so I may have some logic errors where the code tests for spell number ranges.

When Asura, it picks one of the 3 Asuras at random, and overwrites the
party target at $26D4 with 0xF8 (presumably to target all party?)

[03:CD3E]
Note: This is where the Item routine (0x1D) jumps in.

Starting around [03:D2CE] is where it looks to be checking for life-like spells.


[CE28]
    if (num_targets == 0)
        FAIL
   
    if (spell targets only ALL of ally or enemy)
        num_targets = 1                    // Clarification: this is the split damage/healing divider

[CE42]
    if (caster is a player)
    {
        if (caster.mp < spell.mp_cost)
            FAIL
        caster.mp -= spell.mp_cost
    }
   
[CE7B]
    if (using a spell, not an item)
    {
        if (caster has Mute and spell < 5F)   // The "verbal" spells, perhaps.
            FAIL
        if (caster has Piggy and spell isn't Piggy)
            FAIL
        if (caster has Toad and spell isn't Toad)
            FAIL
    }
   
[CEB7]
    hitrate = spell.hitrate
    if (spell is a White spell)
        hitrate += caster.will / 2
    else
        hitrate += caster.wisdom / 2
    if (hitrate > 255)
        hitrate = 255
    if (caster has Darkness)
        hitrate /= 2
    if (caster is in slot 0)
        hitrate *= 5 / 4
   
[CF01]
    // I reordered this section a bit to make the logic easier for me to follow
    if (is a weapon spell from the Item routine)
    {
        successful_hit_count = weapon_spell_multiplier  // from table at 0F:9070
    }
    else if (using an item or <byte at $38ED, possibly flag for Grimoire item?>)
    {
        successful_hit_count = 8
    }
    else
    {
        if (spell has solo multiplier bit?)     // top bit of effect index byte
            attack_multiplier = 1
        else if (spell is a White spell)
            attack_multiplier = caster.will / 4 + 1
        else
            attack_multiplier = caster.wisdom / 4 + 1
        successful_hit_count = calculate_multiplier(hitrate, attack_multiplier)
    }
   
   
[CF3E]
    Sorry, unknown stuff I did not complete.
    Part checks for Wall reflecting.
    Part also checks for some target statuses.  Very incomplete notes:
        If target is Hiding or Swoon, allow spell effects 0A (life) and 30 (I think Revive Monster?), but FAIL any others.
        If target is Stone, allow spell effect 0B (heal status), but FAIL any others.
   
[D049]
    // Note the game code uses a 2x biased integer for the elemental and creature "multipliers",
    // so (1 means 1/2x, 2 means 1x, etc)
    // and sets the top bit for absorb.  Here I just use real numbers like 1, -0.5, for simplicity.
    // The game initializes these memory locations for various calculations later; they are unused for the rest here though.
    is_crit = false
    elemental_multiplier = 1x
    creature_multiplier = 1x
   
    if (spell is a player Call spell)
        power = spell.power * 8
    else
        power = spell.power * 4
   
    if (caster and target are both PCs)
        defense = 0
    else
        defense = target.magic_defense

[D0A9]
    evasion = target.magical_evasion
    if (target has Darkness)
        evasion = 2             // I think it sets to 2, but that seems weird. Did they intend 0?
    if (caster is in slot zero)
        evasion *= 5 / 4        // This seems odd. Is it a penalty for spell use in the front?
   
    defense_multiplier = target.magical_defense_multiplier
   
    if (defense_multiplier > 0)
        if (spell has top bit of elemental index byte)      // <-- Here is the bit in question?
            defense_multiplier = 1
           
    if (target has Toad or Charging)
        defense_multiplier = 0
       
    if (target is a monster)
    {
        if (target.magical_defense_multiplier == 255)
        {
            evasion = 99
            defense_multiplier = 99
        }
    }
    successful_evasion_count = calculate_multiplier(evasion, defense_multiplier)
   
[D113]
    if (caster and target are both PCs)
        net_multiplier = successful_hit_count
    else
        net_multiplier = successful_hit_count - successful_evasion_count
   
    <tests $2A35 if non-zero causes a FAIL>
   
    if (net_multiplier <= 0 OR (target.is_boss AND spell has top bit of hit rate byte))
    {
        if ((spell is A0 [Explode]) or (5F <= spell <= 93) or (spell >= A9))
            net_multiplier = 1
        else
            FAIL
    }

[D162]
    // if invincibility is on, and target is a monster.  let monster target itself though
    if (invincibility_counter != 0 AND target is a monster AND caster != target)
    {
        // more simply this means: everything but the Crystal fails.
        if (using a spell)
            FAIL
        if (item is NOT the Crystal)
            FAIL
    }

       
[D17B]
    <Sorry I didn't finish this part>

    Eventually it jumps to the spell effect routine itself.

So, algorithmically, this bit would clamp the defense multiplier to 1 if it was higher.  In theory, this could affect whether the spell hits or misses, as well as any damage or healing that is calculated subsequently if any.  I honestly haven't looked at which spells have any of the 3 bits on yet though, so I will have to hold off making a better higher level description of its purpose.


119
Could I ask which bit you are talking about? I've done some analysis of the spell routine (based on all the hard work of everyone in this thread) and three of the bit 7's in the spell table, translating into psuedocode. Maybe I can offer something. One of them was rather weird as I recall.  There is something in there about allowing life spells through too, but I'll have to check my notes (later today).

120
Byte 0:
   bit 0:      Layer 1
   bit 1:      Layer 2
   bit 2:      Same layer on opposite side (Transition or Bridge Layer)
   bit 3:      ?
   bit 4:      Closed door tile
   bits 5-7:   ?
Byte 1:
   bits 0-2:   ?
   bit 3:      Bottom half is in front of the character
   bit 4:      Load previous map at previous location (Location Trigger)
   bit 5:      ?
   bit 6:      Enemy encounters possible
   bit 7:      Check tile’s location in [Location Trigger Data]

I have ideas on two of these mystery bits, if it helps anyone.
Byte 0, bit 3:  Save tile
Byte 1, bit 5:  Use alternate battle background (e.g.: Water instead of Cave), or talk-through-able?

For the second one, it is on watery tiles in the Cave tileset.  But in the House tileset, it is on things like desks which makes me wonder if it is how the game lets you talk to NPCs "through" them like the vendors.  Fair warning, I have not tested these theories via patching the game, just noticed patterns.


Pages: « 1 2 3 4 5 6 7 8 9 »