Blade Story - my Zelda clone using MMC5

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Blade Story - my Zelda clone using MMC5
by on (#150523)
As people visiting the Newbie board may remember, I'm diving into an original NES project using MMC5 (possibly eventually getting a cartridge release on the Retro VGS game console). It's gonna be a Legend of Zelda clone with more story, I'm tentatively calling it "Blade Story".

Image

So here it is, at what I consider the true beginning: title screen, and then being able to walk around a single overworld screen. Pretty early of course, but hey if anyone wants to try out my first attempt at programmer art mixed with programmer music and programmer gameplay, have at it :)

http://www.dreamzle.com/blade/bladestory_7_7.nes

P.S. - Man this thing makes me miss the Gameboy Color's Z80 chip - just having a couple virtual 16-bit registers like BC, HL would be so nice, I can see why Nintendo thought using a 6502 would dissuade third-parties from programming it if they were used-to Z80.
Re: Blade Story - my Zelda clone using MMC5
by on (#150529)
In at least my coding style, the 6502's virtual 16-bit registers are $00-$01 and $02-$03. I reserve $00-$0F for local variables.
Re: Blade Story - my Zelda clone using MMC5
by on (#150530)
Zero page was supposed to make up for lack of registers.
Re: Blade Story - my Zelda clone using MMC5
by on (#150533)
When I loaded it FCEUX 2.2.2 with "new PPU" it didn't load anything right. It did look fine with "old PPU", but it may not be running properly in all emulators/hardware. Music is working fine, though.
Re: Blade Story - my Zelda clone using MMC5
by on (#150537)
If you're shooting for a physical release, do you have someone who can produce new mmc5 compatible boards? afaik nobody does that yet, and real mmc5 boards are not readily available.
Re: Blade Story - my Zelda clone using MMC5
by on (#150542)
From my tests it's working in FCEUx 2.2.2 (old PPU), PUnes, Nintendulator, and...one other emulator I forget the name of, Nestopia? It looks like the new FCEUx PPU isn't getting the extended attribute data, that's probably something to do with the fact that you can only write to the extended attribute table while the screen is being drawn (opposite of normal PPU stuff). It could be an incorrect assumption on either mine or the emulator writer's part about whether you can read the MMC5 interrupt flag that says if the screen is being drawn, without actually turning on the MMC5 scanline interrupt. I'll be adding a scanline effect soon (for a HUD at the top of the screen, possibly with its own BG palettes) so I'll be able to test that case out.

As for physical release, I'm not actually targeting the NES but assuming I get far enough along,the Retro VGS. That's a game console that's going to be Kickstartered soon, it uses physical cartridges, and includes an FPGA that can be loaded up with whatever classic consoles they get cores for (or custom cores). It was mentioned in an interview they were going to license cores from Kevtris, and I know his NES core includes MMC5 support, so I'm hoping that's true.
Re: Blade Story - my Zelda clone using MMC5
by on (#150594)
So are you saying that you can't really do an NES release because the boards for an MMC5 haven't been made yet? Why haven't they been made yet?

Also for the title screen. Try going over to pixeljoint.com and see if anyone can do a nice title screen for a decent price. :)
Re: Blade Story - my Zelda clone using MMC5
by on (#150600)
Erockbrox wrote:
So are you saying that you can't really do an NES release because the boards for an MMC5 haven't been made yet? Why haven't they been made yet?
The MMC5 is a ludicrously complicated mapper, extending the NES awfully close to its intrinsic limits. It allows for direct addressing of up to 256 KiB of CHR with 8x8 attributes (using 14 bits for tile # and 2 bits for palette #), up to 8 separate sprite banks when using 8x16 sprites, two extra sound channels, an extra nametable, up to 64 KiB of PRG-RAM that can be banked almost anywhere, vertical (separate left-and-right sections) splits, a hardware multiplier, as well as "ordinary" things like a scanline IRQ.

It's possible to choose a subset of that and get new boards made, but cloning the full MMC5 is well into "real" FPGA territory, making it a fairly expensive endeavor. And the MMC5 had a small enough circulation that getting donor PCBs for any non-trivial number would be relatively hard, too.

On the other hand, it sounds like he's "only" (so far) using the MMC5 for its 8x8 attributes. We've got a few ideas for ways to implement that without adding much hardware...
Re: Blade Story - my Zelda clone using MMC5
by on (#150671)
Yeah, MMC5 makes it hard if I ever want to test on an actual NES - I'd probably have to take apart a Castlevania 3 or Uncharted Waters or something and solder my own ROM chips in. I guess loopy has an early MMC5 core for the PowerPak cart, but as far as I can find it isn't complete.

But, since I was a kid I always heard great things about MMC5, and because I already had to learn to program the NES from scratch and used to program the Gameboy Color (which is quite similar to an NES with MMC5), I thought it'd be extra fun to also write my game for MMC5. Plus, skilled pixel artists are hard to find these days, so I wanted to make their job as easy as possible when I do get one. So the less limitations the better - one palette for char, no real char limit for backgrounds. And the musician can use all the main channels for music, and I'd still have two more MMC5 channels for sound effects.
Re: Blade Story - my Zelda clone using MMC5
by on (#150673)
Even if you can find a reliable source for MMC5 boards, the two more channels will not play on an unmodified NES.
Re: Blade Story - my Zelda clone using MMC5
by on (#150675)
An Analogue NT, though... :P
Re: Blade Story - my Zelda clone using MMC5
by on (#150681)
Dreamwriter wrote:
Yeah, MMC5 makes it hard if I ever want to test on an actual NES - I'd probably have to take apart a Castlevania 3 or Uncharted Waters or something and solder my own ROM chips in. I guess loopy has an early MMC5 core for the PowerPak cart, but as far as I can find it isn't complete.


I believe Loopy's last MMC5 mapper is "complete" for NES. It's incomplete for Famicom. i.e. it has everything except the expansion sound.

If you're really interested in expansion sound, though, I'd maybe suggest the VRC6 instead? It's a very capable mapper, but the sound in particular is very straight-forward to use and versatile. It doesn't have some of MMC5's bells and whistles (e.g. multiplier, expanded attributes, etc.) but it's pretty beefy, and its expansion sound is better. It's also very fully implemented on the PowerPak and Everdrive.
Re: Blade Story - my Zelda clone using MMC5
by on (#150688)
Neat! It's cool so see other people making Zelda clones on the NES!

I gave the demo a try, and came across one notable issue--
When the player touches the top, and/or the right sides of the screen, this causes one of their sprites to offset by a single pixel. I can't say why this would be happening, though.

I *was* going to upload a screenshot, but Imgur is being a butt, today. (busy server)
Re: Blade Story - my Zelda clone using MMC5
by on (#150694)
Why not just use the attachment feature?
Re: Blade Story - my Zelda clone using MMC5
by on (#150745)
Yeah, I've seen the player breaking apart - thanks. I'm not going to allow the player to walk off the border anyways, I'm planning on doing the transition when the player touches the chars at the edge of the screen. That's the next thing I'm adding, support for special chars like that and a couple test screens to walk between. After that it's the HUD at the top and doing a palette swap between the HUD and the rest.
Re: Blade Story - my Zelda clone using MMC5
by on (#150751)
I don't want to be rude but I tried you demo and while the music was promising and felt very "nessish" I don't see in it's current state why you would require the MMC5 mapper. Are you over-engineering your project by any chance? I didn't follow any nes thread recently but I felt I had to comment on this one since I often over-engineered my project in the past so I tought I should comment on it ^-^;;;

Maybe you should try with a more common mapper then switch to MMC5 only if you requires it. Not many games really requires such level of mapper and I'm sure other people on nesdev will tell you the same thing.

Good luck on your project.
Re: Blade Story - my Zelda clone using MMC5
by on (#150755)
You're right that in its current state MMC5 is mostly being wasted (except for the random 8x8 tile palette entry here and there). But realize that everything you see and hear is eventually going to be replaced with professional quality art and music, what's there is my placeholder programmer art.

Also, I like the MMC5, it was fun to figure out its quirks and stuff. By now the engine and pipeline are already set up for multiple char banks and whatnot, and I've used the simple scanline counter (though not in the current demo)
Re: Blade Story - my Zelda clone using MMC5
by on (#151050)
Little update: I now have the player walking back and forth between two screens, each with their own tileset if needed (well, I mean tiles in a different bank, though the only real difference is in my extended atrribute table, so I could mix and match if I wanted). And I wrote a full BG collision system going on rather than just basing collisions on which visual tile is in a spot (it involves creating a map by overwriting the visual map with number-tiles representing the different collision types). I need to organize my screen loading code, though, I didn't do a good enough job making it generic for any screen when I first setup screen drawing.

Image

Next up after the organization: a HUD at the top of the screen with its own palette set.
Re: Blade Story - my Zelda clone using MMC5
by on (#151361)
Got my HUD area at the top, with its own set of 4 BG palette entries being reloaded, for a total of 5 BG palettes total on the screen! It's got a little bit of corruption underneath due to trying to fix the scroll after disabling the PPU, but the palette reloading is all done in the Hblank area off the screen.

Image

You can try it out here if you like:
http://www.dreamzle.com/blade/bladestory_7_23.nes

You can walk to the second screen if you go south, to return to the top screen you must walk north through the HUD around the same region, because I didn't draw the placeholder test maps taking a HUD into account.

I think next I'll do a simple animation of the character walking, and then give her a sword she can swing.
Re: Blade Story - my Zelda clone using MMC5
by on (#151363)
How come one of the first things you've implemented is a 5th palette for the HUD, but you don't even have background art that needs it yet? (Plenty of games are quite content to have a single "reserved" palette and work with only 3. I'm just curious why this feature became such a priority for you?)

Some suggestions:

1. Generally at least the top and bottom 8 lines of the picture aren't visible on NTSC (sometimes a few more). You might want to lower the top of your HUD by 8 or maybe 16 pixels to make sure it's visible?
2. You should also hide sprites until the HUD is finished rendering so that the player and other sprites go under it, instead of on top. If you need sprites on for a sprite-0 test, alternatively you could prevent sprites on the bottom 8 pixels of the HUD by placing 8 sprites there with high priority. (Any sprites above the bottom 8 pixels, you can just eliminate by checking their Y coordinate.)
3. During screen transitions your music gets paused noticeably. You should leave NMI running and play your music there, so that it interrupts the screen rebuild to keep the music in time.
4. Don't re-enable rendering immediately when you're done rebuilding the screen. Wait until the next NMI to write to $2001, so that you can set up the scroll correctly, or your first frame will be misaligned every time.
5. Collision should halt the player on each axis separately. If I'm touching a tree vertically, holding diagonally should still let me move horizontally. The lack of diagonal motion against a blocker has a rather frustrating feel.
6. Walking north from the southern screen, you can get stuck inside the rock.
7. Reset does not clear sprites, and the title screen does not render correctly afterward. (Are you properly blanking memory on reset, or relying on emulators that set it to zero?)
8. Consider a button press to advance the "once upon a time" screen. This is very tedious to wait through, especially when trying to test.
Re: Blade Story - my Zelda clone using MMC5
by on (#151364)
Some more that I noticed when trying out the ROM in NDX:

1) Don't use $0D for black, it can cause problems with some TVs.
2) Make sure to initialize your sprites before doing OAM DMA:
Attachment:
unitialized-sprites.png
unitialized-sprites.png [ 34.64 KiB | Viewed 2274 times ]
Re: Blade Story - my Zelda clone using MMC5
by on (#151369)
Thanks for the great suggestions!

rainwarrior wrote:
How come one of the first things you've implemented is a 5th palette for the HUD, but you don't even have background art that needs it yet? (Plenty of games are quite content to have a single "reserved" palette and work with only 3. I'm just curious why this feature became such a priority for you?)

Well, I don't have any background art at all yet, really - I'm currently not planning on being the artist on this project, the art currently in the game is all programmer-art I created primarily for testing the engine. When I do get an artist, I want them to have as few limitations as possible, because these days great pixel-artists skilled at working with limited palettes are a rarity, so the more I can help them out from the start, the better. It's also one of the big reasons for using MMC5, being able to use as many tiles per map as the artist desires, and not having to worry about keeping palettes on 16x16 boundaries.

And if I do end up doing all the art myself, I *definitely* need all the help I can get - heck, I dedicated an entire palette to a rock!

Also, as an oldschool Gameboy programmer I love pushing systems to do more than they were really designed to do, it's a fun challenge. I had a lot of fun in this case figuring out the timing of getting the palette reloading with minimal corruption (now I just need to get rid of the scroll corruption on the bottom edge).
Re: Blade Story - my Zelda clone using MMC5
by on (#151373)
Dreamwriter wrote:
I had a lot of fun in this case figuring out the timing of getting the palette reloading with minimal corruption (now I just need to get rid of the scroll corruption on the bottom edge).

It's worth noting that this is the kind of thing you should test on real hardware. These fine timing details often vary a lot from one emulator to another, so it's better to calibrate them according to the real hardware.

That said, the mid-screen scroll change should be easier to get right than the palette change. Since you have rendering disabled for the palette update already, using the $2006/5/5/6 combo and enabling rendering near the start of the next HBlank should do the trick.
Re: Blade Story - my Zelda clone using MMC5
by on (#151380)
Walking on the status bar. Hi.
Image
Re: Blade Story - my Zelda clone using MMC5
by on (#151416)
It looks to me like you room data is still full screen even though the HUD is covering it. Start designing the rooms shorter. And you might want to compress your data. This is just from loading room 1. Look at all those 01's. It will save alot of ROM space to compress this and load it somewhere in the RAM as collision info.
Re: Blade Story - my Zelda clone using MMC5
by on (#151420)
dougeff wrote:
And you might want to compress your data.

At least start using metatiles (which are a form of compression), because raw screens will use up all your ROM pretty quickly.
Re: Blade Story - my Zelda clone using MMC5
by on (#151431)
It's worse than you may think - each screen is composed of the basic nametable map, the extended attributes map, and a collision map, all three the size of the full screen (though soon minus the size of the HUD). Plus the 4 palettes. Don't worry, I plan on eventually implementing compression, probably PUcrunch to be specific. I just want to finalize the BG creation pipeline first (I thought I had, but it's kind-of a pain).
Re: Blade Story - my Zelda clone using MMC5
by on (#151436)
After each new feature I go in and solidify and clean up the code, this time I also implemented many of your suggestions too so I posted the new build if anyone's interested:

http://www.dreamzle.com/blade/bladestory_7_24.nes
Re: Blade Story - my Zelda clone using MMC5
by on (#152146)
New art style - looks less RPG and more Zelda. Maybe a bit too much Zelda...

Attachment:
bladestory.png
bladestory.png [ 3.73 KiB | Viewed 2089 times ]
Re: Blade Story - my Zelda clone using MMC5
by on (#152148)
love the "programmer art" :)
Re: Blade Story - my Zelda clone using MMC5
by on (#152150)
It kind of reminds me of Microsoft Paint art. :lol:
Re: Blade Story - my Zelda clone using MMC5
by on (#152407)
I'm having problems setting the scroll values mid-scanline, can someone tell me what I'm doing wrong? It works fine if SCROLL_X and SCROLL_Y are #0, but anything else and I get weird results (for example, after a certain point SCROLL_X scrolls in both X and Y). I'm trying to do the $2006, $2005, $2005, $2006 trick.

Code:
 ; Set scroll, adding current scanline
  lda PPUSTATUS   ; reset scroll status
 
  ; In-scanline scroll = PPUADDR,PPUSCROLL,PPUSCROLL,PPUADDR
  ; ((Y & %11000000) >> 6) | ((Y & %00000011) << 4) | (N << 2)
  ; Simplified to just (N << 2)
  lda #%00000100
  sta PPUADDR
 
  ; X
  lda SCROLL_X
  sta PPUSCROLL
 
  ; Y
  lda SCROLL_Y
  adc #32      ; Add current scanline+1 to scroll
  sta PPUSCROLL
 
  ; ((X & %11111000) >> 3) | ((Y & %00111000) << 2)
  ; Compute munged Y
  and #%00111000
  asl
  asl
  sta HBLANK_TEMP ; Store munged Y in Temp
  lda SCROLL_X
  lsr
  lsr
  lsr
 
  ora HBLANK_TEMP ; Or munged X with munged Y
  sta PPUADDR


I understand it's not optimized as it can be (and I'm eventually going to move the scroll-pos munging out of there, since this code is in the middle of scanline drawing), I'm just trying to get it to work first.
Re: Blade Story - my Zelda clone using MMC5
by on (#152408)
The order you write to PPUSCROLL is backwards from what you intend. (here it's Y first, then X.) Also, there will be visible corruption on-screen between the 3rd and 4th writes if you change fine X.

If you don't change fine X, consider the faster PPUADDR-only method.
Re: Blade Story - my Zelda clone using MMC5
by on (#152417)
Thanks a lot, just swapping the X and Y in PPUSCROLL worked like a charm. I'll get you next time, PPU!

Here's the demo if anyone's interested, scrolling with HUD (with its own HUD palette):
http://www.dreamzle.com/blade/scroll_demo.nes
Re: Blade Story - my Zelda clone using MMC5
by on (#152423)
Is there some reason you're trying to find the hardest way to do everything? Zelda didn't need MMC5 or use complicated scrolling tricks. Learning how to use them is cool and all, but it can also be a form of procrastination. One way artists spark creativity is to force some kind of limitation... Today I'm only going to use blues. Embrace the limitations, say to yourself, "I can make it work with only 4 palettes for background" :)

"Procrastination" because you spend all your time solving technical problems rather than programming your game.
Re: Blade Story - my Zelda clone using MMC5
by on (#152444)
Actually, The Legend of Zelda did use complicated scrolling tricks, to put their own HUD at the top of the screen - if you want a HUD at the top that doesn't scroll, but your game uses vertical scrolling, you have to. Zelda used sprite-0 collision instead of the MMC5 scanline IRQ, but in the end the technique is basically the same.

And as I've mentioned before, I am not going to be the artist on this, and I can't guarantee that the artist will be amazing at limited-color and limited-tile pixel art, so I'm trying to make their job as easy as possible. And why wouldn't I, when I'm doing this in my spare time? I have no deadlines, and at worst I end up with a good general reusable MMC5 game engine with some nice special tricks.
Re: Blade Story - my Zelda clone using MMC5
by on (#152451)
OK, you're right about zelda. My memory is shitty.
Re: Blade Story - my Zelda clone using MMC5
by on (#152980)
Darn, I just ran into a technical limitation I hadn't realized: just how little time there is per vblank on NES. Only being able to update a couple rows of chars per frame while still updating other things like sprites throws my 4-row HUD under a bus if I want vertical scrolling, since I'd have to update all 4 rows plus the actual scroll-reveal row every scroll update. I can't get around it by keeping the HUD on another nametable, because when using MMC5 extended mode all nametables share the same extended palette/char table.

The only solution I can think of that doesn't involve dropping extended mode or the BG HUD is to use the MMC5 vertical split for a side HUD, but that would be insane (and I'd lose my extra HUD palette). That or turn the HUD off during scrolls, which seems rather janky (admittedly, with the Zelda-style scrolling I had planned on it's not as bad, but still janky).
Re: Blade Story - my Zelda clone using MMC5
by on (#152982)
Dreamwriter wrote:
I can't get around it by keeping the HUD on another nametable, because when using MMC5 extended mode all nametables share the same extended palette/char table.
Can't you turn off the extended nametable behavior for just the HUD?
Re: Blade Story - my Zelda clone using MMC5
by on (#152985)
Most of the NES games I've seen, with free bidirectional scrolling, either use a sprite health bar, or no HUD.

Though, it is an interesting puzzle. Can it be done? And, can it be done without lots of attribute glitches.

Edited.
Re: Blade Story - my Zelda clone using MMC5
by on (#152987)
Lots of games have glitch free status bars combined with bidirectional scrolling. Some of them use name table layout tricks, but since you seem to be stuck with a single name table (unless it's indeed possible to disable extended attributes for part of the screen, and you're OK with that) I think that the solution that would work best in your case is the solution used in Crystalis: simply use mapper IRQs to skip the hud during the rendering of the playfield, and always keep it in the same place. Look at a name table viewer while playing some Crystalis and you'll see how it works.
Re: Blade Story - my Zelda clone using MMC5
by on (#152989)
Check how ROM City Rampage did it, perhaps? Of course, you'll have to rip it out of Retro City Rampage. But it's an MMC5 game with extended attributes, a HUD and multdirectional scrolling. (Though it doesn't try to use extra palette for the HUD, so if that's part of the problem this is a bad suggestion.)

1.70 MB gif of what ROM City Rampage's HUD/Nametable updating looks like: http://i.imgur.com/pP6VDps.gif
Re: Blade Story - my Zelda clone using MMC5
by on (#152990)
Crystalis is a great example, but it does have those attribute table glitches I mentioned. And a nice big line of a glitch, right at the split screen.
Re: Blade Story - my Zelda clone using MMC5
by on (#152994)
Kasumi wrote:
1.70 MB gif of what ROM City Rampage's HUD/Nametable updating looks like: http://i.imgur.com/pP6VDps.gif

Looks like the Crystalis trick to me. If you pause, you can see that whatever is right above and right below the status bar in the name table connect directly in the final render. Also notice that there's a blank row above the status bar in the final render, so that the gameplay window can scroll smoothly without glitches.

dougeff wrote:
Crystalis is a great example, but it does have those attribute table glitches I mentioned. And a nice big line of a glitch, right at the split screen.

Yeah, lots of commercial games were glitchy. The technique is perfectly valid, though, you just have to time it right.
Re: Blade Story - my Zelda clone using MMC5
by on (#152998)
I think I see, don't just use the scanline IRQ once for the HUD at the top of the screen, but also a second and third time to adjust hardware scrolling to show the lines above the HUD as if they were directly connected to lines below the HUD. Tricksy hobbitses! Sounds like a plan...

Disabling extended attributes while rendering a HUD on a second nametable is something I considered trying and might actually work (the HUD is all on char bank 0 and only using one palette), but pushing MMC5 that way is a dangerous thing to do when I don't actually have access to the hardware I'm developing for yet, to test how that MMC5 implementation handles it. The way I'm testing now I've got four emulators, and if what I'm doing doesn't look mostly the same on all four, then chances are I'm doing something wrong or dangerous even if one of the four is doing exactly what I want. As long as I'm not doing anything tricky/out of the ordinary for MMC5 I should be fine with this testing method, worst case is I might need to tweak timing a bit once I can get the game on hardware.
Re: Blade Story - my Zelda clone using MMC5
by on (#153001)
tokumaru wrote:
dougeff wrote:
Crystalis is a great example, but it does have those attribute table glitches I mentioned. And a nice big line of a glitch, right at the split screen.

Yeah, lots of commercial games were glitchy. The technique is perfectly valid, though, you just have to time it right.

Some of the glitchiness of Crystalis might have something to do with the fact that it uses DPCM samples.
Re: Blade Story - my Zelda clone using MMC5
by on (#153007)
Re: glitchy

I'm not trying to complain about Crystalis or its technique. I'd love to see more games like this. My point is, don't expect it to look as nice as an SNES (or later) game.
Re: Blade Story - my Zelda clone using MMC5
by on (#153015)
It doesn't have to look like a SNES game to be glitch free. It is perfectly possible to have a status bar and multidirectional scrolling on the NES without glitches, but you have to spend some calibrating the timing to make sure it's solid, and professional developers back in the day had deadlines that prevented them from spending time fixing things like these.
Re: Blade Story - my Zelda clone using MMC5
by on (#153086)
Any thought to your sound engine? Will you be sticking with the plain 2a0x for audio or will you be using MMC5 pulses too?
Re: Blade Story - my Zelda clone using MMC5
by on (#153094)
Right now I'm using Famitone to play back Famitracker music. I was planning on using the additional mmc5 voices, possibly for sound effects allowing me to use the full NES sound system for music.