(v01 09-29-22)
TO LOAD THIS PICO-8 CART, in immediate mode, type: load #spr2p8sci
Hello there.
If you are running this code in Pico-8, you will see that the Spritesheet does not contain this picture ! Instead there is only a single line of code, and a PRINT statement at that to create the display you see above. How is this possible ? Well, we need to go back a day to find this out.
I was taking a look at @GPI's marvelous example of multi-poke using P8SCII code:
https://www.lexaloffle.com/bbs/?tid=49517
And I thought to myself, it would be interesting to write code that could save off an entire 128x128 16-color picture as a single print command. Could it be done ? And yes, it could. The picture above for instance is just 8948-text characters directly in source-code as a single PRINT statement.
It looks a little like this:
?"\^!6000ちちたた▥▥▥ホIお🅾️🅾️🅾️🅾️🅾️🅾️ ...
To do so in your own work and code is quite simple, load up the code I wrote here by bringing up Pico-8 EXE and then loading my cart with: load #spr2p8sci
Change to the directory you have a 128x128 picture you want to convert. From there in immediate mode type, import pic.png
which contains the 128x128 picture you want to convert to a single line of P8SCII code.
Call my function, spr2p8sci()
which is 230-characters long so it's fast and doesn't take much code space.
Once that is done the current picture in the spritesheet will then be saved to clipboard, ready to paste in your code. And be aware that you can post this single line all by itself with nothing else written in your code and it will still display properly.
So in a newly opened Pico-8 process you want to have this picture appear in, in your source-code, press CTRL+P first to enter puny font mode, then press CTRL+V to paste it. Then CTRL+P to leave puny font mode, and there you have it.
Run that code to see that you do not need any functions or code at all except for that one-line to house your picture.
And there you have it !
Now I also want to mention that this is getting compressed of a sort. That is I am NOT just taking every byte of the spritesheet and converting it over with 4-characters in the format, \000
. Nope, because that would take 32768-characters not even counting the print
and quotes and that might not even fit on a single line. I don't know what the limitations are to a single line.
Nor is it doing it via \0
\00
and \000
for 3-digits. That method takes exactly 30687-characters for the current picture.
No, instead I am converting every single byte to a readable character if it is permitted, going from 30687-characters down to even smaller. Now considering the actual graphic memory is 8192-bytes and even converting raw 8192-bytes to 6-bit yields 10923-characters, this method of P8SCII is quite the compression at only 8948-characters !
Which is only 9% bigger than raw memory. And doubtless that could be compressed further from there.
So, yes, that picture above is only 8948-typed characters with no other code needed.
Also if you want to change the memory your picture is stored instead of the screen, simply change the print
statement to: ?"\^!
followed by the 4-digits of hexadecimal memory, currently 6000
you want to put the picture. If if it is 0000
that is the spritesheet, yet you can also store your pictures in high memory such as 8000
A000
C000
and E000
.
Easy to use. Single function, and creates a single line of code close to actual memory size for your picture to display !
Hope This Helps !
Enjoy.
I think I'm gonna fix that pic above. All credit really should go to @zep for his amazing programming language.
I think a found a bug in your code, when it try to code this hex values:
00 49 48 65
it will create
/010A
and this will result in
10 65
You must check afer a 00, if a number follows. In this case you must add a full "/000" instead of a short "/0".
Also you can code /010 in /n, /013 in /r and /009 in /t.
And btw, when you load a cartridge in jaP8e, go to the HEX-Module, select "Sprite" and hit [CTRL]+[C], it will generate the char-string and copy it in the clipboard.
Hi @GPI:
Nope. I am coding all digits "0" (49) through "9" (57) as "\48"
"\57"
etc. I saw this possibility of an error earlier.
So what you have above of 00 49 48 65
will convert to: "\0\49\48A"
However please try a picture if you like that you think it will not get correctly. If it is not displaying the picture properly, please post the picture HERE in a comment and I will use that as a basis to correct my program.
And thanks for your interest !
Oh I've read the title and thought we both did exactly the same thing but I see it's different. I'm using one-off chars, initially with the idea of the good old monochrome+fore/background recoloring on each 8x8 block (as it used to work in old 8bit machines like ZX Spectrum) but then extended it to support more than 2 colours in the same block if needed for details etc. Of course it works best when each 8x8 block is not packed with different coloured pixels.
A wisely drawn full 128x128 spritesheet will result in a ~3700 characters string.
I pasted the same test image (3686 chars for mine) in your cart and it's 10647 chars long. But yeah I suppose your method would perform better with a lot of colours, regular gfx, no old-school tricks/constraints.
Although I've prepared the one-off chars method a couple months ago and used in my current project yeah I still need to post it on bbs, in case others could find it useful. A chars-cheap method to have several full screens in one cart. I'll post it soon (once I manage to finish my game).
@Heracleum --waves hand--
I've also been working on this kind of approach. Not sure when I will be finished to post it...
I started off with one-off characters too and moved to using the custom font to store 1bit 8x8 'tiles'. The custom fonts can make tile re-use and rendering more flexible in my case.
I'm doing a similar type of encoding for cpp 'magic' strings using a bash script.
Hi @aced and @Heracleum:
This could indeed be compressed.
https://www.lexaloffle.com/bbs/?tid=45335
The gist was to have it all available as a single PRINT statement not requiring a decompression algorithm first.
The problem is there is no way to plot a single colored pixel at the cursor and automatically move to the right for the next pixel or have a character that does a CR in that picture area.
https://www.lexaloffle.com/bbs/?tid=49556
If and when it can do this, then it might be possible to use the \*
for repeat in large areas of repeated colors. Currently not though.
This is the best I can do to maintain a single image for a single print statement.
There is an additional method I have in mind that will help -reorganize- the data in the print statement so it uses less characters. I'll work on that method Monday (10-03-22) tomorrow.
[Please log in to post a comment]