This post is mostly just to share an experiment I did when playing around with compressing graphics.
I noticed when looking around, that many PICO-8 carts that do compress graphics were using some form of LZ or RLE compression. Out of curiosity, I decided to do some research on how the Generation 1 Pokemon games compressed an impressive amount of graphics data into the small cart size. It turns out that they use a form of RLE compression. I won't go into detail myself, but instead refer to a great YouTube video that very precisely describes how it works.
Essentially, this compression algorithm stands out because:
- It splits the graphics into bit planes (i.e. 1 bit-per-pixel images)
- It operates on pixel pairs, only encoding runs of pairs of 0's
- It uses several flags to control how the bit planes are mixed in order to increase compression ratios
- The original algorithm compresses 2bpp images (i.e. 4 colours). That being said, there is no reason why it cannot be extended to higher colour depths
Anyway, here is an implementation of a decompression routine for the Pokemon Generation 1 RLE image compression format. Overall, I'm not sure how useful this will be. It costs 400 tokens and decoding the sample 15x15 sprite in the demo cart takes 12 [email protected] On the plus side, it fits neatly into 544 bytes (less than a single row in the sprite editor), compared to its decompressed size of 7200 bytes, albeit with only a quarter of the colours. Note that the compression ratio greatly depends on the data. Also, I did not put much effort into optimizing the implementation for neither tokens nor CPU cyles.
In my opinion some of the "cool stuff" that this approach to compression does (that can be applied to other algorithms) is:
- Using a reduced colour depth greatly reduces graphics size
- RLE compressing a bit plane has some neat properties (the linked video goes into some more detail about this)
No, I didn't compress any other images out of laziness :P. However, you should be able to extract image data from any of the Gen1 game ROMs (this is what I used for test data). For example, this reads the compressed graphics for a (surprise :P) Pokemon located at offset 183637 and 244 bytes long from Yellow (English) version:
dd if=pkmn-yellow-en.gb of=surprise.pkz ibs=1 skip=183637 count=244
The cart makes use of the PICO-8 serial feature for dropped files, so if you have a compressed image, you should be able to load it by just drag-n-dropping it onto the running cart.
Additionally, the creator of the Youtube video I linked also created a web page for compressing/decompressing images. So if you have any 2bpp grayscale images that you want to try out, you should be able to compress them here: http://www.dotsarecool.com/rgme/tech/gen1decompress.html
[Please log in to post a comment]