Log In  

Hey, just thought I'd post this code in case anyone else finds it useful.

If you need a few extra sfx slots in your pico8 cart and can spare the code, here's a little thing that will load a sound into RAM. It takes a table of 168 4-bit values in the .p8 sfx format, and writes out a 68-byte sfx block into one of the sfx slots in memory.

It's a complete test program, tweak, adjust and reuse to your liking.

-- unpack a hex string into a
-- table of numbers.
function unhex(s,n)
 n = n or 2
 local t = {}
 for i = 1, #s, n do
  add(t, ('0x' ..
   sub(s, i, i+n-1)) + 0)
 end
 return t
end

-- unpack a data string
-- including two sounds
-- taken out of a p8 file.
sfxdata = unhex(
   '010800003c6751f473234731347'
.. '3006253c615006253c6050c6150'
.. '00000c615000000000000000000'
.. '000000000000000000000000000'
.. '000000000000000000000000000'
.. '000000000000000000000000000'
.. '000000010300003c63515073182'
.. '701f271232711c2711827113271'
.. '0e2710021124300243002430024'
.. '300243002430024300243002430'
.. '024300243002430024300243002'
.. '430024300243002430024300243'
.. '002430024300', 1)

-- load a new sound into sfx
-- memory at runtime.
--
-- arguments:
-- d = dest sfx slot 0 .. 63
-- s = source sfx number in
--     sfxdata table, 0-based
--     index. each sound is 168
--     values of the table.
-- note: sfxdata must exist as
--       a global or upvalue.
function loadsfx(d, s)
 local t = sfxdata
 d = 0x3200 + 68 * d
 s *= 168
 for i = 0, 3 do
  poke(d + 64 + i, t[s + i * 2 + 1] * 16 + t[s + i * 2 + 2])
 end
 for i = 0, 31 do
  local a = d + i * 2
  local b = s + i * 5 + 9
  poke(a, (t[b] * 16 + t[b + 1]) % 64 + t[b + 2] * 64)
  poke(a + 1, band(t[b + 2], 4) / 4 + t[b + 3] % 8 * 2 + t[b + 4] * 16)
 end
end

-- load sound 0 from sfxdata
-- into the sfx ram at slot #2.
loadsfx(2, 0)
-- play sfx slot 2.
sfx(2)

-- loop forever so we get
-- to hear the sound play.
while true do flip() end

(also thanks to dansanderson, these notes were handy!)

To use your own sounds in this code, change the string in the sfxdata = unhex('...', 1) line with new sfx taken out of a sfx section of a p8 cartridge file. You can open a .p8 file from your carts folder in any text editor, such as notepad, and each line under the sfx section is one sound that you can copy and paste. To specify multiple sounds simply paste them back-to-back in the string, and then use loadsfx() with a different source index to address the various sounds.

Someone should do something to load song data also, and then you could do stuff to load extra songs from code, or generate procedural music!

(note: some of the formatting was to get the BBS to display things correctly with long lines of code, ideally you'd have have one big line with the sfx data all mashed together to save characters and tokens, and to make it easier to copy-and-paste the hex from another p8's sfx data)

P#18828 2016-02-14 02:45 ( Edited 2016-02-14 19:52)

thank you! exactly what I've been looking for. I think it's gonna be a lifesaver for me. I want just a liiiitle extra space for my sound effects and music in the game I'm working on, and I think this is going to be worth the tokens.

I also recently learned about strings in [[brackets]] instead of 'quotation marks' and for some reason they allow for longer strings too. I tested that with this code and managed to save quite a few tokens.

For example,

sfxdata = unhex(
   '010800003c6751f473234731347'
.. '3006253c615006253c6050c6150'
.. '00000c615000000000000000000'
.. '000000000000000000000000000'
.. '000000000000000000000000000'
.. '000000000000000000000000000'
.. '000000010300003c63515073182'
.. '701f271232711c2711827113271'
.. '0e2710021124300243002430024'
.. '300243002430024300243002430'
.. '024300243002430024300243002'
.. '430024300243002430024300243'
.. '002430024300', 1)

...is 30 tokens, but it's reduced to six (!) tokens with this:

sfxdata = unhex(
 [[010800003c6751f4732347313473006253c615006253c6050c615000000c615000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010300003c63515073182701f271232711c27118271132710e2710021124300243002430024300243002430024300243002430024300243002430024300243002430024300243002430024300243002430024300]], 1)

I don't know what the upper limit to strings in brackets is, but you can fit a lot more sound per token this way. that said, I'm dealing with powers I don't understand yet though--I haven't tested anything with this as far as memory or CPU usage. so far so good though.

thanks again for putting this together and making it easy to understand!

P#142804 2024-03-12 14:00

[Please log in to post a comment]

Follow Lexaloffle:          
Generated 2024-03-28 21:32:20 | 0.006s | Q:8