I needed a way to display graphics without using sprites/ or tiles.
So I wrote a small python script that takes an 128x128 image, finds the best matching colors from either the normal or secret palette (or the best 16 colors of both) and stores that in a data string.
If there's interest I can share the python code - main reason I haven't done so is, that I haven't made he python script user friendly :)
No sprites used in this demo.
You can download the image -> string conversion tool and some example code here:
https://github.com/iSpellcaster/pico8rle
This is quite interesting! An image to binary convertor would be incredibly useful in projects, especially if you run out of sprite space
Yeah, that was the idea. But you're swapping sprite space for character count. Still thinking about good ways to reduce the character count.
Right now the batman screen will eat 2696 characters.
I think I can get that down to 2210 by changing the explode_internal() code that I got from this forum.
Updated the cart. It's now using the base64 encoded format. Added an additional screen while reducing the character count quite a bit overall.
The tool to create the rle strings can be found here:
https://github.com/iSpellcaster/pico8rle
Great images. This - and what others have been showing - is all looking very good for displaying images fairly efficiently.
Edit: Removed a large comment regarding a minor bug. My apology for (albeit tentatively) misplacing where the bug was.
Previous post also mentioned the recently introduced pico-8 split command for turning a string into a table. Details are in pico-8.txt.
@spellcaster Glad I could help. =)
@remcode - you're the BEST!
The bug was totally on my side, though!
In my render_rle code, I was missing the last run length.
while i < #table do |
should have been
while i <= #table do |
I should write a small program that writes 100x "Lua is not C" to remember the lua indices...
Thanks a lot!
see Twitter reply for a version using a bit less tokens and faster.
@freds72 - thanks!
I started he code before the update, so I didn't have the shift operators. Wouldn't have guessed that they are that much faster than shr/shl.
I was also stumped to see that the local vars inside the loop are faster local vars outside the loop.
Will update the example code right away.
@freds72 - I was able to get some extra performance out of the spr_rle_flip code, and thought that might be interesting for you.
Will update the cart in a moment.
function spr_rle_flip(table,_x,_y) local w=table[1] local x,y,i,x2=_x+w,_y,3,_x+w for i =3,#table do local t=table[i] local col,rle = (t& 0xff00)>>8 ,t& 0xff if col!=0 then rectfill(x-rle+1,y,x,y,col) end x-=rle if x <=_x then x = x2 y += 1 end end end |
init new vars is faster than updating a value (a bit odd..)
I must admit I rushed the flipped version! nice you had the maths ‘packed’.
note: you have a stray local i that’s not needed
Interesting, I did the same thing with initializing values in my version. I'm going to look into unpacking the string into a table in a compact way, though, as that seems to offer a substantial performance boost over using ord() directly.
I'm still new to bitmasks, is the difference between spr_rle() and draw_rle() that spr_rle() checks to see if there's anything to draw first; so, slightly less cpu-intensive at the cost of a few tokens?
EDIT: Wait, I think I get it. spr_rle() and spr_rle_flip() draw nothing when the value is 0 because that's the transparent value.
@spellcaster, it looks like the script misses on picking color 9 (orange). I wish I knew how else to help! 😅
EDIT: I just noticed it misses on color 13 (lavender?) as well.
@ridgekuhn - yep, the difference between the draw and the spr function is the transparency check. Draw will also fill color 0 (useful for backgrounds).
Will check the what's going on with the colors 8/13 bug. Thanks for finding it :)
@ridgekuhn - found it, fixed it. The current version of the python script on github should work as expected.
I must have messed up defining the palette values in the python script.
@spellcaster Wow, that was fast! Thanks so much for taking care of it! I made this horribly ugly Living Worlds tribute with it, lol.
This is only using one image and so, only 4 colors for the palette cycle. I realized towards the end that I could use more if I made the waterfall into its own image and draw it with spr_rle(), or maybe layer multiple animations if the CPU allowed.
@ridgekuhn did you try the different palette options for it? It does look pretty cool thought :)
I wouldn't have any complaints at all, only writing this because you think it's ugly (which I don't think it is :) )
@spellcaster Well, thank you! ☺️ I didn’t try the palette options, I’d already crushed the image down to the regular Pico-8 palette bc I was testing it with the hex string tool I used on my last cart. btw, I forgot to mention, your script errors out with indexed-color PNGs. Not a problem imo (bc it’s redundant to convert them first since your script does the indexing for you), but probably worth mentioning!
@ridgekuhn - That was caused by a "bugfix" added in the last updated. I added a dummy alpha channel value. And since I'm pretty new to python I kinda thought it would resolve this the same way as lua does. Spoiler: it doesn't.
Fixed it, please let me know if you find any other problems.
Will do, friend! Thanks again for this wonderful little library! 😃
@spellcaster edit: nvm, I found a workaround and this probably isn't worth chasing down!
@ridgekuhn:
Nah, tell me. I hate bugs
If it was the witched pal index thing - I fixed that. If it was a different thing: I'd like to fix that. Currently working on a small update anyway... although I
m not sure if it's going to be an official thing - that depends on how easy it will be to automate the steps I'm currently doing by hand (while checking the feasbility of the approach)
So started playing with this, but noticed the option to combine the 2 palettes isn't producing the correct results. If I use an output file - the output file looks correct, but when using the string with the palette, i get something that looks just like pal2 instead of the combined palettes.
Source image
Output image
DRAW_RLE in pico-8
Strange no?
Now that we have 'split', improved 'ord' function and good support for binary data (https://www.lexaloffle.com/bbs/?tid=38692), I think this cart could have a v2 that takes fewer tokens and is maybe more efficient!
Well, I put out a simplified version of this system some time ago. Includes an easy-to-use Pico-8 encoder and has a few different decoder variants, starting at just 74 tokens. My encoder won't automatically select colors between both palettes, though.
https://www.lexaloffle.com/bbs/?tid=38829
Not sure yet how split() or the new ord() functionality might help, have to think about that.
[Please log in to post a comment]