dddaaannn [Lexaloffle Blog Feed]https://www.lexaloffle.com/bbs/?uid=9599 The Chrome 71 autoplay sound issue <p>Chrome 71 (December 2018) implements the new autoplay audio policy for the Web Audio API, which affects the Pico-8 web player. The BBS is OK because it implements a &quot;curtain&quot; that the user clicks on to start the player, which does the Web Audio enable interaction. But this breaks the exported web player as of Pico-8 0.1.11g: If I export a game to its own page then load the page, Pico-8 starts immediately and is disallowed sound. No interaction enables sound after this point.</p> <p>One fix is for the exported web player to implement a curtain similar to the BBS. I don't know if that meets everyone's needs but would resolve the issue for the exported page. I assume we can work around this by implementing our own player curtain.</p> <p>Interesting side note: This appears to affect stat() calls regarding sound as well. I have a cart that paused on stat(24) != 0, to wait for music to finish playing. The web export with sound disabled never gets past this point. I added a timeout for the pause to get around this, though I still don't have sound in this case.</p> <p><a href="https://developers.google.com/web/updates/2017/09/autoplay-policy-changes">https://developers.google.com/web/updates/2017/09/autoplay-policy-changes</a></p> https://www.lexaloffle.com/bbs/?tid=32513 https://www.lexaloffle.com/bbs/?tid=32513 Sat, 08 Dec 2018 21:55:39 UTC YouTube field in profile needs nuance <p>I notice that the YouTube field of the BBS profile only accepts alphanumeric characters, and whatever is entered becomes a link of the form www.youtube.com/&lt;alphanumericfield&gt;. I'm mostly ignorant of how this part of YouTube works, but my understanding is that not everyone can reserve a youtube.com/&lt;alphanumericfield&gt; URL. You need a certain number of followers, have qualifying channel art, etc. Everyone gets a www.youtube.com/channel/&lt;randomlyassignedalphanumeric&gt; channel URL, but I can't enter that into my BBS profile and get a working link.</p> <p>There's some history with G+ URLs that I've forgotten the details of. It looks like anyone can reserve a www.youtube.com/c/&lt;alphanumericfield&gt; URL. At least I have one, not sure how. But I can't enter that in either.</p> <p>I think the YouTube profile field needs to accept more values and/or provide hints in the profile form on how to link a profile to a channel.</p> https://www.lexaloffle.com/bbs/?tid=32510 https://www.lexaloffle.com/bbs/?tid=32510 Sat, 08 Dec 2018 19:29:23 UTC BBS still doesn't like image filenames with spaces <p>The BBS fails silently when I attempt to attach an image whose filename contains spaces. The upload appears to be successful, but it doesn't appear in the list of available images.</p> <p>I remember this bug from the previous version of the BBS, so it's not new.</p> https://www.lexaloffle.com/bbs/?tid=32446 https://www.lexaloffle.com/bbs/?tid=32446 Tue, 04 Dec 2018 07:34:44 UTC Getting signed out of the BBS quickly <p>It appears that I have to sign in to the BBS on a daily basis. This does not appear to be intentional, and it's certainly annoying. I believe in the previous version of the BBS we had a one month sign-in expiration.</p> <p>My cookies seem to be in reasonable shape for expiration dates:</p> <p>www.lexaloffle.com:<br /> PHPSESSID: when browsing session ends<br /> pass: one month<br /> user: one month</p> <p>lexaloffle.com without the www also sets a cookie, __cfduid, but this doesn't seem related. I have tried clearing and recreating all of these cookies, with no change of behavior.</p> https://www.lexaloffle.com/bbs/?tid=32445 https://www.lexaloffle.com/bbs/?tid=32445 Tue, 04 Dec 2018 07:33:37 UTC macOS &quot;z&quot; pop-up in the web player <p>When playing a game in the web player, if I hold the z key (&quot;o&quot; button), I get the macOS diacritic editor. This interrupts play. I don't recall seeing this prior to the BBS/player update.</p> <p><a href="https://www.lexaloffle.com/bbs/files/9599/macos_held_z.png" target=_view_image><img style="" border=0 src="https://www.lexaloffle.com/bbs/files/9599/macos_held_z.png" width=108 height=160 alt="" /></a></p> https://www.lexaloffle.com/bbs/?tid=32443 https://www.lexaloffle.com/bbs/?tid=32443 Tue, 04 Dec 2018 07:26:40 UTC Santa Panic! <p> <table><tr><td> <a href="/bbs/?pid=59302#p"> <img src="/bbs/thumbs/pico8_santapanic-0.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=59302#p"> Santa Panic!</a><br><br> by <a href="/bbs/?uid=9599"> dddaaannn</a> <br><br><br> <a href="/bbs/?pid=59302#p"> [Click to Play]</a> </td></tr></table> </p> <p>Santa Panic! A gift wrapping arcade game for 1 or 2 players, by dddaaannn and TimSwast. This is game 9 of the PICO-8 Advent calendar 2018.</p> <p>Get those presents wrapped and in the right spots, and get yourself back up the chimney, before you're found out!</p> <ul> <li>Directional pad to move.</li> <li>&quot;O&quot; button to pick up, then &quot;O&quot; again while not moving to drop, or while moving to throw.</li> <li>Wrap a present by walking it to a wrapping station.</li> <li>Pick up your sack and walk into the chimney to leave.</li> </ul> <p>Two player co-op available! You could use the help, but make sure both of you get to the chimney in time!</p> https://www.lexaloffle.com/bbs/?tid=32312 https://www.lexaloffle.com/bbs/?tid=32312 Fri, 23 Nov 2018 22:10:33 UTC GameShell sale: $119! <p>ClockworkPi is having a &quot;Black Friday&quot; sale on GameShells, only $119 (40% off) today only!</p> <p><a href="https://www.clockworkpi.com/"><a href="https://www.clockworkpi.com/">https://www.clockworkpi.com/</a></a></p> <p>This is the <em>new</em> version of the GameShell with more memory and microHDMI out. It <a href="https://www.lexaloffle.com/bbs/?tid=31569">runs Pico-8</a> and is my favorite Pico-8-capable handheld to date.</p> <p>I am not affiliated with ClockworkPi, I'm just passing along the info. Enjoy!</p> https://www.lexaloffle.com/bbs/?tid=32311 https://www.lexaloffle.com/bbs/?tid=32311 Fri, 23 Nov 2018 12:20:29 UTC Pico-8 on a GameShell, review and howto <img style="" border=0 src="https://www.lexaloffle.com/bbs/files/9599/IMG_0342.jpg" width=960 height=1280 alt="" /> <p>This is Pico-8 running on the <a href="https://www.clockworkpi.com/">Clockwork Pi GameShell</a>, a new hackable handheld game machine. GameShell has an ARM architecture, runs Linux, and works with the Raspberry Pi version of Pico-8.</p> <p>Featuring a &quot;modular&quot; design, GameShell comes as a easy-to-assemble kit. You need side cutters or a hobby knife to separate the plastic pieces from their sprues and clean up the ends. Beyond that, the parts go together without tools. There are five modules: the main board, the screen, the battery, the keypad, and the speakers. Each module is enclosed in a plastic case with an easy-to-open lid. The modules are connected with little cables, and they all fit snugly in a Gameboy-sized case. There's a headphone jack and a microUSB port for charging, as well as on-board Wifi. The keypad includes D-pad, ABXY buttons, select, start, menu, and shift. You can also get a separate expansion module for shoulder buttons on the back.</p> <p>I posted some unboxing photos to Twitter: <a href="https://twitter.com/dan_sanderson/status/1022265067142696961">https://twitter.com/dan_sanderson/status/1022265067142696961</a></p> <p>The build quality is excellent, and the kit is designed to be foolproof. Unlike the RaspiBoy, everything fits together easily, with no fiddly bits to get wrong. Everything is injection molded and has a comfortable, traditional Gameboy feel in a thinner lighter form factor. Game play with the membrane-style buttons is fast and fluid. The 320x240 color screen is sharp, and while a little small for games expecting a desktop display, GBA and Pico-8 games are just the right size.</p> <p>The microSD card comes preloaded with a Debian Linux derivative, known as &quot;clockwork OS.&quot; It's just Debian with kernel patches applied for the hardware. The OS boots to a simple Launcher interface that you can use from the gamepad. The Launcher has big icons, and it's easy to add more simply by adding new files in certain places. All OS customizations are open source and on Github, and the Launcher is just a Python app based on Pygame that runs in user space.</p> <p>GameShell also comes with RetroArch preinstalled, along with full versions of Cave Story and freeDM (a Doom clone) to get started. These aren't actually the best examples because they expect a bigger screen, but they'll get you playing right away. Though it's a little under-documented for beginners (and the user community is starting to fill the gaps), it's easy enough to copy over MAME, GBA, and NES ROMs, install new RetroArch cores, and even load up music files for the built-in music player.</p> <p>The wifi reception is surprisingly weak. I have to be a few feet from the wireless router to stay connected, and character throughput over an ssh connection is too laggy for anything more than simple administrative commands or light edits. (I recommend a clever network-aware text editor running on another computer, such as Emacs Tramp, for extensive on-device file editing.) You can <a href="https://forum.clockworkpi.com/t/usb-eth-how-to-transfer-files-if-you-have-unstable-wifi/958">replace the kernel to get ethernet over USB</a>, and you can <a href="https://forum.clockworkpi.com/t/how-to-disable-wifi-power-save-to-prevent-disconnects/933?u=petrakis">disable wifi power-save mode</a> to get better wifi throughput. I haven't tried these yet, nor have I tried connecting a keyboard to the microUSB port (not sure if that'd even work).</p> <p><strong>Setting up Pico-8</strong></p> <p>Pico-8 doesn't quite work out of the box with this set-up. clockwork OS isn't Raspian, so it's missing a few things Pico-8 assumes are there. I had luck with the dynamically linked &quot;pico8_dyn&quot; and an additional step to install wiringPi. (SDL is already present in clockwork OS.) Pico-8 also wants to use the &quot;rpi&quot; SDL video driver by default, which doesn't exist. You can work around this with an environment variable that forces it to use x11. Lastly, the Launcher app is just running in X, but it competes poorly with Pico-8. I determined that changing the Pico-8 config to use a different &quot;fullscreen&quot; mode gets around this. You also need a config change to get the A/B buttons to act as Pico-8 O/X.</p> <p>I wrote a document spelling out all of these steps with a focus on people new to Linux and Pico-8 in the GameShell wiki:</p> <p><a href="https://github.com/clockworkpi/GameShellDocs/wiki/Running-PICO-8-on-the-GameShell">https://github.com/clockworkpi/GameShellDocs/wiki/Running-PICO-8-on-the-GameShell</a></p> <p>Feedback welcome! Now that it's all figured out, it's fairly easy to set up, and it gives you practice with ssh and scp that you'd want anyway for installing emulator ROMs and additional hacking.</p> <p><strong>The best so far</strong></p> <p>Like many, I've wanted a hackable homebrew game machine for so long that I've backed pretty much every Kickstarter on the subject, and have built a few of my own with 3D printed cases and soldering kits. <a href="http://www.8bcraft.com/">RaspiBoy</a> came really close to the ideal feature set with injection molded plastic, membrane buttons, and a stock RaspPi with all ports exposed, but fell down on a few design details in the keypad. I'm looking forward to 8b Craft's RetroStone, with a larger screen, HDMI out, all the USB and ethernet ports, and full pre-assembly. Shipping soon.</p> <p>Until then, the Clockwork Pi GameShell holds the crown as the best hackable handheld. I could play on this hardware for days, everything is well designed for ease of use, and underneath it's a very familiar Linux/X11 set-up. You could probably do the whole RetroPie/EmulationStation thing here, but the simple Launcher with RetroArch is so much cleaner, and feels just right on the hardware. Cave Story is already on there, and it took me mere minutes to find some GBA ROMs and start playing. While the screen is a little small for on-device hacking without a second computer, I'm tempted to wish for an upgraded mainboard with Bluetooth keyboard/mouse capability, and maybe a little kickstand.</p> <p>As an aside, it's also one of the better &quot;modular&quot; designs I've seen. I've been skeptical about modular educational kits for a while, mostly because I was dissatisfied with choices other kits make in where to apply abstraction and proprietary interfaces. Clockwork Pi is just getting started so there's not a lot else you can do with these modules yet, but I can already tell they're making smart simple design choices for the module interfaces and hardware designs. I'm looking forward to seeing where this goes.</p> https://www.lexaloffle.com/bbs/?tid=31569 https://www.lexaloffle.com/bbs/?tid=31569 Sun, 29 Jul 2018 00:20:22 UTC Pico-8 on a GPD-WIN, a very quick review <img style="" border=0 src="https://www.lexaloffle.com/bbs/files/9599/gpdwin_p8.JPG" width=804 height=750 alt="" /> <p>This is Pico-8 on the <a href="http://www.gpd.hk/gpdwin.asp">GamePad Digital GPD-WIN</a> palmtop gaming computer. I won't give this a detailed review because there are better sources of info on this machine, and it's no surprise that it can run Pico-8. But since I posted <a href="https://www.lexaloffle.com/bbs/?tid=30350">pics of RaspiBoy</a> I thought it'd be fun to show it off in comparison.</p> <p>GPD-WIN is a bit famous for being surprisingly good at what it does, but if you haven't seen it before: 5.5 inch touch screen, Intel Atom processor, teeny keyboard, built-in game controls (including shoulder buttons), and it <strong>runs Windows 10</strong>. Install the Windows version of Pico-8 and not only can you play games, but you can make games as well. The keyboard is implausibly small, but it compares favorably to a PocketChip. The whole thing folds up to the size of a 3DS.</p> <img style="" border=0 src="https://www.lexaloffle.com/bbs/files/9599/gpdwin_p8edit.JPG" width=898 height=750 alt="" /> <p>I made a half-hearted attempt at setting up the game controls with Pico-8. You can choose between three controller modes using a hardware switch, including a mouse-and-keyboard emulation mode for regular Windowing. I ended up using this mode and Pico-8's keyconfig to get a reasonable result with the D-pad and buttons. I bet another mode and proper SDL controller set-up would also work. Mouse-and-key mode is also plausible for the editors: left stick to move the mouse, left shoulder button to left-click, etc. Touchscreen mousing is surprisingly good in general, but I personally would prefer the stick for drawing. There is one (and only one) USB-A port for external peripherals. It also supports Bluetooth.</p> <p>The GPD-WIN sells for ~$400 USD, so a bit pricier than a RaspPi set-up (or any handheld game machine subsidized through licensing). It's also a plausible option (only option?) for playing Steam games in a handheld-like, which appears to be its chief purpose. I don't think I'd use it for apps unless I were desperate, or could use its mini-HDMI out and peripherals.</p> <p>GPD-WIN has <a href="https://www.reddit.com/r/gpdwin/">a subreddit of devoted fans</a>, and the subreddit has <a href="https://www.reddit.com/r/gpdwin/wiki/index">a FAQ</a>.</p> <img style="" border=0 src="https://www.lexaloffle.com/bbs/files/9599/gpdwin_windows.JPG" width=832 height=750 alt="" /> https://www.lexaloffle.com/bbs/?tid=30351 https://www.lexaloffle.com/bbs/?tid=30351 Fri, 01 Dec 2017 00:06:14 UTC Pico-8 on RaspiBoy, a quick review <img style="" border=0 src="https://www.lexaloffle.com/bbs/files/9599/IMG_2669.JPG" width=1000 height=882 alt="" /> <p>This is the <a href="http://www.8bcraft.com/">RaspiBoy</a> handheld console kit running Pico-8. Inside, it's a Raspberry Pi Zero connected to a TFT display, a LiPo rechargeable battery, a small speaker, a custom controller board, and a built-in full-size SNES-style controller including shoulder buttons on the back. The custom board provides two USB-A ports for data, a microUSB port strictly for charging, mini-HDMI video out, a headphone jack, a volume wheel for the speaker, and buttons for adjusting the display. RaspiBoy ships as a solderless kit that does not include the RaspPi Zero.</p> <p>The two big ideas here are the full-size SNES-like controller grip and the injection molded case. Injection molding and silicone membrane pushbuttons do more to recreate the mass-market handhelds than any 3D-printed equivalent can. The controller size is comfortable and familiar. Overall, there are a lot of good ideas in the RaspiBoy that we haven't seen yet in this increasingly populated category of small-run manufacturing of Raspberry Pi-based handheld game consoles. The general design ticks a lot of boxes in my ideal version of this concept.</p> <p>Unfortunately, there are some significant failures in the details. The large grip comes at the expense of a wide frame around the TFT screen. As shown in the picture, Pico-8 by default doesn't fill the frame, and the low resolution makes even Pico-8's chunky typeface difficult to read. (I have not yet experimented with options and config to fix this. The -width and -height command-line arguments may come in handy.) A flaw common to RaspPi-based handhelds is the need to formally shut down the operating system before turning it off, or risk corrupting the filesystem. (This could be fixed with custom software and a &quot;soft&quot; power button, but it'd be a project that I haven't seen anyone attempt yet.)</p> <p>While the silicone membrane buttons have a familiar feel, they're a pain to assemble as part of the kit. Plastic buttons sit atop the membrane, and the membrane makes contact with simple copper pads on the circuit board. Getting these to line up while you push the two sides of the case together is difficult, and it took me multiple tries to get it to fit together correctly. Even when fully assembled, the buttons are too unreliable for gaming performance. I had far better luck sticking a prefab USB controller into one of the ports than I did with the built-in controller.</p> <p>RaspiBoy doesn't use any custom software: it's just RetroPie in a common RaspPi configuration, and you install it yourself. So I'm not sure how to explain that Pico-8 misbehaves and crashes after a few minutes of play. I'm tentatively inclined to blame the RaspiBoy, the RaspPi Zero, or possibly the way the controller board connects to the Zero using pogo pins pressed up against the test pads. Needless to say, it's a deal breaker if I can't actually use it to play games reliably. I doubt I'll have the time or patience to troubleshoot this properly.</p> <p>The basic RaspiBoy kit sells for 75 euros (~$90 USD) from <a href="http://www.8bcraft.com/"><a href="http://www.8bcraft.com/">http://www.8bcraft.com/</a></a>.</p> https://www.lexaloffle.com/bbs/?tid=30350 https://www.lexaloffle.com/bbs/?tid=30350 Thu, 30 Nov 2017 23:16:12 UTC Picotool's build and require() <p><a href="https://github.com/dansanderson/picotool">Picotool</a> is a library and toolset for manipulating Pico-8 cart data, useful for build workflows, as well as cart generation and transformation experiments. Many Pico-8 devs use it for its code minification feature (p8tool luamin), which can be handy when your game's code is near the uncompressed character limit.</p> <p>A more recent feature is &quot;p8tool build&quot;, a tool to assemble carts from multiple files. This tool takes a cart and replaces a type of its data from another file. For example, you can copy the spritesheet from another cart like so, such as to collaborate with an artist working in a separate cart file:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> % p8tool build mygame.p8.png --gfx sprites.p8.png </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>You can pull in Lua code from a .lua file with the --lua argument:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> % p8tool build mygame.p8.png --lua mygame.lua </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>When you use --lua, you get an especially powerful feature: build-time support for Lua's require() statement. The main .lua file can call require() to include code from additional .lua files, such as reusable libraries. It supports several features of the official Lua require() statement, such as only including a module once, and module return values.</p> <p>You can get Picotool from its Github repo, as well as file bug reports, here:</p> <p><a href="https://github.com/dansanderson/picotool"><a href="https://github.com/dansanderson/picotool">https://github.com/dansanderson/picotool</a></a></p> <p><strong>Packages and the require() function</strong></p> <p>p8tool build supports a special feature for organizing your Lua code, called packages. When loading Lua code from a file with the --lua mygame.lua argument, your program can call a function named require() to load Lua code from another file. This is similar to the require() function available in some other Lua environments, with some subtle differences due to how picotool does this at build time instead of at run time.</p> <p>Consider the following simple example. Say you have a function you like to use in several games in a file called mylib.lua:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> function handyfunc(x, y) return x + y end handynumber = 3.14 </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Your main game code is in a file named mygame.lua. To use the handyfunc() function within mygame.lua, call require() to load it:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> require(&quot;mylib&quot;) result = handyfunc(2, 3) print(result) r = 5 area = handynumber * r * r </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>All globals defined in the required file are set as globals in your program when require() is called. While this is easy enough to understand, this has the disadvantage of polluting the main program's global namespace.</p> <p>A more typical way to write a Lua package is to put everything intended to be used by other programs in a table:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> HandyPackage = { handyfunc = function(x, y) return x + y end, handynumber = 3.14, } </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Then in mygame.lua:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> require(&quot;mylib&quot;) result = HandyPackage.handyfunc(2, 3) </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>This is cleaner, but still has the disadvantage that the package must be known by the global name HandyPackage wihtin mygame.lua. To fix this, Lua packages can return a value with the return statement. This becomes the return value for the require() call. Furthermore, Lua packages can declare local variables that are not accessible to the main program. You can use these features to hide explicit names and return the table for the package:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> local HandyPackage = { handyfunc = function(x, y) return x + y end, handynumber = 3.14, } return HandyPackage </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>The main program uses the return value of require() to access the package:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> HandyPackage = require(&quot;mylib&quot;) result = HandyPackage.handyfunc(2, 3) </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>The require() function only evaluates the package's code once. Subsequent calls to require() with the same string name do not reevaluate the code. They just return the package's return value. Packages can safely require other packages, and only the first encountered require() call evaluates the package's code.</p> <p><strong>Where packages are located</strong></p> <p>The first argument to require() is a string name. picotool finds the file that goes with the string name using a library lookup path. This is a semicolon-delimited (;) list of filesystem path patterns, where each pattern uses a question mark (?) where the string name would go.</p> <p>The default lookup path is ?;?.lua. With this path, require(&quot;mylib&quot;) would check for a file named mylib, then for a file named mylib.lua, each in the same directory as the file containing the require() call. The lookup path can also use absolute filesystem paths (such as /usr/share/pico8/lib/?.lua). You can customize the lookup path either by passing the --lua-path=... argument on the command line, or by setting the PICO8_LUA_PATH environment variable.</p> <p>For example, with this environment variable set:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> PICO8_LUA_PATH=?;?.lua;/home/dan/p8libs/?/?.p8 </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>The require(&quot;3dlib&quot;) statement would look for these files, in this order, with paths relative to the file containing the require() statement:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> 3dlib 3dlib.lua /home/dan/p8libs/3dlib/3dlib.p8 </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>To prevent malicious code from accessing arbitrary files on your hard drive (unlikely but it's nice to prevent it), the require() string cannot refer to files in parent directories with ../. It can refer to child directories, such as require(&quot;math/linear&quot;).</p> <p>As with Lua, packages are remembered by the string name used with require(). This means it is possible to have two copies of the same package, each known by a different name, if it can be reached two ways with the lookup path. For example, if the file is named foo.lua and the lookup path is ?;?.lua, require(&quot;foo&quot;) and require(&quot;foo.lua&quot;) treat the same file as two different packages.</p> <p><strong>Packages and game loop functions</strong></p> <p>When you write a library of routines for Pico-8, you probably want to write test code for those routines. picotool assumes that this test code would be executed in a Pico-8 game loop, such that the library can be in its own test cart. For this purpose, you can write your library file with _init(), _update() or _update60(), and _draw() functions that test the library. By default, require() will strip the game loop functions from the library when including it in your game code so they don't cause conflicts or consume tokens.</p> <p>For example:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> local HandyPackage = { handyfunc = function(x, y) return x + y end, handynumber = 3.14, } function _update() test1 = HandyPackage.handyfunc(2, 3) end function _draw() cls() print('test1 = '..test1) end return HandyPackage </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>If you want to keep the game loop functions present in a package, you can request them with a second argument to require(), like so:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> require(&quot;mylib&quot;, {use_game_loop=true}) </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p><strong>How require() actually works</strong></p> <p>Of course, Pico-8 does not actually load packages from disk when it runs the cartridge. Instead, picotool inserts each package into the cartridge code in a special way that replicates the behavior of the Lua require() feature.</p> <p>When you run p8tool build with the --lua=... argument, picotool scans the code for calls to the require() function. If it sees any, it loads and parses the file associated with the string name, and does so again if the required file also has require() calls.</p> <p>Each required library is stored once as a function object in a table inserted at the top of the final cartridge's code. A definition of the require() function is also inserted that finds and evaluates the package code in the table as needed.</p> <p>To match Lua's behavior, require() maintains a table named package.loaded that maps string names to return values. As with Lua, you can reset this value to nil to force a require() to reevaluate a package.</p> <p>This feature incurs a small amount of overhead in terms of tokens. Each library uses tokens for its own code, plus a few additional tokens for storing it in the table. The definition for require() is another 40 tokens or so. Naturally, the inserted code also consumes characters.</p> <p><strong>Formatting or minifying Lua in a built cart</strong></p> <p>You can tell p8tool build to format or minify the code in the built output using the --lua-format or --lua-minify command line arguments, respectively.</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> % ./picotool-master/p8tool build mycart.p8.png --lua=mygame.lua --lua-format </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>This is equivalent to building the cart then running p8tool luafmt or p8tool luamin on the result.</p> <p><strong>Future build features</strong></p> <p>I actually implemented require() support back in March of 2017. I didn't announce it at the time because I wanted to implement &quot;dead code elimination,&quot; a feature that would prune unused code from included libraries, thereby saving tokens and making reusable libraries more practical. It'll be a fancy feature to implement, and I need to overhaul the parser to do it right, so that project is on hold for now. I'm announcing require() support now in case anyone has a use for it.</p> <p>Let me know if you have any questions. Feel free to file bug reports and feature requests in <a href="https://github.com/dansanderson/picotool/issues">Picotool's issue tracker on Github</a>.</p> <p>-- Dan</p> https://www.lexaloffle.com/bbs/?tid=30276 https://www.lexaloffle.com/bbs/?tid=30276 Sat, 18 Nov 2017 03:18:36 UTC Installing PocketCHIP 4.4 alpha (w/ Pico-8 1.9) <p>Next Thing Co. now has an alpha test image of the next version of the PocketCHIP software (4.4 alpha) that includes Pico-8 1.9. If you don't mind installing an alpha version (which may have bugs that cause data loss), it's easy to give it a try. It's easy enough that you probably don't even need instructions but there's one bit that I found by guessing so I thought I'd write it up.</p> <p>You'll need a computer running Chrome, a USB-to-micro-USB cable, and your PocketCHIP. Ideally, the computer would be plugged into power so it doesn't lose power in the middle of the update.</p> <ol> <li>In Chrome, go to <a href="http://flash.getchip.com/"><a href="http://flash.getchip.com/">http://flash.getchip.com/</a></a>. If this is your first time using the CHIP flash utility in Chrome, it will prompt you to install the Chrome extension. Do so.</li> <li>Connect PocketCHIP to your computer via the USB cable.</li> <li>Turn on PocketCHIP. Allow PocketCHIP to boot up to the main menu.</li> <li>On PocketCHIP, press the &quot;power&quot; on-screen button. In the power menu, select &quot;Flash Software.&quot;</li> <li>In the Chrome window, start the flasher, then follow the prompts. Ignore the instructions involving a paperclip and &quot;FEL&quot; mode; you accomplished this with the menu option.</li> <li>Leave everything connected until the flasher utility reports success.</li> <li>Unplug PocketCHIP and allow it to reboot.</li> </ol> <p>Start Pico-8 and notice it displays the 0.1.9 version number during start-up. Enjoy!</p> https://www.lexaloffle.com/bbs/?tid=28019 https://www.lexaloffle.com/bbs/?tid=28019 Thu, 03 Nov 2016 23:40:22 UTC Is RaspPi GPIO working yet? <p>As of 0.1.7 the GPIO feature is advertised as in development and involves the memory region 0x5f80-0x5fff (128 bytes). In the web player, this memory region can be accessed by external JavaScript by defining the window global pico8_gpio = new Array(128). Does the RaspPi build do anything with actual RaspPi GPIO pins yet? Does the bundled PocketCHIP version do anything with GPIO? (I get my PocketCHIP on Monday.)</p> <p>I wrote a two-way memory mapper to watch this region and set values as I messed with stuff and didn't get very far. There are some necessary features, such as setting pin modes, that are either missing or encoded in an undocumented way in the memory region. I don't see any activity in either direction if I set pin modes outside of Pico-8 either. I verified my set-up with regular GPIO test code. I also took a quick guess based on the strings tool that Pico-8 was using a GPIO driver with C functions such as gpio_write(), and I tried setting debugger breakpoints and saw no hits, but I'm not confident I did that correctly so that's not conclusive. (Reverse engineering newb. :) )</p> <p>Any official word? Has anyone had success reverse engineering in this area? Any reverse engineering tips or suggestions?</p> https://www.lexaloffle.com/bbs/?tid=4093 https://www.lexaloffle.com/bbs/?tid=4093 Sun, 21 Aug 2016 04:26:55 UTC HOWTO: PICO-8, RetroPie, and Emulation Station <p>I just got a Pimoroni Picade, an arcade mini-cabinet for use with small board computers like the Raspberry Pi. It's a great match for PICO-8!</p> <img style="" border=0 src="https://www.lexaloffle.com/bbs/files/9599/picade_pico8.jpeg" width=2448 height=3264 alt="" /> <p>See also <a href="https://twitter.com/dan_sanderson/status/758079389724659712">a short video I posted to Twitter</a>.</p> <p>The cabinet is $240 / &pound;180, not including the Raspberry Pi and power supply. The cabinet goes together with a screwdriver (no soldering) and is fun and easy to build. (Be sure to refer to the <a href="https://www.youtube.com/watch?v=siNjF3vuUMU">assembly video</a> in addition to the <a href="http://learn.pimoroni.com/tutorial/picade/build">written instructions</a>.) The result is solid and gorgeous.</p> <ul> <li><a href="https://shop.pimoroni.com/products/picade">Pimoroni Picade</a></li> <li><a href="https://www.adafruit.com/products/2706">Picade at Adafruit</a></li> </ul> <p>I used a RaspPi 3 for my Picade. I strongly recommend the USB audio adapter that Adafruit sells, a major improvement in sound quality over connecting the Picade speakers directly to the RaspPi headphone jack. RaspPi 3 has built-in wireless Internet, but if you're using an older model you'll also want a RaspPi-compatible USB wifi dongle.</p> <ul> <li><a href="https://www.adafruit.com/products/3055">Raspberry Pi 3 Model B at Adafruit</a></li> <li><a href="https://www.adafruit.com/products/1995">2.4A power supply at Adafruit</a></li> <li><a href="https://www.adafruit.com/products/1475">USB audio adapter at Adafruit</a></li> <li><a href="https://www.adafruit.com/products/814">USB wifi dongle at Adafruit</a> (for RaspPi 1/2)</li> </ul> <p>RetroPie is an easy-to-use software package of the best retro-gaming projects for the Raspberry Pi. It includes emulators for many platforms (arcade and home computers) as well as media center software, and a master menu called Emulation Station that you can manipulate using just the joystick and buttons so you don't need a keyboard connected once it's all set up.</p> <ul> <li><a href="https://retropie.org.uk/">RetroPie</a></li> </ul> <p><strong>Setting up RetroPie for Picade</strong></p> <p>I won't go through the RetroPie set-up procedure in detail. There are plenty of guides on the web, including at Adafruit. What follows are a few notes from my build.</p> <p><a href="https://retropie.org.uk/download/">Download the RetroPie image</a>, in my case &quot;retropie-v3.8.1-rpi2_rpi3.img&quot;.</p> <p><a href="https://www.sdcard.org/downloads/formatter_4/">Format an appropriately-sized SD card</a>, at least 8 GB. I used a 32 GB card, which takes a while to format. </p> <p>Write the image to the SD card. I have a Mac laptop and I used the command line to do this, as follows:</p> <ol> <li>Determine which disk device (e.g. &quot;disk2&quot;) is the SD card.</li> </ol> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> diskutil list </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <ol start="2"> <li>Unmount the SD card, substituting &quot;disk2&quot; with your actual device name.</li> </ol> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> diskutil unmountDisk /dev/disk2 </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <ol start="3"> <li>Write the image to the SD card, substituting &quot;rdisk2&quot; with your actual device name with a &quot;r&quot; in front of it (&quot;rdisk&quot; instead of &quot;disk&quot;). This command can take a while.</li> </ol> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> sudo dd bs=1m if=retropie-v3.8.1-rpi2_rpi3.img of=/dev/rdisk2 </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>With the SD card still connected to the laptop, edit &quot;/boot/config.txt&quot; (accessible on the Mac as &quot;/Volumes/boot/config.txt&quot;). Uncomment this line so that Picade's screen will work correctly:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> hdmi_force_hotplug=1 </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <ol start="4"> <li> <p>Unmount the SD card then remove it from your computer. Put the SD card in the Pi, hook it all up, and supply power. It should boot to Emulation Station and let you set up the button bindings. I mapped the D-pad controls to the joystick, and took a guess at the six top, two front, and two right buttons. (The two left buttons are for the speaker volume and are not seen by the Pi.) This is easy to change later.</p> </li> <li>From Emulation Station, go into the RetroPie menu and set up wifi. You'll need a keyboard connected to the Pi to enter your wifi password.</li> </ol> <p>Once wifi is set up, select &quot;show IP&quot; from the RetroPie menu. You can use this IP address to connect to the Pi over the wireless network, transfer files, and make config changes. To get to a remote shell from your laptop, use the &quot;ssh&quot; command, substituting your IP address, and enter a password of &quot;raspberry&quot;:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> ssh pi@10.1.10.7 </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>To copy a file to the Pi:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> scp pico-8_0.1.8_arm.zip pi@10.1.10.7:~/ </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <ol start="6"> <li>The USB audio interface needs to be configured from the command line. Guides like <a href="https://learn.adafruit.com/usb-audio-cards-with-a-raspberry-pi/instructions">Adafruit's tutorial</a> and <a href="https://github.com/retropie/retropie-setup/wiki/sound-issues">RetroPie's sound docs</a> get us started. Mine came up as the CM-Headphone type. </li> </ol> <p>For Pico-8, we also need to fix an issue with playback speed. The solution presented here is to configure a virtual device that converts the sampling rate, then pipes it to the actual USB audio device.</p> <p>Create or edit the file &quot;/etc/asound.conf&quot; to contain the following:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> pcm.card { type hw card 1 } pcm.!default { type plug; slave { pcm card; rate 48000; } } ctl.!default { type hw card 1 } </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Reboot the Pi:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> sudo shutdown -r now </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>The Emulation Station menu plays sounds, and RetroPie comes with Doom pre-installed (see the Ports system menu). Test the audio. Use the volume buttons on the left of the cabinet to adjust as needed; it may start out too quiet to hear.</p> <p><strong>PICO-8 on the Picade</strong></p> <p>You can run the Raspberry Pi version of PICO-8 with this set-up. Copy PICO-8 to the Pi and unpack it into the ~/pico-8 directory:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> # (starting from your computer:) scp pico-8_0.1.8_arm.zip pi@10.1.10.7:~/ ssh pi@10.1.10.7 # (now on the RaspPi:) unzip pico-8_0.1.8_arm.zip </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>On the Picade with a keyboard connected, exit Emulation Station (Menu button, Quit, Quit Emulation Station) to get a shell prompt, then run the pico8 command:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> ~/pico-8/pico8 -splore </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Controls, fullscreen graphics, sound, and Splore over the Internet should all just work.</p> <p><strong>Launching PICO-8 from Emulation Station</strong></p> <p>Of course, it'd be better if you didn't need the command line and a keyboard to start up PICO-8, especially since Splore lets you download and play PICO-8 games using just the joystick and buttons. I wanted the ability to launch PICO-8 from Emulation Station, as in <a href="https://twitter.com/dan_sanderson/status/758183137595699200">this video</a>. It turns out this wasn't too difficult, but it involves a few steps.</p> <p>I made two versions of the PICO-8 logo, one with light text and one with dark text, based on the one I made for the PICO-8 wiki (which in turn is heavily based on the official logos). You can get these here:</p> <ul> <li><a href="https://drive.google.com/file/d/0Byb5_-es25q4dlI1bFFGbHJ2c0k/view?usp=sharing">p8logo.png</a></li> <li><a href="https://drive.google.com/file/d/0Byb5_-es25q4OEVpTFVJaHY3VmM/view?usp=sharing">p8logo_dark.png</a></li> </ul> <p>On the Pi, create a new pico8 theme directory for Emulation Station:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> cd /etc/emulationstation sudo mkdir themes/carbon/pico8 </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Copy the logo files to the Pi and move them to this directory. (You will need to use &quot;sudo mv ...&quot; to move the files into place.)</p> <p>You also need to create a &quot;theme.xml&quot; file in this directory. Copy the one from .../themes/carbon/amiga/theme.xml, then edit it (such as with the &quot;nano&quot; editor):</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> sudo cp themes/carbon/amiga/theme.xml themes/carbon/pico8/theme.xml sudo nano -w themes/carbon/pico8/theme.xml </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Make these changes:</p> <ol> <li> <p>Replace all instances of &quot;./art/controller.svg&quot; with &quot;./../amiga/art/controller.svg&quot;.</p> </li> <li>Change the logo for the main system screen, using the dark text version:</li> </ol> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> &lt;view name=&quot;system&quot;&gt; ... &lt;image name=&quot;logo&quot;&gt; &lt;path&gt;./p8logo_dark.png&lt;/path&gt; &lt;/image&gt; &lt;/view&gt; </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <ol start="3"> <li>Change the logo for the system detail screen, using the light text version:</li> </ol> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> &lt;view name=&quot;basic, detailed&quot;&gt; ... &lt;image name=&quot;logo&quot;&gt; &lt;path&gt;./p8logo.png&lt;/path&gt; ... &lt;/image&gt; ... &lt;/view&gt; </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Now you need to add pico8 to the list of systems. Edit the system config file:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> sudo nano -w /etc/emulationstation/es_systems.cfg </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Inside &lt;systemList&gt;...&lt;/systemList&gt;, add these lines:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> &lt;system&gt; &lt;name&gt;pico8&lt;/name&gt; &lt;fullname&gt;PICO-8&lt;/fullname&gt; &lt;path&gt;/home/pi/pico-8&lt;/path&gt; &lt;extension&gt;.sh .SH&lt;/extension&gt; &lt;command&gt;/opt/retropie/supplementary/runcommand/runcommand.sh 0 &quot;/home/pi/pico-8/pico8 -splore&quot;&lt;/command&gt; &lt;platform&gt;pico8&lt;/platform&gt; &lt;theme&gt;pico8&lt;/theme&gt; &lt;/system&gt; </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Emulation Station expects to find a directory of game files under &lt;path&gt; whose names have an extension specified by &lt;extension&gt;, so it can list them all in its menu and launch them individually. If you really want to use this feature with PICO-8 carts (and not use Splore), you could use &lt;extension&gt;.p8 .p8.png&lt;/extension&gt;, &lt;command&gt;/opt/retropie/supplementary/runcommand/runcommand.sh 0 &quot;/home/pi/pico-8/pico8 %ROM%&quot;&lt;/command&gt;, and an appropriate &lt;path&gt;. Every cart you put in your cart directory will appear as a menu option in Emulation Station.</p> <p>For my configuration, I just wanted Emulation Station to launch PICO-8 in Splore mode. My configuration says to look for &quot;.sh&quot; files in the &quot;/home/pi/pico-8&quot; directory and create a menu entry for each one it finds. Emulation Station will not show the system in the main menu unless there is at least one such file. I created an empty file called &quot;/home/pi/pico-8/+Start PICO-8.sh&quot;. When I select this option from the Emulation Station menu, it runs &lt;command&gt;, which in this case ignores the selected menu option and just starts PICO-8 with Splore.</p> <p>Another way to do this is to make &quot;/home/pi/pico-8/+Start PICO-8.sh&quot; a real script that starts PICO-8, like this:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> #!/bin/bash pushd &quot;/home/pi/pico-8&quot; ./pico8 -splore popd </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Don't forget to make the script executable:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> chmod a+x &quot;+Start PICO-8.sh&quot; </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Change the command to &lt;command&gt;/opt/retropie/supplementary/runcommand/runcommand.sh 0 %ROM%&lt;/command&gt;. This runs the script itself as the command when the menu option is selected. Doing it this way lets you add more items to the PICO-8 Emulation Station menu simply by adding more scripts to /home/pi/pico-8, such as to have multiple configurations (such as a non-Splore gamedev mode) or jump straight to your favorite carts.</p> <p>Reboot (&quot;sudo shutdown -r now&quot;) and you should now have PICO-8 in your list of systems. Select the PICO-8 system, then select the &quot;+Start PICO-8&quot; option. PICO-8 starts in Splore mode, and you can browse the BBS, play games, and add them to your favorites all using Picade controls. You only need a keyboard connected if you want to do text searches in Splore, or if you want the ability to exit to the PICO-8 command prompt or code editor.</p> https://www.lexaloffle.com/bbs/?tid=3935 https://www.lexaloffle.com/bbs/?tid=3935 Wed, 27 Jul 2016 04:22:32 UTC Pico-8 Wiki Relaunch! <p>I'm happy to announce the relaunch of the Pico-8 wiki!</p> <p><a href="http://pico-8.wikia.com/"><a href="http://pico-8.wikia.com/">http://pico-8.wikia.com/</a></a></p> <p>I've spent the last few weekends writing articles and reference material for Pico-8, including complete API and command references, a memory map (including format details), a summary of the Lua subset, and tutorials on several subjects. This is very much a rough draft and I still have a list of to-dos, missing articles, more thorough sample code with screenshots, and some stuff I want to reorganize.</p> <p>But it's a wiki, so you can help! Corrections are welcome at this stage. If you want to discuss a change before making it, hit me up on Slack or use Wikia's messaging feature or just reply here. But don't be shy about changing things directly.</p> <p>Let me know what you think!</p> <p>--</p> <p>Two possible points of controversy I'll mention up front:</p> <ul> <li> <p>I tweaked the theme colors so they're reasonably readable, matching the forum site. I'm still a bit concerned that the Pico-8 red is unsuitable for link and header text. One of my monitors apparently doesn't support sub-pixel rendering or something and blurs it all to hell, but I'm not sure how big a problem that is. I tried a bunch of options and all the others seemed to drop the Pico-8 feel of the site. Suggestions welcome.</p> </li> <li>The cos, sin, and atan2 articles currently use a different convention to explain the y-inversion than the official docs do. A quick survey of the Slack group led me to try and explain it as inverting the angle direction and not the sign of sin(). This works until you get to atan2, which requires inverting the dy argument to fit that model. So the choices are counterclockwise with inverted sin() result, or clockwise with inverted atan2() dy argument. Inverting a result seems less problematic than inverting an argument, so I'll probably change it back. (I already have the diagram drawn.) Feedback welcome here as well.</li> </ul> <p>Thanks!</p> <p>-- Dan</p> https://www.lexaloffle.com/bbs/?tid=3630 https://www.lexaloffle.com/bbs/?tid=3630 Sat, 18 Jun 2016 04:40:57 UTC A Tale of Two Cities, chapters 1-3 <p>Here's a simple ebook reader with the first three chapters of A Tale of Two Cities. Press X to advance (once per paragraph / page).</p> <p> <table><tr><td> <a href="/bbs/?pid=16673#p"> <img src="/bbs/thumbs/pico16672.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=16673#p"> A Tale of Two Cities, chapters 1-3</a><br><br> by <a href="/bbs/?uid=9599"> dddaaannn</a> <br><br><br> <a href="/bbs/?pid=16673#p"> [Click to Play]</a> </td></tr></table> </p> <p>This is a tech demo of some tools I've been working on for developing text-based games. It'd be more impressive if it were an actual game, but this victory was hard won so I'm posting it. :)</p> <p>Notes:</p> <ul> <li> <p>Text is stored in cart data, not as string literals in the code.</p> </li> <li> <p>The original source file <em>does</em> have the text as string literals in code. I use a post-processor to extract the string literals, pack them into text data stored in the cart, then replace them with string IDs. I use a custom syntax to flag which strings ought to be extracted so I can still use regular string literals elsewhere. The processing tool lets me adjust the location of the text in memory, so I can set aside space for sprites, sfx, etc. by limiting the size of the text data region.</p> </li> <li> <p>Text is compressed using LZW with variable-width codes. The processor has a compressor written in Python, and it appends a decoder written in Lua to the cart code. This Tale of Two Cites excerpt is 25,613 bytes, and compresses to 12,457 bytes for storage in the cart data, 48% of its original size.</p> </li> <li> <p>My LZW implementation is designed to allow random access to strings during program execution. LZW is a dictionary-based compression algorithm, and all strings share the same dictionary for efficient packing. The entire corpus is not decompressed all at once into Lua memory. Instead, the lookup dictionary is calculated from the bit stream and retained in Lua memory so that strings can be decoded on the fly as they are accessed. In the cart data, I use a simple binary layout that gives each string a header with information that helps track the code bit width during decompression, and byte-aligns each string's first and last characters.</p> </li> <li> <p>This Tale of Two Cities demo gets close to the Lua memory limit with its dictionary. I maximized the size of the dictionary (7,903 entries) to minimize the size of the compressed data. In practice, I'll probably cap the dictionary size to 4,096 entries, which for this text gains a few kilobytes in cart data. But headroom in Lua RAM will be important for real games.</p> </li> <li> <p>The slow scroll of the text in this reader app is artificial, originally intended for use in a text game. Decompression is quite fast after the initial dictionary is built. I have limited interest in making a usable ebook reader cart, but you're welcome to try it. This implementation uses only 292 tokens and 5017 chars, and that could probably be tightened up a bit.</p> </li> <li>This excerpt is 4,634 words. For comparison, Zork I is 14,214 words. Considering Zork had the luxury of paging from a 160k floppy disk and this is packed into a 16k region of cart data, that's not too shabby. :)</li> </ul> <p>I don't know yet if this will actually be useful for a game project, but it was fun to make. The complete code is not ready for public consumption, but here's the Github link anyway: <a href="https://github.com/dansanderson/p8advent">https://github.com/dansanderson/p8advent</a> It's based on and requires picotool.</p> <p>Happy reading!</p> <p>-- Dan</p> https://www.lexaloffle.com/bbs/?tid=2776 https://www.lexaloffle.com/bbs/?tid=2776 Sun, 15 Nov 2015 05:50:38 UTC p8upsidedown turns carts upside down <p>I wrote a new tool that turns carts upside down.</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> % ./p8upsidedown jelpi.p8.png </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p> <table><tr><td> <a href="/bbs/?pid=16099#p"> <img src="/bbs/thumbs/pico16098.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=16099#p"> Jelpi Upsidedown</a><br><br> by <a href="/bbs/?uid=9599"> dddaaannn</a> <br><br><br> <a href="/bbs/?pid=16099#p"> [Click to Play]</a> </td></tr></table> </p> <p>The tool is built with the <a href="https://github.com/dansanderson/picotool">picotool</a> library (<a href="https://www.lexaloffle.com/bbs/?tid=2691">discussion</a>). This version of the tool inverts the sprites, inverts the map, and translates the code to use inverted coordinates for drawing functions.</p> <p>This is meant as a hack/demo and is known not to work with every cart. It works with many carts, and some of the failures are interesting. Notably:</p> <ul> <li> <p>The code translation increases the token count, so large carts (Celeste, Dusk Child) can't be turned upside down.</p> </li> <li> <p>This version doesn't support spr/sspr calls that draw a rectangle of tiles. This wouldn't be too difficult to support: it'd need to flip the entire spritesheet not just individual sprites, translate the sprite IDs in the map, and extend the code to rewrite sprite ID args. But I have other things to do this weekend. :)</p> </li> <li> <p>The print function will always print left to right, so we compromise and merely relocate the y coordinate for print / cursor calls. There's nothing the tool can do with carts that call multiple coordinate-less prints.</p> </li> <li>I wrote this to exercise and demonstrate the picotool libraries for mutating Lua code via the AST. The lib doesn't know how to write out an arbitrary AST and preserve other comments/spaces, so p8upsidedown generates hideous code. Unfortunately the luafmt writer isn't entirely up to snuff either so it's not much help. This is mostly not an issue to Pico-8, though I did find a bug where Pico-8's special &quot;t += val&quot; syntax rejects a newline between the &quot;+=&quot; and the &quot;val&quot;, which p8upsidedown might accidentally introduce.</li> </ul> <p>Anyway, a fun weekend hack with picotool. Enjoy!</p> <p>-- Dan</p> https://www.lexaloffle.com/bbs/?tid=2709 https://www.lexaloffle.com/bbs/?tid=2709 Sun, 01 Nov 2015 19:45:33 UTC picotool: Tools and Python libraries for manipulating Pico-8 game files <p>I'm pleased to announce <strong>picotool</strong>, a set of tools and Python libraries for manipulating Pico-8 game files. picotool can read .p8.png and .p8 files, and can write .p8 files.</p> <p>To get picotool and learn how to use it, visit <a href="https://github.com/dansanderson/picotool">the picotool Github repo</a>.</p> <p>The <strong>p8tool</strong> command is a multi-tool with multiple functions. You can run it like this:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> % p8tool stats helloworld.p8.png hello world (helloworld.p8.png) by zep version: 0 lines: 48 chars: 419 tokens: 134 </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>picotool currently includes the following tools:</p> <ul> <li><strong>build</strong>: builds a cart from pieces of other carts</li> <li><strong>stats</strong>: a statistics reporting tool</li> <li><strong>listlua</strong>: prints the Lua region of a cart</li> <li><strong>writep8</strong>: converts a .p8.png cart to a .p8 cart</li> <li><strong>luafmt</strong>: writes a new .p8 cart with Lua rewritten with regular formatting, to make it easier to read</li> <li><strong>luamin</strong>: writes a new .p8 cart with Lua rewritten to use a minimal number of characters, to make it difficult to read</li> <li><strong>luafind</strong>: searches for lines of Lua code containing a string or matching a pattern</li> <li><strong>listtokens</strong>: prints a visualization of Lua tokens</li> <li><strong>printast</strong>: prints a visualization of the Lua parser abstract syntax tree (AST)</li> </ul> <p>The Python library includes a hand-written Lua parser with support for Pico-8 features, with API access to the token stream and abstract syntax tree. Additional modules provide access to the graphics, map, sound, and music data. All game data can be transformed or created with Python code and written to a .p8 or .p8.png cart file.</p> <p>I've included the Lua minifier (luamin) as an example tool, though I don't actually think it's a good idea to use it. Statistically, you'll run out of tokens before you run out of characters. The Pico-8 community benefits more from published carts with code that is easy to read and well commented. All luamin does is make the code difficult to read, without much benefit.</p> <p>Here is a chart of the character count, minified character count, and token count of 496 carts that have been posted to the BBS, relative to the Pico-8 maximums:</p> <img style="" border=0 src="https://www.lexaloffle.com/bbs/files/9599/tokenchargrowth.png" width=562 height=325 alt="" /> <p>(<a href="https://docs.google.com/spreadsheets/d/1qY3Up8IZl6uH0XUfnF6TkdM_vIzqNxdN-XTmJfZUGnY/edit?usp=sharing">Here's the spreadsheet</a>.)</p> <p>As shown, even un-minified code tends to stay below the token count, percentage-wise. Minifying reduces the (uncompressed) character count to 65% of the original size on average.</p> <p>The inspirational use case for this library is actually luafmt, which re-formats the Lua code of a cart to be easier to read. The current version of this tool is simple and only adjusts indentation. There is much more luafmt can do by analyzing the AST, but this is not yet implemented.</p> <p>As of today, this is very much a v0.1 early release. There are known issues regarding parsing and token counting, and the library APIs are incomplete and messy. This project has already gotten away from me a bit, so I'm not sure how far I'll take it. But if you do want to build against it, patience with non-backwards compatible changes will be appreciated. :)</p> <p>Let me know what you think! Thanks!</p> <p><strong>Update 2015-10-29:</strong> Added luafind tool. Refactored AST walking code to make it easier to build tools that read or transform the parser tree.<br /> <strong>Update 2016-10-17:</strong> Added build tool. Added support for updating and creating .p8.png cartridge files.</p> https://www.lexaloffle.com/bbs/?tid=2691 https://www.lexaloffle.com/bbs/?tid=2691 Thu, 29 Oct 2015 04:20:05 UTC Short-if syntax oddities <p>I don't think anything ought to change, but I thought this was interesting. Pico-8 allows this:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> x = 1 if (x == 1) do print('a') end if (x == 2) do print('b') end </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Notice that this is not &quot;if-then-end&quot; but &quot;if-do-end&quot;. This appears to be supported accidentally due to the &quot;if (...) ...&quot; shortcut, described in the manual as:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> IF THEN END statements on a single line can be expressed without the THEN &amp; END IF (NOT B) I=1 J=2 -- is equivalent to: IF (NOT B) THEN I=1 J=2 END -- note that the condition must be surrounded by brackets. </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>The intent is for &quot;if (cond) exp...&quot; to parse expressions to the end of the line. However, if the last expression is a do-end block, the block is allowed to span multiple lines. Of course, this requires that the condition be in parentheses.</p> <p>I found 7 carts posted to the BBS that use &quot;if-do-end&quot; across multiple lines. Pico-8 does what's intended, so it's hard to call it a mistake.</p> <p>Unrelated: &quot;if (cond) block else block&quot; is undocumented but supported. &quot;if (cond) block elseif (code) block else block&quot; is not supported. The else's block is optional (though pointless to omit): &quot;if (cond) block else&quot; I found 13 carts using the else form of short-if.</p> https://www.lexaloffle.com/bbs/?tid=2636 https://www.lexaloffle.com/bbs/?tid=2636 Tue, 20 Oct 2015 03:22:04 UTC printh tutorial <p>As of version 1.2, PICO-8 includes a command useful for debugging: printh(&quot;string&quot;) This command prints a string to the host operating system's console. You can put printh() calls in your code to examine events or state without cluttering the game screen with debugging information.</p> <p>So how do you see the host operating system's console?</p> <p>In Linux, you probably already run the &quot;pico8&quot; command from a terminal window. If you don't, locate where you put the &quot;pico-8&quot; directory, then run the pico8 command from a terminal window using its full path. For example:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> ~/pico-8/pico8 </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>In Mac OS X, instead of double-clicking the PICO-8 icon, open Terminal, then start PICO-8 with the following command, adjusting the path to match where you put the app. For example:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> /Applications/PICO-8.app/Contents/MacOS/pico8 </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>In Windows, instead of double-clicking the PICO-8 icon, open Command Prompt, then start PICO-8 with the following command:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> &quot;\Program Files (x86)\PICO-8\pico8.exe&quot; </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Note that with the Windows version, the prompt appears immediately (the process is forked). PICO-8 output will appear in this window anyway.</p> <p>Try it out! With PICO-8 running from the console, type this at the PICO-8 prompt:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> printh(&quot;hello&quot;) </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>The message appears in the console window (not the PICO-8 window).</p> <p>(Updated for 1.5.)</p> https://www.lexaloffle.com/bbs/?tid=2549 https://www.lexaloffle.com/bbs/?tid=2549 Fri, 02 Oct 2015 19:12:33 UTC