saving
This commit is contained in:
parent
7c47116ff0
commit
942e577775
|
|
@ -112,7 +112,7 @@ pub fn generateApi(b: *std.Build, parser_exe: *std.Build.Step.Compile, fetch_sdl
|
||||||
.{ .header = "SDL_dialog.h", .output = "dialog" },
|
.{ .header = "SDL_dialog.h", .output = "dialog" },
|
||||||
.{ .header = "SDL_endian.h", .output = "endian" },
|
.{ .header = "SDL_endian.h", .output = "endian" },
|
||||||
.{ .header = "SDL_error.h", .output = "error" },
|
.{ .header = "SDL_error.h", .output = "error" },
|
||||||
// .{ .header = "SDL_events.h", .output = "events" },
|
.{ .header = "SDL_events.h", .output = "events" },
|
||||||
.{ .header = "SDL_filesystem.h", .output = "filesystem" },
|
.{ .header = "SDL_filesystem.h", .output = "filesystem" },
|
||||||
.{ .header = "SDL_gamepad.h", .output = "gamepad" },
|
.{ .header = "SDL_gamepad.h", .output = "gamepad" },
|
||||||
.{ .header = "SDL_gpu.h", .output = "gpu" },
|
.{ .header = "SDL_gpu.h", .output = "gpu" },
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,442 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const Allocator = std.mem.Allocator;
|
||||||
|
const patterns = @import("patterns.zig");
|
||||||
|
const Declaration = patterns.Declaration;
|
||||||
|
|
||||||
|
pub const HeaderCache = struct {
|
||||||
|
// Map from type name to its declaration
|
||||||
|
type_cache: std.StringHashMap(Declaration),
|
||||||
|
// Track which headers we've already parsed (avoid re-parsing)
|
||||||
|
parsed_headers: std.StringHashMap(void),
|
||||||
|
allocator: Allocator,
|
||||||
|
|
||||||
|
pub fn init(allocator: Allocator) HeaderCache {
|
||||||
|
return .{
|
||||||
|
.type_cache = std.StringHashMap(Declaration).init(allocator),
|
||||||
|
.parsed_headers = std.StringHashMap(void).init(allocator),
|
||||||
|
.allocator = allocator,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(self: *HeaderCache) void {
|
||||||
|
// Free type cache keys
|
||||||
|
var type_it = self.type_cache.keyIterator();
|
||||||
|
while (type_it.next()) |key| {
|
||||||
|
self.allocator.free(key.*);
|
||||||
|
}
|
||||||
|
// Free cached declarations
|
||||||
|
var val_it = self.type_cache.valueIterator();
|
||||||
|
while (val_it.next()) |decl| {
|
||||||
|
freeDeclaration(self.allocator, decl.*);
|
||||||
|
}
|
||||||
|
self.type_cache.deinit();
|
||||||
|
|
||||||
|
// Free parsed headers keys
|
||||||
|
var header_it = self.parsed_headers.keyIterator();
|
||||||
|
while (header_it.next()) |key| {
|
||||||
|
self.allocator.free(key.*);
|
||||||
|
}
|
||||||
|
self.parsed_headers.deinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn buildCache(allocator: Allocator, header_path: []const u8) !HeaderCache {
|
||||||
|
var cache = HeaderCache.init(allocator);
|
||||||
|
errdefer cache.deinit();
|
||||||
|
|
||||||
|
const header_dir = std.fs.path.dirname(header_path) orelse ".";
|
||||||
|
try cache.parseHeaderRecursive(header_dir, std.fs.path.basename(header_path));
|
||||||
|
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parseHeaderRecursive(self: *HeaderCache, header_dir: []const u8, filename: []const u8) !void {
|
||||||
|
// Skip non-SDL headers (stdlib, system headers, etc)
|
||||||
|
if (!std.mem.startsWith(u8, filename, "SDL_")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip if already parsed
|
||||||
|
if (self.parsed_headers.contains(filename)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark as parsed
|
||||||
|
try self.parsed_headers.put(try self.allocator.dupe(u8, filename), {});
|
||||||
|
|
||||||
|
// Build full path
|
||||||
|
const full_path = try std.fs.path.join(self.allocator, &[_][]const u8{ header_dir, filename });
|
||||||
|
defer self.allocator.free(full_path);
|
||||||
|
|
||||||
|
std.debug.print(" Caching types from: {s}\n", .{filename});
|
||||||
|
|
||||||
|
// Read and parse this header
|
||||||
|
const content = std.fs.cwd().readFileAlloc(self.allocator, full_path, 10_000_000) catch |err| {
|
||||||
|
std.debug.print(" Warning: Could not read {s}: {}\n", .{ filename, err });
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
defer self.allocator.free(content);
|
||||||
|
|
||||||
|
var scanner = patterns.Scanner.init(self.allocator, content);
|
||||||
|
const decls = scanner.scan() catch |err| {
|
||||||
|
std.debug.print(" Warning: Could not parse {s}: {}\n", .{ filename, err });
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
defer self.allocator.free(decls);
|
||||||
|
|
||||||
|
// Add all type definitions to cache
|
||||||
|
for (decls) |decl| {
|
||||||
|
const type_name = getTypeName(decl);
|
||||||
|
if (type_name) |name| {
|
||||||
|
// Don't cache if already present (first occurrence wins)
|
||||||
|
if (!self.type_cache.contains(name)) {
|
||||||
|
const name_copy = try self.allocator.dupe(u8, name);
|
||||||
|
const decl_copy = try cloneDeclaration(self.allocator, decl);
|
||||||
|
try self.type_cache.put(name_copy, decl_copy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free the original declarations (we made copies)
|
||||||
|
for (decls) |decl| {
|
||||||
|
freeDeclaration(self.allocator, decl);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find and recursively parse all #include "SDL_*.h" directives
|
||||||
|
const includes = try findSDLIncludes(self.allocator, content);
|
||||||
|
defer {
|
||||||
|
for (includes) |inc| self.allocator.free(inc);
|
||||||
|
self.allocator.free(includes);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (includes) |inc_filename| {
|
||||||
|
try self.parseHeaderRecursive(header_dir, inc_filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn lookupType(self: *HeaderCache, type_name: []const u8) ?Declaration {
|
||||||
|
const decl = self.type_cache.get(type_name) orelse return null;
|
||||||
|
// Return a copy so caller owns it
|
||||||
|
return cloneDeclaration(self.allocator, decl) catch null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Lookup a type and recursively resolve all its dependencies
|
||||||
|
/// Returns an array of declarations: [0] is the requested type, [1..] are dependencies
|
||||||
|
pub fn lookupTypeWithDependencies(self: *HeaderCache, type_name: []const u8) ![]Declaration {
|
||||||
|
const dependency_resolver = @import("dependency_resolver.zig");
|
||||||
|
|
||||||
|
var result = try std.ArrayList(Declaration).initCapacity(self.allocator, 10);
|
||||||
|
errdefer {
|
||||||
|
for (result.items) |decl| {
|
||||||
|
freeDeclaration(self.allocator, decl);
|
||||||
|
}
|
||||||
|
result.deinit(self.allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Track which types we've already processed
|
||||||
|
var processed = std.StringHashMap(void).init(self.allocator);
|
||||||
|
defer {
|
||||||
|
var it = processed.keyIterator();
|
||||||
|
while (it.next()) |key| {
|
||||||
|
self.allocator.free(key.*);
|
||||||
|
}
|
||||||
|
processed.deinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Work queue for types to resolve
|
||||||
|
var queue = try std.ArrayList([]const u8).initCapacity(self.allocator, 10);
|
||||||
|
defer {
|
||||||
|
for (queue.items) |item| {
|
||||||
|
self.allocator.free(item);
|
||||||
|
}
|
||||||
|
queue.deinit(self.allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start with the requested type
|
||||||
|
try queue.append(self.allocator, try self.allocator.dupe(u8, type_name));
|
||||||
|
|
||||||
|
// Process queue until empty
|
||||||
|
while (queue.items.len > 0) {
|
||||||
|
const current_type = queue.orderedRemove(0);
|
||||||
|
defer self.allocator.free(current_type);
|
||||||
|
|
||||||
|
// Skip if already processed
|
||||||
|
if (processed.contains(current_type)) continue;
|
||||||
|
try processed.put(try self.allocator.dupe(u8, current_type), {});
|
||||||
|
|
||||||
|
// Look up the type
|
||||||
|
const decl = self.type_cache.get(current_type) orelse continue;
|
||||||
|
|
||||||
|
// Add cloned declaration to result
|
||||||
|
const decl_copy = try cloneDeclaration(self.allocator, decl);
|
||||||
|
try result.append(self.allocator, decl_copy);
|
||||||
|
|
||||||
|
// Analyze this declaration to find its dependencies
|
||||||
|
var resolver = dependency_resolver.DependencyResolver.init(self.allocator);
|
||||||
|
defer resolver.deinit();
|
||||||
|
|
||||||
|
const single_decl = [_]Declaration{decl};
|
||||||
|
try resolver.analyze(&single_decl);
|
||||||
|
|
||||||
|
const missing = try resolver.getMissingTypes(self.allocator);
|
||||||
|
defer {
|
||||||
|
for (missing) |m| self.allocator.free(m);
|
||||||
|
self.allocator.free(missing);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add missing types to queue if not already processed
|
||||||
|
for (missing) |missing_type| {
|
||||||
|
if (!processed.contains(missing_type) and self.type_cache.contains(missing_type)) {
|
||||||
|
try queue.append(self.allocator, try self.allocator.dupe(u8, missing_type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return try result.toOwnedSlice(self.allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn getTypeName(decl: Declaration) ?[]const u8 {
|
||||||
|
return switch (decl) {
|
||||||
|
.opaque_type => |o| o.name,
|
||||||
|
.typedef_decl => |t| t.name,
|
||||||
|
.function_pointer_decl => |fp| fp.name,
|
||||||
|
.c_type_alias => |a| a.name,
|
||||||
|
.enum_decl => |e| e.name,
|
||||||
|
.struct_decl => |s| s.name,
|
||||||
|
.union_decl => |u| u.name,
|
||||||
|
.flag_decl => |f| f.name,
|
||||||
|
.function_decl => null, // Functions don't define types
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn findSDLIncludes(allocator: Allocator, source: []const u8) ![][]const u8 {
|
||||||
|
var includes = std.ArrayList([]const u8){};
|
||||||
|
errdefer {
|
||||||
|
for (includes.items) |inc| allocator.free(inc);
|
||||||
|
includes.deinit(allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
var lines = std.mem.splitScalar(u8, source, '\n');
|
||||||
|
while (lines.next()) |line| {
|
||||||
|
const trimmed = std.mem.trim(u8, line, " \t\r");
|
||||||
|
|
||||||
|
// Match: #include <SDL3/SDL_something.h>
|
||||||
|
if (std.mem.startsWith(u8, trimmed, "#include <SDL3/")) {
|
||||||
|
const after_open = "#include <SDL3/".len;
|
||||||
|
if (std.mem.indexOf(u8, trimmed[after_open..], ">")) |end| {
|
||||||
|
const header_name = trimmed[after_open..][0..end];
|
||||||
|
if (std.mem.startsWith(u8, header_name, "SDL_")) {
|
||||||
|
try includes.append(allocator, try allocator.dupe(u8, header_name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Also match: #include "SDL_something.h"
|
||||||
|
else if (std.mem.startsWith(u8, trimmed, "#include \"SDL_")) {
|
||||||
|
const after_open = "#include \"".len;
|
||||||
|
if (std.mem.indexOf(u8, trimmed[after_open..], "\"")) |end| {
|
||||||
|
const header_name = trimmed[after_open..][0..end];
|
||||||
|
if (std.mem.startsWith(u8, header_name, "SDL_")) {
|
||||||
|
try includes.append(allocator, try allocator.dupe(u8, header_name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return try includes.toOwnedSlice(allocator);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fn cloneDeclaration(allocator: Allocator, decl: Declaration) !Declaration {
|
||||||
|
return switch (decl) {
|
||||||
|
.opaque_type => |o| Declaration{
|
||||||
|
.opaque_type = .{
|
||||||
|
.name = try allocator.dupe(u8, o.name),
|
||||||
|
.doc_comment = if (o.doc_comment) |doc| try allocator.dupe(u8, doc) else null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.typedef_decl => |t| Declaration{
|
||||||
|
.typedef_decl = .{
|
||||||
|
.name = try allocator.dupe(u8, t.name),
|
||||||
|
.underlying_type = try allocator.dupe(u8, t.underlying_type),
|
||||||
|
.doc_comment = if (t.doc_comment) |doc| try allocator.dupe(u8, doc) else null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.enum_decl => |e| Declaration{
|
||||||
|
.enum_decl = .{
|
||||||
|
.name = try allocator.dupe(u8, e.name),
|
||||||
|
.values = try cloneEnumValues(allocator, e.values),
|
||||||
|
.doc_comment = if (e.doc_comment) |doc| try allocator.dupe(u8, doc) else null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.struct_decl => |s| Declaration{
|
||||||
|
.struct_decl = .{
|
||||||
|
.name = try allocator.dupe(u8, s.name),
|
||||||
|
.fields = try cloneFields(allocator, s.fields),
|
||||||
|
.doc_comment = if (s.doc_comment) |doc| try allocator.dupe(u8, doc) else null,
|
||||||
|
.has_unions = s.has_unions,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.union_decl => |u| Declaration{
|
||||||
|
.union_decl = .{
|
||||||
|
.name = try allocator.dupe(u8, u.name),
|
||||||
|
.fields = try cloneFields(allocator, u.fields),
|
||||||
|
.doc_comment = if (u.doc_comment) |doc| try allocator.dupe(u8, doc) else null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.flag_decl => |f| Declaration{
|
||||||
|
.flag_decl = .{
|
||||||
|
.name = try allocator.dupe(u8, f.name),
|
||||||
|
.underlying_type = try allocator.dupe(u8, f.underlying_type),
|
||||||
|
.flags = try cloneFlagValues(allocator, f.flags),
|
||||||
|
.doc_comment = if (f.doc_comment) |doc| try allocator.dupe(u8, doc) else null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.function_decl => |func| Declaration{
|
||||||
|
.function_decl = .{
|
||||||
|
.name = try allocator.dupe(u8, func.name),
|
||||||
|
.return_type = try allocator.dupe(u8, func.return_type),
|
||||||
|
.params = try cloneParams(allocator, func.params),
|
||||||
|
.doc_comment = if (func.doc_comment) |doc| try allocator.dupe(u8, doc) else null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.function_pointer_decl => |fp| Declaration{
|
||||||
|
.function_pointer_decl = .{
|
||||||
|
.name = try allocator.dupe(u8, fp.name),
|
||||||
|
.return_type = try allocator.dupe(u8, fp.return_type),
|
||||||
|
.params = try cloneParams(allocator, fp.params),
|
||||||
|
.doc_comment = if (fp.doc_comment) |doc| try allocator.dupe(u8, doc) else null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.c_type_alias => |a| Declaration{
|
||||||
|
.c_type_alias = .{
|
||||||
|
.name = try allocator.dupe(u8, a.name),
|
||||||
|
.doc_comment = if (a.doc_comment) |doc| try allocator.dupe(u8, doc) else null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cloneEnumValues(allocator: Allocator, values: []const patterns.EnumValue) ![]patterns.EnumValue {
|
||||||
|
const new_values = try allocator.alloc(patterns.EnumValue, values.len);
|
||||||
|
for (values, 0..) |val, i| {
|
||||||
|
new_values[i] = .{
|
||||||
|
.name = try allocator.dupe(u8, val.name),
|
||||||
|
.value = if (val.value) |v| try allocator.dupe(u8, v) else null,
|
||||||
|
.comment = if (val.comment) |c| try allocator.dupe(u8, c) else null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return new_values;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cloneFlagValues(allocator: Allocator, flags: []const patterns.FlagValue) ![]patterns.FlagValue {
|
||||||
|
const new_flags = try allocator.alloc(patterns.FlagValue, flags.len);
|
||||||
|
for (flags, 0..) |flag, i| {
|
||||||
|
new_flags[i] = .{
|
||||||
|
.name = try allocator.dupe(u8, flag.name),
|
||||||
|
.value = try allocator.dupe(u8, flag.value),
|
||||||
|
.comment = if (flag.comment) |c| try allocator.dupe(u8, c) else null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return new_flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cloneFields(allocator: Allocator, fields: []const patterns.FieldDecl) ![]patterns.FieldDecl {
|
||||||
|
const new_fields = try allocator.alloc(patterns.FieldDecl, fields.len);
|
||||||
|
for (fields, 0..) |field, i| {
|
||||||
|
new_fields[i] = .{
|
||||||
|
.name = try allocator.dupe(u8, field.name),
|
||||||
|
.type_name = try allocator.dupe(u8, field.type_name),
|
||||||
|
.comment = if (field.comment) |c| try allocator.dupe(u8, c) else null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return new_fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cloneParams(allocator: Allocator, params: []const patterns.ParamDecl) ![]patterns.ParamDecl {
|
||||||
|
const new_params = try allocator.alloc(patterns.ParamDecl, params.len);
|
||||||
|
for (params, 0..) |param, i| {
|
||||||
|
new_params[i] = .{
|
||||||
|
.name = try allocator.dupe(u8, param.name),
|
||||||
|
.type_name = try allocator.dupe(u8, param.type_name),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return new_params;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn freeDeclaration(allocator: Allocator, decl: Declaration) void {
|
||||||
|
switch (decl) {
|
||||||
|
.opaque_type => |o| {
|
||||||
|
allocator.free(o.name);
|
||||||
|
if (o.doc_comment) |doc| allocator.free(doc);
|
||||||
|
},
|
||||||
|
.typedef_decl => |t| {
|
||||||
|
allocator.free(t.name);
|
||||||
|
allocator.free(t.underlying_type);
|
||||||
|
if (t.doc_comment) |doc| allocator.free(doc);
|
||||||
|
},
|
||||||
|
.enum_decl => |e| {
|
||||||
|
allocator.free(e.name);
|
||||||
|
for (e.values) |val| {
|
||||||
|
allocator.free(val.name);
|
||||||
|
if (val.value) |v| allocator.free(v);
|
||||||
|
if (val.comment) |c| allocator.free(c);
|
||||||
|
}
|
||||||
|
allocator.free(e.values);
|
||||||
|
if (e.doc_comment) |doc| allocator.free(doc);
|
||||||
|
},
|
||||||
|
.struct_decl => |s| {
|
||||||
|
allocator.free(s.name);
|
||||||
|
for (s.fields) |field| {
|
||||||
|
allocator.free(field.name);
|
||||||
|
allocator.free(field.type_name);
|
||||||
|
if (field.comment) |c| allocator.free(c);
|
||||||
|
}
|
||||||
|
allocator.free(s.fields);
|
||||||
|
if (s.doc_comment) |doc| allocator.free(doc);
|
||||||
|
},
|
||||||
|
.union_decl => |u| {
|
||||||
|
allocator.free(u.name);
|
||||||
|
for (u.fields) |field| {
|
||||||
|
allocator.free(field.name);
|
||||||
|
allocator.free(field.type_name);
|
||||||
|
if (field.comment) |c| allocator.free(c);
|
||||||
|
}
|
||||||
|
allocator.free(u.fields);
|
||||||
|
if (u.doc_comment) |doc| allocator.free(doc);
|
||||||
|
},
|
||||||
|
.flag_decl => |f| {
|
||||||
|
allocator.free(f.name);
|
||||||
|
allocator.free(f.underlying_type);
|
||||||
|
for (f.flags) |flag| {
|
||||||
|
allocator.free(flag.name);
|
||||||
|
allocator.free(flag.value);
|
||||||
|
if (flag.comment) |c| allocator.free(c);
|
||||||
|
}
|
||||||
|
allocator.free(f.flags);
|
||||||
|
if (f.doc_comment) |doc| allocator.free(doc);
|
||||||
|
},
|
||||||
|
.function_decl => |func| {
|
||||||
|
allocator.free(func.name);
|
||||||
|
allocator.free(func.return_type);
|
||||||
|
for (func.params) |param| {
|
||||||
|
allocator.free(param.name);
|
||||||
|
allocator.free(param.type_name);
|
||||||
|
}
|
||||||
|
allocator.free(func.params);
|
||||||
|
if (func.doc_comment) |doc| allocator.free(doc);
|
||||||
|
},
|
||||||
|
.function_pointer_decl => |fp| {
|
||||||
|
allocator.free(fp.name);
|
||||||
|
allocator.free(fp.return_type);
|
||||||
|
for (fp.params) |param| {
|
||||||
|
allocator.free(param.name);
|
||||||
|
allocator.free(param.type_name);
|
||||||
|
}
|
||||||
|
allocator.free(fp.params);
|
||||||
|
if (fp.doc_comment) |doc| allocator.free(doc);
|
||||||
|
},
|
||||||
|
.c_type_alias => |a| {
|
||||||
|
allocator.free(a.name);
|
||||||
|
if (a.doc_comment) |doc| allocator.free(doc);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
278
src/parser.zig
278
src/parser.zig
|
|
@ -4,6 +4,7 @@ const codegen = @import("codegen.zig");
|
||||||
const dependency_resolver = @import("dependency_resolver.zig");
|
const dependency_resolver = @import("dependency_resolver.zig");
|
||||||
const json_serializer = @import("json_serializer.zig");
|
const json_serializer = @import("json_serializer.zig");
|
||||||
const io = @import("io.zig");
|
const io = @import("io.zig");
|
||||||
|
const header_cache = @import("header_cache.zig");
|
||||||
|
|
||||||
pub fn main() !void {
|
pub fn main() !void {
|
||||||
const allocator = std.heap.smp_allocator;
|
const allocator = std.heap.smp_allocator;
|
||||||
|
|
@ -251,6 +252,14 @@ pub fn main() !void {
|
||||||
std.debug.print("Adding {d} hardcoded type declarations\n", .{hardcoded_decls.len});
|
std.debug.print("Adding {d} hardcoded type declarations\n", .{hardcoded_decls.len});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var dependency_decls = std.ArrayList(patterns.Declaration){};
|
||||||
|
defer {
|
||||||
|
for (dependency_decls.items) |dep_decl| {
|
||||||
|
freeDeclDeep(allocator, dep_decl);
|
||||||
|
}
|
||||||
|
dependency_decls.deinit(allocator);
|
||||||
|
}
|
||||||
|
|
||||||
if (missing_types.len > 0) {
|
if (missing_types.len > 0) {
|
||||||
std.debug.print("Found {d} missing types:\n", .{missing_types.len});
|
std.debug.print("Found {d} missing types:\n", .{missing_types.len});
|
||||||
for (missing_types) |missing| {
|
for (missing_types) |missing| {
|
||||||
|
|
@ -258,191 +267,142 @@ pub fn main() !void {
|
||||||
}
|
}
|
||||||
std.debug.print("\n", .{});
|
std.debug.print("\n", .{});
|
||||||
|
|
||||||
// Extract missing types from included headers
|
// PHASE 1: Build complete type cache from all SDL headers
|
||||||
std.debug.print("Resolving dependencies from included headers...\n", .{});
|
std.debug.print("Building type cache from all SDL headers...\n", .{});
|
||||||
const includes = try dependency_resolver.parseIncludes(allocator, source);
|
var cache = try header_cache.HeaderCache.buildCache(allocator, header_path);
|
||||||
defer {
|
defer cache.deinit();
|
||||||
for (includes) |inc| allocator.free(inc);
|
std.debug.print("Type cache built successfully\n\n", .{});
|
||||||
allocator.free(includes);
|
|
||||||
}
|
|
||||||
|
|
||||||
const header_dir = std.fs.path.dirname(header_path) orelse ".";
|
// PHASE 2: Resolve dependencies via cache lookup with recursive dependency resolution
|
||||||
|
std.debug.print("Resolving dependencies from cache...\n", .{});
|
||||||
var dependency_decls = std.ArrayList(patterns.Declaration){};
|
|
||||||
|
// Track which types we've already added to avoid duplicates
|
||||||
|
var added_types = std.StringHashMap(void).init(allocator);
|
||||||
defer {
|
defer {
|
||||||
for (dependency_decls.items) |dep_decl| {
|
var it = added_types.keyIterator();
|
||||||
freeDeclDeep(allocator, dep_decl);
|
while (it.next()) |key| {
|
||||||
|
allocator.free(key.*);
|
||||||
}
|
}
|
||||||
dependency_decls.deinit(allocator);
|
added_types.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (missing_types) |missing_type| {
|
for (missing_types) |missing_type| {
|
||||||
var found = false;
|
// Skip if already added
|
||||||
for (includes) |include| {
|
if (added_types.contains(missing_type)) continue;
|
||||||
const dep_path = try std.fs.path.join(allocator, &[_][]const u8{ header_dir, include });
|
|
||||||
defer allocator.free(dep_path);
|
// Look up type with all its dependencies
|
||||||
|
const resolved_decls = cache.lookupTypeWithDependencies(missing_type) catch |err| {
|
||||||
const dep_source = std.fs.cwd().readFileAlloc(allocator, dep_path, 10 * 1024 * 1024) catch continue;
|
std.debug.print(" Warning: Could not resolve {s}: {}\n", .{ missing_type, err });
|
||||||
defer allocator.free(dep_source);
|
continue;
|
||||||
|
};
|
||||||
if (try dependency_resolver.extractTypeFromHeader(allocator, dep_source, missing_type)) |dep_decl| {
|
|
||||||
try dependency_decls.append(allocator, dep_decl);
|
// Add all resolved declarations
|
||||||
std.debug.print(" Found {s} in {s}\n", .{ missing_type, include });
|
for (resolved_decls) |resolved_decl| {
|
||||||
found = true;
|
const decl_type_name = switch (resolved_decl) {
|
||||||
break;
|
.opaque_type => |o| o.name,
|
||||||
|
.typedef_decl => |t| t.name,
|
||||||
|
.function_pointer_decl => |fp| fp.name,
|
||||||
|
.c_type_alias => |a| a.name,
|
||||||
|
.enum_decl => |e| e.name,
|
||||||
|
.struct_decl => |s| s.name,
|
||||||
|
.union_decl => |u| u.name,
|
||||||
|
.flag_decl => |f| f.name,
|
||||||
|
.function_decl => continue, // Skip functions
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!added_types.contains(decl_type_name)) {
|
||||||
|
try dependency_decls.append(allocator, resolved_decl);
|
||||||
|
try added_types.put(try allocator.dupe(u8, decl_type_name), {});
|
||||||
|
|
||||||
|
if (std.mem.eql(u8, decl_type_name, missing_type)) {
|
||||||
|
std.debug.print(" Found {s} in cache\n", .{missing_type});
|
||||||
|
} else {
|
||||||
|
std.debug.print(" + dependency: {s}\n", .{decl_type_name});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Already added, free this duplicate
|
||||||
|
freeDeclDeep(allocator, resolved_decl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found) {
|
allocator.free(resolved_decls);
|
||||||
std.debug.print(" Warning: Could not find definition for type: {s}\n", .{missing_type});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Combine declarations (hardcoded first, then dependencies, then primary!)
|
std.debug.print("\n", .{});
|
||||||
std.debug.print("\nCombining {d} hardcoded + {d} dependency declarations with primary declarations...\n", .{ hardcoded_decls.len, dependency_decls.items.len });
|
}
|
||||||
|
|
||||||
var all_decls = std.ArrayList(patterns.Declaration){};
|
// Combine declarations (hardcoded first, then dependencies, then primary!)
|
||||||
defer all_decls.deinit(allocator);
|
std.debug.print("Combining {d} hardcoded + {d} dependency declarations with primary declarations...\n", .{ hardcoded_decls.len, dependency_decls.items.len });
|
||||||
|
|
||||||
try all_decls.appendSlice(allocator, hardcoded_decls);
|
var all_decls = std.ArrayList(patterns.Declaration){};
|
||||||
try all_decls.appendSlice(allocator, dependency_decls.items);
|
defer all_decls.deinit(allocator);
|
||||||
try all_decls.appendSlice(allocator, decls);
|
|
||||||
|
|
||||||
// Generate code with all declarations
|
try all_decls.appendSlice(allocator, hardcoded_decls);
|
||||||
const output = try codegen.CodeGen.generate(allocator, all_decls.items);
|
try all_decls.appendSlice(allocator, dependency_decls.items);
|
||||||
defer allocator.free(output);
|
try all_decls.appendSlice(allocator, decls);
|
||||||
|
|
||||||
// Parse and format the AST for validation
|
// Generate code with all declarations
|
||||||
const output_z = try allocator.dupeZ(u8, output);
|
const output = try codegen.CodeGen.generate(allocator, all_decls.items);
|
||||||
defer allocator.free(output_z);
|
defer allocator.free(output);
|
||||||
|
|
||||||
var ast = try std.zig.Ast.parse(allocator, output_z, .zig);
|
// Parse and format the AST for validation
|
||||||
defer ast.deinit(allocator);
|
const output_z = try allocator.dupeZ(u8, output);
|
||||||
|
defer allocator.free(output_z);
|
||||||
|
|
||||||
// Check for parse errors
|
var ast = try std.zig.Ast.parse(allocator, output_z, .zig);
|
||||||
if (ast.errors.len > 0) {
|
defer ast.deinit(allocator);
|
||||||
std.debug.print("{s}", .{output_z});
|
|
||||||
std.debug.print("\nError: {d} syntax errors detected in generated code\n", .{ast.errors.len});
|
|
||||||
for (ast.errors) |err| {
|
|
||||||
const loc = ast.tokenLocation(0, err.token);
|
|
||||||
std.debug.print(" Line {d}: {s}\n", .{ loc.line + 1, @tagName(err.tag) });
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write to debug file
|
// Check for parse errors
|
||||||
try writeDebugFile(allocator, header_path, output);
|
if (ast.errors.len > 0) {
|
||||||
|
std.debug.print("{s}", .{output_z});
|
||||||
// Write unformatted output for debugging
|
std.debug.print("\nError: {d} syntax errors detected in generated code\n", .{ast.errors.len});
|
||||||
if (output_file) |file_path| {
|
for (ast.errors) |err| {
|
||||||
try std.fs.cwd().writeFile(.{
|
const loc = ast.tokenLocation(0, err.token);
|
||||||
.sub_path = file_path,
|
std.debug.print(" Line {d}: {s}\n", .{ loc.line + 1, @tagName(err.tag) });
|
||||||
.data = output,
|
|
||||||
});
|
|
||||||
std.debug.print("\nGenerated (with errors): {s}\n", .{file_path});
|
|
||||||
}
|
|
||||||
|
|
||||||
return error.InvalidSyntax;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render formatted output from AST
|
// Write to debug file
|
||||||
const formatted_output = ast.renderAlloc(allocator) catch |err| {
|
try writeDebugFile(allocator, header_path, output);
|
||||||
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
|
// Write unformatted output for debugging
|
||||||
if (output_file) |file_path| {
|
if (output_file) |file_path| {
|
||||||
try writeZigFileWithFmt(allocator, header_path, file_path, formatted_output);
|
|
||||||
} else {
|
|
||||||
_ = try io.stdout().write(formatted_output);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate C mocks if requested (with all declarations)
|
|
||||||
if (mock_output_file) |mock_path| {
|
|
||||||
const mock_codegen = @import("mock_codegen.zig");
|
|
||||||
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(.{
|
try std.fs.cwd().writeFile(.{
|
||||||
.sub_path = mock_path,
|
.sub_path = file_path,
|
||||||
.data = mock_output,
|
.data = output,
|
||||||
});
|
});
|
||||||
std.debug.print("Generated C mocks: {s}\n", .{mock_path});
|
std.debug.print("\nGenerated (with errors): {s}\n", .{file_path});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return error.InvalidSyntax;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render formatted output from AST
|
||||||
|
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 writeZigFileWithFmt(allocator, header_path, file_path, formatted_output);
|
||||||
} else {
|
} else {
|
||||||
std.debug.print("No missing dependencies found!\n\n", .{});
|
_ = try io.stdout().write(formatted_output);
|
||||||
|
}
|
||||||
|
|
||||||
// Generate code (include hardcoded declarations if any)
|
// Generate C mocks if requested (with all declarations)
|
||||||
var gen_decls = std.ArrayList(patterns.Declaration){};
|
if (mock_output_file) |mock_path| {
|
||||||
defer gen_decls.deinit(allocator);
|
const mock_codegen = @import("mock_codegen.zig");
|
||||||
if (hardcoded_decls.len > 0) {
|
const mock_output = try mock_codegen.MockCodeGen.generate(allocator, all_decls.items);
|
||||||
try gen_decls.appendSlice(allocator, hardcoded_decls);
|
defer allocator.free(mock_output);
|
||||||
}
|
|
||||||
try gen_decls.appendSlice(allocator, decls);
|
|
||||||
|
|
||||||
const output = try codegen.CodeGen.generate(allocator, gen_decls.items);
|
try ensureParentDirExists(mock_path);
|
||||||
defer allocator.free(output);
|
try std.fs.cwd().writeFile(.{
|
||||||
|
.sub_path = mock_path,
|
||||||
// Parse and format the AST for validation
|
.data = mock_output,
|
||||||
const output_z = try allocator.dupeZ(u8, output);
|
});
|
||||||
defer allocator.free(output_z);
|
std.debug.print("Generated C mocks: {s}\n", .{mock_path});
|
||||||
|
|
||||||
var ast = try std.zig.Ast.parse(allocator, output_z, .zig);
|
|
||||||
defer ast.deinit(allocator);
|
|
||||||
|
|
||||||
// Check for parse errors
|
|
||||||
if (ast.errors.len > 0) {
|
|
||||||
std.debug.print("\nError: {d} syntax errors detected in generated code\n", .{ast.errors.len});
|
|
||||||
for (ast.errors) |err| {
|
|
||||||
const loc = ast.tokenLocation(0, err.token);
|
|
||||||
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(.{
|
|
||||||
.sub_path = file_path,
|
|
||||||
.data = output,
|
|
||||||
});
|
|
||||||
std.debug.print("\nGenerated (with errors): {s}\n", .{file_path});
|
|
||||||
}
|
|
||||||
|
|
||||||
return error.InvalidSyntax;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Render formatted output from AST
|
|
||||||
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 writeZigFileWithFmt(allocator, header_path, file_path, formatted_output);
|
|
||||||
} else {
|
|
||||||
_ = try io.stdout().write(formatted_output);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate C mocks if requested
|
|
||||||
if (mock_output_file) |mock_path| {
|
|
||||||
const mock_codegen = @import("mock_codegen.zig");
|
|
||||||
const mock_output = try mock_codegen.MockCodeGen.generate(allocator, gen_decls.items);
|
|
||||||
defer allocator.free(mock_output);
|
|
||||||
|
|
||||||
try ensureParentDirExists(mock_path);
|
|
||||||
try std.fs.cwd().writeFile(.{
|
|
||||||
.sub_path = mock_path,
|
|
||||||
.data = mock_output,
|
|
||||||
});
|
|
||||||
std.debug.print("Generated C mocks: {s}\n", .{mock_path});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,770 @@
|
||||||
|
const std = @import("std");
|
||||||
|
pub const c = @import("c.zig").c;
|
||||||
|
|
||||||
|
pub const PenID = u32;
|
||||||
|
|
||||||
|
pub const WindowID = u32;
|
||||||
|
|
||||||
|
pub const AudioDeviceID = u32;
|
||||||
|
|
||||||
|
pub const DisplayID = u32;
|
||||||
|
|
||||||
|
pub const CameraID = u32;
|
||||||
|
|
||||||
|
pub const PenInputFlags = packed struct(u32) {
|
||||||
|
penInputDown: bool = false, // pen is pressed down
|
||||||
|
penInputButton1: bool = false, // button 1 is pressed
|
||||||
|
penInputButton2: bool = false, // button 2 is pressed
|
||||||
|
penInputButton3: bool = false, // button 3 is pressed
|
||||||
|
penInputButton4: bool = false, // button 4 is pressed
|
||||||
|
penInputButton5: bool = false, // button 5 is pressed
|
||||||
|
penInputEraserTip: bool = false, // eraser tip is used
|
||||||
|
pad0: u24 = 0,
|
||||||
|
rsvd: bool = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const MouseButtonFlags = packed struct(u32) {
|
||||||
|
buttonLeft: bool = false,
|
||||||
|
buttonMiddle: bool = false,
|
||||||
|
buttonX1: bool = false,
|
||||||
|
pad0: u28 = 0,
|
||||||
|
rsvd: bool = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Scancode = enum(c_int) {
|
||||||
|
scancodeBackslash,
|
||||||
|
scancodeNonushash,
|
||||||
|
scancodeGrave,
|
||||||
|
scancodeInsert,
|
||||||
|
scancodeNumlockclear,
|
||||||
|
scancodeNonusbackslash,
|
||||||
|
scancodeApplication, //windows contextual menu, compose
|
||||||
|
scancodePower,
|
||||||
|
scancodeHelp, //AL Integrated Help Center
|
||||||
|
scancodeMenu, //Menu (show menu)
|
||||||
|
scancodeStop, //AC Stop
|
||||||
|
scancodeAgain, //AC Redo/Repeat
|
||||||
|
scancodeUndo, //AC Undo
|
||||||
|
scancodeCut, //AC Cut
|
||||||
|
scancodeCopy, //AC Copy
|
||||||
|
scancodePaste, //AC Paste
|
||||||
|
scancodeFind, //AC Find
|
||||||
|
scancodeInternational1,
|
||||||
|
scancodeInternational3, //Yen
|
||||||
|
scancodeLang1, //Hangul/English toggle
|
||||||
|
scancodeLang2, //Hanja conversion
|
||||||
|
scancodeLang3, //Katakana
|
||||||
|
scancodeLang4, //Hiragana
|
||||||
|
scancodeLang5, //Zenkaku/Hankaku
|
||||||
|
scancodeLang6, //reserved
|
||||||
|
scancodeLang7, //reserved
|
||||||
|
scancodeLang8, //reserved
|
||||||
|
scancodeLang9, //reserved
|
||||||
|
scancodeAlterase, //Erase-Eaze
|
||||||
|
scancodeCancel, //AC Cancel
|
||||||
|
scancodeLalt, //alt, option
|
||||||
|
scancodeLgui, //windows, command (apple), meta
|
||||||
|
scancodeRalt, //alt gr, option
|
||||||
|
scancodeRgui, //windows, command (apple), meta
|
||||||
|
scancodeMode,
|
||||||
|
scancodeSleep, //Sleep
|
||||||
|
scancodeWake, //Wake
|
||||||
|
scancodeChannelIncrement, //Channel Increment
|
||||||
|
scancodeChannelDecrement, //Channel Decrement
|
||||||
|
scancodeMediaPlay, //Play
|
||||||
|
scancodeMediaPause, //Pause
|
||||||
|
scancodeMediaRecord, //Record
|
||||||
|
scancodeMediaFastForward, //Fast Forward
|
||||||
|
scancodeMediaRewind, //Rewind
|
||||||
|
scancodeMediaNextTrack, //Next Track
|
||||||
|
scancodeMediaPreviousTrack, //Previous Track
|
||||||
|
scancodeMediaStop, //Stop
|
||||||
|
scancodeMediaEject, //Eject
|
||||||
|
scancodeMediaPlayPause, //Play / Pause
|
||||||
|
scancodeMediaSelect,
|
||||||
|
scancodeAcNew, //AC New
|
||||||
|
scancodeAcOpen, //AC Open
|
||||||
|
scancodeAcClose, //AC Close
|
||||||
|
scancodeAcExit, //AC Exit
|
||||||
|
scancodeAcSave, //AC Save
|
||||||
|
scancodeAcPrint, //AC Print
|
||||||
|
scancodeAcProperties, //AC Properties
|
||||||
|
scancodeAcSearch, //AC Search
|
||||||
|
scancodeAcHome, //AC Home
|
||||||
|
scancodeAcBack, //AC Back
|
||||||
|
scancodeAcForward, //AC Forward
|
||||||
|
scancodeAcStop, //AC Stop
|
||||||
|
scancodeAcRefresh, //AC Refresh
|
||||||
|
scancodeAcBookmarks, //AC Bookmarks
|
||||||
|
scancodeSoftleft,
|
||||||
|
scancodeSoftright,
|
||||||
|
scancodeCall, //Used for accepting phone calls.
|
||||||
|
scancodeEndcall, //Used for rejecting phone calls.
|
||||||
|
scancodeReserved, //400-500 reserved for dynamic keycodes
|
||||||
|
scancodeCount,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const TouchID = u64;
|
||||||
|
|
||||||
|
pub const KeyboardID = u32;
|
||||||
|
|
||||||
|
pub const PenAxis = enum(c_int) {
|
||||||
|
penAxisPressure, //Pen pressure. Unidirectional: 0 to 1.0
|
||||||
|
penAxisXtilt, //Pen horizontal tilt angle. Bidirectional: -90.0 to 90.0 (left-to-right).
|
||||||
|
penAxisYtilt, //Pen vertical tilt angle. Bidirectional: -90.0 to 90.0 (top-to-down).
|
||||||
|
penAxisDistance, //Pen distance to drawing surface. Unidirectional: 0.0 to 1.0
|
||||||
|
penAxisRotation, //Pen barrel rotation. Bidirectional: -180 to 179.9 (clockwise, 0 is facing up, -180.0 is facing down).
|
||||||
|
penAxisSlider, //Pen finger wheel or slider (e.g., Airbrush Pen). Unidirectional: 0 to 1.0
|
||||||
|
penAxisTangentialPressure, //Pressure from squeezing the pen ("barrel pressure").
|
||||||
|
penAxisCount, //Total known pen axis types in this version of SDL. This number may grow in future releases!
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const MouseID = u32;
|
||||||
|
|
||||||
|
pub const MouseWheelDirection = enum(c_int) {
|
||||||
|
mousewheelNormal, //The scroll direction is normal
|
||||||
|
mousewheelFlipped, //The scroll direction is flipped / natural
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const PowerState = enum(c_int) {
|
||||||
|
powerstateError, //error determining power status
|
||||||
|
powerstateUnknown, //cannot determine power status
|
||||||
|
powerstateOnBattery, //Not plugged in, running on the battery
|
||||||
|
powerstateNoBattery, //Plugged in, no battery available
|
||||||
|
powerstateCharging, //Plugged in, charging battery
|
||||||
|
powerstateCharged,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Window = opaque {};
|
||||||
|
|
||||||
|
pub const FingerID = u64;
|
||||||
|
|
||||||
|
pub const Keycode = u32;
|
||||||
|
|
||||||
|
pub const SensorID = u32;
|
||||||
|
|
||||||
|
pub const JoystickID = u32;
|
||||||
|
|
||||||
|
pub const Keymod = u16;
|
||||||
|
|
||||||
|
pub const EventType = enum(c_int) {
|
||||||
|
eventFirst, //Unused (do not remove)
|
||||||
|
eventQuit, //User-requested quit
|
||||||
|
eventTerminating,
|
||||||
|
eventLowMemory,
|
||||||
|
eventWillEnterBackground,
|
||||||
|
eventDidEnterBackground,
|
||||||
|
eventWillEnterForeground,
|
||||||
|
eventDidEnterForeground,
|
||||||
|
eventLocaleChanged, //The user's locale preferences have changed.
|
||||||
|
eventSystemThemeChanged, //The system theme changed
|
||||||
|
eventDisplayOrientation, //Display orientation has changed to data1
|
||||||
|
eventDisplayAdded, //Display has been added to the system
|
||||||
|
eventDisplayRemoved, //Display has been removed from the system
|
||||||
|
eventDisplayMoved, //Display has changed position
|
||||||
|
eventDisplayDesktopModeChanged, //Display has changed desktop mode
|
||||||
|
eventDisplayCurrentModeChanged, //Display has changed current mode
|
||||||
|
eventDisplayContentScaleChanged, //Display has changed content scale
|
||||||
|
eventWindowShown, //Window has been shown
|
||||||
|
eventWindowHidden, //Window has been hidden
|
||||||
|
eventWindowExposed, //Window has been exposed and should be redrawn, and can be redrawn directly from event watchers for this event
|
||||||
|
eventWindowMoved, //Window has been moved to data1, data2
|
||||||
|
eventWindowResized, //Window has been resized to data1xdata2
|
||||||
|
eventWindowPixelSizeChanged, //The pixel size of the window has changed to data1xdata2
|
||||||
|
eventWindowMetalViewResized, //The pixel size of a Metal view associated with the window has changed
|
||||||
|
eventWindowMinimized, //Window has been minimized
|
||||||
|
eventWindowMaximized, //Window has been maximized
|
||||||
|
eventWindowRestored, //Window has been restored to normal size and position
|
||||||
|
eventWindowMouseEnter, //Window has gained mouse focus
|
||||||
|
eventWindowMouseLeave, //Window has lost mouse focus
|
||||||
|
eventWindowFocusGained, //Window has gained keyboard focus
|
||||||
|
eventWindowFocusLost, //Window has lost keyboard focus
|
||||||
|
eventWindowCloseRequested, //The window manager requests that the window be closed
|
||||||
|
eventWindowHitTest, //Window had a hit test that wasn't SDL_HITTEST_NORMAL
|
||||||
|
eventWindowIccprofChanged, //The ICC profile of the window's display has changed
|
||||||
|
eventWindowDisplayChanged, //Window has been moved to display data1
|
||||||
|
eventWindowDisplayScaleChanged, //Window display scale has been changed
|
||||||
|
eventWindowSafeAreaChanged, //The window safe area has been changed
|
||||||
|
eventWindowOccluded, //The window has been occluded
|
||||||
|
eventWindowEnterFullscreen, //The window has entered fullscreen mode
|
||||||
|
eventWindowLeaveFullscreen, //The window has left fullscreen mode
|
||||||
|
eventWindowDestroyed,
|
||||||
|
eventWindowHdrStateChanged, //Window HDR properties have changed
|
||||||
|
eventKeyDown, //Key pressed
|
||||||
|
eventKeyUp, //Key released
|
||||||
|
eventTextEditing, //Keyboard text editing (composition)
|
||||||
|
eventTextInput, //Keyboard text input
|
||||||
|
eventKeymapChanged,
|
||||||
|
eventKeyboardAdded, //A new keyboard has been inserted into the system
|
||||||
|
eventKeyboardRemoved, //A keyboard has been removed
|
||||||
|
eventTextEditingCandidates, //Keyboard text editing candidates
|
||||||
|
eventMouseMotion, //Mouse moved
|
||||||
|
eventMouseButtonDown, //Mouse button pressed
|
||||||
|
eventMouseButtonUp, //Mouse button released
|
||||||
|
eventMouseWheel, //Mouse wheel motion
|
||||||
|
eventMouseAdded, //A new mouse has been inserted into the system
|
||||||
|
eventMouseRemoved, //A mouse has been removed
|
||||||
|
eventJoystickAxisMotion, //Joystick axis motion
|
||||||
|
eventJoystickBallMotion, //Joystick trackball motion
|
||||||
|
eventJoystickHatMotion, //Joystick hat position change
|
||||||
|
eventJoystickButtonDown, //Joystick button pressed
|
||||||
|
eventJoystickButtonUp, //Joystick button released
|
||||||
|
eventJoystickAdded, //A new joystick has been inserted into the system
|
||||||
|
eventJoystickRemoved, //An opened joystick has been removed
|
||||||
|
eventJoystickBatteryUpdated, //Joystick battery level change
|
||||||
|
eventJoystickUpdateComplete, //Joystick update is complete
|
||||||
|
eventGamepadAxisMotion, //Gamepad axis motion
|
||||||
|
eventGamepadButtonDown, //Gamepad button pressed
|
||||||
|
eventGamepadButtonUp, //Gamepad button released
|
||||||
|
eventGamepadAdded, //A new gamepad has been inserted into the system
|
||||||
|
eventGamepadRemoved, //A gamepad has been removed
|
||||||
|
eventGamepadRemapped, //The gamepad mapping was updated
|
||||||
|
eventGamepadTouchpadDown, //Gamepad touchpad was touched
|
||||||
|
eventGamepadTouchpadMotion, //Gamepad touchpad finger was moved
|
||||||
|
eventGamepadTouchpadUp, //Gamepad touchpad finger was lifted
|
||||||
|
eventGamepadSensorUpdate, //Gamepad sensor was updated
|
||||||
|
eventGamepadUpdateComplete, //Gamepad update is complete
|
||||||
|
eventGamepadSteamHandleUpdated, //Gamepad Steam handle has changed
|
||||||
|
eventFingerUp,
|
||||||
|
eventFingerMotion,
|
||||||
|
eventFingerCanceled,
|
||||||
|
eventClipboardUpdate, //The clipboard or primary selection changed
|
||||||
|
eventDropFile, //The system requests a file open
|
||||||
|
eventDropText, //text/plain drag-and-drop event
|
||||||
|
eventDropBegin, //A new set of drops is beginning (NULL filename)
|
||||||
|
eventDropComplete, //Current set of drops is now complete (NULL filename)
|
||||||
|
eventDropPosition, //Position while moving over the window
|
||||||
|
eventAudioDeviceAdded, //A new audio device is available
|
||||||
|
eventAudioDeviceRemoved, //An audio device has been removed.
|
||||||
|
eventAudioDeviceFormatChanged, //An audio device's format has been changed by the system.
|
||||||
|
eventSensorUpdate, //A sensor was updated
|
||||||
|
eventPenProximityIn, //Pressure-sensitive pen has become available
|
||||||
|
eventPenProximityOut, //Pressure-sensitive pen has become unavailable
|
||||||
|
eventPenDown, //Pressure-sensitive pen touched drawing surface
|
||||||
|
eventPenUp, //Pressure-sensitive pen stopped touching drawing surface
|
||||||
|
eventPenButtonDown, //Pressure-sensitive pen button pressed
|
||||||
|
eventPenButtonUp, //Pressure-sensitive pen button released
|
||||||
|
eventPenMotion, //Pressure-sensitive pen is moving on the tablet
|
||||||
|
eventPenAxis, //Pressure-sensitive pen angle/pressure/etc changed
|
||||||
|
eventCameraDeviceAdded, //A new camera device is available
|
||||||
|
eventCameraDeviceRemoved, //A camera device has been removed.
|
||||||
|
eventCameraDeviceApproved, //A camera device has been approved for use by the user.
|
||||||
|
eventCameraDeviceDenied, //A camera device has been denied for use by the user.
|
||||||
|
eventRenderTargetsReset, //The render targets have been reset and their contents need to be updated
|
||||||
|
eventRenderDeviceReset, //The device has been reset and all textures need to be recreated
|
||||||
|
eventRenderDeviceLost, //The device has been lost and can't be recovered.
|
||||||
|
eventPrivate1,
|
||||||
|
eventPrivate2,
|
||||||
|
eventPrivate3,
|
||||||
|
eventPollSentinel, //Signals the end of an event poll cycle
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const CommonEvent = extern struct {
|
||||||
|
_type: u32, // Event type, shared with all events, Uint32 to cover user events which are not in the SDL_EventType enumeration
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const DisplayEvent = extern struct {
|
||||||
|
_type: EventType, // SDL_DISPLAYEVENT_*
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
displayID: DisplayID, // The associated display
|
||||||
|
data1: i32, // event dependent data
|
||||||
|
data2: i32, // event dependent data
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const WindowEvent = extern struct {
|
||||||
|
_type: EventType, // SDL_EVENT_WINDOW_*
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
windowID: WindowID, // The associated window
|
||||||
|
data1: i32, // event dependent data
|
||||||
|
data2: i32, // event dependent data
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const KeyboardDeviceEvent = extern struct {
|
||||||
|
_type: EventType, // SDL_EVENT_KEYBOARD_ADDED or SDL_EVENT_KEYBOARD_REMOVED
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
which: KeyboardID, // The keyboard instance id
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const KeyboardEvent = extern struct {
|
||||||
|
_type: EventType, // SDL_EVENT_KEY_DOWN or SDL_EVENT_KEY_UP
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
windowID: WindowID, // The window with keyboard focus, if any
|
||||||
|
which: KeyboardID, // The keyboard instance id, or 0 if unknown or virtual
|
||||||
|
scancode: Scancode, // SDL physical key code
|
||||||
|
key: Keycode, // SDL virtual key code
|
||||||
|
mod: Keymod, // current key modifiers
|
||||||
|
raw: u16, // The platform dependent scancode for this event
|
||||||
|
down: bool, // true if the key is pressed
|
||||||
|
repeat: bool, // true if this is a key repeat
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const TextEditingEvent = extern struct {
|
||||||
|
_type: EventType, // SDL_EVENT_TEXT_EDITING
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
windowID: WindowID, // The window with keyboard focus, if any
|
||||||
|
text: [*c]const u8, // The editing text
|
||||||
|
start: i32, // The start cursor of selected editing text, or -1 if not set
|
||||||
|
length: i32, // The length of selected editing text, or -1 if not set
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const TextEditingCandidatesEvent = extern struct {
|
||||||
|
_type: EventType, // SDL_EVENT_TEXT_EDITING_CANDIDATES
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
windowID: WindowID, // The window with keyboard focus, if any
|
||||||
|
candidates: [*c]const [*c]const u8, // The list of candidates, or NULL if there are no candidates available
|
||||||
|
num_candidates: i32, // The number of strings in `candidates`
|
||||||
|
selected_candidate: i32, // The index of the selected candidate, or -1 if no candidate is selected
|
||||||
|
horizontal: bool, // true if the list is horizontal, false if it's vertical
|
||||||
|
padding1: u8,
|
||||||
|
padding2: u8,
|
||||||
|
padding3: u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const TextInputEvent = extern struct {
|
||||||
|
_type: EventType, // SDL_EVENT_TEXT_INPUT
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
windowID: WindowID, // The window with keyboard focus, if any
|
||||||
|
text: [*c]const u8, // The input text, UTF-8 encoded
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const MouseDeviceEvent = extern struct {
|
||||||
|
_type: EventType, // SDL_EVENT_MOUSE_ADDED or SDL_EVENT_MOUSE_REMOVED
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
which: MouseID, // The mouse instance id
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const MouseMotionEvent = extern struct {
|
||||||
|
_type: EventType, // SDL_EVENT_MOUSE_MOTION
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
windowID: WindowID, // The window with mouse focus, if any
|
||||||
|
which: MouseID, // The mouse instance id in relative mode, SDL_TOUCH_MOUSEID for touch events, or 0
|
||||||
|
state: MouseButtonFlags, // The current button state
|
||||||
|
x: f32, // X coordinate, relative to window
|
||||||
|
y: f32, // Y coordinate, relative to window
|
||||||
|
xrel: f32, // The relative motion in the X direction
|
||||||
|
yrel: f32, // The relative motion in the Y direction
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const MouseButtonEvent = extern struct {
|
||||||
|
_type: EventType, // SDL_EVENT_MOUSE_BUTTON_DOWN or SDL_EVENT_MOUSE_BUTTON_UP
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
windowID: WindowID, // The window with mouse focus, if any
|
||||||
|
which: MouseID, // The mouse instance id in relative mode, SDL_TOUCH_MOUSEID for touch events, or 0
|
||||||
|
button: u8, // The mouse button index
|
||||||
|
down: bool, // true if the button is pressed
|
||||||
|
clicks: u8, // 1 for single-click, 2 for double-click, etc.
|
||||||
|
padding: u8,
|
||||||
|
x: f32, // X coordinate, relative to window
|
||||||
|
y: f32, // Y coordinate, relative to window
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const MouseWheelEvent = extern struct {
|
||||||
|
_type: EventType, // SDL_EVENT_MOUSE_WHEEL
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
windowID: WindowID, // The window with mouse focus, if any
|
||||||
|
which: MouseID, // The mouse instance id in relative mode or 0
|
||||||
|
x: f32, // The amount scrolled horizontally, positive to the right and negative to the left
|
||||||
|
y: f32, // The amount scrolled vertically, positive away from the user and negative toward the user
|
||||||
|
direction: MouseWheelDirection, // Set to one of the SDL_MOUSEWHEEL_* defines. When FLIPPED the values in X and Y will be opposite. Multiply by -1 to change them back
|
||||||
|
mouse_x: f32, // X coordinate, relative to window
|
||||||
|
mouse_y: f32, // Y coordinate, relative to window
|
||||||
|
integer_x: i32, // The amount scrolled horizontally, accumulated to whole scroll "ticks" (added in 3.2.12)
|
||||||
|
integer_y: i32, // The amount scrolled vertically, accumulated to whole scroll "ticks" (added in 3.2.12)
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const JoyAxisEvent = extern struct {
|
||||||
|
_type: EventType, // SDL_EVENT_JOYSTICK_AXIS_MOTION
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
which: JoystickID, // The joystick instance id
|
||||||
|
axis: u8, // The joystick axis index
|
||||||
|
padding1: u8,
|
||||||
|
padding2: u8,
|
||||||
|
padding3: u8,
|
||||||
|
value: i16, // The axis value (range: -32768 to 32767)
|
||||||
|
padding4: u16,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const JoyBallEvent = extern struct {
|
||||||
|
_type: EventType, // SDL_EVENT_JOYSTICK_BALL_MOTION
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
which: JoystickID, // The joystick instance id
|
||||||
|
ball: u8, // The joystick trackball index
|
||||||
|
padding1: u8,
|
||||||
|
padding2: u8,
|
||||||
|
padding3: u8,
|
||||||
|
xrel: i16, // The relative motion in the X direction
|
||||||
|
yrel: i16, // The relative motion in the Y direction
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const JoyHatEvent = extern struct {
|
||||||
|
_type: EventType, // SDL_EVENT_JOYSTICK_HAT_MOTION
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
which: JoystickID, // The joystick instance id
|
||||||
|
hat: u8, // The joystick hat index
|
||||||
|
padding1: u8,
|
||||||
|
padding2: u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const JoyButtonEvent = extern struct {
|
||||||
|
_type: EventType, // SDL_EVENT_JOYSTICK_BUTTON_DOWN or SDL_EVENT_JOYSTICK_BUTTON_UP
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
which: JoystickID, // The joystick instance id
|
||||||
|
button: u8, // The joystick button index
|
||||||
|
down: bool, // true if the button is pressed
|
||||||
|
padding1: u8,
|
||||||
|
padding2: u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const JoyDeviceEvent = extern struct {
|
||||||
|
_type: EventType, // SDL_EVENT_JOYSTICK_ADDED or SDL_EVENT_JOYSTICK_REMOVED or SDL_EVENT_JOYSTICK_UPDATE_COMPLETE
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
which: JoystickID, // The joystick instance id
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const JoyBatteryEvent = extern struct {
|
||||||
|
_type: EventType, // SDL_EVENT_JOYSTICK_BATTERY_UPDATED
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
which: JoystickID, // The joystick instance id
|
||||||
|
state: PowerState, // The joystick battery state
|
||||||
|
percent: c_int, // The joystick battery percent charge remaining
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const GamepadAxisEvent = extern struct {
|
||||||
|
_type: EventType, // SDL_EVENT_GAMEPAD_AXIS_MOTION
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
which: JoystickID, // The joystick instance id
|
||||||
|
axis: u8, // The gamepad axis (SDL_GamepadAxis)
|
||||||
|
padding1: u8,
|
||||||
|
padding2: u8,
|
||||||
|
padding3: u8,
|
||||||
|
value: i16, // The axis value (range: -32768 to 32767)
|
||||||
|
padding4: u16,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const GamepadButtonEvent = extern struct {
|
||||||
|
_type: EventType, // SDL_EVENT_GAMEPAD_BUTTON_DOWN or SDL_EVENT_GAMEPAD_BUTTON_UP
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
which: JoystickID, // The joystick instance id
|
||||||
|
button: u8, // The gamepad button (SDL_GamepadButton)
|
||||||
|
down: bool, // true if the button is pressed
|
||||||
|
padding1: u8,
|
||||||
|
padding2: u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const GamepadDeviceEvent = extern struct {
|
||||||
|
_type: EventType, // SDL_EVENT_GAMEPAD_ADDED, SDL_EVENT_GAMEPAD_REMOVED, or SDL_EVENT_GAMEPAD_REMAPPED, SDL_EVENT_GAMEPAD_UPDATE_COMPLETE or SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
which: JoystickID, // The joystick instance id
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const GamepadTouchpadEvent = extern struct {
|
||||||
|
_type: EventType, // SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN or SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION or SDL_EVENT_GAMEPAD_TOUCHPAD_UP
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
which: JoystickID, // The joystick instance id
|
||||||
|
touchpad: i32, // The index of the touchpad
|
||||||
|
finger: i32, // The index of the finger on the touchpad
|
||||||
|
x: f32, // Normalized in the range 0...1 with 0 being on the left
|
||||||
|
y: f32, // Normalized in the range 0...1 with 0 being at the top
|
||||||
|
pressure: f32, // Normalized in the range 0...1
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const GamepadSensorEvent = extern struct {
|
||||||
|
_type: EventType, // SDL_EVENT_GAMEPAD_SENSOR_UPDATE
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
which: JoystickID, // The joystick instance id
|
||||||
|
sensor: i32, // The type of the sensor, one of the values of SDL_SensorType
|
||||||
|
data: [3]f32, // Up to 3 values from the sensor, as defined in SDL_sensor.h
|
||||||
|
sensor_timestamp: u64, // The timestamp of the sensor reading in nanoseconds, not necessarily synchronized with the system clock
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const AudioDeviceEvent = extern struct {
|
||||||
|
_type: EventType, // SDL_EVENT_AUDIO_DEVICE_ADDED, or SDL_EVENT_AUDIO_DEVICE_REMOVED, or SDL_EVENT_AUDIO_DEVICE_FORMAT_CHANGED
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
which: AudioDeviceID, // SDL_AudioDeviceID for the device being added or removed or changing
|
||||||
|
recording: bool, // false if a playback device, true if a recording device.
|
||||||
|
padding1: u8,
|
||||||
|
padding2: u8,
|
||||||
|
padding3: u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const CameraDeviceEvent = extern struct {
|
||||||
|
_type: EventType, // SDL_EVENT_CAMERA_DEVICE_ADDED, SDL_EVENT_CAMERA_DEVICE_REMOVED, SDL_EVENT_CAMERA_DEVICE_APPROVED, SDL_EVENT_CAMERA_DEVICE_DENIED
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
which: CameraID, // SDL_CameraID for the device being added or removed or changing
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const RenderEvent = extern struct {
|
||||||
|
_type: EventType, // SDL_EVENT_RENDER_TARGETS_RESET, SDL_EVENT_RENDER_DEVICE_RESET, SDL_EVENT_RENDER_DEVICE_LOST
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
windowID: WindowID, // The window containing the renderer in question.
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const TouchFingerEvent = extern struct {
|
||||||
|
_type: EventType, // SDL_EVENT_FINGER_DOWN, SDL_EVENT_FINGER_UP, SDL_EVENT_FINGER_MOTION, or SDL_EVENT_FINGER_CANCELED
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
touchID: TouchID, // The touch device id
|
||||||
|
fingerID: FingerID,
|
||||||
|
x: f32, // Normalized in the range 0...1
|
||||||
|
y: f32, // Normalized in the range 0...1
|
||||||
|
dx: f32, // Normalized in the range -1...1
|
||||||
|
dy: f32, // Normalized in the range -1...1
|
||||||
|
pressure: f32, // Normalized in the range 0...1
|
||||||
|
windowID: WindowID, // The window underneath the finger, if any
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const PenProximityEvent = extern struct {
|
||||||
|
_type: EventType, // SDL_EVENT_PEN_PROXIMITY_IN or SDL_EVENT_PEN_PROXIMITY_OUT
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
windowID: WindowID, // The window with pen focus, if any
|
||||||
|
which: PenID, // The pen instance id
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const PenMotionEvent = extern struct {
|
||||||
|
_type: EventType, // SDL_EVENT_PEN_MOTION
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
windowID: WindowID, // The window with pen focus, if any
|
||||||
|
which: PenID, // The pen instance id
|
||||||
|
pen_state: PenInputFlags, // Complete pen input state at time of event
|
||||||
|
x: f32, // X coordinate, relative to window
|
||||||
|
y: f32, // Y coordinate, relative to window
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const PenTouchEvent = extern struct {
|
||||||
|
_type: EventType, // SDL_EVENT_PEN_DOWN or SDL_EVENT_PEN_UP
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
windowID: WindowID, // The window with pen focus, if any
|
||||||
|
which: PenID, // The pen instance id
|
||||||
|
pen_state: PenInputFlags, // Complete pen input state at time of event
|
||||||
|
x: f32, // X coordinate, relative to window
|
||||||
|
y: f32, // Y coordinate, relative to window
|
||||||
|
eraser: bool, // true if eraser end is used (not all pens support this).
|
||||||
|
down: bool, // true if the pen is touching or false if the pen is lifted off
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const PenButtonEvent = extern struct {
|
||||||
|
_type: EventType, // SDL_EVENT_PEN_BUTTON_DOWN or SDL_EVENT_PEN_BUTTON_UP
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
windowID: WindowID, // The window with mouse focus, if any
|
||||||
|
which: PenID, // The pen instance id
|
||||||
|
pen_state: PenInputFlags, // Complete pen input state at time of event
|
||||||
|
x: f32, // X coordinate, relative to window
|
||||||
|
y: f32, // Y coordinate, relative to window
|
||||||
|
button: u8, // The pen button index (first button is 1).
|
||||||
|
down: bool, // true if the button is pressed
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const PenAxisEvent = extern struct {
|
||||||
|
_type: EventType, // SDL_EVENT_PEN_AXIS
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
windowID: WindowID, // The window with pen focus, if any
|
||||||
|
which: PenID, // The pen instance id
|
||||||
|
pen_state: PenInputFlags, // Complete pen input state at time of event
|
||||||
|
x: f32, // X coordinate, relative to window
|
||||||
|
y: f32, // Y coordinate, relative to window
|
||||||
|
axis: PenAxis, // Axis that has changed
|
||||||
|
value: f32, // New value of axis
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const DropEvent = extern struct {
|
||||||
|
_type: EventType, // SDL_EVENT_DROP_BEGIN or SDL_EVENT_DROP_FILE or SDL_EVENT_DROP_TEXT or SDL_EVENT_DROP_COMPLETE or SDL_EVENT_DROP_POSITION
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
windowID: WindowID, // The window that was dropped on, if any
|
||||||
|
x: f32, // X coordinate, relative to window (not on begin)
|
||||||
|
y: f32, // Y coordinate, relative to window (not on begin)
|
||||||
|
source: [*c]const u8, // The source app that sent this drop event, or NULL if that isn't available
|
||||||
|
data: [*c]const u8, // The text for SDL_EVENT_DROP_TEXT and the file name for SDL_EVENT_DROP_FILE, NULL for other events
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const ClipboardEvent = extern struct {
|
||||||
|
_type: EventType, // SDL_EVENT_CLIPBOARD_UPDATE
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
owner: bool, // are we owning the clipboard (internal update)
|
||||||
|
num_mime_types: i32, // number of mime types
|
||||||
|
mime_types: [*c][*c]const u8, // current mime types
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const SensorEvent = extern struct {
|
||||||
|
_type: EventType, // SDL_EVENT_SENSOR_UPDATE
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
which: SensorID, // The instance ID of the sensor
|
||||||
|
data: [6]f32, // Up to 6 values from the sensor - additional values can be queried using SDL_GetSensorData()
|
||||||
|
sensor_timestamp: u64, // The timestamp of the sensor reading in nanoseconds, not necessarily synchronized with the system clock
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const QuitEvent = extern struct {
|
||||||
|
_type: EventType, // SDL_EVENT_QUIT
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const UserEvent = extern struct {
|
||||||
|
_type: u32, // SDL_EVENT_USER through SDL_EVENT_LAST-1, Uint32 because these are not in the SDL_EventType enumeration
|
||||||
|
reserved: u32,
|
||||||
|
timestamp: u64, // In nanoseconds, populated using SDL_GetTicksNS()
|
||||||
|
windowID: WindowID, // The associated window if any
|
||||||
|
code: i32, // User defined event code
|
||||||
|
data1: ?*anyopaque, // User defined data pointer
|
||||||
|
data2: ?*anyopaque, // User defined data pointer
|
||||||
|
};
|
||||||
|
|
||||||
|
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 inline fn pumpEvents() void {
|
||||||
|
return c.SDL_PumpEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const EventAction = enum(c_int) {
|
||||||
|
addevent, //Add events to the back of the queue.
|
||||||
|
peekevent, //Check but don't remove events from the queue front.
|
||||||
|
getevent, //Retrieve/remove events from the front of the queue.
|
||||||
|
};
|
||||||
|
|
||||||
|
pub inline fn peepEvents(events: ?*Event, numevents: c_int, action: EventAction, minType: u32, maxType: u32) c_int {
|
||||||
|
return c.SDL_PeepEvents(events, numevents, action, minType, maxType);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn hasEvent(_type: u32) bool {
|
||||||
|
return c.SDL_HasEvent(_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn hasEvents(minType: u32, maxType: u32) bool {
|
||||||
|
return c.SDL_HasEvents(minType, maxType);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn flushEvent(_type: u32) void {
|
||||||
|
return c.SDL_FlushEvent(_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn flushEvents(minType: u32, maxType: u32) void {
|
||||||
|
return c.SDL_FlushEvents(minType, maxType);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn pollEvent(event: ?*Event) bool {
|
||||||
|
return c.SDL_PollEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn waitEvent(event: ?*Event) bool {
|
||||||
|
return c.SDL_WaitEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn waitEventTimeout(event: ?*Event, timeoutMS: i32) bool {
|
||||||
|
return c.SDL_WaitEventTimeout(event, timeoutMS);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn pushEvent(event: ?*Event) bool {
|
||||||
|
return c.SDL_PushEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const EventFilter = c.SDL_EventFilter;
|
||||||
|
|
||||||
|
pub inline fn setEventFilter(filter: EventFilter, userdata: ?*anyopaque) void {
|
||||||
|
return c.SDL_SetEventFilter(filter, userdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn getEventFilter(filter: ?*EventFilter, userdata: [*c]?*anyopaque) bool {
|
||||||
|
return c.SDL_GetEventFilter(filter, userdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn addEventWatch(filter: EventFilter, userdata: ?*anyopaque) bool {
|
||||||
|
return c.SDL_AddEventWatch(filter, userdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn removeEventWatch(filter: EventFilter, userdata: ?*anyopaque) void {
|
||||||
|
return c.SDL_RemoveEventWatch(filter, userdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn filterEvents(filter: EventFilter, userdata: ?*anyopaque) void {
|
||||||
|
return c.SDL_FilterEvents(filter, userdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn setEventEnabled(_type: u32, enabled: bool) void {
|
||||||
|
return c.SDL_SetEventEnabled(_type, enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn eventEnabled(_type: u32) bool {
|
||||||
|
return c.SDL_EventEnabled(_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn registerEvents(numevents: c_int) u32 {
|
||||||
|
return c.SDL_RegisterEvents(numevents);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn getWindowFromEvent(event: *const Event) ?*Window {
|
||||||
|
return c.SDL_GetWindowFromEvent(@ptrCast(event));
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
pub const c = @import("c.zig").c;
|
pub const c = @import("c.zig").c;
|
||||||
|
|
||||||
pub const FunctionPointer = ?*anyopaque;
|
pub const FunctionPointer = c.SDL_FunctionPointer;
|
||||||
|
|
||||||
pub const SharedObject = opaque {
|
pub const SharedObject = opaque {
|
||||||
pub inline fn loadFunction(sharedobject: *SharedObject, name: [*c]const u8) FunctionPointer {
|
pub inline fn loadFunction(sharedobject: *SharedObject, name: [*c]const u8) FunctionPointer {
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,114 @@
|
||||||
|
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 PathType = enum(c_int) {
|
||||||
|
pathtypeNone, //path does not exist
|
||||||
|
pathtypeFile, //a normal file
|
||||||
|
pathtypeDirectory, //a directory
|
||||||
|
pathtypeOther,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Time = i64;
|
||||||
|
|
||||||
|
pub const GlobFlags = packed struct(u32) {
|
||||||
|
globCaseinsensitive: bool = false,
|
||||||
|
pad0: u30 = 0,
|
||||||
|
rsvd: bool = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const EnumerateDirectoryCallback = c.SDL_EnumerateDirectoryCallback;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,325 @@
|
||||||
|
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 Color = extern struct {
|
||||||
|
r: u8,
|
||||||
|
g: u8,
|
||||||
|
b: u8,
|
||||||
|
a: u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
@ -30,7 +30,7 @@ pub const Rect = extern struct {
|
||||||
h: c_int,
|
h: c_int,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const FunctionPointer = ?*anyopaque;
|
pub const FunctionPointer = c.SDL_FunctionPointer;
|
||||||
|
|
||||||
pub const DisplayID = u32;
|
pub const DisplayID = u32;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue