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

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

Cyneprepou4uk

  • Sr. Member
  • ****
  • Posts: 469
  • I am the baldest romhacker
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #640 on: July 18, 2020, 12:07:09 am »
Right, my bad.
iromhacker.ru - NES ROM hacking tutorials for beginners. Please use Google Translate browser extension

Jiggers

  • Sr. Member
  • ****
  • Posts: 405
    • View Profile
    • My Ko-Fi Page
Re: FF1 MMC5 Disassembly Updates
« Reply #641 on: July 18, 2020, 02:24:25 am »
Huh... that's code I copied from somewhere else, too. Those comments don't look like my style, and I wrote the Soundtest stuff before I really understood how flags and branches worked. LOTS of trial and error.  :D And anything to do with controller input I still don't really get.

Almost got things stable again. Need to get the cursor loaded with the main menu, then I'll upload today's progress.
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: 1750
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #642 on: July 18, 2020, 05:10:07 am »
Would there be an issue with sprite loading if I'm loading at most 2x the number of character sprites?
If that's not an issue then, I already have some custom sprites in mind that I made for another project.

Getting ever closer to being able to do summon spells is bringing back ideas I had for Bahamut, Titan, and the Oxyale Fairy. New side quests anyone? :3

Oh, and here's something from AstralEsper's project that I'd like your consideration on since we're on the subject of graphics. More options for character graphics: female sprites.
I think it would just be a matter of expanding the number of available graphics in the character creation screen. Whatcha think? I can whip up new graphics pretty quickly if needed.

Jiggers

  • Sr. Member
  • ****
  • Posts: 405
    • View Profile
    • My Ko-Fi Page
Re: FF1 MMC5 Disassembly Updates
« Reply #643 on: July 18, 2020, 02:10:46 pm »
I was thinking about asking permission to use those. Or just grabbing sprites from FF2, FF3, and throwing out a "hey who wants to make sprites?!" ad in the Discord server. Plus I have some of my own (only one has a map sprite though). The party gen screen is already primed for using all 30 available sprites. I still need to update map sprites for the extra 14 possible sprites, and character stat SRAM so sprites and class aren't sharing half a byte together.

2x sprites? At a time? So you want 8 characters?

For menus/shops, you would either have to move all cursor related stuff so that it uses another part of VRAM, Orrrrr... I should re-write the sprite drawing code (and further tweak the loading code) so that each character only uses 1 line of tiles instead of 2. Menus and shops are tricky because they need to load 3 poses. New game/save screen is fine, because they only need 6 tiles per character, which leaves nearly 5 rows of tiles left over.

For battle, its basically already set up. Just need to double up the RAM that holds tile attributes and things, and I think that's easy enough. And add more positions to some small tables for the sprite loading routine.

What's your plan here? Right now there is room in SRAM for 8 characters. I was going to delete my magic compression routine and use the second $100 bytes for sortable magic inventory and job levels or whatever.
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: 1750
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #644 on: July 18, 2020, 07:55:51 pm »
Not 8 characters. 2 sets of tiles for each of the 4 characters so sprite layering techniques can be used for the illusion of more colors.
Like with Megaman and most of the Robot Masters.
So my plan is just implementing a technique for enhanced character graphics.

Here's what I mean...



Made this a while back when I was messing around with RPG Maker MV.
Sorry for the small resolution.

I'm particularly proud of the Warrior of Light sprite.
Never did figure out what I wanted to fill the final slot with.

There is also the issue of positioning of the overlaid sprites for efficient use of sprite tiles.
So instead of just overlapping an entire second sprite with just one different palette, there would be multiple smaller sprites in relative positions to the base sprite each with their own palette.

For the simplest example of this above, the White Mage would need a sprite for her hair that uses the Thief palette and another for the robe shading that uses the cursor palette.

Alternatively, for the sake of simplicity, it could be left as just a second whole sprite with one of the other two palettes assigned to it. It would limit the possibilities somewhat, but it would still make for better looking character graphics.
« Last Edit: July 18, 2020, 08:36:46 pm by Vanya »

Jiggers

  • Sr. Member
  • ****
  • Posts: 405
    • View Profile
    • My Ko-Fi Page
Re: FF1 MMC5 Disassembly Updates
« Reply #645 on: July 18, 2020, 10:34:26 pm »
Awwwwww HECK that's COOL.

In my opinion, layering them flat on top would be fine. The nonsense that is battle sprite movement isn't something I'd want to inflict on anyone. The only reason I would dip into it again is to make flipping the characters around easier. So adding precise character-specific offsets to that... well... I guess you'd use a table or something, for the first write, then use the normal battle movement stuff for everything after that...?

