Layer cake

layers

How do you create rich animations over a background, on a computer that doesn’t offer much in terms of hardware video features? First, let’s have a look at what the Coco3 offers you that not all 8-bit computers do:

  • 19-bits video address relocation: This means that the image that is displayed by the video chip (the viewport) can be located anywhere within the 512kb memory map, including ranges that are not loaded in CPU RAM (the first 64kb) by the MMU. In fact, the video address is completely independent from any MMU mapping. However, in order to actually modify parts of the viewport, you have to load a 8kb page into CPU RAM. Other 8-bit computers such as the C64 don’t give you that kind of flexibility. The Coco3 lets you really display whatever bytes are at any location in RAM.
  • Page flipping: As a result of the total flexibility in video address relocation, you can flip between 2 viewports, thus modifying one instance while the other is displayed. This allows for flicker-less animation.
  • VSYNC interrupt: You can flip your viewport at the exact time the computer has finished refreshing the screen. With proper timing in the programming, this means that you avoid tearing, a type of flicker that occurs when you flip the viewport while the screen is being refreshed.
  • Hardware horizontal scrolling: The Coco3 allows users to define a 256 bytes wide virtual screen (512 pixels when using a 16-colors mode), and seamlessly scroll the viewport across this virtual area. The word “seamlessly” is important here. The virtual screen truly wraps around, which is amazing when you want to create horizontal scrollers like Super Mario Bros. Which is not the case here. I’m not programming that kind of game.

My game is not using ALL of these hardware features. For instance, I don’t need any horizontal or vertical scrolling… except maybe when I will implement cool transitions between levels! Most of my optimizations are implemented as software. With a 6809 running at 1.7MHz, you really have to be careful what you’re asking the CPU to do. The Coco3 lacks the following features:

  • No hardware sprites
  • No specialized graphics acceleration or math co-processor
  • No DMA or block copy (some CPUs allow you to copy or move a large number of bytes in RAM in just a few instructions through a “pipeline”, but a stock 6809 doesn’t offer this feature)
  • No built-in collision detection
  • No transparency management or hardware blitter (a blitter is a rendering filter)
  • No tileset handling hardware
  • No sounds or music (except for the 6-bit DAC, which requires extensive CPU activity)

One of the fundamental features of any video game is how graphical items stack up on the screen. Some simpler games use a black or single-color background, so moving a sprite or character around only requires to erase its edge to avoid leaving a trail.

Try to animate characters over a non-trivial but static background and you end up having two layers:

  • The background layer, which never changes (we say it is static).
  • The characters layer, where your game character, friends, foes and animated stuff exist. They must kindly restore the background when they move or are animated.

Let’s make it a bit more complex now. What if we want to draw some scenery over the background. Scenery requires some transparency, so that drawing a lamppost or a table over the background doesn’t require you to pre-merge the item with the background tiles. What if we want to use a bitmap for the background? What if we want to move the background (parallax scrolling)? Some decisions need to be made, here.

  • Option 1: The scenery is completely static. You can draw the scenery over the background and it becomes part of it (their pixels are merged), for the duration of the level.
  • Option 2: The scenery has some animation in it. You can merge the static parts (bricks, stairs and such), but the animated items will become part of your characters rendering routine.
  • Option 3: Parallax scrolling. Your scenery will move independently from your background, so you can’t merge them. You need to redraw scenery elements as if they were characters in your game. It requires lots of CPU power, a graphics co-processor and/or high speed processing (which a single 6809 doesn’t have), so you’d better hire an optimization guru.

For Kaboomerang Kim, the solution I have chosen to use mostly Option 2. Some of the scenery is merged with the background, while the animated items are rendering prior to rendering characters. Animated items don’t require super fast animation (since they don’t move around) so I update them in a round-robin fashion: one item per redraw cycle. This saves lots of CPU. And I might implement Option 3 for super cool background animation effects, but this will require quad-buffering (holy cow!), an arcane concept which I will cover in another post!

Finally, some games use a foreground layer, which is populated with scenery that goes in front of the character, enemies and projectiles. This foreground layer can be implemented using many techniques:

  • Redraw at every cycle: If the number of foreground objects is not too high (and especially if the objects are rendered as opaque blocks), then you can redraw them all at the end of every cycle, after redrawing the characters layer. What’s nice with foreground objects is that you just dump them on the screen. The whole point is to cover whatever is behind them.
  • Viewport-wide mask: Another approach is to pre-calculate a transparency mask that will indicate where to punch holes into the characters you are redrawing. This method uses a lot of RAM (it doubles the amount of RAM used to store the viewport) and adds steps when drawing a character. But if you have complex foreground scenery (for example, if your game’s setting is in a medieval castle or in a jungle), then it might be worth the effort.
  • Selective refreshing: When drawing your characters, you can mark positions in the scenery grid that are “dirty”, which means they have to be redrawn. You can also put the coordinates that require foreground redrawing in a queue. So you don’t need to redraw the whole level, just the grid locations where your characters currently are.

I am currently working on the Foreground layer so I have not settled for one of these 3 options yet. They’re all interesting, though the first option (redraw at every cycle) imposes limitations that might prove to be unacceptable if I want to design varied and interesting levels.

So this is how layers stack up in Kaboomerang Kim. Programming a video game is not as simple as it might initially seem, especially on a 8-bit computer with limited graphical capabilities. In the end, what matters is that it looks good, is animated nicely, and is fun to play.

 

Back from a long break

I haven’t posted anything for a while because I was refactoring my code and working on other projects. But I’m back and I will soon post some new videos and stuff! Gotta fill this Coco3’s 512kb with loads of compiled sprites and tiles and animations, until it goes…

kaboom.png

Kim drank some really strong coffee

I have benchmarked the sprite compiler I’ve recently programmed. For 10 000 renderings of a 16×16 sprite with some transparency (I’d say it’s a “reference” case), I’ve got the following results:
– Rendering using a transparency mask table: 44 seconds
– Rendering using a compiled sprite: 10 seconds
That’s pretty impressive. I’ll be able to free up lots of CPU cycles now. And I’m working on even faster compiled sprites!

Dither me up, Scotty!

To make a great game you need great tools, and I have been working on a dithering algorithm for quite a while. I have just programmed an image converter that attempts to select the best 16-colors palette for an image. It uses both solid and checkered colors, with constraints on which colors can be paired.

How does it work? I expand the 64-colors EGA palette to (64×65)/2=2080 virtual colors. Each virtual color is represented either by a solid color or by 2 checkered colors. The resolution doesn’t change (it is not divided by two), it’s like painting a picture using a magic checkered paintbrush. ThenI count the virtual colors in the image, build histograms, and keep the 16 most useful “pure EGA” colors (a checkered color has 0.5 of each color, a solid color has 1.0). It works surprisingly well. The palette selection, checkerboard dithering and RLE encoding worked without a hitch.

These tools will be useful to build background images and splash/menu screens.

So the image below is a pure 320×225 16-colors RGB image displayed on my own Coco3. No video tricks.

17796829_10155295154317922_1811612464419605942_n

Die Kim Die!

Game update! With some help from Simon, I have started making the code faster and better. Lots of functions were “naive implementations” that I had programmed to optimize later. I am a strong believer in “quick and dirty” code that, if programmed smartly, can then be improved. Now we have many enemies on the screen and, even though the animation is still a bit clunky, there isn’t any massive slowdown anymore. This test screen has 4 moving enemies, 3 animated items, and 3 blocks which can be triggered. And there’s still room for more. Collision detection with enemies and lethal blocks is now real; watch the video to see Kim get roasted over a flame. No dying animation yet, just the screen border turning to red. Oh, and there’s the new enemy, the Slimy Snail. Enjoy!

Beware the Baffle Bees!

So after adding the first enemies, I have reached the point where I need to start optimizing my code, both globally and locally. Hopefully Simon Jonassen is helping me with that. Here’s a short video showing the slowdown with 3 medium-sized enemies and 3 animated items. These enemies are called the Baffle Bees and will eventually be a bit more animated and aggressive. They currently use a “coordinates box” and bounce inside its limits.

Boomerang baby

My Coco3 platform game project is progressing slowly, and I was happy to correct a bunch of bugs over the last few days. Here is a video demonstrating how I can chain animations using two triggers: (1) contact with character, and (2) end of animation cycle. When Kim touches the “boomerang in stasis”, it triggers the first function, which then modifies the item so that is runs only once (as a spinning boomerang), and then transitions as circling fireballs. It doesn’t make much sense but hey, it works and it makes it easy to program all sorts of simple effects. Other than that, the platform management code is still buggy and I give myself time to rethink it.

Animated items

Yet another platform game update. The game is taking shape, as I have corrected many bugs and have improved the code, actually reducing it and simplifying it. Amazing what we can do in less than 1500 lines of ASM (including the comments). So now we have animated items, though Kim is not yet interacting with them. These are “placeholders” items, which might not be in the playable version. I’m writing the item collision detection routine, so in the next video, items will disappear when Kim gets close to them.

Kim can now walk, jump sideways and up, fall down, etc. The animations are getting more fluid and we’ll soon be able to make her interact with her surroundings (objects and enemies).

The flicker fest is over, Kim!

More progress in the game project! Now I have double buffering so no more annoying flicker. Despite the code being super inefficient, I had to introduce a very large delay in the routine, and I also had to slow down the walking routine so that we see the movements. This also allowed me to remove dead code and clean up a bit. Also the jump routines are working fine, with wall bounce, etc. I’m not 100% happy with some of the parameters, for instance the “long jump” which goes just too fast. Otherwise it’s going well, and I’ll be adding animated objects next (such as mystery boxes and traps). 🙂

Feel the floor Kim, you’re not a ghost anymore

I have worked a bit on my platform game project today. Now the collision detection algorithm works, so Kim can walk on surfaces and even fall down. Collision detection with respect to the background tiles is grid-based. I will implement jumps (vertical and diagonal left/right) in the next phase. Please note that there is currently no double-buffering, so it’s blinking a lot. I had to introduce delays to reduce the blinking.

Collision detection is still a bit buggy and inefficient. I will have to revisit the algorithms later on. It currently verifies 5-6 points of contact and with optimizations, this could be reduced to 3-4.

Flicker fest

Here’s the first animated prototype of the main character in this future Coco3 platform/puzzle game. No double-buffering so it’s blinking a bit, but right now I’m focusing on state-machine animation to get a nicely animated character.
Yeah it will be a cute little game. Current title is “KABOOMERANG KIM”, coz the character is a girl named Kim, she’s badass, she explores temples in the jungle, and she can throw a flaming boomerang at the critters and bosses.

See how Kim’s character is animated as she walks? I truly want to make her character lively and expressive. I’ll enhance the movement of her hair and arms to make it look more natural. And I’ll eventually replace these horrible cyan colors with deep blues!!

Rebooting the project

So after a pause of roughly 1 year, I’m back at my platform game development with better algorithms, better ASM code and some ideas. Here’s a screenshot of the current prototype in the VCC emulator. Imagine the background being slowly animated and add a few baddies on the screen. Next project update, maybe? All graphics are 100% original.

16806962_10155154032482922_7129606187897551743_n

This is the background/static layer. Things, Enemies and Projectiles will be defined on the dynamic layer. I might add a foreground layer so that moving things will circulate behind it. Current estimate for this graphics pack: 32 background tiles, 32 items, 6 animated enemies (each with 4 frames total), 1 character (with 11 frames).

Here are prototypes for some of the enemies. I might change the palette again, though! I didn’t like the cyan tones in the original palette (in the picture above) so I’ve replaced them with water/sky blue tones.

foes

2016 – A whole year of crazy side-projects!

Yep. I’ve got a new job in February 2016 and decided to put my game project on hold. Anyway, as the code was growing like a cancer (literally), it was becoming unmanageable and I had no idea where I was going. This is why I’ve stopped working on the game project and just tried to get better at 6809 ASM. This took me most of the year but I’ve learned quite a lot and it’s been beneficial.

Here are a few side projects I’ve worked on during this period.

  • Coco3 multilingual font

The Coco 3 defines its default fonts for the hi-res text modes (40×25 and 80×25) somewhere in RAM (I just can’t remember the exact address), and these fonts are defined as binary bitmaps, 8 pixels by 8 pixels (so 8 bytes per character). In this project, I have designed a new Coco font that is almost 100% compatible with the “Latin 1” (ISO8859-1) standard.  Characters that are different from the standard are highlighted in light cyan in the image below:

cc3latin1

Of course this font has nothing fancy, it is purely utilitary but still, the letters are pleasant to the eye. This is due to the letter matrix geometry: each letter is 8×12 pixels. This leaves enough space for all sorts of accents, and in fact, it supports many languages such as French, Spanish, Italian, Danish, etc. However, we couldn’t use it in Basic unless we completely rewrite the text mode functions. See below a screenshot from within the VCC Coco emulator, with text in English, French and Danish.

2017-05-18_10-34-41

Of course, it didn’t look nearly as good on a NTSC or PAL CRT monitor!

Note that people have also been developing some nice fonts for the OS-9 platform, including multilingual fonts. They’ve also been experimenting with some wacky text modes such as 64×25 and 106×25 (super narrow fonts rendered in a 640×225 graphics mode).

  • 10 and 24-colors PMODE 3 on a PAL Coco 2

This is actually a project by Simon Jonassen and Pere Serat, two geniuses who have an extensive knowledge of the inner workings of the Coco1/2 computers. Simon has studied how the VDG chip works and started messing up with VDG and SAM settings at various points during the screen refresh process. By changing the 4-colors palette used in PMODE 3, he has managed to display 8 colors. Of course, this has already been done in some games, Dragonfire being the most impressive. But something funny happens on PAL televisions: when rendering two scanlines with different color palettes, colors mix and merge and you end up with new colors. Comparing Simon’s screenshots with the original 8 colors, I have built a predictive model, which actually predicted all the colors we got, except one.

grid_pmode3_2

And here are the actual results:

color_adjusted2

This led to some funny experimentation, at first with only the CSS2 x CSS2 palette (10 colors, mostly pink/purple). Look at this poney on Pere’s PAL TV:

13305082_10154273084142922_3188671574565493972_o

And here’s Simon’s PAL TV! You can see that the solid color test boxes on the top left are indeed showing 10 distinct funky colors.

simon_poney

You can compare the test boxes in the TV image to the predicted colors in the table above, in Group 2 (CSS2 x CSS2).

Some of the Poney’s edges are jagged due to the brown color interacting with the grey (brown seems to be the least stable color overall), but it is still a good demonstration of the process. The code for rendering the image is generated automatically by I Java tool I wrote. Then I have started working on a more ambitious image, which would use all 24 colors. But I have never finished the project, due to some timing issues (you can’t change CSS palette as often as you’d like during rendering) — manually crafting the image took a long time, and my image conversion tools are NOT automated, which means I have to create palette masks (CSS0 vs CSS1), convert the pixels to PMODE 3 (24 colors to 4 colors), generate the code. I didn’t have the patience to create all these tools.

The sports car image below would be rendered in full 24-colors PMODE 3 on a PAL TV:

car_lowres7

The image below shows the color reduction to PMODE 3, 4 colors (left) as well as the mask used to switch from the CSS0 to the CSS1 palette. Due to timing constraints, granularity is 8 bytes (32 pixels). I should generate the code and give it a try, someday!

sportscar_img_mask

  • OS-NONE

The name is a play on “OS-NINE”! This was my attempt at having 4 full COCO3 (128KB) instances running in separate memory spaces in a COCO3 with 512KB. Despite spending days reading documents about the decompilation of DECB, I still couldn’t make it switch from one instance to another. It seems that some things are “stuck” at specific areas in RAM, or are reset after each DECB user command. Still, I have patched DECB extensively, to the point where I can actually escape from the Basic command interpreter and open the instances menu. Interrupts interception, code relocation, code patches, etc. This was a very complex project. I might get back to it someday.

2017-05-18_11-00-35

  • Sprite optimization competition

I had an mention in Lee Patterson’s Sprite Optimization blog. It all started with his notes about how sprites can be rendered using various algorithms, and trying to find out the best ones out there. At the time, I outsmarted some of the best code brewers by using a very formal decision tree and the TSTx opcode. Bad quality photo of my notes:

Hugo-decisiontree

Lee Patterson’s blog entry on sprite optimization

Note that in the original code base for my Coco 3 game, I was using a different approach. My sprites were pre-processed upon loading and the mask and end-of-line data was interleaved with the pixel data. This translated into interesting rendering speeds, considering that I was managing transparency at the pixel level (and not at the byte level).

And then… someone beat us all with compiled sprites. I have started working on compiled sprites as well this year (March-April 2017) and got some even better results. And now it seems that everyone wants to have their own compiled sprites library, like we started some kind of a movement! Needless to say, generating the code for the 6809 processor isn’t too complicated, and it’s extremely fast. You wouldn’t be able to do that on the 6502.

The image below shows the benchmark results. My more recent sprite compiler would most probably be 2x as fast.

2017-05-18_13-43-40

  • Lens effect

I have worked on a simple Lens effect algorithm that could be adapted to the Coco3. In a way, it works backwards from the usual methods. It doesn’t involve any division or color merging, since the lens is in fact an array of pixel sample coordinates. Many lens effects can be implemented by just playing with a few parameters (lens diameter, focal point, observer’s distance). Inverted image, magnified image, reduced image, etc.

I have written down the data structure requirements for a Coco3 implementation, and I’m pretty sure I could run multiple moving lens on the screen simultaneously (using 32×32 lens on the 256×225 16-colors screen). Which would be a feat by itself. But at the same time, I was so caught up with my daily life at the time (lots of work, house was for sale, we were packing boxes, etc.) that I simply haven’t had the time to finish the implementation. Maybe later this year! The funny thing is, I’m not active in the demo scene, but at the same time, these lens would literally kill. Below is a video of the Java prototype running with a 100-pixels wide mirroring magnifier lens.

Note: The actual animation is very smooth, but my video capture tool isn’t the best around so it looks choppy in YouTube.

And that’s it for 2016, folks! I will soon update my blog to include the most recent developments in my Coco 3 game project — a new code base, better optimizations, better sprites, better graphics. BETTER EVERYTHING! 😉

Crazy algorithms

I’ve been overworked lately, so I won’t try to implement new functionalities in the Coco3 game over the next few days. If I can’t work 1-2 hours straight on the project at this point, it’s not worth it. I need some concentration because I’m implementing the SOD (Sprite Object Descriptors) and I rewrite the main game loop… so I expect TONS of bugs in the process.

Instead, I have spent some time trying to solve a little mathematical problem: is it possible to draw a sine (sinus function) line using no multiplication, division, real numbers (floats), trigonometric functions (obviously) or lookup tables? Obviously, the solution to such a problem will be a discrete function.

Given the fact that the 6809 processor has no integer division and no support for floats, this problem has some practical applications — if I want to draw looping trajectories for projectiles, for instance, this may come in handy. On the other hand, a good old lookup table will always do the trick. If it’s too granular, linear interpolation will work just fine.

First of all, I know all too well that you can’t get a super precise sinus function out of thin air. There is no trivial approximation for trigonometric functions, and they all require some heavy maths involving sums and series. Instead, I will try to approximate the general shape of a sinus function (a graciously oscillating, smooth function with no hard transition).

So a quadratic function it will be. A second-degree function should be enough. If I work with the function’s slope, that should be easy. Even better, the slope’s slope will be a simple square wave oscillator.

Example of a square wave function:

W(x,c) = 1, if x divided by c is even
W(x,c) = 0, otherwise

But we don’t want any division. So let’s create a square wave function called a Bit selector:

B(x,c) = value of bit c in x

Since we want a square wave oscillating around zero, we will add some adjustments around the bit selector (it will oscillate between -1 and +1):

W(x,c) = 2B(x,c) -1

Having a square wave, we can now “integrate” this square wave into a sawtooth function, which will integrate into a nice, smooth quadratic. We will use the magic of first-degree recursive functions, also called memory functions:

S(x,c) = S(x-1,c) + W(x,c)

Since the function is recursive, we will need a first term to start the series. Seriously, you don’t want to get into the details at this point:

S(0) = some initial value that will center the function nicely

I’ll give you a hint. Since we’re working with bits and powers of 2, the initial value is in the form: “2 exponent something“. Finally, we integrate the sawtooth function using a memory function and we will magically get some quadratic function, which we will call F:

F(0) = some initial value that will center the function nicely
F(x,c) = f(x-1,c) + S(x,c)

Let’s look at one of these functions plotted into MS Excel (thanks to VBA):
sine_approx

Surely, there is a way of simplifying this process. It doesn’t imply any difficult calculation (bit selection and a few sums), but the two-levels recursion makes it impractical to implement efficiently in assembler, knowing the depressingly small pool of registers you get in the 6809.

The trick is to avoid the bit selection and square wave functions, and calculate the sawtooth directly. This will involve some binary trickery, using some bit to decide if the slope goes up or down, using AND or MOD operators to trim the bit field and keep the sawtooth at a regular height, etc.

This new approach involves a few bit selectors and a single sum. It looks quite cryptic though, even in Java. Here’s the main function, where I have merged the S(x) and F(x) into one crazy-ass function:

public static int FS(int y0, int x, int k) {
int y = (x % k);
int k_shr = (k >> 1);
int k_min1 = (k-1);
if((y & k_shr) != 0) {
y = (y ^ k_min1);
y++;
}
if((x & k) != 0) {
y = -y;
}
return y + y0;
}

Believe it or not, this function WILL allow you to draw a quadratic wave that looks a lot like a sine wave! Note that the caret “^” operator is the XOR in Java (it is seldom used). Other than that, the code is very tight and bit-oriented, and translates very nicely into Assembler. The only tricky part is to determine the initial value for y0. It’s not super important, as you can add a baseline to the whole function. But starting at the right height means NOT having to add any additional constant during the whole rendering. Formally, the initial y0 for this function is given by:

fo = – 2^(2k-3)
(where “^” is the exponent operator and k is the wavelength)

Here is another view of the VBA version used to plot the function in Excel:
sawtooth_sine

Last but not least, implementing the function in 6809 Assembler using Phoenix IDE and CCASM was not a trivial task, even though I was using the Java code as a reference! It took me 2 hours of painful step-by-step debugging, and the current implementation only works for small values (we’re limited to byte-sized amplitudes). Here is a video showing a crude character-based rendering of the function in a VCC Coco emulator. The whole program takes just a few bytes of memory — the bin file is just 179 bytes long! There is no scrolling involved; I simply redraw the whole low-res text screen each time a sine wave is rendered. Enjoy!

First round of optimization — from snail to drunk turtle

Software development often goes by «efforts». That is, you look at your code, you see structural problems and performance issues, but you don’t want to attack it upfront. So you shuffle bits here and there, rewrite minor functions, and wait until your vision is clear enough to attempt a major overhaul.

It will not show at the surface, but I have rewritten more than 50% of the code to implement a more coherent vision, prepare the code for object-like structures (e.g. records with directs links to their optimized functions, instead of IF-THEN-ELSE tables).

For instance, let’s say you have a Sprite object. You have a generic render_sprite() function, but also an optimized render_sprite16() function for sprites that are 16-bytes wide. Instead of choosing which function to use each time you render it, you can simply keep a pointer to the function within the sprite data itself. If the pointer to the rendering function is at offset zero in the sprite data (located at address sprite_ptr), you can simply write in assembler 6809:

ldy #sprite_ptr
jsr [sprite_ptr]

(Why do we load the address in register Y if we pass it anyway in the JSR call? Because we want to carry a pointer to the structure as we jump to the indirected function.). We can also write:

ldy #sprite_ptr
jsr [,y]

We have to pass the sprite’s address in Y so that the rendering function has access to the appropriate sprite. This technique allows you to create some nifty object-like structures that use fast indirections to call their own subroutines.

After one round of optimizations, we have reached the 30 frames/second mark, and I expect the current demonstration code (with 4 sprites of various sizes) to reach 45 frames/second with some additional optimizations. Then I’ll be comfortable enough have the code benchmarked on a real, physical Coco3 machine. I will increase the number of sprites and see how many I’ll have simultaneously onscreen in a game level (counting the main character, enemies, animated items, explosions and projectiles).

Thanks to Simon Jonassen, 6809 music wizard and ASM expert, for the insights.

My next post will discuss the quasi-object hierarchy and control loop. I will also switch to a different graphics mode (256×224, 16 colors) that will allow me to build a better platform game with a retro “NES feel”. We’re slowly getting there.

Please note that the animation is MUCH smoother in the VCC emulator. The video recorder doesn’t seem to like recording video running at 60 FPS with limited CPU available.

Planning for the road ahead — of palettes and graphical objects

I am proud to announce that we now have a PALETTE for our game. This is an all-around 16-colors palette that excludes magenta and pink, in order to leave some space for more “useful” colors. It was tested against a dozen tilesets from old games, and gave the best results with Mario and Zelda.

palette16c_large

Now that I have a working proof-of-concept, I need to improve my code on three levels:
– Optimize the rendering functions, which are really inefficient right now.
– Simplify the game mechanics, so that I don’t have to write 1 km of code for each object.
– Organize the functions in order to have a versatile and elegant game development API.

I have decided to organize the game objects into 4 categories.

SPRITE
Sprites are graphical objects that are built to be read once, and drawn an unlimited number of times. The rendering loop must be fast. Sprites have built-in transparency; when the pixels are read, color #0 is used as a “transparent” color and a mask is created and interpolated on-the-fly. In order to erase a Sprite, you need two Buffers — one for each screen (we use page-flipping and an off-screen buffer for a smoother animation).

We define both fixed-width Sprites (8, 16, 24, 32 pixels) and free-width Sprites. Fixed-width are faster.

THING
Things are transparency-enabled sprites that have some built-in limitations in order to make them even more efficient. They don’t move on the screen, but they can be animated. They have are available in 8-pixels and 16-pixels widths and can only be rendered at integer positions in the game level grid, e.g. they are rendered right on top of game tiles. They require less memory than Sprites because they are erased simply by redrawing the tile underneath.

ThingSets allow you to manipulate a whole bunch of things in one single operation.

BUFFER
Buffer are opaque rectangles that are used to restore the background image when we erase Sprites. Once a Buffer is read, it records its on-screen position for faster rewriting.

TILE
Tiles are opaque objects used to draw a game level (background and fixed objects). Tiles have fixed width and height and are rendered into the game’s grid. Typically, you’d define 8×8, 16×12 or 16×16 tiles, but other sizes are possible and depend on your game’s granularity and the screen’s resolution.

TileSets allow you to manipulate a whole bunch of tiles in one single operation.

There is still a LOT of work to do optimizing the code and organizing the objects. Here is a video of a demo using tiles, sprites and buffers, BEFORE any code optimization. (The next video will show the same animation AFTER the code is optimized.)

PS: Thanks to John W. Linville’s suggestions, I have VSYNC now and my sprites don’t flicker anymore!!!

First video shown to the World… but why is there lava on the ceiling?

I have recorded my first humble video showing sprites bouncing on the screen, and posted it to my favorite Coco enthusiasts communities: the Coco list at MaltedMedia and the TRS-80 pages in Facebook. It got literally flooded with “LIKE!” in Facebook and people are really eager to see something fresh developed for their beloved 8-bit platform.

I have always thought the Coco3 should have deserved a better commercial success. After all, it was built around the best 8-bit processor of its generation (a 6809 could beat any Z-80, 6502 or 8086/8088 clocked at the same speed). But the Coco3 failed commercially due to many factors such as:
– It arrived late in the 8-bit market, where people were already starting to move to 16-bit computers such as the Amiga and the Intel computers (IBM PC, PCjr, Tandy 1000, etc).
– The 8-bit market was still very much alive in the gaming consoles world, after the console crash of 1983. The 3rd generation consoles such as the Nintendo (NES) were quickly gaining popularity. Despite the fact that the Coco3 had high-res graphics capability, its coprocessor (the GIME chip) didn’t offer ANY sprite management functionalities and to make things worse, the Coco3 didn’t have built-in music/sound capabilities (it had a multi-tone beeper, just like the IBM PC).
– Some people at Tandy were pushing their Tandy “PC compatible” computer line and wanted the Coco3 dead.
– The Coco3 had a very uninspiring color palette. It used a 2Rx2Gx2B color model, where you could select 16 colors out of 64. Unfortunately, the so-called EGA palette suffers from severe limitations. Too many half-tints in the cyan and magenta (which are not very useful) and not enough grayscale. This palette was superior to the C64 palette but more limited than the NES (25 colors, plus some additional grayscale).
– Most commercial game developers were not motivated by the Coco3. There had been HUNDREDS if not THOUSANDS of games developped for the low-res Coco2, but just dozens for the “too little too late” Coco3.

If you ask me, the Coco3 was missing the following:
– A standard diskette drive sold WITH the system and not available as a “special order” at Radio Shack.
– A better coprocessor with asynchronous memory block move functions, bit-blitter functions and perhaps some rudimentary sprite management.
– A coprocessor with 3-voice music with a 256 bytes buffer. Just 3 or 4 fixed waveforms, no need to get too fancy.
– A better joystick. The Coco joystick was somewhat a compromise between a joystick and a mouse. It failed at both.
– A video mode with 16 colors chosen from a 4096-color palette (the Atari computer and AppleIIgs used such a 4Rx4Gx4B color model). You could also use even more colors if you could store tilesets and sprites with local palette selection in the GIME coprocessor.

Still, there is a thriving community of Coco3 enthusiasts. They program games, demos, sound/music routines, utilities, and constantly push the limits of the Coco. They keep OS9 alive (possibly the best and most powerful 8-bit OS ever). And they also organize an annual festival in Chicago (but I won’t be able to attend this time).

Here is a video of my beloved dragons-in-a-bubble bouncing around the screen over some converted sprites.

Claiming the whole screen

At last, after a week of development or so, I have been able to use the whole screen. I have finally understood how the GIME MMU (Memory Management Unit) coprocessor maps virtual memory pages onto physical pages. The Coco3 memory model (which I won’t reproduce here) is very convoluted, as this computer has evolved from a 4k ancestor, went through the horrible VDG graphics phase (256x192x2 colors with artifacting), memory varied from 4k to 16k to 64k to 128k/512k. Some of the oldest routines and structures are still hidden everywhere in memory, ready to jump in your face and make your life miserable. Interrupt vectors. Disk routines. Low-resolution text screen area. Basic interpreter stuff. Etc.

So the biggest challenge is to know where to load your program, where to load your graphical/sound resources, and where to map your high-resolution graphics pages to draw efficiently on-screen.

It took me a while and many tries to figure out where my program should sit, and which low-memory pages I can safely use to map graphics (high-memory pages). Here are some of the graphics modes and how many 8kb pages they use for mapping:
256×192 16c: 3 pages
256×224 16c: 3.5 pages — similar to the NTSC Nintendo screen!
160×192 16c: 1.8 page
160×224 16c: 2.2 pages — now that would be quite horrible, wouldn’t it?
320×192 16c: 3.75 pages
320×224 16c: 4.4 pages — prevents you from mapping all graphics pages at once

So I am thinking about using either 320×200 (the last 8 pixels at the bottom can be used as a status bar, and updated every now and then) or 256×224 to get more vertical resolution and have a Nintendo-like screen geometry. Both modes require 4 memory pages and both modes leave some space at the bottom of page #4 to safely store a few sprites.

Here is another test I’ve run, with a few more old-school sprites and color bands from the palette I’m working on. I still haven’t figured out the Coco3 fonts. I know the low-res fonts are stored in the legacy VDG and are not readable,  but I hope the GIME will give me a pointer to the high-res font table.

We have TWO bubbles floating through the clouds, page-flipping for smoother animation, and a rudimentary palette.
We have TWO bubbles floating through the clouds, page-flipping for smoother animation, and a rudimentary palette.

Pilfering stale sprites for a good cause

Okay — so I wanted to test moving a sprite across the screen (it’s becoming an obsession) but I was too lazy to create some 8-bit graphics. I don’t have any good palette yet. Defining a good all-around game palette requires some planning and compromises. Right now, all I want is to draw some nice graphics and have them flicker their way across the screen.

So instead of learning how to read files from a virtual disk, I’ve decided to use a clever trick — convert graphics to a base64 encoding using a Java utility I’ve written, load them into my code and, well, decode, pack and use them.

So here we have some well-known dragon-in-a-bubble painfully gliding across the screen. And I still haven’t been able to (1) page-flip with an offscreen-buffer to reduce flicker, (2) use the whole screen, (3) disable interrupts that cause random crashes, and (4) VSYNC the drawing to prevent even more flicker from happening.

But we have a moving dragon, and it’s a start.

And just to make it clear: I am NOT programming a Bubble Bobble clone.

Dragon-in-a-bubble sprite slowly and painfully moving across some background color stuff to show transparency. Yay.
Dragon-in-a-bubble sprite slowly and painfully moving across some background color stuff to show transparency. Yay.