Skip to content

Instantly share code, notes, and snippets.

@CaptainPRICE
Created April 9, 2017 23:46
Show Gist options
  • Select an option

  • Save CaptainPRICE/1684b82ecbf6f28e548034ff569f7217 to your computer and use it in GitHub Desktop.

Select an option

Save CaptainPRICE/1684b82ecbf6f28e548034ff569f7217 to your computer and use it in GitHub Desktop.
Garry's Mod: Pack/Unpack a Color/number/string structure to/from "uint32" and string. Works as expected, only 32-bit supported. Output: https://i.imgur.com/U8y7ejv.png
local assert, Color, IsColor, isnumber, isstring, tonumber = assert, Color, IsColor, isnumber, isstring, tonumber
local bit = bit
local bit_band, bit_bor, bit_lshift, bit_rshift = bit.band, bit.bor, bit.lshift, bit.rshift
local string = string
local string_byte, string_char, string_format, string_len = string.byte, string.char, string.format, string.len
local BYTE_MAX, UINT32_MAX = 0xFF, 0xFFFFFFFF -- Max value of unsigned byte. Max value of 32-bit unsigned integer.
--local UINT64_MAX = 0xFFFFFFFFFFFFFFFF -- Max value of 64-bit unsigned integer.
--- Packs a [Color] structure into a 32-bit unsigned integer.
--- @color [Color] structure to be packed.
--- @return Returns a 32-bit unsigned integer of the color.
function PackColor(color)
assert(IsColor(color), string_format("bad argument #%d to 'PackColor' (Color expected, got %s)", 1, type(color)))
return bit_band(bit_bor(bit_lshift(bit_band(color.a, BYTE_MAX), 24), bit_lshift(bit_band(color.r, BYTE_MAX), 16), bit_lshift(bit_band(color.g, BYTE_MAX), 8), bit_band(color.b, BYTE_MAX)), UINT32_MAX)
end
--- Packs a [Color] structure into a string.
--- @color [Color] structure to be packed.
--- @return Returns a string of the color.
function PackColor_Str(color)
assert(IsColor(color), string_format("bad argument #%d to 'PackColor_Str' (Color expected, got %s)", 1, type(color)))
return string_char(bit_band(color.r, BYTE_MAX), bit_band(color.g, BYTE_MAX), bit_band(color.b, BYTE_MAX), bit_band(color.a, BYTE_MAX))
end
--- Unpacks an 32-bit unsigned integer into a [Color] structure.
--- @argb 32-bit unsigned integer to be unpacked.
--- @return Returns the color from an 32-bit unsigned integer.
function UnpackColor(argb)
assert(isnumber(argb), string_format("bad argument #%d to 'UnpackColor' (number expected, got %s)", 1, type(argb)))
return Color(bit_band(bit_rshift(argb, 16), BYTE_MAX), bit_band(bit_rshift(argb, 8), BYTE_MAX), bit_band(argb, BYTE_MAX), bit_band(bit_rshift(argb, 24), BYTE_MAX))
end
--- Unpacks a string into a [Color] structure.
--- @argb String to be unpacked.
--- @return Returns the color from a string.
function UnpackColor_Str(argb)
assert(isstring(argb) and string_len(argb) == 4, string_format("bad argument #%d to 'UnpackColor_Str' (string expected, got %s)", 1, type(argb)))
local r, g, b, a = string_byte(argb, 1, 4)
return Color(tonumber(r), tonumber(g), tonumber(b), tonumber(a))
end
-- These two are not going to work until things go 64-bit, or if you have a 'bignumber' library.
--[[
function PackColor64(color1, color2)
assert(IsColor(color1), string_format("bad argument #%d to 'PackColor64' (Color expected, got %s)", 1, type(color1)))
assert(IsColor(color2), string_format("bad argument #%d to 'PackColor64' (Color expected, got %s)", 2, type(color2)))
return -- TODO. Pack 2 Colors into unsigned 64-bit integer.
end
function UnpackColor64(argb)
assert(isnumber(argb), string_format("bad argument #%d to 'UnpackColor64' (number expected, got %s)", 1, type(argb)))
return -- TODO. Unpack unsigned 64-bit integer into 2 Colors.
end
]]
-- Testing:
if true then return end -- Comment out or remove this line to enable test output.
--print(string_format("BYTE_MAX: %d\tUINT32_MAX: %u\tUINT64_MAX: %.0f", BYTE_MAX, UINT32_MAX, UINT64_MAX))
local color1, color2 = Color(1, 2, 3, 4), Color(250, 252, 254, 255)
print("[1] Color Input:", color1.r, color1.g, color1.b, color1.a)
print("[2] Color Input:", color2.r, color2.g, color2.b, color2.a)
local packed1, packed2 = PackColor(color1), PackColor(color2)
print("[32-bit] Packed #1 Color to uint32:", packed1)
print("[32-bit] Packed #2 Color to uint32:", packed2)
print("[32-bit] Unpacked #1 uint32 to Color:", UnpackColor(packed1))
print("[32-bit] Unpacked #2 uint32 to Color:", UnpackColor(packed2))
packed1, packed2 = PackColor_Str(color1), PackColor_Str(color2)
print("[Str] Packed #1 Color to string:", packed1)
print("[Str] Packed #2 Color to string:", packed2)
print("[Str] Unpacked #1 string to Color:", UnpackColor_Str(packed1))
print("[Str] Unpacked #2 string to Color:", UnpackColor_Str(packed2))
--packed1 = PackColor64(color1, color2)
--print("[64-bit] Packed Colors to uint64:", packed1)
--print("[64-bit] Unpacked uint64 to Colors:", UnpackColor64(packed1))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment