commit 4ab4e4f58b3477587057e08e3252978f60da1071 Author: Andrew Kelley Date: Wed Oct 25 23:30:19 2017 -0400 initial version diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..03299ae --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/zig-cache/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..d561c14 --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# SDL2 Zig Demo + +Here's a basic window with SDL2 in Zig. + +![screenshot](screenshot.png) + +## How to build and run it + +``` +zig build run +``` diff --git a/build.zig b/build.zig new file mode 100644 index 0000000..8856cfa --- /dev/null +++ b/build.zig @@ -0,0 +1,19 @@ +const Builder = @import("std").build.Builder; + +pub fn build(b: &Builder) { + const mode = b.standardReleaseOptions(); + const exe = b.addExecutable("sdl-zig-demo", "src/main.zig"); + exe.setBuildMode(mode); + exe.linkSystemLibrary("SDL2"); + exe.linkSystemLibrary("c"); + + b.default_step.dependOn(&exe.step); + b.installArtifact(exe); + + + const run = b.step("run", "Run the demo"); + const run_cmd = b.addCommand(".", b.env_map, + [][]const u8{exe.getOutputPath(), }); + run.dependOn(&run_cmd.step); + run_cmd.step.dependOn(&exe.step); +} diff --git a/screenshot.png b/screenshot.png new file mode 100644 index 0000000..cd33503 Binary files /dev/null and b/screenshot.png differ diff --git a/src/main.zig b/src/main.zig new file mode 100644 index 0000000..f6be95f --- /dev/null +++ b/src/main.zig @@ -0,0 +1,107 @@ +const c = @cImport({ + @cInclude("SDL2/SDL.h"); +}); +const assert = @import("std").debug.assert; + + +// See https://github.com/zig-lang/zig/issues/565 +// SDL_video.h:#define SDL_WINDOWPOS_UNDEFINED SDL_WINDOWPOS_UNDEFINED_DISPLAY(0) +// SDL_video.h:#define SDL_WINDOWPOS_UNDEFINED_DISPLAY(X) (SDL_WINDOWPOS_UNDEFINED_MASK|(X)) +// SDL_video.h:#define SDL_WINDOWPOS_UNDEFINED_MASK 0x1FFF0000u +const SDL_WINDOWPOS_UNDEFINED = @bitCast(c_int, c.SDL_WINDOWPOS_UNDEFINED_MASK); + +// Zig does not support extern unions yet. +// See https://github.com/zig-lang/zig/issues/144 +const SDL_Event = extern struct { + _type: c.Uint32, + _union: [56]u8, +}; +extern fn SDL_PollEvent(event: &SDL_Event) -> c_int; + +// SDL_RWclose is fundamentally unrepresentable in Zig, because `ctx` is +// evaluated twice. One could make the case that this is a bug in SDL, +// especially since the docs list a real function prototype that would not +// have this double-evaluation of the parameter. +// If SDL would instead of a macro use a static inline function, +// it would resolve the SDL bug as well as make the function visible to Zig +// and to debuggers. +// SDL_rwops.h:#define SDL_RWclose(ctx) (ctx)->close(ctx) +inline fn SDL_RWclose(ctx: &c.SDL_RWops) -> c_int { + const aligned_ctx = @alignCast(@alignOf(my_SDL_RWops), ctx); + const casted_ctx = @ptrCast(&my_SDL_RWops, aligned_ctx); + return casted_ctx.close(casted_ctx); +} +// Zig does not support extern unions yet. +// See https://github.com/zig-lang/zig/issues/144 +const my_SDL_RWops = extern struct { + size: extern fn(), + seek: extern fn(), + read: extern fn(), + write: extern fn(), + close: extern fn(context: &my_SDL_RWops)->c_int, +}; + +error SDLInitializationFailed; + +pub fn main() -> %void { + if (c.SDL_Init(c.SDL_INIT_VIDEO) != 0) { + c.SDL_Log(c"Unable to initialize SDL: %s", c.SDL_GetError()); + return error.SDLInitializationFailed; + } + defer c.SDL_Quit(); + + const screen = c.SDL_CreateWindow(c"My Game Window", + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + 300, 73, + c.SDL_WINDOW_OPENGL) ?? + { + c.SDL_Log(c"Unable to create window: %s", c.SDL_GetError()); + return error.SDLInitializationFailed; + }; + defer c.SDL_DestroyWindow(screen); + + const renderer = c.SDL_CreateRenderer(screen, -1, 0) ?? { + c.SDL_Log(c"Unable to create renderer: %s", c.SDL_GetError()); + return error.SDLInitializationFailed; + }; + defer c.SDL_DestroyRenderer(renderer); + + const zig_bmp = @embedFile("zig.bmp"); + const rw = c.SDL_RWFromConstMem(@ptrCast(&c_void, &zig_bmp[0]), c_int(zig_bmp.len)) ?? { + c.SDL_Log(c"Unable to get RWFromConstMem: %s", c.SDL_GetError()); + return error.SDLInitializationFailed; + }; + defer assert(SDL_RWclose(rw) == 0); + + const zig_surface = c.SDL_LoadBMP_RW(rw, 1) ?? { + c.SDL_Log(c"Unable to load bmp: %s", c.SDL_GetError()); + return error.SDLInitializationFailed; + }; + defer c.SDL_FreeSurface(zig_surface); + + const zig_texture = c.SDL_CreateTextureFromSurface(renderer, zig_surface) ?? { + c.SDL_Log(c"Unable to create texture from surface: %s", c.SDL_GetError()); + return error.SDLInitializationFailed; + }; + defer c.SDL_DestroyTexture(zig_texture); + + var quit = false; + while (!quit) { + var event: SDL_Event = undefined; + while (SDL_PollEvent(&event) != 0) { + switch (event._type) { + c.SDL_QUIT => { + quit = true; + }, + else => {}, + } + } + + _ = c.SDL_RenderClear(renderer); + _ = c.SDL_RenderCopy(renderer, zig_texture, null, null); + c.SDL_RenderPresent(renderer); + + c.SDL_Delay(17); + } +} diff --git a/src/zig.bmp b/src/zig.bmp new file mode 100644 index 0000000..5308a05 Binary files /dev/null and b/src/zig.bmp differ