1
0

add back raygui cloned

This commit is contained in:
Rokas Puzonas 2024-01-21 14:30:49 +02:00
parent 01436636d5
commit 7446790256
19 changed files with 10996 additions and 0 deletions

3
.gitmodules vendored
View File

@ -1,3 +1,6 @@
[submodule "libs/raylib/raylib"]
path = libs/raylib/raylib
url = git@github.com:raysan5/raylib.git
[submodule "libs/raygui/raygui"]
path = libs/raygui/raygui
url = https://github.com/raysan5/raygui

21
libs/raygui/LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2022 Michael Scherbakow
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

81
libs/raygui/README.md Normal file
View File

@ -0,0 +1,81 @@
![logo](logo.png)
# raygui.zig
Idiomatic [raygui](https://github.com/raysan5/raygui) **RAYGUIAPI** (raygui.h) bindings for [Zig](https://ziglang.org/) (master).
## usage
The easy way would be adding this as submodule directly in your source folder.
Thats what I do until there is an official package manager for Zig.
```sh
cd $YOUR_SRC_FOLDER
git submodule add https://github.com/ryupold/raygui.zig raygui
git submodule update --init --recursive
```
The bindings have been prebuilt so you just need to add raylib as module
build.zig:
```zig
const raylib = @import("path/to/raylib.zig/build.zig");
const raygui = @import("path/to/raygui.zig/build.zig");
pub fn build(b: *std.Build) !void {
const target = b.standardTargetOptions(.{});
const mode = b.standardOptimizeOption(.{});
const exe = ...;
raylib.addTo(b, exe, target, mode);
raygui.addTo(b, exe, target, mode);
}
```
and import in main.zig:
```zig
const raylib = @import("raylib");
const raygui = @import("raygui");
pub fn main() void {
raylib.InitWindow(800, 800, "hello world!");
raylib.SetConfigFlags(.FLAG_WINDOW_RESIZABLE);
raylib.SetTargetFPS(60);
defer raylib.CloseWindow();
while (!raylib.WindowShouldClose()) {
raylib.BeginDrawing();
defer raylib.EndDrawing();
raylib.ClearBackground(raylib.BLACK);
raylib.DrawFPS(10, 10);
if (raygui.GuiButton(.{ .x = 100, .y = 100, .width = 200, .height = 100 }, "press me!")) {
std.debug.print("pressed\n", .{});
}
}
}
```
> See `build.zig` in [examples-raylib.zig](https://github.com/ryupold/examples-raylib.zig) for how to build.
> Note: you only need the files `raygui.zig`, `raygui_marshal.h` and `raygui_marshal.c` for this to work
>
This weird workaround with `raygui_marshal.h/raygui_marshal.c` I actually had to make for Webassembly builds to work, because passing structs as function parameters or returning them cannot be done on the Zig side somehow. If I try it, I get a runtime error "index out of bounds". This happens only in WebAssembly builds. So `raygui_marshal.c` must be compiled with `emcc`. See [build.zig](https://github.com/ryupold/examples-raylib.zig/blob/main/build.zig) in the examples.
## custom definitions
An easy way to fix binding mistakes is to edit them in `bindings.json` and setting the custom flag to true. This way the binding will not be overriden when calling `zig build intermediate`.
Additionally you can add custom definitions into `inject.zig, inject.h, inject.c` these files will be prepended accordingly.
## disclaimer
I have NOT tested most of the generated functions, so there might be bugs. Especially when it comes to pointers as it is not decidable (for the generator) what a pointer to C means. Could be single item, array, sentinel terminated and/or nullable. If you run into crashes using one of the functions or types in `raygui.zig` feel free to [create an issue](https://github.com/ryupold/raygui.zig/issues) and I will look into it.
## generate bindings
for current raygui source (submodule)
```sh
zig build parse # create JSON files with raylib_parser
zig build intermediate # generate bindings.json (keeps definitions with custom=true)
zig build bindings # write all intermediate bindings to raylib.zig
```
For easier diffing and to follow changes to the raygui repository I commit also the generated json files.

3419
libs/raygui/bindings.json Normal file

File diff suppressed because it is too large Load Diff

87
libs/raygui/build.zig Normal file
View File

@ -0,0 +1,87 @@
const std = @import("std");
const generate = @import("generate.zig");
const rayguiSrc = "raygui/src/";
pub fn build(b: *std.Build) !void {
const target = b.standardTargetOptions(.{});
//--- parse raygui and generate JSONs for all signatures --------------------------------------
const jsons = b.step("parse", "parse raygui headers and generate raylib parser output as json");
const raylib_parser_build = b.addExecutable(.{
.name = "raylib_parser",
.root_source_file = std.build.FileSource.relative("raylib_parser.zig"),
.target = target,
.optimize = .ReleaseFast,
});
raylib_parser_build.addCSourceFile(.{ .file = .{ .path = "../raylib/raylib/parser/raylib_parser.c" }, .flags = &.{} });
raylib_parser_build.linkLibC();
//raygui
const raygui_H = b.addRunArtifact(raylib_parser_build);
raygui_H.addArgs(&.{
"-i", "raygui/src/raygui.h",
"-o", "raygui.json",
"-f", "JSON",
"-d", "RAYGUIAPI",
});
jsons.dependOn(&raygui_H.step);
//--- Generate intermediate -------------------------------------------------------------------
const intermediate = b.step("intermediate", "generate intermediate representation of the results from 'zig build parse' (keep custom=true)");
var intermediateZig = b.addRunArtifact(b.addExecutable(.{
.name = "intermediate",
.root_source_file = std.build.FileSource.relative("intermediate.zig"),
.target = target,
}));
intermediate.dependOn(&intermediateZig.step);
//--- Generate bindings -----------------------------------------------------------------------
const bindings = b.step("bindings", "generate bindings in from bindings.json");
var generateZig = b.addRunArtifact(b.addExecutable(.{
.name = "generate",
.root_source_file = std.build.FileSource.relative("generate.zig"),
.target = target,
}));
const fmt = b.addFmt(.{ .paths = &.{generate.outputFile} });
fmt.step.dependOn(&generateZig.step);
bindings.dependOn(&fmt.step);
//--- just build raylib_parser.exe ------------------------------------------------------------
const raylib_parser_install = b.step("raylib_parser", "build ./zig-out/bin/raylib_parser.exe");
const generateBindings_install = b.addInstallArtifact(raylib_parser_build, .{});
raylib_parser_install.dependOn(&generateBindings_install.step);
}
// above: generate library
// below: linking (use as dependency)
fn current_file() []const u8 {
return @src().file;
}
const cwd = std.fs.path.dirname(current_file()).?;
const sep = std.fs.path.sep_str;
const dir_raygui = cwd ++ sep ++ "raygui/src";
/// add this package to lib
pub fn addTo(b: *std.Build, lib: *std.build.LibExeObjStep, target: std.zig.CrossTarget, optimize: std.builtin.Mode) void {
_ = b;
_ = optimize;
_ = target;
if (lib.modules.get("raylib") orelse lib.modules.get("raylib.zig") orelse lib.modules.get("raylib-zig")) |raylib| {
lib.addAnonymousModule("raygui", .{
.source_file = .{ .path = cwd ++ sep ++ "raygui.zig" },
.dependencies = &.{
.{ .name = "raylib", .module = raylib },
},
});
lib.addIncludePath(.{ .path = dir_raygui });
lib.addIncludePath(.{ .path = cwd });
lib.linkLibC();
lib.addCSourceFile(.{ .file = .{ .path = cwd ++ sep ++ "raygui_marshal.c" }, .flags = &.{"-DRAYGUI_IMPLEMENTATION"} });
} else {
std.debug.panic("lib needs to have 'raylib', 'raylib.zig' or 'raylib-zig' as module dependency", .{});
}
}

528
libs/raygui/generate.zig Normal file
View File

@ -0,0 +1,528 @@
const std = @import("std");
const fs = std.fs;
const json = std.json;
const allocPrint = std.fmt.allocPrint;
const mapping = @import("type_mapping.zig");
const intermediate = @import("intermediate.zig");
pub const outputFile = "raygui.zig";
pub const injectFile = "inject.zig";
pub const marshalFilePrefix = "raygui_marshal";
fn trim(s: []const u8) []const u8 {
return std.mem.trim(u8, s, &[_]u8{ ' ', '\t', '\n' });
}
pub fn main() !void {
std.log.info("generating raygui.zig ...", .{});
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer {
if (gpa.deinit() == .leak) {
std.log.err("memory leak detected", .{});
}
}
const allocator = gpa.allocator();
var arena = std.heap.ArenaAllocator.init(allocator);
defer arena.deinit();
const bindingsData = try fs.cwd().readFileAlloc(arena.allocator(), intermediate.bindingsJSON, std.math.maxInt(usize));
const bindings = try json.parseFromSliceLeaky(mapping.Intermediate, arena.allocator(), bindingsData, .{
.ignore_unknown_fields = true,
});
var file = try fs.cwd().createFile(outputFile, .{});
defer file.close();
try file.writeAll("\n\n");
const inject = try Injections.load(arena.allocator());
try writeInjections(arena.allocator(), &file, inject);
try writeFunctions(arena.allocator(), &file, bindings, inject);
var h = try fs.cwd().createFile(marshalFilePrefix ++ ".h", .{});
defer h.close();
var c = try fs.cwd().createFile(marshalFilePrefix ++ ".c", .{});
defer c.close();
const raylib: mapping.CombinedRaylib = try mapping.CombinedRaylib.load(arena.allocator(), intermediate.jsonFiles);
try writeCFunctions(arena.allocator(), &h, &c, inject, raylib);
try writeStructs(arena.allocator(), &file, bindings, inject);
try writeEnums(arena.allocator(), &file, bindings, inject);
try writeDefines(arena.allocator(), &file, bindings, inject);
std.log.info("... done", .{});
}
const Injections = struct {
lines: []const []const u8,
symbols: []const []const u8,
pub fn load(allocator: std.mem.Allocator) !@This() {
var injectZigLines = std.ArrayList([]const u8).init(allocator);
var symbols = std.ArrayList([]const u8).init(allocator);
var file = try fs.cwd().openFile(injectFile, .{});
var reader = file.reader();
while (try reader.readUntilDelimiterOrEofAlloc(allocator, '\n', std.math.maxInt(usize))) |line| {
if (std.mem.indexOf(u8, line, "pub const ")) |startIndex| {
if (std.mem.indexOf(u8, line, " = extern struct {")) |endIndex| {
const s = line["pub const ".len + startIndex .. endIndex];
try symbols.append(s);
std.log.debug("inject symbol: {s}", .{s});
} else if (std.mem.indexOf(u8, line, " = raylib.")) |endIndex| {
const s = line["pub const ".len + startIndex .. endIndex];
try symbols.append(s);
std.log.debug("inject symbol: {s}", .{s});
}
}
if (std.mem.indexOf(u8, line, "pub fn ")) |startIndex| {
if (std.mem.indexOf(u8, line, "(")) |endIndex| {
const s = line["pub fn ".len + startIndex .. endIndex];
try symbols.append(s);
std.log.debug("inject symbol: {s}", .{s});
}
}
try injectZigLines.append(line);
}
return @This(){
.lines = try injectZigLines.toOwnedSlice(),
.symbols = try symbols.toOwnedSlice(),
};
}
pub fn containsSymbol(self: @This(), name: []const u8) bool {
for (self.symbols) |s| {
if (eql(s, name)) return true;
}
return false;
}
};
fn writeFunctions(
allocator: std.mem.Allocator,
file: *fs.File,
bindings: mapping.Intermediate,
inject: Injections,
) !void {
var buf: [51200]u8 = undefined;
var fba = std.heap.FixedBufferAllocator.init(&buf);
for (bindings.functions) |func| {
if (inject.containsSymbol(func.name)) continue;
defer fba.reset();
//--- signature -------------------------
const funcDescription: []const u8 = func.description orelse "";
try file.writeAll(
try allocPrint(
allocator,
"\n/// {s}\npub fn {s} (\n",
.{ funcDescription, func.name },
),
);
for (func.params) |param| {
if (param.description) |description| {
try file.writeAll(try allocPrint(
allocator,
"/// {s}\n",
.{description},
));
}
try file.writeAll(try allocPrint(
allocator,
"{s}: {s},\n",
.{ param.name, param.typ },
));
}
if (func.custom) {
try file.writeAll(
try allocPrint(
allocator,
") {s} {{\n",
.{func.returnType},
),
);
} else if (isPointer(func.returnType)) {
if (eql("u8", (stripType(func.returnType)))) {
try file.writeAll(
try allocPrint(
allocator,
") [*:0]const {s} {{\n",
.{stripType(func.returnType)},
),
);
} else {
try file.writeAll(
try allocPrint(
allocator,
") {s} {{\n",
.{func.returnType},
),
);
}
} else {
try file.writeAll(
try allocPrint(
allocator,
") {s} {{\n",
.{func.returnType},
),
);
}
const returnTypeIsVoid = eql(func.returnType, "void");
//--- body ------------------------------
if (isPointer(func.returnType)) {
try file.writeAll(try allocPrint(allocator, "return @ptrCast({s},\n", .{func.returnType}));
} else if (isPrimitiveOrPointer(func.returnType)) {
try file.writeAll("return ");
} else if (!returnTypeIsVoid) {
try file.writeAll(try allocPrint(allocator, "var out: {s} = undefined;\n", .{func.returnType}));
}
try file.writeAll(try allocPrint(allocator, "raygui.m{s}(\n", .{func.name}));
if (!isPrimitiveOrPointer(func.returnType)) {
if (bindings.containsStruct(stripType(func.returnType))) {
try file.writeAll(try allocPrint(allocator, "@ptrCast([*c]raygui.{s}, &out),\n", .{func.returnType}));
} else if (!returnTypeIsVoid) {
try file.writeAll(try allocPrint(allocator, "@ptrCast([*c]{s}, &out),\n", .{func.returnType}));
}
}
for (func.params) |param| {
if (isFunctionPointer(param.typ)) {
try file.writeAll(try allocPrint(allocator, "@ptrCast({s}),\n", .{param.name}));
} else if (bindings.containsStruct(stripType(param.typ)) and isPointer(param.typ)) {
try file.writeAll(try allocPrint(allocator, "@intToPtr([*c]raygui.{s}, @ptrToInt({s})),\n", .{ stripType(param.typ), param.name }));
} else if (bindings.containsEnum(param.typ)) {
try file.writeAll(try allocPrint(allocator, "@enumToInt({s}),\n", .{param.name}));
} else if (bindings.containsStruct(stripType(param.typ))) {
try file.writeAll(try allocPrint(allocator, "@intToPtr([*c]raygui.{s}, @ptrToInt(&{s})),\n", .{ stripType(param.typ), param.name }));
} else if (isPointer(param.typ)) {
if (isConst(param.typ)) {
try file.writeAll(try allocPrint(allocator, "@intToPtr([*c]const {s}, @ptrToInt({s})),\n", .{ stripType(param.typ), param.name }));
} else {
try file.writeAll(try allocPrint(allocator, "@ptrCast([*c]{s}, {s}),\n", .{ stripType(param.typ), param.name }));
}
} else {
try file.writeAll(try allocPrint(allocator, "{s},\n", .{param.name}));
}
}
if (isPointer(func.returnType)) {
try file.writeAll("),\n);\n");
} else {
try file.writeAll(");\n");
}
if (!isPrimitiveOrPointer(func.returnType) and !returnTypeIsVoid) {
try file.writeAll("return out;\n");
}
try file.writeAll("}\n");
}
std.log.info("generated functions", .{});
}
/// write: RETURN NAME(PARAMS...)
/// or: void NAME(RETURN*, PARAMS...)
fn writeCSignature(
allocator: std.mem.Allocator,
file: *fs.File,
func: mapping.RaylibFunction,
) !void {
const returnType = func.returnType;
//return directly
if (mapping.isPrimitiveOrPointer(returnType)) {
try file.writeAll(try allocPrint(allocator, "{s} m{s}(", .{ returnType, func.name }));
if (func.params == null or func.params.?.len == 0) {
try file.writeAll("void");
}
}
//wrap return type and put as first function parameter
else {
try file.writeAll(try allocPrint(allocator, "void m{s}({s} *out", .{ func.name, returnType }));
if (func.params != null and func.params.?.len > 0) {
try file.writeAll(", ");
}
}
if (func.params) |params| {
for (params, 0..) |param, i| {
const paramType = param.type;
if (mapping.isPrimitiveOrPointer(paramType) or isFunctionPointer(paramType)) {
try file.writeAll(try allocPrint(allocator, "{s} {s}", .{ paramType, param.name }));
} else {
try file.writeAll(try allocPrint(allocator, "{s} *{s}", .{ paramType, param.name }));
}
if (i < params.len - 1) {
try file.writeAll(", ");
}
}
}
try file.writeAll(")");
}
fn writeCFunctions(
allocator: std.mem.Allocator,
h: *fs.File,
c: *fs.File,
inject: Injections,
rl: mapping.CombinedRaylib,
) !void {
var hInject = try fs.cwd().openFile("inject.h", .{});
defer hInject.close();
try h.writeFileAll(hInject, .{});
var cInject = try fs.cwd().openFile("inject.c", .{});
defer cInject.close();
try c.writeFileAll(cInject, .{});
for (rl.functions.values()) |func| {
if (inject.containsSymbol(func.name)) continue;
//--- C-HEADER -----------------------------
try h.writeAll(try allocPrint(allocator, "// {s}\n", .{func.description}));
try writeCSignature(allocator, h, func);
try h.writeAll(";\n\n");
try writeCSignature(allocator, c, func);
try c.writeAll("\n{\n");
//--- C-IMPLEMENT -----------------------------
if (eql(func.returnType, "void")) {
try c.writeAll("\t");
} else if (mapping.isPrimitiveOrPointer(func.returnType)) {
try c.writeAll("\treturn ");
} else {
try c.writeAll("\t*out = ");
}
try c.writeAll(
try allocPrint(
allocator,
"{s}(",
.{func.name},
),
);
if (func.params) |params| {
for (params, 0..) |param, i| {
if (mapping.isPrimitiveOrPointer(param.type) or isFunctionPointer(param.type)) {
try c.writeAll(
try allocPrint(
allocator,
"{s}",
.{param.name},
),
);
} else {
try c.writeAll(
try allocPrint(
allocator,
"*{s}",
.{param.name},
),
);
}
if (i < params.len - 1) {
try c.writeAll(", ");
}
}
}
try c.writeAll(");\n}\n\n");
}
}
fn writeStructs(
allocator: std.mem.Allocator,
file: *fs.File,
bindings: mapping.Intermediate,
inject: Injections,
) !void {
var buf: [51200]u8 = undefined;
var fba = std.heap.FixedBufferAllocator.init(&buf);
for (bindings.structs) |s| {
if (inject.containsSymbol(s.name)) continue;
defer fba.reset();
try file.writeAll(
try allocPrint(
allocator,
"\n/// {?s}\npub const {s} = extern struct {{\n",
.{ s.description, s.name },
),
);
for (s.fields) |field| {
try file.writeAll(try allocPrint(allocator, "/// {?s}\n\t{s}: {s},\n", .{
field.description,
field.name,
field.typ,
}));
}
try file.writeAll("\n};\n");
}
std.log.info("generated structs", .{});
}
fn writeEnums(
allocator: std.mem.Allocator,
file: *fs.File,
bindings: mapping.Intermediate,
inject: Injections,
) !void {
var buf: [51200]u8 = undefined;
var fba = std.heap.FixedBufferAllocator.init(&buf);
for (bindings.enums) |e| {
if (inject.containsSymbol(e.name)) continue;
defer fba.reset();
try file.writeAll(
try allocPrint(
allocator,
"\n/// {?s}\npub const {s} = enum(i32) {{\n",
.{ e.description, e.name },
),
);
for (e.values) |value| {
try file.writeAll(try allocPrint(allocator, "/// {?s}\n{s} = {d},\n", .{
value.description,
value.name,
value.value,
}));
}
try file.writeAll("\n};\n");
}
std.log.info("generated enums", .{});
}
fn writeDefines(
allocator: std.mem.Allocator,
file: *fs.File,
bindings: mapping.Intermediate,
inject: Injections,
) !void {
var buf: [51200]u8 = undefined;
var fba = std.heap.FixedBufferAllocator.init(&buf);
for (bindings.defines) |d| {
if (inject.containsSymbol(d.name)) continue;
defer fba.reset();
try file.writeAll(
try allocPrint(
allocator,
"\n/// {?s}\npub const {s}: {s} = {s};\n",
.{ d.description, d.name, d.typ, d.value },
),
);
}
std.log.info("generated defines", .{});
}
fn writeInjections(
_: std.mem.Allocator,
file: *fs.File,
inject: Injections,
) !void {
var buf: [51200]u8 = undefined;
var fba = std.heap.FixedBufferAllocator.init(&buf);
for (inject.lines) |line| {
defer fba.reset();
try file.writeAll(try allocPrint(fba.allocator(), "{s}\n", .{line}));
}
std.log.info("written inject.zig", .{});
}
fn eql(a: []const u8, b: []const u8) bool {
return std.mem.eql(u8, a, b);
}
fn startsWith(haystack: []const u8, needle: []const u8) bool {
return std.mem.startsWith(u8, haystack, needle);
}
fn endsWith(haystack: []const u8, needle: []const u8) bool {
return std.mem.endsWith(u8, haystack, needle);
}
/// is c pointer type
fn isPointer(z: []const u8) bool {
return pointerOffset(z) > 0;
}
fn isFunctionPointer(z: []const u8) bool {
return std.mem.indexOf(u8, z, "fn(") != null or std.mem.endsWith(u8, z, "Callback");
}
fn pointerOffset(z: []const u8) usize {
if (startsWith(z, "*")) return 1;
if (startsWith(z, "?*")) return 2;
if (startsWith(z, "[*]")) return 3;
if (startsWith(z, "?[*]")) return 4;
if (startsWith(z, "[*c]")) return 4;
if (startsWith(z, "[*:0]")) return 5;
if (startsWith(z, "?[*:0]")) return 6;
return 0;
}
fn isConst(z: []const u8) bool {
return startsWith(z[pointerOffset(z)..], "const ");
}
fn isVoid(z: []const u8) bool {
return eql(stripType(z), "void");
}
/// strips const and pointer annotations
/// *const TName -> TName
fn stripType(z: []const u8) []const u8 {
var name = z[pointerOffset(z)..];
name = if (startsWith(name, "const ")) name["const ".len..] else name;
return std.mem.trim(u8, name, " \t\n");
}
/// true if Zig type is primitive or a pointer to anything
/// this means we don't need to wrap it in a pointer
pub fn isPrimitiveOrPointer(z: []const u8) bool {
const primitiveTypes = std.ComptimeStringMap(void, .{
// .{ "void", {} }, // zig void is zero sized while C void is >= 1 byte
.{ "bool", {} },
.{ "u8", {} },
.{ "i8", {} },
.{ "i16", {} },
.{ "u16", {} },
.{ "i32", {} },
.{ "u32", {} },
.{ "i64", {} },
.{ "u64", {} },
.{ "f32", {} },
.{ "f64", {} },
});
return primitiveTypes.has(stripType(z)) or pointerOffset(z) > 0;
}

547
libs/raygui/gui_icons.h Normal file
View File

@ -0,0 +1,547 @@
//////////////////////////////////////////////////////////////////////////////////
// //
// raygui Icons exporter v1.1 - Icons data exported as a values array //
// //
// more info and bugs-report: github.com/raysan5/raygui //
// feedback and support: ray[at]raylibtech.com //
// //
// Copyright (c) 2019-2021 raylib technologies (@raylibtech) //
// //
//////////////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
#define RAYGUI_ICON_SIZE 16 // Size of icons (squared)
#define RAYGUI_ICON_MAX_ICONS 256 // Maximum number of icons
#define RAYGUI_ICON_MAX_NAME_LENGTH 32 // Maximum length of icon name id
// Icons data is defined by bit array (every bit represents one pixel)
// Those arrays are stored as unsigned int data arrays, so every array
// element defines 32 pixels (bits) of information
// Number of elemens depend on RAYGUI_ICON_SIZE (by default 16x16 pixels)
#define RAYGUI_ICON_DATA_ELEMENTS (RAYGUI_ICON_SIZE*RAYGUI_ICON_SIZE/32)
//----------------------------------------------------------------------------------
// Icons enumeration
//----------------------------------------------------------------------------------
typedef enum {
RAYGUI_ICON_NONE = 0,
RAYGUI_ICON_FOLDER_FILE_OPEN = 1,
RAYGUI_ICON_FILE_SAVE_CLASSIC = 2,
RAYGUI_ICON_FOLDER_OPEN = 3,
RAYGUI_ICON_FOLDER_SAVE = 4,
RAYGUI_ICON_FILE_OPEN = 5,
RAYGUI_ICON_FILE_SAVE = 6,
RAYGUI_ICON_FILE_EXPORT = 7,
RAYGUI_ICON_FILE_NEW = 8,
RAYGUI_ICON_FILE_DELETE = 9,
RAYGUI_ICON_FILETYPE_TEXT = 10,
RAYGUI_ICON_FILETYPE_AUDIO = 11,
RAYGUI_ICON_FILETYPE_IMAGE = 12,
RAYGUI_ICON_FILETYPE_PLAY = 13,
RAYGUI_ICON_FILETYPE_VIDEO = 14,
RAYGUI_ICON_FILETYPE_INFO = 15,
RAYGUI_ICON_FILE_COPY = 16,
RAYGUI_ICON_FILE_CUT = 17,
RAYGUI_ICON_FILE_PASTE = 18,
RAYGUI_ICON_CURSOR_HAND = 19,
RAYGUI_ICON_CURSOR_POINTER = 20,
RAYGUI_ICON_CURSOR_CLASSIC = 21,
RAYGUI_ICON_PENCIL = 22,
RAYGUI_ICON_PENCIL_BIG = 23,
RAYGUI_ICON_BRUSH_CLASSIC = 24,
RAYGUI_ICON_BRUSH_PAINTER = 25,
RAYGUI_ICON_WATER_DROP = 26,
RAYGUI_ICON_COLOR_PICKER = 27,
RAYGUI_ICON_RUBBER = 28,
RAYGUI_ICON_COLOR_BUCKET = 29,
RAYGUI_ICON_TEXT_T = 30,
RAYGUI_ICON_TEXT_A = 31,
RAYGUI_ICON_SCALE = 32,
RAYGUI_ICON_RESIZE = 33,
RAYGUI_ICON_FILTER_POINT = 34,
RAYGUI_ICON_FILTER_BILINEAR = 35,
RAYGUI_ICON_CROP = 36,
RAYGUI_ICON_CROP_ALPHA = 37,
RAYGUI_ICON_SQUARE_TOGGLE = 38,
RAYGUI_ICON_SIMMETRY = 39,
RAYGUI_ICON_SIMMETRY_HORIZONTAL = 40,
RAYGUI_ICON_SIMMETRY_VERTICAL = 41,
RAYGUI_ICON_LENS = 42,
RAYGUI_ICON_LENS_BIG = 43,
RAYGUI_ICON_EYE_ON = 44,
RAYGUI_ICON_EYE_OFF = 45,
RAYGUI_ICON_FILTER_TOP = 46,
RAYGUI_ICON_FILTER = 47,
RAYGUI_ICON_TARGET_POINT = 48,
RAYGUI_ICON_TARGET_SMALL = 49,
RAYGUI_ICON_TARGET_BIG = 50,
RAYGUI_ICON_TARGET_MOVE = 51,
RAYGUI_ICON_CURSOR_MOVE = 52,
RAYGUI_ICON_CURSOR_SCALE = 53,
RAYGUI_ICON_CURSOR_SCALE_RIGHT = 54,
RAYGUI_ICON_CURSOR_SCALE_LEFT = 55,
RAYGUI_ICON_UNDO = 56,
RAYGUI_ICON_REDO = 57,
RAYGUI_ICON_REREDO = 58,
RAYGUI_ICON_MUTATE = 59,
RAYGUI_ICON_ROTATE = 60,
RAYGUI_ICON_REPEAT = 61,
RAYGUI_ICON_SHUFFLE = 62,
RAYGUI_ICON_EMPTYBOX = 63,
RAYGUI_ICON_TARGET = 64,
RAYGUI_ICON_TARGET_SMALL_FILL = 65,
RAYGUI_ICON_TARGET_BIG_FILL = 66,
RAYGUI_ICON_TARGET_MOVE_FILL = 67,
RAYGUI_ICON_CURSOR_MOVE_FILL = 68,
RAYGUI_ICON_CURSOR_SCALE_FILL = 69,
RAYGUI_ICON_CURSOR_SCALE_RIGHT_FILL = 70,
RAYGUI_ICON_CURSOR_SCALE_LEFT_FILL = 71,
RAYGUI_ICON_UNDO_FILL = 72,
RAYGUI_ICON_REDO_FILL = 73,
RAYGUI_ICON_REREDO_FILL = 74,
RAYGUI_ICON_MUTATE_FILL = 75,
RAYGUI_ICON_ROTATE_FILL = 76,
RAYGUI_ICON_REPEAT_FILL = 77,
RAYGUI_ICON_SHUFFLE_FILL = 78,
RAYGUI_ICON_EMPTYBOX_SMALL = 79,
RAYGUI_ICON_BOX = 80,
RAYGUI_ICON_BOX_TOP = 81,
RAYGUI_ICON_BOX_TOP_RIGHT = 82,
RAYGUI_ICON_BOX_RIGHT = 83,
RAYGUI_ICON_BOX_BOTTOM_RIGHT = 84,
RAYGUI_ICON_BOX_BOTTOM = 85,
RAYGUI_ICON_BOX_BOTTOM_LEFT = 86,
RAYGUI_ICON_BOX_LEFT = 87,
RAYGUI_ICON_BOX_TOP_LEFT = 88,
RAYGUI_ICON_BOX_CENTER = 89,
RAYGUI_ICON_BOX_CIRCLE_MASK = 90,
RAYGUI_ICON_POT = 91,
RAYGUI_ICON_ALPHA_MULTIPLY = 92,
RAYGUI_ICON_ALPHA_CLEAR = 93,
RAYGUI_ICON_DITHERING = 94,
RAYGUI_ICON_MIPMAPS = 95,
RAYGUI_ICON_BOX_GRID = 96,
RAYGUI_ICON_GRID = 97,
RAYGUI_ICON_BOX_CORNERS_SMALL = 98,
RAYGUI_ICON_BOX_CORNERS_BIG = 99,
RAYGUI_ICON_FOUR_BOXES = 100,
RAYGUI_ICON_GRID_FILL = 101,
RAYGUI_ICON_BOX_MULTISIZE = 102,
RAYGUI_ICON_ZOOM_SMALL = 103,
RAYGUI_ICON_ZOOM_MEDIUM = 104,
RAYGUI_ICON_ZOOM_BIG = 105,
RAYGUI_ICON_ZOOM_ALL = 106,
RAYGUI_ICON_ZOOM_CENTER = 107,
RAYGUI_ICON_BOX_DOTS_SMALL = 108,
RAYGUI_ICON_BOX_DOTS_BIG = 109,
RAYGUI_ICON_BOX_CONCENTRIC = 110,
RAYGUI_ICON_BOX_GRID_BIG = 111,
RAYGUI_ICON_OK_TICK = 112,
RAYGUI_ICON_CROSS = 113,
RAYGUI_ICON_ARROW_LEFT = 114,
RAYGUI_ICON_ARROW_RIGHT = 115,
RAYGUI_ICON_ARROW_BOTTOM = 116,
RAYGUI_ICON_ARROW_TOP = 117,
RAYGUI_ICON_ARROW_LEFT_FILL = 118,
RAYGUI_ICON_ARROW_RIGHT_FILL = 119,
RAYGUI_ICON_ARROW_BOTTOM_FILL = 120,
RAYGUI_ICON_ARROW_TOP_FILL = 121,
RAYGUI_ICON_AUDIO = 122,
RAYGUI_ICON_FX = 123,
RAYGUI_ICON_WAVE = 124,
RAYGUI_ICON_WAVE_SINUS = 125,
RAYGUI_ICON_WAVE_SQUARE = 126,
RAYGUI_ICON_WAVE_TRIANGULAR = 127,
RAYGUI_ICON_CROSS_SMALL = 128,
RAYGUI_ICON_PLAYER_PREVIOUS = 129,
RAYGUI_ICON_PLAYER_PLAY_BACK = 130,
RAYGUI_ICON_PLAYER_PLAY = 131,
RAYGUI_ICON_PLAYER_PAUSE = 132,
RAYGUI_ICON_PLAYER_STOP = 133,
RAYGUI_ICON_PLAYER_NEXT = 134,
RAYGUI_ICON_PLAYER_RECORD = 135,
RAYGUI_ICON_MAGNET = 136,
RAYGUI_ICON_LOCK_CLOSE = 137,
RAYGUI_ICON_LOCK_OPEN = 138,
RAYGUI_ICON_CLOCK = 139,
RAYGUI_ICON_TOOLS = 140,
RAYGUI_ICON_GEAR = 141,
RAYGUI_ICON_GEAR_BIG = 142,
RAYGUI_ICON_BIN = 143,
RAYGUI_ICON_HAND_POINTER = 144,
RAYGUI_ICON_LASER = 145,
RAYGUI_ICON_COIN = 146,
RAYGUI_ICON_EXPLOSION = 147,
RAYGUI_ICON_1UP = 148,
RAYGUI_ICON_PLAYER = 149,
RAYGUI_ICON_PLAYER_JUMP = 150,
RAYGUI_ICON_KEY = 151,
RAYGUI_ICON_DEMON = 152,
RAYGUI_ICON_TEXT_POPUP = 153,
RAYGUI_ICON_GEAR_EX = 154,
RAYGUI_ICON_CRACK = 155,
RAYGUI_ICON_CRACK_POINTS = 156,
RAYGUI_ICON_STAR = 157,
RAYGUI_ICON_DOOR = 158,
RAYGUI_ICON_EXIT = 159,
RAYGUI_ICON_MODE_2D = 160,
RAYGUI_ICON_MODE_3D = 161,
RAYGUI_ICON_CUBE = 162,
RAYGUI_ICON_CUBE_FACE_TOP = 163,
RAYGUI_ICON_CUBE_FACE_LEFT = 164,
RAYGUI_ICON_CUBE_FACE_FRONT = 165,
RAYGUI_ICON_CUBE_FACE_BOTTOM = 166,
RAYGUI_ICON_CUBE_FACE_RIGHT = 167,
RAYGUI_ICON_CUBE_FACE_BACK = 168,
RAYGUI_ICON_CAMERA = 169,
RAYGUI_ICON_SPECIAL = 170,
RAYGUI_ICON_LINK_NET = 171,
RAYGUI_ICON_LINK_BOXES = 172,
RAYGUI_ICON_LINK_MULTI = 173,
RAYGUI_ICON_LINK = 174,
RAYGUI_ICON_LINK_BROKE = 175,
RAYGUI_ICON_TEXT_NOTES = 176,
RAYGUI_ICON_NOTEBOOK = 177,
RAYGUI_ICON_SUITCASE = 178,
RAYGUI_ICON_SUITCASE_ZIP = 179,
RAYGUI_ICON_MAILBOX = 180,
RAYGUI_ICON_MONITOR = 181,
RAYGUI_ICON_PRINTER = 182,
RAYGUI_ICON_PHOTO_CAMERA = 183,
RAYGUI_ICON_PHOTO_CAMERA_FLASH = 184,
RAYGUI_ICON_HOUSE = 185,
RAYGUI_ICON_HEART = 186,
RAYGUI_ICON_CORNER = 187,
RAYGUI_ICON_VERTICAL_BARS = 188,
RAYGUI_ICON_VERTICAL_BARS_FILL = 189,
RAYGUI_ICON_LIFE_BARS = 190,
RAYGUI_ICON_INFO = 191,
RAYGUI_ICON_CROSSLINE = 192,
RAYGUI_ICON_HELP = 193,
RAYGUI_ICON_FILETYPE_ALPHA = 194,
RAYGUI_ICON_FILETYPE_HOME = 195,
RAYGUI_ICON_LAYERS_VISIBLE = 196,
RAYGUI_ICON_LAYERS = 197,
RAYGUI_ICON_WINDOW = 198,
RAYGUI_ICON_199 = 199,
RAYGUI_ICON_200 = 200,
RAYGUI_ICON_201 = 201,
RAYGUI_ICON_202 = 202,
RAYGUI_ICON_203 = 203,
RAYGUI_ICON_204 = 204,
RAYGUI_ICON_205 = 205,
RAYGUI_ICON_206 = 206,
RAYGUI_ICON_207 = 207,
RAYGUI_ICON_208 = 208,
RAYGUI_ICON_209 = 209,
RAYGUI_ICON_210 = 210,
RAYGUI_ICON_211 = 211,
RAYGUI_ICON_212 = 212,
RAYGUI_ICON_213 = 213,
RAYGUI_ICON_214 = 214,
RAYGUI_ICON_215 = 215,
RAYGUI_ICON_216 = 216,
RAYGUI_ICON_217 = 217,
RAYGUI_ICON_218 = 218,
RAYGUI_ICON_219 = 219,
RAYGUI_ICON_220 = 220,
RAYGUI_ICON_221 = 221,
RAYGUI_ICON_222 = 222,
RAYGUI_ICON_223 = 223,
RAYGUI_ICON_224 = 224,
RAYGUI_ICON_225 = 225,
RAYGUI_ICON_226 = 226,
RAYGUI_ICON_227 = 227,
RAYGUI_ICON_228 = 228,
RAYGUI_ICON_229 = 229,
RAYGUI_ICON_230 = 230,
RAYGUI_ICON_231 = 231,
RAYGUI_ICON_232 = 232,
RAYGUI_ICON_233 = 233,
RAYGUI_ICON_234 = 234,
RAYGUI_ICON_235 = 235,
RAYGUI_ICON_236 = 236,
RAYGUI_ICON_237 = 237,
RAYGUI_ICON_238 = 238,
RAYGUI_ICON_239 = 239,
RAYGUI_ICON_240 = 240,
RAYGUI_ICON_241 = 241,
RAYGUI_ICON_242 = 242,
RAYGUI_ICON_243 = 243,
RAYGUI_ICON_244 = 244,
RAYGUI_ICON_245 = 245,
RAYGUI_ICON_246 = 246,
RAYGUI_ICON_247 = 247,
RAYGUI_ICON_248 = 248,
RAYGUI_ICON_249 = 249,
RAYGUI_ICON_250 = 250,
RAYGUI_ICON_251 = 251,
RAYGUI_ICON_252 = 252,
RAYGUI_ICON_253 = 253,
RAYGUI_ICON_254 = 254,
RAYGUI_ICON_255 = 255,
} guiIconName;
//----------------------------------------------------------------------------------
// Icons data
//----------------------------------------------------------------------------------
static unsigned int guiIcons[RAYGUI_ICON_MAX_ICONS*RAYGUI_ICON_DATA_ELEMENTS] = {
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_NONE
0x3ff80000, 0x2f082008, 0x2042207e, 0x40027fc2, 0x40024002, 0x40024002, 0x40024002, 0x00007ffe, // RAYGUI_ICON_FOLDER_FILE_OPEN
0x3ffe0000, 0x44226422, 0x400247e2, 0x5ffa4002, 0x57ea500a, 0x500a500a, 0x40025ffa, 0x00007ffe, // RAYGUI_ICON_FILE_SAVE_CLASSIC
0x00000000, 0x0042007e, 0x40027fc2, 0x40024002, 0x41024002, 0x44424282, 0x793e4102, 0x00000100, // RAYGUI_ICON_FOLDER_OPEN
0x00000000, 0x0042007e, 0x40027fc2, 0x40024002, 0x41024102, 0x44424102, 0x793e4282, 0x00000000, // RAYGUI_ICON_FOLDER_SAVE
0x3ff00000, 0x201c2010, 0x20042004, 0x21042004, 0x24442284, 0x21042104, 0x20042104, 0x00003ffc, // RAYGUI_ICON_FILE_OPEN
0x3ff00000, 0x201c2010, 0x20042004, 0x21042004, 0x21042104, 0x22842444, 0x20042104, 0x00003ffc, // RAYGUI_ICON_FILE_SAVE
0x3ff00000, 0x201c2010, 0x00042004, 0x20041004, 0x20844784, 0x00841384, 0x20042784, 0x00003ffc, // RAYGUI_ICON_FILE_EXPORT
0x3ff00000, 0x201c2010, 0x20042004, 0x20042004, 0x22042204, 0x22042f84, 0x20042204, 0x00003ffc, // RAYGUI_ICON_FILE_NEW
0x3ff00000, 0x201c2010, 0x20042004, 0x20042004, 0x25042884, 0x25042204, 0x20042884, 0x00003ffc, // RAYGUI_ICON_FILE_DELETE
0x3ff00000, 0x201c2010, 0x20042004, 0x20042ff4, 0x20042ff4, 0x20042ff4, 0x20042004, 0x00003ffc, // RAYGUI_ICON_FILETYPE_TEXT
0x3ff00000, 0x201c2010, 0x27042004, 0x244424c4, 0x26442444, 0x20642664, 0x20042004, 0x00003ffc, // RAYGUI_ICON_FILETYPE_AUDIO
0x3ff00000, 0x201c2010, 0x26042604, 0x20042004, 0x35442884, 0x2414222c, 0x20042004, 0x00003ffc, // RAYGUI_ICON_FILETYPE_IMAGE
0x3ff00000, 0x201c2010, 0x20c42004, 0x22442144, 0x22442444, 0x20c42144, 0x20042004, 0x00003ffc, // RAYGUI_ICON_FILETYPE_PLAY
0x3ff00000, 0x3ffc2ff0, 0x3f3c2ff4, 0x3dbc2eb4, 0x3dbc2bb4, 0x3f3c2eb4, 0x3ffc2ff4, 0x00002ff4, // RAYGUI_ICON_FILETYPE_VIDEO
0x3ff00000, 0x201c2010, 0x21842184, 0x21842004, 0x21842184, 0x21842184, 0x20042184, 0x00003ffc, // RAYGUI_ICON_FILETYPE_INFO
0x0ff00000, 0x381c0810, 0x28042804, 0x28042804, 0x28042804, 0x28042804, 0x20102ffc, 0x00003ff0, // RAYGUI_ICON_FILE_COPY
0x00000000, 0x701c0000, 0x079c1e14, 0x55a000f0, 0x079c00f0, 0x701c1e14, 0x00000000, 0x00000000, // RAYGUI_ICON_FILE_CUT
0x01c00000, 0x13e41bec, 0x3f841004, 0x204420c4, 0x20442044, 0x20442044, 0x207c2044, 0x00003fc0, // RAYGUI_ICON_FILE_PASTE
0x00000000, 0x3aa00fe0, 0x2abc2aa0, 0x2aa42aa4, 0x20042aa4, 0x20042004, 0x3ffc2004, 0x00000000, // RAYGUI_ICON_CURSOR_HAND
0x00000000, 0x003c000c, 0x030800c8, 0x30100c10, 0x10202020, 0x04400840, 0x01800280, 0x00000000, // RAYGUI_ICON_CURSOR_POINTER
0x00000000, 0x00180000, 0x01f00078, 0x03e007f0, 0x07c003e0, 0x04000e40, 0x00000000, 0x00000000, // RAYGUI_ICON_CURSOR_CLASSIC
0x00000000, 0x04000000, 0x11000a00, 0x04400a80, 0x01100220, 0x00580088, 0x00000038, 0x00000000, // RAYGUI_ICON_PENCIL
0x04000000, 0x15000a00, 0x50402880, 0x14102820, 0x05040a08, 0x015c028c, 0x007c00bc, 0x00000000, // RAYGUI_ICON_PENCIL_BIG
0x01c00000, 0x01400140, 0x01400140, 0x0ff80140, 0x0ff80808, 0x0aa80808, 0x0aa80aa8, 0x00000ff8, // RAYGUI_ICON_BRUSH_CLASSIC
0x1ffc0000, 0x5ffc7ffe, 0x40004000, 0x00807f80, 0x01c001c0, 0x01c001c0, 0x01c001c0, 0x00000080, // RAYGUI_ICON_BRUSH_PAINTER
0x00000000, 0x00800000, 0x01c00080, 0x03e001c0, 0x07f003e0, 0x036006f0, 0x000001c0, 0x00000000, // RAYGUI_ICON_WATER_DROP
0x00000000, 0x3e003800, 0x1f803f80, 0x0c201e40, 0x02080c10, 0x00840104, 0x00380044, 0x00000000, // RAYGUI_ICON_COLOR_PICKER
0x00000000, 0x07800300, 0x1fe00fc0, 0x3f883fd0, 0x0e021f04, 0x02040402, 0x00f00108, 0x00000000, // RAYGUI_ICON_RUBBER
0x00c00000, 0x02800140, 0x08200440, 0x20081010, 0x2ffe3004, 0x03f807fc, 0x00e001f0, 0x00000040, // RAYGUI_ICON_COLOR_BUCKET
0x00000000, 0x21843ffc, 0x01800180, 0x01800180, 0x01800180, 0x01800180, 0x03c00180, 0x00000000, // RAYGUI_ICON_TEXT_T
0x00800000, 0x01400180, 0x06200340, 0x0c100620, 0x1ff80c10, 0x380c1808, 0x70067004, 0x0000f80f, // RAYGUI_ICON_TEXT_A
0x78000000, 0x50004000, 0x00004800, 0x03c003c0, 0x03c003c0, 0x00100000, 0x0002000a, 0x0000000e, // RAYGUI_ICON_SCALE
0x75560000, 0x5e004002, 0x54001002, 0x41001202, 0x408200fe, 0x40820082, 0x40820082, 0x00006afe, // RAYGUI_ICON_RESIZE
0x00000000, 0x3f003f00, 0x3f003f00, 0x3f003f00, 0x00400080, 0x001c0020, 0x001c001c, 0x00000000, // RAYGUI_ICON_FILTER_POINT
0x6d800000, 0x00004080, 0x40804080, 0x40800000, 0x00406d80, 0x001c0020, 0x001c001c, 0x00000000, // RAYGUI_ICON_FILTER_BILINEAR
0x40080000, 0x1ffe2008, 0x14081008, 0x11081208, 0x10481088, 0x10081028, 0x10047ff8, 0x00001002, // RAYGUI_ICON_CROP
0x00100000, 0x3ffc0010, 0x2ab03550, 0x22b02550, 0x20b02150, 0x20302050, 0x2000fff0, 0x00002000, // RAYGUI_ICON_CROP_ALPHA
0x40000000, 0x1ff82000, 0x04082808, 0x01082208, 0x00482088, 0x00182028, 0x35542008, 0x00000002, // RAYGUI_ICON_SQUARE_TOGGLE
0x00000000, 0x02800280, 0x06c006c0, 0x0ea00ee0, 0x1e901eb0, 0x3e883e98, 0x7efc7e8c, 0x00000000, // RAYGUI_ICON_SIMMETRY
0x01000000, 0x05600100, 0x1d480d50, 0x7d423d44, 0x3d447d42, 0x0d501d48, 0x01000560, 0x00000100, // RAYGUI_ICON_SIMMETRY_HORIZONTAL
0x01800000, 0x04200240, 0x10080810, 0x00001ff8, 0x00007ffe, 0x0ff01ff8, 0x03c007e0, 0x00000180, // RAYGUI_ICON_SIMMETRY_VERTICAL
0x00000000, 0x010800f0, 0x02040204, 0x02040204, 0x07f00308, 0x1c000e00, 0x30003800, 0x00000000, // RAYGUI_ICON_LENS
0x00000000, 0x061803f0, 0x08240c0c, 0x08040814, 0x0c0c0804, 0x23f01618, 0x18002400, 0x00000000, // RAYGUI_ICON_LENS_BIG
0x00000000, 0x00000000, 0x1c7007c0, 0x638e3398, 0x1c703398, 0x000007c0, 0x00000000, 0x00000000, // RAYGUI_ICON_EYE_ON
0x00000000, 0x10002000, 0x04700fc0, 0x610e3218, 0x1c703098, 0x001007a0, 0x00000008, 0x00000000, // RAYGUI_ICON_EYE_OFF
0x00000000, 0x00007ffc, 0x40047ffc, 0x10102008, 0x04400820, 0x02800280, 0x02800280, 0x00000100, // RAYGUI_ICON_FILTER_TOP
0x00000000, 0x40027ffe, 0x10082004, 0x04200810, 0x02400240, 0x02400240, 0x01400240, 0x000000c0, // RAYGUI_ICON_FILTER
0x00800000, 0x00800080, 0x00000080, 0x3c9e0000, 0x00000000, 0x00800080, 0x00800080, 0x00000000, // RAYGUI_ICON_TARGET_POINT
0x00800000, 0x00800080, 0x00800080, 0x3f7e01c0, 0x008001c0, 0x00800080, 0x00800080, 0x00000000, // RAYGUI_ICON_TARGET_SMALL
0x00800000, 0x00800080, 0x03e00080, 0x3e3e0220, 0x03e00220, 0x00800080, 0x00800080, 0x00000000, // RAYGUI_ICON_TARGET_BIG
0x01000000, 0x04400280, 0x01000100, 0x43842008, 0x43849ab2, 0x01002008, 0x04400100, 0x01000280, // RAYGUI_ICON_TARGET_MOVE
0x01000000, 0x04400280, 0x01000100, 0x41042108, 0x41049ff2, 0x01002108, 0x04400100, 0x01000280, // RAYGUI_ICON_CURSOR_MOVE
0x781e0000, 0x500a4002, 0x04204812, 0x00000240, 0x02400000, 0x48120420, 0x4002500a, 0x0000781e, // RAYGUI_ICON_CURSOR_SCALE
0x00000000, 0x20003c00, 0x24002800, 0x01000200, 0x00400080, 0x00140024, 0x003c0004, 0x00000000, // RAYGUI_ICON_CURSOR_SCALE_RIGHT
0x00000000, 0x0004003c, 0x00240014, 0x00800040, 0x02000100, 0x28002400, 0x3c002000, 0x00000000, // RAYGUI_ICON_CURSOR_SCALE_LEFT
0x00000000, 0x00100020, 0x10101fc8, 0x10001020, 0x10001000, 0x10001000, 0x00001fc0, 0x00000000, // RAYGUI_ICON_UNDO
0x00000000, 0x08000400, 0x080813f8, 0x00080408, 0x00080008, 0x00080008, 0x000003f8, 0x00000000, // RAYGUI_ICON_REDO
0x00000000, 0x3ffc0000, 0x20042004, 0x20002000, 0x20402000, 0x3f902020, 0x00400020, 0x00000000, // RAYGUI_ICON_REREDO
0x00000000, 0x3ffc0000, 0x20042004, 0x27fc2004, 0x20202000, 0x3fc82010, 0x00200010, 0x00000000, // RAYGUI_ICON_MUTATE
0x00000000, 0x0ff00000, 0x10081818, 0x11801008, 0x10001180, 0x18101020, 0x00100fc8, 0x00000020, // RAYGUI_ICON_ROTATE
0x00000000, 0x04000200, 0x240429fc, 0x20042204, 0x20442004, 0x3f942024, 0x00400020, 0x00000000, // RAYGUI_ICON_REPEAT
0x00000000, 0x20001000, 0x22104c0e, 0x00801120, 0x11200040, 0x4c0e2210, 0x10002000, 0x00000000, // RAYGUI_ICON_SHUFFLE
0x7ffe0000, 0x50024002, 0x44024802, 0x41024202, 0x40424082, 0x40124022, 0x4002400a, 0x00007ffe, // RAYGUI_ICON_EMPTYBOX
0x00800000, 0x03e00080, 0x08080490, 0x3c9e0808, 0x08080808, 0x03e00490, 0x00800080, 0x00000000, // RAYGUI_ICON_TARGET
0x00800000, 0x00800080, 0x00800080, 0x3ffe01c0, 0x008001c0, 0x00800080, 0x00800080, 0x00000000, // RAYGUI_ICON_TARGET_SMALL_FILL
0x00800000, 0x00800080, 0x03e00080, 0x3ffe03e0, 0x03e003e0, 0x00800080, 0x00800080, 0x00000000, // RAYGUI_ICON_TARGET_BIG_FILL
0x01000000, 0x07c00380, 0x01000100, 0x638c2008, 0x638cfbbe, 0x01002008, 0x07c00100, 0x01000380, // RAYGUI_ICON_TARGET_MOVE_FILL
0x01000000, 0x07c00380, 0x01000100, 0x610c2108, 0x610cfffe, 0x01002108, 0x07c00100, 0x01000380, // RAYGUI_ICON_CURSOR_MOVE_FILL
0x781e0000, 0x6006700e, 0x04204812, 0x00000240, 0x02400000, 0x48120420, 0x700e6006, 0x0000781e, // RAYGUI_ICON_CURSOR_SCALE_FILL
0x00000000, 0x38003c00, 0x24003000, 0x01000200, 0x00400080, 0x000c0024, 0x003c001c, 0x00000000, // RAYGUI_ICON_CURSOR_SCALE_RIGHT_FILL
0x00000000, 0x001c003c, 0x0024000c, 0x00800040, 0x02000100, 0x30002400, 0x3c003800, 0x00000000, // RAYGUI_ICON_CURSOR_SCALE_LEFT_FILL
0x00000000, 0x00300020, 0x10301ff8, 0x10001020, 0x10001000, 0x10001000, 0x00001fc0, 0x00000000, // RAYGUI_ICON_UNDO_FILL
0x00000000, 0x0c000400, 0x0c081ff8, 0x00080408, 0x00080008, 0x00080008, 0x000003f8, 0x00000000, // RAYGUI_ICON_REDO_FILL
0x00000000, 0x3ffc0000, 0x20042004, 0x20002000, 0x20402000, 0x3ff02060, 0x00400060, 0x00000000, // RAYGUI_ICON_REREDO_FILL
0x00000000, 0x3ffc0000, 0x20042004, 0x27fc2004, 0x20202000, 0x3ff82030, 0x00200030, 0x00000000, // RAYGUI_ICON_MUTATE_FILL
0x00000000, 0x0ff00000, 0x10081818, 0x11801008, 0x10001180, 0x18301020, 0x00300ff8, 0x00000020, // RAYGUI_ICON_ROTATE_FILL
0x00000000, 0x06000200, 0x26042ffc, 0x20042204, 0x20442004, 0x3ff42064, 0x00400060, 0x00000000, // RAYGUI_ICON_REPEAT_FILL
0x00000000, 0x30001000, 0x32107c0e, 0x00801120, 0x11200040, 0x7c0e3210, 0x10003000, 0x00000000, // RAYGUI_ICON_SHUFFLE_FILL
0x00000000, 0x30043ffc, 0x24042804, 0x21042204, 0x20442084, 0x20142024, 0x3ffc200c, 0x00000000, // RAYGUI_ICON_EMPTYBOX_SMALL
0x00000000, 0x20043ffc, 0x20042004, 0x20042004, 0x20042004, 0x20042004, 0x3ffc2004, 0x00000000, // RAYGUI_ICON_BOX
0x00000000, 0x23c43ffc, 0x23c423c4, 0x200423c4, 0x20042004, 0x20042004, 0x3ffc2004, 0x00000000, // RAYGUI_ICON_BOX_TOP
0x00000000, 0x3e043ffc, 0x3e043e04, 0x20043e04, 0x20042004, 0x20042004, 0x3ffc2004, 0x00000000, // RAYGUI_ICON_BOX_TOP_RIGHT
0x00000000, 0x20043ffc, 0x20042004, 0x3e043e04, 0x3e043e04, 0x20042004, 0x3ffc2004, 0x00000000, // RAYGUI_ICON_BOX_RIGHT
0x00000000, 0x20043ffc, 0x20042004, 0x20042004, 0x3e042004, 0x3e043e04, 0x3ffc3e04, 0x00000000, // RAYGUI_ICON_BOX_BOTTOM_RIGHT
0x00000000, 0x20043ffc, 0x20042004, 0x20042004, 0x23c42004, 0x23c423c4, 0x3ffc23c4, 0x00000000, // RAYGUI_ICON_BOX_BOTTOM
0x00000000, 0x20043ffc, 0x20042004, 0x20042004, 0x207c2004, 0x207c207c, 0x3ffc207c, 0x00000000, // RAYGUI_ICON_BOX_BOTTOM_LEFT
0x00000000, 0x20043ffc, 0x20042004, 0x207c207c, 0x207c207c, 0x20042004, 0x3ffc2004, 0x00000000, // RAYGUI_ICON_BOX_LEFT
0x00000000, 0x207c3ffc, 0x207c207c, 0x2004207c, 0x20042004, 0x20042004, 0x3ffc2004, 0x00000000, // RAYGUI_ICON_BOX_TOP_LEFT
0x00000000, 0x20043ffc, 0x20042004, 0x23c423c4, 0x23c423c4, 0x20042004, 0x3ffc2004, 0x00000000, // RAYGUI_ICON_BOX_CENTER
0x7ffe0000, 0x40024002, 0x47e24182, 0x4ff247e2, 0x47e24ff2, 0x418247e2, 0x40024002, 0x00007ffe, // RAYGUI_ICON_BOX_CIRCLE_MASK
0x7fff0000, 0x40014001, 0x40014001, 0x49555ddd, 0x4945495d, 0x400149c5, 0x40014001, 0x00007fff, // RAYGUI_ICON_POT
0x7ffe0000, 0x53327332, 0x44ce4cce, 0x41324332, 0x404e40ce, 0x48125432, 0x4006540e, 0x00007ffe, // RAYGUI_ICON_ALPHA_MULTIPLY
0x7ffe0000, 0x53327332, 0x44ce4cce, 0x41324332, 0x5c4e40ce, 0x44124432, 0x40065c0e, 0x00007ffe, // RAYGUI_ICON_ALPHA_CLEAR
0x7ffe0000, 0x42fe417e, 0x42fe417e, 0x42fe417e, 0x42fe417e, 0x42fe417e, 0x42fe417e, 0x00007ffe, // RAYGUI_ICON_DITHERING
0x07fe0000, 0x1ffa0002, 0x7fea000a, 0x402a402a, 0x5b2a512a, 0x5128552a, 0x40205128, 0x00007fe0, // RAYGUI_ICON_MIPMAPS
0x00000000, 0x1ff80000, 0x12481248, 0x12481ff8, 0x1ff81248, 0x12481248, 0x00001ff8, 0x00000000, // RAYGUI_ICON_BOX_GRID
0x12480000, 0x7ffe1248, 0x12481248, 0x12487ffe, 0x7ffe1248, 0x12481248, 0x12487ffe, 0x00001248, // RAYGUI_ICON_GRID
0x00000000, 0x1c380000, 0x1c3817e8, 0x08100810, 0x08100810, 0x17e81c38, 0x00001c38, 0x00000000, // RAYGUI_ICON_BOX_CORNERS_SMALL
0x700e0000, 0x700e5ffa, 0x20042004, 0x20042004, 0x20042004, 0x20042004, 0x5ffa700e, 0x0000700e, // RAYGUI_ICON_BOX_CORNERS_BIG
0x3f7e0000, 0x21422142, 0x21422142, 0x00003f7e, 0x21423f7e, 0x21422142, 0x3f7e2142, 0x00000000, // RAYGUI_ICON_FOUR_BOXES
0x00000000, 0x3bb80000, 0x3bb83bb8, 0x3bb80000, 0x3bb83bb8, 0x3bb80000, 0x3bb83bb8, 0x00000000, // RAYGUI_ICON_GRID_FILL
0x7ffe0000, 0x7ffe7ffe, 0x77fe7000, 0x77fe77fe, 0x777e7700, 0x777e777e, 0x777e777e, 0x0000777e, // RAYGUI_ICON_BOX_MULTISIZE
0x781e0000, 0x40024002, 0x00004002, 0x01800000, 0x00000180, 0x40020000, 0x40024002, 0x0000781e, // RAYGUI_ICON_ZOOM_SMALL
0x781e0000, 0x40024002, 0x00004002, 0x03c003c0, 0x03c003c0, 0x40020000, 0x40024002, 0x0000781e, // RAYGUI_ICON_ZOOM_MEDIUM
0x781e0000, 0x40024002, 0x07e04002, 0x07e007e0, 0x07e007e0, 0x400207e0, 0x40024002, 0x0000781e, // RAYGUI_ICON_ZOOM_BIG
0x781e0000, 0x5ffa4002, 0x1ff85ffa, 0x1ff81ff8, 0x1ff81ff8, 0x5ffa1ff8, 0x40025ffa, 0x0000781e, // RAYGUI_ICON_ZOOM_ALL
0x00000000, 0x2004381c, 0x00002004, 0x00000000, 0x00000000, 0x20040000, 0x381c2004, 0x00000000, // RAYGUI_ICON_ZOOM_CENTER
0x00000000, 0x1db80000, 0x10081008, 0x10080000, 0x00001008, 0x10081008, 0x00001db8, 0x00000000, // RAYGUI_ICON_BOX_DOTS_SMALL
0x35560000, 0x00002002, 0x00002002, 0x00002002, 0x00002002, 0x00002002, 0x35562002, 0x00000000, // RAYGUI_ICON_BOX_DOTS_BIG
0x7ffe0000, 0x40024002, 0x48124ff2, 0x49924812, 0x48124992, 0x4ff24812, 0x40024002, 0x00007ffe, // RAYGUI_ICON_BOX_CONCENTRIC
0x00000000, 0x10841ffc, 0x10841084, 0x1ffc1084, 0x10841084, 0x10841084, 0x00001ffc, 0x00000000, // RAYGUI_ICON_BOX_GRID_BIG
0x00000000, 0x00000000, 0x10000000, 0x04000800, 0x01040200, 0x00500088, 0x00000020, 0x00000000, // RAYGUI_ICON_OK_TICK
0x00000000, 0x10080000, 0x04200810, 0x01800240, 0x02400180, 0x08100420, 0x00001008, 0x00000000, // RAYGUI_ICON_CROSS
0x00000000, 0x02000000, 0x00800100, 0x00200040, 0x00200010, 0x00800040, 0x02000100, 0x00000000, // RAYGUI_ICON_ARROW_LEFT
0x00000000, 0x00400000, 0x01000080, 0x04000200, 0x04000800, 0x01000200, 0x00400080, 0x00000000, // RAYGUI_ICON_ARROW_RIGHT
0x00000000, 0x00000000, 0x00000000, 0x08081004, 0x02200410, 0x00800140, 0x00000000, 0x00000000, // RAYGUI_ICON_ARROW_BOTTOM
0x00000000, 0x00000000, 0x01400080, 0x04100220, 0x10040808, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_ARROW_TOP
0x00000000, 0x02000000, 0x03800300, 0x03e003c0, 0x03e003f0, 0x038003c0, 0x02000300, 0x00000000, // RAYGUI_ICON_ARROW_LEFT_FILL
0x00000000, 0x00400000, 0x01c000c0, 0x07c003c0, 0x07c00fc0, 0x01c003c0, 0x004000c0, 0x00000000, // RAYGUI_ICON_ARROW_RIGHT_FILL
0x00000000, 0x00000000, 0x00000000, 0x0ff81ffc, 0x03e007f0, 0x008001c0, 0x00000000, 0x00000000, // RAYGUI_ICON_ARROW_BOTTOM_FILL
0x00000000, 0x00000000, 0x01c00080, 0x07f003e0, 0x1ffc0ff8, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_ARROW_TOP_FILL
0x00000000, 0x18a008c0, 0x32881290, 0x24822686, 0x26862482, 0x12903288, 0x08c018a0, 0x00000000, // RAYGUI_ICON_AUDIO
0x00000000, 0x04800780, 0x004000c0, 0x662000f0, 0x08103c30, 0x130a0e18, 0x0000318e, 0x00000000, // RAYGUI_ICON_FX
0x00000000, 0x00800000, 0x08880888, 0x2aaa0a8a, 0x0a8a2aaa, 0x08880888, 0x00000080, 0x00000000, // RAYGUI_ICON_WAVE
0x00000000, 0x00600000, 0x01080090, 0x02040108, 0x42044204, 0x24022402, 0x00001800, 0x00000000, // RAYGUI_ICON_WAVE_SINUS
0x00000000, 0x07f80000, 0x04080408, 0x04080408, 0x04080408, 0x7c0e0408, 0x00000000, 0x00000000, // RAYGUI_ICON_WAVE_SQUARE
0x00000000, 0x00000000, 0x00a00040, 0x22084110, 0x08021404, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_WAVE_TRIANGULAR
0x00000000, 0x00000000, 0x04200000, 0x01800240, 0x02400180, 0x00000420, 0x00000000, 0x00000000, // RAYGUI_ICON_CROSS_SMALL
0x00000000, 0x18380000, 0x12281428, 0x10a81128, 0x112810a8, 0x14281228, 0x00001838, 0x00000000, // RAYGUI_ICON_PLAYER_PREVIOUS
0x00000000, 0x18000000, 0x11801600, 0x10181060, 0x10601018, 0x16001180, 0x00001800, 0x00000000, // RAYGUI_ICON_PLAYER_PLAY_BACK
0x00000000, 0x00180000, 0x01880068, 0x18080608, 0x06081808, 0x00680188, 0x00000018, 0x00000000, // RAYGUI_ICON_PLAYER_PLAY
0x00000000, 0x1e780000, 0x12481248, 0x12481248, 0x12481248, 0x12481248, 0x00001e78, 0x00000000, // RAYGUI_ICON_PLAYER_PAUSE
0x00000000, 0x1ff80000, 0x10081008, 0x10081008, 0x10081008, 0x10081008, 0x00001ff8, 0x00000000, // RAYGUI_ICON_PLAYER_STOP
0x00000000, 0x1c180000, 0x14481428, 0x15081488, 0x14881508, 0x14281448, 0x00001c18, 0x00000000, // RAYGUI_ICON_PLAYER_NEXT
0x00000000, 0x03c00000, 0x08100420, 0x10081008, 0x10081008, 0x04200810, 0x000003c0, 0x00000000, // RAYGUI_ICON_PLAYER_RECORD
0x00000000, 0x0c3007e0, 0x13c81818, 0x14281668, 0x14281428, 0x1c381c38, 0x08102244, 0x00000000, // RAYGUI_ICON_MAGNET
0x07c00000, 0x08200820, 0x3ff80820, 0x23882008, 0x21082388, 0x20082108, 0x1ff02008, 0x00000000, // RAYGUI_ICON_LOCK_CLOSE
0x07c00000, 0x08000800, 0x3ff80800, 0x23882008, 0x21082388, 0x20082108, 0x1ff02008, 0x00000000, // RAYGUI_ICON_LOCK_OPEN
0x01c00000, 0x0c180770, 0x3086188c, 0x60832082, 0x60034781, 0x30062002, 0x0c18180c, 0x01c00770, // RAYGUI_ICON_CLOCK
0x0a200000, 0x1b201b20, 0x04200e20, 0x04200420, 0x04700420, 0x0e700e70, 0x0e700e70, 0x04200e70, // RAYGUI_ICON_TOOLS
0x01800000, 0x3bdc318c, 0x0ff01ff8, 0x7c3e1e78, 0x1e787c3e, 0x1ff80ff0, 0x318c3bdc, 0x00000180, // RAYGUI_ICON_GEAR
0x01800000, 0x3ffc318c, 0x1c381ff8, 0x781e1818, 0x1818781e, 0x1ff81c38, 0x318c3ffc, 0x00000180, // RAYGUI_ICON_GEAR_BIG
0x00000000, 0x08080ff8, 0x08081ffc, 0x0aa80aa8, 0x0aa80aa8, 0x0aa80aa8, 0x08080aa8, 0x00000ff8, // RAYGUI_ICON_BIN
0x00000000, 0x00000000, 0x20043ffc, 0x08043f84, 0x04040f84, 0x04040784, 0x000007fc, 0x00000000, // RAYGUI_ICON_HAND_POINTER
0x00000000, 0x24400400, 0x00001480, 0x6efe0e00, 0x00000e00, 0x24401480, 0x00000400, 0x00000000, // RAYGUI_ICON_LASER
0x00000000, 0x03c00000, 0x08300460, 0x11181118, 0x11181118, 0x04600830, 0x000003c0, 0x00000000, // RAYGUI_ICON_COIN
0x00000000, 0x10880080, 0x06c00810, 0x366c07e0, 0x07e00240, 0x00001768, 0x04200240, 0x00000000, // RAYGUI_ICON_EXPLOSION
0x00000000, 0x3d280000, 0x2528252c, 0x3d282528, 0x05280528, 0x05e80528, 0x00000000, 0x00000000, // RAYGUI_ICON_1UP
0x01800000, 0x03c003c0, 0x018003c0, 0x0ff007e0, 0x0bd00bd0, 0x0a500bd0, 0x02400240, 0x02400240, // RAYGUI_ICON_PLAYER
0x01800000, 0x03c003c0, 0x118013c0, 0x03c81ff8, 0x07c003c8, 0x04400440, 0x0c080478, 0x00000000, // RAYGUI_ICON_PLAYER_JUMP
0x3ff80000, 0x30183ff8, 0x30183018, 0x3ff83ff8, 0x03000300, 0x03c003c0, 0x03e00300, 0x000003e0, // RAYGUI_ICON_KEY
0x3ff80000, 0x3ff83ff8, 0x33983ff8, 0x3ff83398, 0x3ff83ff8, 0x00000540, 0x0fe00aa0, 0x00000fe0, // RAYGUI_ICON_DEMON
0x00000000, 0x0ff00000, 0x20041008, 0x25442004, 0x10082004, 0x06000bf0, 0x00000300, 0x00000000, // RAYGUI_ICON_TEXT_POPUP
0x00000000, 0x11440000, 0x07f00be8, 0x1c1c0e38, 0x1c1c0c18, 0x07f00e38, 0x11440be8, 0x00000000, // RAYGUI_ICON_GEAR_EX
0x00000000, 0x20080000, 0x0c601010, 0x07c00fe0, 0x07c007c0, 0x0c600fe0, 0x20081010, 0x00000000, // RAYGUI_ICON_CRACK
0x00000000, 0x20080000, 0x0c601010, 0x04400fe0, 0x04405554, 0x0c600fe0, 0x20081010, 0x00000000, // RAYGUI_ICON_CRACK_POINTS
0x00000000, 0x00800080, 0x01c001c0, 0x1ffc3ffe, 0x03e007f0, 0x07f003e0, 0x0c180770, 0x00000808, // RAYGUI_ICON_STAR
0x0ff00000, 0x08180810, 0x08100818, 0x0a100810, 0x08180810, 0x08100818, 0x08100810, 0x00001ff8, // RAYGUI_ICON_DOOR
0x0ff00000, 0x08100810, 0x08100810, 0x10100010, 0x4f902010, 0x10102010, 0x08100010, 0x00000ff0, // RAYGUI_ICON_EXIT
0x00040000, 0x001f000e, 0x0ef40004, 0x12f41284, 0x0ef41214, 0x10040004, 0x7ffc3004, 0x10003000, // RAYGUI_ICON_MODE_2D
0x78040000, 0x501f600e, 0x0ef44004, 0x12f41284, 0x0ef41284, 0x10140004, 0x7ffc300c, 0x10003000, // RAYGUI_ICON_MODE_3D
0x7fe00000, 0x50286030, 0x47fe4804, 0x44224402, 0x44224422, 0x241275e2, 0x0c06140a, 0x000007fe, // RAYGUI_ICON_CUBE
0x7fe00000, 0x5ff87ff0, 0x47fe4ffc, 0x44224402, 0x44224422, 0x241275e2, 0x0c06140a, 0x000007fe, // RAYGUI_ICON_CUBE_FACE_TOP
0x7fe00000, 0x50386030, 0x47fe483c, 0x443e443e, 0x443e443e, 0x241e75fe, 0x0c06140e, 0x000007fe, // RAYGUI_ICON_CUBE_FACE_LEFT
0x7fe00000, 0x50286030, 0x47fe4804, 0x47fe47fe, 0x47fe47fe, 0x27fe77fe, 0x0ffe17fe, 0x000007fe, // RAYGUI_ICON_CUBE_FACE_FRONT
0x7fe00000, 0x50286030, 0x47fe4804, 0x44224402, 0x44224422, 0x3ff27fe2, 0x0ffe1ffa, 0x000007fe, // RAYGUI_ICON_CUBE_FACE_BOTTOM
0x7fe00000, 0x70286030, 0x7ffe7804, 0x7c227c02, 0x7c227c22, 0x3c127de2, 0x0c061c0a, 0x000007fe, // RAYGUI_ICON_CUBE_FACE_RIGHT
0x7fe00000, 0x7fe87ff0, 0x7ffe7fe4, 0x7fe27fe2, 0x7fe27fe2, 0x24127fe2, 0x0c06140a, 0x000007fe, // RAYGUI_ICON_CUBE_FACE_BACK
0x00000000, 0x2a0233fe, 0x22022602, 0x22022202, 0x2a022602, 0x00a033fe, 0x02080110, 0x00000000, // RAYGUI_ICON_CAMERA
0x00000000, 0x200c3ffc, 0x000c000c, 0x3ffc000c, 0x30003000, 0x30003000, 0x3ffc3004, 0x00000000, // RAYGUI_ICON_SPECIAL
0x00000000, 0x0022003e, 0x012201e2, 0x0100013e, 0x01000100, 0x79000100, 0x4f004900, 0x00007800, // RAYGUI_ICON_LINK_NET
0x00000000, 0x44007c00, 0x45004600, 0x00627cbe, 0x00620022, 0x45007cbe, 0x44004600, 0x00007c00, // RAYGUI_ICON_LINK_BOXES
0x00000000, 0x0044007c, 0x0010007c, 0x3f100010, 0x3f1021f0, 0x3f100010, 0x3f0021f0, 0x00000000, // RAYGUI_ICON_LINK_MULTI
0x00000000, 0x0044007c, 0x00440044, 0x0010007c, 0x00100010, 0x44107c10, 0x440047f0, 0x00007c00, // RAYGUI_ICON_LINK
0x00000000, 0x0044007c, 0x00440044, 0x0000007c, 0x00000010, 0x44007c10, 0x44004550, 0x00007c00, // RAYGUI_ICON_LINK_BROKE
0x02a00000, 0x22a43ffc, 0x20042004, 0x20042ff4, 0x20042ff4, 0x20042ff4, 0x20042004, 0x00003ffc, // RAYGUI_ICON_TEXT_NOTES
0x3ffc0000, 0x20042004, 0x245e27c4, 0x27c42444, 0x2004201e, 0x201e2004, 0x20042004, 0x00003ffc, // RAYGUI_ICON_NOTEBOOK
0x00000000, 0x07e00000, 0x04200420, 0x24243ffc, 0x24242424, 0x24242424, 0x3ffc2424, 0x00000000, // RAYGUI_ICON_SUITCASE
0x00000000, 0x0fe00000, 0x08200820, 0x40047ffc, 0x7ffc5554, 0x40045554, 0x7ffc4004, 0x00000000, // RAYGUI_ICON_SUITCASE_ZIP
0x00000000, 0x20043ffc, 0x3ffc2004, 0x13c81008, 0x100813c8, 0x10081008, 0x1ff81008, 0x00000000, // RAYGUI_ICON_MAILBOX
0x00000000, 0x40027ffe, 0x5ffa5ffa, 0x5ffa5ffa, 0x40025ffa, 0x03c07ffe, 0x1ff81ff8, 0x00000000, // RAYGUI_ICON_MONITOR
0x0ff00000, 0x6bfe7ffe, 0x7ffe7ffe, 0x68167ffe, 0x08106816, 0x08100810, 0x0ff00810, 0x00000000, // RAYGUI_ICON_PRINTER
0x3ff80000, 0xfffe2008, 0x870a8002, 0x904a888a, 0x904a904a, 0x870a888a, 0xfffe8002, 0x00000000, // RAYGUI_ICON_PHOTO_CAMERA
0x0fc00000, 0xfcfe0cd8, 0x8002fffe, 0x84428382, 0x84428442, 0x80028382, 0xfffe8002, 0x00000000, // RAYGUI_ICON_PHOTO_CAMERA_FLASH
0x00000000, 0x02400180, 0x08100420, 0x20041008, 0x23c42004, 0x22442244, 0x3ffc2244, 0x00000000, // RAYGUI_ICON_HOUSE
0x00000000, 0x1c700000, 0x3ff83ef8, 0x3ff83ff8, 0x0fe01ff0, 0x038007c0, 0x00000100, 0x00000000, // RAYGUI_ICON_HEART
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x80000000, 0xe000c000, // RAYGUI_ICON_CORNER
0x00000000, 0x14001c00, 0x15c01400, 0x15401540, 0x155c1540, 0x15541554, 0x1ddc1554, 0x00000000, // RAYGUI_ICON_VERTICAL_BARS
0x00000000, 0x03000300, 0x1b001b00, 0x1b601b60, 0x1b6c1b60, 0x1b6c1b6c, 0x1b6c1b6c, 0x00000000, // RAYGUI_ICON_VERTICAL_BARS_FILL
0x00000000, 0x00000000, 0x403e7ffe, 0x7ffe403e, 0x7ffe0000, 0x43fe43fe, 0x00007ffe, 0x00000000, // RAYGUI_ICON_LIFE_BARS
0x7ffc0000, 0x43844004, 0x43844284, 0x43844004, 0x42844284, 0x42844284, 0x40044384, 0x00007ffc, // RAYGUI_ICON_INFO
0x40008000, 0x10002000, 0x04000800, 0x01000200, 0x00400080, 0x00100020, 0x00040008, 0x00010002, // RAYGUI_ICON_CROSSLINE
0x00000000, 0x1ff01ff0, 0x18301830, 0x1f001830, 0x03001f00, 0x00000300, 0x03000300, 0x00000000, // RAYGUI_ICON_HELP
0x3ff00000, 0x2abc3550, 0x2aac3554, 0x2aac3554, 0x2aac3554, 0x2aac3554, 0x2aac3554, 0x00003ffc, // RAYGUI_ICON_FILETYPE_ALPHA
0x3ff00000, 0x201c2010, 0x22442184, 0x28142424, 0x29942814, 0x2ff42994, 0x20042004, 0x00003ffc, // RAYGUI_ICON_FILETYPE_HOME
0x07fe0000, 0x04020402, 0x7fe20402, 0x44224422, 0x44224422, 0x402047fe, 0x40204020, 0x00007fe0, // RAYGUI_ICON_LAYERS_VISIBLE
0x07fe0000, 0x04020402, 0x7c020402, 0x44024402, 0x44024402, 0x402047fe, 0x40204020, 0x00007fe0, // RAYGUI_ICON_LAYERS
0x00000000, 0x40027ffe, 0x7ffe4002, 0x40024002, 0x40024002, 0x40024002, 0x7ffe4002, 0x00000000, // RAYGUI_ICON_WINDOW
0x09100000, 0x09f00910, 0x09100910, 0x00000910, 0x24a2779e, 0x27a224a2, 0x709e20a2, 0x00000000, // RAYGUI_ICON_199
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_200
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_201
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_202
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_203
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_204
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_205
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_206
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_207
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_208
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_209
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_210
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_211
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_212
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_213
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_214
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_215
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_216
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_217
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_218
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_219
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_220
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_221
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_222
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_223
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_224
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_225
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_226
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_227
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_228
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_229
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_230
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_231
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_232
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_233
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_234
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_235
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_236
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_237
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_238
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_239
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_240
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_241
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_242
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_243
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_244
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_245
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_246
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_247
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_248
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_249
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_250
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_251
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_252
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_253
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_254
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RAYGUI_ICON_255
};

2
libs/raygui/inject.c Normal file
View File

@ -0,0 +1,2 @@
#include "raygui.h"

2
libs/raygui/inject.h Normal file
View File

@ -0,0 +1,2 @@
#include "raygui.h"

66
libs/raygui/inject.zig Normal file
View File

@ -0,0 +1,66 @@
const std = @import("std");
const raygui = @cImport({
@cInclude("raygui.h");
@cInclude("raygui_marshal.h");
});
const raylib = @import("raylib");
pub const Rectangle = raylib.Rectangle;
pub const Vector2 = raylib.Vector2;
pub const Color = raylib.Color;
pub const RICON_SIZE = 32;
pub const RICON_DATA_ELEMENTS = 255;
pub fn textAlignPixelOffset(h: i32) i32 {
return h % 2;
}
fn bitCheck(a: u32, b: u32) bool {
const r = @shlWithOverflow(1, @as(u5, @truncate(b)));
return (a & (r[0])) != 0;
}
/// Draw selected icon using rectangles pixel-by-pixel
pub fn GuiDrawIcon(
icon: raygui.GuiIconName,
posX: i32,
posY: i32,
pixelSize: i32,
color: raylib.Color,
) void {
const iconId = @intFromEnum(icon);
var i: i32 = 0;
var y: i32 = 0;
while (i < RICON_SIZE * RICON_SIZE / 32) : (i += 1) {
var k: u32 = 0;
while (k < 32) : (k += 1) {
if (bitCheck(raygui.guiIcons[@as(usize, @intCast(iconId * RICON_DATA_ELEMENTS + i))], k)) {
_ = raylib.DrawRectangle(
posX + @as(i32, @intCast(k % RICON_SIZE)) * pixelSize,
posY + y * pixelSize,
pixelSize,
pixelSize,
color,
);
}
if ((k == 15) or (k == 31)) {
y += 1;
}
}
}
}
/// Draw button with icon centered
pub fn GuiDrawIconButton(bounds: raylib.Rectangle, icon: GuiIconName, iconTint: raylib.Color) bool {
const pressed = GuiButton(bounds, "");
GuiDrawIcon(
icon,
@as(i32, @intFromFloat(bounds.x + bounds.width / 2 - @as(f32, @floatFromInt(RICON_SIZE)) / 2)),
@as(i32, @intFromFloat(bounds.y + (bounds.height / 2) - @as(f32, @floatFromInt(RICON_SIZE)) / 2)),
1,
iconTint,
);
return pressed;
}

View File

@ -0,0 +1,46 @@
const std = @import("std");
const fs = std.fs;
const mapping = @import("type_mapping.zig");
const json = std.json;
pub const jsonFiles: []const []const u8 = &.{
"raygui.json",
};
pub const bindingsJSON = "bindings.json";
pub fn main() !void {
std.log.info("updating bindings.json ...", .{});
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer {
if (gpa.deinit() == .leak) {
std.log.err("memory leak detected", .{});
}
}
const allocator = gpa.allocator();
var arena = std.heap.ArenaAllocator.init(allocator);
defer arena.deinit();
const raylib: mapping.CombinedRaylib = try mapping.CombinedRaylib.load(arena.allocator(), jsonFiles);
var bindings: mapping.Intermediate = mapping.Intermediate.loadCustoms(arena.allocator(), bindingsJSON) catch |err| Catch: {
std.log.warn("could not open {s}: {?}\n", .{ bindingsJSON, err });
break :Catch mapping.Intermediate{
.enums = &[_]mapping.Enum{},
.structs = &[_]mapping.Struct{},
.functions = &[_]mapping.Function{},
.defines = &[_]mapping.Define{},
};
};
try bindings.addNonCustom(arena.allocator(), raylib);
var file = try fs.cwd().createFile(bindingsJSON, .{});
defer file.close();
try json.stringify(bindings, .{
.emit_null_optional_fields = false,
.whitespace = .indent_2,
}, file.writer());
std.log.info("... done", .{});
}

BIN
libs/raygui/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

1
libs/raygui/raygui Submodule

@ -0,0 +1 @@
Subproject commit e30a826909cefbce39bae4ceaee76da6b163e2b1

3355
libs/raygui/raygui.json Normal file

File diff suppressed because it is too large Load Diff

1694
libs/raygui/raygui.zig Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,277 @@
#include "raygui.h"
void mGuiEnable(void)
{
GuiEnable();
}
void mGuiDisable(void)
{
GuiDisable();
}
void mGuiLock(void)
{
GuiLock();
}
void mGuiUnlock(void)
{
GuiUnlock();
}
bool mGuiIsLocked(void)
{
return GuiIsLocked();
}
void mGuiSetAlpha(float alpha)
{
GuiSetAlpha(alpha);
}
void mGuiSetState(int state)
{
GuiSetState(state);
}
int mGuiGetState(void)
{
return GuiGetState();
}
void mGuiSetFont(Font *font)
{
GuiSetFont(*font);
}
void mGuiGetFont(Font *out)
{
*out = GuiGetFont();
}
void mGuiSetStyle(int control, int property, int value)
{
GuiSetStyle(control, property, value);
}
int mGuiGetStyle(int control, int property)
{
return GuiGetStyle(control, property);
}
void mGuiLoadStyle(const char * fileName)
{
GuiLoadStyle(fileName);
}
void mGuiLoadStyleDefault(void)
{
GuiLoadStyleDefault();
}
void mGuiEnableTooltip(void)
{
GuiEnableTooltip();
}
void mGuiDisableTooltip(void)
{
GuiDisableTooltip();
}
void mGuiSetTooltip(const char * tooltip)
{
GuiSetTooltip(tooltip);
}
const char * mGuiIconText(int iconId, const char * text)
{
return GuiIconText(iconId, text);
}
void mGuiSetIconScale(int scale)
{
GuiSetIconScale(scale);
}
unsigned int * mGuiGetIcons(void)
{
return GuiGetIcons();
}
char ** mGuiLoadIcons(const char * fileName, bool loadIconsName)
{
return GuiLoadIcons(fileName, loadIconsName);
}
int mGuiWindowBox(Rectangle *bounds, const char * title)
{
return GuiWindowBox(*bounds, title);
}
int mGuiGroupBox(Rectangle *bounds, const char * text)
{
return GuiGroupBox(*bounds, text);
}
int mGuiLine(Rectangle *bounds, const char * text)
{
return GuiLine(*bounds, text);
}
int mGuiPanel(Rectangle *bounds, const char * text)
{
return GuiPanel(*bounds, text);
}
int mGuiTabBar(Rectangle *bounds, const char ** text, int count, int * active)
{
return GuiTabBar(*bounds, text, count, active);
}
int mGuiScrollPanel(Rectangle *bounds, const char * text, Rectangle *content, Vector2 * scroll, Rectangle * view)
{
return GuiScrollPanel(*bounds, text, *content, scroll, view);
}
int mGuiLabel(Rectangle *bounds, const char * text)
{
return GuiLabel(*bounds, text);
}
int mGuiButton(Rectangle *bounds, const char * text)
{
return GuiButton(*bounds, text);
}
int mGuiLabelButton(Rectangle *bounds, const char * text)
{
return GuiLabelButton(*bounds, text);
}
int mGuiToggle(Rectangle *bounds, const char * text, bool * active)
{
return GuiToggle(*bounds, text, active);
}
int mGuiToggleGroup(Rectangle *bounds, const char * text, int * active)
{
return GuiToggleGroup(*bounds, text, active);
}
int mGuiToggleSlider(Rectangle *bounds, const char * text, int * active)
{
return GuiToggleSlider(*bounds, text, active);
}
int mGuiCheckBox(Rectangle *bounds, const char * text, bool * checked)
{
return GuiCheckBox(*bounds, text, checked);
}
int mGuiComboBox(Rectangle *bounds, const char * text, int * active)
{
return GuiComboBox(*bounds, text, active);
}
int mGuiDropdownBox(Rectangle *bounds, const char * text, int * active, bool editMode)
{
return GuiDropdownBox(*bounds, text, active, editMode);
}
int mGuiSpinner(Rectangle *bounds, const char * text, int * value, int minValue, int maxValue, bool editMode)
{
return GuiSpinner(*bounds, text, value, minValue, maxValue, editMode);
}
int mGuiValueBox(Rectangle *bounds, const char * text, int * value, int minValue, int maxValue, bool editMode)
{
return GuiValueBox(*bounds, text, value, minValue, maxValue, editMode);
}
int mGuiTextBox(Rectangle *bounds, char * text, int textSize, bool editMode)
{
return GuiTextBox(*bounds, text, textSize, editMode);
}
int mGuiSlider(Rectangle *bounds, const char * textLeft, const char * textRight, float * value, float minValue, float maxValue)
{
return GuiSlider(*bounds, textLeft, textRight, value, minValue, maxValue);
}
int mGuiSliderBar(Rectangle *bounds, const char * textLeft, const char * textRight, float * value, float minValue, float maxValue)
{
return GuiSliderBar(*bounds, textLeft, textRight, value, minValue, maxValue);
}
int mGuiProgressBar(Rectangle *bounds, const char * textLeft, const char * textRight, float * value, float minValue, float maxValue)
{
return GuiProgressBar(*bounds, textLeft, textRight, value, minValue, maxValue);
}
int mGuiStatusBar(Rectangle *bounds, const char * text)
{
return GuiStatusBar(*bounds, text);
}
int mGuiDummyRec(Rectangle *bounds, const char * text)
{
return GuiDummyRec(*bounds, text);
}
int mGuiGrid(Rectangle *bounds, const char * text, float spacing, int subdivs, Vector2 * mouseCell)
{
return GuiGrid(*bounds, text, spacing, subdivs, mouseCell);
}
int mGuiListView(Rectangle *bounds, const char * text, int * scrollIndex, int * active)
{
return GuiListView(*bounds, text, scrollIndex, active);
}
int mGuiListViewEx(Rectangle *bounds, const char ** text, int count, int * scrollIndex, int * active, int * focus)
{
return GuiListViewEx(*bounds, text, count, scrollIndex, active, focus);
}
int mGuiMessageBox(Rectangle *bounds, const char * title, const char * message, const char * buttons)
{
return GuiMessageBox(*bounds, title, message, buttons);
}
int mGuiTextInputBox(Rectangle *bounds, const char * title, const char * message, const char * buttons, char * text, int textMaxSize, bool * secretViewActive)
{
return GuiTextInputBox(*bounds, title, message, buttons, text, textMaxSize, secretViewActive);
}
int mGuiColorPicker(Rectangle *bounds, const char * text, Color * color)
{
return GuiColorPicker(*bounds, text, color);
}
int mGuiColorPanel(Rectangle *bounds, const char * text, Color * color)
{
return GuiColorPanel(*bounds, text, color);
}
int mGuiColorBarAlpha(Rectangle *bounds, const char * text, float * alpha)
{
return GuiColorBarAlpha(*bounds, text, alpha);
}
int mGuiColorBarHue(Rectangle *bounds, const char * text, float * value)
{
return GuiColorBarHue(*bounds, text, value);
}
int mGuiColorPickerHSV(Rectangle *bounds, const char * text, Vector3 * colorHsv)
{
return GuiColorPickerHSV(*bounds, text, colorHsv);
}
int mGuiColorPanelHSV(Rectangle *bounds, const char * text, Vector3 * colorHsv)
{
return GuiColorPanelHSV(*bounds, text, colorHsv);
}

View File

@ -0,0 +1,167 @@
#include "raygui.h"
// Enable gui controls (global state)
void mGuiEnable(void);
// Disable gui controls (global state)
void mGuiDisable(void);
// Lock gui controls (global state)
void mGuiLock(void);
// Unlock gui controls (global state)
void mGuiUnlock(void);
// Check if gui is locked (global state)
bool mGuiIsLocked(void);
// Set gui controls alpha (global state), alpha goes from 0.0f to 1.0f
void mGuiSetAlpha(float alpha);
// Set gui state (global state)
void mGuiSetState(int state);
// Get gui state (global state)
int mGuiGetState(void);
// Set gui custom font (global state)
void mGuiSetFont(Font *font);
// Get gui custom font (global state)
void mGuiGetFont(Font *out);
// Set one style property
void mGuiSetStyle(int control, int property, int value);
// Get one style property
int mGuiGetStyle(int control, int property);
// Load style file over global style variable (.rgs)
void mGuiLoadStyle(const char * fileName);
// Load style default over global style
void mGuiLoadStyleDefault(void);
// Enable gui tooltips (global state)
void mGuiEnableTooltip(void);
// Disable gui tooltips (global state)
void mGuiDisableTooltip(void);
// Set tooltip string
void mGuiSetTooltip(const char * tooltip);
// Get text with icon id prepended (if supported)
const char * mGuiIconText(int iconId, const char * text);
// Set default icon drawing size
void mGuiSetIconScale(int scale);
// Get raygui icons data pointer
unsigned int * mGuiGetIcons(void);
// Load raygui icons file (.rgi) into internal icons data
char ** mGuiLoadIcons(const char * fileName, bool loadIconsName);
// Window Box control, shows a window that can be closed
int mGuiWindowBox(Rectangle *bounds, const char * title);
// Group Box control with text name
int mGuiGroupBox(Rectangle *bounds, const char * text);
// Line separator control, could contain text
int mGuiLine(Rectangle *bounds, const char * text);
// Panel control, useful to group controls
int mGuiPanel(Rectangle *bounds, const char * text);
// Tab Bar control, returns TAB to be closed or -1
int mGuiTabBar(Rectangle *bounds, const char ** text, int count, int * active);
// Scroll Panel control
int mGuiScrollPanel(Rectangle *bounds, const char * text, Rectangle *content, Vector2 * scroll, Rectangle * view);
// Label control, shows text
int mGuiLabel(Rectangle *bounds, const char * text);
// Button control, returns true when clicked
int mGuiButton(Rectangle *bounds, const char * text);
// Label button control, show true when clicked
int mGuiLabelButton(Rectangle *bounds, const char * text);
// Toggle Button control, returns true when active
int mGuiToggle(Rectangle *bounds, const char * text, bool * active);
// Toggle Group control, returns active toggle index
int mGuiToggleGroup(Rectangle *bounds, const char * text, int * active);
// Toggle Slider control, returns true when clicked
int mGuiToggleSlider(Rectangle *bounds, const char * text, int * active);
// Check Box control, returns true when active
int mGuiCheckBox(Rectangle *bounds, const char * text, bool * checked);
// Combo Box control, returns selected item index
int mGuiComboBox(Rectangle *bounds, const char * text, int * active);
// Dropdown Box control, returns selected item
int mGuiDropdownBox(Rectangle *bounds, const char * text, int * active, bool editMode);
// Spinner control, returns selected value
int mGuiSpinner(Rectangle *bounds, const char * text, int * value, int minValue, int maxValue, bool editMode);
// Value Box control, updates input text with numbers
int mGuiValueBox(Rectangle *bounds, const char * text, int * value, int minValue, int maxValue, bool editMode);
// Text Box control, updates input text
int mGuiTextBox(Rectangle *bounds, char * text, int textSize, bool editMode);
// Slider control, returns selected value
int mGuiSlider(Rectangle *bounds, const char * textLeft, const char * textRight, float * value, float minValue, float maxValue);
// Slider Bar control, returns selected value
int mGuiSliderBar(Rectangle *bounds, const char * textLeft, const char * textRight, float * value, float minValue, float maxValue);
// Progress Bar control, shows current progress value
int mGuiProgressBar(Rectangle *bounds, const char * textLeft, const char * textRight, float * value, float minValue, float maxValue);
// Status Bar control, shows info text
int mGuiStatusBar(Rectangle *bounds, const char * text);
// Dummy control for placeholders
int mGuiDummyRec(Rectangle *bounds, const char * text);
// Grid control, returns mouse cell position
int mGuiGrid(Rectangle *bounds, const char * text, float spacing, int subdivs, Vector2 * mouseCell);
// List View control, returns selected list item index
int mGuiListView(Rectangle *bounds, const char * text, int * scrollIndex, int * active);
// List View with extended parameters
int mGuiListViewEx(Rectangle *bounds, const char ** text, int count, int * scrollIndex, int * active, int * focus);
// Message Box control, displays a message
int mGuiMessageBox(Rectangle *bounds, const char * title, const char * message, const char * buttons);
// Text Input Box control, ask for text, supports secret
int mGuiTextInputBox(Rectangle *bounds, const char * title, const char * message, const char * buttons, char * text, int textMaxSize, bool * secretViewActive);
// Color Picker control (multiple color controls)
int mGuiColorPicker(Rectangle *bounds, const char * text, Color * color);
// Color Panel control
int mGuiColorPanel(Rectangle *bounds, const char * text, Color * color);
// Color Bar Alpha control
int mGuiColorBarAlpha(Rectangle *bounds, const char * text, float * alpha);
// Color Bar Hue control
int mGuiColorBarHue(Rectangle *bounds, const char * text, float * value);
// Color Picker control that avoids conversion to RGB on each call (multiple color controls)
int mGuiColorPickerHSV(Rectangle *bounds, const char * text, Vector3 * colorHsv);
// Color Panel control that returns HSV color value, used by GuiColorPickerHSV()
int mGuiColorPanelHSV(Rectangle *bounds, const char * text, Vector3 * colorHsv);

View File

@ -0,0 +1,6 @@
//! run 'zig build jsons' to generate bindings for raylib
//! run 'zig build raylib_parser' to build the raylib_parser.exe
/// this needs to be here so the zig compiler won't complain that there is no entry point
/// but actually we are using main() of 'raylib/src/parser/raylib_parser.c'
pub extern fn main() c_int;

View File

@ -0,0 +1,694 @@
//! Strategy:
//! 1. generate raylib JSONs
//! 2. combine in a union RaylibJson
//! 3. convert to intermediate representation
//! 4. read adjusted intermediate JSONs
//! 5. generate raylib.zig // wrap paramters and pass them to marshall versions of the raylib functions
//! 6. generate marshall.c // unwrap parameters from zig function and call the actual raylib function
//! 7. generate marshall.h // C signatures for all marshalled functions
const std = @import("std");
const json = std.json;
const memoryConstrain: usize = 1024 * 1024 * 1024; // 1 GiB
const Allocator = std.mem.Allocator;
const fmt = std.fmt.allocPrint;
const talloc = std.testing.allocator;
const expect = std.testing.expect;
const expectEqualStrings = std.testing.expectEqualStrings;
//--- Intermediate Format -------------------------------------------------------------------------
pub const Intermediate = struct {
functions: []Function,
enums: []Enum,
structs: []Struct,
defines: []Define,
pub fn loadCustoms(allocator: Allocator, jsonFile: []const u8) !@This() {
var enums = std.ArrayList(Enum).init(allocator);
var structs = std.ArrayList(Struct).init(allocator);
var functions = std.ArrayList(Function).init(allocator);
var defines = std.ArrayList(Define).init(allocator);
const jsonData = try std.fs.cwd().readFileAlloc(allocator, jsonFile, memoryConstrain);
const bindingJson = try json.parseFromSliceLeaky(Intermediate, allocator, jsonData, .{
.ignore_unknown_fields = true,
});
for (bindingJson.enums) |t| {
if (t.custom) {
try enums.append(t);
}
}
for (bindingJson.structs) |t| {
if (t.custom) {
try structs.append(t);
}
}
for (bindingJson.functions) |f| {
if (f.custom) {
try functions.append(f);
}
}
for (bindingJson.defines) |f| {
if (f.custom) {
try defines.append(f);
}
}
return @This(){
.enums = try enums.toOwnedSlice(),
.structs = try structs.toOwnedSlice(),
.functions = try functions.toOwnedSlice(),
.defines = try defines.toOwnedSlice(),
};
}
pub fn addNonCustom(self: *@This(), allocator: Allocator, rlJson: CombinedRaylib) !void {
var enums = std.ArrayList(Enum).init(allocator);
try enums.appendSlice(self.enums);
var structs = std.ArrayList(Struct).init(allocator);
try structs.appendSlice(self.structs);
var functions = std.ArrayList(Function).init(allocator);
try functions.appendSlice(self.functions);
var defines = std.ArrayList(Define).init(allocator);
try defines.appendSlice(self.defines);
outer: for (rlJson.defines.values(), 0..) |d, i| {
for (defines.items) |added| {
if (eql(added.name, d.name)) {
std.log.debug("{s} is customized", .{d.name});
continue :outer;
}
}
const define = parseRaylibDefine(allocator, d) orelse continue :outer;
if (i < defines.items.len) {
try defines.insert(i, define);
} else {
try defines.append(define);
}
}
outer: for (rlJson.enums.values(), 0..) |e, i| {
const name = if (alias.get(e.name)) |n| n else e.name;
for (enums.items) |added| {
if (eql(added.name, name)) {
std.log.debug("{s} is customized", .{name});
continue :outer;
}
}
if (i < enums.items.len) {
try enums.insert(i, try parseRaylibEnum(allocator, e));
} else {
try enums.append(try parseRaylibEnum(allocator, e));
}
}
outer: for (rlJson.structs.values(), 0..) |s, i| {
const name = if (alias.get(s.name)) |n| n else s.name;
for (structs.items) |added| {
if (eql(added.name, name)) {
std.log.debug("{s} is customized", .{name});
continue :outer;
}
}
if (i < structs.items.len) {
try structs.insert(i, try parseRaylibStruct(allocator, s));
} else {
try structs.append(try parseRaylibStruct(allocator, s));
}
}
for (rlJson.defines.values()) |_| {}
outer: for (rlJson.functions.values(), 0..) |f, i| {
for (functions.items) |added| {
if (eql(added.name, f.name)) {
std.log.debug("{s} is customized", .{f.name});
continue :outer;
}
}
if (i < functions.items.len) {
try functions.insert(i, try parseRaylibFunction(allocator, f));
} else {
try functions.append(try parseRaylibFunction(allocator, f));
}
}
self.enums = try enums.toOwnedSlice();
self.structs = try structs.toOwnedSlice();
self.functions = try functions.toOwnedSlice();
self.defines = try defines.toOwnedSlice();
}
pub fn containsStruct(self: @This(), name: []const u8) bool {
for (self.structs) |s| {
if (eql(s.name, name)) return true;
}
return false;
}
pub fn containsEnum(self: @This(), name: []const u8) bool {
for (self.enums) |e| {
if (eql(e.name, name)) return true;
}
return false;
}
pub fn containsDefine(self: @This(), name: []const u8) bool {
for (self.defines) |d| {
if (eql(d.name, name)) return true;
}
return false;
}
};
pub const Function = struct {
name: []const u8,
params: []FunctionParameter,
returnType: []const u8,
description: ?[]const u8 = null,
custom: bool = false,
};
pub const FunctionParameter = struct {
name: []const u8,
typ: []const u8,
description: ?[]const u8 = null,
};
pub fn parseRaylibFunction(allocator: Allocator, func: RaylibFunction) !Function {
var args = std.ArrayList(FunctionParameter).init(allocator);
if (func.params) |params| {
for (params) |p| {
const t = try toZig(allocator, p.type);
try args.append(.{
.name = p.name,
.typ = t,
.description = p.description,
});
}
}
const returnType = try toZig(allocator, func.returnType);
return Function{
.name = func.name,
.params = try args.toOwnedSlice(),
.returnType = returnType,
.description = func.description,
};
}
pub const Struct = struct {
name: []const u8,
fields: []const StructField,
description: ?[]const u8 = null,
custom: bool = false,
};
pub const StructField = struct {
name: []const u8,
typ: []const u8,
description: ?[]const u8 = null,
};
pub fn parseRaylibStruct(allocator: Allocator, s: RaylibStruct) !Struct {
var fields = std.ArrayList(StructField).init(allocator);
for (s.fields) |field| {
var typ = try toZig(allocator, getTypeWithoutArrayNotation(field.type));
if (getArraySize(field.type)) |size| {
typ = try std.fmt.allocPrint(allocator, "[{d}]{s}", .{ size, typ });
}
try fields.append(.{
.name = field.name,
.typ = typ,
.description = field.description,
});
}
return Struct{
.name = if (alias.get(s.name)) |a| a else s.name,
.fields = try fields.toOwnedSlice(),
.description = s.description,
};
}
pub const Define = struct {
name: []const u8,
typ: []const u8,
value: []const u8,
description: ?[]const u8 = null,
custom: bool = false,
};
pub fn parseRaylibDefine(allocator: Allocator, s: RaylibDefine) ?Define {
var typ: []const u8 = undefined;
var value: []const u8 = undefined;
if (eql("INT", s.type)) {
typ = "i32";
value = std.fmt.allocPrint(allocator, "{s}", .{s.value}) catch return null;
} else if (eql("LONG", s.type)) {
typ = "i64";
value = std.fmt.allocPrint(allocator, "{s}", .{s.value}) catch return null;
} else if (eql("FLOAT", s.type)) {
typ = "f32";
value = std.fmt.allocPrint(allocator, "{s}", .{s.value}) catch return null;
} else if (eql("DOUBLE", s.type)) {
typ = "f64";
value = std.fmt.allocPrint(allocator, "{s}", .{s.value}) catch return null;
} else if (eql("STRING", s.type)) {
typ = "[]const u8";
value = std.fmt.allocPrint(allocator, "\"{s}\"", .{s.value}) catch return null;
} else if (eql("COLOR", s.type)) {
typ = "Color";
std.debug.assert(startsWith(s.value, "CLITERAL(Color){"));
std.debug.assert(endsWith(s.value, "}"));
const componentString = s.value["CLITERAL(Color){".len .. s.value.len - 1];
var spliterator = std.mem.split(u8, componentString, ",");
var r = spliterator.next() orelse return null;
r = std.mem.trim(u8, r, " \t\r\n");
var g = spliterator.next() orelse return null;
g = std.mem.trim(u8, g, " \t\r\n");
var b = spliterator.next() orelse return null;
b = std.mem.trim(u8, b, " \t\r\n");
var a = spliterator.next() orelse return null;
a = std.mem.trim(u8, a, " \t\r\n");
value = std.fmt.allocPrint(allocator, ".{{.r={s}, .g={s}, .b={s}, .a={s}}}", .{ r, g, b, a }) catch return null;
} else {
return null;
}
return Define{
.name = s.name,
.typ = typ,
.value = value,
.description = s.description,
};
}
pub const Enum = struct {
name: []const u8,
values: []const EnumValue,
description: ?[]const u8 = null,
custom: bool = false,
};
pub const EnumValue = struct {
name: []const u8,
value: c_int,
description: ?[]const u8 = null,
};
pub fn parseRaylibEnum(allocator: Allocator, e: RaylibEnum) !Enum {
var values = std.ArrayList(EnumValue).init(allocator);
for (e.values) |value| {
try values.append(.{
.name = value.name,
.value = value.value,
.description = value.description,
});
}
return Enum{
.name = e.name,
.values = try values.toOwnedSlice(),
.description = e.description,
};
}
/// is c const type
pub fn isConst(c: []const u8) bool {
return startsWith(c, "const ");
}
test "isConst" {
try expect(!isConst("char *"));
try expect(!isConst("unsigned char *"));
try expect(isConst("const unsigned char *"));
try expect(isConst("const unsigned int *"));
try expect(isConst("const void *"));
try expect(!isConst("Vector2 *"));
try expect(!isConst("Vector2"));
try expect(!isConst("int"));
}
/// is c pointer type
pub fn isPointer(c: []const u8) bool {
return endsWith(c, "*");
}
test "isPointer" {
try expect(isPointer("char *"));
try expect(isPointer("unsigned char *"));
try expect(isPointer("const unsigned char *"));
try expect(isPointer("const unsigned int *"));
try expect(isPointer("Vector2 *"));
try expect(!isPointer("Vector2"));
try expect(!isPointer("int"));
}
pub fn isPointerToPointer(c: []const u8) bool {
return endsWith(c, "**");
}
test "isPointerToPointer" {
try expect(!isPointerToPointer("char *"));
try expect(!isPointerToPointer("unsigned char *"));
try expect(isPointerToPointer("const unsigned char **"));
try expect(isPointerToPointer("const unsigned int **"));
try expect(isPointerToPointer("Vector2 **"));
try expect(!isPointerToPointer("Vector2*"));
try expect(!isPointerToPointer("int"));
}
pub fn isVoid(c: []const u8) bool {
return eql(stripType(c), "void");
}
test "isVoid" {
try expect(!isVoid("char *"));
try expect(!isVoid("unsigned char *"));
try expect(!isVoid("const unsigned char *"));
try expect(isVoid("const void *"));
try expect(isVoid("void *"));
try expect(isVoid("void"));
try expect(isVoid("void **"));
}
/// strips const and pointer annotations
/// const TName * -> TName
pub fn stripType(c: []const u8) []const u8 {
var name = if (isConst(c)) c["const ".len..] else c;
name = if (isPointer(name)) name[0 .. name.len - 1] else name;
// double pointer?
name = if (isPointer(name)) name[0 .. name.len - 1] else name;
name = std.mem.trim(u8, name, " \t\n");
if (alias.get(name)) |ali| {
name = ali;
}
return name;
}
test "stripType" {
try expectEqualStrings("void", stripType("const void *"));
try expectEqualStrings("unsinged int", stripType("unsinged int *"));
try expectEqualStrings("Vector2", stripType("const Vector2 *"));
}
pub fn getArraySize(typ: []const u8) ?usize {
if (std.mem.indexOf(u8, typ, "[")) |open| {
if (std.mem.indexOf(u8, typ, "]")) |close| {
return std.fmt.parseInt(usize, typ[open + 1 .. close], 10) catch null;
}
}
return null;
}
test "getArraySize" {
const expectEqual = std.testing.expectEqual;
try expectEqual(@as(?usize, 4), getArraySize("float[4]"));
try expectEqual(@as(?usize, 44), getArraySize("int[44]"));
try expectEqual(@as(?usize, 123456), getArraySize("a[123456]"));
try expectEqual(@as(?usize, 1), getArraySize("test[1] "));
try expectEqual(@as(?usize, null), getArraySize("foo[]"));
try expectEqual(@as(?usize, null), getArraySize("bar"));
try expectEqual(@as(?usize, null), getArraySize("foo["));
try expectEqual(@as(?usize, null), getArraySize("bar]"));
try expectEqual(@as(?usize, 42), getArraySize(" lol this is ok[42] "));
}
pub fn getTypeWithoutArrayNotation(typ: []const u8) []const u8 {
if (std.mem.indexOf(u8, typ, "[")) |open| {
return typ[0..open];
}
return typ;
}
fn toZig(allocator: Allocator, c: []const u8) ![]const u8 {
if (fixedMapping.get(c)) |fixed| {
return fixed;
}
const consT = if (isConst(c)) "const " else "";
const stripped = stripType(c);
const pointeR = if (isPointer(c))
if (eql(stripped, "unsigned char") or eql(stripped, "char")) "?[*:0]" else "*"
else
"";
const name = if (raylibToZigType.get(stripped)) |primitive| primitive else stripped;
if (isPointer(c)) {
return try fmt(allocator, "{s}{s}{s}", .{ pointeR, consT, name });
}
return name;
}
test "toZig" {
var arena = std.heap.ArenaAllocator.init(talloc);
defer arena.deinit();
const a = arena.allocator();
try expectEqualStrings("i32", try toZig(a, "int"));
try expectEqualStrings("const i32", try toZig(a, "const int"));
try expectEqualStrings("?[*]Vector2", try toZig(a, "Vector2 *"));
}
const raylibToZigType = std.ComptimeStringMap([]const u8, .{
.{ "void", "void" },
.{ "bool", "bool" },
.{ "char", "u8" },
.{ "unsigned char", "u8" },
.{ "short", "i16" },
.{ "unsigned short", "u16" },
.{ "int", "i32" },
.{ "unsigned int", "u32" },
.{ "long", "i64" },
.{ "unsigned long", "u64" },
.{ "unsigned long long", "u64" },
.{ "float", "f32" },
.{ "double", "f64" },
});
const fixedMapping = std.ComptimeStringMap([]const u8, .{
.{ "void *", "*anyopaque" },
.{ "const void *", "*const anyopaque" },
.{ "const unsigned char *", "[*:0]const u8" },
.{ "const char *", "[*:0]const u8" },
.{ "const char **", "[*]const [*:0]const u8" },
.{ "char **", "[*][*:0]u8" },
.{ "rAudioBuffer *", "*anyopaque" },
.{ "rAudioProcessor *", "*anyopaque" },
.{ "Image *", "*Image" },
});
//--- Raylib parser JSONs -------------------------------------------------------------------------
const alias = std.ComptimeStringMap([]const u8, .{
.{ "Camera", "Camera3D" },
.{ "Texture", "Texture2D" },
.{ "TextureCubemap", "Texture2D" },
.{ "RenderTexture", "RenderTexture2D" },
.{ "GuiStyle", "u32" },
.{ "Quaternion", "Vector4" },
.{ "PhysicsBody", "*PhysicsBodyData" },
});
const cAlias = std.ComptimeStringMap([]const u8, .{
.{ "Camera", "Camera3D" },
.{ "Texture", "Texture2D" },
.{ "TextureCubemap", "Texture2D" },
.{ "RenderTexture", "RenderTexture2D" },
.{ "Quaternion", "Vector4" },
.{ "PhysicsBody", "PhysicsBodyData *" },
});
pub const CombinedRaylib = struct {
structs: std.StringArrayHashMap(RaylibStruct),
enums: std.StringArrayHashMap(RaylibEnum),
defines: std.StringArrayHashMap(RaylibDefine),
functions: std.StringArrayHashMap(RaylibFunction),
pub fn load(allocator: Allocator, jsonFiles: []const []const u8) !@This() {
var structs = std.StringArrayHashMap(RaylibStruct).init(allocator);
var enums = std.StringArrayHashMap(RaylibEnum).init(allocator);
var defines = std.StringArrayHashMap(RaylibDefine).init(allocator);
var functions = std.StringArrayHashMap(RaylibFunction).init(allocator);
for (jsonFiles) |jsonFile| {
std.log.info("parsing {s}", .{jsonFile});
const jsonData = try std.fs.cwd().readFileAlloc(allocator, jsonFile, memoryConstrain);
const bindingJson = try json.parseFromSliceLeaky(RaylibJson, allocator, jsonData, .{
.ignore_unknown_fields = true,
.duplicate_field_behavior = .use_last,
});
for (bindingJson.structs) |*s| {
for (s.fields) |*f| {
f.type = cAlias.get(f.type) orelse f.type;
}
try structs.put(s.name, s.*);
}
for (bindingJson.enums) |e| {
try enums.put(e.name, e);
}
for (bindingJson.defines) |d| {
try defines.put(d.name, d);
}
for (bindingJson.functions) |*f| {
f.returnType = cAlias.get(f.returnType) orelse f.returnType;
if (f.params) |params| {
for (params) |*p| {
p.type = cAlias.get(p.type) orelse p.type;
}
}
try functions.put(f.name, f.*);
}
}
return @This(){
.structs = structs,
.enums = enums,
.defines = defines,
.functions = functions,
};
}
pub fn toIntermediate(self: @This(), allocator: Allocator, customs: Intermediate) !Intermediate {
var functions = std.ArrayList(Function).init(allocator);
var enums = std.ArrayList(Enum).init(allocator);
var structs = std.ArrayList(Struct).init(allocator);
enums: for (self.enums.values()) |e| {
for (customs.enums) |tt| {
if (eql(tt.name, e.name)) break :enums;
}
try enums.append(try parseRaylibEnum(allocator, e));
}
structs: for (self.structs.values()) |s| {
for (customs.structs) |tt| {
if (eql(tt.name, s.name)) break :structs;
}
try structs.append(try parseRaylibStruct(allocator, s, customs));
}
for (self.defines.values()) |_| {}
funcs: for (self.functions.values()) |f| {
for (customs.functions) |ff| {
if (eql(ff.name, f.name)) break :funcs;
}
try functions.append(try parseRaylibFunction(allocator, f, customs.types));
}
return Intermediate{
.functions = try functions.toOwnedSlice(),
.enums = try enums.toOwnedSlice(),
.structs = try structs.toOwnedSlice(),
};
}
fn containsStruct(self: @This(), name: []const u8) bool {
return self.structs.contains(name);
}
fn containsEnum(self: @This(), name: []const u8) bool {
return self.enums.contains(name);
}
fn containsFunction(self: @This(), name: []const u8) bool {
return self.functions.contains(name);
}
};
const RaylibJson = struct {
structs: []RaylibStruct,
enums: []RaylibEnum,
defines: []RaylibDefine,
functions: []RaylibFunction,
};
pub const RaylibStruct = struct {
name: []const u8,
description: []const u8,
fields: []RaylibField,
};
pub const RaylibField = struct {
name: []const u8,
description: []const u8,
type: []const u8,
};
pub const RaylibEnum = struct {
name: []const u8,
description: []const u8,
values: []RaylibEnumValue,
};
pub const RaylibEnumValue = struct {
name: []const u8,
description: []const u8,
value: c_int,
};
pub const RaylibFunction = struct {
name: []const u8,
description: []const u8,
returnType: []const u8,
params: ?[]RaylibFunctionParam = null,
};
pub const RaylibFunctionParam = struct {
name: []const u8,
type: []const u8,
description: ?[]const u8 = null,
};
pub const RaylibDefine = struct {
name: []const u8,
type: []const u8,
value: []const u8,
description: ?[]const u8 = null,
};
//--- Helpers -------------------------------------------------------------------------------------
/// true if C type is primitive or a pointer to anything
/// this means we don't need to wrap it in a pointer
pub fn isPrimitiveOrPointer(c: []const u8) bool {
const primitiveTypes = std.ComptimeStringMap(void, .{
.{ "void", {} },
.{ "bool", {} },
.{ "char", {} },
.{ "unsigned char", {} },
.{ "short", {} },
.{ "unsigned short", {} },
.{ "int", {} },
.{ "unsigned int", {} },
.{ "long", {} },
.{ "unsigned long", {} },
.{ "unsigned long long", {} },
.{ "float", {} },
.{ "double", {} },
});
return primitiveTypes.has(stripType(c)) or endsWith(c, "*");
}
fn eql(a: []const u8, b: []const u8) bool {
return std.mem.eql(u8, a, b);
}
fn startsWith(haystack: []const u8, needle: []const u8) bool {
return std.mem.startsWith(u8, haystack, needle);
}
fn endsWith(haystack: []const u8, needle: []const u8) bool {
return std.mem.endsWith(u8, haystack, needle);
}