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

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

Jiggers

  • Sr. Member
  • ****
  • Posts: 355
    • View Profile
    • My Ko-Fi Page
Re: FF1 MMC5 Disassembly Updates
« Reply #560 on: May 14, 2020, 11:40:03 pm »
Quote
Yeah, I saw a similar explanation here:
https://guides.gamercorner.net/ff/walkthrough/game-systems

Aw I thought I was the first one to find this bug. I don't remember it listed in the big list mentioned on that one gamefaqs thread anyway... I feel like I might have found 1-2 other things that count as bugs that were never mentioned, but now I don't remember them either!

Quote
Wait so enemies have a proper elemental attack and status attack byte?
And now this byte in question which was supposed to be attack element is not used?
If so...
Why not use it to directly set the base status attack hit rate?
That way we have way more options.

Yep yep yep... and already done.  :D Doing that allowed a LOT of streamlining of the ailment part of the physical attack routine. Stripped out the base chance and just put in their new stat. Then adjusted some enemies based on their location in the game. Some are UNDER the #100 base now: Coctrices, Arachnids... things I felt were too swarmy at lower levels.

I tend to make changes that favor the player over difficult. I don't like grindy games. I was really impressed that setting EXP and gold to high and encounter rate to low made it a much more enjoyable game for me. The pacing felt more like Chrono Trigger, where so long as you clear out a room of enemies, you don't really HAVE to grind to get through it. Just don't run away.

Just something to keep in mind; I'm not the best person when it comes to making balance stuff, if what you enjoy is a punishing old RPG.

Sooo... Huh. That's really impressive work on those stat tables. What I'm getting from that is... add Magic Evade to mage armor! They sorely need it to keep up. I think that formula looks pretty good and I'll put it in when I get around to the level up stat code, if there's no objections.



I'd like people's thoughts on this change: Making the dialogue box the width of the screen.

This would solve 2 things, the treasure chests closing when the dialogue box is open -- seen here at 13 seconds in: https://www.youtube.com/watch?v=N5M1uq3y0u4 -- as well as sprites being set to background priority on the sides but showing up anyway, such as in the shadows of buildings and under the cobblestones in towns. I've already shifted the box up 1 tile so you no longer talk to legs and a torso when facing an NPC above you.

And dialogue needs to be edited anyway, because I was planning on using one of the new translations... adjusting things to fit would be a relaxing few days--unless Vanya wants to tackle it.

Alternatively, I find some way to only background-prioritize sprites that are on the box's scanlines and NOT on the sides of the box... and figure something out for the chest tops...
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: 1639
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #561 on: May 15, 2020, 01:43:46 am »
Groovy!
I like everything I just read.
I can do the text stuff for sure! Just point me at the resources and I'll get at them!
Which translation do you want to use? ChaosRush's?

Jiggers

  • Sr. Member
  • ****
  • Posts: 355
    • View Profile
    • My Ko-Fi Page
Re: FF1 MMC5 Disassembly Updates
« Reply #562 on: May 15, 2020, 03:07:25 am »
I think that's the one. Was made just last year or so in a thread here? I remember being chuffed that my personalization of the shopkeeper matched what the original game was going for...

Today's fun fact: The fixed bank started out with 435 free bytes! (some of that was from moving the poison damage code to another bank.)

After screwing around with the dialogue box drawing... 599 free bytes! It turns out the little loops I made for drawing battle boxes to RAM work just as well...





Hm... also considering cleaning up the mini map. Make it twice as large. Cut out the little graphics. Maybe stick the "Final Fantasy" back in if there's enough room in an ocean, or maybe not. I party just want to play around with it...

The dungeon sprites don't seem to work properly with some people's hacks, for some reason. I was hoping it would just be a manually made LUT I could edit, but it seems to be combining 4 overworld tiles into 1 pixel, then seeing if there's any teleports on it? So whatever its checking for, isn't getting picked up properly. And Onrac is located in just the perfect spot to have like 4 glowing things... It just rankles me. I want to make everything 1 tile per 1 pixel! XD

Edit: Bah, nevermind, I forgot why that's impossible... UNLESS I use the trick to draw the second half of the screen using the sprite CHR as background tiles and set up a new VBlank routine that swaps it at the right scanline?! This is just crazy enough to work.
« Last Edit: May 16, 2020, 01:23:53 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: 1639
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #563 on: May 16, 2020, 02:06:09 am »
Yeah, that's the Chaos Rush Translation / Re-Localization.
Which version do you want to use?
There is one that keeps some of the more traditional likes and terms and one that is more directly translated.

