I want to update an entire name table in one pass. I have so far looked into three ways of doing it, and am wondering if there are other options I am missing.
The first option was to leave the PPU rendering on and update the second name table over the course of eight vblanks, then swap name tables. This looks farily good, but the delay from user input until the results showed up on the screen was at best 10 frames, and at worst 18 frames. This is not too long, but long enough to be very annoying (try playing "Ultima - Warriors of Destiny", that's where I got the idea).
The second option was to disable the PPU, write the nametable, then re-enable the PPU. I thought this would result in one blank frame between updates, and did not think it would be that noticable. What did happen (at least in FCEUX v2.0.2) is my new name table is rendered on the frame (maybe when I re-enable the PPU mid-frame?) but vertically scrolled significantly. This causes eye strain like a bad battling robot anime.
The solution I have now is to throw a figurative brick at it. I am using MMC5's ExRAM nametable feature to update the nametable mid-frame. This has proven to work quite well, and I do like all of the features of MMC5.
My concerns with using the MMC5 mapper are that the mapper's features may not be well supported on some targets (I.E., CV3 works, but ExRAM Name Tables do not), and it is kind of a shame to have to rip apart a fairly rare kart like RTK2 to make a dev cart.
Is there another solution I missed? Is there another more readily available mapper that supports nametable RAM writes mid-frame?
Thanks,
QBRADQ
Quote:
The second option was to disable the PPU, write the nametable, then re-enable the PPU. I thought this would result in one blank frame between updates, and did not think it would be that noticable. What did happen (at least in FCEUX v2.0.2) is my new name table is rendered on the frame (maybe when I re-enable the PPU mid-frame?) but vertically scrolled significantly. This causes eye strain like a bad battling robot anime.
You should wait an NMI (or poll $2002.7) before enabling the screen back so that it's a stable setup.
Bregalad,
Thank you for the suggestion! That works fairly smoothly. Most of the graphics in my project are mostly black (think Ultima 4 PC here), so this actually looks fairly good.
Well, I just tried this method with some motion on the screen, and even at 4 FPS the blanking is too distracting. I suppose I will stick with MMC5.
Thanks again for your suggestion! It was so obvious after you pointed it out
I have been lurking around here for a while now and have grown to enjoy your technical commentary.
Thanks,
QBRADQ
But how much will this MMC5 cost when you decide to put your game on a Game Pak to be played in a Nintendo Entertainment System?
Using the double-buffering method and a partially unrolled copy loop, it's more than possible to copy an entire nametable within four to six frames.
What exactly are you trying to do by rewriting the entire nametable every frame that can't be done with rewriting only a portion?
MMC5 don't allow to write to $2007 during the frame, it only allow you write to EXRAM during the frame. I don't know how well it would work to select the third EXRAM nametable and write it during the frame, if it works you will definitely have to do it via $5c00-$5fff and not via $2007.
Even using a fully unrolled copy loop and completely skipping the sprite DMA I can only get 192 bytes copied within the NTSC VBlank period. Having the sprite DMA occurring every frame is fairly important so I can have a decent looking OAM cycle.
I do not need to update the name table every frame, but I do want to update it all at once. I am going for a setup similar to Ultima 4 on the PC. I realize that this is not leveraging the NES's strengths, but attempting to do what it is the worst at. It's still possible with the MMC5 though.
So here's my thoughts on the MMC5 dev board I have planned. I will be using a Romance of the Three Kingdoms II cart (EWROM board, 32KB RAM). I chose this cart because it has WRAM (which I need), and it's the cheapest MMC5 board I can find on eBay (about $10 for a non-mint cart, shipping included).
After parts and tools (including shipping) it will cost me about $35. I already have a soldering setup and the experience needed to build it, so that's not a problem. The tools include a security bit to get the cart apart, as I do not already have one.
I' d like to find a 512KB Flash in a DIP package that has a serial write interface, but I'm not sure anyone makes that. I'll have a look on Digikey later. Anyway, I've already got a few 256KB EEPROMs laying around, so that will reduce the cost of the first board by about $7.50.
It's also an extremely useful devcart to have around.
Thanks for the concerns,
QBRADQ
Breglad,
I am writing to ExRAM through $5c00 - $5fff during the frame (using the MMC5's InFrame bit of the IRQ status register to tell when it's safe). It works like a charm, and does not eat up too many in-frame cycles.
I still don't understand why you need to update such a large section of nametable. If you need to update more of the screen, go for a newer system like PC-Engine or SNES. NES isn't meant to have the entire NT changed in 1 frame. But if you have an idea figured out and you think it'll work, good for you. But I think it's wasteful to update the whole NT every game frame. You can't possibly need to do so.
Bah! The whole point is to make an NES program! So far I have made little demos on the Apple II and Commodore 64, but I still prefer the NES's dev scene.
I am not updating the entire name table each frame. I am updating portions of it when those portions change.
The screen will be laid out similar to Ultima 4 / 5 on the PC, with a map window 22x22 characters, an information window of 10x22 characters, and a text window of 32x5 characters. The text window will be updated when text is output (in order to scroll), and the map window will be updated each time the player moves.
These updates should only come in four or five times per second, however the 10 - 18 frame delay between input and the map updating is extremely annoying (play "Ultima - Warriors of Destiny" on the NES for an example). Also the screen blanking when using the PPU disable method causes too much eye strain on an emulator, and that is the primary target of this program anyway.
I am 100% in agreement that this is not the best solution for the NES, and I am not defending it. However it does work.
When it gets down to it, I am rewriting a C64 program on the NES, and I am using the MMC5 to enable me to do it.
Again, thanks for the input!
Good luck with your game! I tried out similar brute-force screen-writing ideas when making some animation demos for the NES, and it looks like I got one screen updated in about 9 VBlanks....
If you have a 22x22 window, and can update up to 192 bytes per VB, then doesn't that give you a full map updated in ~3 VBlanks? Game code, joystick polling, message-writing, etc can wait until after you update the main map, giving a greater appearance of speed.
Honestly I had a setup where by I had two 1KB screen buffers in WRAM and then alternated which screen buffer I was updating to. Each vblank I would copy a portion of the previous screen buffer into the name table. Again I was trying to force the NES into the C64 / PC's role.
Now that you mention it, I think I am starting to get an idea of how I can do this without too much tearing on the map display, and no tearing at all on the other portions of the display. This is very exciting, because I honestly would prefer to target the game at a simpler and more readily accessible board such as SNROM. Plus it would be oh so fitting to rip apart my Ultima - Warriors of Destiny cart to develop this on
Also I had wanted to use CHR-RAM rather than CHR-ROM, and this fits nicely too.
Thanks for the discourse, it has really helped me. I'll update this thread when I have a new approach.
QBRADQ