• Welcome to Final Fantasy Hacktics. Please login or sign up.

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 - Glain

Help! / Re: ASM understanding
January 12, 2021, 06:00:40 pm
They're two separate routines that happen to be placed next to each other.  They both have a closing jr (at 0x186d24 and 0x186d50, respectively).  Neither one has a nop, but what's the relevance of that?  They are referenced in the formula pointer table, of course...

1.  I'm unaware of unknown skill bytes.  If you wanted to consolidate the routines into one by, say, providing the action offset as an argument, it looks like you could save some space.  It doesn't seem like anything amazing though, unless there are a bunch more routines like this.

2.  Are you asking if the AI would use Cheer Up?  I haven't tested that, although I can't say I remember enemy mediators using Praise very often...
Help! / Re: ASM understanding
January 12, 2021, 09:24:27 am
1.  Just off the top of my head, a bunch of code can be made more efficient by keeping values stored in registers instead of reloading or recalculating them, and re-ordering code to remove nops can help quite a bit as well.  Getting a good understanding of what the code is doing in each case gives a good idea of which parts of it seem to be unnecessary.

2.  Generally speaking, it's absolutely not safe, and it should be assumed that a crash would result.  This will usually corrupt the stack pointer and saved register values, unless you've accounted for that.  It can be made to work in very specialized cases with the right (hacky) setup.
The Geomancy ability is intended to be placed in a Default skillset.  As for the Jump ability, yes, it's based on the Lancer job level.  I probably should have mentioned that.
Help! / Re: ASM understanding
January 11, 2021, 09:19:21 am
It's just redundant.

