News: 11 March 2016 - Forum Rules
Current Moderators - DarkSol, KingMike, MathOnNapkins, Azkadellia, Danke

Author Topic: FF1 MMC5 Disassembly Updates  (Read 222569 times)

Jiggers

  • Sr. Member
  • ****
  • Posts: 417
    • View Profile
    • My Ko-Fi Page
Re: FF1 MMC5 Disassembly Updates
« Reply #680 on: August 24, 2020, 06:08:56 pm »
I did something similar to that...

Code: [Select]
OpenTreasureChest:
    LDA #BANK_TREASURE       ; swap to bank containing treasure chest info
    JSR SwapPRG_L

    LDA tileprop             ; get either 0 or 1 from the tile properties
    AND #$01                 ; 1 = first table of treasure
    TAX                      ; 0 = second table of treasure
    LDA lut_TreasureTable_Low, X
    STA tmp
    LDA lut_TreasureTable_High, X
    STA tmp+1
   
    LDA tileprop+1
    ASL A
    BCC @LoadTreasure
   
    INC tmp+1
   
   @LoadTreasure:

Good to know I was on the right track!

So after an FF14 update, food poisoning, and general blehness and wanting to focus on other things... trying to get back at it.

Going to need to re-do a whole lot of battle message strings... I feel like this is stupid, but then... maybe not?

Code: [Select]
BattleItemName_LUT_Low:
    .word lut_MagicNames_Low      ; $0C
    .word lut_EquipmentNames_Low  ; $0D
    .word lut_ItemNames_Low       ; $0E
    .word lut_BattleMessages_Low  ; $0F
    .word lut_GoldNames_Low       ; $10

BattleItemName_LUT_High:
    .word lut_MagicNames_High     ; $0C
    .word lut_EquipmentNames_High ; $0D
    .word lut_ItemNames_High      ; $0E
    .word lut_BattleMessages_High ; $0F   
    .word lut_GoldNames_High      ; $10

BattleDraw_LoadObjectNamePtr:
    SEC
    SBC #$0C                    ; turn control code into 0-based
    TAX
    PHA
    LDA BattleItemName_LUT_Low, X
    STA btltmp+6
    LDA BattleItemName_LUT_Low+1, X
    STA btltmp+7
    LDA BattleItemName_LUT_High, X
    STA btltmp+8
    LDA BattleItemName_LUT_High+1, X
    STA btltmp+9
   
    JSR DrawBattle_IncSrcPtr
    LDA (btldraw_src), Y    ; get the desired index   
    TAY
    LDA (btltmp+6), Y
    STA btldraw_subsrc
    LDA (btltmp+8), Y
    STA btldraw_subsrc+1
    RTS

So $0F $01 will still print the first battle message... $0C $01 should print a spell name... and it all routes through here!

The original code involved loading A and X with the low and high bytes of, say, the item name pointer table, and doing this:

Code: [Select]
   STA btltmp+7 ; $97      ; high byte of pointer table
   
   JSR DrawBattle_IncSrcPtr
   LDA (btldraw_src), Y    ; get the desired index

   ASL A                   ; multiply by 2 (2 bytes per pointer)
   PHP                     ; backup the carry
   STA btltmp+6            ; use as low byte
   
   TXA                     ; get X (low byte of pointer table)
   CLC
   ADC btltmp+6            ; add with low byte of index
   STA btltmp+6            ; use as final low byte
   
   LDA #$00                ; add the carry from the X addition
   ADC btltmp+7   
   PLP                     ; also add the carry from the above *2
   ADC #$00
   STA btltmp+7            ; use as final high byte
   
   LDY #$00                ; get the pointer, store in btldraw_subsrc
   LDA (btltmp+6), Y
   STA btldraw_subsrc
   INY
   LDA (btltmp+6), Y
   STA btldraw_subsrc+1
   
   RTS   

Which, maybe faster, maybe saves space--but is difficult to really understand, doesn't work with what I'm doing with the item name tables, and requires a lot more @local routines in the battle control code compare list...

Edit: Hm. Stupid as it feels, I may have already created equilibrium on the byte-saving, after making sure all the other item name printing routines in the fixed bank use the new format.
« Last Edit: August 24, 2020, 07:37:36 pm by Jiggers »
I know exactly what I'm doing. I just don't know what effect it's going to have.

