djclemmer [Lexaloffle Blog Feed]https://www.lexaloffle.com/bbs/?uid=42224 Escape from Machu-Pico <img style="margin-bottom:16px" border=0 src="/media/42224/helimenu_2.png" alt="" /> <p> <table><tr><td> <a href="/bbs/?pid=115670#p"> <img src="/bbs/thumbs/pico8_djclem_helimenu-8.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=115670#p"> djclem_helimenu</a><br><br> by <a href="/bbs/?uid=42224"> djclemmer</a> <br><br><br> <a href="/bbs/?pid=115670#p"> [Click to Play]</a> </td></tr></table> </p> <p>Things you may find interesting about this cart set:</p> <h2>Sound Effects</h2> <p>The helicopter rotor sound consists of these four notes:</p> <img style="margin-bottom:16px" border=0 src="/media/42224/sound.png" alt="" /> <p>They play in a loop, and as helicopter throttle and rotor &quot;pitch&quot; change, poke commands are used to alter the speed and tone of the notes:</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> if heli_sound==10 then -- SFX 10 is the continuous rotor sound -- deltax is used to determine how much -- rotor 'slap' to add local deltax=heli_xspdtgt-heli.xspd -- rotor slap changes the volume -- of the two notes (noise) -- the more tilt the heli has, -- the more pronounced the 'slap' is local rotorslap=({[0]=0x53,0x53,0x55,0x57,0x59})[abs(heli.tilt)] -- if the helicopter is trying to reverse, -- then make the rotor slap the most pronounced if sgn(heli_xspdtgt) != sgn(heli.xspd) then rotorslap=0x5b end sfxo=stat(50) if sfxo==0 or sfxo==2 then chgit=true -- i only want to change the -- volume of the two noise -- notes only if the &quot;silent&quot; -- notes are being played. -- otherwise it sounds glitchy end if chgit and peek(0x34a9)!=rotorslap then poke(0x34a9,rotorslap) poke(0x34ad,rotorslap) -- these poke addresses are -- presently hard-coded to -- work on sfx(10) end if peek(0x34e9)!=rotorspd then sfxo=stat(50) if sfxo==0 then poke(0x34e9,flr(rotorspd)) -- this changes the playback -- speed of the sfx on ch 0 -- only change the speed at -- first note, to help reduce -- glitchy sounds -- this poke address is -- presently hard-coded to -- work on sfx(10) end 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> <h2>Multi-Cart</h2> <p>This game makes use of two carts: A menu cart, and the gameplay cart. If you aren't familiar with cart-chaining, here is a <a href="https://djclemmer.itch.io/cart-chain-demo">simple demo</a> along with the .P8 source code.</p> <p>Anyway, the two carts call each other back-and-forth, and communicate using <a href="https://pico-8.fandom.com/wiki/Cartdata">CARTDATA</a>. The Cartdata is located at memory location 0x5E00 - 0x5EFF. Note that you may access this memory area using PEEK and POKE, in addition to DGET and DSET, respectively. I use a mix of both methods... I use DGET/DSET to store about 10 numbers (using indices 0-9), and then I also store byte-data, justified at the top of the Cartdata memory region, starting at the highest location of 0x5EFF and works downwards. <a href="https://pico-8.fandom.com/wiki/Memory">Memory Map</a></p> <p>Another thing the menu cart does is draw two graphic assets, and passes them via memory to the gameplay cart. Below is an example of the dashboard when you crash:</p> <img style="margin-bottom:16px" border=0 src="/media/42224/dash.png" alt="" /> <p>This was generated using code, but the token count was a little high, and I was looking to remove tokens from the gameplay cart. So I moved the code to draw this broken dashboard into the menu cart. When the menu cart starts, it draws the broken dashboard (but does not FLIP(), so you don't see this part), then copies it to memory location 0x8000. When the menu cart launches the gameplay cart, a formally-undocumented but known feature is that this region of memory stays intact when loading other cartridges. So the gameplay cart now has this graphic asset located at the same 0x8000 memory location. To draw this broken dash during gameplay I just perform a memory copy:<br /> <code>memcpy(30976,0x8000,1792)</code>. </p> <h2>Image Compression</h2> <p>I use the <a href="https://www.lexaloffle.com/bbs/?tid=34058">PX9 Data Compression Utility</a> to store more graphic assets than would normally fit into a Pico-8 cartridge. The menu cart has the largest image storage requirements, so the discussion below refers to the menu cart:</p> <p>I have about 4 carts worth of sprite/image data used in the menu cartridge. I wrote a utility cart that contains the PX9 compression routine, and one-by-one, RELOADs the spritesheet from each of these carts, compresses the individual images in turn, and stores them in memory starting at 0x2000 (the non-shared map region - see memory layout below). The compressed images take up more space than is available in the map area, and it actually spills over into the Sprite Flags, Music and into the Sound effects memory regions. I do not use any Sprite Flags, and do not have any Music scores, so giving up these locations for compressed image storage is a good tradeoff. I do use sound effects, so what I did is moved all my sound effects to the top of the SFX memory area [SFX(63)] and worked downwards in memory. My sound effects use locations 52-63. The compressed data goes up to about SFX slot #8, so there is room for me to add more SFX or more compressed images, and still have room.</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>Start End Purpose 0x0 0x0fff Sprite sheet (0-127)* 0x1000 0x1fff Sprite sheet (128-255)* / Map (rows 32-63) (shared) 0x2000 0x2fff Map (rows 0-31) 0x3000 0x30ff Sprite flags 0x3100 0x31ff Music 0x3200 0x42ff Sound effects</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 compressed image data uses 5,127 bytes. Therefore the compressed image data is contained in the memory region 0x2000-0x3407</p> https://www.lexaloffle.com/bbs/?tid=48881 https://www.lexaloffle.com/bbs/?tid=48881 Fri, 12 Aug 2022 23:21:21 UTC Escape from Machu-Pico <img style="margin-bottom:16px" border=0 src="/media/42224/helimenu_2.png" alt="" /> <p> <table><tr><td> <a href="/bbs/?pid=115670#p"> <img src="/bbs/thumbs/pico8_djclem_helimenu-8.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=115670#p"> djclem_helimenu</a><br><br> by <a href="/bbs/?uid=42224"> djclemmer</a> <br><br><br> <a href="/bbs/?pid=115670#p"> [Click to Play]</a> </td></tr></table> </p> <p>Things you may find interesting about this cart set:</p> <h2>Sound Effects</h2> <p>The helicopter rotor sound consists of these four notes:</p> <img style="margin-bottom:16px" border=0 src="/media/42224/sound.png" alt="" /> <p>They play in a loop, and as helicopter throttle and rotor &quot;pitch&quot; change, poke commands are used to alter the speed and tone of the notes:</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> if heli_sound==10 then -- SFX 10 is the continuous rotor sound -- deltax is used to determine how much -- rotor 'slap' to add local deltax=heli_xspdtgt-heli.xspd -- rotor slap changes the volume -- of the two notes (noise) -- the more tilt the heli has, -- the more pronounced the 'slap' is local rotorslap=({[0]=0x53,0x53,0x55,0x57,0x59})[abs(heli.tilt)] -- if the helicopter is trying to reverse, -- then make the rotor slap the most pronounced if sgn(heli_xspdtgt) != sgn(heli.xspd) then rotorslap=0x5b end sfxo=stat(50) if sfxo==0 or sfxo==2 then chgit=true -- i only want to change the -- volume of the two noise -- notes only if the &quot;silent&quot; -- notes are being played. -- otherwise it sounds glitchy end if chgit and peek(0x34a9)!=rotorslap then poke(0x34a9,rotorslap) poke(0x34ad,rotorslap) -- these poke addresses are -- presently hard-coded to -- work on sfx(10) end if peek(0x34e9)!=rotorspd then sfxo=stat(50) if sfxo==0 then poke(0x34e9,flr(rotorspd)) -- this changes the playback -- speed of the sfx on ch 0 -- only change the speed at -- first note, to help reduce -- glitchy sounds -- this poke address is -- presently hard-coded to -- work on sfx(10) end 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> <h2>Multi-Cart</h2> <p>This game makes use of two carts: A menu cart, and the gameplay cart. If you aren't familiar with cart-chaining, here is a <a href="https://djclemmer.itch.io/cart-chain-demo">simple demo</a> along with the .P8 source code.</p> <p>Anyway, the two carts call each other back-and-forth, and communicate using <a href="https://pico-8.fandom.com/wiki/Cartdata">CARTDATA</a>. The Cartdata is located at memory location 0x5E00 - 0x5EFF. Note that you may access this memory area using PEEK and POKE, in addition to DGET and DSET, respectively. I use a mix of both methods... I use DGET/DSET to store about 10 numbers (using indices 0-9), and then I also store byte-data, justified at the top of the Cartdata memory region, starting at the highest location of 0x5EFF and works downwards. <a href="https://pico-8.fandom.com/wiki/Memory">Memory Map</a></p> <p>Another thing the menu cart does is draw two graphic assets, and passes them via memory to the gameplay cart. Below is an example of the dashboard when you crash:</p> <img style="margin-bottom:16px" border=0 src="/media/42224/dash.png" alt="" /> <p>This was generated using code, but the token count was a little high, and I was looking to remove tokens from the gameplay cart. So I moved the code to draw this broken dashboard into the menu cart. When the menu cart starts, it draws the broken dashboard (but does not FLIP(), so you don't see this part), then copies it to memory location 0x8000. When the menu cart launches the gameplay cart, a formally-undocumented but known feature is that this region of memory stays intact when loading other cartridges. So the gameplay cart now has this graphic asset located at the same 0x8000 memory location. To draw this broken dash during gameplay I just perform a memory copy:<br /> <code>memcpy(30976,0x8000,1792)</code>. </p> <h2>Image Compression</h2> <p>I use the <a href="https://www.lexaloffle.com/bbs/?tid=34058">PX9 Data Compression Utility</a> to store more graphic assets than would normally fit into a Pico-8 cartridge. The menu cart has the largest image storage requirements, so the discussion below refers to the menu cart:</p> <p>I have about 4 carts worth of sprite/image data used in the menu cartridge. I wrote a utility cart that contains the PX9 compression routine, and one-by-one, RELOADs the spritesheet from each of these carts, compresses the individual images in turn, and stores them in memory starting at 0x2000 (the non-shared map region - see memory layout below). The compressed images take up more space than is available in the map area, and it actually spills over into the Sprite Flags, Music and into the Sound effects memory regions. I do not use any Sprite Flags, and do not have any Music scores, so giving up these locations for compressed image storage is a good tradeoff. I do use sound effects, so what I did is moved all my sound effects to the top of the SFX memory area [SFX(63)] and worked downwards in memory. My sound effects use locations 52-63. The compressed data goes up to about SFX slot #8, so there is room for me to add more SFX or more compressed images, and still have room.</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>Start End Purpose 0x0 0x0fff Sprite sheet (0-127)* 0x1000 0x1fff Sprite sheet (128-255)* / Map (rows 32-63) (shared) 0x2000 0x2fff Map (rows 0-31) 0x3000 0x30ff Sprite flags 0x3100 0x31ff Music 0x3200 0x42ff Sound effects</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 compressed image data uses 5,127 bytes. Therefore the compressed image data is contained in the memory region 0x2000-0x3407</p> https://www.lexaloffle.com/bbs/?tid=48880 https://www.lexaloffle.com/bbs/?tid=48880 Fri, 12 Aug 2022 23:10:08 UTC Memory Test for add/del <p> <table><tr><td> <a href="/bbs/?pid=112478#p"> <img src="/bbs/thumbs/pico8_ldmemtest0001-0.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=112478#p"> ldmemtest0001</a><br><br> by <a href="/bbs/?uid=42224"> djclemmer</a> <br><br><br> <a href="/bbs/?pid=112478#p"> [Click to Play]</a> </td></tr></table> This is the code I mention in a youtube comment on a LazyDevs episode in his Shmup series.</p> https://www.lexaloffle.com/bbs/?tid=47960 https://www.lexaloffle.com/bbs/?tid=47960 Mon, 30 May 2022 14:38:06 UTC