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

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

Vanya

  • Hero Member
  • *****
  • Posts: 1487
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #100 on: March 08, 2019, 05:43:41 am »
No worries! After all this is just a hobby at the end of the day.

I'll have a look at that new update as soon as I get a chance.
I've been pretty busy, too actually. (Still want to try doing some mock ups to illustrate my ideas.)

EDIT:
Fuck it! I did it live!

Magic Changing Frost Giant Garland Bug: Fixed. Tested on the CREEPS too and they didn't change either.

Premature Inventory Scrolling in Shops: Fixed. Tested with 1, 2, 3, 4, 5, and 6 items in the inventory to make sextuple-sure it worked right.

However...

The XP/Gil rewards are still coming in from every enemy, not just IMPs, way too high. Has nothing to do with the magic change bug as far as I can tell.

I noticed another bug in the shops. The EXIT command is borked. It just opens the sell menu instead of leaving the shop.
« Last Edit: March 08, 2019, 06:13:09 am by Vanya »

Disch

  • Hero Member
  • *****
  • Posts: 2716
  • NES Junkie
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #101 on: March 08, 2019, 11:12:50 am »
Is there a git page for this?  If not, it might be worth considering setting one up.

KingMike

  • Forum Moderator
  • Hero Member
  • *****
  • Posts: 6885
  • *sigh* A changed avatar. Big deal.
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #102 on: March 08, 2019, 01:27:03 pm »
Whew, that's a lot... I'll just touch on a few things for now:

You can delete in the save/load screen! Press Start + Select at the same time (holding down one and then the other doesn't work, haven't figured that out yet. Gotta press both at once.)

NES games usually program it to store both HELD and PUSHED states of the controller buttons, somewhere in RAM.
(HELD being the exact state of the controller data, PUSHED being the state after some filtering to remove buttons held on continuous frames, or whatever the polling interval is)
I suppose you could experiment with those.

It would be very easy to find the RAM, just do a breakpoint for $4016 and look where its shifting the data to.

