Monday, October 2, 2017

Sprite blitting and Compression for Bitbox


Here are how and why the future sprite format is defined for bitbox sprites.

Here are the sprite format properties, why they are needed and what impacts it had on the format

  • binary based format
Since all of our data is generally compiled we could express the image as C code. This would be easier than to serialize a binary file and deserialize when loading from flash memory. However, we don't do that, in order to allow sprite data to be put to SD card, or be compressed in flash and the uncompressed to RAM.

  • line-based blitting
As the bitbox is issuing pixels line by line, objects in the bitbox blitter are defined by two methods : what to do each frame and what to do each line (on top of misc values as x,y position, height of blits ...). Thus it will be much better to think of sprites as RUNs of pixels instead of small squares by example.

  • no transparent color
Setting encoding of transparent pixels is not really the way to go for software blitters, because you'll need to check for that color for every pixel. Generally, on a give image the blanks go on strides (borders, by example) and then it's opaque strides. So it's better to encode a RUN of transparent pixels (which you just skip) and then a RUN of pixels you will blit.

  • run-length encoding and packbits algorithm

Coding same color ranges into one (color, number of pixels) pair is named RLE. It's the first useful compression one can use, it's fast and straightforward. It's also good for bitbox, since it's coherent with line-based blitting. It's also very fast because you just have one read and N writes for 2*N pixels if you're blitting 16bpp.

We can also group single pixels, since you generally have many similar pixels then a bunch of single pixels. In that case you can avoid transmitting (1,color) (1,color2) (1,color3).

  • back references

Another way to improve compression for "free" (on decompression side) is to avoid coding twice the same run of pixels. If you can retrieve a past group of pixels already encoded, it's not very expensive to blit from this address instead of the current address. Of course, this is only interesting if you're going to encode less than the size you'd need for encoding the address itself. This is in fact how deflate, gzip and other LZ77 encoders work; but with a modification : in lz77 you can reference the past blit (ie data already extracted). Here we're blitting sprites but once a line has been written, another object can have written over it for the next line, so you can't reference past blitted lines. You have to reference the source data, worsening a bit you ratio. You could reference the same line but generally the interesting parts - non handled by RLE- are in previous lines.

  • explicit EOL encoding
Adding a bit for explicit end of line uses a bit that could be used for length encoding, but it allows avoiding a byte or more to add the blank space. This is generally a net gain, because blits are generally smaller than 32 (sprites) or more than 64 (large background images)

  • extensible size encoding.
Sometimes, and in the majority of sprites by example, you have to encode blits with no more than 32 pixels wide, so having more than 5 bits by example would be wasteful.
But then you have to cut large blits into smaller ones, which can be slower to blit and decode the header, and bigger at the same time.
What's used here is a variable length encoding similar to LZ4 :you use 5 bits for the base and then if the len you want to encode is more than that, you add a byte of data (and another while you don't have to).

By example,
15 is encoded as 15,

30 as 30,

200 as 31 + another byte with 200-31 = 169
31 as 31  + another zero byte yes it's a useless zero byte but that's rare.


All of this leads to a 'blits' encoding, where we store blits with a header and some data.
Header is :
    2 bits for the type of blit,
    1 bit for end of line
    5 bits for length

    + N bytes extra for length as needed

Data is :
    blit "Skip" : nothing
    blit "Fill" : color to blit with
    blit "data" : "length" pixels encoding
    blit "back reference"  : 2 bytes as back reference in bytes since the current bytes. This sliding window allows for more than 64k resources

For encoding pixels, you can of course use raw u16 pixels which are quite big.
  • pixel palette can be slow but dense, but there is a better way.

In order to reduce the storage of individual pixels, you can use less colors and thus less bits per pixel. using 256 colors you can reduce your storage by two comarped to raw 15bpp, when using 16 colors you can reduce by four(but this will have an impact on what you can provide). A global 8bpp encoding is available for either the bitbox micro or the a global 8bpp palette reduction.

Pixel palette is not a panacea however, since it needs much longer to blit. While we can memcpy (setting aside alignment operations) one word at a time (i.e. one u32 word read and one write per couple of pixels), now need one read for 4 u8 pixels, but four reads (one of each palette lookup), adding to the contention of memory buses. What can be done is making a table for multiple pixels lookup but for 256 colors you'd need 65536 entries. Better to limit that number.

What's interesting is that generally you don't use the whole number of different couples for a given set of colors. Not every couple is used, and it's generally much better to limit oneself to 256 couples than 16 individual colors. And in that case, we have 8 pixels for 32 bits of data + one read + one write for 2 pixels, which is very close to the raw pixel encoding speed.

Couples also adds the possibility to allow run-length encoding of dithered patterns which in pixel art and limited color can be useful.

To encode such a picture, I made a small encoder which can extract common couples like you do with the same algorithms for color quantization, except it's now couples quantization.

