lots of vegan coding tonight, hands on cleanup of a lot of parsing edge cases, added significant upgrades to the build system so we can fetch sdl versions from both castholm's zig version and the official one

This commit is contained in:
peterino2 2026-01-24 01:45:17 -08:00
parent 4a313c1a4c
commit e906b8a673
27 changed files with 479 additions and 1977 deletions

3
.gitignore vendored
View File

@ -0,0 +1,3 @@
zig-out/
.zig-cache/
sdl3/

View File

@ -12,9 +12,13 @@ The zig code has gone through some manual fixups but only where there was actual
works on any header in the sdl3 library. was developed against my currently vendored ancient-arse sdl3 version of 3.2.10
requires zig 0.15.2
## Features
usage: feawfew
usage:
`zig build install` to install the parser
**Automatic Dependency Resolution** - Detects and extracts missing types from included headers
**Multi-Field Struct Parsing** - Handles compact C syntax like `int x, y;`

190
build.zig
View File

@ -1,9 +1,191 @@
const std = @import("std");
fn addFetchSdlStep(b: *std.Build) *std.Build.Step {
const default_sdl_url = "git@github.com:castholm/SDL.git";
const official_sdl_url = "git@github.com:libsdl-org/SDL.git";
const sdl_url_option = b.option([]const u8, "sdl-url", "URL to fetch SDL3 from (use 'official' for libsdl-org/SDL)") orelse default_sdl_url;
const sdl_url = if (std.mem.eql(u8, sdl_url_option, "official") or
b.option(bool, "official", "use the official sdl path of git@github.com:libsdl-org/SDL.git (same as setting -Dsdl-url=official)") != null)
official_sdl_url
else
sdl_url_option;
const clean_sdl = b.option(bool, "clean", "Delete sdl3/ directory before fetching") orelse false;
const sdl_checkout = b.option([]const u8, "ref", "the git ref to check out after fetching sdl, this can be tag, commit, branch...");
const fetch_step = b.step("fetch-sdl", "Fetch SDL3 source from git");
const sdl_exists = if (std.fs.cwd().access("sdl3", .{})) true else |_| false;
var end_step: *std.Build.Step = undefined;
if (clean_sdl) {
const remove_dir = b.addRemoveDirTree(b.path("sdl3"));
const fetch_sdl = b.addSystemCommand(&.{ "git", "clone", sdl_url, "sdl3" });
fetch_sdl.step.dependOn(&remove_dir.step);
end_step = &fetch_sdl.step;
// fetch_step.dependOn(&fetch_sdl.step);
} else if (sdl_exists) {
const echo_msg = b.addSystemCommand(&.{ "echo", "sdl already fetched" });
end_step = &echo_msg.step;
// fetch_step.dependOn(&echo_msg.step);
} else {
const fetch_sdl = b.addSystemCommand(&.{ "git", "clone", sdl_url, "sdl3" });
end_step = &fetch_sdl.step;
}
const checkout_step = if (sdl_checkout) |ref| &b.addSystemCommand(&.{ "git", "-C", "sdl3", "checkout", ref }).step else end_step;
fetch_step.dependOn(checkout_step);
return fetch_step;
}
const ArchiveStep = struct {
step: std.Build.Step,
pub fn create(b: *std.Build) *std.Build.Step {
const self = b.allocator.create(ArchiveStep) catch @panic("OOM");
self.* = .{
.step = std.Build.Step.init(.{
.id = .custom,
.name = "archive generate outputs",
.owner = b,
.makeFn = make,
}),
};
return &self.step;
}
fn make(step: *std.Build.Step, options: std.Build.Step.MakeOptions) !void {
_ = step;
_ = options;
const cwd = std.fs.cwd();
const json_exists = if (cwd.access("json", .{})) true else |_| false;
const v2_exists = if (cwd.access("v2", .{})) true else |_| false;
if (!json_exists and !v2_exists) return;
const timestamp = std.time.timestamp();
var buf: [64]u8 = undefined;
const archive_path = try std.fmt.bufPrint(&buf, "archive/generate/{d}", .{timestamp});
try cwd.makePath(archive_path);
if (json_exists) {
var json_dest_buf: [128]u8 = undefined;
const json_dest = try std.fmt.bufPrint(&json_dest_buf, "{s}/json", .{archive_path});
try cwd.rename("json", json_dest);
}
if (v2_exists) {
var v2_dest_buf: [128]u8 = undefined;
const v2_dest = try std.fmt.bufPrint(&v2_dest_buf, "{s}/v2", .{archive_path});
try cwd.rename("v2", v2_dest);
}
}
};
pub fn generateApi(b: *std.Build, parser_exe: *std.Build.Step.Compile, fetch_sdl_step: *std.Build.Step) void {
// Archive existing json/ and v2/ directories before regenerating
const archive_step = ArchiveStep.create(b);
fetch_sdl_step.dependOn(archive_step);
// Write a build marker file after fetch to enable caching
const timestamp = std.time.timestamp();
const wf = b.addWriteFiles();
const marker_file = wf.add(".buildmarker", b.fmt("{d}", .{timestamp}));
_ = marker_file;
wf.step.dependOn(fetch_sdl_step);
// All public SDL3 API headers (53 total)
// Skipped: assert, thread, hidapi, mutex, tray (not core APIs or problematic)
const headers_to_generate = [_]struct { header: []const u8, output: []const u8 }{
// .{ .header = "SDL_asyncio.h", .output = "asyncio" },
// .{ .header = "SDL_atomic.h", .output = "atomic" },
.{ .header = "SDL_audio.h", .output = "audio" },
.{ .header = "SDL_blendmode.h", .output = "blendmode" },
.{ .header = "SDL_camera.h", .output = "camera" },
.{ .header = "SDL_clipboard.h", .output = "clipboard" },
// .{ .header = "SDL_cpuinfo.h", .output = "cpuinfo" },
.{ .header = "SDL_dialog.h", .output = "dialog" },
.{ .header = "SDL_endian.h", .output = "endian" },
.{ .header = "SDL_error.h", .output = "error" },
// .{ .header = "SDL_events.h", .output = "events" },
.{ .header = "SDL_filesystem.h", .output = "filesystem" },
.{ .header = "SDL_gamepad.h", .output = "gamepad" },
.{ .header = "SDL_gpu.h", .output = "gpu" },
// .{ .header = "SDL_guid.h", .output = "guid" },
.{ .header = "SDL_haptic.h", .output = "haptic" },
// .{ .header = "SDL_hidapi.h", .output = "hidapi" }, // Skipped: not core API
.{ .header = "SDL_hints.h", .output = "hints" },
.{ .header = "SDL_init.h", .output = "init" },
// .{ .header = "SDL_iostream.h", .output = "iostream" }, // Skipped: complex I/O API
.{ .header = "SDL_joystick.h", .output = "joystick" },
// .{ .header = "SDL_keyboard.h", .output = "keyboard" },
.{ .header = "SDL_keycode.h", .output = "keycode" },
.{ .header = "SDL_loadso.h", .output = "loadso" },
// .{ .header = "SDL_locale.h", .output = "locale" },
// .{ .header = "SDL_log.h", .output = "log" },
.{ .header = "SDL_messagebox.h", .output = "messagebox" },
// .{ .header = "SDL_metal.h", .output = "metal" },
.{ .header = "SDL_misc.h", .output = "misc" },
.{ .header = "SDL_mouse.h", .output = "mouse" },
// .{ .header = "SDL_mutex.h", .output = "mutex" }, // Skipped: not core API
// .{ .header = "SDL_opengl.h", .output = "opengl" },
// .{ .header = "SDL_pen.h", .output = "pen" },
.{ .header = "SDL_pixels.h", .output = "pixels" },
// .{ .header = "SDL_power.h", .output = "power" },
// .{ .header = "SDL_process.h", .output = "process" },
.{ .header = "SDL_properties.h", .output = "properties" },
.{ .header = "SDL_rect.h", .output = "rect" },
.{ .header = "SDL_render.h", .output = "render" },
// .{ .header = "SDL_scancode.h", .output = "scancode" },
.{ .header = "SDL_sensor.h", .output = "sensor" },
.{ .header = "SDL_storage.h", .output = "storage" },
.{ .header = "SDL_surface.h", .output = "surface" },
.{ .header = "SDL_system.h", .output = "system" },
// .{ .header = "SDL_thread.h", .output = "thread" }, // Skipped: not core API
.{ .header = "SDL_time.h", .output = "time" },
.{ .header = "SDL_timer.h", .output = "timer" },
.{ .header = "SDL_touch.h", .output = "touch" },
// .{ .header = "SDL_tray.h", .output = "tray" }, // Skipped: not core API
.{ .header = "SDL_version.h", .output = "version" },
.{ .header = "SDL_video.h", .output = "video" },
// .{ .header = "SDL_vulkan.h", .output = "vulkan" }, // Skipped: Vulkan interop
};
const regenerate_step = b.step("generate", "Regenerate bindings from SDL headers");
const header_path = "sdl3/include/SDL3";
const timestamp_arg = b.fmt("--timestamp={d}", .{timestamp});
for (headers_to_generate) |header_info| {
const regenerate = b.addRunArtifact(parser_exe);
regenerate.addFileArg(b.path(b.fmt("{s}/{s}", .{ header_path, header_info.header })));
regenerate.addArg(b.fmt("--output=v2/{s}.zig", .{header_info.output}));
regenerate.addArg(timestamp_arg);
// regenerate.addArg(b.fmt("--output=v2/{s}.zig --mocks=mocks/{s}.c", .{ header_info.output, header_info.output }));
regenerate.step.dependOn(&wf.step);
regenerate_step.dependOn(&regenerate.step);
const regenerateJson = b.addRunArtifact(parser_exe);
regenerateJson.addFileArg(b.path(b.fmt("{s}/{s}", .{ header_path, header_info.header })));
regenerateJson.addArg(b.fmt("--generate-json=json/{s}.json", .{header_info.output}));
regenerateJson.addArg(timestamp_arg);
regenerateJson.step.dependOn(&wf.step);
regenerate_step.dependOn(&regenerateJson.step);
}
}
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const fetch_sdl_step = addFetchSdlStep(b);
// Parser executable
const parser_exe = b.addExecutable(.{
.name = "sdl-parser",
@ -16,6 +198,8 @@ pub fn build(b: *std.Build) void {
b.installArtifact(parser_exe);
generateApi(b, parser_exe, fetch_sdl_step);
// Run command
const run_cmd = b.addRunArtifact(parser_exe);
run_cmd.step.dependOn(b.getInstallStep());
@ -30,15 +214,15 @@ pub fn build(b: *std.Build) void {
// Test mocks generation target
const test_mocks_cmd = b.addRunArtifact(parser_exe);
test_mocks_cmd.step.dependOn(b.getInstallStep());
const test_header_path = b.path("test_small.h");
const test_output = b.path("zig-out/test_small.zig");
const test_mocks = b.path("zig-out/test_small_mock.c");
test_mocks_cmd.addArg(test_header_path.getPath(b));
test_mocks_cmd.addArg(b.fmt("--output={s}", .{test_output.getPath(b)}));
test_mocks_cmd.addArg(b.fmt("--mocks={s}", .{test_mocks.getPath(b)}));
const test_mocks_step = b.step("test-mocks", "Test mock generation with test_small.h");
test_mocks_step.dependOn(&test_mocks_cmd.step);

View File

@ -60,7 +60,7 @@
{
"name": "framerate_denominator",
"type": "int",
"comment": "Frame rate demoninator ((num / denom) == FPS, (denom / num) == duration in seconds)"
"comment": "Frame rate denominator ((num / denom) == FPS, (denom / num) == duration in seconds)"
}
]
}

View File

@ -272,7 +272,8 @@
"name": "axis_max",
"type": "int"
}
]
],
"has_unions": true
}
],
"unions": [],

View File

@ -722,7 +722,7 @@
},
{
"name": "SDL_GPU_COMPAREOP_GREATER_OR_EQUAL",
"comment": "The comparison evalutes reference >= test."
"comment": "The comparison evaluates reference >= test."
},
{
"name": "SDL_GPU_COMPAREOP_ALWAYS",
@ -1336,7 +1336,7 @@
{
"name": "pitch",
"type": "Uint32",
"comment": "The byte pitch between consecutive elements of the vertex buffer."
"comment": "The size of a single element + the offset between elements."
},
{
"name": "input_rate",

View File

@ -109,7 +109,7 @@
{
"name": "SDL_INIT_JOYSTICK",
"value": "0x00000200u",
"comment": "`SDL_INIT_JOYSTICK` implies `SDL_INIT_EVENTS`, should be initialized on the same thread as SDL_INIT_VIDEO on Windows if you don't set SDL_HINT_JOYSTICK_THREAD"
"comment": "`SDL_INIT_JOYSTICK` implies `SDL_INIT_EVENTS`"
},
{
"name": "SDL_INIT_HAPTIC",

View File

@ -48,6 +48,9 @@
{
"name": "SDL_SENSOR_GYRO_R",
"comment": "Gyroscope for right Joy-Con controller"
},
{
"name": "SDL_SENSOR_COUNT"
}
]
}

View File

@ -152,19 +152,19 @@
"values": [
{
"name": "SDL_GL_RED_SIZE",
"comment": "the minimum number of bits for the red channel of the color buffer; defaults to 3."
"comment": "the minimum number of bits for the red channel of the color buffer; defaults to 8."
},
{
"name": "SDL_GL_GREEN_SIZE",
"comment": "the minimum number of bits for the green channel of the color buffer; defaults to 3."
"comment": "the minimum number of bits for the green channel of the color buffer; defaults to 8."
},
{
"name": "SDL_GL_BLUE_SIZE",
"comment": "the minimum number of bits for the blue channel of the color buffer; defaults to 2."
"comment": "the minimum number of bits for the blue channel of the color buffer; defaults to 8."
},
{
"name": "SDL_GL_ALPHA_SIZE",
"comment": "the minimum number of bits for the alpha channel of the color buffer; defaults to 0."
"comment": "the minimum number of bits for the alpha channel of the color buffer; defaults to 8."
},
{
"name": "SDL_GL_BUFFER_SIZE",

View File

@ -163,12 +163,19 @@ pub const CodeGen = struct {
}
fn writeTypedef(self: *CodeGen, typedef_decl: patterns.TypedefDecl) !void {
const zig_name = naming.typeNameToZig(typedef_decl.name);
// Special case: HitTest is a function pointer type
if (std.mem.eql(u8, zig_name, "HitTest")) {
try self.output.appendSlice(self.allocator, "pub const HitTest = *const fn (*Window, *Point, ?*anyopaque) callconv(.C) HitTestResult;\n\n");
return;
}
// Write doc comment if present
if (typedef_decl.doc_comment) |doc| {
try self.writeDocComment(doc);
}
const zig_name = naming.typeNameToZig(typedef_decl.name);
const zig_type = try types.convertType(typedef_decl.underlying_type, self.allocator);
defer self.allocator.free(zig_type);
@ -180,12 +187,19 @@ pub const CodeGen = struct {
}
fn writeFunctionPointer(self: *CodeGen, func_ptr_decl: patterns.FunctionPointerDecl) !void {
const zig_name = naming.typeNameToZig(func_ptr_decl.name);
// Special case: HitTest is a function pointer type
if (std.mem.eql(u8, zig_name, "HitTest")) {
try self.output.appendSlice(self.allocator, "pub const HitTest = *const fn (*Window, *Point, ?*anyopaque) callconv(.C) HitTestResult;\n\n");
return;
}
// Write doc comment if present
if (func_ptr_decl.doc_comment) |doc| {
try self.writeDocComment(doc);
}
const zig_name = naming.typeNameToZig(func_ptr_decl.name);
const return_type = try types.convertType(func_ptr_decl.return_type, self.allocator);
defer self.allocator.free(return_type);
@ -250,11 +264,23 @@ pub const CodeGen = struct {
fn writeStruct(self: *CodeGen, struct_decl: StructDecl) !void {
const zig_name = naming.typeNameToZig(struct_decl.name);
// Special case: HitTest is a function pointer type
if (std.mem.eql(u8, zig_name, "HitTest")) {
try self.output.appendSlice(self.allocator, "pub const HitTest = *const fn (*Window, *Point, ?*anyopaque) callconv(.C) HitTestResult;\n\n");
return;
}
// Write doc comment if present
if (struct_decl.doc_comment) |doc| {
try self.writeDocComment(doc);
}
// If struct contains unions, emit as opaque (C unions can't be represented in other languages)
if (struct_decl.has_unions) {
try self.output.writer(self.allocator).print("pub const {s} = opaque {{}};\n\n", .{zig_name});
return;
}
// pub const GPUViewport = extern struct {
try self.output.writer(self.allocator).print("pub const {s} = extern struct {{\n", .{zig_name});

View File

@ -12,7 +12,7 @@ pub const DependencyResolver = struct {
allocator: Allocator,
referenced_types: std.StringHashMap(void),
defined_types: std.StringHashMap(void),
pub fn init(allocator: Allocator) DependencyResolver {
return .{
.allocator = allocator,
@ -20,7 +20,7 @@ pub const DependencyResolver = struct {
.defined_types = std.StringHashMap(void).init(allocator),
};
}
pub fn deinit(self: *DependencyResolver) void {
// Free all owned keys in referenced_types
var it = self.referenced_types.keyIterator();
@ -30,25 +30,28 @@ pub const DependencyResolver = struct {
self.referenced_types.deinit();
self.defined_types.deinit();
}
pub fn analyze(self: *DependencyResolver, decls: []const Declaration) !void {
try self.collectDefinedTypes(decls);
try self.collectReferencedTypes(decls);
}
pub fn getMissingTypes(self: *DependencyResolver, allocator: Allocator) ![][]const u8 {
var missing = std.ArrayList([]const u8){};
var it = self.referenced_types.keyIterator();
while (it.next()) |key| {
if (!self.defined_types.contains(key.*)) {
try missing.append(allocator, try allocator.dupe(u8, key.*));
}
// special case evaluation
if (std.mem.eql(u8, key.*, "SDL_HitTest")) {}
}
return try missing.toOwnedSlice(allocator);
}
fn collectDefinedTypes(self: *DependencyResolver, decls: []const Declaration) !void {
for (decls) |decl| {
const type_name = switch (decl) {
@ -64,7 +67,7 @@ pub const DependencyResolver = struct {
try self.defined_types.put(type_name, {});
}
}
fn collectReferencedTypes(self: *DependencyResolver, decls: []const Declaration) !void {
for (decls) |decl| {
switch (decl) {
@ -94,7 +97,7 @@ pub const DependencyResolver = struct {
}
}
}
fn scanType(self: *DependencyResolver, type_str: []const u8) !void {
const base_type = extractBaseType(type_str);
if (base_type.len > 0 and isSDLType(base_type)) {
@ -111,45 +114,45 @@ pub const DependencyResolver = struct {
pub fn extractBaseType(type_str: []const u8) []const u8 {
var result = type_str;
// Remove leading qualifiers and pointer markers
while (true) {
// Trim whitespace
result = std.mem.trim(u8, result, " \t");
// Remove "const"
if (std.mem.startsWith(u8, result, "const ")) {
result = result["const ".len..];
continue;
}
// Remove "struct"
if (std.mem.startsWith(u8, result, "struct ")) {
result = result["struct ".len..];
continue;
}
// Remove leading "?" (nullable)
if (std.mem.startsWith(u8, result, "?")) {
result = result[1..];
continue;
}
// Remove leading "*" (pointer)
if (std.mem.startsWith(u8, result, "*")) {
result = result[1..];
continue;
}
break;
}
// Trim again
result = std.mem.trim(u8, result, " \t");
// If it contains [*c], extract the part after
if (std.mem.indexOf(u8, result, "[*c]")) |idx| {
result = result[idx + "[*c]".len..];
result = result[idx + "[*c]".len ..];
result = std.mem.trim(u8, result, " \t");
// Remove const again if present
if (std.mem.startsWith(u8, result, "const ")) {
@ -157,35 +160,35 @@ pub fn extractBaseType(type_str: []const u8) []const u8 {
}
result = std.mem.trim(u8, result, " \t");
}
// Remove trailing pointer markers and const qualifiers
while (true) {
result = std.mem.trim(u8, result, " \t");
// Remove trailing "*const" (common pattern)
if (std.mem.endsWith(u8, result, "*const")) {
result = result[0..result.len - "*const".len];
result = result[0 .. result.len - "*const".len];
continue;
}
// Remove trailing "*"
if (std.mem.endsWith(u8, result, "*")) {
result = result[0..result.len-1];
result = result[0 .. result.len - 1];
continue;
}
// Remove trailing "const"
if (std.mem.endsWith(u8, result, " const")) {
result = result[0..result.len - " const".len];
result = result[0 .. result.len - " const".len];
continue;
}
break;
}
// Final trim
result = std.mem.trim(u8, result, " \t");
return result;
}
@ -194,7 +197,7 @@ fn isSDLType(type_str: []const u8) bool {
if (std.mem.startsWith(u8, type_str, "SDL_")) {
return true;
}
// Check for known SDL types that don't have SDL_ prefix in Zig bindings
// These are types that would already be converted from SDL_ to their Zig name
const known_types = [_][]const u8{
@ -207,19 +210,19 @@ fn isSDLType(type_str: []const u8) bool {
"Surface",
"PixelFormat",
};
for (known_types) |known| {
if (std.mem.eql(u8, type_str, known)) {
return true;
}
}
return false;
}
pub fn parseIncludes(allocator: Allocator, source: []const u8) ![][]const u8 {
var includes = std.ArrayList([]const u8){};
var lines = std.mem.splitScalar(u8, source, '\n');
while (lines.next()) |line| {
// Match: #include <SDL3/SDL_something.h>
@ -232,7 +235,7 @@ pub fn parseIncludes(allocator: Allocator, source: []const u8) ![][]const u8 {
}
}
}
return try includes.toOwnedSlice(allocator);
}
@ -249,7 +252,7 @@ pub fn extractTypeFromHeader(
}
allocator.free(all_decls);
}
// Find matching declaration
for (all_decls) |decl| {
const decl_name = switch (decl) {
@ -261,12 +264,12 @@ pub fn extractTypeFromHeader(
.flag_decl => |f| f.name,
else => continue,
};
if (std.mem.eql(u8, decl_name, type_name)) {
return try cloneDeclaration(allocator, decl);
}
}
return null;
}
@ -477,36 +480,36 @@ test "isSDLType identifies SDL types" {
test "DependencyResolver basic functionality" {
const testing = std.testing;
const allocator = testing.allocator;
var resolver = DependencyResolver.init(allocator);
defer resolver.deinit();
// Create test params array on heap
const test_params = try allocator.alloc(patterns.ParamDecl, 1);
defer allocator.free(test_params);
test_params[0] = .{ .name = "rect", .type_name = "*const SDL_Rect" };
const decls = [_]Declaration{
.{ .function_decl = .{
.name = "test",
.return_type = "?*SDL_Window",
.params = test_params,
.doc_comment = null,
}},
} },
.{ .opaque_type = .{
.name = "SDL_Device",
.doc_comment = null,
}},
} },
};
try resolver.analyze(&decls);
const missing = try resolver.getMissingTypes(allocator);
defer {
for (missing) |m| allocator.free(m);
allocator.free(missing);
}
// Should find Window and Rect, but not Device (it's defined)
try testing.expect(missing.len == 2);
}

14
src/io.zig Normal file
View File

@ -0,0 +1,14 @@
var stdout_buffer: [1024]u8 = undefined;
var stdout_writer: *std.Io.Writer = undefined;
var stdout_file: std.fs.Writer = undefined;
pub fn stdout() *std.Io.Writer {
return stdout_writer;
}
pub fn initWriter() void {
stdout_writer = std.fs.File.stdout().writer(&stdout_buffer);
stdout = &stdout_writer.interface;
}
pub const std = @import("std");

View File

@ -226,7 +226,7 @@ pub const JsonSerializer = struct {
try writer.writeAll("{\"name\": ");
try self.writeString(writer, struct_decl.name);
try writer.writeAll(", \"fields\": [");
for (struct_decl.fields, 0..) |field, i| {
try writer.writeAll("{\"name\": ");
try self.writeString(writer, field.name);
@ -239,8 +239,11 @@ pub const JsonSerializer = struct {
try writer.writeAll("}");
if (i < struct_decl.fields.len - 1) try writer.writeAll(", ");
}
try writer.writeAll("]");
if (struct_decl.has_unions) {
try writer.writeAll(", \"has_unions\": true");
}
if (struct_decl.doc_comment) |doc| {
try writer.writeAll(", \"doc\": ");
try self.writeString(writer, doc);

View File

@ -3,6 +3,7 @@ const patterns = @import("patterns.zig");
const codegen = @import("codegen.zig");
const dependency_resolver = @import("dependency_resolver.zig");
const json_serializer = @import("json_serializer.zig");
const io = @import("io.zig");
pub fn main() !void {
const allocator = std.heap.smp_allocator;
@ -11,7 +12,7 @@ pub fn main() !void {
defer std.process.argsFree(allocator, args);
if (args.len < 2) {
std.debug.print("Usage: {s} <header-file> [--output=<output-file>] [--mocks=<mock-file>] [--generate-json=<json-file>]\n", .{args[0]});
std.debug.print("Usage: {s} <header-file> [--output=<output-file>] [--mocks=<mock-file>] [--generate-json=<json-file>] [--timestamp=<timestamp>]\n", .{args[0]});
std.debug.print("Example: {s} ../SDL/include/SDL3/SDL_gpu.h --output=gpu.zig\n", .{args[0]});
std.debug.print(" {s} ../SDL/include/SDL3/SDL_gpu.h --output=gpu.zig --mocks=gpu_mock.c\n", .{args[0]});
std.debug.print(" {s} ../SDL/include/SDL3/SDL_gpu.h --generate-json=gpu.json\n", .{args[0]});
@ -24,25 +25,32 @@ pub fn main() !void {
var output_file: ?[]const u8 = null;
var mock_output_file: ?[]const u8 = null;
var json_output_file: ?[]const u8 = null;
var timestamp: ?i64 = null;
// Parse additional flags
for (args[2..]) |arg| {
const output_prefix = "--output=";
const mocks_prefix = "--mocks=";
const json_prefix = "--generate-json=";
const timestamp_prefix = "--timestamp=";
if (std.mem.startsWith(u8, arg, output_prefix)) {
output_file = arg[output_prefix.len..];
} else if (std.mem.startsWith(u8, arg, mocks_prefix)) {
mock_output_file = arg[mocks_prefix.len..];
} else if (std.mem.startsWith(u8, arg, json_prefix)) {
json_output_file = arg[json_prefix.len..];
} else if (std.mem.startsWith(u8, arg, timestamp_prefix)) {
timestamp = std.fmt.parseInt(i64, arg[timestamp_prefix.len..], 10) catch null;
} else {
std.debug.print("Error: Unknown argument '{s}'\n", .{arg});
std.debug.print("Usage: {s} <header-file> [--output=<output-file>] [--mocks=<mock-file>] [--generate-json=<json-file>]\n", .{args[0]});
std.debug.print("Usage: {s} <header-file> [--output=<output-file>] [--mocks=<mock-file>] [--generate-json=<json-file>] [--timestamp=<timestamp>]\n", .{args[0]});
return error.InvalidArgument;
}
}
// Archive any existing debug directory before this run
archiveExistingDebugDir(allocator, timestamp);
std.debug.print("SDL3 Header Parser\n", .{});
std.debug.print("==================\n\n", .{});
std.debug.print("Parsing: {s}\n\n", .{header_path});
@ -186,6 +194,7 @@ pub fn main() !void {
const formatter = std.json.fmt(parsed.value, .{ .whitespace = .indent_2 });
try std.fmt.format(formatted_output.writer(allocator), "{f}", .{formatter});
try ensureParentDirExists(json_path);
try std.fs.cwd().writeFile(.{
.sub_path = json_path,
.data = formatted_output.items,
@ -247,14 +256,14 @@ pub fn main() !void {
if (try dependency_resolver.extractTypeFromHeader(allocator, dep_source, missing_type)) |dep_decl| {
try dependency_decls.append(allocator, dep_decl);
std.debug.print(" Found {s} in {s}\n", .{ missing_type, include });
std.debug.print(" Found {s} in {s}\n", .{ missing_type, include });
found = true;
break;
}
}
if (!found) {
std.debug.print(" Warning: Could not find definition for type: {s}\n", .{missing_type});
std.debug.print(" Warning: Could not find definition for type: {s}\n", .{missing_type});
}
}
@ -287,6 +296,9 @@ pub fn main() !void {
std.debug.print(" Line {d}: {s}\n", .{ loc.line + 1, @tagName(err.tag) });
}
// Write to debug file
try writeDebugFile(allocator, header_path, output);
// Write unformatted output for debugging
if (output_file) |file_path| {
try std.fs.cwd().writeFile(.{
@ -300,18 +312,18 @@ pub fn main() !void {
}
// Render formatted output from AST
const formatted_output = try ast.renderAlloc(allocator);
const formatted_output = ast.renderAlloc(allocator) catch |err| {
std.debug.print("\nError: AST render failed: {}\n", .{err});
try writeDebugFile(allocator, header_path, output);
return err;
};
defer allocator.free(formatted_output);
// Write formatted output to file or stdout
if (output_file) |file_path| {
try std.fs.cwd().writeFile(.{
.sub_path = file_path,
.data = formatted_output,
});
std.debug.print("Generated: {s}\n", .{file_path});
try writeZigFileWithFmt(allocator, header_path, file_path, formatted_output);
} else {
_ = try std.posix.write(std.posix.STDOUT_FILENO, formatted_output);
_ = try io.stdout().write(formatted_output);
}
// Generate C mocks if requested (with all declarations)
@ -320,6 +332,7 @@ pub fn main() !void {
const mock_output = try mock_codegen.MockCodeGen.generate(allocator, all_decls.items);
defer allocator.free(mock_output);
try ensureParentDirExists(mock_path);
try std.fs.cwd().writeFile(.{
.sub_path = mock_path,
.data = mock_output,
@ -348,6 +361,9 @@ pub fn main() !void {
std.debug.print(" Line {d}: {s}\n", .{ loc.line + 1, @tagName(err.tag) });
}
// Write to debug file
try writeDebugFile(allocator, header_path, output);
// Write unformatted output for debugging
if (output_file) |file_path| {
try std.fs.cwd().writeFile(.{
@ -361,18 +377,18 @@ pub fn main() !void {
}
// Render formatted output from AST
const formatted_output = try ast.renderAlloc(allocator);
const formatted_output = ast.renderAlloc(allocator) catch |err| {
std.debug.print("\nError: AST render failed: {}\n", .{err});
try writeDebugFile(allocator, header_path, output);
return err;
};
defer allocator.free(formatted_output);
// Write formatted output to file or stdout
if (output_file) |file_path| {
try std.fs.cwd().writeFile(.{
.sub_path = file_path,
.data = formatted_output,
});
std.debug.print("Generated: {s}\n", .{file_path});
try writeZigFileWithFmt(allocator, header_path, file_path, formatted_output);
} else {
_ = try std.posix.write(std.posix.STDOUT_FILENO, formatted_output);
_ = try io.stdout().write(formatted_output);
}
// Generate C mocks if requested
@ -381,6 +397,7 @@ pub fn main() !void {
const mock_output = try mock_codegen.MockCodeGen.generate(allocator, decls);
defer allocator.free(mock_output);
try ensureParentDirExists(mock_path);
try std.fs.cwd().writeFile(.{
.sub_path = mock_path,
.data = mock_output,
@ -390,6 +407,133 @@ pub fn main() !void {
}
}
fn writeZigFileWithFmt(allocator: std.mem.Allocator, header_path: []const u8, output_path: []const u8, content: []const u8) !void {
const header_basename = std.fs.path.basename(header_path);
const output_basename = std.fs.path.basename(output_path);
// Create tmp directory
std.fs.cwd().makePath("tmp") catch |err| switch (err) {
error.PathAlreadyExists => {},
else => return err,
};
// Write to tmp file
const tmp_path = try std.fmt.allocPrint(allocator, "tmp/{s}", .{output_basename});
defer allocator.free(tmp_path);
try std.fs.cwd().writeFile(.{
.sub_path = tmp_path,
.data = content,
});
// Run zig ast-check on tmp file
var ast_check = std.process.Child.init(&.{ "zig", "ast-check", tmp_path }, allocator);
ast_check.stderr_behavior = .Pipe;
try ast_check.spawn();
const ast_result = try ast_check.wait();
if (ast_result.Exited != 0) {
// zig ast-check failed - copy to debug folder
std.fs.cwd().makePath("debug") catch |err| switch (err) {
error.PathAlreadyExists => {},
else => return err,
};
// Convert header name: SDL_gpu.h -> SDL_gpu_h
var safe_name = try allocator.alloc(u8, header_basename.len);
defer allocator.free(safe_name);
for (header_basename, 0..) |c, i| {
safe_name[i] = if (c == '.') '_' else c;
}
const debug_path = try std.fmt.allocPrint(allocator, "debug/{s}_fmterror.zig", .{safe_name});
defer allocator.free(debug_path);
try std.fs.cwd().writeFile(.{
.sub_path = debug_path,
.data = content,
});
std.debug.print("zig ast-check failed, debug output written to: {s}\n", .{debug_path});
return error.ZigAstCheckFailed;
}
// Run zig fmt on tmp file
var fmt = std.process.Child.init(&.{ "zig", "fmt", tmp_path }, allocator);
fmt.stderr_behavior = .Pipe;
try fmt.spawn();
_ = try fmt.wait();
// Copy formatted file to final destination
try ensureParentDirExists(output_path);
const formatted_content = try std.fs.cwd().readFileAlloc(allocator, tmp_path, 10 * 1024 * 1024);
defer allocator.free(formatted_content);
try std.fs.cwd().writeFile(.{
.sub_path = output_path,
.data = formatted_content,
});
std.debug.print("Generated: {s}\n", .{output_path});
}
fn ensureParentDirExists(path: []const u8) !void {
if (std.fs.path.dirname(path)) |dir| {
std.fs.cwd().makePath(dir) catch |err| switch (err) {
error.PathAlreadyExists => {},
else => return err,
};
}
}
fn archiveExistingDebugDir(allocator: std.mem.Allocator, provided_timestamp: ?i64) void {
// Check if debug/ directory exists
var debug_dir = std.fs.cwd().openDir("debug", .{}) catch return;
debug_dir.close();
// Use provided timestamp or generate one
const timestamp = provided_timestamp orelse std.time.timestamp();
const archive_path = std.fmt.allocPrint(allocator, "archive/debug/{d}", .{timestamp}) catch return;
defer allocator.free(archive_path);
// Create archive/debug directory if needed
std.fs.cwd().makePath("archive/debug") catch return;
// Move debug/ to archive/debug/<timestamp>/
std.fs.cwd().rename("debug", archive_path) catch |err| {
std.debug.print("Warning: Failed to archive existing debug dir: {}\n", .{err});
return;
};
std.debug.print("Archived existing debug/ to {s}\n", .{archive_path});
}
fn writeDebugFile(allocator: std.mem.Allocator, header_path: []const u8, output: []const u8) !void {
// Get the header basename (e.g., "SDL_gpu.h")
const header_basename = std.fs.path.basename(header_path);
// Convert to safe filename: SDL_gpu.h -> error_SDL_gpu_h.zig
var safe_name = try allocator.alloc(u8, header_basename.len);
defer allocator.free(safe_name);
for (header_basename, 0..) |c, i| {
safe_name[i] = if (c == '.') '_' else c;
}
const debug_filename = try std.fmt.allocPrint(allocator, "debug/error_{s}.zig", .{safe_name});
defer allocator.free(debug_filename);
// Create debug directory if it doesn't exist
std.fs.cwd().makeDir("debug") catch |err| switch (err) {
error.PathAlreadyExists => {},
else => return err,
};
try std.fs.cwd().writeFile(.{
.sub_path = debug_filename,
.data = output,
});
std.debug.print("Debug output written to: {s}\n", .{debug_filename});
}
fn freeDeclDeep(allocator: std.mem.Allocator, decl: patterns.Declaration) void {
switch (decl) {
.opaque_type => |o| {

View File

@ -43,6 +43,7 @@ pub const StructDecl = struct {
name: []const u8, // SDL_GPUViewport
fields: []FieldDecl,
doc_comment: ?[]const u8,
has_unions: bool = false, // If true, codegen should emit as opaque (C unions can't be represented in other languages)
};
pub const UnionDecl = struct {
@ -614,6 +615,12 @@ pub const Scanner = struct {
const body = try self.readBracedBlock();
defer self.allocator.free(body);
// Check if struct contains unions - C unions can't be represented in other languages
const has_unions = std.mem.indexOf(u8, body, "union ") != null or
std.mem.indexOf(u8, body, "union{") != null or
std.mem.indexOf(u8, body, "union\n") != null or
std.mem.indexOf(u8, body, "union\r") != null;
// Parse fields
var fields = try std.ArrayList(FieldDecl).initCapacity(self.allocator, 20);
var lines = std.mem.splitScalar(u8, body, '\n');
@ -672,6 +679,7 @@ pub const Scanner = struct {
.name = try self.allocator.dupe(u8, name),
.fields = try fields.toOwnedSlice(self.allocator),
.doc_comment = doc,
.has_unions = has_unions,
};
}

View File

@ -85,7 +85,7 @@ pub const CameraSpec = extern struct {
width: c_int, // Frame width
height: c_int, // Frame height
framerate_numerator: c_int, // Frame rate numerator ((num / denom) == FPS, (denom / num) == duration in seconds)
framerate_denominator: c_int, // Frame rate demoninator ((num / denom) == FPS, (denom / num) == duration in seconds)
framerate_denominator: c_int, // Frame rate denominator ((num / denom) == FPS, (denom / num) == duration in seconds)
};
pub const CameraPosition = enum(c_int) {

View File

@ -30,6 +30,7 @@ pub const SensorType = enum(c_int) {
sensorGyroL, //Gyroscope for left Joy-Con controller
sensorAccelR, //Accelerometer for right Joy-Con controller
sensorGyroR, //Gyroscope for right Joy-Con controller
sensorCount,
};
pub const PowerState = enum(c_int) {
@ -277,20 +278,7 @@ pub const GamepadBindingType = enum(c_int) {
gamepadBindtypeHat,
};
pub const GamepadBinding = extern struct {
input_type: GamepadBindingType,
button: c_int,
axis: c_int,
axis_min: c_int,
axis_max: c_int,
hat: c_int,
hat_mask: c_int,
output_type: GamepadBindingType,
button: GamepadButton,
axis: GamepadAxis,
axis_min: c_int,
axis_max: c_int,
};
pub const GamepadBinding = opaque {};
pub inline fn addGamepadMapping(mapping: [*c]const u8) c_int {
return c.SDL_AddGamepadMapping(mapping);

View File

@ -651,7 +651,7 @@ pub const GPUCompareOp = enum(c_int) {
compareopLessOrEqual, //The comparison evaluates reference <= test.
compareopGreater, //The comparison evaluates reference > test.
compareopNotEqual, //The comparison evaluates reference != test.
compareopGreaterOrEqual, //The comparison evalutes reference >= test.
compareopGreaterOrEqual, //The comparison evaluates reference >= test.
compareopAlways, //The comparison always evaluates true.
};
@ -836,7 +836,7 @@ pub const GPUSamplerCreateInfo = extern struct {
pub const GPUVertexBufferDescription = extern struct {
slot: u32, // The binding slot of the vertex buffer.
pitch: u32, // The byte pitch between consecutive elements of the vertex buffer.
pitch: u32, // The size of a single element + the offset between elements.
input_rate: GPUVertexInputRate, // Whether attribute addressing is a function of the vertex index or instance index.
instance_step_rate: u32, // Reserved for future use. Must be set to 0.
};

View File

@ -1,113 +0,0 @@
const std = @import("std");
pub const c = @import("c.zig").c;
pub const Event = extern union {
_type: u32, // Event type, shared with all events, Uint32 to cover user events which are not in the SDL_EventType enumeration
common: CommonEvent, // Common event data
display: DisplayEvent, // Display event data
window: WindowEvent, // Window event data
kdevice: KeyboardDeviceEvent, // Keyboard device change event data
key: KeyboardEvent, // Keyboard event data
edit: TextEditingEvent, // Text editing event data
edit_candidates: TextEditingCandidatesEvent, // Text editing candidates event data
text: TextInputEvent, // Text input event data
mdevice: MouseDeviceEvent, // Mouse device change event data
motion: MouseMotionEvent, // Mouse motion event data
button: MouseButtonEvent, // Mouse button event data
wheel: MouseWheelEvent, // Mouse wheel event data
jdevice: JoyDeviceEvent, // Joystick device change event data
jaxis: JoyAxisEvent, // Joystick axis event data
jball: JoyBallEvent, // Joystick ball event data
jhat: JoyHatEvent, // Joystick hat event data
jbutton: JoyButtonEvent, // Joystick button event data
jbattery: JoyBatteryEvent, // Joystick battery event data
gdevice: GamepadDeviceEvent, // Gamepad device event data
gaxis: GamepadAxisEvent, // Gamepad axis event data
gbutton: GamepadButtonEvent, // Gamepad button event data
gtouchpad: GamepadTouchpadEvent, // Gamepad touchpad event data
gsensor: GamepadSensorEvent, // Gamepad sensor event data
adevice: AudioDeviceEvent, // Audio device event data
cdevice: CameraDeviceEvent, // Camera device event data
sensor: SensorEvent, // Sensor event data
quit: QuitEvent, // Quit request event data
user: UserEvent, // Custom event data
tfinger: TouchFingerEvent, // Touch finger event data
pproximity: PenProximityEvent, // Pen proximity event data
ptouch: PenTouchEvent, // Pen tip touching event data
pmotion: PenMotionEvent, // Pen motion event data
pbutton: PenButtonEvent, // Pen button event data
paxis: PenAxisEvent, // Pen axis event data
render: RenderEvent, // Render event data
drop: DropEvent, // Drag and drop event data
clipboard: ClipboardEvent, // Clipboard event data
padding: [128]u8,
};
pub const InitFlags = packed struct(u32) {
initAudio: bool = false, // `SDL_INIT_AUDIO` implies `SDL_INIT_EVENTS`
initVideo: bool = false, // `SDL_INIT_VIDEO` implies `SDL_INIT_EVENTS`, should be initialized on the main thread
initJoystick: bool = false, // `SDL_INIT_JOYSTICK` implies `SDL_INIT_EVENTS`, should be initialized on the same thread as SDL_INIT_VIDEO on Windows if you don't set SDL_HINT_JOYSTICK_THREAD
initHaptic: bool = false,
initGamepad: bool = false, // `SDL_INIT_GAMEPAD` implies `SDL_INIT_JOYSTICK`
initEvents: bool = false,
initSensor: bool = false, // `SDL_INIT_SENSOR` implies `SDL_INIT_EVENTS`
initCamera: bool = false, // `SDL_INIT_CAMERA` implies `SDL_INIT_EVENTS`
pad0: u23 = 0,
rsvd: bool = false,
};
pub const AppResult = enum(c_int) {
appContinue, //Value that requests that the app continue from the main callbacks.
appSuccess, //Value that requests termination with success from the main callbacks.
appFailure, //Value that requests termination with error from the main callbacks.
};
pub const AppInit_func = *const fn (appstate: [*c]?*anyopaque, argc: c_int, argv: [*c][*c]u8) callconv(.C) AppResult;
pub const AppIterate_func = *const fn (appstate: ?*anyopaque) callconv(.C) AppResult;
pub const AppEvent_func = *const fn (appstate: ?*anyopaque, event: ?*Event) callconv(.C) AppResult;
pub const AppQuit_func = *const fn (appstate: ?*anyopaque, result: AppResult) callconv(.C) void;
pub inline fn init(flags: InitFlags) bool {
return c.SDL_Init(@bitCast(flags));
}
pub inline fn initSubSystem(flags: InitFlags) bool {
return c.SDL_InitSubSystem(@bitCast(flags));
}
pub inline fn quitSubSystem(flags: InitFlags) void {
return c.SDL_QuitSubSystem(@bitCast(flags));
}
pub inline fn wasInit(flags: InitFlags) InitFlags {
return @bitCast(c.SDL_WasInit(@bitCast(flags)));
}
pub inline fn quit() void {
return c.SDL_Quit();
}
pub inline fn isMainThread() bool {
return c.SDL_IsMainThread();
}
pub const MainThreadCallback = *const fn (userdata: ?*anyopaque) callconv(.C) void;
pub inline fn runOnMainThread(callback: MainThreadCallback, userdata: ?*anyopaque, wait_complete: bool) bool {
return c.SDL_RunOnMainThread(callback, userdata, wait_complete);
}
pub inline fn setAppMetadata(appname: [*c]const u8, appversion: [*c]const u8, appidentifier: [*c]const u8) bool {
return c.SDL_SetAppMetadata(appname, appversion, appidentifier);
}
pub inline fn setAppMetadataProperty(name: [*c]const u8, value: [*c]const u8) bool {
return c.SDL_SetAppMetadataProperty(name, value);
}
pub inline fn getAppMetadataProperty(name: [*c]const u8) [*c]const u8 {
return c.SDL_GetAppMetadataProperty(name);
}

View File

@ -12,6 +12,7 @@ pub const SensorType = enum(c_int) {
sensorGyroL, //Gyroscope for left Joy-Con controller
sensorAccelR, //Accelerometer for right Joy-Con controller
sensorGyroR, //Gyroscope for right Joy-Con controller
sensorCount,
};
pub const GUID = extern struct {

View File

@ -1,64 +0,0 @@
const std = @import("std");
pub const c = @import("c.zig").c;
pub const Window = opaque {};
pub const MessageBoxFlags = packed struct(u32) {
messageboxError: bool = false, // error dialog
messageboxWarning: bool = false, // warning dialog
messageboxInformation: bool = false, // informational dialog
messageboxButtonsLeftToRight: bool = false, // buttons placed left to right
messageboxButtonsRightToLeft: bool = false, // buttons placed right to left
pad0: u26 = 0,
rsvd: bool = false,
};
pub const MessageBoxButtonFlags = packed struct(u32) {
messageboxButtonReturnkeyDefault: bool = false, // Marks the default button when return is hit
messageboxButtonEscapekeyDefault: bool = false, // Marks the default button when escape is hit
pad0: u29 = 0,
rsvd: bool = false,
};
pub const MessageBoxButtonData = extern struct {
flags: MessageBoxButtonFlags,
buttonID: c_int, // User defined button id (value returned via SDL_ShowMessageBox)
text: [*c]const u8, // The UTF-8 button text
};
pub const MessageBoxColor = extern struct {
r: u8,
g: u8,
b: u8,
};
pub const MessageBoxColorType = enum(c_int) {
messageboxColorBackground,
messageboxColorText,
messageboxColorButtonBorder,
messageboxColorButtonBackground,
messageboxColorButtonSelected,
messageboxColorCount, //Size of the colors array of SDL_MessageBoxColorScheme.
};
pub const MessageBoxColorScheme = extern struct {
colors: [SDL_MESSAGEBOX_COLOR_COUNT]MessageBoxColor,
};
pub const MessageBoxData = extern struct {
flags: MessageBoxFlags,
window: ?*Window, // Parent window, can be NULL
title: [*c]const u8, // UTF-8 title
message: [*c]const u8, // UTF-8 message text
numbuttons: c_int,
buttons: *const MessageBoxButtonData,
colorScheme: *const MessageBoxColorScheme, // SDL_MessageBoxColorScheme, can be NULL to use system settings
};
pub inline fn showMessageBox(messageboxdata: *const MessageBoxData, buttonid: *c_int) bool {
return c.SDL_ShowMessageBox(@ptrCast(messageboxdata), @ptrCast(buttonid));
}
pub inline fn showSimpleMessageBox(flags: MessageBoxFlags, title: [*c]const u8, message: [*c]const u8, window: ?*Window) bool {
return c.SDL_ShowSimpleMessageBox(@bitCast(flags), title, message, window);
}

View File

@ -1,517 +0,0 @@
const std = @import("std");
pub const c = @import("c.zig").c;
pub const FPoint = extern struct {
x: f32,
y: f32,
};
pub const PixelFormat = enum(c_int) {
pixelformatYv12, //Planar mode: Y + V + U (3 planes)
pixelformatIyuv, //Planar mode: Y + U + V (3 planes)
pixelformatYuy2, //Packed mode: Y0+U0+Y1+V0 (1 plane)
pixelformatUyvy, //Packed mode: U0+Y0+V0+Y1 (1 plane)
pixelformatYvyu, //Packed mode: Y0+V0+Y1+U0 (1 plane)
pixelformatNv12, //Planar mode: Y + U/V interleaved (2 planes)
pixelformatNv21, //Planar mode: Y + V/U interleaved (2 planes)
pixelformatP010, //Planar mode: Y + U/V interleaved (2 planes)
pixelformatExternalOes, //Android video texture format
pixelformatMjpg, //Motion JPEG
};
pub const FColor = extern struct {
r: f32,
g: f32,
b: f32,
a: f32,
};
pub const Surface = opaque {
pub inline fn createSoftwareRenderer(surface: *Surface) ?*Renderer {
return c.SDL_CreateSoftwareRenderer(surface);
}
};
pub const ScaleMode = enum(c_int) {
scalemodeNearest, //nearest pixel sampling
scalemodeLinear, //linear filtering
};
pub const PropertiesID = u32;
pub const BlendMode = u32;
pub const Window = opaque {
pub inline fn createRenderer(window: *Window, name: [*c]const u8) ?*Renderer {
return c.SDL_CreateRenderer(window, name);
}
pub inline fn getRenderer(window: *Window) ?*Renderer {
return c.SDL_GetRenderer(window);
}
};
pub const FRect = extern struct {
x: f32,
y: f32,
w: f32,
h: f32,
};
pub const Event = extern union {
_type: u32, // Event type, shared with all events, Uint32 to cover user events which are not in the SDL_EventType enumeration
common: CommonEvent, // Common event data
display: DisplayEvent, // Display event data
window: WindowEvent, // Window event data
kdevice: KeyboardDeviceEvent, // Keyboard device change event data
key: KeyboardEvent, // Keyboard event data
edit: TextEditingEvent, // Text editing event data
edit_candidates: TextEditingCandidatesEvent, // Text editing candidates event data
text: TextInputEvent, // Text input event data
mdevice: MouseDeviceEvent, // Mouse device change event data
motion: MouseMotionEvent, // Mouse motion event data
button: MouseButtonEvent, // Mouse button event data
wheel: MouseWheelEvent, // Mouse wheel event data
jdevice: JoyDeviceEvent, // Joystick device change event data
jaxis: JoyAxisEvent, // Joystick axis event data
jball: JoyBallEvent, // Joystick ball event data
jhat: JoyHatEvent, // Joystick hat event data
jbutton: JoyButtonEvent, // Joystick button event data
jbattery: JoyBatteryEvent, // Joystick battery event data
gdevice: GamepadDeviceEvent, // Gamepad device event data
gaxis: GamepadAxisEvent, // Gamepad axis event data
gbutton: GamepadButtonEvent, // Gamepad button event data
gtouchpad: GamepadTouchpadEvent, // Gamepad touchpad event data
gsensor: GamepadSensorEvent, // Gamepad sensor event data
adevice: AudioDeviceEvent, // Audio device event data
cdevice: CameraDeviceEvent, // Camera device event data
sensor: SensorEvent, // Sensor event data
quit: QuitEvent, // Quit request event data
user: UserEvent, // Custom event data
tfinger: TouchFingerEvent, // Touch finger event data
pproximity: PenProximityEvent, // Pen proximity event data
ptouch: PenTouchEvent, // Pen tip touching event data
pmotion: PenMotionEvent, // Pen motion event data
pbutton: PenButtonEvent, // Pen button event data
paxis: PenAxisEvent, // Pen axis event data
render: RenderEvent, // Render event data
drop: DropEvent, // Drag and drop event data
clipboard: ClipboardEvent, // Clipboard event data
padding: [128]u8,
};
pub const FlipMode = enum(c_int) {
flipNone, //Do not flip
flipHorizontal, //flip horizontally
flipVertical, //flip vertically
};
pub const Rect = extern struct {
x: c_int,
y: c_int,
w: c_int,
h: c_int,
};
pub const WindowFlags = packed struct(u64) {
windowFullscreen: bool = false, // window is in fullscreen mode
windowOpengl: bool = false, // window usable with OpenGL context
windowOccluded: bool = false, // window is occluded
windowHidden: bool = false, // window is neither mapped onto the desktop nor shown in the taskbar/dock/window list; SDL_ShowWindow() is required for it to become visible
windowBorderless: bool = false, // no window decoration
windowResizable: bool = false, // window can be resized
windowMinimized: bool = false, // window is minimized
windowMaximized: bool = false, // window is maximized
windowMouseGrabbed: bool = false, // window has grabbed mouse input
windowInputFocus: bool = false, // window has input focus
windowMouseFocus: bool = false, // window has mouse focus
windowExternal: bool = false, // window not created by SDL
windowModal: bool = false, // window is modal
windowHighPixelDensity: bool = false, // window uses high pixel density back buffer if possible
windowMouseCapture: bool = false, // window has mouse captured (unrelated to MOUSE_GRABBED)
windowMouseRelativeMode: bool = false, // window has relative mode enabled
windowAlwaysOnTop: bool = false, // window should always be above others
windowUtility: bool = false, // window should be treated as a utility window, not showing in the task bar and window list
windowTooltip: bool = false, // window should be treated as a tooltip and does not get mouse or keyboard focus, requires a parent window
windowPopupMenu: bool = false, // window should be treated as a popup menu, requires a parent window
windowKeyboardGrabbed: bool = false, // window has grabbed keyboard input
windowVulkan: bool = false, // window usable for Vulkan surface
windowMetal: bool = false, // window usable for Metal view
windowTransparent: bool = false, // window with transparent buffer
windowNotFocusable: bool = false, // window should not be focusable
pad0: u38 = 0,
rsvd: bool = false,
};
pub const Vertex = extern struct {
position: FPoint, // Vertex position, in SDL_Renderer coordinates
color: FColor, // Vertex color
tex_coord: FPoint, // Normalized texture coordinates, if needed
};
pub const TextureAccess = enum(c_int) {
textureaccessStatic, //Changes rarely, not lockable
textureaccessStreaming, //Changes frequently, lockable
textureaccessTarget, //Texture can be used as a render target
};
pub const RendererLogicalPresentation = enum(c_int) {
logicalPresentationDisabled, //There is no logical size in effect
logicalPresentationStretch, //The rendered content is stretched to the output resolution
logicalPresentationLetterbox, //The rendered content is fit to the largest dimension and the other dimension is letterboxed with black bars
logicalPresentationOverscan, //The rendered content is fit to the smallest dimension and the other dimension extends beyond the output bounds
logicalPresentationIntegerScale, //The rendered content is scaled up by integer multiples to fit the output resolution
};
pub const Renderer = opaque {
pub inline fn getRenderWindow(renderer: *Renderer) ?*Window {
return c.SDL_GetRenderWindow(renderer);
}
pub inline fn getRendererName(renderer: *Renderer) [*c]const u8 {
return c.SDL_GetRendererName(renderer);
}
pub inline fn getRendererProperties(renderer: *Renderer) PropertiesID {
return c.SDL_GetRendererProperties(renderer);
}
pub inline fn getRenderOutputSize(renderer: *Renderer, w: *c_int, h: *c_int) bool {
return c.SDL_GetRenderOutputSize(renderer, @ptrCast(w), @ptrCast(h));
}
pub inline fn getCurrentRenderOutputSize(renderer: *Renderer, w: *c_int, h: *c_int) bool {
return c.SDL_GetCurrentRenderOutputSize(renderer, @ptrCast(w), @ptrCast(h));
}
pub inline fn createTexture(renderer: *Renderer, format: PixelFormat, access: TextureAccess, w: c_int, h: c_int) ?*Texture {
return c.SDL_CreateTexture(renderer, @bitCast(format), access, w, h);
}
pub inline fn createTextureFromSurface(renderer: *Renderer, surface: ?*Surface) ?*Texture {
return c.SDL_CreateTextureFromSurface(renderer, surface);
}
pub inline fn createTextureWithProperties(renderer: *Renderer, props: PropertiesID) ?*Texture {
return c.SDL_CreateTextureWithProperties(renderer, props);
}
pub inline fn setRenderTarget(renderer: *Renderer, texture: ?*Texture) bool {
return c.SDL_SetRenderTarget(renderer, texture);
}
pub inline fn getRenderTarget(renderer: *Renderer) ?*Texture {
return c.SDL_GetRenderTarget(renderer);
}
pub inline fn setRenderLogicalPresentation(renderer: *Renderer, w: c_int, h: c_int, mode: RendererLogicalPresentation) bool {
return c.SDL_SetRenderLogicalPresentation(renderer, w, h, mode);
}
pub inline fn getRenderLogicalPresentation(renderer: *Renderer, w: *c_int, h: *c_int, mode: ?*RendererLogicalPresentation) bool {
return c.SDL_GetRenderLogicalPresentation(renderer, @ptrCast(w), @ptrCast(h), mode);
}
pub inline fn getRenderLogicalPresentationRect(renderer: *Renderer, rect: ?*FRect) bool {
return c.SDL_GetRenderLogicalPresentationRect(renderer, rect);
}
pub inline fn renderCoordinatesFromWindow(renderer: *Renderer, window_x: f32, window_y: f32, x: *f32, y: *f32) bool {
return c.SDL_RenderCoordinatesFromWindow(renderer, window_x, window_y, @ptrCast(x), @ptrCast(y));
}
pub inline fn renderCoordinatesToWindow(renderer: *Renderer, x: f32, y: f32, window_x: *f32, window_y: *f32) bool {
return c.SDL_RenderCoordinatesToWindow(renderer, x, y, @ptrCast(window_x), @ptrCast(window_y));
}
pub inline fn convertEventToRenderCoordinates(renderer: *Renderer, event: ?*Event) bool {
return c.SDL_ConvertEventToRenderCoordinates(renderer, event);
}
pub inline fn setRenderViewport(renderer: *Renderer, rect: *const Rect) bool {
return c.SDL_SetRenderViewport(renderer, @ptrCast(rect));
}
pub inline fn getRenderViewport(renderer: *Renderer, rect: ?*Rect) bool {
return c.SDL_GetRenderViewport(renderer, rect);
}
pub inline fn renderViewportSet(renderer: *Renderer) bool {
return c.SDL_RenderViewportSet(renderer);
}
pub inline fn getRenderSafeArea(renderer: *Renderer, rect: ?*Rect) bool {
return c.SDL_GetRenderSafeArea(renderer, rect);
}
pub inline fn setRenderClipRect(renderer: *Renderer, rect: *const Rect) bool {
return c.SDL_SetRenderClipRect(renderer, @ptrCast(rect));
}
pub inline fn getRenderClipRect(renderer: *Renderer, rect: ?*Rect) bool {
return c.SDL_GetRenderClipRect(renderer, rect);
}
pub inline fn renderClipEnabled(renderer: *Renderer) bool {
return c.SDL_RenderClipEnabled(renderer);
}
pub inline fn setRenderScale(renderer: *Renderer, scaleX: f32, scaleY: f32) bool {
return c.SDL_SetRenderScale(renderer, scaleX, scaleY);
}
pub inline fn getRenderScale(renderer: *Renderer, scaleX: *f32, scaleY: *f32) bool {
return c.SDL_GetRenderScale(renderer, @ptrCast(scaleX), @ptrCast(scaleY));
}
pub inline fn setRenderDrawColor(renderer: *Renderer, r: u8, g: u8, b: u8, a: u8) bool {
return c.SDL_SetRenderDrawColor(renderer, r, g, b, a);
}
pub inline fn setRenderDrawColorFloat(renderer: *Renderer, r: f32, g: f32, b: f32, a: f32) bool {
return c.SDL_SetRenderDrawColorFloat(renderer, r, g, b, a);
}
pub inline fn getRenderDrawColor(renderer: *Renderer, r: [*c]u8, g: [*c]u8, b: [*c]u8, a: [*c]u8) bool {
return c.SDL_GetRenderDrawColor(renderer, r, g, b, a);
}
pub inline fn getRenderDrawColorFloat(renderer: *Renderer, r: *f32, g: *f32, b: *f32, a: *f32) bool {
return c.SDL_GetRenderDrawColorFloat(renderer, @ptrCast(r), @ptrCast(g), @ptrCast(b), @ptrCast(a));
}
pub inline fn setRenderColorScale(renderer: *Renderer, scale: f32) bool {
return c.SDL_SetRenderColorScale(renderer, scale);
}
pub inline fn getRenderColorScale(renderer: *Renderer, scale: *f32) bool {
return c.SDL_GetRenderColorScale(renderer, @ptrCast(scale));
}
pub inline fn setRenderDrawBlendMode(renderer: *Renderer, blendMode: BlendMode) bool {
return c.SDL_SetRenderDrawBlendMode(renderer, @intFromEnum(blendMode));
}
pub inline fn getRenderDrawBlendMode(renderer: *Renderer, blendMode: ?*BlendMode) bool {
return c.SDL_GetRenderDrawBlendMode(renderer, @intFromEnum(blendMode));
}
pub inline fn renderClear(renderer: *Renderer) bool {
return c.SDL_RenderClear(renderer);
}
pub inline fn renderPoint(renderer: *Renderer, x: f32, y: f32) bool {
return c.SDL_RenderPoint(renderer, x, y);
}
pub inline fn renderPoints(renderer: *Renderer, points: *const FPoint, count: c_int) bool {
return c.SDL_RenderPoints(renderer, @ptrCast(points), count);
}
pub inline fn renderLine(renderer: *Renderer, x1: f32, y1: f32, x2: f32, y2: f32) bool {
return c.SDL_RenderLine(renderer, x1, y1, x2, y2);
}
pub inline fn renderLines(renderer: *Renderer, points: *const FPoint, count: c_int) bool {
return c.SDL_RenderLines(renderer, @ptrCast(points), count);
}
pub inline fn renderRect(renderer: *Renderer, rect: *const FRect) bool {
return c.SDL_RenderRect(renderer, @ptrCast(rect));
}
pub inline fn renderRects(renderer: *Renderer, rects: *const FRect, count: c_int) bool {
return c.SDL_RenderRects(renderer, @ptrCast(rects), count);
}
pub inline fn renderFillRect(renderer: *Renderer, rect: *const FRect) bool {
return c.SDL_RenderFillRect(renderer, @ptrCast(rect));
}
pub inline fn renderFillRects(renderer: *Renderer, rects: *const FRect, count: c_int) bool {
return c.SDL_RenderFillRects(renderer, @ptrCast(rects), count);
}
pub inline fn renderTexture(renderer: *Renderer, texture: ?*Texture, srcrect: *const FRect, dstrect: *const FRect) bool {
return c.SDL_RenderTexture(renderer, texture, @ptrCast(srcrect), @ptrCast(dstrect));
}
pub inline fn renderTextureRotated(renderer: *Renderer, texture: ?*Texture, srcrect: *const FRect, dstrect: *const FRect, angle: f64, center: *const FPoint, flip: FlipMode) bool {
return c.SDL_RenderTextureRotated(renderer, texture, @ptrCast(srcrect), @ptrCast(dstrect), angle, @ptrCast(center), @intFromEnum(flip));
}
pub inline fn renderTextureAffine(renderer: *Renderer, texture: ?*Texture, srcrect: *const FRect, origin: *const FPoint, right: *const FPoint, down: *const FPoint) bool {
return c.SDL_RenderTextureAffine(renderer, texture, @ptrCast(srcrect), @ptrCast(origin), @ptrCast(right), @ptrCast(down));
}
pub inline fn renderTextureTiled(renderer: *Renderer, texture: ?*Texture, srcrect: *const FRect, scale: f32, dstrect: *const FRect) bool {
return c.SDL_RenderTextureTiled(renderer, texture, @ptrCast(srcrect), scale, @ptrCast(dstrect));
}
pub inline fn renderTexture9Grid(renderer: *Renderer, texture: ?*Texture, srcrect: *const FRect, left_width: f32, right_width: f32, top_height: f32, bottom_height: f32, scale: f32, dstrect: *const FRect) bool {
return c.SDL_RenderTexture9Grid(renderer, texture, @ptrCast(srcrect), left_width, right_width, top_height, bottom_height, scale, @ptrCast(dstrect));
}
pub inline fn renderGeometry(renderer: *Renderer, texture: ?*Texture, vertices: *const Vertex, num_vertices: c_int, indices: [*c]const c_int, num_indices: c_int) bool {
return c.SDL_RenderGeometry(renderer, texture, @ptrCast(vertices), num_vertices, indices, num_indices);
}
pub inline fn renderGeometryRaw(renderer: *Renderer, texture: ?*Texture, xy: *const f32, xy_stride: c_int, color: *const FColor, color_stride: c_int, uv: *const f32, uv_stride: c_int, num_vertices: c_int, indices: ?*const anyopaque, num_indices: c_int, size_indices: c_int) bool {
return c.SDL_RenderGeometryRaw(renderer, texture, @ptrCast(xy), xy_stride, @ptrCast(color), color_stride, @ptrCast(uv), uv_stride, num_vertices, indices, num_indices, size_indices);
}
pub inline fn renderReadPixels(renderer: *Renderer, rect: *const Rect) ?*Surface {
return c.SDL_RenderReadPixels(renderer, @ptrCast(rect));
}
pub inline fn renderPresent(renderer: *Renderer) bool {
return c.SDL_RenderPresent(renderer);
}
pub inline fn destroyRenderer(renderer: *Renderer) void {
return c.SDL_DestroyRenderer(renderer);
}
pub inline fn flushRenderer(renderer: *Renderer) bool {
return c.SDL_FlushRenderer(renderer);
}
pub inline fn getRenderMetalLayer(renderer: *Renderer) ?*anyopaque {
return c.SDL_GetRenderMetalLayer(renderer);
}
pub inline fn getRenderMetalCommandEncoder(renderer: *Renderer) ?*anyopaque {
return c.SDL_GetRenderMetalCommandEncoder(renderer);
}
pub inline fn addVulkanRenderSemaphores(renderer: *Renderer, wait_stage_mask: u32, wait_semaphore: i64, signal_semaphore: i64) bool {
return c.SDL_AddVulkanRenderSemaphores(renderer, wait_stage_mask, wait_semaphore, signal_semaphore);
}
pub inline fn setRenderVSync(renderer: *Renderer, vsync: c_int) bool {
return c.SDL_SetRenderVSync(renderer, vsync);
}
pub inline fn getRenderVSync(renderer: *Renderer, vsync: *c_int) bool {
return c.SDL_GetRenderVSync(renderer, @ptrCast(vsync));
}
pub inline fn renderDebugText(renderer: *Renderer, x: f32, y: f32, str: [*c]const u8) bool {
return c.SDL_RenderDebugText(renderer, x, y, str);
}
pub inline fn renderDebugTextFormat(renderer: *Renderer, x: f32, y: f32, fmt: [*c]const u8, ...) bool {
return c.SDL_RenderDebugTextFormat(
renderer,
x,
y,
fmt,
);
}
};
pub const Texture = opaque {
pub inline fn getTextureProperties(texture: *Texture) PropertiesID {
return c.SDL_GetTextureProperties(texture);
}
pub inline fn getRendererFromTexture(texture: *Texture) ?*Renderer {
return c.SDL_GetRendererFromTexture(texture);
}
pub inline fn getTextureSize(texture: *Texture, w: *f32, h: *f32) bool {
return c.SDL_GetTextureSize(texture, @ptrCast(w), @ptrCast(h));
}
pub inline fn setTextureColorMod(texture: *Texture, r: u8, g: u8, b: u8) bool {
return c.SDL_SetTextureColorMod(texture, r, g, b);
}
pub inline fn setTextureColorModFloat(texture: *Texture, r: f32, g: f32, b: f32) bool {
return c.SDL_SetTextureColorModFloat(texture, r, g, b);
}
pub inline fn getTextureColorMod(texture: *Texture, r: [*c]u8, g: [*c]u8, b: [*c]u8) bool {
return c.SDL_GetTextureColorMod(texture, r, g, b);
}
pub inline fn getTextureColorModFloat(texture: *Texture, r: *f32, g: *f32, b: *f32) bool {
return c.SDL_GetTextureColorModFloat(texture, @ptrCast(r), @ptrCast(g), @ptrCast(b));
}
pub inline fn setTextureAlphaMod(texture: *Texture, alpha: u8) bool {
return c.SDL_SetTextureAlphaMod(texture, alpha);
}
pub inline fn setTextureAlphaModFloat(texture: *Texture, alpha: f32) bool {
return c.SDL_SetTextureAlphaModFloat(texture, alpha);
}
pub inline fn getTextureAlphaMod(texture: *Texture, alpha: [*c]u8) bool {
return c.SDL_GetTextureAlphaMod(texture, alpha);
}
pub inline fn getTextureAlphaModFloat(texture: *Texture, alpha: *f32) bool {
return c.SDL_GetTextureAlphaModFloat(texture, @ptrCast(alpha));
}
pub inline fn setTextureBlendMode(texture: *Texture, blendMode: BlendMode) bool {
return c.SDL_SetTextureBlendMode(texture, @intFromEnum(blendMode));
}
pub inline fn getTextureBlendMode(texture: *Texture, blendMode: ?*BlendMode) bool {
return c.SDL_GetTextureBlendMode(texture, @intFromEnum(blendMode));
}
pub inline fn setTextureScaleMode(texture: *Texture, scaleMode: ScaleMode) bool {
return c.SDL_SetTextureScaleMode(texture, @intFromEnum(scaleMode));
}
pub inline fn getTextureScaleMode(texture: *Texture, scaleMode: ?*ScaleMode) bool {
return c.SDL_GetTextureScaleMode(texture, @intFromEnum(scaleMode));
}
pub inline fn updateTexture(texture: *Texture, rect: *const Rect, pixels: ?*const anyopaque, pitch: c_int) bool {
return c.SDL_UpdateTexture(texture, @ptrCast(rect), pixels, pitch);
}
pub inline fn updateYUVTexture(texture: *Texture, rect: *const Rect, Yplane: [*c]const u8, Ypitch: c_int, Uplane: [*c]const u8, Upitch: c_int, Vplane: [*c]const u8, Vpitch: c_int) bool {
return c.SDL_UpdateYUVTexture(texture, @ptrCast(rect), Yplane, Ypitch, Uplane, Upitch, Vplane, Vpitch);
}
pub inline fn updateNVTexture(texture: *Texture, rect: *const Rect, Yplane: [*c]const u8, Ypitch: c_int, UVplane: [*c]const u8, UVpitch: c_int) bool {
return c.SDL_UpdateNVTexture(texture, @ptrCast(rect), Yplane, Ypitch, UVplane, UVpitch);
}
pub inline fn lockTexture(texture: *Texture, rect: *const Rect, pixels: [*c]?*anyopaque, pitch: *c_int) bool {
return c.SDL_LockTexture(texture, @ptrCast(rect), pixels, @ptrCast(pitch));
}
pub inline fn lockTextureToSurface(texture: *Texture, rect: *const Rect, surface: [*c][*c]Surface) bool {
return c.SDL_LockTextureToSurface(texture, @ptrCast(rect), surface);
}
pub inline fn unlockTexture(texture: *Texture) void {
return c.SDL_UnlockTexture(texture);
}
pub inline fn destroyTexture(texture: *Texture) void {
return c.SDL_DestroyTexture(texture);
}
};
pub inline fn getNumRenderDrivers() c_int {
return c.SDL_GetNumRenderDrivers();
}
pub inline fn getRenderDriver(index: c_int) [*c]const u8 {
return c.SDL_GetRenderDriver(index);
}
pub inline fn createWindowAndRenderer(title: [*c]const u8, width: c_int, height: c_int, window_flags: WindowFlags, window: [*c][*c]Window, renderer: [*c][*c]Renderer) bool {
return c.SDL_CreateWindowAndRenderer(title, width, height, @bitCast(window_flags), window, renderer);
}
pub inline fn createRendererWithProperties(props: PropertiesID) ?*Renderer {
return c.SDL_CreateRendererWithProperties(props);
}

View File

@ -44,6 +44,7 @@ pub const SensorType = enum(c_int) {
sensorGyroL, //Gyroscope for left Joy-Con controller
sensorAccelR, //Accelerometer for right Joy-Con controller
sensorGyroR, //Gyroscope for right Joy-Con controller
sensorCount,
};
pub inline fn getSensors(count: *c_int) ?*SensorID {

View File

@ -1,103 +0,0 @@
const std = @import("std");
pub const c = @import("c.zig").c;
pub const PathInfo = extern struct {
_type: PathType, // the path type
size: u64, // the file size in bytes
create_time: Time, // the time when the path was created
modify_time: Time, // the last time the path was modified
access_time: Time, // the last time the path was read
};
pub const GlobFlags = packed struct(u32) {
globCaseinsensitive: bool = false,
pad0: u30 = 0,
rsvd: bool = false,
};
pub const PropertiesID = u32;
pub const StorageInterface = extern struct {
version: u32,
close: ?*const anyopaque,
ready: ?*const anyopaque,
enumerate: ?*const anyopaque,
info: ?*const anyopaque,
read_file: ?*const anyopaque,
write_file: ?*const anyopaque,
mkdir: ?*const anyopaque,
remove: ?*const anyopaque,
rename: ?*const anyopaque,
copy: ?*const anyopaque,
space_remaining: ?*const anyopaque,
};
pub const Storage = opaque {
pub inline fn closeStorage(storage: *Storage) bool {
return c.SDL_CloseStorage(storage);
}
pub inline fn storageReady(storage: *Storage) bool {
return c.SDL_StorageReady(storage);
}
pub inline fn getStorageFileSize(storage: *Storage, path: [*c]const u8, length: *u64) bool {
return c.SDL_GetStorageFileSize(storage, path, @ptrCast(length));
}
pub inline fn readStorageFile(storage: *Storage, path: [*c]const u8, destination: ?*anyopaque, length: u64) bool {
return c.SDL_ReadStorageFile(storage, path, destination, length);
}
pub inline fn writeStorageFile(storage: *Storage, path: [*c]const u8, source: ?*const anyopaque, length: u64) bool {
return c.SDL_WriteStorageFile(storage, path, source, length);
}
pub inline fn createStorageDirectory(storage: *Storage, path: [*c]const u8) bool {
return c.SDL_CreateStorageDirectory(storage, path);
}
pub inline fn enumerateStorageDirectory(storage: *Storage, path: [*c]const u8, callback: EnumerateDirectoryCallback, userdata: ?*anyopaque) bool {
return c.SDL_EnumerateStorageDirectory(storage, path, callback, userdata);
}
pub inline fn removeStoragePath(storage: *Storage, path: [*c]const u8) bool {
return c.SDL_RemoveStoragePath(storage, path);
}
pub inline fn renameStoragePath(storage: *Storage, oldpath: [*c]const u8, newpath: [*c]const u8) bool {
return c.SDL_RenameStoragePath(storage, oldpath, newpath);
}
pub inline fn copyStorageFile(storage: *Storage, oldpath: [*c]const u8, newpath: [*c]const u8) bool {
return c.SDL_CopyStorageFile(storage, oldpath, newpath);
}
pub inline fn getStoragePathInfo(storage: *Storage, path: [*c]const u8, info: ?*PathInfo) bool {
return c.SDL_GetStoragePathInfo(storage, path, info);
}
pub inline fn getStorageSpaceRemaining(storage: *Storage) u64 {
return c.SDL_GetStorageSpaceRemaining(storage);
}
pub inline fn globStorageDirectory(storage: *Storage, path: [*c]const u8, pattern: [*c]const u8, flags: GlobFlags, count: *c_int) [*c][*c]u8 {
return c.SDL_GlobStorageDirectory(storage, path, pattern, @bitCast(flags), @ptrCast(count));
}
};
pub inline fn openTitleStorage(override: [*c]const u8, props: PropertiesID) ?*Storage {
return c.SDL_OpenTitleStorage(override, props);
}
pub inline fn openUserStorage(org: [*c]const u8, app: [*c]const u8, props: PropertiesID) ?*Storage {
return c.SDL_OpenUserStorage(org, app, props);
}
pub inline fn openFileStorage(path: [*c]const u8) ?*Storage {
return c.SDL_OpenFileStorage(path);
}
pub inline fn openStorage(iface: *const StorageInterface, userdata: ?*anyopaque) ?*Storage {
return c.SDL_OpenStorage(@ptrCast(iface), userdata);
}

View File

@ -1,318 +0,0 @@
const std = @import("std");
pub const c = @import("c.zig").c;
pub const PixelFormat = enum(c_int) {
pixelformatYv12, //Planar mode: Y + V + U (3 planes)
pixelformatIyuv, //Planar mode: Y + U + V (3 planes)
pixelformatYuy2, //Packed mode: Y0+U0+Y1+V0 (1 plane)
pixelformatUyvy, //Packed mode: U0+Y0+V0+Y1 (1 plane)
pixelformatYvyu, //Packed mode: Y0+V0+Y1+U0 (1 plane)
pixelformatNv12, //Planar mode: Y + U/V interleaved (2 planes)
pixelformatNv21, //Planar mode: Y + V/U interleaved (2 planes)
pixelformatP010, //Planar mode: Y + U/V interleaved (2 planes)
pixelformatExternalOes, //Android video texture format
pixelformatMjpg, //Motion JPEG
};
pub const BlendMode = u32;
pub const IOStream = opaque {
pub inline fn loadBMP_IO(iostream: *IOStream, closeio: bool) ?*Surface {
return c.SDL_LoadBMP_IO(iostream, closeio);
}
};
pub const Rect = extern struct {
x: c_int,
y: c_int,
w: c_int,
h: c_int,
};
pub const Palette = extern struct {
ncolors: c_int, // number of elements in `colors`.
colors: ?*Color, // an array of colors, `ncolors` long.
version: u32, // internal use only, do not touch.
refcount: c_int, // internal use only, do not touch.
};
pub const Colorspace = enum(c_int) {
colorspaceSrgb, //Equivalent to DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709
colorRangeFull,
colorPrimariesBt709,
transferCharacteristicsSrgb,
matrixCoefficientsIdentity,
colorspaceSrgbLinear, //Equivalent to DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709
transferCharacteristicsLinear,
colorspaceHdr10, //Equivalent to DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020
colorPrimariesBt2020,
transferCharacteristicsPq,
colorspaceJpeg, //Equivalent to DXGI_COLOR_SPACE_YCBCR_FULL_G22_NONE_P709_X601
transferCharacteristicsBt601,
matrixCoefficientsBt601,
colorspaceBt601Limited, //Equivalent to DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P601
colorRangeLimited,
colorPrimariesBt601,
colorspaceBt601Full, //Equivalent to DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P601
colorspaceBt709Limited, //Equivalent to DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P709
transferCharacteristicsBt709,
matrixCoefficientsBt709,
colorspaceBt709Full, //Equivalent to DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P709
colorspaceBt2020Limited, //Equivalent to DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P2020
matrixCoefficientsBt2020Ncl,
colorspaceBt2020Full, //Equivalent to DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P2020
colorspaceRgbDefault, //The default colorspace for RGB surfaces if no colorspace is specified
colorspaceYuvDefault, //The default colorspace for YUV surfaces if no colorspace is specified
};
pub const PropertiesID = u32;
pub const SurfaceFlags = packed struct(u32) {
surfacePreallocated: bool = false, // Surface uses preallocated pixel memory
surfaceLockNeeded: bool = false, // Surface needs to be locked to access pixels
surfaceLocked: bool = false, // Surface is currently locked
surfaceSimdAligned: bool = false, // Surface uses pixel memory allocated with SDL_aligned_alloc()
pad0: u27 = 0,
rsvd: bool = false,
};
pub const ScaleMode = enum(c_int) {
scalemodeNearest, //nearest pixel sampling
scalemodeLinear, //linear filtering
};
pub const FlipMode = enum(c_int) {
flipNone, //Do not flip
flipHorizontal, //flip horizontally
flipVertical, //flip vertically
};
pub const Surface = opaque {
pub inline fn destroySurface(surface: *Surface) void {
return c.SDL_DestroySurface(surface);
}
pub inline fn getSurfaceProperties(surface: *Surface) PropertiesID {
return c.SDL_GetSurfaceProperties(surface);
}
pub inline fn setSurfaceColorspace(surface: *Surface, colorspace: Colorspace) bool {
return c.SDL_SetSurfaceColorspace(surface, colorspace);
}
pub inline fn getSurfaceColorspace(surface: *Surface) Colorspace {
return c.SDL_GetSurfaceColorspace(surface);
}
pub inline fn createSurfacePalette(surface: *Surface) ?*Palette {
return c.SDL_CreateSurfacePalette(surface);
}
pub inline fn setSurfacePalette(surface: *Surface, palette: ?*Palette) bool {
return c.SDL_SetSurfacePalette(surface, palette);
}
pub inline fn getSurfacePalette(surface: *Surface) ?*Palette {
return c.SDL_GetSurfacePalette(surface);
}
pub inline fn addSurfaceAlternateImage(surface: *Surface, image: ?*Surface) bool {
return c.SDL_AddSurfaceAlternateImage(surface, image);
}
pub inline fn surfaceHasAlternateImages(surface: *Surface) bool {
return c.SDL_SurfaceHasAlternateImages(surface);
}
pub inline fn getSurfaceImages(surface: *Surface, count: *c_int) [*c][*c]Surface {
return c.SDL_GetSurfaceImages(surface, @ptrCast(count));
}
pub inline fn removeSurfaceAlternateImages(surface: *Surface) void {
return c.SDL_RemoveSurfaceAlternateImages(surface);
}
pub inline fn lockSurface(surface: *Surface) bool {
return c.SDL_LockSurface(surface);
}
pub inline fn unlockSurface(surface: *Surface) void {
return c.SDL_UnlockSurface(surface);
}
pub inline fn saveBMP_IO(surface: *Surface, dst: ?*IOStream, closeio: bool) bool {
return c.SDL_SaveBMP_IO(surface, dst, closeio);
}
pub inline fn saveBMP(surface: *Surface, file: [*c]const u8) bool {
return c.SDL_SaveBMP(surface, file);
}
pub inline fn setSurfaceRLE(surface: *Surface, enabled: bool) bool {
return c.SDL_SetSurfaceRLE(surface, enabled);
}
pub inline fn surfaceHasRLE(surface: *Surface) bool {
return c.SDL_SurfaceHasRLE(surface);
}
pub inline fn setSurfaceColorKey(surface: *Surface, enabled: bool, key: u32) bool {
return c.SDL_SetSurfaceColorKey(surface, enabled, key);
}
pub inline fn surfaceHasColorKey(surface: *Surface) bool {
return c.SDL_SurfaceHasColorKey(surface);
}
pub inline fn getSurfaceColorKey(surface: *Surface, key: *u32) bool {
return c.SDL_GetSurfaceColorKey(surface, @ptrCast(key));
}
pub inline fn setSurfaceColorMod(surface: *Surface, r: u8, g: u8, b: u8) bool {
return c.SDL_SetSurfaceColorMod(surface, r, g, b);
}
pub inline fn getSurfaceColorMod(surface: *Surface, r: [*c]u8, g: [*c]u8, b: [*c]u8) bool {
return c.SDL_GetSurfaceColorMod(surface, r, g, b);
}
pub inline fn setSurfaceAlphaMod(surface: *Surface, alpha: u8) bool {
return c.SDL_SetSurfaceAlphaMod(surface, alpha);
}
pub inline fn getSurfaceAlphaMod(surface: *Surface, alpha: [*c]u8) bool {
return c.SDL_GetSurfaceAlphaMod(surface, alpha);
}
pub inline fn setSurfaceBlendMode(surface: *Surface, blendMode: BlendMode) bool {
return c.SDL_SetSurfaceBlendMode(surface, @intFromEnum(blendMode));
}
pub inline fn getSurfaceBlendMode(surface: *Surface, blendMode: ?*BlendMode) bool {
return c.SDL_GetSurfaceBlendMode(surface, @intFromEnum(blendMode));
}
pub inline fn setSurfaceClipRect(surface: *Surface, rect: *const Rect) bool {
return c.SDL_SetSurfaceClipRect(surface, @ptrCast(rect));
}
pub inline fn getSurfaceClipRect(surface: *Surface, rect: ?*Rect) bool {
return c.SDL_GetSurfaceClipRect(surface, rect);
}
pub inline fn flipSurface(surface: *Surface, flip: FlipMode) bool {
return c.SDL_FlipSurface(surface, @intFromEnum(flip));
}
pub inline fn duplicateSurface(surface: *Surface) ?*Surface {
return c.SDL_DuplicateSurface(surface);
}
pub inline fn scaleSurface(surface: *Surface, width: c_int, height: c_int, scaleMode: ScaleMode) ?*Surface {
return c.SDL_ScaleSurface(surface, width, height, @intFromEnum(scaleMode));
}
pub inline fn convertSurface(surface: *Surface, format: PixelFormat) ?*Surface {
return c.SDL_ConvertSurface(surface, @bitCast(format));
}
pub inline fn convertSurfaceAndColorspace(surface: *Surface, format: PixelFormat, palette: ?*Palette, colorspace: Colorspace, props: PropertiesID) ?*Surface {
return c.SDL_ConvertSurfaceAndColorspace(surface, @bitCast(format), palette, colorspace, props);
}
pub inline fn premultiplySurfaceAlpha(surface: *Surface, linear: bool) bool {
return c.SDL_PremultiplySurfaceAlpha(surface, linear);
}
pub inline fn clearSurface(surface: *Surface, r: f32, g: f32, b: f32, a: f32) bool {
return c.SDL_ClearSurface(surface, r, g, b, a);
}
pub inline fn fillSurfaceRect(surface: *Surface, rect: *const Rect, color: u32) bool {
return c.SDL_FillSurfaceRect(surface, @ptrCast(rect), color);
}
pub inline fn fillSurfaceRects(surface: *Surface, rects: *const Rect, count: c_int, color: u32) bool {
return c.SDL_FillSurfaceRects(surface, @ptrCast(rects), count, color);
}
pub inline fn blitSurface(surface: *Surface, srcrect: *const Rect, dst: ?*Surface, dstrect: *const Rect) bool {
return c.SDL_BlitSurface(surface, @ptrCast(srcrect), dst, @ptrCast(dstrect));
}
pub inline fn blitSurfaceUnchecked(surface: *Surface, srcrect: *const Rect, dst: ?*Surface, dstrect: *const Rect) bool {
return c.SDL_BlitSurfaceUnchecked(surface, @ptrCast(srcrect), dst, @ptrCast(dstrect));
}
pub inline fn blitSurfaceScaled(surface: *Surface, srcrect: *const Rect, dst: ?*Surface, dstrect: *const Rect, scaleMode: ScaleMode) bool {
return c.SDL_BlitSurfaceScaled(surface, @ptrCast(srcrect), dst, @ptrCast(dstrect), @intFromEnum(scaleMode));
}
pub inline fn blitSurfaceUncheckedScaled(surface: *Surface, srcrect: *const Rect, dst: ?*Surface, dstrect: *const Rect, scaleMode: ScaleMode) bool {
return c.SDL_BlitSurfaceUncheckedScaled(surface, @ptrCast(srcrect), dst, @ptrCast(dstrect), @intFromEnum(scaleMode));
}
pub inline fn stretchSurface(surface: *Surface, srcrect: *const Rect, dst: ?*Surface, dstrect: *const Rect, scaleMode: ScaleMode) bool {
return c.SDL_StretchSurface(surface, @ptrCast(srcrect), dst, @ptrCast(dstrect), @intFromEnum(scaleMode));
}
pub inline fn blitSurfaceTiled(surface: *Surface, srcrect: *const Rect, dst: ?*Surface, dstrect: *const Rect) bool {
return c.SDL_BlitSurfaceTiled(surface, @ptrCast(srcrect), dst, @ptrCast(dstrect));
}
pub inline fn blitSurfaceTiledWithScale(surface: *Surface, srcrect: *const Rect, scale: f32, scaleMode: ScaleMode, dst: ?*Surface, dstrect: *const Rect) bool {
return c.SDL_BlitSurfaceTiledWithScale(surface, @ptrCast(srcrect), scale, @intFromEnum(scaleMode), dst, @ptrCast(dstrect));
}
pub inline fn blitSurface9Grid(surface: *Surface, srcrect: *const Rect, left_width: c_int, right_width: c_int, top_height: c_int, bottom_height: c_int, scale: f32, scaleMode: ScaleMode, dst: ?*Surface, dstrect: *const Rect) bool {
return c.SDL_BlitSurface9Grid(surface, @ptrCast(srcrect), left_width, right_width, top_height, bottom_height, scale, @intFromEnum(scaleMode), dst, @ptrCast(dstrect));
}
pub inline fn mapSurfaceRGB(surface: *Surface, r: u8, g: u8, b: u8) u32 {
return c.SDL_MapSurfaceRGB(surface, r, g, b);
}
pub inline fn mapSurfaceRGBA(surface: *Surface, r: u8, g: u8, b: u8, a: u8) u32 {
return c.SDL_MapSurfaceRGBA(surface, r, g, b, a);
}
pub inline fn readSurfacePixel(surface: *Surface, x: c_int, y: c_int, r: [*c]u8, g: [*c]u8, b: [*c]u8, a: [*c]u8) bool {
return c.SDL_ReadSurfacePixel(surface, x, y, r, g, b, a);
}
pub inline fn readSurfacePixelFloat(surface: *Surface, x: c_int, y: c_int, r: *f32, g: *f32, b: *f32, a: *f32) bool {
return c.SDL_ReadSurfacePixelFloat(surface, x, y, @ptrCast(r), @ptrCast(g), @ptrCast(b), @ptrCast(a));
}
pub inline fn writeSurfacePixel(surface: *Surface, x: c_int, y: c_int, r: u8, g: u8, b: u8, a: u8) bool {
return c.SDL_WriteSurfacePixel(surface, x, y, r, g, b, a);
}
pub inline fn writeSurfacePixelFloat(surface: *Surface, x: c_int, y: c_int, r: f32, g: f32, b: f32, a: f32) bool {
return c.SDL_WriteSurfacePixelFloat(surface, x, y, r, g, b, a);
}
};
pub inline fn createSurface(width: c_int, height: c_int, format: PixelFormat) ?*Surface {
return c.SDL_CreateSurface(width, height, @bitCast(format));
}
pub inline fn createSurfaceFrom(width: c_int, height: c_int, format: PixelFormat, pixels: ?*anyopaque, pitch: c_int) ?*Surface {
return c.SDL_CreateSurfaceFrom(width, height, @bitCast(format), pixels, pitch);
}
pub inline fn loadBMP(file: [*c]const u8) ?*Surface {
return c.SDL_LoadBMP(file);
}
pub inline fn convertPixels(width: c_int, height: c_int, src_format: PixelFormat, src: ?*const anyopaque, src_pitch: c_int, dst_format: PixelFormat, dst: ?*anyopaque, dst_pitch: c_int) bool {
return c.SDL_ConvertPixels(width, height, @bitCast(src_format), src, src_pitch, @bitCast(dst_format), dst, dst_pitch);
}
pub inline fn convertPixelsAndColorspace(width: c_int, height: c_int, src_format: PixelFormat, src_colorspace: Colorspace, src_properties: PropertiesID, src: ?*const anyopaque, src_pitch: c_int, dst_format: PixelFormat, dst_colorspace: Colorspace, dst_properties: PropertiesID, dst: ?*anyopaque, dst_pitch: c_int) bool {
return c.SDL_ConvertPixelsAndColorspace(width, height, @bitCast(src_format), src_colorspace, src_properties, src, src_pitch, @bitCast(dst_format), dst_colorspace, dst_properties, dst, dst_pitch);
}
pub inline fn premultiplyAlpha(width: c_int, height: c_int, src_format: PixelFormat, src: ?*const anyopaque, src_pitch: c_int, dst_format: PixelFormat, dst: ?*anyopaque, dst_pitch: c_int, linear: bool) bool {
return c.SDL_PremultiplyAlpha(width, height, @bitCast(src_format), src, src_pitch, @bitCast(dst_format), dst, dst_pitch, linear);
}

View File

@ -1,159 +0,0 @@
const std = @import("std");
pub const c = @import("c.zig").c;
pub const DisplayID = u32;
pub const Window = opaque {
pub inline fn setiOSAnimationCallback(window: *Window, interval: c_int, callback: iOSAnimationCallback, callbackParam: ?*anyopaque) bool {
return c.SDL_SetiOSAnimationCallback(window, interval, callback, callbackParam);
}
};
pub const MSG = opaque {};
pub const WindowsMessageHook = *const fn (userdata: ?*anyopaque, msg: [*c]MSG) callconv(.C) bool;
pub inline fn setWindowsMessageHook(callback: WindowsMessageHook, userdata: ?*anyopaque) void {
return c.SDL_SetWindowsMessageHook(callback, userdata);
}
pub inline fn getDirect3D9AdapterIndex(displayID: DisplayID) c_int {
return c.SDL_GetDirect3D9AdapterIndex(displayID);
}
pub inline fn getDXGIOutputInfo(displayID: DisplayID, adapterIndex: *c_int, outputIndex: *c_int) bool {
return c.SDL_GetDXGIOutputInfo(displayID, @ptrCast(adapterIndex), @ptrCast(outputIndex));
}
pub const X11EventHook = *const fn (userdata: ?*anyopaque, xevent: [*c]XEvent) callconv(.C) bool;
pub inline fn setX11EventHook(callback: X11EventHook, userdata: ?*anyopaque) void {
return c.SDL_SetX11EventHook(callback, userdata);
}
pub inline fn setLinuxThreadPriority(threadID: i64, priority: c_int) bool {
return c.SDL_SetLinuxThreadPriority(threadID, priority);
}
pub inline fn setLinuxThreadPriorityAndPolicy(threadID: i64, sdlPriority: c_int, schedPolicy: c_int) bool {
return c.SDL_SetLinuxThreadPriorityAndPolicy(threadID, sdlPriority, schedPolicy);
}
pub const iOSAnimationCallback = *const fn (userdata: ?*anyopaque) callconv(.C) void;
pub inline fn setiOSEventPump(enabled: bool) void {
return c.SDL_SetiOSEventPump(enabled);
}
pub inline fn getAndroidJNIEnv() ?*anyopaque {
return c.SDL_GetAndroidJNIEnv();
}
pub inline fn getAndroidActivity() ?*anyopaque {
return c.SDL_GetAndroidActivity();
}
pub inline fn getAndroidSDKVersion() c_int {
return c.SDL_GetAndroidSDKVersion();
}
pub inline fn isChromebook() bool {
return c.SDL_IsChromebook();
}
pub inline fn isDeXMode() bool {
return c.SDL_IsDeXMode();
}
pub inline fn sendAndroidBackButton() void {
return c.SDL_SendAndroidBackButton();
}
pub inline fn getAndroidInternalStoragePath() [*c]const u8 {
return c.SDL_GetAndroidInternalStoragePath();
}
pub inline fn getAndroidExternalStorageState() u32 {
return c.SDL_GetAndroidExternalStorageState();
}
pub inline fn getAndroidExternalStoragePath() [*c]const u8 {
return c.SDL_GetAndroidExternalStoragePath();
}
pub inline fn getAndroidCachePath() [*c]const u8 {
return c.SDL_GetAndroidCachePath();
}
pub const RequestAndroidPermissionCallback = *const fn (userdata: ?*anyopaque, permission: [*c]const u8, granted: bool) callconv(.C) void;
pub inline fn requestAndroidPermission(permission: [*c]const u8, cb: RequestAndroidPermissionCallback, userdata: ?*anyopaque) bool {
return c.SDL_RequestAndroidPermission(permission, cb, userdata);
}
pub inline fn showAndroidToast(message: [*c]const u8, duration: c_int, gravity: c_int, xoffset: c_int, yoffset: c_int) bool {
return c.SDL_ShowAndroidToast(message, duration, gravity, xoffset, yoffset);
}
pub inline fn sendAndroidMessage(command: u32, param: c_int) bool {
return c.SDL_SendAndroidMessage(command, param);
}
pub inline fn isTablet() bool {
return c.SDL_IsTablet();
}
pub inline fn isTV() bool {
return c.SDL_IsTV();
}
pub const Sandbox = enum(c_int) {
sandboxUnknownContainer,
sandboxFlatpak,
sandboxSnap,
sandboxMacos,
};
pub inline fn getSandbox() Sandbox {
return c.SDL_GetSandbox();
}
pub inline fn onApplicationWillTerminate() void {
return c.SDL_OnApplicationWillTerminate();
}
pub inline fn onApplicationDidReceiveMemoryWarning() void {
return c.SDL_OnApplicationDidReceiveMemoryWarning();
}
pub inline fn onApplicationWillEnterBackground() void {
return c.SDL_OnApplicationWillEnterBackground();
}
pub inline fn onApplicationDidEnterBackground() void {
return c.SDL_OnApplicationDidEnterBackground();
}
pub inline fn onApplicationWillEnterForeground() void {
return c.SDL_OnApplicationWillEnterForeground();
}
pub inline fn onApplicationDidEnterForeground() void {
return c.SDL_OnApplicationDidEnterForeground();
}
pub inline fn onApplicationDidChangeStatusBarOrientation() void {
return c.SDL_OnApplicationDidChangeStatusBarOrientation();
}
pub const XTaskQueueHandle = *anyopaque;
pub const XUserHandle = *anyopaque;
pub inline fn getGDKTaskQueue(outTaskQueue: [*c]XTaskQueueHandle) bool {
return c.SDL_GetGDKTaskQueue(outTaskQueue);
}
pub inline fn getGDKDefaultUser(outUserHandle: [*c]XUserHandle) bool {
return c.SDL_GetGDKDefaultUser(outUserHandle);
}

View File

@ -1,607 +0,0 @@
const std = @import("std");
pub const c = @import("c.zig").c;
pub const PixelFormat = enum(c_int) {
pixelformatYv12, //Planar mode: Y + V + U (3 planes)
pixelformatIyuv, //Planar mode: Y + U + V (3 planes)
pixelformatYuy2, //Packed mode: Y0+U0+Y1+V0 (1 plane)
pixelformatUyvy, //Packed mode: U0+Y0+V0+Y1 (1 plane)
pixelformatYvyu, //Packed mode: Y0+V0+Y1+U0 (1 plane)
pixelformatNv12, //Planar mode: Y + U/V interleaved (2 planes)
pixelformatNv21, //Planar mode: Y + V/U interleaved (2 planes)
pixelformatP010, //Planar mode: Y + U/V interleaved (2 planes)
pixelformatExternalOes, //Android video texture format
pixelformatMjpg, //Motion JPEG
};
pub const Point = extern struct {
x: c_int,
y: c_int,
};
pub const Surface = opaque {};
pub const PropertiesID = u32;
pub const Rect = extern struct {
x: c_int,
y: c_int,
w: c_int,
h: c_int,
};
pub const FunctionPointer = ?*anyopaque;
pub const DisplayID = u32;
pub const WindowID = u32;
pub const SystemTheme = enum(c_int) {
systemThemeUnknown, //Unknown system theme
systemThemeLight, //Light colored system theme
systemThemeDark, //Dark colored system theme
};
pub const DisplayModeData = opaque {};
pub const DisplayMode = extern struct {
displayID: DisplayID, // the display this mode is associated with
format: PixelFormat, // pixel format
w: c_int, // width
h: c_int, // height
pixel_density: f32, // scale converting size to pixels (e.g. a 1920x1080 mode with 2.0 scale would have 3840x2160 pixels)
refresh_rate: f32, // refresh rate (or 0.0f for unspecified)
refresh_rate_numerator: c_int, // precise refresh rate numerator (or 0 for unspecified)
refresh_rate_denominator: c_int, // precise refresh rate denominator
internal: ?*DisplayModeData, // Private
};
pub const DisplayOrientation = enum(c_int) {
orientationUnknown, //The display orientation can't be determined
orientationLandscape, //The display is in landscape mode, with the right side up, relative to portrait mode
orientationLandscapeFlipped, //The display is in landscape mode, with the left side up, relative to portrait mode
orientationPortrait, //The display is in portrait mode
orientationPortraitFlipped,
};
pub const Window = opaque {
pub inline fn getDisplayForWindow(window: *Window) DisplayID {
return c.SDL_GetDisplayForWindow(window);
}
pub inline fn getWindowPixelDensity(window: *Window) f32 {
return c.SDL_GetWindowPixelDensity(window);
}
pub inline fn getWindowDisplayScale(window: *Window) f32 {
return c.SDL_GetWindowDisplayScale(window);
}
pub inline fn setWindowFullscreenMode(window: *Window, mode: *const DisplayMode) bool {
return c.SDL_SetWindowFullscreenMode(window, @ptrCast(mode));
}
pub inline fn getWindowFullscreenMode(window: *Window) *const DisplayMode {
return @ptrCast(c.SDL_GetWindowFullscreenMode(window));
}
pub inline fn getWindowICCProfile(window: *Window, size: *usize) ?*anyopaque {
return c.SDL_GetWindowICCProfile(window, @ptrCast(size));
}
pub inline fn getWindowPixelFormat(window: *Window) PixelFormat {
return @bitCast(c.SDL_GetWindowPixelFormat(window));
}
pub inline fn createPopupWindow(window: *Window, offset_x: c_int, offset_y: c_int, w: c_int, h: c_int, flags: WindowFlags) ?*Window {
return c.SDL_CreatePopupWindow(window, offset_x, offset_y, w, h, @bitCast(flags));
}
pub inline fn getWindowID(window: *Window) WindowID {
return c.SDL_GetWindowID(window);
}
pub inline fn getWindowParent(window: *Window) ?*Window {
return c.SDL_GetWindowParent(window);
}
pub inline fn getWindowProperties(window: *Window) PropertiesID {
return c.SDL_GetWindowProperties(window);
}
pub inline fn getWindowFlags(window: *Window) WindowFlags {
return @bitCast(c.SDL_GetWindowFlags(window));
}
pub inline fn setWindowTitle(window: *Window, title: [*c]const u8) bool {
return c.SDL_SetWindowTitle(window, title);
}
pub inline fn getWindowTitle(window: *Window) [*c]const u8 {
return c.SDL_GetWindowTitle(window);
}
pub inline fn setWindowIcon(window: *Window, icon: ?*Surface) bool {
return c.SDL_SetWindowIcon(window, icon);
}
pub inline fn setWindowPosition(window: *Window, x: c_int, y: c_int) bool {
return c.SDL_SetWindowPosition(window, x, y);
}
pub inline fn getWindowPosition(window: *Window, x: *c_int, y: *c_int) bool {
return c.SDL_GetWindowPosition(window, @ptrCast(x), @ptrCast(y));
}
pub inline fn setWindowSize(window: *Window, w: c_int, h: c_int) bool {
return c.SDL_SetWindowSize(window, w, h);
}
pub inline fn getWindowSize(window: *Window, w: *c_int, h: *c_int) bool {
return c.SDL_GetWindowSize(window, @ptrCast(w), @ptrCast(h));
}
pub inline fn getWindowSafeArea(window: *Window, rect: ?*Rect) bool {
return c.SDL_GetWindowSafeArea(window, rect);
}
pub inline fn setWindowAspectRatio(window: *Window, min_aspect: f32, max_aspect: f32) bool {
return c.SDL_SetWindowAspectRatio(window, min_aspect, max_aspect);
}
pub inline fn getWindowAspectRatio(window: *Window, min_aspect: *f32, max_aspect: *f32) bool {
return c.SDL_GetWindowAspectRatio(window, @ptrCast(min_aspect), @ptrCast(max_aspect));
}
pub inline fn getWindowBordersSize(window: *Window, top: *c_int, left: *c_int, bottom: *c_int, right: *c_int) bool {
return c.SDL_GetWindowBordersSize(window, @ptrCast(top), @ptrCast(left), @ptrCast(bottom), @ptrCast(right));
}
pub inline fn getWindowSizeInPixels(window: *Window, w: *c_int, h: *c_int) bool {
return c.SDL_GetWindowSizeInPixels(window, @ptrCast(w), @ptrCast(h));
}
pub inline fn setWindowMinimumSize(window: *Window, min_w: c_int, min_h: c_int) bool {
return c.SDL_SetWindowMinimumSize(window, min_w, min_h);
}
pub inline fn getWindowMinimumSize(window: *Window, w: *c_int, h: *c_int) bool {
return c.SDL_GetWindowMinimumSize(window, @ptrCast(w), @ptrCast(h));
}
pub inline fn setWindowMaximumSize(window: *Window, max_w: c_int, max_h: c_int) bool {
return c.SDL_SetWindowMaximumSize(window, max_w, max_h);
}
pub inline fn getWindowMaximumSize(window: *Window, w: *c_int, h: *c_int) bool {
return c.SDL_GetWindowMaximumSize(window, @ptrCast(w), @ptrCast(h));
}
pub inline fn setWindowBordered(window: *Window, bordered: bool) bool {
return c.SDL_SetWindowBordered(window, bordered);
}
pub inline fn setWindowResizable(window: *Window, resizable: bool) bool {
return c.SDL_SetWindowResizable(window, resizable);
}
pub inline fn setWindowAlwaysOnTop(window: *Window, on_top: bool) bool {
return c.SDL_SetWindowAlwaysOnTop(window, on_top);
}
pub inline fn showWindow(window: *Window) bool {
return c.SDL_ShowWindow(window);
}
pub inline fn hideWindow(window: *Window) bool {
return c.SDL_HideWindow(window);
}
pub inline fn raiseWindow(window: *Window) bool {
return c.SDL_RaiseWindow(window);
}
pub inline fn maximizeWindow(window: *Window) bool {
return c.SDL_MaximizeWindow(window);
}
pub inline fn minimizeWindow(window: *Window) bool {
return c.SDL_MinimizeWindow(window);
}
pub inline fn restoreWindow(window: *Window) bool {
return c.SDL_RestoreWindow(window);
}
pub inline fn setWindowFullscreen(window: *Window, fullscreen: bool) bool {
return c.SDL_SetWindowFullscreen(window, fullscreen);
}
pub inline fn syncWindow(window: *Window) bool {
return c.SDL_SyncWindow(window);
}
pub inline fn windowHasSurface(window: *Window) bool {
return c.SDL_WindowHasSurface(window);
}
pub inline fn getWindowSurface(window: *Window) ?*Surface {
return c.SDL_GetWindowSurface(window);
}
pub inline fn setWindowSurfaceVSync(window: *Window, vsync: c_int) bool {
return c.SDL_SetWindowSurfaceVSync(window, vsync);
}
pub inline fn getWindowSurfaceVSync(window: *Window, vsync: *c_int) bool {
return c.SDL_GetWindowSurfaceVSync(window, @ptrCast(vsync));
}
pub inline fn updateWindowSurface(window: *Window) bool {
return c.SDL_UpdateWindowSurface(window);
}
pub inline fn updateWindowSurfaceRects(window: *Window, rects: *const Rect, numrects: c_int) bool {
return c.SDL_UpdateWindowSurfaceRects(window, @ptrCast(rects), numrects);
}
pub inline fn destroyWindowSurface(window: *Window) bool {
return c.SDL_DestroyWindowSurface(window);
}
pub inline fn setWindowKeyboardGrab(window: *Window, grabbed: bool) bool {
return c.SDL_SetWindowKeyboardGrab(window, grabbed);
}
pub inline fn setWindowMouseGrab(window: *Window, grabbed: bool) bool {
return c.SDL_SetWindowMouseGrab(window, grabbed);
}
pub inline fn getWindowKeyboardGrab(window: *Window) bool {
return c.SDL_GetWindowKeyboardGrab(window);
}
pub inline fn getWindowMouseGrab(window: *Window) bool {
return c.SDL_GetWindowMouseGrab(window);
}
pub inline fn setWindowMouseRect(window: *Window, rect: *const Rect) bool {
return c.SDL_SetWindowMouseRect(window, @ptrCast(rect));
}
pub inline fn getWindowMouseRect(window: *Window) *const Rect {
return @ptrCast(c.SDL_GetWindowMouseRect(window));
}
pub inline fn setWindowOpacity(window: *Window, opacity: f32) bool {
return c.SDL_SetWindowOpacity(window, opacity);
}
pub inline fn getWindowOpacity(window: *Window) f32 {
return c.SDL_GetWindowOpacity(window);
}
pub inline fn setWindowParent(window: *Window, parent: ?*Window) bool {
return c.SDL_SetWindowParent(window, parent);
}
pub inline fn setWindowModal(window: *Window, modal: bool) bool {
return c.SDL_SetWindowModal(window, modal);
}
pub inline fn setWindowFocusable(window: *Window, focusable: bool) bool {
return c.SDL_SetWindowFocusable(window, focusable);
}
pub inline fn showWindowSystemMenu(window: *Window, x: c_int, y: c_int) bool {
return c.SDL_ShowWindowSystemMenu(window, x, y);
}
pub inline fn setWindowHitTest(window: *Window, callback: HitTest, callback_data: ?*anyopaque) bool {
return c.SDL_SetWindowHitTest(window, callback, callback_data);
}
pub inline fn setWindowShape(window: *Window, shape: ?*Surface) bool {
return c.SDL_SetWindowShape(window, shape);
}
pub inline fn flashWindow(window: *Window, operation: FlashOperation) bool {
return c.SDL_FlashWindow(window, @intFromEnum(operation));
}
pub inline fn destroyWindow(window: *Window) void {
return c.SDL_DestroyWindow(window);
}
pub inline fn gl_CreateContext(window: *Window) GLContext {
return c.SDL_GL_CreateContext(window);
}
pub inline fn gl_MakeCurrent(window: *Window, context: GLContext) bool {
return c.SDL_GL_MakeCurrent(window, context);
}
pub inline fn egl_GetWindowSurface(window: *Window) EGLSurface {
return c.SDL_EGL_GetWindowSurface(window);
}
pub inline fn gl_SwapWindow(window: *Window) bool {
return c.SDL_GL_SwapWindow(window);
}
};
pub const WindowFlags = packed struct(u64) {
windowFullscreen: bool = false, // window is in fullscreen mode
windowOpengl: bool = false, // window usable with OpenGL context
windowOccluded: bool = false, // window is occluded
windowHidden: bool = false, // window is neither mapped onto the desktop nor shown in the taskbar/dock/window list; SDL_ShowWindow() is required for it to become visible
windowBorderless: bool = false, // no window decoration
windowResizable: bool = false, // window can be resized
windowMinimized: bool = false, // window is minimized
windowMaximized: bool = false, // window is maximized
windowMouseGrabbed: bool = false, // window has grabbed mouse input
windowInputFocus: bool = false, // window has input focus
windowMouseFocus: bool = false, // window has mouse focus
windowExternal: bool = false, // window not created by SDL
windowModal: bool = false, // window is modal
windowHighPixelDensity: bool = false, // window uses high pixel density back buffer if possible
windowMouseCapture: bool = false, // window has mouse captured (unrelated to MOUSE_GRABBED)
windowMouseRelativeMode: bool = false, // window has relative mode enabled
windowAlwaysOnTop: bool = false, // window should always be above others
windowUtility: bool = false, // window should be treated as a utility window, not showing in the task bar and window list
windowTooltip: bool = false, // window should be treated as a tooltip and does not get mouse or keyboard focus, requires a parent window
windowPopupMenu: bool = false, // window should be treated as a popup menu, requires a parent window
windowKeyboardGrabbed: bool = false, // window has grabbed keyboard input
windowVulkan: bool = false, // window usable for Vulkan surface
windowMetal: bool = false, // window usable for Metal view
windowTransparent: bool = false, // window with transparent buffer
windowNotFocusable: bool = false, // window should not be focusable
pad0: u38 = 0,
rsvd: bool = false,
};
pub const FlashOperation = enum(c_int) {
flashCancel, //Cancel any window flash state
flashBriefly, //Flash the window briefly to get attention
flashUntilFocused, //Flash the window until it gets focus
};
pub const GLContext = *anyopaque;
pub const EGLDisplay = ?*anyopaque;
pub const EGLConfig = ?*anyopaque;
pub const EGLSurface = ?*anyopaque;
pub const EGLAttrib = intptr_t;
pub const EGLint = c_int;
pub const EGLAttribArrayCallback = *const fn (userdata: ?*anyopaque) callconv(.C) ?*EGLAttrib;
pub const EGLIntArrayCallback = *const fn (userdata: ?*anyopaque, display: EGLDisplay, config: EGLConfig) callconv(.C) ?*EGLint;
pub const GLAttr = enum(c_int) {
glRedSize, //the minimum number of bits for the red channel of the color buffer; defaults to 3.
glGreenSize, //the minimum number of bits for the green channel of the color buffer; defaults to 3.
glBlueSize, //the minimum number of bits for the blue channel of the color buffer; defaults to 2.
glAlphaSize, //the minimum number of bits for the alpha channel of the color buffer; defaults to 0.
glBufferSize, //the minimum number of bits for frame buffer size; defaults to 0.
glDoublebuffer, //whether the output is single or double buffered; defaults to double buffering on.
glDepthSize, //the minimum number of bits in the depth buffer; defaults to 16.
glStencilSize, //the minimum number of bits in the stencil buffer; defaults to 0.
glAccumRedSize, //the minimum number of bits for the red channel of the accumulation buffer; defaults to 0.
glAccumGreenSize, //the minimum number of bits for the green channel of the accumulation buffer; defaults to 0.
glAccumBlueSize, //the minimum number of bits for the blue channel of the accumulation buffer; defaults to 0.
glAccumAlphaSize, //the minimum number of bits for the alpha channel of the accumulation buffer; defaults to 0.
glStereo, //whether the output is stereo 3D; defaults to off.
glMultisamplebuffers, //the number of buffers used for multisample anti-aliasing; defaults to 0.
glMultisamplesamples, //the number of samples used around the current pixel used for multisample anti-aliasing.
glAcceleratedVisual, //set to 1 to require hardware acceleration, set to 0 to force software rendering; defaults to allow either.
glRetainedBacking, //not used (deprecated).
glContextMajorVersion, //OpenGL context major version.
glContextMinorVersion, //OpenGL context minor version.
glContextFlags, //some combination of 0 or more of elements of the SDL_GLContextFlag enumeration; defaults to 0.
glContextProfileMask, //type of GL context (Core, Compatibility, ES). See SDL_GLProfile; default value depends on platform.
glShareWithCurrentContext, //OpenGL context sharing; defaults to 0.
glFramebufferSrgbCapable, //requests sRGB capable visual; defaults to 0.
glContextReleaseBehavior, //sets context the release behavior. See SDL_GLContextReleaseFlag; defaults to FLUSH.
glContextResetNotification, //set context reset notification. See SDL_GLContextResetNotification; defaults to NO_NOTIFICATION.
glContextNoError,
glFloatbuffers,
glEglPlatform,
};
pub const GLProfile = u32;
pub const GLContextFlag = u32;
pub const GLContextReleaseFlag = u32;
pub const GLContextResetNotification = u32;
pub inline fn getNumVideoDrivers() c_int {
return c.SDL_GetNumVideoDrivers();
}
pub inline fn getVideoDriver(index: c_int) [*c]const u8 {
return c.SDL_GetVideoDriver(index);
}
pub inline fn getCurrentVideoDriver() [*c]const u8 {
return c.SDL_GetCurrentVideoDriver();
}
pub inline fn getSystemTheme() SystemTheme {
return c.SDL_GetSystemTheme();
}
pub inline fn getDisplays(count: *c_int) ?*DisplayID {
return c.SDL_GetDisplays(@ptrCast(count));
}
pub inline fn getPrimaryDisplay() DisplayID {
return c.SDL_GetPrimaryDisplay();
}
pub inline fn getDisplayProperties(displayID: DisplayID) PropertiesID {
return c.SDL_GetDisplayProperties(displayID);
}
pub inline fn getDisplayName(displayID: DisplayID) [*c]const u8 {
return c.SDL_GetDisplayName(displayID);
}
pub inline fn getDisplayBounds(displayID: DisplayID, rect: ?*Rect) bool {
return c.SDL_GetDisplayBounds(displayID, rect);
}
pub inline fn getDisplayUsableBounds(displayID: DisplayID, rect: ?*Rect) bool {
return c.SDL_GetDisplayUsableBounds(displayID, rect);
}
pub inline fn getNaturalDisplayOrientation(displayID: DisplayID) DisplayOrientation {
return c.SDL_GetNaturalDisplayOrientation(displayID);
}
pub inline fn getCurrentDisplayOrientation(displayID: DisplayID) DisplayOrientation {
return c.SDL_GetCurrentDisplayOrientation(displayID);
}
pub inline fn getDisplayContentScale(displayID: DisplayID) f32 {
return c.SDL_GetDisplayContentScale(displayID);
}
pub inline fn getFullscreenDisplayModes(displayID: DisplayID, count: *c_int) [*c][*c]DisplayMode {
return @intFromEnum(c.SDL_GetFullscreenDisplayModes(displayID, @ptrCast(count)));
}
pub inline fn getClosestFullscreenDisplayMode(displayID: DisplayID, w: c_int, h: c_int, refresh_rate: f32, include_high_density_modes: bool, closest: ?*DisplayMode) bool {
return c.SDL_GetClosestFullscreenDisplayMode(displayID, w, h, refresh_rate, include_high_density_modes, @intFromEnum(closest));
}
pub inline fn getDesktopDisplayMode(displayID: DisplayID) *const DisplayMode {
return @ptrCast(c.SDL_GetDesktopDisplayMode(displayID));
}
pub inline fn getCurrentDisplayMode(displayID: DisplayID) *const DisplayMode {
return @ptrCast(c.SDL_GetCurrentDisplayMode(displayID));
}
pub inline fn getDisplayForPoint(point: *const Point) DisplayID {
return c.SDL_GetDisplayForPoint(@ptrCast(point));
}
pub inline fn getDisplayForRect(rect: *const Rect) DisplayID {
return c.SDL_GetDisplayForRect(@ptrCast(rect));
}
pub inline fn getWindows(count: *c_int) [*c][*c]Window {
return c.SDL_GetWindows(@ptrCast(count));
}
pub inline fn createWindow(title: [*c]const u8, w: c_int, h: c_int, flags: WindowFlags) ?*Window {
return c.SDL_CreateWindow(title, w, h, @bitCast(flags));
}
pub inline fn createWindowWithProperties(props: PropertiesID) ?*Window {
return c.SDL_CreateWindowWithProperties(props);
}
pub inline fn getWindowFromID(id: WindowID) ?*Window {
return c.SDL_GetWindowFromID(id);
}
pub inline fn getGrabbedWindow() ?*Window {
return c.SDL_GetGrabbedWindow();
}
pub const HitTestResult = enum(c_int) {
hittestNormal, //Region is normal. No special properties.
hittestDraggable, //Region can drag entire window.
hittestResizeTopleft, //Region is the resizable top-left corner border.
hittestResizeTop, //Region is the resizable top border.
hittestResizeTopright, //Region is the resizable top-right corner border.
hittestResizeRight, //Region is the resizable right border.
hittestResizeBottomright, //Region is the resizable bottom-right corner border.
hittestResizeBottom, //Region is the resizable bottom border.
hittestResizeBottomleft, //Region is the resizable bottom-left corner border.
hittestResizeLeft, //Region is the resizable left border.
};
pub inline fn screenSaverEnabled() bool {
return c.SDL_ScreenSaverEnabled();
}
pub inline fn enableScreenSaver() bool {
return c.SDL_EnableScreenSaver();
}
pub inline fn disableScreenSaver() bool {
return c.SDL_DisableScreenSaver();
}
pub inline fn gl_LoadLibrary(path: [*c]const u8) bool {
return c.SDL_GL_LoadLibrary(path);
}
pub inline fn gl_GetProcAddress(proc: [*c]const u8) FunctionPointer {
return c.SDL_GL_GetProcAddress(proc);
}
pub inline fn egl_GetProcAddress(proc: [*c]const u8) FunctionPointer {
return c.SDL_EGL_GetProcAddress(proc);
}
pub inline fn gl_UnloadLibrary() void {
return c.SDL_GL_UnloadLibrary();
}
pub inline fn gl_ExtensionSupported(extension: [*c]const u8) bool {
return c.SDL_GL_ExtensionSupported(extension);
}
pub inline fn gl_ResetAttributes() void {
return c.SDL_GL_ResetAttributes();
}
pub inline fn gl_SetAttribute(attr: GLAttr, value: c_int) bool {
return c.SDL_GL_SetAttribute(attr, value);
}
pub inline fn gl_GetAttribute(attr: GLAttr, value: *c_int) bool {
return c.SDL_GL_GetAttribute(attr, @ptrCast(value));
}
pub inline fn gl_GetCurrentWindow() ?*Window {
return c.SDL_GL_GetCurrentWindow();
}
pub inline fn gl_GetCurrentContext() GLContext {
return c.SDL_GL_GetCurrentContext();
}
pub inline fn egl_GetCurrentDisplay() EGLDisplay {
return c.SDL_EGL_GetCurrentDisplay();
}
pub inline fn egl_GetCurrentConfig() EGLConfig {
return c.SDL_EGL_GetCurrentConfig();
}
pub inline fn egl_SetAttributeCallbacks(platformAttribCallback: EGLAttribArrayCallback, surfaceAttribCallback: EGLIntArrayCallback, contextAttribCallback: EGLIntArrayCallback, userdata: ?*anyopaque) void {
return c.SDL_EGL_SetAttributeCallbacks(platformAttribCallback, surfaceAttribCallback, contextAttribCallback, userdata);
}
pub inline fn gl_SetSwapInterval(interval: c_int) bool {
return c.SDL_GL_SetSwapInterval(interval);
}
pub inline fn gl_GetSwapInterval(interval: *c_int) bool {
return c.SDL_GL_GetSwapInterval(@ptrCast(interval));
}
pub inline fn gl_DestroyContext(context: GLContext) bool {
return c.SDL_GL_DestroyContext(context);
}