This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
emanuel12324's profile picture

Colors

Started by emanuel12324, 03 March 2017 - 12:26 AM
emanuel12324 #1
Posted 03 March 2017 - 01:26 AM
So, recently I have been playing around with Colorful lamps from the Computronics mod. The way you set the colors is by wrapping the peripheral and then calling setLampColor(int) on it. The problem here is that integer that you supply the method with.

As listed on the mod's wiki page, the colors range from 0 to 32767 (the same as the colors API minus 1). The 5 least significant bits are red, the next five are green, and the last 5 are blue. The first problem I see with this is that computercraft colors are 16 bit, not 15.

My intentions here are to convert hex colors (#FF00FF for example) or RGB (255,255,255 for white) to this number, but I can't seem to figure out how. I'd rather not just use the 16 colors of the colors API as it limits the colors I can produce. I'm sure there is some way to do this conversion through some calculations. If someone could possibly produce a function that does this, that'd be fantastic!

Regards,
Emanuel
Emma #2
Posted 03 March 2017 - 02:43 AM
Ok so we're going to do some bit math, so prepare yourself. First of all, it doesn't matter that cc colors are 16 bit, in fact 2^16 = 65536 not 32768, you take off a bit and 2^15 _does_ equal 32768. Anyways, now to the bit magic. For each colors we have 5 bits, with gives us 32 possible shades per r, g, and b. Since 255 > 32, we will have to collapse those numbers before shoving them into the final output. To do this we can simply divide by 8 (and floor the result). Now that we have a numbers that are five bits each, we can shove each into the final result. However, the bits are in the wrong place! To move them into position, we have to bit shift them to the left, green 5 bits and blue 10 bits over. To do this we will use the Bit API's bit.blshift function. Then once we have the correctly formatted numbers, we have to put them together, we could use bit.bor, but since the space around each of the number's bits are empty, its probably faster to just add them. Here is what I described in code form:

local function convertRGBToInt(red, green, blue)
  local r, g, b = math.floor(red / 8), math.floor(green / 8), math.floor(blue / 8)
  -- We don't have to shift red because it's already its bits are already in the correct position
  local shiftGreen = bit.blshift(g, 5)
  local shiftBlue = bit.blshift(b, 10)

  return r + shiftGreen + shiftBlue
end

local newNumber = convertRGBToInt(35, 223, 117)
I may have done goofed, and misinterpreted where the red, green, and blue components go and reversed them, in this case, do this:

-- Change this
local shiftBlue = bit.blshift(b, 10)

return r + shiftGreen + shiftBlue

-- To this
local shiftRed = bit.blshift(r, 10)

return shiftRed + shiftGreen + b

Hope this helps, and have fun! :D/>
Edited on 03 March 2017 - 01:52 AM
emanuel12324 #3
Posted 03 March 2017 - 03:03 AM
Interestingly enough, the code errors on the line that shifts green saying that it can't index nil, meaning that the variable bit is not a thing. In case you're curious, I am in MC 1.7.10 in the Tekkit Legends modpack. Thoughts?
Emma #4
Posted 03 March 2017 - 03:45 AM
Ah, you're probably running a version where the library was renamed to bit32, try replacing all occurrences of bit with that. If that doesn't work, here is a poly-fill:

function lshift(n, nBits)
return (n * 2^nBits) % 2^32
end
Edited on 03 March 2017 - 02:45 AM
emanuel12324 #5
Posted 03 March 2017 - 04:07 AM
Now it says attempt to call nil, meaning blshift doesn't exist. Looking into the available methods of bit32 through a little for loop, it reveals a couple of methods:

bxor
bor
lshift
rshift
arshift
btest
band
bnot

What do you think? I would assume blshift needs to be replaced by one of the available shifts but I just don't know which one… Is blshift a typo and you meant to say lshift?
Emma #6
Posted 03 March 2017 - 04:27 AM
Yeah, in the old bit lib it's called bit.blshift, I guess the "b" was removed. Indeed, bit32.lshift is the one you want.
emanuel12324 #7
Posted 05 March 2017 - 04:51 AM
Ah super cool. Thanks a lot!
Bomb Bloke #8
Posted 05 March 2017 - 05:24 AM
In case you're curious, I am in MC 1.7.10 in the Tekkit Legends modpack.

You may or may not be interested, but just to elaborate:

A while back Dan had plans to switch CC from Lua 5.1 to 5.2. In preparation for this, he added APIs which simulated some (not all) 5.2 behaviours (such as certain renamed 5.2 libraries, eg bit32), and added a config option for disabling the 5.1 equivalents.

The idea was that coders could use this config option to get some idea as to whether their code would continue to work once the "proper" change over took effect, therefore helping them to incorporate at least some forwards-compatibility.

In any case, for whatever reason whoever puts the Tekkit Legends pack together decided it'd be a good idea to flip the switch and turn off the 5.1 commands within their pack. You still end up using Lua 5.1, of course (under all official ComputerCraft releases). But that's why you can't access the main "bit" library.

Presumably they thought it actually shifts ComputerCraft to Lua 5.2. It doesn't, but rather simply triggers an obscure debug mode that most coders really have no good reason to be using.

http://www.computercraft.info/wiki/ComputerCraft.cfg

https://github.com/alekso56/ComputercraftLua/blob/master/bios.lua#L58
Edited on 05 March 2017 - 04:25 AM