I wrote some NES music! Its a legal ROM file. - I got a Ko-Fi page too.

Vanya

  • Hero Member
  • *****
  • Posts: 1796
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #681 on: August 25, 2020, 06:16:11 am »
Oh, hell. Feeling better I hope!
Sounds like you had a rough time there.

If it'll save space, then redoing the messages isn't stupid.
( I still want to assassinate as many of them as possible! >:3 )

The blehnesss is real! I've been redesigning the character sheet for Microlite2020 for what feels like 30 years! (Really just a few days, but still longer than it should have taken.) I want to get done today even if I end up staying up straight through to Wednesday.

Question! Do you want me to add the script changes to the main branch piecemeal as I'm working on it, or wait until I finish the whole thing? Also, would I be pushing or pulling on the github to add my work to the main branch? Not sure how that whole thing works yet cause I'm lazy and haven't tried to learn it yet. :P

Jiggers

  • Sr. Member
  • ****
  • Posts: 417
    • View Profile
    • My Ko-Fi Page
Re: FF1 MMC5 Disassembly Updates
« Reply #682 on: August 28, 2020, 02:41:26 pm »
Better to wait until its done I think, that way I don't accidentally overwrite it. Or put it on a side-project sort of thing? I think pull is for downloading, push is for uploading... so push!

I need to slowly go over my changes in the game with the disassembler to see why different parts of it are breaking. Ugh. I hate this part sometimes.

The messages themselves don't need re-doing, its the control codes. $10 is now $18 or something like that. So its going to be searching through the battle code to find where messages are displayed on level up, or during attacks, and make sure those are using the right numbers.

I don't know if I'll do it today. Too many projects to pick from.
I know exactly what I'm doing. I just don't know what effect it's going to have.

I wrote some NES music! Its a legal ROM file. - I got a Ko-Fi page too.

Vanya

  • Hero Member
  • *****
  • Posts: 1796
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #683 on: August 31, 2020, 01:39:54 am »
Gotcha. I'll do the side-project thing so I can copy/paste later. :3

Jiggers

  • Sr. Member
  • ****
  • Posts: 417
    • View Profile
    • My Ko-Fi Page
Re: FF1 MMC5 Disassembly Updates
« Reply #684 on: September 12, 2020, 01:39:38 am »
I did some more work today! I keep forgetting where I am and what I'm doing, but I made some progress. Fixed a few things. Item menu now shows item quantities again. Equip menu is almost sorted, maybe? Once I figure out why a small knife is being stored as a wooden staff.

Crashing before battles still, and moving the cursor in shops corrupts the screen and palette...
Status window needs to read its own palette as well...

Yeah, all things that were working before, but when you completely change how data is read for writing item names, try to add in cheering for magic spells, and re-do the whole inventory data storage, this is what happens!

I can't promise I'll keep plugging away at it at the same speeds I used to. Trying to stay interested lately.

I also need to add in a message for trying to equip a new weapon when you have 16 of the item you're unequipping. I've set an overflow trigger to capture it, at least. Otherwise, if you have 15 rapiers and 1 in your hand, you'll store it--which will remain at 15--and then if you cancel, it will pull 1 from the 15 pile, basically throwing away 2 rapiers!  :P So with the overflow trigger, it at least keeps all 16 if you cancel, but there's no prompt to warn you you're gonna toss out 1 by swapping to a new weapon. With the new compression, 15's the limit in storage.

But really, why do you have 15 rapiers. Weirdo.



Quick before bed update: Fixed the small knife turning into a wooden staff when unequipping. Now equipping turns it into wooden nunchucks, and gives Damage 22, Accuracy 10, Critical 10, when it should be 15, 20, 5. Will sort that out next time.
« Last Edit: September 12, 2020, 02:04:46 am by Jiggers »
I know exactly what I'm doing. I just don't know what effect it's going to have.

I wrote some NES music! Its a legal ROM file. - I got a Ko-Fi page too.

Vanya

  • Hero Member
  • *****
  • Posts: 1796
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #685 on: September 12, 2020, 12:47:36 pm »
No worries. This is a hobby, not a job, so take it at whatever pace you want.

When it comes to keeping track of where I was I like to leave myself a detailed comment in the code and separate note in a text file with the location of that note. That way I don't get quite as lost when I come back to something.

