/* Crafter®.Graphics Copyright (C) 2025 Catcrafts® Catcrafts.net This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ export module Crafter.Graphics:Types; import std; export namespace Crafter { struct MousePoint { std::uint32_t x; std::uint32_t y; }; struct MouseDelta { std::int64_t x; std::int64_t y; }; struct MouseMoveEvent { MousePoint lastMousePos; MousePoint currentMousePos; MouseDelta mouseDelta; }; struct ScaleData { std::int32_t x; std::int32_t y; std::int32_t width; std::int32_t height; }; struct ScaleDataBoundless { std::uint32_t x; std::uint32_t y; std::uint32_t width; std::uint32_t height; }; struct ClipRect { std::int32_t left; std::int32_t right; std::int32_t top; std::int32_t bottom; }; struct __attribute__((packed)) Pixel_BU8_GU8_RU8_AU8 { std::uint8_t b; std::uint8_t g; std::uint8_t r; std::uint8_t a; }; struct __attribute__((packed)) Pixel_RU8_GU8_BU8_AU8 { std::uint8_t r; std::uint8_t g; std::uint8_t b; std::uint8_t a; }; struct __attribute__((packed)) Vertex { float x; float y; float z; float w; }; struct __attribute__((packed)) VertexUV { float x; float y; float z; float w; float u; float v; float pad[2]; }; struct __attribute__((packed)) VertexRGBA { float x; float y; float z; float w; float r; float g; float b; float a; }; struct __attribute__((packed)) HeightRGBA { float height; float pad[3]; float r; float g; float b; float a; }; struct FrameTime { std::chrono::time_point now; std::chrono::duration delta; }; enum class OpaqueType { FullyOpaque, // All pixels have A of 255 SemiOpaque, // All pixels have A of 0 or 255 (no blending needed) Transparent // Color blending is used }; constexpr std::int8_t BOUND8 = 9; constexpr std::int8_t SCALE8 = std::numeric_limits::max() / BOUND8; constexpr std::uint8_t SCALEBOUNDLESS8 = std::numeric_limits::max(); constexpr double SCALEDOUBLE8 = static_cast(std::numeric_limits::max() / BOUND8); constexpr double SCALEBOUNDLESSDOUBLE8 = static_cast(std::numeric_limits::max()); constexpr std::int16_t BOUND16 = 9; constexpr std::int16_t SCALE16 = std::numeric_limits::max() / BOUND16; constexpr std::uint16_t SCALEBOUNDLESS16 = std::numeric_limits::max(); constexpr double SCALEDOUBLE16 = static_cast(std::numeric_limits::max() / BOUND16); constexpr double SCALEBOUNDLESSDOUBLE16 = static_cast(std::numeric_limits::max()); constexpr std::int32_t BOUND32 = 9; constexpr std::int32_t SCALE32 = std::numeric_limits::max() / BOUND32; constexpr std::uint32_t SCALEBOUNDLESS32 = std::numeric_limits::max(); constexpr double SCALEDOUBLE32 = static_cast(std::numeric_limits::max() / BOUND32); constexpr double SCALEBOUNDLESSDOUBLE32 = static_cast(std::numeric_limits::max()); constexpr std::int64_t BOUND64 = 9; constexpr std::int64_t SCALE64 = std::numeric_limits::max() / BOUND64; constexpr std::uint64_t SCALEBOUNDLESS64 = std::numeric_limits::max(); constexpr double SCALEDOUBLE64 = static_cast(std::numeric_limits::max() / BOUND64); constexpr double SCALEBOUNDLESSDOUBLE64 = static_cast(std::numeric_limits::max()); template constexpr T FractionalToMapped(double f) requires(std::is_integral_v) { if constexpr (std::is_same_v || std::is_same_v) { return T(f * SCALEDOUBLE8); } else if constexpr (std::is_same_v || std::is_same_v) { return T(f * SCALEDOUBLE16); } else if constexpr (std::is_same_v || std::is_same_v) { return T(f * SCALEDOUBLE32); } else { return T(f * SCALEDOUBLE64); } } template constexpr T FractionalToMappedBoundless(double f) requires(std::is_integral_v) { if constexpr (std::is_same_v || std::is_same_v) { return T(f * SCALEBOUNDLESSDOUBLE8); } else if constexpr (std::is_same_v || std::is_same_v) { return T(f * SCALEBOUNDLESSDOUBLE16); } else if constexpr (std::is_same_v || std::is_same_v) { return T(f * SCALEBOUNDLESSDOUBLE32); } else { return T(f * SCALEBOUNDLESSDOUBLE64); } } template constexpr double MappedToFractional(T mapped) requires(std::is_integral_v) { if constexpr (std::is_same_v || std::is_same_v) { return mapped / SCALEDOUBLE8; } else if constexpr (std::is_same_v || std::is_same_v) { return mapped / SCALEDOUBLE16; } else if constexpr (std::is_same_v || std::is_same_v) { return mapped / SCALEDOUBLE32; } else { return mapped / SCALEDOUBLE64; } } template constexpr double MappedToFractionalBoundless(T mapped) requires(std::is_integral_v) { if constexpr (std::is_same_v || std::is_same_v) { return mapped / SCALEBOUNDLESSDOUBLE8; } else if constexpr (std::is_same_v || std::is_same_v) { return mapped / SCALEBOUNDLESSDOUBLE16; } else if constexpr (std::is_same_v || std::is_same_v) { return mapped / SCALEBOUNDLESSDOUBLE32; } else { return mapped / SCALEBOUNDLESSDOUBLE64; } } template constexpr T MappedToAbsolute(T mapped, T2 absolute) requires(std::is_integral_v) { if constexpr (std::is_same_v || std::is_same_v) { return static_cast(mapped) * absolute / SCALE8; } else if constexpr (std::is_same_v || std::is_same_v) { return static_cast(mapped) * absolute / SCALE16; } else if constexpr (std::is_same_v || std::is_same_v) { return static_cast(mapped) * absolute / SCALE32; } else { return static_cast<__int128>(mapped) * absolute / SCALE64; } } template constexpr T MappedToAbsoluteBoundless(T mapped, T2 absolute) requires(std::is_integral_v) { if constexpr (std::is_same_v || std::is_same_v) { return static_cast(mapped) * absolute / SCALEBOUNDLESS8; } else if constexpr (std::is_same_v || std::is_same_v) { return static_cast(mapped) * absolute / SCALEBOUNDLESS16; } else if constexpr (std::is_same_v || std::is_same_v) { return static_cast(mapped) * absolute / SCALEBOUNDLESS32; } else { return static_cast(mapped) * absolute / SCALEBOUNDLESS64; } } // template // constexpr T PixelToMappedBoundless(T pixel, T2 screen) requires(std::is_integral_v) { // if constexpr (std::is_same_v) { // return (static_cast(relative) * SCALE8) / (static_cast(absolute) * SCALE8); // } else if constexpr (std::is_same_v) { // return (static_cast(relative) * SCALE16) / (static_cast(absolute) * SCALE16); // } else if constexpr (std::is_same_v) { // return (static_cast(relative) * SCALE32) / (static_cast(absolute) * SCALE32); // } else { // return (static_cast(relative) * SCALE32) / (static_cast(absolute) * SCALE32); // } // } template constexpr T AbsoluteToMapped(T absolute, T2 mapped) { if constexpr (std::is_same_v || std::is_same_v) { return static_cast(absolute) * SCALE8 / mapped; } else if constexpr (std::is_same_v || std::is_same_v ) { return static_cast(absolute) * SCALE16 / mapped; } else if constexpr (std::is_same_v|| std::is_same_v) { return static_cast(absolute) * SCALE32 / mapped; } else { return static_cast<__int128>(absolute) * SCALE64 / mapped; } } template constexpr T AbsoluteToMappedBoundless(T absolute, T2 mapped) { if constexpr (std::is_same_v || std::is_same_v ) { return static_cast(absolute) * SCALEBOUNDLESS8 / mapped; } else if constexpr (std::is_same_v || std::is_same_v) { return static_cast(absolute) * SCALEBOUNDLESS16 / mapped; } else if constexpr (std::is_same_v || std::is_same_v) { return static_cast(absolute) * SCALEBOUNDLESS32 / mapped; } else { return static_cast(absolute) * SCALEBOUNDLESS64 / mapped; } } template constexpr T BoundToBoundless(T mapped) { if constexpr (std::is_same_v || std::is_same_v) { return mapped * BOUND8 * 2; } else if constexpr (std::is_same_v || std::is_same_v) { return mapped * BOUND16 * 2; } else if constexpr (std::is_same_v || std::is_same_v) { return mapped * BOUND32 * 2; } else { return mapped * BOUND64 * 2; } } template constexpr T BoundlessToBound(T mapped) { if constexpr (std::is_same_v || std::is_same_v ) { return mapped / 2; } else if constexpr (std::is_same_v || std::is_same_v) { return mapped / 2; } else if constexpr (std::is_same_v || std::is_same_v) { return mapped / 2; } else { return mapped / 2; } } enum class CrafterKeys { // Alphabetic keys A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, // Numeric keys _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, // Function keys F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, // Control keys Escape, Tab, Enter, Space, Backspace, Delete, Insert, Home, End, PageUp, PageDown, CapsLock, NumLock, ScrollLock, // Modifier keys LeftShift, RightShift, LeftCtrl, RightCtrl, LeftAlt, RightAlt, LeftSuper, RightSuper, // Arrow keys Up, Down, Left, Right, // Keypad keys keypad_0, keypad_1, keypad_2, keypad_3, keypad_4, keypad_5, keypad_6, keypad_7, keypad_8, keypad_9, keypad_enter, keypad_plus, keypad_minus, keypad_multiply, keypad_divide, keypad_decimal, // Punctuation and special keys grave, minus, equal, bracket_left, bracket_right, backslash, semicolon, quote, comma, period, slash, print_screen, pause, menu, // Additional keys volume_up, volume_down, volume_mute, media_play, media_stop, media_prev, media_next, browser_back, browser_forward, browser_refresh, browser_stop, browser_search, browser_home, launch_mail, launch_calculator, launch_media_player, CrafterKeysMax }; }