diff --git a/lib/generate_functions.py b/lib/generate_functions.py index 2fb26e4..11c59cb 100755 --- a/lib/generate_functions.py +++ b/lib/generate_functions.py @@ -23,17 +23,93 @@ ZIGGIFY = { "c_uint": "u32" } -IGNORE_TYPES = [ - "[*c]Color", - "[*c]GlyphInfo", - "[*c]c_int", - "[*c]c_uint", - "[*c][*c]u8", - "[*c][*c]const u8", - "[*c]Material", - "[*c]ModelAnimation", - "[*c]f32", +IGNORE_C_TYPE = [ + "rlGetShaderLocsDefault", ] + +TRIVIAL_SIZE = [ + "LoadFileData", + "CompressData", + "DecompressData", + "EncodeDataBase64", + "DecodeDataBase64", + "ExportImageToMemory", + "LoadImagePalette", + "LoadCodepoints", + "TextSplit", + #"LoadMaterials", + "LoadModelAnimations", +] + +HAS_ERROR = TRIVIAL_SIZE + +MANUAL = [ + "TextFormat", + "TraceLog", + "LoadShader", + "LoadRandomSequence", + "ExportDataAsCode", + "SaveFileData", + "LoadImage", + "LoadImageRaw", + "LoadImageAnim", + "LoadImageFromTexture", + "LoadImageFromScreen", + "LoadImageFromMemory", + "LoadImageColors", + "LoadMaterialDefault", + "LoadMaterials", # todo: Make this automatic, by adding a IsXValid check in this script + "LoadModel", + "LoadModelFromMesh", + "LoadTexture", + "LoadTextureFromImage", + "LoadTextureCubemap", + "LoadRenderTexture", + "LoadWave", + "LoadWaveSamples", + "LoadSound", + "LoadMusicStream", + "LoadAudioStream", + "DrawMeshInstanced", + "UnloadModelAnimations", + "ComputeCRC32", + "ComputeMD5", + "ComputeSHA1", + "SetWindowIcons", + "CheckCollisionPointPoly", + "ColorToInt", + "GetFontDefault", + "LoadFont", + "LoadFontEx", + "LoadFontFromImage", + "LoadFontData", + "ImageText", + "ImageTextEx", + "GenImageFontAtlas", + "UnloadFontData", + "DrawTextCodepoints", + "LoadUTF8", + "TextJoin", + "DrawLineStrip", + "DrawTriangleFan", + "DrawTriangleStrip", + "DrawTriangleStrip3D", + "GuiTabBar", + "GuiListViewEx", + "GuiPanel", + "GuiScrollPanel", + "DrawSplineLinear", + "DrawSplineBasis", + "DrawSplineCatmullRom", + "DrawSplineBezierQuadratic", + "DrawSplineBezierCubic", + "ImageKernelConvolution", + "GuiGetIcons", + "GuiLoadIcons", + "GuiSetStyle", + "GuiGetStyle" +] + # Some C types have a different sizes on different systems and Zig # knows that so we tell it to get the system specific size for us. def c_to_zig_type(c: str) -> str: @@ -47,7 +123,9 @@ def c_to_zig_type(c: str) -> str: return const + c -def ziggify_type(name: str, t: str, func_name) -> str: +def ziggify_type(name: str, t: str, func_name: str) -> str: + if func_name in IGNORE_C_TYPE: + return t NO_STRINGS = ["data", "fileData", "compData"] single = [ @@ -65,7 +143,7 @@ def ziggify_type(name: str, t: str, func_name) -> str: "data", "compData", "points", "fileData", "colors", "pixels", "fontChars", "chars", "recs", "codepoints", "textList", "transforms", "animations", "samples", "LoadImageColors", "LoadImagePalette", - "LoadFontData", "LoadCodepoints", "TextSplit", "LoadMaterials", + "LoadFontData", "LoadCodepoints", "LoadMaterials", "LoadModelAnimations", "LoadWaveSamples", "images", "LoadRandomSequence", "sequence", "kernel", "GlyphInfo", "glyphs", "glyphRecs", "matf", "rlGetShaderLocsDefault", "locs", "GuiGetIcons", "GuiLoadIcons" @@ -76,7 +154,7 @@ def ziggify_type(name: str, t: str, func_name) -> str: return "[][:0]const u8" if t.startswith("[*c]") and name not in single and name not in multi: - if (t == "[*c]const u8" or t == "[*c]u8") and name not in NO_STRINGS: # Strings are multis. + if (t == "[*c]const u8" or t == "[*c]u8" or name == "TextSplit") and name not in NO_STRINGS: # Strings are multis. string = True else: raise ValueError(f"{t} {name} not classified") @@ -84,7 +162,9 @@ def ziggify_type(name: str, t: str, func_name) -> str: pre = "" while t.startswith("[*c]"): t = t[4:] - if string and not t.startswith("[*c]"): + if func_name in TRIVIAL_SIZE and not pre: + pre += "[]" + elif string and not t.startswith("[*c]"): pre += "[:0]" elif name in single: pre += "*" @@ -94,7 +174,11 @@ def ziggify_type(name: str, t: str, func_name) -> str: if t in ZIGGIFY: t = ZIGGIFY[t] - return pre + t + error = "" + if name in HAS_ERROR: + error = "RaylibError!" + + return error + pre + t def add_namespace_to_type(t: str) -> str: @@ -119,23 +203,20 @@ def add_namespace_to_type(t: str) -> str: return pre + t -def make_return_cast(source_type: str, dest_type: str, inner: str) -> str: - if source_type == dest_type: +def make_return_cast(func_name: str, source_type: str, dest_type: str, inner: str) -> str: + if source_type == dest_type or func_name in IGNORE_C_TYPE: return inner - if "ExportImageToMemory" in inner: - return f"{inner}[0..@as(usize, @intCast(fileSize.*))]" + if source_type.startswith("[*c][*c]"): + inner = f"@as([*][:0]{source_type[8:]}, @ptrCast({inner}))" + if func_name in TRIVIAL_SIZE: + return f"{inner}[0..@as(usize, @intCast(_len))]" if source_type in ["[*c]const u8", "[*c]u8"]: return f"std.mem.span({inner})" if source_type in ZIGGIFY: return f"@as({dest_type}, {inner})" - # These all have to be done manually because their sizes depend on the - # function arguments. - if source_type in IGNORE_TYPES: - return None - else: - raise ValueError(f"Don't know what to do {source_type} {dest_type} {inner}") + raise ValueError(f"Don't know what to do with '{func_name}': {source_type} {dest_type} {inner}") def fix_pointer(name: str, t: str): @@ -329,87 +410,34 @@ def parse_header(header_name: str, output_file: str, ext_file: str, prefix: str, zig_name = convert_name_case(func_name) - # TODO: Ziggify return type + func_prelude = "" + + if func_name in TRIVIAL_SIZE: + zig_arguments.pop() + zig_call_args[-1] = "@as([*c]c_int, @ptrCast(&_len))" + func_prelude = "var _len: i32 = 0;\n " + zig_arguments = ", ".join(zig_arguments) zig_call_args = ", ".join(zig_call_args) - manual = [ - "TextFormat", - "TraceLog", - "LoadShader", - "ExportDataAsCode", - "LoadFileData", - "SaveFileData", - "LoadImage", - "LoadImageRaw", - "LoadImageAnim", - "LoadImageFromTexture", - "LoadImageFromScreen", - "LoadImageFromMemory", - "LoadMaterialDefault", - "LoadMaterials", - "LoadModel", - "LoadModelFromMesh", - "LoadTexture", - "LoadTextureFromImage", - "LoadTextureCubemap", - "LoadRenderTexture", - "LoadWave", - "LoadSound", - "LoadMusicStream", - "LoadAudioStream", - "DrawMeshInstanced", - "UnloadModelAnimations", - "CompressData", - "DecompressData", - "EncodeDataBase64", - "DecodeDataBase64", - "ComputeCRC32", - "ComputeMD5", - "ComputeSHA1", - "SetWindowIcons", - "CheckCollisionPointPoly", - "ColorToInt", - "GetFontDefault", - "LoadFont", - "LoadFontEx", - "LoadFontFromImage", - "ImageText", - "ImageTextEx", - "GenImageFontAtlas", - "UnloadFontData", - "DrawTextCodepoints", - "LoadUTF8", - "TextJoin", - "DrawLineStrip", - "DrawTriangleFan", - "DrawTriangleStrip", - "DrawTriangleStrip3D", - "GuiTabBar", - "GuiListViewEx", - "GuiPanel", - "GuiScrollPanel", - "DrawSplineLinear", - "DrawSplineBasis", - "DrawSplineCatmullRom", - "DrawSplineBezierQuadratic", - "DrawSplineBezierCubic", - "ImageKernelConvolution", - "GuiSetStyle", - "GuiGetStyle" - ] - - if func_name in manual or "FromMemory" in func_name: + if func_name in MANUAL or "FromMemory" in func_name: continue + inner = f"cdef.{func_name}({zig_call_args})" + + if func_name in TRIVIAL_SIZE: + func_prelude += f"const _ptr = {inner};\n if (_ptr == 0) return RaylibError.{func_name};\n " + inner = "_ptr" + zig_return = ziggify_type(func_name, return_type, func_name) - return_cast = make_return_cast(return_type, zig_return, f"cdef.{func_name}({zig_call_args})") + return_cast = make_return_cast(func_name, return_type, zig_return, inner) if return_cast: zig_funcs.append( inline_comment + f"pub fn {zig_name}({zig_arguments}) {zig_return}" + " {\n " + + func_prelude + ("return " if zig_return != "void" else "") + return_cast + ";" "\n}" diff --git a/lib/preludes/raylib-prelude.zig b/lib/preludes/raylib-prelude.zig index 5120a99..b68d406 100644 --- a/lib/preludes/raylib-prelude.zig +++ b/lib/preludes/raylib-prelude.zig @@ -14,11 +14,17 @@ test { pub const RaylibError = error{ LoadFileData, + CompressData, + DecompressData, + EncodeDataBase64, + DecodeDataBase64, + ExportImageToMemory, LoadImageColors, LoadImagePalette, LoadFont, LoadFontData, LoadCodepoints, + TextSplit, LoadMaterial, LoadMaterials, LoadModelAnimations, @@ -2032,19 +2038,6 @@ pub fn loadRandomSequence(count: u32, min: i32, max: i32) []i32 { return res; } -/// Load file data as byte array (read) -pub fn loadFileData(fileName: [:0]const u8) RaylibError![]u8 { - var bytesRead: i32 = 0; - var res: []u8 = undefined; - - const ptr = cdef.LoadFileData(@as([*c]const u8, @ptrCast(fileName)), @as([*c]c_int, @ptrCast(&bytesRead))); - if (ptr == 0) return RaylibError.LoadFileData; - - res.ptr = @as([*]u8, @ptrCast(ptr)); - res.len = @as(usize, @intCast(bytesRead)); - return res; -} - /// Save data to file from byte array (write), returns true on success pub fn saveFileData(fileName: [:0]const u8, data: []u8) bool { return cdef.SaveFileData(@as([*c]const u8, @ptrCast(fileName)), @as(*anyopaque, @ptrCast(data.ptr)), @as(c_int, @intCast(data.len))); @@ -2055,42 +2048,6 @@ pub fn exportDataAsCode(data: []const u8, fileName: [:0]const u8) bool { return cdef.ExportDataAsCode(@as([*c]const u8, @ptrCast(data)), @as(c_int, @intCast(data.len)), @as([*c]const u8, @ptrCast(fileName))); } -/// Compress data (DEFLATE algorithm), memory must be MemFree() -pub fn compressData(data: []const u8) []u8 { - var compDataSize: i32 = 0; - var res: []u8 = undefined; - res.ptr = cdef.CompressData(@as([*c]const u8, @ptrCast(data)), @as(c_int, @intCast(data.len)), @as([*c]c_int, @ptrCast(&compDataSize))); - res.len = @as(usize, @intCast(compDataSize)); - return res; -} - -/// Decompress data (DEFLATE algorithm), memory must be MemFree() -pub fn decompressData(compData: []const u8) []u8 { - var dataSize: i32 = 0; - var res: []u8 = undefined; - res.ptr = cdef.DecompressData(@as([*c]const u8, @ptrCast(compData)), @as(c_int, @intCast(compData.len)), @as([*c]c_int, @ptrCast(&dataSize))); - res.len = @as(usize, @intCast(dataSize)); - return res; -} - -/// Encode data to Base64 string, memory must be MemFree() -pub fn encodeDataBase64(data: []const u8) []u8 { - var outputSize: i32 = 0; - var res: []u8 = undefined; - res.ptr = cdef.EncodeDataBase64(@as([*c]const u8, @ptrCast(data)), @as(c_int, @intCast(data.len)), @as([*c]c_int, @ptrCast(&outputSize))); - res.len = @as(usize, @intCast(outputSize)); - return res; -} - -/// Decode Base64 string data, memory must be MemFree() -pub fn decodeDataBase64(data: []const u8) []u8 { - var outputSize: i32 = 0; - var res: []u8 = undefined; - res.ptr = cdef.DecodeDataBase64(@as([*c]const u8, @ptrCast(data)), @as([*c]c_int, @ptrCast(&outputSize))); - res.len = @as(usize, @intCast(outputSize)); - return res; -} - pub fn computeCRC32(data: []u8) u32 { return cdef.ComputeCRC32(@as([*c]u8, @ptrCast(data)), @as(c_int, @intCast(data.len))); } @@ -2181,19 +2138,6 @@ pub fn loadImageColors(image: Image) RaylibError![]Color { return res; } -/// Load colors palette from image as a Color array (RGBA - 32bit) -pub fn loadImagePalette(image: Image, maxPaletteSize: i32) RaylibError![]Color { - var colorCount: i32 = 0; - var res: []Color = undefined; - - const ptr = cdef.LoadImagePalette(image, @as(c_int, maxPaletteSize), @as([*c]c_int, @ptrCast(&colorCount))); - if (ptr == 0) return RaylibError.LoadImagePalette; - - res.ptr = @as([*]Color, @ptrCast(ptr)); - res.len = @as(usize, @intCast(colorCount)); - return res; -} - /// Load texture from file into GPU memory (VRAM) pub fn loadTexture(fileName: [:0]const u8) RaylibError!Texture2D { const texture = cdef.LoadTexture(@as([*c]const u8, @ptrCast(fileName))); @@ -2290,22 +2234,6 @@ pub fn loadFontData(fileData: []const u8, fontSize: i32, fontChars: []i32, ty: F return res; } -/// Load all codepoints from a UTF-8 text string, codepoints count returned by parameter -pub fn loadCodepoints(text: [:0]const u8) RaylibError![]i32 { - if (@sizeOf(c_int) != @sizeOf(i32)) { - @compileError("Can't cast pointer to c_int array to i32 because they don't have the same size"); - } - var count: i32 = 0; - var res: []i32 = undefined; - - const ptr = cdef.LoadCodepoints(@as([*c]const u8, @ptrCast(text)), @as([*c]c_int, @ptrCast(&count))); - if (ptr == 0) return RaylibError.LoadCodepoints; - - res.ptr = @as([*]i32, @ptrCast(ptr)); - res.len = @as(usize, @intCast(count)); - return res; -} - /// Text formatting with variables (sprintf() style) pub fn textFormat(text: [:0]const u8, args: anytype) [:0]const u8 { comptime { @@ -2342,15 +2270,6 @@ pub fn traceLog(logLevel: TraceLogLevel, text: [:0]const u8, args: anytype) void @call(.auto, cdef.TraceLog, .{ logLevel, @as([*c]const u8, @ptrCast(text)) } ++ args); } -/// Split text into multiple strings -pub fn textSplit(text: [:0]const u8, delimiter: u8) [][:0]const u8 { - var count: i32 = 0; - var res: [][:0]const u8 = undefined; - res.ptr = @as([*][:0]const u8, @ptrCast(cdef.TextSplit(@as([*c]const u8, @ptrCast(text)), delimiter, @as([*c]c_int, @ptrCast(&count))))); - res.len = @as(usize, @intCast(count)); - return res; -} - /// Draw multiple mesh instances with material and different transforms pub fn drawMeshInstanced(mesh: Mesh, material: Material, transforms: []const Matrix) void { cdef.DrawMeshInstanced(mesh, material, @as([*c]const Matrix, @ptrCast(transforms)), @as(c_int, @intCast(transforms.len))); @@ -2396,19 +2315,6 @@ pub fn loadModelFromMesh(mesh: Mesh) RaylibError!Model { return if (isValid) model else RaylibError.LoadModel; } -/// Load model animations from file -pub fn loadModelAnimations(fileName: [:0]const u8) RaylibError![]ModelAnimation { - var animCount: i32 = 0; - var res: []ModelAnimation = undefined; - - const ptr = cdef.LoadModelAnimations(@as([*c]const u8, @ptrCast(fileName)), @as([*c]c_int, @ptrCast(&animCount))); - if (ptr == 0) return RaylibError.LoadModelAnimations; - - res.ptr = @as([*]ModelAnimation, @ptrCast(ptr)); - res.len = @as(usize, @intCast(animCount)); - return res; -} - /// Unload animation data pub fn unloadModelAnimations(animations: []ModelAnimation) void { cdef.UnloadModelAnimations(@as([*c]ModelAnimation, @ptrCast(animations)), @as(c_int, @intCast(animations.len))); diff --git a/lib/raylib.zig b/lib/raylib.zig index 9a1466c..2960539 100644 --- a/lib/raylib.zig +++ b/lib/raylib.zig @@ -14,11 +14,17 @@ test { pub const RaylibError = error{ LoadFileData, + CompressData, + DecompressData, + EncodeDataBase64, + DecodeDataBase64, + ExportImageToMemory, LoadImageColors, LoadImagePalette, LoadFont, LoadFontData, LoadCodepoints, + TextSplit, LoadMaterial, LoadMaterials, LoadModelAnimations, @@ -2032,19 +2038,6 @@ pub fn loadRandomSequence(count: u32, min: i32, max: i32) []i32 { return res; } -/// Load file data as byte array (read) -pub fn loadFileData(fileName: [:0]const u8) RaylibError![]u8 { - var bytesRead: i32 = 0; - var res: []u8 = undefined; - - const ptr = cdef.LoadFileData(@as([*c]const u8, @ptrCast(fileName)), @as([*c]c_int, @ptrCast(&bytesRead))); - if (ptr == 0) return RaylibError.LoadFileData; - - res.ptr = @as([*]u8, @ptrCast(ptr)); - res.len = @as(usize, @intCast(bytesRead)); - return res; -} - /// Save data to file from byte array (write), returns true on success pub fn saveFileData(fileName: [:0]const u8, data: []u8) bool { return cdef.SaveFileData(@as([*c]const u8, @ptrCast(fileName)), @as(*anyopaque, @ptrCast(data.ptr)), @as(c_int, @intCast(data.len))); @@ -2055,42 +2048,6 @@ pub fn exportDataAsCode(data: []const u8, fileName: [:0]const u8) bool { return cdef.ExportDataAsCode(@as([*c]const u8, @ptrCast(data)), @as(c_int, @intCast(data.len)), @as([*c]const u8, @ptrCast(fileName))); } -/// Compress data (DEFLATE algorithm), memory must be MemFree() -pub fn compressData(data: []const u8) []u8 { - var compDataSize: i32 = 0; - var res: []u8 = undefined; - res.ptr = cdef.CompressData(@as([*c]const u8, @ptrCast(data)), @as(c_int, @intCast(data.len)), @as([*c]c_int, @ptrCast(&compDataSize))); - res.len = @as(usize, @intCast(compDataSize)); - return res; -} - -/// Decompress data (DEFLATE algorithm), memory must be MemFree() -pub fn decompressData(compData: []const u8) []u8 { - var dataSize: i32 = 0; - var res: []u8 = undefined; - res.ptr = cdef.DecompressData(@as([*c]const u8, @ptrCast(compData)), @as(c_int, @intCast(compData.len)), @as([*c]c_int, @ptrCast(&dataSize))); - res.len = @as(usize, @intCast(dataSize)); - return res; -} - -/// Encode data to Base64 string, memory must be MemFree() -pub fn encodeDataBase64(data: []const u8) []u8 { - var outputSize: i32 = 0; - var res: []u8 = undefined; - res.ptr = cdef.EncodeDataBase64(@as([*c]const u8, @ptrCast(data)), @as(c_int, @intCast(data.len)), @as([*c]c_int, @ptrCast(&outputSize))); - res.len = @as(usize, @intCast(outputSize)); - return res; -} - -/// Decode Base64 string data, memory must be MemFree() -pub fn decodeDataBase64(data: []const u8) []u8 { - var outputSize: i32 = 0; - var res: []u8 = undefined; - res.ptr = cdef.DecodeDataBase64(@as([*c]const u8, @ptrCast(data)), @as([*c]c_int, @ptrCast(&outputSize))); - res.len = @as(usize, @intCast(outputSize)); - return res; -} - pub fn computeCRC32(data: []u8) u32 { return cdef.ComputeCRC32(@as([*c]u8, @ptrCast(data)), @as(c_int, @intCast(data.len))); } @@ -2181,19 +2138,6 @@ pub fn loadImageColors(image: Image) RaylibError![]Color { return res; } -/// Load colors palette from image as a Color array (RGBA - 32bit) -pub fn loadImagePalette(image: Image, maxPaletteSize: i32) RaylibError![]Color { - var colorCount: i32 = 0; - var res: []Color = undefined; - - const ptr = cdef.LoadImagePalette(image, @as(c_int, maxPaletteSize), @as([*c]c_int, @ptrCast(&colorCount))); - if (ptr == 0) return RaylibError.LoadImagePalette; - - res.ptr = @as([*]Color, @ptrCast(ptr)); - res.len = @as(usize, @intCast(colorCount)); - return res; -} - /// Load texture from file into GPU memory (VRAM) pub fn loadTexture(fileName: [:0]const u8) RaylibError!Texture2D { const texture = cdef.LoadTexture(@as([*c]const u8, @ptrCast(fileName))); @@ -2290,22 +2234,6 @@ pub fn loadFontData(fileData: []const u8, fontSize: i32, fontChars: []i32, ty: F return res; } -/// Load all codepoints from a UTF-8 text string, codepoints count returned by parameter -pub fn loadCodepoints(text: [:0]const u8) RaylibError![]i32 { - if (@sizeOf(c_int) != @sizeOf(i32)) { - @compileError("Can't cast pointer to c_int array to i32 because they don't have the same size"); - } - var count: i32 = 0; - var res: []i32 = undefined; - - const ptr = cdef.LoadCodepoints(@as([*c]const u8, @ptrCast(text)), @as([*c]c_int, @ptrCast(&count))); - if (ptr == 0) return RaylibError.LoadCodepoints; - - res.ptr = @as([*]i32, @ptrCast(ptr)); - res.len = @as(usize, @intCast(count)); - return res; -} - /// Text formatting with variables (sprintf() style) pub fn textFormat(text: [:0]const u8, args: anytype) [:0]const u8 { comptime { @@ -2342,15 +2270,6 @@ pub fn traceLog(logLevel: TraceLogLevel, text: [:0]const u8, args: anytype) void @call(.auto, cdef.TraceLog, .{ logLevel, @as([*c]const u8, @ptrCast(text)) } ++ args); } -/// Split text into multiple strings -pub fn textSplit(text: [:0]const u8, delimiter: u8) [][:0]const u8 { - var count: i32 = 0; - var res: [][:0]const u8 = undefined; - res.ptr = @as([*][:0]const u8, @ptrCast(cdef.TextSplit(@as([*c]const u8, @ptrCast(text)), delimiter, @as([*c]c_int, @ptrCast(&count))))); - res.len = @as(usize, @intCast(count)); - return res; -} - /// Draw multiple mesh instances with material and different transforms pub fn drawMeshInstanced(mesh: Mesh, material: Material, transforms: []const Matrix) void { cdef.DrawMeshInstanced(mesh, material, @as([*c]const Matrix, @ptrCast(transforms)), @as(c_int, @intCast(transforms.len))); @@ -2396,19 +2315,6 @@ pub fn loadModelFromMesh(mesh: Mesh) RaylibError!Model { return if (isValid) model else RaylibError.LoadModel; } -/// Load model animations from file -pub fn loadModelAnimations(fileName: [:0]const u8) RaylibError![]ModelAnimation { - var animCount: i32 = 0; - var res: []ModelAnimation = undefined; - - const ptr = cdef.LoadModelAnimations(@as([*c]const u8, @ptrCast(fileName)), @as([*c]c_int, @ptrCast(&animCount))); - if (ptr == 0) return RaylibError.LoadModelAnimations; - - res.ptr = @as([*]ModelAnimation, @ptrCast(ptr)); - res.len = @as(usize, @intCast(animCount)); - return res; -} - /// Unload animation data pub fn unloadModelAnimations(animations: []ModelAnimation) void { cdef.UnloadModelAnimations(@as([*c]ModelAnimation, @ptrCast(animations)), @as(c_int, @intCast(animations.len))); @@ -3131,6 +3037,14 @@ pub fn setSaveFileTextCallback(callback: SaveFileTextCallback) void { cdef.SetSaveFileTextCallback(callback); } +/// Load file data as byte array (read) +pub fn loadFileData(fileName: []const u8) RaylibError![]u8 { + var _len: i32 = 0; + const _ptr = cdef.LoadFileData(@as([*c]const u8, @ptrCast(fileName)), @as([*c]c_int, @ptrCast(&_len))); + if (_ptr == 0) return RaylibError.LoadFileData; + return _ptr[0..@as(usize, @intCast(_len))]; +} + /// Unload file data allocated by LoadFileData() pub fn unloadFileData(data: []u8) void { cdef.UnloadFileData(@as([*c]u8, @ptrCast(data))); @@ -3261,6 +3175,38 @@ pub fn getFileModTime(fileName: [:0]const u8) i64 { return @as(i64, cdef.GetFileModTime(@as([*c]const u8, @ptrCast(fileName)))); } +/// Compress data (DEFLATE algorithm), memory must be MemFree() +pub fn compressData(data: []const u8, dataSize: i32) RaylibError![]u8 { + var _len: i32 = 0; + const _ptr = cdef.CompressData(@as([*c]const u8, @ptrCast(data)), @as(c_int, dataSize), @as([*c]c_int, @ptrCast(&_len))); + if (_ptr == 0) return RaylibError.CompressData; + return _ptr[0..@as(usize, @intCast(_len))]; +} + +/// Decompress data (DEFLATE algorithm), memory must be MemFree() +pub fn decompressData(compData: []const u8, compDataSize: i32) RaylibError![]u8 { + var _len: i32 = 0; + const _ptr = cdef.DecompressData(@as([*c]const u8, @ptrCast(compData)), @as(c_int, compDataSize), @as([*c]c_int, @ptrCast(&_len))); + if (_ptr == 0) return RaylibError.DecompressData; + return _ptr[0..@as(usize, @intCast(_len))]; +} + +/// Encode data to Base64 string, memory must be MemFree() +pub fn encodeDataBase64(data: []const u8, dataSize: i32) RaylibError![]u8 { + var _len: i32 = 0; + const _ptr = cdef.EncodeDataBase64(@as([*c]const u8, @ptrCast(data)), @as(c_int, dataSize), @as([*c]c_int, @ptrCast(&_len))); + if (_ptr == 0) return RaylibError.EncodeDataBase64; + return _ptr[0..@as(usize, @intCast(_len))]; +} + +/// Decode Base64 string data, memory must be MemFree() +pub fn decodeDataBase64(data: []const u8) RaylibError![]u8 { + var _len: i32 = 0; + const _ptr = cdef.DecodeDataBase64(@as([*c]const u8, @ptrCast(data)), @as([*c]c_int, @ptrCast(&_len))); + if (_ptr == 0) return RaylibError.DecodeDataBase64; + return _ptr[0..@as(usize, @intCast(_len))]; +} + /// Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS pub fn loadAutomationEventList(fileName: [:0]const u8) AutomationEventList { return cdef.LoadAutomationEventList(@as([*c]const u8, @ptrCast(fileName))); @@ -3847,8 +3793,11 @@ pub fn exportImage(image: Image, fileName: [:0]const u8) bool { } /// Export image to memory buffer -pub fn exportImageToMemory(image: Image, fileType: [:0]const u8, fileSize: *i32) [:0]u8 { - return cdef.ExportImageToMemory(image, @as([*c]const u8, @ptrCast(fileType)), @as([*c]c_int, @ptrCast(fileSize)))[0..@as(usize, @intCast(fileSize.*))]; +pub fn exportImageToMemory(image: Image, fileType: []const u8) RaylibError![]u8 { + var _len: i32 = 0; + const _ptr = cdef.ExportImageToMemory(image, @as([*c]const u8, @ptrCast(fileType)), @as([*c]c_int, @ptrCast(&_len))); + if (_ptr == 0) return RaylibError.ExportImageToMemory; + return _ptr[0..@as(usize, @intCast(_len))]; } /// Export image as code file defining an array of bytes, returns true on success @@ -4036,6 +3985,14 @@ pub fn imageColorReplace(image: *Image, color: Color, replace: Color) void { cdef.ImageColorReplace(@as([*c]Image, @ptrCast(image)), color, replace); } +/// Load colors palette from image as a Color array (RGBA - 32bit) +pub fn loadImagePalette(image: Image, maxPaletteSize: i32) RaylibError![]Color { + var _len: i32 = 0; + const _ptr = cdef.LoadImagePalette(image, @as(c_int, maxPaletteSize), @as([*c]c_int, @ptrCast(&_len))); + if (_ptr == 0) return RaylibError.LoadImagePalette; + return _ptr[0..@as(usize, @intCast(_len))]; +} + /// Unload color data loaded with LoadImageColors() pub fn unloadImageColors(colors: []Color) void { cdef.UnloadImageColors(@as([*c]Color, @ptrCast(colors))); @@ -4396,6 +4353,14 @@ pub fn unloadUTF8(text: [:0]u8) void { cdef.UnloadUTF8(@as([*c]u8, @ptrCast(text))); } +/// Load all codepoints from a UTF-8 text string, codepoints count returned by parameter +pub fn loadCodepoints(text: []const u8) RaylibError![]i32 { + var _len: i32 = 0; + const _ptr = cdef.LoadCodepoints(@as([*c]const u8, @ptrCast(text)), @as([*c]c_int, @ptrCast(&_len))); + if (_ptr == 0) return RaylibError.LoadCodepoints; + return _ptr[0..@as(usize, @intCast(_len))]; +} + /// Unload codepoints data from memory pub fn unloadCodepoints(codepoints: []i32) void { cdef.UnloadCodepoints(@as([*c]c_int, @ptrCast(codepoints))); @@ -4456,6 +4421,14 @@ pub fn textInsert(text: [:0]const u8, insert: [:0]const u8, position: i32) [:0]u return std.mem.span(cdef.TextInsert(@as([*c]const u8, @ptrCast(text)), @as([*c]const u8, @ptrCast(insert)), @as(c_int, position))); } +/// Split text into multiple strings +pub fn textSplit(text: []const u8, delimiter: u8) RaylibError![][:0]u8 { + var _len: i32 = 0; + const _ptr = cdef.TextSplit(@as([*c]const u8, @ptrCast(text)), delimiter, @as([*c]c_int, @ptrCast(&_len))); + if (_ptr == 0) return RaylibError.TextSplit; + return @as([*][:0]u8, @ptrCast(_ptr))[0..@as(usize, @intCast(_len))]; +} + /// Append text at specific position and move cursor! pub fn textAppend(text: [:0]u8, append: [:0]const u8, position: *i32) void { cdef.TextAppend(@as([*c]u8, @ptrCast(text)), @as([*c]const u8, @ptrCast(append)), @as([*c]c_int, @ptrCast(position))); @@ -4781,6 +4754,14 @@ pub fn setModelMeshMaterial(model: *Model, meshId: i32, materialId: i32) void { cdef.SetModelMeshMaterial(@as([*c]Model, @ptrCast(model)), @as(c_int, meshId), @as(c_int, materialId)); } +/// Load model animations from file +pub fn loadModelAnimations(fileName: []const u8) RaylibError![]ModelAnimation { + var _len: i32 = 0; + const _ptr = cdef.LoadModelAnimations(@as([*c]const u8, @ptrCast(fileName)), @as([*c]c_int, @ptrCast(&_len))); + if (_ptr == 0) return RaylibError.LoadModelAnimations; + return _ptr[0..@as(usize, @intCast(_len))]; +} + /// Update model animation pose (CPU) pub fn updateModelAnimation(model: Model, anim: ModelAnimation, frame: i32) void { cdef.UpdateModelAnimation(model, anim, @as(c_int, frame)); diff --git a/lib/rlgl.zig b/lib/rlgl.zig index 010539a..b260568 100644 --- a/lib/rlgl.zig +++ b/lib/rlgl.zig @@ -714,6 +714,11 @@ pub fn rlGetShaderIdDefault() u32 { return @as(u32, cdef.rlGetShaderIdDefault()); } +/// Get default shader locations +pub fn rlGetShaderLocsDefault() [*c]c_int { + return cdef.rlGetShaderLocsDefault(); +} + /// Load a render batch system pub fn rlLoadRenderBatch(numBuffers: i32, bufferElements: i32) rlRenderBatch { return cdef.rlLoadRenderBatch(@as(c_int, numBuffers), @as(c_int, bufferElements));