This happens a lot in the vanilla code, where it's like the compiler generated code to do one thing (in this case, set the action's CT), then generated code to do another thing (set the action's type), and just mashed them together without taking into account that it could have just reused the value in r3 instead of reloading the action pointer.

(Vanilla code isn't going to branch into the middle of the routine, and the only branches inside the routine skip to the end of the routine, so those two bits of code will always be run in sequence.)
Another update to my XML, brought about by an issue found with the swap units hack when units are on proposition.  That issue should be fixed in this latest update. There are also a bunch of new hacks! The original post has the new version of the XML and include files.
Beta v6:

Command line patching is now supported for FFTPatcher, FFTactext, FFTorgASM, and EntryEdit by using command line arguments "-patch" and then specifying the patch file and disc image (or pSX savestate).  There is generally no output on a successful run (unless FFTorgASM is warning that files appearing in patches are either unsupported or not present in the specified savestate), and an error message can appear in the console if there is a problem.  If the program opens up its normal window, then there was something wrong with the passed arguments (file(s) not found, etc.) 
    By default, the console does not wait for the program(s) to finish, because they aren't configured as console applications.  Using "start /wait" will make the console wait.
        start /wait "Patch" FFTPatcher -patch patchfile.fftpatch fft.iso
        start /wait "Patch" FFTactext -patch patchfile.ffttext fft.iso
        start /wait "Patch" FFTorgASM -patch patchfile.xml fft.iso
        start /wait "Patch" EntryEdit -patch patchfile.eepatch fft.iso

    *  Enabled editing ability effects for all applicable abilities.
    *  View stat form now uses correct Monster average Raw MP.

    *  Now displays patch descriptions in a more natural way, with better handling of whitespace.
    *  Persistent labels can now be referenced anywhere in a patch, even if they are defined in later Location tags.
    *  Save Patch XML option now updates variable values and doesn't write out blank Location tags.
    *  Spacebar can check/uncheck patches again, if the selection cache for the type ahead is empty (ESC to clear).
    *  Variables can now be declared with symbol="true" and no accompanying file, sector, or offset.  These variables would then only be referenced as macros in ASM blocks.
    *  Added a "hidden" attribute for patches (true or false, default false).

    *  Added support for .if, .else, .endif preprocessing commands.  Skips lines if condition is not met.  Blocks can contain multiple lines, and nesting is possible.
            .if    >, %ChangePartyLevelRandom, 0
                srl    t3, t2, 4
                move    t3, t1

    *  Fixed an issue where using the "load immediate" pseudo (li) with a label could cause addresses to be calculated incorrectly.  Using li with a label will now always cause it to expand to two instructions.

** Updated with additional fixes (thanks Cerabow and EnderC for reporting issues):

        *  Fixed context menu exception when clicking out of bounds in a data grid view (Action Menus, Monster Skills, Poaching tabs)
        *  Fixed an exception that occurred when setting an item to use an ability with an ID > 0x7F, where the ID would erroneously be used in a reference to the Status Infliction list.
        *  Selected entries for Inflict Status and Item Attributes tabs refresh when the tabs are clicked, so that they display the current correct information for which Items or Abilities are linked to each.
Hacking/Patching Tools / Re: Formula mapping
December 21, 2020, 10:10:40 pm
For some of these questions, it would make sense to look over the MassHexASM thread, which explains some of this.  In short:

The "@" in front of a label means it persists across Location tags.
t1 and t0 are names for the first two "temp" registers (and actually refer to $9 and $8, respectively). Check out the calling conventions.
.eqv is a preprocessor instruction that defines a simple macro which replaces the first string with the second before actually encoding the block.
I tried this out earlier today. I didn't get any freezing but did get weird behavior (enemy AI attacking their own units!) 

I think the issue is that the code block in the second Location tag is one line too long, and overlaps another case (which would jump directly to that line, storing a bad value).  I was able to make a modification that I think got it to work though.

What I did was cut the last line of the second Location tag, paste it over the first nop in the first Location tag, change r2 to r5 in that line, and change r2 to r5 in the "Load Charge Power" line.
Quote from: Arimala on December 05, 2020, 07:50:50 amHmm I did not notice this... using the formula 2D Dmg (PA*(WP+Y)) on the wiki, "addiu r29, r29, 0x0018" did not get transferred over using import code because on the wiki it says:
"27bd 0018 addiu r29,r29,0x 0018" instead of "27bd0018 addiu r29,r29,0x 0018"
Is that space there for a reason? Most of the formulas on the wiki seem to be like that, but not all. I guess it is not intended for this use is why.

This is a mistake on the Wiki that stems from the way the formatting was done. 

To elaborate, if you use View Source to look at how the code is formatted on basically any of the Wiki pages, you should see that each line actually starts with a space.  This makes it so that the code formats the way we want it.

Generally when we put code on the Wiki, we're pasting it from a text file that doesn't have the spaces.  So, to add the spaces, there were times when a certain search/replace was done.  In this case, "0018" was replaced with " 0018" because the start of each line (the RAM address of the line) started with 0018.  That did create the leading spaces, but also the side effects you're seeing.

Quote from: Arimala on December 05, 2020, 07:50:50 amSo if I can just keep using r1 as the base then you are telling me the code on the wiki is less efficient?
From what I could see on all the code, anything new loaded in used a new register.

Yes, the code on the Wiki (the game's default code) is less efficient than it could be in many places, a product of the compiler they used.  In some cases, very much so.

Quote from: Arimala on December 05, 2020, 07:50:50 amI am confused by the wires crossed bit though.
This is taken directly from https://ffhacktics.com/wiki/Store_PA_and_WP_%2B_Y.
lui r4, 0x8019
lbu r4, 0x0036(r4)  Load Attacker's PA

Those two lines don't appear in sequence without another manipulation of r4 first:

00185e5c: 3c048019 lui r4,0x8019
00185e60: 8c842d94 lw r4,0x2d94(r4)    # Load acting unit pointer (from 0x80192d94)


00185e74: 90840036 lbu r4,0x0036(r4)  # Load PA of acting unit (from acting unit pointer + 0x36)

Quote from: Arimala on December 05, 2020, 07:50:50 amand loading ability X is 0x38f9 in all the other formulas from what I saw

Ability X is stored at 0x801938f9.  What you're loading is 0x38f9 away from the acting unit's pointer. 
The acting unit's PA is stored 0x36 bytes away from its pointer, but you're instead loading from 0x80190036.

It should be more like this:
[0x80151114]  lbu r4, 0x0036(r5)  # Load PA of acting unit
[0x80151118]  lui r5, 0x8019
[0x8015111C]  lbu r5, 0x38F9(r5)  # Load Ability's X
The freezing is probably because you're corrupting the stack pointer (r29).  You're subtracting from it at the start of the routine (the first instruction is really "addiu r29, r29, -0x0018" and then not adding that 0x18 back at the end.  The solution is to insert "addiu r29, r29, 0x0018" at the end of your routine before the "jr r31" (or after it).

You are also inexplicably ending your routine after setting XA equal to PA.  What is this doing here?
0x80151140   jr r31   
0x80151144   nop

For efficiency's sake... you can set a register to 0x80190000 and then just keep using it as a base, i.e.:
lui r1, 0x8019          # r1 = 0x80190000
lw  r5, 0x2D94(r1)      # Keep using r1 as the base...
lbu r2, 0x3902(r1)
lbu r3, 0x38FA(r1)

You would only have to repeat the lui after a routine call (jal).

It also looks like you got your wires crossed here:

0x80151114   lui r4, 0x8019   
0x80151118   lbu r4, 0x0036(r4)   # Load Attacker's PA Loading from 0x80190036?
0x8015111C   lbu r5, 0x38F9(r5)   # Load Ability's X   Loading from (Attacker base pointer + 0x38F9)?

Beta v5!

Introducing EntryEdit!
    * Edits Battle Conditionals, World Conditionals, and Events.  Loads/saves to patch files, script files, disc images, and pSX save states!
    * Customizable by editing EntryEdit.exe.config and associated XML files.  Defaults are vanilla, but has pre-built support for Event Instruction Upgrade by setting "ModSuffix" to "Upgrade" in the config file.

FFTP suite now includes MassHexASM.

FFTPatcher, FFTactext, and EntryEdit can open patch files directly (.fftpatch, .ffttext, .eepatch) via command line.  Also works with file association in the file explorer.
Icons added for FFTPatcher, FFTactext, and FFTorgASM.
Version number of the FFTP suite now displayed in the title bar.

    * When importing ISO, no longer loads additional entries per section.
    * When importing ISO, uses non-DTE character map for sections with DTE disabled (such as all OPEN.LZW sections by default).

ASM Encoder/Decoder:
    * Now replaces labels and equivalences in reverse order of name length to avoid replacing partial names.
Help! / Re: Editing Text WOTL PSP
September 30, 2020, 05:03:08 pm
What happens with this version?
Completed Mods / Re: Auto-SCC Patch
September 16, 2020, 08:02:21 pm
Sure, I suppose you could.  At least, I can't think of any reason why not off the top of my head.
Beta v4 release:

    * Fixed bug in ability editor where it could try to update the "inflict status" values for abilities without attributes
    * Fix for ampersands inside certain controls that use TextRenderer.DrawText() (Includes ENTD unit area)

    * Made PSXText.xml and PSPText.xml external files that can be used to configure section entries, DTE, compression, etc.  These were previously the internal psx.xml and psp.xml files.
    * Text sections now have at least the number of entries specified in the appropriate XML file, even if text is loaded from a file without those entries listed.
    * Corrected number of entries for Diary of Nanai and Wyuvle.

    * Moving ASM blocks also updates loads/stores and address references!

ASM Encoder/Decoder:
    * No longer flags load delay on writeback registers.
The conflict is not in data.  It arises because the two hacks are editing program code in the same routine: https://ffhacktics.com/wiki/Equipment_Attribute_Setting

Those hacks rewrite that routine in different ways, so they are not compatible.  There's no way to get around that by moving anything (indeed, there is nothing to move).

(Writing only to free space would be useless because the new code or data would never be referenced by the game.  Other changes are needed to change the behavior of the game.  Some hacks don't need or use free space at all.)
Each entry in the free space viewer refers to one section of a patch. 
Length refers to the length (in bytes) of that section.

Address + Length = Next Address
Next Address + Space To Next Patch = Address of next entry in the list (or the end of the free space block, if there isn't one)

If the Space To Next Patch is negative, it will be colored red, and indicate a conflict with the next entry in the list.

In the screenshot, the free space viewer is only showing one entry, so no conflict is shown.

I took a look at Pride's Item Attribute rewrite patch (v1.1), and it doesn't appear to use free space at all... 

When you saw the conflict in the conflict checker, was the background color red or white?  If it was red, that conflict was not in free space and cannot be resolved with a move.
I'm releasing another version of my XML (and Include files), including the Unit bench hack (10 extra unit slots)!  It's attached to the original post in this thread (direct download).

This update includes the Now Loading routine rewrite, a patch that can expand load and save data, and the Unit bench hack (which includes the former).
This version of my .XML also comes with (and requires) the latest FFTPatcher suite 0.493, currently available here.

EDIT - Uploaded new version of XML to fix problem with circle menu regarding the bench hack.
EDIT - Uploaded new version of XML to add the option to change the checksum end block for the Expand Load and Save Data and Unit Bench hacks.  Changing 3C to 40 (hexadecimal values) will cause saves made without the patch not to load!
EDIT - Uploaded new version of XML to fix issues regarding Tutorials.

EDIT - Uploaded new version of XML to fix an issue with the Speed shortens Ability CT patch where AI routines were unaware of the CT change.
Some fixes and features later, another beta...

FFTPatcher 0.493 Beta v3:

    * Added and modified some patch XMLs (Dokurider.xml added).
    * Fixed issues with Free Space viewer and Conflict Checker.
    * "Complete!" message no longer appears when Canceling an action.
    * Now supports <Include> tags with a "patch" attribute to include another patch (by name).
    * Reload button now reloads the currently selected file.  Select All in the file list before pressing Reload to reload all the files.

This also includes the latest version of my XML file (including the unit bench hack).
EDIT - Updated attachment to include latest fix for bench hack.
I'll have a better consolidation of this later, reflecting the newer version of my XML coming in .493.  But for now...

Now Loading Routine Rewrite

This is a rewrite of the routine that builds the Now Loading message in order to make it shorter.  This frees up 1272 bytes in SCUS.   Also has variables to set the color of the Now Loading message!

    <Patch name="Now Loading Routine Rewrite">
        <Location file="SCUS_942_21" offset="40BD8" mode="ASM" offsetMode="RAM">
             #   ROUTINE: Build Now Loading Message (Rewrite)
                    addiu   sp, sp, -48
                    sw      s0, 16(sp)
                    sw      s1, 20(sp)
                    sw      s2, 24(sp)
                    sw      s3, 28(sp)
                    sw      s4, 32(sp)
                    sw      s5, 36(sp)
                    sw      ra, 40(sp)
                    move    s1, a1
                    move    s2, a2
                    lui     s3, 0x8005
                    addiu   s0, s3, -0x28e0
                    sw      a0, 0x8004760c
                    move    a0, s0
                    li      v0, 9
                    sb      v0, -0x28dd(s3)
                    li      v0, 0x2c
                    sb      v0, -0x28d9(s3)
                    li      t0, 0x80
                    li      t1, 0x80
                    li      t2, 0x80
                    sw      zero, -0x1a48(s3)
                    sb      t0, -0x28dc(s3)
                    sb      t1, -0x28db(s3)
                    sb      t2, -0x28da(s3)
                    jal     0x80023c68
                    li      a1, 0
                    li      v0, 0x1f
                    sh      v0, -0x28ca(s3)
                    li      v0, 0x7887
                    sh      v0, -0x28d2(s3)
                    li      s5, 1
                    addiu   s4, s0, 40
                    move    a0, s4
                    move    a1, s0
                    jal     copy_words
                    li      a2, 40
                    addiu   s5, s5, 1
                    sltiu   t0, s5, 7
                    bne     t0, zero, copy_loop
                    addiu   s4, s4, 40
                    #   "No" block
                    la      a0, 0x8004d720
                    addiu   a1, s2, 200
                    addiu   a2, s1, 160
                    addiu   a3, s2, 208
                    addiu   t0, s1, 172
                    li      t1, 155
                    li      t2, 228
                    li      t3, 163
                    jal     write_and_copy_block
                    li      t4, 240
                    #   "w" block
                    la      a0, 0x8004d748
                    addiu   a1, s2, 200
                    addiu   a2, s1, 171
                    addiu   a3, s2, 208
                    addiu   t0, s1, 178
                    li      t1, 163
                    li      t2, 228
                    li      t3, 171
                    jal     write_and_copy_block
                    li      t4, 235
                    #   "loa" block
                    la      a0, 0x8004d770
                    addiu   a1, s2, 200
                    addiu   a2, s1, 183
                    addiu   a3, s2, 208
                    addiu   t0, s1, 195
                    li      t1, 85
                    li      t2, 173
                    li      t3, 93
                    jal     write_and_copy_block
                    li      t4, 185
                    #   "d" block
                    la      a0, 0x8004d798
                    addiu   a1, s2, 200
                    addiu   a2, s1, 195
                    addiu   a3, s2, 208
                    addiu   t0, s1, 200
                    li      t1, 96
                    li      t2, 209
                    li      t3, 104
                    jal     write_and_copy_block
                    li      t4, 214
                    #   "i" block
                    la      a0, 0x8004d7c0
                    addiu   a1, s2, 200
                    addiu   a2, s1, 199
                    addiu   a3, s2, 208
                    addiu   t0, s1, 202
                    li      t1, 82
                    li      t2, 124
                    li      t3, 90
                    jal     write_and_copy_block
                    li      t4, 127
                    #   "n" block
                    la      a0, 0x8004d7e8
                    addiu   a1, s2, 200
                    addiu   a2, s1, 201
                    addiu   a3, s2, 208
                    addiu   t0, s1, 206
                    li      t1, 204
                    li      t2, 206
                    li      t3, 212
                    jal     write_and_copy_block
                    li      t4, 211
                    #   "g" block
                    la      a0, 0x8004d810
                    addiu   a1, s2, 202
                    addiu   a2, s1, 205
                    addiu   a3, s2, 210
                    addiu   t0, s1, 210
                    li      t1, 164
                    li      t2, 235
                    li      t3, 172
                    jal     write_and_copy_block
                    li      t4, 240
                    la      a0, 0x800459e0
                    li      a1, 0x70
                    jal     0x80022d78
                    li      a2, 0x1e2
                    lw      ra, 40(sp)
                    lw      s5, 36(sp)
                    lw      s4, 32(sp)
                    lw      s3, 28(sp)
                    lw      s2, 24(sp)
                    lw      s1, 20(sp)
                    lw      s0, 16(sp)
                    jr      ra
                    addiu   sp, sp, 48

            #   ROUTINE: Write and copy block
            #       Combines write block with copy segment.
            #       Parameters: Same as Write Block
                    addiu   sp, sp, -16
                    sw      s0, 4(sp)
                    sw      ra, 8(sp)
                    jal     write_block
                    move    s0, a0
                    addiu   a0, s0, 0x118
                    move    a1, s0
                    jal     copy_words
                    li      a2, 40
                    lw      ra, 8(sp)
                    lw      s0, 4(sp)
                    jr      ra
                    addiu   sp, sp, 16

            #   ROUTINE: Write block
            #       Writes a block corresponding to a graphic.
            #       Parameters:
            #           a0 = Base pointer for block
            #           a1 = Top Y Position (Screen)
            #           a2 = Left X Position (Screen)
            #           a3 = Bottom Y Position (Screen)
            #           t0 = Right X Position (Screen)
            #           t1 = Top Y Position (Bitmap)
            #           t2 = Left X Position (Bitmap)
            #           t3 = Bottom Y Position (Bitmap)
            #           t4 = Right X Position (Bitmap)
                    sh      a1, 10(a0)
                    sh      a1, 18(a0)
                    sh      a2, 8(a0)
                    sh      a2, 24(a0)
                    sh      a3, 26(a0)
                    sh      a3, 34(a0)
                    sh      t0, 16(a0)
                    sh      t0, 32(a0)
                    sb      t1, 13(a0)
                    sb      t1, 21(a0)
                    sb      t2, 12(a0)
                    sb      t4, 20(a0)
                    sb      t2, 28(a0)
                    sb      t3, 29(a0)
                    sb      t4, 36(a0)
                    jr      ra
                    sb      t3, 37(a0)

            #   ROUTINE: Copy words
            #       Word-aligned memcpy.  Size must be multiple of 4.
            #       Parameters:
            #           a0 = dest, a1 = src, a2 = size
                    beq     a2, zero, copy_words_end
                    lw      t0, 0(a1)
                    addiu   a2, a2, -4
                    sw      t0, 0(a0)
                    addiu   a0, a0, 4
                    j       copy_words
                    addiu   a1, a1, 4
                    jr      ra
        <Variable name="Color Red Value" file="SCUS_942_21" offset="40C24" offsetMode="RAM" bytes="1" default="80" />
        <Variable name="Color Green Value" file="SCUS_942_21" offset="40C28" offsetMode="RAM" bytes="1" default="80" />
        <Variable name="Color Blue Value" file="SCUS_942_21" offset="40C2C" offsetMode="RAM" bytes="1" default="80" />
Hmm.  It was counting variables wrong.  A simple fix, but that's a pretty fundamental thing that blocks testing, so it's going to require another beta version.  Here it is, attached (Beta v2).  This also includes ctrl + mouse wheel functionality for Shishi zoom and the problem with the cut-off Shishi text about duplicate sprites should also be fixed.