• Welcome to Final Fantasy Hacktics. Please login or sign up.
 
June 16, 2025, 05:46:33 am

News:

Use of ePSXe before 2.0 is highly discouraged. Mednafen, RetroArch, and Duckstation are recommended for playing/testing, pSX is recommended for debugging.


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

1
PSX FFT Hacking / Re: ASM Questions
May 14, 2016, 03:14:05 am
Hello again,

I was wondering if there is any description of the contents of save files?  I've been scouring the wiki and there is tons of info about in-game memory but I can't find a lot about save file contents.  I may not be looking in the right places though, if there is any info please let me know.  I was looking at story progression data specifically, since FFTastic doesn't seem to handle that.
2
PSX FFT Hacking / Re: Status Effect Text
May 02, 2016, 04:31:21 pm
Great; glad it worked!

For editing, I used Paint as well; the import and export BMP functions worked great for me.  I did my editing in Paint, I selected existing letters in the exported .bmp and copied/pasted them into the free space, trying to make the overlap between individual letters look the same as elsewhere in the file (adjacent letters usually share a border, 1px wide, and different letter combinations tend to share different amounts of border).

A few things that may help:

1) I followed Celdia's tutorial to the letter except for the palette offset and size, which I found a better set of inputs from another thread:

    Palette Offset: 37056
    Palette Size:  256

    This gives the full range of palettes in FRAME.BIN; you can navigate between palettes using the triangle arrows at the bottom of the screen.

2)  I am wondering if you were using the correct palette for export?  If I interpreted the threads right, this is the only palette good for editing:



     Hint: this is the only palette that has the brick background intact in the lower part of the image.  The rest of the palettes will have this section garbled up.

I would switch to this palette in tilemolester, export it, edit it and reimport it.  Switching between palettes would show my new text behaving same as the other text.

If it helps, I've attached the before and after exported .bmps that I used to modify FRAME.BIN in the 'Mist' hack. 


**Note: none of the images displayed in these posts are good for editing; they are blown up 2x for readability.  Only the stuff in the attachments are what I actually used to develop this hack.

3
PSX FFT Hacking / Re: Status Effect Text
April 27, 2016, 08:42:47 pm
Thanks, Xifanie! :)  I figured out how to edit FRAME.BIN, so:

Putting it all together...

In order to generate some value, I tried to demo this against some stuff that is already in the community.  I saw that Emmy and Pride have a 'Mist' hack that uses the Wall status, and that it is in use in the Monster Tactics mod.  So as proof of concept I want to make the 'Mist' status also display 'Mist' text images.


1)  Editing FRAME.BIN:

- http://ffhacktics.com/smf/index.php?topic=9584.msg186581#msg186581  ->  This, this, this is the thread with accurate instructions on how to edit FRAME.BIN.  A lot of fruitless searching finally led me to this page.

As per the previous posts, I am going to have one of the unused image data sections point at my new 'Mist' image in my modified FRAME.BIN.  Instructions on how to get the proper values for the image data should be explained via these images:


Original FRAME.BIN:


Modified FRAME.BIN w/ annotations:




2)  Set status pointers to load our modified section of FRAME.BIN.

  a)  So, given the modified FRAME.BIN, we need to set an image data pointer to the bytes DB 48 11 08.  We will use the first unused pointer in the table, at index 1E.
  b)  We want the Wall status to load the 'Mist' image, so we need to modify the Wall byte in the 2 link tables from the previous post, setting its value to 1E.  This will enable Mist        display in both ability targeting and effect.

The following patch accomplishes this; it is simple and alters a grand total of 6(!) bytes.

<Patch name="Wall -> 'Mist' image status display">
    <Description>
      Display "Mist" text images when targeting / inflicting Wall status.  Requires  modifications to FRAME.BIN.
   </Description>
   
    <Location file="BATTLE_BIN" offset="2CD37">
      1E
    </Location>
   
   <Location file="BATTLE_BIN" offset="10093F">
      1E
    </Location>
   
   <Location file="BATTLE_BIN" offset="E5FE0">
      DB481108
   </Location>
   
  </Patch>


And here is the result!  :)





Attached is the modified copy of FRAME.BIN I used + patch file.
4
PSX FFT Hacking / Re: Status Effect Text
April 26, 2016, 02:28:01 am
Ok, (if anyone cares), I've figured out how to manage status text images.


