јAslickproductions.org/forum/index.php?PHPSESSID=5f0fck550j2m4m2fpbtkj2vkm1&action=profile;u=278;area=showposts;start=825e:/My Web Sites/Slick Productions - FFIV Message Board/slickproductions.org/forum/indexb77f.htmlslickproductions.org/forum/index.php?PHPSESSID=5f0fck550j2m4m2fpbtkj2vkm1&action=profile;area=showposts;u=278e:/My Web Sites/Slick Productions - FFIV Message Board/slickproductions.org/forum/indexb77f.html.zxбхg^џџџџџџџџџџџџџџџџџџџџШРK&ПOKtext/htmlISO-8859-1gzip@је&ПџџџџџџџџTue, 10 Mar 2020 19:25:28 GMT0ѓАА Ў0ЎPЎ€ЇВ№Ўахg^џџџџџџџџњ>&П Show Posts - chillyfeez

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

826
In keeping with my recent kick of non-direct gameplay mods, I've been working this morning on a mod that changes the "Stereo/Mono" option into a "Display Max HP/Display Wait Time (in battle)" option.

I've got the functional part of the coding done, just need to do some purely cosmetic cleanup before I can put this one out.
It's a little weird looking, since wait time is rarely ever more than 10 seconds, but there is space for four digit numbers (because normally Max HP is in that space), but on the whole this is a cool little thing.

I have to get ready for work now, and I don't know if I'll get to the finishing touches for a couple of days, so sorry if this is just a teaser.

827
No, that's not intentional, but I am aware of it. Oddly enough, it doesn't happen when you exit a location map to the world map.
There must be a STZ $06AC somewhere in the map loading routine. I can probably find and erase it...

828
Turn Deferring with X turned out to be the super easy one, as a matter of fact!
Major assist to Grimoire LD for his Auto-Hide research here, which was essential to making this one possible.