I'd advise against using the cursor palette... since in battle its the variable palette, and will change constantly. If every weapon was grey, then it might be a cool effect to have characters glowing when magic flashes. But someone swinging a green staff shouldn't make your hair shadow green. XD

But man that's so cool!! What a great idea!
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: 1750
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #646 on: July 19, 2020, 11:05:39 am »
Thanks! No worries about the palettes in the example, I based these on FF3 and it's palettes are organized differently. I would redraw these to some extent for our project. Especially since I don't expect to use the advanced classes in the base game.

Anyway, yeah, just doing a flat layering is good enough and provides a good restriction to encourage more creative solutions to the artwork.

One more idea concerning this, though.
Can each individual 8x8 tile in the overlay sprites be given their own palette fairly easily?
Presumably with a table of some sort?
It would provide some considerable flexibility without messing around with unique sprite positions.

Let me put together a quick example...



Ninja with gold-trimmed, green helmet and blue dougi pants and tabi.

Jiggers

  • Sr. Member
  • ****
  • Posts: 405
    • View Profile
    • My Ko-Fi Page
Re: FF1 MMC5 Disassembly Updates
« Reply #647 on: July 20, 2020, 02:53:29 pm »
I'll have to get back to you on that... My sleepytime math was thinking 6x60 bytes would be needed (because why stop at only the overlay sprites getting their own palette when every part of all 30 battle sprites could be given their own palette), and then I just remembered there's different poses, so poses per character per tile, doubled for the overlay... :huh:

The Sprite loading bank is almost full up as it is (#300 left). If I absolutely need more space for more palette and code, I could take out the extra cursor loading and graphics... But that only gives #83 bytes back.

Right now all the sprite palette allocating is done in Bank C, and I wanted to see if I could move that to the sprite loading bank. So if depends if I can come up with a good way to do that, or if there's space in Bank C after shuffling more code around...

Right now every sprite has 1 byte in a table, and that's applied to all sprite tiles for that character. So we're absolutely going to take something dead simple and complicate the HECK out of it. XD I just don't know how yet, or where.
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: 1750
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #648 on: July 20, 2020, 03:54:28 pm »
Just having an overlay with it's own single palette is good enough.
Giving the overlay sprite tiles their own independent palettes would be great!
Giving them all independent palettes is a bit crazy, but crazy is fun so...
If you think you'll enjoy doing it, then go for it.

Jiggers

  • Sr. Member
  • ****
  • Posts: 405
    • View Profile
    • My Ko-Fi Page
Re: FF1 MMC5 Disassembly Updates
« Reply #649 on: July 22, 2020, 07:06:49 pm »
Event going on in a game has my attention right now, but I took time out to try something stupid, which resulted in me learning something useful!

In Mesen's debugger, right below the scanline counter, is VRam Address. When scroll is 0x 0y (not sure if starting scroll is important here at all; but that's kind of what this whole thing is about!), Vram address is 0000 at scanline -1.

So I stepped through and looked at the values.

Code: [Select]
0000 - scanline -1
1000 - scanline 0
2000 - scanline 1
3000 - scanline 2
4000 - scanline 3
5000 - scanline 4
6000 - scanline 5
7000 - scanline 6
0020 - scanline 7

Scanline 20: 5040
Scanline 30: 7060

36: 5080
37: 6080
38: 7080
39: 00A0 - where backdrop ends
40: 10A0

159: 0280 - where battle text begins

I had been asking, way back when I got help with the palette drawing in Hblank on the NesDev discord, if anyone had made a chart for calculating how to set the scroll for a given scanline... While they tried to explain the process behind it, it flew over my head. Looking at it in action, I get it now! Sort of! And while I still have no idea if someone made a chart for it... but...! Shouldn't be too hard to?

Every 8 scanlines, $20 is added to the low byte. This overflows into the low nybble of the high byte.
Every 1 scanline, $10 is added to the high byte. This just wraps around.

That's the simple Jigs way to explain it, anyway. Probably wrong to explain it like that, but now I get it and I can set the scroll after tweaking palettes midframe ANYWHERE I WANT. ... as long as the scroll is 0. Menu screens, battle. Which is good enough!



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.

Cyneprepou4uk

  • Sr. Member
  • ****
  • Posts: 469
  • I am the baldest romhacker
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #650 on: July 22, 2020, 07:28:25 pm »
Scroll value has nothing to do with changing palettes in the middle of the frame  :)

https://wiki.nesdev.com/w/index.php/Palette_change_mid_frame
iromhacker.ru - NES ROM hacking tutorials for beginners. Please use Google Translate browser extension

