Log In  

Cart #djclem_helimenu-8 | 2022-08-10 | Code ▽ | Embed ▽ | No License

Things you may find interesting about this cart set:

Sound Effects

The helicopter rotor sound consists of these four notes:

They play in a loop, and as helicopter throttle and rotor "pitch" change, poke commands are used to alter the speed and tone of the notes:

 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

  if sfxo==0 or sfxo==2 then
    -- i only want to change the 
    -- volume of the two noise
    -- notes only if the "silent"
    -- notes are being played.
    -- otherwise it sounds glitchy

  if chgit and peek(0x34a9)!=rotorslap then
    -- these poke addresses are
    -- presently hard-coded to
    -- work on sfx(10)

  if peek(0x34e9)!=rotorspd then
    if sfxo==0 then
      -- 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)


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 simple demo along with the .P8 source code.

Anyway, the two carts call each other back-and-forth, and communicate using CARTDATA. 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. Memory Map

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:

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:

Image Compression

I use the PX9 Data Compression Utility 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:

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.

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

The compressed image data uses 5,127 bytes. Therefore the compressed image data is contained in the memory region 0x2000-0x3407

P#115671 2022-08-12 23:21

Pretty cool! It took me a bit to get used to the flying/landing/etc but once I got the hang of it things were pretty intuitive.

The game locked up on me when I chose "Exit" from the menu. Buttons/arrow keys all stopped responding and the Pause menu wouldn't load. This was in the browser, didn't try it in my local PICO-8.

P#115672 2022-08-12 23:39

Yes, running the game locally, selecting "EXIT" will quit the program and return to the Pico-8 prompt. I knew that in the browser it just stops. I didn't realize it took out the pause menu - interesting!

P#115674 2022-08-12 23:47

The menus (with the computer screen and such) reminded me of The Lost World: Jurassic Park on the Sega Genesis. Pretty cool game!

P#115690 2022-08-13 03:06

Nice game, @djclemmer. Sort of Choplifter but with real starting missions you can sink your teeth into. Well done, gold star work !

P#115691 2022-08-13 03:43

This is a great title, and the multi-cart-approach you used seems to suit it well. It really feels like a fully fletched game!
I like that you still stuck with pico8 controls and didnt opt to use the mouse.

P#115693 2022-08-13 06:08

This was awesome. So many things were great about it, and that last mission was tough! It was so hard to land at that group farthest to the right, I really felt accomplished when I finally did it. The only thing it was lacking was music. Amazing work!

P#115735 2022-08-14 04:47

[Please log in to post a comment]