So this works almost exactly like pressing Triangle during battle in FFIV, VIII and XI (can you defer in VI with X? I don't remember).

The only thing is, if another character or monster is taking an action at the time, you have to wait until that action is over to defer, but you CAN hold X so that the turn is deferred as soon as possible.

Patch is below.

Code: [Select]
$03/A400 5C D0 BB 04 JMP $04BBD0[$04:BBD0]    ;Jump to custom
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$04/BBD0 AD 08 01    LDA $0108  [$7E:0108]   
$04/BBD3 29 40       AND #$40                ;Check if X is being pressed or held
$04/BBD5 F0 14       BEQ $14    [$BBEB]      ;If not, skip this process
$04/BBD7 AE 30 35    LDX $3530  [$7E:3530]    ;Load current character's wait time pointer into X
$04/BBDA 9E 08 2A    STZ $2A08,x[$7E:2B35]    ;Store zero in upper byte of character's wait time
$04/BBDD 9E 09 2A    STZ $2A09,x[$7E:2B36]    ;Store zero ("waiting for next turn") in character's wait/ready status byte
$04/BBE0 A9 00       LDA #$00               
$04/BBE2 9D 07 2A    STA $2A07,x[$7E:2B34]    ;store zero in character's wait time (I originally stored a 1 here because I doubted zero would work, but it does, and it was just easier to keep it this way)
$04/BBE5 A6 A6       LDX $A6    [$00:00A6]    ;load character's stats slot into X
$04/BBE7 5C 39 A4 03 JMP $03A439[$03:A439]    ;Jump to Menu erasing routine (the one used for Edward's auto-hide)
$04/BBEB A6 A6       LDX $A6    [$00:00A6]    ;(this is where we jump to if X is not being pressed)
$04/BBED BD 00 20    LDA $2000,x[$7E:212D]    ;reapeat skipped actions at $03/A400
$04/BBF0 5C 05 A4 03 JMP $03A405[$03:A405]    ;back to our regularly scheduled programming

829
OK, well, it ended up being "Press L to toggle running" instead of "Press B to run."
some issues came up with pressing B and a direction button simultaneously, that I could only solve by making it impossible to start or stop running while moving (which necessitated a toggle instead of being able to just hold the button).

As a little bonus, this patch allows you to press L to toggle "slow flying" while in an airship or The Whale, thus solving the difficulty involved in landing near Toroia.

The patch is below. Here's the disassembly of the changes I made:
Code: [Select]
$00/80C2 20 59 FF    JSR $FF59 ;Jump to custom
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$00/FF59 AD 0C 01    LDA $010C  [$00:010C]    ;7E:010C logs whether a button at 7E:0108 is being held down. It is 18 by default, and counts down as a button is held (jumps back to 03 when it gets to zero)
$00/FF5C C9 18       CMP #$18               
$00/FF5E D0 39       BNE $39    [$FF99]      ;Skip the process if any button at 0108 (including L) is being held (this will avoid multiple toggles on a single button push)
$00/FF60 AD 08 01    LDA $0108  [$00:0108]   
$00/FF63 29 20       AND #$20                ;Check if L is being pushed at all
$00/FF65 F0 32       BEQ $32    [$FF99]      ;If not, skip the process
$00/FF67 AD 09 01    LDA $0109  [$00:0109]   
$00/FF6A 29 0F       AND #$0F                ;Check if any d-pad button is being pressed or held
$00/FF6C D0 2B       BNE $2B    [$FF99]      ;If so, skip the process
$00/FF6E AD 04 17    LDA $1704  [$00:1704]   
$00/FF71 D0 0F       BNE $0F    [$FF82]      ;If NOT on foot, skip to the vehicle portion
$00/FF73 AD AC 06    LDA $06AC  [$00:06AC]    ;If on foot, observe current speed setting
$00/FF76 D0 05       BNE $05    [$FF7D]     
$00/FF78 EE AC 06    INC $06AC  [$00:06AC]    ;If Zero, increase to 01
$00/FF7B 80 03       BRA $03    [$FF80]      ;And skip to the end
$00/FF7D 9C AC 06    STZ $06AC  [$00:06AC]    ;If not zero, set to zero
$00/FF80 80 17       BRA $17    [$FF99]      ;And skip to the end
$00/FF82 C9 04       CMP #$04               
$00/FF84 90 13       BCC $13    [$FF99]     
$00/FF86 C9 07       CMP #$07                ;Check if current vehicle is Enterprise, Falcon or Whale
$00/FF88 B0 0F       BCS $0F    [$FF99]      ;If not, Skip the process
$00/FF8A AD AC 06    LDA $06AC  [$00:06AC]    ;If so, observe current speed setting
$00/FF8D D0 07       BNE $07    [$FF96]     
$00/FF8F A9 03       LDA #$03               
$00/FF91 8D AC 06    STA $06AC  [$00:06AC]    ;If speed is Zero, change to 03
$00/FF94 80 03       BRA $03    [$FF99]      ;And skip to the end
$00/FF96 9C AC 06    STZ $06AC  [$00:06AC]    ;If speed is not zero, set to zero
$00/FF99 AD 00 17    LDA $1700  [$00:1700]    ;(the command that was replaced at $00/80c2)
$00/FF9C 60          RTS

830
I actually think 3 will end up being easier than 2 now... Or at least, I have an idea how I might make it work and if it does work it'll be pretty simple.

I'm 99% sure that Press B to Run will be super simple and ready by the end of the day.

And yes, I definitely will post patches to share them with the world!

831
So I've been researching joypad input...

For those of you reading who actually know a thing or two about programming, the way I talk about this may expose my novice a bit. But my ideas and ambitions for what I plan to do with this knowledge are topnotch.

So, from what I've read on the subject, SNES's joypad registers are $4200 (determines if the pad is active), $4212 (determines if the pad is ready to transmit data) and $4218-4219 (a,x,l,r,1,1,1,1 - b,y,s,t,u,d,r,l buttons. Those 1s represent data that simply identify the joypad to the SNES as an actual joypad (and not a mouse or a super scope)

Anyway, this on its own is not particularly useful. If you open ffiv in Geiger's and watch the $4200 block of RAM, you won't see anything interesting. Apparently, part of the initialization at the beginning of a SNES game involves pointing to a place in RAM where controller input will be copied in (essentially) real time. So, by setting a breakpoint to read $4218 at the very start of running the ROM, I was able to find where FFIV copies controller input: $0108-0109.
Go ahead and see for yourself. Open your ffiv ROM in Geiger's and view 7E:0108-0109 in RAM. Watch what happens there when you push (and also hold down) some buttons.

Yay!

I haven't had a whole lot of time to actually do anything with this, but here's what I want to try (in ascending order of difficulty)

1. Implement a "hold B to run" function on the field, a la FFV

2. Revamp the Limit Break in my hack so that the break is truly random (instead of being determined by the lowest two bits of your HP) but the execution is controlled by the player (giving you the option to not execute)

3. Implement a "press X to switch to the next ready character" function in battle, a la ffvii - ix (and possibly others?)

832
OK, here's the re-worked Monster Level Adjusting patch.

The new process (In English)
1) Determine APL (true APL this time)
2) Multiply APL by 2/3 to determine Modified APL
3) Modified APL * 100(hex) / Monster's Level = Adjustment Ratio
4) Adjust Monster level according to Adjustment Ratio (skip if boss)
5) Adjust Attack Multiplier according to Adjustment Ratio (skip if boss)
6) Adjust Attack Base according to Adjustment Ratio (skip if boss)
7) Adjust Physical Defense Multiplier according to Adjustment Ratio
8) Adjust Physical Defense Base according to Adjustment Ratio
9) Adjust Magic Defense Multiplier according to Adjustment Ratio
10) Adjust Magic Defense Base according to Adjustment Ratio
11) Adjust Speed according to Adjustment Ratio
12) Adjust Current HP and Max HP according to Adjustment Ratio (skip if boss)

Here's a commented disassembly (comments are simplified, as many operations are the same as before):
Code: [Select]
$03/90F5 5C 60 DE 01 JMP $01DE60      ;Jump to custom code
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

$01/DE60 9D 24 20    STA $2024,x[$7E:22A4]   
$01/DE63 8E 80 22    STX $2280  [$7E:2280]   
$01/DE66 8C 90 22    STY $2290  [$7E:2290]   
$01/DE69 C2 20       REP #$20               
$01/DE6B 7B          TDC                     
$01/DE6C AA          TAX                     
$01/DE6D A8          TAY                     
$01/DE6E AD 02 20    LDA $2002  [$7E:2002]   
$01/DE71 29 FF 00    AND #$00FF             
$01/DE74 F0 02       BEQ $02    [$DE78]     
$01/DE76 AA          TAX                     
$01/DE77 C8          INY                     
$01/DE78 AD 82 20    LDA $2082  [$7E:2082]   
$01/DE7B 29 FF 00    AND #$00FF             
$01/DE7E F0 09       BEQ $09    [$DE89]     
$01/DE80 85 A9       STA $A9    [$00:00A9]   
$01/DE82 8A          TXA                     
$01/DE83 18          CLC                     
$01/DE84 6D A9 00    ADC $00A9  [$7E:00A9]   
$01/DE87 AA          TAX                     
$01/DE88 C8          INY                     
$01/DE89 AD 02 21    LDA $2102  [$7E:2102]   
$01/DE8C 29 FF 00    AND #$00FF             
$01/DE8F F0 09       BEQ $09    [$DE9A]     
$01/DE91 85 A9       STA $A9    [$00:00A9]   
$01/DE93 8A          TXA                     
$01/DE94 18          CLC                     
$01/DE95 6D A9 00    ADC $00A9  [$7E:00A9]   
$01/DE98 AA          TAX                     
$01/DE99 C8          INY                     
$01/DE9A AD 82 21    LDA $2182  [$7E:2182]   
$01/DE9D 29 FF 00    AND #$00FF             
$01/DEA0 F0 09       BEQ $09    [$DEAB]     
$01/DEA2 85 A9       STA $A9    [$00:00A9]   
$01/DEA4 8A          TXA                     
$01/DEA5 18          CLC                     
$01/DEA6 6D A9 00    ADC $00A9  [$7E:00A9]   
$01/DEA9 AA          TAX                     
$01/DEAA C8          INY                     
$01/DEAB AD 02 22    LDA $2202  [$7E:2202]   
$01/DEAE 29 FF 00    AND #$00FF             
$01/DEB1 F0 09       BEQ $09    [$DEBC]     
$01/DEB3 85 A9       STA $A9    [$00:00A9]   
$01/DEB5 8A          TXA                     
$01/DEB6 18          CLC                     
$01/DEB7 6D A9 00    ADC $00A9  [$7E:00A9]   
$01/DEBA AA          TAX                     
$01/DEBB C8          INY                     
$01/DEBC 8A          TXA                     
$01/DEBD BB          TYX                     
$01/DEBE 20 00 E1    JSR $E100  [$01:E100]   ;Determine APL, by adding all party members' levels and dividing by the amount of party members (01/E100 is the division function)
$01/DEC1 A2 03 00    LDX #$0003             
$01/DEC4 20 00 E1    JSR $E100  [$01:E100]   
$01/DEC7 0A          ASL A                   ;Multiply APL by 2/3 to obtain Adjusted APL
$01/DEC8 48          PHA                     
$01/DEC9 AC 80 22    LDY $2280  [$7E:2280]   
$01/DECC 68          PLA                     
$01/DECD 0A          ASL A                   
$01/DECE 0A          ASL A                   
$01/DECF 0A          ASL A                   
$01/DED0 0A          ASL A                   
$01/DED1 0A          ASL A                   
$01/DED2 0A          ASL A                   
$01/DED3 0A          ASL A                   
$01/DED4 0A          ASL A                   
$01/DED5 BE 02 20    LDX $2002,y[$7E:2282]   
$01/DED8 20 00 E1    JSR $E100  [$01:E100]   ;Determine Adjustment Ratio using the formula: Adj-APL * 100(h) / Monst-Lvl
$01/DEDB 48          PHA                     
$01/DEDC 7B          TDC                     
$01/DEDD E2 20       SEP #$20               
$01/DEDF B9 70 20    LDA $2070,y[$7E:22F0]   
$01/DEE2 30 52       BMI $52    [$DF36]      ;Skip Level, Attack Multiplier and Attack Base adjustments if monster is a Boss
$01/DEE4 C2 20       REP #$20               
$01/DEE6 68          PLA                     
$01/DEE7 BE 02 20    LDX $2002,y[$7E:2282]   
$01/DEEA 86 E8       STX $E8    [$00:00E8]   
$01/DEEC 48          PHA                     
$01/DEED 20 70 E1    JSR $E170  [$01:E170]   
$01/DEF0 E2 20       SEP #$20               
$01/DEF2 99 02 20    STA $2002,y[$7E:2282]   
$01/DEF5 99 70 20    STA $2070,y[$7E:22F0]   
$01/DEF8 69 0A       ADC #$0A               
$01/DEFA 99 2F 20    STA $202F,y[$7E:22AF]   ;Adjust Level (and Level+Boss Bit, and Level+0A) according to Adjustment Ratio
$01/DEFD C2 20       REP #$20               
$01/DEFF B9 1B 20    LDA $201B,y[$7E:229B]   
$01/DF02 29 FF 00    AND #$00FF             
$01/DF05 85 E8       STA $E8    [$00:00E8]   
$01/DF07 68          PLA                     
$01/DF08 48          PHA                     
$01/DF09 20 70 E1    JSR $E170  [$01:E170]   
$01/DF0C C9 0E 00    CMP #$000E             
$01/DF0F 90 03       BCC $03    [$DF14]     
$01/DF11 A9 0D 00    LDA #$000D             
$01/DF14 E2 20       SEP #$20               
$01/DF16 99 1B 20    STA $201B,y[$7E:229B]   ;Adjust Attack Multiplier according to Adjustment Ratio (Max value 0E)
$01/DF19 EA          NOP                     
$01/DF1A C2 20       REP #$20               
$01/DF1C B9 1D 20    LDA $201D,y[$7E:229D]   
$01/DF1F 29 FF 00    AND #$00FF             
$01/DF22 85 E8       STA $E8    [$00:00E8]   
$01/DF24 68          PLA                     
$01/DF25 48          PHA                     
$01/DF26 20 70 E1    JSR $E170  [$01:E170]   
$01/DF29 C9 AF 00    CMP #$00AF             
$01/DF2C 90 03       BCC $03    [$DF31]     
$01/DF2E A9 AE 00    LDA #$00AE             
$01/DF31 E2 20       SEP #$20               
$01/DF33 99 1D 20    STA $201D,y[$7E:229D]   ;Adjust Attack Base according to Adjustment Ratio (Max value AE)
$01/DF36 C2 20       REP #$20               
$01/DF38 B9 28 20    LDA $2028,y[$7E:22A8]   
$01/DF3B 29 FF 00    AND #$00FF             
$01/DF3E 85 E8       STA $E8    [$00:00E8]   
$01/DF40 68          PLA                     
$01/DF41 48          PHA                     
$01/DF42 EA          NOP                     
$01/DF43 20 70 E1    JSR $E170  [$01:E170]   
$01/DF46 C9 00 01    CMP #$0100             
$01/DF49 90 03       BCC $03    [$DF4E]     
$01/DF4B A9 FF 00    LDA #$00FF             
$01/DF4E E2 20       SEP #$20               
$01/DF50 99 28 20    STA $2028,y[$7E:22A8]   ;Adjust P-Defense Multiplier according to Adjustment Ratio
$01/DF53 C2 20       REP #$20               
$01/DF55 B9 2A 20    LDA $202A,y[$7E:22AA]   
$01/DF58 29 FF 00    AND #$00FF             
$01/DF5B 85 E8       STA $E8    [$00:00E8]   
$01/DF5D 68          PLA                     
$01/DF5E 48          PHA                     
$01/DF5F 20 70 E1    JSR $E170  [$01:E170]   
$01/DF62 C9 00 01    CMP #$0100             
$01/DF65 90 03       BCC $03    [$DF6A]     
$01/DF67 A9 FF 00    LDA #$00FF             
$01/DF6A E2 20       SEP #$20               
$01/DF6C 99 2A 20    STA $202A,y[$7E:22AA]   ;Adjust P-Defense Base according to Adjustment Ratio
$01/DF6F C2 20       REP #$20               
$01/DF71 B9 22 20    LDA $2022,y[$7E:22A2]   
$01/DF74 29 FF 00    AND #$00FF             
$01/DF77 85 E8       STA $E8    [$00:00E8]   
$01/DF79 68          PLA                     
$01/DF7A 48          PHA                     
$01/DF7B 20 70 E1    JSR $E170  [$01:E170]   
$01/DF7E C9 00 01    CMP #$0100             
$01/DF81 90 03       BCC $03    [$DF86]     
$01/DF83 A9 FF 00    LDA #$00FF             
$01/DF86 E2 20       SEP #$20               
$01/DF88 99 22 20    STA $2022,y[$7E:22A2]   ;Adjust M-Defense Multiplier according to Adjustment Ratio
$01/DF8B EA          NOP                     
$01/DF8C C2 20       REP #$20               
$01/DF8E B9 24 20    LDA $2024,y[$7E:22A4]   
$01/DF91 29 FF 00    AND #$00FF             
$01/DF94 85 E8       STA $E8    [$00:00E8]   
$01/DF96 68          PLA                     
$01/DF97 48          PHA                     
$01/DF98 20 70 E1    JSR $E170  [$01:E170]   
$01/DF9B C9 00 01    CMP #$0100             
$01/DF9E 90 03       BCC $03    [$DFA3]     
$01/DFA0 A9 FF 00    LDA #$00FF             
$01/DFA3 E2 20       SEP #$20               
$01/DFA5 99 24 20    STA $2024,y[$7E:22A4]   ;Adjust M-Defense Base according to Adjustment Ratio
$01/DFA8 C2 20       REP #$20               
$01/DFAA B9 15 20    LDA $2015,y[$7E:2295]   
$01/DFAD 29 FF 00    AND #$00FF             
$01/DFB0 85 E8       STA $E8    [$00:00E8]   
$01/DFB2 68          PLA                     
$01/DFB3 48          PHA                     
$01/DFB4 20 70 E1    JSR $E170  [$01:E170]   
$01/DFB7 C9 00 01    CMP #$0100             
$01/DFBA 90 03       BCC $03    [$DFBF]     
$01/DFBC A9 FF 00    LDA #$00FF             
$01/DFBF E2 20       SEP #$20               
$01/DFC1 99 15 20    STA $2015,y[$7E:2295]   ;Adjust Agility according to Adjustment Ratio
$01/DFC4 C2 20       REP #$20               
$01/DFC6 BB          TYX                     
$01/DFC7 BD 6F 20    LDA $206F,x[$7E:22EF]   
$01/DFCA 30 36       BMI $36    [$E002]      ;Skip HP/Max Adjustment if Monster is a Boss
$01/DFCC 9E 09 20    STZ $2009,x[$7E:2289]   
$01/DFCF B9 07 20    LDA $2007,y[$7E:2287]   
$01/DFD2 AA          TAX                     
$01/DFD3 29 FF 00    AND #$00FF             
$01/DFD6 85 E8       STA $E8    [$00:00E8]   
$01/DFD8 68          PLA                     
$01/DFD9 48          PHA                     
$01/DFDA 20 70 E1    JSR $E170  [$01:E170]   
$01/DFDD 99 07 20    STA $2007,y[$7E:2287]   
$01/DFE0 8A          TXA                     
$01/DFE1 29 00 FF    AND #$FF00             
$01/DFE4 EB          XBA                     
$01/DFE5 85 E8       STA $E8    [$00:00E8]   
$01/DFE7 68          PLA                     
$01/DFE8 20 70 E1    JSR $E170  [$01:E170]   
$01/DFEB 18          CLC                     
$01/DFEC 79 08 20    ADC $2008,y[$7E:2288]   
$01/DFEF C9 00 01    CMP #$0100             
$01/DFF2 90 03       BCC $03    [$DFF7]     
$01/DFF4 A9 FF 00    LDA #$00FF             
$01/DFF7 99 08 20    STA $2008,y[$7E:2288]   
$01/DFFA B9 07 20    LDA $2007,y[$7E:2287]   
$01/DFFD 99 09 20    STA $2009,y[$7E:2289]   ;Adjust Current HP and Max HP according to Adjustment Ratio
$01/E000 80 01       BRA $01    [$E003]     
$01/E002 68          PLA                     
$01/E003 7B          TDC                     
$01/E004 AA          TAX                     
$01/E005 A8          TAY                     
$01/E006 AE 80 22    LDX $2280  [$7E:2280]   
$01/E009 AC 90 22    LDY $2290  [$7E:2290]   
$01/E00C 9C 80 22    STZ $2280  [$7E:2280]   
$01/E00F 9C 90 22    STZ $2290  [$7E:2290]   
$01/E012 E2 20       SEP #$20                ;Clean/Restore Registers
$01/E014 AD A5 28    LDA $28A5  [$7E:28A5]   
$01/E017 5C FB 90 03 JMP $0390FB[$03:90FB]   ;Back to our regularly scheduled program

