JWinslow23 wrote:
all the code that reads the buttons and updates everything is in NMI, because I wanna make sure it's being done once per frame.
IIRC, Nerdy Nights starts out with one of the worst possible program structures ever: everything in the NMI handler, with the game logic before PPU updates. This is terrible, because you basically have to do everything (logic + PPU updates) in 20 or so scanlines (while the remaining 242 lines of CPU time go unused) or else the PPU updates will spill into the visible picture and glitch everything. That basically means you only get to use less than 8% of the total CPU time if you use that structure.
It's beyond me why anyone would base a tutorial around such a poor architecture. Everything in main would be a much better choice for beginners, because it's also very simple and allows you to use 100% of the CPU time without complications (the trouble only starts if you need more than 100%).
Quote:
Any ideas on how I can move the bulk of this code inside the main game loop (which is still empty)?
You can easily turn what you have into "everything in main". Move the game logic out of the NMI handler and put it into the main loop. Then put the following "wait for vblank" loop right after the game logic:
Code:
lda FrameCounter
WaitForVblank:
cmp FrameCounter
beq WaitForVblank
This will keep the CPU waiting until the "FrameCounter" variable changes, something that will happen in the NMI handler.
Now you can remove the PPU update code out of the NMI handler and put it right after the wait for vblank. Then comes the JMP back to the start of the game logic. Your NMI handler should be empty now, and you can modify it to change that variable I mentioned earlier, signaling that vblank has started:
Code:
NMI:
inc FrameCounter
rti
And that's it. Let me know if something about how this works isn't clear.
Quote:
I'm thinking I would store flags for getting things done inside the main loop, and use the NMI to actually update the relevant values, but I'm a bit iffy on what exactly needs to be done.
That would be split method, the most robust one of you do it right. It's slightly more complicated because you really need flags and such in order to have the separate threads communicate with each other, but you may try going that route if you think it's time.