Jiggers

  • Sr. Member
  • ****
  • Posts: 405
    • View Profile
    • My Ko-Fi Page
Re: FF1 MMC5 Disassembly Updates
« Reply #651 on: July 22, 2020, 09:14:35 pm »
Step 4, restore PPU Address. That's what I mean! I figure out how to know the PPU address in a static screen.

But I also just learned that we can't change the backdrop palette to be a 3rd palette for enemies, for the same reason I removed the round timer box in the upper right corner. The sprite loading routines I wrote months ago can sometimes take up like 60% of screen rendering time. (Hm... or was it the box text stuff? Either way...)

I'm not going to throw away my work, though. This could be useful for someone else's hack that doesn't muck around with character sprites and palettes as much.

Code: [Select]
WaitForVBlank:
    LDA $2002      ; check VBlank flag
    BPL @Wait      ; if off, VBlank hasn't occured yet, so jump to the wait
                   ;  otherwise... whatever code occured since the last frame took longer than
                   ;  1 frame... so...

    LDA #0         ; waste time in this loop for a while...
  @Loop:
      SEC          ; the reason for this is because the game doesn't want NMI to fire during VBlank
      SBC #$01     ;  because then you'd have less than a full VBlank for drawing next frame
      BNE @Loop    ;  Of course... just reading $2002 above will prevent this from happening, so this isn't
                   ;  really necessary, but it doesn't hurt.

  @Wait:
    LDA soft2000   ; Load desired PPU state
    ORA #$80       ; flip on the Enable NMI bit
    STA $2000      ; and write it to PPU status reg
   
    LDA InBattle
    BEQ OnIRQ

    LDA #$00 ; scroll high
    STA tmp+1
    LDA #$A0 ; scroll low
    STA tmp+2
    LDA #$01 ; palette address
    STA tmp
    LDY #$28 ; color
    LDA #39  ; scanline
    JSR Do_Scanline_Palette
   
    LDA #$30 ; scroll high
    STA tmp+1
    LDA #$02 ; palette address
    STA tmp
    LDY #$1A ; color   
    LDA #40-39
    JSR Do_Scanline_Palette
   
    LDA #$50 ; scroll high
    STA tmp+1
    LDA #$03 ; palette address
    STA tmp
    LDY #$31 ; color   
    LDA #41-40
    JSR Do_Scanline_Palette
   
    LDA #$02 ; scroll high
    STA tmp+1
    LDA #$80 ; scroll low
    STA tmp+2
    LDA #$0E ; palette address
    STA tmp

    LDX BattleBGColor
    LDY BattleBackgroundColor_LUT, X

    LDA #159-45   ; scanline for battle text
    JSR Do_Scanline_Palette

    LDA soft2000
    ORA #$90       ; make background tiles use the sprites!
    STA $2000
   
    LDA #$00       
    STA $5203      ; Clear trigger

OnIRQ:             ; IRQs point here, but the game doesn't use IRQs, so it's moot   
@LoopForever:
    LDA $5204      ; JIGS - high bit set when scanline #160 is being drawn
    BPL @LoopForever

Do_Scanline_Palette:   
    STA $5203

   @Loop:
    LDA $5204
    BPL @Loop

    LDX #$0D   ; waits for H-blank so as not to draw weird dots on the screen
  : DEX        ; $0D seems the best so far!
    BNE :-   
    LDA $2002  ; reset toggle
    LDA #$3F   ; set PPU addr to point to palette
    STA $2006   
    STX $2001  ; X = 0, turn off screen
    LDA tmp    ; get palette address low
    STA $2006
    STY $2007  ; save color
    LDY tmp+1  ; get scroll high
    LDA tmp+2  ; get scroll low
    STY $2006
    STA $2006 
    LDA btl_soft2001
    STA $2001  ; turn on screen
    RTS

I was going to try to tighten it up more, but as its not going to work, I didn't bother.



Going over this more... yeah, its my box routines that take up so much PPU rendering time. Maybe the sprites too, I haven't checked. Thinking about boxes still.

Testing with the largest box--Magic--it takes around 7000 cycles to backup the background tiles (box area without the magic box drawn) to RAM. That's about 62 scanlines. The problem is with drawing the new box tiles, and it uses up 17225 cycles. That's 152 scanlines. Between the backdrop and the text boxes, there's 120 scanlines, and it would be best to squeeze a few of those out for safety, so say... 110 scanlines, or 12496 cycles.

