So with the tools having advanced a little more, I was now looking to get some lemmings on screen. I was still unsure exactly how many Lemmings I might actually get running, so after getting that Lemming on screen, I needed to get some variables I could use.
Now, BBC Basic doesn’t do structures, just arrays, and storing things in one big old array would make access pretty annoying. Now you could offset inside the same array like this….
The problem with this, is that it’ll need to lookup LemData, then add on both index% and LemX% each time, and that’s a performance hit in an already slow BASIC interpreter.
So the best thing to do, is just have multiple arrays. As BASIC does lookup the array itself each time, using different one’s isn’t a performance hit, and since there is no cache, we don’t need to worry about cache misses. So what does that look like?
So as you can see, this is much nicer, and BASIC will run quicker too, so win win! Now that I have this, I need to make a basic processing loop. This is a pretty simple FOR/NEXT loop, with a check to see if the Lemming is active.
A reminder here of course, that it’s my pre-processing tools that are allowing goto “labels”, as otherwise I’d need to use line numbers here.
The next thing we need here, is a collision map – something for us to “fall” and “walk” on. Now I can’t use the raw bitmap data for the level, as not only are they in sprite/bitmap memory, and they take up way too much space. So another quick C# program, and I convert the 24bit image, into a single mono bitmap, this takes up far less memory and so we can load this into a simple 6400 byte array.
The only little trick here, is that I’ve not converted it “exactly” into a normal bitmap image. This is because when you read a byte of memory, you get 8 pixels to check, and you normally have to invert the 0 to 7 into a 7 to 0 value. Why is this? Well, because when we get a lemming X coordinate, we AND the lower 3 bits giving us X mod 8 (the remainder of a divide by 8) and that’s a 0 to 7 from the left hand side – as our origin is the top left of the screen. But the for a true bitmap, pixel 0 is actually a $80 which is bit 7, not bit 0.
So to stop having to do this, I simply flip those values, making $80 and $01, $40 becomes $02 and so on. This means I simply have to AND the X coord with 7, and then shift a bit up by that amount, then AND that with the mask. Though after doing all this and feeling very full of myself, I then had to use an array to look up the bit – instead of doing a shift as BBC BASIC doesn’t have that, I then noticed I could have just flipped that bit array instead. Oh well….
I write a simple collision lookup function that returns a 0 for no collision and not zero if it’s solid ground.
Next up, we need to actually process some Lemmings, dropping them out the entrance and then hitting the ground. Before we do that, lets talk about the basic Lemming walker rule. The collision pixel for a lemming, is the pixel under the feet, and the normal rule is the if there are up to 5 pixels above that pixel, then a lemming can climb that in a normal walk cycle, otherwise they’ll need to turn around.
If there are more than 4 pixels empty below, then the lemming will turn into a faller, and start falling. I’ve not bothered with fallers in this demo, it’ll just stay in a walker animation, but I could swap. If a faller falls more than a third of the screen – about 54 pixels, then they’ll splat. All other skills fall off this. You’ll turn into a floater after falling a few pixels, and you’ll turn into a climber if there are more than 5 pixels to mount.
So lets start the loop and then we do “climbing” first, as that lets us walk up single pixel diagonals,
Here you can see the start of the loop, and we read out the X and Y into local variables – so it’s quicker to access, and then we loop over the collision pixels counting “solid” ground pixels. As soon as we hit a zero, we abort the loop and can start looping downwards instead,
So, here you can see I check to see I check to see we found any “up” pixels, and if not, we enter the loop and look for “down” pixels.
But… what you’ll also notice is the use of a multi-line IF, something again BBC BASIC doesn’t do. So how does that work then? Well, back to my pre-processor….
I thought about this for a while, and I came up with a sneaky solution…. Because I already deal with GOTO labels in my pre-processor, I decided to replace the ENDIF‘s with an autogenerated GOTO label, and then add a GOTO at the end of the then. In order for that to work, I need to invert the IF condition, but this is pretty easy, and just involves putting a !([condition]) around the IF. So in the example above, we end up with if !(yd%=0) goto LABEL, and this works really well. At some point I’ll need to add an ELSE in there, but don’t need that for now…
Next we need to then move the Lemming left or right depending on the direction and add on the Y delta we’ve worked out – up or down…
Lastly, we need to actually animate the Lemming. Lemming animations are a little special, as they are tied directly to the sprite position. So we AND the X coordinate with 7, and that is the frame number we use. This helps let lemmings look planted onto the floor, and also helps keep lemmings clean on screen.
And this is the core of the Lemmings processing loop, a basic walker is pretty simple, and under BASIC we can get 20 lemmings walking. That’s actually pretty impressive, as the original Lemmings on the Spectrum only had 20 lemmings, and it was in assembler, not BASIC, and that just shows how fast this little machine is – and how much you can do with BASIC on it.
You can find all this source, and my tools up on my GITHUB: https://github.com/mikedailly/Agon