diff --git a/assets/stretch.bmp b/assets/stretch.bmp new file mode 100644 index 0000000..42657b6 Binary files /dev/null and b/assets/stretch.bmp differ diff --git a/src/zig.bmp b/assets/zig.bmp similarity index 100% rename from src/zig.bmp rename to assets/zig.bmp diff --git a/build.zig b/build.zig index de7f030..4aa240b 100644 --- a/build.zig +++ b/build.zig @@ -12,19 +12,32 @@ pub fn build(b: *Build) void { .target = target, .optimize = optimize, }); - if (target.query.isNativeOs() and target.result.os.tag == .linux) { - // The SDL package doesn't work for Linux yet, so we rely on system - // packages for now. - exe.linkSystemLibrary("SDL2"); - exe.linkLibC(); - } else { - const sdl_dep = b.dependency("sdl", .{ - .optimize = .ReleaseFast, - .target = target, - }); - exe.linkLibrary(sdl_dep.artifact("SDL2")); - } - + // Keeping this here just in case, but dynamic linking is working AFAICT + // if (target.query.isNativeOs() and target.result.os.tag == .linux) { + // // The SDL package doesn't work for Linux yet, so we rely on system + // // packages for now. + // exe.linkSystemLibrary("SDL2"); + // exe.linkSystemLibrary("SDL2_ttf"); + // exe.linkSystemLibrary("SDL2_image"); + // } else { + const sdl_dep = b.dependency("SDL", .{ + .optimize = .ReleaseFast, + .target = target, + }); + const sdl_lib = sdl_dep.artifact("SDL2"); + exe.root_module.addIncludePath(sdl_lib.getEmittedIncludeTree().path(b, "SDL2")); + exe.linkLibrary(sdl_lib); + const sdl_ttf_dep = b.dependency("SDL_ttf", .{ + .optimize = .ReleaseFast, + .target = target, + }); + exe.linkLibrary(sdl_ttf_dep.artifact("SDL2_ttf")); + const sdl_image_dep = b.dependency("SDL_image", .{ + .optimize = .ReleaseFast, + .target = target, + }); + exe.linkLibrary(sdl_image_dep.artifact("SDL2_image")); + // } b.installArtifact(exe); // Create Check step for zls @@ -34,18 +47,9 @@ pub fn build(b: *Build) void { .target = target, .optimize = optimize, }); - if (target.query.isNativeOs() and target.result.os.tag == .linux) { - // The SDL package doesn't work for Linux yet, so we rely on system - // packages for now. - exe_check.linkSystemLibrary("SDL2"); - exe_check.linkLibC(); - } else { - const sdl_dep = b.dependency("sdl", .{ - .optimize = .ReleaseFast, - .target = target, - }); - exe_check.linkLibrary(sdl_dep.artifact("SDL2")); - } + exe_check.linkLibrary(sdl_dep.artifact("SDL2")); + exe_check.linkLibrary(sdl_ttf_dep.artifact("SDL2_ttf")); + exe_check.linkLibrary(sdl_image_dep.artifact("SDL2_image")); const check = b.step("check", "Check if project compiles, used by Zig Language Server"); check.dependOn(&exe_check.step); diff --git a/build.zig.zon b/build.zig.zon index 176bfa3..c8ac121 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -7,6 +7,14 @@ .url = "https://github.com/allyourcodebase/SDL/archive/7e4fc30b201d266f197fef4153f7e046bd189a7c.tar.gz", .hash = "1220c57b0bec66a2378e90cd7a79e36f9e7f60c02acca769ab3e6f974d4ef6766418", }, + .SDL_image = .{ + .url = "https://github.com/allyourcodebase/SDL_image/archive/d7b87f0cd57a1dff93fd0b2455ed7674ae776d4c.tar.gz", + .hash = "12209c505bb1364c6e408995274e8ce037cf5f41ad74f323f1e978efb16422ae2f3b", + }, + .SDL_ttf = .{ + .url = "https://github.com/allyourcodebase/SDL_ttf/archive/8d951496c0638ca7cbcec1eb5a9b3fe1e358241f.tar.gz", + .hash = "1220ffe43566e6406bc15a7c3ad46294f3e4e45e9e323bd2b4e020d3f4b22df5fd83", + }, }, .paths = .{ "build.zig", diff --git a/flake.nix b/flake.nix index 77e9df2..e99f586 100644 --- a/flake.nix +++ b/flake.nix @@ -15,13 +15,21 @@ }; zls = zlsPkg.defaultPackage.${system}; in { - devShell = pkgs.mkShell { + devShell = pkgs.mkShell rec { buildInputs = with pkgs; [ lldb SDL2 + SDL2_ttf + SDL2_image + ## For SDL dynamic linking + libpulseaudio + xorg.libXext + ## zig zls ]; + LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath buildInputs; + C_INCLUDE_PATH = "${pkgs.SDL2}/include:${pkgs.SDL2_ttf}/include:${pkgs.SDL2_image}/include"; }; }); } diff --git a/src/main.zig b/src/main.zig index 6f00187..bd62bd5 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,5 +1,6 @@ const c = @cImport({ @cInclude("SDL2/SDL.h"); + @cInclude("SDL2/SDL_image.h"); }); const std = @import("std"); @@ -10,7 +11,6 @@ const log = c.SDL_Log; var window: *c.struct_SDL_Window = undefined; var screen_surface: *c.struct_SDL_Surface = undefined; -var zig_image: *c.struct_SDL_Surface = undefined; const Offset = struct { x: i32, y: i32, @@ -21,8 +21,10 @@ pub fn main() !void { try init(); defer close(); - try loadMedia(); - var src_rect: c.struct_SDL_Rect = c.SDL_Rect{ .x = 10, .y = 10, .w = 400, .h = 140 }; + const zig_image = try loadSurface("assets/stretch.bmp"); + defer c.SDL_FreeSurface(zig_image); + + var src_rect: c.struct_SDL_Rect = c.SDL_Rect{ .x = 0, .y = 0, .w = SCREEN_WIDTH / 2, .h = SCREEN_HEIGHT / 2 }; var quit = false; while (!quit) { @@ -41,10 +43,10 @@ pub fn main() !void { img_pos.y = img_pos.y + 5; }, c.SDLK_LEFT => { - img_pos.x = img_pos.x + 5; + img_pos.x = img_pos.x - 5; }, c.SDLK_RIGHT => { - img_pos.x = img_pos.x - 5; + img_pos.x = img_pos.x + 5; }, else => {}, } @@ -54,8 +56,8 @@ pub fn main() !void { } } _ = c.SDL_FillRect(screen_surface, null, c.SDL_MapRGB(screen_surface.format, 0xff, 0xff, 0xff)); - var dest_rect = c.SDL_Rect{ .x = src_rect.x + img_pos.x, .y = src_rect.y + img_pos.y, .w = src_rect.w, .h = src_rect.h }; - _ = c.SDL_BlitSurface(zig_image, &src_rect, screen_surface, &dest_rect); + var dest_rect = c.SDL_Rect{ .x = src_rect.x + img_pos.x, .y = src_rect.y + img_pos.y, .w = SCREEN_WIDTH, .h = SCREEN_HEIGHT }; + _ = c.SDL_BlitScaled(zig_image, &src_rect, screen_surface, &dest_rect); _ = c.SDL_UpdateWindowSurface(window); c.SDL_Delay(17); @@ -77,22 +79,33 @@ fn init() !void { } window = opt_window.?; - // get surface and fill with white screen_surface = c.SDL_GetWindowSurface(window); -} -fn loadMedia() !void { - const image: [*c]c.struct_SDL_Surface = c.SDL_LoadBMP("src/zig.bmp"); - if (image == null) { - log("Unable to load media: %s\n", c.SDL_GetError()); - return error.SDLLoadError; - } else { - zig_image = image; + const img_flags = c.IMG_INIT_PNG; + if (c.IMG_Init(img_flags) != img_flags) { + log("Unable to initialize SDL Image: %s\n", c.IMG_GetError()); + return error.SDLInitializationFailed; } } +fn loadSurface(path: [*c]const u8) !*c.struct_SDL_Surface { + // TODO check file exists + const loaded_surface: [*c]c.struct_SDL_Surface = c.SDL_LoadBMP(path); + if (loaded_surface == null) { + log("Unable to load media at path %s: %s\n", path, c.SDL_GetError()); + return error.SDLLoadError; + } + defer c.SDL_FreeSurface(loaded_surface); + // Converting 24bit bmp to 32bit to match display + const optimized_surface = c.SDL_ConvertSurface(loaded_surface, screen_surface.format, 0); + if (optimized_surface == null) { + log("Unable to optimize media at path %s: %s\n", path, c.SDL_GetError()); + return error.SDLLoadError; + } + return optimized_surface; +} + fn close() void { - c.SDL_FreeSurface(zig_image); c.SDL_DestroyWindow(window); c.SDL_Quit(); } diff --git a/src/png.png b/src/png.png new file mode 100644 index 0000000..134d3a7 Binary files /dev/null and b/src/png.png differ