There's not a lot more I can do to speed up the code. Cut out all the branching, backup all the destination and source addresses twice, let things flow and take up twice or three times as much space in ROM, maybe. Just from not doing the RAM page swap every tile would save uh... 12 cycles? Minus 7 for the PLA/PHA instructions to replace it... 9*32*5 = 1440 cycles? Not enough. Haven't done the math on not doing the branches every byte, but... (Branch not taken is 2 bytes, taken is +1, assume no page boundary crossing... 7 cycles... another 2016.) That still doesn't reach the target.

Or, every row of tiles processed is capped off by a call to WaitForVBlank. Which would be a total of 9 frames to process each way, or a pause of 18 frames. Could the be acceptable?

Or, take the box height, divide it by 2, and use that as a secondary countdown timer of sorts, so that when HALF the box is done, it will do a frame. Its not perfect since the boxes are all odd numbered rows, but it does cut 17225 down beneath 12496. No box half should take more than 10000.

Either way, the box tile swapping has to be done during rendering, and here I would use the high bit of the InBattle variable to indicate "hey, boxes need to be drawn while we're waiting for scanline #159!"

The tricky part would then be to find places where battle logic spills out past scanline #39 and work out ways to keep it from doing that.

Then re-do the palette drawing to be real tight--maybe keep the screen off while writing all 3 palettes, as there's 7 lines or so where neither enemies or stoned player graphics are drawn. The characters will need to be shifted down a tile so that the top one's weapon swinging sprite is not in that boundary either.
« Last Edit: July 23, 2020, 02:00:03 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: 1750
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #652 on: July 23, 2020, 02:17:22 pm »
I've never been very good at optimization.
Especially with ASM.
All I can say is that I often find solutions by shifting my point of view and thinking about things from different angles.

Jiggers

  • Sr. Member
  • ****
  • Posts: 405
    • View Profile
    • My Ko-Fi Page
Re: FF1 MMC5 Disassembly Updates
« Reply #653 on: July 26, 2020, 07:10:56 pm »
Nothing too exciting finished up yet. I seperated class and sprite, fixed up the save screen code a lot, and set up a few variables for palette fading. So now fading in the inn takes 8 frames per cycle, but battle fade in is 5, and any other fades can be set up with their own timer. Framecounter increases every time MusicPlay is called, instead of at random points, and doesn't use the high byte since I don't think it ever did? Fixed the minimap not loading again.

Also did some work on class skills-just displaying in battle, for now. Set up a list in Bank A for skill names, and set up a way to print them to boxes. Think I'm going to use some freed up ch_stats to make 2 separate skill IDs for each character. Then make a skill box like I had going on before.

Some ideas:
* Skills are items you collect throughout the game. Talk to NPCs to learn some! Find them in chests! Buy them from shops! Unlock them while leveling?
* Remove Damage/Accuracy/Critical Defense/Evasion/M.Evade from equip screen. Replace with 2 skill slots. This info can be seen when choosing items to equip, so its not lost.
* Job Stone equip slot like FF14 as well.
* Skills tied to class levels, like FF5?

Code: [Select]
ch_stats          = unsram + $0100
ch_class          = ch_stats + $00
ch_sprite         = ch_stats + $01
ch_skill1         = ch_stats + $02
ch_skill2         = ch_stats + $03
ch_jobexp         = ch_stats + $04
ch_joblevel       = ch_stats + $05
;                 = ch_stats + $06
;                 = ch_stats + $07
ch_damagebackup   = ch_stats + $08
ch_defensebackup  = ch_stats + $09
ch_basehp         = ch_stats + $0A ; 0B - 2 bytes
ch_curhp          = ch_stats + $0C ; 0D - 2 bytes
ch_maxhp          = ch_stats + $0E ; 0F - 2 bytes

The way I picture it now, Job Exp is another enemy stat gained at the end of battle. It fills up pretty easily, and when it wraps past $FF, you gain a job level. Job level is saved when switching; job exp is not. Because there's just not enough room unless there's only 20 jobs.

For more than the current number of jobs to be feasible, I do need to get cracking on compressing equipment and magic inventory though. And decompressing magic learned, because that's totally screwed right now.



And I think I figured out a way to compress weapons, armor, and magic into 32 bytes each. That would allow for... $60 more bytes of inventory data for skills, jobs, other magic types? Jobs and skills would only need to be 1 bit each, unless someone wants to physically give their character a job stone that no one else can hold while they have it. But with this system, 15 max for each item.

I am NOT going to program in other magic types until everything else is fully completed. This is just to make space for other people to do crazy stuff like that. Ideally I'd be able to make all these systems work for expansion without more code editing.

