p8x8: convert PICO-8 carts into Picotron carts (some assembly required)
I'm declaring p8x8 good enough for public release! It's a tool to convert pico8 carts to picotron -- it's not perfect and it requires some manual intervention in most cases, but it's magical being able to play a bunch of games on the new system without much effort.
Lots more info (instructions, compatibility notes, CC license, etc) here: https://github.com/pancelor/p8x8/
Teaser video here: https://mastodon.social/@pancelor/112162470395945383
changelog
v1.8 (#p8x8-8, unreleased)
- music/sfx conversion!! just waiting on picotron 010h to add instrument effects
v1.7 (#p8x8-7)
- fix secret palette
- add more docs
- add
p8x8_symbol_visual()
andp8x8_datastring()
alongsidep8x8_symbol()
to help convert symbols. details
Wow! It's not even been two weeks and we already have full backwards compatibility with PICO-8?! Incredible stuff!
looks great! though trying to use it on poom (the pico-8 doom port) it seems to crash
thanks for the report! I've fixed the bug in the exporter
(but note: POOM itself will not run using this tool -- it uses too many advanced/intricate features of PICO-8 which are out of scope for this tool. sorry! that would definitely be cool to see, but it would require a dedicated port)
Great work!! I've used it on several Pico carts and it works very well! Mostly just editing out special characters is enough to get things going.
Do you know how to run the carts (or any cart for that matter) in fullscreen mode? I see the vid() command in the Picotron readme on the desktop, but inserting it into LUA code just gives me an error ... although I can run it in the terminal and it changes the screen rez as it should.
Again, well done! P8x8 (great name too) is also very useful as a first step for porting things over, even on carts that don't run as-is ... takes care of getting maps and sprites and all the source code over to Picotron in one shot.
Thanks for sharing your work!
thank you @cystedtwister! It's a nice feeling to see someone else using it, and it's great to hear that the warnings and manual editing wasn't too much hassle!
fullscreen is already supported! it requires some manual tweaking:
load my-exported-cart.p64
- near the top of main.lua, find
local fullscreen = false
and change it to true - done! the cart now runs in fullscreen
- cool border images are supported too -- save a 480x270 image into sprite slot 1 of gfx/border.gfx
I need to organize the docs better, but FYI the reason vid wasn't working for you was probably because you put the vid()
call inside your pico8 code. The pico8 code is run in a sandbox that sees different global variables from normal code, so it doesn't know what vid
is. You can escape the sandbox by calling p64env.vid()
from inside pico8 code, but in this case it's best to use the builtin fullscreen support in main.lua
Ah, right! I forgot about the sandbox. Nice! Well that worked and it looks beautiful! Super cool. The only issue I'm getting is the keys don't work in fullscreen mode. Could this be an issue with the screen not getting focus? I haven't had a chance to look it over this morning, but will do this afternoon.
Super groovy. Thanks for your reply!
This is so cool!! Maybe this will motivate me to finish my pico8 game now that I can import it into picotron :>
So this can't handle Pico-8's extended character set? That's kind of a big roadblock for me then, as my projects have generally either used lots of shorthand symbols, or 8-bit strings for storing data.
I'm so stoked to get started with picotron now that this exists!!!
...one thing though, I can't find any info in main.lua on your git about borders or fullscreen.
@arrowonionbelly (hm, you might have been looking in the wrong main.lua -- the fullscreen toggle is in baked/main.lua. Also, I just pushed it much higher in that file, to a more noticeable location)
@cystedtwister yep exactly -- has_focus=true
needed to move out of the windowed section (it's updated now, both here and on github)
@JadeLombax -- correct, unfortunately. some assembly required! Pico8's extended characters get all unicode-y (they become 3-6 characters each) and break the parser in picotron; you could write a tool to replace them but the tool would need to guess what context/purpose the symbols have. If you write a down-arrow character in your code, is that meant to be the number 3 (if btnp(⬇️) then
), the image of an arrow (print("use ⬇️/⬆️ to move!")
), or the binary encoding of 131? It seems possible to make heuristics to decide which one to choose, but that sounds like a huge rabbit-hole and a lot of work for me to solve something that would be more easily solved by my users, who have the specific context to know what their code is supposed to mean.
I've decided that this sort of automatic conversion is out-of-scope for this tool, but maybe there are more things I could do to make it easier -- suggestions welcome. Currently, p8x8 generates warnings every time it notices pico8 extended characters, and the warnings suggest an easy upgrade path for the btn/fillp use case: WARN(minor): 1.lua#102 (p8:234) special chars (shift-X / chr(151)) are not supported. use this, for example: fillp(p8x8_symbol"❎") instead of fillp(❎)
(p8x8_symbol is a simple function I added to the sandbox environment that makes this work as expected)
For 8-bit strings in particular, the easiest thing to do is probably to regenerate those strings -- something like mydat=userdata("u8",length_here,"1234deadbeef")
or mydat={[0]=0x12,0x34,0xde,...}
. Maybe I should make a function like p8x8_symbol for this use case too? But I suspect you might run into other major issues with p8x8 (like the difference between number types in pico8 and picotron, and the way this affects bitwise operations. or the fact that p8x8 doesn't attempt to emulate the pico8 memory layout)
ok. I'll try it from the cart on here because I have no idea how to use the loose files on the git yet 😅
"@cystedtwister yep exactly -- has_focus=true needed to move out of the windowed section (it's updated now, both here and on github)"
Works like a charm!
ok I got it working! kinda... seems like my particle physics are boned, something to do with x and y values, not sure how that's gonna pan out, and NONE of the sounds carried over, but it's a start!
I just tried it with my new game and it worked straight away. This is brilliant. Thank you so much!
I made a rad border for my game in fullscreen mode and it prints my opening screen on top of the border, plus when I get game over and it restarts to the start screen, it blanks out the border.
Is it because I'm in vid3 mode? I tried it and rather liked the pixel resolution and didn't experience any blinking so I kept it, but if that's what's interfering with it that... would kinda suck lol.
My particle physics for starfield and rage are all starting way off-screen at the top. Other particles, like the explosions of enemies, are all localized where they need to be. Not sure what the issue there is but if anyone knows why picotron did that, please let me know.
Anyway, in case it's a ME-issue that nobody else is having, here's my pod
EDIT:
oh wait you updated it today. crap. How do I... use your updated code on my game, when I've already imported it and started editing my code in picotron?
EDIT EDIT:
Copied main.lua from baked over and ran it again but that doesn't seem to be the issue. Also switched from vid(3) to vid(0) and same issue of drawing the initial sprite on the left side of the screen. Strange. Anyone else experiencing this?
@arrowonionbelly - vid(3) versus vid(0) shouldn't make a difference -- I bet the problem is that you're calling drawing functions outside of _draw(). (confirmed by commenting out line 88 (spr(spr_border[0].bmp)
) and line 102 (if p8env._draw then p8env._draw() end
) of main.lua). If you're on github, lets talk here: https://github.com/pancelor/p8x8/issues/9 (but if not, here is fine)
> How do I... use your updated code on my game, when I've already imported it and started editing my code in picotron?
Oh, good question -- I'll add docs for that soon. Replacing main.lua is a good idea, since I've made some changes there to fullscreen mode. (note that you'll need to move your fullscreen border image to sprite slot 1) My other updates have generally been better compatibility warnings -- the code conversion hasn't changed, so you aren't missing much. But yes I'll add some docs.
thanks for the bug reports!
I tried making something similar to this a while back (even trying to emulate the 16.16 fixed point) but gave up when things became too convoluted. Insane stuff @pancelor!
THANKS SO MUCH FOR THE TOOL!! CONVERSION IS UNDERWAY!!!
if anyone makes a sound importer that would be rad, please let me know. Took me hours to manually make all my base instruments and then transcode just one sound effect (even the octaves and volume are different...ish)
super noob question, maybe someone can help me?
when I import the cart, I get an error message at the bottom that reads, "want a '.p8' file and not a '.p8.png' file."
am I saving Pico 8 carts incorrectly? thanks!
there are two ways to save carts! https://www.lexaloffle.com/dl/docs/pico-8_manual.html#_Loading_and_Saving
I unfortunately don't have PICO-8 yet, and so, I have no other method to inspect the lua codes within ".p8.png" files :(
Are there any other ways?
Never mind the last comment...
I've found that "shrinko8" can do what I need for now.
I'm glad that they give tools online for such situations...
you can load PNG cart on the edu edition: https://www.pico-8-edu.com/
This is shaping up to be a pretty solid tool for porting Pico-8 games to Picotron.
While attempting to convert my game Looping Larceny, I've discovered that the map
, dget
, and dset
functions are much less efficient here than they are in Pico-8. These functions were causing the game to run over five times slower in Picotron than in Pico-8, where the game runs perfectly. map
can be made faster by drawing less tiles, though.
Also, the flags
parameter of map
appears to be interpreted incorrectly- it appears to only draw tiles that match all of the flags, rather than any of the flags, if that makes sense.
thanks @bluswimmer! I've fixed those bugs (map is faster and interprets flags correctly now; dget/dset are much faster now). you can re-convert your cart or update the changed files (much more finnicky and not officially documented yet)
I'm curious if you had much trouble with converting Looping Larceny -- I couldn't get your palbrite
fading code to work. I just added support for the pico8 secret palette, but it isn't tested very well yet. So, I'm curious what sort of manual fixing you had to do to get that part to work (and if it's any easier now?)
(also note: now that map() just calls picotron's map(), sprite 0 is visible. I'm not sure what to do about that yet. I believe that's intended picotron behavior, so you should probably edit your sprite 0 to be entirely black. (when I converted Looping Larceny sprite 0 showed up on the initial "title screen" but was gone afterwards, very strange. afaict the pico8 poke to show/hide sprite 0 doesn't work in picotron, so I'm very confused why sprite 0 only draws sometimes, but I didn't dig into it))
Thanks for the quick fixes- the game still requires some optimizations to get it to full speed, but it runs significantly better out-of-the-box now.
Regarding palbrite
, I have not really attempted to update that function. For now I have left it commented out.
I pushed some more palette updates, and I was able to get palbrite
working in your cart, @bluswimmer!
function palbrite(b) local p,c,v=p8x8_datastring"あつてとなにぬきのはこふへほのみああちつちちかあうおあえいてうお" pal() for i=b,5 do for j=0,15 do c=peek(0x5480+j)+1 if(c>=48)c-=32 v=ord(sub(p,c,c))-154 if(v>=16)v+=32 pal(j,v,1) end end end |
There are a few changes:
- p8x8_datastring() makes the string hold the data you meant it to hold; explanation here
- I changed the peek address from
0x5f10
to0x5480
(a p8 -> p64 memory layout difference) - I changed the conditionals that messed with c/v if the color is from the secret palette. In p8x8 the secret palette is stored in palette indices 48..63, instead of pico8's 128..143
Wow, thank you! I'm not at my computer right now, but I'll try this out as soon as I can.
I tried this cart for a test. Have errors. https://pahammond.itch.io/berzerk Maybe the Picotron too new?
I have Pico-8 already. Fun game.
@Dunard What are the errors? p8x8 prints out a bunch of warnings for that cart, telling you things you need to fix to make it work -- maybe you mean those?
oh ok yeah I don't know anything about fixing Pico-8 games. No worry.
Whenever I try to load a .p8 cart it just displays a black screen, that is, it does not load any graphics at all. Am I downloading the carts wrong?
by load, do you mean drag-n-drop p8 cart on running p8x8?
following the instructions here: https://github.com/pancelor/p8x8/?tab=readme-ov-file#usage-guide
Yes, that's what I tried to do. Here's a gif of what happens:
I think your file is in a bad format; maybe it was originally celeste.p8.png, but you renamed it to celeste.p8? You need a "real" celeste.p8 instead.
You can create one inside pico-8 by running load celeste.p8.png
and then save celeste.p8
, or alternatively you can drag the PNG into https://thisismypassport.github.io/shrinko8/ with "target format: .p8 file" and "no minification" selected (then click download)
[Please log in to post a comment]