Friday, 30th September 2005
I completely rewrote every single attack pattern from scratch (pretty much - the precalculated paths were left intact) last night. The result of having the ability to start any enemy attack pattern at any time (within reason - I only provide 8 enemy slots!) results in nothing short of sheer mayhem. Yes, collision detection was disabled for the video. I'm looking at you, evolutional...
The small blobs that drift towards me are the aforementioned mines. The attack frequency, number of enemies on-screen and number of mines is far in excess of anything that you'd encounter in the game - this was just a test to add as much to the game as possible.
Another plus-point of the rewrite is that the game now runs correctly inside MEKA, another widely-used Sega Master System emulator. It had issues with certain attacks keeping their sprites way off screen as they ran in, which worked fine on hardware and in Emukon, but not in Meka for some bizarre reason.
One particular running bug that has been very difficult to trace was an annoying flicker in the sprites. Every so often, some of the sprites would disappear for a single frame. Normally it would be a couple, but sometimes ALL the sprites would vanish.
What could it be? Video timing issues? No, Emukon (the emulator I'm using) pops up incorrectly timed VDP writes in a handy window. Enemy drawing code that was accessing another sprite's data, switching it off? In a similar vein, had I miscounted pointer increments in one particular chunk of code for handling enemies, so in certain conditions it would offset all further array writes by a byte, writing incorrect data into the "enemy disable" byte? After much painful analysis, it appears the routines were pretty watertight... Not PUSHing/POPping registers to the stack before calling a destructive routine?
Well, after much pulling out of hair I have found the problem.
The VDP (the graphics chip I'm controlling) has a certain amount of VRAM. One area in that VRAM is dedicated to a sprite table. First you have a list of Y-coordinates, then a list of X-coordinates followed by sprite index numbers. There is a "magic" Y coordinate, $D0. When the VDP hits this particular Y coordinate, it stops drawing sprites! You can (and I do) use this as a stop byte on the sprite table to tell the VDP when you've finished adding sprites (as each frame has a variable number of sprites on it - I'm trying to keep the game nice and dynamic).
So, what's the problem with that? It turns out that SOMETHING - star code, explosion code, bullet code, enemy attack code, I'm not sure which - is trying to draw sprites with a Y coordinate of $D0! Adding this block of code into my sprite drawing routines (I have two - one for 8x16 sprites, such as the stars, bullets and score digits and another that pairs them up for 16x16 sprites, the size of everything else) fixed the rare flicker bug.
cp $D0 jr nz,+ inc a +:
Nice and simple, but it does the trick.