Code: [Select]
ADD_WEAPON:
   LDA weapon_id       ; get the ID of the weapon to check
   LSR A               ; halve the weapon ID
   TAX                 ; put it in X for indexing

   ASL A               ; then restore the weapon ID
   AND #$01            ; see if its even or odd by cutting out all but the lowest bit
   BNE @High           ; if its set, its an odd numbered weapon ID

  @Low:
   LDA inv_weapon, X   ; load the compressed weapon byte
   AND #$0F            ; cut high bits, keep low bits
   CMP #$0F            ; compare to max amount
   BCS @Full           ; if the compare sets carry, jump to the RTS
   
   LDA inv_weapon, X   ; reload the compressed weapon byte
   ADC #$01            ; and add 1 to the low nybble
   BNE @AddItem        ; jump ahead to save a few bytes
 
  @High:
   LDA inv_weapon, X
   AND #$F0
   CMP #$F0
   BCS @Full
   
   LDA inv_weapon, X
   ADC #$10
   
  @AddWeapon:
   STA inv_weapon, X
  @Full:              ; carry set when unable to add more
   RTS                ; carry clear when successful
 
 
REMOVE_WEAPON:
   LDA weapon_id       ; get the ID of the weapon to check
   LSR A               ; halve the weapon ID
   TAX                 ; put it in X for indexing

   ASL A               ; then restore the weapon ID
   AND #$01            ; see if its even or odd by cutting out all but the lowest bit
   BNE @High           ; if its set, its an odd numbered weapon ID

  @Low:
   LDA inv_weapon, X   ; load the compressed weapon byte
   AND #$0F            ; cut high bits, keep low bits
   BEQ @Empty          ; if its 0, there is nothing to subtract

   DEC inv_weapon, X   ; just decrement it
   CLC                 ; clear carry to indicate success
   RTS
 
  @Empty:              ; manually set carry to indicate failure
   SEC
   RTS
 
  @High:
   LDA inv_weapon, X   ; load the compressed weapon byte
   AND #$F0            ; cut low bits, keep high bits
   BEQ @Empty          ; if its 0, there is nothing to subtract

   LDA inv_weapon, X   ; reload it
   SEC
   SBC #$10            ; set carry and subtract #$10
   STA inv_weapon, X   ; save it
   CLC                 ; clear carry to indicate success
   RTS
 
 
 
DOES_WEAPON_EXIST:
   LDA weapon_id       ; get the ID of the weapon to check
   LSR A               ; halve the weapon ID
   TAX                 ; put it in X for indexing

   ASL A               ; then restore the weapon ID
   AND #$01            ; see if its even or odd by cutting out all but the lowest bit
   BNE @High           ; if its set, its an odd numbered weapon ID

  @Low:
   LDA inv_weapon, X   ; load the compressed weapon byte
   AND #$0F            ; cut high bits, keep low bits
   BEQ @Empty          ; if its 0, there is noweapon
   CLC                 ; clear carry to indicate success
   RTS
 
  @Empty:              ; manually set carry to indicate failure
   SEC
   RTS
 
  @High:
   LDA inv_weapon, X   ; load the compressed weapon byte
   AND #$F0            ; cut low bits, keep high bits
   BEQ @Empty          ; if its 0, there is no weapon
   CLC                 ; clear carry to indicate success
   RTS

UPDATE:
 And this version should work with any low/high compressed inventory, so long as tmp and tmp+1 are set to point to the right place in (unsaved) SRAM.

Code: [Select]
ADD_ITEM:
   LDA item_id         ; get the ID of the equipment/spell to check
   LSR A               ; halve the ID
   TAY                 ; put it in Y for indexing

   ASL A               ; then restore the ID
   AND #$01            ; see if its even or odd by cutting out all but the lowest bit
   BNE @High           ; if its set, its an odd numbered ID

  @Low:
   LDA #$01            ; amount to add when low
   LDX #$0F            ; bits to cut/keep, plus max amount when low
   BNE @Check

  @High:
   LDA #$10
   LDX #$F0

  @Check:
   STX tmp+2           ; tmp+2 are the bits to cut/keep with AND
   STA tmp+3           ; tmp+3 is amount to subtract
 
   LDA (tmp), Y        ; tmp, tmp+1 points to weapon, armor, or spells
   AND tmp+2           ; cut/keep the appropriate bits
   CMP tmp+2           ; compare to max amount
   BCS @Full           ; if the compare sets carry, jump to the RTS

   LDA (tmp), Y        ; load the compressed equipment/spell
   ADC tmp+3           ; add the amount to high or low nybble
   STA (tmp), Y        ; then save
  @Full:               ; carry set when unable to add more
   RTS                 ; carry clear when successful
 
 
REMOVE_ITEM:
   LDA item_id         ; get the ID of the equipment/spell to check
   LSR A               ; halve the ID
   TAY                 ; put it in Y for indexing

   ASL A               ; then restore the ID
   AND #$01            ; see if its even or odd by cutting out all but the lowest bit
   BNE @High           ; if its set, its an odd numbered ID

  @Low:
   LDA #$01
   LDX #$0F
   BNE @Check

  @High:
   LDA #$10
   LDX #$F0
   
  @Check:
   STX tmp+2           ; tmp+2 are the bits to cut/keep with AND
   STA tmp+3           ; tmp+3 is amount to subtract

   LDA (tmp), Y        ; tmp, tmp+1 points to weapon, armor, or spells
   AND tmp+2           ; cut/keep the appropriate bits
   BEQ @Empty          ; if its 0, there is nothing to subtract

   LDA (tmp), Y        ; load the compressed equipment/spell
   SEC
   SBC tmp+3           ; subtract the amount from high or low nybble
   STA (tmp), Y        ; then save
   CLC                 ; clear carry to indicate success
   RTS
 
  @Empty:              ; manually set carry to indicate failure
   SEC
   RTS
 
 
 
DOES_ITEM_EXIST:
   LDA item_id         ; get the ID of the equipment/spell to check
   LSR A               ; halve the ID
   TAY                 ; put it in Y for indexing

   ASL A               ; then restore the ID
   AND #$01            ; see if its even or odd by cutting out all but the lowest bit
   BNE @High           ; if its set, its an odd numbered ID

  @Low:
   LDA #$0F           
   BNE @Compare
   
  @High:
   LDA #$F0
 
  @Compare:
   STA tmp+2           ; put the bits to cut or keep into tmp+2
   LDA (tmp), Y        ; tmp, tmp+1 points to weapon, armor, or spells
   AND tmp+2           
   BEQ @Empty          ; if its 0, there is nothing there
   CLC                 ; clear carry to indicate success
   RTS
 
  @Empty:              ; manually set carry to indicate failure
   SEC
   RTS 
« Last Edit: July 26, 2020, 11:24:07 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: 1750
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #654 on: July 28, 2020, 01:09:00 am »
Fantastic! Laying the ground work for other people to do more in their projects is a great thing. In the long run it'll benefit the community more than just putting out a project that suits us.

Integrating Jobs and Skills into the inventory system is brilliant.
I'm not too keen on losing any info from the equipment screen to make room for skill slots.
Would it be possible to have a separate screen for Job stuff?
That would open thing up for some static stat bonuses from your currently equipped job with plenty of space to display stat changes.

I'm not familiar with Job stones. Actually, I'm pretty unfamiliar with FF14 Online 2 as a whole.
Basically all I know is that the first iteration was such a colossal flop that SE apologized and rebuilt it from the ground up. That and I refuse to refer to it as a mainline FF game.

At any rate. With the ability to add new magic types set up, I can definitely say I will put it to use for my own purposes later on. My ideal set of jobs includes a Time Mage and a Green Mage so giving them their own spell group would be great.

Jiggers

  • Sr. Member
  • ****
  • Posts: 405
    • View Profile
    • My Ko-Fi Page
Re: FF1 MMC5 Disassembly Updates
« Reply #655 on: July 29, 2020, 03:30:57 am »
So when I said "I am NOT going to program in other magic types until everything else is fully completed." what I meant was "Hell no I'm not going to completely re-arrange all the data tables and item lists and re-figure out how treasure chests work and how item names are drawn!" Which is really what 90% of the work is.

And then I did that anyway because I forgot that's not what I wanted to do.

I'm still in the middle of the process. I've moved a lot of things around. Prices are broken, treasure chests are broken. Magic now has its own item table. There are now 128 spells, 16 battle-only spells, and enemy attacks are lumped in after that. Skills are now items. Gold in chests has been moved to its own table, so the item table is really only items, key items, skills, class names. I need to see how Common Strings are drawn, I may move those into the item table too. Bank A is starting to run low! And it needs to have room for 64 more magic description texts.  :P

I also want to see if I can combine all the drawing routines into one. There's dialogue, battle, and everything else. Battle draws to RAM, then dispalys. Dialogue does pretty much the same thing I think? And everything else draws straight to the screen. Even if it means adding another step, I feel like there's a thousand bytes to save in code if it all was drawn to RAM and then put on the screen as its needed. That's one of those things that I absolutely must not delve into until the rest is working because its a huge undertaking!

NOW FOR THE BIG NEWS.