Frame encoding :
  • multi-frame format & skiplist

Our format should be used to encode not a single image, but multiple frames animations.
First, it's generally simpler to manage one file per animation than one file per image.
Then you generally produce the content that way.
And then an animation generally contains many slightly different frames but not entirely different frames and colors, so you gain in not having to repeat the palette and the blits.

We do this by specifying a frame size and putting all the frames vertically.

What you need is then an index of each frame start since each frame is not the same size, in order to be able to skip directly to this and not having to unroll the whole sprite from frame zero. So we add a table with skip frame indices. We use a simple u32 list to allow big files, and direct access - we could use a delta encoded u16 since no frame is larger than 64k generally but the next paragraph will explain why - it's not very heavy generally.
  • frame deduplication
Often, an animation can repeat the same frames. for example, you can have an A-B-C-B-A-B... type animation (ping pong) which can be a looping ABCB animation. Why repeat the frame B when you just have to replace the fourth entry of the frame lookup table by the same pointer as the second ?  Therefore the encoder can detect similar frames.
Also, your frame step can be the same length and you can repeat a want a frame to be longer.
That means that frames are no longer unique or the frame index monotonous and cannot be delta-encoded efficiently.


Thursday, June 15, 2017

An editor for 0xFF

0xFF is a simple game engine using a 256x256 pixels image as the only source for a whole game.
While you can make a whole game with gimp, the player also integrates an editor (under construction, but usable)

Here is a small video of me demoing it to make a tiny game. The editor runs on the bitbox, using a mouse or a gamepad.


Friday, May 12, 2017

Small video : soldering of the MCU of a bitbox



While I was soldering some bitboxes I thought some may be interested to see how they are done. Nothing too special - I certainly don't pretend to be good at it , there are way better videos.  Footage is sped up 4x (No sound)

Saturday, December 3, 2016

Bdash updated

Boulder Dash was one of the first games to arrive on the Bitbox, but wasn't really advanced enough. I took some time and it's now getting some attention. A new release has been done, with some new features:

  • using chiptracker and not sound samples (reducing the game size greatly) ! The original soundtrack was provided nicely by Pulkomandy
  • levels ! at last there are more than one level !  now the 1st boulder dash games are available, from a levels.h file describing levels with const strings.
  • butterflies  / fireflies : those deadly enemies are now available to kill you. Implementing those were a little tricky since the game was purely tile based (i.e. the whole game state was an array with tile indices) , and the animals need a direction state, I now have a "sprite in tiles" system.
  • last level restart : up to now you had basically one life.  (which was very annoying). Now, you restart at the last level you started on. Which means you have basically infinite lives. 
  • many small fixes


WIP (non available but shall be available some time)

  • proper lives 
  • title screens with a little text. This will need a smaller tilemap which will share the tileset and vram of the existing one.
  • cool transition effects
  • amoeba & magic wall ! 
  • score / highscore
See it here : https://github.com/makapuf/bitbox-bdash

Tuesday, November 1, 2016

New Game : Mario Watch !

Hi ! It's been a long time since real content has been put on this blog.

Now is a good time to fix that, by announcing a new game on the bitbox  !

Being a kid while the game & watch lcd games were all the rage, I like to reimplement them.
This one is a nice one because it has mario ! Released in 1983, this little will be playable o the bitbox and the micro. A few missing features (sound & scores by example) for now, but the gameplay is starting to take shape !

stay tuned for next updates, you can still begin to play it now !

Game is hosted at : https://github.com/makapuf/bitbox-mariowatch





makapuf

Tuesday, May 31, 2016

Ideas of games to write

Some of us are looking for game ideas to code (just before they've way too many projects ongoing :) )

Of course, you can contribute to one of the WIP projects on the bitbox wiki page (https://github.com/makapuf/bitbox/wiki/Software-Index) - frankly, many of those games need attention and could use some polish.

But hat if you can to create a simple project in a weekend (of course it will run on the bitbox, where else ?), here are some ideas of simple games to try  !

http://www.asahi-net.or.jp/~cs8k-cyu/blog/2014/12/12/games-in-2014/


Examples :
 
And here is someone who coded 50 games last year ! Can you do better ? (I don't :) )
http://www.asahi-net.or.jp/~cs8k-cyu/blog/2014/12/12/games-in-2014/

Thursday, April 21, 2016

Micromo : a Thomson MO5 emulator !

Hi all, I made a port of the dcmo5 emulator for the bitbox micro.
 
The MO5 was a famous (in France, completely unknown everywhere else) computer, not so bad after all, and on par with a Spectrum. 

Its specs : 
  • 320x200 fixed palette 16-colors (16k RAM) with 2 colors by row of 8 pixels
  • CPU : a motorola 6809E @ 1MHz
  • 48kB of RAM / 16kB of ROM
This first version can run Basic, load programs from cassette (embedded on the binary), use a keyboard. It can play some games and runs on Bitbox (should run on micro also). It's a first release, missing selecting cassettes from the (existing) menu, gamepad support or sound.


Thanks a lot to Pulkomandy who is a real MO5 programmer - lots of cool stuff about those micros and democoding on these old clunkers on his site: http://pulkomandy.tk/projects/thomson/wiki

shinra demo
my (much better) demo.

Sunday, March 6, 2016

Answer to preceding post ... ByteBeat

As you may have tried yourself, the tiny binaries produced by the preceding code create long tunes directly coded by a function of time !

So you basically have s=f(t) where s is the output sample, t the sample id and f a simple expression as the one I put on the title.

The thing is you can actually build quite complex song with it ! 

This technique has been called bytebeat and the main article describing it was made by someone named "viznut".

See the original article here http://countercomplex.blogspot.fr/2011/10/algorithmic-symphonies-from-one-line-of.html or here http://canonical.org/~kragen/bytebeat/


Sunday, February 28, 2016

u=t*((t>>13)&31&t>>9)-((t>>7)&23&t>>3)

What is this ?? Well it's a very interesting thing I found on the web the other day.

If you have a bitbox please download and run this small (3.1kB) program - it needs sound, not display. (I'll provide the code  - which is really not much more than what is in the title .. and some background info soon).

Controls : plug in sound output, also try to press the bitbox button. I really like the 8th one ..

(edit) for those with a linux computer, here is a sdl backend compilation of the same code ... ans a big hint

Wednesday, February 24, 2016

new game : Dragon's Lair !


Ah .. such a nice game to play on the Bitbox ! (see Angry Video Game Nerd or Joueur du Grenier reviews ;) ... )

The game is open source and the release is here : https://github.com/makapuf/bitbox-fmv

For more info about the game see : http://www.dragons-lair-project.com/games/pages/dl.asp
for Bitbox itself see main repo / wiki : https://github.com/makapuf/bitbox/



dragons lair! 


This game / engine is aimed at reproducing the dragons lair game on the Bitbox. It's only compatible with the standard bitbox since the data is streamed from SD card.


Tuesday, February 9, 2016

Back from FOSDEM

I got back from the FOSDEM a week and but didn't have the time to write about : here are some small notes about it.


Tuesday, January 26, 2016

Meet you @ FOSDEM 16 !

Just a quick note to say that I'll be presenting the Bitbox and what was done this year at fosdem this weekend  (thanks to all contributors past year !) Link to the presentation

Wednesday, January 20, 2016

New game : Alter Ego

Hi all !

A new game has been published ! It's a port from the Alter Ego NES game (with reused graphics but the code is entirely new). It runs on the bitbox micro as well as the bitbox (as every micro game).



have a look at its gameplay



 



A longer is also available on youtube 
(The game has currently no sound but that shall be improved upon soon !)



Monday, January 4, 2016

Happy new year

Hi ! I wish you an happy new year, which will be hopefully a nice year for bitbox again.

I will be presenting past year at fosdem 2016 (again) and 2016 will hopefully be the year we issue many great new games.


Development hasn't stopped, however !

Wednesday, November 25, 2015

A bitbox Laptop !

Pulkomandy, a known hacker of the bitbox mailing list, has been busy recently and created a laptop with his Bitbox !


Some people have done this with their raspi, but this one is way cooler ;)
This is really a neat hack which will give me neat ideas for my santa list this year :)

You can read more about his build (and more cool articles) and discuss about it on his blog: http://pulkomandy.tk/_/_Hacks%20and%20stuff/_Bitbox%20laptop


Thursday, September 3, 2015

3D is coming ...

Hi !
Not one, but TWO programs that are dealing with 3D have been published !

Friday, June 19, 2015

New game : rapid ball !

Hi, you may be remembering rapid ball on old nokia phones, here is a simple version for the Bitbox ! You just guide a ball falling platform to platform (not the spiky ones) get new lives and avoid touching ceiling or floor ! What score will you do ?

makapuf

Thursday, June 11, 2015

Developing Memory Matrix

Hello, my name is Lucas (not makapuf) and I wanted to walk you through my experience developing a game for the bitbox console.

Intro screen.  Prepare to memorize!

Let's get started!

Wednesday, May 13, 2015

ZX Spectrum emulator !

BitboZx

Hi, here is the first release of the BitBoxZx, a 48k ZX Spectrum emulator !


Saturday, February 21, 2015

New game : Polar !

Polar is a small game written in ~ half a day.

Here is the link to the github project

Here are some screenshots - a very simple game indeed, <200 lines of C and a few sprites.


 

The game is still missing sound, music and more levels .. but the few levels are perfectly playable !

This game has been inspired by Polarity, a game written for ludum dare 23 by nornagon (
http://nornagon.net/games/polarity/ https://github.com/nornagon/polarity. ) but the code and GFX are original.