Thursday 23 March 2017

NES Homebrew Part 3: On the move

So the next part to tackle is the moving eggs. Moving one isn't so bad, but there's the issue of what happens if they collide. the basic sequence of events is this:

  • Player pushes an egg
  • It continues moving until it hits another egg
  • The previously moving egg stops and the hit egg starts moving
  • This process continues until...
  • ...an egg hits a wall.
  • The egg then reverses direction until it ends up at its home position (which should be next to the previous egg).
  • The previous egg then begins to move....
  • ...until the first one arrives at its home position again.
So how do I manage all of this? Well I figured that a stack-based approach would be best. When a push starts the stack will be empty and a moving object is put into the stack and the background object is removed for the moment. As soon as it hits another egg then the process is reversed, and we remove the moving object and place a background object at that position. Another moving object is created in place of the next egg and it's placed at the next slot in the stack. when an egg hits it's home position again it is converted to a background item once and for all, and the stack unwinds one step. If the last stack item needs removing then the stacksize is set to 255(0xff) to signify that it's empty and no further processing is needed.

Simple enough? Well yeah aside from the usual 'It's all in 6502' type issues. I get around this by having a single-byte stack pointer in the zeropage and using the start of the hardware stack page for my egg movement stack. Each egg description in the stack is only 4 bytes, and with a maximum of 12 on a row or column (13 - where the player is standing) this means we have a worst-case scenario of 48 bytes, leaving 216 bytes for the stack. I can't see it ever going over 128 bytes to be honest so I can rob more of the page if needed.

All addressing is done by declaring the structure elements relative to the base of the stack, loading the stack pointer into the X register and referring to the elements with LDA/STA egg_element,x.

The egg_type element contains the current type in the lower nybble (same way the level data was defined to start with) with the movement direction encoded into 2 bits of the upper nybble, giving us a nice round stack element size that isn't too slow to manipulate.

I'm still a couple of functions short - the graphics update stuff isn't plugged into the right points yet, but stepping through the stack handling and movement code looks like it's working. I have the other code I need but I've written it in a way that makes it a ballsache to reuse, so it looks like some refactoring is needed...


No comments:

Post a Comment