This will patch cleanly.

High level Imps will still be tough, but not nearly the Death Bringers they were in the working stages.

Aso, normally higher-level monsters will level down if the ratio calls for it... I figured, what the hell, might as well. You'll level up soon enough fighting weak flamedogs and blacklizzes anyway...

I think I'm done with this patch for now.

 :edit:
The link to this patch was broken. Unfortunately, I do not have a backup of the patch at this time. I will remake one at some point. Sorry.

833
Him, that's an interesting route to take...
I think, though, that I've figured out a good plan. I'll hopefully have an updated patch up later today (or else tomorrow for sure) and will explain it then.

Now that I think about it, I could still work in the item change portion in addition... Maybe won't do that all at once, though.

834
Well, I got the new formula up and running, but it may need an adjustment...
High level Imps become godlike death bringers, because their level starts off so low.
I have a couple of ideas for solving this:
Possibility 1) cut the ratio in half before applying to attack and defense multipliers
Possibility 2) skip modifying multipliers altogether
Possibility 3) raise the starting level of low level monsters (I don't think a monster's level really does anything anyway), thus naturally lowering the level up ratio (this would be the easiest fix, but would also impact the universality of the patch...)

835
Ah... Was not aware of that op. Good to know.

836
 No...
AND #$FF00. The idea is to create a ratio, using the lower byte as the fraction. The formula would make, for instance, a level 50 monster that meets a level 99 party level up to 98.