About the item overflow.
I think the best thing is to have the game check your inventory and each character's equipment and tally that all up before adding anything to inventory. So if all party members have a rapier and you have 12 rapiers in your inventory, then you can't pick up, buy, or otherwise be given another rapier.
We were doing drop items, right? You could extend the drop item routine to select a different item if your inventory is full. Or even convert the item to Gil.
This way it's not possible to get into a situation where you could overflow the inventory.
That is unless we have a cheater!
And if we do, then we can let the rapier obsessed weirdo simply loose any extra rapiers that are unequipped in silence with no need for an extra message for it.

Dirty rapier cheaters...

Jiggers

  • Sr. Member
  • ****
  • Posts: 417
    • View Profile
    • My Ko-Fi Page
Re: FF1 MMC5 Disassembly Updates
« Reply #686 on: September 13, 2020, 02:32:38 am »
I forget, but I think the shop does that. I'm not sure on the feasibility of checking everyone's equipment for treasure chests and stealing though. And I don't THINK I have a drop-after-battle item thing... I didn't want to code more menus and messages for it.

So inventory overflow would mainly be caused by stealing items you already have equipped. It should stop you from stealing more than you can carry, anyway... Hmmm...

Today's progress: Weapon handling in the equipment menu is 99%. Armor is buggy as heck. Magic shops crash.

Today's amazing thing:
* While trying to figure out why weapon's spells aren't drawing right in the equipment menu...
* I figure out the problem is in checking if the item ID is the Bottle, or the Lewds!
* Then while fixing it, I find out I can make that code half the size. Then I move it to the fixed bank...
* And I move some jumps and returns around so that the new checking code flows into loading up the right bank...
* Then because of moving that, I find an error during compiling, where a branch point is 1 byte too far away from its destination label.
* Checking on that, it turns out the branch point wasn't set properly and was only supposed to jump something like 3 bytes... not 128...
* Then realize this branch point could only be taken if the player had cheated to give themselves the sleep, stun, mute, or confuse ailment outside of battle...

I still have no idea how the item menu was drawing correctly since every item ID was being halved! Or was that because it doesn't use DrawComplexString... So many things I forget about.

Update: Closing in on finishing the equip menus! Most things are looking right. I even updated it so you can check elemental properties of things you can't equip. I changed "Element" for armor to "Resist" so that it shows it PROTECTS from ailments, and RESISTS elements. Which brings me to the question... given that ailment protection is new... why did I make the Zeus gauntlets protect against sleep?? Is that an accidental 1 in the data, or did I have some kind of thought like, "how can you sleep with zappy gloves on? They'd jolt you awake!"
« Last Edit: September 13, 2020, 05:14:15 am by Jiggers »
I know exactly what I'm doing. I just don't know what effect it's going to have.

I wrote some NES music! Its a legal ROM file. - I got a Ko-Fi page too.

Vanya

  • Hero Member
  • *****
  • Posts: 1796
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #687 on: September 13, 2020, 08:48:15 am »
Yeap. I don't see any reason why the Zeus Gauntlets would have protection from sleep! LOL :3

Great work on today's amazing thing! I love it when code falls into place like that. :D

Remind me of something? PROTECTS from ailments is like the original where it reduces the chances of getting the ailment, or did you rework it to just prevent ailments entirely like in every other game in the series?

Jiggers

  • Sr. Member
  • ****
  • Posts: 417
    • View Profile
    • My Ko-Fi Page
Re: FF1 MMC5 Disassembly Updates
« Reply #688 on: September 13, 2020, 03:11:49 pm »
Code: [Select]
    LDA btl_attacker_attackailment
    BEQ @NextHitIteration           ; we're done if no ailment to apply
   
   @DoAilmentChance:
    AND btl_defender_statusresist
    BNE @NextHitIteration           ; defender has resistance to the status

Looks like its just straight up preventing, like every other game. Easiest to code and all that.

How did the original do it? It was basically the same, but with a 1/256 chance to fail?
I know exactly what I'm doing. I just don't know what effect it's going to have.

I wrote some NES music! Its a legal ROM file. - I got a Ko-Fi page too.

Vanya

  • Hero Member
  • *****
  • Posts: 1796
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #689 on: September 14, 2020, 10:39:51 am »
Yeah. Pretty much it just made it really hard to succeed.
It lead me to some rare instances of, "What? I thought I was immune to that!?."
So yeah, straight up immunity for the win. :3

Jiggers

  • Sr. Member
  • ****
  • Posts: 417
    • View Profile
    • My Ko-Fi Page
Re: FF1 MMC5 Disassembly Updates
« Reply #690 on: September 28, 2020, 01:44:04 am »
Arrrrrrrrrrrrrrrgh.

I spent all day doing shop things... basically haven't done any work since my last post.

Almost done... so close. Item shop prices are reminiscent of Russian modders' ideas of realism in STALKER games... yes a pure SHOULD cost 50000, why not. Buying magic doesn't actually give you magic... And it doesn't make characters pose yet. These things should be very close to being done though!

I fixed the graphics corruption issue when moving the cursor in the shops, I've got item names displaying properly again, fixed the freezing when displaying item descriptions... These seem so little, but took so long to figure out. So rusty.

Then, while fixing the palettes, I noticed that I had put in a palette space for a Skill Shop, and then... realised all the work I've done today did not take into account a Skill Shop existing. Pbbblt.



Cure doesn't display having 2 equipped, because I edited the RAM, and that only changes when you first load the list or buy/sell something. The posing and magic cobwebs change on cursor movement!

Something, somewhere, is still off (most likely by 1), because the White mage doesn't pose for Blink, and the Red mage poses for Harm and Blink, but not Cure... So Blink is being treated like Fire... yep, this checks out. Wrong permission byte being loaded. I'll fix that, then put this on Github!

Next, learning and unlearning magic needs to be updated, because Cure is not "16"... (If I have 2 Cures, it shows "32")

QUESTION!

What should be done about the spell book menus? They were kind of designed with only white/black in mind.

I'm thinking, maybe each screen is 1 spell level: White, Black on the left, as they are now. Then instead of Level 2 on the right side, its Green/Time. This screen also has 2 free palettes to use, and the magic orbs land quite nicely on some attribute squares. It should be easy to alter the colours to green/purple or whatever else, then just use the white orb tiles for the right side.

Quick note on the 4bytes of attributes to edit: 2C33=77, 23D4=77, 23DC=BB, 23E4=BB. And some notes on possible palette values:



I'm open to other ideas though! For now!



Alright, last update tonight. 5:40 AM.

Uploading it to Github now (over 400 changed files?? what the heck?? I can't even view what files those are without it stuttering!)

Have another question: When you sell something, say at the weapon shop, and its successful, the text "Thank you kindly, what else?" pops up for a brief moment, followed by your sell-able inventory again, then the stat-view overwrites the shopkeeper's dialogue. What should the flow feel like here? Should there be a pause, wait for a button press, so the player can read this message? Should it go back to the Buy/Sell/Exit prompt? Should it hide the inventory window, as if that one sale was your last? What feels best?

September 28, 2020, 08:19:46 pm - (Auto Merged - Double Posts are not allowed before 7 days.)


Pros: I like how everything is centered when you have no spells.

Cons: It does look a LITTLE messy with a 7 letter spell name... And if you have over 10 spells, (say from stealing from enemies, I can't quite figure out a smooth, low-byte budget way to cap that at 9 without doing extra checks) it will display a 1 in place of the tiny x. So that's no good.

Solution: Remove the tiny X (?), keep the single-digits in the spot where they are, but if its over 9, push them to the next slot--beside the border--and have the 1 where they are now?




September 29, 2020, 07:09:02 pm - (Auto Merged - Double Posts are not allowed before 7 days.)
Sometimes the wait a week between post thing bothers me! I'm documenting my progress here!



Re-doing the level up code from scratch. Original/slightly edited code on the left, new code on the right. Not bothering with pointers and junk, that's way too confusing for how many things are being changed here! So that image is just the MP boost portion. I've also added another data table for MP cap, so if you want Red Mages to cap out at 6 MP per level, while Red Wizards cap out at 9... You can do that!

And a bonus, new code for calculating EXP to Next for the status screen: https://cdn.discordapp.com/attachments/291164822194749441/760609974454976582/unknown.png

SHOULD I CONSIDER IT A BUG THAT ON STRONG LEVEL UPS, THE GAME GIVES YOU THE HP BOOST BASED ON YOUR VITALITY BEFORE ACTUALLY GIVING YOU THE VITALITY STAT INCREASE?!?!
« Last Edit: September 29, 2020, 07:18:52 pm by Jiggers »
I know exactly what I'm doing. I just don't know what effect it's going to have.

I wrote some NES music! Its a legal ROM file. - I got a Ko-Fi page too.

Vanya

  • Hero Member
  • *****
  • Posts: 1796
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #691 on: September 29, 2020, 07:12:54 pm »
1) Spellbook layout?

---> One spell level per page is perfectly fine. No need to reinvent the wheel on this one.

2) Shop dialogue flow?

