diff --git a/AGENTS.md b/AGENTS.md index 97060f1..b148314 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -124,11 +124,43 @@ The code generator automatically adds appropriate casts when calling C functions - Booleans → `@bitCast` - Flags (packed structs) → `@bitCast` +**Pointer Optionality:** +- All pointer parameters in standalone functions are optional (`?*const Type`) to allow null values +- The first parameter in methods (the "self" parameter) is non-optional (`*Type`) +- Other parameters in methods are optional (`?*const Type`) + +**Double Pointers to Opaque Types:** +C double pointers like `SDL_Window **` are converted to `[*c]?*Window` instead of `[*c][*c]Window` because: +1. Zig doesn't allow C pointers (`[*c]`) to point to opaque types +2. The inner pointer should be optional since C pointers can be null + +The outer pointer remains a C pointer for interop, while the inner pointer is an optional Zig pointer. + +Similarly, `const void * const *` is converted to `[*c]const *anyopaque` (not `[*c]const [*c]const anyopaque`). + Example: ```zig -pub inline fn createWindow(title: [*c]const u8, w: c_int, h: c_int, flags: WindowFlags) ?*Window { - return @ptrCast(c.SDL_CreateWindow(title, w, h, @bitCast(flags))); - // ^^^^^^^^ return cast ^^^^^ param cast +// Standalone function - all pointers optional +pub inline fn beginGPURenderPass( + gpucommandbuffer: *GPUCommandBuffer, + color_target_infos: ?*const GPUColorTargetInfo, // optional + num_color_targets: u32, + depth_stencil_target_info: ?*const GPUDepthStencilTargetInfo // optional +) ?*GPURenderPass { + return @ptrCast(c.SDL_BeginGPURenderPass(...)); +} + +// Method - self is non-optional, other params are optional +pub inline fn createGPUTexture( + gpudevice: *GPUDevice, // non-optional "self" + createinfo: ?*const GPUTextureCreateInfo // optional +) ?*GPUTexture { + return @ptrCast(c.SDL_CreateGPUTexture(@ptrCast(gpudevice), @ptrCast(createinfo))); +} + +pub inline fn getWindows(count: *c_int) [*c]?*Window { + // ^^^^^^^^^^^^ C pointer to optional Zig pointer to opaque type + return c.SDL_GetWindows(@ptrCast(count)); } ``` diff --git a/api/audio.zig b/api/audio.zig index f13683e..37aaa38 100644 --- a/api/audio.zig +++ b/api/audio.zig @@ -5,7 +5,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 @bitCast(c.SDL_LoadWAV_IO(@ptrCast(iostream), @bitCast(closeio), @ptrCast(spec), audio_buf, @ptrCast(audio_len))); } - }; pub const PropertiesID = u32; @@ -47,7 +46,7 @@ pub const AudioStream = opaque { return @bitCast(c.SDL_GetAudioStreamFormat(@ptrCast(audiostream), @ptrCast(src_spec), @ptrCast(dst_spec))); } - pub inline fn setAudioStreamFormat(audiostream: *AudioStream, src_spec: *const AudioSpec, dst_spec: *const AudioSpec) bool { + pub inline fn setAudioStreamFormat(audiostream: *AudioStream, src_spec: ?*const AudioSpec, dst_spec: ?*const AudioSpec) bool { return @bitCast(c.SDL_SetAudioStreamFormat(@ptrCast(audiostream), @ptrCast(src_spec), @ptrCast(dst_spec))); } @@ -91,7 +90,7 @@ pub const AudioStream = opaque { return @bitCast(c.SDL_PutAudioStreamDataNoCopy(@ptrCast(audiostream), buf, len, callback, userdata)); } - pub inline fn putAudioStreamPlanarData(audiostream: *AudioStream, channel_buffers: [*c]const void * const, num_channels: c_int, num_samples: c_int) bool { + pub inline fn putAudioStreamPlanarData(audiostream: *AudioStream, channel_buffers: [*c]const *anyopaque, num_channels: c_int, num_samples: c_int) bool { return @bitCast(c.SDL_PutAudioStreamPlanarData(@ptrCast(audiostream), channel_buffers, num_channels, num_samples)); } @@ -146,7 +145,6 @@ pub const AudioStream = opaque { pub inline fn destroyAudioStream(audiostream: *AudioStream) void { return c.SDL_DestroyAudioStream(@ptrCast(audiostream)); } - }; pub inline fn getNumAudioDrivers() c_int { @@ -181,7 +179,7 @@ pub inline fn getAudioDeviceChannelMap(devid: AudioDeviceID, count: *c_int) *c_i return @ptrCast(c.SDL_GetAudioDeviceChannelMap(devid, @ptrCast(count))); } -pub inline fn openAudioDevice(devid: AudioDeviceID, spec: *const AudioSpec) AudioDeviceID { +pub inline fn openAudioDevice(devid: AudioDeviceID, spec: ?*const AudioSpec) AudioDeviceID { return c.SDL_OpenAudioDevice(devid, @ptrCast(spec)); } @@ -217,7 +215,7 @@ pub inline fn closeAudioDevice(devid: AudioDeviceID) void { return c.SDL_CloseAudioDevice(devid); } -pub inline fn bindAudioStreams(devid: AudioDeviceID, streams: [*c]*const AudioStream, num_streams: c_int) bool { +pub inline fn bindAudioStreams(devid: AudioDeviceID, streams: [*c]?*const AudioStream, num_streams: c_int) bool { return @bitCast(c.SDL_BindAudioStreams(devid, streams, num_streams)); } @@ -225,11 +223,11 @@ pub inline fn bindAudioStream(devid: AudioDeviceID, stream: ?*AudioStream) bool return @bitCast(c.SDL_BindAudioStream(devid, @ptrCast(stream))); } -pub inline fn unbindAudioStreams(streams: [*c]*const AudioStream, 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); } -pub inline fn createAudioStream(src_spec: *const AudioSpec, dst_spec: *const AudioSpec) ?*AudioStream { +pub inline fn createAudioStream(src_spec: ?*const AudioSpec, dst_spec: ?*const AudioSpec) ?*AudioStream { return @ptrCast(c.SDL_CreateAudioStream(@ptrCast(src_spec), @ptrCast(dst_spec))); } @@ -237,7 +235,7 @@ pub const AudioStreamDataCompleteCallback = c.SDL_AudioStreamDataCompleteCallbac pub const AudioStreamCallback = c.SDL_AudioStreamCallback; -pub inline fn openAudioDeviceStream(devid: AudioDeviceID, spec: *const AudioSpec, callback: AudioStreamCallback, userdata: ?*anyopaque) ?*AudioStream { +pub inline fn openAudioDeviceStream(devid: AudioDeviceID, spec: ?*const AudioSpec, callback: AudioStreamCallback, userdata: ?*anyopaque) ?*AudioStream { return @ptrCast(c.SDL_OpenAudioDeviceStream(devid, @ptrCast(spec), callback, userdata)); } @@ -255,7 +253,7 @@ pub inline fn mixAudio(dst: [*c]u8, src: [*c]const u8, format: AudioFormat, len: return @bitCast(c.SDL_MixAudio(dst, src, @bitCast(format), len, volume)); } -pub inline fn convertAudioSamples(src_spec: *const AudioSpec, src_data: [*c]const u8, src_len: c_int, dst_spec: *const AudioSpec, dst_data: [*c][*c]u8, dst_len: *c_int) bool { +pub inline fn convertAudioSamples(src_spec: ?*const AudioSpec, src_data: [*c]const u8, src_len: c_int, dst_spec: ?*const AudioSpec, dst_data: [*c][*c]u8, dst_len: *c_int) bool { return @bitCast(c.SDL_ConvertAudioSamples(@ptrCast(src_spec), src_data, src_len, @ptrCast(dst_spec), dst_data, @ptrCast(dst_len))); } @@ -266,4 +264,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/api/camera.zig b/api/camera.zig index e4ecf87..4224810 100644 --- a/api/camera.zig +++ b/api/camera.zig @@ -116,7 +116,7 @@ pub inline fn getCameras(count: *c_int) ?*CameraID { return @ptrCast(c.SDL_GetCameras(@ptrCast(count))); } -pub inline fn getCameraSupportedFormats(instance_id: CameraID, count: *c_int) [*c][*c]CameraSpec { +pub inline fn getCameraSupportedFormats(instance_id: CameraID, count: *c_int) [*c]?*CameraSpec { return c.SDL_GetCameraSupportedFormats(instance_id, @ptrCast(count)); } @@ -128,6 +128,6 @@ pub inline fn getCameraPosition(instance_id: CameraID) CameraPosition { return c.SDL_GetCameraPosition(instance_id); } -pub inline fn openCamera(instance_id: CameraID, spec: *const CameraSpec) ?*Camera { +pub inline fn openCamera(instance_id: CameraID, spec: ?*const CameraSpec) ?*Camera { return @ptrCast(c.SDL_OpenCamera(instance_id, @ptrCast(spec))); } diff --git a/api/dialog.zig b/api/dialog.zig index 3af9a6a..e046fbe 100644 --- a/api/dialog.zig +++ b/api/dialog.zig @@ -12,11 +12,11 @@ pub const DialogFileFilter = extern struct { pub const DialogFileCallback = c.SDL_DialogFileCallback; -pub inline fn showOpenFileDialog(callback: DialogFileCallback, userdata: ?*anyopaque, window: ?*Window, filters: *const DialogFileFilter, nfilters: c_int, default_location: [*c]const u8, allow_many: bool) void { +pub inline fn showOpenFileDialog(callback: DialogFileCallback, userdata: ?*anyopaque, window: ?*Window, filters: ?*const DialogFileFilter, nfilters: c_int, default_location: [*c]const u8, allow_many: bool) void { return c.SDL_ShowOpenFileDialog(callback, userdata, @ptrCast(window), @ptrCast(filters), nfilters, default_location, @bitCast(allow_many)); } -pub inline fn showSaveFileDialog(callback: DialogFileCallback, userdata: ?*anyopaque, window: ?*Window, filters: *const DialogFileFilter, nfilters: c_int, default_location: [*c]const u8) void { +pub inline fn showSaveFileDialog(callback: DialogFileCallback, userdata: ?*anyopaque, window: ?*Window, filters: ?*const DialogFileFilter, nfilters: c_int, default_location: [*c]const u8) void { return c.SDL_ShowSaveFileDialog(callback, userdata, @ptrCast(window), @ptrCast(filters), nfilters, default_location); } diff --git a/api/events.zig b/api/events.zig index a0a1574..d416a14 100644 --- a/api/events.zig +++ b/api/events.zig @@ -785,10 +785,10 @@ pub inline fn registerEvents(numevents: c_int) u32 { return c.SDL_RegisterEvents(numevents); } -pub inline fn getWindowFromEvent(event: *const Event) ?*Window { +pub inline fn getWindowFromEvent(event: ?*const Event) ?*Window { return @ptrCast(c.SDL_GetWindowFromEvent(@ptrCast(event))); } -pub inline fn getEventDescription(event: *const Event, buf: [*c]u8, buflen: c_int) c_int { +pub inline fn getEventDescription(event: ?*const Event, buf: [*c]u8, buflen: c_int) c_int { return c.SDL_GetEventDescription(@ptrCast(event), buf, buflen); } diff --git a/api/gamepad.zig b/api/gamepad.zig index 17aebe1..0bf9c84 100644 --- a/api/gamepad.zig +++ b/api/gamepad.zig @@ -121,7 +121,7 @@ pub const Gamepad = opaque { return @ptrCast(c.SDL_GetGamepadJoystick(@ptrCast(gamepad))); } - pub inline fn getGamepadBindings(gamepad: *Gamepad, count: *c_int) [*c][*c]GamepadBinding { + pub inline fn getGamepadBindings(gamepad: *Gamepad, count: *c_int) [*c]?*GamepadBinding { return c.SDL_GetGamepadBindings(@ptrCast(gamepad), @ptrCast(count)); } diff --git a/api/gpu.zig b/api/gpu.zig index bfc2583..32eba0c 100644 --- a/api/gpu.zig +++ b/api/gpu.zig @@ -58,31 +58,31 @@ pub const GPUDevice = opaque { return c.SDL_GetGPUDeviceProperties(@ptrCast(gpudevice)); } - pub inline fn createGPUComputePipeline(gpudevice: *GPUDevice, createinfo: *const GPUComputePipelineCreateInfo) ?*GPUComputePipeline { + pub inline fn createGPUComputePipeline(gpudevice: *GPUDevice, createinfo: ?*const GPUComputePipelineCreateInfo) ?*GPUComputePipeline { return @ptrCast(c.SDL_CreateGPUComputePipeline(@ptrCast(gpudevice), @ptrCast(createinfo))); } - pub inline fn createGPUGraphicsPipeline(gpudevice: *GPUDevice, createinfo: *const GPUGraphicsPipelineCreateInfo) ?*GPUGraphicsPipeline { + pub inline fn createGPUGraphicsPipeline(gpudevice: *GPUDevice, createinfo: ?*const GPUGraphicsPipelineCreateInfo) ?*GPUGraphicsPipeline { return @ptrCast(c.SDL_CreateGPUGraphicsPipeline(@ptrCast(gpudevice), @ptrCast(createinfo))); } - pub inline fn createGPUSampler(gpudevice: *GPUDevice, createinfo: *const GPUSamplerCreateInfo) ?*GPUSampler { + pub inline fn createGPUSampler(gpudevice: *GPUDevice, createinfo: ?*const GPUSamplerCreateInfo) ?*GPUSampler { return @ptrCast(c.SDL_CreateGPUSampler(@ptrCast(gpudevice), @ptrCast(createinfo))); } - pub inline fn createGPUShader(gpudevice: *GPUDevice, createinfo: *const GPUShaderCreateInfo) ?*GPUShader { + pub inline fn createGPUShader(gpudevice: *GPUDevice, createinfo: ?*const GPUShaderCreateInfo) ?*GPUShader { return @ptrCast(c.SDL_CreateGPUShader(@ptrCast(gpudevice), @ptrCast(createinfo))); } - pub inline fn createGPUTexture(gpudevice: *GPUDevice, createinfo: *const GPUTextureCreateInfo) ?*GPUTexture { + pub inline fn createGPUTexture(gpudevice: *GPUDevice, createinfo: ?*const GPUTextureCreateInfo) ?*GPUTexture { return @ptrCast(c.SDL_CreateGPUTexture(@ptrCast(gpudevice), @ptrCast(createinfo))); } - pub inline fn createGPUBuffer(gpudevice: *GPUDevice, createinfo: *const GPUBufferCreateInfo) ?*GPUBuffer { + pub inline fn createGPUBuffer(gpudevice: *GPUDevice, createinfo: ?*const GPUBufferCreateInfo) ?*GPUBuffer { return @ptrCast(c.SDL_CreateGPUBuffer(@ptrCast(gpudevice), @ptrCast(createinfo))); } - pub inline fn createGPUTransferBuffer(gpudevice: *GPUDevice, createinfo: *const GPUTransferBufferCreateInfo) ?*GPUTransferBuffer { + pub inline fn createGPUTransferBuffer(gpudevice: *GPUDevice, createinfo: ?*const GPUTransferBufferCreateInfo) ?*GPUTransferBuffer { return @ptrCast(c.SDL_CreateGPUTransferBuffer(@ptrCast(gpudevice), @ptrCast(createinfo))); } @@ -170,7 +170,7 @@ pub const GPUDevice = opaque { return @bitCast(c.SDL_WaitForGPUIdle(@ptrCast(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: [*c]?*const GPUFence, num_fences: u32) bool { return @bitCast(c.SDL_WaitForGPUFences(@ptrCast(gpudevice), @bitCast(wait_all), fences, num_fences)); } @@ -238,11 +238,11 @@ pub const GPUCommandBuffer = opaque { return c.SDL_PushGPUComputeUniformData(@ptrCast(gpucommandbuffer), slot_index, data, length); } - pub inline fn beginGPURenderPass(gpucommandbuffer: *GPUCommandBuffer, color_target_infos: *const GPUColorTargetInfo, num_color_targets: u32, depth_stencil_target_info: *const GPUDepthStencilTargetInfo) ?*GPURenderPass { + pub inline fn beginGPURenderPass(gpucommandbuffer: *GPUCommandBuffer, color_target_infos: ?*const GPUColorTargetInfo, num_color_targets: u32, depth_stencil_target_info: ?*const GPUDepthStencilTargetInfo) ?*GPURenderPass { return @ptrCast(c.SDL_BeginGPURenderPass(@ptrCast(gpucommandbuffer), @ptrCast(color_target_infos), num_color_targets, @ptrCast(depth_stencil_target_info))); } - pub inline fn beginGPUComputePass(gpucommandbuffer: *GPUCommandBuffer, storage_texture_bindings: *const GPUStorageTextureReadWriteBinding, num_storage_texture_bindings: u32, storage_buffer_bindings: *const GPUStorageBufferReadWriteBinding, num_storage_buffer_bindings: u32) ?*GPUComputePass { + pub inline fn beginGPUComputePass(gpucommandbuffer: *GPUCommandBuffer, storage_texture_bindings: ?*const GPUStorageTextureReadWriteBinding, num_storage_texture_bindings: u32, storage_buffer_bindings: ?*const GPUStorageBufferReadWriteBinding, num_storage_buffer_bindings: u32) ?*GPUComputePass { return @ptrCast(c.SDL_BeginGPUComputePass(@ptrCast(gpucommandbuffer), @ptrCast(storage_texture_bindings), num_storage_texture_bindings, @ptrCast(storage_buffer_bindings), num_storage_buffer_bindings)); } @@ -254,15 +254,15 @@ pub const GPUCommandBuffer = opaque { return c.SDL_GenerateMipmapsForGPUTexture(@ptrCast(gpucommandbuffer), @ptrCast(texture)); } - pub inline fn blitGPUTexture(gpucommandbuffer: *GPUCommandBuffer, info: *const GPUBlitInfo) void { + pub inline fn blitGPUTexture(gpucommandbuffer: *GPUCommandBuffer, info: ?*const GPUBlitInfo) void { return c.SDL_BlitGPUTexture(@ptrCast(gpucommandbuffer), @ptrCast(info)); } - pub inline fn acquireGPUSwapchainTexture(gpucommandbuffer: *GPUCommandBuffer, window: ?*Window, swapchain_texture: [*c][*c]GPUTexture, swapchain_texture_width: *u32, swapchain_texture_height: *u32) bool { + pub inline fn acquireGPUSwapchainTexture(gpucommandbuffer: *GPUCommandBuffer, window: ?*Window, swapchain_texture: [*c]?*GPUTexture, swapchain_texture_width: *u32, swapchain_texture_height: *u32) bool { return @bitCast(c.SDL_AcquireGPUSwapchainTexture(@ptrCast(gpucommandbuffer), @ptrCast(window), swapchain_texture, @ptrCast(swapchain_texture_width), @ptrCast(swapchain_texture_height))); } - pub inline fn waitAndAcquireGPUSwapchainTexture(gpucommandbuffer: *GPUCommandBuffer, window: ?*Window, swapchain_texture: [*c][*c]GPUTexture, swapchain_texture_width: *u32, swapchain_texture_height: *u32) bool { + pub inline fn waitAndAcquireGPUSwapchainTexture(gpucommandbuffer: *GPUCommandBuffer, window: ?*Window, swapchain_texture: [*c]?*GPUTexture, swapchain_texture_width: *u32, swapchain_texture_height: *u32) bool { return @bitCast(c.SDL_WaitAndAcquireGPUSwapchainTexture(@ptrCast(gpucommandbuffer), @ptrCast(window), swapchain_texture, @ptrCast(swapchain_texture_width), @ptrCast(swapchain_texture_height))); } @@ -284,11 +284,11 @@ pub const GPURenderPass = opaque { return c.SDL_BindGPUGraphicsPipeline(@ptrCast(gpurenderpass), @ptrCast(graphics_pipeline)); } - pub inline fn setGPUViewport(gpurenderpass: *GPURenderPass, viewport: *const GPUViewport) void { + pub inline fn setGPUViewport(gpurenderpass: *GPURenderPass, viewport: ?*const GPUViewport) void { return c.SDL_SetGPUViewport(@ptrCast(gpurenderpass), @ptrCast(viewport)); } - pub inline fn setGPUScissor(gpurenderpass: *GPURenderPass, scissor: *const Rect) void { + pub inline fn setGPUScissor(gpurenderpass: *GPURenderPass, scissor: ?*const Rect) void { return c.SDL_SetGPUScissor(@ptrCast(gpurenderpass), @ptrCast(scissor)); } @@ -300,35 +300,35 @@ pub const GPURenderPass = opaque { return c.SDL_SetGPUStencilReference(@ptrCast(gpurenderpass), reference); } - pub inline fn bindGPUVertexBuffers(gpurenderpass: *GPURenderPass, first_slot: u32, bindings: *const GPUBufferBinding, num_bindings: u32) void { + pub inline fn bindGPUVertexBuffers(gpurenderpass: *GPURenderPass, first_slot: u32, bindings: ?*const GPUBufferBinding, num_bindings: u32) void { return c.SDL_BindGPUVertexBuffers(@ptrCast(gpurenderpass), first_slot, @ptrCast(bindings), num_bindings); } - pub inline fn bindGPUIndexBuffer(gpurenderpass: *GPURenderPass, binding: *const GPUBufferBinding, index_element_size: GPUIndexElementSize) void { + pub inline fn bindGPUIndexBuffer(gpurenderpass: *GPURenderPass, binding: ?*const GPUBufferBinding, index_element_size: GPUIndexElementSize) void { return c.SDL_BindGPUIndexBuffer(@ptrCast(gpurenderpass), @ptrCast(binding), index_element_size); } - pub inline fn bindGPUVertexSamplers(gpurenderpass: *GPURenderPass, first_slot: u32, texture_sampler_bindings: *const GPUTextureSamplerBinding, num_bindings: u32) void { + pub inline fn bindGPUVertexSamplers(gpurenderpass: *GPURenderPass, first_slot: u32, texture_sampler_bindings: ?*const GPUTextureSamplerBinding, num_bindings: u32) void { return c.SDL_BindGPUVertexSamplers(@ptrCast(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: [*c]?*const GPUTexture, num_bindings: u32) void { return c.SDL_BindGPUVertexStorageTextures(@ptrCast(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: [*c]?*const GPUBuffer, num_bindings: u32) void { return c.SDL_BindGPUVertexStorageBuffers(@ptrCast(gpurenderpass), first_slot, storage_buffers, num_bindings); } - pub inline fn bindGPUFragmentSamplers(gpurenderpass: *GPURenderPass, first_slot: u32, texture_sampler_bindings: *const GPUTextureSamplerBinding, num_bindings: u32) void { + pub inline fn bindGPUFragmentSamplers(gpurenderpass: *GPURenderPass, first_slot: u32, texture_sampler_bindings: ?*const GPUTextureSamplerBinding, num_bindings: u32) void { return c.SDL_BindGPUFragmentSamplers(@ptrCast(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: [*c]?*const GPUTexture, num_bindings: u32) void { return c.SDL_BindGPUFragmentStorageTextures(@ptrCast(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: [*c]?*const GPUBuffer, num_bindings: u32) void { return c.SDL_BindGPUFragmentStorageBuffers(@ptrCast(gpurenderpass), first_slot, storage_buffers, num_bindings); } @@ -358,15 +358,15 @@ pub const GPUComputePass = opaque { return c.SDL_BindGPUComputePipeline(@ptrCast(gpucomputepass), @ptrCast(compute_pipeline)); } - pub inline fn bindGPUComputeSamplers(gpucomputepass: *GPUComputePass, first_slot: u32, texture_sampler_bindings: *const GPUTextureSamplerBinding, num_bindings: u32) void { + pub inline fn bindGPUComputeSamplers(gpucomputepass: *GPUComputePass, first_slot: u32, texture_sampler_bindings: ?*const GPUTextureSamplerBinding, num_bindings: u32) void { return c.SDL_BindGPUComputeSamplers(@ptrCast(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: [*c]?*const GPUTexture, num_bindings: u32) void { return c.SDL_BindGPUComputeStorageTextures(@ptrCast(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: [*c]?*const GPUBuffer, num_bindings: u32) void { return c.SDL_BindGPUComputeStorageBuffers(@ptrCast(gpucomputepass), first_slot, storage_buffers, num_bindings); } @@ -384,27 +384,27 @@ pub const GPUComputePass = opaque { }; pub const GPUCopyPass = opaque { - pub inline fn uploadToGPUTexture(gpucopypass: *GPUCopyPass, source: *const GPUTextureTransferInfo, destination: *const GPUTextureRegion, cycle: bool) void { + pub inline fn uploadToGPUTexture(gpucopypass: *GPUCopyPass, source: ?*const GPUTextureTransferInfo, destination: ?*const GPUTextureRegion, cycle: bool) void { return c.SDL_UploadToGPUTexture(@ptrCast(gpucopypass), @ptrCast(source), @ptrCast(destination), @bitCast(cycle)); } - pub inline fn uploadToGPUBuffer(gpucopypass: *GPUCopyPass, source: *const GPUTransferBufferLocation, destination: *const GPUBufferRegion, cycle: bool) void { + pub inline fn uploadToGPUBuffer(gpucopypass: *GPUCopyPass, source: ?*const GPUTransferBufferLocation, destination: ?*const GPUBufferRegion, cycle: bool) void { return c.SDL_UploadToGPUBuffer(@ptrCast(gpucopypass), @ptrCast(source), @ptrCast(destination), @bitCast(cycle)); } - pub inline fn copyGPUTextureToTexture(gpucopypass: *GPUCopyPass, source: *const GPUTextureLocation, destination: *const GPUTextureLocation, w: u32, h: u32, d: u32, cycle: bool) void { + pub inline fn copyGPUTextureToTexture(gpucopypass: *GPUCopyPass, source: ?*const GPUTextureLocation, destination: ?*const GPUTextureLocation, w: u32, h: u32, d: u32, cycle: bool) void { return c.SDL_CopyGPUTextureToTexture(@ptrCast(gpucopypass), @ptrCast(source), @ptrCast(destination), w, h, d, @bitCast(cycle)); } - pub inline fn copyGPUBufferToBuffer(gpucopypass: *GPUCopyPass, source: *const GPUBufferLocation, destination: *const GPUBufferLocation, size: u32, cycle: bool) void { + pub inline fn copyGPUBufferToBuffer(gpucopypass: *GPUCopyPass, source: ?*const GPUBufferLocation, destination: ?*const GPUBufferLocation, size: u32, cycle: bool) void { return c.SDL_CopyGPUBufferToBuffer(@ptrCast(gpucopypass), @ptrCast(source), @ptrCast(destination), size, @bitCast(cycle)); } - pub inline fn downloadFromGPUTexture(gpucopypass: *GPUCopyPass, source: *const GPUTextureRegion, destination: *const GPUTextureTransferInfo) void { + pub inline fn downloadFromGPUTexture(gpucopypass: *GPUCopyPass, source: ?*const GPUTextureRegion, destination: ?*const GPUTextureTransferInfo) void { return c.SDL_DownloadFromGPUTexture(@ptrCast(gpucopypass), @ptrCast(source), @ptrCast(destination)); } - pub inline fn downloadFromGPUBuffer(gpucopypass: *GPUCopyPass, source: *const GPUBufferRegion, destination: *const GPUTransferBufferLocation) void { + pub inline fn downloadFromGPUBuffer(gpucopypass: *GPUCopyPass, source: ?*const GPUBufferRegion, destination: ?*const GPUTransferBufferLocation) void { return c.SDL_DownloadFromGPUBuffer(@ptrCast(gpucopypass), @ptrCast(source), @ptrCast(destination)); } @@ -610,7 +610,18 @@ pub const GPUShaderStage = enum(c_int) { shaderstageFragment, }; -pub const GPUShaderFormat = u32; +pub const GPUShaderFormat = packed struct(u32) { + shaderformatPrivate: bool = false, // Shaders for NDA'd platforms. + shaderformatSpirv: bool = false, // SPIR-V shaders for Vulkan. + shaderformatDxbc: bool = false, // DXBC SM5_1 shaders for D3D12. + shaderformatDxil: bool = false, // DXIL SM6_0 shaders for D3D12. + shaderformatMsl: bool = false, // MSL shaders for Metal. + shaderformatMetallib: bool = false, // Precompiled metallib shaders for Metal. + pad0: u25 = 0, + rsvd: bool = false, + + pub const None = GPUShaderFormat{}; +}; pub const GPUVertexElementFormat = enum(c_int) { vertexelementformatInvalid, @@ -875,9 +886,9 @@ pub const GPUVertexAttribute = extern struct { }; pub const GPUVertexInputState = extern struct { - vertex_buffer_descriptions: *const GPUVertexBufferDescription, // A pointer to an array of vertex buffer descriptions. + vertex_buffer_descriptions: ?*const GPUVertexBufferDescription, // A pointer to an array of vertex buffer descriptions. num_vertex_buffers: u32, // The number of vertex buffer descriptions in the above array. - vertex_attributes: *const GPUVertexAttribute, // A pointer to an array of vertex attribute descriptions. + vertex_attributes: ?*const GPUVertexAttribute, // A pointer to an array of vertex attribute descriptions. num_vertex_attributes: u32, // The number of vertex attribute descriptions in the above array. }; @@ -981,7 +992,7 @@ pub const GPUColorTargetDescription = extern struct { }; pub const GPUGraphicsPipelineTargetInfo = extern struct { - color_target_descriptions: *const GPUColorTargetDescription, // A pointer to an array of color target descriptions. + color_target_descriptions: ?*const GPUColorTargetDescription, // A pointer to an array of color target descriptions. num_color_targets: u32, // The number of color target descriptions in the above array. depth_stencil_format: GPUTextureFormat, // The pixel format of the depth-stencil target. Ignored if has_depth_stencil_target is false. has_depth_stencil_target: bool, // true specifies that the pipeline uses a depth-stencil target. diff --git a/api/haptic.zig b/api/haptic.zig index 3861b0d..143ab7c 100644 --- a/api/haptic.zig +++ b/api/haptic.zig @@ -40,15 +40,15 @@ pub const Haptic = opaque { return c.SDL_GetNumHapticAxes(@ptrCast(haptic)); } - pub inline fn hapticEffectSupported(haptic: *Haptic, effect: *const HapticEffect) bool { + pub inline fn hapticEffectSupported(haptic: *Haptic, effect: ?*const HapticEffect) bool { return @bitCast(c.SDL_HapticEffectSupported(@ptrCast(haptic), @ptrCast(effect))); } - pub inline fn createHapticEffect(haptic: *Haptic, effect: *const HapticEffect) HapticEffectID { + pub inline fn createHapticEffect(haptic: *Haptic, effect: ?*const HapticEffect) HapticEffectID { return c.SDL_CreateHapticEffect(@ptrCast(haptic), @ptrCast(effect)); } - pub inline fn updateHapticEffect(haptic: *Haptic, effect: HapticEffectID, data: *const HapticEffect) bool { + pub inline fn updateHapticEffect(haptic: *Haptic, effect: HapticEffectID, data: ?*const HapticEffect) bool { return @bitCast(c.SDL_UpdateHapticEffect(@ptrCast(haptic), effect, @ptrCast(data))); } diff --git a/api/joystick.zig b/api/joystick.zig index 76a104e..3f57466 100644 --- a/api/joystick.zig +++ b/api/joystick.zig @@ -280,8 +280,8 @@ pub const VirtualJoystickDesc = extern struct { nsensors: u16, // the number of sensors on this joystick, requires `sensors` to point at valid descriptions padding2: [2]u16, // unused name: [*c]const u8, // the name of the joystick - touchpads: *const VirtualJoystickTouchpadDesc, // A pointer to an array of touchpad descriptions, required if `ntouchpads` is > 0 - sensors: *const VirtualJoystickSensorDesc, // A pointer to an array of sensor descriptions, required if `nsensors` is > 0 + touchpads: ?*const VirtualJoystickTouchpadDesc, // A pointer to an array of touchpad descriptions, required if `ntouchpads` is > 0 + sensors: ?*const VirtualJoystickSensorDesc, // A pointer to an array of sensor descriptions, required if `nsensors` is > 0 userdata: ?*anyopaque, // User data pointer passed to callbacks Update: ?*const anyopaque, // Called when the joystick state should be updated SetPlayerIndex: ?*const anyopaque, // Called when the player index is set @@ -293,7 +293,7 @@ pub const VirtualJoystickDesc = extern struct { Cleanup: ?*const anyopaque, // Cleans up the userdata when the joystick is detached }; -pub inline fn attachVirtualJoystick(desc: *const VirtualJoystickDesc) JoystickID { +pub inline fn attachVirtualJoystick(desc: ?*const VirtualJoystickDesc) JoystickID { return c.SDL_AttachVirtualJoystick(@ptrCast(desc)); } diff --git a/api/messagebox.zig b/api/messagebox.zig index 52326bc..a7f2d2c 100644 --- a/api/messagebox.zig +++ b/api/messagebox.zig @@ -55,11 +55,11 @@ pub const MessageBoxData = extern struct { title: [*c]const u8, // UTF-8 title message: [*c]const u8, // UTF-8 message text numbuttons: c_int, - buttons: *const MessageBoxButtonData, - colorScheme: *const MessageBoxColorScheme, // SDL_MessageBoxColorScheme, can be NULL to use system settings + buttons: ?*const MessageBoxButtonData, + colorScheme: ?*const MessageBoxColorScheme, // SDL_MessageBoxColorScheme, can be NULL to use system settings }; -pub inline fn showMessageBox(messageboxdata: *const MessageBoxData, buttonid: *c_int) bool { +pub inline fn showMessageBox(messageboxdata: ?*const MessageBoxData, buttonid: *c_int) bool { return @bitCast(c.SDL_ShowMessageBox(@ptrCast(messageboxdata), @ptrCast(buttonid))); } diff --git a/api/pixels.zig b/api/pixels.zig index e47c912..e67e24a 100644 --- a/api/pixels.zig +++ b/api/pixels.zig @@ -206,7 +206,7 @@ pub inline fn getPixelFormatForMasks(bpp: c_int, Rmask: u32, Gmask: u32, Bmask: return @bitCast(c.SDL_GetPixelFormatForMasks(bpp, Rmask, Gmask, Bmask, Amask)); } -pub inline fn getPixelFormatDetails(format: PixelFormat) *const PixelFormatDetails { +pub inline fn getPixelFormatDetails(format: PixelFormat) ?*const PixelFormatDetails { return @ptrCast(c.SDL_GetPixelFormatDetails(@bitCast(format))); } @@ -214,7 +214,7 @@ pub inline fn createPalette(ncolors: c_int) ?*Palette { return @ptrCast(c.SDL_CreatePalette(ncolors)); } -pub inline fn setPaletteColors(palette: ?*Palette, colors: *const Color, firstcolor: c_int, ncolors: c_int) bool { +pub inline fn setPaletteColors(palette: ?*Palette, colors: ?*const Color, firstcolor: c_int, ncolors: c_int) bool { return @bitCast(c.SDL_SetPaletteColors(@ptrCast(palette), @ptrCast(colors), firstcolor, ncolors)); } @@ -222,18 +222,18 @@ pub inline fn destroyPalette(palette: ?*Palette) void { return c.SDL_DestroyPalette(@ptrCast(palette)); } -pub inline fn mapRGB(format: *const PixelFormatDetails, palette: *const Palette, r: u8, g: u8, b: u8) u32 { +pub inline fn mapRGB(format: ?*const PixelFormatDetails, palette: ?*const Palette, r: u8, g: u8, b: u8) u32 { return c.SDL_MapRGB(@ptrCast(format), @ptrCast(palette), r, g, b); } -pub inline fn mapRGBA(format: *const PixelFormatDetails, palette: *const Palette, r: u8, g: u8, b: u8, a: u8) u32 { +pub inline fn mapRGBA(format: ?*const PixelFormatDetails, palette: ?*const Palette, r: u8, g: u8, b: u8, a: u8) u32 { return c.SDL_MapRGBA(@ptrCast(format), @ptrCast(palette), r, g, b, a); } -pub inline fn getRGB(pixelvalue: u32, format: *const PixelFormatDetails, palette: *const Palette, r: [*c]u8, g: [*c]u8, b: [*c]u8) void { +pub inline fn getRGB(pixelvalue: u32, format: ?*const PixelFormatDetails, palette: ?*const Palette, r: [*c]u8, g: [*c]u8, b: [*c]u8) void { return c.SDL_GetRGB(pixelvalue, @ptrCast(format), @ptrCast(palette), r, g, b); } -pub inline fn getRGBA(pixelvalue: u32, format: *const PixelFormatDetails, palette: *const Palette, r: [*c]u8, g: [*c]u8, b: [*c]u8, a: [*c]u8) void { +pub inline fn getRGBA(pixelvalue: u32, format: ?*const PixelFormatDetails, palette: ?*const Palette, r: [*c]u8, g: [*c]u8, b: [*c]u8, a: [*c]u8) void { return c.SDL_GetRGBA(pixelvalue, @ptrCast(format), @ptrCast(palette), r, g, b, a); } diff --git a/api/rect.zig b/api/rect.zig index 04637ec..fcc1543 100644 --- a/api/rect.zig +++ b/api/rect.zig @@ -25,42 +25,42 @@ pub const FRect = extern struct { h: f32, }; -pub inline fn hasRectIntersection(A: *const Rect, B: *const Rect) bool { +pub inline fn hasRectIntersection(A: ?*const Rect, B: ?*const Rect) bool { return @bitCast(c.SDL_HasRectIntersection(@ptrCast(A), @ptrCast(B))); } -pub inline fn getRectIntersection(A: *const Rect, B: *const Rect, result: ?*Rect) bool { +pub inline fn getRectIntersection(A: ?*const Rect, B: ?*const Rect, result: ?*Rect) bool { return @bitCast(c.SDL_GetRectIntersection(@ptrCast(A), @ptrCast(B), @ptrCast(result))); } -pub inline fn getRectUnion(A: *const Rect, B: *const Rect, result: ?*Rect) bool { +pub inline fn getRectUnion(A: ?*const Rect, B: ?*const Rect, result: ?*Rect) bool { return @bitCast(c.SDL_GetRectUnion(@ptrCast(A), @ptrCast(B), @ptrCast(result))); } -pub inline fn getRectEnclosingPoints(points: *const Point, count: c_int, clip: *const Rect, result: ?*Rect) bool { +pub inline fn getRectEnclosingPoints(points: ?*const Point, count: c_int, clip: ?*const Rect, result: ?*Rect) bool { return @bitCast(c.SDL_GetRectEnclosingPoints(@ptrCast(points), count, @ptrCast(clip), @ptrCast(result))); } -pub inline fn getRectAndLineIntersection(rect: *const Rect, X1: *c_int, Y1: *c_int, X2: *c_int, Y2: *c_int) bool { +pub inline fn getRectAndLineIntersection(rect: ?*const Rect, X1: *c_int, Y1: *c_int, X2: *c_int, Y2: *c_int) bool { return @bitCast(c.SDL_GetRectAndLineIntersection(@ptrCast(rect), @ptrCast(X1), @ptrCast(Y1), @ptrCast(X2), @ptrCast(Y2))); } -pub inline fn hasRectIntersectionFloat(A: *const FRect, B: *const FRect) bool { +pub inline fn hasRectIntersectionFloat(A: ?*const FRect, B: ?*const FRect) bool { return @bitCast(c.SDL_HasRectIntersectionFloat(@ptrCast(A), @ptrCast(B))); } -pub inline fn getRectIntersectionFloat(A: *const FRect, B: *const FRect, result: ?*FRect) bool { +pub inline fn getRectIntersectionFloat(A: ?*const FRect, B: ?*const FRect, result: ?*FRect) bool { return @bitCast(c.SDL_GetRectIntersectionFloat(@ptrCast(A), @ptrCast(B), @ptrCast(result))); } -pub inline fn getRectUnionFloat(A: *const FRect, B: *const FRect, result: ?*FRect) bool { +pub inline fn getRectUnionFloat(A: ?*const FRect, B: ?*const FRect, result: ?*FRect) bool { return @bitCast(c.SDL_GetRectUnionFloat(@ptrCast(A), @ptrCast(B), @ptrCast(result))); } -pub inline fn getRectEnclosingPointsFloat(points: *const FPoint, count: c_int, clip: *const FRect, result: ?*FRect) bool { +pub inline fn getRectEnclosingPointsFloat(points: ?*const FPoint, count: c_int, clip: ?*const FRect, result: ?*FRect) bool { return @bitCast(c.SDL_GetRectEnclosingPointsFloat(@ptrCast(points), count, @ptrCast(clip), @ptrCast(result))); } -pub inline fn getRectAndLineIntersectionFloat(rect: *const FRect, X1: *f32, Y1: *f32, X2: *f32, Y2: *f32) bool { +pub inline fn getRectAndLineIntersectionFloat(rect: ?*const FRect, X1: *f32, Y1: *f32, X2: *f32, Y2: *f32) bool { return @bitCast(c.SDL_GetRectAndLineIntersectionFloat(@ptrCast(rect), @ptrCast(X1), @ptrCast(Y1), @ptrCast(X2), @ptrCast(Y2))); } diff --git a/api/render.zig b/api/render.zig index 7dde717..6d4b087 100644 --- a/api/render.zig +++ b/api/render.zig @@ -938,7 +938,7 @@ pub const Renderer = opaque { return @bitCast(c.SDL_ConvertEventToRenderCoordinates(@ptrCast(renderer), @ptrCast(event))); } - pub inline fn setRenderViewport(renderer: *Renderer, rect: *const Rect) bool { + pub inline fn setRenderViewport(renderer: *Renderer, rect: ?*const Rect) bool { return @bitCast(c.SDL_SetRenderViewport(@ptrCast(renderer), @ptrCast(rect))); } @@ -954,7 +954,7 @@ pub const Renderer = opaque { return @bitCast(c.SDL_GetRenderSafeArea(@ptrCast(renderer), @ptrCast(rect))); } - pub inline fn setRenderClipRect(renderer: *Renderer, rect: *const Rect) bool { + pub inline fn setRenderClipRect(renderer: *Renderer, rect: ?*const Rect) bool { return @bitCast(c.SDL_SetRenderClipRect(@ptrCast(renderer), @ptrCast(rect))); } @@ -1014,7 +1014,7 @@ pub const Renderer = opaque { return @bitCast(c.SDL_RenderPoint(@ptrCast(renderer), x, y)); } - pub inline fn renderPoints(renderer: *Renderer, points: *const FPoint, count: c_int) bool { + pub inline fn renderPoints(renderer: *Renderer, points: ?*const FPoint, count: c_int) bool { return @bitCast(c.SDL_RenderPoints(@ptrCast(renderer), @ptrCast(points), count)); } @@ -1022,55 +1022,55 @@ pub const Renderer = opaque { return @bitCast(c.SDL_RenderLine(@ptrCast(renderer), x1, y1, x2, y2)); } - pub inline fn renderLines(renderer: *Renderer, points: *const FPoint, count: c_int) bool { + pub inline fn renderLines(renderer: *Renderer, points: ?*const FPoint, count: c_int) bool { return @bitCast(c.SDL_RenderLines(@ptrCast(renderer), @ptrCast(points), count)); } - pub inline fn renderRect(renderer: *Renderer, rect: *const FRect) bool { + pub inline fn renderRect(renderer: *Renderer, rect: ?*const FRect) bool { return @bitCast(c.SDL_RenderRect(@ptrCast(renderer), @ptrCast(rect))); } - pub inline fn renderRects(renderer: *Renderer, rects: *const FRect, count: c_int) bool { + pub inline fn renderRects(renderer: *Renderer, rects: ?*const FRect, count: c_int) bool { return @bitCast(c.SDL_RenderRects(@ptrCast(renderer), @ptrCast(rects), count)); } - pub inline fn renderFillRect(renderer: *Renderer, rect: *const FRect) bool { + pub inline fn renderFillRect(renderer: *Renderer, rect: ?*const FRect) bool { return @bitCast(c.SDL_RenderFillRect(@ptrCast(renderer), @ptrCast(rect))); } - pub inline fn renderFillRects(renderer: *Renderer, rects: *const FRect, count: c_int) bool { + pub inline fn renderFillRects(renderer: *Renderer, rects: ?*const FRect, count: c_int) bool { return @bitCast(c.SDL_RenderFillRects(@ptrCast(renderer), @ptrCast(rects), count)); } - pub inline fn renderTexture(renderer: *Renderer, texture: ?*Texture, srcrect: *const FRect, dstrect: *const FRect) bool { + pub inline fn renderTexture(renderer: *Renderer, texture: ?*Texture, srcrect: ?*const FRect, dstrect: ?*const FRect) bool { return @bitCast(c.SDL_RenderTexture(@ptrCast(renderer), @ptrCast(texture), @ptrCast(srcrect), @ptrCast(dstrect))); } - pub inline fn renderTextureRotated(renderer: *Renderer, texture: ?*Texture, srcrect: *const FRect, dstrect: *const FRect, angle: f64, center: *const FPoint, flip: FlipMode) bool { + pub inline fn renderTextureRotated(renderer: *Renderer, texture: ?*Texture, srcrect: ?*const FRect, dstrect: ?*const FRect, angle: f64, center: ?*const FPoint, flip: FlipMode) bool { return @bitCast(c.SDL_RenderTextureRotated(@ptrCast(renderer), @ptrCast(texture), @ptrCast(srcrect), @ptrCast(dstrect), angle, @ptrCast(center), @intFromEnum(flip))); } - pub inline fn renderTextureAffine(renderer: *Renderer, texture: ?*Texture, srcrect: *const FRect, origin: *const FPoint, right: *const FPoint, down: *const FPoint) bool { + pub inline fn renderTextureAffine(renderer: *Renderer, texture: ?*Texture, srcrect: ?*const FRect, origin: ?*const FPoint, right: ?*const FPoint, down: ?*const FPoint) bool { return @bitCast(c.SDL_RenderTextureAffine(@ptrCast(renderer), @ptrCast(texture), @ptrCast(srcrect), @ptrCast(origin), @ptrCast(right), @ptrCast(down))); } - pub inline fn renderTextureTiled(renderer: *Renderer, texture: ?*Texture, srcrect: *const FRect, scale: f32, dstrect: *const FRect) bool { + pub inline fn renderTextureTiled(renderer: *Renderer, texture: ?*Texture, srcrect: ?*const FRect, scale: f32, dstrect: ?*const FRect) bool { return @bitCast(c.SDL_RenderTextureTiled(@ptrCast(renderer), @ptrCast(texture), @ptrCast(srcrect), scale, @ptrCast(dstrect))); } - pub inline fn renderTexture9Grid(renderer: *Renderer, texture: ?*Texture, srcrect: *const FRect, left_width: f32, right_width: f32, top_height: f32, bottom_height: f32, scale: f32, dstrect: *const FRect) bool { + pub inline fn renderTexture9Grid(renderer: *Renderer, texture: ?*Texture, srcrect: ?*const FRect, left_width: f32, right_width: f32, top_height: f32, bottom_height: f32, scale: f32, dstrect: ?*const FRect) bool { return @bitCast(c.SDL_RenderTexture9Grid(@ptrCast(renderer), @ptrCast(texture), @ptrCast(srcrect), left_width, right_width, top_height, bottom_height, scale, @ptrCast(dstrect))); } - pub inline fn renderTexture9GridTiled(renderer: *Renderer, texture: ?*Texture, srcrect: *const FRect, left_width: f32, right_width: f32, top_height: f32, bottom_height: f32, scale: f32, dstrect: *const FRect, tileScale: f32) bool { + pub inline fn renderTexture9GridTiled(renderer: *Renderer, texture: ?*Texture, srcrect: ?*const FRect, left_width: f32, right_width: f32, top_height: f32, bottom_height: f32, scale: f32, dstrect: ?*const FRect, tileScale: f32) bool { return @bitCast(c.SDL_RenderTexture9GridTiled(@ptrCast(renderer), @ptrCast(texture), @ptrCast(srcrect), left_width, right_width, top_height, bottom_height, scale, @ptrCast(dstrect), tileScale)); } - pub inline fn renderGeometry(renderer: *Renderer, texture: ?*Texture, vertices: *const Vertex, num_vertices: c_int, indices: [*c]const c_int, num_indices: c_int) bool { + pub inline fn renderGeometry(renderer: *Renderer, texture: ?*Texture, vertices: ?*const Vertex, num_vertices: c_int, indices: [*c]const c_int, num_indices: c_int) bool { return @bitCast(c.SDL_RenderGeometry(@ptrCast(renderer), @ptrCast(texture), @ptrCast(vertices), num_vertices, indices, num_indices)); } - pub inline fn renderGeometryRaw(renderer: *Renderer, texture: ?*Texture, xy: *const f32, xy_stride: c_int, color: *const FColor, color_stride: c_int, uv: *const f32, uv_stride: c_int, num_vertices: c_int, indices: ?*const anyopaque, num_indices: c_int, size_indices: c_int) bool { + pub inline fn renderGeometryRaw(renderer: *Renderer, texture: ?*Texture, xy: *const f32, xy_stride: c_int, color: ?*const FColor, color_stride: c_int, uv: *const f32, uv_stride: c_int, num_vertices: c_int, indices: ?*const anyopaque, num_indices: c_int, size_indices: c_int) bool { return @bitCast(c.SDL_RenderGeometryRaw(@ptrCast(renderer), @ptrCast(texture), @ptrCast(xy), xy_stride, @ptrCast(color), color_stride, @ptrCast(uv), uv_stride, num_vertices, indices, num_indices, size_indices)); } @@ -1082,7 +1082,7 @@ pub const Renderer = opaque { return @bitCast(c.SDL_GetRenderTextureAddressMode(@ptrCast(renderer), @ptrCast(u_mode), @ptrCast(v_mode))); } - pub inline fn renderReadPixels(renderer: *Renderer, rect: *const Rect) ?*Surface { + pub inline fn renderReadPixels(renderer: *Renderer, rect: ?*const Rect) ?*Surface { return @ptrCast(c.SDL_RenderReadPixels(@ptrCast(renderer), @ptrCast(rect))); } @@ -1208,23 +1208,23 @@ pub const Texture = opaque { return @bitCast(c.SDL_GetTextureScaleMode(@ptrCast(texture), @ptrCast(scaleMode))); } - pub inline fn updateTexture(texture: *Texture, rect: *const Rect, pixels: ?*const anyopaque, pitch: c_int) bool { + pub inline fn updateTexture(texture: *Texture, rect: ?*const Rect, pixels: ?*const anyopaque, pitch: c_int) bool { return @bitCast(c.SDL_UpdateTexture(@ptrCast(texture), @ptrCast(rect), pixels, pitch)); } - pub inline fn updateYUVTexture(texture: *Texture, rect: *const Rect, Yplane: [*c]const u8, Ypitch: c_int, Uplane: [*c]const u8, Upitch: c_int, Vplane: [*c]const u8, Vpitch: c_int) bool { + pub inline fn updateYUVTexture(texture: *Texture, rect: ?*const Rect, Yplane: [*c]const u8, Ypitch: c_int, Uplane: [*c]const u8, Upitch: c_int, Vplane: [*c]const u8, Vpitch: c_int) bool { return @bitCast(c.SDL_UpdateYUVTexture(@ptrCast(texture), @ptrCast(rect), Yplane, Ypitch, Uplane, Upitch, Vplane, Vpitch)); } - pub inline fn updateNVTexture(texture: *Texture, rect: *const Rect, Yplane: [*c]const u8, Ypitch: c_int, UVplane: [*c]const u8, UVpitch: c_int) bool { + pub inline fn updateNVTexture(texture: *Texture, rect: ?*const Rect, Yplane: [*c]const u8, Ypitch: c_int, UVplane: [*c]const u8, UVpitch: c_int) bool { return @bitCast(c.SDL_UpdateNVTexture(@ptrCast(texture), @ptrCast(rect), Yplane, Ypitch, UVplane, UVpitch)); } - pub inline fn lockTexture(texture: *Texture, rect: *const Rect, pixels: [*c]?*anyopaque, pitch: *c_int) bool { + pub inline fn lockTexture(texture: *Texture, rect: ?*const Rect, pixels: [*c]?*anyopaque, pitch: *c_int) bool { return @bitCast(c.SDL_LockTexture(@ptrCast(texture), @ptrCast(rect), pixels, @ptrCast(pitch))); } - pub inline fn lockTextureToSurface(texture: *Texture, rect: *const Rect, surface: [*c][*c]Surface) bool { + pub inline fn lockTextureToSurface(texture: *Texture, rect: ?*const Rect, surface: [*c]?*Surface) bool { return @bitCast(c.SDL_LockTextureToSurface(@ptrCast(texture), @ptrCast(rect), surface)); } @@ -1245,7 +1245,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: [*c][*c]Window, renderer: [*c][*c]Renderer) bool { +pub inline fn createWindowAndRenderer(title: [*c]const u8, width: c_int, height: c_int, window_flags: WindowFlags, window: [*c]?*Window, renderer: [*c]?*Renderer) bool { return @bitCast(c.SDL_CreateWindowAndRenderer(title, width, height, @bitCast(window_flags), window, renderer)); } @@ -1256,11 +1256,11 @@ pub inline fn createRendererWithProperties(props: PropertiesID) ?*Renderer { pub const GPURenderStateCreateInfo = extern struct { fragment_shader: ?*GPUShader, // The fragment shader to use when this render state is active num_sampler_bindings: i32, // The number of additional fragment samplers to bind when this render state is active - sampler_bindings: *const GPUTextureSamplerBinding, // Additional fragment samplers to bind when this render state is active + sampler_bindings: ?*const GPUTextureSamplerBinding, // Additional fragment samplers to bind when this render state is active num_storage_textures: i32, // The number of storage textures to bind when this render state is active - storage_textures: [*c]*const GPUTexture, // Storage textures to bind when this render state is active + storage_textures: [*c]?*const GPUTexture, // Storage textures to bind when this render state is active num_storage_buffers: i32, // The number of storage buffers to bind when this render state is active - storage_buffers: [*c]*const GPUBuffer, // Storage buffers to bind when this render state is active + storage_buffers: [*c]?*const GPUBuffer, // Storage buffers to bind when this render state is active props: PropertiesID, // A properties ID for extensions. Should be 0 if no extensions are needed. }; diff --git a/api/storage.zig b/api/storage.zig index dd07876..e54e948 100644 --- a/api/storage.zig +++ b/api/storage.zig @@ -111,6 +111,6 @@ pub inline fn openFileStorage(path: [*c]const u8) ?*Storage { return @ptrCast(c.SDL_OpenFileStorage(path)); } -pub inline fn openStorage(iface: *const StorageInterface, userdata: ?*anyopaque) ?*Storage { +pub inline fn openStorage(iface: ?*const StorageInterface, userdata: ?*anyopaque) ?*Storage { return @ptrCast(c.SDL_OpenStorage(@ptrCast(iface), userdata)); } diff --git a/api/surface.zig b/api/surface.zig index dc1167a..156343c 100644 --- a/api/surface.zig +++ b/api/surface.zig @@ -146,7 +146,7 @@ pub const Surface = opaque { return @bitCast(c.SDL_SurfaceHasAlternateImages(@ptrCast(surface))); } - pub inline fn getSurfaceImages(surface: *Surface, count: *c_int) [*c][*c]Surface { + pub inline fn getSurfaceImages(surface: *Surface, count: *c_int) [*c]?*Surface { return c.SDL_GetSurfaceImages(@ptrCast(surface), @ptrCast(count)); } @@ -222,7 +222,7 @@ pub const Surface = opaque { return @bitCast(c.SDL_GetSurfaceBlendMode(@ptrCast(surface), @ptrCast(blendMode))); } - pub inline fn setSurfaceClipRect(surface: *Surface, rect: *const Rect) bool { + pub inline fn setSurfaceClipRect(surface: *Surface, rect: ?*const Rect) bool { return @bitCast(c.SDL_SetSurfaceClipRect(@ptrCast(surface), @ptrCast(rect))); } @@ -262,43 +262,43 @@ pub const Surface = opaque { return @bitCast(c.SDL_ClearSurface(@ptrCast(surface), r, g, b, a)); } - pub inline fn fillSurfaceRect(surface: *Surface, rect: *const Rect, color: u32) bool { + pub inline fn fillSurfaceRect(surface: *Surface, rect: ?*const Rect, color: u32) bool { return @bitCast(c.SDL_FillSurfaceRect(@ptrCast(surface), @ptrCast(rect), color)); } - pub inline fn fillSurfaceRects(surface: *Surface, rects: *const Rect, count: c_int, color: u32) bool { + pub inline fn fillSurfaceRects(surface: *Surface, rects: ?*const Rect, count: c_int, color: u32) bool { return @bitCast(c.SDL_FillSurfaceRects(@ptrCast(surface), @ptrCast(rects), count, color)); } - pub inline fn blitSurface(surface: *Surface, srcrect: *const Rect, dst: ?*Surface, dstrect: *const Rect) bool { + pub inline fn blitSurface(surface: *Surface, srcrect: ?*const Rect, dst: ?*Surface, dstrect: ?*const Rect) bool { return @bitCast(c.SDL_BlitSurface(@ptrCast(surface), @ptrCast(srcrect), @ptrCast(dst), @ptrCast(dstrect))); } - pub inline fn blitSurfaceUnchecked(surface: *Surface, srcrect: *const Rect, dst: ?*Surface, dstrect: *const Rect) bool { + pub inline fn blitSurfaceUnchecked(surface: *Surface, srcrect: ?*const Rect, dst: ?*Surface, dstrect: ?*const Rect) bool { return @bitCast(c.SDL_BlitSurfaceUnchecked(@ptrCast(surface), @ptrCast(srcrect), @ptrCast(dst), @ptrCast(dstrect))); } - pub inline fn blitSurfaceScaled(surface: *Surface, srcrect: *const Rect, dst: ?*Surface, dstrect: *const Rect, scaleMode: ScaleMode) bool { + pub inline fn blitSurfaceScaled(surface: *Surface, srcrect: ?*const Rect, dst: ?*Surface, dstrect: ?*const Rect, scaleMode: ScaleMode) bool { return @bitCast(c.SDL_BlitSurfaceScaled(@ptrCast(surface), @ptrCast(srcrect), @ptrCast(dst), @ptrCast(dstrect), @intFromEnum(scaleMode))); } - pub inline fn blitSurfaceUncheckedScaled(surface: *Surface, srcrect: *const Rect, dst: ?*Surface, dstrect: *const Rect, scaleMode: ScaleMode) bool { + pub inline fn blitSurfaceUncheckedScaled(surface: *Surface, srcrect: ?*const Rect, dst: ?*Surface, dstrect: ?*const Rect, scaleMode: ScaleMode) bool { return @bitCast(c.SDL_BlitSurfaceUncheckedScaled(@ptrCast(surface), @ptrCast(srcrect), @ptrCast(dst), @ptrCast(dstrect), @intFromEnum(scaleMode))); } - pub inline fn stretchSurface(surface: *Surface, srcrect: *const Rect, dst: ?*Surface, dstrect: *const Rect, scaleMode: ScaleMode) bool { + pub inline fn stretchSurface(surface: *Surface, srcrect: ?*const Rect, dst: ?*Surface, dstrect: ?*const Rect, scaleMode: ScaleMode) bool { return @bitCast(c.SDL_StretchSurface(@ptrCast(surface), @ptrCast(srcrect), @ptrCast(dst), @ptrCast(dstrect), @intFromEnum(scaleMode))); } - pub inline fn blitSurfaceTiled(surface: *Surface, srcrect: *const Rect, dst: ?*Surface, dstrect: *const Rect) bool { + pub inline fn blitSurfaceTiled(surface: *Surface, srcrect: ?*const Rect, dst: ?*Surface, dstrect: ?*const Rect) bool { return @bitCast(c.SDL_BlitSurfaceTiled(@ptrCast(surface), @ptrCast(srcrect), @ptrCast(dst), @ptrCast(dstrect))); } - pub inline fn blitSurfaceTiledWithScale(surface: *Surface, srcrect: *const Rect, scale: f32, scaleMode: ScaleMode, dst: ?*Surface, dstrect: *const Rect) bool { + pub inline fn blitSurfaceTiledWithScale(surface: *Surface, srcrect: ?*const Rect, scale: f32, scaleMode: ScaleMode, dst: ?*Surface, dstrect: ?*const Rect) bool { return @bitCast(c.SDL_BlitSurfaceTiledWithScale(@ptrCast(surface), @ptrCast(srcrect), scale, @intFromEnum(scaleMode), @ptrCast(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 { + 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 @bitCast(c.SDL_BlitSurface9Grid(@ptrCast(surface), @ptrCast(srcrect), left_width, right_width, top_height, bottom_height, scale, @intFromEnum(scaleMode), @ptrCast(dst), @ptrCast(dstrect))); } diff --git a/api/time.zig b/api/time.zig index 7d1ed86..9e16646 100644 --- a/api/time.zig +++ b/api/time.zig @@ -38,7 +38,7 @@ pub inline fn timeToDateTime(ticks: Time, dt: ?*DateTime, localTime: bool) bool return @bitCast(c.SDL_TimeToDateTime(ticks, @ptrCast(dt), @bitCast(localTime))); } -pub inline fn dateTimeToTime(dt: *const DateTime, ticks: ?*Time) bool { +pub inline fn dateTimeToTime(dt: ?*const DateTime, ticks: ?*Time) bool { return @bitCast(c.SDL_DateTimeToTime(@ptrCast(dt), @ptrCast(ticks))); } diff --git a/api/touch.zig b/api/touch.zig index 2bf4bf6..a4a5926 100644 --- a/api/touch.zig +++ b/api/touch.zig @@ -30,6 +30,6 @@ pub inline fn getTouchDeviceType(touchID: TouchID) TouchDeviceType { return @intFromEnum(c.SDL_GetTouchDeviceType(touchID)); } -pub inline fn getTouchFingers(touchID: TouchID, count: *c_int) [*c][*c]Finger { +pub inline fn getTouchFingers(touchID: TouchID, count: *c_int) [*c]?*Finger { return c.SDL_GetTouchFingers(touchID, @ptrCast(count)); } diff --git a/api/video.zig b/api/video.zig index 6d33104..3bd27e9 100644 --- a/api/video.zig +++ b/api/video.zig @@ -77,11 +77,11 @@ pub const Window = opaque { return c.SDL_GetWindowDisplayScale(@ptrCast(window)); } - pub inline fn setWindowFullscreenMode(window: *Window, mode: *const DisplayMode) bool { + pub inline fn setWindowFullscreenMode(window: *Window, mode: ?*const DisplayMode) bool { return @bitCast(c.SDL_SetWindowFullscreenMode(@ptrCast(window), @ptrCast(mode))); } - pub inline fn getWindowFullscreenMode(window: *Window) *const DisplayMode { + pub inline fn getWindowFullscreenMode(window: *Window) ?*const DisplayMode { return @ptrCast(c.SDL_GetWindowFullscreenMode(@ptrCast(window))); } @@ -245,7 +245,7 @@ pub const Window = opaque { return @bitCast(c.SDL_UpdateWindowSurface(@ptrCast(window))); } - pub inline fn updateWindowSurfaceRects(window: *Window, rects: *const Rect, numrects: c_int) bool { + pub inline fn updateWindowSurfaceRects(window: *Window, rects: ?*const Rect, numrects: c_int) bool { return @bitCast(c.SDL_UpdateWindowSurfaceRects(@ptrCast(window), @ptrCast(rects), numrects)); } @@ -269,11 +269,11 @@ pub const Window = opaque { return @bitCast(c.SDL_GetWindowMouseGrab(@ptrCast(window))); } - pub inline fn setWindowMouseRect(window: *Window, rect: *const Rect) bool { + pub inline fn setWindowMouseRect(window: *Window, rect: ?*const Rect) bool { return @bitCast(c.SDL_SetWindowMouseRect(@ptrCast(window), @ptrCast(rect))); } - pub inline fn getWindowMouseRect(window: *Window) *const Rect { + pub inline fn getWindowMouseRect(window: *Window) ?*const Rect { return @ptrCast(c.SDL_GetWindowMouseRect(@ptrCast(window))); } @@ -505,7 +505,7 @@ pub inline fn getDisplayContentScale(displayID: DisplayID) f32 { return c.SDL_GetDisplayContentScale(displayID); } -pub inline fn getFullscreenDisplayModes(displayID: DisplayID, count: *c_int) [*c][*c]DisplayMode { +pub inline fn getFullscreenDisplayModes(displayID: DisplayID, count: *c_int) [*c]?*DisplayMode { return @intFromEnum(c.SDL_GetFullscreenDisplayModes(displayID, @ptrCast(count))); } @@ -513,23 +513,23 @@ pub inline fn getClosestFullscreenDisplayMode(displayID: DisplayID, w: c_int, h: return @bitCast(c.SDL_GetClosestFullscreenDisplayMode(displayID, w, h, refresh_rate, @bitCast(include_high_density_modes), @ptrCast(closest))); } -pub inline fn getDesktopDisplayMode(displayID: DisplayID) *const DisplayMode { +pub inline fn getDesktopDisplayMode(displayID: DisplayID) ?*const DisplayMode { return @ptrCast(c.SDL_GetDesktopDisplayMode(displayID)); } -pub inline fn getCurrentDisplayMode(displayID: DisplayID) *const DisplayMode { +pub inline fn getCurrentDisplayMode(displayID: DisplayID) ?*const DisplayMode { return @ptrCast(c.SDL_GetCurrentDisplayMode(displayID)); } -pub inline fn getDisplayForPoint(point: *const Point) DisplayID { +pub inline fn getDisplayForPoint(point: ?*const Point) DisplayID { return c.SDL_GetDisplayForPoint(@ptrCast(point)); } -pub inline fn getDisplayForRect(rect: *const Rect) DisplayID { +pub inline fn getDisplayForRect(rect: ?*const Rect) DisplayID { return c.SDL_GetDisplayForRect(@ptrCast(rect)); } -pub inline fn getWindows(count: *c_int) [*c][*c]Window { +pub inline fn getWindows(count: *c_int) [*c]?*Window { return c.SDL_GetWindows(@ptrCast(count)); } diff --git a/json/gpu.json b/json/gpu.json index 7368c6b..c50fcd7 100644 --- a/json/gpu.json +++ b/json/gpu.json @@ -41,12 +41,7 @@ "name": "SDL_GPUFence" } ], - "typedefs": [ - { - "name": "SDL_GPUShaderFormat", - "underlying_type": "Uint32" - } - ], + "typedefs": [], "function_pointers": [], "c_type_aliases": [], "enums": [ @@ -2338,6 +2333,46 @@ } ] }, + { + "name": "SDL_GPUShaderFormat", + "underlying_type": "Uint32", + "values": [ + { + "name": "SDL_GPU_SHADERFORMAT_INVALID", + "value": "0" + }, + { + "name": "SDL_GPU_SHADERFORMAT_PRIVATE", + "value": "(1u << 0)", + "comment": "Shaders for NDA'd platforms." + }, + { + "name": "SDL_GPU_SHADERFORMAT_SPIRV", + "value": "(1u << 1)", + "comment": "SPIR-V shaders for Vulkan." + }, + { + "name": "SDL_GPU_SHADERFORMAT_DXBC", + "value": "(1u << 2)", + "comment": "DXBC SM5_1 shaders for D3D12." + }, + { + "name": "SDL_GPU_SHADERFORMAT_DXIL", + "value": "(1u << 3)", + "comment": "DXIL SM6_0 shaders for D3D12." + }, + { + "name": "SDL_GPU_SHADERFORMAT_MSL", + "value": "(1u << 4)", + "comment": "MSL shaders for Metal." + }, + { + "name": "SDL_GPU_SHADERFORMAT_METALLIB", + "value": "(1u << 5)", + "comment": "Precompiled metallib shaders for Metal." + } + ] + }, { "name": "SDL_GPUColorComponentFlags", "underlying_type": "Uint8", diff --git a/src/codegen.zig b/src/codegen.zig index d97c060..2dd0a85 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -811,7 +811,7 @@ pub const CodeGen = struct { // Raw decimal value like "1" or "2" or "4" if (std.fmt.parseInt(u64, trimmed, 10)) |val| { // Find bit position for powers of 2 - if (val == 0) return 0; // Special case + if (val == 0) return error.InvalidBitPosition; // Zero is not a valid flag bit var bit: u7 = 0; // Use u7 to allow checking up to bit 63 while (bit < 64) : (bit += 1) { diff --git a/src/patterns.zig b/src/patterns.zig index 0319c16..955f651 100644 --- a/src/patterns.zig +++ b/src/patterns.zig @@ -1132,7 +1132,7 @@ pub const Scanner = struct { }; const clean_name = std.mem.trimRight(u8, name, ";"); - if (!std.mem.endsWith(u8, clean_name, "Flags")) { + if (!std.mem.endsWith(u8, clean_name, "Flags") and !std.mem.endsWith(u8, clean_name, "Format")) { self.pos = start; return null; } diff --git a/src/types.zig b/src/types.zig index 933ad3a..dec09bd 100644 --- a/src/types.zig +++ b/src/types.zig @@ -84,6 +84,7 @@ pub fn convertType(c_type: []const u8, allocator: Allocator) ![]const u8 { if (std.mem.eql(u8, trimmed, "char**")) return try allocator.dupe(u8, "[*c][*c]u8"); if (std.mem.eql(u8, trimmed, "void *")) return try allocator.dupe(u8, "?*anyopaque"); if (std.mem.eql(u8, trimmed, "const void *")) return try allocator.dupe(u8, "?*const anyopaque"); + if (std.mem.eql(u8, trimmed, "const void * const *")) return try allocator.dupe(u8, "[*c]const *anyopaque"); if (std.mem.eql(u8, trimmed, "void **")) return try allocator.dupe(u8, "[*c]?*anyopaque"); if (std.mem.eql(u8, trimmed, "const Uint8 *")) return try allocator.dupe(u8, "[*c]const u8"); if (std.mem.eql(u8, trimmed, "Uint8 *")) return try allocator.dupe(u8, "[*c]u8"); @@ -96,16 +97,19 @@ pub fn convertType(c_type: []const u8, allocator: Allocator) ![]const u8 { // Match "SDL_Type *const *" (no space before const) 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]?*const {s}", .{base_type}); } // Match "SDL_Type * const *" (space before const) 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]?*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, "[*c][*c]{s}", .{base_type}); + // Use [*c]?*Type instead of [*c][*c]Type because: + // 1. SDL types are often opaque and Zig doesn't allow C pointers to point to opaque types + // 2. Inner pointer should be optional since C pointers can be null + return std.fmt.allocPrint(allocator, "[*c]?*{s}", .{base_type}); } } @@ -133,9 +137,9 @@ pub fn convertType(c_type: []const u8, allocator: Allocator) ![]const u8 { else rest[0 .. rest.len - 1]; if (std.mem.startsWith(u8, base_type, "SDL_")) { - // const SDL_Foo * -> *const Foo + // const SDL_Foo * -> ?*const Foo (nullable for C interop) const zig_type = base_type[4..]; // Remove SDL_ - return std.fmt.allocPrint(allocator, "*const {s}", .{zig_type}); + return std.fmt.allocPrint(allocator, "?*const {s}", .{zig_type}); } } }