Tuesday, September 13, 2022

Cool Herders Graphics Experiments

Way back in the day, I created a silly little demo for the Sega Dreamcast using then then-new KOS development kit. My buddy Binky came up with the design and all the artwork, and we put the original demo together in like two weeks.

Let's zoom in a little on what's going on there...

We've got some nice overlaps going on there. Boxes overlapping the ground, trees overlapping the ground and boxes (both above them and beside them). There are probably lots of ways to do this, but I'm going to tell you how I did it. It's actually pretty basic.

The Dreamcast was the first 3D hardware I worked with, and knowing that, I made all the graphics out of polygons. Each tile/sprite is just two triangles using flat projection, but with the Z axis tilted slightly. The top of the tile is closer to the screen than the bottom. As a result, for free, we get nice overlaps of the sprites and the tiles. It's as if they are actually (slightly) standing up!

This caused some people to make funny faces at me, but nobody ever suggested a simpler idea. (Some people suggested multiple textures for different situations, but why?? Extra work, extra video RAM, extra processing... what?

So this was on the Sega Dreamcast. We had 8MB of video RAM... so we ended up deciding on a basic system with 3 pages of tiles (originally the three had meaning, but in the end only the third page is special). Full 24-bit (I think it was 16 bit on the DC), and lots of wasted space. Each page has 4 pages of animation that plays continuously, and none of this causes the Dreamcast to even notice that you are there. ;)

Of course, some levels have more graphics than others, but I'm sticking with the NZ stage for now.

So this worked fine, and we released a working game and had some fun with it.

After a while, I started working on porting and updating the game, and we landed on the Nintendo DS. Going from 8MB of video RAM to 768kb - with a few limitations on how to use that memory, required the wasteful old layout to be revised. However, the DS's 3D hardware was still up to the task of all those tiles, so I was able to use the same actual layout. We opted to just zoom the screen in and add a radar, so that the original 640x480 resolution was still honored on the smaller 256x192 display. (This also helped the 3D system, as I only render the polygons that are actually in the viewing rectangle.)

Eventually, I wrote a project that parsed the Dreamcast tiles and condensed the texture pages, removing duplicate tiles and making a lookup table that could be used when the code asked for one of the original tiles. We reduced the background color depth to 8 bit as well, which still looked pretty good!

(Still a bit of wasted space, but it was the closest power of two size that fit all the levels. Incidentally, this tight packing is why the game has trouble on DS emulators. They have an off-by-one bug in the texture mapping for flat projection that causes the textures to pull one more pixel than the hardware does. After years and years this has never been fixed, except in DrasticDS for Android.)

With that, the final game pretty much kept the original graphics on a much smaller system. The DS version also added special attacks and improved the story.

(All that said, the DS was actually powerful enough to render the whole screen, as this very early test shot shows!)

Recently, then, I got a challenge and decided to see if I could get this going on the Gameboy Advance. Now, we're talking slightly more restrictions here. Only 64k of video RAM available to tiles, oh, and it's TILE based, not 3D.

I reduced the color depth to 16 colors for this.. and after the first pass, I was able to use a different palette for the destructibles compared to the ground tiles, giving me 32 colors overall (well, really 30 cause of the way the GBA does graphics).

Originally, I was considering hand-calculating the tiles, but I didn't think the CPU would be up to the task. It might have, but then I remembered, oh yeah! There are two layers.

So originally, I thought that would do it. I'll put the top halves on layer 2, and the bottom halves on layer 1. I can put the sprites in the middle.

But, then I realized... oh, wait, the destructible objects (crates, etc) need to go on top of the ground, but under the tops. So fine, three layers then. No problem.

That /almost/ worked. I didn't grab a screenshot, unfortunately, but where the leaves overlap on the left, that was deleting the previous tile and causing corruption (only on specific animation frames!!) But, easy to resolve this - I used the fourth and final layer and alternated the top layer for even and odd.


Check out the layers!

(The four separate layers)

(Combined layers 1 and 2, and 3 and 4).

To get here, I have a new script that processes the original Dreamcast graphics, converting the 48x48 pixel blocks (!!) into the 6x6 character tiles that the GBA works with. The lookup process is just fast enough on the GBA, and will probably need a little bit of optimization.

The new tool also looks for duplicate tiles, and so it can actually find more duplicate graphics (at 8x8) than the DS version did (at 48x48, though the DS version removed empty space).

In the end, all 6 levels, with /almost/ all the graphics, fits in about 350KB, and a single level's tiles fit in a single character set on the GBA (32k or less). I had to say 'almost', because the Toy Factory has so much animation that I had to remove a few tiles. Fortunately, no animation was removed - just the paint on the factory floor (there was a whole tile page of arrows), and three of the five colors of gift boxes.

Anyway... that's all I had to write tonight. I was just pleased to see it come together on such a different system. We'll have to see where it goes in the end!