Saturday 4 March 2017

Initial thoughts

It takes me around 45 minutes to drive to work in the morning, and perhaps a little longer to drive home again, so I get plenty of time to think. Usually I would be thinking about projects at work, but lately I was thinking about what to do with my new found interest in the Dragon. (It's also a great opportunity to listen to the CoCo Crew Podcast, but you can't yet as it's only 2014 and the first episode doesn't come out until next year.)

Maybe I could write a game. I had written two before and knew what was involved. There was even a third partially written game that I could pick up again if I could resurrect the source code. This was a vertically-scrolling-bullet-hell type game that I abandoned after the decline of the Dragon scene. And yet there was still that desire to see a game like Time Pilot '84 on the Dragon, even though I had decided it impossible all those years before.

My son will often ask "why?" at the end of even the most carefully crafted explanations. Most kids do. I like to think it's because they're good engineers and want to challenge assumptions. If you make assumptions then you're making an ass out of u and mptions or something.

Anyway, I'm sat in traffic asking myself "why?" for a variety of reasons but in particular I'm thinking about scrolling:

It's impossible to have an arcade style multidirectional scrolling image on the Dragon.
Why?
Because horizontal scrolling is too slow.
Why?
Because you have to shift the pixels into position before storing them on the screen.
Why?
Because they are not already shifted into the right position.
Why?
Good question...

We could for example have pre-shifted tile data. Several versions of each tile making up the background could be stored in memory, each version pixel-shifted to the required amount and ready for storing directly on the screen.

Well, not exactly directly. A shifted tile will have some empty pixels in the bytes making up the left and right edges. That means those bytes belonging to neighbouring tiles need to be OR'd together because they share the same on-screen byte. Say our original tiles are two bytes wide, then the instructions to put the first row of a tile on screen might look like this:

  pulu a,x   ; 8 cycles
  ora ,y     ; 4
  sta ,y     ; 4
  stx 2,y    ; 6

where u is pointing to the shifted version of the tile and y is pointing to the screen. That takes 22 CPU cycles for the first row of the tile, though in general it would be 24 cycles per row because we would need offsets for ora/sta ,y.

So if we have a PMODE 3 or 4 hi-res screen then we will need to run those instructions 6144/2 = 3072 times to fill the screen. That's 3072 x 24 = 73728 cycles, which is about 12 fps (frames per second). Not terrible, but that doesn't include getting the tile addresses, any form of looping or indeed the rest of the game.

How fast do we actually need? From my small amount of experience of writing games, the faster the better, but 25 fps or higher starts to look like an arcade game. For points of reference, traditional cartoon animation was done at 12 fps or 24 fps to smooth out faster movement. Arcade machines were often running at the NTSC frame rate of 60 fps to give really smooth animation.

A PAL Dragon has a video refresh rate of 50 fps, so we could aim to update the game display once every two video frames or 25 fps. That would give us a little over 35000 CPU cycles per game loop so the pre-shifted tile method of scrolling is still looking way too slow. We need an improved scrolling algorithm or make compromises or both...

No comments:

Post a Comment