In Lua it's pretty simple -- just the 'not' keyword.
if not btn(n) then --True if btn n is NOT pressed end
So it's taken some time, but after using the brick-wall method (banging my head against it until it works) I've finally managed to get a working save-safe (mostly) efficient storage metod that can store up to 10 characters. 11 or more characters will cause an overflow, so I've taken the liberty of putting a sanity check in for that.
I wanted to stick to my original rules (1-53, 1 is capital 'A', 27 is lowercase 'a' and 53 is space), meaning I needed 6 bits per character; after doing a little tinkering with binary (specifically trying to come up with a way to handle bitflags for saves) I came up with a method that seems to be working, but has some overhead (2-4 bits) caused by endianness that I'm not sure how to fix.
Anyway, here's the code (Size: 710)
nums={3,34,44,41,40,41,45,48,9,9} local fmt=string.format --Size counting starts on next line function combine(tab) local out=0 if #tab > 10 then trace"Error: Input table too big."end for i=1,#tab do if tab[i] then if tab[i]>53 then tab[i]=53 end out=out+tab[i] out=out<<6 end end return out end function bytify(num) local out={} local i=1 while num>0 do out[i]=num & 0xFF num=(num >> 8) // 1 i=i+1 end return out end function rebuild(tab) local out=0 for i=#tab,1,-1 do if tab[i] then out = (out << 8) out = out + (tab[i]&0xFF) end end return out end function retable(num) local out={} local i=0 while num>0 do if num>0 then out[i]=num&0x3F num=(num>>6)//1 end i=i+1 end local n={} for i=1,#out do n[#out-(i-1)]=out[i] end return n end --Size counting stops at end of previous line --Debug Stuff but shows how to use the code trace("Starting name:\n "..table.concat(nums,',')) val1 = combine(nums) trace("Integer out:\n "..fmt("%0X",val1)) val2 = bytify(val1) trace("Bytes out:\n "..table.concat(val2,",")) val3 = rebuild(val2) trace("Integer confirm:\n "..fmt("%0X",val3)) val4 = retable(val3) trace("Confirm:\n "..table.concat(val4,','))
And a little proof that it's working (as best as I can make it work with my current skills):
This works in tandem with some of my above code (specifically this:
ltrs="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz " function str2num(str) local s={} for i=1,#str do s[i]=ltrs:find(str:sub(i,i)) end return s end
to convert the name string into a table. I haven't done the opposite conversion yet, but it wouldn't be that difficult, and you could even forgo the string step altogether if you operated strictly on a table and used a "name()" function or equivalent to convert the table into a string for use in your game.
That certainly would be ideal, but unfortunately I'm not currently familiar or comfortable enough with binary operations to make it so. Even in its original PICO-8 form it could be taken from 128 bits down to the same 40. I know it's a terrible waste of space as it is now but I never pretended I really knew what I was doing with TIC-80 (or PICO-8 for that matter). Maybe one day it'll be that efficient but even if it's a jumping-off point for someone more skilled then it's done its job.
Hello! I've been doing the beginnings of tinkering around with TIC-80 after having used PICO-8 for about a month, and while I was looking through the documentation I realized I had run into quite a problem -- PICO-8 gives you 63 values to store user data to, and TIC-80 only gives you 7. This lead to an interesting problem, because one of the things I've been tinkering around with fantasy consoles for is a mini-RPG, complete with name entry.
In PICO-8 it was simple -- since you could only use capital letters I saved each letter as a number 1 to 26, then reconstructed the name with those values.
With TIC-80, I was scratching my head... until an idea hit me: You get 32-bit integers, which give you 2147483647 possible positive values (if the variables are signed, which I assume they are). And since TIC-80 supports lowercase letters, you can range 1 to 52, 53 if you allow for spaces. I decided to store the letters, grouped together, into integers. Since splitting 2147483647 into groups of 2 digits gives 21 47 48 36 47, I can't use the 21 (or 42 if unsigned) at the start. So I store 2 sets of 4 letters in integers ranging from 0 (nothing) to 53,535,353.
Here's the code to do this if you want to replicate the functionality -- you'll just need to implement these into save/load functions.
678 chars excluding comments.
ltrs="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz " local flr=math.floor --Convert 2 32-bit integers into one 8-character string function num2str(v1,v2) local n={0,0,0,0,0,0,0,0} local v2=v2 or 0 local o="" for i=8,5,-1 do n[i]=v2%100 v2 = flr(v2/100) end for i=4,1,-1 do n[i]=v1%100 v1 = flr(v1/100) end for i=1,8 do local l=n[i] if l>0 then o=o..ltrs:sub(l,l) end end return o end --Take a string (str) up to 8 chars and turn it into 2 integers function str2num(str) if #str>8 then error"String too long for str2num." end local s={} for i=1,#str do s[i]=ltrs:find(str:sub(i,i)) end local o={} local t="" local j=1 for i=1,#s do t=t..s[i] if i==4 then o[j]=flr(t*1) j=j+1 t="" end end if #s>4 then o[j]=flr(t*1) end o[2]=o[2] or 0 return o end
I'm sure there's a more efficient way to do this, but I'm used to the PICO-8 syntax. Also apologies for the variable shortening but that was a concession for the 64kb limit -- even though it would be best to do that after I was finished, for some reason I got into that mindset immediately and that's how I wrote it..
Variable 'o' is always "output", table 'n' are the numbers once split to turn into a string, table 's' is the opposite -- the numbers converted from their positions in the 'ltrs' string.
Hopefully people find this useful!
Edit Log:
There was an error being generated when you passed a 4-character string to str2num.
o[j]=flr(t*1)
became
if #s>4 then o[j]=flr(t*1) end
The above line was intended to write the value of 't' to the first number if the length was 1, 2, 3 or 4 characters and write to the second number in any other case. Thanks to not writing the logic properly 't' was trying to be converted from an empty string to a number and caused an error. This edit fixes that problem.
I need this game in my life. Reminds me of a PlayStation 2 game I owned forever ago called HSX: HyperSonic Xtreme. It was a Majesco bargain bin game but it took F-Zero-like gameplay and added a fully featured track editor where you could do a lot of crazy stuff. This feels like that, only better with things like tubes and pipes.
You've got a new fan. Keep up the great work!