For displaying status images in the pre-attack display (targeting), there is a table that is to my knowledge undocumented, that relates all inflicted statuses to a position in the already documented Status Image Data table:

Status Image Table (ALREADY DOCUMENTED)

8014cf68 - Status Image Data (4 bytes each, 0xc4 total)

0x00 - X Load Location
0x01 - Y Load Location
0x02 - Image Width
0x03 - Image Height




















































PositionOffsetImage Data
00x00"Dead"
10x04"Undead"
20x08"Petrify"
30x0c"Invite"
40x10"Darkness"
50x14"Confusion"
60x18"Silence"
70x1c"Blood Suck"
80x20"Oil"
90x24"Float"
A0x28"Reraise"
B0x2c"Transparent"
C0x30"Berserk"
D0x34"Poison"
E0x38"Regen"
F0x3c"Protect"
100x40"Shell"
110x44"Haste"
120x48"Slow"
130x4c"Stop"
140x50"Faith"
150x54"Innocent"
160x58"Charm"
170x5c"Sleep"   
180x60"Don't Move"
190x64"Don't Act"
1A0x68"Reflect"
1B0x6c"Death Sentence"
1C0x70"Stolen"
1D0x74"Broken"
1E0x78*Unused*
1F0x7c*Unused*
200x80*Unused*
210x84*Unused*
220x88*Unused*
230x8c*Unused*
240x90"Quick"
250x94"HP"
260x98"MP"
270x9c"CT"
280xa0"Speed"
290xa4"Brave"
2A0xa8"Faith"
2B0xacSword Icon (PA)
2C0xb0Rod Icon (MA)
2D0xb4"Lv."
2E0xb8"GIL"
2F0xbc"Exp."
300xc0"Frog"



Status link table, pre-attack display (UNDOCUMENTED)

RAM:  0x167920
BATTLE.BIN:  0x100920

Image data position 0xFF = No display (charging, jump, etc...)

Entry length: 1 byte each
Total length: 0x30 bytes

The undocumented table relates all inflictable statuses to the image data.  The statuses are organized by their order in the status bytes that appear in Battle Status data (and often elsewhere)











































PositionStatusPosition in Image Data Table
0Blank0xFF
1Crystal0xFF
2Dead0x00
3Undead0x01
4Charging0xFF
5Jump0xFF
6Defending0xFF
7Performing0xFF
8Petrify0x02
9Invite0x03
ADarkness0x04
BConfusion0x05
CSilence0x06
DBlood Suck0x07
ECursed0xFF
FTreasure0xFF
10Oil0x08
11Float0x09
12Reraise0x0A
13Transparent0x0B
14Berserk0x0C
15Chicken0xFF
16Frog0x30
17Critical0xFF
18Poison0x0D
19Regen0x0E
1AProtect0x0F
1BShell0x10
1CHaste0x11
1DSlow0x12
1EStop0x13
1FWall0xFF
20Faith0x14
21Innocent0x15
22Charm0x16
23Sleep0x17
24Don't Move0x18
25Don't Act0x19
26Reflect0x1A
27Death Sentence0x1B




The undocumented table is very similar to the next table.  It relates all inflictable status to image data, but for post-action display on units affected by the status.

This table is documented, but wasn't 100% explained.

Status link table, post-attack display (PARTIALLY DOCUMENTED)

RAM:  0x93D18
BATTLE.BIN:  0x2CD18

Image data position 0x00 = No display (charging, jump, etc...)

Entry length: 1 byte each
Total length: 0x30 bytes

This table relates all inflictable statuses to the image data.  The statuses are organized by their order in the status bytes that appear in Battle Status data (and often elsewhere)











































PositionStatusPosition in Image Data Table
0Blank0x00
1Crystal0x00
2Dead0x00
3Undead0x01
4Charging0x00
5Jump0x00
6Defending0x00
7Performing0x00
8Petrify0x02
9Invite0x03
ADarkness0x04
BConfusion0x05
CSilence0x06
DBlood Suck0x07
ECursed0x00
FTreasure0x00
10Oil0x08
11Float0x09
12Reraise0x0A
13Transparent0x0B
14Berserk0x0C
15Chicken0x00
16Frog0x00
17Critical0x00
18Poison0x0D
19Regen0x0E
1AProtect0x0F
1BShell0x10
1CHaste0x11
1DSlow0x12
1EStop0x13
1FWall0x00
20Faith0x14
21Innocent0x15
22Charm0x16
23Sleep0x17
24Don't Move0x18
25Don't Act0x19
26Reflect0x1A
27Death Sentence0x1B




So by using these tables one can dictate what images a given status will display pre and post-attack. 

Some of the justifications for using 2 different tables can be seen by examining the data, such as the 'Dead' status being displayed pre-attack, but not shown post-attack, as the unit falling to the ground is indication enough that it's dead!



EXAMPLE:

The game doesn't display the 'Frog' text when the status hits. (I never noticed until working on this)  To get it to display, change the byte in the post attack table from 0x00 to the Frog image ID, 0x30.

Frog Text On-Hit Display Hack

<Patch name="Frog Text On-Hit Display">
    <Description>
      Display "Frog" text image when a unit receives or loses Frog status.
   </Description>
   
    <Location file="BATTLE_BIN" offset="2CD2E">
      30
    </Location>
   
  </Patch>


Similarly, one can co-opt the Wall or Blank display status to display text by activating its bytes in both display link tables.  To get it to display something new, set the Wall bytes to one of the Unused image IDs (0x1E-0x23), then edit that image ID's data to point to an edited section of FRAME.BIN of your choosing.  (Coming Soon)
5
PSX FFT Hacking / Re: Status Effect Text
April 20, 2016, 08:06:41 pm
I am getting closer to figuring it out. 

This looks promising:

8014cf68 - Status Image Data (4 bytes each, 0xc4 total)
      0x00 - X Load Location
      0x01 - Y Load Location
      0x02 - Image Width
      0x03 - Image Height

      0x00 - "Dead"
      0x04 - "Undead"
      0x08 - "Petrify"
      0x0c - "Invite"
      0x10 - "Darkness"
      0x14 - "Confusion"
      0x18 - "Silence"
      0x1c - "Blood Suck"
      0x20 - "Oil"
      0x24 - "Float"
      0x28 - "Reraise"
      0x2c - "Transparent"
      0x30 - "Berserk"
      0x34 - "Poison"
      0x38 - "Regen"
      0x3c - "Protect"
      0x40 - "Shell"
      0x44 - "Haste"
      0x48 - "Slow"
      0x4c - "Stop"
      0x50 - "Faith"
      0x54 - "Innocent"
      0x58 - "Charm"
      0x5c - "Sleep"
      0x60 - "Don't Move"
      0x64 - "Don't Act"
      0x68 - "Reflect"
      0x6c - "Death Sentence"
      0x70 - "Stolen"
      0x74 - "Broken"
      0x78 - (these 6 are unused)
      0x7c -
      0x80 -
      0x84 -
      0x88 -
      0x8c -
      0x90 - "Quick"
      0x94 - "HP"
      0x98 - "MP"
      0x9c - "CT"
      0xa0 - "Speed"
      0xa4 - "Brave"
      0xa8 - "Faith"
      0xac - Sword Icon (PA)
      0xb0 - Rod Icon (MA)
      0xb4 - "Lv."
      0xb8 - "GIL"
      0xbc - "Exp."
      0xc0 - "Frog"


In battle, these seem to correspond to locations in FRAME.BIN.  The offsets in game memory correspond to those on the FRAME.BIN if I just rip the image off of the wiki:

x offset in memory = bitmap x-offset x2
y-offset in memory is more tricky.  I think for status images (ie not HP, MP,...) the top corner pixel of 'Poison' in FRAME.BIN corresponds to (0,0), so the y offset uses that as zero.

Edit:  Ignore the stuff about y-offset.  I'll post back when I actually have this all figured out.
6
PSX FFT Hacking / Re: Status Effect Text
April 20, 2016, 02:52:28 am
Ok gotcha, I get how the Death Sentence -> Doom change would just be a swap in FRAME.BIN.  But when you 'changed something else to Defending', then how did you get the game to display the new 'Defending' text from FRAME.BIN when a unit goes into Defend?  AFAIK there is no text displayed when a unit Defends, so there's more at play here.
7
PSX FFT Hacking / Status Effect Text
April 19, 2016, 08:06:18 pm
Hi all,

I was watching some Jot5 playthrough videos and saw a few neat things, such as the 'Defending' text when a character goes into Defend status, as well as new 'Doom' text instead of Death Sentence.

I was interested in implementing my own new status in place of Wall with status text to display.  I was wondering if any of you could point me in the correct direction for making this display work.  It looks like the text is stored in FRAME.BIN...but is there any area in the code responsible for loading particular slices out of FRAME.BIN?  Did you Jot5 devs need to free up space in FRAME.BIN or is there unused areas in there that one could store new text?
8
Hi,