Hacking the mini-map sounds great.
I wonder if we could get it to work with dungeon areas?
And what about implementing an auto-map feature, too? That would be sick.

When you say dungeon sprites, do you mean the entrance tiles on the overworld?
Making it do 1 pixel per overworld tile would definitely fix that.
Why is that initially impossible?

Jiggers

  • Sr. Member
  • ****
  • Posts: 355
    • View Profile
    • My Ko-Fi Page
Re: FF1 MMC5 Disassembly Updates
« Reply #564 on: May 16, 2020, 02:45:46 am »
I'm still a bit mind-broken on the details...

The mini map routine basically fills the first pattern table with the world map, where every 4 tiles is compressed into 1 pixel. the world map is 256x256 (65536!) tiles. The mini map is 128x128 pixels... Then they went and found all the "Blank" ocean tiles and used those to fill in the fancy dragon-sword graphics and the title. So they obviously got the mini map working first, then did that part...

The screen is 256x240 pixels. I don't know if that accounts for overscan--or if the visible stuff is a little less than that.

So basically the first problem is that expanding the mini map size to 256x256 won't fit in the pattern table. It will need to use background tiles AND sprite tiles to do that. But halfway through rendering I can set the sprite pattern table to be used as more background tiles, that's what I did with battle boxes.

The nametable sizes are 16x16 tiles... 8x8 pixels is 64... So 1024 pixels across, 1024 pixels down, that's 16384 pixels in a square. That's one nametable. But uh. That can only be x2. But the world map is 16384x4. So if every tile is 1 pixel, we could only draw half the map?? But my logic is telling me that the map should be able to expand perfectly into this size. So what step did I miss...

If I WAS able to expand the minimap to 1 tile per pixel, it would cut off some ocean stuff and possibly maybe mess up the "You are here" sprite a bit if you were lurking around the bottom of the map. Not worth thinking about that right now though.

Bah, I get it now. I wasn't thinking horizontally enough. I'd need 2 extra nametables.

This is one of those moments where I wish the MMC5 had CHR ROM as well. Just pre-render the map and swap halfway through every frame.

Now, dungeon mini maps? That's something I was thinking about during this experiment. $7000 in RAM already has the map tiles decompressed there. So drawing could would just need to read from there...

What I think I could do, is use the sprite pattern table as fancy graphics for the top and bottom of the mini map, then convert the map data there into pixels... so kind of a zoomed in overworld view...? Depends on if its loading a perfect square or what, I haven't looked into it that deeply yet.

I'm hoping it will work nicely for dungeons and towns and stuff though!

I think the issue with the town/dungeon/castle sprites not showing in this other hack's mini map is because there's a table that needs to be edited to match any new teleports added to the new tiles. So if anyone edits the actual tile properties enough, they'll need to adjust that too.

Quote
Which version do you want to use?
There is one that keeps some of the more traditional likes and terms and one that is more directly translated.

I'd probably go with the more traditional one.
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: 1639
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #565 on: May 16, 2020, 03:37:30 am »
Ah. OK.

Could you maybe make it so the mini-map starts zoomed-in, but can toggle to the full world view?

I'll make a branch tomorrow and start copying over the retranslation.

Jiggers

  • Sr. Member
  • ****
  • Posts: 355
    • View Profile
    • My Ko-Fi Page
Re: FF1 MMC5 Disassembly Updates
« Reply #566 on: May 16, 2020, 04:21:14 am »
If I can do the zoomed in at all, I'll try it out. I think I'll have the sound test be pressing start while paused, then B+Select will do the mini maps... Or maybe start the overworld zoomed out and A zooms in. Something!

Does CR's translation use different DTE tiles? I need to check it out... is there a full script available? Will be a good time to finalize--or try to--the tiles for text. Like in the intro I have a tile that's just .' and is only used there...  but if it needs to be, I could see about making it in the normal text tiles. I'm also picky about ellipses being only three dots, so I fiddled with the DTE to make that happen.

Also with the new list of common strings, town names and other important bits that are re-used a lot can be compressed in dialogue strings! But the important thing is to see how they are decompressed, to know where to put line breaks.

Dialogue box is 28 wide and 7 high, if we keep a border of space between the box and text. 30 wide and 9 high if we squish things in.