Here's that example (all in hex)
(APL) 63 * 100 = 6300 [this will be achieved by loading the byte before APL and performing AND #$FF00 - it's a few bytes quicker than 8 ASLs]
 :edit: I'm writing it now... no ASLs are quicker because APL is already in the lower byte of A
6300 / (Monster level) 32 = (ratio) 1FA
1FA * 32 = (adjusted monster level) 62

It's absolutely nothing like my original formula. It's much simpler, and hopefully better. If I end up with monster stats that are way too high, I can try slashing the ratio before applying it to non-level stats.

I guess the same formula could be applied to weaken higher-level monsters, but I'm not sure I want to do that...

 :edit: Gotta break to make dinner. Seems to be working so far. I'm debugging as I go, so the coding is slow, but no crashes so far...

837
So I took a long look at those multiplication functions, and I've got an idea.
I'm going to try:
1) set A to 16-bit
2) load APL into A
3) AND #$FF00
4) load monster level into X
5) divide, 16-bit A becomes the multiplier(ignore remainder)
6) load stat to raise into 8-bit X
7) STX $E8
8) Multiply 16-bit A by E8, the result will be a 16-bit A where the lower byte is the modified stat
9) TAX
10) Store X in appropriate stat location

This should serve to raise stats in a ratio very close to APL:Monster level