I was interested in adding a 3rd palette to the Demon sprite.  FFTEVGRP only lets me edit the first 2 palettes of the Demon sprite though- is it possible to alter the 3rd if it is greyed out?

Note I have used Shishi to add the 3rd palette and make it work properly in battle - I am trying to fix up the formation and menu screens.
9
PSX FFT Hacking / Re: ASM Questions
March 21, 2016, 08:19:22 pm
Cool, I would take a look if you had it available.  I'm a bit of an Excel doofus so it may be difficult for me to examine, is the assembly backing the spreadsheet accessible from within the spreadsheet to look at?

I remember seeing the 'Bonus Abilities' section; looks cool; I was wondering what the 'requirements' for an ability are, exactly?  Might be similar to what I'm looking for, if the Bonus Ability skillset has a single skillset id but can display lists that are different from unit to unit...regardless, thanks for the feedback.
10
PSX FFT Hacking / Re: ASM Questions
March 21, 2016, 07:43:26 pm
Hmm, okay, I'll bite. 

I am trying to create a new skillset with a theme of synergy between the skillset's user and allied monsters on the team.  (Unsure of the name, was thinking 'Empathy' or 'Beast Mastery')

The skillset will consist of a 'normal', fixed set of skills (at least 1, up to 4 I was thinking), and the rest of the skill slots being always blank on the world screens but able to be dynamically filled with monster skills of allied monsters in battle.

The main driver of the skillset, and first fixed skill is a 'Bond' ability which allows the user to apply a 'Bond' status, with only allowed targets being allied monsters ('bondees').  When a monster is under 'Bond' status, it's non Monster Skill abilities will be available for the caster that applied Bond to the unit (the 'bonder').  I was also planning on the other 3 fixed abilities for this skillset to only target allied monsters as well, and have additional enhancements if the monster is Bonded to the caster.

The issue that I was getting at, is that if there are multiple units with this skillset, or multiple 'bonders', each instance of their available skills may differ depending on the 'bondees' that each 'bonder' has.  I have a table in memory that stores the relationships between bonders and bondees, and if I was able to determine the requesting unit, when the game asks for an ability from that skillset, I could consult the bond table to determine the correct skills to provide when the routine is called.

I have been making an alpha version of this with the Bond status and table mechanics working correctly (I can post the code if anyone is curious) and I have been developing this using a routine that just overwrites a skillset with the bonded abilities when Bond is applied/removed so that the game can just read the altered skillset, and it works good.  The problem here is that I would need a free skillset for every unit in battle that wants to use this.

tl;dr:
I want to have a single skillset that can behave differently in battle depending on the unit that it is assigned to.  Therefore it would be necessary for me to determine the unit that is making the load request, for a skill from the skillset.


If anyone is interested, there are more details and ideas that I have for this here:


Skillset:  'Empathy', 'Monster Empathy', 'Beast Mastery'


Mechanics of Bond:

- A unit with the skillset may apply 'Bond' status to allied monsters using the Bond ability.  Have not determined the parameters for this, but I was thinking a melee range no charge, 100% success rate skill.

- Only allied, 'true' monsters with monster skillsets can be Bonded.

- A unit under Bond status benefits the 'bonder'.  The bonder has access to all monster skills of the 'bondee'.

- A bonder may have multiple bondees.  Bondees can only have a single 'bonder'.

- 12 ability slots will be available for bondee skills, they will be listed in order of CT remaining for Bond status on each bondee (newest bonded units skills listed first)

- Bond will have a finite CT.  Positive-status dispelling abilities should remove it.

- When Bond status removed, the bondee skills will no longer be available to bonder.  A different bonder applying Bond to an already Bonded unit will remove the existing bond and create a new bond to itself.

- Not sure yet if the bond should go away on bondee death, bonder death, both or none.


Other Ability Ideas:

'Swap', 'Save', ...: 
- Target allied monsters.  Invalid units not targetable.  Caster will exchange position with the targeted unit, dealing damage equal to the difference between target unit HP and caster HP in an AoE around the targeted unit.

- Percent success of Swap will decrease based on distance between the units.  Will always have 100% success rate if units are Bonded, and always 0% success rate if either positions of the exchanged units are illegal.


'Sacrifice', 'Martyr':
- Target allied monsters.  Invalid units not targetable.  Caster dies on successful resolution of ability.  Target unit HP/MP healed to full and unit receives Quick status.  25% chance of adding each of Haste / Protect / Shell.

- If units are Bonded, target receives Haste, Protect and Shell 100% in addition to other effects.


Support Ability:  'Initial Bond'
- Starts a battle with 1 ally unit already Bonded to this unit.  The ally to bond is determined by closest bondable unit on the formation screen.  Ties are randomly determined.


Reaction Ability:  (no idea what to call it)
- May react using the reaction abilities of any bonded units.  Precedence may be determined by using the reaction stacking hack (I think)
11
PSX FFT Hacking / Re: ASM Questions
March 21, 2016, 02:30:29 pm
Hello all,

I am trying to code some junk related to skillsets.  I was wondering, is there an area in memory that identifies a unit that is currently selected?  I have scoured the data location information and haven't seen anything for this.

I would like to override the 'Load Ability from Skillset' routine, and have it do different things depending on what unit the skillset is being loaded for.  However, I have not yet found a reliable way to identify the unit.  The 'acting unit' ID locations have worked somewhat, but they fail in cases like when I'm viewing a unit's skills in the status menu when it's not that unit's turn.

If anyone knows anything regarding this, help is appreciated.  I might be barking down the wrong tree, I know that the unit ID is not something that is officially passed along to the 'Load Ability...' routine, so it might be impossible for me to 100% determine the unit the skillset is being loaded for in all cases.

Thanks!
12
PSX FFT Hacking / Re: ASM Questions
March 10, 2016, 09:57:35 pm
Cool, thanks :)

I thought I would post a preview of what I'm working on.  I'm currently exploring the concept of dynamically generated skillsets.

Specifically, what I wanted was some type of class/skillset that can inherit the abilities of monsters that are in battle with me.  I originally drew this up to be a skillset that's equipped to a 'specialty monster' (eg Archaic Demon, Byblos, etc) but if it makes some sense I could extend it so it's a full fledged job.  I have no interest in overriding a current generic class for this.

Anyway, as a proof of concept I wanted to develop a skillset that just groups all the abilities of monsters that players select for battle in the formation screen.  The skills would only be present while in battle, and not in the overworld.

What I have so far is the code that will populate the skillset with monster abilities at the start of battle.  It's very rough around the edges at this point.

Good Stuff:
- Abilities work properly
- Selectable in act menu and in status screen in battle
- AI will use abilities, although the available abilities are from the player's team rather than their team.  Unsure if slot 2 is required for the AI to have access to all abilities.

Needs Work:
- Missing animations if the sprite set is missing the correct stuff, I think
- Abilities use MP
- Speed is displayed in the status screen for some abilities, ideally they should all display 0 or 'Now' if they do not have a CT
- Erase the skillset at the end of battle
- I want to not include abilities that require monster skill

Nice to Have:
- Have the code search allied units instead of player units.  This would allow enemy formations to use their own monster skills.
- Have all abilities be instant-learned if I expand this to a job.

Most of these issues are just stuff I haven't gotten to yet, I have just reached the point where I have a first release that does something!  Feel free to offer any input or critique.

Patch:

