From c89fe22cc8d7ebee2c9a9d4c2364486b3fdc4898 Mon Sep 17 00:00:00 2001 From: Mr-Auto <36127424+Mr-Auto@users.noreply.github.com> Date: Sun, 30 Jun 2024 18:45:10 +0200 Subject: [PATCH 1/3] color from string --- src/game_api/color.hpp | 52 +- src/game_api/script/lua_vm.cpp | 2 + src/game_api/script/usertypes/color.cpp | 751 +++++++++++++++++++ src/game_api/script/usertypes/color_lua.cpp | 51 ++ src/game_api/script/usertypes/color_lua.hpp | 11 + src/game_api/script/usertypes/crc32.hpp | 339 +++++++++ src/game_api/script/usertypes/entity_lua.cpp | 27 - src/game_api/script/usertypes/gui_lua.cpp | 5 - 8 files changed, 1184 insertions(+), 54 deletions(-) create mode 100644 src/game_api/script/usertypes/color.cpp create mode 100644 src/game_api/script/usertypes/color_lua.cpp create mode 100644 src/game_api/script/usertypes/color_lua.hpp create mode 100644 src/game_api/script/usertypes/crc32.hpp diff --git a/src/game_api/color.hpp b/src/game_api/color.hpp index fe9288e97..96e77cdc6 100644 --- a/src/game_api/color.hpp +++ b/src/game_api/color.hpp @@ -3,8 +3,16 @@ #include "aliases.hpp" #include +#include +#include #include +/// Convert a string to a color, you can use the HTML color names, or even HTML color codes, just prefix them with '#' symbol +/// You can also convert hex string into a color, prefix it with '0x', but use it only if you need to since lua allows for hex values directly too. +/// Default apha value will be 0xFF, unless it's specified +/// Format: [name], #RRGGBB, #RRGGBBAA, 0xBBGGRR, 0xAABBGGRR +uColor get_color(const std::string& color_name, std::optional alpha = std::nullopt); + struct Color { /// Create a new color - defaults to black @@ -14,35 +22,17 @@ struct Color constexpr Color& operator=(const Color&) = default; constexpr Color& operator=(Color&&) = default; - /// Comparison using RGB to avoid non-precise float value - bool operator==(const Color& col) const - { - const auto current = get_rgba(); - const auto compare = col.get_rgba(); - return std::get<0>(current) == std::get<0>(compare) && - std::get<1>(current) == std::get<1>(compare) && - std::get<2>(current) == std::get<2>(compare) && - std::get<3>(current) == std::get<3>(compare); - } - /// Create a new color by specifying its values constexpr Color(float r_, float g_, float b_, float a_) - : r(r_), g(g_), b(b_), a(a_) - { - } + : r(r_), g(g_), b(b_), a(a_){}; /// Create a color from an array of 4 floats constexpr Color(const float (&c)[4]) - : r(c[0]), g(c[1]), b(c[2]), a(c[3]) - { - } + : r(c[0]), g(c[1]), b(c[2]), a(c[3]){}; - constexpr void to_float(float (&c)[4]) const + Color(const std::string& color_name, std::optional alpha = std::nullopt) { - c[0] = r; - c[1] = g; - c[2] = b; - c[3] = a; + set_ucolor(get_color(color_name, alpha)); } static constexpr Color white() @@ -125,6 +115,14 @@ struct Color return Color(0.5f, 0.0f, 0.5f, 1.0f); } + constexpr void to_float(float (&c)[4]) const + { + c[0] = r; + c[1] = g; + c[2] = b; + c[3] = a; + } + /// Returns RGBA colors in 0..255 range std::tuple get_rgba() const { @@ -153,6 +151,7 @@ struct Color uint8_t alpha = (color >> 24U) & 0xFF; return set_rgba(red, green, blue, alpha); } + /// Copies the values of different Color to this one Color& set(Color& other) { @@ -160,6 +159,14 @@ struct Color return *this; } + /// Comparison using RGB to avoid non-precise float value + bool operator==(const Color& col) const noexcept + { + const auto current = get_rgba(); + const auto compare = col.get_rgba(); + return current == compare; + } + float r{0.0f}; float g{0.0f}; float b{0.0f}; @@ -168,6 +175,7 @@ struct Color private: uint8_t toRGB(const float c) const { + // this is not how the game does it, but not sure how to make it 1 : 1 return static_cast(std::round(255 * std::min(std::max(c, 0.0f), 1.0f))); } }; diff --git a/src/game_api/script/lua_vm.cpp b/src/game_api/script/lua_vm.cpp index f6845ecc9..347d290ae 100644 --- a/src/game_api/script/lua_vm.cpp +++ b/src/game_api/script/lua_vm.cpp @@ -66,6 +66,7 @@ #include "usertypes/behavior_lua.hpp" // for register_usertypes #include "usertypes/bucket_lua.hpp" // for register_usertypes #include "usertypes/char_state_lua.hpp" // for register_usertypes +#include "usertypes/color_lua.hpp" // for register_usertypes #include "usertypes/drops_lua.hpp" // for register_usertypes #include "usertypes/entities_activefloors_lua.hpp" // for register_usertypes #include "usertypes/entities_backgrounds_lua.hpp" // for register_usertypes @@ -299,6 +300,7 @@ end NVTables::register_usertypes(lua); NLogic::register_usertypes(lua); NBucket::register_usertypes(lua); + NColor::register_usertypes(lua); StateMemory* main_state = State::get().ptr_main(); diff --git a/src/game_api/script/usertypes/color.cpp b/src/game_api/script/usertypes/color.cpp new file mode 100644 index 000000000..5d812046e --- /dev/null +++ b/src/game_api/script/usertypes/color.cpp @@ -0,0 +1,751 @@ +#include "color.hpp" + +#include + +#include "crc32.hpp" + +uColor get_color(const std::string& color_name, std::optional alpha) +{ + // #RRGGBBAA + // 0xAABBGGRR + // treating not even number of hex characters as user error = behavior is undefined + + if (color_name.size() == 0) + return 0; + + if (color_name[0] == '#' && color_name.size() > 6) + { + std::string hex_string{color_name.begin() + 1, color_name.end()}; // skip # + uint32_t html_color = std::stoul(hex_string, nullptr, 16); + if (color_name.size() < 8) + { + html_color <<= 8; + html_color |= alpha.value_or(0xFF); + } + + char* ptr = (char*)&html_color; + std::reverse(ptr, ptr + 4); + + return html_color; + } + else if (color_name.size() > 2 && color_name[0] == '0' && color_name[1] == 'x') + { + uint32_t color = std::stoul(color_name, nullptr, 16); + if (color_name.size() < 9) + color |= alpha.value_or(0xFF) << 24; + + return color; + } + + uint32_t color = alpha.value_or(0xFF); + color <<= 24; + switch (crc32str(color_name)) + { + case crc32str("IndianRed"): + { + color |= 0x005C5CCD; + break; + } + case crc32str("LightCoral"): + { + color |= 0x008080F0; + break; + } + case crc32str("Salmon"): + { + color |= 0x007280FA; + break; + } + case crc32str("DarkSalmon"): + { + color |= 0x007A96E9; + break; + } + case crc32str("LightSalmon"): + { + color |= 0x007AA0FF; + break; + } + case crc32str("Crimson"): + { + color |= 0x003C14DC; + break; + } + case crc32str("Red"): + { + color |= 0x000000FF; + break; + } + case crc32str("FireBrick"): + { + color |= 0x002222B2; + break; + } + case crc32str("DarkRed"): + { + color |= 0x0000008B; + break; + } + case crc32str("Pink"): + { + color |= 0x00CBC0FF; + break; + } + case crc32str("LightPink"): + { + color |= 0x00C1B6FF; + break; + } + case crc32str("HotPink"): + { + color |= 0x00B469FF; + break; + } + case crc32str("DeepPink"): + { + color |= 0x009314FF; + break; + } + case crc32str("MediumVioletRed"): + { + color |= 0x008515C7; + break; + } + case crc32str("PaleVioletRed"): + { + color |= 0x009370DB; + break; + } + case crc32str("Coral"): + { + color |= 0x00507FFF; + break; + } + case crc32str("Tomato"): + { + color |= 0x004763FF; + break; + } + case crc32str("OrangeRed"): + { + color |= 0x000045FF; + break; + } + case crc32str("DarkOrange"): + { + color |= 0x00008CFF; + break; + } + case crc32str("Orange"): + { + color |= 0x0000A5FF; + break; + } + case crc32str("Gold"): + { + color |= 0x0000D7FF; + break; + } + case crc32str("Yellow"): + { + color |= 0x0000FFFF; + break; + } + case crc32str("LightYellow"): + { + color |= 0x00E0FFFF; + break; + } + case crc32str("LemonChiffon"): + { + color |= 0x00CDFAFF; + break; + } + case crc32str("LightGoldenrodYellow"): + { + color |= 0x00D2FAFA; + break; + } + case crc32str("PapayaWhip"): + { + color |= 0x00D5EFFF; + break; + } + case crc32str("Moccasin"): + { + color |= 0x00B5E4FF; + break; + } + case crc32str("PeachPuff"): + { + color |= 0x00B9DAFF; + break; + } + case crc32str("PaleGoldenrod"): + { + color |= 0x00AAE8EE; + break; + } + case crc32str("Khaki"): + { + color |= 0x008CE6F0; + break; + } + case crc32str("DarkKhaki"): + { + color |= 0x006BB7BD; + break; + } + case crc32str("Lavender"): + { + color |= 0x00FAE6E6; + break; + } + case crc32str("Thistle"): + { + color |= 0x00D8BFD8; + break; + } + case crc32str("Plum"): + { + color |= 0x00DDA0DD; + break; + } + case crc32str("Violet"): + { + color |= 0x00EE82EE; + break; + } + case crc32str("Orchid"): + { + color |= 0x00D670DA; + break; + } + case crc32str("Fuchsia"): + { + color |= 0x00FF00FF; + break; + } + case crc32str("Magenta"): + { + color |= 0x00FF00FF; + break; + } + case crc32str("MediumOrchid"): + { + color |= 0x00D355BA; + break; + } + case crc32str("MediumPurple"): + { + color |= 0x00DB7093; + break; + } + case crc32str("RebeccaPurple"): + { + color |= 0x00993366; + break; + } + case crc32str("BlueViolet"): + { + color |= 0x00E22B8A; + break; + } + case crc32str("DarkViolet"): + { + color |= 0x00D30094; + break; + } + case crc32str("DarkOrchid"): + { + color |= 0x00CC3299; + break; + } + case crc32str("DarkMagenta"): + { + color |= 0x008B008B; + break; + } + case crc32str("Purple"): + { + color |= 0x00800080; + break; + } + case crc32str("Indigo"): + { + color |= 0x0082004B; + break; + } + case crc32str("SlateBlue"): + { + color |= 0x00CD5A6A; + break; + } + case crc32str("DarkSlateBlue"): + { + color |= 0x008B3D48; + break; + } + case crc32str("MediumSlateBlue"): + { + color |= 0x00EE687B; + break; + } + case crc32str("GreenYellow"): + { + color |= 0x002FFFAD; + break; + } + case crc32str("Chartreuse"): + { + color |= 0x0000FF7F; + break; + } + case crc32str("LawnGreen"): + { + color |= 0x0000FC7C; + break; + } + case crc32str("Lime"): + { + color |= 0x0000FF00; + break; + } + case crc32str("LimeGreen"): + { + color |= 0x0032CD32; + break; + } + case crc32str("PaleGreen"): + { + color |= 0x0098FB98; + break; + } + case crc32str("LightGreen"): + { + color |= 0x0090EE90; + break; + } + case crc32str("MediumSpringGreen"): + { + color |= 0x009AFA00; + break; + } + case crc32str("SpringGreen"): + { + color |= 0x007FFF00; + break; + } + case crc32str("MediumSeaGreen"): + { + color |= 0x0071B33C; + break; + } + case crc32str("SeaGreen"): + { + color |= 0x00578B2E; + break; + } + case crc32str("ForestGreen"): + { + color |= 0x00228B22; + break; + } + case crc32str("Green"): + { + color |= 0x00008000; + break; + } + case crc32str("DarkGreen"): + { + color |= 0x00006400; + break; + } + case crc32str("YellowGreen"): + { + color |= 0x0032CD9A; + break; + } + case crc32str("OliveDrab"): + { + color |= 0x00238E6B; + break; + } + case crc32str("Olive"): + { + color |= 0x00008080; + break; + } + case crc32str("DarkOliveGreen"): + { + color |= 0x002F6B55; + break; + } + case crc32str("MediumAquamarine"): + { + color |= 0x00AACD66; + break; + } + case crc32str("DarkSeaGreen"): + { + color |= 0x008BBC8F; + break; + } + case crc32str("LightSeaGreen"): + { + color |= 0x00AAB220; + break; + } + case crc32str("DarkCyan"): + { + color |= 0x008B8B00; + break; + } + case crc32str("Teal"): + { + color |= 0x00808000; + break; + } + case crc32str("Aqua"): + { + color |= 0x00FFFF00; + break; + } + case crc32str("Cyan"): + { + color |= 0x00FFFF00; + break; + } + case crc32str("LightCyan"): + { + color |= 0x00FFFFE0; + break; + } + case crc32str("PaleTurquoise"): + { + color |= 0x00EEEEAF; + break; + } + case crc32str("Aquamarine"): + { + color |= 0x00D4FF7F; + break; + } + case crc32str("Turquoise"): + { + color |= 0x00D0E040; + break; + } + case crc32str("MediumTurquoise"): + { + color |= 0x00CCD148; + break; + } + case crc32str("DarkTurquoise"): + { + color |= 0x00D1CE00; + break; + } + case crc32str("CadetBlue"): + { + color |= 0x00A09E5F; + break; + } + case crc32str("SteelBlue"): + { + color |= 0x00B48246; + break; + } + case crc32str("LightSteelBlue"): + { + color |= 0x00DEC4B0; + break; + } + case crc32str("PowderBlue"): + { + color |= 0x00E6E0B0; + break; + } + case crc32str("LightBlue"): + { + color |= 0x00E6D8AD; + break; + } + case crc32str("SkyBlue"): + { + color |= 0x00EBCE87; + break; + } + case crc32str("LightSkyBlue"): + { + color |= 0x00FACE87; + break; + } + case crc32str("DeepSkyBlue"): + { + color |= 0x00FFBF00; + break; + } + case crc32str("DodgerBlue"): + { + color |= 0x00FF901E; + break; + } + case crc32str("CornflowerBlue"): + { + color |= 0x00ED9564; + break; + } + case crc32str("RoyalBlue"): + { + color |= 0x00E16941; + break; + } + case crc32str("Blue"): + { + color |= 0x00FF0000; + break; + } + case crc32str("MediumBlue"): + { + color |= 0x00CD0000; + break; + } + case crc32str("DarkBlue"): + { + color |= 0x008B0000; + break; + } + case crc32str("Navy"): + { + color |= 0x00800000; + break; + } + case crc32str("MidnightBlue"): + { + color |= 0x00701919; + break; + } + case crc32str("Cornsilk"): + { + color |= 0x00DCF8FF; + break; + } + case crc32str("BlanchedAlmond"): + { + color |= 0x00CDEBFF; + break; + } + case crc32str("Bisque"): + { + color |= 0x00C4E4FF; + break; + } + case crc32str("NavajoWhite"): + { + color |= 0x00ADDEFF; + break; + } + case crc32str("Wheat"): + { + color |= 0x00B3DEF5; + break; + } + case crc32str("BurlyWood"): + { + color |= 0x0087B8DE; + break; + } + case crc32str("Tan"): + { + color |= 0x008CB4D2; + break; + } + case crc32str("RosyBrown"): + { + color |= 0x008F8FBC; + break; + } + case crc32str("SandyBrown"): + { + color |= 0x0060A4F4; + break; + } + case crc32str("Goldenrod"): + { + color |= 0x0020A5DA; + break; + } + case crc32str("DarkGoldenrod"): + { + color |= 0x000B86B8; + break; + } + case crc32str("Peru"): + { + color |= 0x003F85CD; + break; + } + case crc32str("Chocolate"): + { + color |= 0x001E69D2; + break; + } + case crc32str("SaddleBrown"): + { + color |= 0x0013458B; + break; + } + case crc32str("Sienna"): + { + color |= 0x002D52A0; + break; + } + case crc32str("Brown"): + { + color |= 0x002A2AA5; + break; + } + case crc32str("Maroon"): + { + color |= 0x00000080; + break; + } + case crc32str("White"): + { + color |= 0x00FFFFFF; + break; + } + case crc32str("Snow"): + { + color |= 0x00FAFAFF; + break; + } + case crc32str("HoneyDew"): + { + color |= 0x00F0FFF0; + break; + } + case crc32str("MintCream"): + { + color |= 0x00FAFFF5; + break; + } + case crc32str("Azure"): + { + color |= 0x00FFFFF0; + break; + } + case crc32str("AliceBlue"): + { + color |= 0x00FFF8F0; + break; + } + case crc32str("GhostWhite"): + { + color |= 0x00FFF8F8; + break; + } + case crc32str("WhiteSmoke"): + { + color |= 0x00F5F5F5; + break; + } + case crc32str("SeaShell"): + { + color |= 0x00EEF5FF; + break; + } + case crc32str("Beige"): + { + color |= 0x00DCF5F5; + break; + } + case crc32str("OldLace"): + { + color |= 0x00E6F5FD; + break; + } + case crc32str("FloralWhite"): + { + color |= 0x00F0FAFF; + break; + } + case crc32str("Ivory"): + { + color |= 0x00F0FFFF; + break; + } + case crc32str("AntiqueWhite"): + { + color |= 0x00D7EBFA; + break; + } + case crc32str("Linen"): + { + color |= 0x00E6F0FA; + break; + } + case crc32str("LavenderBlush"): + { + color |= 0x00F5F0FF; + break; + } + case crc32str("MistyRose"): + { + color |= 0x00E1E4FF; + break; + } + case crc32str("Gainsboro"): + { + color |= 0x00DCDCDC; + break; + } + case crc32str("LightGray"): + { + color |= 0x00D3D3D3; + break; + } + case crc32str("Silver"): + { + color |= 0x00C0C0C0; + break; + } + case crc32str("DarkGray"): + { + color |= 0x00A9A9A9; + break; + } + case crc32str("Gray"): + { + color |= 0x00808080; + break; + } + case crc32str("DimGray"): + { + color |= 0x00696969; + break; + } + case crc32str("LightSlateGray"): + { + color |= 0x00998877; + break; + } + case crc32str("SlateGray"): + { + color |= 0x00908070; + break; + } + case crc32str("DarkSlateGray"): + { + color |= 0x004F4F2F; + break; + } + case crc32str("Black"): + { + color |= 0x00000000; + break; + } + } + return color; +} diff --git a/src/game_api/script/usertypes/color_lua.cpp b/src/game_api/script/usertypes/color_lua.cpp new file mode 100644 index 000000000..80a67c95e --- /dev/null +++ b/src/game_api/script/usertypes/color_lua.cpp @@ -0,0 +1,51 @@ +#include "color_lua.hpp" + +#include +#include + +#include "aliases.hpp" +#include "color.hpp" + +namespace NColor +{ +void register_usertypes(sol::state& lua) +{ + /// Converts a color to int to be used in drawing functions. Use values from `0..255`. + lua["rgba"] = [](int r, int g, int b, int a) -> uColor + { + return (uColor)(a << 24) + (b << 16) + (g << 8) + (r); + }; + + lua["get_color"] = get_color; + + auto color_type = lua.new_usertype("Color", sol::constructors)>{}, // + sol::meta_function::equal_to, + &Color::operator==); + + color_type["r"] = &Color::r; + color_type["g"] = &Color::g; + color_type["b"] = &Color::b; + color_type["a"] = &Color::a; + color_type["white"] = &Color::white; + color_type["silver"] = &Color::silver; + color_type["gray"] = &Color::gray; + color_type["black"] = &Color::black; + color_type["red"] = &Color::red; + color_type["maroon"] = &Color::maroon; + color_type["yellow"] = &Color::yellow; + color_type["olive"] = &Color::olive; + color_type["lime"] = &Color::lime; + color_type["green"] = &Color::green; + color_type["aqua"] = &Color::aqua; + color_type["teal"] = &Color::teal; + color_type["blue"] = &Color::blue; + color_type["navy"] = &Color::navy; + color_type["fuchsia"] = &Color::fuchsia; + color_type["purple"] = &Color::purple; + color_type["get_rgba"] = &Color::get_rgba; + color_type["set_rgba"] = &Color::set_rgba; + color_type["get_ucolor"] = &Color::get_ucolor; + color_type["set_ucolor"] = &Color::set_ucolor; + color_type["set"] = &Color::set; +} +} // namespace NColor diff --git a/src/game_api/script/usertypes/color_lua.hpp b/src/game_api/script/usertypes/color_lua.hpp new file mode 100644 index 000000000..e41cf7c5b --- /dev/null +++ b/src/game_api/script/usertypes/color_lua.hpp @@ -0,0 +1,11 @@ +#pragma once + +namespace sol +{ +class state; +} // namespace sol + +namespace NColor +{ +void register_usertypes(sol::state& lua); +}; diff --git a/src/game_api/script/usertypes/crc32.hpp b/src/game_api/script/usertypes/crc32.hpp new file mode 100644 index 000000000..00902d852 --- /dev/null +++ b/src/game_api/script/usertypes/crc32.hpp @@ -0,0 +1,339 @@ +/* Crc - 32 BIT ANSI X3.66 CRC checksum files */ + +#include +#include + +/**********************************************************************\ +|* Demonstration program to compute the 32-bit CRC used as the frame *| +|* check sequence in ADCCP (ANSI X3.66, also known as FIPS PUB 71 *| +|* and FED-STD-1003, the U.S. versions of CCITT's X.25 link-level *| +|* protocol). The 32-bit FCS was added via the Federal Register, *| +|* 1 June 1982, p.23798. I presume but don't know for certain that *| +|* this polynomial is or will be included in CCITT V.41, which *| +|* defines the 16-bit CRC (often called CRC-CCITT) polynomial. FIPS *| +|* PUB 78 says that the 32-bit FCS reduces otherwise undetected *| +|* errors by a factor of 10^-5 over 16-bit FCS. *| +\**********************************************************************/ + +/* Copyright (C) 1986 Gary S. Brown. You may use this program, or + code or tables extracted from it, as desired without restriction.*/ + +/* First, the polynomial itself and its table of feedback terms. The */ +/* polynomial is */ +/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */ +/* Note that we take it "backwards" and put the highest-order term in */ +/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */ +/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */ +/* the MSB being 1. */ + +/* Note that the usual hardware shift register implementation, which */ +/* is what we're using (we're merely optimizing it by doing eight-bit */ +/* chunks at a time) shifts bits into the lowest-order term. In our */ +/* implementation, that means shifting towards the right. Why do we */ +/* do it this way? Because the calculated CRC must be transmitted in */ +/* order from highest-order term to lowest-order term. UARTs transmit */ +/* characters in order from LSB to MSB. By storing the CRC this way, */ +/* we hand it to the UART in the order low-byte to high-byte; the UART */ +/* sends each low-bit to hight-bit; and the result is transmission bit */ +/* by bit from highest- to lowest-order term without requiring any bit */ +/* shuffling on our part. Reception works similarly. */ + +/* The feedback terms table consists of 256, 32-bit entries. Notes: */ +/* */ +/* 1. The table can be generated at runtime if desired; code to do so */ +/* is shown later. It might not be obvious, but the feedback */ +/* terms simply represent the results of eight shift/xor opera- */ +/* tions for all combinations of data and CRC register values. */ +/* */ +/* 2. The CRC accumulation logic is the same for all CRC polynomials, */ +/* be they sixteen or thirty-two bits wide. You simply choose the */ +/* appropriate table. Alternatively, because the table can be */ +/* generated at runtime, you can start by generating the table for */ +/* the polynomial in question and use exactly the same "updcrc", */ +/* if your application needn't simultaneously handle two CRC */ +/* polynomials. (Note, however, that XMODEM is strange.) */ +/* */ +/* 3. For 16-bit CRCs, the table entries need be only 16 bits wide; */ +/* of course, 32-bit entries work OK if the high 16 bits are zero. */ +/* */ +/* 4. The values must be right-shifted by eight bits by the "updcrc" */ +/* logic; the shift must be unsigned (bring in zeroes). On some */ +/* hardware you could probably optimize the shift in assembler by */ +/* using byte-swap instructions. */ + +#define UPDC32(octet, crc) (crc_32_tab[((crc) ^ (octet)) & 0xff] ^ ((crc) >> 8)) + +constexpr uint32_t crc_32_tab[] = {/* CRC polynomial 0xedb88320 */ + 0x00000000, + 0x77073096, + 0xee0e612c, + 0x990951ba, + 0x076dc419, + 0x706af48f, + 0xe963a535, + 0x9e6495a3, + 0x0edb8832, + 0x79dcb8a4, + 0xe0d5e91e, + 0x97d2d988, + 0x09b64c2b, + 0x7eb17cbd, + 0xe7b82d07, + 0x90bf1d91, + 0x1db71064, + 0x6ab020f2, + 0xf3b97148, + 0x84be41de, + 0x1adad47d, + 0x6ddde4eb, + 0xf4d4b551, + 0x83d385c7, + 0x136c9856, + 0x646ba8c0, + 0xfd62f97a, + 0x8a65c9ec, + 0x14015c4f, + 0x63066cd9, + 0xfa0f3d63, + 0x8d080df5, + 0x3b6e20c8, + 0x4c69105e, + 0xd56041e4, + 0xa2677172, + 0x3c03e4d1, + 0x4b04d447, + 0xd20d85fd, + 0xa50ab56b, + 0x35b5a8fa, + 0x42b2986c, + 0xdbbbc9d6, + 0xacbcf940, + 0x32d86ce3, + 0x45df5c75, + 0xdcd60dcf, + 0xabd13d59, + 0x26d930ac, + 0x51de003a, + 0xc8d75180, + 0xbfd06116, + 0x21b4f4b5, + 0x56b3c423, + 0xcfba9599, + 0xb8bda50f, + 0x2802b89e, + 0x5f058808, + 0xc60cd9b2, + 0xb10be924, + 0x2f6f7c87, + 0x58684c11, + 0xc1611dab, + 0xb6662d3d, + 0x76dc4190, + 0x01db7106, + 0x98d220bc, + 0xefd5102a, + 0x71b18589, + 0x06b6b51f, + 0x9fbfe4a5, + 0xe8b8d433, + 0x7807c9a2, + 0x0f00f934, + 0x9609a88e, + 0xe10e9818, + 0x7f6a0dbb, + 0x086d3d2d, + 0x91646c97, + 0xe6635c01, + 0x6b6b51f4, + 0x1c6c6162, + 0x856530d8, + 0xf262004e, + 0x6c0695ed, + 0x1b01a57b, + 0x8208f4c1, + 0xf50fc457, + 0x65b0d9c6, + 0x12b7e950, + 0x8bbeb8ea, + 0xfcb9887c, + 0x62dd1ddf, + 0x15da2d49, + 0x8cd37cf3, + 0xfbd44c65, + 0x4db26158, + 0x3ab551ce, + 0xa3bc0074, + 0xd4bb30e2, + 0x4adfa541, + 0x3dd895d7, + 0xa4d1c46d, + 0xd3d6f4fb, + 0x4369e96a, + 0x346ed9fc, + 0xad678846, + 0xda60b8d0, + 0x44042d73, + 0x33031de5, + 0xaa0a4c5f, + 0xdd0d7cc9, + 0x5005713c, + 0x270241aa, + 0xbe0b1010, + 0xc90c2086, + 0x5768b525, + 0x206f85b3, + 0xb966d409, + 0xce61e49f, + 0x5edef90e, + 0x29d9c998, + 0xb0d09822, + 0xc7d7a8b4, + 0x59b33d17, + 0x2eb40d81, + 0xb7bd5c3b, + 0xc0ba6cad, + 0xedb88320, + 0x9abfb3b6, + 0x03b6e20c, + 0x74b1d29a, + 0xead54739, + 0x9dd277af, + 0x04db2615, + 0x73dc1683, + 0xe3630b12, + 0x94643b84, + 0x0d6d6a3e, + 0x7a6a5aa8, + 0xe40ecf0b, + 0x9309ff9d, + 0x0a00ae27, + 0x7d079eb1, + 0xf00f9344, + 0x8708a3d2, + 0x1e01f268, + 0x6906c2fe, + 0xf762575d, + 0x806567cb, + 0x196c3671, + 0x6e6b06e7, + 0xfed41b76, + 0x89d32be0, + 0x10da7a5a, + 0x67dd4acc, + 0xf9b9df6f, + 0x8ebeeff9, + 0x17b7be43, + 0x60b08ed5, + 0xd6d6a3e8, + 0xa1d1937e, + 0x38d8c2c4, + 0x4fdff252, + 0xd1bb67f1, + 0xa6bc5767, + 0x3fb506dd, + 0x48b2364b, + 0xd80d2bda, + 0xaf0a1b4c, + 0x36034af6, + 0x41047a60, + 0xdf60efc3, + 0xa867df55, + 0x316e8eef, + 0x4669be79, + 0xcb61b38c, + 0xbc66831a, + 0x256fd2a0, + 0x5268e236, + 0xcc0c7795, + 0xbb0b4703, + 0x220216b9, + 0x5505262f, + 0xc5ba3bbe, + 0xb2bd0b28, + 0x2bb45a92, + 0x5cb36a04, + 0xc2d7ffa7, + 0xb5d0cf31, + 0x2cd99e8b, + 0x5bdeae1d, + 0x9b64c2b0, + 0xec63f226, + 0x756aa39c, + 0x026d930a, + 0x9c0906a9, + 0xeb0e363f, + 0x72076785, + 0x05005713, + 0x95bf4a82, + 0xe2b87a14, + 0x7bb12bae, + 0x0cb61b38, + 0x92d28e9b, + 0xe5d5be0d, + 0x7cdcefb7, + 0x0bdbdf21, + 0x86d3d2d4, + 0xf1d4e242, + 0x68ddb3f8, + 0x1fda836e, + 0x81be16cd, + 0xf6b9265b, + 0x6fb077e1, + 0x18b74777, + 0x88085ae6, + 0xff0f6a70, + 0x66063bca, + 0x11010b5c, + 0x8f659eff, + 0xf862ae69, + 0x616bffd3, + 0x166ccf45, + 0xa00ae278, + 0xd70dd2ee, + 0x4e048354, + 0x3903b3c2, + 0xa7672661, + 0xd06016f7, + 0x4969474d, + 0x3e6e77db, + 0xaed16a4a, + 0xd9d65adc, + 0x40df0b66, + 0x37d83bf0, + 0xa9bcae53, + 0xdebb9ec5, + 0x47b2cf7f, + 0x30b5ffe9, + 0xbdbdf21c, + 0xcabac28a, + 0x53b39330, + 0x24b4a3a6, + 0xbad03605, + 0xcdd70693, + 0x54de5729, + 0x23d967bf, + 0xb3667a2e, + 0xc4614ab8, + 0x5d681b02, + 0x2a6f2b94, + 0xb40bbe37, + 0xc30c8ea1, + 0x5a05df1b, + 0x2d02ef8d}; + +constexpr uint32_t updateCRC32(unsigned char ch, uint32_t crc) +{ + return UPDC32(ch, crc); +} + +constexpr uint32_t crc32str(std::string_view str) +{ + uint32_t oldcrc32 = 0xFFFFFFFF; + + for (auto c : str) + { + oldcrc32 = UPDC32(c, oldcrc32); + } + + return ~oldcrc32; +} diff --git a/src/game_api/script/usertypes/entity_lua.cpp b/src/game_api/script/usertypes/entity_lua.cpp index 7e4e0ec5e..398dcceae 100644 --- a/src/game_api/script/usertypes/entity_lua.cpp +++ b/src/game_api/script/usertypes/entity_lua.cpp @@ -28,33 +28,6 @@ namespace NEntity { void register_usertypes(sol::state& lua) { - auto color_type = lua.new_usertype("Color", sol::constructors{}, sol::meta_function::equal_to, &Color::operator==); - color_type["r"] = &Color::r; - color_type["g"] = &Color::g; - color_type["b"] = &Color::b; - color_type["a"] = &Color::a; - color_type["white"] = &Color::white; - color_type["silver"] = &Color::silver; - color_type["gray"] = &Color::gray; - color_type["black"] = &Color::black; - color_type["red"] = &Color::red; - color_type["maroon"] = &Color::maroon; - color_type["yellow"] = &Color::yellow; - color_type["olive"] = &Color::olive; - color_type["lime"] = &Color::lime; - color_type["green"] = &Color::green; - color_type["aqua"] = &Color::aqua; - color_type["teal"] = &Color::teal; - color_type["blue"] = &Color::blue; - color_type["navy"] = &Color::navy; - color_type["fuchsia"] = &Color::fuchsia; - color_type["purple"] = &Color::purple; - color_type["get_rgba"] = &Color::get_rgba; - color_type["set_rgba"] = &Color::set_rgba; - color_type["get_ucolor"] = &Color::get_ucolor; - color_type["set_ucolor"] = &Color::set_ucolor; - color_type["set"] = &Color::set; - /// Used in EntityDB lua.new_usertype( "Animation", diff --git a/src/game_api/script/usertypes/gui_lua.cpp b/src/game_api/script/usertypes/gui_lua.cpp index 5ca776824..7d10a9f0d 100644 --- a/src/game_api/script/usertypes/gui_lua.cpp +++ b/src/game_api/script/usertypes/gui_lua.cpp @@ -855,11 +855,6 @@ void register_usertypes(sol::state& lua) guidrawcontext_type["win_width"] = &GuiDrawContext::win_width; guidrawcontext_type["key_picker"] = &GuiDrawContext::key_picker; - /// Converts a color to int to be used in drawing functions. Use values from `0..255`. - lua["rgba"] = [](int r, int g, int b, int a) -> uColor - { - return (uColor)(a << 24) + (b << 16) + (g << 8) + (r); - }; /// Calculate the bounding box of text, so you can center it etc. Returns `width`, `height` in screen distance. lua["draw_text_size"] = [](float size, std::string text) -> std::pair { From bfc202981418d07367f18aee2a7382e34bfd03a8 Mon Sep 17 00:00:00 2001 From: Mr-Auto <36127424+Mr-Auto@users.noreply.github.com> Date: Sun, 30 Jun 2024 21:07:37 +0200 Subject: [PATCH 2/3] update docs --- docs/game_data/spel2.lua | 80 ++++++++++++++++++++--------------- docs/parse_source.py | 1 + docs/src/includes/_globals.md | 10 +++++ docs/src/includes/_types.md | 1 + 4 files changed, 58 insertions(+), 34 deletions(-) diff --git a/docs/game_data/spel2.lua b/docs/game_data/spel2.lua index 740da2263..46e72b0a2 100644 --- a/docs/game_data/spel2.lua +++ b/docs/game_data/spel2.lua @@ -1672,13 +1672,6 @@ function clear_vanilla_sound_callback(id) end ---@param source_uid integer ---@return SoundMeta function play_sound(sound, source_uid) end ----Converts a color to int to be used in drawing functions. Use values from `0..255`. ----@param r integer ----@param g integer ----@param b integer ----@param a integer ----@return uColor -function rgba(r, g, b, a) end ---Calculate the bounding box of text, so you can center it etc. Returns `width`, `height` in screen distance. ---@param size number ---@param text string @@ -1881,6 +1874,21 @@ function pause() end ---Returns the Bucket of data stored in shared memory between Overlunky and Playlunky ---@return Bucket function get_bucket() end +---Converts a color to int to be used in drawing functions. Use values from `0..255`. +---@param r integer +---@param g integer +---@param b integer +---@param a integer +---@return uColor +function rgba(r, g, b, a) end +---Convert a string to a color, you can use the HTML color names, or even HTML color codes, just prefix them with '#' symbol +---You can also convert hex string into a color, prefix it with '0x', but use it only if you need to since lua allows for hex values directly too. +---Default apha value will be 0xFF, unless it's specified +---Format: [name], #RRGGBB, #RRGGBBAA, 0xBBGGRR, 0xAABBGGRR +---@param color_name string +---@param alpha integer? +---@return uColor +function get_color(color_name, alpha) end --## Types do @@ -2376,17 +2384,6 @@ function PRNG:random(i) end ---@return integer? function PRNG:random(min, max) end ----@class Color - ---@field r number - ---@field g number - ---@field b number - ---@field a number - ---@field get_rgba fun(self): integer, integer, integer, integer @Returns RGBA colors in 0..255 range - ---@field set_rgba fun(self, red: integer, green: integer, blue: integer, alpha: integer): Color @Changes color based on given RGBA colors in 0..255 range - ---@field get_ucolor fun(self): uColor @Returns the `uColor` used in `GuiDrawContext` drawing functions - ---@field set_ucolor fun(self, color: uColor): Color @Changes color based on given uColor - ---@field set fun(self, other: Color): Color @Copies the values of different Color to this one - ---@class Animation ---@field id integer ---@field first_tile integer @@ -6459,6 +6456,17 @@ function LogicMagmamanSpawn:remove_spawn(ms) end ---@field io SharedIO @Shared part of ImGuiIO to block keyboard/mouse input across API instances. ---@field count integer @Number of API instances present +---@class Color + ---@field r number + ---@field g number + ---@field b number + ---@field a number + ---@field get_rgba fun(self): integer, integer, integer, integer @Returns RGBA colors in 0..255 range + ---@field set_rgba fun(self, red: integer, green: integer, blue: integer, alpha: integer): Color @Changes color based on given RGBA colors in 0..255 range + ---@field get_ucolor fun(self): uColor @Returns the `uColor` used in `GuiDrawContext` drawing functions + ---@field set_ucolor fun(self, color: uColor): Color @Changes color based on given uColor + ---@field set fun(self, other: Color): Color @Copies the values of different Color to this one + end --## Static class functions @@ -6502,22 +6510,6 @@ SaveState = nil ---Create a new temporary SaveState/clone of the main level state. Unlike save_state slots that are preallocated by the game anyway, these will use 32MiB a pop and aren't freed automatically, so make sure to clear them or reuse the same one to save memory. The garbage collector will eventually clear the SaveStates you don't have a handle to any more though. ---@return SaveState function SaveState:new() end ----Create a new color - defaults to black ----@return Color -function Color:new() end ----@param other Color ----@return Color -function Color:new(other) end ----@param color Color ----@return Color -function Color:new(color) end ----Create a new color by specifying its values ----@param r_ number ----@param g_ number ----@param b_ number ----@param a_ number ----@return Color -function Color:new(r_, g_, b_, a_) end EntityDB = nil ---@param other EntityDB @@ -6633,6 +6625,26 @@ MagmamanSpawnPosition = nil ---@param y_ integer ---@return MagmamanSpawnPosition function MagmamanSpawnPosition:new(x_, y_) end +---Create a new color - defaults to black +---@return Color +function Color:new() end +---@param other Color +---@return Color +function Color:new(other) end +---@param color Color +---@return Color +function Color:new(color) end +---Create a new color by specifying its values +---@param r_ number +---@param g_ number +---@param b_ number +---@param a_ number +---@return Color +function Color:new(r_, g_, b_, a_) end +---@param color_name string +---@param alpha integer? +---@return Color +function Color:new(color_name, alpha) end --## Enums diff --git a/docs/parse_source.py b/docs/parse_source.py index a1e399cb8..d8c92467a 100644 --- a/docs/parse_source.py +++ b/docs/parse_source.py @@ -162,6 +162,7 @@ "../src/game_api/script/usertypes/steam_lua.cpp", "../src/game_api/script/usertypes/logic_lua.cpp", "../src/game_api/script/usertypes/bucket_lua.cpp", + "../src/game_api/script/usertypes/color_lua.cpp", ] vtable_api_files = [ "../src/game_api/script/usertypes/vtables_lua.cpp", diff --git a/docs/src/includes/_globals.md b/docs/src/includes/_globals.md index 9d3a08b74..b3f495525 100644 --- a/docs/src/includes/_globals.md +++ b/docs/src/includes/_globals.md @@ -1407,6 +1407,16 @@ Returns the [Bucket](#Bucket) of data stored in shared memory between [Overlunky Same as `Player.get_heart_color` +### get_color + + +> Search script examples for [get_color](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=get_color) + +#### [uColor](#Aliases) get_color(string color_name, optional alpha = nullopt) + +Convert a string to a color, you can use the HTML color names, or even HTML color codes, just prefix them with '#' symbol You can also convert hex string into a color, prefix it with '0x', but use it only if you need to since lua allows for hex values directly too. Default apha value will be 0xFF, unless it's specified Format: [name], #RRGGBB, #RRGGBBAA, 0xBBGGRR, 0xAABBGGRR + + ### get_current_money diff --git a/docs/src/includes/_types.md b/docs/src/includes/_types.md index 01bf3445b..c25cea040 100644 --- a/docs/src/includes/_types.md +++ b/docs/src/includes/_types.md @@ -631,6 +631,7 @@ Type | Name | Description [Color](#Color) | [new(Color other)](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=Color) | [Color](#Color) | [new(Color color)](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=Color) | [Color](#Color) | [new(float r_, float g_, float b_, float a_)](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=Color) | Create a new color by specifying its values +[Color](#Color) | [new(string color_name, optional alpha = nullopt)](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=Color) | float | [r](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=r) | float | [g](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=g) | float | [b](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=b) | From af39dbd6411e427f4dc3934d5497d967af4f42c1 Mon Sep 17 00:00:00 2001 From: Mr-Auto <36127424+Mr-Auto@users.noreply.github.com> Date: Mon, 1 Jul 2024 11:55:20 +0200 Subject: [PATCH 3/3] move the file --- src/game_api/{script/usertypes => }/crc32.hpp | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/game_api/{script/usertypes => }/crc32.hpp (100%) diff --git a/src/game_api/script/usertypes/crc32.hpp b/src/game_api/crc32.hpp similarity index 100% rename from src/game_api/script/usertypes/crc32.hpp rename to src/game_api/crc32.hpp