Bank 09 is story text--all the bridge scene stuff and ending as well, I hope.
Bank 0A is items, enemies, magic, battle messages, spell descriptions.
Bank 0E is item descriptions, might need to shuffle things around to make those fit.
Bank 10 is environmental text; graves, wells, treasure chests, altars.
Bank 11 is NPC talk.



I AM A GENIUS



Next up, getting the coordinates right. Then, think about the colors some more. Right now I'm going with:

; 0 = floor
; 1 = wall
; 2 = treasure / things to talk to / water
; 3 = other / trees / pillars
; 4 = exit / shop

But maybe for towns, its okay to use the wall color as floor?

I also have to go through all the tilesets in FFHackster and adjust the LUTs; each tileset has its own. So if that's something you want to tackle, Vanya, lemme know before I do it. xD I might do the castle one just so I can make sure rooms aren't messing up.

The background is a bit bright, but I was thinking of using the sprite CHR as the top and bottom, to kind of make it look like a map...

Bad Photoshop: https://cdn.discordapp.com/attachments/505736168659353601/711397706660053002/unknown.png





All better!



Looks like we're gonna need to edit some maps though... Why IS it shifted over like this? This is a map data issue in the original, not my minimap code breaking!

Coneria Castle 1, Sea Shrine B1 (might be okay), Sky Palace 4F (shift 1 up and 1 right)--those should be the only problem maps... Unless it would be better to shift EVERY map over so its more centered! There is enough ROM space for it.


May 17, 2020, 03:07:06 pm - (Auto Merged - Double Posts are not allowed before 7 days.)


In the interest of making this fully modable, I'm taking out the animation of the overworld minimap. And because its slow.

Since the minimap fills ocean tiles with title and dragon-emblem tiles, any major changes to the world map will get screwed up. I don't want that! So the map itself must take full control over the background pattern table.

To have more than just the map graphics on this screen, a special VBlank routine needs to have full control over scanline processing to swap between sprite and background pattern tables. And to draw the map while that routine is going on is beyond me...



Too bad I can't put anything on the sides of the actual map space...

Gotta keep fixing sprites not being in the right place, work on making sure that the loading and unloading is smooth (I can't find where its turning the screen on before its done drawing the map!) and then add in swapping functionality to the overworld.

The world map loading is still taking a few seconds even with the screen off. I'm really not sure how to speed it up any. I guess it could animate while the map color is in full screen, then just... switch the new VBlank routine on to slap on the edges and title in after? But that's gross...

One idea is to scroll to another nametable while loading, then just have a little "Loading..." message until its done, then swap, or scroll over?

Can you switch mirroring modes mid-game so it can scroll up from the bottom of the screen?





The zoomed in overworld would have looked like this, but... it doesn't load into RAM the way I expected. I suspect its loading the whole row... or 4 rows? I'll sleep on it, hopefully no more fever dream coding. See if I can think of a way to somehow decompress the world map in another way. A counter for how many tiles each row was decompressed into, so it can skip to the next row...?

Otherwise, I think its pretty much done! The tile-to-pixel tables still need doing, I'll probably do that soon.

I really wish FFHackster was updated for modern computers with their giant screens, so I can actually see the whole map in editing. And a "shift entire map and wrap the tiles around" command would be wonderful. Wonder if there's any map editors out there that will do it alright?
« Last Edit: May 18, 2020, 02:59:25 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.

Chaos Rush

  • Sr. Member
  • ****
  • Posts: 285
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #567 on: May 18, 2020, 04:20:13 am »
Quote
Does CR's translation use different DTE tiles? I need to check it out... is there a full script available? Will be a good time to finalize--or try to--the tiles for text. Like in the intro I have a tile that's just .' and is only used there...  but if it needs to be, I could see about making it in the normal text tiles. I'm also picky about ellipses being only three dots, so I fiddled with the DTE to make that happen.
Yes, it does use different DTE tiles. My translation is done directly on the Japanese ROM, so a lot of data stuff will differ.

The script for my translation can be viewed using a text editor that I’d like to keep on the down-low. This is buried in a single post in my thread, so I’ll just quote it here:
Quote
In addition to that, I am releasing my FF1 text editor, AirshipText. It supports full text editing of pretty much any NES/Famicom version of FF1, and also has partial support for FF2 (can view text in the Japanese and translated versions). I am choosing not to put it on the database for now due to its rather incomplete state.

AirshipText link: https://www.mediafire.com/file/j7r6c4980uux1x8/AirshipText.zip/file
Anyhow I don’t want to publicize this text editor too much because I don’t plan on maintaining it any further, but you can use it to view the text in my translation (as well as other versions of FF as well).
Creator of STARLIGHT LEGACY intended to be released on Steam.
Discord: https://discord.gg/fTS5Q78
Twitter: https://twitter.com/jmatz1995

Vanya

  • Hero Member
  • *****
  • Posts: 1639
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #568 on: May 18, 2020, 12:53:20 pm »
@Jiggers: You ARE a genius! This s all coming along amazingly.
If you can tell me what I need to do I can do the LUTs in FFHackster, too.

@Chaos Rush: Thanks for the info and the link to the editor! It'll be a big help. :)

Disch

  • Hero Member
  • *****
  • Posts: 2810
  • NES Junkie
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #569 on: May 18, 2020, 02:54:46 pm »
FWIW I'm going to have to retract my offer to do the RNG thing.  I just can't find the time.  Sorry.   :'(

But I'll keep peeking in the topic every now and then to see if there's something I can contribute.

Jiggers

  • Sr. Member
  • ****
  • Posts: 355
    • View Profile
    • My Ko-Fi Page
Re: FF1 MMC5 Disassembly Updates
« Reply #570 on: May 18, 2020, 08:17:15 pm »
No worries! The project's not as hurting for fixed bank space as I thought, so a 256 byte RNG isn't a big a problem as it used to be.

Quote
If you can tell me what I need to do I can do the LUTs in FFHackster, too.

Ah, they're not in Hackster... and I haven't updated my minimap changes to github until I'm satisfied with it...  I'm gonna keep tinkering, see if I come up with any new ideas. Like changing the palette for different maps--bluey for ice caves, red for the volcano and so on.

So you can just focus on the translation stuff if you like!

I thought I figured out a zoomed in overworld minimap, but its still coming out mostly gibberish.

1. DecompressMiniMap sets up 2 rows of overworld tiles at $0500 and $0600. It uses mm_maprow to get the pointer to the row of tiles.
2. ow_scroll_y - #32 should be 32 rows above the player's position. I save this as mm_maprow.
3. $0500 is put into a pointer, then the pointer is incremented after every read, and read with Y=0.
3. ow_scroll_x - #32 should be 32 tiles before the player's position. I save this as the low byte of the pointer, so an ow_scroll_x value of $93 becomes $73, and the pointer starts at $0573--73 tiles into the first row. (Should this value be too high, the routine will start reading from the second decompressed tile row at $0600. I think that should make the edges wrap around when zoomed in.)
4. The rest of the PrepRow routine is the same as it is for towns, but mm_maprow is incremented twice to take into account that DecompressMiniMap does 2 rows. Looks like that might be a logic error on my part.
5. There are no real tile counters involved, but it seems like the tile-to-pixel conversion handles that in its own weird way.

I can't think of anything else I'm missing...



There are so many sprites and they seem to be trying to do the shape of the Coneria peninsula in the sprite viewer?



That led me to believe that the tileset pointers might be wrong, and I was correct! I made a whoopsie and it was still trying to use the town tileset color conversions.



I don't know why the palette changed here, but at least you can see the shape of things.

Bah, I was dumb and put the : one line too high in that last fix.



Just got to fix the sprite locations!



Update! Minimaps are live. Can zoom out to the original overworld map, but not back in at the moment. Zooming out turns the screen blue, need to fix that somehow. Really the whole overworld stuff takes too long with the decompressing and drawing.

Oh, yeah, and only towns and castles still. I'll set the rest up and update soon as I can.
« Last Edit: May 19, 2020, 01:56:05 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: 1639
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #571 on: May 19, 2020, 06:22:13 am »
Nice! OK. Then I'll be on the script then.

Jiggers

  • Sr. Member
  • ****
  • Posts: 355
    • View Profile
    • My Ko-Fi Page
Re: FF1 MMC5 Disassembly Updates
« Reply #572 on: May 19, 2020, 05:21:07 pm »
Playing around weight pixel priority:



In the original, mountains have the highest priority, then desert, then land. Here I swapped land and water:



In my experiments, these two are kind of the only viable versions. In combining 4 tiles into 1 pixel, we get weird stuff if we try anything else:

; 0, 4 = zero weight     : dark green - land
; 1, 5 = lightest weight : brown - mountains
; 2, 6 = medium weight   : blue - water
; 3, 7 = heaviest weight : pale yellow - desert, docks, buildings

This means where water and mountains are side by side, they turn into desert. The original game got around this by giving mountain edges a weight of 1... wait... if that's 0, then...



How's that for a compromise? I really just wanted the rivers to show up blue, and if they only do that in mountains, then... that's alright maybe?

Apart from the elephant trunk in the northwest and the canal spot, I kind of prefer #2 though. It makes Cardia look more like islands, doesn't give you the impression you can just walk around everywhere (you can't), and really shows off Crescent Lake and the bays. Much more defined, at the cost of a little more resolution.
« Last Edit: May 19, 2020, 05:26:50 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: 1639
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #573 on: May 19, 2020, 06:03:08 pm »
I agree.
Despite the trunk getting trunkated (!awful!), I like #2 the best.

Jiggers

  • Sr. Member
  • ****
  • Posts: 355
    • View Profile
    • My Ko-Fi Page
Re: FF1 MMC5 Disassembly Updates
« Reply #574 on: May 19, 2020, 07:46:33 pm »
Woo! Setting the ocean-land tiles to land fixed up some issues.



Think that's as good as its gonna get unless someone edits the overworld map specifically to make this look good. Which is just silly.

And now I can turn my blurry TV filter back on!
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: 1639
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #575 on: May 20, 2020, 05:42:06 am »
Excellent!
The problem with the canal area is the narrowness in the vicinity of rivers.
It's too much a mess for the mapping routine to handle without hard coding things.
And we definitely don't want that.

EDIT: There's no way to make the rivers a lighter shade of blue, is there?
« Last Edit: May 21, 2020, 05:37:55 am by Vanya »

Jiggers

  • Sr. Member
  • ****
  • Posts: 355
    • View Profile
    • My Ko-Fi Page
Re: FF1 MMC5 Disassembly Updates
« Reply #576 on: May 21, 2020, 03:07:30 pm »
Nope, only 4 colors for the map, and sprites.

If anyone knows of a basic level/map editor that deals with RLE compression, I'd love to know. The compression is super simple: 00-7F is the tile, high bit set means the next byte is the repeat count, $FF is end of data, and $00 is I guess a repeat count of 256?

Otherwise I fear I'll have to do this:
* Cut and paste the map data from this project's ROM into a vanilla FF1 rom.
* Open in FFHackster and manually export every single map, which decompresses them.
* Open each file in YY-CHR and use the bit shifting functions to center the map.
* Re-import each map into FFHackster and clean up any mistakes.
* Cut the new compressed map data into .bin files for importing into the next build.
** Keep a list of how each map was shifted and manually update teleport and NPC coordinates!

I have to do that last one either way, but the first 5 steps could be really simplified if I could shift compressed maps!

Actually, I only need a decompression/compression program that I can set up with the right RLE info.

$00 - $7E : copy this byte
$80 - $FE : remove high bit from this byte, use next byte as amount of times to copy $00-$7E
$FF : end of file

Its so very simple, but every program I've found uses something else, even if its a general-use tool and not for a specific game.
« Last Edit: May 22, 2020, 12:05: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.

Vanya

  • Hero Member
  • *****
  • Posts: 1639
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #577 on: May 22, 2020, 12:10:58 pm »
I don't know any specific ones up the top of my head, but let me see what I can dig up:

Found only two things that maybe could be useful:

https://www.romhacking.net/utilities/1395/

For (de)compression.

and

https://www.romhacking.net/utilities/967/

Could have a plug-in made for it to work with Final Fantasy, maybe.
« Last Edit: May 22, 2020, 12:20:08 pm by Vanya »

Jiggers

  • Sr. Member
  • ****
  • Posts: 355
    • View Profile
    • My Ko-Fi Page
Re: FF1 MMC5 Disassembly Updates
« Reply #578 on: May 23, 2020, 07:21:10 pm »
I've looked all over. I don't have the mental fortitude to try installing Perl at this point, and the other one is giving me .NET errors, so I give up for now. I've spent more time looking around and trying things than I would have spent doing it manually at this point.

Made a load of changes to how the minimap loads things. Now I have a weird problem.



This happens just for 1 frame. Order of events:
* soft2000 is set to use sprite CHR as background tiles
* draws the top third of the screen
* at scanline 71, switch to BG CHR as normal
* do music updating between these two scanline checks
* at scanline 199, switch back to sprite CHR as background tiles
* draw one pixel row per frame during VBlank
* at the last row ($0F00) of filling in the BG CHR, pause and set up the zoomed out overworld map
* this does it own VBlank-esque routine (with no NMIs):
-- * calls music first, so that the wait between the two scanline checks is used to convert tiles to pixels
-- * decompresses 2 rows of overworld data while drawing the top of the screen, before scanline 71
-- * for whatever reason, the scanline checks have to be +1-- 72 and 200-- or else this line stays visible until its done
* when done "drawing" the zoomed out overworld map to RAM:
* finish up drawing "Press A To Zoom Out" on the screen, then enable sprites



The bold part is where these two scanlines blip out. The two routines that handle drawing:

Code: [Select]
;; JIGS - this assumes that soft2000 has bit $10 set already
;; so it starts with using the sprite CHR as background tiles

DoMiniMapVBlank:
    LDA $2002     
    BPL @Wait     
    LDA #0       
  @Loop:
      SEC         
      SBC #$01   
      BNE @Loop   

  @Wait:
    LDA soft2000   ; turn on the wait for NMI bit
    ORA #$80
    STA $2000     
   
    LDA #71        ; and set scanline #71 as the one to break on
    STA $5203

   @WaitForScanline71:
    LDA $5204      ; high bit set when scanline #71 is being drawn
    BPL @WaitForScanline71
   
   @Scanline71:   
    LDX #$10       ; waits for H-blank so as not to draw weird dots on the screen
  : DEX       
    BNE :-   
    LDA soft2000
    EOR #$90       ; turn off sprites-as-background-tiles, but turn on the NMI bit thing if its off
    STA $2000
    LDA #199       ; set next break at scanline #199
    STA $5203     
    JSR CallMusicPlay_L
    ;; now there's nothing to do but wait, so while the screen draws
    ;; spend 16 or so scanlines updating the music
    ;; this might be stupid risky
    ;; but vblank has more important things to be doing!
   
  @WaitForScanline199:
    LDA $5204      ; high bit set when scanline #199 is being drawn
    BPL @WaitForScanline199
   
   @Scanline199:   
    LDX #$10   
  : DEX       
    BNE :-   
    LDA soft2000         ; still has bit $10 set, so will set sprite CHR as background tiles again
    ORA #$80             ; turn on the NMI bit again just in case...
    STA $2000
    LDA #$00             ; and clear the scanline break register
    STA $5203     
   @LoopForever:
    JMP @LoopForever     ; then loop forever! (or really until the NMI is triggered)

That's for normal frames, when the overworld isn't being updated in the background.

This next one has NMIs disabled, so its not interrupted:

Code: [Select]
OverworldMap_Prep:
    LDA #0                     ; reset low byte of PPU addr to 0
    STA minimap_ptr

OverworldMapPrep_VBlank:
    JSR CallMusicPlay_L
   
    LDA #72                   ; and set scanline #71 as the one to break on
    STA $5203

MiniMap_2Rows:
    JSR LongCall
    .word MinimapDecompress    ; decompress 2 rows of map data
    .byte BANK_OWMAP
   
    LDY #0                     ; Y will be the x coord (column) counter
    STY tmp                    ;; JIGS - tmp is used as a backup for Y     

   @Wait:
    LDA $5204      ; high bit set when scanline #71 is being drawn
    BPL @Wait
   
   @Scanline72:   
    LDX #$10       ; waits for H-blank so as not to draw weird dots on the screen
  : DEX       
    BNE :-   
    LDA soft2000
    AND #~$10      ; turn off sprites-as-background-tiles
    STA $2000
    LDA #200       ; set next break at scanline #199
    STA $5203     

  @MainLoop:        ; tmp+7 is a counter to keep track of the number of bits
    LDY tmp         ;  that have yet to be shifted into the output CHR bytes
    LDA #8          ; since each byte is actually 8 pixels on a bitplane... multiple pixels         
    STA tmp+7       ; must be rotated into the same byte to be output as graphics.7   

  @RotateLoop:
    LDX mm_mapbuf, Y            ; here we get the minimap tileset data for 4 seperate
    LDA lut_MinimapTileset, X   ; map tiles (in a 2x2 square) and OR them together to combine
    LDX mm_mapbuf+1, Y          ; them to a single pixel.
    ORA lut_MinimapTileset, X   ;  This scales the map down from 256x256 tiles
    LDX mm_mapbuf2, Y           ;  to 128x128 pixels
    ORA lut_MinimapTileset, X
    LDX mm_mapbuf2+1, Y         ; after all this, A contains the output pixel (low 2 bits)
    ORA lut_MinimapTileset, X   ;  and bit 2 indicates whether or not a marker sprite needs to be placed here

    LSR A                       ; shift out low bit
    ROL mm_bplo                 ; rotate it into the low bitplane

    LSR A                       ; shift out the high bit
    ROL mm_bphi                 ; rotate into high bitplane

    LSR A                       ; shift out marker sprite flag
    BCC :+                      ; if set....
      JSR DrawOverworldSprite   ; ... generate a dungeon marker sprite

  : INY                         ; increment our X coord by 2
    INY                         
    DEC tmp+7                   ; decrement our bit counter
    BNE @RotateLoop             ; if more bits needed to fill our bitplanes... keep going

    ; @RotateLoop exits when 8 pixels have been shifted into both high and low
    ; bitplanes.
    STY tmp                    ; JIGS - backup Y - original code used X, but not these kinds of pointers!
    LDY minimap_ptr            ; use low byte of dest pointer as index for draw buffer

    LDA mm_bplo                ; copy both bitplanes to the appropriate areas of the buffer
    STA (MiniMap_DrawBuf), Y
    TYA
    CLC
    ADC #$08                   ; increment destination by 8
    TAY
    LDA mm_bphi
    STA (MiniMap_DrawBuf), Y
    TYA
    CLC
    ADC #$08                   ; and then another 8
    STA minimap_ptr            ; backing up the pointer
    BCC @MainLoop              ; if there was no carry, keep looping
    ; otherwise, if there was carry, we have completed a single row from 16 tiles (128 pixels) 
   
    INC mm_maprow              ; increment map row counter by 2
    INC mm_maprow

  @WaitForNext:
    LDA $5204      ; high bit set when scanline #199 is being drawn
    BPL @WaitForNext
   
  @Scanline200:   
    LDX #$10   
  : DEX       
    BNE :-   
    LDA soft2000         ; still has bit $10 set, so will set sprite CHR as background tiles again
    STA $2000
    LDA #$00             ; and clear the scanline break register
    STA $5203     

    LDA minimap_ptr            ; increment dest PPU address by 1 (next row of pixels)
    CLC
    ADC #1
    AND #$07                   ; and mask with 7 (0-7)
    STA minimap_ptr
    BEQ :+
       JMP OverworldMapPrep_VBlank
    ;BNE MiniMap_2Rows          ; once it wraps from 7->0, we've filled 256 bytes of graphic data (8 rows of pixels)                         

  : INC MiniMap_DrawBuf+1      ; increment high byte of source
    INC minimap_ptr+1          ; increment high byte of PPU dest
    LDA minimap_ptr+1
    CMP #>$1000                ; see if the high byte is #$10
    BEQ :+
       JMP OverworldMap_Prep      ; if not, do another $100 bytes
  : RTS

Switching back to using the normal MinimapVBlank routine after the overworld stuff is done, this glitch doesn't happen.

« Last Edit: May 23, 2020, 07:33:54 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.

Disch

  • Hero Member
  • *****
  • Posts: 2810
  • NES Junkie
    • View Profile
Re: FF1 MMC5 Disassembly Updates
« Reply #579 on: May 23, 2020, 08:42:42 pm »
Just gonna throw this out there...

... maybe this is another opportunity to learn some Python?  Any time you have a small simple task like that map decompression, it's easier than you might think to whip up a Python script to do it.

EDIT:

But if you wanted a decompression/recompression program, how would you want it to work?
How about something that reads the ROM, and then creates ~60 (or however many maps there are) files.
And another that takes those same files and recompresses/injects them into the ROM.

Do the maps need to all be in separate files?  Or could it just make one big file with the maps stored consecutively?

Would that work?  Would you want the in/out offsets to be configurable?


EDIT 2:

A neat idea, since you're using the disassembly, would be to have the decompressed maps stored with the disassembly as bin files, then run a compression program as part of the build script.
« Last Edit: May 23, 2020, 11:10:22 pm by Disch »