Log In  

Is there a way to get a the numeric value of a character?
Something like the lua function string.byte():

string.byte("a") --returns 95


P#18329 2016-01-16 12:05 ( Edited 2016-01-22 02:49)

Sadly there's no equivalent to string.byte/string.char in pico8 at the moment, but the methods described here work pretty well: https://www.lexaloffle.com/bbs/?tid=2420

Essentially, you can work around the problem by having a table that maps single-character strings onto numbers, and for the reverse, a number-to-string table. As noted by YellowAfterLife's method, it works best if you can get away with a contiguous table, because then you can use a numeric for loop and sub() to iterate over a character list rather than building a table by-hand.

If you only need this for printing a custom font, you can get away with a character-to-number table where the numbers are the sprite indexes of the respective characters, and consider only listing the characters that are in your font.

Oh and if you're using strings to store large binary data tables there are other methods to accomplish this

P#18375 2016-01-20 13:15 ( Edited 2016-01-23 21:41)

My idea was to store more maps, in a string table, so each char from the string would be a sprite index, for every map row.
Could you please point me to other methods to store binary data tables?
Thanks for the help!

P#18379 2016-01-21 00:16 ( Edited 2016-01-21 05:16)

Ahh, in my projects, I use the following function to decode hexadecimal strings into tables of numbers.

-- Convert a hexadecimal string into a table of numbers.
-- Arguments:
-- s = the hexadecimal string to decode
-- n = the size (in number of digits) of each item stored in the string
-- (eg. 2 digits gives 00..FF = 1 unsigned byte,
-- 4 digits = 0000..FFFF = 16-bit unsigned integer, etc)
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)
 return t

It takes advantage of Lua's implicit conversion to/from string with .. and + to get a cheap hexadecimal parsing function.

You'd use it like this:

-- unsigned byte table, each entry is 2 characters (00 .. FF, the default).
data = unhex '1010046B0000086B0A00486B000A886B0A0AC8'

-- color-lookup table, each entry is 1 character (0..F).
rainbow = unhex('054d126793bce8af', 1)

-- unsigned 16-bit integers, each entry is 4 characters (0000 .. FFFF)
blob = unhex('0808006800000A1010004200000A4308', 4)

To encode stuff as hex, you need to either write the hex values out by hand, or use an external script of some kind that builds a hex string for you (Python has binascii.hexlify(bytearray) or '{0:2x}'.format(num), Lua has string.format('%02x', num), etc) and copy the results into your pico8 program.

Used enough, this will save a lot on tokens and source code size, but it hurts readability, so I recommend only doing it for stuff where the payoff is large and particularly if it's data you don't need to maintain often. (or data you automatically generate with an external script). But yeah for a map, this definitely makes sense.

Hope that gives some ideas!

Also watch out for the 15360 byte compressed code limit. it's much smaller than the promised 64K characters for source code, so if you use your code for large strings of data rather than executable code, you will definitely approach the compressed limit faster. (also, I wondered, is code actually compressed, or this just essentially the result of compiling the source into bytecode like string.dump/luac in standard Lua?)

P#18380 2016-01-21 01:25 ( Edited 2016-01-22 07:49)

Thanks for the help! That was very useful.

P#18389 2016-01-21 21:49 ( Edited 2016-01-22 02:49)

[Please log in to post a comment]