Created
April 9, 2017 23:46
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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