<Patch name="Battle Monsters Skillset v0.1">
    <Description>
   This patch dynamically generates a skillset in skillset [SETID]
   (default 94, an unused skillset) at the start of battle.
   
   The generated skillset consists of up to 16 unique monster
   skills, sourced from monsters brought by the player to battle.
   </Description>
   
   <Variable name="SETID" default="94" file="BATTLE_BIN" offset="F929C" />
   
    <Location file="BATTLE_BIN" offset="1185F0">
      80810508
    </Location>

    <Location file="BATTLE_BIN" offset="F9600">
      FCFFBD27
      0400BFAF
      1600083C
      9C020835
      00000491
      00000000
      8C81050C
      00000000
      0400BF8F
      0400BD27
      0800E003
      00000000
      E4FFBD27
      0400BFAF
      0800B0AF
      0C00B1AF
      1000B2AF
      1400B3AF
      1800B4AF
      1C00B5AF
      00009520
      B000A92E
      2C002011
      00000000
      0C82050C
      0000A422
      1980103C
      CC241036
      21880000
      01000892
      FF000934
      1E002811
      00000892
      82000934
      1B002815
      12001292
      00000000
      B000492E
      17002015
      21980000
      00004422
      5A69010C
      00006522
      00005420
      0D008012
      A701892E
      0B002011
      0000A422
      EF81050C
      00008522
      07004014
      0000A422
      00002522
      CD81050C
      00008622
      21882202
      0F00292E
      09002011
      01007326
      1600692E
      EBFF2015
      00000000
      C0011026
      FFFF0832
      CD2B092D
      DBFF2015
      00000000
      1C00B58F
      1800B48F
      1400B38F
      1000B28F
      0C00B18F
      0800B08F
      0400BF8F
      1C00BD27
      0800E003
      00000000
      21100000
      0002C92C
      1D002011
      1000A92C
      1B002011
      B000892C
      19002011
      06800B3C
      944A6B35
      19000834
      19008800
      12400000
      21586801
      2150AB00
      030046A1
      00006A91
      00520A00
      01006891
      25504801
      00800834
      0640A800
      0001C92C
      03002015
      00000000
      25504801
      02000010
      27400001
      24504801
      01006AA1
      02520A00
      00006AA1
      01000234
      0800E003
      00000000
      F0FFBD27
      0400BFAF
      0800B0AF
      0C00B1AF
      1000B2AF
      0002892C
      0F002011
      0002A92C
      0D002011
      00009020
      0000B120
      21900000
      00000422
      5A69010C
      00004522
      02005114
      01000234
      04000010
      01005226
      1600492E
      F7FF2015
      21100000
      1000B28F
      0C00B18F
      0800B08F
      0400BF8F
      1000BD27
      0800E003
      00000000
      F4FFBD27
      0400BFAF
      0800B0AF
      0C00B1AF
      00009020
      21880000
      00000422
      00002522
      CD81050C
      21300000
      01003126
      1000292E
      F9FF2015
      00000000
      0C00B18F
      0800B08F
      0400BF8F
      0C00BD27
      0800E003
      00000000
   </Location>
  </Patch>


Source:


#This code will generate a skillset with up to 16 unique abilities
#sourced from player controlled monsters in battle.
#Any non-R/S/M abilities in the selected skillset will be overwritten.

##############################################################

entry:
[0x00160600] addiu sp,sp,-0x0004
[0x00160604] sw ra, 0x0004(sp)

[0x00160608] li t0, 0x0016029C               #ptr to reserved data area
[0x00160610] lbu a0, 0(t0)                  #load skillset to overwrite, default 94
[0x00160614] nop
[0x00160618] jal generateskillset
[0x0016061c] nop
[0x00160620] lw ra, 0x0004(sp)
[0x00160624] addiu sp,sp,0x0004
[0x00160628] jr ra
[0x0016062c] nop

##############################################################

generateskillset:
[0x00160630] addiu sp,sp,-0x001C
[0x00160634] sw ra, 0x0004(sp)
[0x00160638] sw s0 ,0x0008(sp)
[0x0016063c] sw s1, 0x000C(sp)
[0x00160640] sw s2, 0x0010(sp)
[0x00160644] sw s3, 0x0014(sp)
[0x00160648] sw s4, 0x0018(sp)
[0x0016064c] sw s5, 0x001C(sp)

[0x00160650] move s5, a0                  #s5 skillset to overwrite

[0x00160654] sltiu t1, s5, 0x00B0
[0x00160658] beq t1, zero, exit               #leave if monster skillset or invalid
[0x0016065c] nop

[0x00160660] jal eraseskillset               #erase current abilities
[0x00160664] move a0, s5

[0x00160668] li s0, 0x801924CC               #s0 ally unit ptr
[0x00160670] clear s1                     #s1 ability counter (for saving)

unitloop:
[0x00160674] lbu t0, 0x0001(s0)
[0x00160678] ori t1, zero, 0x00ff            #increment if not exist
[0x0016067c] beq t1, t0, unitincrement
[0x00160680] lbu t0, 0x0000(s0)
[0x00160684] ori t1, zero, 0x0082            #increment if not monster
[0x00160688] bne t1, t0, unitincrement
[0x0016068c] lbu s2, 0x0012(s0)               #s2 primary skillset
[0x00160690] nop
[0x00160694] sltiu t1, s2, 0x00B0            #increment if not monster skillset
[0x00160698] bne t1, zero, unitincrement
[0x0016069c] clear s3                      #Got monster skillset - skillset ctr in s3