---> The first thought that came to mind is adding a "pause" so that there is time to read the message for slow readers like me and also to avoid accidentally skipping it entirely with a stray button press.
Next thought was to also add a "waiting for input" after the pause so that it doesn't suddenly change with out the player doing anything.
The inventory window should stay open until there is input from the player.
Pressing 'A' should switch back to selling from the inventory window as normal.
Pressing 'B' should go back to the Buy/Sell/Exit menu.

3) New spellbook layout?

---> I say move everything 1 space to the left and keep the tiny x.
Draw the tiny x and "_0" in empty slots to keep everything centered.
The cursor might overlap the border, but I think most people won't mind.
Otherwise you could just place the cursor over the spell-type icons since they don't move around anyway.

Here's a visual example:
Code: [Select]

[ @ CONFUSEx15 ][ @ -------x 0 ]
[ @ ICE   2x 1 ][ @ -------x 0 ]


4) Documented progress?

---> Good idea! That way you have a clean record of changes to look back on. Nice!
The original level up system is very... D&D-esque. I'm pretty sure this is the only game in the series that does it like this. So shifting to an algorithm based system is definitely the way to go.
The variable MP cap is a really nice touch, too. Huzzah!
« Last Edit: September 29, 2020, 07:19:43 pm by Vanya »

Jiggers

  • Sr. Member
  • ****
  • Posts: 417
    • View Profile
    • My Ko-Fi Page
Re: FF1 MMC5 Disassembly Updates
« Reply #692 on: September 29, 2020, 07:24:39 pm »
Yay a reply!

* Button press on successful selling, can do.

* I like that x 0 thing, the cursor is always doing weird things anyway, but the centering would bug me so much without a 0 on blank spell slots.

* Not really changing the level up algorithms ... just the code. Its confusing with like 8 different pointers, when most of it can be done with X indexing the stats like 90% of the game already does.

But on that note, I just realised that strong level ups give the 20-25 HP gain and add that to your base HP-- which is based on vitality / 4 + 1-- BEFORE increasing your vitality for that level up! Should I switch it?
I know exactly what I'm doing. I just don't know what effect it's going to have.

I wrote some NES music! Its a legal ROM file. - I got a Ko-Fi page too.

Vanya

  • Hero Member
  • *****
  • Posts: 1796
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #693 on: September 29, 2020, 11:12:49 pm »
Sorry! I missed checking up on here the last couple of days 'cause Halloween prep. /|\^._.^/|\

All base stats should be resolved before messing with any derived stats, yes.

I actually really dislike the randomness of the stat growth system they used.
Definitely one of those things I will completely rewrite when I'm doing my own thing with the fruits of this project.

Jiggers

  • Sr. Member
  • ****
  • Posts: 417
    • View Profile
    • My Ko-Fi Page
Re: FF1 MMC5 Disassembly Updates
« Reply #694 on: September 30, 2020, 12:44:42 am »
How would you do it?

I feel pretty good about my re-write.

Code: [Select]
CancelLevelUp:
    JMP ReadjustEquipStats     ; return equipment

