diff --git a/lib/sdl3/parser/src/patterns.zig b/lib/sdl3/parser/src/patterns.zig index 978a21a..6925b17 100644 --- a/lib/sdl3/parser/src/patterns.zig +++ b/lib/sdl3/parser/src/patterns.zig @@ -172,11 +172,25 @@ pub const Scanner = struct { }; // Check they match and end with semicolon + // Or accept mismatched names as long as we have a semicolon (e.g., typedef struct tagMSG MSG;) + // But reject pointer typedefs (e.g., typedef struct X *Y;) - those should be handled by scanTypedef const name2_clean = std.mem.trimRight(u8, name2, ";"); - if (!std.mem.eql(u8, name1, name2_clean)) { + + // Check if it's a pointer typedef - if either name starts with *, reject it + if (std.mem.startsWith(u8, name1, "*") or std.mem.startsWith(u8, name2_clean, "*")) { self.pos = start; return null; } + + const use_name = if (std.mem.eql(u8, name1, name2_clean)) + name1 // Names match, use either + else if (std.mem.endsWith(u8, name2, ";")) + name2_clean // Names don't match but it's a valid forward declaration, use second name + else { + // Not a valid opaque typedef + self.pos = start; + return null; + }; // This is an opaque type (not a struct definition with braces) // Make sure it doesn't have braces @@ -185,7 +199,7 @@ pub const Scanner = struct { return null; } - const name = try self.allocator.dupe(u8, name1); + const name = try self.allocator.dupe(u8, use_name); const doc = self.consumePendingDocComment(); return OpaqueType{ @@ -293,10 +307,19 @@ pub const Scanner = struct { return null; } - // Skip lines with "struct" or "enum" keywords (also handled elsewhere) - if (std.mem.indexOf(u8, line, "struct ") != null or std.mem.indexOf(u8, line, "enum ") != null) { - self.pos = start; - return null; + // Skip lines with "struct" or "enum" keywords UNLESS it's a pointer typedef like: + // typedef struct X *Y; + const has_struct_or_enum = std.mem.indexOf(u8, line, "struct ") != null or std.mem.indexOf(u8, line, "enum ") != null; + if (has_struct_or_enum) { + // Check if it's a pointer typedef: should have * before the final name + const trimmed_check = std.mem.trim(u8, line, " \t\r\n;"); + const has_pointer = std.mem.indexOf(u8, trimmed_check, " *") != null; + if (!has_pointer) { + // Not a pointer typedef, skip it + self.pos = start; + return null; + } + // It's a pointer typedef like "typedef struct X *Y", continue parsing } // Skip function pointer typedefs (contain parentheses) @@ -305,26 +328,61 @@ pub const Scanner = struct { return null; } - // Parse: typedef Type Name; + // Parse: typedef Type Name; or typedef struct X *Name; const trimmed = std.mem.trim(u8, line, " \t\r\n"); const no_semi = std.mem.trimRight(u8, trimmed, ";"); - // Split into tokens + // Find the last token as the name var tokens = std.mem.tokenizeScalar(u8, no_semi, ' '); _ = tokens.next(); // Skip "typedef" - const underlying_type = tokens.next() orelse { + // Collect all remaining tokens + var token_list = std.ArrayList([]const u8).initCapacity(self.allocator, 4) catch { self.pos = start; return null; }; + defer token_list.deinit(self.allocator); + while (tokens.next()) |token| { + try token_list.append(self.allocator, token); + } - const name = tokens.next() orelse { + if (token_list.items.len < 2) { + self.pos = start; + return null; + } + + // Last token is the name (may have * prefix for pointer typedefs) + var name_raw = token_list.items[token_list.items.len - 1]; + // Strip leading * if present and track it + const has_pointer_prefix = std.mem.startsWith(u8, name_raw, "*"); + const name = if (has_pointer_prefix) + name_raw[1..] + else + name_raw; + + // Everything before the name is the underlying type + // For "struct XTaskQueueObject *XTaskQueueHandle", we want "struct XTaskQueueObject *" + var type_buf = std.ArrayList(u8).initCapacity(self.allocator, 64) catch { self.pos = start; return null; }; + defer type_buf.deinit(self.allocator); + for (token_list.items[0..token_list.items.len - 1], 0..) |token, i| { + if (i > 0) try type_buf.append(self.allocator, ' '); + try type_buf.appendSlice(self.allocator, token); + } + // Add the * if it was part of the name token + if (has_pointer_prefix) { + try type_buf.append(self.allocator, ' '); + try type_buf.append(self.allocator, '*'); + } + const underlying_type = try type_buf.toOwnedSlice(self.allocator); - // Make sure it's an SDL type - if (!std.mem.startsWith(u8, name, "SDL_")) { + // Make sure it's an SDL type or one of the known Windows types + if (!std.mem.startsWith(u8, name, "SDL_") and + !std.mem.eql(u8, name, "XTaskQueueHandle") and + !std.mem.eql(u8, name, "XUserHandle")) { + self.allocator.free(underlying_type); self.pos = start; return null; } @@ -345,12 +403,19 @@ pub const Scanner = struct { } // Find the opening brace and extract the name before it + // But stop if we hit a semicolon (indicates forward declaration) + // Allow newlines/whitespace before the brace const name_start = self.pos; + var found_semicolon = false; while (self.pos < self.source.len and self.source[self.pos] != '{') { + if (self.source[self.pos] == ';') { + found_semicolon = true; + break; + } self.pos += 1; } - if (self.pos >= self.source.len) { + if (self.pos >= self.source.len or found_semicolon or self.source[self.pos] != '{') { self.pos = start; return null; } @@ -478,13 +543,20 @@ pub const Scanner = struct { } // Find the opening brace and extract the name before it + // But stop if we hit a semicolon (indicates forward declaration) + // Allow newlines/whitespace before the brace const name_start = self.pos; + var found_semicolon = false; while (self.pos < self.source.len and self.source[self.pos] != '{') { + if (self.source[self.pos] == ';') { + found_semicolon = true; + break; + } self.pos += 1; } - if (self.pos >= self.source.len) { - // No opening brace found - this is an opaque type, not a struct + if (self.pos >= self.source.len or found_semicolon or self.source[self.pos] != '{') { + // No opening brace found - this is an opaque type or forward declaration self.pos = start; return null; } @@ -570,12 +642,19 @@ pub const Scanner = struct { } // Find the opening brace and extract the name before it + // But stop if we hit a semicolon (indicates forward declaration) + // Allow newlines/whitespace before the brace const name_start = self.pos; + var found_semicolon = false; while (self.pos < self.source.len and self.source[self.pos] != '{') { + if (self.source[self.pos] == ';') { + found_semicolon = true; + break; + } self.pos += 1; } - if (self.pos >= self.source.len) { + if (self.pos >= self.source.len or found_semicolon or self.source[self.pos] != '{') { // No opening brace found - this is an opaque type, not a union self.pos = start; return null; diff --git a/lib/sdl3/parser/src/types.zig b/lib/sdl3/parser/src/types.zig index 63042d1..f313228 100644 --- a/lib/sdl3/parser/src/types.zig +++ b/lib/sdl3/parser/src/types.zig @@ -6,6 +6,11 @@ const Allocator = std.mem.Allocator; pub fn convertType(c_type: []const u8, allocator: Allocator) ![]const u8 { const trimmed = std.mem.trim(u8, c_type, " \t"); + // Handle opaque struct pointers: "struct X *" -> "*anyopaque" + if (std.mem.startsWith(u8, trimmed, "struct ") and std.mem.endsWith(u8, trimmed, " *")) { + return try allocator.dupe(u8, "*anyopaque"); + } + // Handle function pointers: For now, just return as placeholder until we implement full conversion if (std.mem.indexOf(u8, trimmed, "(SDLCALL *") != null or std.mem.indexOf(u8, trimmed, "(*") != null) { // TODO: Implement full function pointer conversion @@ -63,15 +68,15 @@ pub fn convertType(c_type: []const u8, allocator: Allocator) ![]const u8 { if (std.mem.eql(u8, trimmed, "const int *")) return try allocator.dupe(u8, "[*c]const c_int"); // Handle SDL types with pointers - // Check for double pointers like "SDL_Type **" + // Check for double pointers like "SDL_Type **" or "SDL_Type * const *" if (std.mem.startsWith(u8, trimmed, "SDL_")) { + if (std.mem.indexOf(u8, trimmed, " * const *")) |pos| { + const base_type = trimmed[4..pos]; // Remove SDL_ prefix and get type + return std.fmt.allocPrint(allocator, "[*c]const *{s}", .{base_type}); + } if (std.mem.indexOf(u8, trimmed, " **")) |pos| { const base_type = trimmed[4..pos]; // Remove SDL_ prefix and get type - return std.fmt.allocPrint(allocator, "?*?*{s}", .{base_type}); - } - if (std.mem.indexOf(u8, trimmed, " *const *")) |pos| { - const base_type = trimmed[4..pos]; // Remove SDL_ prefix and get type - return std.fmt.allocPrint(allocator, "[*c]*const {s}", .{base_type}); + return std.fmt.allocPrint(allocator, "[*c][*c]{s}", .{base_type}); } } diff --git a/lib/sdl3/v2/audio.zig b/lib/sdl3/v2/audio.zig index a5613d3..cf6adc2 100644 --- a/lib/sdl3/v2/audio.zig +++ b/lib/sdl3/v2/audio.zig @@ -7,7 +7,6 @@ pub const IOStream = opaque { pub inline fn loadWAV_IO(iostream: *IOStream, closeio: bool, spec: ?*AudioSpec, audio_buf: [*c][*c]u8, audio_len: *u32) bool { return c.SDL_LoadWAV_IO(iostream, closeio, spec, audio_buf, @ptrCast(audio_len)); } - }; pub const AudioFormat = enum(c_int) { @@ -132,7 +131,6 @@ pub const AudioStream = opaque { pub inline fn destroyAudioStream(audiostream: *AudioStream) void { return c.SDL_DestroyAudioStream(audiostream); } - }; pub inline fn getNumAudioDrivers() c_int { @@ -203,7 +201,7 @@ pub inline fn closeAudioDevice(devid: AudioDeviceID) void { return c.SDL_CloseAudioDevice(devid); } -pub inline fn bindAudioStreams(devid: AudioDeviceID, streams: ?*AudioStream * const, num_streams: c_int) bool { +pub inline fn bindAudioStreams(devid: AudioDeviceID, streams: [*c]const *AudioStream, num_streams: c_int) bool { return c.SDL_BindAudioStreams(devid, streams, num_streams); } @@ -211,7 +209,7 @@ pub inline fn bindAudioStream(devid: AudioDeviceID, stream: ?*AudioStream) bool return c.SDL_BindAudioStream(devid, stream); } -pub inline fn unbindAudioStreams(streams: ?*AudioStream * const, num_streams: c_int) void { +pub inline fn unbindAudioStreams(streams: [*c]const *AudioStream, num_streams: c_int) void { return c.SDL_UnbindAudioStreams(streams, num_streams); } @@ -219,13 +217,13 @@ pub inline fn createAudioStream(src_spec: *const AudioSpec, dst_spec: *const Aud return c.SDL_CreateAudioStream(@ptrCast(src_spec), @ptrCast(dst_spec)); } -pub const AudioStreamCallback = *const fn(userdata: ?*anyopaque, stream: ?*AudioStream, additional_amount: c_int, total_amount: c_int) callconv(.C) void; +pub const AudioStreamCallback = *const fn (userdata: ?*anyopaque, stream: ?*AudioStream, additional_amount: c_int, total_amount: c_int) callconv(.C) void; pub inline fn openAudioDeviceStream(devid: AudioDeviceID, spec: *const AudioSpec, callback: AudioStreamCallback, userdata: ?*anyopaque) ?*AudioStream { return c.SDL_OpenAudioDeviceStream(devid, @ptrCast(spec), callback, userdata); } -pub const AudioPostmixCallback = *const fn(userdata: ?*anyopaque, spec: *const AudioSpec, buffer: *f32, buflen: c_int) callconv(.C) void; +pub const AudioPostmixCallback = *const fn (userdata: ?*anyopaque, spec: *const AudioSpec, buffer: *f32, buflen: c_int) callconv(.C) void; pub inline fn setAudioPostmixCallback(devid: AudioDeviceID, callback: AudioPostmixCallback, userdata: ?*anyopaque) bool { return c.SDL_SetAudioPostmixCallback(devid, callback, userdata); @@ -250,4 +248,3 @@ pub inline fn getAudioFormatName(format: AudioFormat) [*c]const u8 { pub inline fn getSilenceValueForFormat(format: AudioFormat) c_int { return c.SDL_GetSilenceValueForFormat(@bitCast(format)); } - diff --git a/lib/sdl3/v2/camera.zig b/lib/sdl3/v2/camera.zig index 014c157..0db398f 100644 --- a/lib/sdl3/v2/camera.zig +++ b/lib/sdl3/v2/camera.zig @@ -138,7 +138,7 @@ pub inline fn getCameras(count: *c_int) ?*CameraID { return c.SDL_GetCameras(@ptrCast(count)); } -pub inline fn getCameraSupportedFormats(instance_id: CameraID, count: *c_int) ?*?*CameraSpec { +pub inline fn getCameraSupportedFormats(instance_id: CameraID, count: *c_int) [*c][*c]CameraSpec { return c.SDL_GetCameraSupportedFormats(instance_id, @ptrCast(count)); } diff --git a/lib/sdl3/v2/gamepad.zig b/lib/sdl3/v2/gamepad.zig index 379e5c3..332e6b1 100644 --- a/lib/sdl3/v2/gamepad.zig +++ b/lib/sdl3/v2/gamepad.zig @@ -101,7 +101,7 @@ pub const Gamepad = opaque { return c.SDL_GetGamepadJoystick(gamepad); } - pub inline fn getGamepadBindings(gamepad: *Gamepad, count: *c_int) ?*?*GamepadBinding { + pub inline fn getGamepadBindings(gamepad: *Gamepad, count: *c_int) [*c][*c]GamepadBinding { return c.SDL_GetGamepadBindings(gamepad, @ptrCast(count)); } diff --git a/lib/sdl3/v2/gpu.zig b/lib/sdl3/v2/gpu.zig index 1f8a5e0..5b59b53 100644 --- a/lib/sdl3/v2/gpu.zig +++ b/lib/sdl3/v2/gpu.zig @@ -144,7 +144,7 @@ pub const GPUDevice = opaque { return c.SDL_WaitForGPUIdle(gpudevice); } - pub inline fn waitForGPUFences(gpudevice: *GPUDevice, wait_all: bool, fences: [*c]*const GPUFence, num_fences: u32) bool { + pub inline fn waitForGPUFences(gpudevice: *GPUDevice, wait_all: bool, fences: ?*GPUFence *const, num_fences: u32) bool { return c.SDL_WaitForGPUFences(gpudevice, wait_all, fences, num_fences); } @@ -171,6 +171,7 @@ pub const GPUDevice = opaque { pub inline fn gdkResumeGPU(gpudevice: *GPUDevice) void { return c.SDL_GDKResumeGPU(gpudevice); } + }; pub const GPUBuffer = opaque {}; @@ -232,11 +233,11 @@ pub const GPUCommandBuffer = opaque { return c.SDL_BlitGPUTexture(gpucommandbuffer, @ptrCast(info)); } - pub inline fn acquireGPUSwapchainTexture(gpucommandbuffer: *GPUCommandBuffer, window: ?*Window, swapchain_texture: ?*?*GPUTexture, swapchain_texture_width: *u32, swapchain_texture_height: *u32) bool { + pub inline fn acquireGPUSwapchainTexture(gpucommandbuffer: *GPUCommandBuffer, window: ?*Window, swapchain_texture: [*c][*c]GPUTexture, swapchain_texture_width: *u32, swapchain_texture_height: *u32) bool { return c.SDL_AcquireGPUSwapchainTexture(gpucommandbuffer, window, swapchain_texture, @ptrCast(swapchain_texture_width), @ptrCast(swapchain_texture_height)); } - pub inline fn waitAndAcquireGPUSwapchainTexture(gpucommandbuffer: *GPUCommandBuffer, window: ?*Window, swapchain_texture: ?*?*GPUTexture, swapchain_texture_width: *u32, swapchain_texture_height: *u32) bool { + pub inline fn waitAndAcquireGPUSwapchainTexture(gpucommandbuffer: *GPUCommandBuffer, window: ?*Window, swapchain_texture: [*c][*c]GPUTexture, swapchain_texture_width: *u32, swapchain_texture_height: *u32) bool { return c.SDL_WaitAndAcquireGPUSwapchainTexture(gpucommandbuffer, window, swapchain_texture, @ptrCast(swapchain_texture_width), @ptrCast(swapchain_texture_height)); } @@ -251,6 +252,7 @@ pub const GPUCommandBuffer = opaque { pub inline fn cancelGPUCommandBuffer(gpucommandbuffer: *GPUCommandBuffer) bool { return c.SDL_CancelGPUCommandBuffer(gpucommandbuffer); } + }; pub const GPURenderPass = opaque { @@ -286,11 +288,11 @@ pub const GPURenderPass = opaque { return c.SDL_BindGPUVertexSamplers(gpurenderpass, first_slot, @ptrCast(texture_sampler_bindings), num_bindings); } - pub inline fn bindGPUVertexStorageTextures(gpurenderpass: *GPURenderPass, first_slot: u32, storage_textures: [*c]*const GPUTexture, num_bindings: u32) void { + pub inline fn bindGPUVertexStorageTextures(gpurenderpass: *GPURenderPass, first_slot: u32, storage_textures: ?*GPUTexture *const, num_bindings: u32) void { return c.SDL_BindGPUVertexStorageTextures(gpurenderpass, first_slot, storage_textures, num_bindings); } - pub inline fn bindGPUVertexStorageBuffers(gpurenderpass: *GPURenderPass, first_slot: u32, storage_buffers: [*c]*const GPUBuffer, num_bindings: u32) void { + pub inline fn bindGPUVertexStorageBuffers(gpurenderpass: *GPURenderPass, first_slot: u32, storage_buffers: ?*GPUBuffer *const, num_bindings: u32) void { return c.SDL_BindGPUVertexStorageBuffers(gpurenderpass, first_slot, storage_buffers, num_bindings); } @@ -298,11 +300,11 @@ pub const GPURenderPass = opaque { return c.SDL_BindGPUFragmentSamplers(gpurenderpass, first_slot, @ptrCast(texture_sampler_bindings), num_bindings); } - pub inline fn bindGPUFragmentStorageTextures(gpurenderpass: *GPURenderPass, first_slot: u32, storage_textures: [*c]*const GPUTexture, num_bindings: u32) void { + pub inline fn bindGPUFragmentStorageTextures(gpurenderpass: *GPURenderPass, first_slot: u32, storage_textures: ?*GPUTexture *const, num_bindings: u32) void { return c.SDL_BindGPUFragmentStorageTextures(gpurenderpass, first_slot, storage_textures, num_bindings); } - pub inline fn bindGPUFragmentStorageBuffers(gpurenderpass: *GPURenderPass, first_slot: u32, storage_buffers: [*c]*const GPUBuffer, num_bindings: u32) void { + pub inline fn bindGPUFragmentStorageBuffers(gpurenderpass: *GPURenderPass, first_slot: u32, storage_buffers: ?*GPUBuffer *const, num_bindings: u32) void { return c.SDL_BindGPUFragmentStorageBuffers(gpurenderpass, first_slot, storage_buffers, num_bindings); } @@ -325,6 +327,7 @@ pub const GPURenderPass = opaque { pub inline fn endGPURenderPass(gpurenderpass: *GPURenderPass) void { return c.SDL_EndGPURenderPass(gpurenderpass); } + }; pub const GPUComputePass = opaque { @@ -336,11 +339,11 @@ pub const GPUComputePass = opaque { return c.SDL_BindGPUComputeSamplers(gpucomputepass, first_slot, @ptrCast(texture_sampler_bindings), num_bindings); } - pub inline fn bindGPUComputeStorageTextures(gpucomputepass: *GPUComputePass, first_slot: u32, storage_textures: [*c]*const GPUTexture, num_bindings: u32) void { + pub inline fn bindGPUComputeStorageTextures(gpucomputepass: *GPUComputePass, first_slot: u32, storage_textures: ?*GPUTexture *const, num_bindings: u32) void { return c.SDL_BindGPUComputeStorageTextures(gpucomputepass, first_slot, storage_textures, num_bindings); } - pub inline fn bindGPUComputeStorageBuffers(gpucomputepass: *GPUComputePass, first_slot: u32, storage_buffers: [*c]*const GPUBuffer, num_bindings: u32) void { + pub inline fn bindGPUComputeStorageBuffers(gpucomputepass: *GPUComputePass, first_slot: u32, storage_buffers: ?*GPUBuffer *const, num_bindings: u32) void { return c.SDL_BindGPUComputeStorageBuffers(gpucomputepass, first_slot, storage_buffers, num_bindings); } @@ -355,6 +358,7 @@ pub const GPUComputePass = opaque { pub inline fn endGPUComputePass(gpucomputepass: *GPUComputePass) void { return c.SDL_EndGPUComputePass(gpucomputepass); } + }; pub const GPUCopyPass = opaque { @@ -385,6 +389,7 @@ pub const GPUCopyPass = opaque { pub inline fn endGPUCopyPass(gpucopypass: *GPUCopyPass) void { return c.SDL_EndGPUCopyPass(gpucopypass); } + }; pub const GPUFence = opaque {}; @@ -976,3 +981,4 @@ pub inline fn gpuTextureFormatTexelBlockSize(format: GPUTextureFormat) u32 { pub inline fn calculateGPUTextureFormatSize(format: GPUTextureFormat, width: u32, height: u32, depth_or_layer_count: u32) u32 { return c.SDL_CalculateGPUTextureFormatSize(@bitCast(format), width, height, depth_or_layer_count); } + diff --git a/lib/sdl3/v2/loadso.zig b/lib/sdl3/v2/loadso.zig index e326ea4..b59c408 100644 --- a/lib/sdl3/v2/loadso.zig +++ b/lib/sdl3/v2/loadso.zig @@ -1,6 +1,8 @@ const std = @import("std"); pub const c = @import("c.zig").c; +pub const FunctionPointer = ?*anyopaque; + pub const SharedObject = opaque { pub inline fn loadFunction(sharedobject: *SharedObject, name: [*c]const u8) FunctionPointer { return c.SDL_LoadFunction(sharedobject, name); diff --git a/lib/sdl3/v2/locale.zig b/lib/sdl3/v2/locale.zig index 2f8fa01..8d43006 100644 --- a/lib/sdl3/v2/locale.zig +++ b/lib/sdl3/v2/locale.zig @@ -6,6 +6,6 @@ pub const Locale = extern struct { country: [*c]const u8, // A country, like "US" for America. Can be NULL. }; -pub inline fn getPreferredLocales(count: *c_int) ?*?*Locale { +pub inline fn getPreferredLocales(count: *c_int) [*c][*c]Locale { return c.SDL_GetPreferredLocales(@ptrCast(count)); } diff --git a/lib/sdl3/v2/metal.zig b/lib/sdl3/v2/metal.zig index 5326e5a..2dd490d 100644 --- a/lib/sdl3/v2/metal.zig +++ b/lib/sdl3/v2/metal.zig @@ -7,6 +7,8 @@ pub const Window = opaque { } }; +pub const MetalView = ?*anyopaque; + pub inline fn metal_DestroyView(view: MetalView) void { return c.SDL_Metal_DestroyView(view); } diff --git a/lib/sdl3/v2/render.zig b/lib/sdl3/v2/render.zig index 799d0d1..d55ca53 100644 --- a/lib/sdl3/v2/render.zig +++ b/lib/sdl3/v2/render.zig @@ -519,7 +519,7 @@ pub const Texture = opaque { return c.SDL_LockTexture(texture, @ptrCast(rect), pixels, @ptrCast(pitch)); } - pub inline fn lockTextureToSurface(texture: *Texture, rect: *const Rect, surface: ?*?*Surface) bool { + pub inline fn lockTextureToSurface(texture: *Texture, rect: *const Rect, surface: [*c][*c]Surface) bool { return c.SDL_LockTextureToSurface(texture, @ptrCast(rect), surface); } @@ -540,7 +540,7 @@ pub inline fn getRenderDriver(index: c_int) [*c]const u8 { return c.SDL_GetRenderDriver(index); } -pub inline fn createWindowAndRenderer(title: [*c]const u8, width: c_int, height: c_int, window_flags: WindowFlags, window: ?*?*Window, renderer: ?*?*Renderer) bool { +pub inline fn createWindowAndRenderer(title: [*c]const u8, width: c_int, height: c_int, window_flags: WindowFlags, window: [*c][*c]Window, renderer: [*c][*c]Renderer) bool { return c.SDL_CreateWindowAndRenderer(title, width, height, @bitCast(window_flags), window, renderer); } diff --git a/lib/sdl3/v2/surface.zig b/lib/sdl3/v2/surface.zig index c0b4114..4803e32 100644 --- a/lib/sdl3/v2/surface.zig +++ b/lib/sdl3/v2/surface.zig @@ -145,7 +145,7 @@ pub const Surface = opaque { return c.SDL_SurfaceHasAlternateImages(surface); } - pub inline fn getSurfaceImages(surface: *Surface, count: *c_int) ?*?*Surface { + pub inline fn getSurfaceImages(surface: *Surface, count: *c_int) [*c][*c]Surface { return c.SDL_GetSurfaceImages(surface, @ptrCast(count)); } diff --git a/lib/sdl3/v2/system.zig b/lib/sdl3/v2/system.zig index 658cd40..4b5521b 100644 --- a/lib/sdl3/v2/system.zig +++ b/lib/sdl3/v2/system.zig @@ -1,8 +1,118 @@ const std = @import("std"); pub const c = @import("c.zig").c; -pub const tagMSG = extern struct { - 0: SANDBOX_NONE =, +pub const DisplayID = u32; + +pub const Window = opaque { + pub inline fn setiOSAnimationCallback(window: *Window, interval: c_int, callback: iOSAnimationCallback, callbackParam: ?*anyopaque) bool { + return c.SDL_SetiOSAnimationCallback(window, interval, callback, callbackParam); + } +}; + +pub const MSG = opaque {}; + +pub const WindowsMessageHook = *const fn (userdata: ?*anyopaque, msg: [*c]MSG) callconv(.C) bool; + +pub inline fn setWindowsMessageHook(callback: WindowsMessageHook, userdata: ?*anyopaque) void { + return c.SDL_SetWindowsMessageHook(callback, userdata); +} + +pub inline fn getDirect3D9AdapterIndex(displayID: DisplayID) c_int { + return c.SDL_GetDirect3D9AdapterIndex(displayID); +} + +pub inline fn getDXGIOutputInfo(displayID: DisplayID, adapterIndex: *c_int, outputIndex: *c_int) bool { + return c.SDL_GetDXGIOutputInfo(displayID, @ptrCast(adapterIndex), @ptrCast(outputIndex)); +} + +pub const X11EventHook = *const fn (userdata: ?*anyopaque, xevent: [*c]XEvent) callconv(.C) bool; + +pub inline fn setX11EventHook(callback: X11EventHook, userdata: ?*anyopaque) void { + return c.SDL_SetX11EventHook(callback, userdata); +} + +pub inline fn setLinuxThreadPriority(threadID: i64, priority: c_int) bool { + return c.SDL_SetLinuxThreadPriority(threadID, priority); +} + +pub inline fn setLinuxThreadPriorityAndPolicy(threadID: i64, sdlPriority: c_int, schedPolicy: c_int) bool { + return c.SDL_SetLinuxThreadPriorityAndPolicy(threadID, sdlPriority, schedPolicy); +} + +pub const iOSAnimationCallback = *const fn (userdata: ?*anyopaque) callconv(.C) void; + +pub inline fn setiOSEventPump(enabled: bool) void { + return c.SDL_SetiOSEventPump(enabled); +} + +pub inline fn getAndroidJNIEnv() ?*anyopaque { + return c.SDL_GetAndroidJNIEnv(); +} + +pub inline fn getAndroidActivity() ?*anyopaque { + return c.SDL_GetAndroidActivity(); +} + +pub inline fn getAndroidSDKVersion() c_int { + return c.SDL_GetAndroidSDKVersion(); +} + +pub inline fn isChromebook() bool { + return c.SDL_IsChromebook(); +} + +pub inline fn isDeXMode() bool { + return c.SDL_IsDeXMode(); +} + +pub inline fn sendAndroidBackButton() void { + return c.SDL_SendAndroidBackButton(); +} + +pub inline fn getAndroidInternalStoragePath() [*c]const u8 { + return c.SDL_GetAndroidInternalStoragePath(); +} + +pub inline fn getAndroidExternalStorageState() u32 { + return c.SDL_GetAndroidExternalStorageState(); +} + +pub inline fn getAndroidExternalStoragePath() [*c]const u8 { + return c.SDL_GetAndroidExternalStoragePath(); +} + +pub inline fn getAndroidCachePath() [*c]const u8 { + return c.SDL_GetAndroidCachePath(); +} + +pub const RequestAndroidPermissionCallback = *const fn (userdata: ?*anyopaque, permission: [*c]const u8, granted: bool) callconv(.C) void; + +pub inline fn requestAndroidPermission(permission: [*c]const u8, cb: RequestAndroidPermissionCallback, userdata: ?*anyopaque) bool { + return c.SDL_RequestAndroidPermission(permission, cb, userdata); +} + +pub inline fn showAndroidToast(message: [*c]const u8, duration: c_int, gravity: c_int, xoffset: c_int, yoffset: c_int) bool { + return c.SDL_ShowAndroidToast(message, duration, gravity, xoffset, yoffset); +} + +pub inline fn sendAndroidMessage(command: u32, param: c_int) bool { + return c.SDL_SendAndroidMessage(command, param); +} + +pub inline fn isTablet() bool { + return c.SDL_IsTablet(); +} + +pub inline fn isTV() bool { + return c.SDL_IsTV(); +} + +pub const Sandbox = enum(c_int) { + sandboxNone, + sandboxUnknownContainer, + sandboxFlatpak, + sandboxSnap, + sandboxMacos, }; pub inline fn getSandbox() Sandbox { @@ -37,6 +147,10 @@ pub inline fn onApplicationDidChangeStatusBarOrientation() void { return c.SDL_OnApplicationDidChangeStatusBarOrientation(); } +pub const XTaskQueueHandle = *anyopaque; + +pub const XUserHandle = *anyopaque; + pub inline fn getGDKTaskQueue(outTaskQueue: [*c]XTaskQueueHandle) bool { return c.SDL_GetGDKTaskQueue(outTaskQueue); } @@ -44,4 +158,3 @@ pub inline fn getGDKTaskQueue(outTaskQueue: [*c]XTaskQueueHandle) bool { pub inline fn getGDKDefaultUser(outUserHandle: [*c]XUserHandle) bool { return c.SDL_GetGDKDefaultUser(outUserHandle); } - diff --git a/lib/sdl3/v2/touch.zig b/lib/sdl3/v2/touch.zig index 2343cd1..5e45ccc 100644 --- a/lib/sdl3/v2/touch.zig +++ b/lib/sdl3/v2/touch.zig @@ -28,6 +28,6 @@ pub inline fn getTouchDeviceType(touchID: TouchID) TouchDeviceType { return @intFromEnum(c.SDL_GetTouchDeviceType(touchID)); } -pub inline fn getTouchFingers(touchID: TouchID, count: *c_int) ?*?*Finger { +pub inline fn getTouchFingers(touchID: TouchID, count: *c_int) [*c][*c]Finger { return c.SDL_GetTouchFingers(touchID, @ptrCast(count)); } diff --git a/lib/sdl3/v2/video.zig b/lib/sdl3/v2/video.zig index 331e3a5..0e1d7f3 100644 --- a/lib/sdl3/v2/video.zig +++ b/lib/sdl3/v2/video.zig @@ -83,6 +83,8 @@ pub const Rect = extern struct { h: c_int, }; +pub const FunctionPointer = ?*anyopaque; + pub const DisplayID = u32; pub const WindowID = u32; @@ -397,7 +399,27 @@ pub const WindowFlags = packed struct(u64) { rsvd: bool = false, }; -pub const GLContextState = extern struct {}; +pub const GLContext = *anyopaque; + +pub const EGLDisplay = ?*anyopaque; + +pub const EGLConfig = ?*anyopaque; + +pub const EGLSurface = ?*anyopaque; + +pub const EGLAttrib = intptr_t; + +pub const EGLint = c_int; + +pub const EGLAttribArrayCallback = *const fn (userdata: ?*anyopaque) callconv(.C) ?*EGLAttrib; + +pub const EGLIntArrayCallback = *const fn (userdata: ?*anyopaque, display: EGLDisplay, config: EGLConfig) callconv(.C) ?*EGLint; + +pub const GLAttr = enum(c_int) { + glContextNoError, + glFloatbuffers, + glEglPlatform, +}; pub const GLProfile = u32; @@ -459,7 +481,7 @@ pub inline fn getDisplayContentScale(displayID: DisplayID) f32 { return c.SDL_GetDisplayContentScale(displayID); } -pub inline fn getFullscreenDisplayModes(displayID: DisplayID, count: *c_int) ?*?*DisplayMode { +pub inline fn getFullscreenDisplayModes(displayID: DisplayID, count: *c_int) [*c][*c]DisplayMode { return @intFromEnum(c.SDL_GetFullscreenDisplayModes(displayID, @ptrCast(count))); } @@ -483,7 +505,7 @@ pub inline fn getDisplayForRect(rect: *const Rect) DisplayID { return c.SDL_GetDisplayForRect(@ptrCast(rect)); } -pub inline fn getWindows(count: *c_int) ?*?*Window { +pub inline fn getWindows(count: *c_int) [*c][*c]Window { return c.SDL_GetWindows(@ptrCast(count)); }