Really happy with the way this is panning out so far. I’ve done a few things to be proud of:
* Momentum on the angular rotation
* Angular positioning accurate to 8.8 precision (the display is only 8.0 precision but you really feel the extra precision in the input)
* 8 times more accurate perspective correction
* Much more optimised raster renderer - see below
* An optimised Raycaster
* Jerry-rigged fish-eye correction
* Er… you can’t walk through walls any more
* 14-16 frames per second!
Just a quick note - it’s *really* hard to play these demos while holding a mobile phone as a video camera. Sorry for being so crap at multitasking…
The raster renderer! I was trying so hard to get this to speed up, and didn’t seem to be having much luck. In fact it seemed to slow down. WTAF? Felt I was going mad. Then when checking some simple loop counter I realised I’d tweaked it to render each frame *twice* before displaying… Dummy.
Now it’s so smooth! I’ve got checks in there that avoid printing strips (vertical bits of wall) if the wall is the same colour (as the last displayed frame in that position), and the same size or smaller. I just repaint the top and bottom of the current graphic with the sky and ground. The actual printing itself is quite nice too, I unrolled the print routine to just LD (HL),A; INC H; then jump into the routine where needed. At the bottom of the strip, I swap to odd lines and repeat the trick. So the main bulk of the routine prints walls at 5.5ts per pixel, which is just rad.
I’ve said it before but it bears repeating: with complex, full-screen updates, it just doesn’t seem to matter about hitting the 50fps speed. I think if the community had aimed for a more realistic option people wouldn’t have given up on producing software for it… just my arrogant opinion though…
Some other bits I’m not so pleased with yet. I’ve been experimenting with a better raycaster, and got a really good system going. It implements a Bresenham line drawer over the map to check where the rays hit, and each loop is only around 40ts… It’s hard to get an accurate measurement because each angle hits the Move Sideways and Move Forward parts a different amount of times… But still very fast for my money. However it’s not yet at the point where it can tell me *where* within each cell the ray has hit, which is critical to me reducing the resolution of the map and introducing texture mapping again.
The main problem with my approach was the naive way I cast the rays. These guys are pretty disdainful of my obvious mistake :D Instead of aiming to keep the rays the same distance apart, I just worked out 256 equidistant angles in a full turn. This means no amount of smart fish-eye correction will stop the edges of the screen looking plain distorted. However the alternative seems to be using arc tan functions to get a more accurate angle for each ray, and that’s difficult to store for all the angles I can point the camera in. So I’m seeing if I can just expand my stored angles by a factor of, what? 8?, and approximate it.
It’s a shame, because I had a *doozie* of an optimisation idea in the old system. Imagine if you haven’t moved, you just move the camera… Think of all those rays that were already cast, I could just reuse them, cast the remaining few new ones, and bob’s yer uncle. Alas, it’s just not practical. I’m not sure I’d want a raycasting engine that’s so optimised that it’s twice as fast to render when turning round than walking.
Other fun stuff that’s swimming around in the ideas pool right now is gameplay features. One thing I’m getting out of the way immediately here is to decouple the input from the rendering cycle. Even though it takes 3 frames to update the screen, the input will read at 50fps so it feels really responsive. I don’t know why I’m thinking about this stuff as it’s going in the demo and won’t be playable… unless… nah, that would be crazy… Right? (What have I got myself into?)