gauauu on the NesDev Discord server has written us a Python script for converting .bin maps into Tiled format! He's also going to do the Tiled-to-Bin script later. So over the next few weeks I will try to re-align all the maps, their coordinates, and get that minimap side project finished up! As well as making necessary changes to the maps themselves to stop NPCs from wandering into the exits.

Integrating Jobs and Skills into the inventory system is brilliant.
I'm not too keen on losing any info from the equipment screen to make room for skill slots.
Would it be possible to have a separate screen for Job stuff?
That would open thing up for some static stat bonuses from your currently equipped job with plenty of space to display stat changes.

I was sub-consciously thinking about it, and I think this is why I came up with those ideas off the top of my head:
* I really like how the menu screen is organized currently. With the fancy graphics around the orbs, the game timer.
* I don't want the screens to be a mess of numbers and stats the way FF3 is.
* I thought Equip would be a good place to choose your skills, because then you can see your equipment and how it all works together. If you give someone some kind of Chakra healing skill, then forget they have the Heal helm... I like seeing all that strategic information in one place, you know?

How would you organize a Job screen? "Status" could be "Class"? Then expand that into two screens?

FF14... I heard the horror stories, but it was 2.0 that I started with. It was my first MMO, so I have a soft spot for it... and looking back, I kind of hate some things about the story I experienced. The main cast are unplayable characters until the last two expansions, where you get random battle moments and get to control them. They have like 2-4 skills each so its silly, but people not familiar with their class need to be able to get through the story. Wait--I'm not going to write a review here.

