diff options
Diffstat (limited to 'sdl2')
| -rw-r--r-- | sdl2/errors.ha | 31 | ||||
| -rw-r--r-- | sdl2/events.ha | 51 | ||||
| -rw-r--r-- | sdl2/gamecontroller.ha | 16 | ||||
| -rw-r--r-- | sdl2/image/image.ha | 22 | ||||
| -rw-r--r-- | sdl2/joystick.ha | 9 | ||||
| -rw-r--r-- | sdl2/render.ha | 92 | ||||
| -rw-r--r-- | sdl2/video.ha | 18 |
7 files changed, 180 insertions, 59 deletions
diff --git a/sdl2/errors.ha b/sdl2/errors.ha new file mode 100644 index 0000000..bc02505 --- /dev/null +++ b/sdl2/errors.ha @@ -0,0 +1,31 @@ +use strings; + +// Returned when an error occurs in an SDL function. +export type error = !str; + +// Converts an SDL error into a human-friendly string. +export fn strerror(err: error) str = { + return err: str; +}; + +@symbol("SDL_GetError") fn geterror() const *char; + +export fn wrapvoid(ret: int) (void | error) = { + wrapint(ret)?; +}; + +export fn wrapint(ret: int) (int | error) = { + if (ret < 0) { + return strings::fromc(geterror()): error; + }; + return ret; +}; + +export fn wrapptr(ret: nullable *void) (*void | error) = { + match (ret) { + case let v: *void => + return v; + case null => + return strings::fromc(geterror()): error; + }; +}; diff --git a/sdl2/events.ha b/sdl2/events.ha index e26333a..58bbfd7 100644 --- a/sdl2/events.ha +++ b/sdl2/events.ha @@ -377,6 +377,9 @@ export type eventaction = enum { GETEVENT, }; +@symbol("SDL_PeepEvents") fn _peep_events(events: *event, numevents: int, + action: eventaction, mintype: event_type, maxtype: event_type) int; + // Checks the event queue for messages and optionally returns them. // // If 'action' is ADDEVENT, up to 'numevents' events will be added to the back @@ -390,11 +393,16 @@ export type eventaction = enum { // queue, within the specified minimum and maximum type, will be returned and // will be removed from the queue. // -// Returns the number of events actually stored, or -1 if there was an error. -// // This function is thread-safe. -export @symbol("SDL_PeepEvents") fn peep_events(events: *event, numevents: int, - action: eventaction, mintype: event_type, maxtype: event_type) int; +export fn peep_events( + events: *event, + numevents: int, + action: eventaction, + mintype: event_type, + maxtype: event_type, +) (int | error) = { + return wrapint(_peep_events(events, numevents, action, mintype, maxtype)); +}; // Checks to see if certain event types are in the event queue. export @symbol("SDL_HasEvent") fn has_event(event_type: event_type) bool; @@ -414,35 +422,48 @@ export @symbol("SDL_FlushEvent") fn flush_event(event_type: event_type) void; // on the main thread immediately before the flush call. export @symbol("SDL_FlushEvents") fn flush_events(mintype: event_type, maxtype: event_type) void; +@symbol("SDL_PollEvent") fn _poll_event(event: nullable *event) int; + // Polls for currently pending events. // // Returns 1 if there are any pending events, or 0 if there are none available. // // If 'event' is not null, the next event is removed from the queue and stored // in that area. -export @symbol("SDL_PollEvent") fn poll_event(event: nullable *event) int; +export fn poll_event(event: nullable *event) (int | error) = { + return wrapint(_poll_event(event)); +}; + +@symbol("SDL_WaitEvent") fn _wait_event(event: nullable *event) int; // Waits indefinitely for the next available event. // -// Returns 1, or 0 if there was an error while waiting for events. -// // If 'event' is not null, the next event is removed from the queue and stored // in that area. -export @symbol("SDL_WaitEvent") fn wait_event(event: nullable *event) int; +export fn wait_event(event: nullable *event) (void | error) = { + return wrapvoid(_wait_event(event)); +}; + +@symbol("SDL_WaitEventTimeout") fn _wait_event_timeout( + event: nullable *event, timeout: int) int; // Waits until the specified timeout (in milliseconds) for the next available event. // -// Returns 1, or 0 if there was an error while waiting for events. -// // If 'event' is not null, the next event is removed from the queue and stored // in that area. The 'timeout' is the time (in milliseconds) to wait for next // event. -export @symbol("SDL_WaitEventTimeout") fn wait_event_timeout(event: nullable *event, timeout: int) int; +export fn wait_event_timeout( + event: nullable *event, + timeout: int, +) (void | error) = { + return wrapvoid(_wait_event_timeout(event, timeout)); +}; + +@symbol("SDL_PushEvent") fn _push_event(event: *event) int; // Add an event to the event queue. -// -// Returns 1 on success, 0 if the event was filtered, or -1 if the event queue -// was full or there was some other error. -export @symbol("SDL_PushEvent") fn push_event(event: *event) int; +export fn push_event(event: *event) (void | error) = { + return wrapvoid(_push_event(event)); +}; // TODO: Finish rigging up other SDL_events.h bits diff --git a/sdl2/gamecontroller.ha b/sdl2/gamecontroller.ha index 3b752e1..cf78674 100644 --- a/sdl2/gamecontroller.ha +++ b/sdl2/gamecontroller.ha @@ -27,16 +27,20 @@ export type controller_axis = enum u8 { // 'joystick_index' is the same as the 'device_index' passed to // [[joystick_open]]. // -// Returns SDL_TRUE if the given joystick is supported by the game controller -// interface, SDL_FALSE if it isn't or it's an invalid index. +// Returns true if the given joystick is supported by the game controller +// interface, false if it isn't or it's an invalid index. export @symbol("SDL_IsGameController") fn is_game_controller( joystick_index: int) bool; +@symbol("SDL_GameControllerOpen") fn _game_controller_open( + joystick_index: int) nullable *gamecontroller; + // Get the SDL_GameController associated with an instance id. -// -// Returns a [[controller]] on success or NULL on failure. -export @symbol("SDL_GameControllerOpen") fn game_controller_open( - joystick_index: int) *gamecontroller; +export fn game_controller_open( + joystick_index: int, +) (*gamecontroller | error) = { + return wrapptr(_game_controller_open(joystick_index))?: *gamecontroller; +}; // Close a game controller previously opened with [[game_controller_open]]. export @symbol("SDL_GameControllerClose") fn game_controller_close( diff --git a/sdl2/image/image.ha b/sdl2/image/image.ha index 03301e9..6cabee2 100644 --- a/sdl2/image/image.ha +++ b/sdl2/image/image.ha @@ -1,6 +1,7 @@ // TODO: Flesh me out // TODO: SDL_RWops use sdl2; +use strings; // Flags for [[init]]. export type init_flags = enum int { @@ -20,9 +21,24 @@ export @symbol("IMG_Init") fn init(flags: init_flags) int; // Unloads libraries loaded with [[init]] export @symbol("IMG_Quit") fn quit() void; +@symbol("IMG_Load") fn _load(file: const *char) nullable *sdl2::surface; + // Load an image from a file path. -export @symbol("IMG_Load") fn load(file: const *char) nullable *sdl2::surface; +export fn load(file: str) (*sdl2::surface | sdl2::error) = { + const file = strings::to_c(file); + defer free(file); + return sdl2::wrapptr(_load(file))?: *sdl2::surface; +}; -// Load an image directly into a render texture. -export @symbol("IMG_LoadTexture") fn load_texture(renderer: *sdl2::renderer, +@symbol("IMG_LoadTexture") fn _load_texture(renderer: *sdl2::renderer, file: const *char) nullable *sdl2::texture; + +// Load an image directly into a render texture. +export fn load_texture( + renderer: *sdl2::renderer, + file: str, +) (*sdl2::texture | sdl2::error) = { + const file = strings::to_c(file); + defer free(file); + return sdl2::wrapptr(_load_texture(renderer, file))?: *sdl2::texture; +}; diff --git a/sdl2/joystick.ha b/sdl2/joystick.ha index c4f4c96..adbcd14 100644 --- a/sdl2/joystick.ha +++ b/sdl2/joystick.ha @@ -6,8 +6,7 @@ export def JOYSTICK_AXIS_MIN: i16 = -32768; // Minimum value for a joystick axis. export def JOYSTICK_AXIS_MAX: i16 = 32767; -// Count the number of joysticks attached to the system. -// -// Returns the number of attached joysticks on success or a negative error code -// on failure. -export @symbol("SDL_NumJoysticks") fn numjoysticks() int; +@symbol("SDL_NumJoysticks") fn _numjoysticks() int; + +// Returns the number of joysticks attached to the system. +export fn numjoysticks() (int | error) = wrapint(_numjoysticks()); diff --git a/sdl2/render.ha b/sdl2/render.ha index 5bf1b09..649e786 100644 --- a/sdl2/render.ha +++ b/sdl2/render.ha @@ -15,6 +15,10 @@ export type renderer_flags = enum u32 { TARGETTEXTURE = 0x00000008, }; +@symbol("SDL_CreateWindowAndRenderer") fn _create_window_and_renderer( + width: int, height: int, window_flags: window_flags, + window: nullable **window, renderer: nullable **renderer) int; + // Create a window and default renderer. // // 'width' and 'height' set the width and height of the window, in screen @@ -22,11 +26,17 @@ export type renderer_flags = enum u32 { // // 'window' and 'renderer' are out parameters, or null, which are filled in with // the created window and renderer respectively. -// -// Returns 0 on success, or -1 on error. -export @symbol("SDL_CreateWindowAndRenderer") fn create_window_and_renderer( - width: int, height: int, window_flags: window_flags, - window: nullable **window, renderer: nullable **renderer) int; +export fn create_window_and_renderer( + width: int, + height: int, + window_flags: window_flags, + window: nullable **window, + renderer: nullable **renderer, +) (void | error) = wrapvoid(_create_window_and_renderer(width, height, + window_flags, window, renderer)); + +@symbol("SDL_CreateRenderer") fn _create_renderer(window: *window, + index: int, flags: renderer_flags) nullable *renderer; // Create a 2D rendering context for a window. // @@ -34,12 +44,14 @@ export @symbol("SDL_CreateWindowAndRenderer") fn create_window_and_renderer( // the rendering driver to initialize, or -1 to initialize the first one // supporting the requested flags. // -// Returns a valid rendering context, or NULL if there was an error. -// // See also: [[create_software_renderer]], [[get_renderer_info]], // [[destroy_renderer]]. -export @symbol("SDL_CreateRenderer") fn create_renderer(window: *window, - index: int, flags: renderer_flags) nullable *renderer; +export fn create_renderer( + window: *window, + index: int, + flags: renderer_flags, +) (*renderer | error) = + wrapptr(_create_renderer(window, index, flags))?: *renderer; // Destroy the rendering context for a window and free associated textures. // @@ -49,22 +61,27 @@ export @symbol("SDL_DestroyRenderer") fn destroy_renderer(renderer: *renderer) v // Opaque value for the alpha channel (255). export def ALPHA_OPAQUE: u8 = 255; +@symbol("SDL_SetRenderDrawColor") fn _set_render_draw_color(renderer: *renderer, + r: u8, g: u8, b: u8, a: u8) int; + // Set the color used for drawing operations (Rect, Line and Clear). // // 'renderer' is the renderer for which drawing color should be set. 'r', 'g', // 'b', and 'a' respectively set the red, gree, blue, and alpha channels. -// -// Returns 0 on success, or -1 on error -export @symbol("SDL_SetRenderDrawColor") fn set_render_draw_color(renderer: *renderer, - r: u8, g: u8, b: u8, a: u8) int; +export fn set_render_draw_color( + renderer: *renderer, + r: u8, g: u8, b: u8, a: u8, +) (void | error) = wrapvoid(_set_render_draw_color(renderer, r, g, b, a)); + +@symbol("SDL_RenderClear") fn _render_clear(renderer: *renderer) int; // Clear the current rendering target with the drawing color // // This function clears the entire rendering target, ignoring the viewport and // the clip rectangle. -// -// Returns 0 on success, or -1 on error -export @symbol("SDL_RenderClear") fn render_clear(renderer: *renderer) int; +export fn render_clear(renderer: *renderer) (void | error) = { + return wrapvoid(_render_clear(renderer)); +}; // Update the screen with rendering performed. export @symbol("SDL_RenderPresent") fn render_present(renderer: *renderer) void; @@ -72,13 +89,23 @@ export @symbol("SDL_RenderPresent") fn render_present(renderer: *renderer) void; // Destroy the specified texture. export @symbol("SDL_DestroyTexture") fn destroy_texture(texture: *texture) void; -// Query the attributes of a texture -// -// Returns 0 on success, or -1 if the texture is not valid. -export @symbol("SDL_QueryTexture") fn query_texture(texture: *texture, +@symbol("SDL_QueryTexture") fn _query_texture(texture: *texture, format: nullable *u32, access: nullable *int, w: nullable *int, h: nullable *int) int; +// Query the attributes of a texture +export fn query_texture( + texture: *texture, + format: nullable *u32, + access: nullable *int, + w: nullable *int, h: nullable *int, +) (void | error) = { + return wrapvoid(_query_texture(texture, format, access, w, h)); +}; + +@symbol("SDL_SetTextureColorMod") fn _set_texture_color_mod( + texture: *texture, r: u8, g: u8, b: u8) int; + // Set an additional color value multiplied into render copy operations. // // When this texture is rendered, during the copy operation each source color @@ -89,13 +116,22 @@ export @symbol("SDL_QueryTexture") fn query_texture(texture: *texture, // // Color modulation is not always supported by the renderer; it will return -1 // if color modulation is not supported. -// -// Returns 0 on success or a negative error code on failure. -export @symbol("SDL_SetTextureColorMod") fn set_texture_color_mod( - texture: *texture, r: u8, g: u8, b: u8) int; +export fn set_texture_color_mod( + texture: *texture, + r: u8, g: u8, b: u8, +) (void | error) = { + return wrapvoid(_set_texture_color_mod(texture, r, g, b)); +}; -// Copy a portion of the texture to the current rendering target. -// -// Returns 0 on success, or -1 on error -export @symbol("SDL_RenderCopy") fn render_copy(renderer: *renderer, +@symbol("SDL_RenderCopy") fn _render_copy(renderer: *renderer, texture: *texture, srcrect: nullable *rect, dstrect: nullable *rect) int; + +// Copy a portion of the texture to the current rendering target. +export fn render_copy( + renderer: *renderer, + texture: *texture, + srcrect: nullable *rect, + dstrect: nullable *rect, +) (void | error) = { + return wrapvoid(_render_copy(renderer, texture, srcrect, dstrect)); +}; diff --git a/sdl2/video.ha b/sdl2/video.ha index e6dfa58..b1f8b22 100644 --- a/sdl2/video.ha +++ b/sdl2/video.ha @@ -1,4 +1,5 @@ // TODO: Flesh me out +use strings; // The type used to identify a window. (Opaque) export type window = void; @@ -32,6 +33,9 @@ export type window_flags = enum u32 { export def WINDOWPOS_UNDEFINED: int = 0x1FFF0000; export def WINDOWPOS_CENTERED: int = 0x2FFF0000; +@symbol("SDL_CreateWindow") fn _create_window(title: const *char, + x: int, y: int, w: int, h: int, flags: window_flags) nullable *window; + // Create a window with the specified position, dimensions, and flags. // // 'title' is the title of the window, in UTF-8 encoding. See [[strings::to_c]] @@ -66,8 +70,18 @@ export def WINDOWPOS_CENTERED: int = 0x2FFF0000; // removed in a future version of SDL. // // See also: [[destroy_window]] [[gl_loadlibrary]], [[vulkan_loadlibrary]]. -export @symbol("SDL_CreateWindow") fn create_window(title: const *char, - x: int, y: int, w: int, h: int, flags: window_flags) nullable *window; +export fn create_window( + title: str, + x: int, + y: int, + w: int, + h: int, + flags: window_flags, +) (*window | error) = { + let title = strings::to_c(title); + defer free(title); + return wrapptr(_create_window(title, x, y, w, h, flags))?: *window; +}; // Destroy a window. export @symbol("SDL_DestroyWindow") fn destroy_window(window: *window) void; |