Maybe mess with combinations like Start+Select "HELD" (I suppose consequential repeated erasing of SRAM wouldn't hurt).
Or check if Select PUSHED + Start HELD and the reverse.
Or maybe two flags, one for each button, set when pushed, and erase when both are set.

There's probably a simpler way I'm missing.
"My watch says 30 chickens" Google, 2018

Jiggers

  • Full Member
  • ***
  • Posts: 238
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #103 on: March 08, 2019, 11:09:05 pm »
Maybe mess with combinations like Start+Select "HELD" (I suppose consequential repeated erasing of SRAM wouldn't hurt).

I figured it out! It does have variables for different button states, but whatever I was trying last time to read them wasn't working, but it does now. When Start + Select are held, the "joy" variable is #$30, and I was able to have it branch off a CMP. I don't remember why I was having trouble before when I tried almost the same thing...

Is there a git page for this?  If not, it might be worth considering setting one up.

I've been afraid to spend a day figuring out how github works... But yeah, that's really something I should sort out real soon. Edit: Someone helped me out with it!

https://github.com/JiggeryPonkery/FF1-MMC5

The XP/Gil rewards are still coming in from every enemy, not just IMPs, way too high. Has nothing to do with the magic change bug as far as I can tell.

I noticed another bug in the shops. The EXIT command is borked. It just opens the sell menu instead of leaving the shop.

Oops, my bad with the exit shop. I tried to save a few bytes (me: why does it need to CMP #1 there's only buy and sell... one BNE and one BEQ!) and forgot there was actually a third option...

So for the XP/Gil... This is how it looks when the game is checking the stats. (Using Mesen's RAM viewer.)



For some reason, LoadEnemyStats wasn't filling the whole area that enemy stats actually occupy. It grabs all those bytes and combines them into the Gil/XP rewards. So there were some random non-0 bytes where the blue is, maybe? I updated the routine to clear those 256 bytes to 0 before writing enemy stats, so it might be fixed, or that might not have been the issue. But the rest of the code seems fine, and from the looks of things, its definitely grabbing the right bytes to check... I can't think of what else it could be.

So, again, all those little fixes in the last link!
« Last Edit: March 09, 2019, 01:15:16 am by Jiggers »
I know exactly what I'm doing. I just don't know what effect it's going to have.

Vanya

  • Hero Member
  • *****
  • Posts: 1487
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #104 on: March 09, 2019, 04:34:59 am »
Groovy! I can confirm that the XP/Gil, file delete, and exit commands are all fixed.
There are still a few more things left, plus I noticed another one.
Whenever I appear on the world map the party is always facing right.
This occurs even if I just enter the menu and then exit.

Jiggers

  • Full Member
  • ***
  • Posts: 238
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #105 on: March 09, 2019, 03:22:07 pm »
Yay! And Boo.

So I was trying to cheat to check out the pirates, to make sure battles with 9 enemies were loading right. I thought, maybe changing these two positioning variables would teleport me - "unsram_ow_scroll_x" and "unsram_ow_scroll_y". That didn't work, so I looked them up to see what they do, and far as I can tell, they're only used to set the starting positions. So I thought, well that's silly to fill up two bytes of SRAM for something you can just hardcode. But what if people want to change it? I'll set up some constants! But then I forgot you needed a # in front of constant variables to actually make them work as numbers, so it was loading new games at coordinates 0, 0. So I just undid everything I changed and left it alone because I needed to get back on track and not be distracted from my original goal.

Except... I didn't undo everything I changed, I guess? I don't know how I could have messed up the direction you face on loading the overworld. But now I see that Standard maps have this:
LDA #DOWN
STA facing
...and the overworld doesn't seem to set facing at all? It just clears it to 0, then does a routine that sets it to 8 but gets set to 0 again after.


Edit: So for a while I'm going to focus on cleaning up the code that's there. Re-arrange things, make fancy headers for routines, make it look good, like Disch had it before.

Also, I re-arranged all of Bank 0 and freed up 736 bytes. Lots of padding in there to make sure data was on page boundaries or whatnot. I just swapped the data around so there's less need for padding. And re-wrote the game_flags initialization, since its 7 0s and 249 1s. So now it fills with 1s with a loop, then writes the 7 0s to the proper spots. Have not uploaded these changes yet.

I ran into Kary during testing and she cast Fire 3, which was ineffective. Gotta look into that, too.

Gave imps Kary's AI and they were able to cast Fire 3 just fine?



For the item buying bug:

 @CompletePurchase:   
    LDA MMC5_tmp
    LDX shop_curitem
    ORA items, X ; <- add this line
    STA items, X
« Last Edit: March 11, 2019, 04:10:17 pm by Jiggers »
I know exactly what I'm doing. I just don't know what effect it's going to have.

Vanya

  • Hero Member
  • *****
  • Posts: 1487
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #106 on: March 10, 2019, 05:49:37 am »
Cool. Tidying up and rearranging the code will help to better manage the new additions you want to do and make it easier on anyone else who wants to edit the game.

I’m going to go back and review my posts so i can double check any remaining bugs I noticed.
« Last Edit: March 11, 2019, 02:33:45 am by Vanya »

Jiggers

  • Full Member
  • ***
  • Posts: 238
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #107 on: March 14, 2019, 10:37:06 am »


Anyone know what this means? Despite the error, it seems to compile just fine...
I know exactly what I'm doing. I just don't know what effect it's going to have.

Mari42

  • Jr. Member
  • **
  • Posts: 84
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #108 on: March 14, 2019, 11:02:47 am »


Anyone know what this means? Despite the error, it seems to compile just fine...

https://forums.nesdev.com/viewtopic.php?f=10&t=14315#p172009

Jiggers

  • Full Member
  • ***
  • Posts: 238
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #109 on: March 14, 2019, 09:00:15 pm »
Huh, I didn't change anything to do with that, but its not doing it anymore.

Hey, @Disch! FFHackster is the only source for FF1's treasure table converted into items that I've been able to find. Is there any chance you still have the raw, but converted data? Would save me from having to go through the drop-down and tag every single byte... like this:

Code: [Select]
lut_Treasure:
.byte $00, $00 ; 00 ; "Unused" ;
.byte $00, $47 ; 01 ; "Coneria 1" ; Iron Armor
.byte $00, $55 ; 02 ; "Coneria 2" ; Iron shield
.byte $00, $06 ; 03 ; "Coneria 3" ; TNT
.byte $00, $26 ; 04 ; "Coneria 4" ; Iron staff
.byte $00, $27 ; 05 ; "Coneria 5" ; Sabre
.byte $00, $2B ; 06 ; "Coneria 6" ; Silver knife

I'm poking at the treasure chest system. Now the first byte informs what kind of item it is, so that there can be more than 256 item IDs. Weapons and armor are split from other items so there can be more of them. But now I gotta re-do every single byte, after figuring out what the original item was supposed to be!
I know exactly what I'm doing. I just don't know what effect it's going to have.

Disch

  • Hero Member
  • *****
  • Posts: 2716
  • NES Junkie
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #110 on: March 14, 2019, 11:55:05 pm »
Hey, @Disch! FFHackster is the only source for FF1's treasure table converted into items that I've been able to find. Is there any chance you still have the raw, but converted data? Would save me from having to go through the drop-down and tag every single byte... like this:

"raw but converted"?  lol   :P

So going by your example it looks like there are 2 strings you're looking for:  The label name, and the actual item name.

Hackster pulls the label names from the FFHackster.dat file in its directory.  It's a binary file -- I was young... sorry.  You can open it with a hex editor though and the labels are visible at offset 0x51AA, and each label name is exactly 31 characters (if the label is shorter, it's padded with zeros).

The item name ares looked up from the in-game item table, though, so those are not stored anywhere.


I could probably write up a quick-ish Python script to generate that lut_Treasure table in your example.  And while I'm doing that, I might as well convert to the new format you're looking for so you don't have to do it manually.

Can you describe the final format you're shooting for?  You said the first byte is the item type, is it 00=item, 01=weapon, 02=armor, etc?  And are weapons/armor now zero based (weapon 0 = small knife)?  Full spec plz.

Once I have that I'll throw together a script for ya.


EDIT:  The other question is, if I convert the table, do you need the item names?  Extracting the item names would actually be the hardest part because I have to parse a table file and all that nonsense.  Although I might have some python code for loading tables lying around....

Like if I just gave you a file that looked like this:

Code: [Select]
lut_Treasure:
.byte $00, $00     ; Unused
.byte $02, $07     ; Coneria 1
.byte $02, $13     ; Coneria 2
; ...

Would that be good enough?
« Last Edit: March 15, 2019, 12:01:04 am by Disch »

Jiggers

  • Full Member
  • ***
  • Posts: 238
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #111 on: March 15, 2019, 12:45:55 am »
Ooo... no, its the item names I want! I got the label list from something else--one of the other FF1 docs floating around here, I think.

The format is...
;; If the first byte is $00, the second byte is $70 or higher (80 possible amounts of gold)
;; If the first byte is $01, its an item, key item, or magic:
;; second byte: $1 through $0F are consumables   (15 possible items)
;; second byte: $10 through $2F are key items    (32 possible key items)
;; second byte: $30 through $6F are magic spells (64 possible spells)
;; If the first byte is $02, its weapons or armor:
;; $0 through $3F are weapons     (64 possible weapons)
;; $40 through $7F are armors     (64 possible armors)

The weapons/armour table is 0 based, so that it caps at $7F, but I think I kept the IDs the same, so nunchucks are 01, small knife is 02.. Everything else shares the same table as before, but spells are moved up before the amount of gold in chests.

This is how I've got the items organized now... probably not going to change them after this unless something drastic happens, but I think this is a good enough amount of new items.
Code: [Select]
lut_ItemNamePtrTbl:
.word BLANK             ; 00
.word NAME_HEAL         ; 01
.word NAME_X_HEAL       ; 02
.word NAME_ETHER        ; 03
.word NAME_ELIXIR       ; 04
.word NAME_PURE         ; 05
.word NAME_SOFT         ; 06
.word NAME_P_DOWN       ; 07
.word NAME_TENT         ; 08
.word NAME_CABIN        ; 09
.word NAME_HOUSE        ; 0A
.word NAME_EYEDROPS     ; 0B
.word NAME_SMOKEBOMB    ; 0C
.word NAME_HORN         ; 0D
.word BLANK             ; 0E
.word BLANK             ; 0F

;; Key Items
.word NAME_LUTE         ; 10
.word NAME_CROWN        ; 11
.word NAME_CRYSTAL      ; 12
.word NAME_HERB         ; 13
.word NAME_KEY          ; 14
.word NAME_TNT          ; 15
.word NAME_ADAMANT      ; 16
.word NAME_SLAB         ; 17
.word NAME_RUBY         ; 18
.word NAME_ROD          ; 19
.word NAME_FLOATER      ; 1A
.word NAME_CHIME        ; 1B
.word NAME_TAIL         ; 1C
.word NAME_CUBE         ; 1D
.word NAME_BOTTLE       ; 1E
.word NAME_OXYALE       ; 1F
.word NAME_CANOE        ; 20
.word BLANK             ; 21
.word BLANK             ; 22
.word BLANK             ; 23
.word BLANK             ; 24
.word BLANK             ; 25
.word BLANK             ; 26
.word BLANK             ; 27
.word BLANK             ; 28
.word BLANK             ; 29
.word BLANK             ; 2A
.word BLANK             ; 2B
.word ORB1              ; 2C
.word ORB2              ; 2D
.word ORB3              ; 2E
.word ORB4              ; 2F

.word SPELL1       ; 30
.word SPELL2       ; 31
.word SPELL3       ; 32
.word SPELL4       ; 33
.word SPELL5       ; 34
.word SPELL6       ; 35
.word SPELL7       ; 36
.word SPELL8       ; 37
.word SPELL9       ; 38
.word SPELL10      ; 39
.word SPELL11      ; 3A
.word SPELL12      ; 3B
.word SPELL13      ; 3C
.word SPELL14      ; 3D
.word SPELL15      ; 3E
.word SPELL16      ; 3F
.word SPELL17      ; 40
.word SPELL18      ; 41
.word SPELL19      ; 42
.word SPELL20      ; 43
.word SPELL21      ; 44
.word SPELL22      ; 45
.word SPELL23      ; 46
.word SPELL24      ; 47
.word SPELL25      ; 48
.word SPELL26      ; 49
.word SPELL27      ; 4A
.word SPELL28      ; 4B
.word SPELL29      ; 4C
.word SPELL30      ; 4D
.word SPELL31      ; 4E
.word SPELL32      ; 4F
.word SPELL33      ; 50
.word SPELL34      ; 51
.word SPELL35      ; 52
.word SPELL36      ; 53
.word SPELL37      ; 54
.word SPELL38      ; 55
.word SPELL39      ; 56
.word SPELL40      ; 57
.word SPELL41      ; 58
.word SPELL42      ; 59
.word SPELL43      ; 5A
.word SPELL44      ; 5B
.word SPELL45      ; 5C
.word SPELL46      ; 5D
.word SPELL47      ; 5E
.word SPELL48      ; 5F
.word SPELL49      ; 60
.word SPELL50      ; 61
.word SPELL51      ; 62
.word SPELL52      ; 63
.word SPELL53      ; 64
.word SPELL54      ; 65
.word SPELL55      ; 66
.word SPELL56      ; 67
.word SPELL57      ; 68
.word SPELL58      ; 69
.word SPELL59      ; 6A
.word SPELL60      ; 6B
.word SPELL61      ; 6C
.word SPELL62      ; 6D
.word SPELL63      ; 6E
.word SPELL64      ; 6F

.word MoneyChest1  ; 70
.word MoneyChest2  ; 71
.word MoneyChest3  ; 72
.word MoneyChest4  ; 73
.word MoneyChest5  ; 74
.word MoneyChest6  ; 75
.word MoneyChest7  ; 76
.word MoneyChest8  ; 77
.word MoneyChest9  ; 78
.word MoneyChest10 ; 79
.word MoneyChest11 ; 7A
.word MoneyChest12 ; 7B
.word MoneyChest13 ; 7C
.word MoneyChest14 ; 7D
.word MoneyChest15 ; 7E
.word MoneyChest16 ; 7F
.word MoneyChest17 ; 80
.word MoneyChest18 ; 81
.word MoneyChest19 ; 82
.word MoneyChest20 ; 83
.word MoneyChest21 ; 84
.word MoneyChest22 ; 85
.word MoneyChest23 ; 86
.word MoneyChest24 ; 87
.word MoneyChest25 ; 88
.word MoneyChest26 ; 89
.word MoneyChest27 ; 8A
.word MoneyChest28 ; 8B
.word MoneyChest29 ; 8C
.word MoneyChest30 ; 8D
.word MoneyChest31 ; 8E
.word MoneyChest32 ; 8F
.word MoneyChest33 ; 90
.word MoneyChest34 ; 91
.word MoneyChest35 ; 92
.word MoneyChest36 ; 93
.word MoneyChest37 ; 94
.word MoneyChest38 ; 95
.word MoneyChest39 ; 96
.word MoneyChest40 ; 97
.word MoneyChest41 ; 98
.word MoneyChest42 ; 99
.word MoneyChest43 ; 9A
.word MoneyChest44 ; 9B
.word MoneyChest45 ; 9C
.word MoneyChest46 ; 9D
.word MoneyChest47 ; 9E
.word MoneyChest48 ; 9F
.word MoneyChest49 ; A0
.word MoneyChest50 ; A1
.word MoneyChest51 ; A2
.word MoneyChest52 ; A3
.word MoneyChest53 ; A4
.word MoneyChest54 ; A5
.word MoneyChest55 ; A6
.word MoneyChest56 ; A7
.word MoneyChest57 ; A8
.word MoneyChest58 ; A9
.word MoneyChest59 ; AA
.word MoneyChest60 ; AB
.word MoneyChest61 ; AC
.word MoneyChest62 ; AD
.word MoneyChest63 ; AE
.word MoneyChest64 ; AF
.word MoneyChest65 ; B0
.word MoneyChest66 ; B1
.word MoneyChest67 ; B2
.word MoneyChest68 ; B3
.word MoneyChest69 ; B4
.word MoneyChest70 ; B5
.word MoneyChest71 ; B6
.word MoneyChest72 ; B7
.word MoneyChest73 ; B8
.word MoneyChest74 ; B9
.word MoneyChest75 ; BA
.word MoneyChest76 ; BB
.word MoneyChest77 ; BC
.word MoneyChest78 ; BD
.word MoneyChest79 ; BE
.word MoneyChest80 ; BF

My treasure table looks like this so far:
Code: [Select]
lut_Treasure:
.byte $00, $00      ; 00 ; "Unused" ;
.byte $02, ARMOR4   ; 01 ; "Coneria 1" ; Iron Armor
.byte $02, $55      ; 02 ; "Coneria 2" ; Iron shield
.byte $01, TNT      ; 03 ; "Coneria 3" ; TNT
.byte $02, $26      ; 04 ; "Coneria 4" ; Iron staff
.byte $02, $27      ; 05 ; "Coneria 5" ; Sabre
.byte $02, $2B      ; 06 ; "Coneria 6" ; Silver knife
.byte $01, CABIN    ; 07 ; "Temple of Fiends 1" ; Cabin
.byte $01, HEAL     ; 08 ; "Temple of Fiends 2" ; Heal
.byte $02, $5D      ; 09 ; "Temple of Fiends 3" ; Cap
.byte $02, $36      ; 0A ; "Temple of Fiends 4" ; Rune sword
.byte $02, $35      ; 0B ; "Temple of Fiends 5" ; Were sword
.byte $01, SOFT     ; 0C ; "Temple of Fiends 6" ; Soft
.byte $02, $2D      ; 0D ; "Elfland 1" ; Silver helm
.byte $00, $81      ; 0E ; "Elfland 2" ; 400 g
.byte $00, $7E      ; 0F ; "Elfland 3" ; 330 g
.byte $02, $65      ; 10 ; "Elfland 4" ; Copper gloves
.byte $02, $37      ; 11 ; "NorthWest Castle 1" ; Power staff
.byte $02, $66      ; 12 ; "NorthWest Castle 2" ; Iron gloves
.byte $02, $2A      ; 13 ; "NorthWest Castle 3" ; Falchon
.byte $00, $7B      ; 14 ; "Marsh Cave 1" ; 259 g
.byte $00, $4E      ; 15 ; "Marsh Cave 2" ;
.byte $01, HOUSE    ; 16 ; "Marsh Cave 3" ; House
.byte $00, $80      ; 17 ; "Marsh Cave 4" ;
.byte $00, $86      ; 18 ; "Marsh Cave 5" ;
.byte $00, $21      ; 19 ; "Marsh Cave 6" ;
.byte $00, $87      ; 1A ; "Marsh Cave 7" ;
.byte $00, $25      ; 1B ; "Marsh Cave 8" ;
.byte $01, CROWN    ; 1C ; "Marsh Cave 9" ; CROWN

I was gonna make it really easy to edit by putting like, WEAPON1, WEAPON2, etc, in Constants. Maybe even sub-categorize that, so its KNIFE1, SWORD1, HAMMER1, STAFF1, and so on for weapons, and BODY1, HEAD1, ARMS1 and such for armors.

Just having the original item for reference in a list would be a big help, so don't go out of your way to convert it all perfectly unless... that's fun for you? XD
I know exactly what I'm doing. I just don't know what effect it's going to have.

Disch

  • Hero Member
  • *****
  • Posts: 2716
  • NES Junkie
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #112 on: March 15, 2019, 01:08:27 pm »
Okay well I got lazy and scrapped the idea of doing the conversion and just have the labels and item names:

Code: [Select]
Unused                 -
Coneria 1              - Iron   Armor
Coneria 2              - Iron   Shield
Coneria 3              - TNT   
Coneria 4              - Iron   Staff
Coneria 5              - Sabre 
Coneria 6              - Silver Knife
Temple of Fiends 1     - CABIN 
Temple of Fiends 2     - HEAL Potion
Temple of Fiends 3     - Cap   
Temple of Fiends 4     - Rune   Sword
Temple of Fiends 5     - Were   Sword
Temple of Fiends 6     - SOFT Potion 
Elfland 1              - Silver Hammer
Elfland 2              - 400 G
Elfland 3              - 330 G
Elfland 4              - Copper Gauntlets
NorthWest Castle 1     - Power  Staff
NorthWest Castle 2     - Iron   Gauntlets
NorthWest Castle 3     - Falchon
Marsh Cave 1           - 295 G
Marsh Cave 2           - Copper Bracelet
Marsh Cave 3           - HOUSE 
Marsh Cave 4           - 385 G
Marsh Cave 5           - 620 G
Marsh Cave 6           - Short  Sword
Marsh Cave 7           - 680 G
Marsh Cave 8           - Large  Knife
Marsh Cave 9           - CROWN 
Marsh Cave 10          - Iron   Armor
Marsh Cave 11          - Silver Bracelet
Marsh Cave 12          - Silver Knife
Marsh Cave 13          - 1020 G
Dwarf Cave 1           - 450 G
Dwarf Cave 2           - 575 G
Dwarf Cave 3           - CABIN 
Dwarf Cave 4           - Iron   Helmet
Dwarf Cave 5           - Wooden Helmet
Dwarf Cave 6           - Dragon Sword
Dwarf Cave 7           - Silver Knife
Dwarf Cave 8           - Silver Armor
Dwarf Cave 9           - 575 G
Dwarf Cave 10          - HOUSE 
Matoya's Cave 1        - HEAL Potion
Matoya's Cave 2        - PURE Potion
Matoya's Cave 3        - HEAL Potion
Earth Cave 1           - 880 G
Earth Cave 2           - HEAL Potion
Earth Cave 3           - PURE Potion
Earth Cave 4           - 795 G
Earth Cave 5           - 1975 G
Earth Cave 6           - Coral  Sword
Earth Cave 7           - CABIN 
Earth Cave 8           - 330 G
Earth Cave 9           - 5000 G
Earth Cave 10          - Wooden Shield
Earth Cave 11          - 575 G
Earth Cave 12          - 1020 G
Earth Cave 13          - 3400 G
Earth Cave 14          - TENT   
Earth Cave 15          - HEAL Potion
Earth Cave 16          - RUBY   
Earth Cave 17          - 1250 G
Earth Cave 18          - Silver Shield
Earth Cave 19          - CABIN 
Earth Cave 20          - 5450 G
Earth Cave 21          - 1520 G
Earth Cave 22          - Wooden Staff
Earth Cave 23          - 3400 G
Earth Cave 24          - 1455 G
Titan's Tunnel 1       - Silver Helmet
Titan's Tunnel 2       - 450 G
Titan's Tunnel 3       - 620 G
Titan's Tunnel 4       - Great  Axe
Gurgu Volcano 1        - HEAL Potion
Gurgu Volcano 2        - CABIN 
Gurgu Volcano 3        - 1975 G
Gurgu Volcano 4        - PURE Potion
Gurgu Volcano 5        - HEAL Potion
Gurgu Volcano 6        - 1455 G
Gurgu Volcano 7        - Silver Shield
Gurgu Volcano 8        - 1520 G
Gurgu Volcano 9        - Silver Helmet
Gurgu Volcano 10       - Silver Gauntlets
Gurgu Volcano 11       - 1760 G
Gurgu Volcano 12       - Silver Axe
Gurgu Volcano 13       - 795 G
Gurgu Volcano 14       - 750 G
Gurgu Volcano 15       - Giant  Sword
Gurgu Volcano 16       - 4150 G
Gurgu Volcano 17       - 1520 G
Gurgu Volcano 18       - Silver Helmet
Gurgu Volcano 19       - SOFT Potion 
Gurgu Volcano 20       - 2750 G
Gurgu Volcano 21       - 1760 G
Gurgu Volcano 22       - Wooden Staff
Gurgu Volcano 23       - 1250 G
Gurgu Volcano 24       - 10 G
Gurgu Volcano 25       - 155 G
Gurgu Volcano 26       - HOUSE 
Gurgu Volcano 27       - 2000 G
Gurgu Volcano 28       - Ice    Sword
Gurgu Volcano 29       - 880 G
Gurgu Volcano 30       - PURE Potion
Gurgu Volcano 31       - Flame  Shield
Gurgu Volcano 32       - 7340 G
Gurgu Volcano 33       - Flame  Armor
Ice Cave 1             - HEAL Potion
Ice Cave 2             - 10000 G
Ice Cave 3             - 9500 G
Ice Cave 4             - TENT   
Ice Cave 5             - Ice    Shield
Ice Cave 6             - Cloth 
Ice Cave 7             - Flame  Sword
Ice Cave 8             - FLOATER
Ice Cave 9             - 7900 G
Ice Cave 10            - 5450 G
Ice Cave 11            - 9900 G
Ice Cave 12            - 5000 G
Ice Cave 13            - 180 G
Ice Cave 14            - 12350 G
Ice Cave 15            - Silver Gauntlets
Ice Cave 16            - Ice    Armor
Castle of Ordeal 1     - Zeus   Gauntlets
Castle of Ordeal 2     - HOUSE 
Castle of Ordeal 3     - 1455 G
Castle of Ordeal 4     - 7340 G
Castle of Ordeal 5     - Gold   Bracelet
Castle of Ordeal 6     - Ice    Sword
Castle of Ordeal 7     - Iron   Gauntlets
Castle of Ordeal 8     - Heal   Staff
Castle of Ordeal 9     - TAIL   
Cardia 1               - 1455 G
Cardia 2               - 2000 G
Cardia 3               - 2750 G
Cardia 4               - 2750 G
Cardia 5               - 1520 G
Cardia 6               - 10 G
Cardia 7               - 500 G
Cardia 8               - HOUSE 
Cardia 9               - 575 G
Cardia 10              - SOFT Potion 
Cardia 11              - CABIN 
Cardia 12              - 9500 G
Cardia 13              - 160 G
Not Used 1             - 530 G
Not Used 2             - Small  Knife
Not Used 3             - Cap   
Not Used 4             - Zeus   Gauntlets
Sea Shrine 1           - Ribbon 
Sea Shrine 2           - 9900 G
Sea Shrine 3           - 7340 G
Sea Shrine 4           - 2750 G
Sea Shrine 5           - 7690 G
Sea Shrine 6           - 8135 G
Sea Shrine 7           - 5450 G
Sea Shrine 8           - 385 G
Sea Shrine 9           - Power  Gauntlets
Sea Shrine 10          - Light  Axe
Sea Shrine 11          - 9900 G
Sea Shrine 12          - 2000 G
Sea Shrine 13          - 450 G
Sea Shrine 14          - 110 G
Sea Shrine 15          - Light  Axe
Sea Shrine 16          - Opal   Armor
Sea Shrine 17          - 20 G
Sea Shrine 18          - Mage   Staff
Sea Shrine 19          - 12350 G
Sea Shrine 20          - 9000 G
Sea Shrine 21          - 1760 G
Sea Shrine 22          - Opal   Bracelet
Sea Shrine 23          - 2750 G
Sea Shrine 24          - 10000 G
Sea Shrine 25          - 10 G
Sea Shrine 26          - 4150 G
Sea Shrine 27          - 5000 G
Sea Shrine 28          - PURE Potion
Sea Shrine 29          - Opal   Shield
Sea Shrine 30          - Opal   Helmet
Sea Shrine 31          - Opal   Gauntlets
Sea Shrine 32          - SLAB   
Waterfall 1            - Wizard Staff
Waterfall 2            - Ribbon 
Waterfall 3            - 13450 G
Waterfall 4            - 6400 G
Waterfall 5            - 5000 G
Waterfall 6            - Defense
Not Used 5             - HEAL Potion
Not Used 6             - HEAL Potion
Not Used 7             - HEAL Potion
Not Used 8             - HEAL Potion
Not Used 9             - HEAL Potion
Not Used 10            - HEAL Potion
Not Used 11            - HEAL Potion
Not Used 12            - HEAL Potion
Not Used 13            - HEAL Potion
Mirage Tower 1         - Aegis  Shield
Mirage Tower 2         - 2750 G
Mirage Tower 3         - 3400 G
Mirage Tower 4         - 18010 G
Mirage Tower 5         - CABIN 
Mirage Tower 6         - Heal   Helmet
Mirage Tower 7         - 880 G
Mirage Tower 8         - Vorpal
Mirage Tower 9         - HOUSE 
Mirage Tower 10        - 7690 G
Mirage Tower 11        - Sun    Sword
Mirage Tower 12        - 10000 G
Mirage Tower 13        - Dragon Armor
Mirage Tower 14        - 8135 G
Mirage Tower 15        - 7900 G
Mirage Tower 16        - Thor   Hammer
Mirage Tower 17        - 12350 G
Mirage Tower 18        - 13000 G
Sky Palace 1           - 9900 G
Sky Palace 2           - HEAL Potion
Sky Palace 3           - 4150 G
Sky Palace 4           - 7900 G
Sky Palace 5           - 5000 G
Sky Palace 6           - ProRing
Sky Palace 7           - 6720 G
Sky Palace 8           - Heal   Helmet
Sky Palace 9           - 180 G
Sky Palace 10          - Bane   Sword
Sky Palace 11          - White  Shirt
Sky Palace 12          - Black  Shirt
Sky Palace 13          - Ribbon 
Sky Palace 14          - Opal   Gauntlets
Sky Palace 15          - Opal   Shield
Sky Palace 16          - Silver Helmet
Sky Palace 17          - HOUSE 
Sky Palace 18          - 880 G
Sky Palace 19          - 13000 G
Sky Palace 20          - ADAMANT
Sky Palace 21          - 4150 G
Sky Palace 22          - SOFT Potion 
Sky Palace 23          - 3400 G
Sky Palace 24          - Katana
Sky Palace 25          - ProCape
Sky Palace 26          - Cloth 
Sky Palace 27          - 9500 G
Sky Palace 28          - SOFT Potion 
Sky Palace 29          - 6400 G
Sky Palace 30          - 8135 G
Sky Palace 31          - 9000 G
Sky Palace 32          - HEAL Potion
Sky Palace 33          - ProRing
Sky Palace 34          - 5450 G
ToF Revisited 1        - Masmune
ToF Revisited 2        - 26000 G
ToF Revisited 3        - Katana
ToF Revisited 4        - ProRing
ToF Revisited 5        - ProCape
ToF Revisited 6        - 45000 G
ToF Revisited 7        - 65000 G
Unused                 -

If you want the Python scripts so you can tweak them, lemme know.

Jiggers

  • Full Member
  • ***
  • Posts: 238
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #113 on: March 15, 2019, 04:31:56 pm »
I don't know how to use python, but this is perfect! Thank you! :D

I'm working on the item menu now... I've got it loading an item's name, then putting all the text blocks into RAM, then printing from that RAM address. Hopefully by time I've got the scroll offset stuff in place, it will be able to print the whole screen in a single V-blank or two!
I know exactly what I'm doing. I just don't know what effect it's going to have.

Disch

  • Hero Member
  • *****
  • Posts: 2716
  • NES Junkie
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #114 on: March 15, 2019, 04:59:10 pm »
I don't know how to use python

I absolutely love it.

Only on RHDN would someone know 6502 assembly, but not Python.   :laugh:

Anyway, happy to help!  This is a cool project you got going on.

Jiggers

  • Full Member
  • ***
  • Posts: 238
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #115 on: March 16, 2019, 12:04:03 am »
It still took two hours to do the conversions and re-enter all the bytes... but could have been longer.



Here's a peek! This layout allows 16 items per page. Since you never have more than 16 key items at any one time--using the Herb and TNT and things remove them before you can pick up more--it will never need more space than that. If someone DOES edit the game to add more key items, then they've got the ability to make a third page. Pressing select swaps between consumables and key items.

Now coding in using consumables in the menu... then have to figure out battle use. *cry* X-Heal, Elixir, and Phoenix Down should work as intended (if tmp+2 isn't being used while using heal potions), but Ether is going to need some market research. Need to make a new screen that shows MP and then lets you pick a level to refill. Or should it straight up refill all the character's MP across all levels?

Smokebomb: should it stop enemy encounters for X steps, or just lower them further? In battle, it will put all characters into hiding on use. The horn will wake all characters from sleep. Oh, I should rename that to WakeBell or something...

Is there any benefit to using @Local labels, or is that just for organization? Does it save a byte when they're used or something?
« Last Edit: March 16, 2019, 12:40:46 am by Jiggers »
I know exactly what I'm doing. I just don't know what effect it's going to have.

Disch

  • Hero Member
  • *****
  • Posts: 2716
  • NES Junkie
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #116 on: March 16, 2019, 04:23:54 am »
Quote
Is there any benefit to using @Local labels, or is that just for organization?

You say that as if organization isn't a benefit!

Local variables are a scope restriction.  Scope restrictions avoid name conflicts.  Having scopes allows you to not worry about making every single identifier name 100% unique.  For example, you can have a local "@Loop" label, but a global "Loop" label would probably be disastrous.  Or having a local variable named "@box_x" might be useful for a box drawing routine, but having a global "box_x" label would be less useful, since different routines might use different areas for that variable.

Honestly I wish I used local variables more.  I didn't really take full advantage of them until I got near the end of the disassembly.  Instead, I made that wretched "tmp" space that is horribly unclear.

Quote
Does it save a byte when they're used or something?

Nope.  The final binary is the same.  They're really just there to avoid name conflicts and keep identifiers scope restricted.

Vanya

  • Hero Member
  • *****
  • Posts: 1487
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #117 on: March 16, 2019, 08:12:14 am »
Here's a peek! This layout allows 16 items per page. Since you never have more than 16 key items at any one time--using the Herb and TNT and things remove them before you can pick up more--it will never need more space than that. If someone DOES edit the game to add more key items, then they've got the ability to make a third page. Pressing select swaps between consumables and key items.

Any chance that it could be changed to a mini menu instead of a button press?
Like Final Fantasy 5 & 6 but without the Sort command.
Also, what do you mean by having the ability to add a third page exactly?


Quote
Now coding in using consumables in the menu... then have to figure out battle use. *cry* X-Heal, Elixir, and Phoenix Down should work as intended (if tmp+2 isn't being used while using heal potions), but Ether is going to need some market research. Need to make a new screen that shows MP and then lets you pick a level to refill. Or should it straight up refill all the character's MP across all levels?

I'd keep it simple and have it refill all spell levels at once.
Why make a whole new screen from something as mundane as restoring spell charges when you could use the time and space to do something more interesting?

I'd nix the whole spell level thing entirely like they did in Dawn of Souls and Anniversary Edition.
You'd only need to track one byte or two of MP as opposed to 8 of spell charges and maybe have a separate spell level stat so the game can restrict access to spells of higher levels than a character would be able to cast. Still, that would give you like another 5 free bytes for each character's stats, no?


Quote
Smokebomb: should it stop enemy encounters for X steps, or just lower them further? In battle, it will put all characters into hiding on use. The horn will wake all characters from sleep. Oh, I should rename that to WakeBell or something...

Wakeup Bell would be a nice reference to Bravely Default (which is arguably the true continuation of classic Final Fantasy) if it can fit.
One thing , though, just about every version of the Alarm Clock / Wakeup Bell is a single target item.
Might be better to follow suit, plus how often is most of the party going to asleep all at once to justify sitting through the 4 messages that would trigger on each party member?

As for the Smoke Bomb (should be 2 words), while making everyone hide is a pretty cool idea, it does buck tradition a bit from what it does in every other game in the series.
That said, maybe Smoke Screen would be a better name for it instead?
A single smoke bomb is usually enough for a single person to escape or hide, but a smoke screen by definition implies a larger scale situation like hiding the whole party.
I'm not to sure about having an item that manipulates the encounter rate in a game that already lets you do that through a menu option.
So I would have to go with completely preventing enemy encounters for a noticeable number of steps, or maybe even straight up until the next time you use a warp tile to switch maps.

You may also want to consider having both a Smoke Bomb and a Smoke Screen.
Having a traditional Smoke Bomb item might be very useful if all your casters are dead or you are playing with an all martial team.
I'm thinking it would function like the warp spell out of battle, and it would have a 100% escape effect in battle.

Anyway, great work on the item menu so far. Can't wait to try it out for myself. :cheers:

Jiggers

  • Full Member
  • ***
  • Posts: 238
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #118 on: March 19, 2019, 08:16:25 pm »
Nope.  The final binary is the same.  They're really just there to avoid name conflicts and keep identifiers scope restricted.
Ooh, good to know. I've been moving so many little things around, wondering if it will make a difference--hoping it does, because that's the point.

Any chance that it could be changed to a mini menu instead of a button press?

Why not both?

Consumables:

Elixir Screen:

Ether Screen:


I went with Wakeup Bell because Alarm clocks just... don't make sense? And I couldn't figure out what kind of horn icon to make. Birthday party horn? Big tuba? Keeping Smoke bomb because of the 8 character limit (12 for key items.) Could be 9, but it would look ugly pressing up against the numbers...

Ultimate goal is probably VWF, but that's... like, the last thing, maybe.

I want to make the sleep ailment more dangerous. I've made it harder to wake up from than stun, and I made it use the death pose, have 'em all zonked out. I don't think I've EVER been put to sleep in the original game, so I'd like to see more enemies use it.

I might be the only one who really likes the MP per level system... It definitely adds some strategy and difficulty that's different than just making enemies have more health. Saving up your biggest spells for the boss, or using them on those #@&!%in' sorcerers in the ice cave and the ghosts in the  underwater palace? Being forced to fall back on lower-level spells makes you feel desperate and in danger, instead of spamming ethers and your highest spell. So thinking on that, I decided refilling the whole MP pool was a little OP. Elixirs do it, but if I was going to re-design the dungeons and everything, you'd get maybe 5 of them in the whole game...

I updated all the shops to use the new item IDs, did a bit more cleanup of things here and there--its all blurry now. Re-wrote item messages to be simpler. CURE spells now use the same message as Heal and X-Heal, things like that. As you can see in the screenshot, tents, cabins, and houses now have a confirmation before use, and so should the WARP and EXIT spells.

Next steps:
Implement code for smoke bombs...
Magic swapping...
And finally delve into adding the new items in battle.

Edit: Oh, yeah, finally fixed the weird sluggishness in the Options menu. Turns out drawing the text every frame was ... happening. Now it only updates when it needs to.

I'm still unsure about how to update things with github so I'm gonna try to finish a few more things before putting the changes up...?
« Last Edit: March 19, 2019, 08:28:20 pm by Jiggers »
I know exactly what I'm doing. I just don't know what effect it's going to have.

Disch

  • Hero Member
  • *****
  • Posts: 2716
  • NES Junkie
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #119 on: March 19, 2019, 08:56:38 pm »
I assume that's supposed to be Phoenix Down, but since you used the icon for down it ends up reading like "Down down"   :laugh:


Quote
I'm still unsure about how to update things with github so I'm gonna try to finish a few more things before putting the changes up...?


I assume you have git installed?  From a command prompt in your project's root directory:
Code: [Select]
git add .
git commit -m "Put a message here to indicate what you changed with this commit"
git push

'add .' adds all changed files to the list of files to be committed.
'commit' actually commits them (basically saves/backs them up).  Note that commit only commits locally (does not update github)
'push' pushes the committed changes to the remote repo (updates github)


...

But really, I recommend just getting a gui program like SmartGit (free for noncommercial use).  It shows you what files you've changed, and you can just click a button to push them.



Hardest part will be setting SmartGit up to work with your repo, but that's a one time thing and once you figure it out it's pretty easy to do it again.  It has a wizard that sort of walks you through it but if you are completely unfamiliar with git you might not understand some of the lingo.


If you have uncommitted changes it might be tricky.  Here's what I'd do to set up SmartGit:

1 )  Move your entire project directory somewhere else (or just rename the directory it's in).  So the directory where you want your project is entirely empty.
2 )  From SmartGit, Go in the 'Repository' menu, and select 'Clone'
3 )  Follow the prompts.  Select "Remote Git Repository" and give it the URL to your github page
4 )  All the "Selection" stuff can be left to their defaults
5 )  And the "Local Directory" is where you want your project to be
6 )  Once done, it'll clone what was pushed to your repo (what is currently on github)
7 )  Copy/paste your more recently modified files over that (but do NOT copy any hidden '.git/' folders)
8 )  Use SmartGit to commit/push


Note I'm making this all sound a lot more complicated than it is.  It's actually really easy once you do it.  It's only really tricky because of the unpushed changes.  If you push everything with git first, then you can just delete your local copy and do only steps 2-6 above.



EDIT:

As for a few good git practices once you have things set up:

1 ) Don't work directly out of your master.  Whenever you are working on something, branch off of master into a new branch (commonly referred to as a "feature branch").  Try to keep master in stable/working condition at all times.  That way if something REALLY gets hecked up, you can very easily toss your feature branch and fall back to master.

2 ) Commit to your feature branch very frequently.  Keep commits small and keep them frequent.  Once a day at the VERY LEAST (assuming you did work that day).  Often, do more.  Basically any meaningful incremental change should be its own commit.  Each commit is effectively a full backup, and is as easy as a button press.  So if something gets broken, you can easily roll back to see where the problem started.

3 ) Merge your feature branch(es) back into master when you're confident they're stable.  Basically the feature branch gets the small incremental changes you made when adding the feature, and the merge from feature->master is the full & complete feature/bugfix.
« Last Edit: March 19, 2019, 09:06:42 pm by Disch »