For as much as I kind of hated all your so-called friends in the game (sure they have their moments, but for the most part they kind of get on my nerves with some of their stupid ideas... lookin' at you Alphinaud) the last expansion really worked for me. It was where it all came together and gave me those feelings that FF6 and FF9 did. Where even if you didn't like someone, you wanted to see their story play out. And I did cry. I didn't want to but I did. So I absolutely believe it deserves being talked about with mainline FF game titles. Honestly, my biggest complaint about it is that it basically IS a single-player game and I have a hard time getting friends to play it when they have to sit through hours and hours of single-player story stuff just to get to where we can do dungeons and raids together. *raspberries*

Anyway, job stones are basically just an equipment slot. So you start out as a Conjurer, then at level 30 you get a White Mage job stone, and if you take it out you get de-classed back to Conjurer (and everyone hates you in dungeons don't do it.) You can unlock every job in the game on the same character and swap them by either equipping the job stone or equipping the weapon for that job. You can't actually use the job stone without a weapon for it.

Basically, treating jobs as items allows us to use the inventory systems (shops, treasure chests, NPC dialogue routines) to unlock them. My favourite part of FF5 is finding those extra jobs! So this could be fun.
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: 1750
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #656 on: July 29, 2020, 02:46:47 pm »
Sounds to me like they treated jobs the same as they always have, they just called the interface by an item type naming convention.

So Final Fantasy 14 is basically a single player game with multiplayer tacked on?
That softens my opinion on it, but I still wouldn't have used the number in the title.

Let's go off the rails a bit...
(Spoiler tag used since this is definitely off topic.)
Spoiler:
This is how I see the Final fantasy series:
Final Fantasy
Final Fantasy II
Final Fantasy III
Final Fantasy IV
Final Fantasy V
Final Fantasy VI
Final Fantasy VII
-Crisis Core: Final Fantasy VII
-Dirge of Cerberus: Final Fantasy VII
Final Fantasy VIII
Final Fantasy XI
Final Fantasy X
Final Fantasy X-2
Final Fantasy: The 4 Heroes of Light -> Final Fantasy XI: Four Warriors of Light
Bravely Default: Flying Fairy -> Final Fantasy XII: Bravely Default
Bravely Second: End Layer -> Final Fantasy XII-2: End Layer
Bravely Default II -> Final Fantasy XIII

Final Fantasy XI -> Final Fantasy Online
Final Fantasy XIV -> Dumpster Fire or Final Fantasy Online 2
Final Fantasy XIV: A realm Reborn -> Final Fantasy Online II: A Realm Reborn

Final Fantasy Tactics
Vagrant Story -> Final Fantasy Tactics: The Vagrant Story
Final Fantasy XII -> Final Fantasy Tactics: The Zodiac Age
Final Fantasy Advance
Final Fantasy A2

Final Fantasy XIII -> Corridor the Game or Fabula Nova Crystallis
Final Fantasy XIII-2 -> Fabula Nova Crystallis II
Lightning Returns: Final Fantasy XIII -> Lightning Returns: Fabula Nova Crystallis III
Final Fantasy Type-0 (a.k.a. Final Fantasy Agito XIII) -> Fabula Nova Crystallis: Type-0
Final Fantasy XV -> Outdated Fashion Boys and Corporate Greed or Fabula Nova Crystallis IV

That is how I see the series. It's a bit traditionalist, but I'm harsh about things I percieve as "milking the name".

Anyway. I'll have to think about how I would put together a Job screen.
I'll post back tomorrow with a mock-up.

Woot! That's awesome news!
As always, I can do some of the grunt work if you want.

Jiggers

  • Sr. Member
  • ****
  • Posts: 405
    • View Profile
    • My Ko-Fi Page
Re: FF1 MMC5 Disassembly Updates
« Reply #657 on: July 29, 2020, 10:51:28 pm »
FF14 also wallows in Nostalgia. It has the best remix of Matoya's theme ever, as well as a whole raid story about the FF Tactics/FF12 world. Its such a weird mish-mash, but it works. I desperately want an FF1 remake in the game's graphic engine...

"Sounds to me like they treated jobs the same as they always have, they just called the interface by an item type naming convention." Yeah, pretty much, but that gave me the idea to actually use the inventory systems I've coded in for job stuff too. XD

And holy mongoose... I did write an inventory system, didn't I? I've been doing this project so long I kind of forgot that FF1 had pretty much nothing...



Old, vanilla Castle Coneria. Yes, it really was shifted 2 tiles off the other side of the map.



I tracked down what was going on with those tiles. All the grass is teleport tiles, and they were flagged to create a sprite, causing a massive overflow of sprites. So I changed their bytes to be background, hurray everything is neat again!

So what I'm doing is opening each map in Tiled, doing some math to figure out how best to center it, doing Map Offset, clicking Wrap, then remembering the new X and Y offsets, then putting that as + to the original bytes.

Code: [Select]
; 08 ; Coneria Castle 1F
.byte $20,$4E+18,$1C+11 ; Guard near lower pillar
.byte $20,$4A+18,$12+11 ; Guard near stairs
.byte $22,$02+18,$0A+11
.byte $23,$08+18,$0B+11
.byte $25,$47+18,$1C+11
.byte $26,$47+18,$0F+11 ; Invisible lady
.byte $29,$C6+18,$18+11
.byte $2A,$91+18,$17+11
.byte $2C,$56+18,$09+11
.byte $2E,$4E+18,$0F+11
.byte $00,$00+18,$00+11
.byte $00,$00+18,$00+11
.byte $00,$00+18,$00+11
.byte $00,$00+18,$00+11
.byte $00,$00+18,$00+11
.byte $00,$00+18,$00+11
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: 1750
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #658 on: July 30, 2020, 01:51:55 pm »
Nice!! That looks so much better!

Gave a bit of a vibe, on first glance, of game that lead to Final Fantasy:

Jiggers

  • Sr. Member
  • ****
  • Posts: 405
    • View Profile
    • My Ko-Fi Page
Re: FF1 MMC5 Disassembly Updates
« Reply #659 on: July 31, 2020, 04:20:49 am »
Black sky backgrounds in games disturb me for some reason... what game is that?

I think I'm about halfway done the map centering. Onrac is corrupted though. No idea how or when. I'll have to re-extract it from a vanilla build and add the ocean edits in again.

And because of inventory compression, there's still room for a few things... While I'm in the guts of making sure menus load all this information, what can we think of?

So far its:
$40 bytes of items, key items, coordinates, gold, game time, etc.
$40 bytes of weapons and armor (64 each, up to 15 quantity)
$40 bytes of magic (128 spells)
$4 bytes of classes (32 classes, 1 bit each)
$4 bytes of skills
Leaving $38 bytes...

My thought was, Blue Magic. There are currently 48 enemy skill slots, 26 used by vanilla FF1. This could be increased to 64 if needed. And because Blue Magic isn't bought, and can't be sold, it doesn't need to be counted, so it can be compressed into bits. 64 enemy spells only need 8 bytes.

What then, use the other $30 bytes for more skill unlocks? Cyan's 8 sword techs? 1 byte. Edgar's 8 tools? 1 byte. Sabin's 8 blitzes? Yep! 6 bytes! wait...

Not to mention game flags aren't all used up either!

So there's 2 bits for NPC sprites being visible (ie, existing at all), 2 bits for treasure chests (500+ treasure chests in the game), 1 event flag which is used what, 20 times?

So there's 256*3 more bits of information. Want a bestiary that unlocks as you run into enemies? Easy, and as there's only 128 enemies, still hasn't even used up everything.

FF2 password system? I ain't coding the extra mini dialogue box, but sure? More likely to run out of room in Bank A to hold names for things than we are to run out of things to cram into SRAM...

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.