From f989c73947f5a8039c9332dce232b171ca92b543 Mon Sep 17 00:00:00 2001 From: jjanzen Date: Mon, 31 Mar 2025 19:53:34 -0500 Subject: [PATCH] fix zig 14.0 --- build.zig.zon | 28 ++++++--- src/frontend/io_interface.zig | 6 +- src/frontend/sdl.zig | 107 +++++++++++++++++++++++++++++----- src/run.zig | 3 - 4 files changed, 116 insertions(+), 28 deletions(-) diff --git a/build.zig.zon b/build.zig.zon index cf22c40..dcba533 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -6,16 +6,29 @@ // // It is redundant to include "zig" in this name because it is already // within the Zig package namespace. - .name = "simple-lib-use", + .name = .urlg, // This is a [Semantic Version](https://semver.org/). // In a future version of Zig it will be used for package deduplication. .version = "0.0.0", - // This field is optional. - // This is currently advisory only; Zig does not yet do anything - // with this value. - //.minimum_zig_version = "0.11.0", + // Together with name, this represents a globally unique package + // identifier. This field is generated by the Zig toolchain when the + // package is first created, and then *never changes*. This allows + // unambiguous detection of one package being an updated version of + // another. + // + // When forking a Zig project, this id should be regenerated (delete the + // field and run `zig build`) if the upstream project is still maintained. + // Otherwise, the fork is *hostile*, attempting to take control over the + // original project's identity. Thus it is recommended to leave the comment + // on the following line intact, so that it shows up in code reviews that + // modify the field. + .fingerprint = 0x304ee3dc9bb4ef07, // Changing this has security and trust implications. + + // Tracks the earliest Zig version that the package considers to be a + // supported use case. + .minimum_zig_version = "0.14.0", // This field is optional. // Each dependency must either provide a `url` and `hash`, or a `path`. @@ -27,7 +40,8 @@ //.example = .{ // // When updating this field to a new URL, be sure to delete the corresponding // // `hash`, otherwise you are communicating that you expect to find the old hash at - // // the new URL. + // // the new URL. If the contents of a URL change this will result in a hash mismatch + // // which will prevent zig from using it. // .url = "https://example.com/foo.tar.gz", // // // This is computed from the file contents of the directory of files that is @@ -45,7 +59,7 @@ // // build root. In this case the package's hash is irrelevant and therefore not // // computed. This field and `url` are mutually exclusive. // .path = "foo", - + // // // When this is set to `true`, a package is declared to be lazily // // fetched. This makes the dependency only get fetched if it is // // actually used. diff --git a/src/frontend/io_interface.zig b/src/frontend/io_interface.zig index a2aa0ca..08e4293 100644 --- a/src/frontend/io_interface.zig +++ b/src/frontend/io_interface.zig @@ -14,17 +14,17 @@ pub const IOInterface = struct { const gen = struct { pub fn displayMessage(pointer: *anyopaque, str: []const u8) anyerror!void { const self: T = @ptrCast(@alignCast(pointer)); - return ptr_info.Pointer.child.displayMessage(self, str); + return ptr_info.pointer.child.displayMessage(self, str); } pub fn waitForTick(pointer: *anyopaque) anyerror!Action { const self: T = @ptrCast(@alignCast(pointer)); - return ptr_info.Pointer.child.waitForTick(self); + return ptr_info.pointer.child.waitForTick(self); } pub fn deinit(pointer: *anyopaque) void { const self: T = @ptrCast(@alignCast(pointer)); - return ptr_info.Pointer.child.deinit(self); + return ptr_info.pointer.child.deinit(self); } }; diff --git a/src/frontend/sdl.zig b/src/frontend/sdl.zig index bf2fbbb..674ecf9 100644 --- a/src/frontend/sdl.zig +++ b/src/frontend/sdl.zig @@ -5,22 +5,80 @@ const sdl = @cImport({ const Action = @import("../actions.zig").Action; const IOInterface = @import("io_interface.zig").IOInterface; +const TEXT_SPRITE_INDEX = 0; +const TEXT_WIDTH = 10; +const TEXT_HEIGHT = 16; +const TEXT_SCALE = 2; + +const SCREEN_WIDTH = 640; +const SCREEN_HEIGHT = 480; + pub const IO = struct { allocator: std.mem.Allocator, screen: ?*sdl.SDL_Window, - sprites: std.ArrayList([*c]sdl.SDL_Surface), + screen_surface: ?*sdl.SDL_Surface, + sprites: std.ArrayList(?*sdl.SDL_Surface), + + x_pos: c_int, + y_pos: c_int, fn loadSprite(self: *IO) !void { - const sprite = sdl.SDL_LoadBMP("assets/image.bmp"); - if (sprite == null) return error.FailedToLoadSprite; - try self.sprites.append(sprite); + const sprite = sdl.SDL_LoadBMP("assets/ascii.bmp"); + if (sprite == null) { + std.log.err("{s}", .{sdl.SDL_GetError()}); + return error.FailedToLoadSprite; + } + + const optimized_sprite = sdl.SDL_ConvertSurface(sprite, self.screen_surface.?.format); + if (optimized_sprite == null) { + std.log.err("{s}", .{sdl.SDL_GetError()}); + return error.FailedToOptimizeSprite; + } + + _ = sdl.SDL_DestroySurface(sprite); + try self.sprites.append(optimized_sprite); } pub fn displayMessage(self: *IO, str: []const u8) anyerror!void { - _ = self; - _ = str; + // TODO: remove this + _ = sdl.SDL_ClearSurface(self.screen_surface, 1, 1, 1, 1); - // TODO + for (str) |c| { + if (c < ' ') continue; + + if (self.x_pos + TEXT_SCALE * TEXT_WIDTH >= SCREEN_WIDTH) { + self.x_pos = 0; + self.y_pos += TEXT_SCALE * TEXT_HEIGHT; + } else { + self.x_pos += TEXT_SCALE * TEXT_WIDTH; + } + + const index: c_int = c - ' '; + + std.log.debug("index: 0x{x}", .{index}); + + const src_rect = sdl.SDL_Rect{ + .x = index * TEXT_WIDTH, + .y = 0, + .w = TEXT_WIDTH, + .h = TEXT_HEIGHT, + }; + + const dst_rect = sdl.SDL_Rect{ + .x = self.x_pos, + .y = self.y_pos, + .w = TEXT_SCALE * TEXT_WIDTH, + .h = TEXT_SCALE * TEXT_HEIGHT, + }; + + if (!sdl.SDL_BlitSurfaceScaled(self.sprites.items[TEXT_SPRITE_INDEX], &src_rect, self.screen_surface, &dst_rect, sdl.SDL_SCALEMODE_NEAREST)) { + return error.SDL_BlitSurfaceFailed; + } + } + + if (!sdl.SDL_UpdateWindowSurface(self.screen)) { + return error.SDL_UpdateSurfaceFailed; + } } pub fn waitForTick(self: *IO) anyerror!Action { @@ -42,26 +100,45 @@ pub const IO = struct { pub fn init(allocator: std.mem.Allocator) !IOInterface { var io = try allocator.create(IO); io.allocator = allocator; - io.sprites = std.ArrayList([*c]sdl.SDL_Surface).init(allocator); + io.sprites = std.ArrayList(?*sdl.SDL_Surface).init(allocator); - if (!sdl.SDL_Init(sdl.SDL_INIT_VIDEO)) return error.SDL_Failed; + io.x_pos = 0; + io.y_pos = 0; + + if (!sdl.SDL_Init(sdl.SDL_INIT_VIDEO)) { + std.log.err("{s}", .{sdl.SDL_GetError()}); + return error.SDL_Failed; + } io.screen = sdl.SDL_CreateWindow( "urlg", - 640, - 480, + SCREEN_WIDTH, + SCREEN_HEIGHT, 0, ); - if (io.screen == null) return error.SDL_Failed; + if (io.screen == null) { + std.log.err("{s}", .{sdl.SDL_GetError()}); + return error.SDL_Failed; + } + io.screen_surface = sdl.SDL_GetWindowSurface(io.screen); io.loadSprite() catch |err| { io.deinit(); return err; }; - const screen_surface = sdl.SDL_GetWindowSurface(io.screen); - _ = sdl.SDL_BlitSurface(io.sprites.items[0], null, screen_surface, null); - _ = sdl.SDL_UpdateWindowSurface(io.screen); + + try io.displayMessage(" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghjklmnopqrstuvwxyz{|}~"); + //try io.displayMessage("THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG."); + + //_ = sdl.SDL_BlitSurfaceScaled(io.sprites.items[0], null, io.screen_surface, &rect, sdl.SDL_SCALEMODE_NEAREST); + //rect.x += HEX_SCALE + 2 * HEX_ANGLE_DIST; + //_ = sdl.SDL_BlitSurfaceScaled(io.sprites.items[0], null, io.screen_surface, &rect, sdl.SDL_SCALEMODE_NEAREST); + + if (!sdl.SDL_UpdateWindowSurface(io.screen)) { + io.deinit(); + return error.SDL_UpdateSurfaceFailed; + } return IOInterface.init(io); } diff --git a/src/run.zig b/src/run.zig index e20d9b5..01ead36 100644 --- a/src/run.zig +++ b/src/run.zig @@ -4,14 +4,11 @@ const IO = @import("frontend/io_interface.zig").IOInterface; const Action = @import("actions.zig").Action; pub fn run(allocator: std.mem.Allocator, io: *IO) !void { - try io.displayMessage("Initialized"); - var action = Action.illegal; var tick_count: usize = 0; while (action != Action.exit) { const str = try std.fmt.allocPrint(allocator, "{}", .{tick_count}); defer allocator.free(str); - try io.displayMessage(str); action = try io.waitForTick(); switch (action) {