const std = @import("std"); const builtin = @import("builtin"); const sdl = @import("sdl"); const err = @import("error.zig"); const Mouse = @import("mouse.zig"); const Keyboard = @import("keyboard.zig"); pub const Graphics = @import("graphics.zig"); pub const World = @import("world.zig"); const Time = struct { delta: f32, now: sdl.Time, }; pub var alloc: std.mem.Allocator = undefined; var running: bool = false; var time: Time = .{ .delta = 0, .now = 0 }; pub var keyboard: Keyboard = .{}; pub var mouse: Mouse = .{}; const Game = @This(); pub fn init(game_alloc: std.mem.Allocator) void { Game.alloc = game_alloc; Game.running = false; Game.time = Time{ .now = 0, .delta = 0 }; Game.keyboard = .{}; Game.mouse = .{ .x = 0, .y = 0, .dx = 0, .dy = 0 }; Graphics.create(); World.initDebug(); } pub fn run() void { Game.running = true; while (Game.running) { var current_time: sdl.Time = undefined; if (sdl.GetCurrentTime(¤t_time)) { if (Game.time.now != 0) { Game.time.delta = @as(f32, @floatFromInt(current_time - Game.time.now)) * 0.000000001; } Game.time.now = current_time; } else err.sdl(); Game.processEvents(); World.updateReal(Game.time.delta); if (Game.beginDraw()) { World.draw(Game.time.delta); Game.endDraw(); } } } fn beginDraw() bool { return Graphics.beginDraw(); } fn endDraw() void { Graphics.endDraw(); } fn processEvents() void { Game.mouse.dx = 0.0; Game.mouse.dy = 0.0; Game.keyboard.keys.reset(); sdl.PumpEvents(); while (true) { var buffer: [16]sdl.Event = undefined; const count: usize = @intCast(sdl.PeepEvents(&buffer, buffer.len, sdl.GETEVENT, sdl.EVENT_FIRST, sdl.EVENT_LAST)); if (count == -1) err.sdl(); for (buffer[0..count]) |event| { switch (event.type) { sdl.EVENT_QUIT => { Game.running = false; }, sdl.EVENT_WINDOW_RESIZED => { if (event.window.windowID != Graphics.windowId()) continue; Graphics.resize(@intCast(event.window.data1), @intCast(event.window.data2)); }, sdl.EVENT_MOUSE_MOTION => { if (event.motion.windowID != Graphics.windowId()) continue; Game.mouse.x = event.motion.x; Game.mouse.y = event.motion.y; Game.mouse.dx += event.motion.xrel; Game.mouse.dy += event.motion.yrel; }, sdl.EVENT_KEY_DOWN => { if (event.key.windowID != Graphics.windowId()) continue; Game.keyboard.keys.press(event.key.scancode); }, sdl.EVENT_KEY_UP => { if (event.key.windowID != Graphics.windowId()) continue; Game.keyboard.keys.release(event.key.scancode); }, sdl.EVENT_MOUSE_BUTTON_DOWN => { if (event.button.windowID != Graphics.windowId()) continue; Game.mouse.buttons.press(event.button.button); }, sdl.EVENT_MOUSE_BUTTON_UP => { if (event.button.windowID != Graphics.windowId()) continue; Game.mouse.buttons.release(event.button.button); }, else => {}, } } if (count < buffer.len) { break; } } sdl.FlushEvents(sdl.EVENT_FIRST, sdl.EVENT_LAST); } pub fn deinit() void { World.deinit(); Graphics.destroy(); sdl.Quit(); }