From fe66a58d3918e58dd43c4f6386f5d0c5f198335c Mon Sep 17 00:00:00 2001 From: Evan Pratten Date: Tue, 11 Apr 2023 20:05:30 -0400 Subject: [PATCH] Auto-generate some rust wrappers for really annoying ffi artifacts --- .vscode/settings.json | 1 + Cargo.toml | 8 +- examples/basic.rs | 43 +-- scripts/regenerate_colors.py | 44 +++ scripts/regenerate_enums.py | 56 +++ src/colors.rs | 209 ++++++++++ src/enums.rs | 713 +++++++++++++++++++++++++++++++++++ src/lib.rs | 12 +- src/macros.rs | 31 ++ 9 files changed, 1084 insertions(+), 33 deletions(-) create mode 100644 scripts/regenerate_colors.py create mode 100644 scripts/regenerate_enums.py create mode 100644 src/colors.rs create mode 100644 src/enums.rs create mode 100644 src/macros.rs diff --git a/.vscode/settings.json b/.vscode/settings.json index 120c4a6..a9c7b58 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,4 +3,5 @@ "${workspaceFolder}/src", "${workspaceFolder}/third_party/raylib/src", ], + "python.formatting.provider": "yapf", } \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 2a94b24..5325f6d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "raylib-ffi" -version = "4.5.0" +version = "4.5.1" authors = ["Evan Pratten "] edition = "2021" description = "Automatic raw Rust bindings to raylib" @@ -21,3 +21,9 @@ exclude = [ [build-dependencies] bindgen = "^0.63.0" cmake = "^0.1.49" + +[features] +default = ["enums", "macros", "colors"] +enums = [] +macros = [] +colors = [] \ No newline at end of file diff --git a/examples/basic.rs b/examples/basic.rs index 2aa5b9c..0ee1723 100644 --- a/examples/basic.rs +++ b/examples/basic.rs @@ -4,41 +4,22 @@ pub fn main() { raylib_ffi::InitWindow( 800, 450, - "raylib-ffi example - basic window\0".as_ptr() as *const i8, + raylib_ffi::rl_str!("raylib-ffi example - basic window"), ); // Render the window - loop { - // Close the window if requested - if raylib_ffi::WindowShouldClose() { - break; - } - - // Begin a draw call - raylib_ffi::BeginDrawing(); - - // Render text and a background - raylib_ffi::ClearBackground(raylib_ffi::Color { - r: 255, - g: 255, - b: 255, - a: 255, + while !(raylib_ffi::WindowShouldClose()) { + raylib_ffi::draw!({ + // Render text and a background + raylib_ffi::ClearBackground(raylib_ffi::colors::WHITE); + raylib_ffi::DrawText( + raylib_ffi::rl_str!("Congrats! You created your first window!"), + 190, + 200, + 20, + raylib_ffi::colors::BLACK, + ); }); - raylib_ffi::DrawText( - "Congrats! You created your first window!\0".as_ptr() as *const i8, - 190, - 200, - 20, - raylib_ffi::Color { - r: 0, - g: 0, - b: 0, - a: 255, - }, - ); - - // End the draw call - raylib_ffi::EndDrawing(); } // Clean up diff --git a/scripts/regenerate_colors.py b/scripts/regenerate_colors.py new file mode 100644 index 0000000..5318859 --- /dev/null +++ b/scripts/regenerate_colors.py @@ -0,0 +1,44 @@ +import json +from pathlib import Path +import re + +REPO_ROOT = Path(__file__).parent.parent +COLOR_DEF_RE = re.compile(r"CLITERAL\(Color\){ (\d+), (\d+), (\d+), (\d+) }") + +print("Searching for raylib API definitions") +with open(REPO_ROOT / "third_party" / "raylib" / "parser" / "output" / + "raylib_api.json") as f: + raylib_api = json.load(f) + +# Find the raylib defines +raylib_defines = raylib_api["defines"] + +# Delete the old colors file if it exists +if (REPO_ROOT / "src" / "colors.rs").exists(): + print("Deleting old colors file") + (REPO_ROOT / "src" / "colors.rs").unlink() + +# Open the Rust colors file +with open(REPO_ROOT / "src" / "colors.rs", "w") as f: + + # Write a file header + f.writelines([ + "//! This module contains auto-generated Rust representations of raylib's colors.\n" + ]) + + # Search for color definitions + for definition in raylib_defines: + if definition["type"] == "COLOR": + print(f"Writing color: {definition['name']}") + # Parse the RGBA values + match = COLOR_DEF_RE.match(definition["value"]) + if match is None: + raise RuntimeError( + f"Failed to parse color definition {definition}") + r, g, b, a = match.groups() + + # Write the color definition + f.writelines([ + "\n", f"/// {definition['description']}\n", + f"pub const {definition['name']}: crate::Color = crate::Color {{\n\tr: {r},\n\tg: {g},\n\tb: {b},\n\ta: {a},\n}};\n" + ]) diff --git a/scripts/regenerate_enums.py b/scripts/regenerate_enums.py new file mode 100644 index 0000000..1fa8d35 --- /dev/null +++ b/scripts/regenerate_enums.py @@ -0,0 +1,56 @@ +import json +from pathlib import Path + +REPO_ROOT = Path(__file__).parent.parent + +print("Searching for raylib API definitions") +with open(REPO_ROOT / "third_party" / "raylib" / "parser" / "output" / + "raylib_api.json") as f: + raylib_api = json.load(f) + +# Find the raylib enums +raylib_enums = raylib_api["enums"] + +# Delete the old enums file if it exists +if (REPO_ROOT / "src" / "enums.rs").exists(): + print("Deleting old enums file") + (REPO_ROOT / "src" / "enums.rs").unlink() + +# Open the Rust enums file +with open(REPO_ROOT / "src" / "enums.rs", "w") as f: + + # Write a file header + f.writelines([ + "//! This module contains auto-generated Rust representations of raylib's enums.\n" + ]) + + # Translate each found enum + for enum in raylib_enums: + print(f"Translating enum {enum['name']}") + # Write a doc comment and the enum header + f.writelines([ + "\n", f"/// {enum['description']}\n", + "#[repr(C)]\n", + "#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]\n", + f"pub enum {enum['name']} {{\n" + ]) + + # Write each enum variant + for variant in enum["values"]: + # TODO: I'm not sure how best to handle duplicate variant values + if variant["name"] == "KEY_MENU": + continue + + # Normalize the variant name + variant_name = "".join([ + segment.capitalize() for segment in variant["name"].split("_") + ]) + + # Write + f.writelines([ + f"\t/// {variant['description']}\n", + f"\t{variant_name} = {variant['value']},\n" + ]) + + # Write the enum footer + f.writelines(["}\n"]) diff --git a/src/colors.rs b/src/colors.rs new file mode 100644 index 0000000..c261e82 --- /dev/null +++ b/src/colors.rs @@ -0,0 +1,209 @@ +//! This module contains auto-generated Rust representations of raylib's colors. + +/// Light Gray +pub const LIGHTGRAY: crate::Color = crate::Color { + r: 200, + g: 200, + b: 200, + a: 255, +}; + +/// Gray +pub const GRAY: crate::Color = crate::Color { + r: 130, + g: 130, + b: 130, + a: 255, +}; + +/// Dark Gray +pub const DARKGRAY: crate::Color = crate::Color { + r: 80, + g: 80, + b: 80, + a: 255, +}; + +/// Yellow +pub const YELLOW: crate::Color = crate::Color { + r: 253, + g: 249, + b: 0, + a: 255, +}; + +/// Gold +pub const GOLD: crate::Color = crate::Color { + r: 255, + g: 203, + b: 0, + a: 255, +}; + +/// Orange +pub const ORANGE: crate::Color = crate::Color { + r: 255, + g: 161, + b: 0, + a: 255, +}; + +/// Pink +pub const PINK: crate::Color = crate::Color { + r: 255, + g: 109, + b: 194, + a: 255, +}; + +/// Red +pub const RED: crate::Color = crate::Color { + r: 230, + g: 41, + b: 55, + a: 255, +}; + +/// Maroon +pub const MAROON: crate::Color = crate::Color { + r: 190, + g: 33, + b: 55, + a: 255, +}; + +/// Green +pub const GREEN: crate::Color = crate::Color { + r: 0, + g: 228, + b: 48, + a: 255, +}; + +/// Lime +pub const LIME: crate::Color = crate::Color { + r: 0, + g: 158, + b: 47, + a: 255, +}; + +/// Dark Green +pub const DARKGREEN: crate::Color = crate::Color { + r: 0, + g: 117, + b: 44, + a: 255, +}; + +/// Sky Blue +pub const SKYBLUE: crate::Color = crate::Color { + r: 102, + g: 191, + b: 255, + a: 255, +}; + +/// Blue +pub const BLUE: crate::Color = crate::Color { + r: 0, + g: 121, + b: 241, + a: 255, +}; + +/// Dark Blue +pub const DARKBLUE: crate::Color = crate::Color { + r: 0, + g: 82, + b: 172, + a: 255, +}; + +/// Purple +pub const PURPLE: crate::Color = crate::Color { + r: 200, + g: 122, + b: 255, + a: 255, +}; + +/// Violet +pub const VIOLET: crate::Color = crate::Color { + r: 135, + g: 60, + b: 190, + a: 255, +}; + +/// Dark Purple +pub const DARKPURPLE: crate::Color = crate::Color { + r: 112, + g: 31, + b: 126, + a: 255, +}; + +/// Beige +pub const BEIGE: crate::Color = crate::Color { + r: 211, + g: 176, + b: 131, + a: 255, +}; + +/// Brown +pub const BROWN: crate::Color = crate::Color { + r: 127, + g: 106, + b: 79, + a: 255, +}; + +/// Dark Brown +pub const DARKBROWN: crate::Color = crate::Color { + r: 76, + g: 63, + b: 47, + a: 255, +}; + +/// White +pub const WHITE: crate::Color = crate::Color { + r: 255, + g: 255, + b: 255, + a: 255, +}; + +/// Black +pub const BLACK: crate::Color = crate::Color { + r: 0, + g: 0, + b: 0, + a: 255, +}; + +/// Blank (Transparent) +pub const BLANK: crate::Color = crate::Color { + r: 0, + g: 0, + b: 0, + a: 0, +}; + +/// Magenta +pub const MAGENTA: crate::Color = crate::Color { + r: 255, + g: 0, + b: 255, + a: 255, +}; + +/// My own White (raylib logo) +pub const RAYWHITE: crate::Color = crate::Color { + r: 245, + g: 245, + b: 245, + a: 255, +}; diff --git a/src/enums.rs b/src/enums.rs new file mode 100644 index 0000000..df1c42d --- /dev/null +++ b/src/enums.rs @@ -0,0 +1,713 @@ +//! This module contains auto-generated Rust representations of raylib's enums. + +/// System/Window config flags +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum ConfigFlags { + /// Set to try enabling V-Sync on GPU + FlagVsyncHint = 64, + /// Set to run program in fullscreen + FlagFullscreenMode = 2, + /// Set to allow resizable window + FlagWindowResizable = 4, + /// Set to disable window decoration (frame and buttons) + FlagWindowUndecorated = 8, + /// Set to hide window + FlagWindowHidden = 128, + /// Set to minimize window (iconify) + FlagWindowMinimized = 512, + /// Set to maximize window (expanded to monitor) + FlagWindowMaximized = 1024, + /// Set to window non focused + FlagWindowUnfocused = 2048, + /// Set to window always on top + FlagWindowTopmost = 4096, + /// Set to allow windows running while minimized + FlagWindowAlwaysRun = 256, + /// Set to allow transparent framebuffer + FlagWindowTransparent = 16, + /// Set to support HighDPI + FlagWindowHighdpi = 8192, + /// Set to support mouse passthrough, only supported when FLAG_WINDOW_UNDECORATED + FlagWindowMousePassthrough = 16384, + /// Set to try enabling MSAA 4X + FlagMsaa4xHint = 32, + /// Set to try enabling interlaced video format (for V3D) + FlagInterlacedHint = 65536, +} + +/// Trace log level +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum TraceLogLevel { + /// Display all logs + LogAll = 0, + /// Trace logging, intended for internal use only + LogTrace = 1, + /// Debug logging, used for internal debugging, it should be disabled on release builds + LogDebug = 2, + /// Info logging, used for program execution info + LogInfo = 3, + /// Warning logging, used on recoverable failures + LogWarning = 4, + /// Error logging, used on unrecoverable failures + LogError = 5, + /// Fatal logging, used to abort program: exit(EXIT_FAILURE) + LogFatal = 6, + /// Disable logging + LogNone = 7, +} + +/// Keyboard keys (US keyboard layout) +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum KeyboardKey { + /// Key: NULL, used for no key pressed + KeyNull = 0, + /// Key: ' + KeyApostrophe = 39, + /// Key: , + KeyComma = 44, + /// Key: - + KeyMinus = 45, + /// Key: . + KeyPeriod = 46, + /// Key: / + KeySlash = 47, + /// Key: 0 + KeyZero = 48, + /// Key: 1 + KeyOne = 49, + /// Key: 2 + KeyTwo = 50, + /// Key: 3 + KeyThree = 51, + /// Key: 4 + KeyFour = 52, + /// Key: 5 + KeyFive = 53, + /// Key: 6 + KeySix = 54, + /// Key: 7 + KeySeven = 55, + /// Key: 8 + KeyEight = 56, + /// Key: 9 + KeyNine = 57, + /// Key: ; + KeySemicolon = 59, + /// Key: = + KeyEqual = 61, + /// Key: A | a + KeyA = 65, + /// Key: B | b + KeyB = 66, + /// Key: C | c + KeyC = 67, + /// Key: D | d + KeyD = 68, + /// Key: E | e + KeyE = 69, + /// Key: F | f + KeyF = 70, + /// Key: G | g + KeyG = 71, + /// Key: H | h + KeyH = 72, + /// Key: I | i + KeyI = 73, + /// Key: J | j + KeyJ = 74, + /// Key: K | k + KeyK = 75, + /// Key: L | l + KeyL = 76, + /// Key: M | m + KeyM = 77, + /// Key: N | n + KeyN = 78, + /// Key: O | o + KeyO = 79, + /// Key: P | p + KeyP = 80, + /// Key: Q | q + KeyQ = 81, + /// Key: R | r + KeyR = 82, + /// Key: S | s + KeyS = 83, + /// Key: T | t + KeyT = 84, + /// Key: U | u + KeyU = 85, + /// Key: V | v + KeyV = 86, + /// Key: W | w + KeyW = 87, + /// Key: X | x + KeyX = 88, + /// Key: Y | y + KeyY = 89, + /// Key: Z | z + KeyZ = 90, + /// Key: [ + KeyLeftBracket = 91, + /// Key: '\' + KeyBackslash = 92, + /// Key: ] + KeyRightBracket = 93, + /// Key: ` + KeyGrave = 96, + /// Key: Space + KeySpace = 32, + /// Key: Esc + KeyEscape = 256, + /// Key: Enter + KeyEnter = 257, + /// Key: Tab + KeyTab = 258, + /// Key: Backspace + KeyBackspace = 259, + /// Key: Ins + KeyInsert = 260, + /// Key: Del + KeyDelete = 261, + /// Key: Cursor right + KeyRight = 262, + /// Key: Cursor left + KeyLeft = 263, + /// Key: Cursor down + KeyDown = 264, + /// Key: Cursor up + KeyUp = 265, + /// Key: Page up + KeyPageUp = 266, + /// Key: Page down + KeyPageDown = 267, + /// Key: Home + KeyHome = 268, + /// Key: End + KeyEnd = 269, + /// Key: Caps lock + KeyCapsLock = 280, + /// Key: Scroll down + KeyScrollLock = 281, + /// Key: Num lock + KeyNumLock = 282, + /// Key: Print screen + KeyPrintScreen = 283, + /// Key: Pause + KeyPause = 284, + /// Key: F1 + KeyF1 = 290, + /// Key: F2 + KeyF2 = 291, + /// Key: F3 + KeyF3 = 292, + /// Key: F4 + KeyF4 = 293, + /// Key: F5 + KeyF5 = 294, + /// Key: F6 + KeyF6 = 295, + /// Key: F7 + KeyF7 = 296, + /// Key: F8 + KeyF8 = 297, + /// Key: F9 + KeyF9 = 298, + /// Key: F10 + KeyF10 = 299, + /// Key: F11 + KeyF11 = 300, + /// Key: F12 + KeyF12 = 301, + /// Key: Shift left + KeyLeftShift = 340, + /// Key: Control left + KeyLeftControl = 341, + /// Key: Alt left + KeyLeftAlt = 342, + /// Key: Super left + KeyLeftSuper = 343, + /// Key: Shift right + KeyRightShift = 344, + /// Key: Control right + KeyRightControl = 345, + /// Key: Alt right + KeyRightAlt = 346, + /// Key: Super right + KeyRightSuper = 347, + /// Key: KB menu + KeyKbMenu = 348, + /// Key: Keypad 0 + KeyKp0 = 320, + /// Key: Keypad 1 + KeyKp1 = 321, + /// Key: Keypad 2 + KeyKp2 = 322, + /// Key: Keypad 3 + KeyKp3 = 323, + /// Key: Keypad 4 + KeyKp4 = 324, + /// Key: Keypad 5 + KeyKp5 = 325, + /// Key: Keypad 6 + KeyKp6 = 326, + /// Key: Keypad 7 + KeyKp7 = 327, + /// Key: Keypad 8 + KeyKp8 = 328, + /// Key: Keypad 9 + KeyKp9 = 329, + /// Key: Keypad . + KeyKpDecimal = 330, + /// Key: Keypad / + KeyKpDivide = 331, + /// Key: Keypad * + KeyKpMultiply = 332, + /// Key: Keypad - + KeyKpSubtract = 333, + /// Key: Keypad + + KeyKpAdd = 334, + /// Key: Keypad Enter + KeyKpEnter = 335, + /// Key: Keypad = + KeyKpEqual = 336, + /// Key: Android back button + KeyBack = 4, + /// Key: Android volume up button + KeyVolumeUp = 24, + /// Key: Android volume down button + KeyVolumeDown = 25, +} + +/// Mouse buttons +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum MouseButton { + /// Mouse button left + MouseButtonLeft = 0, + /// Mouse button right + MouseButtonRight = 1, + /// Mouse button middle (pressed wheel) + MouseButtonMiddle = 2, + /// Mouse button side (advanced mouse device) + MouseButtonSide = 3, + /// Mouse button extra (advanced mouse device) + MouseButtonExtra = 4, + /// Mouse button forward (advanced mouse device) + MouseButtonForward = 5, + /// Mouse button back (advanced mouse device) + MouseButtonBack = 6, +} + +/// Mouse cursor +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum MouseCursor { + /// Default pointer shape + MouseCursorDefault = 0, + /// Arrow shape + MouseCursorArrow = 1, + /// Text writing cursor shape + MouseCursorIbeam = 2, + /// Cross shape + MouseCursorCrosshair = 3, + /// Pointing hand cursor + MouseCursorPointingHand = 4, + /// Horizontal resize/move arrow shape + MouseCursorResizeEw = 5, + /// Vertical resize/move arrow shape + MouseCursorResizeNs = 6, + /// Top-left to bottom-right diagonal resize/move arrow shape + MouseCursorResizeNwse = 7, + /// The top-right to bottom-left diagonal resize/move arrow shape + MouseCursorResizeNesw = 8, + /// The omnidirectional resize/move cursor shape + MouseCursorResizeAll = 9, + /// The operation-not-allowed shape + MouseCursorNotAllowed = 10, +} + +/// Gamepad buttons +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum GamepadButton { + /// Unknown button, just for error checking + GamepadButtonUnknown = 0, + /// Gamepad left DPAD up button + GamepadButtonLeftFaceUp = 1, + /// Gamepad left DPAD right button + GamepadButtonLeftFaceRight = 2, + /// Gamepad left DPAD down button + GamepadButtonLeftFaceDown = 3, + /// Gamepad left DPAD left button + GamepadButtonLeftFaceLeft = 4, + /// Gamepad right button up (i.e. PS3: Triangle, Xbox: Y) + GamepadButtonRightFaceUp = 5, + /// Gamepad right button right (i.e. PS3: Square, Xbox: X) + GamepadButtonRightFaceRight = 6, + /// Gamepad right button down (i.e. PS3: Cross, Xbox: A) + GamepadButtonRightFaceDown = 7, + /// Gamepad right button left (i.e. PS3: Circle, Xbox: B) + GamepadButtonRightFaceLeft = 8, + /// Gamepad top/back trigger left (first), it could be a trailing button + GamepadButtonLeftTrigger1 = 9, + /// Gamepad top/back trigger left (second), it could be a trailing button + GamepadButtonLeftTrigger2 = 10, + /// Gamepad top/back trigger right (one), it could be a trailing button + GamepadButtonRightTrigger1 = 11, + /// Gamepad top/back trigger right (second), it could be a trailing button + GamepadButtonRightTrigger2 = 12, + /// Gamepad center buttons, left one (i.e. PS3: Select) + GamepadButtonMiddleLeft = 13, + /// Gamepad center buttons, middle one (i.e. PS3: PS, Xbox: XBOX) + GamepadButtonMiddle = 14, + /// Gamepad center buttons, right one (i.e. PS3: Start) + GamepadButtonMiddleRight = 15, + /// Gamepad joystick pressed button left + GamepadButtonLeftThumb = 16, + /// Gamepad joystick pressed button right + GamepadButtonRightThumb = 17, +} + +/// Gamepad axis +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum GamepadAxis { + /// Gamepad left stick X axis + GamepadAxisLeftX = 0, + /// Gamepad left stick Y axis + GamepadAxisLeftY = 1, + /// Gamepad right stick X axis + GamepadAxisRightX = 2, + /// Gamepad right stick Y axis + GamepadAxisRightY = 3, + /// Gamepad back trigger left, pressure level: [1..-1] + GamepadAxisLeftTrigger = 4, + /// Gamepad back trigger right, pressure level: [1..-1] + GamepadAxisRightTrigger = 5, +} + +/// Material map index +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum MaterialMapIndex { + /// Albedo material (same as: MATERIAL_MAP_DIFFUSE) + MaterialMapAlbedo = 0, + /// Metalness material (same as: MATERIAL_MAP_SPECULAR) + MaterialMapMetalness = 1, + /// Normal material + MaterialMapNormal = 2, + /// Roughness material + MaterialMapRoughness = 3, + /// Ambient occlusion material + MaterialMapOcclusion = 4, + /// Emission material + MaterialMapEmission = 5, + /// Heightmap material + MaterialMapHeight = 6, + /// Cubemap material (NOTE: Uses GL_TEXTURE_CUBE_MAP) + MaterialMapCubemap = 7, + /// Irradiance material (NOTE: Uses GL_TEXTURE_CUBE_MAP) + MaterialMapIrradiance = 8, + /// Prefilter material (NOTE: Uses GL_TEXTURE_CUBE_MAP) + MaterialMapPrefilter = 9, + /// Brdf material + MaterialMapBrdf = 10, +} + +/// Shader location index +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum ShaderLocationIndex { + /// Shader location: vertex attribute: position + ShaderLocVertexPosition = 0, + /// Shader location: vertex attribute: texcoord01 + ShaderLocVertexTexcoord01 = 1, + /// Shader location: vertex attribute: texcoord02 + ShaderLocVertexTexcoord02 = 2, + /// Shader location: vertex attribute: normal + ShaderLocVertexNormal = 3, + /// Shader location: vertex attribute: tangent + ShaderLocVertexTangent = 4, + /// Shader location: vertex attribute: color + ShaderLocVertexColor = 5, + /// Shader location: matrix uniform: model-view-projection + ShaderLocMatrixMvp = 6, + /// Shader location: matrix uniform: view (camera transform) + ShaderLocMatrixView = 7, + /// Shader location: matrix uniform: projection + ShaderLocMatrixProjection = 8, + /// Shader location: matrix uniform: model (transform) + ShaderLocMatrixModel = 9, + /// Shader location: matrix uniform: normal + ShaderLocMatrixNormal = 10, + /// Shader location: vector uniform: view + ShaderLocVectorView = 11, + /// Shader location: vector uniform: diffuse color + ShaderLocColorDiffuse = 12, + /// Shader location: vector uniform: specular color + ShaderLocColorSpecular = 13, + /// Shader location: vector uniform: ambient color + ShaderLocColorAmbient = 14, + /// Shader location: sampler2d texture: albedo (same as: SHADER_LOC_MAP_DIFFUSE) + ShaderLocMapAlbedo = 15, + /// Shader location: sampler2d texture: metalness (same as: SHADER_LOC_MAP_SPECULAR) + ShaderLocMapMetalness = 16, + /// Shader location: sampler2d texture: normal + ShaderLocMapNormal = 17, + /// Shader location: sampler2d texture: roughness + ShaderLocMapRoughness = 18, + /// Shader location: sampler2d texture: occlusion + ShaderLocMapOcclusion = 19, + /// Shader location: sampler2d texture: emission + ShaderLocMapEmission = 20, + /// Shader location: sampler2d texture: height + ShaderLocMapHeight = 21, + /// Shader location: samplerCube texture: cubemap + ShaderLocMapCubemap = 22, + /// Shader location: samplerCube texture: irradiance + ShaderLocMapIrradiance = 23, + /// Shader location: samplerCube texture: prefilter + ShaderLocMapPrefilter = 24, + /// Shader location: sampler2d texture: brdf + ShaderLocMapBrdf = 25, +} + +/// Shader uniform data type +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum ShaderUniformDataType { + /// Shader uniform type: float + ShaderUniformFloat = 0, + /// Shader uniform type: vec2 (2 float) + ShaderUniformVec2 = 1, + /// Shader uniform type: vec3 (3 float) + ShaderUniformVec3 = 2, + /// Shader uniform type: vec4 (4 float) + ShaderUniformVec4 = 3, + /// Shader uniform type: int + ShaderUniformInt = 4, + /// Shader uniform type: ivec2 (2 int) + ShaderUniformIvec2 = 5, + /// Shader uniform type: ivec3 (3 int) + ShaderUniformIvec3 = 6, + /// Shader uniform type: ivec4 (4 int) + ShaderUniformIvec4 = 7, + /// Shader uniform type: sampler2d + ShaderUniformSampler2d = 8, +} + +/// Shader attribute data types +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum ShaderAttributeDataType { + /// Shader attribute type: float + ShaderAttribFloat = 0, + /// Shader attribute type: vec2 (2 float) + ShaderAttribVec2 = 1, + /// Shader attribute type: vec3 (3 float) + ShaderAttribVec3 = 2, + /// Shader attribute type: vec4 (4 float) + ShaderAttribVec4 = 3, +} + +/// Pixel formats +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum PixelFormat { + /// 8 bit per pixel (no alpha) + PixelformatUncompressedGrayscale = 1, + /// 8*2 bpp (2 channels) + PixelformatUncompressedGrayAlpha = 2, + /// 16 bpp + PixelformatUncompressedR5g6b5 = 3, + /// 24 bpp + PixelformatUncompressedR8g8b8 = 4, + /// 16 bpp (1 bit alpha) + PixelformatUncompressedR5g5b5a1 = 5, + /// 16 bpp (4 bit alpha) + PixelformatUncompressedR4g4b4a4 = 6, + /// 32 bpp + PixelformatUncompressedR8g8b8a8 = 7, + /// 32 bpp (1 channel - float) + PixelformatUncompressedR32 = 8, + /// 32*3 bpp (3 channels - float) + PixelformatUncompressedR32g32b32 = 9, + /// 32*4 bpp (4 channels - float) + PixelformatUncompressedR32g32b32a32 = 10, + /// 4 bpp (no alpha) + PixelformatCompressedDxt1Rgb = 11, + /// 4 bpp (1 bit alpha) + PixelformatCompressedDxt1Rgba = 12, + /// 8 bpp + PixelformatCompressedDxt3Rgba = 13, + /// 8 bpp + PixelformatCompressedDxt5Rgba = 14, + /// 4 bpp + PixelformatCompressedEtc1Rgb = 15, + /// 4 bpp + PixelformatCompressedEtc2Rgb = 16, + /// 8 bpp + PixelformatCompressedEtc2EacRgba = 17, + /// 4 bpp + PixelformatCompressedPvrtRgb = 18, + /// 4 bpp + PixelformatCompressedPvrtRgba = 19, + /// 8 bpp + PixelformatCompressedAstc4x4Rgba = 20, + /// 2 bpp + PixelformatCompressedAstc8x8Rgba = 21, +} + +/// Texture parameters: filter mode +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum TextureFilter { + /// No filter, just pixel approximation + TextureFilterPoint = 0, + /// Linear filtering + TextureFilterBilinear = 1, + /// Trilinear filtering (linear with mipmaps) + TextureFilterTrilinear = 2, + /// Anisotropic filtering 4x + TextureFilterAnisotropic4x = 3, + /// Anisotropic filtering 8x + TextureFilterAnisotropic8x = 4, + /// Anisotropic filtering 16x + TextureFilterAnisotropic16x = 5, +} + +/// Texture parameters: wrap mode +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum TextureWrap { + /// Repeats texture in tiled mode + TextureWrapRepeat = 0, + /// Clamps texture to edge pixel in tiled mode + TextureWrapClamp = 1, + /// Mirrors and repeats the texture in tiled mode + TextureWrapMirrorRepeat = 2, + /// Mirrors and clamps to border the texture in tiled mode + TextureWrapMirrorClamp = 3, +} + +/// Cubemap layouts +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum CubemapLayout { + /// Automatically detect layout type + CubemapLayoutAutoDetect = 0, + /// Layout is defined by a vertical line with faces + CubemapLayoutLineVertical = 1, + /// Layout is defined by a horizontal line with faces + CubemapLayoutLineHorizontal = 2, + /// Layout is defined by a 3x4 cross with cubemap faces + CubemapLayoutCrossThreeByFour = 3, + /// Layout is defined by a 4x3 cross with cubemap faces + CubemapLayoutCrossFourByThree = 4, + /// Layout is defined by a panorama image (equirrectangular map) + CubemapLayoutPanorama = 5, +} + +/// Font type, defines generation method +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum FontType { + /// Default font generation, anti-aliased + FontDefault = 0, + /// Bitmap font generation, no anti-aliasing + FontBitmap = 1, + /// SDF font generation, requires external shader + FontSdf = 2, +} + +/// Color blending modes (pre-defined) +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum BlendMode { + /// Blend textures considering alpha (default) + BlendAlpha = 0, + /// Blend textures adding colors + BlendAdditive = 1, + /// Blend textures multiplying colors + BlendMultiplied = 2, + /// Blend textures adding colors (alternative) + BlendAddColors = 3, + /// Blend textures subtracting colors (alternative) + BlendSubtractColors = 4, + /// Blend premultiplied textures considering alpha + BlendAlphaPremultiply = 5, + /// Blend textures using custom src/dst factors (use rlSetBlendFactors()) + BlendCustom = 6, + /// Blend textures using custom rgb/alpha separate src/dst factors (use rlSetBlendFactorsSeparate()) + BlendCustomSeparate = 7, +} + +/// Gesture +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum Gesture { + /// No gesture + GestureNone = 0, + /// Tap gesture + GestureTap = 1, + /// Double tap gesture + GestureDoubletap = 2, + /// Hold gesture + GestureHold = 4, + /// Drag gesture + GestureDrag = 8, + /// Swipe right gesture + GestureSwipeRight = 16, + /// Swipe left gesture + GestureSwipeLeft = 32, + /// Swipe up gesture + GestureSwipeUp = 64, + /// Swipe down gesture + GestureSwipeDown = 128, + /// Pinch in gesture + GesturePinchIn = 256, + /// Pinch out gesture + GesturePinchOut = 512, +} + +/// Camera system modes +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum CameraMode { + /// Custom camera + CameraCustom = 0, + /// Free camera + CameraFree = 1, + /// Orbital camera + CameraOrbital = 2, + /// First person camera + CameraFirstPerson = 3, + /// Third person camera + CameraThirdPerson = 4, +} + +/// Camera projection +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum CameraProjection { + /// Perspective projection + CameraPerspective = 0, + /// Orthographic projection + CameraOrthographic = 1, +} + +/// N-patch layout +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum NPatchLayout { + /// Npatch layout: 3x3 tiles + NpatchNinePatch = 0, + /// Npatch layout: 1x3 tiles + NpatchThreePatchVertical = 1, + /// Npatch layout: 3x1 tiles + NpatchThreePatchHorizontal = 2, +} diff --git a/src/lib.rs b/src/lib.rs index 23a4bca..b91326e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,4 +4,14 @@ #![allow(non_snake_case)] // Include the generated bindings -include!(concat!(env!("OUT_DIR"), "/bindings.rs")); \ No newline at end of file +include!(concat!(env!("OUT_DIR"), "/bindings.rs")); + +#[cfg(feature = "enums")] +pub mod enums; + +#[cfg(feature = "macros")] +#[macro_use] +pub mod macros; + +#[cfg(feature = "colors")] +pub mod colors; \ No newline at end of file diff --git a/src/macros.rs b/src/macros.rs new file mode 100644 index 0000000..26ea25f --- /dev/null +++ b/src/macros.rs @@ -0,0 +1,31 @@ +//! Quality of life macros + +/// Begins drawing, creates a new scope, executes code, then cleans up +/// +/// ## Example +/// ```no_run +/// # use raylib_ffi::draw; +/// # fn main(){ unsafe { +/// draw!({ +/// // Graphics code here.. +/// }); +/// # }} +/// ``` +#[macro_export] +macro_rules! draw { + ($expression:expr) => { + raylib_ffi::BeginDrawing(); + { + $expression + } + raylib_ffi::EndDrawing(); + }; +} + +/// Converts a string to `*const i8` for use with raylib +#[macro_export] +macro_rules! rl_str { + ($expression:expr) => { + format!("{}\0", $expression).as_ptr() as *const i8 + }; +} \ No newline at end of file