838
Finding a good balance is kind of a tricky proposition. Near as I can tell, only a handful of non-boss monsters have a level higher than 35, and they're all in the Giant of Bab-il and Lunar Subterrane.

I'm not against the idea of rewriting the formula to make it return more appropriate results - there are obviously more possibilities now that you've shown me the trick to complex multiplication and division - but I think figuring out what is right may require an actual playthrough.

839
Those $0042nn variables are custom SNES math registers.  Just set them, and it knows what to do. ;)  It takes several cycles, which is why the NOPs are there.  Mode-7 registers are another option for math, though I'm less familiar with those.  Yes, both of these should work on FF4.

Rock'n'roll. Thanks, assassin! (And, yes, I was wondering about the NOPs)

840
Well, if you're interested, here's a commented disassembly of the code used to level-up monsters.

Code: [Select]
$03/90F5 5C 60 DE 01 JMP $01DE60      ;Jump to custom code
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$01/DE60 9D 24 20    STA $2024,x[$7E:22A4]   ;Performs the action that was skipped in original code
$01/DE63 8E 80 22    STX $2280  [$7E:2280]   ;Temporarily store Registers X and Y in space that will always be free (monsters don't use 2000-2001,x and 2010-2011,x)
$01/DE66 8C 90 22    STY $2290  [$7E:2290]   ; originally, I just wrote PHX and PHY, but oddly, when I pulled them back, the x value got pulled into y and the y into x... weird
$01/DE69 C2 20       REP #$20               
$01/DE6B 7B          TDC                     
$01/DE6C AA          TAX                     
$01/DE6D A8          TAY                     ;Clear A, X and Y (and set A to 16-bit status)
$01/DE6E AD 02 20    LDA $2002  [$7E:2002]   
$01/DE71 29 FF 00    AND #$00FF             
$01/DE74 F0 02       BEQ $02    [$DE78]      ;Check for a character in slot 1, if none, skip to next check
$01/DE76 AA          TAX                     ;If one is there, store its level into X
$01/DE77 C8          INY                     ;and +1 to Y
$01/DE78 AD 82 20    LDA $2082  [$7E:2082]   
$01/DE7B 29 FF 00    AND #$00FF             
$01/DE7E F0 09       BEQ $09    [$DE89]      ;Check for a character in slot 2, if none, skip to next check
$01/DE80 85 A9       STA $A9    [$00:00A9]   ;If one is there, store its level into A9 (A9-AA seems to be used regularly for temporary storage)
$01/DE82 8A          TXA                     ;Move value in X to A
$01/DE83 18          CLC                     
$01/DE84 6D A9 00    ADC $00A9  [$7E:00A9]   ;Add the (recently stored) value in A9 to accumulator
$01/DE87 AA          TAX                     ;Move sum back to register X
$01/DE88 C8          INY                     ;and +1 to Y
$01/DE89 AD 02 21    LDA $2102  [$7E:2102]   
$01/DE8C 29 FF 00    AND #$00FF             
$01/DE8F F0 09       BEQ $09    [$DE9A]     
$01/DE91 85 A9       STA $A9    [$00:00A9]   
$01/DE93 8A          TXA                     
$01/DE94 18          CLC                     
$01/DE95 6D A9 00    ADC $00A9  [$7E:00A9]   
$01/DE98 AA          TAX                     
$01/DE99 C8          INY                     ;Same exact process for Slot 3
$01/DE9A AD 82 21    LDA $2182  [$7E:2182]   
$01/DE9D 29 FF 00    AND #$00FF             
$01/DEA0 F0 09       BEQ $09    [$DEAB]     
$01/DEA2 85 A9       STA $A9    [$00:00A9]   
$01/DEA4 8A          TXA                     
$01/DEA5 18          CLC                     
$01/DEA6 6D A9 00    ADC $00A9  [$7E:00A9]   
$01/DEA9 AA          TAX                     
$01/DEAA C8          INY                     ;...And slot 4
$01/DEAB AD 02 22    LDA $2202  [$7E:2202]   
$01/DEAE 29 FF 00    AND #$00FF             
$01/DEB1 F0 09       BEQ $09    [$DEBC]     
$01/DEB3 85 A9       STA $A9    [$00:00A9]   
$01/DEB5 8A          TXA                     
$01/DEB6 18          CLC                     
$01/DEB7 6D A9 00    ADC $00A9  [$7E:00A9]   
$01/DEBA AA          TAX                     
$01/DEBB C8          INY                     ;...And slot 5
$01/DEBC 8A          TXA                     ;Move final total into A
$01/DEBD C0 05 00    CPY #$0005             
$01/DEC0 D0 06       BNE $06    [$DEC8]      ;Check if Y = 5, if not skip to next check
$01/DEC2 38          SEC                     
$01/DEC3 ED A9 00    SBC $00A9  [$7E:00A9]   ;Subtract last character's level
$01/DEC6 4A          LSR A                   ;Divide by 2
$01/DEC7 4A          LSR A                   ;Divide by 2
$01/DEC8 C0 04 00    CPY #$0004             
$01/DECB D0 02       BNE $02    [$DECF]      ;Check if Y = 4, if not, skip to next check
$01/DECD 4A          LSR A                   ;Divide by 2
$01/DECE 4A          LSR A                   ;Divide by 2
$01/DECF C0 03 00    CPY #$0003             
$01/DED2 D0 05       BNE $05    [$DED9]      ;Check if Y = 3, if not, skip to next check
$01/DED4 38          SEC                     
$01/DED5 ED A9 00    SBC $00A9  [$7E:00A9]   ;Subtract last character's level
$01/DED8 4A          LSR A                   ;Divide by 2
$01/DED9 C0 02 00    CPY #$0002             
$01/DEDC D0 01       BNE $01    [$DEDF]      ;Check if Y = 2, if not, skip the next Operation
$01/DEDE 4A          LSR A                   ;Divide by 2... Phew! Now we've got out APL. There are definitely inefficiencies here, but it works.
$01/DEDF AE 80 22    LDX $2280  [$7E:2280]   
$01/DEE2 AC 90 22    LDY $2290  [$7E:2290]   
$01/DEE5 9C 80 22    STZ $2280  [$7E:2280]   
$01/DEE8 9C 90 22    STZ $2290  [$7E:2290]   ;Restore X and Y and clear the space in RAM used to store them
$01/DEEB EA          NOP                     
$01/DEEC EA          NOP                     
$01/DEED EA          NOP                     
$01/DEEE EA          NOP                     
$01/DEEF EA          NOP                     
$01/DEF0 85 A9       STA $A9    [$00:00A9]   ;Store APL in A9
$01/DEF2 7B          TDC                     
$01/DEF3 E2 20       SEP #$20                ;Clear A and set 8-bit status
$01/DEF5 BD 70 20    LDA $2070,x[$7E:22F0]   ;Load Monster's "Level plus boss bit"
$01/DEF8 10 07       BPL $07    [$DF01]      ;If not a boss, skip ahead (Probably could have led off with this, but oh well)
$01/DEFA AD A5 28    LDA $28A5  [$7E:28A5]   ;Perform action that we wrote over for the purpose of this process
$01/DEFD 5C FB 90 03 JMP $0390FB[$03:90FB]   ;Jump back to the regular monster loading routine
$01/DF01 A5 A9       LDA $A9    [$00:00A9]   
$01/DF03 DD 02 20    CMP $2002,x[$7E:2282]   
$01/DF06 B0 07       BCS $07    [$DF0F]      ;Compare APL to Monster's level, if APL is higher, keep going
$01/DF08 AD A5 28    LDA $28A5  [$7E:28A5]   ;if APL is lower, preform overwritten operation
$01/DF0B 5C FB 90 03 JMP $0390FB[$03:90FB]   ;And return to regular monster loading routine
$01/DF0F BD 02 20    LDA $2002,x[$7E:2282]   ;Load Monster's level
$01/DF12 C9 54       CMP #$54               
$01/DF14 90 04       BCC $04    [$DF1A]      ;Check if it is 84 (dec) or higher
$01/DF16 A9 7F       LDA #$7F               
$01/DF18 80 05       BRA $05    [$DF1F]      ;If so, then load 127 (dec) into A (this is the highest a monster's level can be, beyond this the monster will set the Boss bit) and skip ahead
$01/DF1A 4A          LSR A                   
$01/DF1B 18          CLC                     
$01/DF1C 7D 02 20    ADC $2002,x[$7E:2282]   ;Multiply level by 1.5
$01/DF1F 9D 02 20    STA $2002,x[$7E:2282]   ;Store monster's new level
$01/DF22 9D 70 20    STA $2070,x[$7E:22F0]   ;Store monster's new "level plus boss bit"
$01/DF25 69 0A       ADC #$0A                ;add 10 (dec)
$01/DF27 9D 2F 20    STA $202F,x[$7E:22AF]   ;Store monster's new "level plus 10"
$01/DF2A BD 1B 20    LDA $201B,x[$7E:229B]   ;Load monster's P-Attack multiplier
$01/DF2D C9 AA       CMP #$AA               
$01/DF2F 90 04       BCC $04    [$DF35]      ;Check if it is 170 (dec) or higher (because otherwise multiplying by 1.5 yields a result higher than FF)
$01/DF31 A9 FF       LDA #$FF               
$01/DF33 80 05       BRA $05    [$DF3A]      ;If so, then load 255 (dec) into A and skip ahead
$01/DF35 4A          LSR A                   
$01/DF36 18          CLC                     
$01/DF37 7D 1B 20    ADC $201B,x[$7E:229B]   ;Multiply by 1.5
$01/DF3A 9D 1B 20    STA $201B,x[$7E:229B]   ;Store monster's new P-Attack Multiplier
$01/DF3D BD 1D 20    LDA $201D,x[$7E:229D]   
$01/DF40 C9 AA       CMP #$AA               
$01/DF42 90 04       BCC $04    [$DF48]     
$01/DF44 A9 FF       LDA #$FF               
$01/DF46 80 05       BRA $05    [$DF4D]     
$01/DF48 4A          LSR A                   
$01/DF49 18          CLC                     
$01/DF4A 7D 1D 20    ADC $201D,x[$7E:229D]   
$01/DF4D 9D 1D 20    STA $201D,x[$7E:229D]   ;Same process for P-Attack Base
$01/DF50 BD 28 20    LDA $2028,x[$7E:22A8]   
$01/DF53 C9 AA       CMP #$AA               
$01/DF55 90 04       BCC $04    [$DF5B]     
$01/DF57 A9 FF       LDA #$FF               
$01/DF59 80 05       BRA $05    [$DF60]     
$01/DF5B 4A          LSR A                   
$01/DF5C 18          CLC                     
$01/DF5D 7D 28 20    ADC $2028,x[$7E:22A8]   
$01/DF60 9D 28 20    STA $2028,x[$7E:22A8]   ;... And P-Defense Multiplier
$01/DF63 BD 2A 20    LDA $202A,x[$7E:22AA]   
$01/DF66 C9 AA       CMP #$AA               
$01/DF68 90 04       BCC $04    [$DF6E]     
$01/DF6A A9 FF       LDA #$FF               
$01/DF6C 80 05       BRA $05    [$DF73]     
$01/DF6E 4A          LSR A                   
$01/DF6F 18          CLC                     
$01/DF70 7D 2A 20    ADC $202A,x[$7E:22AA]   
$01/DF73 9D 2A 20    STA $202A,x[$7E:22AA]   ;... And P-Defense Base
$01/DF76 BD 22 20    LDA $2022,x[$7E:22A2]   
$01/DF79 C9 AA       CMP #$AA               
$01/DF7B 90 04       BCC $04    [$DF81]     
$01/DF7D A9 FF       LDA #$FF               
$01/DF7F 80 05       BRA $05    [$DF86]     
$01/DF81 4A          LSR A                   
$01/DF82 18          CLC                     
$01/DF83 7D 22 20    ADC $2022,x[$7E:22A2]   
$01/DF86 9D 22 20    STA $2022,x[$7E:22A2]   ;... And M-Defense Multiplier
$01/DF89 BD 24 20    LDA $2024,x[$7E:22A4]   
$01/DF8C C9 AA       CMP #$AA               
$01/DF8E 90 04       BCC $04    [$DF94]     
$01/DF90 A9 FF       LDA #$FF               
$01/DF92 80 05       BRA $05    [$DF99]     
$01/DF94 4A          LSR A                   
$01/DF95 18          CLC                     
$01/DF96 7D 24 20    ADC $2024,x[$7E:22A4]   
$01/DF99 9D 24 20    STA $2024,x[$7E:22A4]   ;... And M-Defense Base
$01/DF9C C2 20       REP #$20                ;Set Accumulator 16-bit status
$01/DF9E BD 09 20    LDA $2009,x[$7E:2289]   ;Load Monster's Max HP into A
$01/DFA1 C9 AA AA    CMP #$AAAA             
$01/DFA4 90 05       BCC $05    [$DFAB]      ;Check if it is 43690 (dec) or higher (again, to avoid rolling over)
$01/DFA6 A9 FF FF    LDA #$FFFF             
$01/DFA9 80 05       BRA $05    [$DFB0]      ;If so, load 65535 (dec) into A and skip ahead
$01/DFAB 4A          LSR A                   
$01/DFAC 18          CLC                     
$01/DFAD 7D 09 20    ADC $2009,x[$7E:2289]   ;Multiply by 1.5
$01/DFB0 9D 09 20    STA $2009,x[$7E:2289]   ;Store new Max HP
$01/DFB3 9D 07 20    STA $2007,x[$7E:2287]   ;And store it in Current HP
$01/DFB6 7B          TDC                     
$01/DFB7 E2 20       SEP #$20                ;Clear A and reset 8-bit status
$01/DFB9 A5 A9       LDA $A9    [$00:00A9]   ;Load APL
$01/DFBB 4A          LSR A                   ;Divide by 2
$01/DFBC 85 A9       STA $A9    [$00:00A9]   ;store new APL
$01/DFBE 4C 03 DF    JMP $DF03  [$01:DF03]   ;Jump all the way back to DF03 ("compare APL with monster's level")

Turns out I didn't put in code that increases the monsters' base agility. I think this is OK, though. I'm not sure how modified agility is calculated, but it must take the monster's level into account, because leveled-up BlackLiz'es were definitely faster than normal (they kinda kicked my ass).

This is surely not the cleanest code I've written, but once I had it all working, it was so much that I didn't feel like going back to tidy it up. At any rate, the empty space at 01/DE60 is so huge, even this only takes up about a third of it, so it seemed unnecessary anyway.