Update: SilkWorm Tribute

Lots of trial, error and frustration has got me to this stage:


This video was screen-grabbed from pcem running as a 386SX.

386s are SLOW AS ALL HELL, so I had to do some trickery for the parallax scroll:
  • Use a 'trash buffer': I set up the VGA so there is 32px of invisible data to the left and right of the display (and also above it).  This means I don't have to worry about clipping my sprites.  If they're even partially on-screen, there's enough trash VRAM around the screen that it won't wrap round or corrupt other pixel data.
  • Shrink game area: use a status display to shrink the rendered game area.  I did this with the VGA's Line Compare functionality, so that when it reaches pixel row 176, it will reset to render from VGA offset 0x0000.  (I also had to change the Pixel Panning Mode bit in the Attribute Mode Control Register because I use hardware panning).
  • Solid colour blanking: this can be done with an asm rep stosb and a suitably large value in cx.  A lot quicker on a 386 than reading then writing pixel data.
  • Chain-blitting background bitmap: I wrote asm code to copy the same bitmap all the way across the screen.  Using the VGA latches, I could get 4-px-per-write, use rep movsb to copy the whole row of source pixels, then reset ds:si to the start of the source row and do it again the whole way across the render buffer.  I could still only do 32 rows like this before I noticed a slowdown though.
  • Hardware panning: The front scrolling layer is rendered once to each render page at the start of the program and not touched again.  This saved hella time, but it does mean I can't render any sprites over it.  I found this YouTube video really helpful for this.
I'm gonna take a break from this project for a while because it's quite frustrating to work on.

There is currently a bug with the keyboard-handling interrupt - it misses key releases when you quickly change direction (e.g. down to down-right to right).  It means that the helicopter gets stuck moving in a particular direction until you press and release that direction key again. 

I suspect the problem is my interrupt handler taking too long (i.e. it's still running when the key-release code would come through, so it misses it).  I don't think it could be faster without using a buffer (e.g. the handler just dumps the keyboard data into a buffer to be processed outside the interrupt).  But then, writing keyboard data to a buffer by hand feels like re-inventing the wheel - surely there's an easier way? :/

My whole sprite system was set up so that I could do clipping.  Using a trash buffer meant I could remove the clipping checks to speed it up.  However, if I don't need to clip, I could set up the data in a much more speed-friendly way and make my rendering routing a lot smaller, reducing the cycles wasted on loading those instructions.

I think next month I'll work on a Godot project.




Comments

Popular posts from this blog

Micro:Bit and SPI display

DCS World with TrackIR under Ubuntu

Cardboard Mock-up of USB Joystick