Friday 27 October 2017

Flicker-be-gone! (mostly)

No progress on the collision-detection bug so I decided to implement the double-buffering (page flipping) since it is almost trivial and won't be affected by any other programming issue.

The arcade machine uses a pair of so-called "ping-pong" buffers to allow the DVG to render the frame whilst the CPU is building the next frame. This comes in very handy indeed on the raster ports (Apple IIGS, Coco3) when erasing the previous frame before rendering the current frame.

Of course double-buffering requires erasing the frame prior to the previous frame. The easiest way to implement this with the current architecture is to extend the 2x buffers to 4x and modify the "ping-pong" logic slightly. No more than a handful of instructions in a few strategic locations...


At this point the game is running quite slowly due to the sub-optimal (to put it mildly) erase/render code, so there's little point synchronising the page flipping to the VBLANK and therefore the video still exhibits some flicker. However it is much improved and gives a taste for things to come...

UPDATE: Tonight I thought I'd add some profiling code before starting on any more of the optimisations. When you first start a game (with 4 asteroids on-screen) it's hovering around 55fps. When things get a lot busier, it's down around 20fps, and the lowest I've encountered is 13fps. And when there's all-but-nothing to render, it hits 89fps.

Will be interesting to see where it goes from here...

UPDATE 2: I've just optimised the copyright rendering. The copyright is unique in that it is rendered every frame, in a fixed location, and therefore never needs to be erased.

After some experimentation, and without resorting to stack blasting (which I can't see being optimal in this case due to the OR'ing operation), I came up with the following for each line of 4 words (Y is the video address):

LDD #0x1234
ORA ,Y
ORB 1,Y
STD ,Y
LDD #0x5678
ORA 2,Y
ORB 3,Y
STD 2,Y
...
LEAY 32,Y



That's the best I can come up with late on a Friday night (37 -> 22/24 cycles/line). Improvements welcome!

8 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. The slight flicker remaining actually reminds me of the real arcade machine. The speed seems ok, now it just needs sound. Are you vector drawing the graphics? If so you could probably speed up the code by storing pre-drawn images of the asteroids and the ships in various orientations and then just copy them to the screen.

    ReplyDelete
  3. The speed is actually quite a bit slower than the arcade, especially at the start or when you have a lot of asteroids on the screen. But that's OK, because I'm yet to do any optimisation of the rendering.

    I am not drawing vector graphics, no. I currently have a single bitmap image for each object, which is bit-shifted on-the-fly. I lifted the rendering code from Knight Lore, pretty much. Optimisations I have planned are pre-shifted graphics and compiled bitmaps, as I had implemented on the Apple IIGS version. It made quite a difference to the speed. I'm hoping that I can achieve full game speed at that point, but it's not guaranteed. If I get to that point, I'll have to weigh up my options then... such as not erasing objects (eg chars) that haven't changed/moved.

    ReplyDelete
  4. Very nice indeed. Shouldn't the double buffer eliminate flicker? Is the buffer swap happening too soon or am I misunderstanding something?

    ReplyDelete
    Replies
    1. The flicker seems confined mainly to certain text messages... without really thinking about it I attributed it to the fact that I wasn't syncing the flip with VBLANK but on retrospect that shouldn't cause flickering either... I'll have to look further into it...

      I won't claim my code is bug-free but the flipping is done once the off-screen frame has been erased and re-rendered, so shouldn't be early.

      Delete
    2. I forget how the display address is set on the colour computer but I would guess outside vblank it would only cause tearing with maybe some minor apparent corruption/flickering while the address changes (unless it can change in a single write).

      Hmmm, unless the display processor only latches the screen address at a certain time during the frame. If that's the case then flicker is quite likely to happen as the current frame won't get flipped away immediately.

      Delete
    3. I really should try it on real hardware!

      Delete
  5. Fixed the floppy disk build of Asteroids tonight (never run it until now), and fired up the CocoSDC, running it for the first time ever on real hardware!

    The good news is that it runs fine.

    The ... neutral... news is that it flickers in the same manner as MAME, which is actually good because it means I should be able to debug the flickering on MAME. Can't for the life of me figure out why "1 COIN 1 PLAY" would flicker constantly, while the rest of the text is rock-solid. Unless it's only rendered every 2nd frame... which I don't think it is... Ah, that reminds me to check something...

    ReplyDelete