GPI [Lexaloffle Blog Feed]https://www.lexaloffle.com/bbs/?uid=58188 Mosaik <p> <table><tr><td> <a href="/bbs/?pid=120604#p"> <img src="/bbs/thumbs/pico8_mosaik-1.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=120604#p"> mosaik</a><br><br> by <a href="/bbs/?uid=58188"> GPI</a> <br><br><br> <a href="/bbs/?pid=120604#p"> [Click to Play]</a> </td></tr></table> </p> <img style="margin-bottom:16px" border=0 src="/media/58188/mosaik_2.png" alt="" /> <img style="margin-bottom:16px" border=0 src="/media/58188/mosaik_1.png" alt="" /> <img style="margin-bottom:16px" border=0 src="/media/58188/mosaik_0.png" alt="" /> https://www.lexaloffle.com/bbs/?tid=50205 https://www.lexaloffle.com/bbs/?tid=50205 Sun, 13 Nov 2022 13:24:29 UTC Crillion <p> <table><tr><td> <a href="/bbs/?pid=119855#p"> <img src="/bbs/thumbs/pico8_crillion-2.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=119855#p"> crillion</a><br><br> by <a href="/bbs/?uid=58188"> GPI</a> <br><br><br> <a href="/bbs/?pid=119855#p"> [Click to Play]</a> </td></tr></table> </p> <img style="margin-bottom:16px" border=0 src="/media/58188/crillion_1.gif" alt="" /> <p>A very simple game. Your goal is to destroy all blocks. The problem: You can only move the ball horizontally, the ball moves up and down automatically. </p> <p>Crillion is an adaptation of the game of the same name on the C64. This release contains the levels of the three official Crillion releases: Crillion, Crillion '93 (hard), Crillion II (very hard). In addition, the levels of Brainion are included, which are designed more than puzzles. And &quot;Junior&quot; from Crillion Junior - a very easy level set.</p> <h1>Rules</h1> <h2>Block</h2> <p> <table><tr><td width=256> <img src="https://www.lexaloffle.com/bbs/gfxc/58188_15.png" width=256 height=32> </td> <td valign=bottom> <a style="cursor:pointer;font-size:8pt" onclick=' var el = document.getElementById("gfxcode_58188_15"); if (el.style.display == "none") el.style.display = ""; else el.style.display = "none"; microAjax("https://www.lexaloffle.com/bbs/gfxc/58188_15.txt", function (retdata){ var el = document.getElementById("gfxcode_58188_15"); el.innerHTML = retdata; el.focus(); el.select(); } ); '> [64x8]</a> </td></tr> <tr><td colspan=2> <textarea rows=3 class=lexinput id="gfxcode_58188_15" style="width:640px;background-color:#fed;display:none;overflow:hidden; font-size:6pt;"></textarea> </td> </tr> </table> <br /> In order for the blocks to break, the ball must be the same color as the blocks. </p> <h2>Changer</h2> <p> <table><tr><td width=256> <img src="https://www.lexaloffle.com/bbs/gfxc/58188_19.png" width=256 height=32> </td> <td valign=bottom> <a style="cursor:pointer;font-size:8pt" onclick=' var el = document.getElementById("gfxcode_58188_19"); if (el.style.display == "none") el.style.display = ""; else el.style.display = "none"; microAjax("https://www.lexaloffle.com/bbs/gfxc/58188_19.txt", function (retdata){ var el = document.getElementById("gfxcode_58188_19"); el.innerHTML = retdata; el.focus(); el.select(); } ); '> [64x8]</a> </td></tr> <tr><td colspan=2> <textarea rows=3 class=lexinput id="gfxcode_58188_19" style="width:640px;background-color:#fed;display:none;overflow:hidden; font-size:6pt;"></textarea> </td> </tr> </table> <br /> This allows the ball to be colored. </p> <h2>Skulls</h2> <p> <table><tr><td width=32> <img src="https://www.lexaloffle.com/bbs/gfxc/58188_17.png" width=32 height=32> </td> <td valign=bottom> <a style="cursor:pointer;font-size:8pt" onclick=' var el = document.getElementById("gfxcode_58188_17"); if (el.style.display == "none") el.style.display = ""; else el.style.display = "none"; microAjax("https://www.lexaloffle.com/bbs/gfxc/58188_17.txt", function (retdata){ var el = document.getElementById("gfxcode_58188_17"); el.innerHTML = retdata; el.focus(); el.select(); } ); '> [8x8]</a> </td></tr> <tr><td colspan=2> <textarea rows=3 class=lexinput id="gfxcode_58188_17" style="width:640px;background-color:#fed;display:none;overflow:hidden; font-size:6pt;"></textarea> </td> </tr> </table> <br /> Skulls destroy the character. </p> <h2>Rings</h2> <p> <table><tr><td width=256> <img src="https://www.lexaloffle.com/bbs/gfxc/58188_18.png" width=256 height=32> </td> <td valign=bottom> <a style="cursor:pointer;font-size:8pt" onclick=' var el = document.getElementById("gfxcode_58188_18"); if (el.style.display == "none") el.style.display = ""; else el.style.display = "none"; microAjax("https://www.lexaloffle.com/bbs/gfxc/58188_18.txt", function (retdata){ var el = document.getElementById("gfxcode_58188_18"); el.innerHTML = retdata; el.focus(); el.select(); } ); '> [64x8]</a> </td></tr> <tr><td colspan=2> <textarea rows=3 class=lexinput id="gfxcode_58188_18" style="width:640px;background-color:#fed;display:none;overflow:hidden; font-size:6pt;"></textarea> </td> </tr> </table> <br /> Rings can be pushed in one direction if the color matches the ball.</p> <h1>Download</h1> <p>Binaries for Linux, MacOs, Raspi and Windows:<br /> <a href="https://github.com/GPIforGit/crillion/releases">https://github.com/GPIforGit/crillion/releases</a></p> <h1>Episodes</h1> <p>This release contains the levels from </p> <h2>Crillion</h2> <p>Published in Happy Computer, 1988/07<br /> <a href="https://archive.org/details/happycomputer-magazine-1988-07/page/n51/mode/2up">https://archive.org/details/happycomputer-magazine-1988-07/page/n51/mode/2up</a><br /> By Oliver Kirwa<br /> <a href="https://www.c64-wiki.com/wiki/Crillion">https://www.c64-wiki.com/wiki/Crillion</a></p> <h2>Crillion '93</h2> <p>Published in 64'er Sonderheft 85<br /> <a href="https://archive.org/details/64er_sonderheft_85/page/n5/mode/2up">https://archive.org/details/64er_sonderheft_85/page/n5/mode/2up</a><br /> <a href="http://www.homecomputerworld.com/64ersh.html">http://www.homecomputerworld.com/64ersh.html</a><br /> By Oliver Kirwa<br /> <a href="https://www.c64-wiki.com/wiki/Crillion_%2793">https://www.c64-wiki.com/wiki/Crillion_%2793</a></p> <h2>Crillion II</h2> <p>Published in 64'er Sonderheft 54<br /> <a href="https://archive.org/details/64er_sonderheft_54/page/n7/mode/2up">https://archive.org/details/64er_sonderheft_54/page/n7/mode/2up</a><br /> By Oliver Kirwa</p> <h2>Brainion</h2> <p>Published in &quot;Digital Talk #104&quot;<br /> <a href="https://digital-talk.github.io/">https://digital-talk.github.io/</a><br /> By &quot;The Joker&quot; and &quot;Dr.Guru&quot;<br /> <a href="https://www.c64-wiki.de/wiki/Brainion">https://www.c64-wiki.de/wiki/Brainion</a></p> <h2>Crillion Junior</h2> <p><a href="https://www.c64games.de/phpseiten/spieledetail.php?filnummer=7614">https://www.c64games.de/phpseiten/spieledetail.php?filnummer=7614</a><br /> by holy moses</p> <h1>Level editor</h1> <p>A level editor is available. It is based on &quot;jaP8e&quot; ( <a href="https://www.lexaloffle.com/bbs/?tid=49307">https://www.lexaloffle.com/bbs/?tid=49307</a> ) and must be copied to the &quot;libs&quot; directory of &quot;jaP8e&quot;.<br /> <a href="https://github.com/GPIforGit/crillion/blob/main/moduleCrillion.lua">https://github.com/GPIforGit/crillion/blob/main/moduleCrillion.lua</a></p> <h1>Credits:</h1> <p>Oliver Kirwa for Crillion, Crillion'93, Crillion-Construction-Kit and Crillion II.</p> <p>&quot;The Joker&quot; and &quot;Dr.Guru&quot; for Brainion</p> <p>holy moses for &quot;Crillion Junior&quot;</p> <p>Darrell Flood for the &quot;Sloppy Paint&quot; font (used for the Logo)<br /> <a href="https://www.dafont.com/de/sloppy-paint.font">https://www.dafont.com/de/sloppy-paint.font</a></p> https://www.lexaloffle.com/bbs/?tid=49973 https://www.lexaloffle.com/bbs/?tid=49973 Sun, 30 Oct 2022 13:23:22 UTC Request - Developer Mode <p>SDK-Units of consoles have normally more memory.</p> <p>This can be useful during developing - simple try something without care about limits. Or store additional debug information.</p> <p>it would be nice, if pico-8 would emulate this.</p> <p>This can be done very simple:<br /> The project must be saved as &quot;.p8&quot;-utf8-file.<br /> When the project hit the limit of characters, compressed size and token it will display the known warning with a little addition: &quot;Ignore? (Project can't be exported!) (y/n):&quot; - when you hit y - it will start anyway. Save as .p8 is always possible, since there are no limits.<br /> Of course the export to bin, web, rom, png or whatever is not possible. also the cli-command &quot;-run&quot; should not work on this oversized p8. </p> <p>This would be usfull, when you want to check, if something work. Or when you developed a tool / level editor for a game, which you don't want to share. </p> <p>additional it would be nice to have an debug - enddebug - command</p> <div> <div class=scrollable_with_touch style="width:100%; 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 test(a,b) debug if not a or not b then print(&quot;this should not happen! Got nils!&quot;) end enddebug ... 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>this code should only start when pico-8 is in devoloping-mode.<br /> when it saved to p8.png ( or p8.rom, bin, web), pico-8 should interpret this as comment.</p> <div> <div class=scrollable_with_touch style="width:100%; 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 test(a,b) --[[ if not a or not b then print(&quot;this should not happen! Got nils!&quot;) end --]] ... 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>So the token-limit should not be affect by the debug - enddebug block.</p> https://www.lexaloffle.com/bbs/?tid=49573 https://www.lexaloffle.com/bbs/?tid=49573 Sat, 01 Oct 2022 19:34:32 UTC Custom font with variable width and latin letters <p> <table><tr><td> <a href="/bbs/?pid=118120#p"> <img src="/bbs/thumbs/pico8_variablefont-0.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=118120#p"> variablefont</a><br><br> by <a href="/bbs/?uid=58188"> GPI</a> <br><br><br> <a href="/bbs/?pid=118120#p"> [Click to Play]</a> </td></tr></table> <br /> A very simple font. A little bit bigger than the original, but better readable.<br /> the UTF Latin-1-Suppliment-Characters are included instead the Japanese characters.</p> <p>type</p> <div> <div class=scrollable_with_touch style="width:100%; 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> load &quot;#variablefont&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>in pico-8 to load the cartridge.</p> <p>Created with jaP8e - <a href="https://www.lexaloffle.com/bbs/?tid=49307">https://www.lexaloffle.com/bbs/?tid=49307</a></p> https://www.lexaloffle.com/bbs/?tid=49517 https://www.lexaloffle.com/bbs/?tid=49517 Wed, 28 Sep 2022 18:08:46 UTC [bug] compression error <p>I tried to decompress the source code of my dithering-demo:<br /> <a href="https://www.lexaloffle.com/bbs/?tid=49309">https://www.lexaloffle.com/bbs/?tid=49309</a><br /> and my code failed.</p> <p>First i thought my code is wrong, I translated from this source:<br /> <a href="https://github.com/dansanderson/lexaloffle/blob/main/pxa_compress_snippets.c">https://github.com/dansanderson/lexaloffle/blob/main/pxa_compress_snippets.c</a><br /> the decompress-code to lua, so it is possible that I made a mistake.</p> <p>I can't find a erro, so I looked at the rom-data:</p> <div> <div class=scrollable_with_touch style="width:100%; 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> 4300 00 70 78 61 03 BC 02 39 02 40 C1 AC CE 6D 8C 2E .pxa.&frac14;.9.@&Aacute;&not;&Icirc;m&OElig;. </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 first 8 bytes (00 70 78 61 03 BC 02 39) are the header, so the first databyte is 02<br /> or binary: 00000010</p> <p>When I look in decompress code:</p> <div> <div class=scrollable_with_touch style="width:100%; 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> while (src_pos &lt; comp_len &amp;&amp; dest_pos &lt; raw_len &amp;&amp; dest_pos &lt; max_len) { int block_type = getbit(); // printf(&quot;%d %d\n&quot;, src_pos, block_type); fflush(stdout); if (block_type == 0) { // block int block_offset = getnum() + 1; int block_len = getchain(BLOCK_LEN_CHAIN_BITS, 100000) + PXA_MIN_BLOCK_LEN; // copy // don't just memcpy because might be copying self for repeating pattern while (block_len &gt; 0){ out_p[dest_pos] = out_p[dest_pos - block_offset]; dest_pos++; block_len--; } </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>it read the first bit (a zero) from 0x02 and go through the block_type==0 code.<br /> At this moment the out_p is complete empty and dest_pos is 0, so when the code comes to &quot;out_p[dest_pos] = out_p[dest_pos - block_offset];&quot; it copied data BELOW the output-buffer.</p> https://www.lexaloffle.com/bbs/?tid=49311 https://www.lexaloffle.com/bbs/?tid=49311 Mon, 12 Sep 2022 20:31:32 UTC Dithering demo <p> <table><tr><td> <a href="/bbs/?pid=117283#p"> <img src="/bbs/thumbs/pico8_yemapepoke-0.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=117283#p"> yemapepoke</a><br><br> by <a href="/bbs/?uid=58188"> GPI</a> <br><br><br> <a href="/bbs/?pid=117283#p"> [Click to Play]</a> </td></tr></table> </p> <p>A little demo of importing dithered pictures. The rom contain 3 pictures, switch with x/o.</p> <p>Images are created with jaP8e<br /> <a href="https://www.lexaloffle.com/bbs/?tid=49307">https://www.lexaloffle.com/bbs/?tid=49307</a></p> https://www.lexaloffle.com/bbs/?tid=49309 https://www.lexaloffle.com/bbs/?tid=49309 Mon, 12 Sep 2022 16:50:04 UTC jaP8e - Editor for code, graphic, charset, sound <img style="margin-bottom:16px" border=0 src="/media/58188/mainwindow.gif" alt="" /> <h2>Features</h2> <ul> <li>Source code in lua! </li> <li>Editor for sprite, map, sound, music, charset</li> <li>Map editor with support of custom width / size</li> <li>Name sound and music</li> <li>Custom palette with the extended 128+ color-ids (32 Colors in total)</li> <li>Charset editor with possible to export single characters and variable width</li> <li>Hex editor to copy &amp; past memory to pico-8 string (<a href="https://www.lexaloffle.com/dl/docs/pico-8_manual.html#Raw_memory_writes">URL raw memory access format</a> )</li> <li>Modular design</li> <li>Import images as sprite sheet, map(!), label - with optional dithering</li> </ul> <h1>IMPORTANT</h1> <p>This is a beta release! This means, there are bugs, the program can crash. Make backups before using the editor.</p> <h1>Download</h1> <p><a href="https://github.com/GPIforGit/jaP8e/releases">https://github.com/GPIforGit/jaP8e/releases</a></p> <h2>basic control/setup</h2> <h3>Set the path to pico-8.exe</h3> <p>jaP8e needs to know where the pico-8 execute is. Choose in the Menu the &quot;Pico-8&quot; &gt; &quot;Set Pico8 exectuable&quot; option to set the path. Otherwise it can't run any code or playback sound.</p> <h3>Pico-8 Remote</h3> <p>Since I don't know how to program sounds like in pico-8, jaP8e can't playback sound by default. But it is possible to start a &quot;Remote&quot;-pico-8, which runs in the background and is controlled by jaP8e. Activate this option in the &quot;Pico-8&quot;-menu. After this you can playback any sound effect and music during jaP8e.<br /> This function starts a pico-8 with the remote.p8 file in the background. I send commands through stdin/stdout to this remote.</p> <h3>Change Values in the grey input boxes</h3> <p>You can change the values of the grey input boxes by left click in it and use the keyboard. Alternative you can press and hold the right mousebutton and change the value with x-mouse-movement. The third possibility is to use the mouse wheel over the input fields.</p> <h3>basic layout</h3> <p>On the top you find the modules-tab to switch the editors. On the right top side are currently open files. A Star in the file name indicates that the file has unchanged data.</p> <h3>memory layout</h3> <p>jaP8e &quot;simulate&quot; the memory of pico-8, with a rom and ram section. The rom-section is stored normaly like pico8 does and can access normaly. RAM is stored as meta-data and can't access directly in pico-8, but you can export ram as string to copy in the source code (HEX-Editor).<br /> Also you can reposition the map, sprite, sound, music, spriteflags to any memory location, even when pico 8 doesn't support it.<br /> For example, when you don't use a map in your pico-8-project, you can store there additional sprite data. Simple reposition the sprite to 0x1000 to draw in the map-data. In pico-8 you must manually copy the memory (memcpy) to access this additional sprite data. </p> <h3>Error-message and disable a module</h3> <p>When a error happen, a message box with ok and cancel will open. With ok jaP8e will ignore the error. With cancel the module which cause the error will disabled. At least you can try to save your work when a error happen.</p> <h2>Source Editor</h2> <img style="margin-bottom:16px" border=0 src="/media/58188/mainwindow.gif" alt="" /> <p>on the left side of the window you find some information tabs:</p> <h3>Functions</h3> <p>display every function that jaP8e found in the current tab. Also all comments which start and end with &quot;--&quot; should be visible here.<br /> You can click in the list to jump to the position.<br /> When the cursor in the source code is inside a function, this function will be highlighted in the list.</p> <h3>Sprites</h3> <p>Fast display of all sprites. When you select a number in the source code, the sprite with the same id is highlighted.<br /> Click on a sprite will add the id-nummer in the source code</p> <h3>Charset</h3> <p>Click on a char to add this in the source code.</p> <h3>Sound</h3> <p>When you select a number in the source code, the sound with the same id is highlighted. Press ALT + SPACE to playback this sfx.</p> <h3>Music</h3> <p>same as sound</p> <h3>Palette</h3> <p>show the custom palette (when not changed, this is identical to default), the default palette and the extended palette</p> <h3>Source code editor</h3> <p>Should react nearly the same as the default editor in Pico-8 with some extras. Tabs work as in Pico 8 - simple click in the &quot;+&quot; above. You can also name the tabs, when the first line is a comment.<br /> When you select a word, it will highlight this word in the complete source code. Also when the cursor is over the a brace the matching other brace is highlighted.<br /> When you don't like the color-scheme, you can edit the jaP8e.ini file.<br /> By default the puny-font is disabled and a normal font is used, so all text should be written in lower case!<br /> Copy &amp; past will always ignore the puny-setting.<br /> Look in the menu for many additional functions / keyboard shortcuts.</p> <h2>Map editor</h2> <img style="margin-bottom:16px" border=0 src="/media/58188/map.gif" alt="" /> <p>On the left side you can select a Sprite - you can select more than one.<br /> Grid add a grid, id will display the ids, flags draw a bar with the spriteflags and count shows how often a sprite is used in the map.<br /> With CTRL + Click the current Sprite will exchange the position in the Spritesheet and the map will be corrected.<br /> With CTRL + SHIFT + Click it will exchanged without correction.</p> <p>You can also quick-select patterns in the map by right click and hold. Middle-Mouse button will scroll and the wheel will change the zoom.</p> <p>Below you find some options:<br /> Grid will add a grid to the map, ID will draw the ids of the tiles, when find is active, the selected sprites of the sprite sheet will highlighted in the map.<br /> Also you have different tools like stamp, line etc.<br /> With POS you can change the position of the map in the memory and Width will change the width of the map.<br /> With Background you can select a color to change the background.</p> <p>You can quickselect a sprite with the shift/a/s/d/w-keys</p> <p>In the Menu with File &gt; import &gt; map image you can import an image as Map! The image will sliced in tiles and added to the sprite sheet, when an empty slot is available.</p> <h2>Sprite editor</h2> <img style="margin-bottom:16px" border=0 src="/media/58188/sprite.gif" alt="" /> <p>Control nearly the same as the map editor.<br /> POS and FLAG-Buttons will change where the sprite / spriteflags are located in the memory.<br /> Set Icon will change the icon when you export an binary.<br /> Right click on the color to change the palette.<br /> Important: Palette changes are stored in the ram-section and must be exported in the hex editor to the source code.</p> <h2>Sound editor</h2> <img style="margin-bottom:16px" border=0 src="/media/58188/sound.gif" alt="" /> <p>Should work like the original pico-8 editors. Like in sprites you can with CTRL+Click / CTRL+SHIFT+Click exchange the SFX.<br /> You can additonal name a SFX with 8 characters. This information is stored in the meta-data of the p8-file and is only for your information and not directly useable in pico8.</p> <h2>Music editor</h2> <img style="margin-bottom:16px" border=0 src="/media/58188/music.gif" alt="" /> <p>Can do the same as the pico8 editor.<br /> When you paste a music, the sfx-pattern will be insert at top by default (pico 8 start at bottom). You can change this behaviour in the edit-menu.</p> <h2>Label editor</h2> <img style="margin-bottom:16px" border=0 src="/media/58188/label.gif" alt="" /> <p>Also very basic. You can import an image with the file-&gt;import-&gt;label image in the menu bar. In the settings-menu you can select activate dithering.</p> <h2>Charset editor</h2> <img style="margin-bottom:16px" border=0 src="/media/58188/charset.gif" alt="" /> <p>Important note: Charset is always located in the memory section (0x5600). When you want to use it, you must copy it in the hex editor!<br /> Work like the Sprite editor, but only with two colors. On the right button you can set some basic settings. Variable font with is supported, when you activate &quot;Adj.Enable&quot;, then you can use the &quot;Adj&quot;-field to change the with of the current char (like in the picture, I is here only 2 pixel with.<br /> When you click on the &quot;lazy dog&quot; text you can switch between different example text.<br /> When you ctrl+c on a char, it will copy as a string, that can be use directly in pico 8 <a href="https://www.lexaloffle.com/dl/docs/pico-8_manual.html#One_off_characters">URL pico8-manual</a>. In the edit - menu you can select between binary-char and hexadecimal-char version.<br /> Of course you can paste chars in both formats.</p> <h2>hex editor</h2> <img style="margin-bottom:16px" border=0 src="/media/58188/hex.gif" alt="" /> <p>On the left side you have some select buttons. The &quot;ROM&quot; button select the default position of the items. Under &quot;RAM&quot; you can select some areas which are used by jaP8e. When you move the Sprite/Map/and so on with the &quot;POS&quot;-button, you can select the area here with the &quot;POS&quot;-mark.<br /> The Hex-Buttons below select the memory 0x8000 - 0xff00 location. Click with shift to select to the end of this memory-block.<br /> You can Copy &amp; Paste memory blocks. It is stored as string in the clipboard in the <a href="https://www.lexaloffle.com/dl/docs/pico-8_manual.html#Raw_memory_writes">URL raw memory access format</a> and can be simple copied in the source code!<br /> For example the default palette from memory look like this:</p> <div> <div class=scrollable_with_touch style="width:100%; 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> \^@5f100010\0&sup1;&sup2;&sup3;⁴⁵⁶⁷⁸\t\nᵇᶜ\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>IMPORTANT all data above 0x4300 are saved as meta-data and are not accessible directly by a pico-8 program.</p> <h2>pico-8-support</h2> <p>In the Pico-8 menu you can start your project. At default jaP8e switch to write protect mode and will reload after pico8 is closed (this can be disabled in the pico-8 menu). Your project must be saved before this will work.<br /> You can also export here binarys (you can select a icon in the sprite editor), webpage, .p8.png and more.<br /> The RAM-Section of the current project will be stored as meta data in the .p8 - file. This is way jaP8e can only p8 files directly.</p> <h1>what is luatik?</h1> <p>Luatik is my lua interpreter variant. I patch lua with some features (auto load libraries, += -= is possible and some other goodies). Look in the lunatik-order to get more information.<br /> <a href="https://github.com/GPIforGit/Luatik">https://github.com/GPIforGit/Luatik</a></p> https://www.lexaloffle.com/bbs/?tid=49307 https://www.lexaloffle.com/bbs/?tid=49307 Mon, 12 Sep 2022 15:56:08 UTC [Request] Print (text,&quot;center&quot;,y) <p>I think, that it is common to print a text in center of the screen.</p> <p>With the variable font it become a little bit complicated..<br /> When the text is variable we must do something like this.</p> <div> <div class=scrollable_with_touch style="width:100%; 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> str = &quot;text&quot; len = print(str,0,-0x4000) -- print outside to get the length print(str, 64-len\2, 128) </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>it would be nice, when instead of the x-coordinate a string with the position could be added</p> <div> <div class=scrollable_with_touch style="width:100%; 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> str = &quot;text&quot; print(str, &quot;center&quot;, 128) </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>possible &quot;key-words&quot; would be: &quot;left&quot;, &quot;center&quot;, &quot;right&quot;<br /> for y would be &quot;top&quot;, &quot;center&quot;, &quot;bottom&quot;</p> <p>btw. a &quot;printsize&quot; function would be nice, don't draw anything, only return width and height in pixels.</p> https://www.lexaloffle.com/bbs/?tid=49302 https://www.lexaloffle.com/bbs/?tid=49302 Mon, 12 Sep 2022 10:30:05 UTC The Laboratories of Dr. Creep <p> <table><tr><td> <a href="/bbs/?pid=99419#p"> <img src="/bbs/thumbs/pico8_drcreep-2.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=99419#p"> drcreep</a><br><br> by <a href="/bbs/?uid=58188"> GPI</a> <br><br><br> <a href="/bbs/?pid=99419#p"> [Click to Play]</a> </td></tr></table> </p> <p>Recreation of a C64 classic: Castles of Dr. Creep.<br /> Compared to the original there are some changes, on the one hand because the layout is different (40x24 vs 16x16), on the other hand because I have defused some &quot;backtracking&quot; and death traps. Nevertheless, please note, the levels are from 1984 - there you have something different design.</p> <h1>Story</h1> <p><div><div><input type="button" value=" Show " onClick="if (this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display != '') { this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = ''; this.innerText = ''; this.value = ' Hide '; } else { this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = 'none'; this.innerText = ''; this.value = ' Show '; }"></div><div><div style="display: none;"><br /> So, you're looking for a place to work? Something special, challenging, with a good salary? Well, we have just the thing for you.<br /> Many different options open for your inspection. Just step inside ... Oh? You want to leave already? I'm afraid that's simply not possible ... not until you have taken the complete tour.<br /> You'll notice that we have all the modern conveniences. Electrostatic energy generators to warm things up. Piped-in music which I'm sure you will find quite haunting. Doors galore, and you never know what you will find on the other side. Once the death rays start lining up behind you, however, I know you will be eager to find out.<br /> You may want to step lively over trap doors and through the force fields - we've lost several potential applicants that way. Over there, of course, is mummy's room. Mummy seems to be all wrapped up at the moment, but probably not for long. And a break room? At the Laboratories, all the rooms are restful, although many of the occupants are not.<br /> Neighbours, you ask? I Know you will love them. Frankenstein's Monster just seems to pop up whenever you least expect him.<br /> Well, I really must be leaving now. I'm sure you can find your way around. Don't be alarmed. There's a key in here somewhere. You will find your way out eventually... and if not, Doctor Creep will be back shortly and you can help him with his, ah, experiments.<br /> Goodbye now ... and good luck.<br /> </div></div></div></p> <h1>Playing the game</h1> <p><div><div><input type="button" value=" Show " onClick="if (this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display != '') { this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = ''; this.innerText = ''; this.value = ' Hide '; } else { this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = 'none'; this.innerText = ''; this.value = ' Show '; }"></div><div><div style="display: none;"><br /> You are captured in a Laboratories and your goal is to escape.<br /> Open a map with 🅾️.<br /> In the pause menu you can save a game state. Note that the status is stored before entering the room.<br /> </div></div></div></p> <h2>Obstacles</h2> <p><div><div><input type="button" value=" Show " onClick="if (this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display != '') { this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = ''; this.innerText = ''; this.value = ' Hide '; } else { this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = 'none'; this.innerText = ''; this.value = ' Show '; }"></div><div><div style="display: none;"></p> <h3>Player</h3> <p> <table><tr><td width=32> <img src="https://www.lexaloffle.com/bbs/gfxc/58188_1.png" width=32 height=32> </td> <td valign=bottom> <a style="cursor:pointer;font-size:8pt" onclick=' var el = document.getElementById("gfxcode_58188_1"); if (el.style.display == "none") el.style.display = ""; else el.style.display = "none"; microAjax("https://www.lexaloffle.com/bbs/gfxc/58188_1.txt", function (retdata){ var el = document.getElementById("gfxcode_58188_1"); el.innerHTML = retdata; el.focus(); el.select(); } ); '> [8x8]</a> </td></tr> <tr><td colspan=2> <textarea rows=3 class=lexinput id="gfxcode_58188_1" style="width:640px;background-color:#fed;display:none;overflow:hidden; font-size:6pt;"></textarea> </td> </tr> </table> </p> <h3>Doors and Doorbells</h3> <p> <table><tr><td width=96> <img src="https://www.lexaloffle.com/bbs/gfxc/58188_2.png" width=96 height=64> </td> <td valign=bottom> <a style="cursor:pointer;font-size:8pt" onclick=' var el = document.getElementById("gfxcode_58188_2"); if (el.style.display == "none") el.style.display = ""; else el.style.display = "none"; microAjax("https://www.lexaloffle.com/bbs/gfxc/58188_2.txt", function (retdata){ var el = document.getElementById("gfxcode_58188_2"); el.innerHTML = retdata; el.focus(); el.select(); } ); '> [24x16]</a> </td></tr> <tr><td colspan=2> <textarea rows=3 class=lexinput id="gfxcode_58188_2" style="width:640px;background-color:#fed;display:none;overflow:hidden; font-size:6pt;"></textarea> </td> </tr> </table> <br /> One way to open a door is to use the doorbell. Operate the doorbell by standing in front of it and pressing the ❎ button. To go out an open door, stand in front of the door and press ⬆️ or ❎.</p> <h3>Ladders</h3> <p> <table><tr><td width=64> <img src="https://www.lexaloffle.com/bbs/gfxc/58188_3.png" width=64 height=64> </td> <td valign=bottom> <a style="cursor:pointer;font-size:8pt" onclick=' var el = document.getElementById("gfxcode_58188_3"); if (el.style.display == "none") el.style.display = ""; else el.style.display = "none"; microAjax("https://www.lexaloffle.com/bbs/gfxc/58188_3.txt", function (retdata){ var el = document.getElementById("gfxcode_58188_3"); el.innerHTML = retdata; el.focus(); el.select(); } ); '> [16x16]</a> </td></tr> <tr><td colspan=2> <textarea rows=3 class=lexinput id="gfxcode_58188_3" style="width:640px;background-color:#fed;display:none;overflow:hidden; font-size:6pt;"></textarea> </td> </tr> </table> <br /> To get on a ladder, stand directly behind it and push ⬆️ or ⬇️. You can get off of a ladder whenever your feet are even with the front of a walkway.</p> <h3>Sliding Poles</h3> <p> <table><tr><td width=64> <img src="https://www.lexaloffle.com/bbs/gfxc/58188_4.png" width=64 height=64> </td> <td valign=bottom> <a style="cursor:pointer;font-size:8pt" onclick=' var el = document.getElementById("gfxcode_58188_4"); if (el.style.display == "none") el.style.display = ""; else el.style.display = "none"; microAjax("https://www.lexaloffle.com/bbs/gfxc/58188_4.txt", function (retdata){ var el = document.getElementById("gfxcode_58188_4"); el.innerHTML = retdata; el.focus(); el.select(); } ); '> [16x16]</a> </td></tr> <tr><td colspan=2> <textarea rows=3 class=lexinput id="gfxcode_58188_4" style="width:640px;background-color:#fed;display:none;overflow:hidden; font-size:6pt;"></textarea> </td> </tr> </table> <br /> To get on a sliding pole, stand directly in front of it and pull ⬇️. you cannot climb up the sliding poles. You can get off of a pole whenever your feet are even with the middle of a walkway.</p> <h3>Lightning Machine</h3> <p> <table><tr><td width=64> <img src="https://www.lexaloffle.com/bbs/gfxc/58188_5.png" width=64 height=64> </td> <td valign=bottom> <a style="cursor:pointer;font-size:8pt" onclick=' var el = document.getElementById("gfxcode_58188_5"); if (el.style.display == "none") el.style.display = ""; else el.style.display = "none"; microAjax("https://www.lexaloffle.com/bbs/gfxc/58188_5.txt", function (retdata){ var el = document.getElementById("gfxcode_58188_5"); el.innerHTML = retdata; el.focus(); el.select(); } ); '> [16x16]</a> </td></tr> <tr><td colspan=2> <textarea rows=3 class=lexinput id="gfxcode_58188_5" style="width:640px;background-color:#fed;display:none;overflow:hidden; font-size:6pt;"></textarea> </td> </tr> </table> <br /> Turn the sparks on or off by standing in front of the switch and push ⬆️,⬇️,❎.</p> <h3>Force Field</h3> <p> <table><tr><td width=64> <img src="https://www.lexaloffle.com/bbs/gfxc/58188_6.png" width=64 height=64> </td> <td valign=bottom> <a style="cursor:pointer;font-size:8pt" onclick=' var el = document.getElementById("gfxcode_58188_6"); if (el.style.display == "none") el.style.display = ""; else el.style.display = "none"; microAjax("https://www.lexaloffle.com/bbs/gfxc/58188_6.txt", function (retdata){ var el = document.getElementById("gfxcode_58188_6"); el.innerHTML = retdata; el.focus(); el.select(); } ); '> [16x16]</a> </td></tr> <tr><td colspan=2> <textarea rows=3 class=lexinput id="gfxcode_58188_6" style="width:640px;background-color:#fed;display:none;overflow:hidden; font-size:6pt;"></textarea> </td> </tr> </table> <br /> Turn off the force field by standing in front of the control and pushing ❎. The force field will remain off for a few seconds after the button is released.</p> <h3>Mummy</h3> <p> <table><tr><td width=128> <img src="https://www.lexaloffle.com/bbs/gfxc/58188_7.png" width=128 height=64> </td> <td valign=bottom> <a style="cursor:pointer;font-size:8pt" onclick=' var el = document.getElementById("gfxcode_58188_7"); if (el.style.display == "none") el.style.display = ""; else el.style.display = "none"; microAjax("https://www.lexaloffle.com/bbs/gfxc/58188_7.txt", function (retdata){ var el = document.getElementById("gfxcode_58188_7"); el.innerHTML = retdata; el.focus(); el.select(); } ); '> [32x16]</a> </td></tr> <tr><td colspan=2> <textarea rows=3 class=lexinput id="gfxcode_58188_7" style="width:640px;background-color:#fed;display:none;overflow:hidden; font-size:6pt;"></textarea> </td> </tr> </table> <br /> When you run in front of the ankh, the mummy slides out of its tomb. Mummies are<br /> too stiff to use ladders or sliding poles.</p> <h3>Locks and Keys</h3> <p> <table><tr><td width=64> <img src="https://www.lexaloffle.com/bbs/gfxc/58188_8.png" width=64 height=64> </td> <td valign=bottom> <a style="cursor:pointer;font-size:8pt" onclick=' var el = document.getElementById("gfxcode_58188_8"); if (el.style.display == "none") el.style.display = ""; else el.style.display = "none"; microAjax("https://www.lexaloffle.com/bbs/gfxc/58188_8.txt", function (retdata){ var el = document.getElementById("gfxcode_58188_8"); el.innerHTML = retdata; el.focus(); el.select(); } ); '> [16x16]</a> </td></tr> <tr><td colspan=2> <textarea rows=3 class=lexinput id="gfxcode_58188_8" style="width:640px;background-color:#fed;display:none;overflow:hidden; font-size:6pt;"></textarea> </td> </tr> </table> <br /> To pick up a key, stand in front of it and push ❎. You can open a lock only after you have picked up a key of matching color. Stand in front of the lock and push ❎.</p> <h3>Ray Gun</h3> <p> <table><tr><td width=64> <img src="https://www.lexaloffle.com/bbs/gfxc/58188_9.png" width=64 height=64> </td> <td valign=bottom> <a style="cursor:pointer;font-size:8pt" onclick=' var el = document.getElementById("gfxcode_58188_9"); if (el.style.display == "none") el.style.display = ""; else el.style.display = "none"; microAjax("https://www.lexaloffle.com/bbs/gfxc/58188_9.txt", function (retdata){ var el = document.getElementById("gfxcode_58188_9"); el.innerHTML = retdata; el.focus(); el.select(); } ); '> [16x16]</a> </td></tr> <tr><td colspan=2> <textarea rows=3 class=lexinput id="gfxcode_58188_9" style="width:640px;background-color:#fed;display:none;overflow:hidden; font-size:6pt;"></textarea> </td> </tr> </table> <br /> Operate the gun by standing in front of the control and using ⬆️ and ⬇️ to aim and ❎ to fire. The gun fires automatically when it is at the same level as a player.</p> <h3>Matter Transmitter</h3> <p> <table><tr><td width=96> <img src="https://www.lexaloffle.com/bbs/gfxc/58188_10.png" width=96 height=64> </td> <td valign=bottom> <a style="cursor:pointer;font-size:8pt" onclick=' var el = document.getElementById("gfxcode_58188_10"); if (el.style.display == "none") el.style.display = ""; else el.style.display = "none"; microAjax("https://www.lexaloffle.com/bbs/gfxc/58188_10.txt", function (retdata){ var el = document.getElementById("gfxcode_58188_10"); el.innerHTML = retdata; el.focus(); el.select(); } ); '> [24x16]</a> </td></tr> <tr><td colspan=2> <textarea rows=3 class=lexinput id="gfxcode_58188_10" style="width:640px;background-color:#fed;display:none;overflow:hidden; font-size:6pt;"></textarea> </td> </tr> </table> <br /> Stand in the booth and hold ⬆️ until the color in the booth matches the color of the desired receiver oval. Push ❎ to transmit.</p> <h3>Trapdoor</h3> <p> <table><tr><td width=64> <img src="https://www.lexaloffle.com/bbs/gfxc/58188_11.png" width=64 height=64> </td> <td valign=bottom> <a style="cursor:pointer;font-size:8pt" onclick=' var el = document.getElementById("gfxcode_58188_11"); if (el.style.display == "none") el.style.display = ""; else el.style.display = "none"; microAjax("https://www.lexaloffle.com/bbs/gfxc/58188_11.txt", function (retdata){ var el = document.getElementById("gfxcode_58188_11"); el.innerHTML = retdata; el.focus(); el.select(); } ); '> [16x16]</a> </td></tr> <tr><td colspan=2> <textarea rows=3 class=lexinput id="gfxcode_58188_11" style="width:640px;background-color:#fed;display:none;overflow:hidden; font-size:6pt;"></textarea> </td> </tr> </table> <br /> The trapdoor opens or closes whenever anyone runs in front of the control.</p> <h3>Frankensteins Monster</h3> <p> <table><tr><td width=64> <img src="https://www.lexaloffle.com/bbs/gfxc/58188_12.png" width=64 height=64> </td> <td valign=bottom> <a style="cursor:pointer;font-size:8pt" onclick=' var el = document.getElementById("gfxcode_58188_12"); if (el.style.display == "none") el.style.display = ""; else el.style.display = "none"; microAjax("https://www.lexaloffle.com/bbs/gfxc/58188_12.txt", function (retdata){ var el = document.getElementById("gfxcode_58188_12"); el.innerHTML = retdata; el.focus(); el.select(); } ); '> [16x16]</a> </td></tr> <tr><td colspan=2> <textarea rows=3 class=lexinput id="gfxcode_58188_12" style="width:640px;background-color:#fed;display:none;overflow:hidden; font-size:6pt;"></textarea> </td> </tr> </table> <br /> When you walk in front of his coffin, frankensteins monster awakens and begins to chase you. frankensteins monster is able to use the ladders and sliding poles.</p> <h3>Conveyor Belt</h3> <p> <table><tr><td width=64> <img src="https://www.lexaloffle.com/bbs/gfxc/58188_13.png" width=64 height=64> </td> <td valign=bottom> <a style="cursor:pointer;font-size:8pt" onclick=' var el = document.getElementById("gfxcode_58188_13"); if (el.style.display == "none") el.style.display = ""; else el.style.display = "none"; microAjax("https://www.lexaloffle.com/bbs/gfxc/58188_13.txt", function (retdata){ var el = document.getElementById("gfxcode_58188_13"); el.innerHTML = retdata; el.focus(); el.select(); } ); '> [16x16]</a> </td></tr> <tr><td colspan=2> <textarea rows=3 class=lexinput id="gfxcode_58188_13" style="width:640px;background-color:#fed;display:none;overflow:hidden; font-size:6pt;"></textarea> </td> </tr> </table> <br /> To change the motion of the conveyor belt, stand in front of the control and push ❎.</p> <h3>The exit Door</h3> <p> <table><tr><td width=64> <img src="https://www.lexaloffle.com/bbs/gfxc/58188_14.png" width=64 height=64> </td> <td valign=bottom> <a style="cursor:pointer;font-size:8pt" onclick=' var el = document.getElementById("gfxcode_58188_14"); if (el.style.display == "none") el.style.display = ""; else el.style.display = "none"; microAjax("https://www.lexaloffle.com/bbs/gfxc/58188_14.txt", function (retdata){ var el = document.getElementById("gfxcode_58188_14"); el.innerHTML = retdata; el.focus(); el.select(); } ); '> [16x16]</a> </td></tr> <tr><td colspan=2> <textarea rows=3 class=lexinput id="gfxcode_58188_14" style="width:640px;background-color:#fed;display:none;overflow:hidden; font-size:6pt;"></textarea> </td> </tr> </table> <br /> The door at the right leads out of the laboratory. When you go out this door you have escaped.<br /> </div></div></div></p> <h1>Editor</h1> <p><div><div><input type="button" value=" Show " onClick="if (this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display != '') { this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = ''; this.innerText = ''; this.value = ' Hide '; } else { this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = 'none'; this.innerText = ''; this.value = ' Show '; }"></div><div><div style="display: none;"><br /> <a href="https://github.com/GPIforGit/The-Laboratories-of-Dr.-Creep/releases">https://github.com/GPIforGit/The-Laboratories-of-Dr.-Creep/releases</a> - download the assets</p> <p>There is a editor, splitted in several files:<br /> creep.p8 - the game - stand-alone<br /> creepbuild.p8 - pack all the data and store it in creep.p8<br /> creepedit.p8 - the level-editor</p> <p>And some data - no lua code here. Also only parts of the p8 are packed from this files:<br /> creep_endscreen.p8 - the End-Screen, must be placed completely in the shared gfx rom!<br /> creep_levels.p8 - the level-data<br /> creep_mainback.p8 - the main-menu background, must be placed completely in the shared gfx rom<br /> creep_music.p8 - main-menu music.<br /> creep_sprites_sound.p8 - gfx (only 0x0000-0x1000), gfx-flags and sfx are used from here.</p> <p>You need all the files to edit levels, for playing only the creep.p8</p> <p>Note that when you save the level data, it is stored in &quot;creep_levels.p8&quot;. When you want to test your level, you must run creepbuild.p8 or choose in the pause-menu &quot;build&quot;.</p> <p>There is a limit of 31 rooms and 15 of every object. First select a object with the keys, than place it with the left mouse button.</p> <p>A switch can operate more than one machine. After placing a switch you can link the switch to a machine by simple click left on the machine. Right-click will quit link mode. To relink right click on a switch. </p> <p>Doorbells and locks work the same, link them with doors.</p> <p>When you place a door, you must set an connected door. Move the room with + - &lt; &gt; or switch room over the map (tab) and place there the second door. When you place the second door in the same room you create an exit-door.</p> <p>With tab you enter map mode. Move the cursor over one map and press tab again to enter the room. With left-click on a room you can move it, right click to resize it.</p> <p>The best way to edit the labs is to open pico8 twice, once the editor and once the game. If you want to try something out, select &quot;build&quot; in the editor pause menu and then ctrl+r in the game to reload the changes.<br /> </div></div></div></p> <h2>Working with the editor</h2> <p><div><div><input type="button" value=" Show " onClick="if (this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display != '') { this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = ''; this.innerText = ''; this.value = ' Hide '; } else { this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = 'none'; this.innerText = ''; this.value = ' Show '; }"></div><div><div style="display: none;"><br /> Important - keyboard is only detected, when the pico8-window is activ and the mouse cursor is in the window!</p> <p>left mouse button --- set object or move the object under the cursor</p> <p>right mouse button --- change size of object under the cursor or go through a door or start/stop linking object (switches, door bells or locks)</p> <p>0-9 * / . , --- change state/color of the object, for example the color of the walk ways, active/deactivate, change direction and so on</p> <p>backspace --- delete the active selected object. Important, when you delete a lightning machine or a door, you should check every machine, switch and doorbells - they may be invalid. </p> <p>space -- walk through door</p> <p>w -- walkway<br /> l -- ladder<br /> s -- sliding poles<br /> d -- door<br /> b -- doorbell<br /> o -- lock<br /> k -- key<br /> c -- conver belts<br /> m -- lightning machine<br /> i -- switch for lightning machine<br /> f -- force field<br /> t -- trapdoor<br /> x -- matter transmitter booth<br /> v -- transmitter destination<br /> u -- mummy<br /> r -- frankenstein monster<br /> g -- ray gun</p> <ul> <li>&gt; -- next room</li> <li>&lt; -- previous room</li> </ul> <p>shift+r -- rename lab when you empty the name, the lab will be deleted.</p> <p>shift+s -- save (but not build!) the level data.</p> <p>shift+e shift+1 -- start position player 1</p> <p>shift+w shift+2 -- start position player 2</p> <p>tab -- enter map mode</p> <p>ctrl+c shift+c -- export lab as clipboard-string</p> <p>ctrl+v shift+v -- import lab from clipboard<br /> </div></div></div></p> <h1>behind the scenes</h1> <p><div><div><input type="button" value=" Show " onClick="if (this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display != '') { this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = ''; this.innerText = ''; this.value = ' Hide '; } else { this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = 'none'; this.innerText = ''; this.value = ' Show '; }"></div><div><div style="display: none;"><br /> Some may have guessed it already, the game is a &quot;The Castle of Dr. Creep&quot; clone. A classic on the C64 from 1984 and was quite unique at the time.</p> <p>The original game is relatively complex and uses a complete floppy disk. The problem here is that I wanted to insert as many of the castles as possible. To put them &quot;classically&quot; in the map data does not work, much too large, so a level editor had to be created. Writing it in Pico8 was not so easy, it is almost more complex than the game.</p> <p>A special feature of the level data is that I do not save byte wise, but bit wise. For example, to save the status of a trapdoor, I need exactly one bit. This method is also used for the game saves, otherwise it would be partly impossible to accommodate this in 256 bytes. However, I had to cheat a bit, for example, a round position of the creatures is stored. It is possible that a loaded game does not always remain solvable. But I think I've solved the problem.</p> <p>In addition, I use the lzw logarithm to store even more data. it is possible to place data in source code via string, but somehow I find that inelegant. The packed data also has the advantage that it can be edited more easily with tools without changing the lua code.</p> <p>Compared to the original castle, there are some changes, on the one hand because the layout is different (40x24 vs 16x16), on the other hand because I have defused some &quot;backtracking&quot; and death traps. Nevertheless, please note, the levels are from 1984 - there you have something different design.</p> <p>The game should be similar to the original, but not just copy it. I've made some changes. The monsters, for example, always go at the closer player (in the original it was always player one). Likewise the map, in the original it appears after each level and you have to confirm it, I immediately switch here to the next room. This increases the game speed enormously.</p> <p>The story text is a variant of the text on the back of the box. The object descriptions are variants of original tutorial.<br /> </div></div></div></p> <h1>sources</h1> <p><div><div><input type="button" value=" Show " onClick="if (this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display != '') { this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = ''; this.innerText = ''; this.value = ' Hide '; } else { this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = 'none'; this.innerText = ''; this.value = ' Show '; }"></div><div><div style="display: none;"><br /> The Castles of Dr. Creep Revisited<br /> <a href="https://web.archive.org/web/20161223145535/http://baetzler.de/c64/games/creep/">https://web.archive.org/web/20161223145535/http://baetzler.de/c64/games/creep/</a></p> <p>Doctor Creep<br /> <a href="http://moon.descentforum.net/creep/">http://moon.descentforum.net/creep/</a></p> <p>music:<br /> <a href="https://www.8notes.com/scores/998.asp?ftype=midi">https://www.8notes.com/scores/998.asp?ftype=midi</a></p> <p>Infos about the game:<br /> <a href="https://www.mobygames.com/game/c64/castles-of-dr-creep">https://www.mobygames.com/game/c64/castles-of-dr-creep</a></p> <p>Lempel&ndash;Ziv&ndash;Welch:<br /> <a href="https://rosettacode.org/wiki/LZW_compression">https://rosettacode.org/wiki/LZW_compression</a><br /> <a href="https://en.wikipedia.org/wiki/Lempel%E2%80%93Ziv%E2%80%93Welch">https://en.wikipedia.org/wiki/Lempel%E2%80%93Ziv%E2%80%93Welch</a><br /> </div></div></div></p> https://www.lexaloffle.com/bbs/?tid=45202 https://www.lexaloffle.com/bbs/?tid=45202 Sun, 31 Oct 2021 16:09:50 UTC LZW-compress and decompress <p> <table><tr><td> <a href="/bbs/?pid=99373#p"> <img src="/bbs/thumbs/pico8_lzw-1.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=99373#p"> lzw</a><br><br> by <a href="/bbs/?uid=58188"> GPI</a> <br><br><br> <a href="/bbs/?pid=99373#p"> [Click to Play]</a> </td></tr></table> <br /> I have translated and extend the lua code from here<br /> <a href="https://rosettacode.org/wiki/LZW_compression">https://rosettacode.org/wiki/LZW_compression</a><br /> I tried to reduce the token count, but I wouldn't surprised when someone will shrink it more.</p> <p>lzw is the codec that for example gif use, it was patented, but it expired 2004.<br /> more information:<br /> <a href="https://en.wikipedia.org/wiki/Lempel%E2%80%93Ziv%E2%80%93Welch">https://en.wikipedia.org/wiki/Lempel%E2%80%93Ziv%E2%80%93Welch</a></p> <p>I tested the code with the JELPI-Graphic&amp;Sound data - and it will compress it to 6094 Bytes (from 17152 - ~36%). </p> <p>With the next update the high-memory above 0x8000 will be useable (at the moment only with a undocumented poke), my plan is to place there 32kbit of graphic and sound data. The problem is, that this memory is not saved and I don't want to store it in the source-code because it is too big.</p> <p>With this code I can compress the 32kbit and store it in the &quot;rom&quot; (the lower 0x4300 bytes). Create a &quot;build&quot;-cart which fill the 32kbit (for example with the reload()-function from other carts), compress the data and cstore() the compressed data.<br /> Copy the compressed data to the the &quot;game-cart&quot;, on start decompress the data in the high-memory-area and copy then the part currently needed in the map/sprite-memory.</p> <p>About the tape_()-function: Think about it like a &quot;punched tape&quot; - it can be used to store datas with variable bit-size. You can use it also for the &quot;Persistent cart data&quot;. Normaly you can place 256 Bytes. When you want for example to save if a door is open or closed, you need only one bit. With this routines you can easily store 256*8 = 2048 Doors. The routine should handle 1 to 16 bit values.</p> https://www.lexaloffle.com/bbs/?tid=45188 https://www.lexaloffle.com/bbs/?tid=45188 Sat, 30 Oct 2021 13:10:11 UTC Request - return-value for poke() <p>it would be nice, when the poke() would return the address after the poke, like print() does.</p> <p>for example:</p> <div> <div class=scrollable_with_touch style="width:100%; 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>adr=poke(adr,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>should do the same as</p> <div> <div class=scrollable_with_touch style="width:100%; 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>poke(adr,1) adr+=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>or</p> <div> <div class=scrollable_with_touch style="width:100%; 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>adr=poke2(adr,0xffff)</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>instead of</p> <div> <div class=scrollable_with_touch style="width:100%; 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>poke2(adr,0xffff) adr+=2</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>or</p> <div> <div class=scrollable_with_touch style="width:100%; 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>str=&quot;abcdef&quot; adr = poke(adr,ord(str,1,#str))</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>instead</p> <div> <div class=scrollable_with_touch style="width:100%; 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>str=&quot;abcdef&quot; poke(adr,ord(str,1,#str)) adr+=#str</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> https://www.lexaloffle.com/bbs/?tid=45178 https://www.lexaloffle.com/bbs/?tid=45178 Fri, 29 Oct 2021 18:14:03 UTC Request - Pause-menu position and background <p>it would be nice to select where the pause menu should appear. Also the possiblity to draw a custom background for the pause.</p> <p>For example for a RPG. It would be useful to draw the player-status on screen and the pause-menu on the right button of the screen. In combination with the menuitem-command it would be an easy and &quot;cheap&quot; possibility to create a status-menu. Or display a map of the current level, an inventory and so on.</p> <p>Suggestion: </p> <p>menustyle([&lt;position&gt;[,&lt;draw-function&gt;]])</p> <p>position could be 0=top left, 1=top, 2 top right, 3 left, 4 center (default), 5 right, 6 bottom left, 7 bottom, 8 bottem right<br /> And draw-function is a function which is called direct before the pause-menu appears. </p> https://www.lexaloffle.com/bbs/?tid=45140 https://www.lexaloffle.com/bbs/?tid=45140 Tue, 26 Oct 2021 18:26:48 UTC Map and hi-bit <p>When you want to use the shared part of the worldmap, you can only definied 127 Sprites. In Map-Editor the high-bit 0x80 is completly unused.</p> <p>It would be nice to set a &quot;Map mode&quot; to use this &quot;wasted&quot; bit. Possible solutions would be one of this</p> <ul> <li>Flip X</li> <li>Flip Y</li> <li>Use second palette / apply fill pattern</li> </ul> <p>With Flip you can simple reduce the needed sprites with flipping:<br /> <table><tr><td width=64> <img src="https://www.lexaloffle.com/bbs/gfxc/58188_8.png" width=64 height=64> </td> <td valign=bottom> <a style="cursor:pointer;font-size:8pt" onclick=' var el = document.getElementById("gfxcode_58188_8"); if (el.style.display == "none") el.style.display = ""; else el.style.display = "none"; microAjax("https://www.lexaloffle.com/bbs/gfxc/58188_8.txt", function (retdata){ var el = document.getElementById("gfxcode_58188_8"); el.innerHTML = retdata; el.focus(); el.select(); } ); '> [16x16]</a> </td></tr> <tr><td colspan=2> <textarea rows=3 class=lexinput id="gfxcode_58188_8" style="width:640px;background-color:#fed;display:none;overflow:hidden; font-size:6pt;"></textarea> </td> </tr> </table> </p> <p>Also second palette you can reuse sprites like here (cloud/bush)<br /> <table><tr><td width=96> <img src="https://www.lexaloffle.com/bbs/gfxc/58188_10.png" width=96 height=64> </td> <td valign=bottom> <a style="cursor:pointer;font-size:8pt" onclick=' var el = document.getElementById("gfxcode_58188_10"); if (el.style.display == "none") el.style.display = ""; else el.style.display = "none"; microAjax("https://www.lexaloffle.com/bbs/gfxc/58188_10.txt", function (retdata){ var el = document.getElementById("gfxcode_58188_10"); el.innerHTML = retdata; el.focus(); el.select(); } ); '> [24x16]</a> </td></tr> <tr><td colspan=2> <textarea rows=3 class=lexinput id="gfxcode_58188_10" style="width:640px;background-color:#fed;display:none;overflow:hidden; font-size:6pt;"></textarea> </td> </tr> </table> </p> <p>oh, and of course a combination would be nice:<br /> <table><tr><td width=64> <img src="https://www.lexaloffle.com/bbs/gfxc/58188_12.png" width=64 height=64> </td> <td valign=bottom> <a style="cursor:pointer;font-size:8pt" onclick=' var el = document.getElementById("gfxcode_58188_12"); if (el.style.display == "none") el.style.display = ""; else el.style.display = "none"; microAjax("https://www.lexaloffle.com/bbs/gfxc/58188_12.txt", function (retdata){ var el = document.getElementById("gfxcode_58188_12"); el.innerHTML = retdata; el.focus(); el.select(); } ); '> [16x16]</a> </td></tr> <tr><td colspan=2> <textarea rows=3 class=lexinput id="gfxcode_58188_12" style="width:640px;background-color:#fed;display:none;overflow:hidden; font-size:6pt;"></textarea> </td> </tr> </table> </p> <p>It would be nice to set all effects for every cell, but we only have one bit....</p> <p>Maybe an additional mode would be nice</p> <ul> <li>flip depending on screen quarter<br /> <table><tr><td width=64> <img src="https://www.lexaloffle.com/bbs/gfxc/58188_11.png" width=64 height=64> </td> <td valign=bottom> <a style="cursor:pointer;font-size:8pt" onclick=' var el = document.getElementById("gfxcode_58188_11"); if (el.style.display == "none") el.style.display = ""; else el.style.display = "none"; microAjax("https://www.lexaloffle.com/bbs/gfxc/58188_11.txt", function (retdata){ var el = document.getElementById("gfxcode_58188_11"); el.innerHTML = retdata; el.focus(); el.select(); } ); '> [16x16]</a> </td></tr> <tr><td colspan=2> <textarea rows=3 class=lexinput id="gfxcode_58188_11" style="width:640px;background-color:#fed;display:none;overflow:hidden; font-size:6pt;"></textarea> </td> </tr> </table> <br /> But this could be a little bit confusing. It should orientate on Map-Values, not display.</li> </ul> https://www.lexaloffle.com/bbs/?tid=44854 https://www.lexaloffle.com/bbs/?tid=44854 Sat, 02 Oct 2021 13:12:57 UTC Pic-Man <p> <table><tr><td> <a href="/bbs/?pid=98065#p"> <img src="/bbs/thumbs/pico8_picman-1.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=98065#p"> picman</a><br><br> by <a href="/bbs/?uid=58188"> GPI</a> <br><br><br> <a href="/bbs/?pid=98065#p"> [Click to Play]</a> </td></tr></table> </p> <img style="margin-bottom:16px" border=0 src="/media/58188/picman p8_5.gif" alt="" /> <h1>Controls</h1> <p>It is a Pac-Man close, so simple use the direction-buttons to control Pic-Man.</p> <h1>Rules</h1> <p> <table><tr><td width=96> <img src="https://www.lexaloffle.com/bbs/gfxc/58188_2.png" width=96 height=64> </td> <td valign=bottom> <a style="cursor:pointer;font-size:8pt" onclick=' var el = document.getElementById("gfxcode_58188_2"); if (el.style.display == "none") el.style.display = ""; else el.style.display = "none"; microAjax("https://www.lexaloffle.com/bbs/gfxc/58188_2.txt", function (retdata){ var el = document.getElementById("gfxcode_58188_2"); el.innerHTML = retdata; el.focus(); el.select(); } ); '> [24x16]</a> </td></tr> <tr><td colspan=2> <textarea rows=3 class=lexinput id="gfxcode_58188_2" style="width:640px;background-color:#fed;display:none;overflow:hidden; font-size:6pt;"></textarea> </td> </tr> </table> <br /> You control Pic and your goal is to eat all pills to win the maze.<br /> <table><tr><td width=64> <img src="https://www.lexaloffle.com/bbs/gfxc/58188_3.png" width=64 height=64> </td> <td valign=bottom> <a style="cursor:pointer;font-size:8pt" onclick=' var el = document.getElementById("gfxcode_58188_3"); if (el.style.display == "none") el.style.display = ""; else el.style.display = "none"; microAjax("https://www.lexaloffle.com/bbs/gfxc/58188_3.txt", function (retdata){ var el = document.getElementById("gfxcode_58188_3"); el.innerHTML = retdata; el.focus(); el.select(); } ); '> [16x16]</a> </td></tr> <tr><td colspan=2> <textarea rows=3 class=lexinput id="gfxcode_58188_3" style="width:640px;background-color:#fed;display:none;overflow:hidden; font-size:6pt;"></textarea> </td> </tr> </table> <br /> Don't touch the ghosts, they will kill you.<br /> <table><tr><td width=64> <img src="https://www.lexaloffle.com/bbs/gfxc/58188_4.png" width=64 height=64> </td> <td valign=bottom> <a style="cursor:pointer;font-size:8pt" onclick=' var el = document.getElementById("gfxcode_58188_4"); if (el.style.display == "none") el.style.display = ""; else el.style.display = "none"; microAjax("https://www.lexaloffle.com/bbs/gfxc/58188_4.txt", function (retdata){ var el = document.getElementById("gfxcode_58188_4"); el.innerHTML = retdata; el.focus(); el.select(); } ); '> [16x16]</a> </td></tr> <tr><td colspan=2> <textarea rows=3 class=lexinput id="gfxcode_58188_4" style="width:640px;background-color:#fed;display:none;overflow:hidden; font-size:6pt;"></textarea> </td> </tr> </table> <br /> When you eat a power pill you become strong enough to eat the ghosts.<br /> <table><tr><td width=64> <img src="https://www.lexaloffle.com/bbs/gfxc/58188_5.png" width=64 height=64> </td> <td valign=bottom> <a style="cursor:pointer;font-size:8pt" onclick=' var el = document.getElementById("gfxcode_58188_5"); if (el.style.display == "none") el.style.display = ""; else el.style.display = "none"; microAjax("https://www.lexaloffle.com/bbs/gfxc/58188_5.txt", function (retdata){ var el = document.getElementById("gfxcode_58188_5"); el.innerHTML = retdata; el.focus(); el.select(); } ); '> [16x16]</a> </td></tr> <tr><td colspan=2> <textarea rows=3 class=lexinput id="gfxcode_58188_5" style="width:640px;background-color:#fed;display:none;overflow:hidden; font-size:6pt;"></textarea> </td> </tr> </table> <table><tr><td width=64> <img src="https://www.lexaloffle.com/bbs/gfxc/58188_6.png" width=64 height=64> </td> <td valign=bottom> <a style="cursor:pointer;font-size:8pt" onclick=' var el = document.getElementById("gfxcode_58188_6"); if (el.style.display == "none") el.style.display = ""; else el.style.display = "none"; microAjax("https://www.lexaloffle.com/bbs/gfxc/58188_6.txt", function (retdata){ var el = document.getElementById("gfxcode_58188_6"); el.innerHTML = retdata; el.focus(); el.select(); } ); '> [16x16]</a> </td></tr> <tr><td colspan=2> <textarea rows=3 class=lexinput id="gfxcode_58188_6" style="width:640px;background-color:#fed;display:none;overflow:hidden; font-size:6pt;"></textarea> </td> </tr> </table> <br /> In every maze two fruit will appear in the middle of the maze, don't miss them.<br /> <table><tr><td width=256> <img src="https://www.lexaloffle.com/bbs/gfxc/58188_15.png" width=256 height=32> </td> <td valign=bottom> <a style="cursor:pointer;font-size:8pt" onclick=' var el = document.getElementById("gfxcode_58188_15"); if (el.style.display == "none") el.style.display = ""; else el.style.display = "none"; microAjax("https://www.lexaloffle.com/bbs/gfxc/58188_15.txt", function (retdata){ var el = document.getElementById("gfxcode_58188_15"); el.innerHTML = retdata; el.focus(); el.select(); } ); '> [64x8]</a> </td></tr> <tr><td colspan=2> <textarea rows=3 class=lexinput id="gfxcode_58188_15" style="width:640px;background-color:#fed;display:none;overflow:hidden; font-size:6pt;"></textarea> </td> </tr> </table> <br /> Every 1000,2000,4000,... points you get a extra live. </p> <h1>Behind The Scenes</h1> <p>I watched <a href="https://www.youtube.com/watch?v=S4RHbnBkyh0">URL Game Maker's Toolkit</a> and was amazed, how &quot;complex&quot; the ai of the ghost are. Since Pic-Man was my first PICO8-Project I decide to re-program Pac-Man. And so many problem started.<br /> First problem, the maze, with a 8x8 tile size it is simple to big for the 128x128 screen. 6x6 would fit, but the map-system is not flexible enough. And so I remembered, that on the old classic c64 you often used the print-command. And again a new problem, how to design the font and how to store it? So hours later a created a <a href="https://www.lexaloffle.com/bbs/?tid=44775">URL CharSet Editor</a> and this problem was solved. So the maze is on the screen, now place the pills. First I tried to place the pill exact like the original, but it doesn't work, since my maze is compacter. So i placed more pills and between the &quot;tiles&quot;. First I used sprites to draw the pills-dot, in other systems it is nearly always better to use a sprite/texture instead of drawing direct. Big mistake, it will consume around 90% of the virtual cpu - so I changed it to pset()-commands and now I only consume around 50%.<br /> Next step: The main character. Not difficult, he simple runs in tiles and can only change the direction on every tile. The first version couldn't go backwards, but because in the first levels Pic-Man is faster then the Ghost, I changed this. Also the Original could do this. To draw Pic-Man I used 4 sprites, since I only draw a quarter of Pic-Man and use the flip options of the spr-command.<br /> I wanted as less sprites as possible.<br /> The ghost AI was also many try and errors. My ghost react a little different from the original, they have similar behave, but the ghost go more randomized. Also one Ghost really like the fruits. One Problem was, that it could happen, that two ghosts are run exact the same way and nearly the exact same position. So now when two ghost touch each other and go to the same direction, I forced to change one to choose a different direction at the next possible tile. Same as Pic-Man, the ghost are 4 Sprites. Two for the top, one for the bottom (because of the wave-animation) and the eyes.<br /> So now how to create the title-screen. I don't find that the original looks nice, so I searched for artwork. And the next problem - how can I got a picture to a PICO8-rom? Again hours later a new tool was born: <a href="https://www.lexaloffle.com/bbs/?tid=44789">URL GFXedit</a>. I used only the the shared part of the spritesheet to save the graphic for the title screen. My plan was to use more artwork and replace the shared part. At the end I only add a game over screen, because I run out of space.<br /> So next big problem Music. I'm not a musician and have no idea of music work. I don't like the original wakka-wakka sound of Pac-Man, I like more the Pac-Mania-Music, but how transfer this to PICO8? Midi-files would maybe a solution, but PICO8 can't open it and I have no idea, how the midi-files work. By accident I found MuseScore 3 and the possibility to export to musicxml, a text-based format. So again hours later a wrote a little program to convert the musicxml to pico8 (Sorry unpublished at the moment, because it miss any interface). I'm not really happy with it, but it work.<br /> In the first version I only add one Level, the original one. But since I draw 12 Fruits, I want more than one level. This was first a problem, because I added the pill-position as static data, now I must phrase the level-data to generate the Borders, add the pills, where the fruit appears and where the ghosts and Pic-Man starts. You can edit the mazes in the source-code and more, if you like.<br /> Since the music used much more than 64 sfx-sounds, I placed the sound-date in the sourcecode. I have optimized the data-format (first one was a big hex-string [[0000a0e01002]], second improve the format [[,,a0,e0,10,2]] and the third uses a special-char-format, so it used nearly everywhere only one char per byte. BTW. one song is too long, it has more than 64 sfx. When the first part is finished, I poke new sfx and music-data in the memory and play part 2.<br /> I had planed to add a third song, but he doesn't sound good and I had again a Problem: over 100% compression. Sadly I must delete the first tab of the code - a big comment with the global variables and what they do.<br /> Now the project is complete - It missed the Intermission from the original, but I have no place any more. I also don't have a good idea to add new ones...<br /> And finally I add a volume-control. It live-patch the sfx-data to reduce the volume.</p> <p>Very long text - did someone read it complete?</p> <h1>Credits</h1> <h2>Used Tools</h2> <p><a href="https://www.lexaloffle.com/bbs/?tid=44775">URL CharSet Editor </a><br /> <a href="https://www.lexaloffle.com/bbs/?tid=44789">URL GFXedit</a><br /> MuseScore 3<br /> Corel PaintShop Pro X7</p> <h2>Used resources</h2> <p><a href="https://pacman.fandom.com/wiki/Pac-Man/Gallery">URL Pac-Man Wiki - Pac-Man Gallery</a><br /> <a href="https://shaunlebron.github.io/pacman-mazegen/">URL Pac-Man Maze Generation</a><br /> <a href="https://onlinesequencer.net/1670246">URL Pac-Man by MineWarz</a><br /> <a href="https://onlinesequencer.net/2255638">URL GAME OVER</a><br /> <a href="https://onlinesequencer.net/1876998">URL Pac Man Death by YaketyGrass</a><br /> <a href="http://vgmusic.com/file/4376cd99c5fcfd85137fbfed421ce59a.html#disqus_thread">URL Block Town / Sequenced by: Oedipus / Originally Composed by: Ben Daglish</a><br /> <a href="http://vgmusic.com/file/fcd0e15d0d4624d0c73f6417325dba69.html#disqus_thread">URL Pacman's Park / Sequenced by: Oedipus / Originally Composed by: Ben Daglish</a></p> https://www.lexaloffle.com/bbs/?tid=44840 https://www.lexaloffle.com/bbs/?tid=44840 Thu, 30 Sep 2021 22:02:39 UTC Request: CHR(val1[,val2,val3,...]) <p>It is possible to write a string (for example for a hiscore-table) to the memory with:</p> <div> <div class=scrollable_with_touch style="width:100%; 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>poke(0x5e00,ord(&quot;hallo&quot;,1,5))</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>but this:</p> <div> <div class=scrollable_with_touch style="width:100%; 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>? chr(peek(0x5e00,5))</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>doesn't work, because chr only accept one value.</p> https://www.lexaloffle.com/bbs/?tid=44820 https://www.lexaloffle.com/bbs/?tid=44820 Wed, 29 Sep 2021 17:11:38 UTC GFXedit - editor for sprites, maps, label <h1>GFXedit for Pico8</h1> <img style="margin-bottom:16px" border=0 src="/media/58188/GFXedit.jpg" alt="" /> <h2>Short</h2> <p>GFXedit is a small tool to handle the sprite, map und label data from a p8-file with many features, like export and import as png or lua-data, copy&amp;paste, display the usage of sprite and many more.</p> <h2>Download</h2> <p><a href="https://github.com/GPIforGit/GFXedit/releases/">github.com - GFXedit</a></p> <h2>Sprite-Overview (left side)</h2> <p>You can simple select an sprite with a left click. If you hold down the mouse button, you can select a group of sprites.<br /> With a right click you can Copy the current selected sprite to the &quot;red border&quot; place. When you have selected only one sprite, shift + right click will replace every appearance in the map.<br /> Over/Under the Sprite overviews are Tabs. &quot;Low&quot; to show the sprites &lt;= 127, &quot;High&quot; for sprites &gt;=128 and &quot;Minimap&quot; to activate the minimap.<br /> Under the Sprite-overview you can find the coordinates in the world (if the cursor is in the Worldmap, the ID of the sprite under the cursor and the flags of the ID under the cursor. You can also sets flags of the current selected sprite here.<br /> Below that you find some views:</p> <p>&quot;Flags&quot; activate a small bar under every sprite with small indicators which flag is activ.</p> <p>&quot;ID&quot; show the HEX-Id over every Sprite</p> <p>&quot;Count&quot; show of often a sprite is used.</p> <p>&quot;Grid&quot; activate a small grid</p> <h2>Editor-Overview (right side)</h2> <p>You can select between &quot;Map&quot; - the world editor, &quot;Sprite&quot; - the sprite editor and &quot;Label&quot; a label-viewer of the p8-file. Map and Sprite can be edit, labels only displayed (but in- and exported).<br /> With left click you draw in the map/sprite, with right-click you select a current object under the cursor. You can select multiply objects with the rubber band to copy complete structures. You can even select multiply objects in the map and switch to the sprite-mode to edit this object.<br /> Under the editor field you find some options:</p> <p>&quot;Stamp&quot; - simple draw in the map / sprite </p> <p>&quot;Line&quot; - draw a line</p> <p>&quot;Box&quot; - draw a box</p> <p>&quot;Ellipse&quot; - draw a ellipse</p> <p>&quot;Fill&quot; - fill (on map it is clipped by the current visible screen)</p> <p>&quot;Filled Box&quot; - a filled box</p> <p>&quot;Smart Box&quot; - a variant of box, when you select an 3x3 pattern in the sprite sheet, it will then draw a box in the editor, it will more &quot;stretch&quot; the selection to the draw box.<br /> For Example, when you right-select something like this:<br /> <table><tr><td width=64> <img src="https://www.lexaloffle.com/bbs/gfxc/58188_13.png" width=64 height=64> </td> <td valign=bottom> <a style="cursor:pointer;font-size:8pt" onclick=' var el = document.getElementById("gfxcode_58188_13"); if (el.style.display == "none") el.style.display = ""; else el.style.display = "none"; microAjax("https://www.lexaloffle.com/bbs/gfxc/58188_13.txt", function (retdata){ var el = document.getElementById("gfxcode_58188_13"); el.innerHTML = retdata; el.focus(); el.select(); } ); '> [16x16]</a> </td></tr> <tr><td colspan=2> <textarea rows=3 class=lexinput id="gfxcode_58188_13" style="width:640px;background-color:#fed;display:none;overflow:hidden; font-size:6pt;"></textarea> </td> </tr> </table> <br /> And draw a Box, it will look like this:<br /> <table><tr><td width=64> <img src="https://www.lexaloffle.com/bbs/gfxc/58188_14.png" width=64 height=64> </td> <td valign=bottom> <a style="cursor:pointer;font-size:8pt" onclick=' var el = document.getElementById("gfxcode_58188_14"); if (el.style.display == "none") el.style.display = ""; else el.style.display = "none"; microAjax("https://www.lexaloffle.com/bbs/gfxc/58188_14.txt", function (retdata){ var el = document.getElementById("gfxcode_58188_14"); el.innerHTML = retdata; el.focus(); el.select(); } ); '> [16x16]</a> </td></tr> <tr><td colspan=2> <textarea rows=3 class=lexinput id="gfxcode_58188_14" style="width:640px;background-color:#fed;display:none;overflow:hidden; font-size:6pt;"></textarea> </td> </tr> </table> </p> <p>&quot;Filled Ellipse&quot; - a filled ellipse</p> <p>&quot;ID&quot; - display the id over every tile in the editor.</p> <p>&quot;Grid&quot; - display a grid over the editor</p> <p>&quot;Copy 00&quot; - when active (default) sprite-id 00 and color 0 is draw with stamp/box. Otherwise it will be ignored / transparent.</p> <p>&quot;Find Sel.&quot; - the current objects blinks now in the editor and minimap.</p> <p>&quot;Hi as Hex&quot; - A special and experimental mode. Since &quot;Sprite High&quot; and &quot;Map High&quot; use the same memory, many prefer the map data. Now the high bit is completed unused in the map data. The idea here is, that you can use the useless High-Sprites as indicators in the world. For example place a sign the world (from the lower sprites), activate the &quot;Hi as Hex&quot;-mode, now select a high-sprite (for example &quot;80&quot;) and place it over the sign in the map. The sign-ID is now copied to the Sprite-flag of &quot;80&quot; and the editor shows a sign with an 80 over it.<br /> Of course PICO8 can't handle this, you must write a code that scan the map-data for sprites over 128, store the places in a table and replace the map-data with the sprite-flag of the high-byte-sprite.</p> <p>&quot;Colorfield&quot; - in map mode you can select a background color, in sprite mode the current color.</p> <p>&quot;1&quot; to &quot;10&quot; - a zoom level.</p> <p>&quot;Load Cart&quot; - load data from an p8-file. Only graphics, sound and lua data are ignored. </p> <p>&quot;Merge Cart&quot; - select an p8-file and it will replace the graphic-data in this file.</p> <h2>Export</h2> <p>You have here multiply options to export any kind of data.<br /> You can export as image:</p> <p>&quot;Sprite complete&quot; - export the complete sprite-sheet (128x128 pixels)</p> <p>&quot;Sprites low&quot; - export the sprites 0-127 (128x64 pixels)</p> <p>&quot;Sprites high&quot; - export the sprites 128-255 in the shared memory (128x64 pixels)</p> <p>&quot;Map complete&quot; - export the complete world map (1024x512 pixels)</p> <p>&quot;Map low&quot; - export the &quot;upper&quot; part of the map (1024x256 pixels)</p> <p>&quot;Map high&quot; - export the &quot;lower&quot; part of the map in shared memory (1024x256 pixels)</p> <p>&quot;Label&quot; - export the label used for cartridge-export of pico8</p> <p>&quot;Map screen&quot; - the middle 16x16 tile big screen in the map-editor as image (128x128 pixels)</p> <p>&quot;Sprite selection&quot; - the current selected sprite (vary in size)</p> <p>You can also export as lua-data. You can then copy this data in the pico8 code editor and switch dynamical between diffrent sprite oder mapdata. You can also use this to exchange maps between p8-files.</p> <p>&quot;complete&quot; - contains all map, sprite and spriteflags.</p> <p>&quot;sprites complete&quot; - contains low and high sprites</p> <p>&quot;sprites low &quot; - contains sprites with id &lt;= 127</p> <p>&quot;Map low &quot; - the upper part of the map</p> <p>&quot;Shared&quot; - the shared part the sprite/map data</p> <p>&quot;Sprites-flags&quot; - the flag data of the spritesheet</p> <p>&quot;label&quot; - the cart-label - it use address 0x6000 (Screen data), when you want for example a title-screen.</p> <p>To load the data you need some additional code:</p> <div> <div class=scrollable_with_touch style="width:100%; 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 str2mem(data) local t,a,i,c,d,str,m = split(data) for a = 1,#t,2 do m,str,i=t[a],t[a+1],1 while i &lt;= #str do c,d= ord(str,i,2) i+=c==255 and 2 or 1 if (c&gt;16) poke(m, c==255 and d or c^^0x80) m+=1 end end end data = [[ --some funny chars from the export ]] str2mem(data)</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <h2>Import</h2> <p>Almost the same as the export. You can import any image. Colours are automatic translated to the pico8 colour palette. When a image is too big, it can be cropped or resized.<br /> Something special is &quot;Map screen (center)&quot; for images. It will split the image in 8x8 tiles and try to find this tiles in the Sprite sheet. If it not exist, it will replace the first free tile (complete black ones) with this tile.<br /> When you import text/lua, the exported destination is ignored. You can for example import a label as sprite sheet.</p> <h2>Keyboard</h2> <p>Mouse wheel - change selection of sprite (map) or color (sprite)</p> <p>ctrl + wheel - change zoom</p> <p>0-8/ shift + 0-8 - change current/background color</p> <p>Num0 - Num9 - change zoom level</p> <p>Cursor keys / asdw - change selected sprite (map) or color ( sprite)</p> <p>shift + cursor keys / asdw - move world map</p> <p>ctrl + cursor keys / asdw - move world map screen wide</p> <p>ctrl + z - undo</p> <p>ctrl + y - redo</p> <p>ctrl + c - copy/export menu</p> <p>ctrl + v - pate/import menu</p> <p>ctrl + o - open</p> <p>ctrl + s - merge/save</p> <p>alt + cursor - Sprite-editor: shift sprite</p> <p>alt+shift + cursor - Sprite-editor: flip sprite</p> <p>R - Sprite-editor: rotate sprite</p> <h2>About the string format</h2> <p>Graphic data are too big for a string in &quot;&quot;, but enclose it with [[]] has the disadvantage that escape-sequenzes are not possible. Also chars lower 16 are not printable.<br /> Chars lower than code 16 must be encode in a special form. Also some special characters like &quot;[],&quot; must be encoded to prevent conflicts.<br /> Because chars lower than code 16 are very common (especially code zero), I first flip the high-bit of the char (m = char ^^ 0x80). If m is now lower 16 or one of the special characters, I store the in the string a sequenz of &quot;chr(0xff)..chr(m ^^ 0x80)&quot; otherwise a simple &quot;chr(m)&quot;.</p> <h2>Infos</h2> <p>Icon made by <a href="https://www.freepik.com">https://www.freepik.com</a> from <a href="https://www.flaticon.com/">https://www.flaticon.com/</a></p> https://www.lexaloffle.com/bbs/?tid=44789 https://www.lexaloffle.com/bbs/?tid=44789 Mon, 27 Sep 2021 19:19:23 UTC Charset Editor for Pico8 <h1>CharSet Editor for Pico 8</h1> <img style="margin-bottom:16px" border=0 src="/media/58188/charseteditor.jpg" alt="" /> <h2>Download</h2> <p><a href="https://github.com/GPIforGit/CharsetEditor_Pico8/releases/">github.com - CharsetEditor_Pico8</a></p> <h2>Short manual</h2> <p>A simple tool to create fonts for the virtual console pico8.</p> <p>Left click on the charset to edit this char. Right click will copy the current char to this position.</p> <p>Left click on the char will set a dot, right click will delete it. With the cursor keys you can shift the current char. &quot;Set Default&quot; will reset the current charater to the default.</p> <p>&quot;Lo Width&quot; are for chars with a code &lt;= 127, &quot;Hi Width&quot; for code &gt;=128.</p> <p>With &quot;Copy&quot; and &quot;Paste&quot; you can copy the complete Charset to the clipboard as a string embeded in [[ ]]. Don't indent the string, it could change the font! In pico 8 you need the following code to transfer the string to the memory:</p> <div> <div class=scrollable_with_touch style="width:100%; 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 str2mem(data) local t,a,i,c,d,str,m = split(data) for a = 1,#t,2 do m,str,i=t[a],t[a+1],1 while i &lt;= #str do c,d= ord(str,i,2) i+=c==255 and 2 or 1 if (c&gt;16) poke(m, c==255 and d or c^^0x80) m+=1 end end end myfont = [[0x5600, --some funny chars ]] str2mem(myfont)</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 &quot;Load&quot; and &quot;Save&quot; you can load/save the current font as ascii-file with the extension &quot;.lua&quot;. It is the same format as the clipboard routines.</p> <h2>About the string format</h2> <p>A Font is too big for a string in &quot;&quot;, but enclose it with [[]] has the disadvantage that escape-sequenzes are not possible. Also chars lower 16 are not printable.</p> <p>Chars lower than code 16 must be encode in a special form. Also some special characters like &quot;[],&quot; must be encoded to prevent conflicts.</p> <p>Because chars lower than code 16 are very common (especially code zero), I first flip the high-bit of the char (m = char ^^ 0x80). If m is now lower 16 or one of the special characters, I store the in the string a sequenz of &quot;chr(0xff)..chr(m ^^ 0x80)&quot; otherwise a simple &quot;chr(m)&quot;.</p> <h2>Example code</h2> <div> <div class=scrollable_with_touch style="width:100%; 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>load #customfont_example-0</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=97849#p"> <img src="/bbs/thumbs/pico8_customfont_example-0.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=97849#p"> customfont_example</a><br><br> by <a href="/bbs/?uid=58188"> GPI</a> <br><br><br> <a href="/bbs/?pid=97849#p"> [Click to Play]</a> </td></tr></table> </p> https://www.lexaloffle.com/bbs/?tid=44775 https://www.lexaloffle.com/bbs/?tid=44775 Sun, 26 Sep 2021 11:12:29 UTC Linking nativ window tools <p>I had written a small tool for pico8, but it is written in pure basic and the resulting program is a nativ windows application. </p> <p>Is it allowed to present this tool here with a link to a github-page, including the source code, the binary and how to use it with pico8?</p> https://www.lexaloffle.com/bbs/?tid=44771 https://www.lexaloffle.com/bbs/?tid=44771 Sun, 26 Sep 2021 08:54:31 UTC