Of course it is possible, and I have done this several times in the past for many purposes. The basics you must understand is that the Minecraft/ComputerCraft colours have 1 bit per colour as they're a 2
x. Therefore using knowledge of math we know that a log
2(x) will reverse this to get back to a number, in this case hopefully 0—15 unless we've been given an invalid colour (which you should check for btw). Lua doesn't have a built in log
2 function, but it can be done like so
local function log2( num )
return math.log( num ) / math.log( 2 )
end
once we have these two numbers we must combine them, the simplest way of doing this is by performing a bit shift of one of the colours, lets just pick the text colour, and then using a Bitwise OR to combine them.
local function byteFromColors( fg, bg )
--# convert to 0-15 (the 4 low bits range)
fg = log2( fg )
bg = log2( bg )
--# make one of the colours be in the 4 high bits range by shifting it left 4 places
fg = bit.blshift( fg, 4 )
--# combine the two colours with a bitwise OR
return bit.bor( fg, bg )
end
in order to get the colours back from the byte we just do the inverse, we apply a Bitwise AND (bitmask) to the byte to extract each of the high and low bits, then apply them back to a colour with
2x.
local function colorsFromByte( byte )
--# extract the 4 high bits from the byte
local low = bit.band(b,15)
--# extract the 4 low bits from the byte
local high = bit.brshift(b,4)
--# turn them back into the colours
return 2^high, 2^low
end
to further understand the above code examples make sure to read up on
Bitwise Operations, particularly OR and AND. And if you have any questions, feel free to ask.
EDIT: oh, I would like to just point out that it is possible to store (and read) anything you want within binary data. That is how the Note program is able to read the NBS file for MoarPeripherals (I had to write a LittleEndian to BigEndian converter for that). I have even written code to reduce file sizes of save files, take a look at PokeCC, I was able to reduce the save file size from 15KB to 838 bytes by
simply 'compressing' the data into a byte.