Hello there!
For the past 2 years me together with @MatheusMortatti have been slowly working on a full featured PICO-8 emulator with full RAM emulation and so on. And we are happy to announce, that the project is now finally in a playable state!
You can grab it for free on steam or compile it from source!
Huge thanks to all the authors, who allowed to include their carts in the release collection, and I hope this work will be useful for the community!
The code is written in a way to be easily ported to new platforms, right now we have pinvoke and SDL2 backends, and thats enough to run inside of Unity and all current gen consoles, but it's really easy to add support for platforms like 3DS and so on!
It's been an amazing journey! I'm super happy with how it turned out. If anyone is interested in helping with development, please reach out!!
Wow, PICO-8 really is a console now if we've got an emulator for it.
(haven't been able to mess with it, but I may sometime soon)
Super exciting! You know, consoles like Android really struggle to run Pico-8 games well. Hopefully, someone will port this to Android. Besides that, though, this is very impressive. I hope Pico-8 can become like Doom or Bad Apple where a whole bunch of devices can run it.
Hi @egordorichev. Superb work. May I suggest you also please upload your compiled project to ITCH.IO and if possible, here.
Uploading to STEAM requires you to download the STEAM engine executable installer (which I don't want to do) just to even run your project or even get a copy of it. Try clicking Play Game to see that you must have STEAM installed on your computer or it just won't play it.
Itch.io has no such restrictions or requirements.
Thank you !
The fact that @zep posted his own recent project, Pico-8 v0.2.4c on itch.io and NOT Steam tells me quite a bit right there, @MBoffin.
It's his choice of course, however I won't be able to examine or critique his project if the ONLY place it appears readily compiled is on STEAM. I suspect I am not alone in this.
You don't need to necessarily surmise why PICO-8 is not on Steam. He's been pretty open about his thoughts on the topic. That said, fortunately pemsa has been posted on Github, so until it's on itch, you're welcome to make your own compiled version from that, and even submit issues and changes there if you have critiques.
All that aside, amazing work, egordorichev and Matheus! This is seriously incredible work. I can't imagine how much time and effort you've put into it. And it was so wonderful to see it up on Github as well. Thank you! :)
Nicely done, thank you for posting your program on Itch, @egordorichev. I am trying out your program now and am suitably impressed. Gold star work.
I may have some questions and suggestions later. For now though this is quite exciting and interesting to examine !
. . .
OK:
-
I noticed that if you run the EXE in Windows it boots precisely as Pico-8, opening animation, timing and everything, so I am assuming you modified the original Pico-8 source code to build this project ?
- You have SPLORE. Since Pico-8 can now be run freely online HERE:
https://www.lexaloffle.com/bbs/?tid=47278
SPLORE is the one item that @zep left out in this online version requiring others to purchase Pico-8 properly for $15 in order to have it. Your program has SPLORE, in fact it boots to Splore - so those people interested in merely playing games can now use your engine with P8 files - not needing to purchase Pico-8.
-
Selecting the first cartridge, "8legstolove" with the 🅾️ key, it runs as normal. swapping between pressing the ESC key to bring up the menu with RESET and BACK TO MENU can at times turn the screen black and hang the EXE. I haven't been able to isolate where it happens exactly so it must be random.
-
You have included many sample games from authors I suspect without permission. This in itself is not an entirely bad thing as many I suspect are quite honored to be included in your list here. Some, however, may not be.
- If all the above are accepted and not considered a problem then I have a few suggestions, starting with A.
A. You are only looking for the arrow keys for navigation in your menus and ignoring the number keypad. Suggest you either include the number keypad as an added input or have an option for keyboard/joystick configuration.
B. Your speed of key repeat is very slow, about 2-keystrokes per second. You can see this by booting your EXE and holding the DOWN arrow key to see how slowly it goes from one title to the next.
C. You do not have the OPTIONS menu option available in your menu when you press ENTER or the ESC key. In OPTIONS you can turn the audio sound on or off, change the volume level of it, go to full-screen or not, and view the controls.
D. Add option to EXIT in menu. This will exit the executable neatly and in the case with Windows, return back to Windows. Currently you must press ALT-F4 to close this task or manually close it in the Task Manager.
. . .
I will be running tests of my own to see if my own code runs properly, including saving/loading SRAM of 12288 bytes. I will let you know. All in all, a marvelous program. There will always be questions and concerns for a program of this usefulness and magnitude.
These are some carts I tested running in your PEMSA, @egordorichev, by merely copying over the original P8 sourcecode to the directory your PEMSA runs from. The results were not good.
Prove 32-Colors: Fail, incorrect display Trucolor: Fail, hangs with no display Prove 12288: Fail, says "attempt to index a nil" where the program runs just fine in modern Pico-8. Mildew's Manor: Fail, hangs, no display, verdict: you are not running FLIP() the correct way. 23 Pages: Fail, hangs, no display Fillp Editor: Fail, hangs, no display |
That's enough for now. I think and correct if I am wrong, you are using an early source-code of @zep's that at the time did not run properly, FLIP() in addition to many other things including extended memory access, yes ?
Additionally in your program if you remove all the P8 source-code and transfer just one, say, one of the original that you included such as 8legslove.p8, running your program gives the notice, "NO CART. This is PEMSA. Insert a cart."
Congrats Egor & Matheus! Being intimately aware of PICO-8's dark corners and oddities, I can vouch that this is quite a feat of engineering!
I'm glad that projects like this exist -- it's fascinating to read alternative implementations, and acts as a proof of concept that it would be possible to recover from some catastrophic loss of the PICO-8 source code: e.g. I get hit by a bus and noone knows where it is or what should be done with it. Neither of those two things will happen (and the second one I have more control over), but it means that noone needs to take my word for it.
On that note, I do plan on making the source for PICO-8's runtime available sometime after 1.0. But it might still be some time away so haven't made any firm promises about it. pemsa and other implementations are a great way for authors to reach extra platforms that I haven't supported (yet).
@egordorichev
I do have a request ~ the Steam build looks an awful lot like PICO-8 to a casual newcomer. Would it be possible to rework it (and the logo / product description) to make it clearer this is a separate third-party product? I'm counting on Steam sales to be a large part of the 1.0 release, including the player demographic that makes up most of Steam (rather than authors / students), and I'm afriad this could potentially cause confusion.
@dw817
I don't think any of pemsa is using decompiled P8 source code or anything like that, just designed to imitate the thing it's emulating, which is a reasonable starting point!
On making splore less attractive as a feature to purchase for: it's possible to some degree, but I think being able to freely use the BBS web player is a similar consideration: it becomes clear that you can get a more integrated console-like experience with splore. This will be even more true with the addition of logins & scores at 0.3. I'm more worried about unpredictable secondary effects -- e.g. opportunists from outside the PICO-8 community who move to repackage carts and present them as an official thing slathered in advertising. But I don't want to unnecessarily add barriers for well-intended projects in order to combat these kind of hypothetical scenarios.
bug report: button presses leak through to the cart when launching it from the menu. pressing a button on the menu should cause that button to no longer register until it's been released
I understand, @zep.
If you're greenlighting this, that's fine with me. And yes, the ability to save global data in v 0.3 will definitely be of interest to me.
Likely for me not so much for simple high-scores as the ability to transfer shared complex data such as maps, sprites, and complex interpretive scripting code in the form of single strings exceeding 64-characters in length.
As for your worries about packaged Pico-8, we already have such programs available for the cellphone to run Pico-8 programs, primitive programs but programs nonetheless, such as the "P8 Player."
"Nest 2" looks like they jacked your 96-character font, every single character, pixel-per-pixel copy. Wow.
Likely there are other programs not just in Google Play but available for computers as well such as Windows and Macintosh. And they may be repackages.
Nonetheless if you can toss a cheery hat to all of this, I definitely welcome what the future holds for cosy Pico-8 and ultimately Picotron.
"Nest 2" looks like they jacked your 96-character font, every single character, pixel-per-pixel copy. Wow. |
@dw817 The PICO-8 font (and palette) are licensed as CC-0 (public domain), per the FAQ. So not really "jacked" so much as "used with permission."
"Nonetheless if you can toss a cheery hat to all of this, I definitely welcome what the future holds for cosy Pico-8 and ultimately Picotron."
And so it has.
@dw817 to address all your messages.
No, we have never decompiled PICO-8 or looked at it's source code in any way. For some technical things, like music bits and such the wiki does a pretty great job in explaining the memory layout.
Yes, the emulation is not perfect. The project started over 2 years ago, and since then PICO-8 was getting regular updates, for example oval() is not implemented what so ever. We had to not include some carts because we couldn't figure out how to get them working. But we thought that running complex carts like danktombs and such is enough of a feat to share with the community, instead of waiting for forever until this whole project is 100% accurate (and that will never be true, sadly). We will do our best to bring the project as close to perfect emulation, as possible, but again, it is really tough, people do all sorts of crazy things with their code, for example I've just learned that you could pass strings instead of numbers to some functions. Crazy!
About the carts. All the carts authors gave their permission to run their carts inside of the collection, some preferred to stay away from the project and we did not include their carts.
> I noticed that if you run the EXE in Windows it boots precisely as Pico-8, opening animation, timing and everything, so I am assuming you modified the original Pico-8 source code to build this project ?
If you look at BBS there are plenty of examples of people recreating the boot effect in PICO-8 itself :)
> Additionally in your program if you remove all the P8 source-code and transfer just one, say, one of the original that you included such as 8legslove.p8, running your program gives the notice, "NO CART. This is PEMSA. Insert a cart."
That's how pemsa-sdl is designed to run. It looks for a cart named splore, if it finds it it boots it (or any other cart supplied by the command line arguments), otherwise it plays the no cart animation. So if you want to run your single cart, do pemsa cart.p8
(or pemsa.exe cart.p8
).
Splore is not really splore, it's just a way to select a cart, it has no web access or anything, no favorite carts, etc, it's just a basic menu. So I don't really see an issue with it being a thing. Maybe just calling it splore is not the best thing ever, but that's just out of habbit.
Otherwise, thanks for the bug reports, will be working on them in the near future :)
@zep Sure. Messaged you on discord about the details.
Hi @egordorichev. Thanks for the information. I also tried to examine SPLORE, curious to see if you were just calling, "SPLORE" or something more complex. What I got was this:
pico-8 cartridge // http://www.pico-8.com version 29 __code__ A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z = -2560.5, 31455.5, 32125.5, 1, 6943.5, 3855.5, 2, -19008.5, 4, -20032.5,0.5, -20128.5, 3, -18402.5, -1632.5, 20927.5, -26208.5, -20192.5, 0, 21845.5, 5, 20767.5, -2624.5, 23130.5, -25792.5, -24351.5 sub, cocreate, coresume, yield, costatus, __debug, debug, run, unpack, pack = string.sub, coroutine.create, coroutine.resume, coroutine.yield, coroutine.status, debug, nil, __reset, table.unpack, table.pack function __error(e) print('runtime error',nil,nil,14) print(e,nil,nil,6) print(__debug.traceback(),nil,nil,13) end function foreach(a, f) for i in all(a) do f(i) end end function count(a) if not a then return 0 end return #a end function arraylen(t) local len = 0 for i, _ in pairs(t) do if type(i) == "number" then len = i end end return len end function all(a) local n = arraylen(a) if a == nil or n == 0 then return function() end end local i = 1 local previous_i = nil return function() if (a[i] == previous_i) then i = i + 1 end while (a[i] == nil and i <= n) do i = i + 1 end previous_i = a[i] return a[i] end end function add(a, v, i) if a == nil then return end if i then table.insert(a, i, v) else table.insert(a, v) end return v end function del(a, dv) if a == nil then return end for i, v in ipairs(a) do if v == dv then table.remove(a, i) return dv end end end function deli(a, i) if a ~= nil then table.remove(a, i) end end function __load_splore() __load("splore") __reset_graphics() end local __menu_options_custom={} local __current_option=1 local __menu_on=false local __menu_functions={} local __favorite=false function __update_menu() if not btnp(6) and not __menu_on then return end local __menu_options={} for o in all(__menu_options_custom) do add(__menu_options,o) end add(__menu_options,"continue",1) add(__menu_options,"favorite") add(__menu_options,"reset cart") add(__menu_options,"back to menu") if (btnp(6) or (__menu_on and (btnp(5) or btnp(4)))) and __cart~="splore" then if __menu_on and __current_option==#__menu_options-2 then __favorite=not __favorite else __menu_on=not __menu_on __set_audio_paused(__menu_on) __set_paused(__menu_on) if not __menu_on then local fn=__menu_functions[__current_option-1] if __current_option==#__menu_options -1 then fn=__reset end if __current_option==#__menu_options then fn=__load_splore end if fn then fn() end cls() end end end if not __menu_on then return end if btnp(2) then __current_option=__current_option-1 if __current_option<1 then __current_option=#__menu_options end end if btnp(3) then __current_option=__current_option+1 if __current_option>#__menu_options then __current_option=1 end end local h=10+#__menu_options*8 local x=24 local y=(128-h)/2 rectfill(x,y,x+81,y+h-1,0) rect(x+1,y+1,x+80,y+h-2,7) local ax=x+5 local ay=y-1+__current_option*8 for i=0,2 do line(ax+i,ay+i,ax+i,ay+4-i,7) end for i=1,#__menu_options do local current=__current_option==i print(__menu_options[i],x+11+(__menu_options[i] and 1 or 0),y-1+i*8,7) if i==#__menu_options-2 then print("\135",x+51,y-1+i*8,__favorite and 8 or 13) end end end function menuitem(i,name,fn) if i<1 or i>5 then return end __menu_options_custom[i]=name __menu_functions[i]=fn end function rnd(i) if type(i)=="table" then return i[flr(__rnd(#i))+1] end return __rnd(i) end function split(i,s,c) if s==nil then s="," end if c==nil then c=true end local t={} for p in string.gmatch(i,"([^"..s.."]*)("..s.."?)") do local n if c~=false then n=tonum(p) end add(t,n==nil and p or n) end return t end if not __skip then local data="00077770007777700070700000777000007770000000000000777770007777700070707000700070000000000077777000777770000770000000770000077000007777700077777000000000000770700077707000707770007077700000000000777770007777700070700000777770000777700000000090a0b000001000008111c00000100000f0e0d000" local function wait(a) for i = 1,a do flip() end end cls() for y=0,127 do for x=2,127,8 do pset(x,y,rnd(6)) end end wait(3) for y=0,127,2 do for x=0,127,4 do pset(x,y,6+flr((x+y)/8)%8) end end wait(3) for y=0,127,3 do for x=2,127,4 do pset(x,y,10+rnd(4)) end end wait(3) for y=0,127 do for x=1,127,2 do pset(x,y,pget(x+1,y)) end end wait(2) for y=1,127,4 do memset(0x6000+64*y,0,64*3) end wait(3) cls() wait(15) local osfx="" for i=0,67 do osfx=osfx..tostr(peek(0x3200+i),true) end local s="0070.00000059.0000006b.0000005b.00000070.0000005b.00000075.00000059.00000075.00000053.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000001.0000000c.00000000.00000000.0000" local function psfx(d) for i=0,67 do local ind=i*9+1 poke(0x3200+i,tonum("0x"..sub(d,ind,ind+8))) end end psfx(s) sfx(0) for x=0,34 do for y=0,7 do local i=x*8+y+1 pset(x+1,y+3,tonum("0x"..sub(data,i,i))) end end wait(5) color(6) cursor(0,18) print("pemsa v0.1 v0.1-9-ge7ffe33") wait(5) print("(c) 2014-20 unofficial\n") print("\nbooting catridge...") wait(40) psfx(osfx) end cartdata("__splore") local current=max(1,dget(0)or 1) function read_card() title,author=__read_cdata(carts[current][1]) carts[current]={ carts[current][1], author, title } end function _init() carts=__list_carts() current=min(#carts,current) for c in all(carts)do title,author,label=__read_cdata(c[1]) c[2]=author c[3]=title=="unknown" and c[1] or title c[4]=label end if #carts == 0 then while true do cls() print("no carts found", 1, 1) flip() end end update_bg() end function update_bg() dset(0,current) local c = carts[current] if not c then return end local d=c[4] for i=0,128*128-1 do sset( i%128,flr(i/128), tonum("0x".. sub(d,i+1,i+1)) ) end end function _update() if(btnp(G)) then current=max(1,current-1)update_bg()sfx(0) end if(btnp(M)) then current=min(#carts,current+1)update_bg()sfx(1) end if(btnp(U)or btnp(I)or btnp(6))then __load(carts[current][1]) end end function _draw() cls() sspr(0,0,128,128,0,0) local x,y=16,72 local ex,ey=112,127 rectfill(x-1,y-1,ex+1,ey+1,7) rectfill(x,y,ex,ey,0) clip(x,y,ex-x-1,ey-y+1) local mod=current>6 and (current-6)or 0 for i=1,9 do local cart=carts[i+mod] if cart then local yy=y+1+(i-1)*8 local l=#cart[3]*4 local c=7 if i+mod==current then rectfill(x+1,yy,x+2+l,yy+6,14) rectfill(x+2+l,yy,ex-1,yy+6,15) c=0 end print(cart[3],x+2,yy+1,c) end end clip() end |
Here, for instance, is the opening code to, 8legstolove:
pico-8 cartridge // http://www.pico-8.com version 29 __code__ A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z = -2560.5, 31455.5, 32125.5, 1, 6943.5, 3855.5, 2, -19008.5, 4, -20032.5,0.5, -20128.5, 3, -18402.5, -1632.5, 20927.5, -26208.5, -20192.5, 0, 21845.5, 5, 20767.5, -2624.5, 23130.5, -25792.5, -24351.5 sub, cocreate, coresume, yield, costatus, __debug, debug, run, unpack, pack = string.sub, coroutine.create, coroutine.resume, coroutine.yield, coroutine.status, debug, nil, __reset, table.unpack, table.pack function __error(e) print('runtime error',nil,nil,14) print(e,nil,nil,6) print(__debug.traceback(),nil,nil,13) end function foreach(a, f) for i in all(a) do f(i) end end function count(a) if not a then return 0 end return #a end function arraylen(t) local len = 0 for i, _ in pairs(t) do if type(i) == "number" then len = i end end return len end function all(a) local n = arraylen(a) if a == nil or n == 0 then return function() end end local i = 1 local previous_i = nil return function() if (a[i] == previous_i) then i = i + 1 end while (a[i] == nil and i <= n) do i = i + 1 end previous_i = a[i] return a[i] end end function add(a, v, i) if a == nil then return end if i then table.insert(a, i, v) else table.insert(a, v) end return v end function del(a, dv) if a == nil then return end for i, v in ipairs(a) do if v == dv then table.remove(a, i) return dv end end end function deli(a, i) if a ~= nil then table.remove(a, i) end end function __load_splore() __load("splore") __reset_graphics() end local __menu_options_custom={} local __current_option=1 local __menu_on=false local __menu_functions={} local __favorite=false function __update_menu() if not btnp(6) and not __menu_on then return end local __menu_options={} for o in all(__menu_options_custom) do add(__menu_options,o) end add(__menu_options,"continue",1) add(__menu_options,"favorite") add(__menu_options,"reset cart") add(__menu_options,"back to menu") if (btnp(6) or (__menu_on and (btnp(5) or btnp(4)))) and __cart~="splore" then if __menu_on and __current_option==#__menu_options-2 then __favorite=not __favorite else __menu_on=not __menu_on __set_audio_paused(__menu_on) __set_paused(__menu_on) if not __menu_on then local fn=__menu_functions[__current_option-1] if __current_option==#__menu_options -1 then fn=__reset end if __current_option==#__menu_options then fn=__load_splore end if fn then fn() end cls() end end end if not __menu_on then return end if btnp(2) then __current_option=__current_option-1 if __current_option<1 then __current_option=#__menu_options end end if btnp(3) then __current_option=__current_option+1 if __current_option>#__menu_options then __current_option=1 end end local h=10+#__menu_options*8 local x=24 local y=(128-h)/2 rectfill(x,y,x+81,y+h-1,0) rect(x+1,y+1,x+80,y+h-2,7) local ax=x+5 local ay=y-1+__current_option*8 for i=0,2 do line(ax+i,ay+i,ax+i,ay+4-i,7) end for i=1,#__menu_options do local current=__current_option==i print(__menu_options[i],x+11+(__menu_options[i] and 1 or 0),y-1+i*8,7) if i==#__menu_options-2 then print("\135",x+51,y-1+i*8,__favorite and 8 or 13) end end end function menuitem(i,name,fn) if i<1 or i>5 then return end __menu_options_custom[i]=name __menu_functions[i]=fn end function rnd(i) if type(i)=="table" then return i[flr(__rnd(#i))+1] end return __rnd(i) end function split(i,s,c) if s==nil then s="," end if c==nil then c=true end local t={} for p in string.gmatch(i,"([^"..s.."]*)("..s.."?)") do local n if c~=false then n=tonum(p) end add(t,n==nil and p or n) end return t end if not __skip then local data="00077770007777700070700000777000007770000000000000777770007777700070707000700070000000000077777000777770000770000000770000077000007777700077777000000000000770700077707000707770007077700000000000777770007777700070700000777770000777700000000090a0b000001000008111c00000100000f0e0d000" local function wait(a) for i = 1,a do flip() end end cls() for y=0,127 do for x=2,127,8 do pset(x,y,rnd(6)) end end wait(3) for y=0,127,2 do for x=0,127,4 do pset(x,y,6+flr((x+y)/8)%8) end end wait(3) for y=0,127,3 do for x=2,127,4 do pset(x,y,10+rnd(4)) end end wait(3) for y=0,127 do for x=1,127,2 do pset(x,y,pget(x+1,y)) end end wait(2) for y=1,127,4 do memset(0x6000+64*y,0,64*3) end wait(3) cls() wait(15) local osfx="" for i=0,67 do osfx=osfx..tostr(peek(0x3200+i),true) end local s="0070.00000059.0000006b.0000005b.00000070.0000005b.00000075.00000059.00000075.00000053.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000001.0000000c.00000000.00000000.0000" local function psfx(d) for i=0,67 do local ind=i*9+1 poke(0x3200+i,tonum("0x"..sub(d,ind,ind+8))) end end psfx(s) sfx(0) for x=0,34 do for y=0,7 do local i=x*8+y+1 pset(x+1,y+3,tonum("0x"..sub(data,i,i))) end end wait(5) color(6) cursor(0,18) print("pemsa v0.1 v0.1-9-ge7ffe33") wait(5) print("(c) 2014-20 unofficial\n") print("\nbooting catridge...") wait(40) psfx(osfx) end cartdata("bridgs_8legstolove_1") local scene local next_scene local transition_frames_left=0 local scene_frame local level_num local level local level_tileset local score local score_cumulative local bugs_eaten local timer local frames_until_spawn_bug local spawns_until_pause local spider local entities local new_entities local web_points local web_strands local moving_platforms local tiles local level_spawn_points local wind_frames local wind_dir local wind_x local wind_y local menu_buttons local is_story_mode local tile_flip_matrix={8,4,2,1,128,64,32,16} local scenes={} ... more code ... |
Which not only doesn't run in Pico-8, but if you change the code to lua which is standard with Pico-8, it still doesn't run - it shows errors.
So ... these games you've included have all been converted to a format that does not recognize standard Pico-8 ? Which is odd as if you add a normal Pico-8 game to the directory, such as "Pico Monsters," it =DOES= run properly. so ... why convert all those games to a non-Pico-8 format if in their original format they run just fine ?
@dw817 it's called code for a reason. Pemsa is perfectly capable of running the regular p8 files. But it needs to preprocess PICO-8 lua code into regular lua to run it properly. The result can be stored in the code section. For this collection, I've opted to include preprocessed cards to reduce load times and avoid potential issues.
If you take 8legstolove from PICO-8 BBS in the p8 format and run it with pemsa it will run just fine :)
Wow geeze, you're really tearing into them, aren't you dw817? Ease up a lil...
I don't know for sure, but I think my cart might be the first one that just, blindly recreated the boot animation, including the sound effect?
Those low cart numbers, ah. It's been a while.
Not at all, @JTE. I'm observant. What egordorichev has done goes beyond regular thanks. It is absolutely incredible and wonderful what he has written. I am not doubting this and it is definitely worthy of everyone's gold stars.
A large part of my understanding things comes from being observant when something doesn't function conventionally. From examining absolutely everything around me. It is part of my learning process and leads me to discovering things others may miss.
And yes I did earlier mention that PEMSA does run "most" regular Pico-8 carts, no problem. Which ... is why I was first concerned I could not load any of the demo carts from PEMSA in regular Pico-8.
Which prompted me to examine both of them side-by-side seeing character additions and discrepancies. Especially of note having, "__code__"
instead of "__lua__"
... I suppose if PEMSA just originally ran my own carts without fail, such as Mildew's Manor where it crashes, I wouldn't have taken the time to find out why it wasn't working and would've placed a green checkmark beside it and moved on.
[Please log in to post a comment]