Skip to content

Instantly share code, notes, and snippets.

@bens
Last active April 26, 2020 15:23
Show Gist options
  • Save bens/bd9ba0414fcf74bf05ecf7e6f75c4e97 to your computer and use it in GitHub Desktop.
Save bens/bd9ba0414fcf74bf05ecf7e6f75c4e97 to your computer and use it in GitHub Desktop.
Hello World for SDL2 in ziglang
const std = @import("std");
const c = @cImport(@cInclude("SDL2/SDL.h"));
const SDLError = error{
FailedInit,
FailedCreatingWindow,
FailedGettingEvent,
FailedDraw,
FailedScreenUpdate,
};
// Pressing 'Q' stops the program.
fn is_quit(event: *c.SDL_Event) bool {
return switch (event.type) {
c.SDL_QUIT => true,
c.SDL_KEYDOWN => event.key.keysym.sym == c.SDLK_q,
else => false,
};
}
// A filter function to only enqueue certain events.
export fn event_filter(userdata: ?*c_void, event: [*c]c.SDL_Event) c_int {
return switch (event.*.type) {
c.SDL_KEYDOWN => 1,
c.SDL_WINDOWEVENT => 1,
c.SDL_QUIT => 1,
else => 0,
};
}
const System = struct {
window: *c.SDL_Window,
// Clear the window to a single colour.
fn clear(self: System) SDLError!void {
const s = c.SDL_GetWindowSurface(self.window);
const black = c.SDL_MapRGB(s.*.format, 0, 0, 0);
if (c.SDL_FillRect(s, null, black) != 0) {
std.debug.warn("SDL drawing failed: {s}\n", .{c.SDL_GetError()});
return SDLError.FailedDraw;
}
if (c.SDL_UpdateWindowSurface(self.window) != 0) {
std.debug.warn("SDL screen update failed: {s}\n", .{c.SDL_GetError()});
return SDLError.FailedScreenUpdate;
}
}
};
fn initialise() SDLError!System {
if (c.SDL_Init(c.SDL_INIT_VIDEO | c.SDL_INIT_EVENTS) != 0) {
std.debug.warn("Initialising SDL failed: {s}\n", .{c.SDL_GetError()});
return SDLError.FailedInit;
}
// Make sure we deinit if there's an error later in this function.
errdefer c.SDL_Quit();
const try_window = c.SDL_CreateWindow(
"test",
c.SDL_WINDOWPOS_UNDEFINED,
c.SDL_WINDOWPOS_UNDEFINED,
640,
480,
c.SDL_WINDOW_RESIZABLE,
);
if (try_window) |window| {
c.SDL_SetEventFilter(event_filter, null);
c.SDL_ShowWindow(window);
return System{
.window = window,
};
} else {
std.debug.warn("Creating Window failed: {s}\n", .{c.SDL_GetError()});
return SDLError.FailedCreatingWindow;
}
}
fn deinitialise(system: System) void {
c.SDL_Quit();
}
pub fn main() SDLError!void {
const system = try initialise();
defer deinitialise(system);
const surface = c.SDL_GetWindowSurface(system.window);
// Loop, blocking for events.
var event: c.SDL_Event = undefined;
while (true) {
if (c.SDL_WaitEvent(&event) == 0) {
std.debug.warn(
"Getting next event failed: {s}\n",
.{c.SDL_GetError()},
);
return SDLError.FailedGettingEvent;
}
if (is_quit(&event)) break;
try system.clear();
}
}
@bens
Copy link
Author

bens commented Apr 26, 2020

$ zig run hellosdl.zig -I/usr/include -I/usr/include/SDL2 -lc -lSDL2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment