Log In  

(recommended: use with PICO-8 0.2.1b or later)

This function can be used to convert binary strings into a format that can be pasted into source code. Binary strings contain all characters from chr(0)..chr(255) and as such include unprintable / unstorable characters. escape_binary_str() adds the needed escape codes and stores the remaining characters as-is. For example character 10 becomes \n and character 0 becomes \0, or \000 when followed by a number (to avoid ambiguity).

This is useful for storing dense binary data efficently (e.g. compressed with PX9). If you are storing structured data in code (like a raw image), it will likely be easier and almost as efficient to store them as a bunch of hexadecimal characters.

function escape_binary_str(s)
 local out=""
 for i=1,#s do
  local c  = sub(s,i,i)
  local nc = ord(s,i+1)
  local pr = (nc and nc>=48 and nc<=57) and "00" or ""
  local v=c
  if(c=="\"") v="\\\""
  if(c=="\\") v="\\\\"
  if(ord(c)==0) v="\\"..pr.."0"
  if(ord(c)==10) v="\\n"
  if(ord(c)==13) v="\\r"
  out..= v
 end
 return out
end

Workflow

Step 1. Generate a Binary String

binstr=""
for i=1,256 do
 binstr..=chr(i%256) -- any data you like
end

?#binstr         -- 256
?ord(binstr,256) --   0
?ord(binstr, 13) --  13 

Step 2. Escape the String and Copy to Clipboard

printh(escape_binary_str(binstr), "@clip")

Step 3. Paste into Source Code

* Turn on Puny Mode (CTRL-P) // to make sure uppercase characters are encoded as punyfont

CTRL-V into source code as a string value bindat="[paste here]". You should get something like this:

bindat="¹²³⁴⁵⁶⁷⁸    \nᵇᶜ\rᵉᶠ▮■□⁙⁘‖◀▶「」¥•、。゛゜ !\"#$%&'()*+,-./0123456789:;<=>[email protected]𝘢𝘣𝘤𝘥𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹𝘺𝘻[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~○█▒🐱⬇️░✽●♥☉웃⌂⬅️😐♪🅾️◆…➡️★⧗⬆️ˇ∧❎▤▥あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをんっゃゅょアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲンッャュョ◜◝\0"

4. Enjoy your Binary Data

The contents of bindat can now be accessed with ord(bindat, index) (note that index is 1-based).

P#78950 2020-07-05 21:26 ( Edited 2020-10-29 03:56)

:: merwok

Hi zep! (First comment here but not the first time this is discussed on discord :)

Could you confirm that in addition to 'ord', we can also use 'sub' to get more that one byte at once, and use 'poke' to get the data into memory?

P#96159 2021-08-17 21:58

sub returns a string - @merwork: are you expecting that to work:

poke4(0x4300,sub(byte_str,1,4))

??

P#96170 2021-08-18 08:23 ( Edited 2021-08-18 09:29)
:: merwok

No, I would expect sub to return a substring of the initial byte string!

Edit: tested 'sub', works as intended (doesn’t cut any character), so it can be used to split a big encoded string into sub-strings. This makes it possible for example to encode many levels in one string then get one to load it, rather that being forced to define separate strings. We can’t use 'poke' though, so to load binary data we have to call 'ord' in a loop.

P#96178 2021-08-18 13:41 ( Edited 2021-08-18 17:59)
:: merwok
1

0.2.3 changelog:

> Added: ord(str, pos, num) returns num results starting from character at pos (similar to peek)

One call, no loop \o/

P#96965 2021-09-06 18:16

[Please log in to post a comment]

Follow Lexaloffle:        
Generated 2021-09-26 22:43:42 | 0.070s | Q:17