From 41a208846a74c8ffd3b4f4e6ab53a31663b9f695 Mon Sep 17 00:00:00 2001 From: Nathan Anderson Date: Mon, 6 Jan 2025 09:21:35 -0700 Subject: [PATCH] Added timers to the game --- src/main.zig | 40 ++++++++++++++++++++++--------- src/text.zig | 15 ++++++++---- src/utils/offset.zig | 4 ++++ src/utils/timer.zig | 56 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 100 insertions(+), 15 deletions(-) create mode 100644 src/utils/offset.zig create mode 100644 src/utils/timer.zig diff --git a/src/main.zig b/src/main.zig index ff71409..3a2f64c 100644 --- a/src/main.zig +++ b/src/main.zig @@ -8,6 +8,7 @@ const SCREEN_HEIGHT = 480; const log = sdl.SDL_Log; const GameText = @import("./text.zig").GameText; const RGBAColor = @import("./utils/rgb_color.zig").RGBAColor; +const Timer = @import("./utils/timer.zig").Timer; var window: *sdl.struct_SDL_Window = undefined; // var screen_surface: *sdl.struct_SDL_Surface = undefined; @@ -41,6 +42,8 @@ pub fn main() !void { var quit = false; var shifted = false; + var start_time: u32 = 0; + var timer = Timer{}; while (!quit) { var event: sdl.SDL_Event = undefined; while (sdl.SDL_PollEvent(&event) != 0) { @@ -58,17 +61,14 @@ pub fn main() !void { }, sdl.SDL_KEYDOWN => { switch (event.key.keysym.sym) { - sdl.SDLK_r => { - game_state.r = if (shifted) game_state.r - 5 else game_state.r + 5; + sdl.SDLK_RETURN => { + start_time = sdl.SDL_GetTicks(); }, - sdl.SDLK_g => { - game_state.g = if (shifted) game_state.g - 5 else game_state.g + 5; + sdl.SDLK_s => { + if (timer.status == .started) timer.stop() else timer.start(); }, - sdl.SDLK_b => { - game_state.b = if (shifted) game_state.b - 5 else game_state.b + 5; - }, - sdl.SDLK_LSHIFT => { - shifted = true; + sdl.SDLK_p => { + if (timer.status == .paused) timer.unpause() else timer.pause(); }, // sdl.SDLK_UP => { // img_pos.y = img_pos.y - 5; @@ -93,8 +93,26 @@ pub fn main() !void { _ = sdl.SDL_RenderClear(renderer); _ = sdl.SDL_RenderCopy(renderer, bg_texture, null, null); game_state.update_tick(); - var text = try GameText.loadFromRenderedText("Test 123", RGBAColor.whiteSmoke().tosdl()); - try text.render(&game_state); + var text = try GameText.loadFromRenderedText("Press S to start / stop", RGBAColor.whiteSmoke().tosdl()); + try text.render( + &game_state, + .{ .x = @intCast(game_state.SCREEN_WIDTH - text.w), .y = 2 }, + ); + text = try GameText.loadFromRenderedText("Press P to pause / unpause", RGBAColor.whiteSmoke().tosdl()); + try text.render( + &game_state, + .{ .x = @intCast(game_state.SCREEN_WIDTH - text.w), .y = 24 }, + ); + + var buf: [8]u8 = undefined; + const timer_ms = timer.getTicks(); + // const timer_base = std.math.log10(timer_ms) + 3; + const time_str: []const u8 = try std.fmt.bufPrint(&buf, "{d}ms", .{timer_ms}); + var time_text = try GameText.loadFromRenderedText(time_str, RGBAColor.whiteSmoke().tosdl()); + try time_text.render( + &game_state, + .{ .x = @intCast(game_state.SCREEN_WIDTH - time_text.w), .y = 64 }, + ); // Render red rect // const fill_rect: sdl.struct_SDL_Rect = sdl.SDL_Rect{ .x = SCREEN_WIDTH / 4, .y = SCREEN_HEIGHT / 4, .w = SCREEN_WIDTH / 2 + img_pos.x, .h = SCREEN_HEIGHT / 2 + img_pos.y }; diff --git a/src/text.zig b/src/text.zig index a8ee724..29d0aa9 100644 --- a/src/text.zig +++ b/src/text.zig @@ -1,6 +1,8 @@ const sdl = @import("./sdl.zig").c; const std = @import("std"); const GameState = @import("./game_state.zig").GameState; +const Offset = @import("./utils/offset.zig").Offset; +const FONT_SIZE = 24; var font: ?*sdl.TTF_Font = null; var text_texture: ?*sdl.SDL_Texture = null; @@ -14,7 +16,8 @@ pub const GameText = struct { h: u32, pub fn loadFromRenderedText(text: []const u8, color: sdl.SDL_Color) !GameText { - const c_text: [*c]const u8 = @ptrCast(text); + const trunc_str = text[0..text.len]; + const c_text: [*c]const u8 = @ptrCast(trunc_str); const text_surface: [*c]sdl.SDL_Surface = sdl.TTF_RenderText_Solid(font.?, c_text, color) orelse { sdl.SDL_Log("Error loading text surface: %s\n", sdl.SDL_GetError()); return error.FailedToRenderSurface; @@ -45,7 +48,11 @@ pub const GameText = struct { return error.Unimplemented; } - pub fn render(self: *GameText, game_state: *GameState) !void { + pub fn render( + self: *GameText, + game_state: *GameState, + offset: Offset, + ) !void { if (!text_init) { return error.TextNotInitialized; } @@ -62,12 +69,12 @@ pub const GameText = struct { }; const srcr = sdl.SDL_Rect{ .x = 0, .y = 0, .w = @intCast(self.w), .h = @intCast(self.h) }; - const destr = sdl.SDL_Rect{ .x = @intCast(game_state.SCREEN_WIDTH - self.w), .y = 10, .w = @intCast(self.w), .h = @intCast(self.h) }; + const destr = sdl.SDL_Rect{ .x = @intCast(offset.x), .y = @intCast(offset.y), .w = @intCast(self.w), .h = @intCast(self.h) }; _ = sdl.SDL_RenderCopy(game_state.renderer, text_texture, &srcr, &destr); } pub fn initFont() !void { - const loaded_font = sdl.TTF_OpenFont("./assets/fonts/DepartureMonoNF-Regular.ttf", 24) orelse { + const loaded_font = sdl.TTF_OpenFont("./assets/fonts/DepartureMonoNF-Regular.ttf", FONT_SIZE) orelse { sdl.SDL_Log("Error loading ttf font: %s\n", sdl.TTF_GetError()); return error.FailedToLoadFont; }; diff --git a/src/utils/offset.zig b/src/utils/offset.zig new file mode 100644 index 0000000..386bc5f --- /dev/null +++ b/src/utils/offset.zig @@ -0,0 +1,4 @@ +pub const Offset = struct { + x: i32, + y: i32, +}; diff --git a/src/utils/timer.zig b/src/utils/timer.zig new file mode 100644 index 0000000..02d43db --- /dev/null +++ b/src/utils/timer.zig @@ -0,0 +1,56 @@ +const sdl = @import("./../sdl.zig").c; + +pub const TimerStatus = enum { started, stopped, paused }; + +pub const Timer = struct { + start_ticks_ms: u32 = 0, + pause_ticks_ms: u32 = 0, + status: TimerStatus = TimerStatus.stopped, + + pub fn start(self: *Timer) void { + if (self.status == .started) return; + self.status = .started; + self.start_ticks_ms = sdl.SDL_GetTicks(); + self.pause_ticks_ms = 0; + } + + pub fn stop(self: *Timer) void { + if (self.status == .stopped) return; + self.status = .stopped; + self.start_ticks_ms = 0; + self.pause_ticks_ms = 0; + } + + pub fn reset(self: *Timer) void { + self.status = .started; + self.start_ticks_ms = sdl.SDL_GetTicks(); + self.pause_ticks_ms = 0; + } + + pub fn pause(self: *Timer) void { + if (self.status == .paused or self.status == .stopped) return; + self.status = .paused; + self.pause_ticks_ms = sdl.SDL_GetTicks(); + } + + pub fn unpause(self: *Timer) void { + if (self.status == .started or self.status == .stopped) return; + self.status = .started; + self.start_ticks_ms = sdl.SDL_GetTicks() - self.pause_ticks_ms; + self.pause_ticks_ms = 0; + } + + pub fn getTicks(self: *Timer) u32 { + switch (self.status) { + .stopped => { + return 0; + }, + .paused => { + return self.pause_ticks_ms; + }, + .started => { + return sdl.SDL_GetTicks() - self.start_ticks_ms; + }, + } + } +};