diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..642b88b --- /dev/null +++ b/.editorconfig @@ -0,0 +1,19 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 8 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[*.{c,h}] +indent_size = 4 + +[*.lua] +indent_size = 4 +max_line_length = 120 + +[*.nix] +indent_size = 2 diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..3550a30 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake diff --git a/.gitignore b/.gitignore index 122ecdd..98f7c04 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ +/.direnv/ + +/build/ + # Compiled Lua sources luac.out @@ -40,6 +44,7 @@ luac.out # Avoid ignoring release execs !release/win32/rlua.exe -!src/external/lua/lib/liblua53.a -!src/external/lua/lib/liblua53dll.a -!src/external/lua/lib/lua53.dll +!src/external/lua/lib/liblua55.a +!src/external/lua/lib/liblua55.so +!src/external/lua/lib-win64/liblua55.a +!src/external/lua/lib-win64/lua55.dll diff --git a/.luarc.jsonc b/.luarc.jsonc new file mode 100644 index 0000000..3a696cb --- /dev/null +++ b/.luarc.jsonc @@ -0,0 +1,32 @@ +{ + "$schema": "https://raw.githubusercontent.com/LuaLS/vscode-lua/master/setting/schema.json", + "runtime": { + "version": "Lua 5.5", + }, + "workspace": { + "checkThirdParty": false + }, + "diagnostics": { + "unusedLocalExclude": [ + "_*" + ], + "groupFileStatus": { + "ambiguity": "Any", + "duplicate": "Any", + "global": "Any", + "luadoc": "None", + "redefined": "Any", + "strict": "Any", + "strong": "None", + "type-check": "Any", + "unbalanced": "Any", + "unused": "Any" + } + }, + "hint": { + "enable": true, + "setType": true, + "paramType": true, + "paramName": "All" + } +} diff --git a/.stylua.toml b/.stylua.toml new file mode 100644 index 0000000..a69d6bf --- /dev/null +++ b/.stylua.toml @@ -0,0 +1,13 @@ +block_newline_gaps = "Never" +call_parentheses = "Always" +collapse_simple_statement = "Never" +column_width = 120 +indent_type = "Spaces" +indent_width = 4 +line_endings = "Unix" +quote_style = "AutoPreferDouble" +space_after_function_names = "Never" +syntax = "Lua54" # TODO: update to Lua55 once https://github.com/Kampfkarren/full-moon/pull/356 is merged + +[sort_requires] +enabled = true diff --git a/LICENSE b/LICENSE index 5aab379..91ed83f 100644 --- a/LICENSE +++ b/LICENSE @@ -2,6 +2,7 @@ raylib-lua is licensed under an unmodified zlib/libpng license, which is an OSI- BSD-like license that allows static linking with closed source software: Copyright (c) 2016-2017 Ghassan Al-Mashareqa and Ramon Santamaria (@raysan5) +Copyright (c) 2026 yilisharcs This software is provided "as-is", without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/README.md b/README.md index 3d85649..426085f 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,46 @@ -Lua bindings for raylib, a simple and easy-to-use library to enjoy videogames programming (www.raylib.com) +Lua 5.5 bindings for raylib v6.0, a simple and easy-to-use library to enjoy videogames programming (www.raylib.com) raylib-lua binding is self-contained in a header-only file: [raylib-lua.h](src/raylib-lua.h). Just include that file in your project to allow loading and execution of raylib code written in Lua. Check [code examples](examples) for reference. +As a bonus, include [\_meta.lua](src/_meta.lua) to have LSP support. raylib-lua could be useful for prototyping, tools development, graphic applications, embedded systems and education.

-**WARNING: Current raylib-lua binding is very outdated! It's based on raylib 1.7 and port to newer raylib versions is stopped. Consider switching to [raylib-lua-sol](https://github.com/RobLoach/raylib-lua-sol), updated to latest raylib 2.6.** +### Build and Usage +A Linux build script is provided to compile the library and the launcher: + +```bash +./build.lua +``` + +It supports both X11 (default) and Wayland backends. For Wayland: + +```bash +CFLAGS="-D_GLFW_WAYLAND" ./build.lua +``` ### rLuaLauncher A raylib-lua launcher is also provided: [rluaLauncher](tools/rLuaLauncher/rlualauncher.c). This launcher allows you to run raylib-lua -programs from command line, or just with *drag & drop* of .lua files into *rlualauncher.exe*. +programs from the command line: + +```bash +./build/rlualauncher examples/core/core_basic_window.lua +``` -Note that launcher can also be compiled for other platforms, just need to link with Lua library and raylib library. +Note that the launcher can also be compiled for other platforms, just link with the Lua library and raylib library. For more details, just check comments on sources. ### rLuaParser -In an effort to automatize raylib-lua binding generation I created [rLuaParser](https://github.com/raysan5/raylib-lua/tree/master/tools/rLuaParser), unfortunately there are several side cases that are not solved yet on the parsing, specially when dealing with opaque data types. Any help or contribution is welcome! +The bindings are automatically generated using [rLuaParser](tools/rLuaParser/rluaparser.lua), which replaces the old C parser. It +parses `raylib.h` to generate the C header-only binding and Lua metadata. The current implementation +may be incomplete; any help or contribution is welcome! # License @@ -30,3 +48,4 @@ raylib-lua is licensed under an unmodified zlib/libpng license, which is an OSI- BSD-like license that allows static linking with closed source software. Check [LICENSE](LICENSE) for further details. *Copyright (c) 2016-2019 Ghassan Al-Mashareqa and Ramon Santamaria ([@raysan5](https://twitter.com/raysan5))* +*Copyright (c) 2026 yilisharcs ([@yilisharcs](https://twitter.com/yilisharcs))* diff --git a/build.lua b/build.lua new file mode 100755 index 0000000..f9d0b98 --- /dev/null +++ b/build.lua @@ -0,0 +1,205 @@ +#!/usr/bin/env lua + +local u = assert(io.popen("uname -s"), "popen failed") +local uname = u:read("*l") + +-- TODO: add Windows support (MinGW or MSVC toolchain, Win32 platform libs) +if uname ~= "Linux" then + print("ERROR: this build script only supports Linux (detected: " .. tostring(uname) .. ")") + os.exit(1) +end + +local CC = os.getenv("CC") or "gcc" +local AR = os.getenv("AR") or "ar" +local CFLAGS = os.getenv("CFLAGS") or "" +local LDFLAGS = os.getenv("LDFLAGS") or "" +local BUILD = os.getenv("BUILD_DIR") or "build" +local RAYLIB_SRC_PATH = os.getenv("RAYLIB_SRC_PATH") or "../raylib/src" + +-- library types: STATIC or SHARED +local RAYLIB_LIBTYPE = os.getenv("RAYLIB_LIBTYPE") or "STATIC" +local LUA_LIBTYPE = os.getenv("LUA_LIBTYPE") or "STATIC" + +-- backend: X11 default (alt: -D_GLFW_WAYLAND in CFLAGS) +local glfw_flag = CFLAGS:match("-D_GLFW_[%w_]+") or "-D_GLFW_X11" +local platform_libs = glfw_flag:find("WAYLAND") and "-lwayland-client -lwayland-cursor -lwayland-egl -lxkbcommon" + or "-lX11" + +local common_libs = table.concat({ + "-lGL", -- OpenGL + "-lm", -- math functions, used internally + "-lpthread", -- POSIX threads + "-ldl", -- dlopen/dlsym + "-lrt", -- real-time extensions + platform_libs, +}, " ") + +local function exists(path) + local f = io.open(path, "r") + return f ~= nil +end + +local function run(cmd) + print(cmd) + local ok = os.execute(cmd) + if not ok then + os.exit(1) + end +end + +os.execute("mkdir -p " .. BUILD) + +-- libraylib +local raylib_lib = (RAYLIB_LIBTYPE == "SHARED") and (BUILD .. "/libraylib.so") or (BUILD .. "/libraylib.a") + +-- invalidate cache on backend switch +local marker_path = BUILD .. "/.backend" +local m_in = io.open(marker_path, "r") +local old_backend = m_in and m_in:read("*l") or "" + +if old_backend ~= glfw_flag and exists(raylib_lib) then + print("INFO: backend changed; rebuilding raylib") + os.execute("rm " .. raylib_lib) +end + +-- generate wayland protocol headers from bundled XML +if glfw_flag:find("WAYLAND") then + local wl_deps = RAYLIB_SRC_PATH .. "/external/glfw/deps/wayland" + local protocols = { + "fractional-scale-v1.xml", + "idle-inhibit-unstable-v1.xml", + "pointer-constraints-unstable-v1.xml", + "relative-pointer-unstable-v1.xml", + "viewporter.xml", + "wayland.xml", + "xdg-activation-v1.xml", + "xdg-decoration-unstable-v1.xml", + "xdg-shell.xml", + } + for _, xml in ipairs(protocols) do + local base = xml:gsub("%.xml$", "") + run(("wayland-scanner client-header %s/%s %s/%s-client-protocol.h"):format(wl_deps, xml, BUILD, base)) + run(("wayland-scanner private-code %s/%s %s/%s-client-protocol-code.h"):format(wl_deps, xml, BUILD, base)) + end +end + +if not exists(raylib_lib) then + local raylib_sources = { + RAYLIB_SRC_PATH .. "/raudio.c", + RAYLIB_SRC_PATH .. "/rcore.c", + RAYLIB_SRC_PATH .. "/rglfw.c", + RAYLIB_SRC_PATH .. "/rmodels.c", + RAYLIB_SRC_PATH .. "/rshapes.c", + RAYLIB_SRC_PATH .. "/rtext.c", + RAYLIB_SRC_PATH .. "/rtextures.c", + } + + local raylib_cflags = table.concat({ + "-std=c99", + "-DPLATFORM_DESKTOP_GLFW", + "-DGRAPHICS_API_OPENGL_33", + "-D_GNU_SOURCE", + glfw_flag, + -- raylib default, good balance of speed and perf + "-O1", + "-Wall", + -- required for shared, safe for static + "-fPIC", + CFLAGS, + -- [[ INCLUDES ]] + "-I" .. RAYLIB_SRC_PATH, + "-I" .. RAYLIB_SRC_PATH .. "/external/glfw/include", + "-I" .. BUILD, + }, " ") + + if RAYLIB_LIBTYPE == "SHARED" then + run(table.concat({ + CC, + "-o", + raylib_lib, + "-shared", + raylib_cflags, + table.concat(raylib_sources, " "), + -- [[ LIBS ]] + common_libs, + LDFLAGS, + }, " ")) + else + -- compile raylib into object files for the static lib archive + local objs = {} + for _, src in ipairs(raylib_sources) do + local obj = BUILD .. "/" .. src:match("([^/]+)%.c$") .. ".o" + run(table.concat({ + CC, + "-c", + src, + "-o", + obj, + raylib_cflags, + }, " ")) + table.insert(objs, obj) + end + -- generate archive + run(table.concat({ + AR, + "rcs", + raylib_lib, + table.concat(objs, " "), + }, " ")) + -- cleanup artifacts + run("rm " .. table.concat(objs, " ")) + end + + local m = io.open(marker_path, "w") + if m then + m:write(glfw_flag) + end +else + print(raylib_lib .. " found; skipping (cached)") +end + +-- tools/rLuaLauncher/rlualauncher.c +local lua_lib_path = "src/external/lua/lib/liblua55.a" +if LUA_LIBTYPE == "SHARED" then + lua_lib_path = "-llua55" + -- deploy .so for shared build + if exists("src/external/lua/lib/liblua55.so") then + run("cp src/external/lua/lib/liblua55.so " .. BUILD .. "/liblua55.so") + end +end + +local raylib_link = (RAYLIB_LIBTYPE == "SHARED") and "-lraylib" or raylib_lib + +run(table.concat({ + CC, + "-o", + BUILD .. "/rlualauncher", + "-std=c99", + -- raylib default, good balance of speed and perf + "-O1", + "-Wall", + CFLAGS, + -- [[ INCLUDES ]] + "-I" .. RAYLIB_SRC_PATH, + "-Isrc", + "-Isrc/external/lua/include", + -- [[ SOURCES ]] + "tools/rLuaLauncher/rlualauncher.c", + -- prepend lib dirs to the linker path + "-L" .. BUILD, + "-Lsrc/external/lua/lib", + -- [[ LIBS ]] + raylib_link, + lua_lib_path, + common_libs, + LDFLAGS, + -- embed the executable's dir as the dll search path at runtime + "-Wl,-rpath,'$ORIGIN'", +}, " ")) + +print("---") +print(raylib_lib) +print(BUILD .. "/rlualauncher") +if LUA_LIBTYPE == "SHARED" then + print(BUILD .. "/liblua55.so") +end diff --git a/examples/core/core_basic_window.lua b/examples/core/core_basic_window.lua index ea3337a..981d37f 100644 --- a/examples/core/core_basic_window.lua +++ b/examples/core/core_basic_window.lua @@ -1,26 +1,27 @@ -------------------------------------------------------------------------------------------- +-------------------------------------------------------------------------------------- -- -- raylib [core] example - Basic window -- --- This example has been created using raylib 1.6 (www.raylib.com) +-- This example has been created using raylib 6.0 (www.raylib.com) -- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) -- -- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) +-- Copyright (c) 2026 yilisharcs -- -------------------------------------------------------------------------------------------- +-------------------------------------------------------------------------------------- -- Initialization -------------------------------------------------------------------------------------------- +-------------------------------------------------------------------------------------- local screenWidth = 800 local screenHeight = 450 -InitWindow(screenWidth, screenHeight, "raylib [core] example - basic window") +rl.InitWindow(screenWidth, screenHeight, "raylib [core] example - basic window") -SetTargetFPS(60) -- Set target frames-per-second -------------------------------------------------------------------------------------------- +rl.SetTargetFPS(60); -- Set our game to run at 60 frames-per-second +-------------------------------------------------------------------------------------- -- Main game loop -while not WindowShouldClose() do -- Detect window close button or ESC key +while not rl.WindowShouldClose() do -- Detect window close button or ESC key -- Update --------------------------------------------------------------------------------------- -- TODO: Update your variables here @@ -28,17 +29,17 @@ while not WindowShouldClose() do -- Detect window close button or ESC -- Draw --------------------------------------------------------------------------------------- - BeginDrawing() + rl.BeginDrawing() - ClearBackground(RAYWHITE) + rl.ClearBackground(rl.RAYWHITE) - DrawText("Congrats! You created your first window!", 190, 200, 20, LIGHTGRAY) + rl.DrawText("Congrats! You created your first window!", 190, 200, 20, rl.LIGHTGRAY) - EndDrawing() + rl.EndDrawing() --------------------------------------------------------------------------------------- end -- De-Initialization -------------------------------------------------------------------------------------------- -CloseWindow() -- Close window and OpenGL context -------------------------------------------------------------------------------------------- \ No newline at end of file +-------------------------------------------------------------------------------------- +rl.CloseWindow() -- Close window and OpenGL context +-------------------------------------------------------------------------------------- diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..f52cab9 --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1779560665, + "narHash": "sha256-tpyBcxPpcQb8ukyNF7DoCwfSY3VPsxHoYwj00Cayv5o=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "64c08a7ca051951c8eae34e3e3cb1e202fe36786", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..81b3010 --- /dev/null +++ b/flake.nix @@ -0,0 +1,36 @@ +{ + description = "raylib-lua"; + + inputs.nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; + + outputs = { + self, + nixpkgs, + }: let + system = "x86_64-linux"; + pkgs = nixpkgs.legacyPackages.${system}; + in { + devShells.${system}.default = pkgs.mkShell { + buildInputs = [ + pkgs.lua5_5 + # opengl + pkgs.libGL + # x11 + pkgs.libX11 + pkgs.libXcursor + pkgs.libXi + pkgs.libXinerama + pkgs.libXrandr + # wayland + pkgs.wayland + pkgs.wayland-scanner + pkgs.libxkbcommon + ## web support + # pkgs.emscripten + ]; + + ## audio + # LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath [pkgs.alsa-lib]; + }; + }; +} diff --git a/src/_meta.lua b/src/_meta.lua new file mode 100644 index 0000000..29ad42f --- /dev/null +++ b/src/_meta.lua @@ -0,0 +1,5032 @@ +---@meta _ +--[[ ********************************************************************************************** + + raylib-lua v6.0 - raylib Lua type definitions for LuaLS + + AUTO-GENERATED by tools/rLuaParser/rluaparser.lua + + LICENSE: zlib/libpng + + Copyright (c) 2026 yilisharcs + +************************************************************************************************ ]] + +error("Cannot require a meta file") + +--- AudioStream, custom audio stream +---@class rl.AudioStream +--- Pointer to internal data used by the audio system +---@field buffer userdata +--- Pointer to internal data processor, useful for audio effects +---@field processor userdata +--- Frequency (samples per second) +---@field sampleRate integer +--- Bit depth (bits per sample): 8, 16, 32 (24 not supported) +---@field sampleSize integer +--- Number of channels (1-mono, 2-stereo, ...) +---@field channels integer + +--- Automation event +---@class rl.AutomationEvent +--- Event frame +---@field frame integer +--- Event type (AutomationEventType) +---@field type integer +--- Event parameters (if required) +---@field params { [1]: integer, [2]: integer, [3]: integer, [4]: integer } + +--- Automation event list +---@class rl.AutomationEventList +--- Events max entries (MAX_AUTOMATION_EVENTS) +---@field capacity integer +--- Events entries count +---@field count integer +--- Events entries +---@field events userdata + +--- Bone, skeletal animation bone +---@class rl.BoneInfo +--- Bone name +---@field name string +--- Bone parent +---@field parent integer + +--- BoundingBox +---@class rl.BoundingBox +--- Minimum vertex box-corner +---@field min rl.Vector3 +--- Maximum vertex box-corner +---@field max rl.Vector3 + +--- Camera2D, defines position/orientation in 2d space +---@class rl.Camera2D +--- Camera offset (screen space offset from window origin) +---@field offset rl.Vector2 +--- Camera target (world space target point that is mapped to screen space offset) +---@field target rl.Vector2 +--- Camera rotation in degrees (pivots around target) +---@field rotation number +--- Camera zoom (scaling around target), must not be set to 0, set to 1.0f for no scale +---@field zoom number + +--- Camera, defines position/orientation in 3d space +---@class rl.Camera3D +--- Camera position +---@field position rl.Vector3 +--- Camera target it looks-at +---@field target rl.Vector3 +--- Camera up vector (rotation over its axis) +---@field up rl.Vector3 +--- Camera field-of-view aperture in Y (degrees) in perspective, used as near plane height in world units in orthographic +---@field fovy number +--- Camera projection: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC +---@field projection integer + +--- Color, 4 components, R8G8B8A8 (32bit) +---@class rl.Color +--- Color red value +---@field r integer +--- Color green value +---@field g integer +--- Color blue value +---@field b integer +--- Color alpha value +---@field a integer + +--- File path list +---@class rl.FilePathList +--- Filepaths entries count +---@field count integer +--- Filepaths entries +---@field paths userdata + +--- Font, font texture and GlyphInfo array data +---@class rl.Font +--- Base size (default chars height) +---@field baseSize integer +--- Number of glyph characters +---@field glyphCount integer +--- Padding around the glyph characters +---@field glyphPadding integer +--- Texture atlas containing the glyphs +---@field texture rl.Texture +--- Rectangles in texture for the glyphs +---@field recs userdata +--- Glyphs info data +---@field glyphs userdata + +--- GlyphInfo, font characters glyphs info +---@class rl.GlyphInfo +--- Character value (Unicode) +---@field value integer +--- Character offset X when drawing +---@field offsetX integer +--- Character offset Y when drawing +---@field offsetY integer +--- Character advance position X +---@field advanceX integer +--- Character image data +---@field image rl.Image + +--- Image, pixel data stored in CPU memory (RAM) +---@class rl.Image +--- Image raw data +---@field data userdata +--- Image base width +---@field width integer +--- Image base height +---@field height integer +--- Mipmap levels, 1 by default +---@field mipmaps integer +--- Data format (PixelFormat type) +---@field format integer + +--- Material, includes shader and maps +---@class rl.Material +--- Material shader +---@field shader rl.Shader +--- Material maps array (MAX_MATERIAL_MAPS) +---@field maps userdata +--- Material generic parameters (if required) +---@field params { [1]: number, [2]: number, [3]: number, [4]: number } + +--- MaterialMap +---@class rl.MaterialMap +--- Material map texture +---@field texture rl.Texture +--- Material map color +---@field color rl.Color +--- Material map value +---@field value number + +--- Matrix, 4x4 components, column major, OpenGL style, right-handed +---@class rl.Matrix +--- Matrix first row (4 components) +---@field m0 number +--- Matrix second row (4 components) +---@field m1 number +--- Matrix third row (4 components) +---@field m2 number +--- Matrix fourth row (4 components) +---@field m3 number +--- Matrix first row (4 components) +---@field m4 number +--- Matrix second row (4 components) +---@field m5 number +--- Matrix third row (4 components) +---@field m6 number +--- Matrix fourth row (4 components) +---@field m7 number +--- Matrix first row (4 components) +---@field m8 number +--- Matrix second row (4 components) +---@field m9 number +--- Matrix third row (4 components) +---@field m10 number +--- Matrix fourth row (4 components) +---@field m11 number +--- Matrix first row (4 components) +---@field m12 number +--- Matrix second row (4 components) +---@field m13 number +--- Matrix third row (4 components) +---@field m14 number +--- Matrix fourth row (4 components) +---@field m15 number + +--- Mesh, vertex data and vao/vbo +---@class rl.Mesh +--- Number of vertices stored in arrays +---@field vertexCount integer +--- Number of triangles stored (indexed or not) +---@field triangleCount integer +--- Vertex position (XYZ - 3 components per vertex) (shader-location = 0) +---@field vertices userdata +--- Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1) +---@field texcoords userdata +--- Vertex texture second coordinates (UV - 2 components per vertex) (shader-location = 5) +---@field texcoords2 userdata +--- Vertex normals (XYZ - 3 components per vertex) (shader-location = 2) +---@field normals userdata +--- Vertex tangents (XYZW - 4 components per vertex) (shader-location = 4) +---@field tangents userdata +--- Vertex colors (RGBA - 4 components per vertex) (shader-location = 3) +---@field colors userdata +--- Vertex indices (in case vertex data comes indexed) +---@field indices userdata +--- Number of bones (MAX: 256 bones) +---@field boneCount integer +--- Vertex bone indices, up to 4 bones influence by vertex (skinning) (shader-location = 6) +---@field boneIndices userdata +--- Vertex bone weight, up to 4 bones influence by vertex (skinning) (shader-location = 7) +---@field boneWeights userdata +--- Animated vertex positions (after bones transformations) +---@field animVertices userdata +--- Animated normals (after bones transformations) +---@field animNormals userdata +--- OpenGL Vertex Array Object id +---@field vaoId integer +--- OpenGL Vertex Buffer Objects id (default vertex data) +---@field vboId userdata + +--- Model, meshes, materials and animation data +---@class rl.Model +--- Local transform matrix +---@field transform rl.Matrix +--- Number of meshes +---@field meshCount integer +--- Number of materials +---@field materialCount integer +--- Meshes array +---@field meshes userdata +--- Materials array +---@field materials userdata +--- Mesh material number +---@field meshMaterial userdata +--- Skeleton for animation +---@field skeleton rl.ModelSkeleton +--- Current animation pose (Transform[]) +---@field currentPose userdata +--- Bones animated transformation matrices +---@field boneMatrices userdata + +--- ModelAnimation, contains a full animation sequence +---@class rl.ModelAnimation +--- Animation name +---@field name string +--- Number of bones (per pose) +---@field boneCount integer +--- Number of animation key frames +---@field keyframeCount integer +--- Animation sequence keyframe poses [keyframe][pose] +---@field keyframePoses userdata + +--- Skeleton, animation bones hierarchy +---@class rl.ModelSkeleton +--- Number of bones +---@field boneCount integer +--- Bones information (skeleton) +---@field bones userdata +--- Bones base transformation (Transform[]) +---@field bindPose userdata + +--- Music, audio stream, anything longer than ~10 seconds should be streamed +---@class rl.Music +--- Audio stream +---@field stream rl.AudioStream +--- Total number of frames (considering channels) +---@field frameCount integer +--- Music looping enable +---@field looping boolean +--- Type of music context (audio filetype) +---@field ctxType integer +--- Audio context data, depends on type +---@field ctxData userdata + +--- NPatchInfo, n-patch layout info +---@class rl.NPatchInfo +--- Texture source rectangle +---@field source rl.Rectangle +--- Left border offset +---@field left integer +--- Top border offset +---@field top integer +--- Right border offset +---@field right integer +--- Bottom border offset +---@field bottom integer +--- Layout of the n-patch: 3x3, 1x3 or 3x1 +---@field layout integer + +--- Ray, ray for raycasting +---@class rl.Ray +--- Ray position (origin) +---@field position rl.Vector3 +--- Ray direction (normalized) +---@field direction rl.Vector3 + +--- RayCollision, ray hit information +---@class rl.RayCollision +--- Did the ray hit something? +---@field hit boolean +--- Distance to the nearest hit +---@field distance number +--- Point of the nearest hit +---@field point rl.Vector3 +--- Surface normal of hit +---@field normal rl.Vector3 + +--- Rectangle, 4 components +---@class rl.Rectangle +--- Rectangle top-left corner position x +---@field x number +--- Rectangle top-left corner position y +---@field y number +--- Rectangle width +---@field width number +--- Rectangle height +---@field height number + +--- RenderTexture, fbo for texture rendering +---@class rl.RenderTexture +--- OpenGL framebuffer object id +---@field id integer +--- Color buffer attachment texture +---@field texture rl.Texture +--- Depth buffer attachment texture +---@field depth rl.Texture + +--- Shader +---@class rl.Shader +--- Shader program id +---@field id integer +--- Shader locations array (RL_MAX_SHADER_LOCATIONS) +---@field locs userdata + +--- Sound +---@class rl.Sound +--- Audio stream +---@field stream rl.AudioStream +--- Total number of frames (considering channels) +---@field frameCount integer + +--- Texture, tex data stored in GPU memory (VRAM) +---@class rl.Texture +--- OpenGL texture id +---@field id integer +--- Texture base width +---@field width integer +--- Texture base height +---@field height integer +--- Mipmap levels, 1 by default +---@field mipmaps integer +--- Data format (PixelFormat type) +---@field format integer + +--- Transform, vertex transformation data +---@class rl.Transform +--- Translation +---@field translation rl.Vector3 +--- Rotation +---@field rotation rl.Vector4 +--- Scale +---@field scale rl.Vector3 + +--- Vector2, 2 components +---@class rl.Vector2 +--- Vector x component +---@field x number +--- Vector y component +---@field y number + +--- Vector3, 3 components +---@class rl.Vector3 +--- Vector x component +---@field x number +--- Vector y component +---@field y number +--- Vector z component +---@field z number + +--- Vector4, 4 components +---@class rl.Vector4 +--- Vector x component +---@field x number +--- Vector y component +---@field y number +--- Vector z component +---@field z number +--- Vector w component +---@field w number + +--- VrDeviceInfo, Head-Mounted-Display device parameters +---@class rl.VrDeviceInfo +--- Horizontal resolution in pixels +---@field hResolution integer +--- Vertical resolution in pixels +---@field vResolution integer +--- Horizontal size in meters +---@field hScreenSize number +--- Vertical size in meters +---@field vScreenSize number +--- Distance between eye and display in meters +---@field eyeToScreenDistance number +--- Lens separation distance in meters +---@field lensSeparationDistance number +--- IPD (distance between pupils) in meters +---@field interpupillaryDistance number +--- Lens distortion constant parameters +---@field lensDistortionValues { [1]: number, [2]: number, [3]: number, [4]: number } +--- Chromatic aberration correction parameters +---@field chromaAbCorrection { [1]: number, [2]: number, [3]: number, [4]: number } + +--- VrStereoConfig, VR stereo rendering configuration for simulator +---@class rl.VrStereoConfig +--- VR projection matrices (per eye) +---@field projection { [1]: rl.Matrix, [2]: rl.Matrix } +--- VR view offset matrices (per eye) +---@field viewOffset { [1]: rl.Matrix, [2]: rl.Matrix } +--- VR left lens center +---@field leftLensCenter { [1]: number, [2]: number } +--- VR right lens center +---@field rightLensCenter { [1]: number, [2]: number } +--- VR left screen center +---@field leftScreenCenter { [1]: number, [2]: number } +--- VR right screen center +---@field rightScreenCenter { [1]: number, [2]: number } +--- VR distortion scale +---@field scale { [1]: number, [2]: number } +--- VR distortion scale in +---@field scaleIn { [1]: number, [2]: number } + +--- Wave, audio wave data +---@class rl.Wave +--- Total number of frames (considering channels) +---@field frameCount integer +--- Frequency (samples per second) +---@field sampleRate integer +--- Bit depth (bits per sample): 8, 16, 32 (24 not supported) +---@field sampleSize integer +--- Number of channels (1-mono, 2-stereo, ...) +---@field channels integer +--- Buffer data pointer +---@field data userdata + +---@class (partial) rl +rl = {} + +---@alias rl.ConfigFlags integer +---@alias rl.TraceLogLevel integer +---@alias rl.KeyboardKey integer +---@alias rl.MouseButton integer +---@alias rl.MouseCursor integer +---@alias rl.GamepadButton integer +---@alias rl.GamepadAxis integer +---@alias rl.MaterialMapIndex integer +---@alias rl.ShaderLocationIndex integer +---@alias rl.ShaderUniformDataType integer +---@alias rl.ShaderAttributeDataType integer +---@alias rl.PixelFormat integer +---@alias rl.TextureFilter integer +---@alias rl.TextureWrap integer +---@alias rl.CubemapLayout integer +---@alias rl.FontType integer +---@alias rl.BlendMode integer +---@alias rl.Gesture integer +---@alias rl.CameraMode integer +---@alias rl.CameraProjection integer +---@alias rl.NPatchLayout integer + +--- Set to try enabling V-Sync on GPU +---@type rl.ConfigFlags +rl.FLAG_VSYNC_HINT = 0x00000040 +--- Set to run program in fullscreen +---@type rl.ConfigFlags +rl.FLAG_FULLSCREEN_MODE = 0x00000002 +--- Set to allow resizable window +---@type rl.ConfigFlags +rl.FLAG_WINDOW_RESIZABLE = 0x00000004 +--- Set to disable window decoration (frame and buttons) +---@type rl.ConfigFlags +rl.FLAG_WINDOW_UNDECORATED = 0x00000008 +--- Set to hide window +---@type rl.ConfigFlags +rl.FLAG_WINDOW_HIDDEN = 0x00000080 +--- Set to minimize window (iconify) +---@type rl.ConfigFlags +rl.FLAG_WINDOW_MINIMIZED = 0x00000200 +--- Set to maximize window (expanded to monitor) +---@type rl.ConfigFlags +rl.FLAG_WINDOW_MAXIMIZED = 0x00000400 +--- Set to window non focused +---@type rl.ConfigFlags +rl.FLAG_WINDOW_UNFOCUSED = 0x00000800 +--- Set to window always on top +---@type rl.ConfigFlags +rl.FLAG_WINDOW_TOPMOST = 0x00001000 +--- Set to allow windows running while minimized +---@type rl.ConfigFlags +rl.FLAG_WINDOW_ALWAYS_RUN = 0x00000100 +--- Set to allow transparent framebuffer +---@type rl.ConfigFlags +rl.FLAG_WINDOW_TRANSPARENT = 0x00000010 +--- Set to support HighDPI +---@type rl.ConfigFlags +rl.FLAG_WINDOW_HIGHDPI = 0x00002000 +--- Set to support mouse passthrough, only supported when FLAG_WINDOW_UNDECORATED +---@type rl.ConfigFlags +rl.FLAG_WINDOW_MOUSE_PASSTHROUGH = 0x00004000 +--- Set to run program in borderless windowed mode +---@type rl.ConfigFlags +rl.FLAG_BORDERLESS_WINDOWED_MODE = 0x00008000 +--- Set to try enabling MSAA 4X +---@type rl.ConfigFlags +rl.FLAG_MSAA_4X_HINT = 0x00000020 +--- Set to try enabling interlaced video format (for V3D) +---@type rl.ConfigFlags +rl.FLAG_INTERLACED_HINT = 0x00010000 +--- Display all logs +---@type rl.TraceLogLevel +rl.LOG_ALL = 0 +--- Trace logging, intended for internal use only +---@type rl.TraceLogLevel +rl.LOG_TRACE = 1 +--- Debug logging, used for internal debugging, it should be disabled on release builds +---@type rl.TraceLogLevel +rl.LOG_DEBUG = 2 +--- Info logging, used for program execution info +---@type rl.TraceLogLevel +rl.LOG_INFO = 3 +--- Warning logging, used on recoverable failures +---@type rl.TraceLogLevel +rl.LOG_WARNING = 4 +--- Error logging, used on unrecoverable failures +---@type rl.TraceLogLevel +rl.LOG_ERROR = 5 +--- Fatal logging, used to abort program: exit(EXIT_FAILURE) +---@type rl.TraceLogLevel +rl.LOG_FATAL = 6 +--- Disable logging +---@type rl.TraceLogLevel +rl.LOG_NONE = 7 +--- Key: NULL, used for no key pressed +---@type rl.KeyboardKey +rl.KEY_NULL = 0 +--- Key: ' +---@type rl.KeyboardKey +rl.KEY_APOSTROPHE = 39 +--- Key: , +---@type rl.KeyboardKey +rl.KEY_COMMA = 44 +--- Key: - +---@type rl.KeyboardKey +rl.KEY_MINUS = 45 +--- Key: . +---@type rl.KeyboardKey +rl.KEY_PERIOD = 46 +--- Key: / +---@type rl.KeyboardKey +rl.KEY_SLASH = 47 +--- Key: 0 +---@type rl.KeyboardKey +rl.KEY_ZERO = 48 +--- Key: 1 +---@type rl.KeyboardKey +rl.KEY_ONE = 49 +--- Key: 2 +---@type rl.KeyboardKey +rl.KEY_TWO = 50 +--- Key: 3 +---@type rl.KeyboardKey +rl.KEY_THREE = 51 +--- Key: 4 +---@type rl.KeyboardKey +rl.KEY_FOUR = 52 +--- Key: 5 +---@type rl.KeyboardKey +rl.KEY_FIVE = 53 +--- Key: 6 +---@type rl.KeyboardKey +rl.KEY_SIX = 54 +--- Key: 7 +---@type rl.KeyboardKey +rl.KEY_SEVEN = 55 +--- Key: 8 +---@type rl.KeyboardKey +rl.KEY_EIGHT = 56 +--- Key: 9 +---@type rl.KeyboardKey +rl.KEY_NINE = 57 +--- Key: ; +---@type rl.KeyboardKey +rl.KEY_SEMICOLON = 59 +--- Key: = +---@type rl.KeyboardKey +rl.KEY_EQUAL = 61 +--- Key: A | a +---@type rl.KeyboardKey +rl.KEY_A = 65 +--- Key: B | b +---@type rl.KeyboardKey +rl.KEY_B = 66 +--- Key: C | c +---@type rl.KeyboardKey +rl.KEY_C = 67 +--- Key: D | d +---@type rl.KeyboardKey +rl.KEY_D = 68 +--- Key: E | e +---@type rl.KeyboardKey +rl.KEY_E = 69 +--- Key: F | f +---@type rl.KeyboardKey +rl.KEY_F = 70 +--- Key: G | g +---@type rl.KeyboardKey +rl.KEY_G = 71 +--- Key: H | h +---@type rl.KeyboardKey +rl.KEY_H = 72 +--- Key: I | i +---@type rl.KeyboardKey +rl.KEY_I = 73 +--- Key: J | j +---@type rl.KeyboardKey +rl.KEY_J = 74 +--- Key: K | k +---@type rl.KeyboardKey +rl.KEY_K = 75 +--- Key: L | l +---@type rl.KeyboardKey +rl.KEY_L = 76 +--- Key: M | m +---@type rl.KeyboardKey +rl.KEY_M = 77 +--- Key: N | n +---@type rl.KeyboardKey +rl.KEY_N = 78 +--- Key: O | o +---@type rl.KeyboardKey +rl.KEY_O = 79 +--- Key: P | p +---@type rl.KeyboardKey +rl.KEY_P = 80 +--- Key: Q | q +---@type rl.KeyboardKey +rl.KEY_Q = 81 +--- Key: R | r +---@type rl.KeyboardKey +rl.KEY_R = 82 +--- Key: S | s +---@type rl.KeyboardKey +rl.KEY_S = 83 +--- Key: T | t +---@type rl.KeyboardKey +rl.KEY_T = 84 +--- Key: U | u +---@type rl.KeyboardKey +rl.KEY_U = 85 +--- Key: V | v +---@type rl.KeyboardKey +rl.KEY_V = 86 +--- Key: W | w +---@type rl.KeyboardKey +rl.KEY_W = 87 +--- Key: X | x +---@type rl.KeyboardKey +rl.KEY_X = 88 +--- Key: Y | y +---@type rl.KeyboardKey +rl.KEY_Y = 89 +--- Key: Z | z +---@type rl.KeyboardKey +rl.KEY_Z = 90 +--- Key: [ +---@type rl.KeyboardKey +rl.KEY_LEFT_BRACKET = 91 +--- Key: '\' +---@type rl.KeyboardKey +rl.KEY_BACKSLASH = 92 +--- Key: ] +---@type rl.KeyboardKey +rl.KEY_RIGHT_BRACKET = 93 +--- Key: ` +---@type rl.KeyboardKey +rl.KEY_GRAVE = 96 +--- Key: Space +---@type rl.KeyboardKey +rl.KEY_SPACE = 32 +--- Key: Esc +---@type rl.KeyboardKey +rl.KEY_ESCAPE = 256 +--- Key: Enter +---@type rl.KeyboardKey +rl.KEY_ENTER = 257 +--- Key: Tab +---@type rl.KeyboardKey +rl.KEY_TAB = 258 +--- Key: Backspace +---@type rl.KeyboardKey +rl.KEY_BACKSPACE = 259 +--- Key: Ins +---@type rl.KeyboardKey +rl.KEY_INSERT = 260 +--- Key: Del +---@type rl.KeyboardKey +rl.KEY_DELETE = 261 +--- Key: Cursor right +---@type rl.KeyboardKey +rl.KEY_RIGHT = 262 +--- Key: Cursor left +---@type rl.KeyboardKey +rl.KEY_LEFT = 263 +--- Key: Cursor down +---@type rl.KeyboardKey +rl.KEY_DOWN = 264 +--- Key: Cursor up +---@type rl.KeyboardKey +rl.KEY_UP = 265 +--- Key: Page up +---@type rl.KeyboardKey +rl.KEY_PAGE_UP = 266 +--- Key: Page down +---@type rl.KeyboardKey +rl.KEY_PAGE_DOWN = 267 +--- Key: Home +---@type rl.KeyboardKey +rl.KEY_HOME = 268 +--- Key: End +---@type rl.KeyboardKey +rl.KEY_END = 269 +--- Key: Caps lock +---@type rl.KeyboardKey +rl.KEY_CAPS_LOCK = 280 +--- Key: Scroll down +---@type rl.KeyboardKey +rl.KEY_SCROLL_LOCK = 281 +--- Key: Num lock +---@type rl.KeyboardKey +rl.KEY_NUM_LOCK = 282 +--- Key: Print screen +---@type rl.KeyboardKey +rl.KEY_PRINT_SCREEN = 283 +--- Key: Pause +---@type rl.KeyboardKey +rl.KEY_PAUSE = 284 +--- Key: F1 +---@type rl.KeyboardKey +rl.KEY_F1 = 290 +--- Key: F2 +---@type rl.KeyboardKey +rl.KEY_F2 = 291 +--- Key: F3 +---@type rl.KeyboardKey +rl.KEY_F3 = 292 +--- Key: F4 +---@type rl.KeyboardKey +rl.KEY_F4 = 293 +--- Key: F5 +---@type rl.KeyboardKey +rl.KEY_F5 = 294 +--- Key: F6 +---@type rl.KeyboardKey +rl.KEY_F6 = 295 +--- Key: F7 +---@type rl.KeyboardKey +rl.KEY_F7 = 296 +--- Key: F8 +---@type rl.KeyboardKey +rl.KEY_F8 = 297 +--- Key: F9 +---@type rl.KeyboardKey +rl.KEY_F9 = 298 +--- Key: F10 +---@type rl.KeyboardKey +rl.KEY_F10 = 299 +--- Key: F11 +---@type rl.KeyboardKey +rl.KEY_F11 = 300 +--- Key: F12 +---@type rl.KeyboardKey +rl.KEY_F12 = 301 +--- Key: Shift left +---@type rl.KeyboardKey +rl.KEY_LEFT_SHIFT = 340 +--- Key: Control left +---@type rl.KeyboardKey +rl.KEY_LEFT_CONTROL = 341 +--- Key: Alt left +---@type rl.KeyboardKey +rl.KEY_LEFT_ALT = 342 +--- Key: Super left +---@type rl.KeyboardKey +rl.KEY_LEFT_SUPER = 343 +--- Key: Shift right +---@type rl.KeyboardKey +rl.KEY_RIGHT_SHIFT = 344 +--- Key: Control right +---@type rl.KeyboardKey +rl.KEY_RIGHT_CONTROL = 345 +--- Key: Alt right +---@type rl.KeyboardKey +rl.KEY_RIGHT_ALT = 346 +--- Key: Super right +---@type rl.KeyboardKey +rl.KEY_RIGHT_SUPER = 347 +--- Key: KB menu +---@type rl.KeyboardKey +rl.KEY_KB_MENU = 348 +--- Key: Keypad 0 +---@type rl.KeyboardKey +rl.KEY_KP_0 = 320 +--- Key: Keypad 1 +---@type rl.KeyboardKey +rl.KEY_KP_1 = 321 +--- Key: Keypad 2 +---@type rl.KeyboardKey +rl.KEY_KP_2 = 322 +--- Key: Keypad 3 +---@type rl.KeyboardKey +rl.KEY_KP_3 = 323 +--- Key: Keypad 4 +---@type rl.KeyboardKey +rl.KEY_KP_4 = 324 +--- Key: Keypad 5 +---@type rl.KeyboardKey +rl.KEY_KP_5 = 325 +--- Key: Keypad 6 +---@type rl.KeyboardKey +rl.KEY_KP_6 = 326 +--- Key: Keypad 7 +---@type rl.KeyboardKey +rl.KEY_KP_7 = 327 +--- Key: Keypad 8 +---@type rl.KeyboardKey +rl.KEY_KP_8 = 328 +--- Key: Keypad 9 +---@type rl.KeyboardKey +rl.KEY_KP_9 = 329 +--- Key: Keypad . +---@type rl.KeyboardKey +rl.KEY_KP_DECIMAL = 330 +--- Key: Keypad / +---@type rl.KeyboardKey +rl.KEY_KP_DIVIDE = 331 +--- Key: Keypad * +---@type rl.KeyboardKey +rl.KEY_KP_MULTIPLY = 332 +--- Key: Keypad - +---@type rl.KeyboardKey +rl.KEY_KP_SUBTRACT = 333 +--- Key: Keypad + +---@type rl.KeyboardKey +rl.KEY_KP_ADD = 334 +--- Key: Keypad Enter +---@type rl.KeyboardKey +rl.KEY_KP_ENTER = 335 +--- Key: Keypad = +---@type rl.KeyboardKey +rl.KEY_KP_EQUAL = 336 +--- Key: Android back button +---@type rl.KeyboardKey +rl.KEY_BACK = 4 +--- Key: Android menu button +---@type rl.KeyboardKey +rl.KEY_MENU = 5 +--- Key: Android volume up button +---@type rl.KeyboardKey +rl.KEY_VOLUME_UP = 24 +--- Key: Android volume down button +---@type rl.KeyboardKey +rl.KEY_VOLUME_DOWN = 25 +--- Mouse button left +---@type rl.MouseButton +rl.MOUSE_BUTTON_LEFT = 0 +--- Mouse button right +---@type rl.MouseButton +rl.MOUSE_BUTTON_RIGHT = 1 +--- Mouse button middle (pressed wheel) +---@type rl.MouseButton +rl.MOUSE_BUTTON_MIDDLE = 2 +--- Mouse button side (advanced mouse device) +---@type rl.MouseButton +rl.MOUSE_BUTTON_SIDE = 3 +--- Mouse button extra (advanced mouse device) +---@type rl.MouseButton +rl.MOUSE_BUTTON_EXTRA = 4 +--- Mouse button forward (advanced mouse device) +---@type rl.MouseButton +rl.MOUSE_BUTTON_FORWARD = 5 +--- Mouse button back (advanced mouse device) +---@type rl.MouseButton +rl.MOUSE_BUTTON_BACK = 6 +--- Default pointer shape +---@type rl.MouseCursor +rl.MOUSE_CURSOR_DEFAULT = 0 +--- Arrow shape +---@type rl.MouseCursor +rl.MOUSE_CURSOR_ARROW = 1 +--- Text writing cursor shape +---@type rl.MouseCursor +rl.MOUSE_CURSOR_IBEAM = 2 +--- Cross shape +---@type rl.MouseCursor +rl.MOUSE_CURSOR_CROSSHAIR = 3 +--- Pointing hand cursor +---@type rl.MouseCursor +rl.MOUSE_CURSOR_POINTING_HAND = 4 +--- Horizontal resize/move arrow shape +---@type rl.MouseCursor +rl.MOUSE_CURSOR_RESIZE_EW = 5 +--- Vertical resize/move arrow shape +---@type rl.MouseCursor +rl.MOUSE_CURSOR_RESIZE_NS = 6 +--- Top-left to bottom-right diagonal resize/move arrow shape +---@type rl.MouseCursor +rl.MOUSE_CURSOR_RESIZE_NWSE = 7 +--- The top-right to bottom-left diagonal resize/move arrow shape +---@type rl.MouseCursor +rl.MOUSE_CURSOR_RESIZE_NESW = 8 +--- The omnidirectional resize/move cursor shape +---@type rl.MouseCursor +rl.MOUSE_CURSOR_RESIZE_ALL = 9 +--- The operation-not-allowed shape +---@type rl.MouseCursor +rl.MOUSE_CURSOR_NOT_ALLOWED = 10 +--- Unknown button, for error checking +---@type rl.GamepadButton +rl.GAMEPAD_BUTTON_UNKNOWN = 0 +--- Gamepad left DPAD up button +---@type rl.GamepadButton +rl.GAMEPAD_BUTTON_LEFT_FACE_UP = 1 +--- Gamepad left DPAD right button +---@type rl.GamepadButton +rl.GAMEPAD_BUTTON_LEFT_FACE_RIGHT = 2 +--- Gamepad left DPAD down button +---@type rl.GamepadButton +rl.GAMEPAD_BUTTON_LEFT_FACE_DOWN = 3 +--- Gamepad left DPAD left button +---@type rl.GamepadButton +rl.GAMEPAD_BUTTON_LEFT_FACE_LEFT = 4 +--- Gamepad right button up (i.e. PS3: Triangle, Xbox: Y) +---@type rl.GamepadButton +rl.GAMEPAD_BUTTON_RIGHT_FACE_UP = 5 +--- Gamepad right button right (i.e. PS3: Circle, Xbox: B) +---@type rl.GamepadButton +rl.GAMEPAD_BUTTON_RIGHT_FACE_RIGHT = 6 +--- Gamepad right button down (i.e. PS3: Cross, Xbox: A) +---@type rl.GamepadButton +rl.GAMEPAD_BUTTON_RIGHT_FACE_DOWN = 7 +--- Gamepad right button left (i.e. PS3: Square, Xbox: X) +---@type rl.GamepadButton +rl.GAMEPAD_BUTTON_RIGHT_FACE_LEFT = 8 +--- Gamepad top/back trigger left (first), it could be a trailing button +---@type rl.GamepadButton +rl.GAMEPAD_BUTTON_LEFT_TRIGGER_1 = 9 +--- Gamepad top/back trigger left (second), it could be a trailing button +---@type rl.GamepadButton +rl.GAMEPAD_BUTTON_LEFT_TRIGGER_2 = 10 +--- Gamepad top/back trigger right (first), it could be a trailing button +---@type rl.GamepadButton +rl.GAMEPAD_BUTTON_RIGHT_TRIGGER_1 = 11 +--- Gamepad top/back trigger right (second), it could be a trailing button +---@type rl.GamepadButton +rl.GAMEPAD_BUTTON_RIGHT_TRIGGER_2 = 12 +--- Gamepad center buttons, left one (i.e. PS3: Select) +---@type rl.GamepadButton +rl.GAMEPAD_BUTTON_MIDDLE_LEFT = 13 +--- Gamepad center buttons, middle one (i.e. PS3: PS, Xbox: XBOX) +---@type rl.GamepadButton +rl.GAMEPAD_BUTTON_MIDDLE = 14 +--- Gamepad center buttons, right one (i.e. PS3: Start) +---@type rl.GamepadButton +rl.GAMEPAD_BUTTON_MIDDLE_RIGHT = 15 +--- Gamepad joystick pressed button left +---@type rl.GamepadButton +rl.GAMEPAD_BUTTON_LEFT_THUMB = 16 +--- Gamepad joystick pressed button right +---@type rl.GamepadButton +rl.GAMEPAD_BUTTON_RIGHT_THUMB = 17 +--- Gamepad left stick X axis +---@type rl.GamepadAxis +rl.GAMEPAD_AXIS_LEFT_X = 0 +--- Gamepad left stick Y axis +---@type rl.GamepadAxis +rl.GAMEPAD_AXIS_LEFT_Y = 1 +--- Gamepad right stick X axis +---@type rl.GamepadAxis +rl.GAMEPAD_AXIS_RIGHT_X = 2 +--- Gamepad right stick Y axis +---@type rl.GamepadAxis +rl.GAMEPAD_AXIS_RIGHT_Y = 3 +--- Gamepad back trigger left, pressure level: [1..-1] +---@type rl.GamepadAxis +rl.GAMEPAD_AXIS_LEFT_TRIGGER = 4 +--- Gamepad back trigger right, pressure level: [1..-1] +---@type rl.GamepadAxis +rl.GAMEPAD_AXIS_RIGHT_TRIGGER = 5 +--- Albedo material (same as: MATERIAL_MAP_DIFFUSE) +---@type rl.MaterialMapIndex +rl.MATERIAL_MAP_ALBEDO = 0 +--- Metalness material (same as: MATERIAL_MAP_SPECULAR) +---@type rl.MaterialMapIndex +rl.MATERIAL_MAP_METALNESS = 1 +--- Normal material +---@type rl.MaterialMapIndex +rl.MATERIAL_MAP_NORMAL = 2 +--- Roughness material +---@type rl.MaterialMapIndex +rl.MATERIAL_MAP_ROUGHNESS = 3 +--- Ambient occlusion material +---@type rl.MaterialMapIndex +rl.MATERIAL_MAP_OCCLUSION = 4 +--- Emission material +---@type rl.MaterialMapIndex +rl.MATERIAL_MAP_EMISSION = 5 +--- Heightmap material +---@type rl.MaterialMapIndex +rl.MATERIAL_MAP_HEIGHT = 6 +--- Cubemap material (NOTE: Uses GL_TEXTURE_CUBE_MAP) +---@type rl.MaterialMapIndex +rl.MATERIAL_MAP_CUBEMAP = 7 +--- Irradiance material (NOTE: Uses GL_TEXTURE_CUBE_MAP) +---@type rl.MaterialMapIndex +rl.MATERIAL_MAP_IRRADIANCE = 8 +--- Prefilter material (NOTE: Uses GL_TEXTURE_CUBE_MAP) +---@type rl.MaterialMapIndex +rl.MATERIAL_MAP_PREFILTER = 9 +--- Brdf material +---@type rl.MaterialMapIndex +rl.MATERIAL_MAP_BRDF = 10 +--- Shader location: vertex attribute: position +---@type rl.ShaderLocationIndex +rl.SHADER_LOC_VERTEX_POSITION = 0 +--- Shader location: vertex attribute: texcoord01 +---@type rl.ShaderLocationIndex +rl.SHADER_LOC_VERTEX_TEXCOORD01 = 1 +--- Shader location: vertex attribute: texcoord02 +---@type rl.ShaderLocationIndex +rl.SHADER_LOC_VERTEX_TEXCOORD02 = 2 +--- Shader location: vertex attribute: normal +---@type rl.ShaderLocationIndex +rl.SHADER_LOC_VERTEX_NORMAL = 3 +--- Shader location: vertex attribute: tangent +---@type rl.ShaderLocationIndex +rl.SHADER_LOC_VERTEX_TANGENT = 4 +--- Shader location: vertex attribute: color +---@type rl.ShaderLocationIndex +rl.SHADER_LOC_VERTEX_COLOR = 5 +--- Shader location: matrix uniform: model-view-projection +---@type rl.ShaderLocationIndex +rl.SHADER_LOC_MATRIX_MVP = 6 +--- Shader location: matrix uniform: view (camera transform) +---@type rl.ShaderLocationIndex +rl.SHADER_LOC_MATRIX_VIEW = 7 +--- Shader location: matrix uniform: projection +---@type rl.ShaderLocationIndex +rl.SHADER_LOC_MATRIX_PROJECTION = 8 +--- Shader location: matrix uniform: model (transform) +---@type rl.ShaderLocationIndex +rl.SHADER_LOC_MATRIX_MODEL = 9 +--- Shader location: matrix uniform: normal +---@type rl.ShaderLocationIndex +rl.SHADER_LOC_MATRIX_NORMAL = 10 +--- Shader location: vector uniform: view +---@type rl.ShaderLocationIndex +rl.SHADER_LOC_VECTOR_VIEW = 11 +--- Shader location: vector uniform: diffuse color +---@type rl.ShaderLocationIndex +rl.SHADER_LOC_COLOR_DIFFUSE = 12 +--- Shader location: vector uniform: specular color +---@type rl.ShaderLocationIndex +rl.SHADER_LOC_COLOR_SPECULAR = 13 +--- Shader location: vector uniform: ambient color +---@type rl.ShaderLocationIndex +rl.SHADER_LOC_COLOR_AMBIENT = 14 +--- Shader location: sampler2d texture: albedo (same as: SHADER_LOC_MAP_DIFFUSE) +---@type rl.ShaderLocationIndex +rl.SHADER_LOC_MAP_ALBEDO = 15 +--- Shader location: sampler2d texture: metalness (same as: SHADER_LOC_MAP_SPECULAR) +---@type rl.ShaderLocationIndex +rl.SHADER_LOC_MAP_METALNESS = 16 +--- Shader location: sampler2d texture: normal +---@type rl.ShaderLocationIndex +rl.SHADER_LOC_MAP_NORMAL = 17 +--- Shader location: sampler2d texture: roughness +---@type rl.ShaderLocationIndex +rl.SHADER_LOC_MAP_ROUGHNESS = 18 +--- Shader location: sampler2d texture: occlusion +---@type rl.ShaderLocationIndex +rl.SHADER_LOC_MAP_OCCLUSION = 19 +--- Shader location: sampler2d texture: emission +---@type rl.ShaderLocationIndex +rl.SHADER_LOC_MAP_EMISSION = 20 +--- Shader location: sampler2d texture: heightmap +---@type rl.ShaderLocationIndex +rl.SHADER_LOC_MAP_HEIGHT = 21 +--- Shader location: samplerCube texture: cubemap +---@type rl.ShaderLocationIndex +rl.SHADER_LOC_MAP_CUBEMAP = 22 +--- Shader location: samplerCube texture: irradiance +---@type rl.ShaderLocationIndex +rl.SHADER_LOC_MAP_IRRADIANCE = 23 +--- Shader location: samplerCube texture: prefilter +---@type rl.ShaderLocationIndex +rl.SHADER_LOC_MAP_PREFILTER = 24 +--- Shader location: sampler2d texture: brdf +---@type rl.ShaderLocationIndex +rl.SHADER_LOC_MAP_BRDF = 25 +--- Shader location: vertex attribute: bone indices +---@type rl.ShaderLocationIndex +rl.SHADER_LOC_VERTEX_BONEIDS = 26 +--- Shader location: vertex attribute: bone weights +---@type rl.ShaderLocationIndex +rl.SHADER_LOC_VERTEX_BONEWEIGHTS = 27 +--- Shader location: matrix attribute: bone transforms (animation) +---@type rl.ShaderLocationIndex +rl.SHADER_LOC_MATRIX_BONETRANSFORMS = 28 +--- Shader location: vertex attribute: instance transforms +---@type rl.ShaderLocationIndex +rl.SHADER_LOC_VERTEX_INSTANCETRANSFORM = 29 +--- Shader uniform type: float +---@type rl.ShaderUniformDataType +rl.SHADER_UNIFORM_FLOAT = 0 +--- Shader uniform type: vec2 (2 float) +---@type rl.ShaderUniformDataType +rl.SHADER_UNIFORM_VEC2 = 1 +--- Shader uniform type: vec3 (3 float) +---@type rl.ShaderUniformDataType +rl.SHADER_UNIFORM_VEC3 = 2 +--- Shader uniform type: vec4 (4 float) +---@type rl.ShaderUniformDataType +rl.SHADER_UNIFORM_VEC4 = 3 +--- Shader uniform type: int +---@type rl.ShaderUniformDataType +rl.SHADER_UNIFORM_INT = 4 +--- Shader uniform type: ivec2 (2 int) +---@type rl.ShaderUniformDataType +rl.SHADER_UNIFORM_IVEC2 = 5 +--- Shader uniform type: ivec3 (3 int) +---@type rl.ShaderUniformDataType +rl.SHADER_UNIFORM_IVEC3 = 6 +--- Shader uniform type: ivec4 (4 int) +---@type rl.ShaderUniformDataType +rl.SHADER_UNIFORM_IVEC4 = 7 +--- Shader uniform type: unsigned int +---@type rl.ShaderUniformDataType +rl.SHADER_UNIFORM_UINT = 8 +--- Shader uniform type: uivec2 (2 unsigned int) +---@type rl.ShaderUniformDataType +rl.SHADER_UNIFORM_UIVEC2 = 9 +--- Shader uniform type: uivec3 (3 unsigned int) +---@type rl.ShaderUniformDataType +rl.SHADER_UNIFORM_UIVEC3 = 10 +--- Shader uniform type: uivec4 (4 unsigned int) +---@type rl.ShaderUniformDataType +rl.SHADER_UNIFORM_UIVEC4 = 11 +--- Shader uniform type: sampler2d +---@type rl.ShaderUniformDataType +rl.SHADER_UNIFORM_SAMPLER2D = 12 +--- Shader attribute type: float +---@type rl.ShaderAttributeDataType +rl.SHADER_ATTRIB_FLOAT = 0 +--- Shader attribute type: vec2 (2 float) +---@type rl.ShaderAttributeDataType +rl.SHADER_ATTRIB_VEC2 = 1 +--- Shader attribute type: vec3 (3 float) +---@type rl.ShaderAttributeDataType +rl.SHADER_ATTRIB_VEC3 = 2 +--- Shader attribute type: vec4 (4 float) +---@type rl.ShaderAttributeDataType +rl.SHADER_ATTRIB_VEC4 = 3 +--- 8 bit per pixel (no alpha) +---@type rl.PixelFormat +rl.PIXELFORMAT_UNCOMPRESSED_GRAYSCALE = 1 +--- 8*2 bpp (2 channels) +---@type rl.PixelFormat +rl.PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA = 2 +--- 16 bpp +---@type rl.PixelFormat +rl.PIXELFORMAT_UNCOMPRESSED_R5G6B5 = 3 +--- 24 bpp +---@type rl.PixelFormat +rl.PIXELFORMAT_UNCOMPRESSED_R8G8B8 = 4 +--- 16 bpp (1 bit alpha) +---@type rl.PixelFormat +rl.PIXELFORMAT_UNCOMPRESSED_R5G5B5A1 = 5 +--- 16 bpp (4 bit alpha) +---@type rl.PixelFormat +rl.PIXELFORMAT_UNCOMPRESSED_R4G4B4A4 = 6 +--- 32 bpp +---@type rl.PixelFormat +rl.PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 = 7 +--- 32 bpp (1 channel - float) +---@type rl.PixelFormat +rl.PIXELFORMAT_UNCOMPRESSED_R32 = 8 +--- 32*3 bpp (3 channels - float) +---@type rl.PixelFormat +rl.PIXELFORMAT_UNCOMPRESSED_R32G32B32 = 9 +--- 32*4 bpp (4 channels - float) +---@type rl.PixelFormat +rl.PIXELFORMAT_UNCOMPRESSED_R32G32B32A32 = 10 +--- 16 bpp (1 channel - half float) +---@type rl.PixelFormat +rl.PIXELFORMAT_UNCOMPRESSED_R16 = 11 +--- 16*3 bpp (3 channels - half float) +---@type rl.PixelFormat +rl.PIXELFORMAT_UNCOMPRESSED_R16G16B16 = 12 +--- 16*4 bpp (4 channels - half float) +---@type rl.PixelFormat +rl.PIXELFORMAT_UNCOMPRESSED_R16G16B16A16 = 13 +--- 4 bpp (no alpha) +---@type rl.PixelFormat +rl.PIXELFORMAT_COMPRESSED_DXT1_RGB = 14 +--- 4 bpp (1 bit alpha) +---@type rl.PixelFormat +rl.PIXELFORMAT_COMPRESSED_DXT1_RGBA = 15 +--- 8 bpp +---@type rl.PixelFormat +rl.PIXELFORMAT_COMPRESSED_DXT3_RGBA = 16 +--- 8 bpp +---@type rl.PixelFormat +rl.PIXELFORMAT_COMPRESSED_DXT5_RGBA = 17 +--- 4 bpp +---@type rl.PixelFormat +rl.PIXELFORMAT_COMPRESSED_ETC1_RGB = 18 +--- 4 bpp +---@type rl.PixelFormat +rl.PIXELFORMAT_COMPRESSED_ETC2_RGB = 19 +--- 8 bpp +---@type rl.PixelFormat +rl.PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA = 20 +--- 4 bpp +---@type rl.PixelFormat +rl.PIXELFORMAT_COMPRESSED_PVRT_RGB = 21 +--- 4 bpp +---@type rl.PixelFormat +rl.PIXELFORMAT_COMPRESSED_PVRT_RGBA = 22 +--- 8 bpp +---@type rl.PixelFormat +rl.PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA = 23 +--- 2 bpp +---@type rl.PixelFormat +rl.PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA = 24 +--- No filter, pixel approximation +---@type rl.TextureFilter +rl.TEXTURE_FILTER_POINT = 0 +--- Linear filtering +---@type rl.TextureFilter +rl.TEXTURE_FILTER_BILINEAR = 1 +--- Trilinear filtering (linear with mipmaps) +---@type rl.TextureFilter +rl.TEXTURE_FILTER_TRILINEAR = 2 +--- Anisotropic filtering 4x +---@type rl.TextureFilter +rl.TEXTURE_FILTER_ANISOTROPIC_4X = 3 +--- Anisotropic filtering 8x +---@type rl.TextureFilter +rl.TEXTURE_FILTER_ANISOTROPIC_8X = 4 +--- Anisotropic filtering 16x +---@type rl.TextureFilter +rl.TEXTURE_FILTER_ANISOTROPIC_16X = 5 +--- Repeats texture in tiled mode +---@type rl.TextureWrap +rl.TEXTURE_WRAP_REPEAT = 0 +--- Clamps texture to edge pixel in tiled mode +---@type rl.TextureWrap +rl.TEXTURE_WRAP_CLAMP = 1 +--- Mirrors and repeats the texture in tiled mode +---@type rl.TextureWrap +rl.TEXTURE_WRAP_MIRROR_REPEAT = 2 +--- Mirrors and clamps to border the texture in tiled mode +---@type rl.TextureWrap +rl.TEXTURE_WRAP_MIRROR_CLAMP = 3 +--- Automatically detect layout type +---@type rl.CubemapLayout +rl.CUBEMAP_LAYOUT_AUTO_DETECT = 0 +--- Layout is defined by a vertical line with faces +---@type rl.CubemapLayout +rl.CUBEMAP_LAYOUT_LINE_VERTICAL = 1 +--- Layout is defined by a horizontal line with faces +---@type rl.CubemapLayout +rl.CUBEMAP_LAYOUT_LINE_HORIZONTAL = 2 +--- Layout is defined by a 3x4 cross with cubemap faces +---@type rl.CubemapLayout +rl.CUBEMAP_LAYOUT_CROSS_THREE_BY_FOUR = 3 +--- Layout is defined by a 4x3 cross with cubemap faces +---@type rl.CubemapLayout +rl.CUBEMAP_LAYOUT_CROSS_FOUR_BY_THREE = 4 +--- Default font generation, anti-aliased +---@type rl.FontType +rl.FONT_DEFAULT = 0 +--- Bitmap font generation, no anti-aliasing +---@type rl.FontType +rl.FONT_BITMAP = 1 +--- SDF font generation, requires external shader +---@type rl.FontType +rl.FONT_SDF = 2 +--- Blend textures considering alpha (default) +---@type rl.BlendMode +rl.BLEND_ALPHA = 0 +--- Blend textures adding colors +---@type rl.BlendMode +rl.BLEND_ADDITIVE = 1 +--- Blend textures multiplying colors +---@type rl.BlendMode +rl.BLEND_MULTIPLIED = 2 +--- Blend textures adding colors (alternative) +---@type rl.BlendMode +rl.BLEND_ADD_COLORS = 3 +--- Blend textures subtracting colors (alternative) +---@type rl.BlendMode +rl.BLEND_SUBTRACT_COLORS = 4 +--- Blend premultiplied textures considering alpha +---@type rl.BlendMode +rl.BLEND_ALPHA_PREMULTIPLY = 5 +--- Blend textures using custom src/dst factors (use rlSetBlendFactors()) +---@type rl.BlendMode +rl.BLEND_CUSTOM = 6 +--- Blend textures using custom rgb/alpha separate src/dst factors (use rlSetBlendFactorsSeparate()) +---@type rl.BlendMode +rl.BLEND_CUSTOM_SEPARATE = 7 +--- No gesture +---@type rl.Gesture +rl.GESTURE_NONE = 0 +--- Tap gesture +---@type rl.Gesture +rl.GESTURE_TAP = 1 +--- Double tap gesture +---@type rl.Gesture +rl.GESTURE_DOUBLETAP = 2 +--- Hold gesture +---@type rl.Gesture +rl.GESTURE_HOLD = 4 +--- Drag gesture +---@type rl.Gesture +rl.GESTURE_DRAG = 8 +--- Swipe right gesture +---@type rl.Gesture +rl.GESTURE_SWIPE_RIGHT = 16 +--- Swipe left gesture +---@type rl.Gesture +rl.GESTURE_SWIPE_LEFT = 32 +--- Swipe up gesture +---@type rl.Gesture +rl.GESTURE_SWIPE_UP = 64 +--- Swipe down gesture +---@type rl.Gesture +rl.GESTURE_SWIPE_DOWN = 128 +--- Pinch in gesture +---@type rl.Gesture +rl.GESTURE_PINCH_IN = 256 +--- Pinch out gesture +---@type rl.Gesture +rl.GESTURE_PINCH_OUT = 512 +--- Camera custom, controlled by user (UpdateCamera() does nothing) +---@type rl.CameraMode +rl.CAMERA_CUSTOM = 0 +--- Camera free mode +---@type rl.CameraMode +rl.CAMERA_FREE = 1 +--- Camera orbital, around target, zoom supported +---@type rl.CameraMode +rl.CAMERA_ORBITAL = 2 +--- Camera first person +---@type rl.CameraMode +rl.CAMERA_FIRST_PERSON = 3 +--- Camera third person +---@type rl.CameraMode +rl.CAMERA_THIRD_PERSON = 4 +--- Perspective projection +---@type rl.CameraProjection +rl.CAMERA_PERSPECTIVE = 0 +--- Orthographic projection +---@type rl.CameraProjection +rl.CAMERA_ORTHOGRAPHIC = 1 +--- Npatch layout: 3x3 tiles +---@type rl.NPatchLayout +rl.NPATCH_NINE_PATCH = 0 +--- Npatch layout: 1x3 tiles +---@type rl.NPatchLayout +rl.NPATCH_THREE_PATCH_VERTICAL = 1 +--- Npatch layout: 3x1 tiles +---@type rl.NPatchLayout +rl.NPATCH_THREE_PATCH_HORIZONTAL = 2 +---@type number +rl.PI = 3.14159265358979323846 +---@type number +rl.DEG2RAD = (rl.PI/180.0) +---@type number +rl.RAD2DEG = (180.0/rl.PI) +--- Light Gray +---@type rl.Color +rl.LIGHTGRAY = nil +--- Gray +---@type rl.Color +rl.GRAY = nil +--- Dark Gray +---@type rl.Color +rl.DARKGRAY = nil +--- Yellow +---@type rl.Color +rl.YELLOW = nil +--- Gold +---@type rl.Color +rl.GOLD = nil +--- Orange +---@type rl.Color +rl.ORANGE = nil +--- Pink +---@type rl.Color +rl.PINK = nil +--- Red +---@type rl.Color +rl.RED = nil +--- Maroon +---@type rl.Color +rl.MAROON = nil +--- Green +---@type rl.Color +rl.GREEN = nil +--- Lime +---@type rl.Color +rl.LIME = nil +--- Dark Green +---@type rl.Color +rl.DARKGREEN = nil +--- Sky Blue +---@type rl.Color +rl.SKYBLUE = nil +--- Blue +---@type rl.Color +rl.BLUE = nil +--- Dark Blue +---@type rl.Color +rl.DARKBLUE = nil +--- Purple +---@type rl.Color +rl.PURPLE = nil +--- Violet +---@type rl.Color +rl.VIOLET = nil +--- Dark Purple +---@type rl.Color +rl.DARKPURPLE = nil +--- Beige +---@type rl.Color +rl.BEIGE = nil +--- Brown +---@type rl.Color +rl.BROWN = nil +--- Dark Brown +---@type rl.Color +rl.DARKBROWN = nil +--- White +---@type rl.Color +rl.WHITE = nil +--- Black +---@type rl.Color +rl.BLACK = nil +--- Blank (Transparent) +---@type rl.Color +rl.BLANK = nil +--- Magenta +---@type rl.Color +rl.MAGENTA = nil +--- My own White (raylib logo) +---@type rl.Color +rl.RAYWHITE = nil +---@type integer +rl.MOUSE_LEFT_BUTTON = nil +---@type integer +rl.MOUSE_RIGHT_BUTTON = nil +---@type integer +rl.MOUSE_MIDDLE_BUTTON = nil +---@type integer +rl.MATERIAL_MAP_DIFFUSE = nil +---@type integer +rl.MATERIAL_MAP_SPECULAR = nil +---@type integer +rl.SHADER_LOC_MAP_DIFFUSE = nil +---@type integer +rl.SHADER_LOC_MAP_SPECULAR = nil +--- Get a ray trace from screen position (i.e mouse) +---@param position rl.Vector2 +---@param camera rl.Camera3D +---@return rl.Ray +function rl.GetMouseRay(position, camera) end + + +--- Callbacks to hook some internal functions +--- WARNING: These callbacks are intended for advanced users +--- Logging: Redirect trace log messages +---@param logLevel integer +---@param text string +---@param args rl.va_list +function rl.TraceLogCallback(logLevel, text, args) end + +--- FileIO: Load binary data +---@param fileName string +---@param dataSize userdata +---@return userdata +function rl.LoadFileDataCallback(fileName, dataSize) end + +--- FileIO: Save binary data +---@param fileName string +---@param data userdata +---@param dataSize integer +---@return boolean +function rl.SaveFileDataCallback(fileName, data, dataSize) end + +--- FileIO: Load text data +---@param fileName string +---@return string +function rl.LoadFileTextCallback(fileName) end + +--- FileIO: Save text data +---@param fileName string +---@param text string +---@return boolean +function rl.SaveFileTextCallback(fileName, text) end + +--- Window-related functions +--- Initialize window and OpenGL context +---@param width integer +---@param height integer +---@param title string +function rl.InitWindow(width, height, title) end + +--- Close window and unload OpenGL context +function rl.CloseWindow() end + +--- Check if application should close (KEY_ESCAPE pressed or windows close icon clicked) +---@return boolean +function rl.WindowShouldClose() end + +--- Check if window has been initialized successfully +---@return boolean +function rl.IsWindowReady() end + +--- Check if window is currently fullscreen +---@return boolean +function rl.IsWindowFullscreen() end + +--- Check if window is currently hidden +---@return boolean +function rl.IsWindowHidden() end + +--- Check if window is currently minimized +---@return boolean +function rl.IsWindowMinimized() end + +--- Check if window is currently maximized +---@return boolean +function rl.IsWindowMaximized() end + +--- Check if window is currently focused +---@return boolean +function rl.IsWindowFocused() end + +--- Check if window has been resized last frame +---@return boolean +function rl.IsWindowResized() end + +--- Check if one specific window flag is enabled +---@param flag integer +---@return boolean +function rl.IsWindowState(flag) end + +--- Set window configuration state using flags +---@param flags integer +function rl.SetWindowState(flags) end + +--- Clear window configuration state flags +---@param flags integer +function rl.ClearWindowState(flags) end + +--- Toggle window state: fullscreen/windowed, resizes monitor to match window resolution +function rl.ToggleFullscreen() end + +--- Toggle window state: borderless windowed, resizes window to match monitor resolution +function rl.ToggleBorderlessWindowed() end + +--- Set window state: maximized, if resizable +function rl.MaximizeWindow() end + +--- Set window state: minimized, if resizable +function rl.MinimizeWindow() end + +--- Restore window from being minimized/maximized +function rl.RestoreWindow() end + +--- Set icon for window (single image, RGBA 32bit) +---@param image rl.Image +function rl.SetWindowIcon(image) end + +--- Set icon for window (multiple images, RGBA 32bit) +---@param images userdata +---@param count integer +function rl.SetWindowIcons(images, count) end + +--- Set title for window +---@param title string +function rl.SetWindowTitle(title) end + +--- Set window position on screen +---@param x integer +---@param y integer +function rl.SetWindowPosition(x, y) end + +--- Set monitor for the current window +---@param monitor integer +function rl.SetWindowMonitor(monitor) end + +--- Set window minimum dimensions (for FLAG_WINDOW_RESIZABLE) +---@param width integer +---@param height integer +function rl.SetWindowMinSize(width, height) end + +--- Set window maximum dimensions (for FLAG_WINDOW_RESIZABLE) +---@param width integer +---@param height integer +function rl.SetWindowMaxSize(width, height) end + +--- Set window dimensions +---@param width integer +---@param height integer +function rl.SetWindowSize(width, height) end + +--- Set window opacity [0.0f..1.0f] +---@param opacity number +function rl.SetWindowOpacity(opacity) end + +--- Set window focused +function rl.SetWindowFocused() end + +--- Get native window handle +---@return userdata +function rl.GetWindowHandle() end + +--- Get current screen width +---@return integer +function rl.GetScreenWidth() end + +--- Get current screen height +---@return integer +function rl.GetScreenHeight() end + +--- Get current render width (it considers HiDPI) +---@return integer +function rl.GetRenderWidth() end + +--- Get current render height (it considers HiDPI) +---@return integer +function rl.GetRenderHeight() end + +--- Get number of connected monitors +---@return integer +function rl.GetMonitorCount() end + +--- Get current monitor where window is placed +---@return integer +function rl.GetCurrentMonitor() end + +--- Get specified monitor position +---@param monitor integer +---@return rl.Vector2 +function rl.GetMonitorPosition(monitor) end + +--- Get specified monitor width (current video mode used by monitor) +---@param monitor integer +---@return integer +function rl.GetMonitorWidth(monitor) end + +--- Get specified monitor height (current video mode used by monitor) +---@param monitor integer +---@return integer +function rl.GetMonitorHeight(monitor) end + +--- Get specified monitor physical width in millimetres +---@param monitor integer +---@return integer +function rl.GetMonitorPhysicalWidth(monitor) end + +--- Get specified monitor physical height in millimetres +---@param monitor integer +---@return integer +function rl.GetMonitorPhysicalHeight(monitor) end + +--- Get specified monitor refresh rate +---@param monitor integer +---@return integer +function rl.GetMonitorRefreshRate(monitor) end + +--- Get window position XY on monitor +---@return rl.Vector2 +function rl.GetWindowPosition() end + +--- Get window scale DPI factor +---@return rl.Vector2 +function rl.GetWindowScaleDPI() end + +--- Get the human-readable, UTF-8 encoded name of the specified monitor +---@param monitor integer +---@return string +function rl.GetMonitorName(monitor) end + +--- Set clipboard text content +---@param text string +function rl.SetClipboardText(text) end + +--- Get clipboard text content +---@return string +function rl.GetClipboardText() end + +--- Get clipboard image content +---@return rl.Image +function rl.GetClipboardImage() end + +--- Enable waiting for events on EndDrawing(), no automatic event polling +function rl.EnableEventWaiting() end + +--- Disable waiting for events on EndDrawing(), automatic events polling +function rl.DisableEventWaiting() end + +--- Cursor-related functions +--- Shows cursor +function rl.ShowCursor() end + +--- Hides cursor +function rl.HideCursor() end + +--- Check if cursor is not visible +---@return boolean +function rl.IsCursorHidden() end + +--- Enables cursor (unlock cursor) +function rl.EnableCursor() end + +--- Disables cursor (lock cursor) +function rl.DisableCursor() end + +--- Check if cursor is on the screen +---@return boolean +function rl.IsCursorOnScreen() end + +--- Drawing-related functions +--- Set background color (framebuffer clear color) +---@param color rl.Color +function rl.ClearBackground(color) end + +--- Setup canvas (framebuffer) to start drawing +function rl.BeginDrawing() end + +--- End canvas drawing and swap buffers (double buffering) +function rl.EndDrawing() end + +--- Begin 2D mode with custom camera (2D) +---@param camera rl.Camera2D +function rl.BeginMode2D(camera) end + +--- Ends 2D mode with custom camera +function rl.EndMode2D() end + +--- Begin 3D mode with custom camera (3D) +---@param camera rl.Camera3D +function rl.BeginMode3D(camera) end + +--- Ends 3D mode and returns to default 2D orthographic mode +function rl.EndMode3D() end + +--- Begin drawing to render texture +---@param target rl.RenderTexture +function rl.BeginTextureMode(target) end + +--- Ends drawing to render texture +function rl.EndTextureMode() end + +--- Begin custom shader drawing +---@param shader rl.Shader +function rl.BeginShaderMode(shader) end + +--- End custom shader drawing (use default shader) +function rl.EndShaderMode() end + +--- Begin blending mode (alpha, additive, multiplied, subtract, custom) +---@param mode integer +function rl.BeginBlendMode(mode) end + +--- End blending mode (reset to default: alpha blending) +function rl.EndBlendMode() end + +--- Begin scissor mode (define screen area for following drawing) +---@param x integer +---@param y integer +---@param width integer +---@param height integer +function rl.BeginScissorMode(x, y, width, height) end + +--- End scissor mode +function rl.EndScissorMode() end + +--- Begin stereo rendering (requires VR simulator) +---@param config rl.VrStereoConfig +function rl.BeginVrStereoMode(config) end + +--- End stereo rendering (requires VR simulator) +function rl.EndVrStereoMode() end + +--- VR stereo config functions for VR simulator +--- Load VR stereo config for VR simulator device parameters +---@param device rl.VrDeviceInfo +---@return rl.VrStereoConfig +function rl.LoadVrStereoConfig(device) end + +--- Unload VR stereo config +---@param config rl.VrStereoConfig +function rl.UnloadVrStereoConfig(config) end + +--- Shader management functions +--- NOTE: Shader functionality is not available on OpenGL 1.1 +--- Load shader from files and bind default locations +---@param vsFileName string +---@param fsFileName string +---@return rl.Shader +function rl.LoadShader(vsFileName, fsFileName) end + +--- Load shader from code strings and bind default locations +---@param vsCode string +---@param fsCode string +---@return rl.Shader +function rl.LoadShaderFromMemory(vsCode, fsCode) end + +--- Check if a shader is valid (loaded on GPU) +---@param shader rl.Shader +---@return boolean +function rl.IsShaderValid(shader) end + +--- Get shader uniform location +---@param shader rl.Shader +---@param uniformName string +---@return integer +function rl.GetShaderLocation(shader, uniformName) end + +--- Get shader attribute location +---@param shader rl.Shader +---@param attribName string +---@return integer +function rl.GetShaderLocationAttrib(shader, attribName) end + +--- Set shader uniform value +---@param shader rl.Shader +---@param locIndex integer +---@param value userdata +---@param uniformType integer +function rl.SetShaderValue(shader, locIndex, value, uniformType) end + +--- Set shader uniform value vector +---@param shader rl.Shader +---@param locIndex integer +---@param value userdata +---@param uniformType integer +---@param count integer +function rl.SetShaderValueV(shader, locIndex, value, uniformType, count) end + +--- Set shader uniform value (matrix 4x4) +---@param shader rl.Shader +---@param locIndex integer +---@param mat rl.Matrix +function rl.SetShaderValueMatrix(shader, locIndex, mat) end + +--- Set shader uniform value and bind the texture (sampler2d) +---@param shader rl.Shader +---@param locIndex integer +---@param texture rl.Texture +function rl.SetShaderValueTexture(shader, locIndex, texture) end + +--- Unload shader from GPU memory (VRAM) +---@param shader rl.Shader +function rl.UnloadShader(shader) end + +--- Get a ray trace from screen position (i.e mouse) +---@param position rl.Vector2 +---@param camera rl.Camera3D +---@return rl.Ray +function rl.GetScreenToWorldRay(position, camera) end + +--- Get a ray trace from screen position (i.e mouse) in a viewport +---@param position rl.Vector2 +---@param camera rl.Camera3D +---@param width integer +---@param height integer +---@return rl.Ray +function rl.GetScreenToWorldRayEx(position, camera, width, height) end + +--- Get the screen space position for a 3d world space position +---@param position rl.Vector3 +---@param camera rl.Camera3D +---@return rl.Vector2 +function rl.GetWorldToScreen(position, camera) end + +--- Get size position for a 3d world space position +---@param position rl.Vector3 +---@param camera rl.Camera3D +---@param width integer +---@param height integer +---@return rl.Vector2 +function rl.GetWorldToScreenEx(position, camera, width, height) end + +--- Get the screen space position for a 2d camera world space position +---@param position rl.Vector2 +---@param camera rl.Camera2D +---@return rl.Vector2 +function rl.GetWorldToScreen2D(position, camera) end + +--- Get the world space position for a 2d camera screen space position +---@param position rl.Vector2 +---@param camera rl.Camera2D +---@return rl.Vector2 +function rl.GetScreenToWorld2D(position, camera) end + +--- Get camera transform matrix (view matrix) +---@param camera rl.Camera3D +---@return rl.Matrix +function rl.GetCameraMatrix(camera) end + +--- Get camera 2d transform matrix +---@param camera rl.Camera2D +---@return rl.Matrix +function rl.GetCameraMatrix2D(camera) end + +--- Timing-related functions +--- Set target FPS (maximum) +---@param fps integer +function rl.SetTargetFPS(fps) end + +--- Get time in seconds for last frame drawn (delta time) +---@return number +function rl.GetFrameTime() end + +--- Get elapsed time in seconds since InitWindow() +---@return number +function rl.GetTime() end + +--- Get current FPS +---@return integer +function rl.GetFPS() end + +--- Custom frame control functions +--- NOTE: Those functions are intended for advanced users that want full control over the frame processing +--- By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timing + PollInputEvents() +--- To avoid that behaviour and control frame processes manually, enable in config.h: SUPPORT_CUSTOM_FRAME_CONTROL +--- Swap back buffer with front buffer (screen drawing) +function rl.SwapScreenBuffer() end + +--- Register all input events +function rl.PollInputEvents() end + +--- Wait for some time (halt program execution) +---@param seconds number +function rl.WaitTime(seconds) end + +--- Random values generation functions +--- Set the seed for the random number generator +---@param seed integer +function rl.SetRandomSeed(seed) end + +--- Get a random value between min and max (both included) +---@param min integer +---@param max integer +---@return integer +function rl.GetRandomValue(min, max) end + +--- Load random values sequence, no values repeated +---@param count integer +---@param min integer +---@param max integer +---@return userdata +function rl.LoadRandomSequence(count, min, max) end + +--- Unload random values sequence +---@param sequence userdata +function rl.UnloadRandomSequence(sequence) end + +--- Misc. functions +--- Takes a screenshot of current screen (filename extension defines format) +---@param fileName string +function rl.TakeScreenshot(fileName) end + +--- Setup init configuration flags (view FLAGS) +---@param flags integer +function rl.SetConfigFlags(flags) end + +--- Open URL with default system browser (if available) +---@param url string +function rl.OpenURL(url) end + +--- Logging system +--- Set the current threshold (minimum) log level +---@param logLevel integer +function rl.SetTraceLogLevel(logLevel) end + +--- Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...) +---@param logLevel integer +---@param text string +---@param ... any +function rl.TraceLog(logLevel, text, ...) end + +--- Set custom trace log +---@param callback rl.TraceLogCallback +function rl.SetTraceLogCallback(callback) end + +--- Memory management, using internal allocators +--- Internal memory allocator +---@param size integer +---@return userdata +function rl.MemAlloc(size) end + +--- Internal memory reallocator +---@param ptr userdata +---@param size integer +---@return userdata +function rl.MemRealloc(ptr, size) end + +--- Internal memory free +---@param ptr userdata +function rl.MemFree(ptr) end + +--- File system management functions +--- Load file data as byte array (read) +---@param fileName string +---@param dataSize userdata +---@return userdata +function rl.LoadFileData(fileName, dataSize) end + +--- Unload file data allocated by LoadFileData() +---@param data userdata +function rl.UnloadFileData(data) end + +--- Save data to file from byte array (write), returns true on success +---@param fileName string +---@param data userdata +---@param dataSize integer +---@return boolean +function rl.SaveFileData(fileName, data, dataSize) end + +--- Export data to code (.h), returns true on success +---@param data userdata +---@param dataSize integer +---@param fileName string +---@return boolean +function rl.ExportDataAsCode(data, dataSize, fileName) end + +--- Load text data from file (read), returns a '\0' terminated string +---@param fileName string +---@return string +function rl.LoadFileText(fileName) end + +--- Unload file text data allocated by LoadFileText() +---@param text string +function rl.UnloadFileText(text) end + +--- Save text data to file (write), string must be '\0' terminated, returns true on success +---@param fileName string +---@param text string +---@return boolean +function rl.SaveFileText(fileName, text) end + +--- File access custom callbacks +--- WARNING: Callbacks setup is intended for advanced users +--- Set custom file binary data loader +---@param callback rl.LoadFileDataCallback +function rl.SetLoadFileDataCallback(callback) end + +--- Set custom file binary data saver +---@param callback rl.SaveFileDataCallback +function rl.SetSaveFileDataCallback(callback) end + +--- Set custom file text data loader +---@param callback rl.LoadFileTextCallback +function rl.SetLoadFileTextCallback(callback) end + +--- Set custom file text data saver +---@param callback rl.SaveFileTextCallback +function rl.SetSaveFileTextCallback(callback) end + +--- Rename file (if exists) +---@param fileName string +---@param fileRename string +---@return integer +function rl.FileRename(fileName, fileRename) end + +--- Remove file (if exists) +---@param fileName string +---@return integer +function rl.FileRemove(fileName) end + +--- Copy file from one path to another, dstPath created if it doesn't exist +---@param srcPath string +---@param dstPath string +---@return integer +function rl.FileCopy(srcPath, dstPath) end + +--- Move file from one directory to another, dstPath created if it doesn't exist +---@param srcPath string +---@param dstPath string +---@return integer +function rl.FileMove(srcPath, dstPath) end + +--- Replace text in an existing file +---@param fileName string +---@param search string +---@param replacement string +---@return integer +function rl.FileTextReplace(fileName, search, replacement) end + +--- Find text in existing file +---@param fileName string +---@param search string +---@return integer +function rl.FileTextFindIndex(fileName, search) end + +--- Check if file exists +---@param fileName string +---@return boolean +function rl.FileExists(fileName) end + +--- Check if a directory path exists +---@param dirPath string +---@return boolean +function rl.DirectoryExists(dirPath) end + +--- Check file extension (recommended include point: .png, .wav) +---@param fileName string +---@param ext string +---@return boolean +function rl.IsFileExtension(fileName, ext) end + +--- Get file length in bytes (NOTE: GetFileSize() conflicts with windows.h) +---@param fileName string +---@return integer +function rl.GetFileLength(fileName) end + +--- Get file modification time (last write time) +---@param fileName string +---@return integer +function rl.GetFileModTime(fileName) end + +--- Get pointer to extension for a filename string (includes dot: '.png') +---@param fileName string +---@return string +function rl.GetFileExtension(fileName) end + +--- Get pointer to filename for a path string +---@param filePath string +---@return string +function rl.GetFileName(filePath) end + +--- Get filename string without extension (uses static string) +---@param filePath string +---@return string +function rl.GetFileNameWithoutExt(filePath) end + +--- Get full path for a given fileName with path (uses static string) +---@param filePath string +---@return string +function rl.GetDirectoryPath(filePath) end + +--- Get previous directory path for a given path (uses static string) +---@param dirPath string +---@return string +function rl.GetPrevDirectoryPath(dirPath) end + +--- Get current working directory (uses static string) +---@return string +function rl.GetWorkingDirectory() end + +--- Get the directory of the running application (uses static string) +---@return string +function rl.GetApplicationDirectory() end + +--- Create directories (including full path requested), returns 0 on success +---@param dirPath string +---@return integer +function rl.MakeDirectory(dirPath) end + +--- Change working directory, return true on success +---@param dirPath string +---@return boolean +function rl.ChangeDirectory(dirPath) end + +--- Check if a given path is a file or a directory +---@param path string +---@return boolean +function rl.IsPathFile(path) end + +--- Check if fileName is valid for the platform/OS +---@param fileName string +---@return boolean +function rl.IsFileNameValid(fileName) end + +--- Load directory filepaths, files and directories, no subdirs scan +---@param dirPath string +---@return rl.FilePathList +function rl.LoadDirectoryFiles(dirPath) end + +--- Load directory filepaths with extension filtering and subdir scan; some filters available: "*.*", "FILES*", "DIRS*" +---@param basePath string +---@param filter string +---@param scanSubdirs boolean +---@return rl.FilePathList +function rl.LoadDirectoryFilesEx(basePath, filter, scanSubdirs) end + +--- Unload filepaths +---@param files rl.FilePathList +function rl.UnloadDirectoryFiles(files) end + +--- Check if a file has been dropped into window +---@return boolean +function rl.IsFileDropped() end + +--- Load dropped filepaths +---@return rl.FilePathList +function rl.LoadDroppedFiles() end + +--- Unload dropped filepaths +---@param files rl.FilePathList +function rl.UnloadDroppedFiles(files) end + +--- Get the file count in a directory +---@param dirPath string +---@return integer +function rl.GetDirectoryFileCount(dirPath) end + +--- Get the file count in a directory with extension filtering and recursive directory scan. Use 'DIR' in the filter string to include directories in the result +---@param basePath string +---@param filter string +---@param scanSubdirs boolean +---@return integer +function rl.GetDirectoryFileCountEx(basePath, filter, scanSubdirs) end + +--- Compression/Encoding functionality +--- Compress data (DEFLATE algorithm), memory must be MemFree() +---@param data userdata +---@param dataSize integer +---@param compDataSize userdata +---@return userdata +function rl.CompressData(data, dataSize, compDataSize) end + +--- Decompress data (DEFLATE algorithm), memory must be MemFree() +---@param compData userdata +---@param compDataSize integer +---@param dataSize userdata +---@return userdata +function rl.DecompressData(compData, compDataSize, dataSize) end + +--- Encode data to Base64 string (includes NULL terminator), memory must be MemFree() +---@param data userdata +---@param dataSize integer +---@param outputSize userdata +---@return string +function rl.EncodeDataBase64(data, dataSize, outputSize) end + +--- Decode Base64 string (expected NULL terminated), memory must be MemFree() +---@param text string +---@param outputSize userdata +---@return userdata +function rl.DecodeDataBase64(text, outputSize) end + +--- Compute CRC32 hash code +---@param data userdata +---@param dataSize integer +---@return integer +function rl.ComputeCRC32(data, dataSize) end + +--- Compute MD5 hash code, returns static int[4] (16 bytes) +---@param data userdata +---@param dataSize integer +---@return userdata +function rl.ComputeMD5(data, dataSize) end + +--- Compute SHA1 hash code, returns static int[5] (20 bytes) +---@param data userdata +---@param dataSize integer +---@return userdata +function rl.ComputeSHA1(data, dataSize) end + +--- Compute SHA256 hash code, returns static int[8] (32 bytes) +---@param data userdata +---@param dataSize integer +---@return userdata +function rl.ComputeSHA256(data, dataSize) end + +--- Automation events functionality +--- Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS +---@param fileName string +---@return rl.AutomationEventList +function rl.LoadAutomationEventList(fileName) end + +--- Unload automation events list from file +---@param list rl.AutomationEventList +function rl.UnloadAutomationEventList(list) end + +--- Export automation events list as text file +---@param list rl.AutomationEventList +---@param fileName string +---@return boolean +function rl.ExportAutomationEventList(list, fileName) end + +--- Set automation event list to record to +---@param list userdata +function rl.SetAutomationEventList(list) end + +--- Set automation event internal base frame to start recording +---@param frame integer +function rl.SetAutomationEventBaseFrame(frame) end + +--- Start recording automation events (AutomationEventList must be set) +function rl.StartAutomationEventRecording() end + +--- Stop recording automation events +function rl.StopAutomationEventRecording() end + +--- Play a recorded automation event +---@param event rl.AutomationEvent +function rl.PlayAutomationEvent(event) end + +--- Input Handling Functions (Module: core) +--- Input-related functions: keyboard +--- Check if a key has been pressed once +---@param key integer +---@return boolean +function rl.IsKeyPressed(key) end + +--- Check if a key has been pressed again +---@param key integer +---@return boolean +function rl.IsKeyPressedRepeat(key) end + +--- Check if a key is being pressed +---@param key integer +---@return boolean +function rl.IsKeyDown(key) end + +--- Check if a key has been released once +---@param key integer +---@return boolean +function rl.IsKeyReleased(key) end + +--- Check if a key is NOT being pressed +---@param key integer +---@return boolean +function rl.IsKeyUp(key) end + +--- Get key pressed (keycode), call it multiple times for keys queued, returns 0 when the queue is empty +---@return integer +function rl.GetKeyPressed() end + +--- Get char pressed (unicode), call it multiple times for chars queued, returns 0 when the queue is empty +---@return integer +function rl.GetCharPressed() end + +--- Get name of a QWERTY key on the current keyboard layout (eg returns string 'q' for KEY_A on an AZERTY keyboard) +---@param key integer +---@return string +function rl.GetKeyName(key) end + +--- Set a custom key to exit program (default is ESC) +---@param key integer +function rl.SetExitKey(key) end + +--- Input-related functions: gamepads +--- Check if a gamepad is available +---@param gamepad integer +---@return boolean +function rl.IsGamepadAvailable(gamepad) end + +--- Get gamepad internal name id +---@param gamepad integer +---@return string +function rl.GetGamepadName(gamepad) end + +--- Check if a gamepad button has been pressed once +---@param gamepad integer +---@param button integer +---@return boolean +function rl.IsGamepadButtonPressed(gamepad, button) end + +--- Check if a gamepad button is being pressed +---@param gamepad integer +---@param button integer +---@return boolean +function rl.IsGamepadButtonDown(gamepad, button) end + +--- Check if a gamepad button has been released once +---@param gamepad integer +---@param button integer +---@return boolean +function rl.IsGamepadButtonReleased(gamepad, button) end + +--- Check if a gamepad button is NOT being pressed +---@param gamepad integer +---@param button integer +---@return boolean +function rl.IsGamepadButtonUp(gamepad, button) end + +--- Get the last gamepad button pressed +---@return integer +function rl.GetGamepadButtonPressed() end + +--- Get axis count for a gamepad +---@param gamepad integer +---@return integer +function rl.GetGamepadAxisCount(gamepad) end + +--- Get movement value for a gamepad axis +---@param gamepad integer +---@param axis integer +---@return number +function rl.GetGamepadAxisMovement(gamepad, axis) end + +--- Set internal gamepad mappings (SDL_GameControllerDB) +---@param mappings string +---@return integer +function rl.SetGamepadMappings(mappings) end + +--- Set gamepad vibration for both motors (duration in seconds) +---@param gamepad integer +---@param leftMotor number +---@param rightMotor number +---@param duration number +function rl.SetGamepadVibration(gamepad, leftMotor, rightMotor, duration) end + +--- Input-related functions: mouse +--- Check if a mouse button has been pressed once +---@param button integer +---@return boolean +function rl.IsMouseButtonPressed(button) end + +--- Check if a mouse button is being pressed +---@param button integer +---@return boolean +function rl.IsMouseButtonDown(button) end + +--- Check if a mouse button has been released once +---@param button integer +---@return boolean +function rl.IsMouseButtonReleased(button) end + +--- Check if a mouse button is NOT being pressed +---@param button integer +---@return boolean +function rl.IsMouseButtonUp(button) end + +--- Get mouse position X +---@return integer +function rl.GetMouseX() end + +--- Get mouse position Y +---@return integer +function rl.GetMouseY() end + +--- Get mouse position XY +---@return rl.Vector2 +function rl.GetMousePosition() end + +--- Get mouse delta between frames +---@return rl.Vector2 +function rl.GetMouseDelta() end + +--- Set mouse position XY +---@param x integer +---@param y integer +function rl.SetMousePosition(x, y) end + +--- Set mouse offset +---@param offsetX integer +---@param offsetY integer +function rl.SetMouseOffset(offsetX, offsetY) end + +--- Set mouse scaling +---@param scaleX number +---@param scaleY number +function rl.SetMouseScale(scaleX, scaleY) end + +--- Get mouse wheel movement for X or Y, whichever is larger +---@return number +function rl.GetMouseWheelMove() end + +--- Get mouse wheel movement for both X and Y +---@return rl.Vector2 +function rl.GetMouseWheelMoveV() end + +--- Set mouse cursor +---@param cursor integer +function rl.SetMouseCursor(cursor) end + +--- Input-related functions: touch +--- Get touch position X for touch point 0 (relative to screen size) +---@return integer +function rl.GetTouchX() end + +--- Get touch position Y for touch point 0 (relative to screen size) +---@return integer +function rl.GetTouchY() end + +--- Get touch position XY for a touch point index (relative to screen size) +---@param index integer +---@return rl.Vector2 +function rl.GetTouchPosition(index) end + +--- Get touch point identifier for given index +---@param index integer +---@return integer +function rl.GetTouchPointId(index) end + +--- Get number of touch points +---@return integer +function rl.GetTouchPointCount() end + +--- Gestures and Touch Handling Functions (Module: rgestures) +--- Enable a set of gestures using flags +---@param flags integer +function rl.SetGesturesEnabled(flags) end + +--- Check if a gesture have been detected +---@param gesture integer +---@return boolean +function rl.IsGestureDetected(gesture) end + +--- Get latest detected gesture +---@return integer +function rl.GetGestureDetected() end + +--- Get gesture hold time in seconds +---@return number +function rl.GetGestureHoldDuration() end + +--- Get gesture drag vector +---@return rl.Vector2 +function rl.GetGestureDragVector() end + +--- Get gesture drag angle +---@return number +function rl.GetGestureDragAngle() end + +--- Get gesture pinch delta +---@return rl.Vector2 +function rl.GetGesturePinchVector() end + +--- Get gesture pinch angle +---@return number +function rl.GetGesturePinchAngle() end + +--- Camera System Functions (Module: rcamera) +--- Update camera position for selected mode +---@param camera userdata +---@param mode integer +function rl.UpdateCamera(camera, mode) end + +--- Update camera movement/rotation +---@param camera userdata +---@param movement rl.Vector3 +---@param rotation rl.Vector3 +---@param zoom number +function rl.UpdateCameraPro(camera, movement, rotation, zoom) end + +--- Basic Shapes Drawing Functions (Module: shapes) +--- Set texture and rectangle to be used on shapes drawing +--- NOTE: It can be useful when using basic shapes and one single font, +--- defining a font char white rectangle would allow drawing everything in a single draw call +--- Set texture and rectangle to be used on shapes drawing +---@param texture rl.Texture +---@param source rl.Rectangle +function rl.SetShapesTexture(texture, source) end + +--- Get texture that is used for shapes drawing +---@return rl.Texture +function rl.GetShapesTexture() end + +--- Get texture source rectangle that is used for shapes drawing +---@return rl.Rectangle +function rl.GetShapesTextureRectangle() end + +--- Basic shapes drawing functions +--- Draw a pixel using geometry [Can be slow, use with care] +---@param posX integer +---@param posY integer +---@param color rl.Color +function rl.DrawPixel(posX, posY, color) end + +--- Draw a pixel using geometry (Vector version) [Can be slow, use with care] +---@param position rl.Vector2 +---@param color rl.Color +function rl.DrawPixelV(position, color) end + +--- Draw a line +---@param startPosX integer +---@param startPosY integer +---@param endPosX integer +---@param endPosY integer +---@param color rl.Color +function rl.DrawLine(startPosX, startPosY, endPosX, endPosY, color) end + +--- Draw a line (using gl lines) +---@param startPos rl.Vector2 +---@param endPos rl.Vector2 +---@param color rl.Color +function rl.DrawLineV(startPos, endPos, color) end + +--- Draw a line (using triangles/quads) +---@param startPos rl.Vector2 +---@param endPos rl.Vector2 +---@param thick number +---@param color rl.Color +function rl.DrawLineEx(startPos, endPos, thick, color) end + +--- Draw lines sequence (using gl lines) +---@param points userdata +---@param pointCount integer +---@param color rl.Color +function rl.DrawLineStrip(points, pointCount, color) end + +--- Draw line segment cubic-bezier in-out interpolation +---@param startPos rl.Vector2 +---@param endPos rl.Vector2 +---@param thick number +---@param color rl.Color +function rl.DrawLineBezier(startPos, endPos, thick, color) end + +--- Draw a dashed line +---@param startPos rl.Vector2 +---@param endPos rl.Vector2 +---@param dashSize integer +---@param spaceSize integer +---@param color rl.Color +function rl.DrawLineDashed(startPos, endPos, dashSize, spaceSize, color) end + +--- Draw a color-filled circle +---@param centerX integer +---@param centerY integer +---@param radius number +---@param color rl.Color +function rl.DrawCircle(centerX, centerY, radius, color) end + +--- Draw a color-filled circle (Vector version) +---@param center rl.Vector2 +---@param radius number +---@param color rl.Color +function rl.DrawCircleV(center, radius, color) end + +--- Draw a gradient-filled circle +---@param center rl.Vector2 +---@param radius number +---@param inner rl.Color +---@param outer rl.Color +function rl.DrawCircleGradient(center, radius, inner, outer) end + +--- Draw a piece of a circle +---@param center rl.Vector2 +---@param radius number +---@param startAngle number +---@param endAngle number +---@param segments integer +---@param color rl.Color +function rl.DrawCircleSector(center, radius, startAngle, endAngle, segments, color) end + +--- Draw circle sector outline +---@param center rl.Vector2 +---@param radius number +---@param startAngle number +---@param endAngle number +---@param segments integer +---@param color rl.Color +function rl.DrawCircleSectorLines(center, radius, startAngle, endAngle, segments, color) end + +--- Draw circle outline +---@param centerX integer +---@param centerY integer +---@param radius number +---@param color rl.Color +function rl.DrawCircleLines(centerX, centerY, radius, color) end + +--- Draw circle outline (Vector version) +---@param center rl.Vector2 +---@param radius number +---@param color rl.Color +function rl.DrawCircleLinesV(center, radius, color) end + +--- Draw ellipse +---@param centerX integer +---@param centerY integer +---@param radiusH number +---@param radiusV number +---@param color rl.Color +function rl.DrawEllipse(centerX, centerY, radiusH, radiusV, color) end + +--- Draw ellipse (Vector version) +---@param center rl.Vector2 +---@param radiusH number +---@param radiusV number +---@param color rl.Color +function rl.DrawEllipseV(center, radiusH, radiusV, color) end + +--- Draw ellipse outline +---@param centerX integer +---@param centerY integer +---@param radiusH number +---@param radiusV number +---@param color rl.Color +function rl.DrawEllipseLines(centerX, centerY, radiusH, radiusV, color) end + +--- Draw ellipse outline (Vector version) +---@param center rl.Vector2 +---@param radiusH number +---@param radiusV number +---@param color rl.Color +function rl.DrawEllipseLinesV(center, radiusH, radiusV, color) end + +--- Draw ring +---@param center rl.Vector2 +---@param innerRadius number +---@param outerRadius number +---@param startAngle number +---@param endAngle number +---@param segments integer +---@param color rl.Color +function rl.DrawRing(center, innerRadius, outerRadius, startAngle, endAngle, segments, color) end + +--- Draw ring outline +---@param center rl.Vector2 +---@param innerRadius number +---@param outerRadius number +---@param startAngle number +---@param endAngle number +---@param segments integer +---@param color rl.Color +function rl.DrawRingLines(center, innerRadius, outerRadius, startAngle, endAngle, segments, color) end + +--- Draw a color-filled rectangle +---@param posX integer +---@param posY integer +---@param width integer +---@param height integer +---@param color rl.Color +function rl.DrawRectangle(posX, posY, width, height, color) end + +--- Draw a color-filled rectangle (Vector version) +---@param position rl.Vector2 +---@param size rl.Vector2 +---@param color rl.Color +function rl.DrawRectangleV(position, size, color) end + +--- Draw a color-filled rectangle +---@param rec rl.Rectangle +---@param color rl.Color +function rl.DrawRectangleRec(rec, color) end + +--- Draw a color-filled rectangle with pro parameters +---@param rec rl.Rectangle +---@param origin rl.Vector2 +---@param rotation number +---@param color rl.Color +function rl.DrawRectanglePro(rec, origin, rotation, color) end + +--- Draw a vertical-gradient-filled rectangle +---@param posX integer +---@param posY integer +---@param width integer +---@param height integer +---@param top rl.Color +---@param bottom rl.Color +function rl.DrawRectangleGradientV(posX, posY, width, height, top, bottom) end + +--- Draw a horizontal-gradient-filled rectangle +---@param posX integer +---@param posY integer +---@param width integer +---@param height integer +---@param left rl.Color +---@param right rl.Color +function rl.DrawRectangleGradientH(posX, posY, width, height, left, right) end + +--- Draw a gradient-filled rectangle with custom vertex colors +---@param rec rl.Rectangle +---@param topLeft rl.Color +---@param bottomLeft rl.Color +---@param bottomRight rl.Color +---@param topRight rl.Color +function rl.DrawRectangleGradientEx(rec, topLeft, bottomLeft, bottomRight, topRight) end + +--- Draw rectangle outline +---@param posX integer +---@param posY integer +---@param width integer +---@param height integer +---@param color rl.Color +function rl.DrawRectangleLines(posX, posY, width, height, color) end + +--- Draw rectangle outline with extended parameters +---@param rec rl.Rectangle +---@param lineThick number +---@param color rl.Color +function rl.DrawRectangleLinesEx(rec, lineThick, color) end + +--- Draw rectangle with rounded edges +---@param rec rl.Rectangle +---@param roundness number +---@param segments integer +---@param color rl.Color +function rl.DrawRectangleRounded(rec, roundness, segments, color) end + +--- Draw rectangle lines with rounded edges +---@param rec rl.Rectangle +---@param roundness number +---@param segments integer +---@param color rl.Color +function rl.DrawRectangleRoundedLines(rec, roundness, segments, color) end + +--- Draw rectangle with rounded edges outline +---@param rec rl.Rectangle +---@param roundness number +---@param segments integer +---@param lineThick number +---@param color rl.Color +function rl.DrawRectangleRoundedLinesEx(rec, roundness, segments, lineThick, color) end + +--- Draw a color-filled triangle (vertex in counter-clockwise order!) +---@param v1 rl.Vector2 +---@param v2 rl.Vector2 +---@param v3 rl.Vector2 +---@param color rl.Color +function rl.DrawTriangle(v1, v2, v3, color) end + +--- Draw triangle outline (vertex in counter-clockwise order!) +---@param v1 rl.Vector2 +---@param v2 rl.Vector2 +---@param v3 rl.Vector2 +---@param color rl.Color +function rl.DrawTriangleLines(v1, v2, v3, color) end + +--- Draw a triangle fan defined by points (first vertex is the center) +---@param points userdata +---@param pointCount integer +---@param color rl.Color +function rl.DrawTriangleFan(points, pointCount, color) end + +--- Draw a triangle strip defined by points +---@param points userdata +---@param pointCount integer +---@param color rl.Color +function rl.DrawTriangleStrip(points, pointCount, color) end + +--- Draw a regular polygon (Vector version) +---@param center rl.Vector2 +---@param sides integer +---@param radius number +---@param rotation number +---@param color rl.Color +function rl.DrawPoly(center, sides, radius, rotation, color) end + +--- Draw a polygon outline of n sides +---@param center rl.Vector2 +---@param sides integer +---@param radius number +---@param rotation number +---@param color rl.Color +function rl.DrawPolyLines(center, sides, radius, rotation, color) end + +--- Draw a polygon outline of n sides with extended parameters +---@param center rl.Vector2 +---@param sides integer +---@param radius number +---@param rotation number +---@param lineThick number +---@param color rl.Color +function rl.DrawPolyLinesEx(center, sides, radius, rotation, lineThick, color) end + +--- Splines drawing functions +--- Draw spline: Linear, minimum 2 points +---@param points userdata +---@param pointCount integer +---@param thick number +---@param color rl.Color +function rl.DrawSplineLinear(points, pointCount, thick, color) end + +--- Draw spline: B-Spline, minimum 4 points +---@param points userdata +---@param pointCount integer +---@param thick number +---@param color rl.Color +function rl.DrawSplineBasis(points, pointCount, thick, color) end + +--- Draw spline: Catmull-Rom, minimum 4 points +---@param points userdata +---@param pointCount integer +---@param thick number +---@param color rl.Color +function rl.DrawSplineCatmullRom(points, pointCount, thick, color) end + +--- Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...] +---@param points userdata +---@param pointCount integer +---@param thick number +---@param color rl.Color +function rl.DrawSplineBezierQuadratic(points, pointCount, thick, color) end + +--- Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...] +---@param points userdata +---@param pointCount integer +---@param thick number +---@param color rl.Color +function rl.DrawSplineBezierCubic(points, pointCount, thick, color) end + +--- Draw spline segment: Linear, 2 points +---@param p1 rl.Vector2 +---@param p2 rl.Vector2 +---@param thick number +---@param color rl.Color +function rl.DrawSplineSegmentLinear(p1, p2, thick, color) end + +--- Draw spline segment: B-Spline, 4 points +---@param p1 rl.Vector2 +---@param p2 rl.Vector2 +---@param p3 rl.Vector2 +---@param p4 rl.Vector2 +---@param thick number +---@param color rl.Color +function rl.DrawSplineSegmentBasis(p1, p2, p3, p4, thick, color) end + +--- Draw spline segment: Catmull-Rom, 4 points +---@param p1 rl.Vector2 +---@param p2 rl.Vector2 +---@param p3 rl.Vector2 +---@param p4 rl.Vector2 +---@param thick number +---@param color rl.Color +function rl.DrawSplineSegmentCatmullRom(p1, p2, p3, p4, thick, color) end + +--- Draw spline segment: Quadratic Bezier, 2 points, 1 control point +---@param p1 rl.Vector2 +---@param c2 rl.Vector2 +---@param p3 rl.Vector2 +---@param thick number +---@param color rl.Color +function rl.DrawSplineSegmentBezierQuadratic(p1, c2, p3, thick, color) end + +--- Draw spline segment: Cubic Bezier, 2 points, 2 control points +---@param p1 rl.Vector2 +---@param c2 rl.Vector2 +---@param c3 rl.Vector2 +---@param p4 rl.Vector2 +---@param thick number +---@param color rl.Color +function rl.DrawSplineSegmentBezierCubic(p1, c2, c3, p4, thick, color) end + +--- Spline segment point evaluation functions, for a given t [0.0f .. 1.0f] +--- Get (evaluate) spline point: Linear +---@param startPos rl.Vector2 +---@param endPos rl.Vector2 +---@param t number +---@return rl.Vector2 +function rl.GetSplinePointLinear(startPos, endPos, t) end + +--- Get (evaluate) spline point: B-Spline +---@param p1 rl.Vector2 +---@param p2 rl.Vector2 +---@param p3 rl.Vector2 +---@param p4 rl.Vector2 +---@param t number +---@return rl.Vector2 +function rl.GetSplinePointBasis(p1, p2, p3, p4, t) end + +--- Get (evaluate) spline point: Catmull-Rom +---@param p1 rl.Vector2 +---@param p2 rl.Vector2 +---@param p3 rl.Vector2 +---@param p4 rl.Vector2 +---@param t number +---@return rl.Vector2 +function rl.GetSplinePointCatmullRom(p1, p2, p3, p4, t) end + +--- Get (evaluate) spline point: Quadratic Bezier +---@param p1 rl.Vector2 +---@param c2 rl.Vector2 +---@param p3 rl.Vector2 +---@param t number +---@return rl.Vector2 +function rl.GetSplinePointBezierQuad(p1, c2, p3, t) end + +--- Get (evaluate) spline point: Cubic Bezier +---@param p1 rl.Vector2 +---@param c2 rl.Vector2 +---@param c3 rl.Vector2 +---@param p4 rl.Vector2 +---@param t number +---@return rl.Vector2 +function rl.GetSplinePointBezierCubic(p1, c2, c3, p4, t) end + +--- Basic shapes collision detection functions +--- Check collision between two rectangles +---@param rec1 rl.Rectangle +---@param rec2 rl.Rectangle +---@return boolean +function rl.CheckCollisionRecs(rec1, rec2) end + +--- Check collision between two circles +---@param center1 rl.Vector2 +---@param radius1 number +---@param center2 rl.Vector2 +---@param radius2 number +---@return boolean +function rl.CheckCollisionCircles(center1, radius1, center2, radius2) end + +--- Check collision between circle and rectangle +---@param center rl.Vector2 +---@param radius number +---@param rec rl.Rectangle +---@return boolean +function rl.CheckCollisionCircleRec(center, radius, rec) end + +--- Check if circle collides with a line created betweeen two points [p1] and [p2] +---@param center rl.Vector2 +---@param radius number +---@param p1 rl.Vector2 +---@param p2 rl.Vector2 +---@return boolean +function rl.CheckCollisionCircleLine(center, radius, p1, p2) end + +--- Check if point is inside rectangle +---@param point rl.Vector2 +---@param rec rl.Rectangle +---@return boolean +function rl.CheckCollisionPointRec(point, rec) end + +--- Check if point is inside circle +---@param point rl.Vector2 +---@param center rl.Vector2 +---@param radius number +---@return boolean +function rl.CheckCollisionPointCircle(point, center, radius) end + +--- Check if point is inside a triangle +---@param point rl.Vector2 +---@param p1 rl.Vector2 +---@param p2 rl.Vector2 +---@param p3 rl.Vector2 +---@return boolean +function rl.CheckCollisionPointTriangle(point, p1, p2, p3) end + +--- Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold] +---@param point rl.Vector2 +---@param p1 rl.Vector2 +---@param p2 rl.Vector2 +---@param threshold integer +---@return boolean +function rl.CheckCollisionPointLine(point, p1, p2, threshold) end + +--- Check if point is within a polygon described by array of vertices +---@param point rl.Vector2 +---@param points userdata +---@param pointCount integer +---@return boolean +function rl.CheckCollisionPointPoly(point, points, pointCount) end + +--- Check the collision between two lines defined by two points each, returns collision point by reference +---@param startPos1 rl.Vector2 +---@param endPos1 rl.Vector2 +---@param startPos2 rl.Vector2 +---@param endPos2 rl.Vector2 +---@param collisionPoint userdata +---@return boolean +function rl.CheckCollisionLines(startPos1, endPos1, startPos2, endPos2, collisionPoint) end + +--- Get collision rectangle for two rectangles collision +---@param rec1 rl.Rectangle +---@param rec2 rl.Rectangle +---@return rl.Rectangle +function rl.GetCollisionRec(rec1, rec2) end + +--- Texture Loading and Drawing Functions (Module: textures) +--- Image loading functions +--- NOTE: These functions do not require GPU access +--- Load image from file into CPU memory (RAM) +---@param fileName string +---@return rl.Image +function rl.LoadImage(fileName) end + +--- Load image from RAW file data +---@param fileName string +---@param width integer +---@param height integer +---@param format integer +---@param headerSize integer +---@return rl.Image +function rl.LoadImageRaw(fileName, width, height, format, headerSize) end + +--- Load image sequence from file (frames appended to image.data) +---@param fileName string +---@param frames userdata +---@return rl.Image +function rl.LoadImageAnim(fileName, frames) end + +--- Load image sequence from memory buffer +---@param fileType string +---@param fileData userdata +---@param dataSize integer +---@param frames userdata +---@return rl.Image +function rl.LoadImageAnimFromMemory(fileType, fileData, dataSize, frames) end + +--- Load image from memory buffer, fileType refers to extension: i.e. '.png' +---@param fileType string +---@param fileData userdata +---@param dataSize integer +---@return rl.Image +function rl.LoadImageFromMemory(fileType, fileData, dataSize) end + +--- Load image from GPU texture data +---@param texture rl.Texture +---@return rl.Image +function rl.LoadImageFromTexture(texture) end + +--- Load image from screen buffer and (screenshot) +---@return rl.Image +function rl.LoadImageFromScreen() end + +--- Check if an image is valid (data and parameters) +---@param image rl.Image +---@return boolean +function rl.IsImageValid(image) end + +--- Unload image from CPU memory (RAM) +---@param image rl.Image +function rl.UnloadImage(image) end + +--- Export image data to file, returns true on success +---@param image rl.Image +---@param fileName string +---@return boolean +function rl.ExportImage(image, fileName) end + +--- Export image to memory buffer, memory must be MemFree() +---@param image rl.Image +---@param fileType string +---@param fileSize userdata +---@return userdata +function rl.ExportImageToMemory(image, fileType, fileSize) end + +--- Export image as code file defining an array of bytes, returns true on success +---@param image rl.Image +---@param fileName string +---@return boolean +function rl.ExportImageAsCode(image, fileName) end + +--- Image generation functions +--- Generate image: plain color +---@param width integer +---@param height integer +---@param color rl.Color +---@return rl.Image +function rl.GenImageColor(width, height, color) end + +--- Generate image: linear gradient, direction in degrees [0..360], 0=Vertical gradient +---@param width integer +---@param height integer +---@param direction integer +---@param start rl.Color +---@param end_ rl.Color +---@return rl.Image +function rl.GenImageGradientLinear(width, height, direction, start, end_) end + +--- Generate image: radial gradient +---@param width integer +---@param height integer +---@param density number +---@param inner rl.Color +---@param outer rl.Color +---@return rl.Image +function rl.GenImageGradientRadial(width, height, density, inner, outer) end + +--- Generate image: square gradient +---@param width integer +---@param height integer +---@param density number +---@param inner rl.Color +---@param outer rl.Color +---@return rl.Image +function rl.GenImageGradientSquare(width, height, density, inner, outer) end + +--- Generate image: checked +---@param width integer +---@param height integer +---@param checksX integer +---@param checksY integer +---@param col1 rl.Color +---@param col2 rl.Color +---@return rl.Image +function rl.GenImageChecked(width, height, checksX, checksY, col1, col2) end + +--- Generate image: white noise +---@param width integer +---@param height integer +---@param factor number +---@return rl.Image +function rl.GenImageWhiteNoise(width, height, factor) end + +--- Generate image: perlin noise +---@param width integer +---@param height integer +---@param offsetX integer +---@param offsetY integer +---@param scale number +---@return rl.Image +function rl.GenImagePerlinNoise(width, height, offsetX, offsetY, scale) end + +--- Generate image: cellular algorithm, bigger tileSize means bigger cells +---@param width integer +---@param height integer +---@param tileSize integer +---@return rl.Image +function rl.GenImageCellular(width, height, tileSize) end + +--- Generate image: grayscale image from text data +---@param width integer +---@param height integer +---@param text string +---@return rl.Image +function rl.GenImageText(width, height, text) end + +--- Image manipulation functions +--- Create an image duplicate (useful for transformations) +---@param image rl.Image +---@return rl.Image +function rl.ImageCopy(image) end + +--- Create an image from another image piece +---@param image rl.Image +---@param rec rl.Rectangle +---@return rl.Image +function rl.ImageFromImage(image, rec) end + +--- Create an image from a selected channel of another image (GRAYSCALE) +---@param image rl.Image +---@param selectedChannel integer +---@return rl.Image +function rl.ImageFromChannel(image, selectedChannel) end + +--- Create an image from text (default font) +---@param text string +---@param fontSize integer +---@param color rl.Color +---@return rl.Image +function rl.ImageText(text, fontSize, color) end + +--- Create an image from text (custom sprite font) +---@param font rl.Font +---@param text string +---@param fontSize number +---@param spacing number +---@param tint rl.Color +---@return rl.Image +function rl.ImageTextEx(font, text, fontSize, spacing, tint) end + +--- Convert image data to desired format +---@param image userdata +---@param newFormat integer +function rl.ImageFormat(image, newFormat) end + +--- Convert image to POT (power-of-two) +---@param image userdata +---@param fill rl.Color +function rl.ImageToPOT(image, fill) end + +--- Crop an image to a defined rectangle +---@param image userdata +---@param crop rl.Rectangle +function rl.ImageCrop(image, crop) end + +--- Crop image depending on alpha value +---@param image userdata +---@param threshold number +function rl.ImageAlphaCrop(image, threshold) end + +--- Clear alpha channel to desired color +---@param image userdata +---@param color rl.Color +---@param threshold number +function rl.ImageAlphaClear(image, color, threshold) end + +--- Apply alpha mask to image +---@param image userdata +---@param alphaMask rl.Image +function rl.ImageAlphaMask(image, alphaMask) end + +--- Premultiply alpha channel +---@param image userdata +function rl.ImageAlphaPremultiply(image) end + +--- Apply Gaussian blur using a box blur approximation +---@param image userdata +---@param blurSize integer +function rl.ImageBlurGaussian(image, blurSize) end + +--- Apply custom square convolution kernel to image +---@param image userdata +---@param kernel userdata +---@param kernelSize integer +function rl.ImageKernelConvolution(image, kernel, kernelSize) end + +--- Resize image (Bicubic scaling algorithm) +---@param image userdata +---@param newWidth integer +---@param newHeight integer +function rl.ImageResize(image, newWidth, newHeight) end + +--- Resize image (Nearest-Neighbor scaling algorithm) +---@param image userdata +---@param newWidth integer +---@param newHeight integer +function rl.ImageResizeNN(image, newWidth, newHeight) end + +--- Resize canvas and fill with color +---@param image userdata +---@param newWidth integer +---@param newHeight integer +---@param offsetX integer +---@param offsetY integer +---@param fill rl.Color +function rl.ImageResizeCanvas(image, newWidth, newHeight, offsetX, offsetY, fill) end + +--- Compute all mipmap levels for a provided image +---@param image userdata +function rl.ImageMipmaps(image) end + +--- Dither image data to 16bpp or lower (Floyd-Steinberg dithering) +---@param image userdata +---@param rBpp integer +---@param gBpp integer +---@param bBpp integer +---@param aBpp integer +function rl.ImageDither(image, rBpp, gBpp, bBpp, aBpp) end + +--- Flip image vertically +---@param image userdata +function rl.ImageFlipVertical(image) end + +--- Flip image horizontally +---@param image userdata +function rl.ImageFlipHorizontal(image) end + +--- Rotate image by input angle in degrees (-359 to 359) +---@param image userdata +---@param degrees integer +function rl.ImageRotate(image, degrees) end + +--- Rotate image clockwise 90deg +---@param image userdata +function rl.ImageRotateCW(image) end + +--- Rotate image counter-clockwise 90deg +---@param image userdata +function rl.ImageRotateCCW(image) end + +--- Modify image color: tint +---@param image userdata +---@param color rl.Color +function rl.ImageColorTint(image, color) end + +--- Modify image color: invert +---@param image userdata +function rl.ImageColorInvert(image) end + +--- Modify image color: grayscale +---@param image userdata +function rl.ImageColorGrayscale(image) end + +--- Modify image color: contrast (-100 to 100) +---@param image userdata +---@param contrast number +function rl.ImageColorContrast(image, contrast) end + +--- Modify image color: brightness (-255 to 255) +---@param image userdata +---@param brightness integer +function rl.ImageColorBrightness(image, brightness) end + +--- Modify image color: replace color +---@param image userdata +---@param color rl.Color +---@param replace rl.Color +function rl.ImageColorReplace(image, color, replace) end + +--- Load color data from image as a Color array (RGBA - 32bit) +---@param image rl.Image +---@return userdata +function rl.LoadImageColors(image) end + +--- Load colors palette from image as a Color array (RGBA - 32bit) +---@param image rl.Image +---@param maxPaletteSize integer +---@param colorCount userdata +---@return userdata +function rl.LoadImagePalette(image, maxPaletteSize, colorCount) end + +--- Unload color data loaded with LoadImageColors() +---@param colors userdata +function rl.UnloadImageColors(colors) end + +--- Unload colors palette loaded with LoadImagePalette() +---@param colors userdata +function rl.UnloadImagePalette(colors) end + +--- Get image alpha border rectangle +---@param image rl.Image +---@param threshold number +---@return rl.Rectangle +function rl.GetImageAlphaBorder(image, threshold) end + +--- Get image pixel color at (x, y) position +---@param image rl.Image +---@param x integer +---@param y integer +---@return rl.Color +function rl.GetImageColor(image, x, y) end + +--- Image drawing functions +--- NOTE: Image software-rendering functions (CPU) +--- Clear image background with given color +---@param dst userdata +---@param color rl.Color +function rl.ImageClearBackground(dst, color) end + +--- Draw pixel within an image +---@param dst userdata +---@param posX integer +---@param posY integer +---@param color rl.Color +function rl.ImageDrawPixel(dst, posX, posY, color) end + +--- Draw pixel within an image (Vector version) +---@param dst userdata +---@param position rl.Vector2 +---@param color rl.Color +function rl.ImageDrawPixelV(dst, position, color) end + +--- Draw line within an image +---@param dst userdata +---@param startPosX integer +---@param startPosY integer +---@param endPosX integer +---@param endPosY integer +---@param color rl.Color +function rl.ImageDrawLine(dst, startPosX, startPosY, endPosX, endPosY, color) end + +--- Draw line within an image (Vector version) +---@param dst userdata +---@param start rl.Vector2 +---@param end_ rl.Vector2 +---@param color rl.Color +function rl.ImageDrawLineV(dst, start, end_, color) end + +--- Draw a line defining thickness within an image +---@param dst userdata +---@param start rl.Vector2 +---@param end_ rl.Vector2 +---@param thick integer +---@param color rl.Color +function rl.ImageDrawLineEx(dst, start, end_, thick, color) end + +--- Draw a filled circle within an image +---@param dst userdata +---@param centerX integer +---@param centerY integer +---@param radius integer +---@param color rl.Color +function rl.ImageDrawCircle(dst, centerX, centerY, radius, color) end + +--- Draw a filled circle within an image (Vector version) +---@param dst userdata +---@param center rl.Vector2 +---@param radius integer +---@param color rl.Color +function rl.ImageDrawCircleV(dst, center, radius, color) end + +--- Draw circle outline within an image +---@param dst userdata +---@param centerX integer +---@param centerY integer +---@param radius integer +---@param color rl.Color +function rl.ImageDrawCircleLines(dst, centerX, centerY, radius, color) end + +--- Draw circle outline within an image (Vector version) +---@param dst userdata +---@param center rl.Vector2 +---@param radius integer +---@param color rl.Color +function rl.ImageDrawCircleLinesV(dst, center, radius, color) end + +--- Draw rectangle within an image +---@param dst userdata +---@param posX integer +---@param posY integer +---@param width integer +---@param height integer +---@param color rl.Color +function rl.ImageDrawRectangle(dst, posX, posY, width, height, color) end + +--- Draw rectangle within an image (Vector version) +---@param dst userdata +---@param position rl.Vector2 +---@param size rl.Vector2 +---@param color rl.Color +function rl.ImageDrawRectangleV(dst, position, size, color) end + +--- Draw rectangle within an image +---@param dst userdata +---@param rec rl.Rectangle +---@param color rl.Color +function rl.ImageDrawRectangleRec(dst, rec, color) end + +--- Draw rectangle lines within an image +---@param dst userdata +---@param rec rl.Rectangle +---@param thick integer +---@param color rl.Color +function rl.ImageDrawRectangleLines(dst, rec, thick, color) end + +--- Draw triangle within an image +---@param dst userdata +---@param v1 rl.Vector2 +---@param v2 rl.Vector2 +---@param v3 rl.Vector2 +---@param color rl.Color +function rl.ImageDrawTriangle(dst, v1, v2, v3, color) end + +--- Draw triangle with interpolated colors within an image +---@param dst userdata +---@param v1 rl.Vector2 +---@param v2 rl.Vector2 +---@param v3 rl.Vector2 +---@param c1 rl.Color +---@param c2 rl.Color +---@param c3 rl.Color +function rl.ImageDrawTriangleEx(dst, v1, v2, v3, c1, c2, c3) end + +--- Draw triangle outline within an image +---@param dst userdata +---@param v1 rl.Vector2 +---@param v2 rl.Vector2 +---@param v3 rl.Vector2 +---@param color rl.Color +function rl.ImageDrawTriangleLines(dst, v1, v2, v3, color) end + +--- Draw a triangle fan defined by points within an image (first vertex is the center) +---@param dst userdata +---@param points userdata +---@param pointCount integer +---@param color rl.Color +function rl.ImageDrawTriangleFan(dst, points, pointCount, color) end + +--- Draw a triangle strip defined by points within an image +---@param dst userdata +---@param points userdata +---@param pointCount integer +---@param color rl.Color +function rl.ImageDrawTriangleStrip(dst, points, pointCount, color) end + +--- Draw a source image within a destination image (tint applied to source) +---@param dst userdata +---@param src rl.Image +---@param srcRec rl.Rectangle +---@param dstRec rl.Rectangle +---@param tint rl.Color +function rl.ImageDraw(dst, src, srcRec, dstRec, tint) end + +--- Draw text (using default font) within an image (destination) +---@param dst userdata +---@param text string +---@param posX integer +---@param posY integer +---@param fontSize integer +---@param color rl.Color +function rl.ImageDrawText(dst, text, posX, posY, fontSize, color) end + +--- Draw text (custom sprite font) within an image (destination) +---@param dst userdata +---@param font rl.Font +---@param text string +---@param position rl.Vector2 +---@param fontSize number +---@param spacing number +---@param tint rl.Color +function rl.ImageDrawTextEx(dst, font, text, position, fontSize, spacing, tint) end + +--- Texture loading functions +--- NOTE: These functions require GPU access +--- Load texture from file into GPU memory (VRAM) +---@param fileName string +---@return rl.Texture +function rl.LoadTexture(fileName) end + +--- Load texture from image data +---@param image rl.Image +---@return rl.Texture +function rl.LoadTextureFromImage(image) end + +--- Load cubemap from image, multiple image cubemap layouts supported +---@param image rl.Image +---@param layout integer +---@return rl.Texture +function rl.LoadTextureCubemap(image, layout) end + +--- Load texture for rendering (framebuffer) +---@param width integer +---@param height integer +---@return rl.RenderTexture +function rl.LoadRenderTexture(width, height) end + +--- Check if a texture is valid (loaded in GPU) +---@param texture rl.Texture +---@return boolean +function rl.IsTextureValid(texture) end + +--- Unload texture from GPU memory (VRAM) +---@param texture rl.Texture +function rl.UnloadTexture(texture) end + +--- Check if a render texture is valid (loaded in GPU) +---@param target rl.RenderTexture +---@return boolean +function rl.IsRenderTextureValid(target) end + +--- Unload render texture from GPU memory (VRAM) +---@param target rl.RenderTexture +function rl.UnloadRenderTexture(target) end + +--- Update GPU texture with new data (pixels should be able to fill texture) +---@param texture rl.Texture +---@param pixels userdata +function rl.UpdateTexture(texture, pixels) end + +--- Update GPU texture rectangle with new data (pixels and rec should fit in texture) +---@param texture rl.Texture +---@param rec rl.Rectangle +---@param pixels userdata +function rl.UpdateTextureRec(texture, rec, pixels) end + +--- Texture configuration functions +--- Generate GPU mipmaps for a texture +---@param texture userdata +function rl.GenTextureMipmaps(texture) end + +--- Set texture scaling filter mode +---@param texture rl.Texture +---@param filter integer +function rl.SetTextureFilter(texture, filter) end + +--- Set texture wrapping mode +---@param texture rl.Texture +---@param wrap integer +function rl.SetTextureWrap(texture, wrap) end + +--- Texture drawing functions +--- Draw a Texture2D +---@param texture rl.Texture +---@param posX integer +---@param posY integer +---@param tint rl.Color +function rl.DrawTexture(texture, posX, posY, tint) end + +--- Draw a Texture2D with position defined as Vector2 +---@param texture rl.Texture +---@param position rl.Vector2 +---@param tint rl.Color +function rl.DrawTextureV(texture, position, tint) end + +--- Draw a Texture2D with extended parameters +---@param texture rl.Texture +---@param position rl.Vector2 +---@param rotation number +---@param scale number +---@param tint rl.Color +function rl.DrawTextureEx(texture, position, rotation, scale, tint) end + +--- Draw a part of a texture defined by a rectangle +---@param texture rl.Texture +---@param source rl.Rectangle +---@param position rl.Vector2 +---@param tint rl.Color +function rl.DrawTextureRec(texture, source, position, tint) end + +--- Draw a part of a texture defined by a rectangle with 'pro' parameters +---@param texture rl.Texture +---@param source rl.Rectangle +---@param dest rl.Rectangle +---@param origin rl.Vector2 +---@param rotation number +---@param tint rl.Color +function rl.DrawTexturePro(texture, source, dest, origin, rotation, tint) end + +--- Draws a texture (or part of it) that stretches or shrinks nicely +---@param texture rl.Texture +---@param nPatchInfo rl.NPatchInfo +---@param dest rl.Rectangle +---@param origin rl.Vector2 +---@param rotation number +---@param tint rl.Color +function rl.DrawTextureNPatch(texture, nPatchInfo, dest, origin, rotation, tint) end + +--- Color/pixel related functions +--- Check if two colors are equal +---@param col1 rl.Color +---@param col2 rl.Color +---@return boolean +function rl.ColorIsEqual(col1, col2) end + +--- Get color with alpha applied, alpha goes from 0.0f to 1.0f +---@param color rl.Color +---@param alpha number +---@return rl.Color +function rl.Fade(color, alpha) end + +--- Get hexadecimal value for a Color (0xRRGGBBAA) +---@param color rl.Color +---@return integer +function rl.ColorToInt(color) end + +--- Get Color normalized as float [0..1] +---@param color rl.Color +---@return rl.Vector4 +function rl.ColorNormalize(color) end + +--- Get Color from normalized values [0..1] +---@param normalized rl.Vector4 +---@return rl.Color +function rl.ColorFromNormalized(normalized) end + +--- Get HSV values for a Color, hue [0..360], saturation/value [0..1] +---@param color rl.Color +---@return rl.Vector3 +function rl.ColorToHSV(color) end + +--- Get a Color from HSV values, hue [0..360], saturation/value [0..1] +---@param hue number +---@param saturation number +---@param value number +---@return rl.Color +function rl.ColorFromHSV(hue, saturation, value) end + +--- Get color multiplied with another color +---@param color rl.Color +---@param tint rl.Color +---@return rl.Color +function rl.ColorTint(color, tint) end + +--- Get color with brightness correction, brightness factor goes from -1.0f to 1.0f +---@param color rl.Color +---@param factor number +---@return rl.Color +function rl.ColorBrightness(color, factor) end + +--- Get color with contrast correction, contrast values between -1.0f and 1.0f +---@param color rl.Color +---@param contrast number +---@return rl.Color +function rl.ColorContrast(color, contrast) end + +--- Get color with alpha applied, alpha goes from 0.0f to 1.0f +---@param color rl.Color +---@param alpha number +---@return rl.Color +function rl.ColorAlpha(color, alpha) end + +--- Get src alpha-blended into dst color with tint +---@param dst rl.Color +---@param src rl.Color +---@param tint rl.Color +---@return rl.Color +function rl.ColorAlphaBlend(dst, src, tint) end + +--- Get color lerp interpolation between two colors, factor [0.0f..1.0f] +---@param color1 rl.Color +---@param color2 rl.Color +---@param factor number +---@return rl.Color +function rl.ColorLerp(color1, color2, factor) end + +--- Get Color structure from hexadecimal value +---@param hexValue integer +---@return rl.Color +function rl.GetColor(hexValue) end + +--- Get Color from a source pixel pointer of certain format +---@param srcPtr userdata +---@param format integer +---@return rl.Color +function rl.GetPixelColor(srcPtr, format) end + +--- Set color formatted into destination pixel pointer +---@param dstPtr userdata +---@param color rl.Color +---@param format integer +function rl.SetPixelColor(dstPtr, color, format) end + +--- Get pixel data size in bytes for certain format +---@param width integer +---@param height integer +---@param format integer +---@return integer +function rl.GetPixelDataSize(width, height, format) end + +--- Font Loading and Text Drawing Functions (Module: text) +--- Font loading/unloading functions +--- Get the default Font +---@return rl.Font +function rl.GetFontDefault() end + +--- Load font from file into GPU memory (VRAM) +---@param fileName string +---@return rl.Font +function rl.LoadFont(fileName) end + +--- Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character set, font size is provided in pixels height +---@param fileName string +---@param fontSize integer +---@param codepoints userdata +---@param codepointCount integer +---@return rl.Font +function rl.LoadFontEx(fileName, fontSize, codepoints, codepointCount) end + +--- Load font from Image (XNA style) +---@param image rl.Image +---@param key rl.Color +---@param firstChar integer +---@return rl.Font +function rl.LoadFontFromImage(image, key, firstChar) end + +--- Load font from memory buffer, fileType refers to extension: i.e. '.ttf' +---@param fileType string +---@param fileData userdata +---@param dataSize integer +---@param fontSize integer +---@param codepoints userdata +---@param codepointCount integer +---@return rl.Font +function rl.LoadFontFromMemory(fileType, fileData, dataSize, fontSize, codepoints, codepointCount) end + +--- Check if a font is valid (font data loaded, WARNING: GPU texture not checked) +---@param font rl.Font +---@return boolean +function rl.IsFontValid(font) end + +--- Load font data for further use +---@param fileData userdata +---@param dataSize integer +---@param fontSize integer +---@param codepoints userdata +---@param codepointCount integer +---@param type integer +---@param glyphCount userdata +---@return userdata +function rl.LoadFontData(fileData, dataSize, fontSize, codepoints, codepointCount, type, glyphCount) end + +--- Generate image font atlas using chars info +---@param glyphs userdata +---@param glyphRecs userdata +---@param glyphCount integer +---@param fontSize integer +---@param padding integer +---@param packMethod integer +---@return rl.Image +function rl.GenImageFontAtlas(glyphs, glyphRecs, glyphCount, fontSize, padding, packMethod) end + +--- Unload font chars info data (RAM) +---@param glyphs userdata +---@param glyphCount integer +function rl.UnloadFontData(glyphs, glyphCount) end + +--- Unload font from GPU memory (VRAM) +---@param font rl.Font +function rl.UnloadFont(font) end + +--- Export font as code file, returns true on success +---@param font rl.Font +---@param fileName string +---@return boolean +function rl.ExportFontAsCode(font, fileName) end + +--- Text drawing functions +--- Draw current FPS +---@param posX integer +---@param posY integer +function rl.DrawFPS(posX, posY) end + +--- Draw text (using default font) +---@param text string +---@param posX integer +---@param posY integer +---@param fontSize integer +---@param color rl.Color +function rl.DrawText(text, posX, posY, fontSize, color) end + +--- Draw text using font and additional parameters +---@param font rl.Font +---@param text string +---@param position rl.Vector2 +---@param fontSize number +---@param spacing number +---@param tint rl.Color +function rl.DrawTextEx(font, text, position, fontSize, spacing, tint) end + +--- Draw text using Font and pro parameters (rotation) +---@param font rl.Font +---@param text string +---@param position rl.Vector2 +---@param origin rl.Vector2 +---@param rotation number +---@param fontSize number +---@param spacing number +---@param tint rl.Color +function rl.DrawTextPro(font, text, position, origin, rotation, fontSize, spacing, tint) end + +--- Draw one character (codepoint) +---@param font rl.Font +---@param codepoint integer +---@param position rl.Vector2 +---@param fontSize number +---@param tint rl.Color +function rl.DrawTextCodepoint(font, codepoint, position, fontSize, tint) end + +--- Draw multiple character (codepoint) +---@param font rl.Font +---@param codepoints userdata +---@param codepointCount integer +---@param position rl.Vector2 +---@param fontSize number +---@param spacing number +---@param tint rl.Color +function rl.DrawTextCodepoints(font, codepoints, codepointCount, position, fontSize, spacing, tint) end + +--- Text font info functions +--- Set vertical line spacing when drawing with line-breaks +---@param spacing integer +function rl.SetTextLineSpacing(spacing) end + +--- Measure string width for default font +---@param text string +---@param fontSize integer +---@return integer +function rl.MeasureText(text, fontSize) end + +--- Measure string size for Font +---@param font rl.Font +---@param text string +---@param fontSize number +---@param spacing number +---@return rl.Vector2 +function rl.MeasureTextEx(font, text, fontSize, spacing) end + +--- Measure string size for an existing array of codepoints for Font +---@param font rl.Font +---@param codepoints userdata +---@param length integer +---@param fontSize number +---@param spacing number +---@return rl.Vector2 +function rl.MeasureTextCodepoints(font, codepoints, length, fontSize, spacing) end + +--- Get glyph index position in font for a codepoint (unicode character), fallback to '?' if not found +---@param font rl.Font +---@param codepoint integer +---@return integer +function rl.GetGlyphIndex(font, codepoint) end + +--- Get glyph font info data for a codepoint (unicode character), fallback to '?' if not found +---@param font rl.Font +---@param codepoint integer +---@return rl.GlyphInfo +function rl.GetGlyphInfo(font, codepoint) end + +--- Get glyph rectangle in font atlas for a codepoint (unicode character), fallback to '?' if not found +---@param font rl.Font +---@param codepoint integer +---@return rl.Rectangle +function rl.GetGlyphAtlasRec(font, codepoint) end + +--- Text codepoints management functions (unicode characters) +--- Load UTF-8 text encoded from codepoints array +---@param codepoints userdata +---@param length integer +---@return string +function rl.LoadUTF8(codepoints, length) end + +--- Unload UTF-8 text encoded from codepoints array +---@param text string +function rl.UnloadUTF8(text) end + +--- Load all codepoints from a UTF-8 text string, codepoints count returned by parameter +---@param text string +---@param count userdata +---@return userdata +function rl.LoadCodepoints(text, count) end + +--- Unload codepoints data from memory +---@param codepoints userdata +function rl.UnloadCodepoints(codepoints) end + +--- Get total number of codepoints in a UTF-8 encoded string +---@param text string +---@return integer +function rl.GetCodepointCount(text) end + +--- Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure +---@param text string +---@param codepointSize userdata +---@return integer +function rl.GetCodepoint(text, codepointSize) end + +--- Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure +---@param text string +---@param codepointSize userdata +---@return integer +function rl.GetCodepointNext(text, codepointSize) end + +--- Get previous codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure +---@param text string +---@param codepointSize userdata +---@return integer +function rl.GetCodepointPrevious(text, codepointSize) end + +--- Encode one codepoint into UTF-8 byte array (array length returned as parameter) +---@param codepoint integer +---@param utf8Size userdata +---@return string +function rl.CodepointToUTF8(codepoint, utf8Size) end + +--- Text strings management functions (no UTF-8 strings, only byte chars) +--- WARNING 1: Most of these functions use internal static buffers[], it's recommended to store returned data on user-side for re-use +--- WARNING 2: Some functions allocate memory internally for the returned strings, those strings must be freed by user using MemFree() +--- Load text as separate lines ('\n') +---@param text string +---@param count userdata +---@return userdata +function rl.LoadTextLines(text, count) end + +--- Unload text lines +---@param text userdata +---@param lineCount integer +function rl.UnloadTextLines(text, lineCount) end + +--- Copy one string to another, returns bytes copied +---@param dst string +---@param src string +---@return integer +function rl.TextCopy(dst, src) end + +--- Check if two text string are equal +---@param text1 string +---@param text2 string +---@return boolean +function rl.TextIsEqual(text1, text2) end + +--- Get text length, checks for '\0' ending +---@param text string +---@return integer +function rl.TextLength(text) end + +--- Text formatting with variables (sprintf() style) +---@param text string +---@param ... any +---@return string +function rl.TextFormat(text, ...) end + +--- Get a piece of a text string +---@param text string +---@param position integer +---@param length integer +---@return string +function rl.TextSubtext(text, position, length) end + +--- Remove text spaces, concat words +---@param text string +---@return string +function rl.TextRemoveSpaces(text) end + +--- Get text between two strings +---@param text string +---@param begin string +---@param end_ string +---@return string +function rl.GetTextBetween(text, begin, end_) end + +--- Replace text string with new string +---@param text string +---@param search string +---@param replacement string +---@return string +function rl.TextReplace(text, search, replacement) end + +--- Replace text string with new string, memory must be MemFree() +---@param text string +---@param search string +---@param replacement string +---@return string +function rl.TextReplaceAlloc(text, search, replacement) end + +--- Replace text between two specific strings +---@param text string +---@param begin string +---@param end_ string +---@param replacement string +---@return string +function rl.TextReplaceBetween(text, begin, end_, replacement) end + +--- Replace text between two specific strings, memory must be MemFree() +---@param text string +---@param begin string +---@param end_ string +---@param replacement string +---@return string +function rl.TextReplaceBetweenAlloc(text, begin, end_, replacement) end + +--- Insert text in a defined byte position +---@param text string +---@param insert string +---@param position integer +---@return string +function rl.TextInsert(text, insert, position) end + +--- Insert text in a defined byte position, memory must be MemFree() +---@param text string +---@param insert string +---@param position integer +---@return string +function rl.TextInsertAlloc(text, insert, position) end + +--- Join text strings with delimiter +---@param textList userdata +---@param count integer +---@param delimiter string +---@return string +function rl.TextJoin(textList, count, delimiter) end + +--- Split text into multiple strings, using MAX_TEXTSPLIT_COUNT static strings +---@param text string +---@param delimiter integer +---@param count userdata +---@return userdata +function rl.TextSplit(text, delimiter, count) end + +--- Append text at specific position and move cursor +---@param text string +---@param append string +---@param position userdata +function rl.TextAppend(text, append, position) end + +--- Find first text occurrence within a string, -1 if not found +---@param text string +---@param search string +---@return integer +function rl.TextFindIndex(text, search) end + +--- Get upper case version of provided string +---@param text string +---@return string +function rl.TextToUpper(text) end + +--- Get lower case version of provided string +---@param text string +---@return string +function rl.TextToLower(text) end + +--- Get Pascal case notation version of provided string +---@param text string +---@return string +function rl.TextToPascal(text) end + +--- Get Snake case notation version of provided string +---@param text string +---@return string +function rl.TextToSnake(text) end + +--- Get Camel case notation version of provided string +---@param text string +---@return string +function rl.TextToCamel(text) end + +--- Get integer value from text +---@param text string +---@return integer +function rl.TextToInteger(text) end + +--- Get float value from text +---@param text string +---@return number +function rl.TextToFloat(text) end + +--- Basic 3d Shapes Drawing Functions (Module: models) +--- Basic geometric 3D shapes drawing functions +--- Draw a line in 3D world space +---@param startPos rl.Vector3 +---@param endPos rl.Vector3 +---@param color rl.Color +function rl.DrawLine3D(startPos, endPos, color) end + +--- Draw a point in 3D space, actually a small line +---@param position rl.Vector3 +---@param color rl.Color +function rl.DrawPoint3D(position, color) end + +--- Draw a circle in 3D world space +---@param center rl.Vector3 +---@param radius number +---@param rotationAxis rl.Vector3 +---@param rotationAngle number +---@param color rl.Color +function rl.DrawCircle3D(center, radius, rotationAxis, rotationAngle, color) end + +--- Draw a color-filled triangle (vertex in counter-clockwise order!) +---@param v1 rl.Vector3 +---@param v2 rl.Vector3 +---@param v3 rl.Vector3 +---@param color rl.Color +function rl.DrawTriangle3D(v1, v2, v3, color) end + +--- Draw a triangle strip defined by points +---@param points userdata +---@param pointCount integer +---@param color rl.Color +function rl.DrawTriangleStrip3D(points, pointCount, color) end + +--- Draw cube +---@param position rl.Vector3 +---@param width number +---@param height number +---@param length number +---@param color rl.Color +function rl.DrawCube(position, width, height, length, color) end + +--- Draw cube (Vector version) +---@param position rl.Vector3 +---@param size rl.Vector3 +---@param color rl.Color +function rl.DrawCubeV(position, size, color) end + +--- Draw cube wires +---@param position rl.Vector3 +---@param width number +---@param height number +---@param length number +---@param color rl.Color +function rl.DrawCubeWires(position, width, height, length, color) end + +--- Draw cube wires (Vector version) +---@param position rl.Vector3 +---@param size rl.Vector3 +---@param color rl.Color +function rl.DrawCubeWiresV(position, size, color) end + +--- Draw sphere +---@param centerPos rl.Vector3 +---@param radius number +---@param color rl.Color +function rl.DrawSphere(centerPos, radius, color) end + +--- Draw sphere with extended parameters +---@param centerPos rl.Vector3 +---@param radius number +---@param rings integer +---@param slices integer +---@param color rl.Color +function rl.DrawSphereEx(centerPos, radius, rings, slices, color) end + +--- Draw sphere wires +---@param centerPos rl.Vector3 +---@param radius number +---@param rings integer +---@param slices integer +---@param color rl.Color +function rl.DrawSphereWires(centerPos, radius, rings, slices, color) end + +--- Draw a cylinder/cone +---@param position rl.Vector3 +---@param radiusTop number +---@param radiusBottom number +---@param height number +---@param slices integer +---@param color rl.Color +function rl.DrawCylinder(position, radiusTop, radiusBottom, height, slices, color) end + +--- Draw a cylinder with base at startPos and top at endPos +---@param startPos rl.Vector3 +---@param endPos rl.Vector3 +---@param startRadius number +---@param endRadius number +---@param sides integer +---@param color rl.Color +function rl.DrawCylinderEx(startPos, endPos, startRadius, endRadius, sides, color) end + +--- Draw a cylinder/cone wires +---@param position rl.Vector3 +---@param radiusTop number +---@param radiusBottom number +---@param height number +---@param slices integer +---@param color rl.Color +function rl.DrawCylinderWires(position, radiusTop, radiusBottom, height, slices, color) end + +--- Draw a cylinder wires with base at startPos and top at endPos +---@param startPos rl.Vector3 +---@param endPos rl.Vector3 +---@param startRadius number +---@param endRadius number +---@param sides integer +---@param color rl.Color +function rl.DrawCylinderWiresEx(startPos, endPos, startRadius, endRadius, sides, color) end + +--- Draw a capsule with the center of its sphere caps at startPos and endPos +---@param startPos rl.Vector3 +---@param endPos rl.Vector3 +---@param radius number +---@param slices integer +---@param rings integer +---@param color rl.Color +function rl.DrawCapsule(startPos, endPos, radius, slices, rings, color) end + +--- Draw capsule wireframe with the center of its sphere caps at startPos and endPos +---@param startPos rl.Vector3 +---@param endPos rl.Vector3 +---@param radius number +---@param slices integer +---@param rings integer +---@param color rl.Color +function rl.DrawCapsuleWires(startPos, endPos, radius, slices, rings, color) end + +--- Draw a plane XZ +---@param centerPos rl.Vector3 +---@param size rl.Vector2 +---@param color rl.Color +function rl.DrawPlane(centerPos, size, color) end + +--- Draw a ray line +---@param ray rl.Ray +---@param color rl.Color +function rl.DrawRay(ray, color) end + +--- Draw a grid (centered at (0, 0, 0)) +---@param slices integer +---@param spacing number +function rl.DrawGrid(slices, spacing) end + +--- Model 3d Loading and Drawing Functions (Module: models) +--- Model management functions +--- Load model from files (meshes and materials) +---@param fileName string +---@return rl.Model +function rl.LoadModel(fileName) end + +--- Load model from generated mesh (default material) +---@param mesh rl.Mesh +---@return rl.Model +function rl.LoadModelFromMesh(mesh) end + +--- Check if a model is valid (loaded in GPU, VAO/VBOs) +---@param model rl.Model +---@return boolean +function rl.IsModelValid(model) end + +--- Unload model (including meshes) from memory (RAM and/or VRAM) +---@param model rl.Model +function rl.UnloadModel(model) end + +--- Compute model bounding box limits (considers all meshes) +---@param model rl.Model +---@return rl.BoundingBox +function rl.GetModelBoundingBox(model) end + +--- Model drawing functions +--- Draw a model (with texture if set) +---@param model rl.Model +---@param position rl.Vector3 +---@param scale number +---@param tint rl.Color +function rl.DrawModel(model, position, scale, tint) end + +--- Draw a model with extended parameters +---@param model rl.Model +---@param position rl.Vector3 +---@param rotationAxis rl.Vector3 +---@param rotationAngle number +---@param scale rl.Vector3 +---@param tint rl.Color +function rl.DrawModelEx(model, position, rotationAxis, rotationAngle, scale, tint) end + +--- Draw a model wires (with texture if set) +---@param model rl.Model +---@param position rl.Vector3 +---@param scale number +---@param tint rl.Color +function rl.DrawModelWires(model, position, scale, tint) end + +--- Draw a model wires (with texture if set) with extended parameters +---@param model rl.Model +---@param position rl.Vector3 +---@param rotationAxis rl.Vector3 +---@param rotationAngle number +---@param scale rl.Vector3 +---@param tint rl.Color +function rl.DrawModelWiresEx(model, position, rotationAxis, rotationAngle, scale, tint) end + +--- Draw bounding box (wires) +---@param box rl.BoundingBox +---@param color rl.Color +function rl.DrawBoundingBox(box, color) end + +--- Draw a billboard texture +---@param camera rl.Camera3D +---@param texture rl.Texture +---@param position rl.Vector3 +---@param scale number +---@param tint rl.Color +function rl.DrawBillboard(camera, texture, position, scale, tint) end + +--- Draw a billboard texture defined by source +---@param camera rl.Camera3D +---@param texture rl.Texture +---@param source rl.Rectangle +---@param position rl.Vector3 +---@param size rl.Vector2 +---@param tint rl.Color +function rl.DrawBillboardRec(camera, texture, source, position, size, tint) end + +--- Draw a billboard texture defined by source and rotation +---@param camera rl.Camera3D +---@param texture rl.Texture +---@param source rl.Rectangle +---@param position rl.Vector3 +---@param up rl.Vector3 +---@param size rl.Vector2 +---@param origin rl.Vector2 +---@param rotation number +---@param tint rl.Color +function rl.DrawBillboardPro(camera, texture, source, position, up, size, origin, rotation, tint) end + +--- Mesh management functions +--- Upload mesh vertex data in GPU and provide VAO/VBO ids +---@param mesh userdata +---@param dynamic boolean +function rl.UploadMesh(mesh, dynamic) end + +--- Update mesh vertex data in GPU for a specific buffer index +---@param mesh rl.Mesh +---@param index integer +---@param data userdata +---@param dataSize integer +---@param offset integer +function rl.UpdateMeshBuffer(mesh, index, data, dataSize, offset) end + +--- Unload mesh data from CPU and GPU +---@param mesh rl.Mesh +function rl.UnloadMesh(mesh) end + +--- Draw a 3d mesh with material and transform +---@param mesh rl.Mesh +---@param material rl.Material +---@param transform rl.Matrix +function rl.DrawMesh(mesh, material, transform) end + +--- Draw multiple mesh instances with material and different transforms +---@param mesh rl.Mesh +---@param material rl.Material +---@param transforms userdata +---@param instances integer +function rl.DrawMeshInstanced(mesh, material, transforms, instances) end + +--- Compute mesh bounding box limits +---@param mesh rl.Mesh +---@return rl.BoundingBox +function rl.GetMeshBoundingBox(mesh) end + +--- Compute mesh tangents +---@param mesh userdata +function rl.GenMeshTangents(mesh) end + +--- Export mesh data to file, returns true on success +---@param mesh rl.Mesh +---@param fileName string +---@return boolean +function rl.ExportMesh(mesh, fileName) end + +--- Export mesh as code file (.h) defining multiple arrays of vertex attributes +---@param mesh rl.Mesh +---@param fileName string +---@return boolean +function rl.ExportMeshAsCode(mesh, fileName) end + +--- Mesh generation functions +--- Generate polygonal mesh +---@param sides integer +---@param radius number +---@return rl.Mesh +function rl.GenMeshPoly(sides, radius) end + +--- Generate plane mesh (with subdivisions) +---@param width number +---@param length number +---@param resX integer +---@param resZ integer +---@return rl.Mesh +function rl.GenMeshPlane(width, length, resX, resZ) end + +--- Generate cuboid mesh +---@param width number +---@param height number +---@param length number +---@return rl.Mesh +function rl.GenMeshCube(width, height, length) end + +--- Generate sphere mesh (standard sphere) +---@param radius number +---@param rings integer +---@param slices integer +---@return rl.Mesh +function rl.GenMeshSphere(radius, rings, slices) end + +--- Generate half-sphere mesh (no bottom cap) +---@param radius number +---@param rings integer +---@param slices integer +---@return rl.Mesh +function rl.GenMeshHemiSphere(radius, rings, slices) end + +--- Generate cylinder mesh +---@param radius number +---@param height number +---@param slices integer +---@return rl.Mesh +function rl.GenMeshCylinder(radius, height, slices) end + +--- Generate cone/pyramid mesh +---@param radius number +---@param height number +---@param slices integer +---@return rl.Mesh +function rl.GenMeshCone(radius, height, slices) end + +--- Generate torus mesh +---@param radius number +---@param size number +---@param radSeg integer +---@param sides integer +---@return rl.Mesh +function rl.GenMeshTorus(radius, size, radSeg, sides) end + +--- Generate trefoil knot mesh +---@param radius number +---@param size number +---@param radSeg integer +---@param sides integer +---@return rl.Mesh +function rl.GenMeshKnot(radius, size, radSeg, sides) end + +--- Generate heightmap mesh from image data +---@param heightmap rl.Image +---@param size rl.Vector3 +---@return rl.Mesh +function rl.GenMeshHeightmap(heightmap, size) end + +--- Generate cubes-based map mesh from image data +---@param cubicmap rl.Image +---@param cubeSize rl.Vector3 +---@return rl.Mesh +function rl.GenMeshCubicmap(cubicmap, cubeSize) end + +--- Material loading/unloading functions +--- Load materials from model file +---@param fileName string +---@param materialCount userdata +---@return userdata +function rl.LoadMaterials(fileName, materialCount) end + +--- Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps) +---@return rl.Material +function rl.LoadMaterialDefault() end + +--- Check if a material is valid (shader assigned, map textures loaded in GPU) +---@param material rl.Material +---@return boolean +function rl.IsMaterialValid(material) end + +--- Unload material from GPU memory (VRAM) +---@param material rl.Material +function rl.UnloadMaterial(material) end + +--- Set texture for a material map type (MATERIAL_MAP_DIFFUSE, MATERIAL_MAP_SPECULAR...) +---@param material userdata +---@param mapType integer +---@param texture rl.Texture +function rl.SetMaterialTexture(material, mapType, texture) end + +--- Set material for a mesh +---@param model userdata +---@param meshId integer +---@param materialId integer +function rl.SetModelMeshMaterial(model, meshId, materialId) end + +--- Model animations loading/unloading functions +--- Load model animations from file +---@param fileName string +---@param animCount userdata +---@return userdata +function rl.LoadModelAnimations(fileName, animCount) end + +--- Update model animation pose (vertex buffers and bone matrices) +---@param model rl.Model +---@param anim rl.ModelAnimation +---@param frame number +function rl.UpdateModelAnimation(model, anim, frame) end + +--- Update model animation pose, blending two animations +---@param model rl.Model +---@param animA rl.ModelAnimation +---@param frameA number +---@param animB rl.ModelAnimation +---@param frameB number +---@param blend number +function rl.UpdateModelAnimationEx(model, animA, frameA, animB, frameB, blend) end + +--- Unload animation array data +---@param animations userdata +---@param animCount integer +function rl.UnloadModelAnimations(animations, animCount) end + +--- Check model animation skeleton match +---@param model rl.Model +---@param anim rl.ModelAnimation +---@return boolean +function rl.IsModelAnimationValid(model, anim) end + +--- Collision detection functions +--- Check collision between two spheres +---@param center1 rl.Vector3 +---@param radius1 number +---@param center2 rl.Vector3 +---@param radius2 number +---@return boolean +function rl.CheckCollisionSpheres(center1, radius1, center2, radius2) end + +--- Check collision between two bounding boxes +---@param box1 rl.BoundingBox +---@param box2 rl.BoundingBox +---@return boolean +function rl.CheckCollisionBoxes(box1, box2) end + +--- Check collision between box and sphere +---@param box rl.BoundingBox +---@param center rl.Vector3 +---@param radius number +---@return boolean +function rl.CheckCollisionBoxSphere(box, center, radius) end + +--- Get collision info between ray and sphere +---@param ray rl.Ray +---@param center rl.Vector3 +---@param radius number +---@return rl.RayCollision +function rl.GetRayCollisionSphere(ray, center, radius) end + +--- Get collision info between ray and box +---@param ray rl.Ray +---@param box rl.BoundingBox +---@return rl.RayCollision +function rl.GetRayCollisionBox(ray, box) end + +--- Get collision info between ray and mesh +---@param ray rl.Ray +---@param mesh rl.Mesh +---@param transform rl.Matrix +---@return rl.RayCollision +function rl.GetRayCollisionMesh(ray, mesh, transform) end + +--- Get collision info between ray and triangle +---@param ray rl.Ray +---@param p1 rl.Vector3 +---@param p2 rl.Vector3 +---@param p3 rl.Vector3 +---@return rl.RayCollision +function rl.GetRayCollisionTriangle(ray, p1, p2, p3) end + +--- Get collision info between ray and quad +---@param ray rl.Ray +---@param p1 rl.Vector3 +---@param p2 rl.Vector3 +---@param p3 rl.Vector3 +---@param p4 rl.Vector3 +---@return rl.RayCollision +function rl.GetRayCollisionQuad(ray, p1, p2, p3, p4) end + +--- Audio Loading and Playing Functions (Module: audio) +---@param bufferData userdata +---@param frames integer +function rl.AudioCallback(bufferData, frames) end + +--- Audio device management functions +--- Initialize audio device and context +function rl.InitAudioDevice() end + +--- Close the audio device and context +function rl.CloseAudioDevice() end + +--- Check if audio device has been initialized successfully +---@return boolean +function rl.IsAudioDeviceReady() end + +--- Set master volume (listener) +---@param volume number +function rl.SetMasterVolume(volume) end + +--- Get master volume (listener) +---@return number +function rl.GetMasterVolume() end + +--- Wave/Sound loading/unloading functions +--- Load wave data from file +---@param fileName string +---@return rl.Wave +function rl.LoadWave(fileName) end + +--- Load wave from memory buffer, fileType refers to extension: i.e. '.wav' +---@param fileType string +---@param fileData userdata +---@param dataSize integer +---@return rl.Wave +function rl.LoadWaveFromMemory(fileType, fileData, dataSize) end + +--- Checks if wave data is valid (data loaded and parameters) +---@param wave rl.Wave +---@return boolean +function rl.IsWaveValid(wave) end + +--- Load sound from file +---@param fileName string +---@return rl.Sound +function rl.LoadSound(fileName) end + +--- Load sound from wave data +---@param wave rl.Wave +---@return rl.Sound +function rl.LoadSoundFromWave(wave) end + +--- Create a new sound that shares the same sample data as the source sound, does not own the sound data +---@param source rl.Sound +---@return rl.Sound +function rl.LoadSoundAlias(source) end + +--- Checks if a sound is valid (data loaded and buffers initialized) +---@param sound rl.Sound +---@return boolean +function rl.IsSoundValid(sound) end + +--- Update sound buffer with new data (default data format: 32 bit float, stereo) +---@param sound rl.Sound +---@param data userdata +---@param sampleCount integer +function rl.UpdateSound(sound, data, sampleCount) end + +--- Unload wave data +---@param wave rl.Wave +function rl.UnloadWave(wave) end + +--- Unload sound +---@param sound rl.Sound +function rl.UnloadSound(sound) end + +--- Unload a sound alias (does not deallocate sample data) +---@param alias rl.Sound +function rl.UnloadSoundAlias(alias) end + +--- Export wave data to file, returns true on success +---@param wave rl.Wave +---@param fileName string +---@return boolean +function rl.ExportWave(wave, fileName) end + +--- Export wave sample data to code (.h), returns true on success +---@param wave rl.Wave +---@param fileName string +---@return boolean +function rl.ExportWaveAsCode(wave, fileName) end + +--- Wave/Sound management functions +--- Play a sound +---@param sound rl.Sound +function rl.PlaySound(sound) end + +--- Stop playing a sound +---@param sound rl.Sound +function rl.StopSound(sound) end + +--- Pause a sound +---@param sound rl.Sound +function rl.PauseSound(sound) end + +--- Resume a paused sound +---@param sound rl.Sound +function rl.ResumeSound(sound) end + +--- Check if a sound is currently playing +---@param sound rl.Sound +---@return boolean +function rl.IsSoundPlaying(sound) end + +--- Set volume for a sound (1.0 is max level) +---@param sound rl.Sound +---@param volume number +function rl.SetSoundVolume(sound, volume) end + +--- Set pitch for a sound (1.0 is base level) +---@param sound rl.Sound +---@param pitch number +function rl.SetSoundPitch(sound, pitch) end + +--- Set pan for a sound (-1.0 left, 0.0 center, 1.0 right) +---@param sound rl.Sound +---@param pan number +function rl.SetSoundPan(sound, pan) end + +--- Copy a wave to a new wave +---@param wave rl.Wave +---@return rl.Wave +function rl.WaveCopy(wave) end + +--- Crop a wave to defined frames range +---@param wave userdata +---@param initFrame integer +---@param finalFrame integer +function rl.WaveCrop(wave, initFrame, finalFrame) end + +--- Convert wave data to desired format +---@param wave userdata +---@param sampleRate integer +---@param sampleSize integer +---@param channels integer +function rl.WaveFormat(wave, sampleRate, sampleSize, channels) end + +--- Load samples data from wave as a 32bit float data array +---@param wave rl.Wave +---@return userdata +function rl.LoadWaveSamples(wave) end + +--- Unload samples data loaded with LoadWaveSamples() +---@param samples userdata +function rl.UnloadWaveSamples(samples) end + +--- Music management functions +--- Load music stream from file +---@param fileName string +---@return rl.Music +function rl.LoadMusicStream(fileName) end + +--- Load music stream from data +---@param fileType string +---@param data userdata +---@param dataSize integer +---@return rl.Music +function rl.LoadMusicStreamFromMemory(fileType, data, dataSize) end + +--- Checks if a music stream is valid (context and buffers initialized) +---@param music rl.Music +---@return boolean +function rl.IsMusicValid(music) end + +--- Unload music stream +---@param music rl.Music +function rl.UnloadMusicStream(music) end + +--- Start music playing +---@param music rl.Music +function rl.PlayMusicStream(music) end + +--- Check if music is playing +---@param music rl.Music +---@return boolean +function rl.IsMusicStreamPlaying(music) end + +--- Updates buffers for music streaming +---@param music rl.Music +function rl.UpdateMusicStream(music) end + +--- Stop music playing +---@param music rl.Music +function rl.StopMusicStream(music) end + +--- Pause music playing +---@param music rl.Music +function rl.PauseMusicStream(music) end + +--- Resume playing paused music +---@param music rl.Music +function rl.ResumeMusicStream(music) end + +--- Seek music to a position (in seconds) +---@param music rl.Music +---@param position number +function rl.SeekMusicStream(music, position) end + +--- Set volume for music (1.0 is max level) +---@param music rl.Music +---@param volume number +function rl.SetMusicVolume(music, volume) end + +--- Set pitch for a music (1.0 is base level) +---@param music rl.Music +---@param pitch number +function rl.SetMusicPitch(music, pitch) end + +--- Set pan for a music (-1.0 left, 0.0 center, 1.0 right) +---@param music rl.Music +---@param pan number +function rl.SetMusicPan(music, pan) end + +--- Get music time length (in seconds) +---@param music rl.Music +---@return number +function rl.GetMusicTimeLength(music) end + +--- Get current music time played (in seconds) +---@param music rl.Music +---@return number +function rl.GetMusicTimePlayed(music) end + +--- AudioStream management functions +--- Load audio stream (to stream raw audio pcm data) +---@param sampleRate integer +---@param sampleSize integer +---@param channels integer +---@return rl.AudioStream +function rl.LoadAudioStream(sampleRate, sampleSize, channels) end + +--- Checks if an audio stream is valid (buffers initialized) +---@param stream rl.AudioStream +---@return boolean +function rl.IsAudioStreamValid(stream) end + +--- Unload audio stream and free memory +---@param stream rl.AudioStream +function rl.UnloadAudioStream(stream) end + +--- Update audio stream buffers with data +---@param stream rl.AudioStream +---@param data userdata +---@param frameCount integer +function rl.UpdateAudioStream(stream, data, frameCount) end + +--- Check if any audio stream buffers requires refill +---@param stream rl.AudioStream +---@return boolean +function rl.IsAudioStreamProcessed(stream) end + +--- Play audio stream +---@param stream rl.AudioStream +function rl.PlayAudioStream(stream) end + +--- Pause audio stream +---@param stream rl.AudioStream +function rl.PauseAudioStream(stream) end + +--- Resume audio stream +---@param stream rl.AudioStream +function rl.ResumeAudioStream(stream) end + +--- Check if audio stream is playing +---@param stream rl.AudioStream +---@return boolean +function rl.IsAudioStreamPlaying(stream) end + +--- Stop audio stream +---@param stream rl.AudioStream +function rl.StopAudioStream(stream) end + +--- Set volume for audio stream (1.0 is max level) +---@param stream rl.AudioStream +---@param volume number +function rl.SetAudioStreamVolume(stream, volume) end + +--- Set pitch for audio stream (1.0 is base level) +---@param stream rl.AudioStream +---@param pitch number +function rl.SetAudioStreamPitch(stream, pitch) end + +--- Set pan for audio stream (-1.0 to 1.0 range, 0.0 is centered) +---@param stream rl.AudioStream +---@param pan number +function rl.SetAudioStreamPan(stream, pan) end + +--- Default size for new audio streams +---@param size integer +function rl.SetAudioStreamBufferSizeDefault(size) end + +--- Audio thread callback to request new data +---@param stream rl.AudioStream +---@param callback rl.AudioCallback +function rl.SetAudioStreamCallback(stream, callback) end + +--- Attach audio stream processor to stream, receives frames x 2 samples as 'float' (stereo) +---@param stream rl.AudioStream +---@param processor rl.AudioCallback +function rl.AttachAudioStreamProcessor(stream, processor) end + +--- Detach audio stream processor from stream +---@param stream rl.AudioStream +---@param processor rl.AudioCallback +function rl.DetachAudioStreamProcessor(stream, processor) end + +--- Attach audio stream processor to the entire audio pipeline, receives frames x 2 samples as 'float' (stereo) +---@param processor rl.AudioCallback +function rl.AttachAudioMixedProcessor(processor) end + +--- Detach audio stream processor from the entire audio pipeline +---@param processor rl.AudioCallback +function rl.DetachAudioMixedProcessor(processor) end diff --git a/src/external/lua/include/lauxlib.h b/src/external/lua/include/lauxlib.h old mode 100644 new mode 100755 index ddb7c22..7f1d3ca --- a/src/external/lua/include/lauxlib.h +++ b/src/external/lua/include/lauxlib.h @@ -1,5 +1,5 @@ /* -** $Id: lauxlib.h,v 1.129 2015/11/23 11:29:43 roberto Exp $ +** $Id: lauxlib.h $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ @@ -12,14 +12,29 @@ #include #include +#include "luaconf.h" #include "lua.h" +/* global table */ +#define LUA_GNAME "_G" -/* extra error code for 'luaL_load' */ + +typedef struct luaL_Buffer luaL_Buffer; + + +/* extra error code for 'luaL_loadfilex' */ #define LUA_ERRFILE (LUA_ERRERR+1) +/* key, in the registry, for table of loaded modules */ +#define LUA_LOADED_TABLE "_LOADED" + + +/* key, in the registry, for table of preloaded loaders */ +#define LUA_PRELOAD_TABLE "_PRELOAD" + + typedef struct luaL_Reg { const char *name; lua_CFunction func; @@ -36,6 +51,7 @@ LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len); LUALIB_API int (luaL_argerror) (lua_State *L, int arg, const char *extramsg); +LUALIB_API int (luaL_typeerror) (lua_State *L, int arg, const char *tname); LUALIB_API const char *(luaL_checklstring) (lua_State *L, int arg, size_t *l); LUALIB_API const char *(luaL_optlstring) (lua_State *L, int arg, @@ -65,6 +81,10 @@ LUALIB_API int (luaL_checkoption) (lua_State *L, int arg, const char *def, LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname); LUALIB_API int (luaL_execresult) (lua_State *L, int stat); +LUALIB_API void *luaL_alloc (void *ud, void *ptr, size_t osize, + size_t nsize); + + /* predefined references */ #define LUA_NOREF (-2) #define LUA_REFNIL (-1) @@ -83,10 +103,14 @@ LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); LUALIB_API lua_State *(luaL_newstate) (void); +LUALIB_API unsigned luaL_makeseed (lua_State *L); + LUALIB_API lua_Integer (luaL_len) (lua_State *L, int idx); -LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, - const char *r); +LUALIB_API void (luaL_addgsub) (luaL_Buffer *b, const char *s, + const char *p, const char *r); +LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, + const char *p, const char *r); LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup); @@ -112,7 +136,11 @@ LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname, (luaL_checkversion(L), luaL_newlibtable(L,l), luaL_setfuncs(L,l,0)) #define luaL_argcheck(L, cond,arg,extramsg) \ - ((void)((cond) || luaL_argerror(L, (arg), (extramsg)))) + ((void)(luai_likely(cond) || luaL_argerror(L, (arg), (extramsg)))) + +#define luaL_argexpected(L,cond,arg,tname) \ + ((void)(luai_likely(cond) || luaL_typeerror(L, (arg), (tname)))) + #define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) #define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) @@ -131,19 +159,43 @@ LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname, #define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL) +/* +** Perform arithmetic operations on lua_Integer values with wrap-around +** semantics, as the Lua core does. +*/ +#define luaL_intop(op,v1,v2) \ + ((lua_Integer)((lua_Unsigned)(v1) op (lua_Unsigned)(v2))) + + +/* push the value used to represent failure/error */ +#if defined(LUA_FAILISFALSE) +#define luaL_pushfail(L) lua_pushboolean(L, 0) +#else +#define luaL_pushfail(L) lua_pushnil(L) +#endif + + + /* ** {====================================================== ** Generic Buffer manipulation ** ======================================================= */ -typedef struct luaL_Buffer { +struct luaL_Buffer { char *b; /* buffer address */ size_t size; /* buffer size */ size_t n; /* number of characters in buffer */ lua_State *L; - char initb[LUAL_BUFFERSIZE]; /* initial buffer */ -} luaL_Buffer; + union { + LUAI_MAXALIGN; /* ensure maximum alignment for buffer */ + char b[LUAL_BUFFERSIZE]; /* initial buffer */ + } init; +}; + + +#define luaL_bufflen(bf) ((bf)->n) +#define luaL_buffaddr(bf) ((bf)->b) #define luaL_addchar(B,c) \ @@ -152,6 +204,8 @@ typedef struct luaL_Buffer { #define luaL_addsize(B,s) ((B)->n += (s)) +#define luaL_buffsub(B,s) ((B)->n -= (s)) + LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); LUALIB_API char *(luaL_prepbuffsize) (luaL_Buffer *B, size_t sz); LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); @@ -190,45 +244,6 @@ typedef struct luaL_Stream { /* }====================================================== */ - -/* compatibility with old module system */ -#if defined(LUA_COMPAT_MODULE) - -LUALIB_API void (luaL_pushmodule) (lua_State *L, const char *modname, - int sizehint); -LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname, - const luaL_Reg *l, int nup); - -#define luaL_register(L,n,l) (luaL_openlib(L,(n),(l),0)) - -#endif - - -/* -** {================================================================== -** "Abstraction Layer" for basic report of messages and errors -** =================================================================== -*/ - -/* print a string */ -#if !defined(lua_writestring) -#define lua_writestring(s,l) fwrite((s), sizeof(char), (l), stdout) -#endif - -/* print a newline and flush the output */ -#if !defined(lua_writeline) -#define lua_writeline() (lua_writestring("\n", 1), fflush(stdout)) -#endif - -/* print an error message */ -#if !defined(lua_writestringerror) -#define lua_writestringerror(s,p) \ - (fprintf(stderr, (s), (p)), fflush(stderr)) -#endif - -/* }================================================================== */ - - /* ** {============================================================ ** Compatibility with deprecated conversions diff --git a/src/external/lua/include/lua.h b/src/external/lua/include/lua.h old mode 100644 new mode 100755 index f78899f..ab473dc --- a/src/external/lua/include/lua.h +++ b/src/external/lua/include/lua.h @@ -1,7 +1,7 @@ /* -** $Id: lua.h,v 1.331 2016/05/30 15:53:28 roberto Exp $ +** $Id: lua.h $ ** Lua - A Scripting Language -** Lua.org, PUC-Rio, Brazil (http://www.lua.org) +** Lua.org, PUC-Rio, Brazil (www.lua.org) ** See Copyright Notice at the end of this file */ @@ -13,18 +13,19 @@ #include -#include "luaconf.h" +#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2025 Lua.org, PUC-Rio" +#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" -#define LUA_VERSION_MAJOR "5" -#define LUA_VERSION_MINOR "3" -#define LUA_VERSION_NUM 503 -#define LUA_VERSION_RELEASE "3" +#define LUA_VERSION_MAJOR_N 5 +#define LUA_VERSION_MINOR_N 5 +#define LUA_VERSION_RELEASE_N 0 -#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR -#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE -#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2016 Lua.org, PUC-Rio" -#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" +#define LUA_VERSION_NUM (LUA_VERSION_MAJOR_N * 100 + LUA_VERSION_MINOR_N) +#define LUA_VERSION_RELEASE_NUM (LUA_VERSION_NUM * 100 + LUA_VERSION_RELEASE_N) + + +#include "luaconf.h" /* mark for precompiled code ('Lua') */ @@ -36,10 +37,10 @@ /* ** Pseudo-indices -** (-LUAI_MAXSTACK is the minimum valid index; we keep some free empty -** space after that to help overflow detection) +** (The stack size is limited to INT_MAX/2; we keep some free empty +** space after that to help overflow detection.) */ -#define LUA_REGISTRYINDEX (-LUAI_MAXSTACK - 1000) +#define LUA_REGISTRYINDEX (-(INT_MAX/2 + 1000)) #define lua_upvalueindex(i) (LUA_REGISTRYINDEX - (i)) @@ -49,8 +50,7 @@ #define LUA_ERRRUN 2 #define LUA_ERRSYNTAX 3 #define LUA_ERRMEM 4 -#define LUA_ERRGCMM 5 -#define LUA_ERRERR 6 +#define LUA_ERRERR 5 typedef struct lua_State lua_State; @@ -71,7 +71,7 @@ typedef struct lua_State lua_State; #define LUA_TUSERDATA 7 #define LUA_TTHREAD 8 -#define LUA_NUMTAGS 9 +#define LUA_NUMTYPES 9 @@ -80,9 +80,10 @@ typedef struct lua_State lua_State; /* predefined values in the registry */ -#define LUA_RIDX_MAINTHREAD 1 +/* index 1 is reserved for the reference mechanism */ #define LUA_RIDX_GLOBALS 2 -#define LUA_RIDX_LAST LUA_RIDX_GLOBALS +#define LUA_RIDX_MAINTHREAD 3 +#define LUA_RIDX_LAST 3 /* type of numbers in Lua */ @@ -124,6 +125,23 @@ typedef int (*lua_Writer) (lua_State *L, const void *p, size_t sz, void *ud); typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); +/* +** Type for warning functions +*/ +typedef void (*lua_WarnFunction) (void *ud, const char *msg, int tocont); + + +/* +** Type used by the debug API to collect debug information +*/ +typedef struct lua_Debug lua_Debug; + + +/* +** Functions to be called by the debugger in specific events +*/ +typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); + /* ** generic extra include file @@ -142,14 +160,15 @@ extern const char lua_ident[]; /* ** state manipulation */ -LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud); +LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud, unsigned seed); LUA_API void (lua_close) (lua_State *L); LUA_API lua_State *(lua_newthread) (lua_State *L); +LUA_API int (lua_closethread) (lua_State *L, lua_State *from); LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf); -LUA_API const lua_Number *(lua_version) (lua_State *L); +LUA_API lua_Number (lua_version) (lua_State *L); /* @@ -182,7 +201,7 @@ LUA_API lua_Number (lua_tonumberx) (lua_State *L, int idx, int *isnum); LUA_API lua_Integer (lua_tointegerx) (lua_State *L, int idx, int *isnum); LUA_API int (lua_toboolean) (lua_State *L, int idx); LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len); -LUA_API size_t (lua_rawlen) (lua_State *L, int idx); +LUA_API lua_Unsigned (lua_rawlen) (lua_State *L, int idx); LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx); LUA_API void *(lua_touserdata) (lua_State *L, int idx); LUA_API lua_State *(lua_tothread) (lua_State *L, int idx); @@ -225,6 +244,8 @@ LUA_API void (lua_pushnil) (lua_State *L); LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n); LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n); LUA_API const char *(lua_pushlstring) (lua_State *L, const char *s, size_t len); +LUA_API const char *(lua_pushexternalstring) (lua_State *L, + const char *s, size_t len, lua_Alloc falloc, void *ud); LUA_API const char *(lua_pushstring) (lua_State *L, const char *s); LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt, va_list argp); @@ -247,9 +268,9 @@ LUA_API int (lua_rawgeti) (lua_State *L, int idx, lua_Integer n); LUA_API int (lua_rawgetp) (lua_State *L, int idx, const void *p); LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec); -LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz); +LUA_API void *(lua_newuserdatauv) (lua_State *L, size_t sz, int nuvalue); LUA_API int (lua_getmetatable) (lua_State *L, int objindex); -LUA_API int (lua_getuservalue) (lua_State *L, int idx); +LUA_API int (lua_getiuservalue) (lua_State *L, int idx, int n); /* @@ -263,7 +284,7 @@ LUA_API void (lua_rawset) (lua_State *L, int idx); LUA_API void (lua_rawseti) (lua_State *L, int idx, lua_Integer n); LUA_API void (lua_rawsetp) (lua_State *L, int idx, const void *p); LUA_API int (lua_setmetatable) (lua_State *L, int objindex); -LUA_API void (lua_setuservalue) (lua_State *L, int idx); +LUA_API int (lua_setiuservalue) (lua_State *L, int idx, int n); /* @@ -288,7 +309,8 @@ LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data, int strip); */ LUA_API int (lua_yieldk) (lua_State *L, int nresults, lua_KContext ctx, lua_KFunction k); -LUA_API int (lua_resume) (lua_State *L, lua_State *from, int narg); +LUA_API int (lua_resume) (lua_State *L, lua_State *from, int narg, + int *nres); LUA_API int (lua_status) (lua_State *L); LUA_API int (lua_isyieldable) (lua_State *L); @@ -296,7 +318,14 @@ LUA_API int (lua_isyieldable) (lua_State *L); /* -** garbage-collection function and options +** Warning-related functions +*/ +LUA_API void (lua_setwarnf) (lua_State *L, lua_WarnFunction f, void *ud); +LUA_API void (lua_warning) (lua_State *L, const char *msg, int tocont); + + +/* +** garbage-collection options */ #define LUA_GCSTOP 0 @@ -305,11 +334,30 @@ LUA_API int (lua_isyieldable) (lua_State *L); #define LUA_GCCOUNT 3 #define LUA_GCCOUNTB 4 #define LUA_GCSTEP 5 -#define LUA_GCSETPAUSE 6 -#define LUA_GCSETSTEPMUL 7 -#define LUA_GCISRUNNING 9 +#define LUA_GCISRUNNING 6 +#define LUA_GCGEN 7 +#define LUA_GCINC 8 +#define LUA_GCPARAM 9 + + +/* +** garbage-collection parameters +*/ +/* parameters for generational mode */ +#define LUA_GCPMINORMUL 0 /* control minor collections */ +#define LUA_GCPMAJORMINOR 1 /* control shift major->minor */ +#define LUA_GCPMINORMAJOR 2 /* control shift minor->major */ -LUA_API int (lua_gc) (lua_State *L, int what, int data); +/* parameters for incremental mode */ +#define LUA_GCPPAUSE 3 /* size of pause between successive GCs */ +#define LUA_GCPSTEPMUL 4 /* GC "speed" */ +#define LUA_GCPSTEPSIZE 5 /* GC granularity */ + +/* number of parameters */ +#define LUA_GCPN 6 + + +LUA_API int (lua_gc) (lua_State *L, int what, ...); /* @@ -323,11 +371,15 @@ LUA_API int (lua_next) (lua_State *L, int idx); LUA_API void (lua_concat) (lua_State *L, int n); LUA_API void (lua_len) (lua_State *L, int idx); -LUA_API size_t (lua_stringtonumber) (lua_State *L, const char *s); +#define LUA_N2SBUFFSZ 64 +LUA_API unsigned (lua_numbertocstring) (lua_State *L, int idx, char *buff); +LUA_API size_t (lua_stringtonumber) (lua_State *L, const char *s); LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud); LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud); +LUA_API void (lua_toclose) (lua_State *L, int idx); +LUA_API void (lua_closeslot) (lua_State *L, int idx); /* @@ -377,16 +429,16 @@ LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud); /* ** {============================================================== -** compatibility macros for unsigned conversions +** compatibility macros ** =============================================================== */ -#if defined(LUA_COMPAT_APIINTCASTS) -#define lua_pushunsigned(L,n) lua_pushinteger(L, (lua_Integer)(n)) -#define lua_tounsignedx(L,i,is) ((lua_Unsigned)lua_tointegerx(L,i,is)) -#define lua_tounsigned(L,i) lua_tounsignedx(L,(i),NULL) +#define lua_newuserdata(L,s) lua_newuserdatauv(L,s,1) +#define lua_getuservalue(L,idx) lua_getiuservalue(L,idx,1) +#define lua_setuservalue(L,idx) lua_setiuservalue(L,idx,1) + +#define lua_resetthread(L) lua_closethread(L,NULL) -#endif /* }============================================================== */ /* @@ -414,12 +466,6 @@ LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud); #define LUA_MASKLINE (1 << LUA_HOOKLINE) #define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT) -typedef struct lua_Debug lua_Debug; /* activation record */ - - -/* Functions to be called by the debugger in specific events */ -typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); - LUA_API int (lua_getstack) (lua_State *L, int level, lua_Debug *ar); LUA_API int (lua_getinfo) (lua_State *L, const char *what, lua_Debug *ar); @@ -444,13 +490,17 @@ struct lua_Debug { const char *namewhat; /* (n) 'global', 'local', 'field', 'method' */ const char *what; /* (S) 'Lua', 'C', 'main', 'tail' */ const char *source; /* (S) */ + size_t srclen; /* (S) */ int currentline; /* (l) */ int linedefined; /* (S) */ int lastlinedefined; /* (S) */ unsigned char nups; /* (u) number of upvalues */ unsigned char nparams;/* (u) number of parameters */ char isvararg; /* (u) */ + unsigned char extraargs; /* (t) number of extra arguments */ char istailcall; /* (t) */ + int ftransfer; /* (r) index of first value transferred */ + int ntransfer; /* (r) number of transferred values */ char short_src[LUA_IDSIZE]; /* (S) */ /* private part */ struct CallInfo *i_ci; /* active function */ @@ -459,8 +509,19 @@ struct lua_Debug { /* }====================================================================== */ +#define LUAI_TOSTRAUX(x) #x +#define LUAI_TOSTR(x) LUAI_TOSTRAUX(x) + +#define LUA_VERSION_MAJOR LUAI_TOSTR(LUA_VERSION_MAJOR_N) +#define LUA_VERSION_MINOR LUAI_TOSTR(LUA_VERSION_MINOR_N) +#define LUA_VERSION_RELEASE LUAI_TOSTR(LUA_VERSION_RELEASE_N) + +#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR +#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE + + /****************************************************************************** -* Copyright (C) 1994-2016 Lua.org, PUC-Rio. +* Copyright (C) 1994-2025 Lua.org, PUC-Rio. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the diff --git a/src/external/lua/include/lua.hpp b/src/external/lua/include/lua.hpp old mode 100644 new mode 100755 index ec417f5..2853364 --- a/src/external/lua/include/lua.hpp +++ b/src/external/lua/include/lua.hpp @@ -1,6 +1,7 @@ // lua.hpp // Lua header files for C++ -// <> not supplied automatically because Lua also compiles as C++ +// 'extern "C" not supplied automatically in lua.h and other headers +// because Lua also compiles as C++ extern "C" { #include "lua.h" diff --git a/src/external/lua/include/luaconf.h b/src/external/lua/include/luaconf.h old mode 100644 new mode 100755 index 867e9cb..96a7780 --- a/src/external/lua/include/luaconf.h +++ b/src/external/lua/include/luaconf.h @@ -1,5 +1,5 @@ /* -** $Id: luaconf.h,v 1.255 2016/05/01 20:06:09 roberto Exp $ +** $Id: luaconf.h $ ** Configuration file for Lua ** See Copyright Notice in lua.h */ @@ -14,6 +14,16 @@ /* ** =================================================================== +** General Configuration File for Lua +** +** Some definitions here can be changed externally, through the compiler +** (e.g., with '-D' options): They are commented out or protected +** by '#if !defined' guards. However, several other definitions +** should be changed directly here, either because they affect the +** Lua ABI (by making the changes here, you ensure that all software +** connected to Lua, such as C libraries, will be compiled with the same +** configuration); or because they are seldom changed. +** ** Search for "@@" to find all configurable definitions. ** =================================================================== */ @@ -22,20 +32,10 @@ /* ** {==================================================================== ** System Configuration: macros to adapt (if needed) Lua to some -** particular platform, for instance compiling it with 32-bit numbers or -** restricting it to C89. +** particular platform, for instance restricting it to C89. ** ===================================================================== */ -/* -@@ LUA_32BITS enables Lua with 32-bit integers and 32-bit floats. You -** can also define LUA_32BITS in the make file, but changing here you -** ensure that all software connected to Lua will be compiled with the -** same configuration. -*/ -/* #define LUA_32BITS */ - - /* @@ LUA_USE_C89 controls the use of non-ISO-C89 features. ** Define it if you want Lua to avoid the use of a few C99 features @@ -58,48 +58,62 @@ #endif +/* +** When POSIX DLL ('LUA_USE_DLOPEN') is enabled, the Lua stand-alone +** application will try to dynamically link a 'readline' facility +** for its REPL. In that case, LUA_READLINELIB is the name of the +** library it will look for those facilities. If lua.c cannot open +** the specified library, it will generate a warning and then run +** without 'readline'. If that macro is not defined, lua.c will not +** use 'readline'. +*/ #if defined(LUA_USE_LINUX) #define LUA_USE_POSIX #define LUA_USE_DLOPEN /* needs an extra library: -ldl */ -#define LUA_USE_READLINE /* needs some extra libraries */ +#define LUA_READLINELIB "libreadline.so" #endif #if defined(LUA_USE_MACOSX) #define LUA_USE_POSIX -#define LUA_USE_DLOPEN /* MacOS does not need -ldl */ -#define LUA_USE_READLINE /* needs an extra library: -lreadline */ +#define LUA_USE_DLOPEN /* macOS does not need -ldl */ +#define LUA_READLINELIB "libedit.dylib" #endif -/* -@@ LUA_C89_NUMBERS ensures that Lua uses the largest types available for -** C89 ('long' and 'double'); Windows always has '__int64', so it does -** not need to use this case. -*/ -#if defined(LUA_USE_C89) && !defined(LUA_USE_WINDOWS) -#define LUA_C89_NUMBERS +#if defined(LUA_USE_IOS) +#define LUA_USE_POSIX +#define LUA_USE_DLOPEN #endif +#if defined(LUA_USE_C89) && defined(LUA_USE_POSIX) +#error "POSIX is not compatible with C89" +#endif + /* -@@ LUAI_BITSINT defines the (minimum) number of bits in an 'int'. +@@ LUAI_IS32INT is true iff 'int' has (at least) 32 bits. */ -/* avoid undefined shifts */ -#if ((INT_MAX >> 15) >> 15) >= 1 -#define LUAI_BITSINT 32 -#else -/* 'int' always must have at least 16 bits */ -#define LUAI_BITSINT 16 -#endif +#define LUAI_IS32INT ((UINT_MAX >> 30) >= 3) + +/* }================================================================== */ + +/* +** {================================================================== +** Configuration for Number types. These options should not be +** set externally, because any other code connected to Lua must +** use the same configuration. +** =================================================================== +*/ + /* @@ LUA_INT_TYPE defines the type for Lua integers. @@ LUA_FLOAT_TYPE defines the type for Lua floats. -** Lua should work fine with any mix of these options (if supported -** by your C compiler). The usual configurations are 64-bit integers +** Lua should work fine with any mix of these options supported +** by your C compiler. The usual configurations are 64-bit integers ** and 'double' (the default), 32-bit integers and 'float' (for ** restricted platforms), and 'long'/'double' (for C compilers not ** compliant with C99, which may not have support for 'long long'). @@ -115,49 +129,79 @@ #define LUA_FLOAT_DOUBLE 2 #define LUA_FLOAT_LONGDOUBLE 3 -#if defined(LUA_32BITS) /* { */ + +/* Default configuration ('long long' and 'double', for 64-bit Lua) */ +#define LUA_INT_DEFAULT LUA_INT_LONGLONG +#define LUA_FLOAT_DEFAULT LUA_FLOAT_DOUBLE + + +/* +@@ LUA_32BITS enables Lua with 32-bit integers and 32-bit floats. +*/ +/* #define LUA_32BITS */ + + +/* +@@ LUA_C89_NUMBERS ensures that Lua uses the largest types available for +** C89 ('long' and 'double'); Windows always has '__int64', so it does +** not need to use this case. +*/ +#if defined(LUA_USE_C89) && !defined(LUA_USE_WINDOWS) +#define LUA_C89_NUMBERS 1 +#else +#define LUA_C89_NUMBERS 0 +#endif + + +#if defined(LUA_32BITS) /* { */ /* ** 32-bit integers and 'float' */ -#if LUAI_BITSINT >= 32 /* use 'int' if big enough */ +#if LUAI_IS32INT /* use 'int' if big enough */ #define LUA_INT_TYPE LUA_INT_INT #else /* otherwise use 'long' */ #define LUA_INT_TYPE LUA_INT_LONG #endif #define LUA_FLOAT_TYPE LUA_FLOAT_FLOAT -#elif defined(LUA_C89_NUMBERS) /* }{ */ +#elif LUA_C89_NUMBERS /* }{ */ /* ** largest types available for C89 ('long' and 'double') */ #define LUA_INT_TYPE LUA_INT_LONG #define LUA_FLOAT_TYPE LUA_FLOAT_DOUBLE -#endif /* } */ +#else /* }{ */ +/* use defaults */ +#define LUA_INT_TYPE LUA_INT_DEFAULT +#define LUA_FLOAT_TYPE LUA_FLOAT_DEFAULT -/* -** default configuration for 64-bit Lua ('long long' and 'double') -*/ -#if !defined(LUA_INT_TYPE) -#define LUA_INT_TYPE LUA_INT_LONGLONG -#endif +#endif /* } */ -#if !defined(LUA_FLOAT_TYPE) -#define LUA_FLOAT_TYPE LUA_FLOAT_DOUBLE -#endif /* }================================================================== */ - /* ** {================================================================== ** Configuration for Paths. ** =================================================================== */ +/* +** LUA_PATH_SEP is the character that separates templates in a path. +** LUA_PATH_MARK is the string that marks the substitution points in a +** template. +** LUA_EXEC_DIR in a Windows path is replaced by the executable's +** directory. +*/ +#define LUA_PATH_SEP ";" +#define LUA_PATH_MARK "?" +#define LUA_EXEC_DIR "!" + + /* @@ LUA_PATH_DEFAULT is the default path that Lua uses to look for ** Lua libraries. @@ -167,6 +211,7 @@ ** hierarchy or if you want to install your libraries in ** non-conventional directories. */ + #define LUA_VDIR LUA_VERSION_MAJOR "." LUA_VERSION_MINOR #if defined(_WIN32) /* { */ /* @@ -176,29 +221,40 @@ #define LUA_LDIR "!\\lua\\" #define LUA_CDIR "!\\" #define LUA_SHRDIR "!\\..\\share\\lua\\" LUA_VDIR "\\" + +#if !defined(LUA_PATH_DEFAULT) #define LUA_PATH_DEFAULT \ LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua;" \ LUA_SHRDIR"?.lua;" LUA_SHRDIR"?\\init.lua;" \ ".\\?.lua;" ".\\?\\init.lua" +#endif + +#if !defined(LUA_CPATH_DEFAULT) #define LUA_CPATH_DEFAULT \ LUA_CDIR"?.dll;" \ LUA_CDIR"..\\lib\\lua\\" LUA_VDIR "\\?.dll;" \ - LUA_CDIR"loadall.dll;" ".\\?.dll;" \ - LUA_CDIR"?53.dll;" ".\\?53.dll" + LUA_CDIR"loadall.dll;" ".\\?.dll" +#endif #else /* }{ */ #define LUA_ROOT "/usr/local/" #define LUA_LDIR LUA_ROOT "share/lua/" LUA_VDIR "/" #define LUA_CDIR LUA_ROOT "lib/lua/" LUA_VDIR "/" + +#if !defined(LUA_PATH_DEFAULT) #define LUA_PATH_DEFAULT \ LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua;" \ "./?.lua;" "./?/init.lua" +#endif + +#if !defined(LUA_CPATH_DEFAULT) #define LUA_CPATH_DEFAULT \ - LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so;" \ - LUA_CDIR"lib?53.so;" "./lib?53.so" + LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so" +#endif + #endif /* } */ @@ -207,12 +263,25 @@ ** CHANGE it if your machine does not use "/" as the directory separator ** and is not Windows. (On Windows Lua automatically uses "\".) */ +#if !defined(LUA_DIRSEP) + #if defined(_WIN32) #define LUA_DIRSEP "\\" #else #define LUA_DIRSEP "/" #endif +#endif + + +/* +** LUA_IGMARK is a mark to ignore all after it when building the +** module name (e.g., used to build the luaopen_ function name). +** Typically, the suffix after the mark is the module version, +** as in "mod-v1.2.so". +*/ +#define LUA_IGMARK "-" + /* }================================================================== */ @@ -246,34 +315,17 @@ #endif /* } */ -/* more often than not the libs go together with the core */ +/* +** More often than not the libs go together with the core. +*/ #define LUALIB_API LUA_API -#define LUAMOD_API LUALIB_API - - -/* -@@ LUAI_FUNC is a mark for all extern functions that are not to be -** exported to outside modules. -@@ LUAI_DDEF and LUAI_DDEC are marks for all extern (const) variables -** that are not to be exported to outside modules (LUAI_DDEF for -** definitions and LUAI_DDEC for declarations). -** CHANGE them if you need to mark them in some special way. Elf/gcc -** (versions 3.2 and later) mark them as "hidden" to optimize access -** when Lua is compiled as a shared library. Not all elf targets support -** this attribute. Unfortunately, gcc does not offer a way to check -** whether the target offers that support, and those without support -** give a warning about it. To avoid these warnings, change to the -** default definition. -*/ -#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \ - defined(__ELF__) /* { */ -#define LUAI_FUNC __attribute__((visibility("hidden"))) extern -#else /* }{ */ -#define LUAI_FUNC extern -#endif /* } */ -#define LUAI_DDEC LUAI_FUNC -#define LUAI_DDEF /* empty */ +#if defined(__cplusplus) +/* Lua uses the "C name" when calling open functions */ +#define LUAMOD_API extern "C" +#else +#define LUAMOD_API LUA_API +#endif /* }================================================================== */ @@ -285,88 +337,26 @@ */ /* -@@ LUA_COMPAT_5_2 controls other macros for compatibility with Lua 5.2. -@@ LUA_COMPAT_5_1 controls other macros for compatibility with Lua 5.1. -** You can define it to get all options, or change specific options -** to fit your specific needs. +@@ LUA_COMPAT_GLOBAL avoids 'global' being a reserved word */ -#if defined(LUA_COMPAT_5_2) /* { */ +#define LUA_COMPAT_GLOBAL + /* @@ LUA_COMPAT_MATHLIB controls the presence of several deprecated ** functions in the mathematical library. +** (These functions were already officially removed in 5.3; +** nevertheless they are still available here.) */ -#define LUA_COMPAT_MATHLIB - -/* -@@ LUA_COMPAT_BITLIB controls the presence of library 'bit32'. -*/ -#define LUA_COMPAT_BITLIB - -/* -@@ LUA_COMPAT_IPAIRS controls the effectiveness of the __ipairs metamethod. -*/ -#define LUA_COMPAT_IPAIRS - -/* -@@ LUA_COMPAT_APIINTCASTS controls the presence of macros for -** manipulating other integer types (lua_pushunsigned, lua_tounsigned, -** luaL_checkint, luaL_checklong, etc.) -*/ -#define LUA_COMPAT_APIINTCASTS - -#endif /* } */ - - -#if defined(LUA_COMPAT_5_1) /* { */ - -/* Incompatibilities from 5.2 -> 5.3 */ -#define LUA_COMPAT_MATHLIB -#define LUA_COMPAT_APIINTCASTS - -/* -@@ LUA_COMPAT_UNPACK controls the presence of global 'unpack'. -** You can replace it with 'table.unpack'. -*/ -#define LUA_COMPAT_UNPACK - -/* -@@ LUA_COMPAT_LOADERS controls the presence of table 'package.loaders'. -** You can replace it with 'package.searchers'. -*/ -#define LUA_COMPAT_LOADERS - -/* -@@ macro 'lua_cpcall' emulates deprecated function lua_cpcall. -** You can call your C function directly (with light C functions). -*/ -#define lua_cpcall(L,f,u) \ - (lua_pushcfunction(L, (f)), \ - lua_pushlightuserdata(L,(u)), \ - lua_pcall(L,1,0,0)) - +/* #define LUA_COMPAT_MATHLIB */ -/* -@@ LUA_COMPAT_LOG10 defines the function 'log10' in the math library. -** You can rewrite 'log10(x)' as 'log(x, 10)'. -*/ -#define LUA_COMPAT_LOG10 - -/* -@@ LUA_COMPAT_LOADSTRING defines the function 'loadstring' in the base -** library. You can rewrite 'loadstring(s)' as 'load(s)'. -*/ -#define LUA_COMPAT_LOADSTRING - -/* -@@ LUA_COMPAT_MAXN defines the function 'maxn' in the table library. -*/ -#define LUA_COMPAT_MAXN /* @@ The following macros supply trivial compatibility for some ** changes in the API. The macros themselves document how to ** change your code to avoid using them. +** (Once more, these macros were officially removed in 5.3, but they are +** still available here.) */ #define lua_strlen(L,i) lua_rawlen(L, (i)) @@ -375,69 +365,41 @@ #define lua_equal(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPEQ) #define lua_lessthan(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPLT) -/* -@@ LUA_COMPAT_MODULE controls compatibility with previous -** module functions 'module' (Lua) and 'luaL_register' (C). -*/ -#define LUA_COMPAT_MODULE - -#endif /* } */ - - -/* -@@ LUA_COMPAT_FLOATSTRING makes Lua format integral floats without a -@@ a float mark ('.0'). -** This macro is not on by default even in compatibility mode, -** because this is not really an incompatibility. -*/ -/* #define LUA_COMPAT_FLOATSTRING */ - /* }================================================================== */ /* ** {================================================================== -** Configuration for Numbers. +** Configuration for Numbers (low-level part). ** Change these definitions if no predefined LUA_FLOAT_* / LUA_INT_* ** satisfy your needs. ** =================================================================== */ /* -@@ LUA_NUMBER is the floating-point type used by Lua. -@@ LUAI_UACNUMBER is the result of an 'usual argument conversion' +@@ LUAI_UACNUMBER is the result of a 'default argument promotion' @@ over a floating number. -@@ l_mathlim(x) corrects limit name 'x' to the proper float type +@@ l_floatatt(x) corrects float attribute 'x' to the proper float type ** by prefixing it with one of FLT/DBL/LDBL. @@ LUA_NUMBER_FRMLEN is the length modifier for writing floats. -@@ LUA_NUMBER_FMT is the format for writing floats. -@@ lua_number2str converts a float to a string. +@@ LUA_NUMBER_FMT is the format for writing floats with the maximum +** number of digits that respects tostring(tonumber(numeral)) == numeral. +** (That would be floor(log10(2^n)), where n is the number of bits in +** the float mantissa.) +@@ LUA_NUMBER_FMT_N is the format for writing floats with the minimum +** number of digits that ensures tonumber(tostring(number)) == number. +** (That would be LUA_NUMBER_FMT+2.) @@ l_mathop allows the addition of an 'l' or 'f' to all math operations. @@ l_floor takes the floor of a float. -@@ lua_str2number converts a decimal numeric string to a number. +@@ lua_str2number converts a decimal numeral to a number. */ -/* The following definitions are good for most cases here */ +/* The following definition is good for most cases here */ #define l_floor(x) (l_mathop(floor)(x)) -#define lua_number2str(s,sz,n) l_sprintf((s), sz, LUA_NUMBER_FMT, (n)) - -/* -@@ lua_numbertointeger converts a float number to an integer, or -** returns 0 if float is not within the range of a lua_Integer. -** (The range comparisons are tricky because of rounding. The tests -** here assume a two-complement representation, where MININTEGER always -** has an exact representation as a float; MAXINTEGER may not have one, -** and therefore its conversion to float may have an ill-defined value.) -*/ -#define lua_numbertointeger(n,p) \ - ((n) >= (LUA_NUMBER)(LUA_MININTEGER) && \ - (n) < -(LUA_NUMBER)(LUA_MININTEGER) && \ - (*(p) = (LUA_INTEGER)(n), 1)) - /* now the variable definitions */ @@ -445,12 +407,13 @@ #define LUA_NUMBER float -#define l_mathlim(n) (FLT_##n) +#define l_floatatt(n) (FLT_##n) #define LUAI_UACNUMBER double #define LUA_NUMBER_FRMLEN "" #define LUA_NUMBER_FMT "%.7g" +#define LUA_NUMBER_FMT_N "%.9g" #define l_mathop(op) op##f @@ -461,12 +424,13 @@ #define LUA_NUMBER long double -#define l_mathlim(n) (LDBL_##n) +#define l_floatatt(n) (LDBL_##n) #define LUAI_UACNUMBER long double #define LUA_NUMBER_FRMLEN "L" #define LUA_NUMBER_FMT "%.19Lg" +#define LUA_NUMBER_FMT_N "%.21Lg" #define l_mathop(op) op##l @@ -476,12 +440,13 @@ #define LUA_NUMBER double -#define l_mathlim(n) (DBL_##n) +#define l_floatatt(n) (DBL_##n) #define LUAI_UACNUMBER double #define LUA_NUMBER_FRMLEN "" -#define LUA_NUMBER_FMT "%.14g" +#define LUA_NUMBER_FMT "%.15g" +#define LUA_NUMBER_FMT_N "%.17g" #define l_mathop(op) op @@ -496,16 +461,14 @@ /* -@@ LUA_INTEGER is the integer type used by Lua. -** @@ LUA_UNSIGNED is the unsigned version of LUA_INTEGER. -** -@@ LUAI_UACINT is the result of an 'usual argument conversion' -@@ over a lUA_INTEGER. +@@ LUAI_UACINT is the result of a 'default argument promotion' +@@ over a LUA_INTEGER. @@ LUA_INTEGER_FRMLEN is the length modifier for reading/writing integers. @@ LUA_INTEGER_FMT is the format for writing integers. @@ LUA_MAXINTEGER is the maximum value for a LUA_INTEGER. @@ LUA_MININTEGER is the minimum value for a LUA_INTEGER. +@@ LUA_MAXUNSIGNED is the maximum value for a LUA_UNSIGNED. @@ lua_integer2str converts an integer to a string. */ @@ -513,10 +476,12 @@ /* The following definitions are good for most cases here */ #define LUA_INTEGER_FMT "%" LUA_INTEGER_FRMLEN "d" -#define lua_integer2str(s,sz,n) l_sprintf((s), sz, LUA_INTEGER_FMT, (n)) #define LUAI_UACINT LUA_INTEGER +#define lua_integer2str(s,sz,n) \ + l_sprintf((s), sz, LUA_INTEGER_FMT, (LUAI_UACINT)(n)) + /* ** use LUAI_UACINT here to avoid problems with promotions (which ** can turn a comparison between unsigneds into a signed comparison) @@ -534,6 +499,8 @@ #define LUA_MAXINTEGER INT_MAX #define LUA_MININTEGER INT_MIN +#define LUA_MAXUNSIGNED UINT_MAX + #elif LUA_INT_TYPE == LUA_INT_LONG /* }{ long */ #define LUA_INTEGER long @@ -542,6 +509,8 @@ #define LUA_MAXINTEGER LONG_MAX #define LUA_MININTEGER LONG_MIN +#define LUA_MAXUNSIGNED ULONG_MAX + #elif LUA_INT_TYPE == LUA_INT_LONGLONG /* }{ long long */ /* use presence of macro LLONG_MAX as proxy for C99 compliance */ @@ -554,6 +523,8 @@ #define LUA_MAXINTEGER LLONG_MAX #define LUA_MININTEGER LLONG_MIN +#define LUA_MAXUNSIGNED ULLONG_MAX + #elif defined(LUA_USE_WINDOWS) /* }{ */ /* in Windows, can use specific Windows types */ @@ -563,6 +534,8 @@ #define LUA_MAXINTEGER _I64_MAX #define LUA_MININTEGER _I64_MIN +#define LUA_MAXUNSIGNED _UI64_MAX + #else /* }{ */ #error "Compiler does not support 'long long'. Use option '-DLUA_32BITS' \ @@ -597,7 +570,7 @@ /* -@@ lua_strx2number converts an hexadecimal numeric string to a number. +@@ lua_strx2number converts a hexadecimal numeral to a number. ** In C99, 'strtod' does that conversion. Otherwise, you can ** leave 'lua_strx2number' undefined and Lua will provide its own ** implementation. @@ -608,13 +581,21 @@ /* -@@ lua_number2strx converts a float to an hexadecimal numeric string. +@@ lua_pointer2str converts a pointer to a readable string in a +** non-specified way. +*/ +#define lua_pointer2str(buff,sz,p) l_sprintf(buff,sz,"%p",p) + + +/* +@@ lua_number2strx converts a float to a hexadecimal numeral. ** In C99, 'sprintf' (with format specifiers '%a'/'%A') does that. ** Otherwise, you can leave 'lua_number2strx' undefined and Lua will ** provide its own implementation. */ #if !defined(LUA_USE_C89) -#define lua_number2strx(L,b,sz,f,n) ((void)L, l_sprintf(b,sz,f,n)) +#define lua_number2strx(L,b,sz,f,n) \ + ((void)L, l_sprintf(b,sz,f,(LUAI_UACNUMBER)(n))) #endif @@ -653,12 +634,33 @@ /* @@ lua_getlocaledecpoint gets the locale "radix character" (decimal point). ** Change that if you do not want to use C locales. (Code using this -** macro must include header 'locale.h'.) +** macro must include the header 'locale.h'.) */ #if !defined(lua_getlocaledecpoint) #define lua_getlocaledecpoint() (localeconv()->decimal_point[0]) #endif + +/* +** macros to improve jump prediction, used mostly for error handling +** and debug facilities. (Some macros in the Lua API use these macros. +** Define LUA_NOBUILTIN if you do not want '__builtin_expect' in your +** code.) +*/ +#if !defined(luai_likely) + +#if defined(__GNUC__) && !defined(LUA_NOBUILTIN) +#define luai_likely(x) (__builtin_expect(((x) != 0), 1)) +#define luai_unlikely(x) (__builtin_expect(((x) != 0), 0)) +#else +#define luai_likely(x) (x) +#define luai_unlikely(x) (x) +#endif + +#endif + + + /* }================================================================== */ @@ -682,10 +684,7 @@ @@ LUA_USE_APICHECK turns on several consistency checks on the C API. ** Define it as a help when debugging C code. */ -#if defined(LUA_USE_APICHECK) -#include -#define luai_apicheck(l,e) assert(e) -#endif +/* #define LUA_USE_APICHECK */ /* }================================================================== */ @@ -694,23 +693,10 @@ ** {================================================================== ** Macros that affect the API and must be stable (that is, must be the ** same when you compile Lua and when you compile code that links to -** Lua). You probably do not want/need to change them. +** Lua). ** ===================================================================== */ -/* -@@ LUAI_MAXSTACK limits the size of the Lua stack. -** CHANGE it if you need a different limit. This limit is arbitrary; -** its only purpose is to stop Lua from consuming unlimited stack -** space (and to reserve some numbers for pseudo-indices). -*/ -#if LUAI_BITSINT >= 32 -#define LUAI_MAXSTACK 1000000 -#else -#define LUAI_MAXSTACK 15000 -#endif - - /* @@ LUA_EXTRASPACE defines the size of a raw memory area associated with ** a Lua state with very fast access. @@ -721,35 +707,27 @@ /* @@ LUA_IDSIZE gives the maximum size for the description of the source -@@ of a function in debug information. +** of a function in debug information. ** CHANGE it if you want a different size. */ #define LUA_IDSIZE 60 /* -@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. -** CHANGE it if it uses too much C-stack space. (For long double, -** 'string.format("%.99f", 1e4932)' needs ~5030 bytes, so a -** smaller buffer would force a memory allocation for each call to -** 'string.format'.) +@@ LUAL_BUFFERSIZE is the initial buffer size used by the lauxlib +** buffer system. */ -#if defined(LUA_FLOAT_LONGDOUBLE) -#define LUAL_BUFFERSIZE 8192 -#else -#define LUAL_BUFFERSIZE ((int)(0x80 * sizeof(void*) * sizeof(lua_Integer))) -#endif - -/* }================================================================== */ +#define LUAL_BUFFERSIZE ((int)(16 * sizeof(void*) * sizeof(lua_Number))) /* -@@ LUA_QL describes how error messages quote program elements. -** Lua does not use these macros anymore; they are here for -** compatibility only. +@@ LUAI_MAXALIGN defines fields that, when used in a union, ensure +** maximum alignment for the other items in that union. */ -#define LUA_QL(x) "'" x "'" -#define LUA_QS LUA_QL("%s") +#define LUAI_MAXALIGN lua_Number n; double u; void *s; lua_Integer i; long l + +/* }================================================================== */ + @@ -763,7 +741,5 @@ - - #endif diff --git a/src/external/lua/include/lualib.h b/src/external/lua/include/lualib.h old mode 100644 new mode 100755 index 5165c0f..068f60a --- a/src/external/lua/include/lualib.h +++ b/src/external/lua/include/lualib.h @@ -1,5 +1,5 @@ /* -** $Id: lualib.h,v 1.44 2014/02/06 17:32:33 roberto Exp $ +** $Id: lualib.h $ ** Lua standard libraries ** See Copyright Notice in lua.h */ @@ -11,48 +11,55 @@ #include "lua.h" +/* version suffix for environment variable names */ +#define LUA_VERSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR +#define LUA_GLIBK 1 LUAMOD_API int (luaopen_base) (lua_State *L); +#define LUA_LOADLIBNAME "package" +#define LUA_LOADLIBK (LUA_GLIBK << 1) +LUAMOD_API int (luaopen_package) (lua_State *L); + + #define LUA_COLIBNAME "coroutine" +#define LUA_COLIBK (LUA_LOADLIBK << 1) LUAMOD_API int (luaopen_coroutine) (lua_State *L); -#define LUA_TABLIBNAME "table" -LUAMOD_API int (luaopen_table) (lua_State *L); +#define LUA_DBLIBNAME "debug" +#define LUA_DBLIBK (LUA_COLIBK << 1) +LUAMOD_API int (luaopen_debug) (lua_State *L); #define LUA_IOLIBNAME "io" +#define LUA_IOLIBK (LUA_DBLIBK << 1) LUAMOD_API int (luaopen_io) (lua_State *L); +#define LUA_MATHLIBNAME "math" +#define LUA_MATHLIBK (LUA_IOLIBK << 1) +LUAMOD_API int (luaopen_math) (lua_State *L); + #define LUA_OSLIBNAME "os" +#define LUA_OSLIBK (LUA_MATHLIBK << 1) LUAMOD_API int (luaopen_os) (lua_State *L); #define LUA_STRLIBNAME "string" +#define LUA_STRLIBK (LUA_OSLIBK << 1) LUAMOD_API int (luaopen_string) (lua_State *L); +#define LUA_TABLIBNAME "table" +#define LUA_TABLIBK (LUA_STRLIBK << 1) +LUAMOD_API int (luaopen_table) (lua_State *L); + #define LUA_UTF8LIBNAME "utf8" +#define LUA_UTF8LIBK (LUA_TABLIBK << 1) LUAMOD_API int (luaopen_utf8) (lua_State *L); -#define LUA_BITLIBNAME "bit32" -LUAMOD_API int (luaopen_bit32) (lua_State *L); -#define LUA_MATHLIBNAME "math" -LUAMOD_API int (luaopen_math) (lua_State *L); +/* open selected libraries */ +LUALIB_API void (luaL_openselectedlibs) (lua_State *L, int load, int preload); -#define LUA_DBLIBNAME "debug" -LUAMOD_API int (luaopen_debug) (lua_State *L); - -#define LUA_LOADLIBNAME "package" -LUAMOD_API int (luaopen_package) (lua_State *L); - - -/* open all previous libraries */ -LUALIB_API void (luaL_openlibs) (lua_State *L); - - - -#if !defined(lua_assert) -#define lua_assert(x) ((void)0) -#endif +/* open all libraries */ +#define luaL_openlibs(L) luaL_openselectedlibs(L, ~0, 0) #endif diff --git a/src/external/lua/lib-win64/liblua55.a b/src/external/lua/lib-win64/liblua55.a new file mode 100644 index 0000000..d6ae770 Binary files /dev/null and b/src/external/lua/lib-win64/liblua55.a differ diff --git a/src/external/lua/lib-win64/lua55.dll b/src/external/lua/lib-win64/lua55.dll new file mode 100644 index 0000000..ff62671 Binary files /dev/null and b/src/external/lua/lib-win64/lua55.dll differ diff --git a/src/external/lua/lib/liblua53.a b/src/external/lua/lib/liblua53.a deleted file mode 100644 index e51c0c8..0000000 Binary files a/src/external/lua/lib/liblua53.a and /dev/null differ diff --git a/src/external/lua/lib/liblua53dll.a b/src/external/lua/lib/liblua53dll.a deleted file mode 100644 index 32646db..0000000 Binary files a/src/external/lua/lib/liblua53dll.a and /dev/null differ diff --git a/src/external/lua/lib/liblua55.a b/src/external/lua/lib/liblua55.a new file mode 100755 index 0000000..e251de7 Binary files /dev/null and b/src/external/lua/lib/liblua55.a differ diff --git a/src/external/lua/lib/liblua55.so b/src/external/lua/lib/liblua55.so new file mode 100755 index 0000000..858528f Binary files /dev/null and b/src/external/lua/lib/liblua55.so differ diff --git a/src/external/lua/lib/lua53.dll b/src/external/lua/lib/lua53.dll deleted file mode 100644 index 45300d6..0000000 Binary files a/src/external/lua/lib/lua53.dll and /dev/null differ diff --git a/src/raylib-lua.h b/src/raylib-lua.h index 0bb5859..939a836 100644 --- a/src/raylib-lua.h +++ b/src/raylib-lua.h @@ -1,50 +1,37 @@ /********************************************************************************************** * -* raylib-lua v2.0 - raylib Lua bindings for raylib v2.0 +* raylib-lua v6.0 - raylib Lua bindings for raylib v6.0 * -* NOTES: +* AUTO-GENERATED by tools/rLuaParser/rluaparser.lua * -* The following types are treated as objects with named fields, same as in C. -* Color, Vector2, Vector3, Rectangle, Ray, Camera, Camera2D -* -* Lua defines utility functions to create those objects. +* Parsed: 606 functions, 35 structs, 21 enums, 41 defines, 8 aliases * -* USAGE EXAMPLE: -* local cl = Color(255,255,255,255) -* local rec = Rectangle(10, 10, 100, 100) -* local ray = Ray(Vector3(20, 20, 20), Vector3(50, 50, 50)) -* local x2 = rec.x + rec.width +* NOTES: * -* The following types are immutable, and you can only read their non-pointer arguments. -* Image, Texture2D, RenderTexture2D, Font +* The following types are treated as Lua tables with named fields, same as in C: +* Matrix, Vector2, Vector3, Vector4, Color, Rectangle, Ray, Camera, BoundingBox * -* All other object types are opaque, that is, you cannot access or change their fields directly. +* The following types are opaque userdata with field access and automatic memory management (__gc): +* Image, Texture2D, RenderTexture2D, Mesh, Model, Shader, Font, Sound, Music, Wave * * Remember that ALL raylib types have REFERENCE SEMANTICS in Lua. -* There is currently no way to create a copy of an opaque object. -* -* Some raylib functions take a pointer to an array, and the size of that array. -* The equivalent Lua functions take only an array table of the specified type UNLESS -* it's a pointer to a large char array (e.g. for images), then it takes (and potentially returns) -* a Lua string (without the size argument, as Lua strings are sized by default). -* -* Some raylib functions take pointers to objects to modify (e.g. ImageToPOT(), etc.) -* In Lua, these functions take values and return a new changed value, instead. +* Tables (value types) are passed to C by copying fields, but multiple references +* on the Lua side point to the same table object. * -* So, in C: ImageToPOT(&image, BLACK); -* In Lua becomes: image = ImageToPOT(image, BLACK) -* -* Remember that Lua functions can return multiple values. -* This is to preserve value semantics of raylib objects. +* Some raylib functions take pointers to objects to modify (e.g. UpdateCamera(), etc.) +* For table-based types like Camera, the binding automatically writes modified fields +* back to the original Lua table. For resource types like Image, changes are made +* directly to the memory block. * * CONTRIBUTORS: * Ghassan Al-Mashareqa (ghassan@ghassan.pl): Original binding creation (for raylib 1.3) * Ramon Santamaria (@raysan5): Review, update and maintenance -* +* yilisharcs: Modernization and automatic generator (for raylib 6.0) * * LICENSE: zlib/libpng * * Copyright (c) 2015-2017 Ghassan Al-Mashareqa and Ramon Santamaria (@raysan5) +* Copyright (c) 2026 yilisharcs * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. @@ -65,9 +52,10 @@ #pragma once -#include "raylib.h" +#include +#include +#include -#define RLUA_STATIC #ifdef RLUA_STATIC #define RLUADEF static // Functions just visible to module including this file #else @@ -78,5705 +66,9049 @@ #endif #endif -//---------------------------------------------------------------------------------- -// Global Variables Definition -//---------------------------------------------------------------------------------- -// ... +RLUADEF lua_State *rlua_open(void); +RLUADEF void rlua_close(lua_State *L); -//---------------------------------------------------------------------------------- -// Module Functions Declaration -//---------------------------------------------------------------------------------- -RLUADEF void rLuaInitDevice(void); // Initialize Lua system -RLUADEF void rLuaExecuteCode(const char *code); // Execute raylib Lua code -RLUADEF void rLuaExecuteFile(const char *filename); // Execute raylib Lua script -RLUADEF void rLuaCloseDevice(void); // De-initialize Lua system +#ifdef RLUA_IMPLEMENTATION +#include "raylib.h" +#include +#include +#include +#include // Required for: va_list - Only used by TraceLogCallback +#include + +// --- Global State --- +static lua_State *RLUA_State = NULL; +static int RLUA_LogRef = LUA_REFNIL; +static pthread_mutex_t RLUA_LogMutex = PTHREAD_MUTEX_INITIALIZER; + +// --- Marshalling Helpers --- + +typedef struct { + void *data; + int count; + const char *tname; + bool owned; +} RLUA_Handle; + +static void* RLUA_CHECK_Resource(lua_State *L, int index, const char *tname) { + RLUA_Handle *h = (RLUA_Handle *)luaL_checkudata(L, index, tname); + return h->data; +} + +static void RLUA_PUSH_Resource(lua_State *L, void *data, size_t size, const char *tname) { + RLUA_Handle *h = (RLUA_Handle *)lua_newuserdata(L, sizeof(RLUA_Handle)); + h->data = RL_MALLOC(size); + memcpy(h->data, data, size); + h->count = 1; + h->tname = tname; + h->owned = true; + luaL_setmetatable(L, tname); +} + +static void RLUA_PUSH_View(lua_State *L, const void *data, int count, const char *tname, bool owned) { + RLUA_Handle *h = (RLUA_Handle *)lua_newuserdata(L, sizeof(RLUA_Handle)); + h->data = (void *)data; + h->count = count; + h->tname = tname; + h->owned = owned; + luaL_setmetatable(L, tname); +} + +// --- Callback Trampolines --- +static void RLUA_TraceLogTrampoline(int logLevel, const char *text, va_list args) { + if (!RLUA_State || RLUA_LogRef == LUA_REFNIL) return; + char buffer[1024]; + vsnprintf(buffer, sizeof(buffer), text, args); + pthread_mutex_lock(&RLUA_LogMutex); + lua_State *L = RLUA_State; + lua_rawgeti(L, LUA_REGISTRYINDEX, RLUA_LogRef); + lua_pushinteger(L, logLevel); + lua_pushstring(L, buffer); + if (lua_pcall(L, 2, 0, 0) != LUA_OK) { + TraceLog(LOG_ERROR, "LUA: TraceLogCallback: %s", lua_tostring(L, -1)); + lua_pop(L, 1); + } + pthread_mutex_unlock(&RLUA_LogMutex); +} -/*********************************************************************************** -* -* RLUA IMPLEMENTATION -* -************************************************************************************/ +// --- Type Aliases --- -#if defined(RLUA_IMPLEMENTATION) +#define RLUA_CHECK_Camera RLUA_CHECK_Camera3D +#define RLUA_PUSH_Camera RLUA_PUSH_Camera3D +#define RLUA_WRITEBACK_Camera RLUA_WRITEBACK_Camera3D +#define RLUA_CHECK_ModelAnimPose(L, idx) (ModelAnimPose)RLUA_CHECK_Resource(L, idx, "Transform") +#define RLUA_PUSH_ModelAnimPose(L, val) RLUA_PUSH_View(L, val, 1, "Transform", false) +#define RLUA_CHECK_Quaternion RLUA_CHECK_Vector4 +#define RLUA_PUSH_Quaternion RLUA_PUSH_Vector4 +#define RLUA_CHECK_RenderTexture2D(L, idx) (*(RenderTexture2D*)RLUA_CHECK_Resource(L, idx, "RenderTexture")) +#define RLUA_PUSH_RenderTexture2D(L, val) RLUA_PUSH_Resource(L, &val, sizeof(RenderTexture2D), "RenderTexture") +#define RLUA_CHECK_Texture2D(L, idx) (*(Texture2D*)RLUA_CHECK_Resource(L, idx, "Texture")) +#define RLUA_PUSH_Texture2D(L, val) RLUA_PUSH_Resource(L, &val, sizeof(Texture2D), "Texture") +#define RLUA_CHECK_TextureCubemap(L, idx) (*(TextureCubemap*)RLUA_CHECK_Resource(L, idx, "Texture")) +#define RLUA_PUSH_TextureCubemap(L, val) RLUA_PUSH_Resource(L, &val, sizeof(TextureCubemap), "Texture") -#include "raylib.h" -#include "raymath.h" -#define PHYSAC_IMPLEMENTATION -#include "physac.h" +// --- Generated Marshallers --- -#include -#include +// Vector2, 2 components +static Vector2 RLUA_CHECK_Vector2(lua_State *L, int index) +{ + Vector2 result = { 0 }; + if (lua_istable(L, index)) { + lua_getfield(L, index, "x"); + result.x = (float)luaL_checknumber(L, -1); // Vector x component + lua_pop(L, 1); + lua_getfield(L, index, "y"); + result.y = (float)luaL_checknumber(L, -1); // Vector y component + lua_pop(L, 1); + } + return result; +} +static void RLUA_PUSH_Vector2(lua_State *L, Vector2 result) +{ + lua_createtable(L, 0, 2); + lua_pushnumber(L, result.x); // Vector x component + lua_setfield(L, -2, "x"); + lua_pushnumber(L, result.y); // Vector y component + lua_setfield(L, -2, "y"); +} +static void RLUA_WRITEBACK_Vector2(lua_State *L, int index, Vector2 val) +{ + if (lua_istable(L, index)) { + lua_pushnumber(L, val.x); // Vector x component + lua_setfield(L, index, "x"); + lua_pushnumber(L, val.y); // Vector y component + lua_setfield(L, index, "y"); + } +} -#include -#include -#include -//---------------------------------------------------------------------------------- -// Defines and Macros -//---------------------------------------------------------------------------------- -#define LuaPush_int(L, value) lua_pushinteger(L, value) -#define LuaPush_float(L, value) lua_pushnumber(L, value); -#define LuaPush_bool(L, value) lua_pushboolean(L, value) -#define LuaPush_string(L, value) lua_pushstring(L, value) - -#define LuaPush_Image(L, img) LuaPushOpaqueTypeWithMetatable(L, img, Image) -#define LuaPush_Texture2D(L, tex) LuaPushOpaqueTypeWithMetatable(L, tex, Texture2D) -#define LuaPush_RenderTexture2D(L, tex) LuaPushOpaqueTypeWithMetatable(L, tex, RenderTexture2D) -#define LuaPush_Font(L, sf) LuaPushOpaqueTypeWithMetatable(L, sf, Font) -#define LuaPush_Mesh(L, vd) LuaPushOpaqueType(L, vd) -#define LuaPush_Shader(L, s) LuaPushOpaqueType(L, s) -#define LuaPush_Sound(L, snd) LuaPushOpaqueType(L, snd) -#define LuaPush_Wave(L, wav) LuaPushOpaqueType(L, wav) -#define LuaPush_Music(L, mus) LuaPushOpaqueType(L, mus) -#define LuaPush_AudioStream(L, aud) LuaPushOpaqueType(L, aud) -#define LuaPush_PhysicsBody(L, body) LuaPushOpaqueType(L, body) - -#define LuaGetArgument_ptr (void *)luaL_checkinteger -#define LuaGetArgument_int (int)luaL_checkinteger -#define LuaGetArgument_unsigned (unsigned)luaL_checkinteger -#define LuaGetArgument_char (char)luaL_checkinteger -#define LuaGetArgument_float (float)luaL_checknumber -#define LuaGetArgument_double luaL_checknumber -#define LuaGetArgument_string luaL_checkstring - -#define LuaGetArgument_Image(L, img) *(Image *)LuaGetArgumentOpaqueTypeWithMetatable(L, img, "Image") -#define LuaGetArgument_Texture2D(L, tex) *(Texture2D *)LuaGetArgumentOpaqueTypeWithMetatable(L, tex, "Texture2D") -#define LuaGetArgument_RenderTexture2D(L, rtex) *(RenderTexture2D *)LuaGetArgumentOpaqueTypeWithMetatable(L, rtex, "RenderTexture2D") -#define LuaGetArgument_Font(L, sf) *(Font *)LuaGetArgumentOpaqueTypeWithMetatable(L, sf, "Font") -#define LuaGetArgument_Mesh(L, vd) *(Mesh *)LuaGetArgumentOpaqueType(L, vd) -#define LuaGetArgument_Shader(L, s) *(Shader *)LuaGetArgumentOpaqueType(L, s) -#define LuaGetArgument_Sound(L, snd) *(Sound *)LuaGetArgumentOpaqueType(L, snd) -#define LuaGetArgument_Wave(L, wav) *(Wave *)LuaGetArgumentOpaqueType(L, wav) -#define LuaGetArgument_Music(L, mus) *(Music *)LuaGetArgumentOpaqueType(L, mus) -#define LuaGetArgument_AudioStream(L, aud) *(AudioStream *)LuaGetArgumentOpaqueType(L, aud) -#define LuaGetArgument_PhysicsBody(L, body) *(PhysicsBody *)LuaGetArgumentOpaqueType(L, body) - -#define LuaPushOpaqueType(L, str) LuaPushOpaque(L, &str, sizeof(str)) -#define LuaPushOpaqueTypeWithMetatable(L, str, meta) LuaPushOpaqueWithMetatable(L, &str, sizeof(str), #meta) - -//---------------------------------------------------------------------------------- -// Global Variables Definition -//---------------------------------------------------------------------------------- -static lua_State* mainLuaState = 0; -static lua_State* L = 0; - -//---------------------------------------------------------------------------------- -// Module specific Functions Declaration -//---------------------------------------------------------------------------------- -static void LuaPush_Color(lua_State* L, Color color); -static void LuaPush_Vector2(lua_State* L, Vector2 vec); -static void LuaPush_Vector3(lua_State* L, Vector3 vec); -static void LuaPush_Vector4(lua_State* L, Vector4 vec); -static void LuaPush_Quaternion(lua_State* L, Quaternion vec); -static void LuaPush_Matrix(lua_State* L, Matrix *matrix); -static void LuaPush_Rectangle(lua_State* L, Rectangle rect); -static void LuaPush_Camera(lua_State* L, Camera cam); -static void LuaPush_Camera2D(lua_State* L, Camera2D cam); -static void LuaPush_Model(lua_State* L, Model mdl); -static void LuaPush_Ray(lua_State* L, Ray ray); -static void LuaPush_RayHitInfo(lua_State* L, RayHitInfo hit); - -static Color LuaGetArgument_Color(lua_State* L, int index); -static Vector2 LuaGetArgument_Vector2(lua_State* L, int index); -static Vector3 LuaGetArgument_Vector3(lua_State* L, int index); -static Vector4 LuaGetArgument_Vector4(lua_State* L, int index); -static Quaternion LuaGetArgument_Quaternion(lua_State* L, int index); -static Matrix LuaGetArgument_Matrix(lua_State* L, int index); -static Rectangle LuaGetArgument_Rectangle(lua_State* L, int index); -static Camera LuaGetArgument_Camera(lua_State* L, int index); -static Camera2D LuaGetArgument_Camera2D(lua_State* L, int index); -static Model LuaGetArgument_Model(lua_State* L, int index); -static Ray LuaGetArgument_Ray(lua_State* L, int index); - -//---------------------------------------------------------------------------------- -// rlua Helper Functions -//---------------------------------------------------------------------------------- -static void LuaStartEnum(void) +// Vector3, 3 components +static Vector3 RLUA_CHECK_Vector3(lua_State *L, int index) +{ + Vector3 result = { 0 }; + if (lua_istable(L, index)) { + lua_getfield(L, index, "x"); + result.x = (float)luaL_checknumber(L, -1); // Vector x component + lua_pop(L, 1); + lua_getfield(L, index, "y"); + result.y = (float)luaL_checknumber(L, -1); // Vector y component + lua_pop(L, 1); + lua_getfield(L, index, "z"); + result.z = (float)luaL_checknumber(L, -1); // Vector z component + lua_pop(L, 1); + } + return result; +} +static void RLUA_PUSH_Vector3(lua_State *L, Vector3 result) +{ + lua_createtable(L, 0, 3); + lua_pushnumber(L, result.x); // Vector x component + lua_setfield(L, -2, "x"); + lua_pushnumber(L, result.y); // Vector y component + lua_setfield(L, -2, "y"); + lua_pushnumber(L, result.z); // Vector z component + lua_setfield(L, -2, "z"); +} + + +// Vector4, 4 components +static Vector4 RLUA_CHECK_Vector4(lua_State *L, int index) +{ + Vector4 result = { 0 }; + if (lua_istable(L, index)) { + lua_getfield(L, index, "x"); + result.x = (float)luaL_checknumber(L, -1); // Vector x component + lua_pop(L, 1); + lua_getfield(L, index, "y"); + result.y = (float)luaL_checknumber(L, -1); // Vector y component + lua_pop(L, 1); + lua_getfield(L, index, "z"); + result.z = (float)luaL_checknumber(L, -1); // Vector z component + lua_pop(L, 1); + lua_getfield(L, index, "w"); + result.w = (float)luaL_checknumber(L, -1); // Vector w component + lua_pop(L, 1); + } + return result; +} +static void RLUA_PUSH_Vector4(lua_State *L, Vector4 result) +{ + lua_createtable(L, 0, 4); + lua_pushnumber(L, result.x); // Vector x component + lua_setfield(L, -2, "x"); + lua_pushnumber(L, result.y); // Vector y component + lua_setfield(L, -2, "y"); + lua_pushnumber(L, result.z); // Vector z component + lua_setfield(L, -2, "z"); + lua_pushnumber(L, result.w); // Vector w component + lua_setfield(L, -2, "w"); +} + + +// Matrix, 4x4 components, column major, OpenGL style, right-handed +static Matrix RLUA_CHECK_Matrix(lua_State *L, int index) +{ + Matrix result = { 0 }; + if (lua_istable(L, index)) { + lua_getfield(L, index, "m0"); + result.m0 = (float)luaL_checknumber(L, -1); // Matrix first row (4 components) + lua_pop(L, 1); + lua_getfield(L, index, "m1"); + result.m1 = (float)luaL_checknumber(L, -1); // Matrix second row (4 components) + lua_pop(L, 1); + lua_getfield(L, index, "m2"); + result.m2 = (float)luaL_checknumber(L, -1); // Matrix third row (4 components) + lua_pop(L, 1); + lua_getfield(L, index, "m3"); + result.m3 = (float)luaL_checknumber(L, -1); // Matrix fourth row (4 components) + lua_pop(L, 1); + lua_getfield(L, index, "m4"); + result.m4 = (float)luaL_checknumber(L, -1); // Matrix first row (4 components) + lua_pop(L, 1); + lua_getfield(L, index, "m5"); + result.m5 = (float)luaL_checknumber(L, -1); // Matrix second row (4 components) + lua_pop(L, 1); + lua_getfield(L, index, "m6"); + result.m6 = (float)luaL_checknumber(L, -1); // Matrix third row (4 components) + lua_pop(L, 1); + lua_getfield(L, index, "m7"); + result.m7 = (float)luaL_checknumber(L, -1); // Matrix fourth row (4 components) + lua_pop(L, 1); + lua_getfield(L, index, "m8"); + result.m8 = (float)luaL_checknumber(L, -1); // Matrix first row (4 components) + lua_pop(L, 1); + lua_getfield(L, index, "m9"); + result.m9 = (float)luaL_checknumber(L, -1); // Matrix second row (4 components) + lua_pop(L, 1); + lua_getfield(L, index, "m10"); + result.m10 = (float)luaL_checknumber(L, -1); // Matrix third row (4 components) + lua_pop(L, 1); + lua_getfield(L, index, "m11"); + result.m11 = (float)luaL_checknumber(L, -1); // Matrix fourth row (4 components) + lua_pop(L, 1); + lua_getfield(L, index, "m12"); + result.m12 = (float)luaL_checknumber(L, -1); // Matrix first row (4 components) + lua_pop(L, 1); + lua_getfield(L, index, "m13"); + result.m13 = (float)luaL_checknumber(L, -1); // Matrix second row (4 components) + lua_pop(L, 1); + lua_getfield(L, index, "m14"); + result.m14 = (float)luaL_checknumber(L, -1); // Matrix third row (4 components) + lua_pop(L, 1); + lua_getfield(L, index, "m15"); + result.m15 = (float)luaL_checknumber(L, -1); // Matrix fourth row (4 components) + lua_pop(L, 1); + } + return result; +} +static void RLUA_PUSH_Matrix(lua_State *L, Matrix result) +{ + lua_createtable(L, 0, 16); + lua_pushnumber(L, result.m0); // Matrix first row (4 components) + lua_setfield(L, -2, "m0"); + lua_pushnumber(L, result.m1); // Matrix second row (4 components) + lua_setfield(L, -2, "m1"); + lua_pushnumber(L, result.m2); // Matrix third row (4 components) + lua_setfield(L, -2, "m2"); + lua_pushnumber(L, result.m3); // Matrix fourth row (4 components) + lua_setfield(L, -2, "m3"); + lua_pushnumber(L, result.m4); // Matrix first row (4 components) + lua_setfield(L, -2, "m4"); + lua_pushnumber(L, result.m5); // Matrix second row (4 components) + lua_setfield(L, -2, "m5"); + lua_pushnumber(L, result.m6); // Matrix third row (4 components) + lua_setfield(L, -2, "m6"); + lua_pushnumber(L, result.m7); // Matrix fourth row (4 components) + lua_setfield(L, -2, "m7"); + lua_pushnumber(L, result.m8); // Matrix first row (4 components) + lua_setfield(L, -2, "m8"); + lua_pushnumber(L, result.m9); // Matrix second row (4 components) + lua_setfield(L, -2, "m9"); + lua_pushnumber(L, result.m10); // Matrix third row (4 components) + lua_setfield(L, -2, "m10"); + lua_pushnumber(L, result.m11); // Matrix fourth row (4 components) + lua_setfield(L, -2, "m11"); + lua_pushnumber(L, result.m12); // Matrix first row (4 components) + lua_setfield(L, -2, "m12"); + lua_pushnumber(L, result.m13); // Matrix second row (4 components) + lua_setfield(L, -2, "m13"); + lua_pushnumber(L, result.m14); // Matrix third row (4 components) + lua_setfield(L, -2, "m14"); + lua_pushnumber(L, result.m15); // Matrix fourth row (4 components) + lua_setfield(L, -2, "m15"); +} + + +// Color, 4 components, R8G8B8A8 (32bit) +static Color RLUA_CHECK_Color(lua_State *L, int index) +{ + Color result = { 0 }; + if (lua_istable(L, index)) { + lua_getfield(L, index, "r"); + result.r = (unsigned char)luaL_checkinteger(L, -1); // Color red value + lua_pop(L, 1); + lua_getfield(L, index, "g"); + result.g = (unsigned char)luaL_checkinteger(L, -1); // Color green value + lua_pop(L, 1); + lua_getfield(L, index, "b"); + result.b = (unsigned char)luaL_checkinteger(L, -1); // Color blue value + lua_pop(L, 1); + lua_getfield(L, index, "a"); + result.a = (unsigned char)luaL_checkinteger(L, -1); // Color alpha value + lua_pop(L, 1); + } + return result; +} +static void RLUA_PUSH_Color(lua_State *L, Color result) +{ + lua_createtable(L, 0, 4); + lua_pushinteger(L, result.r); // Color red value + lua_setfield(L, -2, "r"); + lua_pushinteger(L, result.g); // Color green value + lua_setfield(L, -2, "g"); + lua_pushinteger(L, result.b); // Color blue value + lua_setfield(L, -2, "b"); + lua_pushinteger(L, result.a); // Color alpha value + lua_setfield(L, -2, "a"); +} + + +// Rectangle, 4 components +static Rectangle RLUA_CHECK_Rectangle(lua_State *L, int index) +{ + Rectangle result = { 0 }; + if (lua_istable(L, index)) { + lua_getfield(L, index, "x"); + result.x = (float)luaL_checknumber(L, -1); // Rectangle top-left corner position x + lua_pop(L, 1); + lua_getfield(L, index, "y"); + result.y = (float)luaL_checknumber(L, -1); // Rectangle top-left corner position y + lua_pop(L, 1); + lua_getfield(L, index, "width"); + result.width = (float)luaL_checknumber(L, -1); // Rectangle width + lua_pop(L, 1); + lua_getfield(L, index, "height"); + result.height = (float)luaL_checknumber(L, -1); // Rectangle height + lua_pop(L, 1); + } + return result; +} +static void RLUA_PUSH_Rectangle(lua_State *L, Rectangle result) +{ + lua_createtable(L, 0, 4); + lua_pushnumber(L, result.x); // Rectangle top-left corner position x + lua_setfield(L, -2, "x"); + lua_pushnumber(L, result.y); // Rectangle top-left corner position y + lua_setfield(L, -2, "y"); + lua_pushnumber(L, result.width); // Rectangle width + lua_setfield(L, -2, "width"); + lua_pushnumber(L, result.height); // Rectangle height + lua_setfield(L, -2, "height"); +} + + +// NPatchInfo, n-patch layout info +static NPatchInfo RLUA_CHECK_NPatchInfo(lua_State *L, int index) +{ + NPatchInfo result = { 0 }; + if (lua_istable(L, index)) { + lua_getfield(L, index, "source"); + result.source = RLUA_CHECK_Rectangle(L, -1); // Texture source rectangle + lua_pop(L, 1); + lua_getfield(L, index, "left"); + result.left = (int)luaL_checkinteger(L, -1); // Left border offset + lua_pop(L, 1); + lua_getfield(L, index, "top"); + result.top = (int)luaL_checkinteger(L, -1); // Top border offset + lua_pop(L, 1); + lua_getfield(L, index, "right"); + result.right = (int)luaL_checkinteger(L, -1); // Right border offset + lua_pop(L, 1); + lua_getfield(L, index, "bottom"); + result.bottom = (int)luaL_checkinteger(L, -1); // Bottom border offset + lua_pop(L, 1); + lua_getfield(L, index, "layout"); + result.layout = (int)luaL_checkinteger(L, -1); // Layout of the n-patch: 3x3, 1x3 or 3x1 + lua_pop(L, 1); + } + return result; +} +static void RLUA_PUSH_NPatchInfo(lua_State *L, NPatchInfo result) +{ + lua_createtable(L, 0, 6); + RLUA_PUSH_Rectangle(L, result.source); // Texture source rectangle + lua_setfield(L, -2, "source"); + lua_pushinteger(L, result.left); // Left border offset + lua_setfield(L, -2, "left"); + lua_pushinteger(L, result.top); // Top border offset + lua_setfield(L, -2, "top"); + lua_pushinteger(L, result.right); // Right border offset + lua_setfield(L, -2, "right"); + lua_pushinteger(L, result.bottom); // Bottom border offset + lua_setfield(L, -2, "bottom"); + lua_pushinteger(L, result.layout); // Layout of the n-patch: 3x3, 1x3 or 3x1 + lua_setfield(L, -2, "layout"); +} + + +// GlyphInfo, font characters glyphs info +static GlyphInfo RLUA_CHECK_GlyphInfo(lua_State *L, int index) +{ + GlyphInfo result = { 0 }; + if (lua_istable(L, index)) { + lua_getfield(L, index, "value"); + result.value = (int)luaL_checkinteger(L, -1); // Character value (Unicode) + lua_pop(L, 1); + lua_getfield(L, index, "offsetX"); + result.offsetX = (int)luaL_checkinteger(L, -1); // Character offset X when drawing + lua_pop(L, 1); + lua_getfield(L, index, "offsetY"); + result.offsetY = (int)luaL_checkinteger(L, -1); // Character offset Y when drawing + lua_pop(L, 1); + lua_getfield(L, index, "advanceX"); + result.advanceX = (int)luaL_checkinteger(L, -1); // Character advance position X + lua_pop(L, 1); + lua_getfield(L, index, "image"); + result.image = *(Image*)RLUA_CHECK_Resource(L, -1, "Image"); // Character image data + lua_pop(L, 1); + } + return result; +} +static void RLUA_PUSH_GlyphInfo(lua_State *L, GlyphInfo result) +{ + lua_createtable(L, 0, 5); + lua_pushinteger(L, result.value); // Character value (Unicode) + lua_setfield(L, -2, "value"); + lua_pushinteger(L, result.offsetX); // Character offset X when drawing + lua_setfield(L, -2, "offsetX"); + lua_pushinteger(L, result.offsetY); // Character offset Y when drawing + lua_setfield(L, -2, "offsetY"); + lua_pushinteger(L, result.advanceX); // Character advance position X + lua_setfield(L, -2, "advanceX"); + RLUA_PUSH_Resource(L, &result.image, sizeof(Image), "Image"); // Character image data + lua_setfield(L, -2, "image"); +} + + +// Camera, defines position/orientation in 3d space +static Camera3D RLUA_CHECK_Camera3D(lua_State *L, int index) +{ + Camera3D result = { 0 }; + if (lua_istable(L, index)) { + lua_getfield(L, index, "position"); + result.position = RLUA_CHECK_Vector3(L, -1); // Camera position + lua_pop(L, 1); + lua_getfield(L, index, "target"); + result.target = RLUA_CHECK_Vector3(L, -1); // Camera target it looks-at + lua_pop(L, 1); + lua_getfield(L, index, "up"); + result.up = RLUA_CHECK_Vector3(L, -1); // Camera up vector (rotation over its axis) + lua_pop(L, 1); + lua_getfield(L, index, "fovy"); + result.fovy = (float)luaL_checknumber(L, -1); // Camera field-of-view aperture in Y (degrees) in perspective, used as near plane height in world units in orthographic + lua_pop(L, 1); + lua_getfield(L, index, "projection"); + result.projection = (int)luaL_checkinteger(L, -1); // Camera projection: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC + lua_pop(L, 1); + } + return result; +} +static void RLUA_PUSH_Camera3D(lua_State *L, Camera3D result) +{ + lua_createtable(L, 0, 5); + RLUA_PUSH_Vector3(L, result.position); // Camera position + lua_setfield(L, -2, "position"); + RLUA_PUSH_Vector3(L, result.target); // Camera target it looks-at + lua_setfield(L, -2, "target"); + RLUA_PUSH_Vector3(L, result.up); // Camera up vector (rotation over its axis) + lua_setfield(L, -2, "up"); + lua_pushnumber(L, result.fovy); // Camera field-of-view aperture in Y (degrees) in perspective, used as near plane height in world units in orthographic + lua_setfield(L, -2, "fovy"); + lua_pushinteger(L, result.projection); // Camera projection: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC + lua_setfield(L, -2, "projection"); +} +static void RLUA_WRITEBACK_Camera3D(lua_State *L, int index, Camera3D val) +{ + if (lua_istable(L, index)) { + RLUA_PUSH_Vector3(L, val.position); // Camera position + lua_setfield(L, index, "position"); + RLUA_PUSH_Vector3(L, val.target); // Camera target it looks-at + lua_setfield(L, index, "target"); + RLUA_PUSH_Vector3(L, val.up); // Camera up vector (rotation over its axis) + lua_setfield(L, index, "up"); + lua_pushnumber(L, val.fovy); // Camera field-of-view aperture in Y (degrees) in perspective, used as near plane height in world units in orthographic + lua_setfield(L, index, "fovy"); + lua_pushinteger(L, val.projection); // Camera projection: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC + lua_setfield(L, index, "projection"); + } +} + + +// Camera2D, defines position/orientation in 2d space +static Camera2D RLUA_CHECK_Camera2D(lua_State *L, int index) +{ + Camera2D result = { 0 }; + if (lua_istable(L, index)) { + lua_getfield(L, index, "offset"); + result.offset = RLUA_CHECK_Vector2(L, -1); // Camera offset (screen space offset from window origin) + lua_pop(L, 1); + lua_getfield(L, index, "target"); + result.target = RLUA_CHECK_Vector2(L, -1); // Camera target (world space target point that is mapped to screen space offset) + lua_pop(L, 1); + lua_getfield(L, index, "rotation"); + result.rotation = (float)luaL_checknumber(L, -1); // Camera rotation in degrees (pivots around target) + lua_pop(L, 1); + lua_getfield(L, index, "zoom"); + result.zoom = (float)luaL_checknumber(L, -1); // Camera zoom (scaling around target), must not be set to 0, set to 1.0f for no scale + lua_pop(L, 1); + } + return result; +} +static void RLUA_PUSH_Camera2D(lua_State *L, Camera2D result) +{ + lua_createtable(L, 0, 4); + RLUA_PUSH_Vector2(L, result.offset); // Camera offset (screen space offset from window origin) + lua_setfield(L, -2, "offset"); + RLUA_PUSH_Vector2(L, result.target); // Camera target (world space target point that is mapped to screen space offset) + lua_setfield(L, -2, "target"); + lua_pushnumber(L, result.rotation); // Camera rotation in degrees (pivots around target) + lua_setfield(L, -2, "rotation"); + lua_pushnumber(L, result.zoom); // Camera zoom (scaling around target), must not be set to 0, set to 1.0f for no scale + lua_setfield(L, -2, "zoom"); +} + + +// MaterialMap +static MaterialMap RLUA_CHECK_MaterialMap(lua_State *L, int index) +{ + MaterialMap result = { 0 }; + if (lua_istable(L, index)) { + lua_getfield(L, index, "texture"); + result.texture = *(Texture2D*)RLUA_CHECK_Resource(L, -1, "Texture2D"); // Material map texture + lua_pop(L, 1); + lua_getfield(L, index, "color"); + result.color = RLUA_CHECK_Color(L, -1); // Material map color + lua_pop(L, 1); + lua_getfield(L, index, "value"); + result.value = (float)luaL_checknumber(L, -1); // Material map value + lua_pop(L, 1); + } + return result; +} +static void RLUA_PUSH_MaterialMap(lua_State *L, MaterialMap result) +{ + lua_createtable(L, 0, 3); + RLUA_PUSH_Resource(L, &result.texture, sizeof(Texture2D), "Texture2D"); // Material map texture + lua_setfield(L, -2, "texture"); + RLUA_PUSH_Color(L, result.color); // Material map color + lua_setfield(L, -2, "color"); + lua_pushnumber(L, result.value); // Material map value + lua_setfield(L, -2, "value"); +} + + +// Transform, vertex transformation data +static Transform RLUA_CHECK_Transform(lua_State *L, int index) +{ + Transform result = { 0 }; + if (lua_istable(L, index)) { + lua_getfield(L, index, "translation"); + result.translation = RLUA_CHECK_Vector3(L, -1); // Translation + lua_pop(L, 1); + lua_getfield(L, index, "rotation"); + result.rotation = RLUA_CHECK_Quaternion(L, -1); // Rotation + lua_pop(L, 1); + lua_getfield(L, index, "scale"); + result.scale = RLUA_CHECK_Vector3(L, -1); // Scale + lua_pop(L, 1); + } + return result; +} +static void RLUA_PUSH_Transform(lua_State *L, Transform result) +{ + lua_createtable(L, 0, 3); + RLUA_PUSH_Vector3(L, result.translation); // Translation + lua_setfield(L, -2, "translation"); + RLUA_PUSH_Quaternion(L, result.rotation); // Rotation + lua_setfield(L, -2, "rotation"); + RLUA_PUSH_Vector3(L, result.scale); // Scale + lua_setfield(L, -2, "scale"); +} + + +// Bone, skeletal animation bone +static BoneInfo RLUA_CHECK_BoneInfo(lua_State *L, int index) +{ + BoneInfo result = { 0 }; + if (lua_istable(L, index)) { + lua_getfield(L, index, "name"); + if (lua_isstring(L, -1)) { strncpy(result.name, lua_tostring(L, -1), 32 - 1); } // Bone name + lua_pop(L, 1); + lua_getfield(L, index, "parent"); + result.parent = (int)luaL_checkinteger(L, -1); // Bone parent + lua_pop(L, 1); + } + return result; +} +static void RLUA_PUSH_BoneInfo(lua_State *L, BoneInfo result) +{ + lua_createtable(L, 0, 2); + lua_pushstring(L, result.name); // Bone name + lua_setfield(L, -2, "name"); + lua_pushinteger(L, result.parent); // Bone parent + lua_setfield(L, -2, "parent"); +} + + +// Skeleton, animation bones hierarchy +static ModelSkeleton RLUA_CHECK_ModelSkeleton(lua_State *L, int index) +{ + ModelSkeleton result = { 0 }; + if (lua_istable(L, index)) { + lua_getfield(L, index, "boneCount"); + result.boneCount = (int)luaL_checkinteger(L, -1); // Number of bones + lua_pop(L, 1); + lua_getfield(L, index, "bones"); + result.bones = (BoneInfo *)lua_touserdata(L, -1); // Bones information (skeleton) + lua_pop(L, 1); + lua_getfield(L, index, "bindPose"); + result.bindPose = RLUA_CHECK_ModelAnimPose(L, -1); // Bones base transformation (Transform[]) + lua_pop(L, 1); + } + return result; +} +static void RLUA_PUSH_ModelSkeleton(lua_State *L, ModelSkeleton result) +{ + lua_createtable(L, 0, 3); + lua_pushinteger(L, result.boneCount); // Number of bones + lua_setfield(L, -2, "boneCount"); + lua_pushlightuserdata(L, result.bones); // Bones information (skeleton) + lua_setfield(L, -2, "bones"); + RLUA_PUSH_ModelAnimPose(L, result.bindPose); // Bones base transformation (Transform[]) + lua_setfield(L, -2, "bindPose"); +} + + +// Ray, ray for raycasting +static Ray RLUA_CHECK_Ray(lua_State *L, int index) +{ + Ray result = { 0 }; + if (lua_istable(L, index)) { + lua_getfield(L, index, "position"); + result.position = RLUA_CHECK_Vector3(L, -1); // Ray position (origin) + lua_pop(L, 1); + lua_getfield(L, index, "direction"); + result.direction = RLUA_CHECK_Vector3(L, -1); // Ray direction (normalized) + lua_pop(L, 1); + } + return result; +} +static void RLUA_PUSH_Ray(lua_State *L, Ray result) +{ + lua_createtable(L, 0, 2); + RLUA_PUSH_Vector3(L, result.position); // Ray position (origin) + lua_setfield(L, -2, "position"); + RLUA_PUSH_Vector3(L, result.direction); // Ray direction (normalized) + lua_setfield(L, -2, "direction"); +} + + +// RayCollision, ray hit information +static RayCollision RLUA_CHECK_RayCollision(lua_State *L, int index) +{ + RayCollision result = { 0 }; + if (lua_istable(L, index)) { + lua_getfield(L, index, "hit"); + result.hit = lua_toboolean(L, -1); // Did the ray hit something? + lua_pop(L, 1); + lua_getfield(L, index, "distance"); + result.distance = (float)luaL_checknumber(L, -1); // Distance to the nearest hit + lua_pop(L, 1); + lua_getfield(L, index, "point"); + result.point = RLUA_CHECK_Vector3(L, -1); // Point of the nearest hit + lua_pop(L, 1); + lua_getfield(L, index, "normal"); + result.normal = RLUA_CHECK_Vector3(L, -1); // Surface normal of hit + lua_pop(L, 1); + } + return result; +} +static void RLUA_PUSH_RayCollision(lua_State *L, RayCollision result) +{ + lua_createtable(L, 0, 4); + lua_pushboolean(L, result.hit); // Did the ray hit something? + lua_setfield(L, -2, "hit"); + lua_pushnumber(L, result.distance); // Distance to the nearest hit + lua_setfield(L, -2, "distance"); + RLUA_PUSH_Vector3(L, result.point); // Point of the nearest hit + lua_setfield(L, -2, "point"); + RLUA_PUSH_Vector3(L, result.normal); // Surface normal of hit + lua_setfield(L, -2, "normal"); +} + + +// BoundingBox +static BoundingBox RLUA_CHECK_BoundingBox(lua_State *L, int index) +{ + BoundingBox result = { 0 }; + if (lua_istable(L, index)) { + lua_getfield(L, index, "min"); + result.min = RLUA_CHECK_Vector3(L, -1); // Minimum vertex box-corner + lua_pop(L, 1); + lua_getfield(L, index, "max"); + result.max = RLUA_CHECK_Vector3(L, -1); // Maximum vertex box-corner + lua_pop(L, 1); + } + return result; +} +static void RLUA_PUSH_BoundingBox(lua_State *L, BoundingBox result) +{ + lua_createtable(L, 0, 2); + RLUA_PUSH_Vector3(L, result.min); // Minimum vertex box-corner + lua_setfield(L, -2, "min"); + RLUA_PUSH_Vector3(L, result.max); // Maximum vertex box-corner + lua_setfield(L, -2, "max"); +} + + +// VrDeviceInfo, Head-Mounted-Display device parameters +static VrDeviceInfo RLUA_CHECK_VrDeviceInfo(lua_State *L, int index) +{ + VrDeviceInfo result = { 0 }; + if (lua_istable(L, index)) { + lua_getfield(L, index, "hResolution"); + result.hResolution = (int)luaL_checkinteger(L, -1); // Horizontal resolution in pixels + lua_pop(L, 1); + lua_getfield(L, index, "vResolution"); + result.vResolution = (int)luaL_checkinteger(L, -1); // Vertical resolution in pixels + lua_pop(L, 1); + lua_getfield(L, index, "hScreenSize"); + result.hScreenSize = (float)luaL_checknumber(L, -1); // Horizontal size in meters + lua_pop(L, 1); + lua_getfield(L, index, "vScreenSize"); + result.vScreenSize = (float)luaL_checknumber(L, -1); // Vertical size in meters + lua_pop(L, 1); + lua_getfield(L, index, "eyeToScreenDistance"); + result.eyeToScreenDistance = (float)luaL_checknumber(L, -1); // Distance between eye and display in meters + lua_pop(L, 1); + lua_getfield(L, index, "lensSeparationDistance"); + result.lensSeparationDistance = (float)luaL_checknumber(L, -1); // Lens separation distance in meters + lua_pop(L, 1); + lua_getfield(L, index, "interpupillaryDistance"); + result.interpupillaryDistance = (float)luaL_checknumber(L, -1); // IPD (distance between pupils) in meters + lua_pop(L, 1); + lua_getfield(L, index, "lensDistortionValues"); + if (lua_istable(L, -1)) { + for (int i = 0; i < 4; i++) { + lua_geti(L, -1, i + 1); + result.lensDistortionValues[i] = (float)luaL_checknumber(L, -1); + lua_pop(L, 1); + } + } + lua_pop(L, 1); + lua_getfield(L, index, "chromaAbCorrection"); + if (lua_istable(L, -1)) { + for (int i = 0; i < 4; i++) { + lua_geti(L, -1, i + 1); + result.chromaAbCorrection[i] = (float)luaL_checknumber(L, -1); + lua_pop(L, 1); + } + } + lua_pop(L, 1); + } + return result; +} +static void RLUA_PUSH_VrDeviceInfo(lua_State *L, VrDeviceInfo result) +{ + lua_createtable(L, 0, 9); + lua_pushinteger(L, result.hResolution); // Horizontal resolution in pixels + lua_setfield(L, -2, "hResolution"); + lua_pushinteger(L, result.vResolution); // Vertical resolution in pixels + lua_setfield(L, -2, "vResolution"); + lua_pushnumber(L, result.hScreenSize); // Horizontal size in meters + lua_setfield(L, -2, "hScreenSize"); + lua_pushnumber(L, result.vScreenSize); // Vertical size in meters + lua_setfield(L, -2, "vScreenSize"); + lua_pushnumber(L, result.eyeToScreenDistance); // Distance between eye and display in meters + lua_setfield(L, -2, "eyeToScreenDistance"); + lua_pushnumber(L, result.lensSeparationDistance); // Lens separation distance in meters + lua_setfield(L, -2, "lensSeparationDistance"); + lua_pushnumber(L, result.interpupillaryDistance); // IPD (distance between pupils) in meters + lua_setfield(L, -2, "interpupillaryDistance"); + lua_createtable(L, 4, 0); + for (int i = 0; i < 4; i++) { + lua_pushnumber(L, result.lensDistortionValues[i]); + lua_seti(L, -2, i + 1); + } + lua_setfield(L, -2, "lensDistortionValues"); + lua_createtable(L, 4, 0); + for (int i = 0; i < 4; i++) { + lua_pushnumber(L, result.chromaAbCorrection[i]); + lua_seti(L, -2, i + 1); + } + lua_setfield(L, -2, "chromaAbCorrection"); +} + + +// VrStereoConfig, VR stereo rendering configuration for simulator +static VrStereoConfig RLUA_CHECK_VrStereoConfig(lua_State *L, int index) +{ + VrStereoConfig result = { 0 }; + if (lua_istable(L, index)) { + lua_getfield(L, index, "projection"); + if (lua_istable(L, -1)) { + for (int i = 0; i < 2; i++) { + lua_geti(L, -1, i + 1); + result.projection[i] = RLUA_CHECK_Matrix(L, -1); + lua_pop(L, 1); + } + } + lua_pop(L, 1); + lua_getfield(L, index, "viewOffset"); + if (lua_istable(L, -1)) { + for (int i = 0; i < 2; i++) { + lua_geti(L, -1, i + 1); + result.viewOffset[i] = RLUA_CHECK_Matrix(L, -1); + lua_pop(L, 1); + } + } + lua_pop(L, 1); + lua_getfield(L, index, "leftLensCenter"); + if (lua_istable(L, -1)) { + for (int i = 0; i < 2; i++) { + lua_geti(L, -1, i + 1); + result.leftLensCenter[i] = (float)luaL_checknumber(L, -1); + lua_pop(L, 1); + } + } + lua_pop(L, 1); + lua_getfield(L, index, "rightLensCenter"); + if (lua_istable(L, -1)) { + for (int i = 0; i < 2; i++) { + lua_geti(L, -1, i + 1); + result.rightLensCenter[i] = (float)luaL_checknumber(L, -1); + lua_pop(L, 1); + } + } + lua_pop(L, 1); + lua_getfield(L, index, "leftScreenCenter"); + if (lua_istable(L, -1)) { + for (int i = 0; i < 2; i++) { + lua_geti(L, -1, i + 1); + result.leftScreenCenter[i] = (float)luaL_checknumber(L, -1); + lua_pop(L, 1); + } + } + lua_pop(L, 1); + lua_getfield(L, index, "rightScreenCenter"); + if (lua_istable(L, -1)) { + for (int i = 0; i < 2; i++) { + lua_geti(L, -1, i + 1); + result.rightScreenCenter[i] = (float)luaL_checknumber(L, -1); + lua_pop(L, 1); + } + } + lua_pop(L, 1); + lua_getfield(L, index, "scale"); + if (lua_istable(L, -1)) { + for (int i = 0; i < 2; i++) { + lua_geti(L, -1, i + 1); + result.scale[i] = (float)luaL_checknumber(L, -1); + lua_pop(L, 1); + } + } + lua_pop(L, 1); + lua_getfield(L, index, "scaleIn"); + if (lua_istable(L, -1)) { + for (int i = 0; i < 2; i++) { + lua_geti(L, -1, i + 1); + result.scaleIn[i] = (float)luaL_checknumber(L, -1); + lua_pop(L, 1); + } + } + lua_pop(L, 1); + } + return result; +} +static void RLUA_PUSH_VrStereoConfig(lua_State *L, VrStereoConfig result) +{ + lua_createtable(L, 0, 8); + lua_createtable(L, 2, 0); + for (int i = 0; i < 2; i++) { + RLUA_PUSH_Matrix(L, result.projection[i]); + lua_seti(L, -2, i + 1); + } + lua_setfield(L, -2, "projection"); + lua_createtable(L, 2, 0); + for (int i = 0; i < 2; i++) { + RLUA_PUSH_Matrix(L, result.viewOffset[i]); + lua_seti(L, -2, i + 1); + } + lua_setfield(L, -2, "viewOffset"); + lua_createtable(L, 2, 0); + for (int i = 0; i < 2; i++) { + lua_pushnumber(L, result.leftLensCenter[i]); + lua_seti(L, -2, i + 1); + } + lua_setfield(L, -2, "leftLensCenter"); + lua_createtable(L, 2, 0); + for (int i = 0; i < 2; i++) { + lua_pushnumber(L, result.rightLensCenter[i]); + lua_seti(L, -2, i + 1); + } + lua_setfield(L, -2, "rightLensCenter"); + lua_createtable(L, 2, 0); + for (int i = 0; i < 2; i++) { + lua_pushnumber(L, result.leftScreenCenter[i]); + lua_seti(L, -2, i + 1); + } + lua_setfield(L, -2, "leftScreenCenter"); + lua_createtable(L, 2, 0); + for (int i = 0; i < 2; i++) { + lua_pushnumber(L, result.rightScreenCenter[i]); + lua_seti(L, -2, i + 1); + } + lua_setfield(L, -2, "rightScreenCenter"); + lua_createtable(L, 2, 0); + for (int i = 0; i < 2; i++) { + lua_pushnumber(L, result.scale[i]); + lua_seti(L, -2, i + 1); + } + lua_setfield(L, -2, "scale"); + lua_createtable(L, 2, 0); + for (int i = 0; i < 2; i++) { + lua_pushnumber(L, result.scaleIn[i]); + lua_seti(L, -2, i + 1); + } + lua_setfield(L, -2, "scaleIn"); +} + + +// File path list +static FilePathList RLUA_CHECK_FilePathList(lua_State *L, int index) +{ + FilePathList result = { 0 }; + if (lua_istable(L, index)) { + lua_getfield(L, index, "count"); + result.count = (unsigned int)luaL_checkinteger(L, -1); // Filepaths entries count + lua_pop(L, 1); + lua_getfield(L, index, "paths"); + result.paths = (char **)lua_touserdata(L, -1); // Filepaths entries + lua_pop(L, 1); + } + return result; +} +static void RLUA_PUSH_FilePathList(lua_State *L, FilePathList result) +{ + lua_createtable(L, 0, 2); + lua_pushinteger(L, result.count); // Filepaths entries count + lua_setfield(L, -2, "count"); + lua_pushlightuserdata(L, result.paths); // Filepaths entries + lua_setfield(L, -2, "paths"); +} + + +// Automation event +static AutomationEvent RLUA_CHECK_AutomationEvent(lua_State *L, int index) +{ + AutomationEvent result = { 0 }; + if (lua_istable(L, index)) { + lua_getfield(L, index, "frame"); + result.frame = (unsigned int)luaL_checkinteger(L, -1); // Event frame + lua_pop(L, 1); + lua_getfield(L, index, "type"); + result.type = (unsigned int)luaL_checkinteger(L, -1); // Event type (AutomationEventType) + lua_pop(L, 1); + lua_getfield(L, index, "params"); + if (lua_istable(L, -1)) { + for (int i = 0; i < 4; i++) { + lua_geti(L, -1, i + 1); + result.params[i] = (int)luaL_checkinteger(L, -1); + lua_pop(L, 1); + } + } + lua_pop(L, 1); + } + return result; +} +static void RLUA_PUSH_AutomationEvent(lua_State *L, AutomationEvent result) +{ + lua_createtable(L, 0, 3); + lua_pushinteger(L, result.frame); // Event frame + lua_setfield(L, -2, "frame"); + lua_pushinteger(L, result.type); // Event type (AutomationEventType) + lua_setfield(L, -2, "type"); + lua_createtable(L, 4, 0); + for (int i = 0; i < 4; i++) { + lua_pushinteger(L, result.params[i]); + lua_seti(L, -2, i + 1); + } + lua_setfield(L, -2, "params"); +} + + +// Automation event list +static AutomationEventList RLUA_CHECK_AutomationEventList(lua_State *L, int index) +{ + AutomationEventList result = { 0 }; + if (lua_istable(L, index)) { + lua_getfield(L, index, "capacity"); + result.capacity = (unsigned int)luaL_checkinteger(L, -1); // Events max entries (MAX_AUTOMATION_EVENTS) + lua_pop(L, 1); + lua_getfield(L, index, "count"); + result.count = (unsigned int)luaL_checkinteger(L, -1); // Events entries count + lua_pop(L, 1); + lua_getfield(L, index, "events"); + result.events = (AutomationEvent *)lua_touserdata(L, -1); // Events entries + lua_pop(L, 1); + } + return result; +} +static void RLUA_PUSH_AutomationEventList(lua_State *L, AutomationEventList result) +{ + lua_createtable(L, 0, 3); + lua_pushinteger(L, result.capacity); // Events max entries (MAX_AUTOMATION_EVENTS) + lua_setfield(L, -2, "capacity"); + lua_pushinteger(L, result.count); // Events entries count + lua_setfield(L, -2, "count"); + lua_pushlightuserdata(L, result.events); // Events entries + lua_setfield(L, -2, "events"); +} +static void RLUA_WRITEBACK_AutomationEventList(lua_State *L, int index, AutomationEventList val) +{ + if (lua_istable(L, index)) { + lua_pushinteger(L, val.capacity); // Events max entries (MAX_AUTOMATION_EVENTS) + lua_setfield(L, index, "capacity"); + lua_pushinteger(L, val.count); // Events entries count + lua_setfield(L, index, "count"); + } +} + + +// --- Resource Destructors (__gc) --- + +static int rl_AudioStream_gc(lua_State *L) +{ + RLUA_Handle *h = (RLUA_Handle *)luaL_checkudata(L, 1, "AudioStream"); + if (h->data && h->owned) { + UnloadAudioStream(*(AudioStream*)h->data); + RL_FREE(h->data); + } + return 0; +} + +static int rl_Font_gc(lua_State *L) +{ + RLUA_Handle *h = (RLUA_Handle *)luaL_checkudata(L, 1, "Font"); + if (h->data && h->owned) { + UnloadFont(*(Font*)h->data); + RL_FREE(h->data); + } + return 0; +} + +static int rl_Image_gc(lua_State *L) +{ + RLUA_Handle *h = (RLUA_Handle *)luaL_checkudata(L, 1, "Image"); + if (h->data && h->owned) { + UnloadImage(*(Image*)h->data); + RL_FREE(h->data); + } + return 0; +} + +static int rl_Material_gc(lua_State *L) +{ + RLUA_Handle *h = (RLUA_Handle *)luaL_checkudata(L, 1, "Material"); + if (h->data && h->owned) { + UnloadMaterial(*(Material*)h->data); + RL_FREE(h->data); + } + return 0; +} + +static int rl_Mesh_gc(lua_State *L) +{ + RLUA_Handle *h = (RLUA_Handle *)luaL_checkudata(L, 1, "Mesh"); + if (h->data && h->owned) { + UnloadMesh(*(Mesh*)h->data); + RL_FREE(h->data); + } + return 0; +} + +static int rl_Model_gc(lua_State *L) +{ + RLUA_Handle *h = (RLUA_Handle *)luaL_checkudata(L, 1, "Model"); + if (h->data && h->owned) { + UnloadModel(*(Model*)h->data); + RL_FREE(h->data); + } + return 0; +} + +static int rl_Music_gc(lua_State *L) +{ + RLUA_Handle *h = (RLUA_Handle *)luaL_checkudata(L, 1, "Music"); + if (h->data && h->owned) { + UnloadMusicStream(*(Music*)h->data); + RL_FREE(h->data); + } + return 0; +} + +static int rl_RenderTexture_gc(lua_State *L) +{ + RLUA_Handle *h = (RLUA_Handle *)luaL_checkudata(L, 1, "RenderTexture"); + if (h->data && h->owned) { + UnloadRenderTexture(*(RenderTexture*)h->data); + RL_FREE(h->data); + } + return 0; +} + +static int rl_RenderTexture2D_gc(lua_State *L) +{ + RLUA_Handle *h = (RLUA_Handle *)luaL_checkudata(L, 1, "RenderTexture2D"); + if (h->data && h->owned) { + UnloadRenderTexture(*(RenderTexture2D*)h->data); + RL_FREE(h->data); + } + return 0; +} + +static int rl_Shader_gc(lua_State *L) +{ + RLUA_Handle *h = (RLUA_Handle *)luaL_checkudata(L, 1, "Shader"); + if (h->data && h->owned) { + UnloadShader(*(Shader*)h->data); + RL_FREE(h->data); + } + return 0; +} + +static int rl_Sound_gc(lua_State *L) +{ + RLUA_Handle *h = (RLUA_Handle *)luaL_checkudata(L, 1, "Sound"); + if (h->data && h->owned) { + UnloadSound(*(Sound*)h->data); + RL_FREE(h->data); + } + return 0; +} + +static int rl_Texture_gc(lua_State *L) +{ + RLUA_Handle *h = (RLUA_Handle *)luaL_checkudata(L, 1, "Texture"); + if (h->data && h->owned) { + UnloadTexture(*(Texture*)h->data); + RL_FREE(h->data); + } + return 0; +} + +static int rl_Texture2D_gc(lua_State *L) +{ + RLUA_Handle *h = (RLUA_Handle *)luaL_checkudata(L, 1, "Texture2D"); + if (h->data && h->owned) { + UnloadTexture(*(Texture2D*)h->data); + RL_FREE(h->data); + } + return 0; +} + +static int rl_TextureCubemap_gc(lua_State *L) +{ + RLUA_Handle *h = (RLUA_Handle *)luaL_checkudata(L, 1, "TextureCubemap"); + if (h->data && h->owned) { + UnloadTexture(*(TextureCubemap*)h->data); + RL_FREE(h->data); + } + return 0; +} + +static int rl_Wave_gc(lua_State *L) +{ + RLUA_Handle *h = (RLUA_Handle *)luaL_checkudata(L, 1, "Wave"); + if (h->data && h->owned) { + UnloadWave(*(Wave*)h->data); + RL_FREE(h->data); + } + return 0; +} + +// --- Resource Indexers (__index) --- + +static int rl_AudioStream_index(lua_State *L) +{ + RLUA_Handle *h = (RLUA_Handle *)luaL_checkudata(L, 1, "AudioStream"); + if (lua_isnumber(L, 2)) { + int i = lua_tointeger(L, 2) - 1; + if (i < 0 || i >= h->count) return luaL_error(L, "index out of bounds"); + AudioStream *ptr = &((AudioStream *)h->data)[i]; + RLUA_PUSH_View(L, ptr, 1, "AudioStream", false); + return 1; + } + const char *key = luaL_checkstring(L, 2); + AudioStream *data = (AudioStream *)h->data; + if (strcmp(key, "buffer") == 0) { // Pointer to internal data used by the audio system + lua_pushlightuserdata(L, data->buffer); + return 1; + } + if (strcmp(key, "processor") == 0) { // Pointer to internal data processor, useful for audio effects + lua_pushlightuserdata(L, data->processor); + return 1; + } + if (strcmp(key, "sampleRate") == 0) { // Frequency (samples per second) + lua_pushinteger(L, data->sampleRate); + return 1; + } + if (strcmp(key, "sampleSize") == 0) { // Bit depth (bits per sample): 8, 16, 32 (24 not supported) + lua_pushinteger(L, data->sampleSize); + return 1; + } + if (strcmp(key, "channels") == 0) { // Number of channels (1-mono, 2-stereo, ...) + lua_pushinteger(L, data->channels); + return 1; + } + return 0; +} + +static int rl_Font_index(lua_State *L) +{ + RLUA_Handle *h = (RLUA_Handle *)luaL_checkudata(L, 1, "Font"); + if (lua_isnumber(L, 2)) { + int i = lua_tointeger(L, 2) - 1; + if (i < 0 || i >= h->count) return luaL_error(L, "index out of bounds"); + Font *ptr = &((Font *)h->data)[i]; + RLUA_PUSH_View(L, ptr, 1, "Font", false); + return 1; + } + const char *key = luaL_checkstring(L, 2); + Font *data = (Font *)h->data; + if (strcmp(key, "baseSize") == 0) { // Base size (default chars height) + lua_pushinteger(L, data->baseSize); + return 1; + } + if (strcmp(key, "glyphCount") == 0) { // Number of glyph characters + lua_pushinteger(L, data->glyphCount); + return 1; + } + if (strcmp(key, "glyphPadding") == 0) { // Padding around the glyph characters + lua_pushinteger(L, data->glyphPadding); + return 1; + } + if (strcmp(key, "texture") == 0) { // Texture atlas containing the glyphs + RLUA_PUSH_View(L, &data->texture, 1, "Texture2D", false); + return 1; + } + if (strcmp(key, "recs") == 0) { // Rectangles in texture for the glyphs + lua_pushlightuserdata(L, data->recs); + return 1; + } + if (strcmp(key, "glyphs") == 0) { // Glyphs info data + lua_pushlightuserdata(L, data->glyphs); + return 1; + } + return 0; +} + +static int rl_Image_index(lua_State *L) +{ + RLUA_Handle *h = (RLUA_Handle *)luaL_checkudata(L, 1, "Image"); + if (lua_isnumber(L, 2)) { + int i = lua_tointeger(L, 2) - 1; + if (i < 0 || i >= h->count) return luaL_error(L, "index out of bounds"); + Image *ptr = &((Image *)h->data)[i]; + RLUA_PUSH_View(L, ptr, 1, "Image", false); + return 1; + } + const char *key = luaL_checkstring(L, 2); + Image *data = (Image *)h->data; + if (strcmp(key, "data") == 0) { // Image raw data + lua_pushlightuserdata(L, data->data); + return 1; + } + if (strcmp(key, "width") == 0) { // Image base width + lua_pushinteger(L, data->width); + return 1; + } + if (strcmp(key, "height") == 0) { // Image base height + lua_pushinteger(L, data->height); + return 1; + } + if (strcmp(key, "mipmaps") == 0) { // Mipmap levels, 1 by default + lua_pushinteger(L, data->mipmaps); + return 1; + } + if (strcmp(key, "format") == 0) { // Data format (PixelFormat type) + lua_pushinteger(L, data->format); + return 1; + } + return 0; +} + +static int rl_Material_index(lua_State *L) +{ + RLUA_Handle *h = (RLUA_Handle *)luaL_checkudata(L, 1, "Material"); + if (lua_isnumber(L, 2)) { + int i = lua_tointeger(L, 2) - 1; + if (i < 0 || i >= h->count) return luaL_error(L, "index out of bounds"); + Material *ptr = &((Material *)h->data)[i]; + RLUA_PUSH_View(L, ptr, 1, "Material", false); + return 1; + } + const char *key = luaL_checkstring(L, 2); + Material *data = (Material *)h->data; + if (strcmp(key, "shader") == 0) { // Material shader + RLUA_PUSH_View(L, &data->shader, 1, "Shader", false); + return 1; + } + if (strcmp(key, "maps") == 0) { // Material maps array (MAX_MATERIAL_MAPS) + lua_pushlightuserdata(L, data->maps); + return 1; + } + return 0; +} + +static int rl_Mesh_index(lua_State *L) +{ + RLUA_Handle *h = (RLUA_Handle *)luaL_checkudata(L, 1, "Mesh"); + if (lua_isnumber(L, 2)) { + int i = lua_tointeger(L, 2) - 1; + if (i < 0 || i >= h->count) return luaL_error(L, "index out of bounds"); + Mesh *ptr = &((Mesh *)h->data)[i]; + RLUA_PUSH_View(L, ptr, 1, "Mesh", false); + return 1; + } + const char *key = luaL_checkstring(L, 2); + Mesh *data = (Mesh *)h->data; + if (strcmp(key, "vertexCount") == 0) { // Number of vertices stored in arrays + lua_pushinteger(L, data->vertexCount); + return 1; + } + if (strcmp(key, "triangleCount") == 0) { // Number of triangles stored (indexed or not) + lua_pushinteger(L, data->triangleCount); + return 1; + } + if (strcmp(key, "vertices") == 0) { // Vertex position (XYZ - 3 components per vertex) (shader-location = 0) + lua_pushlightuserdata(L, data->vertices); + return 1; + } + if (strcmp(key, "texcoords") == 0) { // Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1) + lua_pushlightuserdata(L, data->texcoords); + return 1; + } + if (strcmp(key, "texcoords2") == 0) { // Vertex texture second coordinates (UV - 2 components per vertex) (shader-location = 5) + lua_pushlightuserdata(L, data->texcoords2); + return 1; + } + if (strcmp(key, "normals") == 0) { // Vertex normals (XYZ - 3 components per vertex) (shader-location = 2) + lua_pushlightuserdata(L, data->normals); + return 1; + } + if (strcmp(key, "tangents") == 0) { // Vertex tangents (XYZW - 4 components per vertex) (shader-location = 4) + lua_pushlightuserdata(L, data->tangents); + return 1; + } + if (strcmp(key, "colors") == 0) { // Vertex colors (RGBA - 4 components per vertex) (shader-location = 3) + lua_pushlightuserdata(L, data->colors); + return 1; + } + if (strcmp(key, "indices") == 0) { // Vertex indices (in case vertex data comes indexed) + lua_pushlightuserdata(L, data->indices); + return 1; + } + if (strcmp(key, "boneCount") == 0) { // Number of bones (MAX: 256 bones) + lua_pushinteger(L, data->boneCount); + return 1; + } + if (strcmp(key, "boneIndices") == 0) { // Vertex bone indices, up to 4 bones influence by vertex (skinning) (shader-location = 6) + lua_pushlightuserdata(L, data->boneIndices); + return 1; + } + if (strcmp(key, "boneWeights") == 0) { // Vertex bone weight, up to 4 bones influence by vertex (skinning) (shader-location = 7) + lua_pushlightuserdata(L, data->boneWeights); + return 1; + } + if (strcmp(key, "animVertices") == 0) { // Animated vertex positions (after bones transformations) + lua_pushlightuserdata(L, data->animVertices); + return 1; + } + if (strcmp(key, "animNormals") == 0) { // Animated normals (after bones transformations) + lua_pushlightuserdata(L, data->animNormals); + return 1; + } + if (strcmp(key, "vaoId") == 0) { // OpenGL Vertex Array Object id + lua_pushinteger(L, data->vaoId); + return 1; + } + if (strcmp(key, "vboId") == 0) { // OpenGL Vertex Buffer Objects id (default vertex data) + lua_pushlightuserdata(L, data->vboId); + return 1; + } + return 0; +} + +static int rl_Model_index(lua_State *L) +{ + RLUA_Handle *h = (RLUA_Handle *)luaL_checkudata(L, 1, "Model"); + if (lua_isnumber(L, 2)) { + int i = lua_tointeger(L, 2) - 1; + if (i < 0 || i >= h->count) return luaL_error(L, "index out of bounds"); + Model *ptr = &((Model *)h->data)[i]; + RLUA_PUSH_View(L, ptr, 1, "Model", false); + return 1; + } + const char *key = luaL_checkstring(L, 2); + Model *data = (Model *)h->data; + if (strcmp(key, "transform") == 0) { // Local transform matrix + RLUA_PUSH_Matrix(L, data->transform); + return 1; + } + if (strcmp(key, "meshCount") == 0) { // Number of meshes + lua_pushinteger(L, data->meshCount); + return 1; + } + if (strcmp(key, "materialCount") == 0) { // Number of materials + lua_pushinteger(L, data->materialCount); + return 1; + } + if (strcmp(key, "meshes") == 0) { // Meshes array + lua_pushlightuserdata(L, data->meshes); + return 1; + } + if (strcmp(key, "materials") == 0) { // Materials array + lua_pushlightuserdata(L, data->materials); + return 1; + } + if (strcmp(key, "meshMaterial") == 0) { // Mesh material number + lua_pushlightuserdata(L, data->meshMaterial); + return 1; + } + if (strcmp(key, "skeleton") == 0) { // Skeleton for animation + RLUA_PUSH_ModelSkeleton(L, data->skeleton); + return 1; + } + if (strcmp(key, "currentPose") == 0) { // Current animation pose (Transform[]) + RLUA_PUSH_ModelAnimPose(L, data->currentPose); + return 1; + } + if (strcmp(key, "boneMatrices") == 0) { // Bones animated transformation matrices + lua_pushlightuserdata(L, data->boneMatrices); + return 1; + } + return 0; +} + +static int rl_ModelAnimation_index(lua_State *L) +{ + RLUA_Handle *h = (RLUA_Handle *)luaL_checkudata(L, 1, "ModelAnimation"); + if (lua_isnumber(L, 2)) { + int i = lua_tointeger(L, 2) - 1; + if (i < 0 || i >= h->count) return luaL_error(L, "index out of bounds"); + ModelAnimation *ptr = &((ModelAnimation *)h->data)[i]; + RLUA_PUSH_View(L, ptr, 1, "ModelAnimation", false); + return 1; + } + const char *key = luaL_checkstring(L, 2); + ModelAnimation *data = (ModelAnimation *)h->data; + if (strcmp(key, "boneCount") == 0) { // Number of bones (per pose) + lua_pushinteger(L, data->boneCount); + return 1; + } + if (strcmp(key, "keyframeCount") == 0) { // Number of animation key frames + lua_pushinteger(L, data->keyframeCount); + return 1; + } + if (strcmp(key, "keyframePoses") == 0) { // Animation sequence keyframe poses [keyframe][pose] + lua_pushlightuserdata(L, data->keyframePoses); + return 1; + } + return 0; +} + +static int rl_Music_index(lua_State *L) +{ + RLUA_Handle *h = (RLUA_Handle *)luaL_checkudata(L, 1, "Music"); + if (lua_isnumber(L, 2)) { + int i = lua_tointeger(L, 2) - 1; + if (i < 0 || i >= h->count) return luaL_error(L, "index out of bounds"); + Music *ptr = &((Music *)h->data)[i]; + RLUA_PUSH_View(L, ptr, 1, "Music", false); + return 1; + } + const char *key = luaL_checkstring(L, 2); + Music *data = (Music *)h->data; + if (strcmp(key, "stream") == 0) { // Audio stream + RLUA_PUSH_View(L, &data->stream, 1, "AudioStream", false); + return 1; + } + if (strcmp(key, "frameCount") == 0) { // Total number of frames (considering channels) + lua_pushinteger(L, data->frameCount); + return 1; + } + if (strcmp(key, "looping") == 0) { // Music looping enable + lua_pushboolean(L, data->looping); + return 1; + } + if (strcmp(key, "ctxType") == 0) { // Type of music context (audio filetype) + lua_pushinteger(L, data->ctxType); + return 1; + } + if (strcmp(key, "ctxData") == 0) { // Audio context data, depends on type + lua_pushlightuserdata(L, data->ctxData); + return 1; + } + return 0; +} + +static int rl_RenderTexture_index(lua_State *L) +{ + RLUA_Handle *h = (RLUA_Handle *)luaL_checkudata(L, 1, "RenderTexture"); + if (lua_isnumber(L, 2)) { + int i = lua_tointeger(L, 2) - 1; + if (i < 0 || i >= h->count) return luaL_error(L, "index out of bounds"); + RenderTexture *ptr = &((RenderTexture *)h->data)[i]; + RLUA_PUSH_View(L, ptr, 1, "RenderTexture", false); + return 1; + } + const char *key = luaL_checkstring(L, 2); + RenderTexture *data = (RenderTexture *)h->data; + if (strcmp(key, "id") == 0) { // OpenGL framebuffer object id + lua_pushinteger(L, data->id); + return 1; + } + if (strcmp(key, "texture") == 0) { // Color buffer attachment texture + RLUA_PUSH_View(L, &data->texture, 1, "Texture", false); + return 1; + } + if (strcmp(key, "depth") == 0) { // Depth buffer attachment texture + RLUA_PUSH_View(L, &data->depth, 1, "Texture", false); + return 1; + } + return 0; +} + +static int rl_Shader_index(lua_State *L) +{ + RLUA_Handle *h = (RLUA_Handle *)luaL_checkudata(L, 1, "Shader"); + if (lua_isnumber(L, 2)) { + int i = lua_tointeger(L, 2) - 1; + if (i < 0 || i >= h->count) return luaL_error(L, "index out of bounds"); + Shader *ptr = &((Shader *)h->data)[i]; + RLUA_PUSH_View(L, ptr, 1, "Shader", false); + return 1; + } + const char *key = luaL_checkstring(L, 2); + Shader *data = (Shader *)h->data; + if (strcmp(key, "id") == 0) { // Shader program id + lua_pushinteger(L, data->id); + return 1; + } + if (strcmp(key, "locs") == 0) { // Shader locations array (RL_MAX_SHADER_LOCATIONS) + lua_pushlightuserdata(L, data->locs); + return 1; + } + return 0; +} + +static int rl_Sound_index(lua_State *L) +{ + RLUA_Handle *h = (RLUA_Handle *)luaL_checkudata(L, 1, "Sound"); + if (lua_isnumber(L, 2)) { + int i = lua_tointeger(L, 2) - 1; + if (i < 0 || i >= h->count) return luaL_error(L, "index out of bounds"); + Sound *ptr = &((Sound *)h->data)[i]; + RLUA_PUSH_View(L, ptr, 1, "Sound", false); + return 1; + } + const char *key = luaL_checkstring(L, 2); + Sound *data = (Sound *)h->data; + if (strcmp(key, "stream") == 0) { // Audio stream + RLUA_PUSH_View(L, &data->stream, 1, "AudioStream", false); + return 1; + } + if (strcmp(key, "frameCount") == 0) { // Total number of frames (considering channels) + lua_pushinteger(L, data->frameCount); + return 1; + } + return 0; +} + +static int rl_Texture_index(lua_State *L) +{ + RLUA_Handle *h = (RLUA_Handle *)luaL_checkudata(L, 1, "Texture"); + if (lua_isnumber(L, 2)) { + int i = lua_tointeger(L, 2) - 1; + if (i < 0 || i >= h->count) return luaL_error(L, "index out of bounds"); + Texture *ptr = &((Texture *)h->data)[i]; + RLUA_PUSH_View(L, ptr, 1, "Texture", false); + return 1; + } + const char *key = luaL_checkstring(L, 2); + Texture *data = (Texture *)h->data; + if (strcmp(key, "id") == 0) { // OpenGL texture id + lua_pushinteger(L, data->id); + return 1; + } + if (strcmp(key, "width") == 0) { // Texture base width + lua_pushinteger(L, data->width); + return 1; + } + if (strcmp(key, "height") == 0) { // Texture base height + lua_pushinteger(L, data->height); + return 1; + } + if (strcmp(key, "mipmaps") == 0) { // Mipmap levels, 1 by default + lua_pushinteger(L, data->mipmaps); + return 1; + } + if (strcmp(key, "format") == 0) { // Data format (PixelFormat type) + lua_pushinteger(L, data->format); + return 1; + } + return 0; +} + +static int rl_Wave_index(lua_State *L) +{ + RLUA_Handle *h = (RLUA_Handle *)luaL_checkudata(L, 1, "Wave"); + if (lua_isnumber(L, 2)) { + int i = lua_tointeger(L, 2) - 1; + if (i < 0 || i >= h->count) return luaL_error(L, "index out of bounds"); + Wave *ptr = &((Wave *)h->data)[i]; + RLUA_PUSH_View(L, ptr, 1, "Wave", false); + return 1; + } + const char *key = luaL_checkstring(L, 2); + Wave *data = (Wave *)h->data; + if (strcmp(key, "frameCount") == 0) { // Total number of frames (considering channels) + lua_pushinteger(L, data->frameCount); + return 1; + } + if (strcmp(key, "sampleRate") == 0) { // Frequency (samples per second) + lua_pushinteger(L, data->sampleRate); + return 1; + } + if (strcmp(key, "sampleSize") == 0) { // Bit depth (bits per sample): 8, 16, 32 (24 not supported) + lua_pushinteger(L, data->sampleSize); + return 1; + } + if (strcmp(key, "channels") == 0) { // Number of channels (1-mono, 2-stereo, ...) + lua_pushinteger(L, data->channels); + return 1; + } + if (strcmp(key, "data") == 0) { // Buffer data pointer + lua_pushlightuserdata(L, data->data); + return 1; + } + return 0; +} + +// --- Wrappers --- + +// Callbacks to hook some internal functions +// WARNING: These callbacks are intended for advanced users + +// Window-related functions +// Initialize window and OpenGL context +static int rl_InitWindow(lua_State *L) +{ + int width = (int)luaL_checkinteger(L, 1); + int height = (int)luaL_checkinteger(L, 2); + const char * title = luaL_checkstring(L, 3); + InitWindow(width, height, title); + return 0; +} + +// Close window and unload OpenGL context +static int rl_CloseWindow(lua_State *L) +{ + CloseWindow(); + return 0; +} + +// Check if application should close (KEY_ESCAPE pressed or windows close icon clicked) +static int rl_WindowShouldClose(lua_State *L) +{ + bool result = WindowShouldClose(); + lua_pushboolean(L, result); + return 1; +} + +// Check if window has been initialized successfully +static int rl_IsWindowReady(lua_State *L) +{ + bool result = IsWindowReady(); + lua_pushboolean(L, result); + return 1; +} + +// Check if window is currently fullscreen +static int rl_IsWindowFullscreen(lua_State *L) +{ + bool result = IsWindowFullscreen(); + lua_pushboolean(L, result); + return 1; +} + +// Check if window is currently hidden +static int rl_IsWindowHidden(lua_State *L) +{ + bool result = IsWindowHidden(); + lua_pushboolean(L, result); + return 1; +} + +// Check if window is currently minimized +static int rl_IsWindowMinimized(lua_State *L) +{ + bool result = IsWindowMinimized(); + lua_pushboolean(L, result); + return 1; +} + +// Check if window is currently maximized +static int rl_IsWindowMaximized(lua_State *L) +{ + bool result = IsWindowMaximized(); + lua_pushboolean(L, result); + return 1; +} + +// Check if window is currently focused +static int rl_IsWindowFocused(lua_State *L) +{ + bool result = IsWindowFocused(); + lua_pushboolean(L, result); + return 1; +} + +// Check if window has been resized last frame +static int rl_IsWindowResized(lua_State *L) +{ + bool result = IsWindowResized(); + lua_pushboolean(L, result); + return 1; +} + +// Check if one specific window flag is enabled +static int rl_IsWindowState(lua_State *L) +{ + unsigned int flag = (unsigned int)luaL_checkinteger(L, 1); + bool result = IsWindowState(flag); + lua_pushboolean(L, result); + return 1; +} + +// Set window configuration state using flags +static int rl_SetWindowState(lua_State *L) +{ + unsigned int flags = (unsigned int)luaL_checkinteger(L, 1); + SetWindowState(flags); + return 0; +} + +// Clear window configuration state flags +static int rl_ClearWindowState(lua_State *L) +{ + unsigned int flags = (unsigned int)luaL_checkinteger(L, 1); + ClearWindowState(flags); + return 0; +} + +// Toggle window state: fullscreen/windowed, resizes monitor to match window resolution +static int rl_ToggleFullscreen(lua_State *L) +{ + ToggleFullscreen(); + return 0; +} + +// Toggle window state: borderless windowed, resizes window to match monitor resolution +static int rl_ToggleBorderlessWindowed(lua_State *L) +{ + ToggleBorderlessWindowed(); + return 0; +} + +// Set window state: maximized, if resizable +static int rl_MaximizeWindow(lua_State *L) +{ + MaximizeWindow(); + return 0; +} + +// Set window state: minimized, if resizable +static int rl_MinimizeWindow(lua_State *L) +{ + MinimizeWindow(); + return 0; +} + +// Restore window from being minimized/maximized +static int rl_RestoreWindow(lua_State *L) +{ + RestoreWindow(); + return 0; +} + +// Set icon for window (single image, RGBA 32bit) +static int rl_SetWindowIcon(lua_State *L) +{ + Image image = *(Image*)RLUA_CHECK_Resource(L, 1, "Image"); + SetWindowIcon(image); + return 0; +} + +// Set icon for window (multiple images, RGBA 32bit) +static int rl_SetWindowIcons(lua_State *L) +{ + Image * images = (Image *)lua_touserdata(L, 1); + int count = (int)luaL_checkinteger(L, 2); + SetWindowIcons(images, count); + return 0; +} + +// Set title for window +static int rl_SetWindowTitle(lua_State *L) +{ + const char * title = luaL_checkstring(L, 1); + SetWindowTitle(title); + return 0; +} + +// Set window position on screen +static int rl_SetWindowPosition(lua_State *L) +{ + int x = (int)luaL_checkinteger(L, 1); + int y = (int)luaL_checkinteger(L, 2); + SetWindowPosition(x, y); + return 0; +} + +// Set monitor for the current window +static int rl_SetWindowMonitor(lua_State *L) +{ + int monitor = (int)luaL_checkinteger(L, 1); + SetWindowMonitor(monitor); + return 0; +} + +// Set window minimum dimensions (for FLAG_WINDOW_RESIZABLE) +static int rl_SetWindowMinSize(lua_State *L) +{ + int width = (int)luaL_checkinteger(L, 1); + int height = (int)luaL_checkinteger(L, 2); + SetWindowMinSize(width, height); + return 0; +} + +// Set window maximum dimensions (for FLAG_WINDOW_RESIZABLE) +static int rl_SetWindowMaxSize(lua_State *L) +{ + int width = (int)luaL_checkinteger(L, 1); + int height = (int)luaL_checkinteger(L, 2); + SetWindowMaxSize(width, height); + return 0; +} + +// Set window dimensions +static int rl_SetWindowSize(lua_State *L) +{ + int width = (int)luaL_checkinteger(L, 1); + int height = (int)luaL_checkinteger(L, 2); + SetWindowSize(width, height); + return 0; +} + +// Set window opacity [0.0f..1.0f] +static int rl_SetWindowOpacity(lua_State *L) +{ + float opacity = (float)luaL_checknumber(L, 1); + SetWindowOpacity(opacity); + return 0; +} + +// Set window focused +static int rl_SetWindowFocused(lua_State *L) +{ + SetWindowFocused(); + return 0; +} + +// Get native window handle +static int rl_GetWindowHandle(lua_State *L) +{ + void * result = GetWindowHandle(); + lua_pushlightuserdata(L, result); + return 1; +} + +// Get current screen width +static int rl_GetScreenWidth(lua_State *L) +{ + int result = GetScreenWidth(); + lua_pushinteger(L, result); + return 1; +} + +// Get current screen height +static int rl_GetScreenHeight(lua_State *L) +{ + int result = GetScreenHeight(); + lua_pushinteger(L, result); + return 1; +} + +// Get current render width (it considers HiDPI) +static int rl_GetRenderWidth(lua_State *L) +{ + int result = GetRenderWidth(); + lua_pushinteger(L, result); + return 1; +} + +// Get current render height (it considers HiDPI) +static int rl_GetRenderHeight(lua_State *L) +{ + int result = GetRenderHeight(); + lua_pushinteger(L, result); + return 1; +} + +// Get number of connected monitors +static int rl_GetMonitorCount(lua_State *L) +{ + int result = GetMonitorCount(); + lua_pushinteger(L, result); + return 1; +} + +// Get current monitor where window is placed +static int rl_GetCurrentMonitor(lua_State *L) +{ + int result = GetCurrentMonitor(); + lua_pushinteger(L, result); + return 1; +} + +// Get specified monitor position +static int rl_GetMonitorPosition(lua_State *L) +{ + int monitor = (int)luaL_checkinteger(L, 1); + Vector2 result = GetMonitorPosition(monitor); + RLUA_PUSH_Vector2(L, result); + return 1; +} + +// Get specified monitor width (current video mode used by monitor) +static int rl_GetMonitorWidth(lua_State *L) +{ + int monitor = (int)luaL_checkinteger(L, 1); + int result = GetMonitorWidth(monitor); + lua_pushinteger(L, result); + return 1; +} + +// Get specified monitor height (current video mode used by monitor) +static int rl_GetMonitorHeight(lua_State *L) +{ + int monitor = (int)luaL_checkinteger(L, 1); + int result = GetMonitorHeight(monitor); + lua_pushinteger(L, result); + return 1; +} + +// Get specified monitor physical width in millimetres +static int rl_GetMonitorPhysicalWidth(lua_State *L) +{ + int monitor = (int)luaL_checkinteger(L, 1); + int result = GetMonitorPhysicalWidth(monitor); + lua_pushinteger(L, result); + return 1; +} + +// Get specified monitor physical height in millimetres +static int rl_GetMonitorPhysicalHeight(lua_State *L) +{ + int monitor = (int)luaL_checkinteger(L, 1); + int result = GetMonitorPhysicalHeight(monitor); + lua_pushinteger(L, result); + return 1; +} + +// Get specified monitor refresh rate +static int rl_GetMonitorRefreshRate(lua_State *L) +{ + int monitor = (int)luaL_checkinteger(L, 1); + int result = GetMonitorRefreshRate(monitor); + lua_pushinteger(L, result); + return 1; +} + +// Get window position XY on monitor +static int rl_GetWindowPosition(lua_State *L) +{ + Vector2 result = GetWindowPosition(); + RLUA_PUSH_Vector2(L, result); + return 1; +} + +// Get window scale DPI factor +static int rl_GetWindowScaleDPI(lua_State *L) +{ + Vector2 result = GetWindowScaleDPI(); + RLUA_PUSH_Vector2(L, result); + return 1; +} + +// Get the human-readable, UTF-8 encoded name of the specified monitor +static int rl_GetMonitorName(lua_State *L) +{ + int monitor = (int)luaL_checkinteger(L, 1); + const char * result = GetMonitorName(monitor); + lua_pushstring(L, result); + return 1; +} + +// Set clipboard text content +static int rl_SetClipboardText(lua_State *L) +{ + const char * text = luaL_checkstring(L, 1); + SetClipboardText(text); + return 0; +} + +// Get clipboard text content +static int rl_GetClipboardText(lua_State *L) +{ + const char * result = GetClipboardText(); + lua_pushstring(L, result); + return 1; +} + +// Get clipboard image content +static int rl_GetClipboardImage(lua_State *L) +{ + Image result = GetClipboardImage(); + RLUA_PUSH_Resource(L, &result, sizeof(Image), "Image"); + return 1; +} + +// Enable waiting for events on EndDrawing(), no automatic event polling +static int rl_EnableEventWaiting(lua_State *L) +{ + EnableEventWaiting(); + return 0; +} + +// Disable waiting for events on EndDrawing(), automatic events polling +static int rl_DisableEventWaiting(lua_State *L) +{ + DisableEventWaiting(); + return 0; +} + +// Cursor-related functions +// Shows cursor +static int rl_ShowCursor(lua_State *L) +{ + ShowCursor(); + return 0; +} + +// Hides cursor +static int rl_HideCursor(lua_State *L) +{ + HideCursor(); + return 0; +} + +// Check if cursor is not visible +static int rl_IsCursorHidden(lua_State *L) +{ + bool result = IsCursorHidden(); + lua_pushboolean(L, result); + return 1; +} + +// Enables cursor (unlock cursor) +static int rl_EnableCursor(lua_State *L) +{ + EnableCursor(); + return 0; +} + +// Disables cursor (lock cursor) +static int rl_DisableCursor(lua_State *L) +{ + DisableCursor(); + return 0; +} + +// Check if cursor is on the screen +static int rl_IsCursorOnScreen(lua_State *L) +{ + bool result = IsCursorOnScreen(); + lua_pushboolean(L, result); + return 1; +} + +// Drawing-related functions +// Set background color (framebuffer clear color) +static int rl_ClearBackground(lua_State *L) +{ + Color color = RLUA_CHECK_Color(L, 1); + ClearBackground(color); + return 0; +} + +// Setup canvas (framebuffer) to start drawing +static int rl_BeginDrawing(lua_State *L) +{ + BeginDrawing(); + return 0; +} + +// End canvas drawing and swap buffers (double buffering) +static int rl_EndDrawing(lua_State *L) +{ + EndDrawing(); + return 0; +} + +// Begin 2D mode with custom camera (2D) +static int rl_BeginMode2D(lua_State *L) +{ + Camera2D camera = RLUA_CHECK_Camera2D(L, 1); + BeginMode2D(camera); + return 0; +} + +// Ends 2D mode with custom camera +static int rl_EndMode2D(lua_State *L) +{ + EndMode2D(); + return 0; +} + +// Begin 3D mode with custom camera (3D) +static int rl_BeginMode3D(lua_State *L) +{ + Camera3D camera = RLUA_CHECK_Camera3D(L, 1); + BeginMode3D(camera); + return 0; +} + +// Ends 3D mode and returns to default 2D orthographic mode +static int rl_EndMode3D(lua_State *L) +{ + EndMode3D(); + return 0; +} + +// Begin drawing to render texture +static int rl_BeginTextureMode(lua_State *L) +{ + RenderTexture2D target = *(RenderTexture2D*)RLUA_CHECK_Resource(L, 1, "RenderTexture2D"); + BeginTextureMode(target); + return 0; +} + +// Ends drawing to render texture +static int rl_EndTextureMode(lua_State *L) +{ + EndTextureMode(); + return 0; +} + +// Begin custom shader drawing +static int rl_BeginShaderMode(lua_State *L) +{ + Shader shader = *(Shader*)RLUA_CHECK_Resource(L, 1, "Shader"); + BeginShaderMode(shader); + return 0; +} + +// End custom shader drawing (use default shader) +static int rl_EndShaderMode(lua_State *L) +{ + EndShaderMode(); + return 0; +} + +// Begin blending mode (alpha, additive, multiplied, subtract, custom) +static int rl_BeginBlendMode(lua_State *L) +{ + int mode = (int)luaL_checkinteger(L, 1); + BeginBlendMode(mode); + return 0; +} + +// End blending mode (reset to default: alpha blending) +static int rl_EndBlendMode(lua_State *L) +{ + EndBlendMode(); + return 0; +} + +// Begin scissor mode (define screen area for following drawing) +static int rl_BeginScissorMode(lua_State *L) +{ + int x = (int)luaL_checkinteger(L, 1); + int y = (int)luaL_checkinteger(L, 2); + int width = (int)luaL_checkinteger(L, 3); + int height = (int)luaL_checkinteger(L, 4); + BeginScissorMode(x, y, width, height); + return 0; +} + +// End scissor mode +static int rl_EndScissorMode(lua_State *L) +{ + EndScissorMode(); + return 0; +} + +// Begin stereo rendering (requires VR simulator) +static int rl_BeginVrStereoMode(lua_State *L) +{ + VrStereoConfig config = RLUA_CHECK_VrStereoConfig(L, 1); + BeginVrStereoMode(config); + return 0; +} + +// End stereo rendering (requires VR simulator) +static int rl_EndVrStereoMode(lua_State *L) +{ + EndVrStereoMode(); + return 0; +} + +// VR stereo config functions for VR simulator +// Load VR stereo config for VR simulator device parameters +static int rl_LoadVrStereoConfig(lua_State *L) +{ + VrDeviceInfo device = RLUA_CHECK_VrDeviceInfo(L, 1); + VrStereoConfig result = LoadVrStereoConfig(device); + RLUA_PUSH_VrStereoConfig(L, result); + return 1; +} + +// Unload VR stereo config +static int rl_UnloadVrStereoConfig(lua_State *L) +{ + VrStereoConfig config = RLUA_CHECK_VrStereoConfig(L, 1); + UnloadVrStereoConfig(config); + return 0; +} + +// Shader management functions +// NOTE: Shader functionality is not available on OpenGL 1.1 +// Load shader from files and bind default locations +static int rl_LoadShader(lua_State *L) +{ + const char * vsFileName = luaL_checkstring(L, 1); + const char * fsFileName = luaL_checkstring(L, 2); + Shader result = LoadShader(vsFileName, fsFileName); + RLUA_PUSH_Resource(L, &result, sizeof(Shader), "Shader"); + return 1; +} + +// Load shader from code strings and bind default locations +static int rl_LoadShaderFromMemory(lua_State *L) +{ + const char * vsCode = luaL_checkstring(L, 1); + const char * fsCode = luaL_checkstring(L, 2); + Shader result = LoadShaderFromMemory(vsCode, fsCode); + RLUA_PUSH_Resource(L, &result, sizeof(Shader), "Shader"); + return 1; +} + +// Check if a shader is valid (loaded on GPU) +static int rl_IsShaderValid(lua_State *L) +{ + Shader shader = *(Shader*)RLUA_CHECK_Resource(L, 1, "Shader"); + bool result = IsShaderValid(shader); + lua_pushboolean(L, result); + return 1; +} + +// Get shader uniform location +static int rl_GetShaderLocation(lua_State *L) +{ + Shader shader = *(Shader*)RLUA_CHECK_Resource(L, 1, "Shader"); + const char * uniformName = luaL_checkstring(L, 2); + int result = GetShaderLocation(shader, uniformName); + lua_pushinteger(L, result); + return 1; +} + +// Get shader attribute location +static int rl_GetShaderLocationAttrib(lua_State *L) +{ + Shader shader = *(Shader*)RLUA_CHECK_Resource(L, 1, "Shader"); + const char * attribName = luaL_checkstring(L, 2); + int result = GetShaderLocationAttrib(shader, attribName); + lua_pushinteger(L, result); + return 1; +} + +// Set shader uniform value +static int rl_SetShaderValue(lua_State *L) +{ + Shader shader = *(Shader*)RLUA_CHECK_Resource(L, 1, "Shader"); + int locIndex = (int)luaL_checkinteger(L, 2); + const void * value = (const void *)lua_touserdata(L, 3); + int uniformType = (int)luaL_checkinteger(L, 4); + SetShaderValue(shader, locIndex, value, uniformType); + return 0; +} + +// Set shader uniform value vector +static int rl_SetShaderValueV(lua_State *L) +{ + Shader shader = *(Shader*)RLUA_CHECK_Resource(L, 1, "Shader"); + int locIndex = (int)luaL_checkinteger(L, 2); + const void * value = (const void *)lua_touserdata(L, 3); + int uniformType = (int)luaL_checkinteger(L, 4); + int count = (int)luaL_checkinteger(L, 5); + SetShaderValueV(shader, locIndex, value, uniformType, count); + return 0; +} + +// Set shader uniform value (matrix 4x4) +static int rl_SetShaderValueMatrix(lua_State *L) +{ + Shader shader = *(Shader*)RLUA_CHECK_Resource(L, 1, "Shader"); + int locIndex = (int)luaL_checkinteger(L, 2); + Matrix mat = RLUA_CHECK_Matrix(L, 3); + SetShaderValueMatrix(shader, locIndex, mat); + return 0; +} + +// Set shader uniform value and bind the texture (sampler2d) +static int rl_SetShaderValueTexture(lua_State *L) +{ + Shader shader = *(Shader*)RLUA_CHECK_Resource(L, 1, "Shader"); + int locIndex = (int)luaL_checkinteger(L, 2); + Texture2D texture = *(Texture2D*)RLUA_CHECK_Resource(L, 3, "Texture2D"); + SetShaderValueTexture(shader, locIndex, texture); + return 0; +} + +// Unload shader from GPU memory (VRAM) +static int rl_UnloadShader(lua_State *L) +{ + Shader shader = *(Shader*)RLUA_CHECK_Resource(L, 1, "Shader"); + UnloadShader(shader); + return 0; +} + +// Get a ray trace from screen position (i.e mouse) +static int rl_GetScreenToWorldRay(lua_State *L) +{ + Vector2 position = RLUA_CHECK_Vector2(L, 1); + Camera camera = RLUA_CHECK_Camera(L, 2); + Ray result = GetScreenToWorldRay(position, camera); + RLUA_PUSH_Ray(L, result); + return 1; +} + +// Get a ray trace from screen position (i.e mouse) in a viewport +static int rl_GetScreenToWorldRayEx(lua_State *L) +{ + Vector2 position = RLUA_CHECK_Vector2(L, 1); + Camera camera = RLUA_CHECK_Camera(L, 2); + int width = (int)luaL_checkinteger(L, 3); + int height = (int)luaL_checkinteger(L, 4); + Ray result = GetScreenToWorldRayEx(position, camera, width, height); + RLUA_PUSH_Ray(L, result); + return 1; +} + +// Get the screen space position for a 3d world space position +static int rl_GetWorldToScreen(lua_State *L) +{ + Vector3 position = RLUA_CHECK_Vector3(L, 1); + Camera camera = RLUA_CHECK_Camera(L, 2); + Vector2 result = GetWorldToScreen(position, camera); + RLUA_PUSH_Vector2(L, result); + return 1; +} + +// Get size position for a 3d world space position +static int rl_GetWorldToScreenEx(lua_State *L) +{ + Vector3 position = RLUA_CHECK_Vector3(L, 1); + Camera camera = RLUA_CHECK_Camera(L, 2); + int width = (int)luaL_checkinteger(L, 3); + int height = (int)luaL_checkinteger(L, 4); + Vector2 result = GetWorldToScreenEx(position, camera, width, height); + RLUA_PUSH_Vector2(L, result); + return 1; +} + +// Get the screen space position for a 2d camera world space position +static int rl_GetWorldToScreen2D(lua_State *L) +{ + Vector2 position = RLUA_CHECK_Vector2(L, 1); + Camera2D camera = RLUA_CHECK_Camera2D(L, 2); + Vector2 result = GetWorldToScreen2D(position, camera); + RLUA_PUSH_Vector2(L, result); + return 1; +} + +// Get the world space position for a 2d camera screen space position +static int rl_GetScreenToWorld2D(lua_State *L) +{ + Vector2 position = RLUA_CHECK_Vector2(L, 1); + Camera2D camera = RLUA_CHECK_Camera2D(L, 2); + Vector2 result = GetScreenToWorld2D(position, camera); + RLUA_PUSH_Vector2(L, result); + return 1; +} + +// Get camera transform matrix (view matrix) +static int rl_GetCameraMatrix(lua_State *L) +{ + Camera camera = RLUA_CHECK_Camera(L, 1); + Matrix result = GetCameraMatrix(camera); + RLUA_PUSH_Matrix(L, result); + return 1; +} + +// Get camera 2d transform matrix +static int rl_GetCameraMatrix2D(lua_State *L) +{ + Camera2D camera = RLUA_CHECK_Camera2D(L, 1); + Matrix result = GetCameraMatrix2D(camera); + RLUA_PUSH_Matrix(L, result); + return 1; +} + +// Timing-related functions +// Set target FPS (maximum) +static int rl_SetTargetFPS(lua_State *L) +{ + int fps = (int)luaL_checkinteger(L, 1); + SetTargetFPS(fps); + return 0; +} + +// Get time in seconds for last frame drawn (delta time) +static int rl_GetFrameTime(lua_State *L) +{ + float result = GetFrameTime(); + lua_pushnumber(L, result); + return 1; +} + +// Get elapsed time in seconds since InitWindow() +static int rl_GetTime(lua_State *L) +{ + double result = GetTime(); + lua_pushnumber(L, result); + return 1; +} + +// Get current FPS +static int rl_GetFPS(lua_State *L) +{ + int result = GetFPS(); + lua_pushinteger(L, result); + return 1; +} + +// Custom frame control functions +// NOTE: Those functions are intended for advanced users that want full control over the frame processing +// By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timing + PollInputEvents() +// To avoid that behaviour and control frame processes manually, enable in config.h: SUPPORT_CUSTOM_FRAME_CONTROL +// Swap back buffer with front buffer (screen drawing) +static int rl_SwapScreenBuffer(lua_State *L) +{ + SwapScreenBuffer(); + return 0; +} + +// Register all input events +static int rl_PollInputEvents(lua_State *L) +{ + PollInputEvents(); + return 0; +} + +// Wait for some time (halt program execution) +static int rl_WaitTime(lua_State *L) +{ + double seconds = luaL_checknumber(L, 1); + WaitTime(seconds); + return 0; +} + +// Random values generation functions +// Set the seed for the random number generator +static int rl_SetRandomSeed(lua_State *L) +{ + unsigned int seed = (unsigned int)luaL_checkinteger(L, 1); + SetRandomSeed(seed); + return 0; +} + +// Get a random value between min and max (both included) +static int rl_GetRandomValue(lua_State *L) +{ + int min = (int)luaL_checkinteger(L, 1); + int max = (int)luaL_checkinteger(L, 2); + int result = GetRandomValue(min, max); + lua_pushinteger(L, result); + return 1; +} + +// Load random values sequence, no values repeated +static int rl_LoadRandomSequence(lua_State *L) +{ + unsigned int count = (unsigned int)luaL_checkinteger(L, 1); + int min = (int)luaL_checkinteger(L, 2); + int max = (int)luaL_checkinteger(L, 3); + int * result = LoadRandomSequence(count, min, max); + lua_pushlightuserdata(L, result); + return 1; +} + +// Unload random values sequence +static int rl_UnloadRandomSequence(lua_State *L) +{ + int * sequence = (int *)lua_touserdata(L, 1); + UnloadRandomSequence(sequence); + return 0; +} + +// Misc. functions +// Takes a screenshot of current screen (filename extension defines format) +static int rl_TakeScreenshot(lua_State *L) +{ + const char * fileName = luaL_checkstring(L, 1); + TakeScreenshot(fileName); + return 0; +} + +// Setup init configuration flags (view FLAGS) +static int rl_SetConfigFlags(lua_State *L) +{ + unsigned int flags = (unsigned int)luaL_checkinteger(L, 1); + SetConfigFlags(flags); + return 0; +} + +// Open URL with default system browser (if available) +static int rl_OpenURL(lua_State *L) +{ + const char * url = luaL_checkstring(L, 1); + OpenURL(url); + return 0; +} + +// Logging system +// Set the current threshold (minimum) log level +static int rl_SetTraceLogLevel(lua_State *L) { - lua_newtable(L); + int logLevel = (int)luaL_checkinteger(L, 1); + SetTraceLogLevel(logLevel); + return 0; } -static void LuaSetEnum(const char *name, int value) +// Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...) +static int rl_TraceLog(lua_State *L) { - LuaPush_int(L, value); - lua_setfield(L, -2, name); + int n = lua_gettop(L); + if (n < 2) return luaL_error(L, "TraceLog requires at least 2 arguments"); + int logLevel = (int)luaL_checkinteger(L, 1); + if (n == 2) { + TraceLog(logLevel, "%s", luaL_checkstring(L, 2)); + } else { + lua_getglobal(L, "string"); + lua_getfield(L, -1, "format"); + for (int i = 2; i <= n; i++) lua_pushvalue(L, i); + lua_call(L, n - 1, 1); + TraceLog(logLevel, "%s", lua_tostring(L, -1)); + lua_pop(L, 2); + } + return 0; } -static void LuaSetEnumColor(const char *name, Color color) +// Set custom trace log +static int rl_SetTraceLogCallback(lua_State *L) { - LuaPush_Color(L, color); - lua_setfield(L, -2, name); + if (lua_isnil(L, 1)) { + if (RLUA_LogRef != LUA_REFNIL) { + luaL_unref(L, LUA_REGISTRYINDEX, RLUA_LogRef); + RLUA_LogRef = LUA_REFNIL; + } + SetTraceLogCallback(NULL); + } else { + luaL_checktype(L, 1, LUA_TFUNCTION); + if (RLUA_LogRef != LUA_REFNIL) luaL_unref(L, LUA_REGISTRYINDEX, RLUA_LogRef); + lua_pushvalue(L, 1); + RLUA_LogRef = luaL_ref(L, LUA_REGISTRYINDEX); + SetTraceLogCallback(RLUA_TraceLogTrampoline); + } + return 0; } -static void LuaEndEnum(const char *name) + +// Memory management, using internal allocators +// Internal memory allocator +static int rl_MemAlloc(lua_State *L) { - lua_setglobal(L, name); + unsigned int size = (unsigned int)luaL_checkinteger(L, 1); + void * result = MemAlloc(size); + lua_pushlightuserdata(L, result); + return 1; } -static void LuaPushOpaque(lua_State* L, void *ptr, size_t size) +// Internal memory reallocator +static int rl_MemRealloc(lua_State *L) { - void *ud = lua_newuserdata(L, size); - memcpy(ud, ptr, size); + void * ptr = lua_touserdata(L, 1); + unsigned int size = (unsigned int)luaL_checkinteger(L, 2); + void * result = MemRealloc(ptr, size); + lua_pushlightuserdata(L, result); + return 1; } -static void LuaPushOpaqueWithMetatable(lua_State* L, void *ptr, size_t size, const char *metatable_name) +// Internal memory free +static int rl_MemFree(lua_State *L) { - void *ud = lua_newuserdata(L, size); - memcpy(ud, ptr, size); - luaL_setmetatable(L, metatable_name); + void * ptr = lua_touserdata(L, 1); + MemFree(ptr); + return 0; } -static void* LuaGetArgumentOpaqueType(lua_State* L, int index) +// File system management functions +// Load file data as byte array (read) +static int rl_LoadFileData(lua_State *L) { - return lua_touserdata(L, index); + const char * fileName = luaL_checkstring(L, 1); + int dataSize = 0; + unsigned char * result = LoadFileData(fileName, &dataSize); + RLUA_PUSH_View(L, result, dataSize, "unsigned char", true); + return 1; } -static void* LuaGetArgumentOpaqueTypeWithMetatable(lua_State* L, int index, const char *metatable_name) +// Unload file data allocated by LoadFileData() +static int rl_UnloadFileData(lua_State *L) { - return luaL_checkudata(L, index, metatable_name); + unsigned char * data = (unsigned char *)lua_touserdata(L, 1); + UnloadFileData(data); + return 0; } -//---------------------------------------------------------------------------------- -// LuaIndex* functions -//---------------------------------------------------------------------------------- -static int LuaIndexImage(lua_State* L) +// Save data to file from byte array (write), returns true on success +static int rl_SaveFileData(lua_State *L) { - Image img = LuaGetArgument_Image(L, 1); - const char *key = luaL_checkstring(L, 2); - - if (!strcmp(key, "width")) LuaPush_int(L, img.width); - else if (!strcmp(key, "height")) LuaPush_int(L, img.height); - else if (!strcmp(key, "mipmaps")) LuaPush_int(L, img.mipmaps); - else if (!strcmp(key, "format")) LuaPush_int(L, img.format); - else return 0; - + const char * fileName = luaL_checkstring(L, 1); + void * data = lua_touserdata(L, 2); + int dataSize = (int)luaL_checkinteger(L, 3); + bool result = SaveFileData(fileName, data, dataSize); + lua_pushboolean(L, result); return 1; } -static int LuaIndexTexture2D(lua_State* L) +// Export data to code (.h), returns true on success +static int rl_ExportDataAsCode(lua_State *L) { - Texture2D img = LuaGetArgument_Texture2D(L, 1); - const char *key = luaL_checkstring(L, 2); - - if (!strcmp(key, "width")) LuaPush_int(L, img.width); - else if (!strcmp(key, "height")) LuaPush_int(L, img.height); - else if (!strcmp(key, "mipmaps")) LuaPush_int(L, img.mipmaps); - else if (!strcmp(key, "format")) LuaPush_int(L, img.format); - else if (!strcmp(key, "id")) LuaPush_int(L, img.id); - else return 0; - + const unsigned char * data = (const unsigned char *)lua_touserdata(L, 1); + int dataSize = (int)luaL_checkinteger(L, 2); + const char * fileName = luaL_checkstring(L, 3); + bool result = ExportDataAsCode(data, dataSize, fileName); + lua_pushboolean(L, result); return 1; } -static int LuaIndexRenderTexture2D(lua_State* L) +// Load text data from file (read), returns a '\0' terminated string +static int rl_LoadFileText(lua_State *L) { - RenderTexture2D img = LuaGetArgument_RenderTexture2D(L, 1); - const char *key = luaL_checkstring(L, 2); - - if (!strcmp(key, "texture")) LuaPush_Texture2D(L, img.texture); - else if (!strcmp(key, "depth")) LuaPush_Texture2D(L, img.depth); - else return 0; - + const char * fileName = luaL_checkstring(L, 1); + char * result = LoadFileText(fileName); + lua_pushstring(L, result); return 1; } -static int LuaIndexFont(lua_State* L) +// Unload file text data allocated by LoadFileText() +static int rl_UnloadFileText(lua_State *L) { - Font img = LuaGetArgument_Font(L, 1); - const char *key = luaL_checkstring(L, 2); - - if (!strcmp(key, "baseSize")) LuaPush_int(L, img.baseSize); - else if (!strcmp(key, "texture")) LuaPush_Texture2D(L, img.texture); - else if (!strcmp(key, "charsCount")) LuaPush_int(L, img.charsCount); - else return 0; - + const char * text = luaL_checkstring(L, 1); + UnloadFileText((char *)text); + return 0; +} + +// Save text data to file (write), string must be '\0' terminated, returns true on success +static int rl_SaveFileText(lua_State *L) +{ + const char * fileName = luaL_checkstring(L, 1); + const char * text = luaL_checkstring(L, 2); + bool result = SaveFileText(fileName, text); + lua_pushboolean(L, result); return 1; } -static void LuaBuildOpaqueMetatables(void) +// File access custom callbacks +// WARNING: Callbacks setup is intended for advanced users +// Set custom file binary data loader +static int rl_SetLoadFileDataCallback(lua_State *L) { - luaL_newmetatable(L, "Image"); - lua_pushcfunction(L, &LuaIndexImage); - lua_setfield(L, -2, "__index"); - lua_pop(L, 1); + LoadFileDataCallback callback = (LoadFileDataCallback)lua_touserdata(L, 1); + SetLoadFileDataCallback(callback); + return 0; +} - luaL_newmetatable(L, "Texture2D"); - lua_pushcfunction(L, &LuaIndexTexture2D); - lua_setfield(L, -2, "__index"); - lua_pop(L, 1); +// Set custom file binary data saver +static int rl_SetSaveFileDataCallback(lua_State *L) +{ + SaveFileDataCallback callback = (SaveFileDataCallback)lua_touserdata(L, 1); + SetSaveFileDataCallback(callback); + return 0; +} - luaL_newmetatable(L, "RenderTexture2D"); - lua_pushcfunction(L, &LuaIndexRenderTexture2D); - lua_setfield(L, -2, "__index"); - lua_pop(L, 1); +// Set custom file text data loader +static int rl_SetLoadFileTextCallback(lua_State *L) +{ + LoadFileTextCallback callback = (LoadFileTextCallback)lua_touserdata(L, 1); + SetLoadFileTextCallback(callback); + return 0; +} - luaL_newmetatable(L, "Font"); - lua_pushcfunction(L, &LuaIndexFont); - lua_setfield(L, -2, "__index"); - lua_pop(L, 1); +// Set custom file text data saver +static int rl_SetSaveFileTextCallback(lua_State *L) +{ + SaveFileTextCallback callback = (SaveFileTextCallback)lua_touserdata(L, 1); + SetSaveFileTextCallback(callback); + return 0; } -//---------------------------------------------------------------------------------- -// LuaGetArgument functions -//---------------------------------------------------------------------------------- +// Rename file (if exists) +static int rl_FileRename(lua_State *L) +{ + const char * fileName = luaL_checkstring(L, 1); + const char * fileRename = luaL_checkstring(L, 2); + int result = FileRename(fileName, fileRename); + lua_pushinteger(L, result); + return 1; +} -// Vector2 type -static Vector2 LuaGetArgument_Vector2(lua_State *L, int index) +// Remove file (if exists) +static int rl_FileRemove(lua_State *L) { - Vector2 result = { 0 }; - index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values - luaL_argcheck(L, lua_getfield(L, index, "x") == LUA_TNUMBER, index, "Expected Vector2.x"); - result.x = LuaGetArgument_float(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "y") == LUA_TNUMBER, index, "Expected Vector2.y"); - result.y = LuaGetArgument_float(L, -1); - lua_pop(L, 2); - return result; + const char * fileName = luaL_checkstring(L, 1); + int result = FileRemove(fileName); + lua_pushinteger(L, result); + return 1; } -// Vector3 type -static Vector3 LuaGetArgument_Vector3(lua_State *L, int index) +// Copy file from one path to another, dstPath created if it doesn't exist +static int rl_FileCopy(lua_State *L) { - Vector3 result = { 0 }; - index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values - luaL_argcheck(L, lua_getfield(L, index, "x") == LUA_TNUMBER, index, "Expected Vector3.x"); - result.x = LuaGetArgument_float(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "y") == LUA_TNUMBER, index, "Expected Vector3.y"); - result.y = LuaGetArgument_float(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "z") == LUA_TNUMBER, index, "Expected Vector3.z"); - result.z = LuaGetArgument_float(L, -1); - lua_pop(L, 3); - return result; + const char * srcPath = luaL_checkstring(L, 1); + const char * dstPath = luaL_checkstring(L, 2); + int result = FileCopy(srcPath, dstPath); + lua_pushinteger(L, result); + return 1; } -// Vector4 type -static Vector4 LuaGetArgument_Vector4(lua_State *L, int index) +// Move file from one directory to another, dstPath created if it doesn't exist +static int rl_FileMove(lua_State *L) { - Vector4 result = { 0 }; - index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values - luaL_argcheck(L, lua_getfield(L, index, "x") == LUA_TNUMBER, index, "Expected Vector4.x"); - result.x = LuaGetArgument_float(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "y") == LUA_TNUMBER, index, "Expected Vector4.y"); - result.y = LuaGetArgument_float(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "z") == LUA_TNUMBER, index, "Expected Vector4.z"); - result.z = LuaGetArgument_float(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "w") == LUA_TNUMBER, index, "Expected Vector4.w"); - result.w = LuaGetArgument_float(L, -1); - lua_pop(L, 4); - return result; + const char * srcPath = luaL_checkstring(L, 1); + const char * dstPath = luaL_checkstring(L, 2); + int result = FileMove(srcPath, dstPath); + lua_pushinteger(L, result); + return 1; } -static Quaternion LuaGetArgument_Quaternion(lua_State* L, int index) +// Replace text in an existing file +static int rl_FileTextReplace(lua_State *L) { - Quaternion result = { 0 }; - index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values - luaL_argcheck(L, lua_getfield(L, index, "x") == LUA_TNUMBER, index, "Expected Quaternion.x"); - result.x = LuaGetArgument_float(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "y") == LUA_TNUMBER, index, "Expected Quaternion.y"); - result.y = LuaGetArgument_float(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "z") == LUA_TNUMBER, index, "Expected Quaternion.z"); - result.z = LuaGetArgument_float(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "w") == LUA_TNUMBER, index, "Expected Quaternion.w"); - result.w = LuaGetArgument_float(L, -1); - lua_pop(L, 4); - return result; + const char * fileName = luaL_checkstring(L, 1); + const char * search = luaL_checkstring(L, 2); + const char * replacement = luaL_checkstring(L, 3); + int result = FileTextReplace(fileName, search, replacement); + lua_pushinteger(L, result); + return 1; } -// Matrix type -static Matrix LuaGetArgument_Matrix(lua_State* L, int index) +// Find text in existing file +static int rl_FileTextFindIndex(lua_State *L) { - Matrix result = { 0 }; - float* ptr = &result.m0; - index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values + const char * fileName = luaL_checkstring(L, 1); + const char * search = luaL_checkstring(L, 2); + int result = FileTextFindIndex(fileName, search); + lua_pushinteger(L, result); + return 1; +} - for (int i = 0; i < 16; i++) - { - lua_geti(L, index, i+1); - ptr[i] = luaL_checknumber(L, -1); - } - lua_pop(L, 16); - return result; +// Check if file exists +static int rl_FileExists(lua_State *L) +{ + const char * fileName = luaL_checkstring(L, 1); + bool result = FileExists(fileName); + lua_pushboolean(L, result); + return 1; } -// Color type, RGBA (32bit) -static Color LuaGetArgument_Color(lua_State *L, int index) +// Check if a directory path exists +static int rl_DirectoryExists(lua_State *L) { - Color result = { 0 }; - index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values - luaL_argcheck(L, lua_getfield(L, index, "r") == LUA_TNUMBER, index, "Expected Color.r"); - result.r = LuaGetArgument_unsigned(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "g") == LUA_TNUMBER, index, "Expected Color.g"); - result.g = LuaGetArgument_unsigned(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "b") == LUA_TNUMBER, index, "Expected Color.b"); - result.b = LuaGetArgument_unsigned(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "a") == LUA_TNUMBER, index, "Expected Color.a"); - result.a = LuaGetArgument_unsigned(L, -1); - lua_pop(L, 4); - return result; + const char * dirPath = luaL_checkstring(L, 1); + bool result = DirectoryExists(dirPath); + lua_pushboolean(L, result); + return 1; } -// Rectangle type -static Rectangle LuaGetArgument_Rectangle(lua_State *L, int index) +// Check file extension (recommended include point: .png, .wav) +static int rl_IsFileExtension(lua_State *L) { - Rectangle result = { 0 }; - index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values - luaL_argcheck(L, lua_getfield(L, index, "x") == LUA_TNUMBER, index, "Expected Rectangle.x"); - result.x = LuaGetArgument_float(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "y") == LUA_TNUMBER, index, "Expected Rectangle.y"); - result.y = LuaGetArgument_float(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "width") == LUA_TNUMBER, index, "Expected Rectangle.width"); - result.width = LuaGetArgument_float(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "height") == LUA_TNUMBER, index, "Expected Rectangle.height"); - result.height = LuaGetArgument_float(L, -1); - lua_pop(L, 4); - return result; + const char * fileName = luaL_checkstring(L, 1); + const char * ext = luaL_checkstring(L, 2); + bool result = IsFileExtension(fileName, ext); + lua_pushboolean(L, result); + return 1; } -// Image type -> Opaque +// Get file length in bytes (NOTE: GetFileSize() conflicts with windows.h) +static int rl_GetFileLength(lua_State *L) +{ + const char * fileName = luaL_checkstring(L, 1); + int result = GetFileLength(fileName); + lua_pushinteger(L, result); + return 1; +} -// Texture2D type -> Opaque +// Get file modification time (last write time) +static int rl_GetFileModTime(lua_State *L) +{ + const char * fileName = luaL_checkstring(L, 1); + long result = GetFileModTime(fileName); + lua_pushinteger(L, result); + return 1; +} -// RenderTexture2D type -> Opaque +// Get pointer to extension for a filename string (includes dot: '.png') +static int rl_GetFileExtension(lua_State *L) +{ + const char * fileName = luaL_checkstring(L, 1); + const char * result = GetFileExtension(fileName); + lua_pushstring(L, result); + return 1; +} -// Font character info type -static CharInfo LuaGetArgument_CharInfo(lua_State *L, int index) +// Get pointer to filename for a path string +static int rl_GetFileName(lua_State *L) { - CharInfo result = { 0 }; - index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values - luaL_argcheck(L, lua_getfield(L, index, "value") == LUA_TNUMBER, index, "Expected CharInfo.value"); - result.value = LuaGetArgument_int(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "rec") == LUA_TNUMBER, index, "Expected CharInfo.rec"); - result.rec = LuaGetArgument_Rectangle(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "offsetX") == LUA_TNUMBER, index, "Expected CharInfo.offsetX"); - result.offsetX = LuaGetArgument_int(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "offsetY") == LUA_TNUMBER, index, "Expected CharInfo.offsetY"); - result.offsetY = LuaGetArgument_int(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "advanceX") == LUA_TNUMBER, index, "Expected CharInfo.advanceX"); - result.advanceX = LuaGetArgument_int(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "char *data") == LUA_TNUMBER, index, "Expected CharInfo.char *data"); - result.char *data = LuaGetArgument_unsigned(L, -1); - lua_pop(L, 6); - return result; + const char * filePath = luaL_checkstring(L, 1); + const char * result = GetFileName(filePath); + lua_pushstring(L, result); + return 1; } -// Font type -> Opaque - -// Camera type, defines a camera position/orientation in 3d space -static Camera LuaGetArgument_Camera(lua_State *L, int index) -{ - Camera result = { 0 }; - index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values - luaL_argcheck(L, lua_getfield(L, index, "position") == LUA_TNUMBER, index, "Expected Camera.position"); - result.position = LuaGetArgument_Vector3(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "target") == LUA_TNUMBER, index, "Expected Camera.target"); - result.target = LuaGetArgument_Vector3(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "up") == LUA_TNUMBER, index, "Expected Camera.up"); - result.up = LuaGetArgument_Vector3(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "fovy") == LUA_TNUMBER, index, "Expected Camera.fovy"); - result.fovy = LuaGetArgument_float(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "type") == LUA_TNUMBER, index, "Expected Camera.type"); - result.type = LuaGetArgument_int(L, -1); - lua_pop(L, 5); - return result; +// Get filename string without extension (uses static string) +static int rl_GetFileNameWithoutExt(lua_State *L) +{ + const char * filePath = luaL_checkstring(L, 1); + const char * result = GetFileNameWithoutExt(filePath); + lua_pushstring(L, result); + return 1; } -// Camera2D type, defines a 2d camera -static Camera2D LuaGetArgument_Camera2D(lua_State *L, int index) +// Get full path for a given fileName with path (uses static string) +static int rl_GetDirectoryPath(lua_State *L) { - Camera2D result = { 0 }; - index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values - luaL_argcheck(L, lua_getfield(L, index, "offset") == LUA_TNUMBER, index, "Expected Camera2D.offset"); - result.offset = LuaGetArgument_Vector2(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "target") == LUA_TNUMBER, index, "Expected Camera2D.target"); - result.target = LuaGetArgument_Vector2(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "rotation") == LUA_TNUMBER, index, "Expected Camera2D.rotation"); - result.rotation = LuaGetArgument_float(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "zoom") == LUA_TNUMBER, index, "Expected Camera2D.zoom"); - result.zoom = LuaGetArgument_float(L, -1); - lua_pop(L, 4); - return result; + const char * filePath = luaL_checkstring(L, 1); + const char * result = GetDirectoryPath(filePath); + lua_pushstring(L, result); + return 1; } -// Bounding box type -static BoundingBox LuaGetArgument_BoundingBox(lua_State *L, int index) +// Get previous directory path for a given path (uses static string) +static int rl_GetPrevDirectoryPath(lua_State *L) { - BoundingBox result = { 0 }; - index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values - luaL_argcheck(L, lua_getfield(L, index, "min") == LUA_TNUMBER, index, "Expected BoundingBox.min"); - result.min = LuaGetArgument_Vector3(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "max") == LUA_TNUMBER, index, "Expected BoundingBox.max"); - result.max = LuaGetArgument_Vector3(L, -1); - lua_pop(L, 2); - return result; + const char * dirPath = luaL_checkstring(L, 1); + const char * result = GetPrevDirectoryPath(dirPath); + lua_pushstring(L, result); + return 1; } -// Mesh type -> Opaque +// Get current working directory (uses static string) +static int rl_GetWorkingDirectory(lua_State *L) +{ + const char * result = GetWorkingDirectory(); + lua_pushstring(L, result); + return 1; +} -// Shader type -> Opaque +// Get the directory of the running application (uses static string) +static int rl_GetApplicationDirectory(lua_State *L) +{ + const char * result = GetApplicationDirectory(); + lua_pushstring(L, result); + return 1; +} -// Material texture map -static MaterialMap LuaGetArgument_MaterialMap(lua_State *L, int index) +// Create directories (including full path requested), returns 0 on success +static int rl_MakeDirectory(lua_State *L) { - MaterialMap result = { 0 }; - index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values - luaL_argcheck(L, lua_getfield(L, index, "texture") == LUA_TNUMBER, index, "Expected MaterialMap.texture"); - result.texture = LuaGetArgument_Texture2D(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "color") == LUA_TNUMBER, index, "Expected MaterialMap.color"); - result.color = LuaGetArgument_Color(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "value") == LUA_TNUMBER, index, "Expected MaterialMap.value"); - result.value = LuaGetArgument_float(L, -1); - lua_pop(L, 3); - return result; + const char * dirPath = luaL_checkstring(L, 1); + int result = MakeDirectory(dirPath); + lua_pushinteger(L, result); + return 1; } -// Material type -> REVIEW -/* -static Material LuaGetArgument_Material(lua_State *L, int index) +// Change working directory, return true on success +static int rl_ChangeDirectory(lua_State *L) { - Material result = { 0 }; - index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values - luaL_argcheck(L, lua_getfield(L, index, "shader") == LUA_TNUMBER, index, "Expected Material.shader"); - result.shader = LuaGetArgument_Shader(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "maps[MAX_MATERIAL_MAPS]") == LUA_TNUMBER, index, "Expected Material.maps[MAX_MATERIAL_MAPS]"); - result.maps[MAX_MATERIAL_MAPS] = LuaGetArgument_MaterialMap(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "*params") == LUA_TNUMBER, index, "Expected Material.*params"); - result.*params = LuaGetArgument_float(L, -1); - lua_pop(L, 3); - return result; + const char * dirPath = luaL_checkstring(L, 1); + bool result = ChangeDirectory(dirPath); + lua_pushboolean(L, result); + return 1; } -static Material LuaGetArgument_Material(lua_State* L, int index) -{ - Material result; - index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values - luaL_argcheck(L, lua_getfield(L, index, "shader") == LUA_TUSERDATA, index, "Expected Material"); - result.shader = LuaGetArgument_Shader(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "texDiffuse") == LUA_TUSERDATA, index, "Expected Material"); - result.texDiffuse = LuaGetArgument_Texture2D(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "texNormal") == LUA_TUSERDATA, index, "Expected Material"); - result.texNormal = LuaGetArgument_Texture2D(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "texSpecular") == LUA_TUSERDATA, index, "Expected Material"); - result.texSpecular = LuaGetArgument_Texture2D(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "colDiffuse") == LUA_TTABLE, index, "Expected Material"); - result.colDiffuse = LuaGetArgument_Color(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "colAmbient") == LUA_TTABLE, index, "Expected Material"); - result.colAmbient = LuaGetArgument_Color(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "colSpecular") == LUA_TTABLE, index, "Expected Material"); - result.colSpecular = LuaGetArgument_Color(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "glossiness") == LUA_TNUMBER, index, "Expected Material"); - result.glossiness = LuaGetArgument_float(L, -1); - lua_pop(L, 8); - return result; +// Check if a given path is a file or a directory +static int rl_IsPathFile(lua_State *L) +{ + const char * path = luaL_checkstring(L, 1); + bool result = IsPathFile(path); + lua_pushboolean(L, result); + return 1; } -*/ -// Model type -static Model LuaGetArgument_Model(lua_State *L, int index) +// Check if fileName is valid for the platform/OS +static int rl_IsFileNameValid(lua_State *L) { - Model result = { 0 }; - index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values - luaL_argcheck(L, lua_getfield(L, index, "mesh") == LUA_TNUMBER, index, "Expected Model.mesh"); - result.mesh = LuaGetArgument_Mesh(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "transform") == LUA_TNUMBER, index, "Expected Model.transform"); - result.transform = LuaGetArgument_Matrix(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "material") == LUA_TNUMBER, index, "Expected Model.material"); - result.material = LuaGetArgument_Material(L, -1); - lua_pop(L, 3); - return result; + const char * fileName = luaL_checkstring(L, 1); + bool result = IsFileNameValid(fileName); + lua_pushboolean(L, result); + return 1; } -// Ray type (useful for raycast) -static Ray LuaGetArgument_Ray(lua_State *L, int index) +// Load directory filepaths, files and directories, no subdirs scan +static int rl_LoadDirectoryFiles(lua_State *L) { - Ray result = { 0 }; - index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values - luaL_argcheck(L, lua_getfield(L, index, "position") == LUA_TNUMBER, index, "Expected Ray.position"); - result.position = LuaGetArgument_Vector3(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "direction") == LUA_TNUMBER, index, "Expected Ray.direction"); - result.direction = LuaGetArgument_Vector3(L, -1); - lua_pop(L, 2); - return result; + const char * dirPath = luaL_checkstring(L, 1); + FilePathList result = LoadDirectoryFiles(dirPath); + RLUA_PUSH_FilePathList(L, result); + return 1; } -// Raycast hit information -static RayHitInfo LuaGetArgument_RayHitInfo(lua_State *L, int index) -{ - RayHitInfo result = { 0 }; - index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values - luaL_argcheck(L, lua_getfield(L, index, "hit") == LUA_TNUMBER, index, "Expected RayHitInfo.hit"); - result.hit = LuaGetArgument_bool(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "distance") == LUA_TNUMBER, index, "Expected RayHitInfo.distance"); - result.distance = LuaGetArgument_float(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "position") == LUA_TNUMBER, index, "Expected RayHitInfo.position"); - result.position = LuaGetArgument_Vector3(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "normal") == LUA_TNUMBER, index, "Expected RayHitInfo.normal"); - result.normal = LuaGetArgument_Vector3(L, -1); - lua_pop(L, 4); - return result; +// Load directory filepaths with extension filtering and subdir scan; some filters available: "*.*", "FILES*", "DIRS*" +static int rl_LoadDirectoryFilesEx(lua_State *L) +{ + const char * basePath = luaL_checkstring(L, 1); + const char * filter = luaL_checkstring(L, 2); + bool scanSubdirs = lua_toboolean(L, 3); + FilePathList result = LoadDirectoryFilesEx(basePath, filter, scanSubdirs); + RLUA_PUSH_FilePathList(L, result); + return 1; } -// Wave type -> Opaque +// Unload filepaths +static int rl_UnloadDirectoryFiles(lua_State *L) +{ + FilePathList files = RLUA_CHECK_FilePathList(L, 1); + UnloadDirectoryFiles(files); + return 0; +} -// Sound type -> Opaque +// Check if a file has been dropped into window +static int rl_IsFileDropped(lua_State *L) +{ + bool result = IsFileDropped(); + lua_pushboolean(L, result); + return 1; +} -// MusicData type -> Opaque +// Load dropped filepaths +static int rl_LoadDroppedFiles(lua_State *L) +{ + FilePathList result = LoadDroppedFiles(); + RLUA_PUSH_FilePathList(L, result); + return 1; +} -// Head-Mounted-Display device parameters -static VrDeviceInfo LuaGetArgument_VrDeviceInfo(lua_State *L, int index) +// Unload dropped filepaths +static int rl_UnloadDroppedFiles(lua_State *L) { - VrDeviceInfo result = { 0 }; - index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values - luaL_argcheck(L, lua_getfield(L, index, "hResolution") == LUA_TNUMBER, index, "Expected VrDeviceInfo.hResolution"); - result.hResolution = LuaGetArgument_int(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "vResolution") == LUA_TNUMBER, index, "Expected VrDeviceInfo.vResolution"); - result.vResolution = LuaGetArgument_int(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "hScreenSize") == LUA_TNUMBER, index, "Expected VrDeviceInfo.hScreenSize"); - result.hScreenSize = LuaGetArgument_float(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "vScreenSize") == LUA_TNUMBER, index, "Expected VrDeviceInfo.vScreenSize"); - result.vScreenSize = LuaGetArgument_float(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "vScreenCenter") == LUA_TNUMBER, index, "Expected VrDeviceInfo.vScreenCenter"); - result.vScreenCenter = LuaGetArgument_float(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "eyeToScreenDistance") == LUA_TNUMBER, index, "Expected VrDeviceInfo.eyeToScreenDistance"); - result.eyeToScreenDistance = LuaGetArgument_float(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "lensSeparationDistance") == LUA_TNUMBER, index, "Expected VrDeviceInfo.lensSeparationDistance"); - result.lensSeparationDistance = LuaGetArgument_float(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "interpupillaryDistance") == LUA_TNUMBER, index, "Expected VrDeviceInfo.interpupillaryDistance"); - result.interpupillaryDistance = LuaGetArgument_float(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "lensDistortionValues[4]") == LUA_TNUMBER, index, "Expected VrDeviceInfo.lensDistortionValues[4]"); - result.lensDistortionValues[4] = LuaGetArgument_float(L, -1); - luaL_argcheck(L, lua_getfield(L, index, "chromaAbCorrection[4]") == LUA_TNUMBER, index, "Expected VrDeviceInfo.chromaAbCorrection[4]"); - result.chromaAbCorrection[4] = LuaGetArgument_float(L, -1); - lua_pop(L, 10); - return result; + FilePathList files = RLUA_CHECK_FilePathList(L, 1); + UnloadDroppedFiles(files); + return 0; } -//---------------------------------------------------------------------------------- -// LuaPush functions -//---------------------------------------------------------------------------------- -static void LuaPush_Color(lua_State* L, Color color) +// Get the file count in a directory +static int rl_GetDirectoryFileCount(lua_State *L) { - lua_createtable(L, 0, 4); - LuaPush_int(L, color.r); - lua_setfield(L, -2, "r"); - LuaPush_int(L, color.g); - lua_setfield(L, -2, "g"); - LuaPush_int(L, color.b); - lua_setfield(L, -2, "b"); - LuaPush_int(L, color.a); - lua_setfield(L, -2, "a"); + const char * dirPath = luaL_checkstring(L, 1); + unsigned int result = GetDirectoryFileCount(dirPath); + lua_pushinteger(L, result); + return 1; } -static void LuaPush_Vector2(lua_State* L, Vector2 vec) +// Get the file count in a directory with extension filtering and recursive directory scan. Use 'DIR' in the filter string to include directories in the result +static int rl_GetDirectoryFileCountEx(lua_State *L) { - lua_createtable(L, 0, 2); - LuaPush_float(L, vec.x); - lua_setfield(L, -2, "x"); - LuaPush_float(L, vec.y); - lua_setfield(L, -2, "y"); + const char * basePath = luaL_checkstring(L, 1); + const char * filter = luaL_checkstring(L, 2); + bool scanSubdirs = lua_toboolean(L, 3); + unsigned int result = GetDirectoryFileCountEx(basePath, filter, scanSubdirs); + lua_pushinteger(L, result); + return 1; } -static void LuaPush_Vector3(lua_State* L, Vector3 vec) +// Compression/Encoding functionality +// Compress data (DEFLATE algorithm), memory must be MemFree() +static int rl_CompressData(lua_State *L) { - lua_createtable(L, 0, 3); - LuaPush_float(L, vec.x); - lua_setfield(L, -2, "x"); - LuaPush_float(L, vec.y); - lua_setfield(L, -2, "y"); - LuaPush_float(L, vec.z); - lua_setfield(L, -2, "z"); + const unsigned char * data = (const unsigned char *)lua_touserdata(L, 1); + int dataSize = (int)luaL_checkinteger(L, 2); + int compDataSize = 0; + unsigned char * result = CompressData(data, dataSize, &compDataSize); + RLUA_PUSH_View(L, result, compDataSize, "unsigned char", true); + return 1; } -static void LuaPush_Vector4(lua_State* L, Vector4 vec) +// Decompress data (DEFLATE algorithm), memory must be MemFree() +static int rl_DecompressData(lua_State *L) { - lua_createtable(L, 0, 4); - LuaPush_float(L, vec.x); - lua_setfield(L, -2, "x"); - LuaPush_float(L, vec.y); - lua_setfield(L, -2, "y"); - LuaPush_float(L, vec.z); - lua_setfield(L, -2, "z"); - LuaPush_float(L, vec.w); - lua_setfield(L, -2, "w"); + const unsigned char * compData = (const unsigned char *)lua_touserdata(L, 1); + int compDataSize = (int)luaL_checkinteger(L, 2); + int dataSize = 0; + unsigned char * result = DecompressData(compData, compDataSize, &dataSize); + RLUA_PUSH_View(L, result, dataSize, "unsigned char", true); + return 1; } -static void LuaPush_Quaternion(lua_State* L, Quaternion vec) +// Encode data to Base64 string (includes NULL terminator), memory must be MemFree() +static int rl_EncodeDataBase64(lua_State *L) { - lua_createtable(L, 0, 4); - LuaPush_float(L, vec.x); - lua_setfield(L, -2, "x"); - LuaPush_float(L, vec.y); - lua_setfield(L, -2, "y"); - LuaPush_float(L, vec.z); - lua_setfield(L, -2, "z"); - LuaPush_float(L, vec.w); - lua_setfield(L, -2, "w"); + const unsigned char * data = (const unsigned char *)lua_touserdata(L, 1); + int dataSize = (int)luaL_checkinteger(L, 2); + int outputSize = 0; + char * result = EncodeDataBase64(data, dataSize, &outputSize); + RLUA_PUSH_View(L, result, outputSize, "char", true); + return 1; } -static void LuaPush_Matrix(lua_State* L, Matrix *matrix) +// Decode Base64 string (expected NULL terminated), memory must be MemFree() +static int rl_DecodeDataBase64(lua_State *L) { - int i; - lua_createtable(L, 16, 0); - float* num = (&matrix->m0); - for (i = 0; i < 16; i++) - { - LuaPush_float(L, num[i]); - lua_rawseti(L, -2, i + 1); - } + const char * text = luaL_checkstring(L, 1); + int outputSize = 0; + unsigned char * result = DecodeDataBase64(text, &outputSize); + RLUA_PUSH_View(L, result, outputSize, "unsigned char", true); + return 1; } -static void LuaPush_Rectangle(lua_State* L, Rectangle rect) +// Compute CRC32 hash code +static int rl_ComputeCRC32(lua_State *L) { - lua_createtable(L, 0, 4); - LuaPush_int(L, rect.x); - lua_setfield(L, -2, "x"); - LuaPush_int(L, rect.y); - lua_setfield(L, -2, "y"); - LuaPush_int(L, rect.width); - lua_setfield(L, -2, "width"); - LuaPush_int(L, rect.height); - lua_setfield(L, -2, "height"); + unsigned char * data = (unsigned char *)lua_touserdata(L, 1); + int dataSize = (int)luaL_checkinteger(L, 2); + unsigned int result = ComputeCRC32(data, dataSize); + lua_pushinteger(L, result); + return 1; } -static void LuaPush_Ray(lua_State* L, Ray ray) +// Compute MD5 hash code, returns static int[4] (16 bytes) +static int rl_ComputeMD5(lua_State *L) { - lua_createtable(L, 0, 2); - LuaPush_Vector3(L, ray.position); - lua_setfield(L, -2, "position"); - LuaPush_Vector3(L, ray.direction); - lua_setfield(L, -2, "direction"); + unsigned char * data = (unsigned char *)lua_touserdata(L, 1); + int dataSize = (int)luaL_checkinteger(L, 2); + unsigned int * result = ComputeMD5(data, dataSize); + lua_pushlightuserdata(L, result); + return 1; } -static void LuaPush_RayHitInfo(lua_State* L, RayHitInfo hit) +// Compute SHA1 hash code, returns static int[5] (20 bytes) +static int rl_ComputeSHA1(lua_State *L) { - lua_createtable(L, 0, 4); - LuaPush_int(L, hit.hit); - lua_setfield(L, -2, "hit"); - LuaPush_float(L, hit.distance); - lua_setfield(L, -2, "distance"); - LuaPush_Vector3(L, hit.position); - lua_setfield(L, -2, "position"); - LuaPush_Vector3(L, hit.normal); - lua_setfield(L, -2, "normal"); + unsigned char * data = (unsigned char *)lua_touserdata(L, 1); + int dataSize = (int)luaL_checkinteger(L, 2); + unsigned int * result = ComputeSHA1(data, dataSize); + lua_pushlightuserdata(L, result); + return 1; } -static void LuaPush_BoundingBox(lua_State* L, BoundingBox bb) +// Compute SHA256 hash code, returns static int[8] (32 bytes) +static int rl_ComputeSHA256(lua_State *L) { - lua_createtable(L, 0, 2); - LuaPush_Vector3(L, bb.min); - lua_setfield(L, -2, "min"); - LuaPush_Vector3(L, bb.max); - lua_setfield(L, -2, "max"); + unsigned char * data = (unsigned char *)lua_touserdata(L, 1); + int dataSize = (int)luaL_checkinteger(L, 2); + unsigned int * result = ComputeSHA256(data, dataSize); + lua_pushlightuserdata(L, result); + return 1; } -static void LuaPush_Camera(lua_State* L, Camera cam) +// Automation events functionality +// Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS +static int rl_LoadAutomationEventList(lua_State *L) { - lua_createtable(L, 0, 4); - LuaPush_Vector3(L, cam.position); - lua_setfield(L, -2, "position"); - LuaPush_Vector3(L, cam.target); - lua_setfield(L, -2, "target"); - LuaPush_Vector3(L, cam.up); - lua_setfield(L, -2, "up"); - LuaPush_float(L, cam.fovy); - lua_setfield(L, -2, "fovy"); + const char * fileName = luaL_checkstring(L, 1); + AutomationEventList result = LoadAutomationEventList(fileName); + RLUA_PUSH_AutomationEventList(L, result); + return 1; } -static void LuaPush_Camera2D(lua_State* L, Camera2D cam) +// Unload automation events list from file +static int rl_UnloadAutomationEventList(lua_State *L) { - lua_createtable(L, 0, 4); - LuaPush_Vector2(L, cam.offset); - lua_setfield(L, -2, "offset"); - LuaPush_Vector2(L, cam.target); - lua_setfield(L, -2, "target"); - LuaPush_float(L, cam.rotation); - lua_setfield(L, -2, "rotation"); - LuaPush_float(L, cam.zoom); - lua_setfield(L, -2, "zoom"); + AutomationEventList list = RLUA_CHECK_AutomationEventList(L, 1); + UnloadAutomationEventList(list); + return 0; } -// REVIEW!!! -/* -static void LuaPush_Material(lua_State* L, Material mat) +// Export automation events list as text file +static int rl_ExportAutomationEventList(lua_State *L) { - lua_createtable(L, 0, 8); - LuaPush_Shader(L, mat.shader); - lua_setfield(L, -2, "shader"); - LuaPush_Texture2D(L, mat.texDiffuse); - lua_setfield(L, -2, "texDiffuse"); - LuaPush_Texture2D(L, mat.texNormal); - lua_setfield(L, -2, "texNormal"); - LuaPush_Texture2D(L, mat.texSpecular); - lua_setfield(L, -2, "texSpecular"); - LuaPush_Color(L, mat.colDiffuse); - lua_setfield(L, -2, "colDiffuse"); - LuaPush_Color(L, mat.colAmbient); - lua_setfield(L, -2, "colAmbient"); - LuaPush_Color(L, mat.colSpecular); - lua_setfield(L, -2, "colSpecular"); - LuaPush_float(L, mat.glossiness); - lua_setfield(L, -2, "glossiness"); -} -*/ - -static void LuaPush_Model(lua_State* L, Model mdl) + AutomationEventList list = RLUA_CHECK_AutomationEventList(L, 1); + const char * fileName = luaL_checkstring(L, 2); + bool result = ExportAutomationEventList(list, fileName); + lua_pushboolean(L, result); + return 1; +} + +// Set automation event list to record to +static int rl_SetAutomationEventList(lua_State *L) { - lua_createtable(L, 0, 3); - LuaPush_Mesh(L, mdl.mesh); - lua_setfield(L, -2, "mesh"); - LuaPush_Matrix(L, &mdl.transform); - lua_setfield(L, -2, "transform"); - LuaPush_Material(L, mdl.material); - lua_setfield(L, -2, "material"); + AutomationEventList list = RLUA_CHECK_AutomationEventList(L, 1); + SetAutomationEventList(&list); + RLUA_WRITEBACK_AutomationEventList(L, 1, list); + return 0; } -//---------------------------------------------------------------------------------- -// raylib Lua Structure constructors -//---------------------------------------------------------------------------------- -static int lua_Color(lua_State* L) +// Set automation event internal base frame to start recording +static int rl_SetAutomationEventBaseFrame(lua_State *L) { - LuaPush_Color(L, (Color) { (unsigned char)luaL_checkinteger(L, 1), (unsigned char)luaL_checkinteger(L, 2), (unsigned char)luaL_checkinteger(L, 3), (unsigned char)luaL_checkinteger(L, 4) }); - return 1; + int frame = (int)luaL_checkinteger(L, 1); + SetAutomationEventBaseFrame(frame); + return 0; } -static int lua_Vector2(lua_State* L) +// Start recording automation events (AutomationEventList must be set) +static int rl_StartAutomationEventRecording(lua_State *L) { - LuaPush_Vector2(L, (Vector2) { (float)luaL_checknumber(L, 1), (float)luaL_checknumber(L, 2) }); - return 1; + StartAutomationEventRecording(); + return 0; } -static int lua_Vector3(lua_State* L) +// Stop recording automation events +static int rl_StopAutomationEventRecording(lua_State *L) { - LuaPush_Vector3(L, (Vector3) { (float)luaL_checknumber(L, 1), (float)luaL_checknumber(L, 2), (float)luaL_checknumber(L, 3) }); - return 1; + StopAutomationEventRecording(); + return 0; } -static int lua_Vector4(lua_State* L) +// Play a recorded automation event +static int rl_PlayAutomationEvent(lua_State *L) { - LuaPush_Vector4(L, (Vector4) { (float)luaL_checknumber(L, 1), (float)luaL_checknumber(L, 2), (float)luaL_checknumber(L, 3), (float)luaL_checknumber(L, 4) }); - return 1; + AutomationEvent event = RLUA_CHECK_AutomationEvent(L, 1); + PlayAutomationEvent(event); + return 0; } -static int lua_Quaternion(lua_State* L) +// ------------------------------------------------------------------------------------ +// Input Handling Functions (Module: core) +// ------------------------------------------------------------------------------------ +// Input-related functions: keyboard +// Check if a key has been pressed once +static int rl_IsKeyPressed(lua_State *L) { - LuaPush_Quaternion(L, (Quaternion) { (float)luaL_checknumber(L, 1), (float)luaL_checknumber(L, 2), (float)luaL_checknumber(L, 3), (float)luaL_checknumber(L, 4) }); + int key = (int)luaL_checkinteger(L, 1); + bool result = IsKeyPressed(key); + lua_pushboolean(L, result); return 1; } -static int lua_Rectangle(lua_State* L) +// Check if a key has been pressed again +static int rl_IsKeyPressedRepeat(lua_State *L) { - LuaPush_Rectangle(L, (Rectangle) { (float)luaL_checknumber(L, 1), (float)luaL_checknumber(L, 2), (float)luaL_checknumber(L, 3), (float)luaL_checknumber(L, 4) }); + int key = (int)luaL_checkinteger(L, 1); + bool result = IsKeyPressedRepeat(key); + lua_pushboolean(L, result); return 1; } -static int lua_Ray(lua_State* L) +// Check if a key is being pressed +static int rl_IsKeyDown(lua_State *L) { - Vector3 pos = LuaGetArgument_Vector3(L, 1); - Vector3 dir = LuaGetArgument_Vector3(L, 2); - LuaPush_Ray(L, (Ray) { { pos.x, pos.y, pos.z }, { dir.x, dir.y, dir.z } }); + int key = (int)luaL_checkinteger(L, 1); + bool result = IsKeyDown(key); + lua_pushboolean(L, result); return 1; } -static int lua_RayHitInfo(lua_State* L) +// Check if a key has been released once +static int rl_IsKeyReleased(lua_State *L) { - int hit = LuaGetArgument_int(L, 1); - float dis = LuaGetArgument_float(L, 2); - Vector3 pos = LuaGetArgument_Vector3(L, 3); - Vector3 norm = LuaGetArgument_Vector3(L, 4); - LuaPush_RayHitInfo(L, (RayHitInfo) { hit, dis, { pos.x, pos.y, pos.z }, { norm.x, norm.y, norm.z } }); + int key = (int)luaL_checkinteger(L, 1); + bool result = IsKeyReleased(key); + lua_pushboolean(L, result); return 1; } -static int lua_BoundingBox(lua_State* L) +// Check if a key is NOT being pressed +static int rl_IsKeyUp(lua_State *L) { - Vector3 min = LuaGetArgument_Vector3(L, 1); - Vector3 max = LuaGetArgument_Vector3(L, 2); - LuaPush_BoundingBox(L, (BoundingBox) { { min.x, min.y, min.z }, { max.x, max.y, max.z } }); + int key = (int)luaL_checkinteger(L, 1); + bool result = IsKeyUp(key); + lua_pushboolean(L, result); return 1; } -static int lua_Camera(lua_State* L) +// Get key pressed (keycode), call it multiple times for keys queued, returns 0 when the queue is empty +static int rl_GetKeyPressed(lua_State *L) { - Vector3 pos = LuaGetArgument_Vector3(L, 1); - Vector3 tar = LuaGetArgument_Vector3(L, 2); - Vector3 up = LuaGetArgument_Vector3(L, 3); - float fovy = LuaGetArgument_float(L, 4); - LuaPush_Camera(L, (Camera) { { pos.x, pos.y, pos.z }, { tar.x, tar.y, tar.z }, { up.x, up.y, up.z }, fovy }); + int result = GetKeyPressed(); + lua_pushinteger(L, result); return 1; } -static int lua_Camera2D(lua_State* L) +// Get char pressed (unicode), call it multiple times for chars queued, returns 0 when the queue is empty +static int rl_GetCharPressed(lua_State *L) { - Vector2 off = LuaGetArgument_Vector2(L, 1); - Vector2 tar = LuaGetArgument_Vector2(L, 2); - float rot = LuaGetArgument_float(L, 3); - float zoom = LuaGetArgument_float(L, 4); - LuaPush_Camera2D(L, (Camera2D) { { off.x, off.y }, { tar.x, tar.y }, rot, zoom }); + int result = GetCharPressed(); + lua_pushinteger(L, result); return 1; } -/************************************************************************************* -* -* raylib Lua Functions Bindings -* -**************************************************************************************/ - -//------------------------------------------------------------------------------------ -// raylib [core] module functions - Window and Graphics Device -//------------------------------------------------------------------------------------ - -// Initialize window and OpenGL context -int lua_InitWindow(lua_State *L) +// Get name of a QWERTY key on the current keyboard layout (eg returns string 'q' for KEY_A on an AZERTY keyboard) +static int rl_GetKeyName(lua_State *L) { - int width = LuaGetArgument_int(L, 1); - int height = LuaGetArgument_int(L, 2); - const char *title = LuaGetArgument_string(L, 3); - InitWindow(width, height, title); - return 0; + int key = (int)luaL_checkinteger(L, 1); + const char * result = GetKeyName(key); + lua_pushstring(L, result); + return 1; } -// Close window and unload OpenGL context -int lua_CloseWindow(lua_State *L) +// Set a custom key to exit program (default is ESC) +static int rl_SetExitKey(lua_State *L) { - CloseWindow(); + int key = (int)luaL_checkinteger(L, 1); + SetExitKey(key); return 0; } -// Check if window has been initialized successfully -int lua_IsWindowReady(lua_State *L) +// Input-related functions: gamepads +// Check if a gamepad is available +static int rl_IsGamepadAvailable(lua_State *L) { - bool result = IsWindowReady(); - LuaPush_bool(L, result); + int gamepad = (int)luaL_checkinteger(L, 1); + bool result = IsGamepadAvailable(gamepad); + lua_pushboolean(L, result); return 1; } -// Check if KEY_ESCAPE pressed or Close icon pressed -int lua_WindowShouldClose(lua_State *L) +// Get gamepad internal name id +static int rl_GetGamepadName(lua_State *L) { - bool result = WindowShouldClose(); - LuaPush_bool(L, result); + int gamepad = (int)luaL_checkinteger(L, 1); + const char * result = GetGamepadName(gamepad); + lua_pushstring(L, result); return 1; } -// Check if window has been minimized (or lost focus) -int lua_IsWindowMinimized(lua_State *L) +// Check if a gamepad button has been pressed once +static int rl_IsGamepadButtonPressed(lua_State *L) { - bool result = IsWindowMinimized(); - LuaPush_bool(L, result); + int gamepad = (int)luaL_checkinteger(L, 1); + int button = (int)luaL_checkinteger(L, 2); + bool result = IsGamepadButtonPressed(gamepad, button); + lua_pushboolean(L, result); return 1; } -// Toggle fullscreen mode (only PLATFORM_DESKTOP) -int lua_ToggleFullscreen(lua_State *L) +// Check if a gamepad button is being pressed +static int rl_IsGamepadButtonDown(lua_State *L) { - ToggleFullscreen(); - return 0; + int gamepad = (int)luaL_checkinteger(L, 1); + int button = (int)luaL_checkinteger(L, 2); + bool result = IsGamepadButtonDown(gamepad, button); + lua_pushboolean(L, result); + return 1; } -// Set icon for window (only PLATFORM_DESKTOP) -int lua_SetWindowIcon(lua_State *L) +// Check if a gamepad button has been released once +static int rl_IsGamepadButtonReleased(lua_State *L) { - Image image = LuaGetArgument_Image(L, 1); - SetWindowIcon(image); - return 0; + int gamepad = (int)luaL_checkinteger(L, 1); + int button = (int)luaL_checkinteger(L, 2); + bool result = IsGamepadButtonReleased(gamepad, button); + lua_pushboolean(L, result); + return 1; } -// Set title for window (only PLATFORM_DESKTOP) -int lua_SetWindowTitle(lua_State *L) +// Check if a gamepad button is NOT being pressed +static int rl_IsGamepadButtonUp(lua_State *L) { - const char *title = LuaGetArgument_string(L, 1); - SetWindowTitle(title); - return 0; + int gamepad = (int)luaL_checkinteger(L, 1); + int button = (int)luaL_checkinteger(L, 2); + bool result = IsGamepadButtonUp(gamepad, button); + lua_pushboolean(L, result); + return 1; } -// Set window position on screen (only PLATFORM_DESKTOP) -int lua_SetWindowPosition(lua_State *L) +// Get the last gamepad button pressed +static int rl_GetGamepadButtonPressed(lua_State *L) { - int x = LuaGetArgument_int(L, 1); - int y = LuaGetArgument_int(L, 2); - SetWindowPosition(x, y); - return 0; + int result = GetGamepadButtonPressed(); + lua_pushinteger(L, result); + return 1; } -// Set monitor for the current window (fullscreen mode) -int lua_SetWindowMonitor(lua_State *L) +// Get axis count for a gamepad +static int rl_GetGamepadAxisCount(lua_State *L) { - int monitor = LuaGetArgument_int(L, 1); - SetWindowMonitor(monitor); - return 0; + int gamepad = (int)luaL_checkinteger(L, 1); + int result = GetGamepadAxisCount(gamepad); + lua_pushinteger(L, result); + return 1; } -// Set window minimum dimensions (for FLAG_WINDOW_RESIZABLE) -int lua_SetWindowMinSize(lua_State *L) +// Get movement value for a gamepad axis +static int rl_GetGamepadAxisMovement(lua_State *L) { - int width = LuaGetArgument_int(L, 1); - int height = LuaGetArgument_int(L, 2); - SetWindowMinSize(width, height); - return 0; + int gamepad = (int)luaL_checkinteger(L, 1); + int axis = (int)luaL_checkinteger(L, 2); + float result = GetGamepadAxisMovement(gamepad, axis); + lua_pushnumber(L, result); + return 1; +} + +// Set internal gamepad mappings (SDL_GameControllerDB) +static int rl_SetGamepadMappings(lua_State *L) +{ + const char * mappings = luaL_checkstring(L, 1); + int result = SetGamepadMappings(mappings); + lua_pushinteger(L, result); + return 1; } -// Set window dimensions -int lua_SetWindowSize(lua_State *L) +// Set gamepad vibration for both motors (duration in seconds) +static int rl_SetGamepadVibration(lua_State *L) { - int width = LuaGetArgument_int(L, 1); - int height = LuaGetArgument_int(L, 2); - SetWindowSize(width, height); + int gamepad = (int)luaL_checkinteger(L, 1); + float leftMotor = (float)luaL_checknumber(L, 2); + float rightMotor = (float)luaL_checknumber(L, 3); + float duration = (float)luaL_checknumber(L, 4); + SetGamepadVibration(gamepad, leftMotor, rightMotor, duration); return 0; } -// Get current screen width -int lua_GetScreenWidth(lua_State *L) +// Input-related functions: mouse +// Check if a mouse button has been pressed once +static int rl_IsMouseButtonPressed(lua_State *L) { - int result = GetScreenWidth(); - LuaPush_int(L, result); + int button = (int)luaL_checkinteger(L, 1); + bool result = IsMouseButtonPressed(button); + lua_pushboolean(L, result); return 1; } -// Get current screen height -int lua_GetScreenHeight(lua_State *L) +// Check if a mouse button is being pressed +static int rl_IsMouseButtonDown(lua_State *L) { - int result = GetScreenHeight(); - LuaPush_int(L, result); + int button = (int)luaL_checkinteger(L, 1); + bool result = IsMouseButtonDown(button); + lua_pushboolean(L, result); return 1; } -// Cursor-related functions -// Shows cursor -int lua_ShowCursor(lua_State *L) +// Check if a mouse button has been released once +static int rl_IsMouseButtonReleased(lua_State *L) { - ShowCursor(); - return 0; + int button = (int)luaL_checkinteger(L, 1); + bool result = IsMouseButtonReleased(button); + lua_pushboolean(L, result); + return 1; } -// Hides cursor -int lua_HideCursor(lua_State *L) +// Check if a mouse button is NOT being pressed +static int rl_IsMouseButtonUp(lua_State *L) { - HideCursor(); - return 0; + int button = (int)luaL_checkinteger(L, 1); + bool result = IsMouseButtonUp(button); + lua_pushboolean(L, result); + return 1; } -// Check if cursor is not visible -int lua_IsCursorHidden(lua_State *L) +// Get mouse position X +static int rl_GetMouseX(lua_State *L) { - bool result = IsCursorHidden(); - LuaPush_bool(L, result); + int result = GetMouseX(); + lua_pushinteger(L, result); return 1; } -// Enables cursor (unlock cursor) -int lua_EnableCursor(lua_State *L) +// Get mouse position Y +static int rl_GetMouseY(lua_State *L) { - EnableCursor(); - return 0; + int result = GetMouseY(); + lua_pushinteger(L, result); + return 1; } -// Disables cursor (lock cursor) -int lua_DisableCursor(lua_State *L) +// Get mouse position XY +static int rl_GetMousePosition(lua_State *L) { - DisableCursor(); - return 0; + Vector2 result = GetMousePosition(); + RLUA_PUSH_Vector2(L, result); + return 1; } -// Drawing-related functions -// Set background color (framebuffer clear color) -int lua_ClearBackground(lua_State *L) +// Get mouse delta between frames +static int rl_GetMouseDelta(lua_State *L) { - Color color = LuaGetArgument_Color(L, 1); - ClearBackground(color); - return 0; + Vector2 result = GetMouseDelta(); + RLUA_PUSH_Vector2(L, result); + return 1; } -// Setup canvas (framebuffer) to start drawing -int lua_BeginDrawing(lua_State *L) +// Set mouse position XY +static int rl_SetMousePosition(lua_State *L) { - BeginDrawing(); + int x = (int)luaL_checkinteger(L, 1); + int y = (int)luaL_checkinteger(L, 2); + SetMousePosition(x, y); return 0; } -// End canvas drawing and swap buffers (double buffering) -int lua_EndDrawing(lua_State *L) +// Set mouse offset +static int rl_SetMouseOffset(lua_State *L) { - EndDrawing(); + int offsetX = (int)luaL_checkinteger(L, 1); + int offsetY = (int)luaL_checkinteger(L, 2); + SetMouseOffset(offsetX, offsetY); return 0; } -// Initialize 2D mode with custom camera (2D) -int lua_BeginMode2D(lua_State *L) +// Set mouse scaling +static int rl_SetMouseScale(lua_State *L) { - Camera2D camera = LuaGetArgument_Camera2D(L, 1); - BeginMode2D(camera); + float scaleX = (float)luaL_checknumber(L, 1); + float scaleY = (float)luaL_checknumber(L, 2); + SetMouseScale(scaleX, scaleY); return 0; } -// Ends 2D mode with custom camera -int lua_EndMode2D(lua_State *L) +// Get mouse wheel movement for X or Y, whichever is larger +static int rl_GetMouseWheelMove(lua_State *L) { - EndMode2D(); - return 0; + float result = GetMouseWheelMove(); + lua_pushnumber(L, result); + return 1; } -// Initializes 3D mode with custom camera (3D) -int lua_BeginMode3D(lua_State *L) +// Get mouse wheel movement for both X and Y +static int rl_GetMouseWheelMoveV(lua_State *L) { - Camera3D camera = LuaGetArgument_Camera3D(L, 1); - BeginMode3D(camera); - return 0; + Vector2 result = GetMouseWheelMoveV(); + RLUA_PUSH_Vector2(L, result); + return 1; } -// Ends 3D mode and returns to default 2D orthographic mode -int lua_EndMode3D(lua_State *L) +// Set mouse cursor +static int rl_SetMouseCursor(lua_State *L) { - EndMode3D(); + int cursor = (int)luaL_checkinteger(L, 1); + SetMouseCursor(cursor); return 0; } -// Initializes render texture for drawing -int lua_BeginTextureMode(lua_State *L) +// Input-related functions: touch +// Get touch position X for touch point 0 (relative to screen size) +static int rl_GetTouchX(lua_State *L) { - RenderTexture2D target = LuaGetArgument_RenderTexture2D(L, 1); - BeginTextureMode(target); - return 0; + int result = GetTouchX(); + lua_pushinteger(L, result); + return 1; } -// Ends drawing to render texture -int lua_EndTextureMode(lua_State *L) +// Get touch position Y for touch point 0 (relative to screen size) +static int rl_GetTouchY(lua_State *L) { - EndTextureMode(); - return 0; + int result = GetTouchY(); + lua_pushinteger(L, result); + return 1; } -// Screen-space-related functions -// Returns a ray trace from mouse position -int lua_GetMouseRay(lua_State *L) +// Get touch position XY for a touch point index (relative to screen size) +static int rl_GetTouchPosition(lua_State *L) { - Vector2 mousePosition = LuaGetArgument_Vector2(L, 1); - Camera camera = LuaGetArgument_Camera(L, 2); - Ray result = GetMouseRay(mousePosition, camera); - LuaPush_Ray(L, result); + int index = (int)luaL_checkinteger(L, 1); + Vector2 result = GetTouchPosition(index); + RLUA_PUSH_Vector2(L, result); return 1; } -// Returns the screen space position for a 3d world space position -int lua_GetWorldToScreen(lua_State *L) +// Get touch point identifier for given index +static int rl_GetTouchPointId(lua_State *L) { - Vector3 position = LuaGetArgument_Vector3(L, 1); - Camera camera = LuaGetArgument_Camera(L, 2); - Vector2 result = GetWorldToScreen(position, camera); - LuaPush_Vector2(L, result); + int index = (int)luaL_checkinteger(L, 1); + int result = GetTouchPointId(index); + lua_pushinteger(L, result); return 1; } -// Returns camera transform matrix (view matrix) -int lua_GetCameraMatrix(lua_State *L) +// Get number of touch points +static int rl_GetTouchPointCount(lua_State *L) { - Camera camera = LuaGetArgument_Camera(L, 1); - Matrix result = GetCameraMatrix(camera); - LuaPush_Matrix(L, result); + int result = GetTouchPointCount(); + lua_pushinteger(L, result); return 1; } -// Timming-related functions -// Set target FPS (maximum) -int lua_SetTargetFPS(lua_State *L) +// ------------------------------------------------------------------------------------ +// Gestures and Touch Handling Functions (Module: rgestures) +// ------------------------------------------------------------------------------------ +// Enable a set of gestures using flags +static int rl_SetGesturesEnabled(lua_State *L) { - int fps = LuaGetArgument_int(L, 1); - SetTargetFPS(fps); + unsigned int flags = (unsigned int)luaL_checkinteger(L, 1); + SetGesturesEnabled(flags); return 0; } -// Returns current FPS -int lua_GetFPS(lua_State *L) +// Check if a gesture have been detected +static int rl_IsGestureDetected(lua_State *L) { - int result = GetFPS(); - LuaPush_int(L, result); + unsigned int gesture = (unsigned int)luaL_checkinteger(L, 1); + bool result = IsGestureDetected(gesture); + lua_pushboolean(L, result); return 1; } -// Returns time in seconds for last frame drawn -int lua_GetFrameTime(lua_State *L) +// Get latest detected gesture +static int rl_GetGestureDetected(lua_State *L) { - float result = GetFrameTime(); - LuaPush_float(L, result); + int result = GetGestureDetected(); + lua_pushinteger(L, result); return 1; } -// Returns elapsed time in seconds since InitWindow() -int lua_GetTime(lua_State *L) +// Get gesture hold time in seconds +static int rl_GetGestureHoldDuration(lua_State *L) { - double result = GetTime(); - LuaPush_double(L, result); + float result = GetGestureHoldDuration(); + lua_pushnumber(L, result); return 1; } -// Color-related functions -// Returns hexadecimal value for a Color -int lua_ColorToInt(lua_State *L) +// Get gesture drag vector +static int rl_GetGestureDragVector(lua_State *L) { - Color color = LuaGetArgument_Color(L, 1); - int result = ColorToInt(color); - LuaPush_int(L, result); + Vector2 result = GetGestureDragVector(); + RLUA_PUSH_Vector2(L, result); return 1; } -// Returns color normalized as float [0..1] -int lua_ColorNormalize(lua_State *L) +// Get gesture drag angle +static int rl_GetGestureDragAngle(lua_State *L) { - Color color = LuaGetArgument_Color(L, 1); - Vector4 result = ColorNormalize(color); - LuaPush_Vector4(L, result); + float result = GetGestureDragAngle(); + lua_pushnumber(L, result); return 1; } -// Returns HSV values for a Color -int lua_ColorToHSV(lua_State *L) +// Get gesture pinch delta +static int rl_GetGesturePinchVector(lua_State *L) { - Color color = LuaGetArgument_Color(L, 1); - Vector3 result = ColorToHSV(color); - LuaPush_Vector3(L, result); + Vector2 result = GetGesturePinchVector(); + RLUA_PUSH_Vector2(L, result); return 1; } -// Returns a Color struct from hexadecimal value -int lua_GetColor(lua_State *L) +// Get gesture pinch angle +static int rl_GetGesturePinchAngle(lua_State *L) { - int hexValue = LuaGetArgument_int(L, 1); - Color result = GetColor(hexValue); - LuaPush_Color(L, result); + float result = GetGesturePinchAngle(); + lua_pushnumber(L, result); return 1; } -// Color fade-in or fade-out, alpha goes from 0.0f to 1.0f -int lua_Fade(lua_State *L) +// ------------------------------------------------------------------------------------ +// Camera System Functions (Module: rcamera) +// ------------------------------------------------------------------------------------ +// Update camera position for selected mode +static int rl_UpdateCamera(lua_State *L) { - Color color = LuaGetArgument_Color(L, 1); - float alpha = LuaGetArgument_float(L, 2); - Color result = Fade(color, alpha); - LuaPush_Color(L, result); - return 1; + Camera camera = RLUA_CHECK_Camera(L, 1); + int mode = (int)luaL_checkinteger(L, 2); + UpdateCamera(&camera, mode); + RLUA_WRITEBACK_Camera(L, 1, camera); + return 0; } -// Misc. functions -// Activate raylib logo at startup (can be done with flags) -int lua_ShowLogo(lua_State *L) +// Update camera movement/rotation +static int rl_UpdateCameraPro(lua_State *L) { - ShowLogo(); + Camera camera = RLUA_CHECK_Camera(L, 1); + Vector3 movement = RLUA_CHECK_Vector3(L, 2); + Vector3 rotation = RLUA_CHECK_Vector3(L, 3); + float zoom = (float)luaL_checknumber(L, 4); + UpdateCameraPro(&camera, movement, rotation, zoom); + RLUA_WRITEBACK_Camera(L, 1, camera); return 0; } -// Setup window configuration flags (view FLAGS) -int lua_SetConfigFlags(lua_State *L) +// ------------------------------------------------------------------------------------ +// Basic Shapes Drawing Functions (Module: shapes) +// ------------------------------------------------------------------------------------ +// Set texture and rectangle to be used on shapes drawing +// NOTE: It can be useful when using basic shapes and one single font, +// defining a font char white rectangle would allow drawing everything in a single draw call +// Set texture and rectangle to be used on shapes drawing +static int rl_SetShapesTexture(lua_State *L) { - unsigned char flags = LuaGetArgument_unsigned(L, 1); - SetConfigFlags(flags); + Texture2D texture = *(Texture2D*)RLUA_CHECK_Resource(L, 1, "Texture2D"); + Rectangle source = RLUA_CHECK_Rectangle(L, 2); + SetShapesTexture(texture, source); return 0; } -// Enable trace log message types (bit flags based) -int lua_SetTraceLog(lua_State *L) +// Get texture that is used for shapes drawing +static int rl_GetShapesTexture(lua_State *L) { - unsigned char types = LuaGetArgument_unsigned(L, 1); - SetTraceLog(types); - return 0; + Texture2D result = GetShapesTexture(); + RLUA_PUSH_Resource(L, &result, sizeof(Texture2D), "Texture2D"); + return 1; } -/* -#if defined(PLATFORM_WEB) -static int LuaDrawLoopFunc; - -static void LuaDrawLoop() +// Get texture source rectangle that is used for shapes drawing +static int rl_GetShapesTextureRectangle(lua_State *L) { - lua_rawgeti(L, LUA_REGISTRYINDEX, LuaDrawLoopFunc); - lua_call(L, 0, 0); + Rectangle result = GetShapesTextureRectangle(); + RLUA_PUSH_Rectangle(L, result); + return 1; } -int lua_SetDrawingLoop(lua_State* L) +// Basic shapes drawing functions +// Draw a pixel using geometry [Can be slow, use with care] +static int rl_DrawPixel(lua_State *L) { - luaL_argcheck(L, lua_isfunction(L, 1), 1, "Loop function expected"); - lua_pushvalue(L, 1); - LuaDrawLoopFunc = luaL_ref(L, LUA_REGISTRYINDEX); - SetDrawingLoop(&LuaDrawLoop); + int posX = (int)luaL_checkinteger(L, 1); + int posY = (int)luaL_checkinteger(L, 2); + Color color = RLUA_CHECK_Color(L, 3); + DrawPixel(posX, posY, color); return 0; } -#else -// Set target FPS (maximum) -int lua_SetTargetFPS(lua_State* L) + +// Draw a pixel using geometry (Vector version) [Can be slow, use with care] +static int rl_DrawPixelV(lua_State *L) { - int arg1 = LuaGetArgument_int(L, 1); - SetTargetFPS(arg1); + Vector2 position = RLUA_CHECK_Vector2(L, 1); + Color color = RLUA_CHECK_Color(L, 2); + DrawPixelV(position, color); return 0; } -#endif -*/ +// Draw a line +static int rl_DrawLine(lua_State *L) +{ + int startPosX = (int)luaL_checkinteger(L, 1); + int startPosY = (int)luaL_checkinteger(L, 2); + int endPosX = (int)luaL_checkinteger(L, 3); + int endPosY = (int)luaL_checkinteger(L, 4); + Color color = RLUA_CHECK_Color(L, 5); + DrawLine(startPosX, startPosY, endPosX, endPosY, color); + return 0; +} -/* -// Converts Color to float array and normalizes -int lua_ColorToFloat(lua_State* L) +// Draw a line (using gl lines) +static int rl_DrawLineV(lua_State *L) { - Color arg1 = LuaGetArgument_Color(L, 1); - float *result = ColorToFloat(arg1); - lua_createtable(L, 4, 0); - for (int i = 0; i < 4; i++) - { - LuaPush_float(L, result[i]); - lua_rawseti(L, -2, i + 1); - } - free(result); - return 1; + Vector2 startPos = RLUA_CHECK_Vector2(L, 1); + Vector2 endPos = RLUA_CHECK_Vector2(L, 2); + Color color = RLUA_CHECK_Color(L, 3); + DrawLineV(startPos, endPos, color); + return 0; } -// Converts Vector3 to float array -int lua_VectorToFloat(lua_State* L) +// Draw a line (using triangles/quads) +static int rl_DrawLineEx(lua_State *L) { - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - float *result = VectorToFloat(arg1); - lua_createtable(L, 3, 0); - for (int i = 0; i < 3; i++) - { - LuaPush_float(L, result[i]); - lua_rawseti(L, -2, i + 1); - } - free(result); - return 1; + Vector2 startPos = RLUA_CHECK_Vector2(L, 1); + Vector2 endPos = RLUA_CHECK_Vector2(L, 2); + float thick = (float)luaL_checknumber(L, 3); + Color color = RLUA_CHECK_Color(L, 4); + DrawLineEx(startPos, endPos, thick, color); + return 0; } -// Converts Matrix to float array -int lua_MatrixToFloat(lua_State* L) +// Draw lines sequence (using gl lines) +static int rl_DrawLineStrip(lua_State *L) { - Matrix arg1 = LuaGetArgument_Matrix(L, 1); - float *result = MatrixToFloat(arg1); - lua_createtable(L, 16, 0); - for (int i = 0; i < 16; i++) - { - LuaPush_float(L, result[i]); - lua_rawseti(L, -2, i + 1); - } - free(result); - return 1; + const Vector2 * points = (const Vector2 *)lua_touserdata(L, 1); + int pointCount = (int)luaL_checkinteger(L, 2); + Color color = RLUA_CHECK_Color(L, 3); + DrawLineStrip(points, pointCount, color); + return 0; } -*/ -// WARNING: Show trace log messages (INFO, WARNING, ERROR, DEBUG) -int lua_TraceLog(lua_State* L) +// Draw line segment cubic-bezier in-out interpolation +static int rl_DrawLineBezier(lua_State *L) { - int num_args = lua_gettop(L) - 1; - int arg1 = LuaGetArgument_int(L, 1); + Vector2 startPos = RLUA_CHECK_Vector2(L, 1); + Vector2 endPos = RLUA_CHECK_Vector2(L, 2); + float thick = (float)luaL_checknumber(L, 3); + Color color = RLUA_CHECK_Color(L, 4); + DrawLineBezier(startPos, endPos, thick, color); + return 0; +} - /// type, fmt, args... +// Draw a dashed line +static int rl_DrawLineDashed(lua_State *L) +{ + Vector2 startPos = RLUA_CHECK_Vector2(L, 1); + Vector2 endPos = RLUA_CHECK_Vector2(L, 2); + int dashSize = (int)luaL_checkinteger(L, 3); + int spaceSize = (int)luaL_checkinteger(L, 4); + Color color = RLUA_CHECK_Color(L, 5); + DrawLineDashed(startPos, endPos, dashSize, spaceSize, color); + return 0; +} - lua_rotate(L, 1, -1); /// fmt, args..., type - lua_pop(L, 1); /// fmt, args... +// Draw a color-filled circle +static int rl_DrawCircle(lua_State *L) +{ + int centerX = (int)luaL_checkinteger(L, 1); + int centerY = (int)luaL_checkinteger(L, 2); + float radius = (float)luaL_checknumber(L, 3); + Color color = RLUA_CHECK_Color(L, 4); + DrawCircle(centerX, centerY, radius, color); + return 0; +} - lua_getglobal(L, "string"); /// fmt, args..., [string] - lua_getfield(L, 1, "format"); /// fmt, args..., [string], format() - lua_rotate(L, 1, 2); /// [string], format(), fmt, args... - lua_call(L, num_args, 1); /// [string], formatted_string +// Draw a color-filled circle (Vector version) +static int rl_DrawCircleV(lua_State *L) +{ + Vector2 center = RLUA_CHECK_Vector2(L, 1); + float radius = (float)luaL_checknumber(L, 2); + Color color = RLUA_CHECK_Color(L, 3); + DrawCircleV(center, radius, color); + return 0; +} - TraceLog(arg1, "%s", luaL_checkstring(L,-1)); +// Draw a gradient-filled circle +static int rl_DrawCircleGradient(lua_State *L) +{ + Vector2 center = RLUA_CHECK_Vector2(L, 1); + float radius = (float)luaL_checknumber(L, 2); + Color inner = RLUA_CHECK_Color(L, 3); + Color outer = RLUA_CHECK_Color(L, 4); + DrawCircleGradient(center, radius, inner, outer); return 0; } -// Takes a screenshot of current screen (saved a .png) -int lua_TakeScreenshot(lua_State *L) +// Draw a piece of a circle +static int rl_DrawCircleSector(lua_State *L) { - const char *fileName = LuaGetArgument_string(L, 1); - TakeScreenshot(fileName); + Vector2 center = RLUA_CHECK_Vector2(L, 1); + float radius = (float)luaL_checknumber(L, 2); + float startAngle = (float)luaL_checknumber(L, 3); + float endAngle = (float)luaL_checknumber(L, 4); + int segments = (int)luaL_checkinteger(L, 5); + Color color = RLUA_CHECK_Color(L, 6); + DrawCircleSector(center, radius, startAngle, endAngle, segments, color); return 0; } -// Returns a random value between min and max (both included) -int lua_GetRandomValue(lua_State *L) +// Draw circle sector outline +static int rl_DrawCircleSectorLines(lua_State *L) { - int min = LuaGetArgument_int(L, 1); - int max = LuaGetArgument_int(L, 2); - int result = GetRandomValue(min, max); - LuaPush_int(L, result); - return 1; + Vector2 center = RLUA_CHECK_Vector2(L, 1); + float radius = (float)luaL_checknumber(L, 2); + float startAngle = (float)luaL_checknumber(L, 3); + float endAngle = (float)luaL_checknumber(L, 4); + int segments = (int)luaL_checkinteger(L, 5); + Color color = RLUA_CHECK_Color(L, 6); + DrawCircleSectorLines(center, radius, startAngle, endAngle, segments, color); + return 0; } -// Check file extension -int lua_IsFileExtension(lua_State *L) +// Draw circle outline +static int rl_DrawCircleLines(lua_State *L) { - const char *fileName = LuaGetArgument_string(L, 1); - const char *ext = LuaGetArgument_string(L, 2); - bool result = IsFileExtension(fileName, ext); - LuaPush_bool(L, result); - return 1; + int centerX = (int)luaL_checkinteger(L, 1); + int centerY = (int)luaL_checkinteger(L, 2); + float radius = (float)luaL_checknumber(L, 3); + Color color = RLUA_CHECK_Color(L, 4); + DrawCircleLines(centerX, centerY, radius, color); + return 0; } -// WARNING: Get pointer to extension for a filename string -int lua_GetExtension(lua_State *L) +// Draw circle outline (Vector version) +static int rl_DrawCircleLinesV(lua_State *L) { - const char *fileName = LuaGetArgument_string(L, 1); - const char *result = GetExtension(fileName); - LuaPush_string(L, result); - return 1; + Vector2 center = RLUA_CHECK_Vector2(L, 1); + float radius = (float)luaL_checknumber(L, 2); + Color color = RLUA_CHECK_Color(L, 3); + DrawCircleLinesV(center, radius, color); + return 0; } -// Get pointer to filename for a path string -int lua_GetFileName(lua_State *L) +// Draw ellipse +static int rl_DrawEllipse(lua_State *L) { - const char *filePath = LuaGetArgument_string(L, 1); - string result = GetFileName(filePath); - LuaPush_string(L, result); - return 1; + int centerX = (int)luaL_checkinteger(L, 1); + int centerY = (int)luaL_checkinteger(L, 2); + float radiusH = (float)luaL_checknumber(L, 3); + float radiusV = (float)luaL_checknumber(L, 4); + Color color = RLUA_CHECK_Color(L, 5); + DrawEllipse(centerX, centerY, radiusH, radiusV, color); + return 0; } -// Get full path for a given fileName (uses static string) -int lua_GetDirectoryPath(lua_State *L) +// Draw ellipse (Vector version) +static int rl_DrawEllipseV(lua_State *L) { - const char *fileName = LuaGetArgument_string(L, 1); - string result = GetDirectoryPath(fileName); - LuaPush_string(L, result); - return 1; + Vector2 center = RLUA_CHECK_Vector2(L, 1); + float radiusH = (float)luaL_checknumber(L, 2); + float radiusV = (float)luaL_checknumber(L, 3); + Color color = RLUA_CHECK_Color(L, 4); + DrawEllipseV(center, radiusH, radiusV, color); + return 0; } -// Get current working directory (uses static string) -int lua_GetWorkingDirectory(lua_State *L) +// Draw ellipse outline +static int rl_DrawEllipseLines(lua_State *L) { - string result = GetWorkingDirectory(); - LuaPush_string(L, result); - return 1; + int centerX = (int)luaL_checkinteger(L, 1); + int centerY = (int)luaL_checkinteger(L, 2); + float radiusH = (float)luaL_checknumber(L, 3); + float radiusV = (float)luaL_checknumber(L, 4); + Color color = RLUA_CHECK_Color(L, 5); + DrawEllipseLines(centerX, centerY, radiusH, radiusV, color); + return 0; } -// Change working directory, returns true if success -int lua_ChangeDirectory(lua_State *L) +// Draw ellipse outline (Vector version) +static int rl_DrawEllipseLinesV(lua_State *L) { - const char *dir = LuaGetArgument_string(L, 1); - bool result = ChangeDirectory(dir); - LuaPush_bool(L, result); - return 1; + Vector2 center = RLUA_CHECK_Vector2(L, 1); + float radiusH = (float)luaL_checknumber(L, 2); + float radiusV = (float)luaL_checknumber(L, 3); + Color color = RLUA_CHECK_Color(L, 4); + DrawEllipseLinesV(center, radiusH, radiusV, color); + return 0; } -// Check if a file has been dropped into window -int lua_IsFileDropped(lua_State* L) +// Draw ring +static int rl_DrawRing(lua_State *L) { - bool result = IsFileDropped(); - LuaPush_bool(L, result); - return 1; + Vector2 center = RLUA_CHECK_Vector2(L, 1); + float innerRadius = (float)luaL_checknumber(L, 2); + float outerRadius = (float)luaL_checknumber(L, 3); + float startAngle = (float)luaL_checknumber(L, 4); + float endAngle = (float)luaL_checknumber(L, 5); + int segments = (int)luaL_checkinteger(L, 6); + Color color = RLUA_CHECK_Color(L, 7); + DrawRing(center, innerRadius, outerRadius, startAngle, endAngle, segments, color); + return 0; } -// WARNING: Get dropped files names -int lua_GetDroppedFiles(lua_State* L) +// Draw ring outline +static int rl_DrawRingLines(lua_State *L) { - int count = 0; - char **result = GetDroppedFiles(&count); - lua_createtable(L, count, 0); - for (int i = 0; i < count; i++) - { - LuaPush_string(L, result[i]); - lua_rawseti(L, -2, i + 1); - } - return 1; + Vector2 center = RLUA_CHECK_Vector2(L, 1); + float innerRadius = (float)luaL_checknumber(L, 2); + float outerRadius = (float)luaL_checknumber(L, 3); + float startAngle = (float)luaL_checknumber(L, 4); + float endAngle = (float)luaL_checknumber(L, 5); + int segments = (int)luaL_checkinteger(L, 6); + Color color = RLUA_CHECK_Color(L, 7); + DrawRingLines(center, innerRadius, outerRadius, startAngle, endAngle, segments, color); + return 0; } -// Clear dropped files paths buffer -int lua_ClearDroppedFiles(lua_State* L) +// Draw a color-filled rectangle +static int rl_DrawRectangle(lua_State *L) { - ClearDroppedFiles(); + int posX = (int)luaL_checkinteger(L, 1); + int posY = (int)luaL_checkinteger(L, 2); + int width = (int)luaL_checkinteger(L, 3); + int height = (int)luaL_checkinteger(L, 4); + Color color = RLUA_CHECK_Color(L, 5); + DrawRectangle(posX, posY, width, height, color); return 0; } -// Save integer value to storage file (to defined position) -int lua_StorageSaveValue(lua_State *L) +// Draw a color-filled rectangle (Vector version) +static int rl_DrawRectangleV(lua_State *L) { - int position = LuaGetArgument_int(L, 1); - int value = LuaGetArgument_int(L, 2); - StorageSaveValue(position, value); + Vector2 position = RLUA_CHECK_Vector2(L, 1); + Vector2 size = RLUA_CHECK_Vector2(L, 2); + Color color = RLUA_CHECK_Color(L, 3); + DrawRectangleV(position, size, color); return 0; } -// Load integer value from storage file (from defined position) -int lua_StorageLoadValue(lua_State *L) +// Draw a color-filled rectangle +static int rl_DrawRectangleRec(lua_State *L) { - int position = LuaGetArgument_int(L, 1); - int result = StorageLoadValue(position); - LuaPush_int(L, result); - return 1; + Rectangle rec = RLUA_CHECK_Rectangle(L, 1); + Color color = RLUA_CHECK_Color(L, 2); + DrawRectangleRec(rec, color); + return 0; } -//------------------------------------------------------------------------------------ -// raylib [core] module functions - Input Handling -//------------------------------------------------------------------------------------ +// Draw a color-filled rectangle with pro parameters +static int rl_DrawRectanglePro(lua_State *L) +{ + Rectangle rec = RLUA_CHECK_Rectangle(L, 1); + Vector2 origin = RLUA_CHECK_Vector2(L, 2); + float rotation = (float)luaL_checknumber(L, 3); + Color color = RLUA_CHECK_Color(L, 4); + DrawRectanglePro(rec, origin, rotation, color); + return 0; +} -// Detect if a key has been pressed once -int lua_IsKeyPressed(lua_State *L) +// Draw a vertical-gradient-filled rectangle +static int rl_DrawRectangleGradientV(lua_State *L) { - int key = LuaGetArgument_int(L, 1); - bool result = IsKeyPressed(key); - LuaPush_bool(L, result); - return 1; + int posX = (int)luaL_checkinteger(L, 1); + int posY = (int)luaL_checkinteger(L, 2); + int width = (int)luaL_checkinteger(L, 3); + int height = (int)luaL_checkinteger(L, 4); + Color top = RLUA_CHECK_Color(L, 5); + Color bottom = RLUA_CHECK_Color(L, 6); + DrawRectangleGradientV(posX, posY, width, height, top, bottom); + return 0; } -// Detect if a key is being pressed -int lua_IsKeyDown(lua_State *L) +// Draw a horizontal-gradient-filled rectangle +static int rl_DrawRectangleGradientH(lua_State *L) { - int key = LuaGetArgument_int(L, 1); - bool result = IsKeyDown(key); - LuaPush_bool(L, result); - return 1; + int posX = (int)luaL_checkinteger(L, 1); + int posY = (int)luaL_checkinteger(L, 2); + int width = (int)luaL_checkinteger(L, 3); + int height = (int)luaL_checkinteger(L, 4); + Color left = RLUA_CHECK_Color(L, 5); + Color right = RLUA_CHECK_Color(L, 6); + DrawRectangleGradientH(posX, posY, width, height, left, right); + return 0; } -// Detect if a key has been released once -int lua_IsKeyReleased(lua_State *L) +// Draw a gradient-filled rectangle with custom vertex colors +static int rl_DrawRectangleGradientEx(lua_State *L) { - int key = LuaGetArgument_int(L, 1); - bool result = IsKeyReleased(key); - LuaPush_bool(L, result); - return 1; + Rectangle rec = RLUA_CHECK_Rectangle(L, 1); + Color topLeft = RLUA_CHECK_Color(L, 2); + Color bottomLeft = RLUA_CHECK_Color(L, 3); + Color bottomRight = RLUA_CHECK_Color(L, 4); + Color topRight = RLUA_CHECK_Color(L, 5); + DrawRectangleGradientEx(rec, topLeft, bottomLeft, bottomRight, topRight); + return 0; } -// Detect if a key is NOT being pressed -int lua_IsKeyUp(lua_State *L) +// Draw rectangle outline +static int rl_DrawRectangleLines(lua_State *L) { - int key = LuaGetArgument_int(L, 1); - bool result = IsKeyUp(key); - LuaPush_bool(L, result); - return 1; + int posX = (int)luaL_checkinteger(L, 1); + int posY = (int)luaL_checkinteger(L, 2); + int width = (int)luaL_checkinteger(L, 3); + int height = (int)luaL_checkinteger(L, 4); + Color color = RLUA_CHECK_Color(L, 5); + DrawRectangleLines(posX, posY, width, height, color); + return 0; } -// Get latest key pressed -int lua_GetKeyPressed(lua_State *L) +// Draw rectangle outline with extended parameters +static int rl_DrawRectangleLinesEx(lua_State *L) { - int result = GetKeyPressed(); - LuaPush_int(L, result); - return 1; + Rectangle rec = RLUA_CHECK_Rectangle(L, 1); + float lineThick = (float)luaL_checknumber(L, 2); + Color color = RLUA_CHECK_Color(L, 3); + DrawRectangleLinesEx(rec, lineThick, color); + return 0; } -// Set a custom key to exit program (default is ESC) -int lua_SetExitKey(lua_State *L) +// Draw rectangle with rounded edges +static int rl_DrawRectangleRounded(lua_State *L) { - int key = LuaGetArgument_int(L, 1); - SetExitKey(key); + Rectangle rec = RLUA_CHECK_Rectangle(L, 1); + float roundness = (float)luaL_checknumber(L, 2); + int segments = (int)luaL_checkinteger(L, 3); + Color color = RLUA_CHECK_Color(L, 4); + DrawRectangleRounded(rec, roundness, segments, color); return 0; } -// Input-related functions: gamepads -// Detect if a gamepad is available -int lua_IsGamepadAvailable(lua_State *L) +// Draw rectangle lines with rounded edges +static int rl_DrawRectangleRoundedLines(lua_State *L) { - int gamepad = LuaGetArgument_int(L, 1); - bool result = IsGamepadAvailable(gamepad); - LuaPush_bool(L, result); - return 1; + Rectangle rec = RLUA_CHECK_Rectangle(L, 1); + float roundness = (float)luaL_checknumber(L, 2); + int segments = (int)luaL_checkinteger(L, 3); + Color color = RLUA_CHECK_Color(L, 4); + DrawRectangleRoundedLines(rec, roundness, segments, color); + return 0; } -// WARNING: Check gamepad name (if available) -int lua_IsGamepadName(lua_State* L) +// Draw rectangle with rounded edges outline +static int rl_DrawRectangleRoundedLinesEx(lua_State *L) { - int arg1 = LuaGetArgument_int(L, 1); - const char *arg2 = LuaGetArgument_string(L, 2); - bool result = IsGamepadName(arg1, arg2); - LuaPush_bool(L, result); - return 1; + Rectangle rec = RLUA_CHECK_Rectangle(L, 1); + float roundness = (float)luaL_checknumber(L, 2); + int segments = (int)luaL_checkinteger(L, 3); + float lineThick = (float)luaL_checknumber(L, 4); + Color color = RLUA_CHECK_Color(L, 5); + DrawRectangleRoundedLinesEx(rec, roundness, segments, lineThick, color); + return 0; } -// WARNING: Return gamepad internal name id -int lua_GetGamepadName(lua_State* L) +// Draw a color-filled triangle (vertex in counter-clockwise order!) +static int rl_DrawTriangle(lua_State *L) { - int arg1 = LuaGetArgument_int(L, 1); - const char *result = GetGamepadName(arg1); - LuaPush_string(L, result); - return 1; + Vector2 v1 = RLUA_CHECK_Vector2(L, 1); + Vector2 v2 = RLUA_CHECK_Vector2(L, 2); + Vector2 v3 = RLUA_CHECK_Vector2(L, 3); + Color color = RLUA_CHECK_Color(L, 4); + DrawTriangle(v1, v2, v3, color); + return 0; } -// Detect if a gamepad button has been pressed once -int lua_IsGamepadButtonPressed(lua_State *L) +// Draw triangle outline (vertex in counter-clockwise order!) +static int rl_DrawTriangleLines(lua_State *L) { - int gamepad = LuaGetArgument_int(L, 1); - int button = LuaGetArgument_int(L, 2); - bool result = IsGamepadButtonPressed(gamepad, button); - LuaPush_bool(L, result); - return 1; + Vector2 v1 = RLUA_CHECK_Vector2(L, 1); + Vector2 v2 = RLUA_CHECK_Vector2(L, 2); + Vector2 v3 = RLUA_CHECK_Vector2(L, 3); + Color color = RLUA_CHECK_Color(L, 4); + DrawTriangleLines(v1, v2, v3, color); + return 0; } -// Detect if a gamepad button is being pressed -int lua_IsGamepadButtonDown(lua_State *L) +// Draw a triangle fan defined by points (first vertex is the center) +static int rl_DrawTriangleFan(lua_State *L) { - int gamepad = LuaGetArgument_int(L, 1); - int button = LuaGetArgument_int(L, 2); - bool result = IsGamepadButtonDown(gamepad, button); - LuaPush_bool(L, result); - return 1; + const Vector2 * points = (const Vector2 *)lua_touserdata(L, 1); + int pointCount = (int)luaL_checkinteger(L, 2); + Color color = RLUA_CHECK_Color(L, 3); + DrawTriangleFan(points, pointCount, color); + return 0; } -// Detect if a gamepad button has been released once -int lua_IsGamepadButtonReleased(lua_State *L) +// Draw a triangle strip defined by points +static int rl_DrawTriangleStrip(lua_State *L) { - int gamepad = LuaGetArgument_int(L, 1); - int button = LuaGetArgument_int(L, 2); - bool result = IsGamepadButtonReleased(gamepad, button); - LuaPush_bool(L, result); - return 1; + const Vector2 * points = (const Vector2 *)lua_touserdata(L, 1); + int pointCount = (int)luaL_checkinteger(L, 2); + Color color = RLUA_CHECK_Color(L, 3); + DrawTriangleStrip(points, pointCount, color); + return 0; } -// Detect if a gamepad button is NOT being pressed -int lua_IsGamepadButtonUp(lua_State *L) +// Draw a regular polygon (Vector version) +static int rl_DrawPoly(lua_State *L) { - int gamepad = LuaGetArgument_int(L, 1); - int button = LuaGetArgument_int(L, 2); - bool result = IsGamepadButtonUp(gamepad, button); - LuaPush_bool(L, result); - return 1; + Vector2 center = RLUA_CHECK_Vector2(L, 1); + int sides = (int)luaL_checkinteger(L, 2); + float radius = (float)luaL_checknumber(L, 3); + float rotation = (float)luaL_checknumber(L, 4); + Color color = RLUA_CHECK_Color(L, 5); + DrawPoly(center, sides, radius, rotation, color); + return 0; } -// Get the last gamepad button pressed -int lua_GetGamepadButtonPressed(lua_State *L) +// Draw a polygon outline of n sides +static int rl_DrawPolyLines(lua_State *L) { - int result = GetGamepadButtonPressed(); - LuaPush_int(L, result); - return 1; + Vector2 center = RLUA_CHECK_Vector2(L, 1); + int sides = (int)luaL_checkinteger(L, 2); + float radius = (float)luaL_checknumber(L, 3); + float rotation = (float)luaL_checknumber(L, 4); + Color color = RLUA_CHECK_Color(L, 5); + DrawPolyLines(center, sides, radius, rotation, color); + return 0; } -// Return gamepad axis count for a gamepad -int lua_GetGamepadAxisCount(lua_State *L) +// Draw a polygon outline of n sides with extended parameters +static int rl_DrawPolyLinesEx(lua_State *L) { - int gamepad = LuaGetArgument_int(L, 1); - int result = GetGamepadAxisCount(gamepad); - LuaPush_int(L, result); - return 1; + Vector2 center = RLUA_CHECK_Vector2(L, 1); + int sides = (int)luaL_checkinteger(L, 2); + float radius = (float)luaL_checknumber(L, 3); + float rotation = (float)luaL_checknumber(L, 4); + float lineThick = (float)luaL_checknumber(L, 5); + Color color = RLUA_CHECK_Color(L, 6); + DrawPolyLinesEx(center, sides, radius, rotation, lineThick, color); + return 0; } -// Return axis movement value for a gamepad axis -int lua_GetGamepadAxisMovement(lua_State *L) +// Splines drawing functions +// Draw spline: Linear, minimum 2 points +static int rl_DrawSplineLinear(lua_State *L) { - int gamepad = LuaGetArgument_int(L, 1); - int axis = LuaGetArgument_int(L, 2); - float result = GetGamepadAxisMovement(gamepad, axis); - LuaPush_float(L, result); - return 1; + const Vector2 * points = (const Vector2 *)lua_touserdata(L, 1); + int pointCount = (int)luaL_checkinteger(L, 2); + float thick = (float)luaL_checknumber(L, 3); + Color color = RLUA_CHECK_Color(L, 4); + DrawSplineLinear(points, pointCount, thick, color); + return 0; } -// Input-related functions: mouse -// Detect if a mouse button has been pressed once -int lua_IsMouseButtonPressed(lua_State *L) +// Draw spline: B-Spline, minimum 4 points +static int rl_DrawSplineBasis(lua_State *L) { - int button = LuaGetArgument_int(L, 1); - bool result = IsMouseButtonPressed(button); - LuaPush_bool(L, result); - return 1; + const Vector2 * points = (const Vector2 *)lua_touserdata(L, 1); + int pointCount = (int)luaL_checkinteger(L, 2); + float thick = (float)luaL_checknumber(L, 3); + Color color = RLUA_CHECK_Color(L, 4); + DrawSplineBasis(points, pointCount, thick, color); + return 0; } -// Detect if a mouse button is being pressed -int lua_IsMouseButtonDown(lua_State *L) +// Draw spline: Catmull-Rom, minimum 4 points +static int rl_DrawSplineCatmullRom(lua_State *L) { - int button = LuaGetArgument_int(L, 1); - bool result = IsMouseButtonDown(button); - LuaPush_bool(L, result); - return 1; + const Vector2 * points = (const Vector2 *)lua_touserdata(L, 1); + int pointCount = (int)luaL_checkinteger(L, 2); + float thick = (float)luaL_checknumber(L, 3); + Color color = RLUA_CHECK_Color(L, 4); + DrawSplineCatmullRom(points, pointCount, thick, color); + return 0; } -// Detect if a mouse button has been released once -int lua_IsMouseButtonReleased(lua_State *L) +// Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...] +static int rl_DrawSplineBezierQuadratic(lua_State *L) { - int button = LuaGetArgument_int(L, 1); - bool result = IsMouseButtonReleased(button); - LuaPush_bool(L, result); - return 1; + const Vector2 * points = (const Vector2 *)lua_touserdata(L, 1); + int pointCount = (int)luaL_checkinteger(L, 2); + float thick = (float)luaL_checknumber(L, 3); + Color color = RLUA_CHECK_Color(L, 4); + DrawSplineBezierQuadratic(points, pointCount, thick, color); + return 0; } -// Detect if a mouse button is NOT being pressed -int lua_IsMouseButtonUp(lua_State *L) +// Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...] +static int rl_DrawSplineBezierCubic(lua_State *L) { - int button = LuaGetArgument_int(L, 1); - bool result = IsMouseButtonUp(button); - LuaPush_bool(L, result); - return 1; + const Vector2 * points = (const Vector2 *)lua_touserdata(L, 1); + int pointCount = (int)luaL_checkinteger(L, 2); + float thick = (float)luaL_checknumber(L, 3); + Color color = RLUA_CHECK_Color(L, 4); + DrawSplineBezierCubic(points, pointCount, thick, color); + return 0; } -// Returns mouse position X -int lua_GetMouseX(lua_State *L) +// Draw spline segment: Linear, 2 points +static int rl_DrawSplineSegmentLinear(lua_State *L) { - int result = GetMouseX(); - LuaPush_int(L, result); - return 1; + Vector2 p1 = RLUA_CHECK_Vector2(L, 1); + Vector2 p2 = RLUA_CHECK_Vector2(L, 2); + float thick = (float)luaL_checknumber(L, 3); + Color color = RLUA_CHECK_Color(L, 4); + DrawSplineSegmentLinear(p1, p2, thick, color); + return 0; } -// Returns mouse position Y -int lua_GetMouseY(lua_State *L) +// Draw spline segment: B-Spline, 4 points +static int rl_DrawSplineSegmentBasis(lua_State *L) { - int result = GetMouseY(); - LuaPush_int(L, result); - return 1; + Vector2 p1 = RLUA_CHECK_Vector2(L, 1); + Vector2 p2 = RLUA_CHECK_Vector2(L, 2); + Vector2 p3 = RLUA_CHECK_Vector2(L, 3); + Vector2 p4 = RLUA_CHECK_Vector2(L, 4); + float thick = (float)luaL_checknumber(L, 5); + Color color = RLUA_CHECK_Color(L, 6); + DrawSplineSegmentBasis(p1, p2, p3, p4, thick, color); + return 0; } -// Returns mouse position XY -int lua_GetMousePosition(lua_State *L) +// Draw spline segment: Catmull-Rom, 4 points +static int rl_DrawSplineSegmentCatmullRom(lua_State *L) { - Vector2 result = GetMousePosition(); - LuaPush_Vector2(L, result); - return 1; + Vector2 p1 = RLUA_CHECK_Vector2(L, 1); + Vector2 p2 = RLUA_CHECK_Vector2(L, 2); + Vector2 p3 = RLUA_CHECK_Vector2(L, 3); + Vector2 p4 = RLUA_CHECK_Vector2(L, 4); + float thick = (float)luaL_checknumber(L, 5); + Color color = RLUA_CHECK_Color(L, 6); + DrawSplineSegmentCatmullRom(p1, p2, p3, p4, thick, color); + return 0; } -// Set mouse position XY -int lua_SetMousePosition(lua_State *L) +// Draw spline segment: Quadratic Bezier, 2 points, 1 control point +static int rl_DrawSplineSegmentBezierQuadratic(lua_State *L) { - Vector2 position = LuaGetArgument_Vector2(L, 1); - SetMousePosition(position); + Vector2 p1 = RLUA_CHECK_Vector2(L, 1); + Vector2 c2 = RLUA_CHECK_Vector2(L, 2); + Vector2 p3 = RLUA_CHECK_Vector2(L, 3); + float thick = (float)luaL_checknumber(L, 4); + Color color = RLUA_CHECK_Color(L, 5); + DrawSplineSegmentBezierQuadratic(p1, c2, p3, thick, color); return 0; } -// Set mouse scaling -int lua_SetMouseScale(lua_State *L) +// Draw spline segment: Cubic Bezier, 2 points, 2 control points +static int rl_DrawSplineSegmentBezierCubic(lua_State *L) { - float scale = LuaGetArgument_float(L, 1); - SetMouseScale(scale); + Vector2 p1 = RLUA_CHECK_Vector2(L, 1); + Vector2 c2 = RLUA_CHECK_Vector2(L, 2); + Vector2 c3 = RLUA_CHECK_Vector2(L, 3); + Vector2 p4 = RLUA_CHECK_Vector2(L, 4); + float thick = (float)luaL_checknumber(L, 5); + Color color = RLUA_CHECK_Color(L, 6); + DrawSplineSegmentBezierCubic(p1, c2, c3, p4, thick, color); return 0; } -// Returns mouse wheel movement Y -int lua_GetMouseWheelMove(lua_State *L) +// Spline segment point evaluation functions, for a given t [0.0f .. 1.0f] +// Get (evaluate) spline point: Linear +static int rl_GetSplinePointLinear(lua_State *L) { - int result = GetMouseWheelMove(); - LuaPush_int(L, result); + Vector2 startPos = RLUA_CHECK_Vector2(L, 1); + Vector2 endPos = RLUA_CHECK_Vector2(L, 2); + float t = (float)luaL_checknumber(L, 3); + Vector2 result = GetSplinePointLinear(startPos, endPos, t); + RLUA_PUSH_Vector2(L, result); return 1; } -// Input-related functions: touch -// Returns touch position X for touch point 0 (relative to screen size) -int lua_GetTouchX(lua_State *L) +// Get (evaluate) spline point: B-Spline +static int rl_GetSplinePointBasis(lua_State *L) { - int result = GetTouchX(); - LuaPush_int(L, result); + Vector2 p1 = RLUA_CHECK_Vector2(L, 1); + Vector2 p2 = RLUA_CHECK_Vector2(L, 2); + Vector2 p3 = RLUA_CHECK_Vector2(L, 3); + Vector2 p4 = RLUA_CHECK_Vector2(L, 4); + float t = (float)luaL_checknumber(L, 5); + Vector2 result = GetSplinePointBasis(p1, p2, p3, p4, t); + RLUA_PUSH_Vector2(L, result); return 1; } -// Returns touch position Y for touch point 0 (relative to screen size) -int lua_GetTouchY(lua_State *L) +// Get (evaluate) spline point: Catmull-Rom +static int rl_GetSplinePointCatmullRom(lua_State *L) { - int result = GetTouchY(); - LuaPush_int(L, result); + Vector2 p1 = RLUA_CHECK_Vector2(L, 1); + Vector2 p2 = RLUA_CHECK_Vector2(L, 2); + Vector2 p3 = RLUA_CHECK_Vector2(L, 3); + Vector2 p4 = RLUA_CHECK_Vector2(L, 4); + float t = (float)luaL_checknumber(L, 5); + Vector2 result = GetSplinePointCatmullRom(p1, p2, p3, p4, t); + RLUA_PUSH_Vector2(L, result); return 1; } -// Returns touch position XY for a touch point index (relative to screen size) -int lua_GetTouchPosition(lua_State *L) +// Get (evaluate) spline point: Quadratic Bezier +static int rl_GetSplinePointBezierQuad(lua_State *L) { - int index = LuaGetArgument_int(L, 1); - Vector2 result = GetTouchPosition(index); - LuaPush_Vector2(L, result); + Vector2 p1 = RLUA_CHECK_Vector2(L, 1); + Vector2 c2 = RLUA_CHECK_Vector2(L, 2); + Vector2 p3 = RLUA_CHECK_Vector2(L, 3); + float t = (float)luaL_checknumber(L, 4); + Vector2 result = GetSplinePointBezierQuad(p1, c2, p3, t); + RLUA_PUSH_Vector2(L, result); return 1; } -//------------------------------------------------------------------------------------ -// raylib [gestures] module functions - Gestures and Touch Handling -//------------------------------------------------------------------------------------ - -// Enable a set of gestures using flags -int lua_SetGesturesEnabled(lua_State *L) +// Get (evaluate) spline point: Cubic Bezier +static int rl_GetSplinePointBezierCubic(lua_State *L) { - unsigned int gestureFlags = LuaGetArgument_unsigned(L, 1); - SetGesturesEnabled(gestureFlags); - return 0; + Vector2 p1 = RLUA_CHECK_Vector2(L, 1); + Vector2 c2 = RLUA_CHECK_Vector2(L, 2); + Vector2 c3 = RLUA_CHECK_Vector2(L, 3); + Vector2 p4 = RLUA_CHECK_Vector2(L, 4); + float t = (float)luaL_checknumber(L, 5); + Vector2 result = GetSplinePointBezierCubic(p1, c2, c3, p4, t); + RLUA_PUSH_Vector2(L, result); + return 1; } -// Check if a gesture have been detected -int lua_IsGestureDetected(lua_State *L) +// Basic shapes collision detection functions +// Check collision between two rectangles +static int rl_CheckCollisionRecs(lua_State *L) { - int gesture = LuaGetArgument_int(L, 1); - bool result = IsGestureDetected(gesture); - LuaPush_bool(L, result); + Rectangle rec1 = RLUA_CHECK_Rectangle(L, 1); + Rectangle rec2 = RLUA_CHECK_Rectangle(L, 2); + bool result = CheckCollisionRecs(rec1, rec2); + lua_pushboolean(L, result); return 1; } -// Get latest detected gesture -int lua_GetGestureDetected(lua_State *L) +// Check collision between two circles +static int rl_CheckCollisionCircles(lua_State *L) { - int result = GetGestureDetected(); - LuaPush_int(L, result); + Vector2 center1 = RLUA_CHECK_Vector2(L, 1); + float radius1 = (float)luaL_checknumber(L, 2); + Vector2 center2 = RLUA_CHECK_Vector2(L, 3); + float radius2 = (float)luaL_checknumber(L, 4); + bool result = CheckCollisionCircles(center1, radius1, center2, radius2); + lua_pushboolean(L, result); return 1; } -// Get touch points count -int lua_GetTouchPointsCount(lua_State *L) +// Check collision between circle and rectangle +static int rl_CheckCollisionCircleRec(lua_State *L) { - int result = GetTouchPointsCount(); - LuaPush_int(L, result); + Vector2 center = RLUA_CHECK_Vector2(L, 1); + float radius = (float)luaL_checknumber(L, 2); + Rectangle rec = RLUA_CHECK_Rectangle(L, 3); + bool result = CheckCollisionCircleRec(center, radius, rec); + lua_pushboolean(L, result); return 1; } -// Get gesture hold time in milliseconds -int lua_GetGestureHoldDuration(lua_State *L) +// Check if circle collides with a line created betweeen two points [p1] and [p2] +static int rl_CheckCollisionCircleLine(lua_State *L) { - float result = GetGestureHoldDuration(); - LuaPush_float(L, result); + Vector2 center = RLUA_CHECK_Vector2(L, 1); + float radius = (float)luaL_checknumber(L, 2); + Vector2 p1 = RLUA_CHECK_Vector2(L, 3); + Vector2 p2 = RLUA_CHECK_Vector2(L, 4); + bool result = CheckCollisionCircleLine(center, radius, p1, p2); + lua_pushboolean(L, result); return 1; } -// Get gesture drag vector -int lua_GetGestureDragVector(lua_State *L) +// Check if point is inside rectangle +static int rl_CheckCollisionPointRec(lua_State *L) { - Vector2 result = GetGestureDragVector(); - LuaPush_Vector2(L, result); + Vector2 point = RLUA_CHECK_Vector2(L, 1); + Rectangle rec = RLUA_CHECK_Rectangle(L, 2); + bool result = CheckCollisionPointRec(point, rec); + lua_pushboolean(L, result); return 1; } -// Get gesture drag angle -int lua_GetGestureDragAngle(lua_State *L) +// Check if point is inside circle +static int rl_CheckCollisionPointCircle(lua_State *L) { - float result = GetGestureDragAngle(); - LuaPush_float(L, result); + Vector2 point = RLUA_CHECK_Vector2(L, 1); + Vector2 center = RLUA_CHECK_Vector2(L, 2); + float radius = (float)luaL_checknumber(L, 3); + bool result = CheckCollisionPointCircle(point, center, radius); + lua_pushboolean(L, result); return 1; } -// Get gesture pinch delta -int lua_GetGesturePinchVector(lua_State *L) +// Check if point is inside a triangle +static int rl_CheckCollisionPointTriangle(lua_State *L) { - Vector2 result = GetGesturePinchVector(); - LuaPush_Vector2(L, result); + Vector2 point = RLUA_CHECK_Vector2(L, 1); + Vector2 p1 = RLUA_CHECK_Vector2(L, 2); + Vector2 p2 = RLUA_CHECK_Vector2(L, 3); + Vector2 p3 = RLUA_CHECK_Vector2(L, 4); + bool result = CheckCollisionPointTriangle(point, p1, p2, p3); + lua_pushboolean(L, result); return 1; } -// Get gesture pinch angle -int lua_GetGesturePinchAngle(lua_State *L) +// Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold] +static int rl_CheckCollisionPointLine(lua_State *L) { - float result = GetGesturePinchAngle(); - LuaPush_float(L, result); + Vector2 point = RLUA_CHECK_Vector2(L, 1); + Vector2 p1 = RLUA_CHECK_Vector2(L, 2); + Vector2 p2 = RLUA_CHECK_Vector2(L, 3); + int threshold = (int)luaL_checkinteger(L, 4); + bool result = CheckCollisionPointLine(point, p1, p2, threshold); + lua_pushboolean(L, result); return 1; } -//------------------------------------------------------------------------------------ -// raylib [camera] module functions - Camera System -//------------------------------------------------------------------------------------ - -// Set camera mode (multiple camera modes available) -int lua_SetCameraMode(lua_State *L) +// Check if point is within a polygon described by array of vertices +static int rl_CheckCollisionPointPoly(lua_State *L) { - Camera camera = LuaGetArgument_Camera(L, 1); - int mode = LuaGetArgument_int(L, 2); - SetCameraMode(camera, mode); - return 0; + Vector2 point = RLUA_CHECK_Vector2(L, 1); + const Vector2 * points = (const Vector2 *)lua_touserdata(L, 2); + int pointCount = (int)luaL_checkinteger(L, 3); + bool result = CheckCollisionPointPoly(point, points, pointCount); + lua_pushboolean(L, result); + return 1; } -// Update camera position for selected mode -int lua_UpdateCamera(lua_State *L) +// Check the collision between two lines defined by two points each, returns collision point by reference +static int rl_CheckCollisionLines(lua_State *L) { - Camera camera = LuaGetArgument_Camera(L, 1); - UpdateCamera(camera); - return 0; + Vector2 startPos1 = RLUA_CHECK_Vector2(L, 1); + Vector2 endPos1 = RLUA_CHECK_Vector2(L, 2); + Vector2 startPos2 = RLUA_CHECK_Vector2(L, 3); + Vector2 endPos2 = RLUA_CHECK_Vector2(L, 4); + Vector2 collisionPoint = RLUA_CHECK_Vector2(L, 5); + bool result = CheckCollisionLines(startPos1, endPos1, startPos2, endPos2, &collisionPoint); + RLUA_WRITEBACK_Vector2(L, 5, collisionPoint); + lua_pushboolean(L, result); + return 1; } -// Set camera pan key to combine with mouse movement (free camera) -int lua_SetCameraPanControl(lua_State *L) +// Get collision rectangle for two rectangles collision +static int rl_GetCollisionRec(lua_State *L) { - int panKey = LuaGetArgument_int(L, 1); - SetCameraPanControl(panKey); - return 0; + Rectangle rec1 = RLUA_CHECK_Rectangle(L, 1); + Rectangle rec2 = RLUA_CHECK_Rectangle(L, 2); + Rectangle result = GetCollisionRec(rec1, rec2); + RLUA_PUSH_Rectangle(L, result); + return 1; } -// Set camera alt key to combine with mouse movement (free camera) -int lua_SetCameraAltControl(lua_State *L) +// ------------------------------------------------------------------------------------ +// Texture Loading and Drawing Functions (Module: textures) +// ------------------------------------------------------------------------------------ +// Image loading functions +// NOTE: These functions do not require GPU access +// Load image from file into CPU memory (RAM) +static int rl_LoadImage(lua_State *L) { - int altKey = LuaGetArgument_int(L, 1); - SetCameraAltControl(altKey); - return 0; + const char * fileName = luaL_checkstring(L, 1); + Image result = LoadImage(fileName); + RLUA_PUSH_Resource(L, &result, sizeof(Image), "Image"); + return 1; } -// Set camera smooth zoom key to combine with mouse (free camera) -int lua_SetCameraSmoothZoomControl(lua_State *L) +// Load image from RAW file data +static int rl_LoadImageRaw(lua_State *L) { - int szKey = LuaGetArgument_int(L, 1); - SetCameraSmoothZoomControl(szKey); - return 0; + const char * fileName = luaL_checkstring(L, 1); + int width = (int)luaL_checkinteger(L, 2); + int height = (int)luaL_checkinteger(L, 3); + int format = (int)luaL_checkinteger(L, 4); + int headerSize = (int)luaL_checkinteger(L, 5); + Image result = LoadImageRaw(fileName, width, height, format, headerSize); + RLUA_PUSH_Resource(L, &result, sizeof(Image), "Image"); + return 1; } -// Set camera move controls (1st person and 3rd person cameras) -int lua_SetCameraMoveControls(lua_State *L) +// Load image sequence from file (frames appended to image.data) +static int rl_LoadImageAnim(lua_State *L) { - int frontKey = LuaGetArgument_int(L, 1); - int backKey = LuaGetArgument_int(L, 2); - int rightKey = LuaGetArgument_int(L, 3); - int leftKey = LuaGetArgument_int(L, 4); - int upKey = LuaGetArgument_int(L, 5); - int downKey = LuaGetArgument_int(L, 6); - SetCameraMoveControls(frontKey, backKey, rightKey, leftKey, upKey, downKey); - return 0; + const char * fileName = luaL_checkstring(L, 1); + int * frames = (int *)lua_touserdata(L, 2); + Image result = LoadImageAnim(fileName, frames); + RLUA_PUSH_Resource(L, &result, sizeof(Image), "Image"); + return 1; } -//------------------------------------------------------------------------------------ -// raylib [shapes] module functions - Basic Shapes Drawing -//------------------------------------------------------------------------------------ - -// Draw a pixel -int lua_DrawPixel(lua_State *L) +// Load image sequence from memory buffer +static int rl_LoadImageAnimFromMemory(lua_State *L) { - int posX = LuaGetArgument_int(L, 1); - int posY = LuaGetArgument_int(L, 2); - Color color = LuaGetArgument_Color(L, 3); - DrawPixel(posX, posY, color); - return 0; + const char * fileType = luaL_checkstring(L, 1); + const unsigned char * fileData = (const unsigned char *)lua_touserdata(L, 2); + int dataSize = (int)luaL_checkinteger(L, 3); + int * frames = (int *)lua_touserdata(L, 4); + Image result = LoadImageAnimFromMemory(fileType, fileData, dataSize, frames); + RLUA_PUSH_Resource(L, &result, sizeof(Image), "Image"); + return 1; } -// Draw a pixel (Vector version) -int lua_DrawPixelV(lua_State *L) +// Load image from memory buffer, fileType refers to extension: i.e. '.png' +static int rl_LoadImageFromMemory(lua_State *L) { - Vector2 position = LuaGetArgument_Vector2(L, 1); - Color color = LuaGetArgument_Color(L, 2); - DrawPixelV(position, color); - return 0; + const char * fileType = luaL_checkstring(L, 1); + const unsigned char * fileData = (const unsigned char *)lua_touserdata(L, 2); + int dataSize = (int)luaL_checkinteger(L, 3); + Image result = LoadImageFromMemory(fileType, fileData, dataSize); + RLUA_PUSH_Resource(L, &result, sizeof(Image), "Image"); + return 1; } -// Draw a line -int lua_DrawLine(lua_State *L) +// Load image from GPU texture data +static int rl_LoadImageFromTexture(lua_State *L) { - int startPosX = LuaGetArgument_int(L, 1); - int startPosY = LuaGetArgument_int(L, 2); - int endPosX = LuaGetArgument_int(L, 3); - int endPosY = LuaGetArgument_int(L, 4); - Color color = LuaGetArgument_Color(L, 5); - DrawLine(startPosX, startPosY, endPosX, endPosY, color); - return 0; + Texture2D texture = *(Texture2D*)RLUA_CHECK_Resource(L, 1, "Texture2D"); + Image result = LoadImageFromTexture(texture); + RLUA_PUSH_Resource(L, &result, sizeof(Image), "Image"); + return 1; } -// Draw a line (Vector version) -int lua_DrawLineV(lua_State *L) +// Load image from screen buffer and (screenshot) +static int rl_LoadImageFromScreen(lua_State *L) { - Vector2 startPos = LuaGetArgument_Vector2(L, 1); - Vector2 endPos = LuaGetArgument_Vector2(L, 2); - Color color = LuaGetArgument_Color(L, 3); - DrawLineV(startPos, endPos, color); - return 0; + Image result = LoadImageFromScreen(); + RLUA_PUSH_Resource(L, &result, sizeof(Image), "Image"); + return 1; } -// Draw a line defining thickness -int lua_DrawLineEx(lua_State *L) +// Check if an image is valid (data and parameters) +static int rl_IsImageValid(lua_State *L) { - Vector2 startPos = LuaGetArgument_Vector2(L, 1); - Vector2 endPos = LuaGetArgument_Vector2(L, 2); - float thick = LuaGetArgument_float(L, 3); - Color color = LuaGetArgument_Color(L, 4); - DrawLineEx(startPos, endPos, thick, color); - return 0; + Image image = *(Image*)RLUA_CHECK_Resource(L, 1, "Image"); + bool result = IsImageValid(image); + lua_pushboolean(L, result); + return 1; } -// Draw a line using cubic-bezier curves in-out -int lua_DrawLineBezier(lua_State *L) +// Unload image from CPU memory (RAM) +static int rl_UnloadImage(lua_State *L) { - Vector2 startPos = LuaGetArgument_Vector2(L, 1); - Vector2 endPos = LuaGetArgument_Vector2(L, 2); - float thick = LuaGetArgument_float(L, 3); - Color color = LuaGetArgument_Color(L, 4); - DrawLineBezier(startPos, endPos, thick, color); + Image image = *(Image*)RLUA_CHECK_Resource(L, 1, "Image"); + UnloadImage(image); return 0; } -// Draw a color-filled circle -int lua_DrawCircle(lua_State *L) +// Export image data to file, returns true on success +static int rl_ExportImage(lua_State *L) { - int centerX = LuaGetArgument_int(L, 1); - int centerY = LuaGetArgument_int(L, 2); - float radius = LuaGetArgument_float(L, 3); - Color color = LuaGetArgument_Color(L, 4); - DrawCircle(centerX, centerY, radius, color); - return 0; + Image image = *(Image*)RLUA_CHECK_Resource(L, 1, "Image"); + const char * fileName = luaL_checkstring(L, 2); + bool result = ExportImage(image, fileName); + lua_pushboolean(L, result); + return 1; } -// Draw a gradient-filled circle -int lua_DrawCircleGradient(lua_State *L) +// Export image to memory buffer, memory must be MemFree() +static int rl_ExportImageToMemory(lua_State *L) { - int centerX = LuaGetArgument_int(L, 1); - int centerY = LuaGetArgument_int(L, 2); - float radius = LuaGetArgument_float(L, 3); - Color color1 = LuaGetArgument_Color(L, 4); - Color color2 = LuaGetArgument_Color(L, 5); - DrawCircleGradient(centerX, centerY, radius, color1, color2); - return 0; + Image image = *(Image*)RLUA_CHECK_Resource(L, 1, "Image"); + const char * fileType = luaL_checkstring(L, 2); + int fileSize = 0; + unsigned char * result = ExportImageToMemory(image, fileType, &fileSize); + RLUA_PUSH_View(L, result, fileSize, "unsigned char", true); + return 1; } -// Draw a color-filled circle (Vector version) -int lua_DrawCircleV(lua_State *L) +// Export image as code file defining an array of bytes, returns true on success +static int rl_ExportImageAsCode(lua_State *L) { - Vector2 center = LuaGetArgument_Vector2(L, 1); - float radius = LuaGetArgument_float(L, 2); - Color color = LuaGetArgument_Color(L, 3); - DrawCircleV(center, radius, color); - return 0; + Image image = *(Image*)RLUA_CHECK_Resource(L, 1, "Image"); + const char * fileName = luaL_checkstring(L, 2); + bool result = ExportImageAsCode(image, fileName); + lua_pushboolean(L, result); + return 1; } -// Draw circle outline -int lua_DrawCircleLines(lua_State *L) +// Image generation functions +// Generate image: plain color +static int rl_GenImageColor(lua_State *L) { - int centerX = LuaGetArgument_int(L, 1); - int centerY = LuaGetArgument_int(L, 2); - float radius = LuaGetArgument_float(L, 3); - Color color = LuaGetArgument_Color(L, 4); - DrawCircleLines(centerX, centerY, radius, color); - return 0; + int width = (int)luaL_checkinteger(L, 1); + int height = (int)luaL_checkinteger(L, 2); + Color color = RLUA_CHECK_Color(L, 3); + Image result = GenImageColor(width, height, color); + RLUA_PUSH_Resource(L, &result, sizeof(Image), "Image"); + return 1; } -// Draw a color-filled rectangle -int lua_DrawRectangle(lua_State *L) +// Generate image: linear gradient, direction in degrees [0..360], 0=Vertical gradient +static int rl_GenImageGradientLinear(lua_State *L) { - int posX = LuaGetArgument_int(L, 1); - int posY = LuaGetArgument_int(L, 2); - int width = LuaGetArgument_int(L, 3); - int height = LuaGetArgument_int(L, 4); - Color color = LuaGetArgument_Color(L, 5); - DrawRectangle(posX, posY, width, height, color); - return 0; + int width = (int)luaL_checkinteger(L, 1); + int height = (int)luaL_checkinteger(L, 2); + int direction = (int)luaL_checkinteger(L, 3); + Color start = RLUA_CHECK_Color(L, 4); + Color end = RLUA_CHECK_Color(L, 5); + Image result = GenImageGradientLinear(width, height, direction, start, end); + RLUA_PUSH_Resource(L, &result, sizeof(Image), "Image"); + return 1; } -// Draw a color-filled rectangle (Vector version) -int lua_DrawRectangleV(lua_State *L) +// Generate image: radial gradient +static int rl_GenImageGradientRadial(lua_State *L) { - Vector2 position = LuaGetArgument_Vector2(L, 1); - Vector2 size = LuaGetArgument_Vector2(L, 2); - Color color = LuaGetArgument_Color(L, 3); - DrawRectangleV(position, size, color); - return 0; + int width = (int)luaL_checkinteger(L, 1); + int height = (int)luaL_checkinteger(L, 2); + float density = (float)luaL_checknumber(L, 3); + Color inner = RLUA_CHECK_Color(L, 4); + Color outer = RLUA_CHECK_Color(L, 5); + Image result = GenImageGradientRadial(width, height, density, inner, outer); + RLUA_PUSH_Resource(L, &result, sizeof(Image), "Image"); + return 1; } -// Draw a color-filled rectangle -int lua_DrawRectangleRec(lua_State *L) +// Generate image: square gradient +static int rl_GenImageGradientSquare(lua_State *L) { - Rectangle rec = LuaGetArgument_Rectangle(L, 1); - Color color = LuaGetArgument_Color(L, 2); - DrawRectangleRec(rec, color); - return 0; + int width = (int)luaL_checkinteger(L, 1); + int height = (int)luaL_checkinteger(L, 2); + float density = (float)luaL_checknumber(L, 3); + Color inner = RLUA_CHECK_Color(L, 4); + Color outer = RLUA_CHECK_Color(L, 5); + Image result = GenImageGradientSquare(width, height, density, inner, outer); + RLUA_PUSH_Resource(L, &result, sizeof(Image), "Image"); + return 1; } -// Draw a color-filled rectangle with pro parameters -int lua_DrawRectanglePro(lua_State *L) -{ - Rectangle rec = LuaGetArgument_Rectangle(L, 1); - Vector2 origin = LuaGetArgument_Vector2(L, 2); - float rotation = LuaGetArgument_float(L, 3); - Color color = LuaGetArgument_Color(L, 4); - DrawRectanglePro(rec, origin, rotation, color); - return 0; +// Generate image: checked +static int rl_GenImageChecked(lua_State *L) +{ + int width = (int)luaL_checkinteger(L, 1); + int height = (int)luaL_checkinteger(L, 2); + int checksX = (int)luaL_checkinteger(L, 3); + int checksY = (int)luaL_checkinteger(L, 4); + Color col1 = RLUA_CHECK_Color(L, 5); + Color col2 = RLUA_CHECK_Color(L, 6); + Image result = GenImageChecked(width, height, checksX, checksY, col1, col2); + RLUA_PUSH_Resource(L, &result, sizeof(Image), "Image"); + return 1; } -// Draw a vertical-gradient-filled rectangle -int lua_DrawRectangleGradientV(lua_State *L) +// Generate image: white noise +static int rl_GenImageWhiteNoise(lua_State *L) { - int posX = LuaGetArgument_int(L, 1); - int posY = LuaGetArgument_int(L, 2); - int width = LuaGetArgument_int(L, 3); - int height = LuaGetArgument_int(L, 4); - Color color1 = LuaGetArgument_Color(L, 5); - Color color2 = LuaGetArgument_Color(L, 6); - DrawRectangleGradientV(posX, posY, width, height, color1, color2); - return 0; + int width = (int)luaL_checkinteger(L, 1); + int height = (int)luaL_checkinteger(L, 2); + float factor = (float)luaL_checknumber(L, 3); + Image result = GenImageWhiteNoise(width, height, factor); + RLUA_PUSH_Resource(L, &result, sizeof(Image), "Image"); + return 1; } -// Draw a horizontal-gradient-filled rectangle -int lua_DrawRectangleGradientH(lua_State *L) +// Generate image: perlin noise +static int rl_GenImagePerlinNoise(lua_State *L) { - int posX = LuaGetArgument_int(L, 1); - int posY = LuaGetArgument_int(L, 2); - int width = LuaGetArgument_int(L, 3); - int height = LuaGetArgument_int(L, 4); - Color color1 = LuaGetArgument_Color(L, 5); - Color color2 = LuaGetArgument_Color(L, 6); - DrawRectangleGradientH(posX, posY, width, height, color1, color2); - return 0; + int width = (int)luaL_checkinteger(L, 1); + int height = (int)luaL_checkinteger(L, 2); + int offsetX = (int)luaL_checkinteger(L, 3); + int offsetY = (int)luaL_checkinteger(L, 4); + float scale = (float)luaL_checknumber(L, 5); + Image result = GenImagePerlinNoise(width, height, offsetX, offsetY, scale); + RLUA_PUSH_Resource(L, &result, sizeof(Image), "Image"); + return 1; } -// Draw a gradient-filled rectangle with custom vertex colors -int lua_DrawRectangleGradientEx(lua_State *L) +// Generate image: cellular algorithm, bigger tileSize means bigger cells +static int rl_GenImageCellular(lua_State *L) { - Rectangle rec = LuaGetArgument_Rectangle(L, 1); - Color col1 = LuaGetArgument_Color(L, 2); - Color col2 = LuaGetArgument_Color(L, 3); - Color col3 = LuaGetArgument_Color(L, 4); - Color col4 = LuaGetArgument_Color(L, 5); - DrawRectangleGradientEx(rec, col1, col2, col3, col4); - return 0; + int width = (int)luaL_checkinteger(L, 1); + int height = (int)luaL_checkinteger(L, 2); + int tileSize = (int)luaL_checkinteger(L, 3); + Image result = GenImageCellular(width, height, tileSize); + RLUA_PUSH_Resource(L, &result, sizeof(Image), "Image"); + return 1; } -// Draw rectangle outline -int lua_DrawRectangleLines(lua_State *L) +// Generate image: grayscale image from text data +static int rl_GenImageText(lua_State *L) { - int posX = LuaGetArgument_int(L, 1); - int posY = LuaGetArgument_int(L, 2); - int width = LuaGetArgument_int(L, 3); - int height = LuaGetArgument_int(L, 4); - Color color = LuaGetArgument_Color(L, 5); - DrawRectangleLines(posX, posY, width, height, color); - return 0; + int width = (int)luaL_checkinteger(L, 1); + int height = (int)luaL_checkinteger(L, 2); + const char * text = luaL_checkstring(L, 3); + Image result = GenImageText(width, height, text); + RLUA_PUSH_Resource(L, &result, sizeof(Image), "Image"); + return 1; } -// Draw rectangle outline with extended parameters -int lua_DrawRectangleLinesEx(lua_State *L) +// Image manipulation functions +// Create an image duplicate (useful for transformations) +static int rl_ImageCopy(lua_State *L) { - Rectangle rec = LuaGetArgument_Rectangle(L, 1); - int lineThick = LuaGetArgument_int(L, 2); - Color color = LuaGetArgument_Color(L, 3); - DrawRectangleLinesEx(rec, lineThick, color); - return 0; + Image image = *(Image*)RLUA_CHECK_Resource(L, 1, "Image"); + Image result = ImageCopy(image); + RLUA_PUSH_Resource(L, &result, sizeof(Image), "Image"); + return 1; } -// Draw a color-filled triangle -int lua_DrawTriangle(lua_State *L) +// Create an image from another image piece +static int rl_ImageFromImage(lua_State *L) { - Vector2 v1 = LuaGetArgument_Vector2(L, 1); - Vector2 v2 = LuaGetArgument_Vector2(L, 2); - Vector2 v3 = LuaGetArgument_Vector2(L, 3); - Color color = LuaGetArgument_Color(L, 4); - DrawTriangle(v1, v2, v3, color); - return 0; + Image image = *(Image*)RLUA_CHECK_Resource(L, 1, "Image"); + Rectangle rec = RLUA_CHECK_Rectangle(L, 2); + Image result = ImageFromImage(image, rec); + RLUA_PUSH_Resource(L, &result, sizeof(Image), "Image"); + return 1; } -// Draw triangle outline -int lua_DrawTriangleLines(lua_State *L) +// Create an image from a selected channel of another image (GRAYSCALE) +static int rl_ImageFromChannel(lua_State *L) { - Vector2 v1 = LuaGetArgument_Vector2(L, 1); - Vector2 v2 = LuaGetArgument_Vector2(L, 2); - Vector2 v3 = LuaGetArgument_Vector2(L, 3); - Color color = LuaGetArgument_Color(L, 4); - DrawTriangleLines(v1, v2, v3, color); - return 0; + Image image = *(Image*)RLUA_CHECK_Resource(L, 1, "Image"); + int selectedChannel = (int)luaL_checkinteger(L, 2); + Image result = ImageFromChannel(image, selectedChannel); + RLUA_PUSH_Resource(L, &result, sizeof(Image), "Image"); + return 1; } -// Draw a regular polygon (Vector version) -int lua_DrawPoly(lua_State *L) +// Create an image from text (default font) +static int rl_ImageText(lua_State *L) { - Vector2 center = LuaGetArgument_Vector2(L, 1); - int sides = LuaGetArgument_int(L, 2); - float radius = LuaGetArgument_float(L, 3); - float rotation = LuaGetArgument_float(L, 4); - Color color = LuaGetArgument_Color(L, 5); - DrawPoly(center, sides, radius, rotation, color); - return 0; + const char * text = luaL_checkstring(L, 1); + int fontSize = (int)luaL_checkinteger(L, 2); + Color color = RLUA_CHECK_Color(L, 3); + Image result = ImageText(text, fontSize, color); + RLUA_PUSH_Resource(L, &result, sizeof(Image), "Image"); + return 1; } +// Create an image from text (custom sprite font) +static int rl_ImageTextEx(lua_State *L) +{ + Font font = *(Font*)RLUA_CHECK_Resource(L, 1, "Font"); + const char * text = luaL_checkstring(L, 2); + float fontSize = (float)luaL_checknumber(L, 3); + float spacing = (float)luaL_checknumber(L, 4); + Color tint = RLUA_CHECK_Color(L, 5); + Image result = ImageTextEx(font, text, fontSize, spacing, tint); + RLUA_PUSH_Resource(L, &result, sizeof(Image), "Image"); + return 1; +} -// TODO: This thing should be here? -#define GET_TABLE(type, name, index) \ - type* name = 0; \ - size_t name##_size = 0; \ - { \ - size_t sz = 0; \ - luaL_checktype(L, index, LUA_TTABLE); \ - lua_pushnil(L); \ - while (lua_next(L, index)) { \ - LuaGetArgument_##type(L, -1); \ - sz++; \ - lua_pop(L, 1); \ - } \ - name = calloc(sz, sizeof(type)); \ - sz = 0; \ - lua_pushnil(L); \ - while (lua_next(L, index)) { \ - name[sz] = LuaGetArgument_##type(L, -1); \ - sz++; \ - lua_pop(L, 1); \ - } \ - lua_pop(L, 1); \ - name##_size = sz; \ - } - -// WARNING: Draw a closed polygon defined by points -int lua_DrawPolyEx(lua_State* L) +// Convert image data to desired format +static int rl_ImageFormat(lua_State *L) { - GET_TABLE(Vector2, arg1, 1); - Color arg2 = LuaGetArgument_Color(L, 2); - DrawPolyEx(arg1, arg1_size, arg2); - free(arg1); + Image * image = (Image *)lua_touserdata(L, 1); + int newFormat = (int)luaL_checkinteger(L, 2); + ImageFormat(image, newFormat); return 0; } -// WARNING: Draw polygon lines -int lua_DrawPolyExLines(lua_State* L) +// Convert image to POT (power-of-two) +static int rl_ImageToPOT(lua_State *L) { - GET_TABLE(Vector2, arg1, 1); - Color arg2 = LuaGetArgument_Color(L, 2); - DrawPolyExLines(arg1, arg1_size, arg2); - free(arg1); + Image * image = (Image *)lua_touserdata(L, 1); + Color fill = RLUA_CHECK_Color(L, 2); + ImageToPOT(image, fill); return 0; } -// Check collision between two rectangles -int lua_CheckCollisionRecs(lua_State *L) +// Crop an image to a defined rectangle +static int rl_ImageCrop(lua_State *L) { - Rectangle rec1 = LuaGetArgument_Rectangle(L, 1); - Rectangle rec2 = LuaGetArgument_Rectangle(L, 2); - bool result = CheckCollisionRecs(rec1, rec2); - LuaPush_bool(L, result); - return 1; + Image * image = (Image *)lua_touserdata(L, 1); + Rectangle crop = RLUA_CHECK_Rectangle(L, 2); + ImageCrop(image, crop); + return 0; } -// Check collision between two circles -int lua_CheckCollisionCircles(lua_State *L) +// Crop image depending on alpha value +static int rl_ImageAlphaCrop(lua_State *L) { - Vector2 center1 = LuaGetArgument_Vector2(L, 1); - float radius1 = LuaGetArgument_float(L, 2); - Vector2 center2 = LuaGetArgument_Vector2(L, 3); - float radius2 = LuaGetArgument_float(L, 4); - bool result = CheckCollisionCircles(center1, radius1, center2, radius2); - LuaPush_bool(L, result); - return 1; + Image * image = (Image *)lua_touserdata(L, 1); + float threshold = (float)luaL_checknumber(L, 2); + ImageAlphaCrop(image, threshold); + return 0; } -// Check collision between circle and rectangle -int lua_CheckCollisionCircleRec(lua_State *L) +// Clear alpha channel to desired color +static int rl_ImageAlphaClear(lua_State *L) { - Vector2 center = LuaGetArgument_Vector2(L, 1); - float radius = LuaGetArgument_float(L, 2); - Rectangle rec = LuaGetArgument_Rectangle(L, 3); - bool result = CheckCollisionCircleRec(center, radius, rec); - LuaPush_bool(L, result); - return 1; + Image * image = (Image *)lua_touserdata(L, 1); + Color color = RLUA_CHECK_Color(L, 2); + float threshold = (float)luaL_checknumber(L, 3); + ImageAlphaClear(image, color, threshold); + return 0; } -// Get collision rectangle for two rectangles collision -int lua_GetCollisionRec(lua_State *L) +// Apply alpha mask to image +static int rl_ImageAlphaMask(lua_State *L) { - Rectangle rec1 = LuaGetArgument_Rectangle(L, 1); - Rectangle rec2 = LuaGetArgument_Rectangle(L, 2); - Rectangle result = GetCollisionRec(rec1, rec2); - LuaPush_Rectangle(L, result); - return 1; + Image * image = (Image *)lua_touserdata(L, 1); + Image alphaMask = *(Image*)RLUA_CHECK_Resource(L, 2, "Image"); + ImageAlphaMask(image, alphaMask); + return 0; } -// Check if point is inside rectangle -int lua_CheckCollisionPointRec(lua_State *L) +// Premultiply alpha channel +static int rl_ImageAlphaPremultiply(lua_State *L) { - Vector2 point = LuaGetArgument_Vector2(L, 1); - Rectangle rec = LuaGetArgument_Rectangle(L, 2); - bool result = CheckCollisionPointRec(point, rec); - LuaPush_bool(L, result); - return 1; + Image * image = (Image *)lua_touserdata(L, 1); + ImageAlphaPremultiply(image); + return 0; } -// Check if point is inside circle -int lua_CheckCollisionPointCircle(lua_State *L) +// Apply Gaussian blur using a box blur approximation +static int rl_ImageBlurGaussian(lua_State *L) { - Vector2 point = LuaGetArgument_Vector2(L, 1); - Vector2 center = LuaGetArgument_Vector2(L, 2); - float radius = LuaGetArgument_float(L, 3); - bool result = CheckCollisionPointCircle(point, center, radius); - LuaPush_bool(L, result); - return 1; + Image * image = (Image *)lua_touserdata(L, 1); + int blurSize = (int)luaL_checkinteger(L, 2); + ImageBlurGaussian(image, blurSize); + return 0; } -// Check if point is inside a triangle -int lua_CheckCollisionPointTriangle(lua_State *L) +// Apply custom square convolution kernel to image +static int rl_ImageKernelConvolution(lua_State *L) { - Vector2 point = LuaGetArgument_Vector2(L, 1); - Vector2 p1 = LuaGetArgument_Vector2(L, 2); - Vector2 p2 = LuaGetArgument_Vector2(L, 3); - Vector2 p3 = LuaGetArgument_Vector2(L, 4); - bool result = CheckCollisionPointTriangle(point, p1, p2, p3); - LuaPush_bool(L, result); - return 1; + Image * image = (Image *)lua_touserdata(L, 1); + const float * kernel = (const float *)lua_touserdata(L, 2); + int kernelSize = (int)luaL_checkinteger(L, 3); + ImageKernelConvolution(image, kernel, kernelSize); + return 0; } -//------------------------------------------------------------------------------------ -// raylib [textures] module functions - Texture Loading and Drawing -//------------------------------------------------------------------------------------ - -// Load image from file into CPU memory (RAM) -int lua_LoadImage(lua_State *L) +// Resize image (Bicubic scaling algorithm) +static int rl_ImageResize(lua_State *L) { - const char *fileName = LuaGetArgument_string(L, 1); - Image result = LoadImage(fileName); - LuaPush_Image(L, result); - return 1; + Image * image = (Image *)lua_touserdata(L, 1); + int newWidth = (int)luaL_checkinteger(L, 2); + int newHeight = (int)luaL_checkinteger(L, 3); + ImageResize(image, newWidth, newHeight); + return 0; } -// WARNING: Load image from Color array data (RGBA - 32bit) -int lua_LoadImageEx(lua_State* L) +// Resize image (Nearest-Neighbor scaling algorithm) +static int rl_ImageResizeNN(lua_State *L) { - // TODO: arg1 parameter is a Color array... - - GET_TABLE(Color, arg1, 1); // Color *pixels - int arg2 = LuaGetArgument_int(L, 2); - int arg3 = LuaGetArgument_int(L, 3); - Image result = LoadImageEx(arg1, arg2, arg3); // ISSUE: #3 number expected, got no value - LuaPush_Image(L, result); - free(arg1); - return 1; + Image * image = (Image *)lua_touserdata(L, 1); + int newWidth = (int)luaL_checkinteger(L, 2); + int newHeight = (int)luaL_checkinteger(L, 3); + ImageResizeNN(image, newWidth, newHeight); + return 0; } -// WARNING: Load image from raw data with pro parameters -int lua_LoadImagePro(lua_State* L) +// Resize canvas and fill with color +static int rl_ImageResizeCanvas(lua_State *L) { - // TODO: arg1 parameter is a void pointer... - - void *arg1 = LuaGetArgument_ptr(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - int arg3 = LuaGetArgument_int(L, 3); - int arg4 = LuaGetArgument_int(L, 4); - Image result = LoadImagePro(arg1, arg2, arg3, arg4); - LuaPush_Image(L, result); - free(arg1); - return 1; + Image * image = (Image *)lua_touserdata(L, 1); + int newWidth = (int)luaL_checkinteger(L, 2); + int newHeight = (int)luaL_checkinteger(L, 3); + int offsetX = (int)luaL_checkinteger(L, 4); + int offsetY = (int)luaL_checkinteger(L, 5); + Color fill = RLUA_CHECK_Color(L, 6); + ImageResizeCanvas(image, newWidth, newHeight, offsetX, offsetY, fill); + return 0; } -// Load image from RAW file data -int lua_LoadImageRaw(lua_State *L) +// Compute all mipmap levels for a provided image +static int rl_ImageMipmaps(lua_State *L) { - const char *fileName = LuaGetArgument_string(L, 1); - int width = LuaGetArgument_int(L, 2); - int height = LuaGetArgument_int(L, 3); - int format = LuaGetArgument_int(L, 4); - int headerSize = LuaGetArgument_int(L, 5); - Image result = LoadImageRaw(fileName, width, height, format, headerSize); - LuaPush_Image(L, result); - return 1; + Image * image = (Image *)lua_touserdata(L, 1); + ImageMipmaps(image); + return 0; } -// Export image as a PNG file -int lua_ExportImage(lua_State *L) +// Dither image data to 16bpp or lower (Floyd-Steinberg dithering) +static int rl_ImageDither(lua_State *L) { - const char *fileName = LuaGetArgument_string(L, 1); - Image image = LuaGetArgument_Image(L, 2); - ExportImage(fileName, image); + Image * image = (Image *)lua_touserdata(L, 1); + int rBpp = (int)luaL_checkinteger(L, 2); + int gBpp = (int)luaL_checkinteger(L, 3); + int bBpp = (int)luaL_checkinteger(L, 4); + int aBpp = (int)luaL_checkinteger(L, 5); + ImageDither(image, rBpp, gBpp, bBpp, aBpp); return 0; } -// Load texture from file into GPU memory (VRAM) -int lua_LoadTexture(lua_State *L) +// Flip image vertically +static int rl_ImageFlipVertical(lua_State *L) { - const char *fileName = LuaGetArgument_string(L, 1); - Texture2D result = LoadTexture(fileName); - LuaPush_Texture2D(L, result); - return 1; + Image * image = (Image *)lua_touserdata(L, 1); + ImageFlipVertical(image); + return 0; } -// Load texture from image data -int lua_LoadTextureFromImage(lua_State *L) +// Flip image horizontally +static int rl_ImageFlipHorizontal(lua_State *L) { - Image image = LuaGetArgument_Image(L, 1); - Texture2D result = LoadTextureFromImage(image); - LuaPush_Texture2D(L, result); - return 1; + Image * image = (Image *)lua_touserdata(L, 1); + ImageFlipHorizontal(image); + return 0; } -// Load texture for rendering (framebuffer) -int lua_LoadRenderTexture(lua_State *L) +// Rotate image by input angle in degrees (-359 to 359) +static int rl_ImageRotate(lua_State *L) { - int width = LuaGetArgument_int(L, 1); - int height = LuaGetArgument_int(L, 2); - RenderTexture2D result = LoadRenderTexture(width, height); - LuaPush_RenderTexture2D(L, result); - return 1; + Image * image = (Image *)lua_touserdata(L, 1); + int degrees = (int)luaL_checkinteger(L, 2); + ImageRotate(image, degrees); + return 0; } -// Unload image from CPU memory (RAM) -int lua_UnloadImage(lua_State *L) +// Rotate image clockwise 90deg +static int rl_ImageRotateCW(lua_State *L) { - Image image = LuaGetArgument_Image(L, 1); - UnloadImage(image); + Image * image = (Image *)lua_touserdata(L, 1); + ImageRotateCW(image); return 0; } -// Unload texture from GPU memory (VRAM) -int lua_UnloadTexture(lua_State *L) +// Rotate image counter-clockwise 90deg +static int rl_ImageRotateCCW(lua_State *L) { - Texture2D texture = LuaGetArgument_Texture2D(L, 1); - UnloadTexture(texture); + Image * image = (Image *)lua_touserdata(L, 1); + ImageRotateCCW(image); return 0; } -// Unload render texture from GPU memory (VRAM) -int lua_UnloadRenderTexture(lua_State *L) +// Modify image color: tint +static int rl_ImageColorTint(lua_State *L) { - RenderTexture2D target = LuaGetArgument_RenderTexture2D(L, 1); - UnloadRenderTexture(target); + Image * image = (Image *)lua_touserdata(L, 1); + Color color = RLUA_CHECK_Color(L, 2); + ImageColorTint(image, color); return 0; } -// WARNING: Get pixel data from image as a Color struct array -int lua_GetImageData(lua_State* L) +// Modify image color: invert +static int rl_ImageColorInvert(lua_State *L) { - // TODO: return value is a Color array - - Image arg1 = LuaGetArgument_Image(L, 1); - Color *result = GetImageData(arg1); - lua_createtable(L, arg1.width*arg1.height, 0); - for (int i = 0; i < arg1.width*arg1.height; i++) - { - LuaPush_Color(L, result[i]); - lua_rawseti(L, -2, i + 1); - } - free(result); - return 1; + Image * image = (Image *)lua_touserdata(L, 1); + ImageColorInvert(image); + return 0; } -// WARNING: Get pixel data from image as Vector4 array (float normalized) -int lua_GetImageDataNormalized(lua_State *L) +// Modify image color: grayscale +static int rl_ImageColorGrayscale(lua_State *L) { - // TODO. - - return 1; + Image * image = (Image *)lua_touserdata(L, 1); + ImageColorGrayscale(image); + return 0; } -// Get pixel data size in bytes (image or texture) -int lua_GetPixelDataSize(lua_State *L) +// Modify image color: contrast (-100 to 100) +static int rl_ImageColorContrast(lua_State *L) { - int width = LuaGetArgument_int(L, 1); - int height = LuaGetArgument_int(L, 2); - int format = LuaGetArgument_int(L, 3); - int result = GetPixelDataSize(width, height, format); - LuaPush_int(L, result); - return 1; + Image * image = (Image *)lua_touserdata(L, 1); + float contrast = (float)luaL_checknumber(L, 2); + ImageColorContrast(image, contrast); + return 0; } -// Get pixel data from GPU texture and return an Image -int lua_GetTextureData(lua_State *L) +// Modify image color: brightness (-255 to 255) +static int rl_ImageColorBrightness(lua_State *L) { - Texture2D texture = LuaGetArgument_Texture2D(L, 1); - Image result = GetTextureData(texture); - LuaPush_Image(L, result); - return 1; + Image * image = (Image *)lua_touserdata(L, 1); + int brightness = (int)luaL_checkinteger(L, 2); + ImageColorBrightness(image, brightness); + return 0; } - -// WARNING: Update GPU texture with new data -int lua_UpdateTexture(lua_State* L) +// Modify image color: replace color +static int rl_ImageColorReplace(lua_State *L) { - // TODO: arg2 parameters is a void pointer... - - Texture2D arg1 = LuaGetArgument_Texture2D(L, 1); - void *arg2 = LuaGetArgument_ptr(L, 2); - UpdateTexture(arg1, arg2); // ISSUE: #2 string expected, got table -> GetImageData() returns a table! + Image * image = (Image *)lua_touserdata(L, 1); + Color color = RLUA_CHECK_Color(L, 2); + Color replace = RLUA_CHECK_Color(L, 3); + ImageColorReplace(image, color, replace); return 0; } -//---------------------------------------------------------------------------------- -// Image manipulation functions -//---------------------------------------------------------------------------------- - -// Create an image duplicate (useful for transformations) -int lua_ImageCopy(lua_State *L) +// Load color data from image as a Color array (RGBA - 32bit) +static int rl_LoadImageColors(lua_State *L) { - Image image = LuaGetArgument_Image(L, 1); - Image result = ImageCopy(image); - LuaPush_Image(L, result); + Image image = *(Image*)RLUA_CHECK_Resource(L, 1, "Image"); + Color * result = LoadImageColors(image); + lua_pushlightuserdata(L, result); return 1; } -// Convert image to POT (power-of-two) -int lua_ImageToPOT(lua_State *L) +// Load colors palette from image as a Color array (RGBA - 32bit) +static int rl_LoadImagePalette(lua_State *L) { - Image image = LuaGetArgument_Image(L, 1); - Color fillColor = LuaGetArgument_Color(L, 2); - ImageToPOT(image, fillColor); - return 0; + Image image = *(Image*)RLUA_CHECK_Resource(L, 1, "Image"); + int maxPaletteSize = (int)luaL_checkinteger(L, 2); + int colorCount = 0; + Color * result = LoadImagePalette(image, maxPaletteSize, &colorCount); + RLUA_PUSH_View(L, result, colorCount, "Color", true); + return 1; } -// Convert image data to desired format -int lua_ImageFormat(lua_State *L) +// Unload color data loaded with LoadImageColors() +static int rl_UnloadImageColors(lua_State *L) { - Image image = LuaGetArgument_Image(L, 1); - int newFormat = LuaGetArgument_int(L, 2); - ImageFormat(image, newFormat); + Color * colors = (Color *)lua_touserdata(L, 1); + UnloadImageColors(colors); return 0; } -// Apply alpha mask to image -int lua_ImageAlphaMask(lua_State *L) +// Unload colors palette loaded with LoadImagePalette() +static int rl_UnloadImagePalette(lua_State *L) { - Image image = LuaGetArgument_Image(L, 1); - Image alphaMask = LuaGetArgument_Image(L, 2); - ImageAlphaMask(image, alphaMask); + Color * colors = (Color *)lua_touserdata(L, 1); + UnloadImagePalette(colors); return 0; } -// Clear alpha channel to desired color -int lua_ImageAlphaClear(lua_State *L) +// Get image alpha border rectangle +static int rl_GetImageAlphaBorder(lua_State *L) { - Image image = LuaGetArgument_Image(L, 1); - Color color = LuaGetArgument_Color(L, 2); - float threshold = LuaGetArgument_float(L, 3); - ImageAlphaClear(image, color, threshold); - return 0; + Image image = *(Image*)RLUA_CHECK_Resource(L, 1, "Image"); + float threshold = (float)luaL_checknumber(L, 2); + Rectangle result = GetImageAlphaBorder(image, threshold); + RLUA_PUSH_Rectangle(L, result); + return 1; } -// Crop image depending on alpha value -int lua_ImageAlphaCrop(lua_State *L) +// Get image pixel color at (x, y) position +static int rl_GetImageColor(lua_State *L) { - Image image = LuaGetArgument_Image(L, 1); - float threshold = LuaGetArgument_float(L, 2); - ImageAlphaCrop(image, threshold); - return 0; + Image image = *(Image*)RLUA_CHECK_Resource(L, 1, "Image"); + int x = (int)luaL_checkinteger(L, 2); + int y = (int)luaL_checkinteger(L, 3); + Color result = GetImageColor(image, x, y); + RLUA_PUSH_Color(L, result); + return 1; } -// Premultiply alpha channel -int lua_ImageAlphaPremultiply(lua_State *L) +// Image drawing functions +// NOTE: Image software-rendering functions (CPU) +// Clear image background with given color +static int rl_ImageClearBackground(lua_State *L) { - Image image = LuaGetArgument_Image(L, 1); - ImageAlphaPremultiply(image); + Image * dst = (Image *)lua_touserdata(L, 1); + Color color = RLUA_CHECK_Color(L, 2); + ImageClearBackground(dst, color); return 0; } -// Crop an image to a defined rectangle -int lua_ImageCrop(lua_State *L) +// Draw pixel within an image +static int rl_ImageDrawPixel(lua_State *L) { - Image image = LuaGetArgument_Image(L, 1); - Rectangle crop = LuaGetArgument_Rectangle(L, 2); - ImageCrop(image, crop); + Image * dst = (Image *)lua_touserdata(L, 1); + int posX = (int)luaL_checkinteger(L, 2); + int posY = (int)luaL_checkinteger(L, 3); + Color color = RLUA_CHECK_Color(L, 4); + ImageDrawPixel(dst, posX, posY, color); return 0; } -// Resize image (bilinear filtering) -int lua_ImageResize(lua_State *L) +// Draw pixel within an image (Vector version) +static int rl_ImageDrawPixelV(lua_State *L) { - Image image = LuaGetArgument_Image(L, 1); - int newWidth = LuaGetArgument_int(L, 2); - int newHeight = LuaGetArgument_int(L, 3); - ImageResize(image, newWidth, newHeight); + Image * dst = (Image *)lua_touserdata(L, 1); + Vector2 position = RLUA_CHECK_Vector2(L, 2); + Color color = RLUA_CHECK_Color(L, 3); + ImageDrawPixelV(dst, position, color); return 0; } -// Resize image (Nearest-Neighbor scaling algorithm) -int lua_ImageResizeNN(lua_State *L) +// Draw line within an image +static int rl_ImageDrawLine(lua_State *L) { - Image image = LuaGetArgument_Image(L, 1); - int newWidth = LuaGetArgument_int(L, 2); - int newHeight = LuaGetArgument_int(L, 3); - ImageResizeNN(image, newWidth, newHeight); + Image * dst = (Image *)lua_touserdata(L, 1); + int startPosX = (int)luaL_checkinteger(L, 2); + int startPosY = (int)luaL_checkinteger(L, 3); + int endPosX = (int)luaL_checkinteger(L, 4); + int endPosY = (int)luaL_checkinteger(L, 5); + Color color = RLUA_CHECK_Color(L, 6); + ImageDrawLine(dst, startPosX, startPosY, endPosX, endPosY, color); return 0; } -// Resize canvas and fill with color -int lua_ImageResizeCanvas(lua_State *L) +// Draw line within an image (Vector version) +static int rl_ImageDrawLineV(lua_State *L) { - Image image = LuaGetArgument_Image(L, 1); - int newWidth = LuaGetArgument_int(L, 2); - int newHeight = LuaGetArgument_int(L, 3); - int offsetX = LuaGetArgument_int(L, 4); - int offsetY = LuaGetArgument_int(L, 5); - Color color = LuaGetArgument_Color(L, 6); - ImageResizeCanvas(image, newWidth, newHeight, offsetX, offsetY, color); + Image * dst = (Image *)lua_touserdata(L, 1); + Vector2 start = RLUA_CHECK_Vector2(L, 2); + Vector2 end = RLUA_CHECK_Vector2(L, 3); + Color color = RLUA_CHECK_Color(L, 4); + ImageDrawLineV(dst, start, end, color); return 0; } -// Generate all mipmap levels for a provided image -int lua_ImageMipmaps(lua_State *L) +// Draw a line defining thickness within an image +static int rl_ImageDrawLineEx(lua_State *L) { - Image image = LuaGetArgument_Image(L, 1); - ImageMipmaps(image); + Image * dst = (Image *)lua_touserdata(L, 1); + Vector2 start = RLUA_CHECK_Vector2(L, 2); + Vector2 end = RLUA_CHECK_Vector2(L, 3); + int thick = (int)luaL_checkinteger(L, 4); + Color color = RLUA_CHECK_Color(L, 5); + ImageDrawLineEx(dst, start, end, thick, color); return 0; } -// Dither image data to 16bpp or lower (Floyd-Steinberg dithering) -int lua_ImageDither(lua_State *L) +// Draw a filled circle within an image +static int rl_ImageDrawCircle(lua_State *L) { - Image image = LuaGetArgument_Image(L, 1); - int rBpp = LuaGetArgument_int(L, 2); - int gBpp = LuaGetArgument_int(L, 3); - int bBpp = LuaGetArgument_int(L, 4); - int aBpp = LuaGetArgument_int(L, 5); - ImageDither(image, rBpp, gBpp, bBpp, aBpp); + Image * dst = (Image *)lua_touserdata(L, 1); + int centerX = (int)luaL_checkinteger(L, 2); + int centerY = (int)luaL_checkinteger(L, 3); + int radius = (int)luaL_checkinteger(L, 4); + Color color = RLUA_CHECK_Color(L, 5); + ImageDrawCircle(dst, centerX, centerY, radius, color); return 0; } -// Create an image from text (default font) -int lua_ImageText(lua_State *L) +// Draw a filled circle within an image (Vector version) +static int rl_ImageDrawCircleV(lua_State *L) { - const char *text = LuaGetArgument_string(L, 1); - int fontSize = LuaGetArgument_int(L, 2); - Color color = LuaGetArgument_Color(L, 3); - Image result = ImageText(text, fontSize, color); - LuaPush_Image(L, result); - return 1; + Image * dst = (Image *)lua_touserdata(L, 1); + Vector2 center = RLUA_CHECK_Vector2(L, 2); + int radius = (int)luaL_checkinteger(L, 3); + Color color = RLUA_CHECK_Color(L, 4); + ImageDrawCircleV(dst, center, radius, color); + return 0; } -// Create an image from text (custom sprite font) -int lua_ImageTextEx(lua_State *L) +// Draw circle outline within an image +static int rl_ImageDrawCircleLines(lua_State *L) { - Font font = LuaGetArgument_Font(L, 1); - const char *text = LuaGetArgument_string(L, 2); - float fontSize = LuaGetArgument_float(L, 3); - float spacing = LuaGetArgument_float(L, 4); - Color tint = LuaGetArgument_Color(L, 5); - Image result = ImageTextEx(font, text, fontSize, spacing, tint); - LuaPush_Image(L, result); - return 1; + Image * dst = (Image *)lua_touserdata(L, 1); + int centerX = (int)luaL_checkinteger(L, 2); + int centerY = (int)luaL_checkinteger(L, 3); + int radius = (int)luaL_checkinteger(L, 4); + Color color = RLUA_CHECK_Color(L, 5); + ImageDrawCircleLines(dst, centerX, centerY, radius, color); + return 0; } -// Draw a source image within a destination image -int lua_ImageDraw(lua_State *L) +// Draw circle outline within an image (Vector version) +static int rl_ImageDrawCircleLinesV(lua_State *L) { - Image dst = LuaGetArgument_Image(L, 1); - Image src = LuaGetArgument_Image(L, 2); - Rectangle srcRec = LuaGetArgument_Rectangle(L, 3); - Rectangle dstRec = LuaGetArgument_Rectangle(L, 4); - ImageDraw(&dst, src, srcRec, dstRec); // WARNING: & required! + Image * dst = (Image *)lua_touserdata(L, 1); + Vector2 center = RLUA_CHECK_Vector2(L, 2); + int radius = (int)luaL_checkinteger(L, 3); + Color color = RLUA_CHECK_Color(L, 4); + ImageDrawCircleLinesV(dst, center, radius, color); return 0; } // Draw rectangle within an image -int lua_ImageDrawRectangle(lua_State *L) +static int rl_ImageDrawRectangle(lua_State *L) { - Image dst = LuaGetArgument_Image(L, 1); - Vector2 position = LuaGetArgument_Vector2(L, 2); - Rectangle rec = LuaGetArgument_Rectangle(L, 3); - Color color = LuaGetArgument_Color(L, 4); - ImageDrawRectangle(dst, position, rec, color); + Image * dst = (Image *)lua_touserdata(L, 1); + int posX = (int)luaL_checkinteger(L, 2); + int posY = (int)luaL_checkinteger(L, 3); + int width = (int)luaL_checkinteger(L, 4); + int height = (int)luaL_checkinteger(L, 5); + Color color = RLUA_CHECK_Color(L, 6); + ImageDrawRectangle(dst, posX, posY, width, height, color); return 0; } -// Draw text (default font) within an image (destination) -int lua_ImageDrawText(lua_State *L) +// Draw rectangle within an image (Vector version) +static int rl_ImageDrawRectangleV(lua_State *L) { - Image dst = LuaGetArgument_Image(L, 1); - Vector2 position = LuaGetArgument_Vector2(L, 2); - const char *text = LuaGetArgument_string(L, 3); // WARNING: all const char require * - int fontSize = LuaGetArgument_int(L, 4); - Color color = LuaGetArgument_Color(L, 5); - ImageDrawText(&dst, position, text, fontSize, color); + Image * dst = (Image *)lua_touserdata(L, 1); + Vector2 position = RLUA_CHECK_Vector2(L, 2); + Vector2 size = RLUA_CHECK_Vector2(L, 3); + Color color = RLUA_CHECK_Color(L, 4); + ImageDrawRectangleV(dst, position, size, color); return 0; } -// Draw text (custom sprite font) within an image (destination) -int lua_ImageDrawTextEx(lua_State *L) +// Draw rectangle within an image +static int rl_ImageDrawRectangleRec(lua_State *L) { - Image dst = LuaGetArgument_Image(L, 1); - Vector2 position = LuaGetArgument_Vector2(L, 2); - Font font = LuaGetArgument_Font(L, 3); - const char *text = LuaGetArgument_string(L, 4); - float fontSize = LuaGetArgument_float(L, 5); - float spacing = LuaGetArgument_float(L, 6); - Color color = LuaGetArgument_Color(L, 7); - ImageDrawTextEx(&dst, position, font, text, fontSize, spacing, color); + Image * dst = (Image *)lua_touserdata(L, 1); + Rectangle rec = RLUA_CHECK_Rectangle(L, 2); + Color color = RLUA_CHECK_Color(L, 3); + ImageDrawRectangleRec(dst, rec, color); return 0; } -// Flip image vertically -int lua_ImageFlipVertical(lua_State *L) +// Draw rectangle lines within an image +static int rl_ImageDrawRectangleLines(lua_State *L) { - Image image = LuaGetArgument_Image(L, 1); - ImageFlipVertical(image); + Image * dst = (Image *)lua_touserdata(L, 1); + Rectangle rec = RLUA_CHECK_Rectangle(L, 2); + int thick = (int)luaL_checkinteger(L, 3); + Color color = RLUA_CHECK_Color(L, 4); + ImageDrawRectangleLines(dst, rec, thick, color); return 0; } -// Flip image horizontally -int lua_ImageFlipHorizontal(lua_State *L) +// Draw triangle within an image +static int rl_ImageDrawTriangle(lua_State *L) { - Image image = LuaGetArgument_Image(L, 1); - ImageFlipHorizontal(image); + Image * dst = (Image *)lua_touserdata(L, 1); + Vector2 v1 = RLUA_CHECK_Vector2(L, 2); + Vector2 v2 = RLUA_CHECK_Vector2(L, 3); + Vector2 v3 = RLUA_CHECK_Vector2(L, 4); + Color color = RLUA_CHECK_Color(L, 5); + ImageDrawTriangle(dst, v1, v2, v3, color); return 0; } -// Rotate image clockwise 90deg -int lua_ImageRotateCW(lua_State *L) +// Draw triangle with interpolated colors within an image +static int rl_ImageDrawTriangleEx(lua_State *L) { - Image image = LuaGetArgument_Image(L, 1); - ImageRotateCW(image); + Image * dst = (Image *)lua_touserdata(L, 1); + Vector2 v1 = RLUA_CHECK_Vector2(L, 2); + Vector2 v2 = RLUA_CHECK_Vector2(L, 3); + Vector2 v3 = RLUA_CHECK_Vector2(L, 4); + Color c1 = RLUA_CHECK_Color(L, 5); + Color c2 = RLUA_CHECK_Color(L, 6); + Color c3 = RLUA_CHECK_Color(L, 7); + ImageDrawTriangleEx(dst, v1, v2, v3, c1, c2, c3); return 0; } -// Rotate image counter-clockwise 90deg -int lua_ImageRotateCCW(lua_State *L) +// Draw triangle outline within an image +static int rl_ImageDrawTriangleLines(lua_State *L) { - Image image = LuaGetArgument_Image(L, 1); - ImageRotateCCW(image); + Image * dst = (Image *)lua_touserdata(L, 1); + Vector2 v1 = RLUA_CHECK_Vector2(L, 2); + Vector2 v2 = RLUA_CHECK_Vector2(L, 3); + Vector2 v3 = RLUA_CHECK_Vector2(L, 4); + Color color = RLUA_CHECK_Color(L, 5); + ImageDrawTriangleLines(dst, v1, v2, v3, color); return 0; } -// Modify image color: tint -int lua_ImageColorTint(lua_State *L) +// Draw a triangle fan defined by points within an image (first vertex is the center) +static int rl_ImageDrawTriangleFan(lua_State *L) { - Image image = LuaGetArgument_Image(L, 1); - Color color = LuaGetArgument_Color(L, 2); - ImageColorTint(image, color); + Image * dst = (Image *)lua_touserdata(L, 1); + const Vector2 * points = (const Vector2 *)lua_touserdata(L, 2); + int pointCount = (int)luaL_checkinteger(L, 3); + Color color = RLUA_CHECK_Color(L, 4); + ImageDrawTriangleFan(dst, points, pointCount, color); return 0; } -// Modify image color: invert -int lua_ImageColorInvert(lua_State *L) +// Draw a triangle strip defined by points within an image +static int rl_ImageDrawTriangleStrip(lua_State *L) { - Image image = LuaGetArgument_Image(L, 1); - ImageColorInvert(image); + Image * dst = (Image *)lua_touserdata(L, 1); + const Vector2 * points = (const Vector2 *)lua_touserdata(L, 2); + int pointCount = (int)luaL_checkinteger(L, 3); + Color color = RLUA_CHECK_Color(L, 4); + ImageDrawTriangleStrip(dst, points, pointCount, color); return 0; } -// Modify image color: grayscale -int lua_ImageColorGrayscale(lua_State *L) +// Draw a source image within a destination image (tint applied to source) +static int rl_ImageDraw(lua_State *L) { - Image image = LuaGetArgument_Image(L, 1); - ImageColorGrayscale(image); + Image * dst = (Image *)lua_touserdata(L, 1); + Image src = *(Image*)RLUA_CHECK_Resource(L, 2, "Image"); + Rectangle srcRec = RLUA_CHECK_Rectangle(L, 3); + Rectangle dstRec = RLUA_CHECK_Rectangle(L, 4); + Color tint = RLUA_CHECK_Color(L, 5); + ImageDraw(dst, src, srcRec, dstRec, tint); return 0; } -// Modify image color: contrast (-100 to 100) -int lua_ImageColorContrast(lua_State *L) +// Draw text (using default font) within an image (destination) +static int rl_ImageDrawText(lua_State *L) { - Image image = LuaGetArgument_Image(L, 1); - float contrast = LuaGetArgument_float(L, 2); - ImageColorContrast(image, contrast); + Image * dst = (Image *)lua_touserdata(L, 1); + const char * text = luaL_checkstring(L, 2); + int posX = (int)luaL_checkinteger(L, 3); + int posY = (int)luaL_checkinteger(L, 4); + int fontSize = (int)luaL_checkinteger(L, 5); + Color color = RLUA_CHECK_Color(L, 6); + ImageDrawText(dst, text, posX, posY, fontSize, color); return 0; } -// Modify image color: brightness (-255 to 255) -int lua_ImageColorBrightness(lua_State *L) +// Draw text (custom sprite font) within an image (destination) +static int rl_ImageDrawTextEx(lua_State *L) { - Image image = LuaGetArgument_Image(L, 1); - int brightness = LuaGetArgument_int(L, 2); - ImageColorBrightness(image, brightness); + Image * dst = (Image *)lua_touserdata(L, 1); + Font font = *(Font*)RLUA_CHECK_Resource(L, 2, "Font"); + const char * text = luaL_checkstring(L, 3); + Vector2 position = RLUA_CHECK_Vector2(L, 4); + float fontSize = (float)luaL_checknumber(L, 5); + float spacing = (float)luaL_checknumber(L, 6); + Color tint = RLUA_CHECK_Color(L, 7); + ImageDrawTextEx(dst, font, text, position, fontSize, spacing, tint); return 0; } -// Modify image color: replace color -int lua_ImageColorReplace(lua_State *L) +// Texture loading functions +// NOTE: These functions require GPU access +// Load texture from file into GPU memory (VRAM) +static int rl_LoadTexture(lua_State *L) { - Image image = LuaGetArgument_Image(L, 1); - Color color = LuaGetArgument_Color(L, 2); - Color replace = LuaGetArgument_Color(L, 3); - ImageColorReplace(image, color, replace); - return 0; + const char * fileName = luaL_checkstring(L, 1); + Texture2D result = LoadTexture(fileName); + RLUA_PUSH_Resource(L, &result, sizeof(Texture2D), "Texture2D"); + return 1; } -// Image generation functions -// Generate image: plain color -int lua_GenImageColor(lua_State *L) +// Load texture from image data +static int rl_LoadTextureFromImage(lua_State *L) { - int width = LuaGetArgument_int(L, 1); - int height = LuaGetArgument_int(L, 2); - Color color = LuaGetArgument_Color(L, 3); - Image result = GenImageColor(width, height, color); - LuaPush_Image(L, result); + Image image = *(Image*)RLUA_CHECK_Resource(L, 1, "Image"); + Texture2D result = LoadTextureFromImage(image); + RLUA_PUSH_Resource(L, &result, sizeof(Texture2D), "Texture2D"); return 1; } -// Generate image: vertical gradient -int lua_GenImageGradientV(lua_State *L) +// Load cubemap from image, multiple image cubemap layouts supported +static int rl_LoadTextureCubemap(lua_State *L) { - int width = LuaGetArgument_int(L, 1); - int height = LuaGetArgument_int(L, 2); - Color top = LuaGetArgument_Color(L, 3); - Color bottom = LuaGetArgument_Color(L, 4); - Image result = GenImageGradientV(width, height, top, bottom); - LuaPush_Image(L, result); + Image image = *(Image*)RLUA_CHECK_Resource(L, 1, "Image"); + int layout = (int)luaL_checkinteger(L, 2); + TextureCubemap result = LoadTextureCubemap(image, layout); + RLUA_PUSH_Resource(L, &result, sizeof(TextureCubemap), "TextureCubemap"); return 1; } -// Generate image: horizontal gradient -int lua_GenImageGradientH(lua_State *L) +// Load texture for rendering (framebuffer) +static int rl_LoadRenderTexture(lua_State *L) { - int width = LuaGetArgument_int(L, 1); - int height = LuaGetArgument_int(L, 2); - Color left = LuaGetArgument_Color(L, 3); - Color right = LuaGetArgument_Color(L, 4); - Image result = GenImageGradientH(width, height, left, right); - LuaPush_Image(L, result); + int width = (int)luaL_checkinteger(L, 1); + int height = (int)luaL_checkinteger(L, 2); + RenderTexture2D result = LoadRenderTexture(width, height); + RLUA_PUSH_Resource(L, &result, sizeof(RenderTexture2D), "RenderTexture2D"); return 1; } -// Generate image: radial gradient -int lua_GenImageGradientRadial(lua_State *L) +// Check if a texture is valid (loaded in GPU) +static int rl_IsTextureValid(lua_State *L) { - int width = LuaGetArgument_int(L, 1); - int height = LuaGetArgument_int(L, 2); - float density = LuaGetArgument_float(L, 3); - Color inner = LuaGetArgument_Color(L, 4); - Color outer = LuaGetArgument_Color(L, 5); - Image result = GenImageGradientRadial(width, height, density, inner, outer); - LuaPush_Image(L, result); + Texture2D texture = *(Texture2D*)RLUA_CHECK_Resource(L, 1, "Texture2D"); + bool result = IsTextureValid(texture); + lua_pushboolean(L, result); return 1; } -// Generate image: checked -int lua_GenImageChecked(lua_State *L) -{ - int width = LuaGetArgument_int(L, 1); - int height = LuaGetArgument_int(L, 2); - int checksX = LuaGetArgument_int(L, 3); - int checksY = LuaGetArgument_int(L, 4); - Color col1 = LuaGetArgument_Color(L, 5); - Color col2 = LuaGetArgument_Color(L, 6); - Image result = GenImageChecked(width, height, checksX, checksY, col1, col2); - LuaPush_Image(L, result); - return 1; +// Unload texture from GPU memory (VRAM) +static int rl_UnloadTexture(lua_State *L) +{ + Texture2D texture = *(Texture2D*)RLUA_CHECK_Resource(L, 1, "Texture2D"); + UnloadTexture(texture); + return 0; } -// Generate image: white noise -int lua_GenImageWhiteNoise(lua_State *L) +// Check if a render texture is valid (loaded in GPU) +static int rl_IsRenderTextureValid(lua_State *L) { - int width = LuaGetArgument_int(L, 1); - int height = LuaGetArgument_int(L, 2); - float factor = LuaGetArgument_float(L, 3); - Image result = GenImageWhiteNoise(width, height, factor); - LuaPush_Image(L, result); + RenderTexture2D target = *(RenderTexture2D*)RLUA_CHECK_Resource(L, 1, "RenderTexture2D"); + bool result = IsRenderTextureValid(target); + lua_pushboolean(L, result); return 1; } -// Generate image: perlin noise -int lua_GenImagePerlinNoise(lua_State *L) +// Unload render texture from GPU memory (VRAM) +static int rl_UnloadRenderTexture(lua_State *L) { - int width = LuaGetArgument_int(L, 1); - int height = LuaGetArgument_int(L, 2); - int offsetX = LuaGetArgument_int(L, 3); - int offsetY = LuaGetArgument_int(L, 4); - float scale = LuaGetArgument_float(L, 5); - Image result = GenImagePerlinNoise(width, height, offsetX, offsetY, scale); - LuaPush_Image(L, result); - return 1; + RenderTexture2D target = *(RenderTexture2D*)RLUA_CHECK_Resource(L, 1, "RenderTexture2D"); + UnloadRenderTexture(target); + return 0; } -// Generate image: cellular algorithm. Bigger tileSize means bigger cells -int lua_GenImageCellular(lua_State *L) +// Update GPU texture with new data (pixels should be able to fill texture) +static int rl_UpdateTexture(lua_State *L) { - int width = LuaGetArgument_int(L, 1); - int height = LuaGetArgument_int(L, 2); - int tileSize = LuaGetArgument_int(L, 3); - Image result = GenImageCellular(width, height, tileSize); - LuaPush_Image(L, result); - return 1; + Texture2D texture = *(Texture2D*)RLUA_CHECK_Resource(L, 1, "Texture2D"); + const void * pixels = (const void *)lua_touserdata(L, 2); + UpdateTexture(texture, pixels); + return 0; } -// Texture2D configuration functions +// Update GPU texture rectangle with new data (pixels and rec should fit in texture) +static int rl_UpdateTextureRec(lua_State *L) +{ + Texture2D texture = *(Texture2D*)RLUA_CHECK_Resource(L, 1, "Texture2D"); + Rectangle rec = RLUA_CHECK_Rectangle(L, 2); + const void * pixels = (const void *)lua_touserdata(L, 3); + UpdateTextureRec(texture, rec, pixels); + return 0; +} +// Texture configuration functions // Generate GPU mipmaps for a texture -int lua_GenTextureMipmaps(lua_State *L) +static int rl_GenTextureMipmaps(lua_State *L) { - Texture2D texture = LuaGetArgument_Texture2D(L, 1); + Texture2D * texture = (Texture2D *)lua_touserdata(L, 1); GenTextureMipmaps(texture); return 0; } // Set texture scaling filter mode -int lua_SetTextureFilter(lua_State *L) +static int rl_SetTextureFilter(lua_State *L) { - Texture2D texture = LuaGetArgument_Texture2D(L, 1); - int filterMode = LuaGetArgument_int(L, 2); - SetTextureFilter(texture, filterMode); + Texture2D texture = *(Texture2D*)RLUA_CHECK_Resource(L, 1, "Texture2D"); + int filter = (int)luaL_checkinteger(L, 2); + SetTextureFilter(texture, filter); return 0; } // Set texture wrapping mode -int lua_SetTextureWrap(lua_State *L) +static int rl_SetTextureWrap(lua_State *L) { - Texture2D texture = LuaGetArgument_Texture2D(L, 1); - int wrapMode = LuaGetArgument_int(L, 2); - SetTextureWrap(texture, wrapMode); + Texture2D texture = *(Texture2D*)RLUA_CHECK_Resource(L, 1, "Texture2D"); + int wrap = (int)luaL_checkinteger(L, 2); + SetTextureWrap(texture, wrap); return 0; } -// Texture2D drawing functions - +// Texture drawing functions // Draw a Texture2D -int lua_DrawTexture(lua_State *L) +static int rl_DrawTexture(lua_State *L) { - Texture2D texture = LuaGetArgument_Texture2D(L, 1); - int posX = LuaGetArgument_int(L, 2); - int posY = LuaGetArgument_int(L, 3); - Color tint = LuaGetArgument_Color(L, 4); + Texture2D texture = *(Texture2D*)RLUA_CHECK_Resource(L, 1, "Texture2D"); + int posX = (int)luaL_checkinteger(L, 2); + int posY = (int)luaL_checkinteger(L, 3); + Color tint = RLUA_CHECK_Color(L, 4); DrawTexture(texture, posX, posY, tint); return 0; } // Draw a Texture2D with position defined as Vector2 -int lua_DrawTextureV(lua_State *L) +static int rl_DrawTextureV(lua_State *L) { - Texture2D texture = LuaGetArgument_Texture2D(L, 1); - Vector2 position = LuaGetArgument_Vector2(L, 2); - Color tint = LuaGetArgument_Color(L, 3); + Texture2D texture = *(Texture2D*)RLUA_CHECK_Resource(L, 1, "Texture2D"); + Vector2 position = RLUA_CHECK_Vector2(L, 2); + Color tint = RLUA_CHECK_Color(L, 3); DrawTextureV(texture, position, tint); return 0; } // Draw a Texture2D with extended parameters -int lua_DrawTextureEx(lua_State *L) +static int rl_DrawTextureEx(lua_State *L) { - Texture2D texture = LuaGetArgument_Texture2D(L, 1); - Vector2 position = LuaGetArgument_Vector2(L, 2); - float rotation = LuaGetArgument_float(L, 3); - float scale = LuaGetArgument_float(L, 4); - Color tint = LuaGetArgument_Color(L, 5); + Texture2D texture = *(Texture2D*)RLUA_CHECK_Resource(L, 1, "Texture2D"); + Vector2 position = RLUA_CHECK_Vector2(L, 2); + float rotation = (float)luaL_checknumber(L, 3); + float scale = (float)luaL_checknumber(L, 4); + Color tint = RLUA_CHECK_Color(L, 5); DrawTextureEx(texture, position, rotation, scale, tint); return 0; } // Draw a part of a texture defined by a rectangle -int lua_DrawTextureRec(lua_State *L) +static int rl_DrawTextureRec(lua_State *L) { - Texture2D texture = LuaGetArgument_Texture2D(L, 1); - Rectangle sourceRec = LuaGetArgument_Rectangle(L, 2); - Vector2 position = LuaGetArgument_Vector2(L, 3); - Color tint = LuaGetArgument_Color(L, 4); - DrawTextureRec(texture, sourceRec, position, tint); + Texture2D texture = *(Texture2D*)RLUA_CHECK_Resource(L, 1, "Texture2D"); + Rectangle source = RLUA_CHECK_Rectangle(L, 2); + Vector2 position = RLUA_CHECK_Vector2(L, 3); + Color tint = RLUA_CHECK_Color(L, 4); + DrawTextureRec(texture, source, position, tint); return 0; } // Draw a part of a texture defined by a rectangle with 'pro' parameters -int lua_DrawTexturePro(lua_State *L) +static int rl_DrawTexturePro(lua_State *L) { - Texture2D texture = LuaGetArgument_Texture2D(L, 1); - Rectangle sourceRec = LuaGetArgument_Rectangle(L, 2); - Rectangle destRec = LuaGetArgument_Rectangle(L, 3); - Vector2 origin = LuaGetArgument_Vector2(L, 4); - float rotation = LuaGetArgument_float(L, 5); - Color tint = LuaGetArgument_Color(L, 6); - DrawTexturePro(texture, sourceRec, destRec, origin, rotation, tint); + Texture2D texture = *(Texture2D*)RLUA_CHECK_Resource(L, 1, "Texture2D"); + Rectangle source = RLUA_CHECK_Rectangle(L, 2); + Rectangle dest = RLUA_CHECK_Rectangle(L, 3); + Vector2 origin = RLUA_CHECK_Vector2(L, 4); + float rotation = (float)luaL_checknumber(L, 5); + Color tint = RLUA_CHECK_Color(L, 6); + DrawTexturePro(texture, source, dest, origin, rotation, tint); return 0; } -//------------------------------------------------------------------------------------ -// raylib [text] module functions - Font Loading and Text Drawing -//------------------------------------------------------------------------------------ - -// Get the default Font -int lua_GetFontDefault(lua_State *L) +// Draws a texture (or part of it) that stretches or shrinks nicely +static int rl_DrawTextureNPatch(lua_State *L) { - Font result = GetFontDefault(); - LuaPush_Font(L, result); - return 1; + Texture2D texture = *(Texture2D*)RLUA_CHECK_Resource(L, 1, "Texture2D"); + NPatchInfo nPatchInfo = RLUA_CHECK_NPatchInfo(L, 2); + Rectangle dest = RLUA_CHECK_Rectangle(L, 3); + Vector2 origin = RLUA_CHECK_Vector2(L, 4); + float rotation = (float)luaL_checknumber(L, 5); + Color tint = RLUA_CHECK_Color(L, 6); + DrawTextureNPatch(texture, nPatchInfo, dest, origin, rotation, tint); + return 0; } -// Load font from file into GPU memory (VRAM) -int lua_LoadFont(lua_State *L) +// Color/pixel related functions +// Check if two colors are equal +static int rl_ColorIsEqual(lua_State *L) { - const char *fileName = LuaGetArgument_string(L, 1); - Font result = LoadFont(fileName); - LuaPush_Font(L, result); + Color col1 = RLUA_CHECK_Color(L, 1); + Color col2 = RLUA_CHECK_Color(L, 2); + bool result = ColorIsEqual(col1, col2); + lua_pushboolean(L, result); return 1; } -// Load font from file with extended parameters -int lua_LoadFontEx(lua_State *L) +// Get color with alpha applied, alpha goes from 0.0f to 1.0f +static int rl_Fade(lua_State *L) { - const char *fileName = LuaGetArgument_string(L, 1); - int fontSize = LuaGetArgument_int(L, 2); - int charsCount = LuaGetArgument_int(L, 3); - int fontChars = LuaGetArgument_int(L, 4); - Font result = LoadFontEx(fileName, fontSize, charsCount, fontChars); - LuaPush_Font(L, result); + Color color = RLUA_CHECK_Color(L, 1); + float alpha = (float)luaL_checknumber(L, 2); + Color result = Fade(color, alpha); + RLUA_PUSH_Color(L, result); return 1; } -// Load font data for further use -int lua_LoadFontData(lua_State *L) +// Get hexadecimal value for a Color (0xRRGGBBAA) +static int rl_ColorToInt(lua_State *L) { - const char *fileName = LuaGetArgument_string(L, 1); - int fontSize = LuaGetArgument_int(L, 2); - int fontChars = LuaGetArgument_int(L, 3); - int charsCount = LuaGetArgument_int(L, 4); - bool sdf = LuaGetArgument_bool(L, 5); - CharInfo result = LoadFontData(fileName, fontSize, fontChars, charsCount, sdf); - LuaPush_CharInfo(L, result); + Color color = RLUA_CHECK_Color(L, 1); + int result = ColorToInt(color); + lua_pushinteger(L, result); return 1; } -// Generate image font atlas using chars info -int lua_GenImageFontAtlas(lua_State *L) +// Get Color normalized as float [0..1] +static int rl_ColorNormalize(lua_State *L) { - CharInfo chars = LuaGetArgument_CharInfo(L, 1); - int fontSize = LuaGetArgument_int(L, 2); - int charsCount = LuaGetArgument_int(L, 3); - int padding = LuaGetArgument_int(L, 4); - int packMethod = LuaGetArgument_int(L, 5); - Image result = GenImageFontAtlas(chars, fontSize, charsCount, padding, packMethod); - LuaPush_Image(L, result); + Color color = RLUA_CHECK_Color(L, 1); + Vector4 result = ColorNormalize(color); + RLUA_PUSH_Vector4(L, result); return 1; } -// Unload Font from GPU memory (VRAM) -int lua_UnloadFont(lua_State *L) +// Get Color from normalized values [0..1] +static int rl_ColorFromNormalized(lua_State *L) { - Font font = LuaGetArgument_Font(L, 1); - UnloadFont(font); - return 0; + Vector4 normalized = RLUA_CHECK_Vector4(L, 1); + Color result = ColorFromNormalized(normalized); + RLUA_PUSH_Color(L, result); + return 1; } -// Text drawing functions -// Shows current FPS -int lua_DrawFPS(lua_State *L) +// Get HSV values for a Color, hue [0..360], saturation/value [0..1] +static int rl_ColorToHSV(lua_State *L) { - int posX = LuaGetArgument_int(L, 1); - int posY = LuaGetArgument_int(L, 2); - DrawFPS(posX, posY); - return 0; + Color color = RLUA_CHECK_Color(L, 1); + Vector3 result = ColorToHSV(color); + RLUA_PUSH_Vector3(L, result); + return 1; } -// Draw text (using default font) -int lua_DrawText(lua_State *L) +// Get a Color from HSV values, hue [0..360], saturation/value [0..1] +static int rl_ColorFromHSV(lua_State *L) { - const char *text = LuaGetArgument_string(L, 1); - int posX = LuaGetArgument_int(L, 2); - int posY = LuaGetArgument_int(L, 3); - int fontSize = LuaGetArgument_int(L, 4); - Color color = LuaGetArgument_Color(L, 5); - DrawText(text, posX, posY, fontSize, color); - return 0; + float hue = (float)luaL_checknumber(L, 1); + float saturation = (float)luaL_checknumber(L, 2); + float value = (float)luaL_checknumber(L, 3); + Color result = ColorFromHSV(hue, saturation, value); + RLUA_PUSH_Color(L, result); + return 1; } -// WARNING: Draw text using font and additional parameters -int lua_DrawTextEx(lua_State *L) +// Get color multiplied with another color +static int rl_ColorTint(lua_State *L) { - Font font = LuaGetArgument_Font(L, 1); - const char *text = LuaGetArgument_string(L, 2); - Vector2 position = LuaGetArgument_Vector2(L, 3); - float fontSize = LuaGetArgument_float(L, 4); - float spacing = LuaGetArgument_float(L, 5); - Color tint = LuaGetArgument_Color(L, 6); - DrawTextEx(font, text, position, fontSize, spacing, tint); - return 0; + Color color = RLUA_CHECK_Color(L, 1); + Color tint = RLUA_CHECK_Color(L, 2); + Color result = ColorTint(color, tint); + RLUA_PUSH_Color(L, result); + return 1; } -// Text misc. functions -// Measure string width for default font -int lua_MeasureText(lua_State *L) +// Get color with brightness correction, brightness factor goes from -1.0f to 1.0f +static int rl_ColorBrightness(lua_State *L) { - const char *text = LuaGetArgument_string(L, 1); - int fontSize = LuaGetArgument_int(L, 2); - int result = MeasureText(text, fontSize); - LuaPush_int(L, result); + Color color = RLUA_CHECK_Color(L, 1); + float factor = (float)luaL_checknumber(L, 2); + Color result = ColorBrightness(color, factor); + RLUA_PUSH_Color(L, result); return 1; } -// Measure string size for Font -int lua_MeasureTextEx(lua_State *L) +// Get color with contrast correction, contrast values between -1.0f and 1.0f +static int rl_ColorContrast(lua_State *L) { - Font font = LuaGetArgument_Font(L, 1); - const char *text = LuaGetArgument_string(L, 2); - float fontSize = LuaGetArgument_float(L, 3); - float spacing = LuaGetArgument_float(L, 4); - Vector2 result = MeasureTextEx(font, text, fontSize, spacing); - LuaPush_Vector2(L, result); + Color color = RLUA_CHECK_Color(L, 1); + float contrast = (float)luaL_checknumber(L, 2); + Color result = ColorContrast(color, contrast); + RLUA_PUSH_Color(L, result); return 1; } -// WARNING: FormatText() can be replaced by Lua function: string.format() -// WARNING: SubText() can be replaced by Lua function: string.sub() - -// Get index position for a unicode character on font -int lua_GetGlyphIndex(lua_State *L) +// Get color with alpha applied, alpha goes from 0.0f to 1.0f +static int rl_ColorAlpha(lua_State *L) { - Font font = LuaGetArgument_Font(L, 1); - int character = LuaGetArgument_int(L, 2); - int result = GetGlyphIndex(font, character); - LuaPush_int(L, result); + Color color = RLUA_CHECK_Color(L, 1); + float alpha = (float)luaL_checknumber(L, 2); + Color result = ColorAlpha(color, alpha); + RLUA_PUSH_Color(L, result); return 1; } -//------------------------------------------------------------------------------------ -// raylib [models] module functions - Basic 3d Shapes Drawing Functions -//------------------------------------------------------------------------------------ - -// Draw a line in 3D world space -int lua_DrawLine3D(lua_State *L) +// Get src alpha-blended into dst color with tint +static int rl_ColorAlphaBlend(lua_State *L) { - Vector3 startPos = LuaGetArgument_Vector3(L, 1); - Vector3 endPos = LuaGetArgument_Vector3(L, 2); - Color color = LuaGetArgument_Color(L, 3); - DrawLine3D(startPos, endPos, color); - return 0; + Color dst = RLUA_CHECK_Color(L, 1); + Color src = RLUA_CHECK_Color(L, 2); + Color tint = RLUA_CHECK_Color(L, 3); + Color result = ColorAlphaBlend(dst, src, tint); + RLUA_PUSH_Color(L, result); + return 1; } -// Draw a circle in 3D world space -int lua_DrawCircle3D(lua_State *L) +// Get color lerp interpolation between two colors, factor [0.0f..1.0f] +static int rl_ColorLerp(lua_State *L) { - Vector3 center = LuaGetArgument_Vector3(L, 1); - float radius = LuaGetArgument_float(L, 2); - Vector3 rotationAxis = LuaGetArgument_Vector3(L, 3); - float rotationAngle = LuaGetArgument_float(L, 4); - Color color = LuaGetArgument_Color(L, 5); - DrawCircle3D(center, radius, rotationAxis, rotationAngle, color); - return 0; + Color color1 = RLUA_CHECK_Color(L, 1); + Color color2 = RLUA_CHECK_Color(L, 2); + float factor = (float)luaL_checknumber(L, 3); + Color result = ColorLerp(color1, color2, factor); + RLUA_PUSH_Color(L, result); + return 1; } -// Draw cube -int lua_DrawCube(lua_State *L) +// Get Color structure from hexadecimal value +static int rl_GetColor(lua_State *L) { - Vector3 position = LuaGetArgument_Vector3(L, 1); - float width = LuaGetArgument_float(L, 2); - float height = LuaGetArgument_float(L, 3); - float length = LuaGetArgument_float(L, 4); - Color color = LuaGetArgument_Color(L, 5); - DrawCube(position, width, height, length, color); - return 0; + unsigned int hexValue = (unsigned int)luaL_checkinteger(L, 1); + Color result = GetColor(hexValue); + RLUA_PUSH_Color(L, result); + return 1; } -// Draw cube (Vector version) -int lua_DrawCubeV(lua_State *L) +// Get Color from a source pixel pointer of certain format +static int rl_GetPixelColor(lua_State *L) { - Vector3 position = LuaGetArgument_Vector3(L, 1); - Vector3 size = LuaGetArgument_Vector3(L, 2); - Color color = LuaGetArgument_Color(L, 3); - DrawCubeV(position, size, color); - return 0; + void * srcPtr = lua_touserdata(L, 1); + int format = (int)luaL_checkinteger(L, 2); + Color result = GetPixelColor(srcPtr, format); + RLUA_PUSH_Color(L, result); + return 1; } -// Draw cube wires -int lua_DrawCubeWires(lua_State *L) +// Set color formatted into destination pixel pointer +static int rl_SetPixelColor(lua_State *L) { - Vector3 position = LuaGetArgument_Vector3(L, 1); - float width = LuaGetArgument_float(L, 2); - float height = LuaGetArgument_float(L, 3); - float length = LuaGetArgument_float(L, 4); - Color color = LuaGetArgument_Color(L, 5); - DrawCubeWires(position, width, height, length, color); + void * dstPtr = lua_touserdata(L, 1); + Color color = RLUA_CHECK_Color(L, 2); + int format = (int)luaL_checkinteger(L, 3); + SetPixelColor(dstPtr, color, format); return 0; } -// Draw cube textured -int lua_DrawCubeTexture(lua_State *L) +// Get pixel data size in bytes for certain format +static int rl_GetPixelDataSize(lua_State *L) { - Texture2D texture = LuaGetArgument_Texture2D(L, 1); - Vector3 position = LuaGetArgument_Vector3(L, 2); - float width = LuaGetArgument_float(L, 3); - float height = LuaGetArgument_float(L, 4); - float length = LuaGetArgument_float(L, 5); - Color color = LuaGetArgument_Color(L, 6); - DrawCubeTexture(texture, position, width, height, length, color); - return 0; + int width = (int)luaL_checkinteger(L, 1); + int height = (int)luaL_checkinteger(L, 2); + int format = (int)luaL_checkinteger(L, 3); + int result = GetPixelDataSize(width, height, format); + lua_pushinteger(L, result); + return 1; } -// Draw sphere -int lua_DrawSphere(lua_State *L) +// ------------------------------------------------------------------------------------ +// Font Loading and Text Drawing Functions (Module: text) +// ------------------------------------------------------------------------------------ +// Font loading/unloading functions +// Get the default Font +static int rl_GetFontDefault(lua_State *L) { - Vector3 centerPos = LuaGetArgument_Vector3(L, 1); - float radius = LuaGetArgument_float(L, 2); - Color color = LuaGetArgument_Color(L, 3); - DrawSphere(centerPos, radius, color); - return 0; + Font result = GetFontDefault(); + RLUA_PUSH_Resource(L, &result, sizeof(Font), "Font"); + return 1; } -// Draw sphere with extended parameters -int lua_DrawSphereEx(lua_State *L) +// Load font from file into GPU memory (VRAM) +static int rl_LoadFont(lua_State *L) { - Vector3 centerPos = LuaGetArgument_Vector3(L, 1); - float radius = LuaGetArgument_float(L, 2); - int rings = LuaGetArgument_int(L, 3); - int slices = LuaGetArgument_int(L, 4); - Color color = LuaGetArgument_Color(L, 5); - DrawSphereEx(centerPos, radius, rings, slices, color); - return 0; + const char * fileName = luaL_checkstring(L, 1); + Font result = LoadFont(fileName); + RLUA_PUSH_Resource(L, &result, sizeof(Font), "Font"); + return 1; } -// Draw sphere wires -int lua_DrawSphereWires(lua_State *L) +// Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character set, font size is provided in pixels height +static int rl_LoadFontEx(lua_State *L) { - Vector3 centerPos = LuaGetArgument_Vector3(L, 1); - float radius = LuaGetArgument_float(L, 2); - int rings = LuaGetArgument_int(L, 3); - int slices = LuaGetArgument_int(L, 4); - Color color = LuaGetArgument_Color(L, 5); - DrawSphereWires(centerPos, radius, rings, slices, color); - return 0; -} - -// Draw a cylinder/cone -int lua_DrawCylinder(lua_State *L) -{ - Vector3 position = LuaGetArgument_Vector3(L, 1); - float radiusTop = LuaGetArgument_float(L, 2); - float radiusBottom = LuaGetArgument_float(L, 3); - float height = LuaGetArgument_float(L, 4); - int slices = LuaGetArgument_int(L, 5); - Color color = LuaGetArgument_Color(L, 6); - DrawCylinder(position, radiusTop, radiusBottom, height, slices, color); - return 0; -} - -// Draw a cylinder/cone wires -int lua_DrawCylinderWires(lua_State *L) -{ - Vector3 position = LuaGetArgument_Vector3(L, 1); - float radiusTop = LuaGetArgument_float(L, 2); - float radiusBottom = LuaGetArgument_float(L, 3); - float height = LuaGetArgument_float(L, 4); - int slices = LuaGetArgument_int(L, 5); - Color color = LuaGetArgument_Color(L, 6); - DrawCylinderWires(position, radiusTop, radiusBottom, height, slices, color); - return 0; + const char * fileName = luaL_checkstring(L, 1); + int fontSize = (int)luaL_checkinteger(L, 2); + const int * codepoints = (const int *)lua_touserdata(L, 3); + int codepointCount = (int)luaL_checkinteger(L, 4); + Font result = LoadFontEx(fileName, fontSize, codepoints, codepointCount); + RLUA_PUSH_Resource(L, &result, sizeof(Font), "Font"); + return 1; } -// Draw a plane XZ -int lua_DrawPlane(lua_State *L) +// Load font from Image (XNA style) +static int rl_LoadFontFromImage(lua_State *L) { - Vector3 centerPos = LuaGetArgument_Vector3(L, 1); - Vector2 size = LuaGetArgument_Vector2(L, 2); - Color color = LuaGetArgument_Color(L, 3); - DrawPlane(centerPos, size, color); - return 0; + Image image = *(Image*)RLUA_CHECK_Resource(L, 1, "Image"); + Color key = RLUA_CHECK_Color(L, 2); + int firstChar = (int)luaL_checkinteger(L, 3); + Font result = LoadFontFromImage(image, key, firstChar); + RLUA_PUSH_Resource(L, &result, sizeof(Font), "Font"); + return 1; } -// Draw a ray line -int lua_DrawRay(lua_State *L) +// Load font from memory buffer, fileType refers to extension: i.e. '.ttf' +static int rl_LoadFontFromMemory(lua_State *L) { - Ray ray = LuaGetArgument_Ray(L, 1); - Color color = LuaGetArgument_Color(L, 2); - DrawRay(ray, color); - return 0; + const char * fileType = luaL_checkstring(L, 1); + const unsigned char * fileData = (const unsigned char *)lua_touserdata(L, 2); + int dataSize = (int)luaL_checkinteger(L, 3); + int fontSize = (int)luaL_checkinteger(L, 4); + const int * codepoints = (const int *)lua_touserdata(L, 5); + int codepointCount = (int)luaL_checkinteger(L, 6); + Font result = LoadFontFromMemory(fileType, fileData, dataSize, fontSize, codepoints, codepointCount); + RLUA_PUSH_Resource(L, &result, sizeof(Font), "Font"); + return 1; } -// Draw a grid (centered at (0, 0, 0)) -int lua_DrawGrid(lua_State *L) +// Check if a font is valid (font data loaded, WARNING: GPU texture not checked) +static int rl_IsFontValid(lua_State *L) { - int slices = LuaGetArgument_int(L, 1); - float spacing = LuaGetArgument_float(L, 2); - DrawGrid(slices, spacing); - return 0; + Font font = *(Font*)RLUA_CHECK_Resource(L, 1, "Font"); + bool result = IsFontValid(font); + lua_pushboolean(L, result); + return 1; } -// Draw simple gizmo -int lua_DrawGizmo(lua_State *L) +// Load font data for further use +static int rl_LoadFontData(lua_State *L) { - Vector3 position = LuaGetArgument_Vector3(L, 1); - DrawGizmo(position); - return 0; + const unsigned char * fileData = (const unsigned char *)lua_touserdata(L, 1); + int dataSize = (int)luaL_checkinteger(L, 2); + int fontSize = (int)luaL_checkinteger(L, 3); + const int * codepoints = (const int *)lua_touserdata(L, 4); + int codepointCount = (int)luaL_checkinteger(L, 5); + int type = (int)luaL_checkinteger(L, 6); + int glyphCount = 0; + GlyphInfo * result = LoadFontData(fileData, dataSize, fontSize, codepoints, codepointCount, type, &glyphCount); + RLUA_PUSH_View(L, result, glyphCount, "GlyphInfo", true); + return 1; } -//------------------------------------------------------------------------------------ -// raylib [models] module functions -//------------------------------------------------------------------------------------ - -// Load model from files (mesh and material) -int lua_LoadModel(lua_State *L) +// Generate image font atlas using chars info +static int rl_GenImageFontAtlas(lua_State *L) { - const char *fileName = LuaGetArgument_string(L, 1); - Model result = LoadModel(fileName); - LuaPush_Model(L, result); + const GlyphInfo * glyphs = (const GlyphInfo *)lua_touserdata(L, 1); + Rectangle ** glyphRecs = (Rectangle **)lua_touserdata(L, 2); + int glyphCount = (int)luaL_checkinteger(L, 3); + int fontSize = (int)luaL_checkinteger(L, 4); + int padding = (int)luaL_checkinteger(L, 5); + int packMethod = (int)luaL_checkinteger(L, 6); + Image result = GenImageFontAtlas(glyphs, glyphRecs, glyphCount, fontSize, padding, packMethod); + RLUA_PUSH_Resource(L, &result, sizeof(Image), "Image"); return 1; } -// Load model from generated mesh -int lua_LoadModelFromMesh(lua_State *L) +// Unload font chars info data (RAM) +static int rl_UnloadFontData(lua_State *L) { - Mesh mesh = LuaGetArgument_Mesh(L, 1); - Model result = LoadModelFromMesh(mesh); - LuaPush_Model(L, result); - return 1; + GlyphInfo * glyphs = (GlyphInfo *)lua_touserdata(L, 1); + int glyphCount = (int)luaL_checkinteger(L, 2); + UnloadFontData(glyphs, glyphCount); + return 0; } -// Unload model from memory (RAM and/or VRAM) -int lua_UnloadModel(lua_State *L) +// Unload font from GPU memory (VRAM) +static int rl_UnloadFont(lua_State *L) { - Model model = LuaGetArgument_Model(L, 1); - UnloadModel(model); + Font font = *(Font*)RLUA_CHECK_Resource(L, 1, "Font"); + UnloadFont(font); return 0; } -// Mesh loading/unloading functions -// Load mesh from file -int lua_LoadMesh(lua_State *L) +// Export font as code file, returns true on success +static int rl_ExportFontAsCode(lua_State *L) { - const char *fileName = LuaGetArgument_string(L, 1); - Mesh result = LoadMesh(fileName); - LuaPush_Mesh(L, result); + Font font = *(Font*)RLUA_CHECK_Resource(L, 1, "Font"); + const char * fileName = luaL_checkstring(L, 2); + bool result = ExportFontAsCode(font, fileName); + lua_pushboolean(L, result); return 1; } -// Unload mesh from memory (RAM and/or VRAM) -int lua_UnloadMesh(lua_State *L) +// Text drawing functions +// Draw current FPS +static int rl_DrawFPS(lua_State *L) { - Mesh mesh = LuaGetArgument_Mesh(L, 1); - UnloadMesh(mesh); + int posX = (int)luaL_checkinteger(L, 1); + int posY = (int)luaL_checkinteger(L, 2); + DrawFPS(posX, posY); return 0; } -// Export mesh as an OBJ file -int lua_ExportMesh(lua_State *L) +// Draw text (using default font) +static int rl_DrawText(lua_State *L) { - const char *fileName = LuaGetArgument_string(L, 1); - Mesh mesh = LuaGetArgument_Mesh(L, 2); - ExportMesh(fileName, mesh); + const char * text = luaL_checkstring(L, 1); + int posX = (int)luaL_checkinteger(L, 2); + int posY = (int)luaL_checkinteger(L, 3); + int fontSize = (int)luaL_checkinteger(L, 4); + Color color = RLUA_CHECK_Color(L, 5); + DrawText(text, posX, posY, fontSize, color); return 0; } -// Mesh manipulation functions -// Compute mesh bounding box limits -int lua_MeshBoundingBox(lua_State *L) -{ - Mesh mesh = LuaGetArgument_Mesh(L, 1); - BoundingBox result = MeshBoundingBox(mesh); - LuaPush_BoundingBox(L, result); - return 1; -} - -// Compute mesh tangents -int lua_MeshTangents(lua_State *L) +// Draw text using font and additional parameters +static int rl_DrawTextEx(lua_State *L) { - Mesh mesh = LuaGetArgument_Mesh(L, 1); - MeshTangents(mesh); + Font font = *(Font*)RLUA_CHECK_Resource(L, 1, "Font"); + const char * text = luaL_checkstring(L, 2); + Vector2 position = RLUA_CHECK_Vector2(L, 3); + float fontSize = (float)luaL_checknumber(L, 4); + float spacing = (float)luaL_checknumber(L, 5); + Color tint = RLUA_CHECK_Color(L, 6); + DrawTextEx(font, text, position, fontSize, spacing, tint); return 0; } -// Compute mesh binormals -int lua_MeshBinormals(lua_State *L) +// Draw text using Font and pro parameters (rotation) +static int rl_DrawTextPro(lua_State *L) { - Mesh mesh = LuaGetArgument_Mesh(L, 1); - MeshBinormals(mesh); + Font font = *(Font*)RLUA_CHECK_Resource(L, 1, "Font"); + const char * text = luaL_checkstring(L, 2); + Vector2 position = RLUA_CHECK_Vector2(L, 3); + Vector2 origin = RLUA_CHECK_Vector2(L, 4); + float rotation = (float)luaL_checknumber(L, 5); + float fontSize = (float)luaL_checknumber(L, 6); + float spacing = (float)luaL_checknumber(L, 7); + Color tint = RLUA_CHECK_Color(L, 8); + DrawTextPro(font, text, position, origin, rotation, fontSize, spacing, tint); return 0; } -// Mesh generation functions - -// Generate plane mesh (with subdivisions) -int lua_GenMeshPlane(lua_State *L) -{ - float width = LuaGetArgument_float(L, 1); - float length = LuaGetArgument_float(L, 2); - int resX = LuaGetArgument_int(L, 3); - int resZ = LuaGetArgument_int(L, 4); - Mesh result = GenMeshPlane(width, length, resX, resZ); - LuaPush_Mesh(L, result); - return 1; -} - -// Generate cuboid mesh -int lua_GenMeshCube(lua_State *L) +// Draw one character (codepoint) +static int rl_DrawTextCodepoint(lua_State *L) { - float width = LuaGetArgument_float(L, 1); - float height = LuaGetArgument_float(L, 2); - float length = LuaGetArgument_float(L, 3); - Mesh result = GenMeshCube(width, height, length); - LuaPush_Mesh(L, result); - return 1; + Font font = *(Font*)RLUA_CHECK_Resource(L, 1, "Font"); + int codepoint = (int)luaL_checkinteger(L, 2); + Vector2 position = RLUA_CHECK_Vector2(L, 3); + float fontSize = (float)luaL_checknumber(L, 4); + Color tint = RLUA_CHECK_Color(L, 5); + DrawTextCodepoint(font, codepoint, position, fontSize, tint); + return 0; } -// Generate sphere mesh (standard sphere) -int lua_GenMeshSphere(lua_State *L) +// Draw multiple character (codepoint) +static int rl_DrawTextCodepoints(lua_State *L) { - float radius = LuaGetArgument_float(L, 1); - int rings = LuaGetArgument_int(L, 2); - int slices = LuaGetArgument_int(L, 3); - Mesh result = GenMeshSphere(radius, rings, slices); - LuaPush_Mesh(L, result); - return 1; + Font font = *(Font*)RLUA_CHECK_Resource(L, 1, "Font"); + const int * codepoints = (const int *)lua_touserdata(L, 2); + int codepointCount = (int)luaL_checkinteger(L, 3); + Vector2 position = RLUA_CHECK_Vector2(L, 4); + float fontSize = (float)luaL_checknumber(L, 5); + float spacing = (float)luaL_checknumber(L, 6); + Color tint = RLUA_CHECK_Color(L, 7); + DrawTextCodepoints(font, codepoints, codepointCount, position, fontSize, spacing, tint); + return 0; } -// Generate half-sphere mesh (no bottom cap) -int lua_GenMeshHemiSphere(lua_State *L) +// Text font info functions +// Set vertical line spacing when drawing with line-breaks +static int rl_SetTextLineSpacing(lua_State *L) { - float radius = LuaGetArgument_float(L, 1); - int rings = LuaGetArgument_int(L, 2); - int slices = LuaGetArgument_int(L, 3); - Mesh result = GenMeshHemiSphere(radius, rings, slices); - LuaPush_Mesh(L, result); - return 1; + int spacing = (int)luaL_checkinteger(L, 1); + SetTextLineSpacing(spacing); + return 0; } -// Generate cylinder mesh -int lua_GenMeshCylinder(lua_State *L) +// Measure string width for default font +static int rl_MeasureText(lua_State *L) { - float radius = LuaGetArgument_float(L, 1); - float height = LuaGetArgument_float(L, 2); - int slices = LuaGetArgument_int(L, 3); - Mesh result = GenMeshCylinder(radius, height, slices); - LuaPush_Mesh(L, result); + const char * text = luaL_checkstring(L, 1); + int fontSize = (int)luaL_checkinteger(L, 2); + int result = MeasureText(text, fontSize); + lua_pushinteger(L, result); return 1; } -// Generate torus mesh -int lua_GenMeshTorus(lua_State *L) +// Measure string size for Font +static int rl_MeasureTextEx(lua_State *L) { - float radius = LuaGetArgument_float(L, 1); - float size = LuaGetArgument_float(L, 2); - int radSeg = LuaGetArgument_int(L, 3); - int sides = LuaGetArgument_int(L, 4); - Mesh result = GenMeshTorus(radius, size, radSeg, sides); - LuaPush_Mesh(L, result); + Font font = *(Font*)RLUA_CHECK_Resource(L, 1, "Font"); + const char * text = luaL_checkstring(L, 2); + float fontSize = (float)luaL_checknumber(L, 3); + float spacing = (float)luaL_checknumber(L, 4); + Vector2 result = MeasureTextEx(font, text, fontSize, spacing); + RLUA_PUSH_Vector2(L, result); return 1; } -// Generate trefoil knot mesh -int lua_GenMeshKnot(lua_State *L) +// Measure string size for an existing array of codepoints for Font +static int rl_MeasureTextCodepoints(lua_State *L) { - float radius = LuaGetArgument_float(L, 1); - float size = LuaGetArgument_float(L, 2); - int radSeg = LuaGetArgument_int(L, 3); - int sides = LuaGetArgument_int(L, 4); - Mesh result = GenMeshKnot(radius, size, radSeg, sides); - LuaPush_Mesh(L, result); + Font font = *(Font*)RLUA_CHECK_Resource(L, 1, "Font"); + const int * codepoints = (const int *)lua_touserdata(L, 2); + int length = (int)luaL_checkinteger(L, 3); + float fontSize = (float)luaL_checknumber(L, 4); + float spacing = (float)luaL_checknumber(L, 5); + Vector2 result = MeasureTextCodepoints(font, codepoints, length, fontSize, spacing); + RLUA_PUSH_Vector2(L, result); return 1; } -// Generate heightmap mesh from image data -int lua_GenMeshHeightmap(lua_State *L) +// Get glyph index position in font for a codepoint (unicode character), fallback to '?' if not found +static int rl_GetGlyphIndex(lua_State *L) { - Image heightmap = LuaGetArgument_Image(L, 1); - Vector3 size = LuaGetArgument_Vector3(L, 2); - Mesh result = GenMeshHeightmap(heightmap, size); - LuaPush_Mesh(L, result); + Font font = *(Font*)RLUA_CHECK_Resource(L, 1, "Font"); + int codepoint = (int)luaL_checkinteger(L, 2); + int result = GetGlyphIndex(font, codepoint); + lua_pushinteger(L, result); return 1; } -// Generate cubes-based map mesh from image data -int lua_GenMeshCubicmap(lua_State *L) +// Get glyph font info data for a codepoint (unicode character), fallback to '?' if not found +static int rl_GetGlyphInfo(lua_State *L) { - Image cubicmap = LuaGetArgument_Image(L, 1); - Vector3 cubeSize = LuaGetArgument_Vector3(L, 2); - Mesh result = GenMeshCubicmap(cubicmap, cubeSize); - LuaPush_Mesh(L, result); + Font font = *(Font*)RLUA_CHECK_Resource(L, 1, "Font"); + int codepoint = (int)luaL_checkinteger(L, 2); + GlyphInfo result = GetGlyphInfo(font, codepoint); + RLUA_PUSH_GlyphInfo(L, result); return 1; } -// Material loading/unloading functions -// Load material from file -int lua_LoadMaterial(lua_State *L) +// Get glyph rectangle in font atlas for a codepoint (unicode character), fallback to '?' if not found +static int rl_GetGlyphAtlasRec(lua_State *L) { - const char *fileName = LuaGetArgument_string(L, 1); - Material result = LoadMaterial(fileName); - LuaPush_Material(L, result); + Font font = *(Font*)RLUA_CHECK_Resource(L, 1, "Font"); + int codepoint = (int)luaL_checkinteger(L, 2); + Rectangle result = GetGlyphAtlasRec(font, codepoint); + RLUA_PUSH_Rectangle(L, result); return 1; } -// Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps) -int lua_LoadMaterialDefault(lua_State *L) +// Text codepoints management functions (unicode characters) +// Load UTF-8 text encoded from codepoints array +static int rl_LoadUTF8(lua_State *L) { - Material result = LoadMaterialDefault(); - LuaPush_Material(L, result); + const int * codepoints = (const int *)lua_touserdata(L, 1); + int length = (int)luaL_checkinteger(L, 2); + char * result = LoadUTF8(codepoints, length); + lua_pushstring(L, result); return 1; } -// Unload material from GPU memory (VRAM) -int lua_UnloadMaterial(lua_State *L) +// Unload UTF-8 text encoded from codepoints array +static int rl_UnloadUTF8(lua_State *L) { - Material material = LuaGetArgument_Material(L, 1); - UnloadMaterial(material); + const char * text = luaL_checkstring(L, 1); + UnloadUTF8((char *)text); return 0; } -// Model drawing functions -// Draw a model (with texture if set) -int lua_DrawModel(lua_State *L) +// Load all codepoints from a UTF-8 text string, codepoints count returned by parameter +static int rl_LoadCodepoints(lua_State *L) { - Model model = LuaGetArgument_Model(L, 1); - Vector3 position = LuaGetArgument_Vector3(L, 2); - float scale = LuaGetArgument_float(L, 3); - Color tint = LuaGetArgument_Color(L, 4); - DrawModel(model, position, scale, tint); - return 0; + const char * text = luaL_checkstring(L, 1); + int count = 0; + int * result = LoadCodepoints(text, &count); + RLUA_PUSH_View(L, result, count, "int", true); + return 1; } -// Draw a model with extended parameters -int lua_DrawModelEx(lua_State *L) -{ - Model model = LuaGetArgument_Model(L, 1); - Vector3 position = LuaGetArgument_Vector3(L, 2); - Vector3 rotationAxis = LuaGetArgument_Vector3(L, 3); - float rotationAngle = LuaGetArgument_float(L, 4); - Vector3 scale = LuaGetArgument_Vector3(L, 5); - Color tint = LuaGetArgument_Color(L, 6); - DrawModelEx(model, position, rotationAxis, rotationAngle, scale, tint); +// Unload codepoints data from memory +static int rl_UnloadCodepoints(lua_State *L) +{ + int * codepoints = (int *)lua_touserdata(L, 1); + UnloadCodepoints(codepoints); return 0; } -// Draw a model wires (with texture if set) -int lua_DrawModelWires(lua_State *L) +// Get total number of codepoints in a UTF-8 encoded string +static int rl_GetCodepointCount(lua_State *L) { - Model model = LuaGetArgument_Model(L, 1); - Vector3 position = LuaGetArgument_Vector3(L, 2); - float scale = LuaGetArgument_float(L, 3); - Color tint = LuaGetArgument_Color(L, 4); - DrawModelWires(model, position, scale, tint); - return 0; + const char * text = luaL_checkstring(L, 1); + int result = GetCodepointCount(text); + lua_pushinteger(L, result); + return 1; } -// Draw a model wires (with texture if set) with extended parameters -int lua_DrawModelWiresEx(lua_State *L) -{ - Model model = LuaGetArgument_Model(L, 1); - Vector3 position = LuaGetArgument_Vector3(L, 2); - Vector3 rotationAxis = LuaGetArgument_Vector3(L, 3); - float rotationAngle = LuaGetArgument_float(L, 4); - Vector3 scale = LuaGetArgument_Vector3(L, 5); - Color tint = LuaGetArgument_Color(L, 6); - DrawModelWiresEx(model, position, rotationAxis, rotationAngle, scale, tint); - return 0; +// Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure +static int rl_GetCodepoint(lua_State *L) +{ + const char * text = luaL_checkstring(L, 1); + int * codepointSize = (int *)lua_touserdata(L, 2); + int result = GetCodepoint(text, codepointSize); + lua_pushinteger(L, result); + return 1; } -// Draw bounding box (wires) -int lua_DrawBoundingBox(lua_State *L) +// Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure +static int rl_GetCodepointNext(lua_State *L) { - BoundingBox box = LuaGetArgument_BoundingBox(L, 1); - Color color = LuaGetArgument_Color(L, 2); - DrawBoundingBox(box, color); - return 0; + const char * text = luaL_checkstring(L, 1); + int * codepointSize = (int *)lua_touserdata(L, 2); + int result = GetCodepointNext(text, codepointSize); + lua_pushinteger(L, result); + return 1; } -// Draw a billboard texture -int lua_DrawBillboard(lua_State *L) +// Get previous codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure +static int rl_GetCodepointPrevious(lua_State *L) { - Camera camera = LuaGetArgument_Camera(L, 1); - Texture2D texture = LuaGetArgument_Texture2D(L, 2); - Vector3 center = LuaGetArgument_Vector3(L, 3); - float size = LuaGetArgument_float(L, 4); - Color tint = LuaGetArgument_Color(L, 5); - DrawBillboard(camera, texture, center, size, tint); - return 0; + const char * text = luaL_checkstring(L, 1); + int * codepointSize = (int *)lua_touserdata(L, 2); + int result = GetCodepointPrevious(text, codepointSize); + lua_pushinteger(L, result); + return 1; } -// Draw a billboard texture defined by sourceRec -int lua_DrawBillboardRec(lua_State *L) +// Encode one codepoint into UTF-8 byte array (array length returned as parameter) +static int rl_CodepointToUTF8(lua_State *L) { - Camera camera = LuaGetArgument_Camera(L, 1); - Texture2D texture = LuaGetArgument_Texture2D(L, 2); - Rectangle sourceRec = LuaGetArgument_Rectangle(L, 3); - Vector3 center = LuaGetArgument_Vector3(L, 4); - float size = LuaGetArgument_float(L, 5); - Color tint = LuaGetArgument_Color(L, 6); - DrawBillboardRec(camera, texture, sourceRec, center, size, tint); - return 0; + int codepoint = (int)luaL_checkinteger(L, 1); + int utf8Size = 0; + const char * result = CodepointToUTF8(codepoint, &utf8Size); + RLUA_PUSH_View(L, result, utf8Size, "const char", true); + return 1; } -// Collision detection functions -// Detect collision between two spheres -int lua_CheckCollisionSpheres(lua_State *L) +// Text strings management functions (no UTF-8 strings, only byte chars) +// WARNING 1: Most of these functions use internal static buffers[], it's recommended to store returned data on user-side for re-use +// WARNING 2: Some functions allocate memory internally for the returned strings, those strings must be freed by user using MemFree() +// Load text as separate lines ('\n') +static int rl_LoadTextLines(lua_State *L) { - Vector3 centerA = LuaGetArgument_Vector3(L, 1); - float radiusA = LuaGetArgument_float(L, 2); - Vector3 centerB = LuaGetArgument_Vector3(L, 3); - float radiusB = LuaGetArgument_float(L, 4); - bool result = CheckCollisionSpheres(centerA, radiusA, centerB, radiusB); - LuaPush_bool(L, result); + const char * text = luaL_checkstring(L, 1); + int count = 0; + char ** result = LoadTextLines(text, &count); + RLUA_PUSH_View(L, result, count, "char *", true); return 1; } -// Detect collision between two bounding boxes -int lua_CheckCollisionBoxes(lua_State *L) +// Unload text lines +static int rl_UnloadTextLines(lua_State *L) { - BoundingBox box1 = LuaGetArgument_BoundingBox(L, 1); - BoundingBox box2 = LuaGetArgument_BoundingBox(L, 2); - bool result = CheckCollisionBoxes(box1, box2); - LuaPush_bool(L, result); - return 1; + char ** text = (char **)lua_touserdata(L, 1); + int lineCount = (int)luaL_checkinteger(L, 2); + UnloadTextLines(text, lineCount); + return 0; } -// Detect collision between box and sphere -int lua_CheckCollisionBoxSphere(lua_State *L) +// Copy one string to another, returns bytes copied +static int rl_TextCopy(lua_State *L) { - BoundingBox box = LuaGetArgument_BoundingBox(L, 1); - Vector3 centerSphere = LuaGetArgument_Vector3(L, 2); - float radiusSphere = LuaGetArgument_float(L, 3); - bool result = CheckCollisionBoxSphere(box, centerSphere, radiusSphere); - LuaPush_bool(L, result); + const char * dst = luaL_checkstring(L, 1); + const char * src = luaL_checkstring(L, 2); + int result = TextCopy((char *)dst, src); + lua_pushinteger(L, result); return 1; } -// Detect collision between ray and sphere -int lua_CheckCollisionRaySphere(lua_State *L) +// Check if two text string are equal +static int rl_TextIsEqual(lua_State *L) { - Ray ray = LuaGetArgument_Ray(L, 1); - Vector3 spherePosition = LuaGetArgument_Vector3(L, 2); - float sphereRadius = LuaGetArgument_float(L, 3); - bool result = CheckCollisionRaySphere(ray, spherePosition, sphereRadius); - LuaPush_bool(L, result); + const char * text1 = luaL_checkstring(L, 1); + const char * text2 = luaL_checkstring(L, 2); + bool result = TextIsEqual(text1, text2); + lua_pushboolean(L, result); return 1; } -// Detect collision between ray and sphere, returns collision point -int lua_CheckCollisionRaySphereEx(lua_State *L) +// Get text length, checks for '\0' ending +static int rl_TextLength(lua_State *L) { - Ray ray = LuaGetArgument_Ray(L, 1); - Vector3 spherePosition = LuaGetArgument_Vector3(L, 2); - float sphereRadius = LuaGetArgument_float(L, 3); - Vector3 collisionPoint = LuaGetArgument_Vector3(L, 4); - bool result = CheckCollisionRaySphereEx(ray, spherePosition, sphereRadius, collisionPoint); - LuaPush_bool(L, result); + const char * text = luaL_checkstring(L, 1); + unsigned int result = TextLength(text); + lua_pushinteger(L, result); return 1; } -// Detect collision between ray and box -int lua_CheckCollisionRayBox(lua_State *L) +// Text formatting with variables (sprintf() style) +static int rl_TextFormat(lua_State *L) { - Ray ray = LuaGetArgument_Ray(L, 1); - BoundingBox box = LuaGetArgument_BoundingBox(L, 2); - bool result = CheckCollisionRayBox(ray, box); - LuaPush_bool(L, result); + int n = lua_gettop(L); + if (n < 1) return luaL_error(L, "TextFormat requires at least 1 argument"); + if (n == 1) { + lua_pushstring(L, TextFormat("%s", luaL_checkstring(L, 1))); + } else { + lua_getglobal(L, "string"); + lua_getfield(L, -1, "format"); + for (int i = 1; i <= n; i++) lua_pushvalue(L, i); + lua_call(L, n, 1); + const char *formatted = lua_tostring(L, -1); + lua_pushstring(L, TextFormat("%s", formatted)); + lua_insert(L, 1); + lua_settop(L, 1); + } return 1; } -// Get collision info between ray and model -int lua_GetCollisionRayModel(lua_State *L) +// Get a piece of a text string +static int rl_TextSubtext(lua_State *L) { - Ray ray = LuaGetArgument_Ray(L, 1); - Model model = LuaGetArgument_Model(L, 2); - RayHitInfo result = GetCollisionRayModel(ray, model); - LuaPush_RayHitInfo(L, result); + const char * text = luaL_checkstring(L, 1); + int position = (int)luaL_checkinteger(L, 2); + int length = (int)luaL_checkinteger(L, 3); + const char * result = TextSubtext(text, position, length); + lua_pushstring(L, result); return 1; } -// Get collision info between ray and triangle -int lua_GetCollisionRayTriangle(lua_State *L) +// Remove text spaces, concat words +static int rl_TextRemoveSpaces(lua_State *L) { - Ray ray = LuaGetArgument_Ray(L, 1); - Vector3 p1 = LuaGetArgument_Vector3(L, 2); - Vector3 p2 = LuaGetArgument_Vector3(L, 3); - Vector3 p3 = LuaGetArgument_Vector3(L, 4); - RayHitInfo result = GetCollisionRayTriangle(ray, p1, p2, p3); - LuaPush_RayHitInfo(L, result); + const char * text = luaL_checkstring(L, 1); + const char * result = TextRemoveSpaces(text); + lua_pushstring(L, result); return 1; } -// Get collision info between ray and ground plane (Y-normal plane) -int lua_GetCollisionRayGround(lua_State *L) +// Get text between two strings +static int rl_GetTextBetween(lua_State *L) { - Ray ray = LuaGetArgument_Ray(L, 1); - float groundHeight = LuaGetArgument_float(L, 2); - RayHitInfo result = GetCollisionRayGround(ray, groundHeight); - LuaPush_RayHitInfo(L, result); + const char * text = luaL_checkstring(L, 1); + const char * begin = luaL_checkstring(L, 2); + const char * end = luaL_checkstring(L, 3); + char * result = GetTextBetween(text, begin, end); + lua_pushstring(L, result); return 1; } -//------------------------------------------------------------------------------------ -// raylib [raymath] module functions - Shaders -//------------------------------------------------------------------------------------ - -// WARNING: Load chars array from text file -int lua_LoadText(lua_State *L) +// Replace text string with new string +static int rl_TextReplace(lua_State *L) { - const char *fileName = LuaGetArgument_string(L, 1); - char *result = LoadText(fileName); - LuaPush_string(L, result); // WARNING_ LuaPush_char not valid + const char * text = luaL_checkstring(L, 1); + const char * search = luaL_checkstring(L, 2); + const char * replacement = luaL_checkstring(L, 3); + char * result = TextReplace(text, search, replacement); + lua_pushstring(L, result); return 1; } -// Load shader from files and bind default locations -int lua_LoadShader(lua_State *L) +// Replace text string with new string, memory must be MemFree() +static int rl_TextReplaceAlloc(lua_State *L) { - const char *vsFileName = LuaGetArgument_string(L, 1); - const char *fsFileName = LuaGetArgument_string(L, 2); - Shader result = LoadShader(vsFileName, fsFileName); - LuaPush_Shader(L, result); + const char * text = luaL_checkstring(L, 1); + const char * search = luaL_checkstring(L, 2); + const char * replacement = luaL_checkstring(L, 3); + char * result = TextReplaceAlloc(text, search, replacement); + lua_pushstring(L, result); return 1; } -// Load shader from code strings and bind default locations -int lua_LoadShaderCode(lua_State *L) +// Replace text between two specific strings +static int rl_TextReplaceBetween(lua_State *L) { - char *vsCode = LuaGetArgument_char(L, 1); - char *fsCode = LuaGetArgument_char(L, 2); - Shader result = LoadShaderCode(vsCode, fsCode); - LuaPush_Shader(L, result); + const char * text = luaL_checkstring(L, 1); + const char * begin = luaL_checkstring(L, 2); + const char * end = luaL_checkstring(L, 3); + const char * replacement = luaL_checkstring(L, 4); + char * result = TextReplaceBetween(text, begin, end, replacement); + lua_pushstring(L, result); return 1; } -// Unload shader from GPU memory (VRAM) -int lua_UnloadShader(lua_State *L) +// Replace text between two specific strings, memory must be MemFree() +static int rl_TextReplaceBetweenAlloc(lua_State *L) { - Shader shader = LuaGetArgument_Shader(L, 1); - UnloadShader(shader); - return 0; + const char * text = luaL_checkstring(L, 1); + const char * begin = luaL_checkstring(L, 2); + const char * end = luaL_checkstring(L, 3); + const char * replacement = luaL_checkstring(L, 4); + char * result = TextReplaceBetweenAlloc(text, begin, end, replacement); + lua_pushstring(L, result); + return 1; } -// Get default shader -int lua_GetShaderDefault(lua_State *L) +// Insert text in a defined byte position +static int rl_TextInsert(lua_State *L) { - Shader result = GetShaderDefault(); - LuaPush_Shader(L, result); + const char * text = luaL_checkstring(L, 1); + const char * insert = luaL_checkstring(L, 2); + int position = (int)luaL_checkinteger(L, 3); + char * result = TextInsert(text, insert, position); + lua_pushstring(L, result); return 1; } -// Get default texture -int lua_GetTextureDefault(lua_State *L) +// Insert text in a defined byte position, memory must be MemFree() +static int rl_TextInsertAlloc(lua_State *L) { - Texture2D result = GetTextureDefault(); - LuaPush_Texture2D(L, result); + const char * text = luaL_checkstring(L, 1); + const char * insert = luaL_checkstring(L, 2); + int position = (int)luaL_checkinteger(L, 3); + char * result = TextInsertAlloc(text, insert, position); + lua_pushstring(L, result); return 1; } -// Shader configuration functions - -// Get shader uniform location -int lua_GetShaderLocation(lua_State *L) +// Join text strings with delimiter +static int rl_TextJoin(lua_State *L) { - Shader shader = LuaGetArgument_Shader(L, 1); - const char *uniformName = LuaGetArgument_string(L, 2); - int result = GetShaderLocation(shader, uniformName); - LuaPush_int(L, result); + char ** textList = (char **)lua_touserdata(L, 1); + int count = (int)luaL_checkinteger(L, 2); + const char * delimiter = luaL_checkstring(L, 3); + char * result = TextJoin(textList, count, delimiter); + lua_pushstring(L, result); return 1; } -// WARNING: Set shader uniform values (float) -int lua_SetShaderValue(lua_State* L) +// Split text into multiple strings, using MAX_TEXTSPLIT_COUNT static strings +static int rl_TextSplit(lua_State *L) { - Shader arg1 = LuaGetArgument_Shader(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - GET_TABLE(float, arg3, 3); - SetShaderValue(arg1, arg2, arg3, arg3_size); - free(arg3); - return 0; + const char * text = luaL_checkstring(L, 1); + char delimiter = (char)luaL_checkinteger(L, 2); + int count = 0; + char ** result = TextSplit(text, delimiter, &count); + RLUA_PUSH_View(L, result, count, "char *", true); + return 1; } -// WARNING: Set shader uniform values (int) -int lua_SetShaderValuei(lua_State* L) +// Append text at specific position and move cursor +static int rl_TextAppend(lua_State *L) { - Shader arg1 = LuaGetArgument_Shader(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - GET_TABLE(int, arg3, 3); - SetShaderValuei(arg1, arg2, arg3, arg3_size); - free(arg3); + const char * text = luaL_checkstring(L, 1); + const char * append = luaL_checkstring(L, 2); + int * position = (int *)lua_touserdata(L, 3); + TextAppend((char *)text, append, position); return 0; } -// Set shader uniform value (matrix 4x4) -int lua_SetShaderValueMatrix(lua_State *L) +// Find first text occurrence within a string, -1 if not found +static int rl_TextFindIndex(lua_State *L) { - Shader shader = LuaGetArgument_Shader(L, 1); - int uniformLoc = LuaGetArgument_int(L, 2); - Matrix mat = LuaGetArgument_Matrix(L, 3); - SetShaderValueMatrix(shader, uniformLoc, mat); - return 0; + const char * text = luaL_checkstring(L, 1); + const char * search = luaL_checkstring(L, 2); + int result = TextFindIndex(text, search); + lua_pushinteger(L, result); + return 1; } -// Set a custom projection matrix (replaces internal projection matrix) -int lua_SetMatrixProjection(lua_State *L) +// Get upper case version of provided string +static int rl_TextToUpper(lua_State *L) { - Matrix proj = LuaGetArgument_Matrix(L, 1); - SetMatrixProjection(proj); - return 0; + const char * text = luaL_checkstring(L, 1); + char * result = TextToUpper(text); + lua_pushstring(L, result); + return 1; } -// Set a custom modelview matrix (replaces internal modelview matrix) -int lua_SetMatrixModelview(lua_State *L) +// Get lower case version of provided string +static int rl_TextToLower(lua_State *L) { - Matrix view = LuaGetArgument_Matrix(L, 1); - SetMatrixModelview(view); - return 0; + const char * text = luaL_checkstring(L, 1); + char * result = TextToLower(text); + lua_pushstring(L, result); + return 1; } -// Get internal modelview matrix -int lua_GetMatrixModelview(lua_State *L) +// Get Pascal case notation version of provided string +static int rl_TextToPascal(lua_State *L) { - Matrix view = LuaGetArgument_Matrix(L, 1); - Matrix result = GetMatrixModelview(view); - LuaPush_Matrix(L, result); + const char * text = luaL_checkstring(L, 1); + char * result = TextToPascal(text); + lua_pushstring(L, result); return 1; } -// Texture maps generation (PBR) -// NOTE: Required shaders should be provided -// Generate cubemap texture from HDR texture -int lua_GenTextureCubemap(lua_State *L) +// Get Snake case notation version of provided string +static int rl_TextToSnake(lua_State *L) { - Shader shader = LuaGetArgument_Shader(L, 1); - Texture2D skyHDR = LuaGetArgument_Texture2D(L, 2); - int size = LuaGetArgument_int(L, 3); - Texture2D result = GenTextureCubemap(shader, skyHDR, size); - LuaPush_Texture2D(L, result); + const char * text = luaL_checkstring(L, 1); + char * result = TextToSnake(text); + lua_pushstring(L, result); return 1; } -// Generate irradiance texture using cubemap data -int lua_GenTextureIrradiance(lua_State *L) +// Get Camel case notation version of provided string +static int rl_TextToCamel(lua_State *L) { - Shader shader = LuaGetArgument_Shader(L, 1); - Texture2D cubemap = LuaGetArgument_Texture2D(L, 2); - int size = LuaGetArgument_int(L, 3); - Texture2D result = GenTextureIrradiance(shader, cubemap, size); - LuaPush_Texture2D(L, result); + const char * text = luaL_checkstring(L, 1); + char * result = TextToCamel(text); + lua_pushstring(L, result); return 1; } -// Generate prefilter texture using cubemap data -int lua_GenTexturePrefilter(lua_State *L) +// Get integer value from text +static int rl_TextToInteger(lua_State *L) { - Shader shader = LuaGetArgument_Shader(L, 1); - Texture2D cubemap = LuaGetArgument_Texture2D(L, 2); - int size = LuaGetArgument_int(L, 3); - Texture2D result = GenTexturePrefilter(shader, cubemap, size); - LuaPush_Texture2D(L, result); + const char * text = luaL_checkstring(L, 1); + int result = TextToInteger(text); + lua_pushinteger(L, result); return 1; } -// Generate BRDF texture using cubemap data -int lua_GenTextureBRDF(lua_State *L) +// Get float value from text +static int rl_TextToFloat(lua_State *L) { - Shader shader = LuaGetArgument_Shader(L, 1); - Texture2D cubemap = LuaGetArgument_Texture2D(L, 2); - int size = LuaGetArgument_int(L, 3); - Texture2D result = GenTextureBRDF(shader, cubemap, size); - LuaPush_Texture2D(L, result); + const char * text = luaL_checkstring(L, 1); + float result = TextToFloat(text); + lua_pushnumber(L, result); return 1; } -// Shading begin/end functions -// Begin custom shader drawing -int lua_BeginShaderMode(lua_State *L) +// ------------------------------------------------------------------------------------ +// Basic 3d Shapes Drawing Functions (Module: models) +// ------------------------------------------------------------------------------------ +// Basic geometric 3D shapes drawing functions +// Draw a line in 3D world space +static int rl_DrawLine3D(lua_State *L) { - Shader shader = LuaGetArgument_Shader(L, 1); - BeginShaderMode(shader); + Vector3 startPos = RLUA_CHECK_Vector3(L, 1); + Vector3 endPos = RLUA_CHECK_Vector3(L, 2); + Color color = RLUA_CHECK_Color(L, 3); + DrawLine3D(startPos, endPos, color); return 0; } -// End custom shader drawing (use default shader) -int lua_EndShaderMode(lua_State *L) +// Draw a point in 3D space, actually a small line +static int rl_DrawPoint3D(lua_State *L) { - EndShaderMode(); + Vector3 position = RLUA_CHECK_Vector3(L, 1); + Color color = RLUA_CHECK_Color(L, 2); + DrawPoint3D(position, color); return 0; } -// Begin blending mode (alpha, additive, multiplied) -int lua_BeginBlendMode(lua_State *L) +// Draw a circle in 3D world space +static int rl_DrawCircle3D(lua_State *L) { - int mode = LuaGetArgument_int(L, 1); - BeginBlendMode(mode); + Vector3 center = RLUA_CHECK_Vector3(L, 1); + float radius = (float)luaL_checknumber(L, 2); + Vector3 rotationAxis = RLUA_CHECK_Vector3(L, 3); + float rotationAngle = (float)luaL_checknumber(L, 4); + Color color = RLUA_CHECK_Color(L, 5); + DrawCircle3D(center, radius, rotationAxis, rotationAngle, color); return 0; } -// End blending mode (reset to default: alpha blending) -int lua_EndBlendMode(lua_State *L) +// Draw a color-filled triangle (vertex in counter-clockwise order!) +static int rl_DrawTriangle3D(lua_State *L) { - EndBlendMode(); + Vector3 v1 = RLUA_CHECK_Vector3(L, 1); + Vector3 v2 = RLUA_CHECK_Vector3(L, 2); + Vector3 v3 = RLUA_CHECK_Vector3(L, 3); + Color color = RLUA_CHECK_Color(L, 4); + DrawTriangle3D(v1, v2, v3, color); return 0; } -//------------------------------------------------------------------------------------ -// raylib [rlgl] module functions - VR experience -//------------------------------------------------------------------------------------ - -// Get VR device information for some standard devices -int lua_GetVrDeviceInfo(lua_State *L) +// Draw a triangle strip defined by points +static int rl_DrawTriangleStrip3D(lua_State *L) { - int vrDeviceType = LuaGetArgument_int(L, 1); - VrDeviceInfo result = GetVrDeviceInfo(vrDeviceType); - LuaPush_VrDeviceInfo(L, result); - return 1; + const Vector3 * points = (const Vector3 *)lua_touserdata(L, 1); + int pointCount = (int)luaL_checkinteger(L, 2); + Color color = RLUA_CHECK_Color(L, 3); + DrawTriangleStrip3D(points, pointCount, color); + return 0; } -// Init VR simulator for selected device parameters -int lua_InitVrSimulator(lua_State *L) +// Draw cube +static int rl_DrawCube(lua_State *L) { - VrDeviceInfo info = LuaGetArgument_VrDeviceInfo(L, 1); - InitVrSimulator(info); + Vector3 position = RLUA_CHECK_Vector3(L, 1); + float width = (float)luaL_checknumber(L, 2); + float height = (float)luaL_checknumber(L, 3); + float length = (float)luaL_checknumber(L, 4); + Color color = RLUA_CHECK_Color(L, 5); + DrawCube(position, width, height, length, color); return 0; } -// Close VR simulator for current device -int lua_CloseVrSimulator(lua_State *L) +// Draw cube (Vector version) +static int rl_DrawCubeV(lua_State *L) { - CloseVrSimulator(); + Vector3 position = RLUA_CHECK_Vector3(L, 1); + Vector3 size = RLUA_CHECK_Vector3(L, 2); + Color color = RLUA_CHECK_Color(L, 3); + DrawCubeV(position, size, color); return 0; } -// Detect if VR simulator is ready -int lua_IsVrSimulatorReady(lua_State *L) +// Draw cube wires +static int rl_DrawCubeWires(lua_State *L) { - bool result = IsVrSimulatorReady(); - LuaPush_bool(L, result); - return 1; + Vector3 position = RLUA_CHECK_Vector3(L, 1); + float width = (float)luaL_checknumber(L, 2); + float height = (float)luaL_checknumber(L, 3); + float length = (float)luaL_checknumber(L, 4); + Color color = RLUA_CHECK_Color(L, 5); + DrawCubeWires(position, width, height, length, color); + return 0; } -// Set VR distortion shader for stereoscopic rendering -int lua_SetVrDistortionShader(lua_State *L) +// Draw cube wires (Vector version) +static int rl_DrawCubeWiresV(lua_State *L) { - Shader shader = LuaGetArgument_Shader(L, 1); - SetVrDistortionShader(shader); + Vector3 position = RLUA_CHECK_Vector3(L, 1); + Vector3 size = RLUA_CHECK_Vector3(L, 2); + Color color = RLUA_CHECK_Color(L, 3); + DrawCubeWiresV(position, size, color); return 0; } -// Update VR tracking (position and orientation) and camera -int lua_UpdateVrTracking(lua_State *L) +// Draw sphere +static int rl_DrawSphere(lua_State *L) { - Camera camera = LuaGetArgument_Camera(L, 1); - UpdateVrTracking(camera); + Vector3 centerPos = RLUA_CHECK_Vector3(L, 1); + float radius = (float)luaL_checknumber(L, 2); + Color color = RLUA_CHECK_Color(L, 3); + DrawSphere(centerPos, radius, color); return 0; } -// Enable/Disable VR experience -int lua_ToggleVrMode(lua_State *L) +// Draw sphere with extended parameters +static int rl_DrawSphereEx(lua_State *L) { - ToggleVrMode(); + Vector3 centerPos = RLUA_CHECK_Vector3(L, 1); + float radius = (float)luaL_checknumber(L, 2); + int rings = (int)luaL_checkinteger(L, 3); + int slices = (int)luaL_checkinteger(L, 4); + Color color = RLUA_CHECK_Color(L, 5); + DrawSphereEx(centerPos, radius, rings, slices, color); return 0; } -// Begin VR simulator stereo rendering -int lua_BeginVrDrawing(lua_State *L) +// Draw sphere wires +static int rl_DrawSphereWires(lua_State *L) { - BeginVrDrawing(); + Vector3 centerPos = RLUA_CHECK_Vector3(L, 1); + float radius = (float)luaL_checknumber(L, 2); + int rings = (int)luaL_checkinteger(L, 3); + int slices = (int)luaL_checkinteger(L, 4); + Color color = RLUA_CHECK_Color(L, 5); + DrawSphereWires(centerPos, radius, rings, slices, color); + return 0; +} + +// Draw a cylinder/cone +static int rl_DrawCylinder(lua_State *L) +{ + Vector3 position = RLUA_CHECK_Vector3(L, 1); + float radiusTop = (float)luaL_checknumber(L, 2); + float radiusBottom = (float)luaL_checknumber(L, 3); + float height = (float)luaL_checknumber(L, 4); + int slices = (int)luaL_checkinteger(L, 5); + Color color = RLUA_CHECK_Color(L, 6); + DrawCylinder(position, radiusTop, radiusBottom, height, slices, color); return 0; } -// End VR simulator stereo rendering -int lua_EndVrDrawing(lua_State *L) +// Draw a cylinder with base at startPos and top at endPos +static int rl_DrawCylinderEx(lua_State *L) { - EndVrDrawing(); + Vector3 startPos = RLUA_CHECK_Vector3(L, 1); + Vector3 endPos = RLUA_CHECK_Vector3(L, 2); + float startRadius = (float)luaL_checknumber(L, 3); + float endRadius = (float)luaL_checknumber(L, 4); + int sides = (int)luaL_checkinteger(L, 5); + Color color = RLUA_CHECK_Color(L, 6); + DrawCylinderEx(startPos, endPos, startRadius, endRadius, sides, color); return 0; } -//------------------------------------------------------------------------------------ -// raylib [audio] module functions - Audio Loading and Playing -//------------------------------------------------------------------------------------ +// Draw a cylinder/cone wires +static int rl_DrawCylinderWires(lua_State *L) +{ + Vector3 position = RLUA_CHECK_Vector3(L, 1); + float radiusTop = (float)luaL_checknumber(L, 2); + float radiusBottom = (float)luaL_checknumber(L, 3); + float height = (float)luaL_checknumber(L, 4); + int slices = (int)luaL_checkinteger(L, 5); + Color color = RLUA_CHECK_Color(L, 6); + DrawCylinderWires(position, radiusTop, radiusBottom, height, slices, color); + return 0; +} -// Initialize audio device and context -int lua_InitAudioDevice(lua_State *L) +// Draw a cylinder wires with base at startPos and top at endPos +static int rl_DrawCylinderWiresEx(lua_State *L) { - InitAudioDevice(); + Vector3 startPos = RLUA_CHECK_Vector3(L, 1); + Vector3 endPos = RLUA_CHECK_Vector3(L, 2); + float startRadius = (float)luaL_checknumber(L, 3); + float endRadius = (float)luaL_checknumber(L, 4); + int sides = (int)luaL_checkinteger(L, 5); + Color color = RLUA_CHECK_Color(L, 6); + DrawCylinderWiresEx(startPos, endPos, startRadius, endRadius, sides, color); return 0; } -// Close the audio device and context -int lua_CloseAudioDevice(lua_State *L) +// Draw a capsule with the center of its sphere caps at startPos and endPos +static int rl_DrawCapsule(lua_State *L) { - CloseAudioDevice(); + Vector3 startPos = RLUA_CHECK_Vector3(L, 1); + Vector3 endPos = RLUA_CHECK_Vector3(L, 2); + float radius = (float)luaL_checknumber(L, 3); + int slices = (int)luaL_checkinteger(L, 4); + int rings = (int)luaL_checkinteger(L, 5); + Color color = RLUA_CHECK_Color(L, 6); + DrawCapsule(startPos, endPos, radius, slices, rings, color); return 0; } -// Check if audio device has been initialized successfully -int lua_IsAudioDeviceReady(lua_State *L) +// Draw capsule wireframe with the center of its sphere caps at startPos and endPos +static int rl_DrawCapsuleWires(lua_State *L) { - bool result = IsAudioDeviceReady(); - LuaPush_bool(L, result); - return 1; + Vector3 startPos = RLUA_CHECK_Vector3(L, 1); + Vector3 endPos = RLUA_CHECK_Vector3(L, 2); + float radius = (float)luaL_checknumber(L, 3); + int slices = (int)luaL_checkinteger(L, 4); + int rings = (int)luaL_checkinteger(L, 5); + Color color = RLUA_CHECK_Color(L, 6); + DrawCapsuleWires(startPos, endPos, radius, slices, rings, color); + return 0; } -// Set master volume (listener) -int lua_SetMasterVolume(lua_State *L) +// Draw a plane XZ +static int rl_DrawPlane(lua_State *L) { - float volume = LuaGetArgument_float(L, 1); - SetMasterVolume(volume); + Vector3 centerPos = RLUA_CHECK_Vector3(L, 1); + Vector2 size = RLUA_CHECK_Vector2(L, 2); + Color color = RLUA_CHECK_Color(L, 3); + DrawPlane(centerPos, size, color); return 0; } -// Wave/Sound loading/unloading functions -// Load wave data from file -int lua_LoadWave(lua_State *L) +// Draw a ray line +static int rl_DrawRay(lua_State *L) { - const char *fileName = LuaGetArgument_string(L, 1); - Wave result = LoadWave(fileName); - LuaPush_Wave(L, result); - return 1; + Ray ray = RLUA_CHECK_Ray(L, 1); + Color color = RLUA_CHECK_Color(L, 2); + DrawRay(ray, color); + return 0; } -// WARNING: Load wave data from raw array data -int lua_LoadWaveEx(lua_State* L) +// Draw a grid (centered at (0, 0, 0)) +static int rl_DrawGrid(lua_State *L) +{ + int slices = (int)luaL_checkinteger(L, 1); + float spacing = (float)luaL_checknumber(L, 2); + DrawGrid(slices, spacing); + return 0; +} + +// ------------------------------------------------------------------------------------ +// Model 3d Loading and Drawing Functions (Module: models) +// ------------------------------------------------------------------------------------ +// Model management functions +// Load model from files (meshes and materials) +static int rl_LoadModel(lua_State *L) { - // TODO: arg1 parameter should be a float arrat... - - float *arg1 = 0; - int arg2 = LuaGetArgument_int(L, 2); - int arg3 = LuaGetArgument_int(L, 3); - int arg4 = LuaGetArgument_int(L, 4); - int arg5 = LuaGetArgument_int(L, 5); - Wave result = LoadWaveEx(arg1, arg2, arg3, arg4, arg5); - LuaPush_Wave(L, result); + const char * fileName = luaL_checkstring(L, 1); + Model result = LoadModel(fileName); + RLUA_PUSH_Resource(L, &result, sizeof(Model), "Model"); return 1; } -// Load sound from file -int lua_LoadSound(lua_State *L) +// Load model from generated mesh (default material) +static int rl_LoadModelFromMesh(lua_State *L) { - const char *fileName = LuaGetArgument_string(L, 1); - Sound result = LoadSound(fileName); - LuaPush_Sound(L, result); + Mesh mesh = *(Mesh*)RLUA_CHECK_Resource(L, 1, "Mesh"); + Model result = LoadModelFromMesh(mesh); + RLUA_PUSH_Resource(L, &result, sizeof(Model), "Model"); return 1; } -// Load sound from wave data -int lua_LoadSoundFromWave(lua_State *L) +// Check if a model is valid (loaded in GPU, VAO/VBOs) +static int rl_IsModelValid(lua_State *L) { - Wave wave = LuaGetArgument_Wave(L, 1); - Sound result = LoadSoundFromWave(wave); - LuaPush_Sound(L, result); + Model model = *(Model*)RLUA_CHECK_Resource(L, 1, "Model"); + bool result = IsModelValid(model); + lua_pushboolean(L, result); return 1; } -// WARNING: Update sound buffer with new data -int lua_UpdateSound(lua_State* L) +// Unload model (including meshes) from memory (RAM and/or VRAM) +static int rl_UnloadModel(lua_State *L) { - // TODO: arg2 parameter is a void pointer... - - Sound arg1 = LuaGetArgument_Sound(L, 1); - void *arg2 = LuaGetArgument_ptr(L, 2); - int arg3 = LuaGetArgument_int(L, 3); - UpdateSound(arg1, arg2, arg3); + Model model = *(Model*)RLUA_CHECK_Resource(L, 1, "Model"); + UnloadModel(model); return 0; } -// Unload wave data -int lua_UnloadWave(lua_State *L) +// Compute model bounding box limits (considers all meshes) +static int rl_GetModelBoundingBox(lua_State *L) { - Wave wave = LuaGetArgument_Wave(L, 1); - UnloadWave(wave); - return 0; + Model model = *(Model*)RLUA_CHECK_Resource(L, 1, "Model"); + BoundingBox result = GetModelBoundingBox(model); + RLUA_PUSH_BoundingBox(L, result); + return 1; } -// Unload sound -int lua_UnloadSound(lua_State *L) +// Model drawing functions +// Draw a model (with texture if set) +static int rl_DrawModel(lua_State *L) { - Sound sound = LuaGetArgument_Sound(L, 1); - UnloadSound(sound); + Model model = *(Model*)RLUA_CHECK_Resource(L, 1, "Model"); + Vector3 position = RLUA_CHECK_Vector3(L, 2); + float scale = (float)luaL_checknumber(L, 3); + Color tint = RLUA_CHECK_Color(L, 4); + DrawModel(model, position, scale, tint); return 0; } -// Wave/Sound management functions -// Play a sound -int lua_PlaySound(lua_State *L) -{ - Sound sound = LuaGetArgument_Sound(L, 1); - PlaySound(sound); +// Draw a model with extended parameters +static int rl_DrawModelEx(lua_State *L) +{ + Model model = *(Model*)RLUA_CHECK_Resource(L, 1, "Model"); + Vector3 position = RLUA_CHECK_Vector3(L, 2); + Vector3 rotationAxis = RLUA_CHECK_Vector3(L, 3); + float rotationAngle = (float)luaL_checknumber(L, 4); + Vector3 scale = RLUA_CHECK_Vector3(L, 5); + Color tint = RLUA_CHECK_Color(L, 6); + DrawModelEx(model, position, rotationAxis, rotationAngle, scale, tint); return 0; } -// Pause a sound -int lua_PauseSound(lua_State *L) +// Draw a model wires (with texture if set) +static int rl_DrawModelWires(lua_State *L) { - Sound sound = LuaGetArgument_Sound(L, 1); - PauseSound(sound); + Model model = *(Model*)RLUA_CHECK_Resource(L, 1, "Model"); + Vector3 position = RLUA_CHECK_Vector3(L, 2); + float scale = (float)luaL_checknumber(L, 3); + Color tint = RLUA_CHECK_Color(L, 4); + DrawModelWires(model, position, scale, tint); return 0; } -// Resume a paused sound -int lua_ResumeSound(lua_State *L) -{ - Sound sound = LuaGetArgument_Sound(L, 1); - ResumeSound(sound); +// Draw a model wires (with texture if set) with extended parameters +static int rl_DrawModelWiresEx(lua_State *L) +{ + Model model = *(Model*)RLUA_CHECK_Resource(L, 1, "Model"); + Vector3 position = RLUA_CHECK_Vector3(L, 2); + Vector3 rotationAxis = RLUA_CHECK_Vector3(L, 3); + float rotationAngle = (float)luaL_checknumber(L, 4); + Vector3 scale = RLUA_CHECK_Vector3(L, 5); + Color tint = RLUA_CHECK_Color(L, 6); + DrawModelWiresEx(model, position, rotationAxis, rotationAngle, scale, tint); return 0; } -// Stop playing a sound -int lua_StopSound(lua_State *L) +// Draw bounding box (wires) +static int rl_DrawBoundingBox(lua_State *L) { - Sound sound = LuaGetArgument_Sound(L, 1); - StopSound(sound); + BoundingBox box = RLUA_CHECK_BoundingBox(L, 1); + Color color = RLUA_CHECK_Color(L, 2); + DrawBoundingBox(box, color); return 0; } -// Check if a sound is currently playing -int lua_IsSoundPlaying(lua_State *L) +// Draw a billboard texture +static int rl_DrawBillboard(lua_State *L) { - Sound sound = LuaGetArgument_Sound(L, 1); - bool result = IsSoundPlaying(sound); - LuaPush_bool(L, result); - return 1; + Camera camera = RLUA_CHECK_Camera(L, 1); + Texture2D texture = *(Texture2D*)RLUA_CHECK_Resource(L, 2, "Texture2D"); + Vector3 position = RLUA_CHECK_Vector3(L, 3); + float scale = (float)luaL_checknumber(L, 4); + Color tint = RLUA_CHECK_Color(L, 5); + DrawBillboard(camera, texture, position, scale, tint); + return 0; } -// Set volume for a sound (1.0 is max level) -int lua_SetSoundVolume(lua_State *L) +// Draw a billboard texture defined by source +static int rl_DrawBillboardRec(lua_State *L) { - Sound sound = LuaGetArgument_Sound(L, 1); - float volume = LuaGetArgument_float(L, 2); - SetSoundVolume(sound, volume); + Camera camera = RLUA_CHECK_Camera(L, 1); + Texture2D texture = *(Texture2D*)RLUA_CHECK_Resource(L, 2, "Texture2D"); + Rectangle source = RLUA_CHECK_Rectangle(L, 3); + Vector3 position = RLUA_CHECK_Vector3(L, 4); + Vector2 size = RLUA_CHECK_Vector2(L, 5); + Color tint = RLUA_CHECK_Color(L, 6); + DrawBillboardRec(camera, texture, source, position, size, tint); return 0; } -// Set pitch for a sound (1.0 is base level) -int lua_SetSoundPitch(lua_State *L) +// Draw a billboard texture defined by source and rotation +static int rl_DrawBillboardPro(lua_State *L) { - Sound sound = LuaGetArgument_Sound(L, 1); - float pitch = LuaGetArgument_float(L, 2); - SetSoundPitch(sound, pitch); + Camera camera = RLUA_CHECK_Camera(L, 1); + Texture2D texture = *(Texture2D*)RLUA_CHECK_Resource(L, 2, "Texture2D"); + Rectangle source = RLUA_CHECK_Rectangle(L, 3); + Vector3 position = RLUA_CHECK_Vector3(L, 4); + Vector3 up = RLUA_CHECK_Vector3(L, 5); + Vector2 size = RLUA_CHECK_Vector2(L, 6); + Vector2 origin = RLUA_CHECK_Vector2(L, 7); + float rotation = (float)luaL_checknumber(L, 8); + Color tint = RLUA_CHECK_Color(L, 9); + DrawBillboardPro(camera, texture, source, position, up, size, origin, rotation, tint); return 0; } -// Convert wave data to desired format -int lua_WaveFormat(lua_State *L) +// Mesh management functions +// Upload mesh vertex data in GPU and provide VAO/VBO ids +static int rl_UploadMesh(lua_State *L) { - Wave wave = LuaGetArgument_Wave(L, 1); - int sampleRate = LuaGetArgument_int(L, 2); - int sampleSize = LuaGetArgument_int(L, 3); - int channels = LuaGetArgument_int(L, 4); - WaveFormat(wave, sampleRate, sampleSize, channels); + Mesh * mesh = (Mesh *)lua_touserdata(L, 1); + bool dynamic = lua_toboolean(L, 2); + UploadMesh(mesh, dynamic); return 0; } -// Copy a wave to a new wave -int lua_WaveCopy(lua_State *L) +// Update mesh vertex data in GPU for a specific buffer index +static int rl_UpdateMeshBuffer(lua_State *L) { - Wave wave = LuaGetArgument_Wave(L, 1); - Wave result = WaveCopy(wave); - LuaPush_Wave(L, result); - return 1; + Mesh mesh = *(Mesh*)RLUA_CHECK_Resource(L, 1, "Mesh"); + int index = (int)luaL_checkinteger(L, 2); + const void * data = (const void *)lua_touserdata(L, 3); + int dataSize = (int)luaL_checkinteger(L, 4); + int offset = (int)luaL_checkinteger(L, 5); + UpdateMeshBuffer(mesh, index, data, dataSize, offset); + return 0; } -// Crop a wave to defined samples range -int lua_WaveCrop(lua_State *L) +// Unload mesh data from CPU and GPU +static int rl_UnloadMesh(lua_State *L) { - Wave wave = LuaGetArgument_Wave(L, 1); - int initSample = LuaGetArgument_int(L, 2); - int finalSample = LuaGetArgument_int(L, 3); - WaveCrop(wave, initSample, finalSample); + Mesh mesh = *(Mesh*)RLUA_CHECK_Resource(L, 1, "Mesh"); + UnloadMesh(mesh); return 0; } -// WARNING: Get samples data from wave as a floats array -int lua_GetWaveData(lua_State* L) +// Draw a 3d mesh with material and transform +static int rl_DrawMesh(lua_State *L) { - // TODO: return value should be a float array... - - Wave arg1 = LuaGetArgument_Wave(L, 1); - float *result = GetWaveData(arg1); - //LuaPush_float(L, result); - //LuaPush_float(L, result); + Mesh mesh = *(Mesh*)RLUA_CHECK_Resource(L, 1, "Mesh"); + Material material = *(Material*)RLUA_CHECK_Resource(L, 2, "Material"); + Matrix transform = RLUA_CHECK_Matrix(L, 3); + DrawMesh(mesh, material, transform); return 0; } -// Music management functions +// Draw multiple mesh instances with material and different transforms +static int rl_DrawMeshInstanced(lua_State *L) +{ + Mesh mesh = *(Mesh*)RLUA_CHECK_Resource(L, 1, "Mesh"); + Material material = *(Material*)RLUA_CHECK_Resource(L, 2, "Material"); + const Matrix * transforms = (const Matrix *)lua_touserdata(L, 3); + int instances = (int)luaL_checkinteger(L, 4); + DrawMeshInstanced(mesh, material, transforms, instances); + return 0; +} -// Load music stream from file -int lua_LoadMusicStream(lua_State *L) +// Compute mesh bounding box limits +static int rl_GetMeshBoundingBox(lua_State *L) { - const char *fileName = LuaGetArgument_string(L, 1); - Music result = LoadMusicStream(fileName); - LuaPush_Music(L, result); + Mesh mesh = *(Mesh*)RLUA_CHECK_Resource(L, 1, "Mesh"); + BoundingBox result = GetMeshBoundingBox(mesh); + RLUA_PUSH_BoundingBox(L, result); return 1; } -// Unload music stream -int lua_UnloadMusicStream(lua_State *L) +// Compute mesh tangents +static int rl_GenMeshTangents(lua_State *L) { - Music music = LuaGetArgument_Music(L, 1); - UnloadMusicStream(music); + Mesh * mesh = (Mesh *)lua_touserdata(L, 1); + GenMeshTangents(mesh); return 0; } -// Start music playing -int lua_PlayMusicStream(lua_State *L) +// Export mesh data to file, returns true on success +static int rl_ExportMesh(lua_State *L) { - Music music = LuaGetArgument_Music(L, 1); - PlayMusicStream(music); - return 0; + Mesh mesh = *(Mesh*)RLUA_CHECK_Resource(L, 1, "Mesh"); + const char * fileName = luaL_checkstring(L, 2); + bool result = ExportMesh(mesh, fileName); + lua_pushboolean(L, result); + return 1; } -// Updates buffers for music streaming -int lua_UpdateMusicStream(lua_State *L) +// Export mesh as code file (.h) defining multiple arrays of vertex attributes +static int rl_ExportMeshAsCode(lua_State *L) { - Music music = LuaGetArgument_Music(L, 1); - UpdateMusicStream(music); - return 0; + Mesh mesh = *(Mesh*)RLUA_CHECK_Resource(L, 1, "Mesh"); + const char * fileName = luaL_checkstring(L, 2); + bool result = ExportMeshAsCode(mesh, fileName); + lua_pushboolean(L, result); + return 1; } -// Stop music playing -int lua_StopMusicStream(lua_State *L) +// Mesh generation functions +// Generate polygonal mesh +static int rl_GenMeshPoly(lua_State *L) { - Music music = LuaGetArgument_Music(L, 1); - StopMusicStream(music); - return 0; + int sides = (int)luaL_checkinteger(L, 1); + float radius = (float)luaL_checknumber(L, 2); + Mesh result = GenMeshPoly(sides, radius); + RLUA_PUSH_Resource(L, &result, sizeof(Mesh), "Mesh"); + return 1; } -// Pause music playing -int lua_PauseMusicStream(lua_State *L) +// Generate plane mesh (with subdivisions) +static int rl_GenMeshPlane(lua_State *L) { - Music music = LuaGetArgument_Music(L, 1); - PauseMusicStream(music); - return 0; + float width = (float)luaL_checknumber(L, 1); + float length = (float)luaL_checknumber(L, 2); + int resX = (int)luaL_checkinteger(L, 3); + int resZ = (int)luaL_checkinteger(L, 4); + Mesh result = GenMeshPlane(width, length, resX, resZ); + RLUA_PUSH_Resource(L, &result, sizeof(Mesh), "Mesh"); + return 1; } -// Resume playing paused music -int lua_ResumeMusicStream(lua_State *L) +// Generate cuboid mesh +static int rl_GenMeshCube(lua_State *L) { - Music music = LuaGetArgument_Music(L, 1); - ResumeMusicStream(music); - return 0; + float width = (float)luaL_checknumber(L, 1); + float height = (float)luaL_checknumber(L, 2); + float length = (float)luaL_checknumber(L, 3); + Mesh result = GenMeshCube(width, height, length); + RLUA_PUSH_Resource(L, &result, sizeof(Mesh), "Mesh"); + return 1; } -// Check if music is playing -int lua_IsMusicPlaying(lua_State *L) +// Generate sphere mesh (standard sphere) +static int rl_GenMeshSphere(lua_State *L) { - Music music = LuaGetArgument_Music(L, 1); - bool result = IsMusicPlaying(music); - LuaPush_bool(L, result); + float radius = (float)luaL_checknumber(L, 1); + int rings = (int)luaL_checkinteger(L, 2); + int slices = (int)luaL_checkinteger(L, 3); + Mesh result = GenMeshSphere(radius, rings, slices); + RLUA_PUSH_Resource(L, &result, sizeof(Mesh), "Mesh"); return 1; } -// Set volume for music (1.0 is max level) -int lua_SetMusicVolume(lua_State *L) +// Generate half-sphere mesh (no bottom cap) +static int rl_GenMeshHemiSphere(lua_State *L) { - Music music = LuaGetArgument_Music(L, 1); - float volume = LuaGetArgument_float(L, 2); - SetMusicVolume(music, volume); - return 0; + float radius = (float)luaL_checknumber(L, 1); + int rings = (int)luaL_checkinteger(L, 2); + int slices = (int)luaL_checkinteger(L, 3); + Mesh result = GenMeshHemiSphere(radius, rings, slices); + RLUA_PUSH_Resource(L, &result, sizeof(Mesh), "Mesh"); + return 1; } -// Set pitch for a music (1.0 is base level) -int lua_SetMusicPitch(lua_State *L) +// Generate cylinder mesh +static int rl_GenMeshCylinder(lua_State *L) { - Music music = LuaGetArgument_Music(L, 1); - float pitch = LuaGetArgument_float(L, 2); - SetMusicPitch(music, pitch); - return 0; + float radius = (float)luaL_checknumber(L, 1); + float height = (float)luaL_checknumber(L, 2); + int slices = (int)luaL_checkinteger(L, 3); + Mesh result = GenMeshCylinder(radius, height, slices); + RLUA_PUSH_Resource(L, &result, sizeof(Mesh), "Mesh"); + return 1; } -// Set music loop count (loop repeats) -int lua_SetMusicLoopCount(lua_State *L) +// Generate cone/pyramid mesh +static int rl_GenMeshCone(lua_State *L) { - Music music = LuaGetArgument_Music(L, 1); - int count = LuaGetArgument_int(L, 2); - SetMusicLoopCount(music, count); - return 0; + float radius = (float)luaL_checknumber(L, 1); + float height = (float)luaL_checknumber(L, 2); + int slices = (int)luaL_checkinteger(L, 3); + Mesh result = GenMeshCone(radius, height, slices); + RLUA_PUSH_Resource(L, &result, sizeof(Mesh), "Mesh"); + return 1; } -// Get music time length (in seconds) -int lua_GetMusicTimeLength(lua_State *L) +// Generate torus mesh +static int rl_GenMeshTorus(lua_State *L) { - Music music = LuaGetArgument_Music(L, 1); - float result = GetMusicTimeLength(music); - LuaPush_float(L, result); + float radius = (float)luaL_checknumber(L, 1); + float size = (float)luaL_checknumber(L, 2); + int radSeg = (int)luaL_checkinteger(L, 3); + int sides = (int)luaL_checkinteger(L, 4); + Mesh result = GenMeshTorus(radius, size, radSeg, sides); + RLUA_PUSH_Resource(L, &result, sizeof(Mesh), "Mesh"); return 1; } -// Get current music time played (in seconds) -int lua_GetMusicTimePlayed(lua_State *L) +// Generate trefoil knot mesh +static int rl_GenMeshKnot(lua_State *L) { - Music music = LuaGetArgument_Music(L, 1); - float result = GetMusicTimePlayed(music); - LuaPush_float(L, result); + float radius = (float)luaL_checknumber(L, 1); + float size = (float)luaL_checknumber(L, 2); + int radSeg = (int)luaL_checkinteger(L, 3); + int sides = (int)luaL_checkinteger(L, 4); + Mesh result = GenMeshKnot(radius, size, radSeg, sides); + RLUA_PUSH_Resource(L, &result, sizeof(Mesh), "Mesh"); return 1; } -// AudioStream management functions -// Init audio stream (to stream raw audio pcm data) -int lua_InitAudioStream(lua_State *L) +// Generate heightmap mesh from image data +static int rl_GenMeshHeightmap(lua_State *L) +{ + Image heightmap = *(Image*)RLUA_CHECK_Resource(L, 1, "Image"); + Vector3 size = RLUA_CHECK_Vector3(L, 2); + Mesh result = GenMeshHeightmap(heightmap, size); + RLUA_PUSH_Resource(L, &result, sizeof(Mesh), "Mesh"); + return 1; +} + +// Generate cubes-based map mesh from image data +static int rl_GenMeshCubicmap(lua_State *L) { - unsigned int sampleRate = LuaGetArgument_unsigned(L, 1); - unsigned int sampleSize = LuaGetArgument_unsigned(L, 2); - unsigned int channels = LuaGetArgument_unsigned(L, 3); - AudioStream result = InitAudioStream(sampleRate, sampleSize, channels); - LuaPush_AudioStream(L, result); + Image cubicmap = *(Image*)RLUA_CHECK_Resource(L, 1, "Image"); + Vector3 cubeSize = RLUA_CHECK_Vector3(L, 2); + Mesh result = GenMeshCubicmap(cubicmap, cubeSize); + RLUA_PUSH_Resource(L, &result, sizeof(Mesh), "Mesh"); return 1; } -// WARNING: Update audio stream buffers with data -int lua_UpdateAudioStream(lua_State* L) +// Material loading/unloading functions +// Load materials from model file +static int rl_LoadMaterials(lua_State *L) { - // TODO: arg2 parameter is a void pointer... - - AudioStream arg1 = LuaGetArgument_AudioStream(L, 1); - void *arg2 = LuaGetArgument_ptr(L, 2); - int arg3 = LuaGetArgument_int(L, 3); - UpdateAudioStream(arg1, arg2, arg3); - return 0; + const char * fileName = luaL_checkstring(L, 1); + int materialCount = 0; + Material * result = LoadMaterials(fileName, &materialCount); + RLUA_PUSH_View(L, result, materialCount, "Material", true); + return 1; } -// Close audio stream and free memory -int lua_CloseAudioStream(lua_State *L) +// Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps) +static int rl_LoadMaterialDefault(lua_State *L) { - AudioStream stream = LuaGetArgument_AudioStream(L, 1); - CloseAudioStream(stream); - return 0; + Material result = LoadMaterialDefault(); + RLUA_PUSH_Resource(L, &result, sizeof(Material), "Material"); + return 1; } -// Check if any audio stream buffers requires refill -int lua_IsAudioBufferProcessed(lua_State *L) +// Check if a material is valid (shader assigned, map textures loaded in GPU) +static int rl_IsMaterialValid(lua_State *L) { - AudioStream stream = LuaGetArgument_AudioStream(L, 1); - bool result = IsAudioBufferProcessed(stream); - LuaPush_bool(L, result); + Material material = *(Material*)RLUA_CHECK_Resource(L, 1, "Material"); + bool result = IsMaterialValid(material); + lua_pushboolean(L, result); return 1; } -// Play audio stream -int lua_PlayAudioStream(lua_State *L) +// Unload material from GPU memory (VRAM) +static int rl_UnloadMaterial(lua_State *L) { - AudioStream stream = LuaGetArgument_AudioStream(L, 1); - PlayAudioStream(stream); + Material material = *(Material*)RLUA_CHECK_Resource(L, 1, "Material"); + UnloadMaterial(material); return 0; } -// Pause audio stream -int lua_PauseAudioStream(lua_State *L) +// Set texture for a material map type (MATERIAL_MAP_DIFFUSE, MATERIAL_MAP_SPECULAR...) +static int rl_SetMaterialTexture(lua_State *L) { - AudioStream stream = LuaGetArgument_AudioStream(L, 1); - PauseAudioStream(stream); + Material * material = (Material *)lua_touserdata(L, 1); + int mapType = (int)luaL_checkinteger(L, 2); + Texture2D texture = *(Texture2D*)RLUA_CHECK_Resource(L, 3, "Texture2D"); + SetMaterialTexture(material, mapType, texture); return 0; } -// Resume audio stream -int lua_ResumeAudioStream(lua_State *L) +// Set material for a mesh +static int rl_SetModelMeshMaterial(lua_State *L) { - AudioStream stream = LuaGetArgument_AudioStream(L, 1); - ResumeAudioStream(stream); + Model * model = (Model *)lua_touserdata(L, 1); + int meshId = (int)luaL_checkinteger(L, 2); + int materialId = (int)luaL_checkinteger(L, 3); + SetModelMeshMaterial(model, meshId, materialId); return 0; } -// Check if audio stream is playing -int lua_IsAudioStreamPlaying(lua_State *L) +// Model animations loading/unloading functions +// Load model animations from file +static int rl_LoadModelAnimations(lua_State *L) { - AudioStream stream = LuaGetArgument_AudioStream(L, 1); - bool result = IsAudioStreamPlaying(stream); - LuaPush_bool(L, result); + const char * fileName = luaL_checkstring(L, 1); + int animCount = 0; + ModelAnimation * result = LoadModelAnimations(fileName, &animCount); + RLUA_PUSH_View(L, result, animCount, "ModelAnimation", true); return 1; } -// Stop audio stream -int lua_StopAudioStream(lua_State *L) +// Update model animation pose (vertex buffers and bone matrices) +static int rl_UpdateModelAnimation(lua_State *L) { - AudioStream stream = LuaGetArgument_AudioStream(L, 1); - StopAudioStream(stream); + Model model = *(Model*)RLUA_CHECK_Resource(L, 1, "Model"); + ModelAnimation anim = *(ModelAnimation*)RLUA_CHECK_Resource(L, 2, "ModelAnimation"); + float frame = (float)luaL_checknumber(L, 3); + UpdateModelAnimation(model, anim, frame); return 0; } -// Set volume for audio stream (1.0 is max level) -int lua_SetAudioStreamVolume(lua_State *L) +// Update model animation pose, blending two animations +static int rl_UpdateModelAnimationEx(lua_State *L) { - AudioStream stream = LuaGetArgument_AudioStream(L, 1); - float volume = LuaGetArgument_float(L, 2); - SetAudioStreamVolume(stream, volume); + Model model = *(Model*)RLUA_CHECK_Resource(L, 1, "Model"); + ModelAnimation animA = *(ModelAnimation*)RLUA_CHECK_Resource(L, 2, "ModelAnimation"); + float frameA = (float)luaL_checknumber(L, 3); + ModelAnimation animB = *(ModelAnimation*)RLUA_CHECK_Resource(L, 4, "ModelAnimation"); + float frameB = (float)luaL_checknumber(L, 5); + float blend = (float)luaL_checknumber(L, 6); + UpdateModelAnimationEx(model, animA, frameA, animB, frameB, blend); return 0; } -// Set pitch for audio stream (1.0 is base level) -int lua_SetAudioStreamPitch(lua_State *L) +// Unload animation array data +static int rl_UnloadModelAnimations(lua_State *L) { - AudioStream stream = LuaGetArgument_AudioStream(L, 1); - float pitch = LuaGetArgument_float(L, 2); - SetAudioStreamPitch(stream, pitch); + ModelAnimation * animations = (ModelAnimation *)lua_touserdata(L, 1); + int animCount = (int)luaL_checkinteger(L, 2); + UnloadModelAnimations(animations, animCount); return 0; } -// TODO: FROM HERE DOWN! - -//---------------------------------------------------------------------------------- -// Module Functions Definition - Utils math -//---------------------------------------------------------------------------------- -int lua_Clamp(lua_State* L) +// Check model animation skeleton match +static int rl_IsModelAnimationValid(lua_State *L) { - float arg1 = LuaGetArgument_float(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - float arg3 = LuaGetArgument_float(L, 3); - float result = Clamp(arg1, arg2, arg3); - LuaPush_float(L, result); + Model model = *(Model*)RLUA_CHECK_Resource(L, 1, "Model"); + ModelAnimation anim = *(ModelAnimation*)RLUA_CHECK_Resource(L, 2, "ModelAnimation"); + bool result = IsModelAnimationValid(model, anim); + lua_pushboolean(L, result); return 1; } -//---------------------------------------------------------------------------------- -// Module Functions Definition - Vector2 math -//---------------------------------------------------------------------------------- -int lua_Vector2Zero(lua_State* L) +// Collision detection functions +// Check collision between two spheres +static int rl_CheckCollisionSpheres(lua_State *L) { - Vector2 result = Vector2Zero(); - LuaPush_Vector2(L, result); + Vector3 center1 = RLUA_CHECK_Vector3(L, 1); + float radius1 = (float)luaL_checknumber(L, 2); + Vector3 center2 = RLUA_CHECK_Vector3(L, 3); + float radius2 = (float)luaL_checknumber(L, 4); + bool result = CheckCollisionSpheres(center1, radius1, center2, radius2); + lua_pushboolean(L, result); return 1; } -int lua_Vector2One(lua_State* L) +// Check collision between two bounding boxes +static int rl_CheckCollisionBoxes(lua_State *L) { - Vector2 result = Vector2One(); - LuaPush_Vector2(L, result); + BoundingBox box1 = RLUA_CHECK_BoundingBox(L, 1); + BoundingBox box2 = RLUA_CHECK_BoundingBox(L, 2); + bool result = CheckCollisionBoxes(box1, box2); + lua_pushboolean(L, result); return 1; } -int lua_Vector2Add(lua_State* L) +// Check collision between box and sphere +static int rl_CheckCollisionBoxSphere(lua_State *L) { - Vector2 arg1 = LuaGetArgument_Vector2(L, 1); - Vector2 arg2 = LuaGetArgument_Vector2(L, 2); - Vector2 result = Vector2Add(arg1, arg2); - LuaPush_Vector2(L, result); + BoundingBox box = RLUA_CHECK_BoundingBox(L, 1); + Vector3 center = RLUA_CHECK_Vector3(L, 2); + float radius = (float)luaL_checknumber(L, 3); + bool result = CheckCollisionBoxSphere(box, center, radius); + lua_pushboolean(L, result); return 1; } -int lua_Vector2Subtract(lua_State* L) +// Get collision info between ray and sphere +static int rl_GetRayCollisionSphere(lua_State *L) { - Vector2 arg1 = LuaGetArgument_Vector2(L, 1); - Vector2 arg2 = LuaGetArgument_Vector2(L, 2); - Vector2 result = Vector2Subtract(arg1, arg2); - LuaPush_Vector2(L, result); + Ray ray = RLUA_CHECK_Ray(L, 1); + Vector3 center = RLUA_CHECK_Vector3(L, 2); + float radius = (float)luaL_checknumber(L, 3); + RayCollision result = GetRayCollisionSphere(ray, center, radius); + RLUA_PUSH_RayCollision(L, result); return 1; } -int lua_Vector2Lenght(lua_State* L) +// Get collision info between ray and box +static int rl_GetRayCollisionBox(lua_State *L) { - Vector2 arg1 = LuaGetArgument_Vector2(L, 1); - float result = Vector2Lenght(arg1); - LuaPush_float(L, result); + Ray ray = RLUA_CHECK_Ray(L, 1); + BoundingBox box = RLUA_CHECK_BoundingBox(L, 2); + RayCollision result = GetRayCollisionBox(ray, box); + RLUA_PUSH_RayCollision(L, result); return 1; } -int lua_Vector2DotProduct(lua_State* L) +// Get collision info between ray and mesh +static int rl_GetRayCollisionMesh(lua_State *L) { - Vector2 arg1 = LuaGetArgument_Vector2(L, 1); - Vector2 arg2 = LuaGetArgument_Vector2(L, 2); - float result = Vector2DotProduct(arg1, arg2); - LuaPush_float(L, result); + Ray ray = RLUA_CHECK_Ray(L, 1); + Mesh mesh = *(Mesh*)RLUA_CHECK_Resource(L, 2, "Mesh"); + Matrix transform = RLUA_CHECK_Matrix(L, 3); + RayCollision result = GetRayCollisionMesh(ray, mesh, transform); + RLUA_PUSH_RayCollision(L, result); return 1; } -int lua_Vector2Distance(lua_State* L) +// Get collision info between ray and triangle +static int rl_GetRayCollisionTriangle(lua_State *L) { - Vector2 arg1 = LuaGetArgument_Vector2(L, 1); - Vector2 arg2 = LuaGetArgument_Vector2(L, 2); - float result = Vector2Distance(arg1, arg2); - LuaPush_float(L, result); + Ray ray = RLUA_CHECK_Ray(L, 1); + Vector3 p1 = RLUA_CHECK_Vector3(L, 2); + Vector3 p2 = RLUA_CHECK_Vector3(L, 3); + Vector3 p3 = RLUA_CHECK_Vector3(L, 4); + RayCollision result = GetRayCollisionTriangle(ray, p1, p2, p3); + RLUA_PUSH_RayCollision(L, result); return 1; } -int lua_Vector2Angle(lua_State* L) +// Get collision info between ray and quad +static int rl_GetRayCollisionQuad(lua_State *L) { - Vector2 arg1 = LuaGetArgument_Vector2(L, 1); - Vector2 arg2 = LuaGetArgument_Vector2(L, 2); - float result = Vector2Angle(arg1, arg2); - LuaPush_float(L, result); + Ray ray = RLUA_CHECK_Ray(L, 1); + Vector3 p1 = RLUA_CHECK_Vector3(L, 2); + Vector3 p2 = RLUA_CHECK_Vector3(L, 3); + Vector3 p3 = RLUA_CHECK_Vector3(L, 4); + Vector3 p4 = RLUA_CHECK_Vector3(L, 5); + RayCollision result = GetRayCollisionQuad(ray, p1, p2, p3, p4); + RLUA_PUSH_RayCollision(L, result); return 1; } -int lua_Vector2Scale(lua_State* L) -{ - Vector2 arg1 = LuaGetArgument_Vector2(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - Vector2Scale(&arg1, arg2); - LuaPush_Vector2(L, arg1); - return 1; -} +// ------------------------------------------------------------------------------------ +// Audio Loading and Playing Functions (Module: audio) +// ------------------------------------------------------------------------------------ -int lua_Vector2Negate(lua_State* L) +// Audio device management functions +// Initialize audio device and context +static int rl_InitAudioDevice(lua_State *L) { - Vector2 arg1 = LuaGetArgument_Vector2(L, 1); - Vector2Negate(&arg1); - LuaPush_Vector2(L, arg1); - return 1; + InitAudioDevice(); + return 0; } -int lua_Vector2Divide(lua_State* L) +// Close the audio device and context +static int rl_CloseAudioDevice(lua_State *L) { - Vector2 arg1 = LuaGetArgument_Vector2(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - Vector2Divide(&arg1, arg2); - LuaPush_Vector2(L, arg1); - return 1; + CloseAudioDevice(); + return 0; } -int lua_Vector2Normalize(lua_State* L) +// Check if audio device has been initialized successfully +static int rl_IsAudioDeviceReady(lua_State *L) { - Vector2 arg1 = LuaGetArgument_Vector2(L, 1); - Vector2Normalize(&arg1); - LuaPush_Vector2(L, arg1); + bool result = IsAudioDeviceReady(); + lua_pushboolean(L, result); return 1; } -//---------------------------------------------------------------------------------- -// raylib [raymath] module functions - Vector3 math -//---------------------------------------------------------------------------------- -int lua_VectorZero(lua_State* L) +// Set master volume (listener) +static int rl_SetMasterVolume(lua_State *L) { - Vector3 result = VectorZero(); - LuaPush_Vector3(L, result); - return 1; + float volume = (float)luaL_checknumber(L, 1); + SetMasterVolume(volume); + return 0; } -int lua_VectorOne(lua_State* L) +// Get master volume (listener) +static int rl_GetMasterVolume(lua_State *L) { - Vector3 result = VectorOne(); - LuaPush_Vector3(L, result); + float result = GetMasterVolume(); + lua_pushnumber(L, result); return 1; } -int lua_VectorAdd(lua_State* L) +// Wave/Sound loading/unloading functions +// Load wave data from file +static int rl_LoadWave(lua_State *L) { - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - Vector3 arg2 = LuaGetArgument_Vector3(L, 2); - Vector3 result = VectorAdd(arg1, arg2); - LuaPush_Vector3(L, result); + const char * fileName = luaL_checkstring(L, 1); + Wave result = LoadWave(fileName); + RLUA_PUSH_Resource(L, &result, sizeof(Wave), "Wave"); return 1; } -int lua_VectorSubtract(lua_State* L) +// Load wave from memory buffer, fileType refers to extension: i.e. '.wav' +static int rl_LoadWaveFromMemory(lua_State *L) { - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - Vector3 arg2 = LuaGetArgument_Vector3(L, 2); - Vector3 result = VectorSubtract(arg1, arg2); - LuaPush_Vector3(L, result); + const char * fileType = luaL_checkstring(L, 1); + const unsigned char * fileData = (const unsigned char *)lua_touserdata(L, 2); + int dataSize = (int)luaL_checkinteger(L, 3); + Wave result = LoadWaveFromMemory(fileType, fileData, dataSize); + RLUA_PUSH_Resource(L, &result, sizeof(Wave), "Wave"); return 1; } -int lua_VectorCrossProduct(lua_State* L) +// Checks if wave data is valid (data loaded and parameters) +static int rl_IsWaveValid(lua_State *L) { - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - Vector3 arg2 = LuaGetArgument_Vector3(L, 2); - Vector3 result = VectorCrossProduct(arg1, arg2); - LuaPush_Vector3(L, result); + Wave wave = *(Wave*)RLUA_CHECK_Resource(L, 1, "Wave"); + bool result = IsWaveValid(wave); + lua_pushboolean(L, result); return 1; } -int lua_VectorPerpendicular(lua_State* L) +// Load sound from file +static int rl_LoadSound(lua_State *L) { - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - Vector3 result = VectorPerpendicular(arg1); - LuaPush_Vector3(L, result); + const char * fileName = luaL_checkstring(L, 1); + Sound result = LoadSound(fileName); + RLUA_PUSH_Resource(L, &result, sizeof(Sound), "Sound"); return 1; } -int lua_VectorDotProduct(lua_State* L) +// Load sound from wave data +static int rl_LoadSoundFromWave(lua_State *L) { - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - Vector3 arg2 = LuaGetArgument_Vector3(L, 2); - float result = VectorDotProduct(arg1, arg2); - LuaPush_float(L, result); + Wave wave = *(Wave*)RLUA_CHECK_Resource(L, 1, "Wave"); + Sound result = LoadSoundFromWave(wave); + RLUA_PUSH_Resource(L, &result, sizeof(Sound), "Sound"); return 1; } -int lua_VectorLength(lua_State* L) +// Create a new sound that shares the same sample data as the source sound, does not own the sound data +static int rl_LoadSoundAlias(lua_State *L) { - const Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - float result = VectorLength(arg1); - LuaPush_float(L, result); + Sound source = *(Sound*)RLUA_CHECK_Resource(L, 1, "Sound"); + Sound result = LoadSoundAlias(source); + RLUA_PUSH_Resource(L, &result, sizeof(Sound), "Sound"); return 1; } -int lua_VectorScale(lua_State* L) +// Checks if a sound is valid (data loaded and buffers initialized) +static int rl_IsSoundValid(lua_State *L) { - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - VectorScale(&arg1, arg2); - LuaPush_Vector3(L, arg1); + Sound sound = *(Sound*)RLUA_CHECK_Resource(L, 1, "Sound"); + bool result = IsSoundValid(sound); + lua_pushboolean(L, result); return 1; } -int lua_VectorNegate(lua_State* L) +// Update sound buffer with new data (default data format: 32 bit float, stereo) +static int rl_UpdateSound(lua_State *L) { - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - VectorNegate(&arg1); - LuaPush_Vector3(L, arg1); - return 1; + Sound sound = *(Sound*)RLUA_CHECK_Resource(L, 1, "Sound"); + const void * data = (const void *)lua_touserdata(L, 2); + int sampleCount = (int)luaL_checkinteger(L, 3); + UpdateSound(sound, data, sampleCount); + return 0; } -int lua_VectorNormalize(lua_State* L) +// Unload wave data +static int rl_UnloadWave(lua_State *L) { - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - VectorNormalize(&arg1); - LuaPush_Vector3(L, arg1); - return 1; + Wave wave = *(Wave*)RLUA_CHECK_Resource(L, 1, "Wave"); + UnloadWave(wave); + return 0; } -int lua_VectorDistance(lua_State* L) +// Unload sound +static int rl_UnloadSound(lua_State *L) { - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - Vector3 arg2 = LuaGetArgument_Vector3(L, 2); - float result = VectorDistance(arg1, arg2); - LuaPush_float(L, result); - return 1; + Sound sound = *(Sound*)RLUA_CHECK_Resource(L, 1, "Sound"); + UnloadSound(sound); + return 0; } -int lua_VectorLerp(lua_State* L) +// Unload a sound alias (does not deallocate sample data) +static int rl_UnloadSoundAlias(lua_State *L) { - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - Vector3 arg2 = LuaGetArgument_Vector3(L, 2); - float arg3 = LuaGetArgument_float(L, 3); - Vector3 result = VectorLerp(arg1, arg2, arg3); - LuaPush_Vector3(L, result); - return 1; + Sound alias = *(Sound*)RLUA_CHECK_Resource(L, 1, "Sound"); + UnloadSoundAlias(alias); + return 0; } -int lua_VectorReflect(lua_State* L) +// Export wave data to file, returns true on success +static int rl_ExportWave(lua_State *L) { - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - Vector3 arg2 = LuaGetArgument_Vector3(L, 2); - Vector3 result = VectorReflect(arg1, arg2); - LuaPush_Vector3(L, result); + Wave wave = *(Wave*)RLUA_CHECK_Resource(L, 1, "Wave"); + const char * fileName = luaL_checkstring(L, 2); + bool result = ExportWave(wave, fileName); + lua_pushboolean(L, result); return 1; } -int lua_VectorTransform(lua_State* L) +// Export wave sample data to code (.h), returns true on success +static int rl_ExportWaveAsCode(lua_State *L) { - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - Matrix arg2 = LuaGetArgument_Matrix(L, 2); - VectorTransform(&arg1, arg2); - LuaPush_Vector3(L, arg1); + Wave wave = *(Wave*)RLUA_CHECK_Resource(L, 1, "Wave"); + const char * fileName = luaL_checkstring(L, 2); + bool result = ExportWaveAsCode(wave, fileName); + lua_pushboolean(L, result); return 1; } -//---------------------------------------------------------------------------------- -// raylib [raymath] module functions - Matrix math -//---------------------------------------------------------------------------------- -int lua_MatrixDeterminant(lua_State* L) +// Wave/Sound management functions +// Play a sound +static int rl_PlaySound(lua_State *L) { - Matrix arg1 = LuaGetArgument_Matrix(L, 1); - float result = MatrixDeterminant(arg1); - LuaPush_float(L, result); - return 1; + Sound sound = *(Sound*)RLUA_CHECK_Resource(L, 1, "Sound"); + PlaySound(sound); + return 0; } -int lua_MatrixTrace(lua_State* L) +// Stop playing a sound +static int rl_StopSound(lua_State *L) { - Matrix arg1 = LuaGetArgument_Matrix(L, 1); - float result = MatrixTrace(arg1); - LuaPush_float(L, result); - return 1; + Sound sound = *(Sound*)RLUA_CHECK_Resource(L, 1, "Sound"); + StopSound(sound); + return 0; } -int lua_MatrixTranspose(lua_State* L) +// Pause a sound +static int rl_PauseSound(lua_State *L) { - Matrix arg1 = LuaGetArgument_Matrix(L, 1); - MatrixTranspose(&arg1); - LuaPush_Matrix(L, &arg1); - return 1; + Sound sound = *(Sound*)RLUA_CHECK_Resource(L, 1, "Sound"); + PauseSound(sound); + return 0; } -int lua_MatrixInvert(lua_State* L) +// Resume a paused sound +static int rl_ResumeSound(lua_State *L) { - Matrix arg1 = LuaGetArgument_Matrix(L, 1); - MatrixInvert(&arg1); - LuaPush_Matrix(L, &arg1); - return 1; + Sound sound = *(Sound*)RLUA_CHECK_Resource(L, 1, "Sound"); + ResumeSound(sound); + return 0; } -int lua_MatrixNormalize(lua_State* L) +// Check if a sound is currently playing +static int rl_IsSoundPlaying(lua_State *L) { - Matrix arg1 = LuaGetArgument_Matrix(L, 1); - MatrixNormalize(&arg1); - LuaPush_Matrix(L, &arg1); + Sound sound = *(Sound*)RLUA_CHECK_Resource(L, 1, "Sound"); + bool result = IsSoundPlaying(sound); + lua_pushboolean(L, result); return 1; } -int lua_MatrixIdentity(lua_State* L) +// Set volume for a sound (1.0 is max level) +static int rl_SetSoundVolume(lua_State *L) { - Matrix result = MatrixIdentity(); - LuaPush_Matrix(L, &result); - return 1; + Sound sound = *(Sound*)RLUA_CHECK_Resource(L, 1, "Sound"); + float volume = (float)luaL_checknumber(L, 2); + SetSoundVolume(sound, volume); + return 0; } -int lua_MatrixAdd(lua_State* L) +// Set pitch for a sound (1.0 is base level) +static int rl_SetSoundPitch(lua_State *L) { - Matrix arg1 = LuaGetArgument_Matrix(L, 1); - Matrix arg2 = LuaGetArgument_Matrix(L, 2); - Matrix result = MatrixAdd(arg1, arg2); - LuaPush_Matrix(L, &result); - return 1; + Sound sound = *(Sound*)RLUA_CHECK_Resource(L, 1, "Sound"); + float pitch = (float)luaL_checknumber(L, 2); + SetSoundPitch(sound, pitch); + return 0; } -int lua_MatrixSubstract(lua_State* L) +// Set pan for a sound (-1.0 left, 0.0 center, 1.0 right) +static int rl_SetSoundPan(lua_State *L) { - Matrix arg1 = LuaGetArgument_Matrix(L, 1); - Matrix arg2 = LuaGetArgument_Matrix(L, 2); - Matrix result = MatrixSubstract(arg1, arg2); - LuaPush_Matrix(L, &result); - return 1; + Sound sound = *(Sound*)RLUA_CHECK_Resource(L, 1, "Sound"); + float pan = (float)luaL_checknumber(L, 2); + SetSoundPan(sound, pan); + return 0; } -int lua_MatrixTranslate(lua_State* L) +// Copy a wave to a new wave +static int rl_WaveCopy(lua_State *L) { - float arg1 = LuaGetArgument_float(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - float arg3 = LuaGetArgument_float(L, 3); - Matrix result = MatrixTranslate(arg1, arg2, arg3); - LuaPush_Matrix(L, &result); + Wave wave = *(Wave*)RLUA_CHECK_Resource(L, 1, "Wave"); + Wave result = WaveCopy(wave); + RLUA_PUSH_Resource(L, &result, sizeof(Wave), "Wave"); return 1; } -int lua_MatrixRotate(lua_State* L) +// Crop a wave to defined frames range +static int rl_WaveCrop(lua_State *L) { - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - Matrix result = MatrixRotate(arg1, arg2); - LuaPush_Matrix(L, &result); - return 1; + Wave * wave = (Wave *)lua_touserdata(L, 1); + int initFrame = (int)luaL_checkinteger(L, 2); + int finalFrame = (int)luaL_checkinteger(L, 3); + WaveCrop(wave, initFrame, finalFrame); + return 0; } -int lua_MatrixRotateX(lua_State* L) +// Convert wave data to desired format +static int rl_WaveFormat(lua_State *L) { - float arg1 = LuaGetArgument_float(L, 1); - Matrix result = MatrixRotateX(arg1); - LuaPush_Matrix(L, &result); - return 1; + Wave * wave = (Wave *)lua_touserdata(L, 1); + int sampleRate = (int)luaL_checkinteger(L, 2); + int sampleSize = (int)luaL_checkinteger(L, 3); + int channels = (int)luaL_checkinteger(L, 4); + WaveFormat(wave, sampleRate, sampleSize, channels); + return 0; } -int lua_MatrixRotateY(lua_State* L) +// Load samples data from wave as a 32bit float data array +static int rl_LoadWaveSamples(lua_State *L) { - float arg1 = LuaGetArgument_float(L, 1); - Matrix result = MatrixRotateY(arg1); - LuaPush_Matrix(L, &result); + Wave wave = *(Wave*)RLUA_CHECK_Resource(L, 1, "Wave"); + float * result = LoadWaveSamples(wave); + lua_pushlightuserdata(L, result); return 1; } -int lua_MatrixRotateZ(lua_State* L) +// Unload samples data loaded with LoadWaveSamples() +static int rl_UnloadWaveSamples(lua_State *L) { - float arg1 = LuaGetArgument_float(L, 1); - Matrix result = MatrixRotateZ(arg1); - LuaPush_Matrix(L, &result); - return 1; + float * samples = (float *)lua_touserdata(L, 1); + UnloadWaveSamples(samples); + return 0; } -int lua_MatrixScale(lua_State* L) +// Music management functions +// Load music stream from file +static int rl_LoadMusicStream(lua_State *L) { - float arg1 = LuaGetArgument_float(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - float arg3 = LuaGetArgument_float(L, 3); - Matrix result = MatrixScale(arg1, arg2, arg3); - LuaPush_Matrix(L, &result); + const char * fileName = luaL_checkstring(L, 1); + Music result = LoadMusicStream(fileName); + RLUA_PUSH_Resource(L, &result, sizeof(Music), "Music"); return 1; } -int lua_MatrixMultiply(lua_State* L) +// Load music stream from data +static int rl_LoadMusicStreamFromMemory(lua_State *L) { - Matrix arg1 = LuaGetArgument_Matrix(L, 1); - Matrix arg2 = LuaGetArgument_Matrix(L, 2); - Matrix result = MatrixMultiply(arg1, arg2); - LuaPush_Matrix(L, &result); + const char * fileType = luaL_checkstring(L, 1); + const unsigned char * data = (const unsigned char *)lua_touserdata(L, 2); + int dataSize = (int)luaL_checkinteger(L, 3); + Music result = LoadMusicStreamFromMemory(fileType, data, dataSize); + RLUA_PUSH_Resource(L, &result, sizeof(Music), "Music"); return 1; } -int lua_MatrixFrustum(lua_State* L) +// Checks if a music stream is valid (context and buffers initialized) +static int rl_IsMusicValid(lua_State *L) { - double arg1 = LuaGetArgument_double(L, 1); - double arg2 = LuaGetArgument_double(L, 2); - double arg3 = LuaGetArgument_double(L, 3); - double arg4 = LuaGetArgument_double(L, 4); - double arg5 = LuaGetArgument_double(L, 5); - double arg6 = LuaGetArgument_double(L, 6); - Matrix result = MatrixFrustum(arg1, arg2, arg3, arg4, arg5, arg6); - LuaPush_Matrix(L, &result); + Music music = *(Music*)RLUA_CHECK_Resource(L, 1, "Music"); + bool result = IsMusicValid(music); + lua_pushboolean(L, result); return 1; } -int lua_MatrixPerspective(lua_State* L) +// Unload music stream +static int rl_UnloadMusicStream(lua_State *L) { - double arg1 = LuaGetArgument_double(L, 1); - double arg2 = LuaGetArgument_double(L, 2); - double arg3 = LuaGetArgument_double(L, 3); - double arg4 = LuaGetArgument_double(L, 4); - Matrix result = MatrixPerspective(arg1, arg2, arg3, arg4); - LuaPush_Matrix(L, &result); - return 1; + Music music = *(Music*)RLUA_CHECK_Resource(L, 1, "Music"); + UnloadMusicStream(music); + return 0; } -int lua_MatrixOrtho(lua_State* L) +// Start music playing +static int rl_PlayMusicStream(lua_State *L) { - double arg1 = LuaGetArgument_double(L, 1); - double arg2 = LuaGetArgument_double(L, 2); - double arg3 = LuaGetArgument_double(L, 3); - double arg4 = LuaGetArgument_double(L, 4); - double arg5 = LuaGetArgument_double(L, 5); - double arg6 = LuaGetArgument_double(L, 6); - Matrix result = MatrixOrtho(arg1, arg2, arg3, arg4, arg5, arg6); - LuaPush_Matrix(L, &result); - return 1; + Music music = *(Music*)RLUA_CHECK_Resource(L, 1, "Music"); + PlayMusicStream(music); + return 0; } -int lua_MatrixLookAt(lua_State* L) +// Check if music is playing +static int rl_IsMusicStreamPlaying(lua_State *L) { - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - Vector3 arg2 = LuaGetArgument_Vector3(L, 2); - Vector3 arg3 = LuaGetArgument_Vector3(L, 3); - Matrix result = MatrixLookAt(arg1, arg2, arg3); - LuaPush_Matrix(L, &result); + Music music = *(Music*)RLUA_CHECK_Resource(L, 1, "Music"); + bool result = IsMusicStreamPlaying(music); + lua_pushboolean(L, result); return 1; } -//---------------------------------------------------------------------------------- -// raylib [raymath] module functions - Quaternion math -//---------------------------------------------------------------------------------- -int lua_QuaternionLength(lua_State* L) +// Updates buffers for music streaming +static int rl_UpdateMusicStream(lua_State *L) { - Quaternion arg1 = LuaGetArgument_Quaternion(L, 1); - float result = QuaternionLength(arg1); - LuaPush_float(L, result); - return 1; + Music music = *(Music*)RLUA_CHECK_Resource(L, 1, "Music"); + UpdateMusicStream(music); + return 0; } -int lua_QuaternionNormalize(lua_State* L) +// Stop music playing +static int rl_StopMusicStream(lua_State *L) { - Quaternion arg1 = LuaGetArgument_Quaternion(L, 1); - QuaternionNormalize(&arg1); - LuaPush_Quaternion(L, arg1); - return 1; + Music music = *(Music*)RLUA_CHECK_Resource(L, 1, "Music"); + StopMusicStream(music); + return 0; } -int lua_QuaternionMultiply(lua_State* L) +// Pause music playing +static int rl_PauseMusicStream(lua_State *L) { - Quaternion arg1 = LuaGetArgument_Quaternion(L, 1); - Quaternion arg2 = LuaGetArgument_Quaternion(L, 2); - Quaternion result = QuaternionMultiply(arg1, arg2); - LuaPush_Quaternion(L, result); - return 1; + Music music = *(Music*)RLUA_CHECK_Resource(L, 1, "Music"); + PauseMusicStream(music); + return 0; } -int lua_QuaternionSlerp(lua_State* L) +// Resume playing paused music +static int rl_ResumeMusicStream(lua_State *L) { - Quaternion arg1 = LuaGetArgument_Quaternion(L, 1); - Quaternion arg2 = LuaGetArgument_Quaternion(L, 2); - float arg3 = LuaGetArgument_float(L, 3); - Quaternion result = QuaternionSlerp(arg1, arg2, arg3); - LuaPush_Quaternion(L, result); - return 1; + Music music = *(Music*)RLUA_CHECK_Resource(L, 1, "Music"); + ResumeMusicStream(music); + return 0; } -int lua_QuaternionFromMatrix(lua_State* L) +// Seek music to a position (in seconds) +static int rl_SeekMusicStream(lua_State *L) { - Matrix arg1 = LuaGetArgument_Matrix(L, 1); - Quaternion result = QuaternionFromMatrix(arg1); - LuaPush_Quaternion(L, result); - return 1; + Music music = *(Music*)RLUA_CHECK_Resource(L, 1, "Music"); + float position = (float)luaL_checknumber(L, 2); + SeekMusicStream(music, position); + return 0; } -int lua_QuaternionToMatrix(lua_State* L) +// Set volume for music (1.0 is max level) +static int rl_SetMusicVolume(lua_State *L) { - Quaternion arg1 = LuaGetArgument_Quaternion(L, 1); - Matrix result = QuaternionToMatrix(arg1); - LuaPush_Matrix(L, &result); - return 1; + Music music = *(Music*)RLUA_CHECK_Resource(L, 1, "Music"); + float volume = (float)luaL_checknumber(L, 2); + SetMusicVolume(music, volume); + return 0; } -int lua_QuaternionFromAxisAngle(lua_State* L) +// Set pitch for a music (1.0 is base level) +static int rl_SetMusicPitch(lua_State *L) { - Vector3 arg1 = LuaGetArgument_Vector3(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - Quaternion result = QuaternionFromAxisAngle(arg1, arg2); - LuaPush_Quaternion(L, result); - return 1; + Music music = *(Music*)RLUA_CHECK_Resource(L, 1, "Music"); + float pitch = (float)luaL_checknumber(L, 2); + SetMusicPitch(music, pitch); + return 0; } -int lua_QuaternionToAxisAngle(lua_State* L) +// Set pan for a music (-1.0 left, 0.0 center, 1.0 right) +static int rl_SetMusicPan(lua_State *L) { - Quaternion arg1 = LuaGetArgument_Quaternion(L, 1); - Vector3 arg2; - float arg3 = 0; - QuaternionToAxisAngle(arg1, &arg2, &arg3); - LuaPush_Vector3(L, arg2); - LuaPush_float(L, arg3); - return 2; + Music music = *(Music*)RLUA_CHECK_Resource(L, 1, "Music"); + float pan = (float)luaL_checknumber(L, 2); + SetMusicPan(music, pan); + return 0; } -int lua_QuaternionFromEuler(lua_State* L) +// Get music time length (in seconds) +static int rl_GetMusicTimeLength(lua_State *L) { - float arg1 = LuaGetArgument_float(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - float arg3 = LuaGetArgument_float(L, 3); - Quaternion result = QuaternionFromEuler(arg1, arg2, arg3); - LuaPush_Quaternion(L, result); + Music music = *(Music*)RLUA_CHECK_Resource(L, 1, "Music"); + float result = GetMusicTimeLength(music); + lua_pushnumber(L, result); return 1; } -int lua_QuaternionToEuler(lua_State* L) +// Get current music time played (in seconds) +static int rl_GetMusicTimePlayed(lua_State *L) { - Quaternion arg1 = LuaGetArgument_Quaternion(L, 1); - Vector3 result = QuaternionToEuler(arg1); - LuaPush_Vector3(L, result); + Music music = *(Music*)RLUA_CHECK_Resource(L, 1, "Music"); + float result = GetMusicTimePlayed(music); + lua_pushnumber(L, result); return 1; } -int lua_QuaternionTransform(lua_State* L) +// AudioStream management functions +// Load audio stream (to stream raw audio pcm data) +static int rl_LoadAudioStream(lua_State *L) { - Quaternion arg1 = LuaGetArgument_Quaternion(L, 1); - Matrix arg2 = LuaGetArgument_Matrix(L, 2); - QuaternionTransform(&arg1, arg2); - LuaPush_Quaternion(L, arg1); + unsigned int sampleRate = (unsigned int)luaL_checkinteger(L, 1); + unsigned int sampleSize = (unsigned int)luaL_checkinteger(L, 2); + unsigned int channels = (unsigned int)luaL_checkinteger(L, 3); + AudioStream result = LoadAudioStream(sampleRate, sampleSize, channels); + RLUA_PUSH_Resource(L, &result, sizeof(AudioStream), "AudioStream"); return 1; } -//---------------------------------------------------------------------------------- -// physics [physac] module functions -//---------------------------------------------------------------------------------- - -// Initializes physics values, pointers and creates physics loop thread -int lua_InitPhysics(lua_State* L) +// Checks if an audio stream is valid (buffers initialized) +static int rl_IsAudioStreamValid(lua_State *L) { - InitPhysics(); - return 0; + AudioStream stream = *(AudioStream*)RLUA_CHECK_Resource(L, 1, "AudioStream"); + bool result = IsAudioStreamValid(stream); + lua_pushboolean(L, result); + return 1; } -// Returns true if physics thread is currently enabled -int lua_IsPhysicsEnabled(lua_State* L) +// Unload audio stream and free memory +static int rl_UnloadAudioStream(lua_State *L) { - bool result = IsPhysicsEnabled(); - LuaPush_bool(L, result); - return 1; + AudioStream stream = *(AudioStream*)RLUA_CHECK_Resource(L, 1, "AudioStream"); + UnloadAudioStream(stream); + return 0; } -// Sets physics global gravity force -int lua_SetPhysicsGravity(lua_State* L) +// Update audio stream buffers with data +static int rl_UpdateAudioStream(lua_State *L) { - float arg1 = LuaGetArgument_float(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - SetPhysicsGravity(arg1, arg2); + AudioStream stream = *(AudioStream*)RLUA_CHECK_Resource(L, 1, "AudioStream"); + const void * data = (const void *)lua_touserdata(L, 2); + int frameCount = (int)luaL_checkinteger(L, 3); + UpdateAudioStream(stream, data, frameCount); return 0; } -// Creates a new circle physics body with generic parameters -int lua_CreatePhysicsBodyCircle(lua_State* L) +// Check if any audio stream buffers requires refill +static int rl_IsAudioStreamProcessed(lua_State *L) { - Vector2 arg1 = LuaGetArgument_Vector2(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - float arg3 = LuaGetArgument_float(L, 3); - PhysicsBody result = CreatePhysicsBodyCircle(arg1, arg2, arg3); - LuaPush_PhysicsBody(L, result); + AudioStream stream = *(AudioStream*)RLUA_CHECK_Resource(L, 1, "AudioStream"); + bool result = IsAudioStreamProcessed(stream); + lua_pushboolean(L, result); return 1; } -// Creates a new rectangle physics body with generic parameters -int lua_CreatePhysicsBodyRectangle(lua_State* L) +// Play audio stream +static int rl_PlayAudioStream(lua_State *L) { - Vector2 arg1 = LuaGetArgument_Vector2(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - float arg3 = LuaGetArgument_float(L, 3); - float arg4 = LuaGetArgument_float(L, 4); - PhysicsBody result = CreatePhysicsBodyRectangle(arg1, arg2, arg3, arg4); - LuaPush_PhysicsBody(L, result); - return 1; + AudioStream stream = *(AudioStream*)RLUA_CHECK_Resource(L, 1, "AudioStream"); + PlayAudioStream(stream); + return 0; } -// Creates a new polygon physics body with generic parameters -int lua_CreatePhysicsBodyPolygon(lua_State* L) +// Pause audio stream +static int rl_PauseAudioStream(lua_State *L) { - Vector2 arg1 = LuaGetArgument_Vector2(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - int arg3 = LuaGetArgument_int(L, 3); - float arg4 = LuaGetArgument_float(L, 4); - PhysicsBody result = CreatePhysicsBodyPolygon(arg1, arg2, arg3, arg4); - LuaPush_PhysicsBody(L, result); - return 1; + AudioStream stream = *(AudioStream*)RLUA_CHECK_Resource(L, 1, "AudioStream"); + PauseAudioStream(stream); + return 0; } -// Adds a force to a physics body -int lua_PhysicsAddForce(lua_State* L) +// Resume audio stream +static int rl_ResumeAudioStream(lua_State *L) { - PhysicsBody arg1 = LuaGetArgument_PhysicsBody(L, 1); - Vector2 arg2 = LuaGetArgument_Vector2(L, 2); - PhysicsAddForce(arg1, arg2); + AudioStream stream = *(AudioStream*)RLUA_CHECK_Resource(L, 1, "AudioStream"); + ResumeAudioStream(stream); return 0; } -// Adds an angular force to a physics body -int lua_PhysicsAddTorque(lua_State* L) +// Check if audio stream is playing +static int rl_IsAudioStreamPlaying(lua_State *L) { - PhysicsBody arg1 = LuaGetArgument_PhysicsBody(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - PhysicsAddTorque(arg1, arg2); - return 0; + AudioStream stream = *(AudioStream*)RLUA_CHECK_Resource(L, 1, "AudioStream"); + bool result = IsAudioStreamPlaying(stream); + lua_pushboolean(L, result); + return 1; } -// Shatters a polygon shape physics body to little physics bodies with explosion force -int lua_PhysicsShatter(lua_State* L) +// Stop audio stream +static int rl_StopAudioStream(lua_State *L) { - PhysicsBody arg1 = LuaGetArgument_PhysicsBody(L, 1); - Vector2 arg2 = LuaGetArgument_Vector2(L, 2); - float arg3 = LuaGetArgument_float(L, 3); - PhysicsShatter(arg1, arg2, arg3); + AudioStream stream = *(AudioStream*)RLUA_CHECK_Resource(L, 1, "AudioStream"); + StopAudioStream(stream); return 0; } -// Returns the current amount of created physics bodies -int lua_GetPhysicsBodiesCount(lua_State* L) +// Set volume for audio stream (1.0 is max level) +static int rl_SetAudioStreamVolume(lua_State *L) { - int result = GetPhysicsBodiesCount(); - LuaPush_int(L, result); - return 1; + AudioStream stream = *(AudioStream*)RLUA_CHECK_Resource(L, 1, "AudioStream"); + float volume = (float)luaL_checknumber(L, 2); + SetAudioStreamVolume(stream, volume); + return 0; } -// Returns a physics body of the bodies pool at a specific index -int lua_GetPhysicsBody(lua_State* L) +// Set pitch for audio stream (1.0 is base level) +static int rl_SetAudioStreamPitch(lua_State *L) { - int arg1 = LuaGetArgument_int(L, 1); - PhysicsBody result = GetPhysicsBody(arg1); - LuaPush_PhysicsBody(L, result); - return 1; + AudioStream stream = *(AudioStream*)RLUA_CHECK_Resource(L, 1, "AudioStream"); + float pitch = (float)luaL_checknumber(L, 2); + SetAudioStreamPitch(stream, pitch); + return 0; } -// Returns the physics body shape type (PHYSICS_CIRCLE or PHYSICS_POLYGON) -int lua_GetPhysicsShapeType(lua_State* L) +// Set pan for audio stream (-1.0 to 1.0 range, 0.0 is centered) +static int rl_SetAudioStreamPan(lua_State *L) { - int arg1 = LuaGetArgument_int(L, 1); - int result = GetPhysicsShapeType(arg1); - LuaPush_int(L, result); - return 1; + AudioStream stream = *(AudioStream*)RLUA_CHECK_Resource(L, 1, "AudioStream"); + float pan = (float)luaL_checknumber(L, 2); + SetAudioStreamPan(stream, pan); + return 0; } -// Returns the amount of vertices of a physics body shape -int lua_GetPhysicsShapeVerticesCount(lua_State* L) +// Default size for new audio streams +static int rl_SetAudioStreamBufferSizeDefault(lua_State *L) { - int arg1 = LuaGetArgument_int(L, 1); - int result = GetPhysicsShapeVerticesCount(arg1); - LuaPush_int(L, result); - return 1; + int size = (int)luaL_checkinteger(L, 1); + SetAudioStreamBufferSizeDefault(size); + return 0; } -// Returns transformed position of a body shape (body position + vertex transformed position) -int lua_GetPhysicsShapeVertex(lua_State* L) +// Audio thread callback to request new data +static int rl_SetAudioStreamCallback(lua_State *L) { - PhysicsBody arg1 = LuaGetArgument_PhysicsBody(L, 1); - int arg2 = LuaGetArgument_int(L, 2); - Vector2 result = GetPhysicsShapeVertex(arg1, arg2); - LuaPush_Vector2(L, result); - return 1; + AudioStream stream = *(AudioStream*)RLUA_CHECK_Resource(L, 1, "AudioStream"); + AudioCallback callback = (AudioCallback)lua_touserdata(L, 2); + SetAudioStreamCallback(stream, callback); + return 0; } -// Sets physics body shape transform based on radians parameter -int lua_SetPhysicsBodyRotation(lua_State* L) +// Attach audio stream processor to stream, receives frames x 2 samples as 'float' (stereo) +static int rl_AttachAudioStreamProcessor(lua_State *L) { - PhysicsBody arg1 = LuaGetArgument_PhysicsBody(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - SetPhysicsBodyRotation(arg1, arg2); + AudioStream stream = *(AudioStream*)RLUA_CHECK_Resource(L, 1, "AudioStream"); + AudioCallback processor = (AudioCallback)lua_touserdata(L, 2); + AttachAudioStreamProcessor(stream, processor); return 0; } -// Unitializes and destroy a physics body -int lua_DestroyPhysicsBody(lua_State* L) +// Detach audio stream processor from stream +static int rl_DetachAudioStreamProcessor(lua_State *L) { - PhysicsBody arg1 = LuaGetArgument_PhysicsBody(L, 1); - DestroyPhysicsBody(arg1); + AudioStream stream = *(AudioStream*)RLUA_CHECK_Resource(L, 1, "AudioStream"); + AudioCallback processor = (AudioCallback)lua_touserdata(L, 2); + DetachAudioStreamProcessor(stream, processor); return 0; } -// Destroys created physics bodies and manifolds and resets global values -int lua_ResetPhysics(lua_State* L) +// Attach audio stream processor to the entire audio pipeline, receives frames x 2 samples as 'float' (stereo) +static int rl_AttachAudioMixedProcessor(lua_State *L) { - ResetPhysics(); + AudioCallback processor = (AudioCallback)lua_touserdata(L, 1); + AttachAudioMixedProcessor(processor); return 0; } -// Unitializes physics pointers and closes physics loop thread -int lua_ClosePhysics(lua_State* L) +// Detach audio stream processor from the entire audio pipeline +static int rl_DetachAudioMixedProcessor(lua_State *L) { - ClosePhysics(); + AudioCallback processor = (AudioCallback)lua_touserdata(L, 1); + DetachAudioMixedProcessor(processor); return 0; } -//---------------------------------------------------------------------------------- -// Functions Registering -//---------------------------------------------------------------------------------- -#define REG(name) { #name, lua_##name }, - -static luaL_Reg raylib_functions[] = { - - // Register non-opaque data types - REG(Color) - REG(Vector2) - REG(Vector3) - REG(Vector4) - //REG(Matrix) - REG(Quaternion) - REG(Rectangle) - REG(Ray) - REG(RayHitInfo) - REG(Camera) - REG(Camera2D) - REG(BoundingBox) - //REG(Material) - - // Register functions - //-------------------- - REG(InitWindow) - REG(CloseWindow) - REG(IsWindowReady) - REG(WindowShouldClose) - REG(IsWindowMinimized) - REG(ToggleFullscreen) - REG(SetWindowIcon) - REG(SetWindowTitle) - REG(SetWindowPosition) - REG(SetWindowMonitor) - REG(SetWindowMinSize) - REG(SetWindowSize) - REG(GetScreenWidth) - REG(GetScreenHeight) - REG(ShowCursor) - REG(HideCursor) - REG(IsCursorHidden) - REG(EnableCursor) - REG(DisableCursor) - REG(ClearBackground) - REG(BeginDrawing) - REG(EndDrawing) - REG(BeginMode2D) - REG(EndMode2D) - REG(BeginMode3D) - REG(EndMode3D) - REG(BeginTextureMode) - REG(EndTextureMode) - REG(GetMouseRay) - REG(GetWorldToScreen) - REG(GetCameraMatrix) - REG(SetTargetFPS) - REG(GetFPS) - REG(GetFrameTime) - REG(GetTime) - REG(ColorToInt) - REG(ColorNormalize) - REG(ColorToHSV) - REG(GetColor) - REG(Fade) - REG(ShowLogo) - REG(SetConfigFlags) - REG(SetTraceLog) - REG(TraceLog) - REG(TakeScreenshot) - REG(GetRandomValue) - REG(IsFileExtension) - REG(GetExtension) - REG(GetFileName) - REG(GetDirectoryPath) - REG(GetWorkingDirectory) - REG(ChangeDirectory) - REG(IsFileDropped) - REG(GetDroppedFiles) - REG(ClearDroppedFiles) - REG(StorageSaveValue) - REG(StorageLoadValue) - REG(IsKeyPressed) - REG(IsKeyDown) - REG(IsKeyReleased) - REG(IsKeyUp) - REG(GetKeyPressed) - REG(SetExitKey) - REG(IsGamepadAvailable) - REG(IsGamepadName) - REG(GetGamepadName) - REG(IsGamepadButtonPressed) - REG(IsGamepadButtonDown) - REG(IsGamepadButtonReleased) - REG(IsGamepadButtonUp) - REG(GetGamepadButtonPressed) - REG(GetGamepadAxisCount) - REG(GetGamepadAxisMovement) - REG(IsMouseButtonPressed) - REG(IsMouseButtonDown) - REG(IsMouseButtonReleased) - REG(IsMouseButtonUp) - REG(GetMouseX) - REG(GetMouseY) - REG(GetMousePosition) - REG(SetMousePosition) - REG(SetMouseScale) - REG(GetMouseWheelMove) - REG(GetTouchX) - REG(GetTouchY) - REG(GetTouchPosition) - REG(SetGesturesEnabled) - REG(IsGestureDetected) - REG(GetGestureDetected) - REG(GetTouchPointsCount) - REG(GetGestureHoldDuration) - REG(GetGestureDragVector) - REG(GetGestureDragAngle) - REG(GetGesturePinchVector) - REG(GetGesturePinchAngle) - REG(SetCameraMode) - REG(UpdateCamera) - REG(SetCameraPanControl) - REG(SetCameraAltControl) - REG(SetCameraSmoothZoomControl) - REG(SetCameraMoveControls) - REG(DrawPixel) - REG(DrawPixelV) - REG(DrawLine) - REG(DrawLineV) - REG(DrawLineEx) - REG(DrawLineBezier) - REG(DrawCircle) - REG(DrawCircleGradient) - REG(DrawCircleV) - REG(DrawCircleLines) - REG(DrawRectangle) - REG(DrawRectangleV) - REG(DrawRectangleRec) - REG(DrawRectanglePro) - REG(DrawRectangleGradientV) - REG(DrawRectangleGradientH) - REG(DrawRectangleGradientEx) - REG(DrawRectangleLines) - REG(DrawRectangleLinesEx) - REG(DrawTriangle) - REG(DrawTriangleLines) - REG(DrawPoly) - REG(DrawPolyEx) - REG(DrawPolyExLines) - REG(CheckCollisionRecs) - REG(CheckCollisionCircles) - REG(CheckCollisionCircleRec) - REG(GetCollisionRec) - REG(CheckCollisionPointRec) - REG(CheckCollisionPointCircle) - REG(CheckCollisionPointTriangle) - REG(LoadImage) - REG(LoadImageEx) - REG(LoadImagePro) - REG(LoadImageRaw) - REG(ExportImage) - REG(LoadTexture) - REG(LoadTextureFromImage) - REG(LoadRenderTexture) - REG(UnloadImage) - REG(UnloadTexture) - REG(UnloadRenderTexture) - REG(GetImageData) - REG(GetImageDataNormalized) - REG(GetPixelDataSize) - REG(GetTextureData) - REG(UpdateTexture) - REG(ImageCopy) - REG(ImageToPOT) - REG(ImageFormat) - REG(ImageAlphaMask) - REG(ImageAlphaClear) - REG(ImageAlphaCrop) - REG(ImageAlphaPremultiply) - REG(ImageCrop) - REG(ImageResize) - REG(ImageResizeNN) - REG(ImageResizeCanvas) - REG(ImageMipmaps) - REG(ImageDither) - REG(ImageText) - REG(ImageTextEx) - REG(ImageDraw) - REG(ImageDrawRectangle) - REG(ImageDrawText) - REG(ImageDrawTextEx) - REG(ImageFlipVertical) - REG(ImageFlipHorizontal) - REG(ImageRotateCW) - REG(ImageRotateCCW) - REG(ImageColorTint) - REG(ImageColorInvert) - REG(ImageColorGrayscale) - REG(ImageColorContrast) - REG(ImageColorBrightness) - REG(ImageColorReplace) - REG(GenImageColor) - REG(GenImageGradientV) - REG(GenImageGradientH) - REG(GenImageGradientRadial) - REG(GenImageChecked) - REG(GenImageWhiteNoise) - REG(GenImagePerlinNoise) - REG(GenImageCellular) - REG(GenTextureMipmaps) - REG(SetTextureFilter) - REG(SetTextureWrap) - REG(DrawTexture) - REG(DrawTextureV) - REG(DrawTextureEx) - REG(DrawTextureRec) - REG(DrawTexturePro) - REG(GetFontDefault) - REG(LoadFont) - REG(LoadFontEx) - REG(LoadFontData) - REG(GenImageFontAtlas) - REG(UnloadFont) - REG(DrawFPS) - REG(DrawText) - REG(DrawTextEx) - REG(MeasureText) - REG(MeasureTextEx) - REG(FormatText) - REG(SubText) - REG(GetGlyphIndex) - REG(DrawLine3D) - REG(DrawCircle3D) - REG(DrawCube) - REG(DrawCubeV) - REG(DrawCubeWires) - REG(DrawCubeTexture) - REG(DrawSphere) - REG(DrawSphereEx) - REG(DrawSphereWires) - REG(DrawCylinder) - REG(DrawCylinderWires) - REG(DrawPlane) - REG(DrawRay) - REG(DrawGrid) - REG(DrawGizmo) - REG(LoadModel) - REG(LoadModelFromMesh) - REG(UnloadModel) - REG(LoadMesh) - REG(UnloadMesh) - REG(ExportMesh) - REG(MeshBoundingBox) - REG(MeshTangents) - REG(MeshBinormals) - REG(GenMeshPlane) - REG(GenMeshCube) - REG(GenMeshSphere) - REG(GenMeshHemiSphere) - REG(GenMeshCylinder) - REG(GenMeshTorus) - REG(GenMeshKnot) - REG(GenMeshHeightmap) - REG(GenMeshCubicmap) - REG(LoadMaterial) - REG(LoadMaterialDefault) - REG(UnloadMaterial) - REG(DrawModel) - REG(DrawModelEx) - REG(DrawModelWires) - REG(DrawModelWiresEx) - REG(DrawBoundingBox) - REG(DrawBillboard) - REG(DrawBillboardRec) - REG(CheckCollisionSpheres) - REG(CheckCollisionBoxes) - REG(CheckCollisionBoxSphere) - REG(CheckCollisionRaySphere) - REG(CheckCollisionRaySphereEx) - REG(CheckCollisionRayBox) - REG(GetCollisionRayModel) - REG(GetCollisionRayTriangle) - REG(GetCollisionRayGround) - REG(LoadText) - REG(LoadShader) - REG(LoadShaderCode) - REG(UnloadShader) - REG(GetShaderDefault) - REG(GetTextureDefault) - REG(GetShaderLocation) - REG(SetShaderValue) - REG(SetShaderValuei) - REG(SetShaderValueMatrix) - REG(SetMatrixProjection) - REG(SetMatrixModelview) - REG(GetMatrixModelview) - REG(GenTextureCubemap) - REG(GenTextureIrradiance) - REG(GenTexturePrefilter) - REG(GenTextureBRDF) - REG(BeginShaderMode) - REG(EndShaderMode) - REG(BeginBlendMode) - REG(EndBlendMode) - REG(GetVrDeviceInfo) - REG(InitVrSimulator) - REG(CloseVrSimulator) - REG(IsVrSimulatorReady) - REG(SetVrDistortionShader) - REG(UpdateVrTracking) - REG(ToggleVrMode) - REG(BeginVrDrawing) - REG(EndVrDrawing) - REG(InitAudioDevice) - REG(CloseAudioDevice) - REG(IsAudioDeviceReady) - REG(SetMasterVolume) - REG(LoadWave) - REG(LoadWaveEx) - REG(LoadSound) - REG(LoadSoundFromWave) - REG(UpdateSound) - REG(UnloadWave) - REG(UnloadSound) - REG(PlaySound) - REG(PauseSound) - REG(ResumeSound) - REG(StopSound) - REG(IsSoundPlaying) - REG(SetSoundVolume) - REG(SetSoundPitch) - REG(WaveFormat) - REG(WaveCopy) - REG(WaveCrop) - REG(GetWaveData) - REG(LoadMusicStream) - REG(UnloadMusicStream) - REG(PlayMusicStream) - REG(UpdateMusicStream) - REG(StopMusicStream) - REG(PauseMusicStream) - REG(ResumeMusicStream) - REG(IsMusicPlaying) - REG(SetMusicVolume) - REG(SetMusicPitch) - REG(SetMusicLoopCount) - REG(GetMusicTimeLength) - REG(GetMusicTimePlayed) - REG(InitAudioStream) - REG(UpdateAudioStream) - REG(CloseAudioStream) - REG(IsAudioBufferProcessed) - REG(PlayAudioStream) - REG(PauseAudioStream) - REG(ResumeAudioStream) - REG(IsAudioStreamPlaying) - REG(StopAudioStream) - REG(SetAudioStreamVolume) - REG(SetAudioStreamPitch) - - - // [raymath] module functions - general - REG(Clamp) - - // [raymath] module functions - Vector2 - REG(Vector2Zero) - REG(Vector2One) - REG(Vector2Add) - REG(Vector2Subtract) - REG(Vector2Lenght) - REG(Vector2DotProduct) - REG(Vector2Distance) - REG(Vector2Angle) - REG(Vector2Scale) - REG(Vector2Negate) - REG(Vector2Divide) - REG(Vector2Normalize) - - // [raymath] module functions - Vector3 - REG(VectorZero) - REG(VectorOne) - REG(VectorAdd) - REG(VectorSubtract) - REG(VectorCrossProduct) - REG(VectorPerpendicular) - REG(VectorLength) - REG(VectorDotProduct) - REG(VectorDistance) - REG(VectorScale) - REG(VectorNegate) - REG(VectorNormalize) - REG(VectorTransform) - REG(VectorLerp) - REG(VectorReflect) - - // [raymath] module functions - Matrix - REG(MatrixDeterminant) - REG(MatrixTrace) - REG(MatrixTranspose) - REG(MatrixInvert) - REG(MatrixNormalize) - REG(MatrixIdentity) - REG(MatrixAdd) - REG(MatrixSubstract) - REG(MatrixTranslate) - REG(MatrixRotate) - REG(MatrixRotateX) - REG(MatrixRotateY) - REG(MatrixRotateZ) - REG(MatrixScale) - REG(MatrixMultiply) - REG(MatrixFrustum) - REG(MatrixPerspective) - REG(MatrixOrtho) - REG(MatrixLookAt) - - // [raymath] module functions - Quaternion - REG(QuaternionLength) - REG(QuaternionNormalize) - REG(QuaternionMultiply) - REG(QuaternionSlerp) - REG(QuaternionFromMatrix) - REG(QuaternionToMatrix) - REG(QuaternionFromAxisAngle) - REG(QuaternionToAxisAngle) - REG(QuaternionFromEuler) - REG(QuaternionToEuler) - REG(QuaternionTransform) - - // [physac] module functions - REG(InitPhysics) - REG(IsPhysicsEnabled) - REG(SetPhysicsGravity) - REG(CreatePhysicsBodyCircle) - REG(CreatePhysicsBodyRectangle) - REG(CreatePhysicsBodyPolygon) - REG(PhysicsAddForce) - REG(PhysicsAddTorque) - REG(PhysicsShatter) - REG(GetPhysicsBodiesCount) - REG(GetPhysicsBody) - REG(GetPhysicsShapeType) - REG(GetPhysicsShapeVerticesCount) - REG(GetPhysicsShapeVertex) - REG(SetPhysicsBodyRotation) - REG(DestroyPhysicsBody) - REG(ResetPhysics) - REG(ClosePhysics) - - { NULL, NULL } // sentinel: end signal -}; +// --- Registries --- -// Register raylib Lua functionality -static void rLuaRegisterFunctions(const char *opt_table) +static void rLuaRegisterMetatables(lua_State *L) { - if (opt_table) lua_createtable(L, 0, sizeof(raylib_functions)/sizeof(raylib_functions[0])); - else lua_pushglobaltable(L); + luaL_newmetatable(L, "AudioStream"); + lua_pushcfunction(L, rl_AudioStream_index); + lua_setfield(L, -2, "__index"); + lua_pushcfunction(L, rl_AudioStream_gc); + lua_setfield(L, -2, "__gc"); + lua_pop(L, 1); - luaL_setfuncs(L, raylib_functions, 0); -} + luaL_newmetatable(L, "Font"); + lua_pushcfunction(L, rl_Font_index); + lua_setfield(L, -2, "__index"); + lua_pushcfunction(L, rl_Font_gc); + lua_setfield(L, -2, "__gc"); + lua_pop(L, 1); -//---------------------------------------------------------------------------------- -// raylib Lua API -//---------------------------------------------------------------------------------- - -// Initialize Lua system -RLUADEF void rLuaInitDevice(void) -{ - mainLuaState = luaL_newstate(); - L = mainLuaState; - - LuaStartEnum(); - LuaSetEnum("SHOW_LOGO", 1); - LuaSetEnum("FULLSCREEN_MODE", 2); - LuaSetEnum("WINDOW_RESIZABLE", 4); - LuaSetEnum("WINDOW_DECORATED", 8); - LuaSetEnum("WINDOW_TRANSPARENT", 16); - LuaSetEnum("MSAA_4X_HINT", 32); - LuaSetEnum("VSYNC_HINT", 64); - LuaEndEnum("FLAG"); - - LuaStartEnum(); - LuaSetEnum("SPACE", 32); - LuaSetEnum("ESCAPE", 256); - LuaSetEnum("ENTER", 257); - LuaSetEnum("BACKSPACE", 259); - LuaSetEnum("RIGHT", 262); - LuaSetEnum("LEFT", 263); - LuaSetEnum("DOWN", 264); - LuaSetEnum("UP", 265); - LuaSetEnum("F1", 290); - LuaSetEnum("F2", 291); - LuaSetEnum("F3", 292); - LuaSetEnum("F4", 293); - LuaSetEnum("F5", 294); - LuaSetEnum("F6", 295); - LuaSetEnum("F7", 296); - LuaSetEnum("F8", 297); - LuaSetEnum("F9", 298); - LuaSetEnum("F10", 299); - LuaSetEnum("LEFT_SHIFT", 340); - LuaSetEnum("LEFT_CONTROL", 341); - LuaSetEnum("LEFT_ALT", 342); - LuaSetEnum("RIGHT_SHIFT", 344); - LuaSetEnum("RIGHT_CONTROL", 345); - LuaSetEnum("RIGHT_ALT", 346); - LuaSetEnum("ZERO", 48); - LuaSetEnum("ONE", 49); - LuaSetEnum("TWO", 50); - LuaSetEnum("THREE", 51); - LuaSetEnum("FOUR", 52); - LuaSetEnum("FIVE", 53); - LuaSetEnum("SIX", 54); - LuaSetEnum("SEVEN", 55); - LuaSetEnum("EIGHT", 56); - LuaSetEnum("NINE", 57); - LuaSetEnum("A", 65); - LuaSetEnum("B", 66); - LuaSetEnum("C", 67); - LuaSetEnum("D", 68); - LuaSetEnum("E", 69); - LuaSetEnum("F", 70); - LuaSetEnum("G", 71); - LuaSetEnum("H", 72); - LuaSetEnum("I", 73); - LuaSetEnum("J", 74); - LuaSetEnum("K", 75); - LuaSetEnum("L", 76); - LuaSetEnum("M", 77); - LuaSetEnum("N", 78); - LuaSetEnum("O", 79); - LuaSetEnum("P", 80); - LuaSetEnum("Q", 81); - LuaSetEnum("R", 82); - LuaSetEnum("S", 83); - LuaSetEnum("T", 84); - LuaSetEnum("U", 85); - LuaSetEnum("V", 86); - LuaSetEnum("W", 87); - LuaSetEnum("X", 88); - LuaSetEnum("Y", 89); - LuaSetEnum("Z", 90); - LuaEndEnum("KEY"); - - LuaStartEnum(); - LuaSetEnum("LEFT_BUTTON", 0); - LuaSetEnum("RIGHT_BUTTON", 1); - LuaSetEnum("MIDDLE_BUTTON", 2); - LuaEndEnum("MOUSE"); - - LuaStartEnum(); - LuaSetEnum("PLAYER1", 0); - LuaSetEnum("PLAYER2", 1); - LuaSetEnum("PLAYER3", 2); - LuaSetEnum("PLAYER4", 3); - - LuaSetEnum("PS3_BUTTON_TRIANGLE", 0); - LuaSetEnum("PS3_BUTTON_CIRCLE", 1); - LuaSetEnum("PS3_BUTTON_CROSS", 2); - LuaSetEnum("PS3_BUTTON_SQUARE", 3); - LuaSetEnum("PS3_BUTTON_L1", 6); - LuaSetEnum("PS3_BUTTON_R1", 7); - LuaSetEnum("PS3_BUTTON_L2", 4); - LuaSetEnum("PS3_BUTTON_R2", 5); - LuaSetEnum("PS3_BUTTON_START", 8); - LuaSetEnum("PS3_BUTTON_SELECT", 9); - LuaSetEnum("PS3_BUTTON_UP", 24); - LuaSetEnum("PS3_BUTTON_RIGHT", 25); - LuaSetEnum("PS3_BUTTON_DOWN", 26); - LuaSetEnum("PS3_BUTTON_LEFT", 27); - LuaSetEnum("PS3_BUTTON_PS", 12); - LuaSetEnum("PS3_AXIS_LEFT_X", 0); - LuaSetEnum("PS3_AXIS_LEFT_Y", 1); - LuaSetEnum("PS3_AXIS_RIGHT_X", 2); - LuaSetEnum("PS3_AXIS_RIGHT_Y", 5); - LuaSetEnum("PS3_AXIS_L2", 3); // [1..-1] (pressure-level) - LuaSetEnum("PS3_AXIS_R2", 4); // [1..-1] (pressure-level) - -// Xbox360 USB Controller Buttons - LuaSetEnum("XBOX_BUTTON_A", 0); - LuaSetEnum("XBOX_BUTTON_B", 1); - LuaSetEnum("XBOX_BUTTON_X", 2); - LuaSetEnum("XBOX_BUTTON_Y", 3); - LuaSetEnum("XBOX_BUTTON_LB", 4); - LuaSetEnum("XBOX_BUTTON_RB", 5); - LuaSetEnum("XBOX_BUTTON_SELECT", 6); - LuaSetEnum("XBOX_BUTTON_START", 7); - LuaSetEnum("XBOX_BUTTON_UP", 10); - LuaSetEnum("XBOX_BUTTON_RIGHT", 11); - LuaSetEnum("XBOX_BUTTON_DOWN", 12); - LuaSetEnum("XBOX_BUTTON_LEFT", 13); - LuaSetEnum("XBOX_BUTTON_HOME", 8); -#if defined(PLATFORM_RPI) - LuaSetEnum("XBOX_AXIS_LEFT_X", 0); // [-1..1] (left->right) - LuaSetEnum("XBOX_AXIS_LEFT_Y", 1); // [-1..1] (up->down) - LuaSetEnum("XBOX_AXIS_RIGHT_X", 3); // [-1..1] (left->right) - LuaSetEnum("XBOX_AXIS_RIGHT_Y", 4); // [-1..1] (up->down) - LuaSetEnum("XBOX_AXIS_LT", 2); // [-1..1] (pressure-level) - LuaSetEnum("XBOX_AXIS_RT", 5); // [-1..1] (pressure-level) -#else - LuaSetEnum("XBOX_AXIS_LEFT_X", 0); // [-1..1] (left->right) - LuaSetEnum("XBOX_AXIS_LEFT_Y", 1); // [1..-1] (up->down) - LuaSetEnum("XBOX_AXIS_RIGHT_X", 2); // [-1..1] (left->right) - LuaSetEnum("XBOX_AXIS_RIGHT_Y", 3); // [1..-1] (up->down) - LuaSetEnum("XBOX_AXIS_LT", 4); // [-1..1] (pressure-level) - LuaSetEnum("XBOX_AXIS_RT", 5); // [-1..1] (pressure-level) -#endif - LuaEndEnum("GAMEPAD"); + luaL_newmetatable(L, "Image"); + lua_pushcfunction(L, rl_Image_index); + lua_setfield(L, -2, "__index"); + lua_pushcfunction(L, rl_Image_gc); + lua_setfield(L, -2, "__gc"); + lua_pop(L, 1); - lua_pushglobaltable(L); - LuaSetEnumColor("LIGHTGRAY", LIGHTGRAY); - LuaSetEnumColor("GRAY", GRAY); - LuaSetEnumColor("DARKGRAY", DARKGRAY); - LuaSetEnumColor("YELLOW", YELLOW); - LuaSetEnumColor("GOLD", GOLD); - LuaSetEnumColor("ORANGE", ORANGE); - LuaSetEnumColor("PINK", PINK); - LuaSetEnumColor("RED", RED); - LuaSetEnumColor("MAROON", MAROON); - LuaSetEnumColor("GREEN", GREEN); - LuaSetEnumColor("LIME", LIME); - LuaSetEnumColor("DARKGREEN", DARKGREEN); - LuaSetEnumColor("SKYBLUE", SKYBLUE); - LuaSetEnumColor("BLUE", BLUE); - LuaSetEnumColor("DARKBLUE", DARKBLUE); - LuaSetEnumColor("PURPLE", PURPLE); - LuaSetEnumColor("VIOLET", VIOLET); - LuaSetEnumColor("DARKPURPLE", DARKPURPLE); - LuaSetEnumColor("BEIGE", BEIGE); - LuaSetEnumColor("BROWN", BROWN); - LuaSetEnumColor("DARKBROWN", DARKBROWN); - LuaSetEnumColor("WHITE", WHITE); - LuaSetEnumColor("BLACK", BLACK); - LuaSetEnumColor("BLANK", BLANK); - LuaSetEnumColor("MAGENTA", MAGENTA); - LuaSetEnumColor("RAYWHITE", RAYWHITE); + luaL_newmetatable(L, "Material"); + lua_pushcfunction(L, rl_Material_index); + lua_setfield(L, -2, "__index"); + lua_pushcfunction(L, rl_Material_gc); + lua_setfield(L, -2, "__gc"); lua_pop(L, 1); - LuaStartEnum(); - LuaSetEnum("UNCOMPRESSED_GRAYSCALE", UNCOMPRESSED_GRAYSCALE); - LuaSetEnum("UNCOMPRESSED_GRAY_ALPHA", UNCOMPRESSED_GRAY_ALPHA); - LuaSetEnum("UNCOMPRESSED_R5G6B5", UNCOMPRESSED_R5G6B5); - LuaSetEnum("UNCOMPRESSED_R8G8B8", UNCOMPRESSED_R8G8B8); - LuaSetEnum("UNCOMPRESSED_R5G5B5A1", UNCOMPRESSED_R5G5B5A1); - LuaSetEnum("UNCOMPRESSED_R4G4B4A4", UNCOMPRESSED_R4G4B4A4); - LuaSetEnum("UNCOMPRESSED_R8G8B8A8", UNCOMPRESSED_R8G8B8A8); - LuaSetEnum("COMPRESSED_DXT1_RGB", COMPRESSED_DXT1_RGB); - LuaSetEnum("COMPRESSED_DXT1_RGBA", COMPRESSED_DXT1_RGBA); - LuaSetEnum("COMPRESSED_DXT3_RGBA", COMPRESSED_DXT3_RGBA); - LuaSetEnum("COMPRESSED_DXT5_RGBA", COMPRESSED_DXT5_RGBA); - LuaSetEnum("COMPRESSED_ETC1_RGB", COMPRESSED_ETC1_RGB); - LuaSetEnum("COMPRESSED_ETC2_RGB", COMPRESSED_ETC2_RGB); - LuaSetEnum("COMPRESSED_ETC2_EAC_RGBA", COMPRESSED_ETC2_EAC_RGBA); - LuaSetEnum("COMPRESSED_PVRT_RGB", COMPRESSED_PVRT_RGB); - LuaSetEnum("COMPRESSED_PVRT_RGBA", COMPRESSED_PVRT_RGBA); - LuaSetEnum("COMPRESSED_ASTC_4x4_RGBA", COMPRESSED_ASTC_4x4_RGBA); - LuaSetEnum("COMPRESSED_ASTC_8x8_RGBA", COMPRESSED_ASTC_8x8_RGBA); - LuaEndEnum("TextureFormat"); - - LuaStartEnum(); - LuaSetEnum("ALPHA", BLEND_ALPHA); - LuaSetEnum("ADDITIVE", BLEND_ADDITIVE); - LuaSetEnum("MULTIPLIED", BLEND_MULTIPLIED); - LuaEndEnum("BlendMode"); - - LuaStartEnum(); - LuaSetEnum("POINT", FILTER_POINT); - LuaSetEnum("BILINEAR", FILTER_BILINEAR); - LuaSetEnum("TRILINEAR", FILTER_TRILINEAR); - LuaSetEnum("ANISOTROPIC_4X", FILTER_ANISOTROPIC_4X); - LuaSetEnum("ANISOTROPIC_8X", FILTER_ANISOTROPIC_8X); - LuaSetEnum("ANISOTROPIC_16X", FILTER_ANISOTROPIC_16X); - LuaEndEnum("TextureFilter"); - - LuaStartEnum(); - LuaSetEnum("NONE", GESTURE_NONE); - LuaSetEnum("TAP", GESTURE_TAP); - LuaSetEnum("DOUBLETAP", GESTURE_DOUBLETAP); - LuaSetEnum("HOLD", GESTURE_HOLD); - LuaSetEnum("DRAG", GESTURE_DRAG); - LuaSetEnum("SWIPE_RIGHT", GESTURE_SWIPE_RIGHT); - LuaSetEnum("SWIPE_LEFT", GESTURE_SWIPE_LEFT); - LuaSetEnum("SWIPE_UP", GESTURE_SWIPE_UP); - LuaSetEnum("SWIPE_DOWN", GESTURE_SWIPE_DOWN); - LuaSetEnum("PINCH_IN", GESTURE_PINCH_IN); - LuaSetEnum("PINCH_OUT", GESTURE_PINCH_OUT); - LuaEndEnum("Gestures"); - - LuaStartEnum(); - LuaSetEnum("CUSTOM", CAMERA_CUSTOM); - LuaSetEnum("FREE", CAMERA_FREE); - LuaSetEnum("ORBITAL", CAMERA_ORBITAL); - LuaSetEnum("FIRST_PERSON", CAMERA_FIRST_PERSON); - LuaSetEnum("THIRD_PERSON", CAMERA_THIRD_PERSON); - LuaEndEnum("CameraMode"); - - LuaStartEnum(); - LuaSetEnum("DEFAULT_DEVICE", HMD_DEFAULT_DEVICE); - LuaSetEnum("OCULUS_RIFT_DK2", HMD_OCULUS_RIFT_DK2); - LuaSetEnum("OCULUS_RIFT_CV1", HMD_OCULUS_RIFT_CV1); - LuaSetEnum("VALVE_HTC_VIVE", HMD_VALVE_HTC_VIVE); - LuaSetEnum("SAMSUNG_GEAR_VR", HMD_SAMSUNG_GEAR_VR); - LuaSetEnum("GOOGLE_CARDBOARD", HMD_GOOGLE_CARDBOARD); - LuaSetEnum("SONY_PLAYSTATION_VR", HMD_SONY_PLAYSTATION_VR); - LuaSetEnum("RAZER_OSVR", HMD_RAZER_OSVR); - LuaSetEnum("FOVE_VR", HMD_FOVE_VR); - LuaEndEnum("VrDevice"); + luaL_newmetatable(L, "Mesh"); + lua_pushcfunction(L, rl_Mesh_index); + lua_setfield(L, -2, "__index"); + lua_pushcfunction(L, rl_Mesh_gc); + lua_setfield(L, -2, "__gc"); + lua_pop(L, 1); - lua_pushglobaltable(L); - LuaSetEnum("INFO", INFO); - LuaSetEnum("ERROR", ERROR); - LuaSetEnum("WARNING", WARNING); - LuaSetEnum("DEBUG", DEBUG); - LuaSetEnum("OTHER", OTHER); + luaL_newmetatable(L, "Model"); + lua_pushcfunction(L, rl_Model_index); + lua_setfield(L, -2, "__index"); + lua_pushcfunction(L, rl_Model_gc); + lua_setfield(L, -2, "__gc"); lua_pop(L, 1); - LuaPush_bool(L, true); -#if defined(PLATFORM_DESKTOP) - lua_setglobal(L, "PLATFORM_DESKTOP"); -#elif defined(PLATFORM_ANDROID) - lua_setglobal(L, "PLATFORM_ANDROID"); -#elif defined(PLATFORM_RPI) - lua_setglobal(L, "PLATFORM_RPI"); -#elif defined(PLATFORM_WEB) - lua_setglobal(L, "PLATFORM_WEB"); -#endif + luaL_newmetatable(L, "ModelAnimation"); + lua_pushcfunction(L, rl_ModelAnimation_index); + lua_setfield(L, -2, "__index"); + lua_pop(L, 1); - luaL_openlibs(L); - LuaBuildOpaqueMetatables(); + luaL_newmetatable(L, "Music"); + lua_pushcfunction(L, rl_Music_index); + lua_setfield(L, -2, "__index"); + lua_pushcfunction(L, rl_Music_gc); + lua_setfield(L, -2, "__gc"); + lua_pop(L, 1); - rLuaRegisterFunctions(0); // Register Lua raylib functions -} + luaL_newmetatable(L, "RenderTexture"); + lua_pushcfunction(L, rl_RenderTexture_index); + lua_setfield(L, -2, "__index"); + lua_pushcfunction(L, rl_RenderTexture_gc); + lua_setfield(L, -2, "__gc"); + lua_pop(L, 1); -// De-initialize Lua system -RLUADEF void rLuaCloseDevice(void) -{ - if (mainLuaState) - { - lua_close(mainLuaState); - mainLuaState = 0; - L = 0; - } -} + luaL_newmetatable(L, "RenderTexture2D"); + lua_pushcfunction(L, rl_RenderTexture2D_gc); + lua_setfield(L, -2, "__gc"); + lua_pop(L, 1); -// Execute raylib Lua code -RLUADEF void rLuaExecuteCode(const char *code) -{ - if (!mainLuaState) - { - TraceLog(WARNING, "Lua device not initialized"); - return; - } + luaL_newmetatable(L, "Shader"); + lua_pushcfunction(L, rl_Shader_index); + lua_setfield(L, -2, "__index"); + lua_pushcfunction(L, rl_Shader_gc); + lua_setfield(L, -2, "__gc"); + lua_pop(L, 1); + + luaL_newmetatable(L, "Sound"); + lua_pushcfunction(L, rl_Sound_index); + lua_setfield(L, -2, "__index"); + lua_pushcfunction(L, rl_Sound_gc); + lua_setfield(L, -2, "__gc"); + lua_pop(L, 1); - int result = luaL_dostring(L, code); + luaL_newmetatable(L, "Texture"); + lua_pushcfunction(L, rl_Texture_index); + lua_setfield(L, -2, "__index"); + lua_pushcfunction(L, rl_Texture_gc); + lua_setfield(L, -2, "__gc"); + lua_pop(L, 1); + + luaL_newmetatable(L, "Texture2D"); + lua_pushcfunction(L, rl_Texture2D_gc); + lua_setfield(L, -2, "__gc"); + lua_pop(L, 1); + + luaL_newmetatable(L, "TextureCubemap"); + lua_pushcfunction(L, rl_TextureCubemap_gc); + lua_setfield(L, -2, "__gc"); + lua_pop(L, 1); + + luaL_newmetatable(L, "Wave"); + lua_pushcfunction(L, rl_Wave_index); + lua_setfield(L, -2, "__index"); + lua_pushcfunction(L, rl_Wave_gc); + lua_setfield(L, -2, "__gc"); + lua_pop(L, 1); - switch (result) - { - case LUA_OK: break; - case LUA_ERRRUN: TraceLog(ERROR, "Lua Runtime Error: %s", lua_tostring(L, -1)); break; - case LUA_ERRMEM: TraceLog(ERROR, "Lua Memory Error: %s", lua_tostring(L, -1)); break; - default: TraceLog(ERROR, "Lua Error: %s", lua_tostring(L, -1)); break; - } } +static void rLuaRegisterConstants(lua_State *L) +{ + lua_pushinteger(L, 64); + lua_setfield(L, -2, "FLAG_VSYNC_HINT"); + lua_pushinteger(L, 2); + lua_setfield(L, -2, "FLAG_FULLSCREEN_MODE"); + lua_pushinteger(L, 4); + lua_setfield(L, -2, "FLAG_WINDOW_RESIZABLE"); + lua_pushinteger(L, 8); + lua_setfield(L, -2, "FLAG_WINDOW_UNDECORATED"); + lua_pushinteger(L, 128); + lua_setfield(L, -2, "FLAG_WINDOW_HIDDEN"); + lua_pushinteger(L, 512); + lua_setfield(L, -2, "FLAG_WINDOW_MINIMIZED"); + lua_pushinteger(L, 1024); + lua_setfield(L, -2, "FLAG_WINDOW_MAXIMIZED"); + lua_pushinteger(L, 2048); + lua_setfield(L, -2, "FLAG_WINDOW_UNFOCUSED"); + lua_pushinteger(L, 4096); + lua_setfield(L, -2, "FLAG_WINDOW_TOPMOST"); + lua_pushinteger(L, 256); + lua_setfield(L, -2, "FLAG_WINDOW_ALWAYS_RUN"); + lua_pushinteger(L, 16); + lua_setfield(L, -2, "FLAG_WINDOW_TRANSPARENT"); + lua_pushinteger(L, 8192); + lua_setfield(L, -2, "FLAG_WINDOW_HIGHDPI"); + lua_pushinteger(L, 16384); + lua_setfield(L, -2, "FLAG_WINDOW_MOUSE_PASSTHROUGH"); + lua_pushinteger(L, 32768); + lua_setfield(L, -2, "FLAG_BORDERLESS_WINDOWED_MODE"); + lua_pushinteger(L, 32); + lua_setfield(L, -2, "FLAG_MSAA_4X_HINT"); + lua_pushinteger(L, 65536); + lua_setfield(L, -2, "FLAG_INTERLACED_HINT"); + lua_pushinteger(L, 0); + lua_setfield(L, -2, "LOG_ALL"); + lua_pushinteger(L, 1); + lua_setfield(L, -2, "LOG_TRACE"); + lua_pushinteger(L, 2); + lua_setfield(L, -2, "LOG_DEBUG"); + lua_pushinteger(L, 3); + lua_setfield(L, -2, "LOG_INFO"); + lua_pushinteger(L, 4); + lua_setfield(L, -2, "LOG_WARNING"); + lua_pushinteger(L, 5); + lua_setfield(L, -2, "LOG_ERROR"); + lua_pushinteger(L, 6); + lua_setfield(L, -2, "LOG_FATAL"); + lua_pushinteger(L, 7); + lua_setfield(L, -2, "LOG_NONE"); + lua_pushinteger(L, 0); + lua_setfield(L, -2, "KEY_NULL"); + lua_pushinteger(L, 39); + lua_setfield(L, -2, "KEY_APOSTROPHE"); + lua_pushinteger(L, 44); + lua_setfield(L, -2, "KEY_COMMA"); + lua_pushinteger(L, 45); + lua_setfield(L, -2, "KEY_MINUS"); + lua_pushinteger(L, 46); + lua_setfield(L, -2, "KEY_PERIOD"); + lua_pushinteger(L, 47); + lua_setfield(L, -2, "KEY_SLASH"); + lua_pushinteger(L, 48); + lua_setfield(L, -2, "KEY_ZERO"); + lua_pushinteger(L, 49); + lua_setfield(L, -2, "KEY_ONE"); + lua_pushinteger(L, 50); + lua_setfield(L, -2, "KEY_TWO"); + lua_pushinteger(L, 51); + lua_setfield(L, -2, "KEY_THREE"); + lua_pushinteger(L, 52); + lua_setfield(L, -2, "KEY_FOUR"); + lua_pushinteger(L, 53); + lua_setfield(L, -2, "KEY_FIVE"); + lua_pushinteger(L, 54); + lua_setfield(L, -2, "KEY_SIX"); + lua_pushinteger(L, 55); + lua_setfield(L, -2, "KEY_SEVEN"); + lua_pushinteger(L, 56); + lua_setfield(L, -2, "KEY_EIGHT"); + lua_pushinteger(L, 57); + lua_setfield(L, -2, "KEY_NINE"); + lua_pushinteger(L, 59); + lua_setfield(L, -2, "KEY_SEMICOLON"); + lua_pushinteger(L, 61); + lua_setfield(L, -2, "KEY_EQUAL"); + lua_pushinteger(L, 65); + lua_setfield(L, -2, "KEY_A"); + lua_pushinteger(L, 66); + lua_setfield(L, -2, "KEY_B"); + lua_pushinteger(L, 67); + lua_setfield(L, -2, "KEY_C"); + lua_pushinteger(L, 68); + lua_setfield(L, -2, "KEY_D"); + lua_pushinteger(L, 69); + lua_setfield(L, -2, "KEY_E"); + lua_pushinteger(L, 70); + lua_setfield(L, -2, "KEY_F"); + lua_pushinteger(L, 71); + lua_setfield(L, -2, "KEY_G"); + lua_pushinteger(L, 72); + lua_setfield(L, -2, "KEY_H"); + lua_pushinteger(L, 73); + lua_setfield(L, -2, "KEY_I"); + lua_pushinteger(L, 74); + lua_setfield(L, -2, "KEY_J"); + lua_pushinteger(L, 75); + lua_setfield(L, -2, "KEY_K"); + lua_pushinteger(L, 76); + lua_setfield(L, -2, "KEY_L"); + lua_pushinteger(L, 77); + lua_setfield(L, -2, "KEY_M"); + lua_pushinteger(L, 78); + lua_setfield(L, -2, "KEY_N"); + lua_pushinteger(L, 79); + lua_setfield(L, -2, "KEY_O"); + lua_pushinteger(L, 80); + lua_setfield(L, -2, "KEY_P"); + lua_pushinteger(L, 81); + lua_setfield(L, -2, "KEY_Q"); + lua_pushinteger(L, 82); + lua_setfield(L, -2, "KEY_R"); + lua_pushinteger(L, 83); + lua_setfield(L, -2, "KEY_S"); + lua_pushinteger(L, 84); + lua_setfield(L, -2, "KEY_T"); + lua_pushinteger(L, 85); + lua_setfield(L, -2, "KEY_U"); + lua_pushinteger(L, 86); + lua_setfield(L, -2, "KEY_V"); + lua_pushinteger(L, 87); + lua_setfield(L, -2, "KEY_W"); + lua_pushinteger(L, 88); + lua_setfield(L, -2, "KEY_X"); + lua_pushinteger(L, 89); + lua_setfield(L, -2, "KEY_Y"); + lua_pushinteger(L, 90); + lua_setfield(L, -2, "KEY_Z"); + lua_pushinteger(L, 91); + lua_setfield(L, -2, "KEY_LEFT_BRACKET"); + lua_pushinteger(L, 92); + lua_setfield(L, -2, "KEY_BACKSLASH"); + lua_pushinteger(L, 93); + lua_setfield(L, -2, "KEY_RIGHT_BRACKET"); + lua_pushinteger(L, 96); + lua_setfield(L, -2, "KEY_GRAVE"); + lua_pushinteger(L, 32); + lua_setfield(L, -2, "KEY_SPACE"); + lua_pushinteger(L, 256); + lua_setfield(L, -2, "KEY_ESCAPE"); + lua_pushinteger(L, 257); + lua_setfield(L, -2, "KEY_ENTER"); + lua_pushinteger(L, 258); + lua_setfield(L, -2, "KEY_TAB"); + lua_pushinteger(L, 259); + lua_setfield(L, -2, "KEY_BACKSPACE"); + lua_pushinteger(L, 260); + lua_setfield(L, -2, "KEY_INSERT"); + lua_pushinteger(L, 261); + lua_setfield(L, -2, "KEY_DELETE"); + lua_pushinteger(L, 262); + lua_setfield(L, -2, "KEY_RIGHT"); + lua_pushinteger(L, 263); + lua_setfield(L, -2, "KEY_LEFT"); + lua_pushinteger(L, 264); + lua_setfield(L, -2, "KEY_DOWN"); + lua_pushinteger(L, 265); + lua_setfield(L, -2, "KEY_UP"); + lua_pushinteger(L, 266); + lua_setfield(L, -2, "KEY_PAGE_UP"); + lua_pushinteger(L, 267); + lua_setfield(L, -2, "KEY_PAGE_DOWN"); + lua_pushinteger(L, 268); + lua_setfield(L, -2, "KEY_HOME"); + lua_pushinteger(L, 269); + lua_setfield(L, -2, "KEY_END"); + lua_pushinteger(L, 280); + lua_setfield(L, -2, "KEY_CAPS_LOCK"); + lua_pushinteger(L, 281); + lua_setfield(L, -2, "KEY_SCROLL_LOCK"); + lua_pushinteger(L, 282); + lua_setfield(L, -2, "KEY_NUM_LOCK"); + lua_pushinteger(L, 283); + lua_setfield(L, -2, "KEY_PRINT_SCREEN"); + lua_pushinteger(L, 284); + lua_setfield(L, -2, "KEY_PAUSE"); + lua_pushinteger(L, 290); + lua_setfield(L, -2, "KEY_F1"); + lua_pushinteger(L, 291); + lua_setfield(L, -2, "KEY_F2"); + lua_pushinteger(L, 292); + lua_setfield(L, -2, "KEY_F3"); + lua_pushinteger(L, 293); + lua_setfield(L, -2, "KEY_F4"); + lua_pushinteger(L, 294); + lua_setfield(L, -2, "KEY_F5"); + lua_pushinteger(L, 295); + lua_setfield(L, -2, "KEY_F6"); + lua_pushinteger(L, 296); + lua_setfield(L, -2, "KEY_F7"); + lua_pushinteger(L, 297); + lua_setfield(L, -2, "KEY_F8"); + lua_pushinteger(L, 298); + lua_setfield(L, -2, "KEY_F9"); + lua_pushinteger(L, 299); + lua_setfield(L, -2, "KEY_F10"); + lua_pushinteger(L, 300); + lua_setfield(L, -2, "KEY_F11"); + lua_pushinteger(L, 301); + lua_setfield(L, -2, "KEY_F12"); + lua_pushinteger(L, 340); + lua_setfield(L, -2, "KEY_LEFT_SHIFT"); + lua_pushinteger(L, 341); + lua_setfield(L, -2, "KEY_LEFT_CONTROL"); + lua_pushinteger(L, 342); + lua_setfield(L, -2, "KEY_LEFT_ALT"); + lua_pushinteger(L, 343); + lua_setfield(L, -2, "KEY_LEFT_SUPER"); + lua_pushinteger(L, 344); + lua_setfield(L, -2, "KEY_RIGHT_SHIFT"); + lua_pushinteger(L, 345); + lua_setfield(L, -2, "KEY_RIGHT_CONTROL"); + lua_pushinteger(L, 346); + lua_setfield(L, -2, "KEY_RIGHT_ALT"); + lua_pushinteger(L, 347); + lua_setfield(L, -2, "KEY_RIGHT_SUPER"); + lua_pushinteger(L, 348); + lua_setfield(L, -2, "KEY_KB_MENU"); + lua_pushinteger(L, 320); + lua_setfield(L, -2, "KEY_KP_0"); + lua_pushinteger(L, 321); + lua_setfield(L, -2, "KEY_KP_1"); + lua_pushinteger(L, 322); + lua_setfield(L, -2, "KEY_KP_2"); + lua_pushinteger(L, 323); + lua_setfield(L, -2, "KEY_KP_3"); + lua_pushinteger(L, 324); + lua_setfield(L, -2, "KEY_KP_4"); + lua_pushinteger(L, 325); + lua_setfield(L, -2, "KEY_KP_5"); + lua_pushinteger(L, 326); + lua_setfield(L, -2, "KEY_KP_6"); + lua_pushinteger(L, 327); + lua_setfield(L, -2, "KEY_KP_7"); + lua_pushinteger(L, 328); + lua_setfield(L, -2, "KEY_KP_8"); + lua_pushinteger(L, 329); + lua_setfield(L, -2, "KEY_KP_9"); + lua_pushinteger(L, 330); + lua_setfield(L, -2, "KEY_KP_DECIMAL"); + lua_pushinteger(L, 331); + lua_setfield(L, -2, "KEY_KP_DIVIDE"); + lua_pushinteger(L, 332); + lua_setfield(L, -2, "KEY_KP_MULTIPLY"); + lua_pushinteger(L, 333); + lua_setfield(L, -2, "KEY_KP_SUBTRACT"); + lua_pushinteger(L, 334); + lua_setfield(L, -2, "KEY_KP_ADD"); + lua_pushinteger(L, 335); + lua_setfield(L, -2, "KEY_KP_ENTER"); + lua_pushinteger(L, 336); + lua_setfield(L, -2, "KEY_KP_EQUAL"); + lua_pushinteger(L, 4); + lua_setfield(L, -2, "KEY_BACK"); + lua_pushinteger(L, 5); + lua_setfield(L, -2, "KEY_MENU"); + lua_pushinteger(L, 24); + lua_setfield(L, -2, "KEY_VOLUME_UP"); + lua_pushinteger(L, 25); + lua_setfield(L, -2, "KEY_VOLUME_DOWN"); + lua_pushinteger(L, 0); + lua_setfield(L, -2, "MOUSE_BUTTON_LEFT"); + lua_pushinteger(L, 1); + lua_setfield(L, -2, "MOUSE_BUTTON_RIGHT"); + lua_pushinteger(L, 2); + lua_setfield(L, -2, "MOUSE_BUTTON_MIDDLE"); + lua_pushinteger(L, 3); + lua_setfield(L, -2, "MOUSE_BUTTON_SIDE"); + lua_pushinteger(L, 4); + lua_setfield(L, -2, "MOUSE_BUTTON_EXTRA"); + lua_pushinteger(L, 5); + lua_setfield(L, -2, "MOUSE_BUTTON_FORWARD"); + lua_pushinteger(L, 6); + lua_setfield(L, -2, "MOUSE_BUTTON_BACK"); + lua_pushinteger(L, 0); + lua_setfield(L, -2, "MOUSE_CURSOR_DEFAULT"); + lua_pushinteger(L, 1); + lua_setfield(L, -2, "MOUSE_CURSOR_ARROW"); + lua_pushinteger(L, 2); + lua_setfield(L, -2, "MOUSE_CURSOR_IBEAM"); + lua_pushinteger(L, 3); + lua_setfield(L, -2, "MOUSE_CURSOR_CROSSHAIR"); + lua_pushinteger(L, 4); + lua_setfield(L, -2, "MOUSE_CURSOR_POINTING_HAND"); + lua_pushinteger(L, 5); + lua_setfield(L, -2, "MOUSE_CURSOR_RESIZE_EW"); + lua_pushinteger(L, 6); + lua_setfield(L, -2, "MOUSE_CURSOR_RESIZE_NS"); + lua_pushinteger(L, 7); + lua_setfield(L, -2, "MOUSE_CURSOR_RESIZE_NWSE"); + lua_pushinteger(L, 8); + lua_setfield(L, -2, "MOUSE_CURSOR_RESIZE_NESW"); + lua_pushinteger(L, 9); + lua_setfield(L, -2, "MOUSE_CURSOR_RESIZE_ALL"); + lua_pushinteger(L, 10); + lua_setfield(L, -2, "MOUSE_CURSOR_NOT_ALLOWED"); + lua_pushinteger(L, 0); + lua_setfield(L, -2, "GAMEPAD_BUTTON_UNKNOWN"); + lua_pushinteger(L, 1); + lua_setfield(L, -2, "GAMEPAD_BUTTON_LEFT_FACE_UP"); + lua_pushinteger(L, 2); + lua_setfield(L, -2, "GAMEPAD_BUTTON_LEFT_FACE_RIGHT"); + lua_pushinteger(L, 3); + lua_setfield(L, -2, "GAMEPAD_BUTTON_LEFT_FACE_DOWN"); + lua_pushinteger(L, 4); + lua_setfield(L, -2, "GAMEPAD_BUTTON_LEFT_FACE_LEFT"); + lua_pushinteger(L, 5); + lua_setfield(L, -2, "GAMEPAD_BUTTON_RIGHT_FACE_UP"); + lua_pushinteger(L, 6); + lua_setfield(L, -2, "GAMEPAD_BUTTON_RIGHT_FACE_RIGHT"); + lua_pushinteger(L, 7); + lua_setfield(L, -2, "GAMEPAD_BUTTON_RIGHT_FACE_DOWN"); + lua_pushinteger(L, 8); + lua_setfield(L, -2, "GAMEPAD_BUTTON_RIGHT_FACE_LEFT"); + lua_pushinteger(L, 9); + lua_setfield(L, -2, "GAMEPAD_BUTTON_LEFT_TRIGGER_1"); + lua_pushinteger(L, 10); + lua_setfield(L, -2, "GAMEPAD_BUTTON_LEFT_TRIGGER_2"); + lua_pushinteger(L, 11); + lua_setfield(L, -2, "GAMEPAD_BUTTON_RIGHT_TRIGGER_1"); + lua_pushinteger(L, 12); + lua_setfield(L, -2, "GAMEPAD_BUTTON_RIGHT_TRIGGER_2"); + lua_pushinteger(L, 13); + lua_setfield(L, -2, "GAMEPAD_BUTTON_MIDDLE_LEFT"); + lua_pushinteger(L, 14); + lua_setfield(L, -2, "GAMEPAD_BUTTON_MIDDLE"); + lua_pushinteger(L, 15); + lua_setfield(L, -2, "GAMEPAD_BUTTON_MIDDLE_RIGHT"); + lua_pushinteger(L, 16); + lua_setfield(L, -2, "GAMEPAD_BUTTON_LEFT_THUMB"); + lua_pushinteger(L, 17); + lua_setfield(L, -2, "GAMEPAD_BUTTON_RIGHT_THUMB"); + lua_pushinteger(L, 0); + lua_setfield(L, -2, "GAMEPAD_AXIS_LEFT_X"); + lua_pushinteger(L, 1); + lua_setfield(L, -2, "GAMEPAD_AXIS_LEFT_Y"); + lua_pushinteger(L, 2); + lua_setfield(L, -2, "GAMEPAD_AXIS_RIGHT_X"); + lua_pushinteger(L, 3); + lua_setfield(L, -2, "GAMEPAD_AXIS_RIGHT_Y"); + lua_pushinteger(L, 4); + lua_setfield(L, -2, "GAMEPAD_AXIS_LEFT_TRIGGER"); + lua_pushinteger(L, 5); + lua_setfield(L, -2, "GAMEPAD_AXIS_RIGHT_TRIGGER"); + lua_pushinteger(L, 0); + lua_setfield(L, -2, "MATERIAL_MAP_ALBEDO"); + lua_pushinteger(L, 1); + lua_setfield(L, -2, "MATERIAL_MAP_METALNESS"); + lua_pushinteger(L, 2); + lua_setfield(L, -2, "MATERIAL_MAP_NORMAL"); + lua_pushinteger(L, 3); + lua_setfield(L, -2, "MATERIAL_MAP_ROUGHNESS"); + lua_pushinteger(L, 4); + lua_setfield(L, -2, "MATERIAL_MAP_OCCLUSION"); + lua_pushinteger(L, 5); + lua_setfield(L, -2, "MATERIAL_MAP_EMISSION"); + lua_pushinteger(L, 6); + lua_setfield(L, -2, "MATERIAL_MAP_HEIGHT"); + lua_pushinteger(L, 7); + lua_setfield(L, -2, "MATERIAL_MAP_CUBEMAP"); + lua_pushinteger(L, 8); + lua_setfield(L, -2, "MATERIAL_MAP_IRRADIANCE"); + lua_pushinteger(L, 9); + lua_setfield(L, -2, "MATERIAL_MAP_PREFILTER"); + lua_pushinteger(L, 10); + lua_setfield(L, -2, "MATERIAL_MAP_BRDF"); + lua_pushinteger(L, 0); + lua_setfield(L, -2, "SHADER_LOC_VERTEX_POSITION"); + lua_pushinteger(L, 1); + lua_setfield(L, -2, "SHADER_LOC_VERTEX_TEXCOORD01"); + lua_pushinteger(L, 2); + lua_setfield(L, -2, "SHADER_LOC_VERTEX_TEXCOORD02"); + lua_pushinteger(L, 3); + lua_setfield(L, -2, "SHADER_LOC_VERTEX_NORMAL"); + lua_pushinteger(L, 4); + lua_setfield(L, -2, "SHADER_LOC_VERTEX_TANGENT"); + lua_pushinteger(L, 5); + lua_setfield(L, -2, "SHADER_LOC_VERTEX_COLOR"); + lua_pushinteger(L, 6); + lua_setfield(L, -2, "SHADER_LOC_MATRIX_MVP"); + lua_pushinteger(L, 7); + lua_setfield(L, -2, "SHADER_LOC_MATRIX_VIEW"); + lua_pushinteger(L, 8); + lua_setfield(L, -2, "SHADER_LOC_MATRIX_PROJECTION"); + lua_pushinteger(L, 9); + lua_setfield(L, -2, "SHADER_LOC_MATRIX_MODEL"); + lua_pushinteger(L, 10); + lua_setfield(L, -2, "SHADER_LOC_MATRIX_NORMAL"); + lua_pushinteger(L, 11); + lua_setfield(L, -2, "SHADER_LOC_VECTOR_VIEW"); + lua_pushinteger(L, 12); + lua_setfield(L, -2, "SHADER_LOC_COLOR_DIFFUSE"); + lua_pushinteger(L, 13); + lua_setfield(L, -2, "SHADER_LOC_COLOR_SPECULAR"); + lua_pushinteger(L, 14); + lua_setfield(L, -2, "SHADER_LOC_COLOR_AMBIENT"); + lua_pushinteger(L, 15); + lua_setfield(L, -2, "SHADER_LOC_MAP_ALBEDO"); + lua_pushinteger(L, 16); + lua_setfield(L, -2, "SHADER_LOC_MAP_METALNESS"); + lua_pushinteger(L, 17); + lua_setfield(L, -2, "SHADER_LOC_MAP_NORMAL"); + lua_pushinteger(L, 18); + lua_setfield(L, -2, "SHADER_LOC_MAP_ROUGHNESS"); + lua_pushinteger(L, 19); + lua_setfield(L, -2, "SHADER_LOC_MAP_OCCLUSION"); + lua_pushinteger(L, 20); + lua_setfield(L, -2, "SHADER_LOC_MAP_EMISSION"); + lua_pushinteger(L, 21); + lua_setfield(L, -2, "SHADER_LOC_MAP_HEIGHT"); + lua_pushinteger(L, 22); + lua_setfield(L, -2, "SHADER_LOC_MAP_CUBEMAP"); + lua_pushinteger(L, 23); + lua_setfield(L, -2, "SHADER_LOC_MAP_IRRADIANCE"); + lua_pushinteger(L, 24); + lua_setfield(L, -2, "SHADER_LOC_MAP_PREFILTER"); + lua_pushinteger(L, 25); + lua_setfield(L, -2, "SHADER_LOC_MAP_BRDF"); + lua_pushinteger(L, 26); + lua_setfield(L, -2, "SHADER_LOC_VERTEX_BONEIDS"); + lua_pushinteger(L, 27); + lua_setfield(L, -2, "SHADER_LOC_VERTEX_BONEWEIGHTS"); + lua_pushinteger(L, 28); + lua_setfield(L, -2, "SHADER_LOC_MATRIX_BONETRANSFORMS"); + lua_pushinteger(L, 29); + lua_setfield(L, -2, "SHADER_LOC_VERTEX_INSTANCETRANSFORM"); + lua_pushinteger(L, 0); + lua_setfield(L, -2, "SHADER_UNIFORM_FLOAT"); + lua_pushinteger(L, 1); + lua_setfield(L, -2, "SHADER_UNIFORM_VEC2"); + lua_pushinteger(L, 2); + lua_setfield(L, -2, "SHADER_UNIFORM_VEC3"); + lua_pushinteger(L, 3); + lua_setfield(L, -2, "SHADER_UNIFORM_VEC4"); + lua_pushinteger(L, 4); + lua_setfield(L, -2, "SHADER_UNIFORM_INT"); + lua_pushinteger(L, 5); + lua_setfield(L, -2, "SHADER_UNIFORM_IVEC2"); + lua_pushinteger(L, 6); + lua_setfield(L, -2, "SHADER_UNIFORM_IVEC3"); + lua_pushinteger(L, 7); + lua_setfield(L, -2, "SHADER_UNIFORM_IVEC4"); + lua_pushinteger(L, 8); + lua_setfield(L, -2, "SHADER_UNIFORM_UINT"); + lua_pushinteger(L, 9); + lua_setfield(L, -2, "SHADER_UNIFORM_UIVEC2"); + lua_pushinteger(L, 10); + lua_setfield(L, -2, "SHADER_UNIFORM_UIVEC3"); + lua_pushinteger(L, 11); + lua_setfield(L, -2, "SHADER_UNIFORM_UIVEC4"); + lua_pushinteger(L, 12); + lua_setfield(L, -2, "SHADER_UNIFORM_SAMPLER2D"); + lua_pushinteger(L, 0); + lua_setfield(L, -2, "SHADER_ATTRIB_FLOAT"); + lua_pushinteger(L, 1); + lua_setfield(L, -2, "SHADER_ATTRIB_VEC2"); + lua_pushinteger(L, 2); + lua_setfield(L, -2, "SHADER_ATTRIB_VEC3"); + lua_pushinteger(L, 3); + lua_setfield(L, -2, "SHADER_ATTRIB_VEC4"); + lua_pushinteger(L, 1); + lua_setfield(L, -2, "PIXELFORMAT_UNCOMPRESSED_GRAYSCALE"); + lua_pushinteger(L, 2); + lua_setfield(L, -2, "PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA"); + lua_pushinteger(L, 3); + lua_setfield(L, -2, "PIXELFORMAT_UNCOMPRESSED_R5G6B5"); + lua_pushinteger(L, 4); + lua_setfield(L, -2, "PIXELFORMAT_UNCOMPRESSED_R8G8B8"); + lua_pushinteger(L, 5); + lua_setfield(L, -2, "PIXELFORMAT_UNCOMPRESSED_R5G5B5A1"); + lua_pushinteger(L, 6); + lua_setfield(L, -2, "PIXELFORMAT_UNCOMPRESSED_R4G4B4A4"); + lua_pushinteger(L, 7); + lua_setfield(L, -2, "PIXELFORMAT_UNCOMPRESSED_R8G8B8A8"); + lua_pushinteger(L, 8); + lua_setfield(L, -2, "PIXELFORMAT_UNCOMPRESSED_R32"); + lua_pushinteger(L, 9); + lua_setfield(L, -2, "PIXELFORMAT_UNCOMPRESSED_R32G32B32"); + lua_pushinteger(L, 10); + lua_setfield(L, -2, "PIXELFORMAT_UNCOMPRESSED_R32G32B32A32"); + lua_pushinteger(L, 11); + lua_setfield(L, -2, "PIXELFORMAT_UNCOMPRESSED_R16"); + lua_pushinteger(L, 12); + lua_setfield(L, -2, "PIXELFORMAT_UNCOMPRESSED_R16G16B16"); + lua_pushinteger(L, 13); + lua_setfield(L, -2, "PIXELFORMAT_UNCOMPRESSED_R16G16B16A16"); + lua_pushinteger(L, 14); + lua_setfield(L, -2, "PIXELFORMAT_COMPRESSED_DXT1_RGB"); + lua_pushinteger(L, 15); + lua_setfield(L, -2, "PIXELFORMAT_COMPRESSED_DXT1_RGBA"); + lua_pushinteger(L, 16); + lua_setfield(L, -2, "PIXELFORMAT_COMPRESSED_DXT3_RGBA"); + lua_pushinteger(L, 17); + lua_setfield(L, -2, "PIXELFORMAT_COMPRESSED_DXT5_RGBA"); + lua_pushinteger(L, 18); + lua_setfield(L, -2, "PIXELFORMAT_COMPRESSED_ETC1_RGB"); + lua_pushinteger(L, 19); + lua_setfield(L, -2, "PIXELFORMAT_COMPRESSED_ETC2_RGB"); + lua_pushinteger(L, 20); + lua_setfield(L, -2, "PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA"); + lua_pushinteger(L, 21); + lua_setfield(L, -2, "PIXELFORMAT_COMPRESSED_PVRT_RGB"); + lua_pushinteger(L, 22); + lua_setfield(L, -2, "PIXELFORMAT_COMPRESSED_PVRT_RGBA"); + lua_pushinteger(L, 23); + lua_setfield(L, -2, "PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA"); + lua_pushinteger(L, 24); + lua_setfield(L, -2, "PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA"); + lua_pushinteger(L, 0); + lua_setfield(L, -2, "TEXTURE_FILTER_POINT"); + lua_pushinteger(L, 1); + lua_setfield(L, -2, "TEXTURE_FILTER_BILINEAR"); + lua_pushinteger(L, 2); + lua_setfield(L, -2, "TEXTURE_FILTER_TRILINEAR"); + lua_pushinteger(L, 3); + lua_setfield(L, -2, "TEXTURE_FILTER_ANISOTROPIC_4X"); + lua_pushinteger(L, 4); + lua_setfield(L, -2, "TEXTURE_FILTER_ANISOTROPIC_8X"); + lua_pushinteger(L, 5); + lua_setfield(L, -2, "TEXTURE_FILTER_ANISOTROPIC_16X"); + lua_pushinteger(L, 0); + lua_setfield(L, -2, "TEXTURE_WRAP_REPEAT"); + lua_pushinteger(L, 1); + lua_setfield(L, -2, "TEXTURE_WRAP_CLAMP"); + lua_pushinteger(L, 2); + lua_setfield(L, -2, "TEXTURE_WRAP_MIRROR_REPEAT"); + lua_pushinteger(L, 3); + lua_setfield(L, -2, "TEXTURE_WRAP_MIRROR_CLAMP"); + lua_pushinteger(L, 0); + lua_setfield(L, -2, "CUBEMAP_LAYOUT_AUTO_DETECT"); + lua_pushinteger(L, 1); + lua_setfield(L, -2, "CUBEMAP_LAYOUT_LINE_VERTICAL"); + lua_pushinteger(L, 2); + lua_setfield(L, -2, "CUBEMAP_LAYOUT_LINE_HORIZONTAL"); + lua_pushinteger(L, 3); + lua_setfield(L, -2, "CUBEMAP_LAYOUT_CROSS_THREE_BY_FOUR"); + lua_pushinteger(L, 4); + lua_setfield(L, -2, "CUBEMAP_LAYOUT_CROSS_FOUR_BY_THREE"); + lua_pushinteger(L, 0); + lua_setfield(L, -2, "FONT_DEFAULT"); + lua_pushinteger(L, 1); + lua_setfield(L, -2, "FONT_BITMAP"); + lua_pushinteger(L, 2); + lua_setfield(L, -2, "FONT_SDF"); + lua_pushinteger(L, 0); + lua_setfield(L, -2, "BLEND_ALPHA"); + lua_pushinteger(L, 1); + lua_setfield(L, -2, "BLEND_ADDITIVE"); + lua_pushinteger(L, 2); + lua_setfield(L, -2, "BLEND_MULTIPLIED"); + lua_pushinteger(L, 3); + lua_setfield(L, -2, "BLEND_ADD_COLORS"); + lua_pushinteger(L, 4); + lua_setfield(L, -2, "BLEND_SUBTRACT_COLORS"); + lua_pushinteger(L, 5); + lua_setfield(L, -2, "BLEND_ALPHA_PREMULTIPLY"); + lua_pushinteger(L, 6); + lua_setfield(L, -2, "BLEND_CUSTOM"); + lua_pushinteger(L, 7); + lua_setfield(L, -2, "BLEND_CUSTOM_SEPARATE"); + lua_pushinteger(L, 0); + lua_setfield(L, -2, "GESTURE_NONE"); + lua_pushinteger(L, 1); + lua_setfield(L, -2, "GESTURE_TAP"); + lua_pushinteger(L, 2); + lua_setfield(L, -2, "GESTURE_DOUBLETAP"); + lua_pushinteger(L, 4); + lua_setfield(L, -2, "GESTURE_HOLD"); + lua_pushinteger(L, 8); + lua_setfield(L, -2, "GESTURE_DRAG"); + lua_pushinteger(L, 16); + lua_setfield(L, -2, "GESTURE_SWIPE_RIGHT"); + lua_pushinteger(L, 32); + lua_setfield(L, -2, "GESTURE_SWIPE_LEFT"); + lua_pushinteger(L, 64); + lua_setfield(L, -2, "GESTURE_SWIPE_UP"); + lua_pushinteger(L, 128); + lua_setfield(L, -2, "GESTURE_SWIPE_DOWN"); + lua_pushinteger(L, 256); + lua_setfield(L, -2, "GESTURE_PINCH_IN"); + lua_pushinteger(L, 512); + lua_setfield(L, -2, "GESTURE_PINCH_OUT"); + lua_pushinteger(L, 0); + lua_setfield(L, -2, "CAMERA_CUSTOM"); + lua_pushinteger(L, 1); + lua_setfield(L, -2, "CAMERA_FREE"); + lua_pushinteger(L, 2); + lua_setfield(L, -2, "CAMERA_ORBITAL"); + lua_pushinteger(L, 3); + lua_setfield(L, -2, "CAMERA_FIRST_PERSON"); + lua_pushinteger(L, 4); + lua_setfield(L, -2, "CAMERA_THIRD_PERSON"); + lua_pushinteger(L, 0); + lua_setfield(L, -2, "CAMERA_PERSPECTIVE"); + lua_pushinteger(L, 1); + lua_setfield(L, -2, "CAMERA_ORTHOGRAPHIC"); + lua_pushinteger(L, 0); + lua_setfield(L, -2, "NPATCH_NINE_PATCH"); + lua_pushinteger(L, 1); + lua_setfield(L, -2, "NPATCH_THREE_PATCH_VERTICAL"); + lua_pushinteger(L, 2); + lua_setfield(L, -2, "NPATCH_THREE_PATCH_HORIZONTAL"); + lua_pushnumber(L, 3.14159265358979323846f); + lua_setfield(L, -2, "PI"); + lua_pushnumber(L, (PI/180.0f)); + lua_setfield(L, -2, "DEG2RAD"); + lua_pushnumber(L, (180.0f/PI)); + lua_setfield(L, -2, "RAD2DEG"); + RLUA_PUSH_Color(L, CLITERAL(Color){ 200, 200, 200, 255 }); + lua_setfield(L, -2, "LIGHTGRAY"); + RLUA_PUSH_Color(L, CLITERAL(Color){ 130, 130, 130, 255 }); + lua_setfield(L, -2, "GRAY"); + RLUA_PUSH_Color(L, CLITERAL(Color){ 80, 80, 80, 255 }); + lua_setfield(L, -2, "DARKGRAY"); + RLUA_PUSH_Color(L, CLITERAL(Color){ 253, 249, 0, 255 }); + lua_setfield(L, -2, "YELLOW"); + RLUA_PUSH_Color(L, CLITERAL(Color){ 255, 203, 0, 255 }); + lua_setfield(L, -2, "GOLD"); + RLUA_PUSH_Color(L, CLITERAL(Color){ 255, 161, 0, 255 }); + lua_setfield(L, -2, "ORANGE"); + RLUA_PUSH_Color(L, CLITERAL(Color){ 255, 109, 194, 255 }); + lua_setfield(L, -2, "PINK"); + RLUA_PUSH_Color(L, CLITERAL(Color){ 230, 41, 55, 255 }); + lua_setfield(L, -2, "RED"); + RLUA_PUSH_Color(L, CLITERAL(Color){ 190, 33, 55, 255 }); + lua_setfield(L, -2, "MAROON"); + RLUA_PUSH_Color(L, CLITERAL(Color){ 0, 228, 48, 255 }); + lua_setfield(L, -2, "GREEN"); + RLUA_PUSH_Color(L, CLITERAL(Color){ 0, 158, 47, 255 }); + lua_setfield(L, -2, "LIME"); + RLUA_PUSH_Color(L, CLITERAL(Color){ 0, 117, 44, 255 }); + lua_setfield(L, -2, "DARKGREEN"); + RLUA_PUSH_Color(L, CLITERAL(Color){ 102, 191, 255, 255 }); + lua_setfield(L, -2, "SKYBLUE"); + RLUA_PUSH_Color(L, CLITERAL(Color){ 0, 121, 241, 255 }); + lua_setfield(L, -2, "BLUE"); + RLUA_PUSH_Color(L, CLITERAL(Color){ 0, 82, 172, 255 }); + lua_setfield(L, -2, "DARKBLUE"); + RLUA_PUSH_Color(L, CLITERAL(Color){ 200, 122, 255, 255 }); + lua_setfield(L, -2, "PURPLE"); + RLUA_PUSH_Color(L, CLITERAL(Color){ 135, 60, 190, 255 }); + lua_setfield(L, -2, "VIOLET"); + RLUA_PUSH_Color(L, CLITERAL(Color){ 112, 31, 126, 255 }); + lua_setfield(L, -2, "DARKPURPLE"); + RLUA_PUSH_Color(L, CLITERAL(Color){ 211, 176, 131, 255 }); + lua_setfield(L, -2, "BEIGE"); + RLUA_PUSH_Color(L, CLITERAL(Color){ 127, 106, 79, 255 }); + lua_setfield(L, -2, "BROWN"); + RLUA_PUSH_Color(L, CLITERAL(Color){ 76, 63, 47, 255 }); + lua_setfield(L, -2, "DARKBROWN"); + RLUA_PUSH_Color(L, CLITERAL(Color){ 255, 255, 255, 255 }); + lua_setfield(L, -2, "WHITE"); + RLUA_PUSH_Color(L, CLITERAL(Color){ 0, 0, 0, 255 }); + lua_setfield(L, -2, "BLACK"); + RLUA_PUSH_Color(L, CLITERAL(Color){ 0, 0, 0, 0 }); + lua_setfield(L, -2, "BLANK"); + RLUA_PUSH_Color(L, CLITERAL(Color){ 255, 0, 255, 255 }); + lua_setfield(L, -2, "MAGENTA"); + RLUA_PUSH_Color(L, CLITERAL(Color){ 245, 245, 245, 255 }); + lua_setfield(L, -2, "RAYWHITE"); + lua_pushinteger(L, MOUSE_BUTTON_LEFT); + lua_setfield(L, -2, "MOUSE_LEFT_BUTTON"); + lua_pushinteger(L, MOUSE_BUTTON_RIGHT); + lua_setfield(L, -2, "MOUSE_RIGHT_BUTTON"); + lua_pushinteger(L, MOUSE_BUTTON_MIDDLE); + lua_setfield(L, -2, "MOUSE_MIDDLE_BUTTON"); + lua_pushinteger(L, MATERIAL_MAP_ALBEDO); + lua_setfield(L, -2, "MATERIAL_MAP_DIFFUSE"); + lua_pushinteger(L, MATERIAL_MAP_METALNESS); + lua_setfield(L, -2, "MATERIAL_MAP_SPECULAR"); + lua_pushinteger(L, SHADER_LOC_MAP_ALBEDO); + lua_setfield(L, -2, "SHADER_LOC_MAP_DIFFUSE"); + lua_pushinteger(L, SHADER_LOC_MAP_METALNESS); + lua_setfield(L, -2, "SHADER_LOC_MAP_SPECULAR"); +} + +// raylib functions list +static const struct luaL_Reg raylib_functions[] = { + {"InitWindow", rl_InitWindow}, + {"CloseWindow", rl_CloseWindow}, + {"WindowShouldClose", rl_WindowShouldClose}, + {"IsWindowReady", rl_IsWindowReady}, + {"IsWindowFullscreen", rl_IsWindowFullscreen}, + {"IsWindowHidden", rl_IsWindowHidden}, + {"IsWindowMinimized", rl_IsWindowMinimized}, + {"IsWindowMaximized", rl_IsWindowMaximized}, + {"IsWindowFocused", rl_IsWindowFocused}, + {"IsWindowResized", rl_IsWindowResized}, + {"IsWindowState", rl_IsWindowState}, + {"SetWindowState", rl_SetWindowState}, + {"ClearWindowState", rl_ClearWindowState}, + {"ToggleFullscreen", rl_ToggleFullscreen}, + {"ToggleBorderlessWindowed", rl_ToggleBorderlessWindowed}, + {"MaximizeWindow", rl_MaximizeWindow}, + {"MinimizeWindow", rl_MinimizeWindow}, + {"RestoreWindow", rl_RestoreWindow}, + {"SetWindowIcon", rl_SetWindowIcon}, + {"SetWindowIcons", rl_SetWindowIcons}, + {"SetWindowTitle", rl_SetWindowTitle}, + {"SetWindowPosition", rl_SetWindowPosition}, + {"SetWindowMonitor", rl_SetWindowMonitor}, + {"SetWindowMinSize", rl_SetWindowMinSize}, + {"SetWindowMaxSize", rl_SetWindowMaxSize}, + {"SetWindowSize", rl_SetWindowSize}, + {"SetWindowOpacity", rl_SetWindowOpacity}, + {"SetWindowFocused", rl_SetWindowFocused}, + {"GetWindowHandle", rl_GetWindowHandle}, + {"GetScreenWidth", rl_GetScreenWidth}, + {"GetScreenHeight", rl_GetScreenHeight}, + {"GetRenderWidth", rl_GetRenderWidth}, + {"GetRenderHeight", rl_GetRenderHeight}, + {"GetMonitorCount", rl_GetMonitorCount}, + {"GetCurrentMonitor", rl_GetCurrentMonitor}, + {"GetMonitorPosition", rl_GetMonitorPosition}, + {"GetMonitorWidth", rl_GetMonitorWidth}, + {"GetMonitorHeight", rl_GetMonitorHeight}, + {"GetMonitorPhysicalWidth", rl_GetMonitorPhysicalWidth}, + {"GetMonitorPhysicalHeight", rl_GetMonitorPhysicalHeight}, + {"GetMonitorRefreshRate", rl_GetMonitorRefreshRate}, + {"GetWindowPosition", rl_GetWindowPosition}, + {"GetWindowScaleDPI", rl_GetWindowScaleDPI}, + {"GetMonitorName", rl_GetMonitorName}, + {"SetClipboardText", rl_SetClipboardText}, + {"GetClipboardText", rl_GetClipboardText}, + {"GetClipboardImage", rl_GetClipboardImage}, + {"EnableEventWaiting", rl_EnableEventWaiting}, + {"DisableEventWaiting", rl_DisableEventWaiting}, + {"ShowCursor", rl_ShowCursor}, + {"HideCursor", rl_HideCursor}, + {"IsCursorHidden", rl_IsCursorHidden}, + {"EnableCursor", rl_EnableCursor}, + {"DisableCursor", rl_DisableCursor}, + {"IsCursorOnScreen", rl_IsCursorOnScreen}, + {"ClearBackground", rl_ClearBackground}, + {"BeginDrawing", rl_BeginDrawing}, + {"EndDrawing", rl_EndDrawing}, + {"BeginMode2D", rl_BeginMode2D}, + {"EndMode2D", rl_EndMode2D}, + {"BeginMode3D", rl_BeginMode3D}, + {"EndMode3D", rl_EndMode3D}, + {"BeginTextureMode", rl_BeginTextureMode}, + {"EndTextureMode", rl_EndTextureMode}, + {"BeginShaderMode", rl_BeginShaderMode}, + {"EndShaderMode", rl_EndShaderMode}, + {"BeginBlendMode", rl_BeginBlendMode}, + {"EndBlendMode", rl_EndBlendMode}, + {"BeginScissorMode", rl_BeginScissorMode}, + {"EndScissorMode", rl_EndScissorMode}, + {"BeginVrStereoMode", rl_BeginVrStereoMode}, + {"EndVrStereoMode", rl_EndVrStereoMode}, + {"LoadVrStereoConfig", rl_LoadVrStereoConfig}, + {"UnloadVrStereoConfig", rl_UnloadVrStereoConfig}, + {"LoadShader", rl_LoadShader}, + {"LoadShaderFromMemory", rl_LoadShaderFromMemory}, + {"IsShaderValid", rl_IsShaderValid}, + {"GetShaderLocation", rl_GetShaderLocation}, + {"GetShaderLocationAttrib", rl_GetShaderLocationAttrib}, + {"SetShaderValue", rl_SetShaderValue}, + {"SetShaderValueV", rl_SetShaderValueV}, + {"SetShaderValueMatrix", rl_SetShaderValueMatrix}, + {"SetShaderValueTexture", rl_SetShaderValueTexture}, + {"UnloadShader", rl_UnloadShader}, + {"GetScreenToWorldRay", rl_GetScreenToWorldRay}, + {"GetScreenToWorldRayEx", rl_GetScreenToWorldRayEx}, + {"GetWorldToScreen", rl_GetWorldToScreen}, + {"GetWorldToScreenEx", rl_GetWorldToScreenEx}, + {"GetWorldToScreen2D", rl_GetWorldToScreen2D}, + {"GetScreenToWorld2D", rl_GetScreenToWorld2D}, + {"GetCameraMatrix", rl_GetCameraMatrix}, + {"GetCameraMatrix2D", rl_GetCameraMatrix2D}, + {"SetTargetFPS", rl_SetTargetFPS}, + {"GetFrameTime", rl_GetFrameTime}, + {"GetTime", rl_GetTime}, + {"GetFPS", rl_GetFPS}, + {"SwapScreenBuffer", rl_SwapScreenBuffer}, + {"PollInputEvents", rl_PollInputEvents}, + {"WaitTime", rl_WaitTime}, + {"SetRandomSeed", rl_SetRandomSeed}, + {"GetRandomValue", rl_GetRandomValue}, + {"LoadRandomSequence", rl_LoadRandomSequence}, + {"UnloadRandomSequence", rl_UnloadRandomSequence}, + {"TakeScreenshot", rl_TakeScreenshot}, + {"SetConfigFlags", rl_SetConfigFlags}, + {"OpenURL", rl_OpenURL}, + {"SetTraceLogLevel", rl_SetTraceLogLevel}, + {"TraceLog", rl_TraceLog}, + {"SetTraceLogCallback", rl_SetTraceLogCallback}, + {"MemAlloc", rl_MemAlloc}, + {"MemRealloc", rl_MemRealloc}, + {"MemFree", rl_MemFree}, + {"LoadFileData", rl_LoadFileData}, + {"UnloadFileData", rl_UnloadFileData}, + {"SaveFileData", rl_SaveFileData}, + {"ExportDataAsCode", rl_ExportDataAsCode}, + {"LoadFileText", rl_LoadFileText}, + {"UnloadFileText", rl_UnloadFileText}, + {"SaveFileText", rl_SaveFileText}, + {"SetLoadFileDataCallback", rl_SetLoadFileDataCallback}, + {"SetSaveFileDataCallback", rl_SetSaveFileDataCallback}, + {"SetLoadFileTextCallback", rl_SetLoadFileTextCallback}, + {"SetSaveFileTextCallback", rl_SetSaveFileTextCallback}, + {"FileRename", rl_FileRename}, + {"FileRemove", rl_FileRemove}, + {"FileCopy", rl_FileCopy}, + {"FileMove", rl_FileMove}, + {"FileTextReplace", rl_FileTextReplace}, + {"FileTextFindIndex", rl_FileTextFindIndex}, + {"FileExists", rl_FileExists}, + {"DirectoryExists", rl_DirectoryExists}, + {"IsFileExtension", rl_IsFileExtension}, + {"GetFileLength", rl_GetFileLength}, + {"GetFileModTime", rl_GetFileModTime}, + {"GetFileExtension", rl_GetFileExtension}, + {"GetFileName", rl_GetFileName}, + {"GetFileNameWithoutExt", rl_GetFileNameWithoutExt}, + {"GetDirectoryPath", rl_GetDirectoryPath}, + {"GetPrevDirectoryPath", rl_GetPrevDirectoryPath}, + {"GetWorkingDirectory", rl_GetWorkingDirectory}, + {"GetApplicationDirectory", rl_GetApplicationDirectory}, + {"MakeDirectory", rl_MakeDirectory}, + {"ChangeDirectory", rl_ChangeDirectory}, + {"IsPathFile", rl_IsPathFile}, + {"IsFileNameValid", rl_IsFileNameValid}, + {"LoadDirectoryFiles", rl_LoadDirectoryFiles}, + {"LoadDirectoryFilesEx", rl_LoadDirectoryFilesEx}, + {"UnloadDirectoryFiles", rl_UnloadDirectoryFiles}, + {"IsFileDropped", rl_IsFileDropped}, + {"LoadDroppedFiles", rl_LoadDroppedFiles}, + {"UnloadDroppedFiles", rl_UnloadDroppedFiles}, + {"GetDirectoryFileCount", rl_GetDirectoryFileCount}, + {"GetDirectoryFileCountEx", rl_GetDirectoryFileCountEx}, + {"CompressData", rl_CompressData}, + {"DecompressData", rl_DecompressData}, + {"EncodeDataBase64", rl_EncodeDataBase64}, + {"DecodeDataBase64", rl_DecodeDataBase64}, + {"ComputeCRC32", rl_ComputeCRC32}, + {"ComputeMD5", rl_ComputeMD5}, + {"ComputeSHA1", rl_ComputeSHA1}, + {"ComputeSHA256", rl_ComputeSHA256}, + {"LoadAutomationEventList", rl_LoadAutomationEventList}, + {"UnloadAutomationEventList", rl_UnloadAutomationEventList}, + {"ExportAutomationEventList", rl_ExportAutomationEventList}, + {"SetAutomationEventList", rl_SetAutomationEventList}, + {"SetAutomationEventBaseFrame", rl_SetAutomationEventBaseFrame}, + {"StartAutomationEventRecording", rl_StartAutomationEventRecording}, + {"StopAutomationEventRecording", rl_StopAutomationEventRecording}, + {"PlayAutomationEvent", rl_PlayAutomationEvent}, + {"IsKeyPressed", rl_IsKeyPressed}, + {"IsKeyPressedRepeat", rl_IsKeyPressedRepeat}, + {"IsKeyDown", rl_IsKeyDown}, + {"IsKeyReleased", rl_IsKeyReleased}, + {"IsKeyUp", rl_IsKeyUp}, + {"GetKeyPressed", rl_GetKeyPressed}, + {"GetCharPressed", rl_GetCharPressed}, + {"GetKeyName", rl_GetKeyName}, + {"SetExitKey", rl_SetExitKey}, + {"IsGamepadAvailable", rl_IsGamepadAvailable}, + {"GetGamepadName", rl_GetGamepadName}, + {"IsGamepadButtonPressed", rl_IsGamepadButtonPressed}, + {"IsGamepadButtonDown", rl_IsGamepadButtonDown}, + {"IsGamepadButtonReleased", rl_IsGamepadButtonReleased}, + {"IsGamepadButtonUp", rl_IsGamepadButtonUp}, + {"GetGamepadButtonPressed", rl_GetGamepadButtonPressed}, + {"GetGamepadAxisCount", rl_GetGamepadAxisCount}, + {"GetGamepadAxisMovement", rl_GetGamepadAxisMovement}, + {"SetGamepadMappings", rl_SetGamepadMappings}, + {"SetGamepadVibration", rl_SetGamepadVibration}, + {"IsMouseButtonPressed", rl_IsMouseButtonPressed}, + {"IsMouseButtonDown", rl_IsMouseButtonDown}, + {"IsMouseButtonReleased", rl_IsMouseButtonReleased}, + {"IsMouseButtonUp", rl_IsMouseButtonUp}, + {"GetMouseX", rl_GetMouseX}, + {"GetMouseY", rl_GetMouseY}, + {"GetMousePosition", rl_GetMousePosition}, + {"GetMouseDelta", rl_GetMouseDelta}, + {"SetMousePosition", rl_SetMousePosition}, + {"SetMouseOffset", rl_SetMouseOffset}, + {"SetMouseScale", rl_SetMouseScale}, + {"GetMouseWheelMove", rl_GetMouseWheelMove}, + {"GetMouseWheelMoveV", rl_GetMouseWheelMoveV}, + {"SetMouseCursor", rl_SetMouseCursor}, + {"GetTouchX", rl_GetTouchX}, + {"GetTouchY", rl_GetTouchY}, + {"GetTouchPosition", rl_GetTouchPosition}, + {"GetTouchPointId", rl_GetTouchPointId}, + {"GetTouchPointCount", rl_GetTouchPointCount}, + {"SetGesturesEnabled", rl_SetGesturesEnabled}, + {"IsGestureDetected", rl_IsGestureDetected}, + {"GetGestureDetected", rl_GetGestureDetected}, + {"GetGestureHoldDuration", rl_GetGestureHoldDuration}, + {"GetGestureDragVector", rl_GetGestureDragVector}, + {"GetGestureDragAngle", rl_GetGestureDragAngle}, + {"GetGesturePinchVector", rl_GetGesturePinchVector}, + {"GetGesturePinchAngle", rl_GetGesturePinchAngle}, + {"UpdateCamera", rl_UpdateCamera}, + {"UpdateCameraPro", rl_UpdateCameraPro}, + {"SetShapesTexture", rl_SetShapesTexture}, + {"GetShapesTexture", rl_GetShapesTexture}, + {"GetShapesTextureRectangle", rl_GetShapesTextureRectangle}, + {"DrawPixel", rl_DrawPixel}, + {"DrawPixelV", rl_DrawPixelV}, + {"DrawLine", rl_DrawLine}, + {"DrawLineV", rl_DrawLineV}, + {"DrawLineEx", rl_DrawLineEx}, + {"DrawLineStrip", rl_DrawLineStrip}, + {"DrawLineBezier", rl_DrawLineBezier}, + {"DrawLineDashed", rl_DrawLineDashed}, + {"DrawCircle", rl_DrawCircle}, + {"DrawCircleV", rl_DrawCircleV}, + {"DrawCircleGradient", rl_DrawCircleGradient}, + {"DrawCircleSector", rl_DrawCircleSector}, + {"DrawCircleSectorLines", rl_DrawCircleSectorLines}, + {"DrawCircleLines", rl_DrawCircleLines}, + {"DrawCircleLinesV", rl_DrawCircleLinesV}, + {"DrawEllipse", rl_DrawEllipse}, + {"DrawEllipseV", rl_DrawEllipseV}, + {"DrawEllipseLines", rl_DrawEllipseLines}, + {"DrawEllipseLinesV", rl_DrawEllipseLinesV}, + {"DrawRing", rl_DrawRing}, + {"DrawRingLines", rl_DrawRingLines}, + {"DrawRectangle", rl_DrawRectangle}, + {"DrawRectangleV", rl_DrawRectangleV}, + {"DrawRectangleRec", rl_DrawRectangleRec}, + {"DrawRectanglePro", rl_DrawRectanglePro}, + {"DrawRectangleGradientV", rl_DrawRectangleGradientV}, + {"DrawRectangleGradientH", rl_DrawRectangleGradientH}, + {"DrawRectangleGradientEx", rl_DrawRectangleGradientEx}, + {"DrawRectangleLines", rl_DrawRectangleLines}, + {"DrawRectangleLinesEx", rl_DrawRectangleLinesEx}, + {"DrawRectangleRounded", rl_DrawRectangleRounded}, + {"DrawRectangleRoundedLines", rl_DrawRectangleRoundedLines}, + {"DrawRectangleRoundedLinesEx", rl_DrawRectangleRoundedLinesEx}, + {"DrawTriangle", rl_DrawTriangle}, + {"DrawTriangleLines", rl_DrawTriangleLines}, + {"DrawTriangleFan", rl_DrawTriangleFan}, + {"DrawTriangleStrip", rl_DrawTriangleStrip}, + {"DrawPoly", rl_DrawPoly}, + {"DrawPolyLines", rl_DrawPolyLines}, + {"DrawPolyLinesEx", rl_DrawPolyLinesEx}, + {"DrawSplineLinear", rl_DrawSplineLinear}, + {"DrawSplineBasis", rl_DrawSplineBasis}, + {"DrawSplineCatmullRom", rl_DrawSplineCatmullRom}, + {"DrawSplineBezierQuadratic", rl_DrawSplineBezierQuadratic}, + {"DrawSplineBezierCubic", rl_DrawSplineBezierCubic}, + {"DrawSplineSegmentLinear", rl_DrawSplineSegmentLinear}, + {"DrawSplineSegmentBasis", rl_DrawSplineSegmentBasis}, + {"DrawSplineSegmentCatmullRom", rl_DrawSplineSegmentCatmullRom}, + {"DrawSplineSegmentBezierQuadratic", rl_DrawSplineSegmentBezierQuadratic}, + {"DrawSplineSegmentBezierCubic", rl_DrawSplineSegmentBezierCubic}, + {"GetSplinePointLinear", rl_GetSplinePointLinear}, + {"GetSplinePointBasis", rl_GetSplinePointBasis}, + {"GetSplinePointCatmullRom", rl_GetSplinePointCatmullRom}, + {"GetSplinePointBezierQuad", rl_GetSplinePointBezierQuad}, + {"GetSplinePointBezierCubic", rl_GetSplinePointBezierCubic}, + {"CheckCollisionRecs", rl_CheckCollisionRecs}, + {"CheckCollisionCircles", rl_CheckCollisionCircles}, + {"CheckCollisionCircleRec", rl_CheckCollisionCircleRec}, + {"CheckCollisionCircleLine", rl_CheckCollisionCircleLine}, + {"CheckCollisionPointRec", rl_CheckCollisionPointRec}, + {"CheckCollisionPointCircle", rl_CheckCollisionPointCircle}, + {"CheckCollisionPointTriangle", rl_CheckCollisionPointTriangle}, + {"CheckCollisionPointLine", rl_CheckCollisionPointLine}, + {"CheckCollisionPointPoly", rl_CheckCollisionPointPoly}, + {"CheckCollisionLines", rl_CheckCollisionLines}, + {"GetCollisionRec", rl_GetCollisionRec}, + {"LoadImage", rl_LoadImage}, + {"LoadImageRaw", rl_LoadImageRaw}, + {"LoadImageAnim", rl_LoadImageAnim}, + {"LoadImageAnimFromMemory", rl_LoadImageAnimFromMemory}, + {"LoadImageFromMemory", rl_LoadImageFromMemory}, + {"LoadImageFromTexture", rl_LoadImageFromTexture}, + {"LoadImageFromScreen", rl_LoadImageFromScreen}, + {"IsImageValid", rl_IsImageValid}, + {"UnloadImage", rl_UnloadImage}, + {"ExportImage", rl_ExportImage}, + {"ExportImageToMemory", rl_ExportImageToMemory}, + {"ExportImageAsCode", rl_ExportImageAsCode}, + {"GenImageColor", rl_GenImageColor}, + {"GenImageGradientLinear", rl_GenImageGradientLinear}, + {"GenImageGradientRadial", rl_GenImageGradientRadial}, + {"GenImageGradientSquare", rl_GenImageGradientSquare}, + {"GenImageChecked", rl_GenImageChecked}, + {"GenImageWhiteNoise", rl_GenImageWhiteNoise}, + {"GenImagePerlinNoise", rl_GenImagePerlinNoise}, + {"GenImageCellular", rl_GenImageCellular}, + {"GenImageText", rl_GenImageText}, + {"ImageCopy", rl_ImageCopy}, + {"ImageFromImage", rl_ImageFromImage}, + {"ImageFromChannel", rl_ImageFromChannel}, + {"ImageText", rl_ImageText}, + {"ImageTextEx", rl_ImageTextEx}, + {"ImageFormat", rl_ImageFormat}, + {"ImageToPOT", rl_ImageToPOT}, + {"ImageCrop", rl_ImageCrop}, + {"ImageAlphaCrop", rl_ImageAlphaCrop}, + {"ImageAlphaClear", rl_ImageAlphaClear}, + {"ImageAlphaMask", rl_ImageAlphaMask}, + {"ImageAlphaPremultiply", rl_ImageAlphaPremultiply}, + {"ImageBlurGaussian", rl_ImageBlurGaussian}, + {"ImageKernelConvolution", rl_ImageKernelConvolution}, + {"ImageResize", rl_ImageResize}, + {"ImageResizeNN", rl_ImageResizeNN}, + {"ImageResizeCanvas", rl_ImageResizeCanvas}, + {"ImageMipmaps", rl_ImageMipmaps}, + {"ImageDither", rl_ImageDither}, + {"ImageFlipVertical", rl_ImageFlipVertical}, + {"ImageFlipHorizontal", rl_ImageFlipHorizontal}, + {"ImageRotate", rl_ImageRotate}, + {"ImageRotateCW", rl_ImageRotateCW}, + {"ImageRotateCCW", rl_ImageRotateCCW}, + {"ImageColorTint", rl_ImageColorTint}, + {"ImageColorInvert", rl_ImageColorInvert}, + {"ImageColorGrayscale", rl_ImageColorGrayscale}, + {"ImageColorContrast", rl_ImageColorContrast}, + {"ImageColorBrightness", rl_ImageColorBrightness}, + {"ImageColorReplace", rl_ImageColorReplace}, + {"LoadImageColors", rl_LoadImageColors}, + {"LoadImagePalette", rl_LoadImagePalette}, + {"UnloadImageColors", rl_UnloadImageColors}, + {"UnloadImagePalette", rl_UnloadImagePalette}, + {"GetImageAlphaBorder", rl_GetImageAlphaBorder}, + {"GetImageColor", rl_GetImageColor}, + {"ImageClearBackground", rl_ImageClearBackground}, + {"ImageDrawPixel", rl_ImageDrawPixel}, + {"ImageDrawPixelV", rl_ImageDrawPixelV}, + {"ImageDrawLine", rl_ImageDrawLine}, + {"ImageDrawLineV", rl_ImageDrawLineV}, + {"ImageDrawLineEx", rl_ImageDrawLineEx}, + {"ImageDrawCircle", rl_ImageDrawCircle}, + {"ImageDrawCircleV", rl_ImageDrawCircleV}, + {"ImageDrawCircleLines", rl_ImageDrawCircleLines}, + {"ImageDrawCircleLinesV", rl_ImageDrawCircleLinesV}, + {"ImageDrawRectangle", rl_ImageDrawRectangle}, + {"ImageDrawRectangleV", rl_ImageDrawRectangleV}, + {"ImageDrawRectangleRec", rl_ImageDrawRectangleRec}, + {"ImageDrawRectangleLines", rl_ImageDrawRectangleLines}, + {"ImageDrawTriangle", rl_ImageDrawTriangle}, + {"ImageDrawTriangleEx", rl_ImageDrawTriangleEx}, + {"ImageDrawTriangleLines", rl_ImageDrawTriangleLines}, + {"ImageDrawTriangleFan", rl_ImageDrawTriangleFan}, + {"ImageDrawTriangleStrip", rl_ImageDrawTriangleStrip}, + {"ImageDraw", rl_ImageDraw}, + {"ImageDrawText", rl_ImageDrawText}, + {"ImageDrawTextEx", rl_ImageDrawTextEx}, + {"LoadTexture", rl_LoadTexture}, + {"LoadTextureFromImage", rl_LoadTextureFromImage}, + {"LoadTextureCubemap", rl_LoadTextureCubemap}, + {"LoadRenderTexture", rl_LoadRenderTexture}, + {"IsTextureValid", rl_IsTextureValid}, + {"UnloadTexture", rl_UnloadTexture}, + {"IsRenderTextureValid", rl_IsRenderTextureValid}, + {"UnloadRenderTexture", rl_UnloadRenderTexture}, + {"UpdateTexture", rl_UpdateTexture}, + {"UpdateTextureRec", rl_UpdateTextureRec}, + {"GenTextureMipmaps", rl_GenTextureMipmaps}, + {"SetTextureFilter", rl_SetTextureFilter}, + {"SetTextureWrap", rl_SetTextureWrap}, + {"DrawTexture", rl_DrawTexture}, + {"DrawTextureV", rl_DrawTextureV}, + {"DrawTextureEx", rl_DrawTextureEx}, + {"DrawTextureRec", rl_DrawTextureRec}, + {"DrawTexturePro", rl_DrawTexturePro}, + {"DrawTextureNPatch", rl_DrawTextureNPatch}, + {"ColorIsEqual", rl_ColorIsEqual}, + {"Fade", rl_Fade}, + {"ColorToInt", rl_ColorToInt}, + {"ColorNormalize", rl_ColorNormalize}, + {"ColorFromNormalized", rl_ColorFromNormalized}, + {"ColorToHSV", rl_ColorToHSV}, + {"ColorFromHSV", rl_ColorFromHSV}, + {"ColorTint", rl_ColorTint}, + {"ColorBrightness", rl_ColorBrightness}, + {"ColorContrast", rl_ColorContrast}, + {"ColorAlpha", rl_ColorAlpha}, + {"ColorAlphaBlend", rl_ColorAlphaBlend}, + {"ColorLerp", rl_ColorLerp}, + {"GetColor", rl_GetColor}, + {"GetPixelColor", rl_GetPixelColor}, + {"SetPixelColor", rl_SetPixelColor}, + {"GetPixelDataSize", rl_GetPixelDataSize}, + {"GetFontDefault", rl_GetFontDefault}, + {"LoadFont", rl_LoadFont}, + {"LoadFontEx", rl_LoadFontEx}, + {"LoadFontFromImage", rl_LoadFontFromImage}, + {"LoadFontFromMemory", rl_LoadFontFromMemory}, + {"IsFontValid", rl_IsFontValid}, + {"LoadFontData", rl_LoadFontData}, + {"GenImageFontAtlas", rl_GenImageFontAtlas}, + {"UnloadFontData", rl_UnloadFontData}, + {"UnloadFont", rl_UnloadFont}, + {"ExportFontAsCode", rl_ExportFontAsCode}, + {"DrawFPS", rl_DrawFPS}, + {"DrawText", rl_DrawText}, + {"DrawTextEx", rl_DrawTextEx}, + {"DrawTextPro", rl_DrawTextPro}, + {"DrawTextCodepoint", rl_DrawTextCodepoint}, + {"DrawTextCodepoints", rl_DrawTextCodepoints}, + {"SetTextLineSpacing", rl_SetTextLineSpacing}, + {"MeasureText", rl_MeasureText}, + {"MeasureTextEx", rl_MeasureTextEx}, + {"MeasureTextCodepoints", rl_MeasureTextCodepoints}, + {"GetGlyphIndex", rl_GetGlyphIndex}, + {"GetGlyphInfo", rl_GetGlyphInfo}, + {"GetGlyphAtlasRec", rl_GetGlyphAtlasRec}, + {"LoadUTF8", rl_LoadUTF8}, + {"UnloadUTF8", rl_UnloadUTF8}, + {"LoadCodepoints", rl_LoadCodepoints}, + {"UnloadCodepoints", rl_UnloadCodepoints}, + {"GetCodepointCount", rl_GetCodepointCount}, + {"GetCodepoint", rl_GetCodepoint}, + {"GetCodepointNext", rl_GetCodepointNext}, + {"GetCodepointPrevious", rl_GetCodepointPrevious}, + {"CodepointToUTF8", rl_CodepointToUTF8}, + {"LoadTextLines", rl_LoadTextLines}, + {"UnloadTextLines", rl_UnloadTextLines}, + {"TextCopy", rl_TextCopy}, + {"TextIsEqual", rl_TextIsEqual}, + {"TextLength", rl_TextLength}, + {"TextFormat", rl_TextFormat}, + {"TextSubtext", rl_TextSubtext}, + {"TextRemoveSpaces", rl_TextRemoveSpaces}, + {"GetTextBetween", rl_GetTextBetween}, + {"TextReplace", rl_TextReplace}, + {"TextReplaceAlloc", rl_TextReplaceAlloc}, + {"TextReplaceBetween", rl_TextReplaceBetween}, + {"TextReplaceBetweenAlloc", rl_TextReplaceBetweenAlloc}, + {"TextInsert", rl_TextInsert}, + {"TextInsertAlloc", rl_TextInsertAlloc}, + {"TextJoin", rl_TextJoin}, + {"TextSplit", rl_TextSplit}, + {"TextAppend", rl_TextAppend}, + {"TextFindIndex", rl_TextFindIndex}, + {"TextToUpper", rl_TextToUpper}, + {"TextToLower", rl_TextToLower}, + {"TextToPascal", rl_TextToPascal}, + {"TextToSnake", rl_TextToSnake}, + {"TextToCamel", rl_TextToCamel}, + {"TextToInteger", rl_TextToInteger}, + {"TextToFloat", rl_TextToFloat}, + {"DrawLine3D", rl_DrawLine3D}, + {"DrawPoint3D", rl_DrawPoint3D}, + {"DrawCircle3D", rl_DrawCircle3D}, + {"DrawTriangle3D", rl_DrawTriangle3D}, + {"DrawTriangleStrip3D", rl_DrawTriangleStrip3D}, + {"DrawCube", rl_DrawCube}, + {"DrawCubeV", rl_DrawCubeV}, + {"DrawCubeWires", rl_DrawCubeWires}, + {"DrawCubeWiresV", rl_DrawCubeWiresV}, + {"DrawSphere", rl_DrawSphere}, + {"DrawSphereEx", rl_DrawSphereEx}, + {"DrawSphereWires", rl_DrawSphereWires}, + {"DrawCylinder", rl_DrawCylinder}, + {"DrawCylinderEx", rl_DrawCylinderEx}, + {"DrawCylinderWires", rl_DrawCylinderWires}, + {"DrawCylinderWiresEx", rl_DrawCylinderWiresEx}, + {"DrawCapsule", rl_DrawCapsule}, + {"DrawCapsuleWires", rl_DrawCapsuleWires}, + {"DrawPlane", rl_DrawPlane}, + {"DrawRay", rl_DrawRay}, + {"DrawGrid", rl_DrawGrid}, + {"LoadModel", rl_LoadModel}, + {"LoadModelFromMesh", rl_LoadModelFromMesh}, + {"IsModelValid", rl_IsModelValid}, + {"UnloadModel", rl_UnloadModel}, + {"GetModelBoundingBox", rl_GetModelBoundingBox}, + {"DrawModel", rl_DrawModel}, + {"DrawModelEx", rl_DrawModelEx}, + {"DrawModelWires", rl_DrawModelWires}, + {"DrawModelWiresEx", rl_DrawModelWiresEx}, + {"DrawBoundingBox", rl_DrawBoundingBox}, + {"DrawBillboard", rl_DrawBillboard}, + {"DrawBillboardRec", rl_DrawBillboardRec}, + {"DrawBillboardPro", rl_DrawBillboardPro}, + {"UploadMesh", rl_UploadMesh}, + {"UpdateMeshBuffer", rl_UpdateMeshBuffer}, + {"UnloadMesh", rl_UnloadMesh}, + {"DrawMesh", rl_DrawMesh}, + {"DrawMeshInstanced", rl_DrawMeshInstanced}, + {"GetMeshBoundingBox", rl_GetMeshBoundingBox}, + {"GenMeshTangents", rl_GenMeshTangents}, + {"ExportMesh", rl_ExportMesh}, + {"ExportMeshAsCode", rl_ExportMeshAsCode}, + {"GenMeshPoly", rl_GenMeshPoly}, + {"GenMeshPlane", rl_GenMeshPlane}, + {"GenMeshCube", rl_GenMeshCube}, + {"GenMeshSphere", rl_GenMeshSphere}, + {"GenMeshHemiSphere", rl_GenMeshHemiSphere}, + {"GenMeshCylinder", rl_GenMeshCylinder}, + {"GenMeshCone", rl_GenMeshCone}, + {"GenMeshTorus", rl_GenMeshTorus}, + {"GenMeshKnot", rl_GenMeshKnot}, + {"GenMeshHeightmap", rl_GenMeshHeightmap}, + {"GenMeshCubicmap", rl_GenMeshCubicmap}, + {"LoadMaterials", rl_LoadMaterials}, + {"LoadMaterialDefault", rl_LoadMaterialDefault}, + {"IsMaterialValid", rl_IsMaterialValid}, + {"UnloadMaterial", rl_UnloadMaterial}, + {"SetMaterialTexture", rl_SetMaterialTexture}, + {"SetModelMeshMaterial", rl_SetModelMeshMaterial}, + {"LoadModelAnimations", rl_LoadModelAnimations}, + {"UpdateModelAnimation", rl_UpdateModelAnimation}, + {"UpdateModelAnimationEx", rl_UpdateModelAnimationEx}, + {"UnloadModelAnimations", rl_UnloadModelAnimations}, + {"IsModelAnimationValid", rl_IsModelAnimationValid}, + {"CheckCollisionSpheres", rl_CheckCollisionSpheres}, + {"CheckCollisionBoxes", rl_CheckCollisionBoxes}, + {"CheckCollisionBoxSphere", rl_CheckCollisionBoxSphere}, + {"GetRayCollisionSphere", rl_GetRayCollisionSphere}, + {"GetRayCollisionBox", rl_GetRayCollisionBox}, + {"GetRayCollisionMesh", rl_GetRayCollisionMesh}, + {"GetRayCollisionTriangle", rl_GetRayCollisionTriangle}, + {"GetRayCollisionQuad", rl_GetRayCollisionQuad}, + {"InitAudioDevice", rl_InitAudioDevice}, + {"CloseAudioDevice", rl_CloseAudioDevice}, + {"IsAudioDeviceReady", rl_IsAudioDeviceReady}, + {"SetMasterVolume", rl_SetMasterVolume}, + {"GetMasterVolume", rl_GetMasterVolume}, + {"LoadWave", rl_LoadWave}, + {"LoadWaveFromMemory", rl_LoadWaveFromMemory}, + {"IsWaveValid", rl_IsWaveValid}, + {"LoadSound", rl_LoadSound}, + {"LoadSoundFromWave", rl_LoadSoundFromWave}, + {"LoadSoundAlias", rl_LoadSoundAlias}, + {"IsSoundValid", rl_IsSoundValid}, + {"UpdateSound", rl_UpdateSound}, + {"UnloadWave", rl_UnloadWave}, + {"UnloadSound", rl_UnloadSound}, + {"UnloadSoundAlias", rl_UnloadSoundAlias}, + {"ExportWave", rl_ExportWave}, + {"ExportWaveAsCode", rl_ExportWaveAsCode}, + {"PlaySound", rl_PlaySound}, + {"StopSound", rl_StopSound}, + {"PauseSound", rl_PauseSound}, + {"ResumeSound", rl_ResumeSound}, + {"IsSoundPlaying", rl_IsSoundPlaying}, + {"SetSoundVolume", rl_SetSoundVolume}, + {"SetSoundPitch", rl_SetSoundPitch}, + {"SetSoundPan", rl_SetSoundPan}, + {"WaveCopy", rl_WaveCopy}, + {"WaveCrop", rl_WaveCrop}, + {"WaveFormat", rl_WaveFormat}, + {"LoadWaveSamples", rl_LoadWaveSamples}, + {"UnloadWaveSamples", rl_UnloadWaveSamples}, + {"LoadMusicStream", rl_LoadMusicStream}, + {"LoadMusicStreamFromMemory", rl_LoadMusicStreamFromMemory}, + {"IsMusicValid", rl_IsMusicValid}, + {"UnloadMusicStream", rl_UnloadMusicStream}, + {"PlayMusicStream", rl_PlayMusicStream}, + {"IsMusicStreamPlaying", rl_IsMusicStreamPlaying}, + {"UpdateMusicStream", rl_UpdateMusicStream}, + {"StopMusicStream", rl_StopMusicStream}, + {"PauseMusicStream", rl_PauseMusicStream}, + {"ResumeMusicStream", rl_ResumeMusicStream}, + {"SeekMusicStream", rl_SeekMusicStream}, + {"SetMusicVolume", rl_SetMusicVolume}, + {"SetMusicPitch", rl_SetMusicPitch}, + {"SetMusicPan", rl_SetMusicPan}, + {"GetMusicTimeLength", rl_GetMusicTimeLength}, + {"GetMusicTimePlayed", rl_GetMusicTimePlayed}, + {"LoadAudioStream", rl_LoadAudioStream}, + {"IsAudioStreamValid", rl_IsAudioStreamValid}, + {"UnloadAudioStream", rl_UnloadAudioStream}, + {"UpdateAudioStream", rl_UpdateAudioStream}, + {"IsAudioStreamProcessed", rl_IsAudioStreamProcessed}, + {"PlayAudioStream", rl_PlayAudioStream}, + {"PauseAudioStream", rl_PauseAudioStream}, + {"ResumeAudioStream", rl_ResumeAudioStream}, + {"IsAudioStreamPlaying", rl_IsAudioStreamPlaying}, + {"StopAudioStream", rl_StopAudioStream}, + {"SetAudioStreamVolume", rl_SetAudioStreamVolume}, + {"SetAudioStreamPitch", rl_SetAudioStreamPitch}, + {"SetAudioStreamPan", rl_SetAudioStreamPan}, + {"SetAudioStreamBufferSizeDefault", rl_SetAudioStreamBufferSizeDefault}, + {"SetAudioStreamCallback", rl_SetAudioStreamCallback}, + {"AttachAudioStreamProcessor", rl_AttachAudioStreamProcessor}, + {"DetachAudioStreamProcessor", rl_DetachAudioStreamProcessor}, + {"AttachAudioMixedProcessor", rl_AttachAudioMixedProcessor}, + {"DetachAudioMixedProcessor", rl_DetachAudioMixedProcessor}, + {"GetMouseRay", rl_GetScreenToWorldRay}, + + { NULL, NULL } // sentinel +}; -// Execute raylib Lua script -RLUADEF void rLuaExecuteFile(const char *filename) -{ - if (!mainLuaState) - { - TraceLog(WARNING, "Lua device not initialized"); - return; - } +RLUADEF lua_State *rlua_open(void) { + lua_State *L = luaL_newstate(); + luaL_openlibs(L); + + RLUA_State = L; + rLuaRegisterMetatables(L); + +#ifdef RAYLIB_STRIP_PREFIX + // Register functions as globals + lua_pushglobaltable(L); + luaL_setfuncs(L, raylib_functions, 0); + lua_pop(L, 1); + + // Register constants as globals + lua_pushglobaltable(L); + rLuaRegisterConstants(L); + lua_pop(L, 1); + + // rl table mirrors globals via __index = _G + lua_newtable(L); + lua_newtable(L); + lua_pushglobaltable(L); + lua_setfield(L, -2, "__index"); + lua_setmetatable(L, -2); + lua_setglobal(L, "rl"); +#else + lua_newtable(L); + rLuaRegisterConstants(L); + luaL_setfuncs(L, raylib_functions, 0); + lua_setglobal(L, "rl"); +#endif - int result = luaL_dofile(L, filename); + return L; +} - switch (result) - { - case LUA_OK: break; - case LUA_ERRRUN: TraceLog(ERROR, "Lua Runtime Error: %s", lua_tostring(L, -1)); - case LUA_ERRMEM: TraceLog(ERROR, "Lua Memory Error: %s", lua_tostring(L, -1)); - default: TraceLog(ERROR, "Lua Error: %s", lua_tostring(L, -1)); +RLUADEF void rlua_close(lua_State *L) { + if (RLUA_LogRef != LUA_REFNIL) { + luaL_unref(L, LUA_REGISTRYINDEX, RLUA_LogRef); + RLUA_LogRef = LUA_REFNIL; } + RLUA_State = NULL; + lua_close(L); } -#endif // RLUA_IMPLEMENTATION + +#endif diff --git a/tools/rLuaLauncher/rlualauncher.c b/tools/rLuaLauncher/rlualauncher.c index 1a8d776..bb73798 100644 --- a/tools/rLuaLauncher/rlualauncher.c +++ b/tools/rLuaLauncher/rlualauncher.c @@ -1,26 +1,30 @@ /******************************************************************************************* * -* rLuaLauncher v1.1 - raylib Lua Launcher +* rlualauncher v2.0 - raylib Lua Launcher * * DEPENDENCIES: * -* raylib 2.0 - This program uses latest raylib version (www.raylib.com) -* Lua 5.3.3 - http://luabinaries.sourceforge.net/download.html +* raylib 6.0 - This program uses latest raylib version (www.raylib.com) +* Lua 5.5 - https://luabinaries.sourceforge.net/download.html * -* COMPILATION (GCC): +* COMPILATION: * -* gcc -o rlualauncher.exe rlualauncher.c -s rlualauncher.rc.o -I. -Iexternal/lua/include \ -* -Lexternal/lua/lib -lraylib -lopengl32 -lgdi32 -llua53 -std=c99 -Wall -Wl,--subsystem,windows +* ./build.lua # X11 (default) +* CFLAGS="-D_GLFW_WAYLAND" ./build.lua # Wayland * * USAGE: * -* Just launch your raylib .lua file from command line: rll.exe core_basic_window.lua -* or drag&drop your .lua file over rll.exe +* Just launch your raylib .lua file from the command line: * +* ./build/rLuaLauncher core_basic_window.lua +* +* NOTE: Windows is not currently supported. +* TODO: The original had drag-and-drop support. * * LICENSE: zlib/libpng * * Copyright (c) 2016-2018 Ramon Santamaria (@raysan5) +* Copyright (c) 2026 yilisharcs * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. @@ -49,106 +53,27 @@ //------------------------------------------------------------------------------------ int main(int argc, char *argv[]) { - if (argc > 1) + const char *entryLua = (argc > 1) ? argv[1] : "main.lua"; + + if (argc > 2) { - // TODO: Support additional arguments for lua file execution - - if (IsFileExtension(argv[1], ".lua")) - { - rLuaInitDevice(); // Initialize lua device - rLuaExecuteFile(argv[1]); // Execute lua program (argument file) - rLuaCloseDevice(); // Close Lua device and free resources - } + TraceLog(LOG_WARNING, "Too many arguments provided"); + TraceLog(LOG_INFO, "Usage: %s [script.lua] (defaults to main.lua)", argv[0]); + return 1; } - else - { - bool launcherShouldClose = false; - - while (!launcherShouldClose) - { - // Initialization - //-------------------------------------------------------------------------------------- - int screenWidth = 800; - int screenHeight = 450; - InitWindow(screenWidth, screenHeight, "rLL - raylib Lua Launcher"); - - // NOTE: Drag and drop support only available for desktop platforms: Windows, Linux, OSX - int count = 0; - char **droppedFiles; - char luaFileToLoad[256]; - - bool runLuaFile = false; - - SetTargetFPS(60); - //-------------------------------------------------------------------------------------- - - while (!WindowShouldClose() && !runLuaFile) - { - // Update - //---------------------------------------------------------------------------------- + lua_State *L = rlua_open(); + if (L == NULL) { + TraceLog(LOG_ERROR, "LUA: Failed to initialize Lua state"); + return 1; + } - // Load a dropped Lua file dynamically - if (IsFileDropped()) - { - droppedFiles = GetDroppedFiles(&count); - - if (count == 1) // Only support one Lua file dropped - { - if (IsFileExtension(droppedFiles[0], ".lua")) - { - runLuaFile = true; - strcpy(luaFileToLoad, droppedFiles[0]); - } - else TraceLog(WARNING, "[%s] Fileformat not supported", droppedFiles[0]); - } - - ClearDroppedFiles(); - } - //---------------------------------------------------------------------------------- - - // Draw - //---------------------------------------------------------------------------------- - BeginDrawing(); - - ClearBackground(RAYWHITE); - - DrawText("rLL - raylib Lua launcher", 10, 10, 20, LIGHTGRAY); - DrawText("rLL v1.1", 10, 430, 10, GRAY); - DrawText("< drag & drop raylib Lua file here >", 230, 180, 20, GRAY); - - EndDrawing(); - //---------------------------------------------------------------------------------- - } - - // De-Initialization - //-------------------------------------------------------------------------------------- - ClearDroppedFiles(); // Clear internal buffers - - CloseWindow(); // Close window and OpenGL context - //-------------------------------------------------------------------------------------- - - launcherShouldClose = true; // Close launcher if no Lua file loaded - - if (runLuaFile) - { - TraceLog(INFO, "------------------------------------"); - TraceLog(INFO, "Loading Lua file: %s", luaFileToLoad); - TraceLog(INFO, "------------------------------------"); - - rLuaInitDevice(); // Initialize lua device - ChangeDirectory(GetDirectoryPath(luaFileToLoad)); - rLuaExecuteFile(luaFileToLoad); - rLuaCloseDevice(); // Close Lua device and free resources - - launcherShouldClose = false; // Return to launcher to load another Lua file - - TraceLog(INFO, "------------------------------------"); - TraceLog(INFO, "Closing Lua file..."); - TraceLog(INFO, "------------------------------------"); - } - } + if (luaL_dofile(L, entryLua) != LUA_OK) { + TraceLog(LOG_ERROR, "LUA: %s", lua_tostring(L, -1)); + rlua_close(L); + return 1; } + rlua_close(L); return 0; } diff --git a/tools/rLuaParser/rluaparser.c b/tools/rLuaParser/rluaparser.c index 1521fa8..e69de29 100644 --- a/tools/rLuaParser/rluaparser.c +++ b/tools/rLuaParser/rluaparser.c @@ -1,287 +0,0 @@ -/********************************************************************************************** - - rluaparser - raylib header parser to generate automatic Lua binding - - This parser scans raylib.h for functions that start with RLAPI and - generates raylib-lua function binding. - - Converts: - RLAPI Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0f to 1.0f - - To: - // Color fade-in or fade-out, alpha goes from 0.0f to 1.0f - int lua_Fade(lua_State* L) - { - Color arg1 = LuaGetArgument_Color(L, 1); - float arg2 = LuaGetArgument_float(L, 2); - Color result = Fade(arg1, arg2); - LuaPush_Color(L, result); - return 1; - } - - Requirements to create binding raylib -> raylib-lua - NOTE: "Type" refers to raylib defined structs (Vector2, Texture2D...) - [ ] 1. Review LuaPush_Type defines/functions - [ ] 2. Review LuaGetArgument_Type defines/functions - [ ] 3. Review LuaIndexType functions (some raylib structs have changed) - [ ] 4. Review lua_Type functions (raylib Lua structure constructors) - [x] 5. Review function bindings (90% of raylib-lua.h code) --> DONE by this PARSER! - NOTE: Some functions could require specific reviews - [ ] 6. Review registered raylib lua functions --> REG() - [ ] 7. Review enumerators setup on InitLuaDevice() - - LICENSE: zlib/libpng - - Copyright (c) 2018 Ramon Santamaria (@raysan5) - -**********************************************************************************************/ - -#include -#include -#include -#include - -int main() -{ - #define MAX_BUFFER_SIZE 512 - - FILE *rFile = fopen("raylib_test.h", "rt"); - FILE *rluaFile = fopen("raylib-lua_test.h", "wt"); - - if ((rFile == NULL) || (rluaFile == NULL)) - { - printf("File could not be opened.\n"); - return 0; - } - - char *buffer = (char *)calloc(MAX_BUFFER_SIZE, 1); - - char *luaPushFuncs = (char *)calloc(1024*512, 1); // 512 KB - char *luaPushPtr = luaPushFuncs; - - char *luaREG = (char *)calloc(1024*256, 1); // 256 KB - char *luaREGPtr = luaREG; - - int funcsCount = 0; - - while (!feof(rFile)) - { - // Read one full line - fgets(buffer, MAX_BUFFER_SIZE, rFile); - - if (buffer[0] == '/') fprintf(rluaFile, "%s", buffer); // Direct copy of code comments - else if (strncmp(buffer, "RLAPI", 5) == 0) // raylib function declaration - { - char funcType[64]; - char funcTypeAux[64]; - char funcName[64]; - char funcDesc[256]; - - char params[128]; - char paramType[8][16]; - char paramName[8][32]; - - sscanf(buffer, "RLAPI %s %[^(]s", funcType, funcName); - - if (strcmp(funcType, "const") == 0) - { - sscanf(buffer, "RLAPI %s %s %[^(]s", funcType, funcTypeAux, funcName); - strcpy(funcType, "string"); - } - - if ((funcName[0] == '*') && (funcName[1] == '*')) strcpy(funcName, funcName + 2); - else if (funcName[0] == '*') strcpy(funcName, funcName + 1); - - int index = 0; - char *ptr = NULL; - - ptr = strchr(buffer, '('); - - if (ptr != NULL) index = (int)(ptr - buffer); - else printf("Character not found!\n"); - - sscanf(buffer + (index + 1), "%[^)]s", params); // Read what's inside '(' and ')' <-- CRASH after 128 iterations! - - ptr = strchr(buffer, '/'); - index = (int)(ptr - buffer); - - sscanf(buffer + index, "%[^\n]s", funcDesc); // Read function comment after declaration - - // Generate Lua function lua_FuncName() - //--------------------------------------- - fprintf(rluaFile, "%s\n", funcDesc); - - fprintf(rluaFile, "int lua_%s(lua_State *L)\n{\n", funcName); - - // Scan params string for number of func params, type and name - char *paramPtr[16]; // Allocate 16 pointers for possible parameters - int paramsCount = 0; - paramPtr[paramsCount] = strtok(params, ","); - - bool funcVoid = (strcmp(funcType, "void") == 0); - bool paramsVoid = false; - char paramConst[8][16]; - - int len = 0; - - while (paramPtr[paramsCount] != NULL) - { - sscanf(paramPtr[paramsCount], "%s %s\n", paramType[paramsCount], paramName[paramsCount]); - - if (paramName[paramsCount][0] == '*') strcpy(paramName[paramsCount], paramName[paramsCount] + 1); - - if (strcmp(paramType[paramsCount], "void") == 0) - { - paramsVoid = true; - break; - } - - if (strcmp(paramType[paramsCount], "const") == 0) - { - sscanf(paramPtr[paramsCount], "%s %s %s\n", paramConst[paramsCount], paramType[paramsCount], paramName[paramsCount]); - - if (paramName[paramsCount][0] == '*') strcpy(paramName[paramsCount], paramName[paramsCount] + 1); - - fprintf(rluaFile, " %s %s %s = LuaGetArgument_%s(L, %i);\n", paramConst[paramsCount], paramType[paramsCount], paramName[paramsCount], (strcmp(paramType[paramsCount], "char") == 0) ? "string" : paramType[paramsCount], paramsCount + 1); - } - else if (strcmp(paramType[paramsCount], "unsigned") == 0) - { - sscanf(paramPtr[paramsCount], "%s %s %s\n", paramConst[paramsCount], paramType[paramsCount], paramName[paramsCount]); - - if (paramName[paramsCount][0] == '*') strcpy(paramName[paramsCount], paramName[paramsCount] + 1); - - fprintf(rluaFile, " %s %s %s = LuaGetArgument_%s(L, %i);\n", paramConst[paramsCount], paramType[paramsCount], paramName[paramsCount], paramConst[paramsCount], paramsCount + 1); - } - //else if (strcmp(paramType[paramsCount], "...") == 0) - else fprintf(rluaFile, " %s %s = LuaGetArgument_%s(L, %i);\n", paramType[paramsCount], paramName[paramsCount], paramType[paramsCount], paramsCount + 1); - - paramsCount++; - paramPtr[paramsCount] = strtok(NULL, ","); - } - - if (funcVoid) fprintf(rluaFile, " %s(", funcName); - else fprintf(rluaFile, " %s result = %s(", funcType, funcName); - - if (!paramsVoid) - { - for (int i = 0; i < paramsCount - 1; i++) fprintf(rluaFile, "%s, ", paramName[i]); - fprintf(rluaFile, "%s", paramName[paramsCount - 1]); - } - - fprintf(rluaFile, ");\n"); - - if (!funcVoid) fprintf(rluaFile, " LuaPush_%s(L, result);\n", funcType); - - fprintf(rluaFile, " return %i;\n}\n\n", funcVoid ? 0:1); - - fflush(rluaFile); - - funcsCount++; - printf("Function processed %02i: %s\n", funcsCount, funcName); - - memset(buffer, 0, MAX_BUFFER_SIZE); - - // Register function names REG() into luaREG string - //-------------------------------------------------- - len += sprintf(luaREGPtr + len, " REG(%s)\n", funcName); - luaREGPtr += len; - - } - else if (strncmp(buffer, "typedef", 7) == 0) // raylib data type definition - { - char typeName[64]; - char typeDesc[256]; - - int paramsCount = 0; - char paramTypes[16][32] = {{ 0 }}; - char paramNames[16][32] = {{ 0 }}; - char paramDescs[16][128] = {{ 0 }}; - - if (strncmp(buffer + 8, "struct", 6) == 0) - { - - - sscanf(buffer, "typedef struct %s {", typeName); - - fgets(buffer, MAX_BUFFER_SIZE, rFile); // Read one new full line - - while (buffer[0] != '}') // Not closing structure type - { - if (buffer[0] != '\n') - { - sscanf(buffer, " %s %[^;]s %[^\n]s", ¶mTypes[paramsCount][0], ¶mNames[paramsCount][0], ¶mDescs[paramsCount][0]); - paramsCount++; - } - - fgets(buffer, MAX_BUFFER_SIZE, rFile); // Read one new full line - } - - // Generate LuaGetArgument functions - //----------------------------------- - fprintf(rluaFile, "static %s LuaGetArgument_%s(lua_State *L, int index)\n{\n", typeName, typeName); - fprintf(rluaFile, " %s result = { 0 };\n", typeName); - fprintf(rluaFile, " index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values\n"); - for (int i = 0; i < paramsCount; i++) - { - // TODO: Consider different types (LUA_TNUMBER, LUA_TTABLE) - fprintf(rluaFile, " luaL_argcheck(L, lua_getfield(L, index, \"%s\") == LUA_TNUMBER, index, \"Expected %s.%s\");\n", paramNames[i], typeName, paramNames[i]); - - // TODO: Consider different data types (lua_tonumber, LuaGetArgument_Vector3) - fprintf(rluaFile, " result.%s = LuaGetArgument_%s(L, -1);\n", paramNames[i], paramTypes[i]); - } - fprintf(rluaFile, " lua_pop(L, %i);\n", paramsCount); - fprintf(rluaFile, " return result;\n}\n\n"); - - // Generate LuaPush functions - // NOTE: LuaPush functions are written in a separate string buffer, that will be written to file at the end - //----------------------------------- - int len = 0; - len += sprintf(luaPushPtr + len, "static void LuaPush_%s(lua_State* L, %s obj)\n{\n", typeName, typeName); - len += sprintf(luaPushPtr + len, " lua_createtable(L, 0, %i);\n", paramsCount); - for (int i = 0; i < paramsCount; i++) - { - len += sprintf(luaPushPtr + len, " LuaPush_%s(L, obj.%s);\n", paramTypes[i], (paramNames[i][0] == '*') ? (paramNames[i] + 1) : paramNames[i]); - len += sprintf(luaPushPtr + len, " lua_setfield(L, -2, \"%s\");\n", paramNames[i]); - } - len += sprintf(luaPushPtr + len, "}\n\n"); - - luaPushPtr += len; - } - else if (strncmp(buffer + 8, "enum", 4) == 0) - { - //sscanf(buffer, "typedef enum {"); - //printf("enum detected!\n"); - - fgets(buffer, MAX_BUFFER_SIZE, rFile); // Read one new full line - fprintf(rluaFile, "LuaStartEnum();\n"); - - while (buffer[0] != '}') // Not closing structure type - { - if (buffer[0] != '\n') - { - sscanf(buffer, " %s", ¶mNames[paramsCount][0]); - fprintf(rluaFile, "LuaSetEnum(\"%s\", %s);\n", ¶mNames[paramsCount][0], ¶mNames[paramsCount][0]); - paramsCount++; - } - - fgets(buffer, MAX_BUFFER_SIZE, rFile); // Read one new full line - } - fprintf(rluaFile, "LuaEndEnum(\"name\");\n"); - } - } - } - - fprintf(rluaFile, "%s", luaPushFuncs); - fprintf(rluaFile, "// raylib Functions (and data types) list\nstatic luaL_Reg raylib_functions[] = {\n"); - fprintf(rluaFile, "%s\n", luaREG); - fprintf(rluaFile, " { NULL, NULL } // sentinel: end signal\n};"); - - free(buffer); - free(luaPushFuncs); - free(luaREG); - - fclose(rFile); - fclose(rluaFile); - - return 0; -} \ No newline at end of file diff --git a/tools/rLuaParser/rluaparser.lua b/tools/rLuaParser/rluaparser.lua new file mode 100755 index 0000000..9ba710d --- /dev/null +++ b/tools/rLuaParser/rluaparser.lua @@ -0,0 +1,1812 @@ +#!/usr/bin/env lua +--[[ ********************************************************************************************** + + rluaparser v6.0 - A simple raylib header parser to generate automatic Lua bindings + + FEATURES: + - Scans raylib.h to generate C binding header (raylib-lua.h) + - Generates LuaLS type annotations (_meta.lua) for full LSP support + - Hybrid type system with automatic resource management (__gc) + - Support for RAYLIB_STRIP_PREFIX global namespace toggle + + NOTES: + - Designed for raylib 6.0 and Lua 5.5 + - Resolves alias chains (e.g. Texture2D -> Texture) automatically + - TODO: Missing low-level callbacks: + - [ ] LoadFileData + - [ ] SaveFileData + - [ ] LoadFileText + - [ ] SaveFileText + - [ ] AudioCallback + - TODO: Generate type annotations for RAYLIB_STRIP_PREFIX + + DEPENDENCIES: + - Lua 5.5 (Standard library only, no external dependencies) + + USAGE: + lua rluaparser.lua [output.lua] + + LICENSE: zlib/libpng + + rluaparser is licensed under an unmodified zlib/libpng license, which is an OSI-certified, + BSD-like license that allows static linking with closed source software: + + Copyright (c) 2026 yilisharcs + + This software is provided "as-is", without any express or implied warranty. In no event + will the authors be held liable for any damages arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, including commercial + applications, and to alter it and redistribute it freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not claim that you + wrote the original software. If you use this software in a product, an acknowledgment + in the product documentation would be appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be misrepresented + as being the original software. + + 3. This notice may not be removed or altered from any source distribution. + +********************************************************************************************** ]] + +-- PARSER ====================================================================================== {{{ + +local Parser = {} + +function Parser.preprocess(text) + -- strip block comments + text = text:gsub("/%*.-%*/", "") + + local result, acc, line_nr = {}, {}, 0 + for raw_line in text:gmatch("([^\n]+)") do + line_nr = line_nr + 1 + local line = raw_line + + if line:match("^%s*//") then + -- standalone comment + local c = line:match("^%s*//(.+)$") + c = c and c:match("^%s*(.-)%s*$") + if c then + acc[#acc + 1] = c + end + else + -- collect trailing + local t_part, t_comment = line:match("^(.-)//(.+)$") + if t_part then + -- trim before + t_part = t_part:match("^%s*(.-)%s*$") + if #t_part > 0 then + -- trim after + local comment = t_comment:match("^%s*(.-)%s*$") + -- snapshots acc into notes, then resets + local notes = #acc > 0 and { table.unpack(acc) } or nil + acc = {} -- start fresh for next block + result[#result + 1] = { + text = t_part, + comment = comment, + notes = notes, + line = line_nr, + } + end + else + -- plain code. trim again + local trimmed = line:match("^%s*(.-)%s*$") + if #trimmed > 0 then + -- snapshots acc into notes, then resets + local notes = #acc > 0 and { table.unpack(acc) } or nil + acc = {} -- start fresh for next block + result[#result + 1] = { + text = trimmed, + notes = notes, + line = line_nr, + } + end + end + end + end + + return result +end + +-- keywords for type-name splitting +local C_KEYWORDS = { + bool = true, + char = true, + const = true, + double = true, + enum = true, + float = true, + int = true, + long = true, + short = true, + signed = true, + struct = true, + union = true, + unsigned = true, + void = true, +} + +-- split "unsigned char *name" into type="unsigned char *", name="name" +function Parser.split_type_name(s) + local tokens = {} + -- split by whitespace + for tok in s:gmatch("%S+") do + tokens[#tokens + 1] = tok + end + if #tokens == 0 then + return "", "" + end + + local name_tok = tokens[#tokens] + -- strip leading * from name, as they are pointer qualifiers on the type + local pointer_prefix = name_tok:match("^(%*+)") + if pointer_prefix then + name_tok = name_tok:sub(#pointer_prefix + 1) + end + if #name_tok == 0 or C_KEYWORDS[name_tok] then + return s, "" + end + + -- all tokens except last form the type; reattach any * prefixes + local type_tokens = {} + for i = 1, #tokens - 1 do + type_tokens[#type_tokens + 1] = tokens[i] + end + if pointer_prefix then + type_tokens[#type_tokens + 1] = pointer_prefix + end + return table.concat(type_tokens, " "), name_tok +end + +-- }}} + +-- SCANNERS ==================================================================================== {{{ +local matchers = { + -- RLAPI function declaration + { + match = function(line) + return line.text:match("^RLAPI") + end, + consume = function(lines, idx) + local line = lines[idx] + local retType, funcName, params = line.text:match("^RLAPI%s+(.-)%s*([%w_]+)%s*%((.-)%)%s*;%s*$") + if not retType then + io.stderr:write("WARN: failed to parse RLAPI: ", line.text, "\n") + return nil, 1 + end + local node = { + type = "function", + name = funcName, + retType = retType, + params = {}, + notes = line.notes, + comment = line.comment, + } + if params == "void" then + goto finalize + end + + for param in params:gmatch("[^,]+") do + local trimmed = param:match("^%s*(.-)%s*$") + if trimmed:match("^%.%.%.$") then + node.params[#node.params + 1] = { + name = "...", + isVariadic = true, + } + else + local pType, pName = Parser.split_type_name(trimmed) + node.params[#node.params + 1] = { + type = pType, + name = pName, + } + end + end + + ::finalize:: + + return node, 1 + end, + }, + -- typedef struct ... { ... } Name; + { + match = function(line) + return line.text:match("^typedef struct") and line.text:match("{") + end, + consume = function(lines, idx) + local line = lines[idx] + local structName = line.text:match("^typedef struct%s+([%w_]+)%s*{") + local fields = {} + local i = idx + 1 + while i <= #lines do + local l = lines[i] + local closeName = l.text:match("^}%s*([%w_]+)%s*;%s*$") + if closeName then + structName = structName or closeName + return { + type = "struct", + name = structName, + fields = fields, + notes = line.notes, + comment = line.comment, + }, + -- lines consumed: from typedef struct to closing } Name; + i - idx + 1 + end + local fieldText = l.text:match("^%s*(.-);%s*$") + if fieldText then + -- handle comma-separated fields like "float m0, m4, m8, m12;" + local clean = fieldText:gsub(",%s+", ",") + local fType, fNames = clean:match("^(.-)%s+([%w_,]+)%s*$") + if not fType then + fType, fNames = Parser.split_type_name(clean) + end + if fType and fNames then + for fName in fNames:gmatch("[^,]+") do + fields[#fields + 1] = { + type = fType, + name = fName, + comment = l.comment, + } + end + end + end + -- advance to next line in struct body + i = i + 1 + end + io.stderr:write("WARN: unclosed struct: ", line.text, "\n") + return nil, #lines - idx + 1 + end, + }, + -- typedef enum { ... } Name; + { + match = function(line) + return line.text:match("^typedef enum") and line.text:match("{") + end, + consume = function(lines, idx) + local line = lines[idx] + local text = line.text + local fields = {} + -- handle single-line typedef enum { a, b } Name; or typedef enum Name { a, b } Name; + local body, closeName = text:match("{(.-)}%s*([%w_]+)%s*;%s*$") + if closeName then + if closeName == "bool" then + return nil, 1 + end + for part in body:gmatch("[^,]+") do + local trimmed = part:match("^%s*(.-)%s*$") + local name, value = trimmed:match("^([%w_]+)%s*=%s*(.+)$") + if name then + fields[#fields + 1] = { name = name, value = value } + else + name = trimmed:match("^([%w_]+)%s*$") + if name then + fields[#fields + 1] = { + name = name, + value = nil, + } + end + end + end + return { + type = "enum", + name = closeName, + fields = fields, + notes = line.notes, + comment = line.comment, + }, + 1 + end + local i = idx + 1 + while i <= #lines do + local l = lines[i] + closeName = l.text:match("^}%s*([%w_]+)%s*;%s*$") + if closeName then + if closeName ~= "bool" then + return { + type = "enum", + name = closeName, + fields = fields, + notes = line.notes, + comment = line.comment, + }, + i - idx + 1 + end + return nil, i - idx + 1 + end + local fText = l.text:match("^%s*(.-),?%s*$") + if fText and #fText > 0 then + local name, value = fText:match("^([%w_]+)%s*=%s*(.+)$") + if name then + fields[#fields + 1] = { + name = name, + value = value, + comment = l.comment, + } + else + name = fText:match("^([%w_]+)%s*$") + if name then + fields[#fields + 1] = { + name = name, + value = nil, + comment = l.comment, + } + end + end + end + i = i + 1 + end + io.stderr:write("WARN: unclosed enum: ", text, "\n") + return nil, #lines - idx + 1 + end, + }, + -- #define NAME value + { + match = function(line) + local text = line.text + if not text:match("^#define") then + return false + elseif text:match("^#define%s+RL_") then + return false + elseif text:match("^#define%s+RAYLIB_H%s*$") then + return false + else + return true + end + end, + consume = function(lines, idx) + local line = lines[idx] + local name, value = line.text:match("^#define%s+([%w_]+)%s+(.*)$") + if not name then + return nil, 1 + end + -- filter function-like macros (value contains ( but not as leading expression) + -- e.g. __declspec(dllexport) vs (PI/180.0f) + if value:match("%S%(") and not value:match("CLITERAL") then + return nil, 1 + end + local category + if name:match("^RAYLIB_VERSION") then + category = "version" + elseif value:match("CLITERAL") then + category = "color" + elseif value:match('^"') then + category = "string" + elseif value:match("%.") or value:match("%df$") or value:match("^PI$") then + category = "float" + elseif value:match("^[%w_]+$") then + category = "alias" + else + category = "integer" + end + return { + type = "define", + name = name, + value = value, + category = category, + notes = line.notes, + comment = line.comment, + }, + 1 + end, + }, + -- typedef ; (alias, forward decl, or callback) + { + match = function(line) + local text = line.text + return text:match("^typedef") and not text:match("^typedef%s+(enum|struct)") + end, + consume = function(lines, idx) + local line = lines[idx] + local text = line.text + -- callback typedef: typedef (*)(); + if text:match("%(%*") then + local retType, cbName, params = text:match("^typedef%s+(.-)%s*%(%*([%w_]+)%)%s*%((.-)%)%s*;%s*$") + if retType and cbName then + local node = { + type = "function", + name = cbName, + retType = retType, + isCallback = true, + notes = line.notes, + comment = line.comment, + } + if params and params ~= "void" then + node.params = {} + for param in params:gmatch("[^,]+") do + local trimmed = param:match("^%s*(.-)%s*$") + local pType, pName = Parser.split_type_name(trimmed) + node.params[#node.params + 1] = { + type = pType, + name = pName, + } + end + end + return node, 1 + end + io.stderr:write("WARN: failed to parse callback typedef: ", text, "\n") + return nil, 1 + end + -- regular alias: typedef ; + local aliasedType, aliasName = text:match("^typedef%s+(.-)%s*([%w_]+)%s*;%s*$") + if aliasedType and aliasName then + aliasedType = aliasedType:match("^%s*(.-)%s*$") + return { + type = "alias", + name = aliasName, + aliasedType = aliasedType, + notes = line.notes, + comment = line.comment, + }, + 1 + end + io.stderr:write("WARN: failed to parse typedef: ", text, "\n") + return nil, 1 + end, + }, +} + +function Parser.scan(lines) + local ast = { + function_xs = {}, + struct_xs = {}, + enum_xs = {}, + define_xs = {}, + alias_xs = {}, + } + local idx = 1 + while idx <= #lines do + local line = lines[idx] + local matched = false + for _, m in ipairs(matchers) do + if m.match(line) then + local node, consumed = m.consume(lines, idx) + if node then + local key = node.type .. "_xs" + -- push node onto its type-specific list in the ast table + ast[key][#ast[key] + 1] = node + end + -- always consume + idx = idx + consumed + matched = true + break + end + end + if not matched then + if + -- blank lines + not line.text:match("^%s*$") + -- preproc conds + and not line.text:match("^#if") + and not line.text:match("^#else") + and not line.text:match("^#endif") + and not line.text:match("^#ifdef") + and not line.text:match("^#ifndef") + and not line.text:match("^#elif") + and not line.text:match("^#pragma") + and not line.text:match("^#error") + and not line.text:match("^#undef") + and not line.text:match("^#include") + -- unused defines + and not line.text:match("^#define%s+RAYLIB_H") + and not line.text:match("^#define%s+RL_%w+_TYPE%s*$") + and not line.text:match("^#define%s+RL_MALLOC") + and not line.text:match("^#define%s+RL_CALLOC") + and not line.text:match("^#define%s+RL_REALLOC") + and not line.text:match("^#define%s+RL_FREE") + and not line.text:match('^extern%s+"C"') + -- final closing brace + and not line.text:match("^}%s*$") + then + io.stderr:write("WARN: unrecognized: ", line.text, "\n") + end + idx = idx + 1 + end + end + return ast +end + +function Parser.analyze(ast) + -- build alias resolution map + local type_map = {} + for _, alias in ipairs(ast.alias_xs) do + type_map[alias.name] = alias.aliasedType + end + -- resolve alias chains (e.g. Color -> unsigned int -> stop) + for name, resolved in pairs(type_map) do + local seen = {} + while type_map[resolved] and not seen[resolved] do + seen[resolved] = true + resolved = type_map[resolved] + end + type_map[name] = resolved + end + ast.type_map = type_map + + -- fill sequential enum values + for _, enum in ipairs(ast.enum_xs) do + local val = 0 + for _, field in ipairs(enum.fields) do + if field.value == nil then + field.value = val + else + val = tonumber(field.value) or val + end + val = val + 1 + end + end + + -- classify mutated types + local mutated_types = {} + for _, f in ipairs(ast.function_xs) do + if f.name:match("^Unload") or f.name:match("^Export") then + goto next_func + end + for _, p in ipairs(f.params or {}) do + if not p.type then + goto next_param + end + local base = p.type:match("^(.-)%s*%*$") + if not base or base:match("const%s+") then + goto next_param + end + base = base:match("^%s*(.-)%s*$") + mutated_types[base] = true + ::next_param:: + end + ::next_func:: + end + + -- resolve mutated aliases to base types + for name, _ in pairs(mutated_types) do + local resolved = type_map[name] + if resolved then + mutated_types[resolved] = true + end + end + ast.mutated_types = mutated_types +end +-- }}} + +-- C EMITTER =================================================================================== {{{ + +-- value types: structs passed by value (Lua tables) +local VALUE_STRUCTS = { + -- math + Matrix = true, + Quaternion = true, + Vector2 = true, + Vector3 = true, + Vector4 = true, + -- geometry and color + Color = true, + Rectangle = true, + -- cameras + Camera = true, + Camera2D = true, + Camera3D = true, + -- collision + BoundingBox = true, + Ray = true, + RayCollision = true, + -- asset + GlyphInfo = true, + NPatchInfo = true, + -- nested and auxiliary types + BoneInfo = true, + MaterialMap = true, + ModelSkeleton = true, + Transform = true, + -- system and VR + AutomationEvent = true, + AutomationEventList = true, + FilePathList = true, + VrDeviceInfo = true, + VrStereoConfig = true, +} + +-- resource types: structs passed by pointer with __gc/unload +local RESOURCE_TYPES = { + -- visual + Image = "UnloadImage", + RenderTexture = "UnloadRenderTexture", + RenderTexture2D = "UnloadRenderTexture", + Texture = "UnloadTexture", + Texture2D = "UnloadTexture", + TextureCubemap = "UnloadTexture", + -- 3D + Mesh = "UnloadMesh", + Model = "UnloadModel", + ModelAnimation = "", -- Requires count for unloading, skip __gc for now + -- audio + AudioStream = "UnloadAudioStream", + Music = "UnloadMusicStream", + Sound = "UnloadSound", + Wave = "UnloadWave", + -- other + Font = "UnloadFont", + Material = "UnloadMaterial", + Shader = "UnloadShader", +} + +-- stylua: ignore +local PRIMITIVE_TYPES = { + int = { check = "(int)luaL_checkinteger", push = "lua_pushinteger" }, + float = { check = "(float)luaL_checknumber", push = "lua_pushnumber" }, + bool = { check = "lua_toboolean", push = "lua_pushboolean" }, + double = { check = "luaL_checknumber", push = "lua_pushnumber" }, + long = { check = "(long)luaL_checkinteger", push = "lua_pushinteger" }, + unsigned = { check = "(unsigned)luaL_checkinteger", push = "lua_pushinteger" }, + unsigned_int = { check = "(unsigned int)luaL_checkinteger", push = "lua_pushinteger" }, + unsigned_char = { check = "(unsigned char)luaL_checkinteger", push = "lua_pushinteger" }, + char = { check = "(char)luaL_checkinteger", push = "lua_pushinteger" }, + unsigned_short = { check = "(unsigned short)luaL_checkinteger", push = "lua_pushinteger" }, + short = { check = "(short)luaL_checkinteger", push = "lua_pushinteger" }, + const_char_ptr = { check = "luaL_checkstring", push = "lua_pushstring" }, + char_ptr = { check = "luaL_checkstring", push = "lua_pushstring" }, + void_ptr = { check = "lua_touserdata", push = "lua_pushlightuserdata" }, + unsigned_char_ptr = { check = "(unsigned char *)lua_touserdata", push = "lua_pushlightuserdata" }, + const_unsigned_char_ptr = { check = "(const unsigned char *)lua_touserdata", push = "lua_pushlightuserdata" }, +} + +-- normalize "const char *" -> "const_char_ptr" +function Parser.normalizeType(t) + if not t then + return "" + else + return t:gsub("%s*%*%s*", "_ptr"):gsub("%s+", "_"):gsub("_+", "_"):gsub("^_", ""):gsub("_$", "") + end +end + +function Parser.getCheckExpression(normType, rawType, index) + if PRIMITIVE_TYPES[normType] then + return ("%s(L, %d)"):format(PRIMITIVE_TYPES[normType].check, index) + elseif normType:match("_ptr$") or normType:match("Callback$") then + return ("(%s)lua_touserdata(L, %d)"):format(rawType, index) + elseif RESOURCE_TYPES[normType] then + return ('*(%s*)RLUA_CHECK_Resource(L, %d, "%s")'):format(rawType, index, normType) + else + return ("RLUA_CHECK_%s(L, %d)"):format(normType, index) + end +end + +function Parser.getPushStatement(normType, rawType, source) + if PRIMITIVE_TYPES[normType] then + return ("%s(L, %s);"):format(PRIMITIVE_TYPES[normType].push, source) + elseif normType:match("_ptr$") then + return ("lua_pushlightuserdata(L, %s);"):format(source) + elseif RESOURCE_TYPES[normType] then + return ('RLUA_PUSH_Resource(L, &%s, sizeof(%s), "%s");'):format(source, rawType, normType) + else + return ("RLUA_PUSH_%s(L, %s);"):format(normType, source) + end +end + +-- render function wrapper +function Parser.renderFunction(func) + local t = {} + for _, note in ipairs(func.notes or {}) do + t[#t + 1] = ("// %s"):format(note) + end + + -- discard typedefs but keep the comments + if func.isCallback then + if #t > 0 then + return table.concat(t, "\n") .. "\n" + else + return nil + end + end + + if func.comment then + t[#t + 1] = ("// %s"):format(func.comment) + end + t[#t + 1] = ("static int rl_%s(lua_State *L)"):format(func.name) + t[#t + 1] = "{" + + if func.name == "SetTraceLogCallback" then + t[#t + 1] = [[ + if (lua_isnil(L, 1)) { + if (RLUA_LogRef != LUA_REFNIL) { + luaL_unref(L, LUA_REGISTRYINDEX, RLUA_LogRef); + RLUA_LogRef = LUA_REFNIL; + } + SetTraceLogCallback(NULL); + } else { + luaL_checktype(L, 1, LUA_TFUNCTION); + if (RLUA_LogRef != LUA_REFNIL) luaL_unref(L, LUA_REGISTRYINDEX, RLUA_LogRef); + lua_pushvalue(L, 1); + RLUA_LogRef = luaL_ref(L, LUA_REGISTRYINDEX); + SetTraceLogCallback(RLUA_TraceLogTrampoline); + } + return 0; +} +]] + t[#t + 1] = "" + return table.concat(t, "\n") + end + + local isVariadic = false + for _, p in ipairs(func.params or {}) do + if p.isVariadic then + isVariadic = true + break + end + end + + if isVariadic then + if func.name == "TraceLog" then + t[#t + 1] = + -- c + [[ + int n = lua_gettop(L); + if (n < 2) return luaL_error(L, "TraceLog requires at least 2 arguments"); + int logLevel = (int)luaL_checkinteger(L, 1); + if (n == 2) { + TraceLog(logLevel, "%s", luaL_checkstring(L, 2)); + } else { + lua_getglobal(L, "string"); + lua_getfield(L, -1, "format"); + for (int i = 2; i <= n; i++) lua_pushvalue(L, i); + lua_call(L, n - 1, 1); + TraceLog(logLevel, "%s", lua_tostring(L, -1)); + lua_pop(L, 2); + } + return 0;]] + elseif func.name == "TextFormat" then + t[#t + 1] = + -- c + [[ + int n = lua_gettop(L); + if (n < 1) return luaL_error(L, "TextFormat requires at least 1 argument"); + if (n == 1) { + lua_pushstring(L, TextFormat("%s", luaL_checkstring(L, 1))); + } else { + lua_getglobal(L, "string"); + lua_getfield(L, -1, "format"); + for (int i = 1; i <= n; i++) lua_pushvalue(L, i); + lua_call(L, n, 1); + const char *formatted = lua_tostring(L, -1); + lua_pushstring(L, TextFormat("%s", formatted)); + lua_insert(L, 1); + lua_settop(L, 1); + } + return 1;]] + else + t[#t + 1] = (" // TODO: Hand-write variadic wrapper for %s"):format(func.name) + t[#t + 1] = " return 0;" + end + else + -- check for "pointer return + out-param count" pattern + local retNorm = Parser.normalizeType(func.retType) + local countParam = nil + if func.retType:match("%*$") then + for _, p in ipairs(func.params or {}) do + if p.type == "int *" or p.type == "unsigned int *" then + countParam = p + break + end + end + end + + -- check for value-struct mutation candidates + local mutates = {} + if func.name:match("^Unload") or func.name:match("^Export") then + goto end_mutates + end + for i, p in ipairs(func.params or {}) do + local base = p.type:match("^(.-)%s*%*$") + if not base or base:match("const%s+") then + goto next_mutate + end + base = base:match("^%s*(.-)%s*$") + if VALUE_STRUCTS[base] then + mutates[i] = base + end + ::next_mutate:: + end + ::end_mutates:: + + -- unpack arguments from the Lua stack + for i, p in ipairs(func.params or {}) do + if p == countParam then + t[#t + 1] = (" int %s = 0;"):format(p.name) + elseif mutates[i] then + t[#t + 1] = (" %s %s = RLUA_CHECK_%s(L, %d);"):format(mutates[i], p.name, mutates[i], i) + else + local pNorm = Parser.normalizeType(p.type) + local expr = Parser.getCheckExpression(pNorm, p.type, i) + local declType = p.type + if pNorm == "char_ptr" or pNorm == "const_char_ptr" then + declType = "const char *" + end + t[#t + 1] = (" %s %s = %s;"):format(declType, p.name, expr) + end + end + + -- construct the raylib C function call + local callArgs = {} + for i, p in ipairs(func.params or {}) do + if p == countParam then + callArgs[#callArgs + 1] = "&" .. p.name + elseif mutates[i] then + callArgs[#callArgs + 1] = "&" .. p.name + else + local arg = p.name + local pNorm = Parser.normalizeType(p.type) + if pNorm == "char_ptr" then + arg = ("(%s)%s"):format(p.type, p.name) + end + callArgs[#callArgs + 1] = arg + end + end + local args = table.concat(callArgs, ", ") + + if retNorm == "void" then + t[#t + 1] = (" %s(%s);"):format(func.name, args) + for i, p in ipairs(func.params or {}) do + if mutates[i] then + t[#t + 1] = (" RLUA_WRITEBACK_%s(L, %d, %s);"):format(mutates[i], i, p.name) + end + end + t[#t + 1] = " return 0;" + else + t[#t + 1] = (" %s result = %s(%s);"):format(func.retType, func.name, args) + for i, p in ipairs(func.params or {}) do + if mutates[i] then + t[#t + 1] = (" RLUA_WRITEBACK_%s(L, %d, %s);"):format(mutates[i], i, p.name) + end + end + if countParam then + local baseType = func.retType:gsub("%s*%*$", "") + t[#t + 1] = (' RLUA_PUSH_View(L, result, %s, "%s", true);'):format(countParam.name, baseType) + t[#t + 1] = " return 1;" + else + t[#t + 1] = " " .. Parser.getPushStatement(retNorm, func.retType, "result") + t[#t + 1] = " return 1;" + end + end + end + + t[#t + 1] = "}" + t[#t + 1] = "" + return table.concat(t, "\n") +end + +-- render struct check (table -> C struct) +function Parser.renderStructCheck(struct) + local t = {} + if struct.notes then + for _, note in ipairs(struct.notes) do + t[#t + 1] = ("// %s"):format(note) + end + end + t[#t + 1] = ("static %s RLUA_CHECK_%s(lua_State *L, int index)"):format(struct.name, struct.name) + t[#t + 1] = "{" + t[#t + 1] = (" %s result = { 0 };"):format(struct.name) + t[#t + 1] = " if (lua_istable(L, index)) {" + + local sorted = {} + for i, f in ipairs(struct.fields or {}) do + sorted[#sorted + 1] = { field = f, index = i } + end + table.sort(sorted, function(a, b) + local na = a.field.name:match("^m(%d+)$") + local nb = b.field.name:match("^m(%d+)$") + if na and nb then + return tonumber(na) < tonumber(nb) + end + return a.index < b.index + end) + + for _, entry in ipairs(sorted) do + local field = entry.field + local name, array_size = field.name:match("([%w_]+)%[(%d+)%]") + if not name then + t[#t + 1] = (' lua_getfield(L, index, "%s");'):format(field.name) + local fNorm = Parser.normalizeType(field.type) + local expr = Parser.getCheckExpression(fNorm, field.type, -1) + local comment = field.comment and (" // %s"):format(field.comment) or "" + t[#t + 1] = (" result.%s = %s;%s"):format(field.name, expr, comment) + t[#t + 1] = " lua_pop(L, 1);" + else + t[#t + 1] = (' lua_getfield(L, index, "%s");'):format(name) + if field.type == "char" then + local comment = field.comment and (" // %s"):format(field.comment) or "" + t[#t + 1] = (" if (lua_isstring(L, -1)) { strncpy(result.%s, lua_tostring(L, -1), %s - 1); }%s"):format( + name, + array_size, + comment + ) + else + t[#t + 1] = " if (lua_istable(L, -1)) {" + t[#t + 1] = (" for (int i = 0; i < %s; i++) {"):format(array_size) + t[#t + 1] = " lua_geti(L, -1, i + 1);" + local fNorm = Parser.normalizeType(field.type) + local expr = Parser.getCheckExpression(fNorm, field.type, -1) + t[#t + 1] = (" result.%s[i] = %s;"):format(name, expr) + t[#t + 1] = " lua_pop(L, 1);" + t[#t + 1] = " }" + t[#t + 1] = " }" + end + t[#t + 1] = " lua_pop(L, 1);" + end + end + + t[#t + 1] = " }" + t[#t + 1] = " return result;" + t[#t + 1] = "}" + return table.concat(t, "\n") +end + +-- render struct push (C struct -> Lua table) +function Parser.renderStructPush(struct) + local t = {} + t[#t + 1] = ("static void RLUA_PUSH_%s(lua_State *L, %s result)"):format(struct.name, struct.name) + t[#t + 1] = "{" + t[#t + 1] = (" lua_createtable(L, 0, %d);"):format(#(struct.fields or {})) + + local sorted = {} + for i, f in ipairs(struct.fields or {}) do + sorted[#sorted + 1] = { field = f, index = i } + end + table.sort(sorted, function(a, b) + local na = a.field.name:match("^m(%d+)$") + local nb = b.field.name:match("^m(%d+)$") + if na and nb then + return tonumber(na) < tonumber(nb) + end + return a.index < b.index + end) + + for _, entry in ipairs(sorted) do + local field = entry.field + local name, array_size = field.name:match("([%w_]+)%[(%d+)%]") + if not name then + local fNorm = Parser.normalizeType(field.type) + local comment = field.comment and (" // %s"):format(field.comment) or "" + t[#t + 1] = " " .. Parser.getPushStatement(fNorm, field.type, "result." .. field.name) .. comment + t[#t + 1] = (' lua_setfield(L, -2, "%s");'):format(field.name) + else + if field.type == "char" then + local comment = field.comment and (" // %s"):format(field.comment) or "" + t[#t + 1] = (" lua_pushstring(L, result.%s);%s"):format(name, comment) + t[#t + 1] = (' lua_setfield(L, -2, "%s");'):format(name) + else + t[#t + 1] = (" lua_createtable(L, %s, 0);"):format(array_size) + t[#t + 1] = (" for (int i = 0; i < %s; i++) {"):format(array_size) + local fNorm = Parser.normalizeType(field.type) + t[#t + 1] = " " .. Parser.getPushStatement(fNorm, field.type, "result." .. name .. "[i]") + t[#t + 1] = " lua_seti(L, -2, i + 1);" + t[#t + 1] = " }" + t[#t + 1] = (' lua_setfield(L, -2, "%s");'):format(name) + end + end + end + + t[#t + 1] = "}" + return table.concat(t, "\n") +end + +-- render struct writeback (C struct -> Lua table) +function Parser.renderStructWriteback(struct, ast) + local t = {} + t[#t + 1] = ("static void RLUA_WRITEBACK_%s(lua_State *L, int index, %s val)"):format(struct.name, struct.name) + t[#t + 1] = "{" + t[#t + 1] = " if (lua_istable(L, index)) {" + + local sorted = {} + for i, f in ipairs(struct.fields or {}) do + sorted[#sorted + 1] = { field = f, index = i } + end + table.sort(sorted, function(a, b) + local na = a.field.name:match("^m(%d+)$") + local nb = b.field.name:match("^m(%d+)$") + if na and nb then + return tonumber(na) < tonumber(nb) + end + return a.index < b.index + end) + + for _, entry in ipairs(sorted) do + local f = entry.field + local fNorm = Parser.normalizeType(f.type) + local comment = f.comment and (" // %s"):format(f.comment) or "" + if PRIMITIVE_TYPES[fNorm] then + t[#t + 1] = " " .. Parser.getPushStatement(fNorm, f.type, "val." .. f.name) .. comment + t[#t + 1] = (' lua_setfield(L, index, "%s");'):format(f.name) + elseif VALUE_STRUCTS[fNorm] then + t[#t + 1] = (" RLUA_PUSH_%s(L, val.%s);%s"):format(fNorm, f.name, comment) + t[#t + 1] = (' lua_setfield(L, index, "%s");'):format(f.name) + elseif ast.type_map[f.type] then + local resolved = ast.type_map[f.type] + local rNorm = Parser.normalizeType(resolved) + if PRIMITIVE_TYPES[rNorm] then + t[#t + 1] = " " .. Parser.getPushStatement(rNorm, resolved, "val." .. f.name) .. comment + t[#t + 1] = (' lua_setfield(L, index, "%s");'):format(f.name) + end + end + end + t[#t + 1] = " }" + t[#t + 1] = "}" + return table.concat(t, "\n") +end + +-- render function registry (luaL_Reg array) +function Parser.renderFunctionRegistry(ast) + local function_names = {} + for _, f in ipairs(ast.function_xs) do + function_names[f.name] = true + end + + local t = { + "// raylib functions list", + "static const struct luaL_Reg raylib_functions[] = {", + } + for _, f in ipairs(ast.function_xs) do + if not f.isCallback then + t[#t + 1] = (' {"%s", rl_%s},'):format(f.name, f.name) + end + end + for _, d in ipairs(ast.define_xs) do + if d.category == "alias" and function_names[d.value] then + t[#t + 1] = (' {"%s", rl_%s},'):format(d.name, d.value) + end + end + t[#t + 1] = "" + t[#t + 1] = " { NULL, NULL } // sentinel" + t[#t + 1] = "};" + t[#t + 1] = "" + return table.concat(t, "\n") +end + +-- render constants registry +function Parser.renderDefineRegistry(ast) + local function_names = {} + for _, f in ipairs(ast.function_xs) do + function_names[f.name] = true + end + + local t = { "static void rLuaRegisterConstants(lua_State *L)", "{" } + + -- enum constants + for _, enum in ipairs(ast.enum_xs) do + for _, field in ipairs(enum.fields) do + local v = field.value + if type(v) == "string" then + v = tonumber(v) or v + end + if type(v) == "number" then + t[#t + 1] = (" lua_pushinteger(L, %d);"):format(v) + else + t[#t + 1] = (" lua_pushinteger(L, %s);"):format(tostring(v)) + end + t[#t + 1] = (' lua_setfield(L, -2, "%s");'):format(field.name) + end + end + + -- #define constants + for _, d in ipairs(ast.define_xs) do + if d.category == "alias" and function_names[d.value] then + goto continue_def + end + + if d.category == "version" then + goto continue_def + end + + local pusher = "lua_pushinteger" + if d.category == "float" then + pusher = "lua_pushnumber" + elseif d.category == "string" then + pusher = "lua_pushstring" + elseif d.category == "color" then + pusher = "RLUA_PUSH_Color" + end + + t[#t + 1] = (" %s(L, %s);"):format(pusher, d.value) + t[#t + 1] = (' lua_setfield(L, -2, "%s");'):format(d.name) + + ::continue_def:: + end + + t[#t + 1] = "}" + t[#t + 1] = "" + return table.concat(t, "\n") +end + +-- resource destructors (__gc) +function Parser.renderDestructors() + local t = { "// --- Resource Destructors (__gc) ---", "" } + local sorted = {} + for name, func in pairs(RESOURCE_TYPES) do + if func ~= "" then + sorted[#sorted + 1] = { name = name, func = func } + end + end + table.sort(sorted, function(a, b) + return a.name < b.name + end) + + for _, item in ipairs(sorted) do + t[#t + 1] = ("static int rl_%s_gc(lua_State *L)"):format(item.name) + t[#t + 1] = "{" + t[#t + 1] = (' RLUA_Handle *h = (RLUA_Handle *)luaL_checkudata(L, 1, "%s");'):format(item.name) + t[#t + 1] = " if (h->data && h->owned) {" + t[#t + 1] = (" %s(*(%s*)h->data);"):format(item.func, item.name) + t[#t + 1] = " RL_FREE(h->data);" + t[#t + 1] = " }" + t[#t + 1] = " return 0;" + t[#t + 1] = "}" + t[#t + 1] = "" + end + return table.concat(t, "\n") +end + +-- resource indexers (__index) +function Parser.renderIndexers(ast) + local structs_by_name = {} + for _, s in ipairs(ast.struct_xs) do + structs_by_name[s.name] = s + end + + local t = { "// --- Resource Indexers (__index) ---", "" } + local sorted = {} + for name, _ in pairs(RESOURCE_TYPES) do + sorted[#sorted + 1] = name + end + table.sort(sorted) + + for _, tname in ipairs(sorted) do + local struct = structs_by_name[tname] + if struct then + t[#t + 1] = ("static int rl_%s_index(lua_State *L)"):format(tname) + t[#t + 1] = "{" + t[#t + 1] = (' RLUA_Handle *h = (RLUA_Handle *)luaL_checkudata(L, 1, "%s");'):format(tname) + t[#t + 1] = " if (lua_isnumber(L, 2)) {" + t[#t + 1] = " int i = lua_tointeger(L, 2) - 1;" + t[#t + 1] = ' if (i < 0 || i >= h->count) return luaL_error(L, "index out of bounds");' + t[#t + 1] = (" %s *ptr = &((%s *)h->data)[i];"):format(tname, tname) + t[#t + 1] = (' RLUA_PUSH_View(L, ptr, 1, "%s", false);'):format(tname) + t[#t + 1] = " return 1;" + t[#t + 1] = " }" + t[#t + 1] = " const char *key = luaL_checkstring(L, 2);" + t[#t + 1] = (" %s *data = (%s *)h->data;"):format(tname, tname) + + for _, field in ipairs(struct.fields or {}) do + if not field.name:match("%[") then + local comment = field.comment and (" // %s"):format(field.comment) or "" + t[#t + 1] = (' if (strcmp(key, "%s") == 0) {%s'):format(field.name, comment) + local fNorm = Parser.normalizeType(field.type) + if VALUE_STRUCTS[fNorm] then + t[#t + 1] = (" RLUA_PUSH_%s(L, data->%s);"):format(field.type, field.name) + elseif RESOURCE_TYPES[fNorm] then + t[#t + 1] = (' RLUA_PUSH_View(L, &data->%s, 1, "%s", false);'):format(field.name, fNorm) + else + t[#t + 1] = " " .. Parser.getPushStatement(fNorm, field.type, "data->" .. field.name) + end + t[#t + 1] = " return 1;" + t[#t + 1] = " }" + end + end + t[#t + 1] = " return 0;" + t[#t + 1] = "}" + t[#t + 1] = "" + end + end + return table.concat(t, "\n") +end + +-- metatable registries +function Parser.renderMetatableRegistries(ast) + local structs_by_name = {} + for _, s in ipairs(ast.struct_xs) do + structs_by_name[s.name] = s + end + + local t = { "static void rLuaRegisterMetatables(lua_State *L)", "{" } + local sorted = {} + for name, _ in pairs(RESOURCE_TYPES) do + sorted[#sorted + 1] = name + end + table.sort(sorted) + + for _, tname in ipairs(sorted) do + t[#t + 1] = (' luaL_newmetatable(L, "%s");'):format(tname) + if structs_by_name[tname] then + t[#t + 1] = (" lua_pushcfunction(L, rl_%s_index);"):format(tname) + t[#t + 1] = ' lua_setfield(L, -2, "__index");' + end + local func = RESOURCE_TYPES[tname] + if func ~= "" then + t[#t + 1] = (" lua_pushcfunction(L, rl_%s_gc);"):format(tname) + t[#t + 1] = ' lua_setfield(L, -2, "__gc");' + end + t[#t + 1] = " lua_pop(L, 1);" + t[#t + 1] = "" + end + + t[#t + 1] = "}" + return table.concat(t, "\n") +end + +-- type alias marshallers (Camera -> Camera3D, Quaternion -> Vector4, etc.) +function Parser.renderTypeAliases(ast) + local structs_by_name = {} + for _, s in ipairs(ast.struct_xs) do + structs_by_name[s.name] = s + end + + local t = {} + local sorted = {} + for name in pairs(ast.type_map) do + sorted[#sorted + 1] = name + end + table.sort(sorted) + for _, aliasName in ipairs(sorted) do + local resolvedType = ast.type_map[aliasName] + if RESOURCE_TYPES[resolvedType] then + t[#t + 1] = ('#define RLUA_CHECK_%s(L, idx) (*(%s*)RLUA_CHECK_Resource(L, idx, "%s"))'):format( + aliasName, + aliasName, + resolvedType + ) + t[#t + 1] = ('#define RLUA_PUSH_%s(L, val) RLUA_PUSH_Resource(L, &val, sizeof(%s), "%s")'):format( + aliasName, + aliasName, + resolvedType + ) + elseif structs_by_name[resolvedType] then + t[#t + 1] = ("#define RLUA_CHECK_%s RLUA_CHECK_%s"):format(aliasName, resolvedType) + t[#t + 1] = ("#define RLUA_PUSH_%s RLUA_PUSH_%s"):format(aliasName, resolvedType) + if ast.mutated_types[aliasName] or ast.mutated_types[resolvedType] then + t[#t + 1] = ("#define RLUA_WRITEBACK_%s RLUA_WRITEBACK_%s"):format(aliasName, resolvedType) + end + elseif resolvedType:match("%*$") then + local base = resolvedType:gsub("%s*%*$", "") + if structs_by_name[base] then + t[#t + 1] = ('#define RLUA_CHECK_%s(L, idx) (%s)RLUA_CHECK_Resource(L, idx, "%s")'):format( + aliasName, + aliasName, + base + ) + t[#t + 1] = ('#define RLUA_PUSH_%s(L, val) RLUA_PUSH_View(L, val, 1, "%s", false)'):format( + aliasName, + base + ) + end + end + end + return table.concat(t, "\n") +end + +function Parser.emit_c(ast, out) + local sections = {} + + -- header (boilerplate before implementation) + sections[#sections + 1] = string.format( + -- c + [[ +/********************************************************************************************** +* +* raylib-lua v6.0 - raylib Lua bindings for raylib v6.0 +* +* AUTO-GENERATED by tools/rLuaParser/rluaparser.lua +* +* Parsed: %d functions, %d structs, %d enums, %d defines, %d aliases +* +* NOTES: +* +* The following types are treated as Lua tables with named fields, same as in C: +* Matrix, Vector2, Vector3, Vector4, Color, Rectangle, Ray, Camera, BoundingBox +* +* The following types are opaque userdata with field access and automatic memory management (__gc): +* Image, Texture2D, RenderTexture2D, Mesh, Model, Shader, Font, Sound, Music, Wave +* +* Remember that ALL raylib types have REFERENCE SEMANTICS in Lua. +* Tables (value types) are passed to C by copying fields, but multiple references +* on the Lua side point to the same table object. +* +* Some raylib functions take pointers to objects to modify (e.g. UpdateCamera(), etc.) +* For table-based types like Camera, the binding automatically writes modified fields +* back to the original Lua table. For resource types like Image, changes are made +* directly to the memory block. +* +* CONTRIBUTORS: +* Ghassan Al-Mashareqa (ghassan@ghassan.pl): Original binding creation (for raylib 1.3) +* Ramon Santamaria (@raysan5): Review, update and maintenance +* yilisharcs: Modernization and automatic generator (for raylib 6.0) +* +* LICENSE: zlib/libpng +* +* Copyright (c) 2015-2017 Ghassan Al-Mashareqa and Ramon Santamaria (@raysan5) +* Copyright (c) 2026 yilisharcs +* +* This software is provided "as-is", without any express or implied warranty. In no event +* will the authors be held liable for any damages arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, including commercial +* applications, and to alter it and redistribute it freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not claim that you +* wrote the original software. If you use this software in a product, an acknowledgment +* in the product documentation would be appreciated but is not required. +* +* 2. Altered source versions must be plainly marked as such, and must not be misrepresented +* as being the original software. +* +* 3. This notice may not be removed or altered from any source distribution. +* +**********************************************************************************************/ + +#pragma once + +#include +#include +#include + +#ifdef RLUA_STATIC + #define RLUADEF static // Functions just visible to module including this file +#else + #ifdef __cplusplus + #define RLUADEF extern "C" // Functions visible from other files (no name mangling of functions in C++) + #else + #define RLUADEF extern // Functions visible from other files + #endif +#endif + +RLUADEF lua_State *rlua_open(void); +RLUADEF void rlua_close(lua_State *L); +]], + #ast.function_xs, + #ast.struct_xs, + #ast.enum_xs, + #ast.define_xs, + #ast.alias_xs + ) + + sections[#sections + 1] = + -- c + [[ +#ifdef RLUA_IMPLEMENTATION +#include "raylib.h" +#include +#include +#include +#include // Required for: va_list - Only used by TraceLogCallback +#include + +// --- Global State --- +static lua_State *RLUA_State = NULL; +static int RLUA_LogRef = LUA_REFNIL; +static pthread_mutex_t RLUA_LogMutex = PTHREAD_MUTEX_INITIALIZER; + +// --- Marshalling Helpers --- + +typedef struct { + void *data; + int count; + const char *tname; + bool owned; +} RLUA_Handle; + +static void* RLUA_CHECK_Resource(lua_State *L, int index, const char *tname) { + RLUA_Handle *h = (RLUA_Handle *)luaL_checkudata(L, index, tname); + return h->data; +} + +static void RLUA_PUSH_Resource(lua_State *L, void *data, size_t size, const char *tname) { + RLUA_Handle *h = (RLUA_Handle *)lua_newuserdata(L, sizeof(RLUA_Handle)); + h->data = RL_MALLOC(size); + memcpy(h->data, data, size); + h->count = 1; + h->tname = tname; + h->owned = true; + luaL_setmetatable(L, tname); +} + +static void RLUA_PUSH_View(lua_State *L, const void *data, int count, const char *tname, bool owned) { + RLUA_Handle *h = (RLUA_Handle *)lua_newuserdata(L, sizeof(RLUA_Handle)); + h->data = (void *)data; + h->count = count; + h->tname = tname; + h->owned = owned; + luaL_setmetatable(L, tname); +} + +// --- Callback Trampolines --- +static void RLUA_TraceLogTrampoline(int logLevel, const char *text, va_list args) { + if (!RLUA_State || RLUA_LogRef == LUA_REFNIL) return; + char buffer[1024]; + vsnprintf(buffer, sizeof(buffer), text, args); + pthread_mutex_lock(&RLUA_LogMutex); + lua_State *L = RLUA_State; + lua_rawgeti(L, LUA_REGISTRYINDEX, RLUA_LogRef); + lua_pushinteger(L, logLevel); + lua_pushstring(L, buffer); + if (lua_pcall(L, 2, 0, 0) != LUA_OK) { + TraceLog(LOG_ERROR, "LUA: TraceLogCallback: %s", lua_tostring(L, -1)); + lua_pop(L, 1); + } + pthread_mutex_unlock(&RLUA_LogMutex); +} +]] + + -- type aliases + local aliases = Parser.renderTypeAliases(ast) + if #aliases > 0 then + sections[#sections + 1] = "// --- Type Aliases ---\n" + sections[#sections + 1] = aliases + sections[#sections + 1] = "\n" + end + + -- generated struct marshallers + sections[#sections + 1] = "// --- Generated Marshallers ---\n" + for _, s in ipairs(ast.struct_xs) do + if VALUE_STRUCTS[s.name] then + sections[#sections + 1] = Parser.renderStructCheck(s) + sections[#sections + 1] = Parser.renderStructPush(s) + if ast.mutated_types[s.name] then + sections[#sections + 1] = Parser.renderStructWriteback(s, ast) + end + sections[#sections + 1] = "\n" + end + end + + -- destructors + sections[#sections + 1] = Parser.renderDestructors() + + -- indexers + sections[#sections + 1] = Parser.renderIndexers(ast) + + -- function wrappers + sections[#sections + 1] = "// --- Wrappers ---\n" + for _, f in ipairs(ast.function_xs) do + sections[#sections + 1] = Parser.renderFunction(f) + end + + -- registries + sections[#sections + 1] = "// --- Registries ---\n" + sections[#sections + 1] = Parser.renderMetatableRegistries(ast) + sections[#sections + 1] = Parser.renderDefineRegistry(ast) + sections[#sections + 1] = Parser.renderFunctionRegistry(ast) + + -- rlua_open / rlua_close + sections[#sections + 1] = + -- c + [[ +RLUADEF lua_State *rlua_open(void) { + lua_State *L = luaL_newstate(); + luaL_openlibs(L); + + RLUA_State = L; + rLuaRegisterMetatables(L); + +#ifdef RAYLIB_STRIP_PREFIX + // Register functions as globals + lua_pushglobaltable(L); + luaL_setfuncs(L, raylib_functions, 0); + lua_pop(L, 1); + + // Register constants as globals + lua_pushglobaltable(L); + rLuaRegisterConstants(L); + lua_pop(L, 1); + + // rl table mirrors globals via __index = _G + lua_newtable(L); + lua_newtable(L); + lua_pushglobaltable(L); + lua_setfield(L, -2, "__index"); + lua_setmetatable(L, -2); + lua_setglobal(L, "rl"); +#else + lua_newtable(L); + rLuaRegisterConstants(L); + luaL_setfuncs(L, raylib_functions, 0); + lua_setglobal(L, "rl"); +#endif + + return L; +} + +RLUADEF void rlua_close(lua_State *L) { + if (RLUA_LogRef != LUA_REFNIL) { + luaL_unref(L, LUA_REGISTRYINDEX, RLUA_LogRef); + RLUA_LogRef = LUA_REFNIL; + } + RLUA_State = NULL; + lua_close(L); +} + +#endif +]] + + out:write(table.concat(sections, "\n")) +end + +-- }}} + +-- LUA EMITTER ================================================================================= {{{ + +function Parser.cToLuaType(c_type, ast) + if not c_type or c_type == "" then + return "any" + end + local t = c_type:gsub("%s*const%s*", " "):match("^%s*(.-)%s*$") + if t == "const char *" or t == "const char*" or t == "char *" or t == "char*" then + return "string" + end + if t == "bool" then + return "boolean" + end + if + t == "int" + or t == "unsigned int" + or t == "char" + or t == "unsigned char" + or t == "short" + or t == "unsigned short" + or t == "long" + or t == "unsigned long" + or t == "unsigned" + or t:match("^RL_") + then + return "integer" + end + if t == "float" or t == "double" then + return "number" + end + if t:match("%*$") or t:match("%* ") then + return "userdata" + end + local resolved = ast.type_map and ast.type_map[t] + if resolved then + return Parser.cToLuaType(resolved, ast) + end + return ("rl.%s"):format(t) +end + +function Parser.cToLuaTypename(c_type, ast) + if not c_type or c_type == "" or c_type:match("^void$") then + return "nil" + end + return Parser.cToLuaType(c_type, ast) +end + +function Parser.emit_lua(ast, out) + local t = {} + + local funcs_by_name = {} + for _, f in ipairs(ast.function_xs) do + funcs_by_name[f.name] = f + end + + local function render_lua_func(f, name) + for _, note in ipairs(f.notes or {}) do + if not note:match("^%s*[-=]+%s*$") then + t[#t + 1] = ("--- %s"):format(note) + end + end + if f.comment then + t[#t + 1] = ("--- %s"):format(f.comment) + end + + local isVariadic = false + for _, p in ipairs(f.params or {}) do + if p.isVariadic then + isVariadic = true + break + end + end + + for _, p in ipairs(f.params or {}) do + if not p.isVariadic then + local pname = p.name == "end" and "end_" or p.name + t[#t + 1] = ("---@param %s %s"):format(pname, Parser.cToLuaTypename(p.type, ast)) + end + end + if isVariadic then + t[#t + 1] = "---@param ... any" + end + local ret_type = Parser.cToLuaTypename(f.retType, ast) + if ret_type ~= "nil" then + t[#t + 1] = ("---@return %s"):format(ret_type) + end + local pnames = {} + for _, p in ipairs(f.params or {}) do + if p.isVariadic then + pnames[#pnames + 1] = "..." + else + local pname = p.name == "end" and "end_" or p.name + pnames[#pnames + 1] = pname + end + end + t[#t + 1] = ("function rl.%s(%s) end"):format(name, table.concat(pnames, ", ")) + t[#t + 1] = "" + end + + t[#t + 1] = "---@meta _" + t[#t + 1] = "--[[ **********************************************************************************************" + t[#t + 1] = "" + t[#t + 1] = " raylib-lua v6.0 - raylib Lua type definitions for LuaLS" + t[#t + 1] = "" + t[#t + 1] = " AUTO-GENERATED by tools/rLuaParser/rluaparser.lua" + t[#t + 1] = "" + t[#t + 1] = " LICENSE: zlib/libpng" + t[#t + 1] = "" + t[#t + 1] = " Copyright (c) 2026 yilisharcs" + t[#t + 1] = "" + t[#t + 1] = "************************************************************************************************ ]]" + t[#t + 1] = "" + t[#t + 1] = 'error("Cannot require a meta file")' + t[#t + 1] = "" + + -- struct class definitions + local sorted_structs = {} + for _, s in ipairs(ast.struct_xs) do + sorted_structs[#sorted_structs + 1] = s + end + table.sort(sorted_structs, function(a, b) + return a.name < b.name + end) + + for _, s in ipairs(sorted_structs) do + for _, note in ipairs(s.notes or {}) do + if not note:match("^%s*[-=]+%s*$") then + t[#t + 1] = ("--- %s"):format(note) + end + end + if s.comment then + t[#t + 1] = ("--- %s"):format(s.comment) + end + t[#t + 1] = ("---@class rl.%s"):format(s.name) + local sorted_fields = {} + for i, f in ipairs(s.fields or {}) do + sorted_fields[#sorted_fields + 1] = { field = f, index = i } + end + table.sort(sorted_fields, function(a, b) + local na = a.field.name:match("^m(%d+)$") + local nb = b.field.name:match("^m(%d+)$") + if na and nb then + return tonumber(na) < tonumber(nb) + end + return a.index < b.index + end) + for _, entry in ipairs(sorted_fields) do + local f = entry.field + if f.comment then + t[#t + 1] = ("--- %s"):format(f.comment) + end + local baseName, arraySize = f.name:match("([%w_]+)%[(%d+)%]") + if baseName then + if f.type == "char" then + t[#t + 1] = ("---@field %s string"):format(baseName) + else + local entries = {} + local fType = Parser.cToLuaType(f.type, ast) + for i = 1, tonumber(arraySize) do + entries[#entries + 1] = ("[%d]: %s"):format(i, fType) + end + t[#t + 1] = ("---@field %s { %s }"):format(baseName, table.concat(entries, ", ")) + end + else + t[#t + 1] = ("---@field %s %s"):format(f.name, Parser.cToLuaType(f.type, ast)) + end + end + t[#t + 1] = "" + end + + -- module table declaration + t[#t + 1] = "---@class (partial) rl" + t[#t + 1] = "rl = {}" + t[#t + 1] = "" + + -- enum type aliases + for _, enum in ipairs(ast.enum_xs) do + t[#t + 1] = ("---@alias rl.%s integer"):format(enum.name) + end + t[#t + 1] = "" + + -- enum constants + for _, enum in ipairs(ast.enum_xs) do + for _, field in ipairs(enum.fields) do + if field.comment then + t[#t + 1] = ("--- %s"):format(field.comment) + end + t[#t + 1] = ("---@type rl.%s"):format(enum.name) + t[#t + 1] = ("rl.%s = %s"):format(field.name, field.value or "nil") + end + end + + -- define constants + for _, d in ipairs(ast.define_xs) do + if d.category ~= "version" then + if d.category == "alias" and funcs_by_name[d.value] then + render_lua_func(funcs_by_name[d.value], d.name) + else + if d.comment then + t[#t + 1] = ("--- %s"):format(d.comment) + end + local def_type = "integer" + local val = "nil" + if d.category == "float" then + def_type = "number" + val = d.value:gsub("([%d.])f", "%1"):gsub("PI", "rl.PI") + elseif d.category == "string" then + def_type = "string" + val = d.value + elseif d.category == "color" then + def_type = "rl.Color" + val = "nil" + elseif d.category == "alias" then + val = "nil" + elseif d.category == "integer" then + val = d.value + end + t[#t + 1] = ("---@type %s"):format(def_type) + t[#t + 1] = ("rl.%s = %s"):format(d.name, val) + end + end + end + + t[#t + 1] = "" + + -- function declarations + for _, f in ipairs(ast.function_xs) do + render_lua_func(f, f.name) + end + + out:write(table.concat(t, "\n")) +end + +-- }}} + +-- EXECUTION ============================================================================================== + +local input_f, c_out_f, lua_out_f = ... + +if not input_f or not c_out_f then + io.stderr:write("Usage: rluaparser.lua [output.lua]\n") + os.exit(1) +end + +local rl = assert(io.open(input_f, "r")) +local content = rl:read("*a") + +local major = tonumber(content:match("#define%s+RAYLIB_VERSION_MAJOR%s+(%d+)")) +local minor = tonumber(content:match("#define%s+RAYLIB_VERSION_MINOR%s+(%d+)")) + +local EXPECTED_MAJOR = 6 +local EXPECTED_MINOR = 0 + +-- manually verify that version changes didn't introduce any bugs in the parser! +if major ~= EXPECTED_MAJOR or minor ~= EXPECTED_MINOR then + io.stderr:write( + ("ERROR: Version mismatch.\nExpected raylib %d.%d, found %s.%s\n"):format( + EXPECTED_MAJOR, + EXPECTED_MINOR, + major or "unknown", + minor or "unknown" + ) + ) + os.exit(1) +end + +local lines = Parser.preprocess(content) +local ast = Parser.scan(lines) +Parser.analyze(ast) + +-- io.stderr:write(("functions: %d\n"):format(#ast.function_xs)) +-- io.stderr:write(("structs: %d\n"):format(#ast.struct_xs)) +-- io.stderr:write(("enums: %d\n"):format(#ast.enum_xs)) +-- io.stderr:write(("defines: %d\n"):format(#ast.define_xs)) +-- io.stderr:write(("aliases: %d\n"):format(#ast.alias_xs)) + +local c_out = assert(io.open(c_out_f, "w")) +Parser.emit_c(ast, c_out) + +if lua_out_f then + local lua_out = assert(io.open(lua_out_f, "w")) + Parser.emit_lua(ast, lua_out) +end