transferloop:                     
[0x001606a0] move a0, s2                  #a0 skillset to read
[0x001606a4] jal 0x0005a568                  #load ability from skillset
[0x001606a8] move a1, s3                  #a1 ability index (read)
[0x001606ac] move s4, v0                  #s4 loaded ability
[0x001606b0] beq s4, zero, transferincrement   #branch if ability blank
[0x001606b4] sltiu t1, s4, 0x01a7   
[0x001606b8] beq t1, zero, transferincrement   #branch if not an ability
[0x001606bc] move a0, s5                  #a0 skillset to overwrite
[0x001606c0] jal abilityinskillset
[0x001606c4] move a1, s4                  #a1 loaded ability
[0x001606c8] bne v0, zero, transferincrement   #branch if duplicate ability

[0x001606cc] move a0, s5                  #a0 skillset to overwrite
[0x001606d0] move a1, s1                  #a1 ability index (write)
[0x001606d4] jal saveability      
[0x001606d8] move a2, s4                  #a2 ability
[0x001606dc] addu s1, s1, v0               #Increment ability counter if saved

[0x001606e0] sltiu t1, s1, 0x0F
[0x001606e4] beq t1, zero, exit               #leave if 0x10 skills saved

transferincrement:
[0x001606e8] addiu s3, s3, 1
[0x001606ec] sltiu t1, s3, 0x16
[0x001606f0] bne t1, zero, transferloop         #loop through skills 0 - 0x16
[0x001606f4] nop

unitincrement:
[0x001606f8] addiu s0, s0, 0x01c0
[0x001606fc] andi t0, s0, 0xFFFF;
[0x00160700] sltiu t1, t0, 0x2BCD
[0x00160704] bne t1, zero, unitloop            #loop through player controlled units
[0x00160708] nop

exit:
[0x0016070c] lw s5, 0x001C(sp)
[0x00160710] lw s4, 0x0018(sp)
[0x00160714] lw s3, 0x0014(sp)
[0x00160718] lw s2, 0x0010(sp)
[0x0016071c] lw s1, 0x000C(sp)
[0x00160720] lw s0, 0x0008(sp)
[0x00160724] lw ra, 0x0004(sp)
[0x00160728] addiu sp,sp,0x001C
[0x0016072c] jr ra
[0x00160730] nop

##############################################################

saveability:  #a0 skillset, a1 ability index, a2 ability, v0 save success (boolean)
[0x00160734] clear v0
[0x00160738] sltiu t1, a2, 0x0200
[0x0016073c] beq t1, zero, exitsa            #leave if invalid ability
[0x00160740] sltiu t1, a1, 0x0010
[0x00160744] beq t1, zero, exitsa            #leave if index >= 0x010 (no RSM support for now)
[0x00160748] sltiu t1, a0, 0x00B0
[0x0016074c] beq t1, zero, exitsa            #leave if monster skillset or invalid

[0x00160750] li t3, 0x80064a94               #t3 ptr to skillsets
[0x00160758] ori t0, zero, 0x19
[0x0016075c] multu a0, t0
[0x00160760] mflo t0                              
[0x00160764] addu t3, t3, t0               #t3 ptr to skillset   

[0x00160768] addu t2, a1, t3
[0x0016076c] sb a2, 3(t2)                  #save ability

[0x00160770] lbu t2, 0(t3)                  
[0x00160774] sll t2, t2, 8
[0x00160778] lbu t0, 1(t3)                  
[0x0016077c] or t2, t2, t0                  #t2 ability flags

[0x00160780] ori t0, zero, 0x8000
[0x00160784] srlv t0, t0, a1                #t0 ability flag bitmask

[0x00160788] sltiu t1, a2, 0x100
[0x0016078c] bne t1, zero, noflag            #branch on no flag
[0x00160790] nop
[0x00160794] or t2, t2, t0                  #set bit
[0x00160798] b saveflags
noflag:
[0x0016079c] not t0, t0
[0x001607a0] and t2, t2, t0                  #unset bit
saveflags:
[0x001607a4] sb t2, 1(t3)                  
[0x001607a8] srl t2, t2, 8
[0x001607ac] sb t2, 0(t3)                   #save updated flags
[0x001607b0] ori v0, zero, 1               #success
exitsa:
[0x001607b4] jr ra
[0x001607b8] nop

##############################################################

abilityinskillset: #a0 skillset, a1 ability, v0 ability exists in skillset (boolean)
[0x001607bc] addiu sp,sp,-0x0010
[0x001607c0] sw ra, 0x0004(sp)
[0x001607c4] sw s0 ,0x0008(sp)
[0x001607c8] sw s1, 0x000C(sp)
[0x001607cc] sw s2, 0x0010(sp)

[0x001607d0] sltiu t1, a0, 0x0200
[0x001607d4] beq t1, zero, exitais            #leave if invalid skillset
[0x001607d8] sltiu t1, a1, 0x0200
[0x001607dc] beq t1, zero, exitais            #leave if invalid ability
[0x001607e0] move s0, a0                  #s0 skillset
[0x001607e4] move s1, a1                  #s1 ability
[0x001607e8] clear s2                     #s2 ability counter

abilityloop:
[0x001607ec] move a0, s0                  #a0 skillset
[0x001607f0] jal 0x0005a568                  #load ability from skillset
[0x001607f4] move a1, s2                  #a1 ability index
[0x001607f8] bne v0, s1, nomatch

[0x001607fc] ori v0, zero, 1               #ability found
[0x00160800] b exitais

nomatch:
[0x00160804] addiu s2, s2, 1
[0x00160808] sltiu t1, s2, 0x16
[0x0016080c] bne t1, zero, abilityloop         #loop through skills 0 - 0x16
[0x00160810] clear v0

exitais:
[0x00160814] lw s2, 0x0010(sp)
[0x00160818] lw s1, 0x000C(sp)
[0x0016081c] lw s0, 0x0008(sp)
[0x00160820] lw ra, 0x0004(sp)
[0x00160824] addiu sp,sp,0x0010
[0x00160828] jr ra
[0x0016082c] nop

##############################################################

eraseskillset: #a0 skillset
[0x00160830] addiu sp,sp,-0x000C
[0x00160834] sw ra, 0x0004(sp)
[0x00160838] sw s0 ,0x0008(sp)
[0x0016083c] sw s1, 0x000C(sp)

[0x00160840] move s0, a0
[0x00160844] clear s1
eraseloop:                              #erase all action abilities
[0x00160848] move a0, s0
[0x0016084c] move a1, s1
[0x00160850] jal saveability
[0x00160854] clear a2
[0x00160858] addiu s1, s1, 1
[0x0016085c] sltiu t1, s1, 0x10
[0x00160860] bne t1, zero, eraseloop         #loop through skills 0 - 0x10      
[0x00160864] nop

[0x00160868] lw s1, 0x000C(sp)
[0x0016086c] lw s0, 0x0008(sp)
[0x00160870] lw ra, 0x0004(sp)
[0x00160874] addiu sp,sp,0x000C
[0x00160878] jr ra
[0x0016087c] nop

##############################################################


13
PSX FFT Hacking / Re: ASM Questions
March 08, 2016, 01:32:33 pm
Thanks for the helpful replies. 

I wanted to be diligent about maintaining the program state and using the stack correctly, especially since I was planning on calling some of the existing FFT routines from within my code.

Xifanie, I was only looking at the jump and return portions of your hack, so hopefully my coding standards haven't been damaged too badly :P
14
PSX FFT Hacking / ASM Questions
March 07, 2016, 08:37:06 pm
Hi all,

New to FFT hacking and hacking in general.  This is my first foray into assembly language coding and I had a few questions on how stuff is done.


1)  I want to create a new routine in free space that is called from existing code.  In order to do that I need to use 2 instructions I assume, a jump and delay slot.  Assuming this is correct, what is done with the instructions that are overwritten by the jump/delay? 

I was studying Xifanie's Weapon Strike fix v1 as an example, and it looked like the 2 existing instructions that were stomped (saving $31 to stack) were tacked on to the end of the Weapon Strike routine before jumping back to the original code.  I was wondering if this is a general solution that can be used.


2)  Temporary registers:  If I call a routine from my code that is in the middle of an existing routine in the original code, and the original code is using the temporary registers (4-7 I think) do I need my routine to handle saving the temporary registers?  I was reading some assembly stuff and it says that saving temporaries is the caller's responsibility, not the callee's but in this situation I would need to overwrite even more existing code lines to do this.  I was wondering how this works?  Does my code need to save them (seems bad) or do I need to overwrite more lines from the existing code to do this?

And please let me know if I am way off base with these questions, or if I am lacking some fundamental knowledge.  I am very new to assembly and hacking so there may be some holes in my knowledge that I am not aware of.

Thanks!