LevelUp:
    JSR UnadjustEquipStats     ; remove equipment so it doesn't interfere with stat boosts
   
    LDX char_index
    LDA ch_level, X
    CMP #50 - 1
    BEQ CancelLevelUp
   
    PHA                        ; back it up for just a bit

    INC ch_level, X            ; add 1 to level
    LDA ch_level, X
    CLC
    ADC #1                     ; add 1 more for printing it
    STA LevelUp_PrintLevel     ; save new level for printing
    LDA #0
    STA LevelUp_PrintLevel+1   ; high byte clear
   
    LDA ch_class, X            ; get the pointers for the class's level up data
    ASL A
    TAY
    LDA LevelUp_ClassDataPointers, Y
    STA tmp
    LDA LevelUp_ClassDataPointers+1, Y
    STA tmp+1
   
    PLA                        ; pull old level
    ASL A                      ; * 2 and put in Y
    TAY
    LDA (tmp), Y               
    STA LevelUp_StatData       ; data for stat boosts
    INY
    LDA (tmp), Y               
    STA LevelUp_MPData         ; data for MP boosts
   
    LDA ch_class, X            ; use class to get magic defense bonus 
    TAY
    LDA LevelUp_MagicDefenseBonus, Y
    CLC
    ADC ch_magicdefense, X
    JSR CapAAt200
    STA ch_magicdefense, X      ; add and save the bonus
   
    LDA LevelUp_HitRateBonus, Y ; do the same for hit rate
    CLC
    ADC ch_hitrate, X
    JSR CapAAt200
    STA ch_hitrate, X
   
    LDA LevelUp_MPCap, Y         ; get max amount of MP per level for this class
    STA LevelUp_MPCap

    ;; do MP stuff!
   
    LDY #8                       ; use Y as a loop counter
    LDA LevelUp_MPData
   @MP_Loop:
    LSR A                        ; shift out the low bit
    BCC @Next_MP_NoPull
        PHA                      ; backup shifted MP data
        LDA ch_mp, X
        AND #$0F                 ; remove high bits (current MP)
        CMP LevelUp_MPCap        ; see if this level of MP is capped already
        BEQ @Next_MP             ; if so, skip it
       
        LDA ch_mp, X             ; else, add 1 to the low bits (max MP) and save
        CLC
        ADC #01
        STA ch_mp, X

   @Next_MP:
    PLA
   @Next_MP_NoPull:
    INX                          ; move X to next MP byte                 
    DEY           
    BNE @MP_Loop
   
    ;; now do stat boosts!
    ;; LevelUp_StatData bits are:
    ;; 00011111
    ;;    ^^^^^
    ;;    |||||  Stat:     Loop Iteration:
    ;;    ||||-- Speed     (4) first
    ;;    |||--- Vitality  (3) second
    ;;    ||---- Intellect (2) third
    ;;    |----- Agility   (1) fourth
    ;;    ------ Strength  (0) fifth
   
    LDA #4
    STA tmp                       ; loop counter
   
   @StatUpdate_Loop:
    LSR LevelUp_StatData
    BCS @IncreaseStat             ; if set, increase the stat

   @RandomChance:                 ; else...
    JSR BattleRNG_L               ; get a random number
    AND #$03
    BEQ @IncreaseStat             ; if its 0, (25% chance), increase it
    LDA #0                        ; else, set the stat buffer byte for this stat to 0
    BEQ @NextStat
   
   @IncreaseStat:
    LDA char_index
    CLC
    ADC tmp                       ; add loop counter to char_index to get proper stat
    TAX
    INC ch_mainstats, X           ; increment the stat     
    LDA ch_mainstats, X
    CMP #100
    BNE @NextStat
      DEC ch_mainstats, X         ; oops, it was over 100, decrement it back to 99
      LDA ch_mainstats, X
   
   @NextStat:                     ; A = 0 from failing the random chance, or the new stat
    LDY tmp
    STA LevelUp_StatBuffer, Y     ; fill the buffer that tells the level up boxes what messages to display
   
    DEY
    STY tmp
    BPL @StatUpdate_Loop          ; end loop when counter rolls over to $FF
   
   ;; and finally, HP
   
    LDX char_index
    LDA ch_vitality, X
    LSR A
    LSR A
    CLC
    ADC #01                       ; base HP bonus is vitality / 4 + 1
    PHA                     
   
    LDA LevelUp_StatData
    AND #$01                      ; is the strong level up bit set? (it was shifted into the lowest bit)
    BEQ :+
        LDA #20                   ; if it is, get between 20-25 extra HP
        LDX #25
        JSR RandAX
  : STA tmp                       ; store the bonus here (0 if the level up bit was not set!)
    PLA                           ; pull base HP bonus
    CLC
    ADC tmp                       ; add strong bonus, if it exists
   
    LDX char_index                ; reset X to char_index
    ADC ch_maxhp, X               ; add level up HP bonus to max HP
    STA ch_maxhp, X
    STA LevelUp_PrintHP           ; and put the new max into this, for printing
    LDA ch_maxhp+1, X
    ADC #0
    STA ch_maxhp+1, X             ; save any carry-over
    STA LevelUp_PrintHP+1
    CMP #HP_MAX_HIGH              ; now compare to max possible values ($03)
    BCC @Finished                 ; if its $00, $01, $02, skip ahead
   
   @CheckLowHP:
    LDA #HP_MAX_HIGH              ; in case it was over 3, save it as 3
    STA ch_maxhp+1, X   
    STA LevelUp_PrintHP+1
   
    LDA ch_maxhp, X               ; compare low byte to max value ($E7)
    CMP #HP_MAX_LOW
    BCC @Finished                 ; if that is also under, skip ahead
        LDA #HP_MAX_LOW           ; otherwise, set HP to max value (high byte already = its own max value)
        STA ch_maxhp, X
        STA LevelUp_PrintHP       ; and update the printing byte as well   
   
   @Finished:   
    JMP ReadjustEquipStats        ; and re-do all the substats with the new base stats!

Everything makes sense to me now... assuming I didn't miss something.
« Last Edit: September 30, 2020, 12:58:36 am by Jiggers »
I know exactly what I'm doing. I just don't know what effect it's going to have.

I wrote some NES music! Its a legal ROM file. - I got a Ko-Fi page too.

abw

  • Hero Member
  • *****
  • Posts: 554
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #695 on: September 30, 2020, 09:29:32 pm »
For what it's worth, FF2 also increases HP (which is based on Vitality) before increasing Vitality. FF2 also increases MP (which is based on Magic Power) before increasing Magic Power.

Vanya

  • Hero Member
  • *****
  • Posts: 1796
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #696 on: October 01, 2020, 04:33:03 am »
It was programmed by the same guy in relatively close succession, so it makes sense that it would carry over.



@Jiggs:

What I would do differently with the level system is to totally remove the dependence on tables and not have "strong level ups" at all. Stats would instead be calculated as a constant growth value that is then multiplied by the character's level, and finally has a multiplier applied depending on the character's class/job. This is basically what FF5 does.

Jiggers

  • Sr. Member
  • ****
  • Posts: 417
    • View Profile
    • My Ko-Fi Page
Re: FF1 MMC5 Disassembly Updates
« Reply #697 on: October 01, 2020, 04:03:02 pm »
Interesting... that would maybe be difficult to do with 1 byte per stat, and stats capped at 99? Or I'm imagining the multipliers are adding a lot more... I need to look at some FF5 documents! You'd still need 1 table for the class multiplier though?

I couldn't sleep last night, so I tried to think of boring code. Instead, I thought I had a breakthrough for inventory compression. https://cdn.discordapp.com/attachments/445675875594141697/761155243064557578/Untitled-page.png Its like waking up to find alien writing all over your walls. But its not so different from how I changed the "Can this class equip this item?" routine.

The concept falls apart in a few places. Specifically, how to compare 1 bit across 4 bytes. Item ID #16 would be $01 (reading left to right) for the second byte, but match on the first.

...and since I had to go out for errands in the middle of writing this, I solved it in the car! Item ID right-shifted 3 times becomes Y.

Code: [Select]
DOES_ITEM_EXIST_1BIT:
    JSR Inv_Setup_1BIT
    AND tmp, Y
    RTS              ; Zero flag set if it does not exist

ADD_ITEM_1BIT:
    JSR Inv_Setup_1BIT
    ORA tmp, Y       ; add the bit!
    BNE :+   
   
REMOVE_ITEM_1BIT:
    JSR Inv_Setup_1BIT
    EOR tmp, Y              ; remove the bit while keeping the rest the same?
  : STA (OneBitPointer), Y  ; save and exit
    RTS

