Tuesday, March 2, 2010

Horribly broken mid-screen bankswitching/mirroring

Oops..  Well, at least hardware and software renderers are rendering the same output.  Not quite sure how I broke it, but I think I may be mapping VROM over top of VRAM, and thusly getting junk written on top of it.  I need to impement a cart event debugger/logger, ASAP!

Update:  Nah, the code that could have banskwitched a VROM into VRAM was incorrect, but unreachable in that mapper (Afterburner is the only game/cart/mapper that I know of that has nametables in rom only and bankswitches them).  The code is a little bit complicated, because what I do is keep an array which holds the starting address for each 4k block of VROM, and bankswitching updates these pointers.  To top that off, every time a bankswitch happens, this array is pushed onto the next level of a 2D array, the bankswitch cache, which holds every bankswitch that happened in a frame.  I do this, because for the GPU version, I don't send pixels, but I send the information needed to draw the pixels (the current ppu status bytes, the bankswitch cache, a similarly implemented palette cache, the rom itself, and the vram).

So, a bankswitch, or a change to the mirror bits, triggers a call to UpdateBankSwitchCache, which pushes the current banks onto the stack.  To cut down on redundancy, I decided to only to process a mirroring change, if the new mirroring was different (for a explanation of NES mirroring see the nesdev wiki).  Well, the NES nerds might already see what I did wrong.  if (this.mirroring != mirroring) is not enough.  For one-screen mirroring, the location of the screen is also important.  To me, this makes  if (this.mirroring != mirroring && this.oneScreenOffset != oneScreenOffset).

So, the moral of the story, is make sure you are taking a step back and considering *all* pertinent variables before you optimize something.  I'm also guilty of premature optimization, as the bankswitch cache is as of yet in no danger of overflowing.  Theoretically, there could be thousands of bankswitches during a frame, it's up to the cart and mapper.  Realistically, it's very unlikely, at least on conventional mappers in commercial carts. 

So TMNT and others display just fine, once again.  Happy turtlin'.

No comments: