From a8f63313ee5f729b6cbc8e38a151c05cef454291 Mon Sep 17 00:00:00 2001 From: kdx Date: Wed, 31 May 2023 21:59:22 +0200 Subject: draw begin+end --- src/main.zig | 3 +++ src/zxc.zig | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 84 insertions(+), 4 deletions(-) diff --git a/src/main.zig b/src/main.zig index 4a5c92c..ea12f00 100644 --- a/src/main.zig +++ b/src/main.zig @@ -8,4 +8,7 @@ pub fn main() !void { .target_fps = 60, }); defer z.deinit(); + + try z.drawBegin(); + try z.drawEnd(); } diff --git a/src/zxc.zig b/src/zxc.zig index f394f7d..599dfaa 100644 --- a/src/zxc.zig +++ b/src/zxc.zig @@ -6,13 +6,14 @@ const Config = struct { const RenderMode = enum { Pixel, PixelPerfect, - HdRender, + Hd, }; width: usize, height: usize, scale: usize = 1, - target_fps: usize, + target_fps: ?u31, + show_cursor: bool = false, render: RenderMode = .Pixel, title: [:0]const u8 = "ZXC", }; @@ -20,12 +21,20 @@ const Config = struct { config: Config, window: sdl.Window, renderer: sdl.Renderer, +target: ?sdl.Texture, +min_dt: u64, +next_time: u64, +tick: u64, pub fn init(config: Config) !Self { var self = Self{ .config = config, .window = undefined, .renderer = undefined, + .target = null, + .min_dt = undefined, + .next_time = undefined, + .tick = 0, }; try sdl.init(.{ .video = true }); @@ -54,17 +63,85 @@ pub fn init(config: Config) !Self { sdl.RendererFlags{ .accelerated = true }, ); errdefer self.renderer.destroy(); + try self.renderer.setDrawBlendMode(.blend); + + if (config.render != .Hd) { + self.target = try sdl.createTexture( + self.renderer, + .rgb888, + .target, + config.width, + config.height, + ); + } + errdefer if (self.target != null) self.target.?.destroy(); + + if (!config.show_cursor) + _ = try sdl.showCursor(false); _ = sdl.setHint( sdl.hint.render_scale_quality, - if (config.render == .HdRender) "1" else "0", + if (config.render == .Hd) "1" else "0", ); + if (config.target_fps != null) { + self.min_dt = 1000 / config.target_fps.?; + self.next_time = sdl.getTicks64(); + } + return self; } -pub fn deinit(self: Self) void { +pub fn deinit(self: *const Self) void { + if (self.target != null) + self.target.?.destroy(); self.renderer.destroy(); self.window.destroy(); sdl.quit(); } + +pub fn drawBegin(self: *const Self) !void { + if (self.config.render == .Hd) + return; + + try self.renderer.setTarget(self.target); +} + +pub fn drawEnd(self: *Self) !void { + if (self.config.render != .Hd) { + try self.renderer.setTarget(null); + try self.renderer.setColorRGBA(0, 0, 0, 255); + try self.renderer.clear(); + + const size = self.window.getSize(); + const scw = @intToFloat(f64, self.config.width); + const sch = @intToFloat(f64, self.config.height); + + const scale = brk: { + const ratio_w = @intToFloat(f64, size.width) / scw; + const ratio_h = @intToFloat(f64, size.height) / sch; + const ratio = if (ratio_w < ratio_h) ratio_w else ratio_h; + break :brk if (ratio > 1) std.math.floor(ratio) else ratio; + }; + + const dst_rect = sdl.Rectangle{ + .x = size.width - @floatToInt(c_int, scw * scale), + .y = size.height - @floatToInt(c_int, sch * scale), + .width = @floatToInt(c_int, scw * scale), + .height = @floatToInt(c_int, sch * scale), + }; + try self.renderer.copy(self.target.?, dst_rect, null); + } + + if (self.config.target_fps != null) { + self.next_time += self.min_dt; + const cur_time = sdl.getTicks64(); + if (self.next_time <= cur_time) + self.next_time = cur_time + else + sdl.delay(@truncate(u32, self.next_time - cur_time)); + } + + self.renderer.present(); + self.tick += 1; +} -- cgit v1.2.3