Inv_Setup_1BIT:
    PHA              ; backup item ID
    LDX #$10         ; clear $10 bytes of temp RAM
    LDA #0
   @Loop:
    STA tmp, X
    DEX
    BNE @Loop
    PLA              ; restore item ID
    TAX              ; put in X for loop counter
    LSR A            ; then shift right 3 times
    LSR A
    LSR A
    PHA              ; item ID now = which byte of tmp RAM to check against
   
    SEC              ; set C
   @ShiftLoop_X:
    LDY #0
   @ShiftLoop_Y:
    ROR tmp, Y       ; and shift C into the correct bit
    INY
    CPY #$10         ; when Y = $10, its done one shift of each byte of tmp RAM
    BNE @ShiftLoop_Y
    DEX             
    BNE @ShiftLoop_X
   
    PLA
    TAY
    LDA (OneBitPointer), Y ; get byte of compressed inventory   
    RTS     

Now the question is, what's the best way to set the pointer? Does it really need to be the (xxxx), Y format? If so, would a table of pointers to key items, skills, enemy sightings, etc., save more space? Then input to any of the 3 routines is just X = item ID, Y = inventory type?

And then, for a bestiary list, you'd need all $10 bytes of tmp RAM, so the shift loop would be bigger, I can't see any way around that... (Edit: using Y as both a counter and index worked!) $20 bytes if you have an inventory of single-count items that is #256 long! This must be what close to what FF2 does, with its treasure chests.
« Last Edit: October 03, 2020, 01:07:19 am by Jiggers »
I know exactly what I'm doing. I just don't know what effect it's going to have.

I wrote some NES music! Its a legal ROM file. - I got a Ko-Fi page too.

Vanya

  • Hero Member
  • *****
  • Posts: 1796
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #698 on: October 02, 2020, 07:39:09 pm »
Yeah, I figured there would still be one table for class multipliers.
But that beats the massive level up tables, no?

Inventory Compression? Your scribbles are neater than mine.
I love this sort of process when solving programming issues.
Nothing beats that "Aha" moment.

Jiggers

  • Sr. Member
  • ****
  • Posts: 417
    • View Profile
    • My Ko-Fi Page
Re: FF1 MMC5 Disassembly Updates
« Reply #699 on: October 06, 2020, 01:32:12 am »
Porridge is leaking out my ears.

I AGAIN redid a bunch of ch_stats stuff, because... I wanted to try adding in dual-wielding. Which led me to realize that storing weapon data in ch_stats was kinda not the best plan after all, and the original game's "dumb" way of doing things might be better? So now, all those extra substats are gone, calculated by equipment and stats at the start of battle instead, and put into buffers.

Which meant re-doing how defender and attacker stats are loaded in general... Which is verging on hard-coded RAM addresses not being messed with to keep working, which is the opposite of the system I had worked out before.  :'(

On the plus side... if it works--and I'm still not really sure if I can do that--then... yay, dual-wielding!

Also LOTS more ch_stats for things, so I've upped skills to 4, which should fill out a menu nicely. And I've added battle perks (what happens when you land a critical hit and win the luck contest), and perks. These are pretty much class-based. The critical hit perks are just like before, but instead of checking for Thief/Ninja, it just checks to see if that 1 bit is set that ups your critical hit chance.

Likewise, Perks are the same thing. Basically just class checks, reduced to 1 bit. This way, multiple classes can have similar perks. BlackBelt/Master no longer need be the only unarmed-using class.

The perks so far:
UNARMED - Has all the old BB/Master stat stuff going on, can use fist sprites when unequipped.
STEALTHY - Being hidden gives them a boost to things. Can steal from shops.
DUAL-WIELD - Can equip a second weapon in the left hand slot instead of a shield (hopefully!)

Still trying to work out how magic would affect a second weapon--it may just not. So anything that changes weapon's category, element, ailments, ailment proc chance, etc, will only do it to the main hand weapon.

Other perk ideas: Keep in mind, I only want to add 5 more of these.
NO FLOOR DAMAGE

... and that's all I got in the noodle.

Weapon and Armour masteries are also on the table. Get your class level up high enough and unlock being able to equip helmets on a mage! Or axes on a thief! So those are all 1 byte each as well, 1 bit per weapon type. I could add more? There's room for more weapon graphics (and magic graphics), so maybe 2 bytes for weapon masteries... though how I'd actually set weapon types for 1 bit is something to think about later. I'm keeping the permissions bytes, though. I like how flexible those are.
I know exactly what I'm doing. I just don't know what effect it's going to have.

I wrote some NES music! Its a legal ROM file. - I got a Ko-Fi page too.