Fix frame and grabbing
This commit is contained in:
@@ -33,8 +33,8 @@ pub fn build(b: *std.Build) void {
|
||||
|
||||
exe.root_module.addIncludePath(b.path("src"));
|
||||
exe.root_module.addCSourceFiles(.{
|
||||
.files = &.{ "src/xdg-shell.c", },
|
||||
.language = .c,
|
||||
.files = &.{ "src/xdg-shell.c", },
|
||||
});
|
||||
|
||||
b.installArtifact(exe);
|
||||
|
||||
+83
-44
@@ -1,4 +1,5 @@
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const linux = std.os.linux;
|
||||
|
||||
const puzzle = @import("puzzle");
|
||||
@@ -46,6 +47,7 @@ const WaylandState = struct {
|
||||
seat: ?*c.wl_seat,
|
||||
shared_memory: ?*c.wl_shm,
|
||||
xdg_wm_base: ?*c.xdg_wm_base,
|
||||
surface: ?*c.wl_surface,
|
||||
|
||||
xkb_context: ?*c.xkb_context,
|
||||
xkb_keymap: ?*c.xkb_keymap,
|
||||
@@ -54,6 +56,7 @@ const WaylandState = struct {
|
||||
allocator: std.mem.Allocator,
|
||||
|
||||
resize: bool,
|
||||
frame_ready: bool,
|
||||
|
||||
window_resized: bool,
|
||||
window_width: i32,
|
||||
@@ -107,7 +110,25 @@ fn createSharedMemoryPool(wl_state: WaylandState) !MemoryPool {
|
||||
};
|
||||
}
|
||||
|
||||
fn xdg_wm_base_handle_ping(data: ?*anyopaque, xdg_wm_base: ?*c.struct_xdg_wm_base, serial: u32) callconv(.c) void {
|
||||
fn wlFrameHandleDone(data: ?*anyopaque, callback: ?*c.wl_callback, callback_data: u32) callconv(.c) void {
|
||||
_ = callback_data;
|
||||
|
||||
var wl_state: *WaylandState = @ptrCast(@alignCast(data));
|
||||
|
||||
c.wl_callback_destroy(callback);
|
||||
|
||||
const new_callback: ?*c.wl_callback = c.wl_surface_frame(wl_state.surface);
|
||||
_ = c.wl_callback_add_listener(new_callback, &frame_callback_listener, wl_state);
|
||||
|
||||
std.debug.print("[Wayland] Frame ready\n", .{});
|
||||
wl_state.frame_ready = true;
|
||||
}
|
||||
|
||||
const frame_callback_listener: c.wl_callback_listener = .{
|
||||
.done = wlFrameHandleDone,
|
||||
};
|
||||
|
||||
fn xdg_wm_base_handle_ping(data: ?*anyopaque, xdg_wm_base: ?*c.xdg_wm_base, serial: u32) callconv(.c) void {
|
||||
_ = data;
|
||||
std.debug.print("[Wayland] Pong.\n", .{});
|
||||
c.xdg_wm_base_pong(xdg_wm_base, serial);
|
||||
@@ -118,7 +139,7 @@ const xdg_wm_base_listener: c.xdg_wm_base_listener = .{
|
||||
};
|
||||
|
||||
// configure: ?*const fn (?*anyopaque, ?*struct_xdg_surface, u32) callconv(.c) void = @import("std").mem.zeroes(?*const fn (?*anyopaque, ?*struct_xdg_surface, u32) callconv(.c) void),
|
||||
fn xdg_surface_handle_configure(data: ?*anyopaque, xdg_surface: ?*c.struct_xdg_surface, serial: u32) callconv(.c) void {
|
||||
fn xdg_surface_handle_configure(data: ?*anyopaque, xdg_surface: ?*c.xdg_surface, serial: u32) callconv(.c) void {
|
||||
var wl_state: *WaylandState = @ptrCast(@alignCast(data));
|
||||
|
||||
c.xdg_surface_ack_configure(xdg_surface, serial);
|
||||
@@ -137,10 +158,10 @@ const xdg_surface_listener: c.xdg_surface_listener = .{
|
||||
|
||||
fn xdg_toplevel_handle_configure(
|
||||
data: ?*anyopaque,
|
||||
xdg_toplevel: ?*c.struct_xdg_toplevel,
|
||||
xdg_toplevel: ?*c.xdg_toplevel,
|
||||
width: i32,
|
||||
height: i32,
|
||||
names: [*c]c.struct_wl_array,
|
||||
names: [*c]c.wl_array,
|
||||
) callconv(.c) void {
|
||||
var wl_state: *WaylandState = @ptrCast(@alignCast(data));
|
||||
_ = xdg_toplevel;
|
||||
@@ -154,7 +175,7 @@ fn xdg_toplevel_handle_configure(
|
||||
}
|
||||
}
|
||||
|
||||
fn xdg_toplevel_handle_close(data: ?*anyopaque, xdg_toplevel: ?*c.struct_xdg_toplevel) callconv(.c) void {
|
||||
fn xdg_toplevel_handle_close(data: ?*anyopaque, xdg_toplevel: ?*c.xdg_toplevel) callconv(.c) void {
|
||||
var wl_state: *WaylandState = @ptrCast(@alignCast(data));
|
||||
_ = xdg_toplevel;
|
||||
|
||||
@@ -162,20 +183,20 @@ fn xdg_toplevel_handle_close(data: ?*anyopaque, xdg_toplevel: ?*c.struct_xdg_top
|
||||
wl_state.running = false;
|
||||
}
|
||||
|
||||
fn xdg_toplevel_handle_configure_bounds(data: ?*anyopaque, toplevel: ?*c.struct_xdg_toplevel, width: i32, height: i32) callconv(.c) void {
|
||||
fn xdg_toplevel_handle_configure_bounds(data: ?*anyopaque, toplevel: ?*c.xdg_toplevel, width: i32, height: i32) callconv(.c) void {
|
||||
_ = data;
|
||||
_ = toplevel;
|
||||
std.debug.print("[Wayland] xdg toplevel configure bounds: w = {d}, h = {d}.\n", .{ width, height });
|
||||
}
|
||||
|
||||
fn xdg_toplevel_handle_wm_capabilities(data: ?*anyopaque, toplevel: ?*c.struct_xdg_toplevel, names: [*c]c.struct_wl_array) callconv(.c) void {
|
||||
fn xdg_toplevel_handle_wm_capabilities(data: ?*anyopaque, toplevel: ?*c.xdg_toplevel, names: [*c]c.wl_array) callconv(.c) void {
|
||||
_ = data;
|
||||
_ = toplevel;
|
||||
_ = names;
|
||||
std.debug.print("[Wayland] xdg toplevel wm capabilities.\n", .{});
|
||||
}
|
||||
|
||||
const xdg_toplevel_listener: c.struct_xdg_toplevel_listener = .{
|
||||
const xdg_toplevel_listener: c.xdg_toplevel_listener = .{
|
||||
.configure = xdg_toplevel_handle_configure,
|
||||
.close = xdg_toplevel_handle_close,
|
||||
.configure_bounds = xdg_toplevel_handle_configure_bounds,
|
||||
@@ -194,7 +215,7 @@ const xdg_toplevel_listener: c.struct_xdg_toplevel_listener = .{
|
||||
/// @param surface surface entered by the pointer
|
||||
/// @param surface_x surface-local x coordinate
|
||||
/// @param surface_y surface-local y coordinate
|
||||
fn wlPointerHandleEnter(data: ?*anyopaque, wl_pointer: ?*c.struct_wl_pointer, serial: u32, surface: ?*c.struct_wl_surface, surface_x: c.wl_fixed_t, surface_y: c.wl_fixed_t) callconv(.c) void {
|
||||
fn wlPointerHandleEnter(data: ?*anyopaque, wl_pointer: ?*c.wl_pointer, serial: u32, surface: ?*c.wl_surface, surface_x: c.wl_fixed_t, surface_y: c.wl_fixed_t) callconv(.c) void {
|
||||
const wl_state: *WaylandState = @ptrCast(@alignCast(data));
|
||||
|
||||
_ = wl_pointer;
|
||||
@@ -215,7 +236,7 @@ fn wlPointerHandleEnter(data: ?*anyopaque, wl_pointer: ?*c.struct_wl_pointer, se
|
||||
/// the new focus.
|
||||
/// @param serial serial number of the leave event
|
||||
/// @param surface surface left by the pointer
|
||||
fn wlPointerHandleLeave(data: ?*anyopaque, wl_pointer: ?*c.struct_wl_pointer, serial: u32, surface: ?*c.struct_wl_surface) callconv(.c) void {
|
||||
fn wlPointerHandleLeave(data: ?*anyopaque, wl_pointer: ?*c.wl_pointer, serial: u32, surface: ?*c.wl_surface) callconv(.c) void {
|
||||
const wl_state: *WaylandState = @ptrCast(@alignCast(data));
|
||||
|
||||
_ = wl_pointer;
|
||||
@@ -233,7 +254,7 @@ fn wlPointerHandleLeave(data: ?*anyopaque, wl_pointer: ?*c.struct_wl_pointer, se
|
||||
/// @param time timestamp with millisecond granularity
|
||||
/// @param surface_x surface-local x coordinate
|
||||
/// @param surface_y surface-local y coordinate
|
||||
fn wlPointerHandleMotion(data: ?*anyopaque, wl_pointer: ?*c.struct_wl_pointer, time: u32, surface_x: c.wl_fixed_t, surface_y: c.wl_fixed_t) callconv(.c) void {
|
||||
fn wlPointerHandleMotion(data: ?*anyopaque, wl_pointer: ?*c.wl_pointer, time: u32, surface_x: c.wl_fixed_t, surface_y: c.wl_fixed_t) callconv(.c) void {
|
||||
const wl_state: *WaylandState = @ptrCast(@alignCast(data));
|
||||
|
||||
_ = wl_pointer;
|
||||
@@ -263,7 +284,7 @@ fn wlPointerHandleMotion(data: ?*anyopaque, wl_pointer: ?*c.struct_wl_pointer, t
|
||||
/// @param time timestamp with millisecond granularity
|
||||
/// @param button button that produced the event
|
||||
/// @param state physical state of the button
|
||||
fn wlPointerHandleButton(data: ?*anyopaque, wl_pointer: ?*c.struct_wl_pointer, serial: u32, time: u32, button: u32, state: u32) callconv(.c) void {
|
||||
fn wlPointerHandleButton(data: ?*anyopaque, wl_pointer: ?*c.wl_pointer, serial: u32, time: u32, button: u32, state: u32) callconv(.c) void {
|
||||
const wl_state: *WaylandState = @ptrCast(@alignCast(data));
|
||||
|
||||
_ = wl_pointer;
|
||||
@@ -296,7 +317,7 @@ fn wlPointerHandleButton(data: ?*anyopaque, wl_pointer: ?*c.struct_wl_pointer, s
|
||||
/// @param time timestamp with millisecond granularity
|
||||
/// @param axis axis type
|
||||
/// @param value length of vector in surface-local coordinate space
|
||||
fn wlPointerHandleAxis(data: ?*anyopaque, wl_pointer: ?*c.struct_wl_pointer, time: u32, axis: u32, value: c.wl_fixed_t) callconv(.c) void {
|
||||
fn wlPointerHandleAxis(data: ?*anyopaque, wl_pointer: ?*c.wl_pointer, time: u32, axis: u32, value: c.wl_fixed_t) callconv(.c) void {
|
||||
const wl_state: *WaylandState = @ptrCast(@alignCast(data));
|
||||
|
||||
_ = wl_pointer;
|
||||
@@ -337,7 +358,7 @@ fn wlPointerHandleAxis(data: ?*anyopaque, wl_pointer: ?*c.struct_wl_pointer, tim
|
||||
/// @param axis_source source of the axis event
|
||||
/// @since 5
|
||||
///
|
||||
fn wlPointerHandleAxisSource(data: ?*anyopaque, wl_pointer: ?*c.struct_wl_pointer, axis_source: u32) callconv(.c) void {
|
||||
fn wlPointerHandleAxisSource(data: ?*anyopaque, wl_pointer: ?*c.wl_pointer, axis_source: u32) callconv(.c) void {
|
||||
_ = data;
|
||||
_ = wl_pointer;
|
||||
_ = axis_source;
|
||||
@@ -362,7 +383,7 @@ fn wlPointerHandleAxisSource(data: ?*anyopaque, wl_pointer: ?*c.struct_wl_pointe
|
||||
/// @param time timestamp with millisecond granularity
|
||||
/// @param axis the axis stopped with this event
|
||||
/// @since 5
|
||||
fn wlPointerHandleAxisStop(data: ?*anyopaque, wl_pointer: ?*c.struct_wl_pointer, time: u32, axis: u32) callconv(.c) void {
|
||||
fn wlPointerHandleAxisStop(data: ?*anyopaque, wl_pointer: ?*c.wl_pointer, time: u32, axis: u32) callconv(.c) void {
|
||||
_ = data;
|
||||
_ = wl_pointer;
|
||||
_ = time;
|
||||
@@ -406,7 +427,7 @@ fn wlPointerHandleAxisStop(data: ?*anyopaque, wl_pointer: ?*c.struct_wl_pointer,
|
||||
/// @param discrete number of steps
|
||||
/// @since 5
|
||||
/// @deprecated Deprecated since version 8
|
||||
fn wlPointerHandleAxisDiscrete(data: ?*anyopaque, wl_pointer: ?*c.struct_wl_pointer, axis: u32, discrete: i32) callconv(.c) void {
|
||||
fn wlPointerHandleAxisDiscrete(data: ?*anyopaque, wl_pointer: ?*c.wl_pointer, axis: u32, discrete: i32) callconv(.c) void {
|
||||
_ = data;
|
||||
_ = wl_pointer;
|
||||
_ = axis;
|
||||
@@ -439,7 +460,7 @@ fn wlPointerHandleAxisDiscrete(data: ?*anyopaque, wl_pointer: ?*c.struct_wl_poin
|
||||
/// @param axis axis type
|
||||
/// @param value120 scroll distance as fraction of 120
|
||||
/// @since 8
|
||||
fn wlPointerHandleAxisValue120(data: ?*anyopaque, wl_pointer: ?*c.struct_wl_pointer, axis: u32, value120: i32) callconv(.c) void {
|
||||
fn wlPointerHandleAxisValue120(data: ?*anyopaque, wl_pointer: ?*c.wl_pointer, axis: u32, value120: i32) callconv(.c) void {
|
||||
_ = data;
|
||||
_ = wl_pointer;
|
||||
_ = axis;
|
||||
@@ -486,7 +507,7 @@ fn wlPointerHandleAxisValue120(data: ?*anyopaque, wl_pointer: ?*c.struct_wl_poin
|
||||
/// @param axis axis type
|
||||
/// @param direction physical direction relative to axis motion
|
||||
/// @since 9
|
||||
fn wlPointerHandleAxisRelativeDirection(data: ?*anyopaque, wl_pointer: ?*c.struct_wl_pointer, axis: u32, direction: u32) callconv(.c) void {
|
||||
fn wlPointerHandleAxisRelativeDirection(data: ?*anyopaque, wl_pointer: ?*c.wl_pointer, axis: u32, direction: u32) callconv(.c) void {
|
||||
_ = data;
|
||||
_ = wl_pointer;
|
||||
_ = axis;
|
||||
@@ -530,7 +551,7 @@ fn wlPointerHandleAxisRelativeDirection(data: ?*anyopaque, wl_pointer: ?*c.struc
|
||||
/// and wl_pointer.enter event being split across multiple
|
||||
/// wl_pointer.frame groups.
|
||||
/// @since 5
|
||||
fn wlPointerHandleFrame(data: ?*anyopaque, wl_pointer: ?*c.struct_wl_pointer) callconv(.c) void {
|
||||
fn wlPointerHandleFrame(data: ?*anyopaque, wl_pointer: ?*c.wl_pointer) callconv(.c) void {
|
||||
_ = wl_pointer;
|
||||
const wl_state: *WaylandState = @ptrCast(@alignCast(data));
|
||||
|
||||
@@ -577,7 +598,7 @@ fn wlPointerHandleFrame(data: ?*anyopaque, wl_pointer: ?*c.struct_wl_pointer) ca
|
||||
wl_state.pointer_event = std.mem.zeroInit(WlPointerEvent, .{});
|
||||
}
|
||||
|
||||
const wl_pointer_listener: c.struct_wl_pointer_listener = .{
|
||||
const wl_pointer_listener: c.wl_pointer_listener = .{
|
||||
.enter = wlPointerHandleEnter,
|
||||
.leave = wlPointerHandleLeave,
|
||||
.motion = wlPointerHandleMotion,
|
||||
@@ -593,7 +614,7 @@ const wl_pointer_listener: c.struct_wl_pointer_listener = .{
|
||||
|
||||
fn wlKeyboardHandleKeymap(
|
||||
data: ?*anyopaque,
|
||||
wl_keyboard: ?*c.struct_wl_keyboard,
|
||||
wl_keyboard: ?*c.wl_keyboard,
|
||||
format: u32,
|
||||
fd: i32,
|
||||
size: u32,
|
||||
@@ -606,12 +627,12 @@ fn wlKeyboardHandleKeymap(
|
||||
std.debug.panic("[Wayland] Keyboard keymap handler failed mmap", .{});
|
||||
};
|
||||
|
||||
const keymap: ?*c.struct_xkb_keymap = c.xkb_keymap_new_from_string(wl_state.xkb_context, @ptrCast(map_shm), c.XKB_KEYMAP_FORMAT_TEXT_V1, c.XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
const keymap: ?*c.xkb_keymap = c.xkb_keymap_new_from_string(wl_state.xkb_context, @ptrCast(map_shm), c.XKB_KEYMAP_FORMAT_TEXT_V1, c.XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
|
||||
std.posix.munmap(map_shm);
|
||||
std.posix.close(fd);
|
||||
|
||||
const xkb_state: ?*c.struct_xkb_state = c.xkb_state_new(keymap);
|
||||
const xkb_state: ?*c.xkb_state = c.xkb_state_new(keymap);
|
||||
|
||||
// NOTE: Unmap existing ones
|
||||
if (wl_state.xkb_keymap != null) c.xkb_keymap_unref(wl_state.xkb_keymap);
|
||||
@@ -650,7 +671,7 @@ fn wlKeyboardHandleKey(data: ?*anyopaque, keyboard: ?*c.wl_keyboard, serial: u32
|
||||
|
||||
const pressed = state == c.WL_KEYBOARD_KEY_STATE_PRESSED or state == c.WL_KEYBOARD_KEY_STATE_REPEATED;
|
||||
|
||||
std.debug.print("{s} {any}\n", .{buf, pressed});
|
||||
std.debug.print("{s} {any}\n", .{ buf, pressed });
|
||||
|
||||
switch (sym) {
|
||||
c.XKB_KEY_Escape => {
|
||||
@@ -706,12 +727,12 @@ const wl_keyboard_listener: c.wl_keyboard_listener = .{
|
||||
.repeat_info = wlKeyboardHandleRepeatInfo,
|
||||
};
|
||||
|
||||
fn wlSeatHandleCapabilities(data: ?*anyopaque, wl_seat: ?*c.struct_wl_seat, capabilities: u32) callconv(.c) void {
|
||||
fn wlSeatHandleCapabilities(data: ?*anyopaque, wl_seat: ?*c.wl_seat, capabilities: u32) callconv(.c) void {
|
||||
const wl_state: *WaylandState = @ptrCast(@alignCast(data));
|
||||
|
||||
if (capabilities & c.WL_SEAT_CAPABILITY_POINTER == c.WL_SEAT_CAPABILITY_POINTER) {
|
||||
std.debug.print("[Wayland] wl_seat: got pointer capability\n", .{});
|
||||
const pointer: ?*c.struct_wl_pointer = c.wl_seat_get_pointer(wl_seat);
|
||||
const pointer: ?*c.wl_pointer = c.wl_seat_get_pointer(wl_seat);
|
||||
_ = c.wl_pointer_add_listener(pointer, &wl_pointer_listener, wl_state);
|
||||
}
|
||||
|
||||
@@ -722,20 +743,20 @@ fn wlSeatHandleCapabilities(data: ?*anyopaque, wl_seat: ?*c.struct_wl_seat, capa
|
||||
}
|
||||
}
|
||||
|
||||
fn wlSeatHandleName(data: ?*anyopaque, wl_seat: ?*c.struct_wl_seat, name: [*c]const u8) callconv(.c) void {
|
||||
fn wlSeatHandleName(data: ?*anyopaque, wl_seat: ?*c.wl_seat, name: [*c]const u8) callconv(.c) void {
|
||||
_ = data;
|
||||
_ = wl_seat;
|
||||
std.debug.print("[Wayland] wl_seat name {s}\n", .{name});
|
||||
}
|
||||
|
||||
const wl_seat_listener: c.struct_wl_seat_listener = .{
|
||||
const wl_seat_listener: c.wl_seat_listener = .{
|
||||
.capabilities = wlSeatHandleCapabilities,
|
||||
.name = wlSeatHandleName,
|
||||
};
|
||||
|
||||
fn registry_handle_global(
|
||||
data: ?*anyopaque,
|
||||
registry: ?*c.struct_wl_registry,
|
||||
registry: ?*c.wl_registry,
|
||||
name: u32,
|
||||
interface: [*c]const u8,
|
||||
version: u32,
|
||||
@@ -758,7 +779,7 @@ fn registry_handle_global(
|
||||
}
|
||||
}
|
||||
|
||||
const registry_listener: c.struct_wl_registry_listener = .{
|
||||
const registry_listener: c.wl_registry_listener = .{
|
||||
.global = registry_handle_global,
|
||||
};
|
||||
|
||||
@@ -799,6 +820,7 @@ pub fn main() u8 {
|
||||
std.debug.print("ERROR: Could not create surface.\n", .{});
|
||||
return 1;
|
||||
}
|
||||
wl_state.surface = wl_surface;
|
||||
|
||||
const xdg_surface = c.xdg_wm_base_get_xdg_surface(wl_state.xdg_wm_base, wl_surface);
|
||||
if (xdg_surface == null) {
|
||||
@@ -816,7 +838,7 @@ pub fn main() u8 {
|
||||
|
||||
_ = c.xdg_toplevel_add_listener(xdg_toplevel, &xdg_toplevel_listener, &wl_state);
|
||||
|
||||
c.xdg_toplevel_set_title(xdg_toplevel, "Oceanbox Tyler");
|
||||
c.xdg_toplevel_set_title(xdg_toplevel, "Zig A-Puzzle-A-Day");
|
||||
|
||||
c.wl_surface_commit(wl_surface);
|
||||
|
||||
@@ -834,9 +856,9 @@ pub fn main() u8 {
|
||||
|
||||
var shared_memory_pool: ?*c.wl_shm_pool = undefined;
|
||||
var shared_memory_pool_data: []u8 = undefined;
|
||||
var wl_buffer: *c.struct_wl_buffer = undefined;
|
||||
var wl_buffer: *c.wl_buffer = undefined;
|
||||
|
||||
const monitor_update_hz: f64 = 30;
|
||||
const monitor_update_hz: f64 = 144;
|
||||
const game_update_hz: f64 = monitor_update_hz;
|
||||
const frame_target_time_s: f64 = 1.0 / game_update_hz;
|
||||
const frame_target_time_ms: f64 = std.time.ms_per_s * frame_target_time_s;
|
||||
@@ -858,6 +880,8 @@ pub fn main() u8 {
|
||||
.permanent_storage = app_permanent_storage,
|
||||
};
|
||||
|
||||
var frame_callback_added = false;
|
||||
|
||||
var timer = std.time.Timer.start() catch {
|
||||
std.debug.print("[Wayland] ERROR: timer not supported.\n", .{});
|
||||
return 1;
|
||||
@@ -940,15 +964,17 @@ pub fn main() u8 {
|
||||
|
||||
const render_start_time: u64 = timer.read();
|
||||
|
||||
wl_state.app_input.delta_time = frame_target_time_s;
|
||||
if (wl_state.frame_ready) {
|
||||
wl_state.app_input.delta_time = frame_target_time_s;
|
||||
|
||||
const app_offscreen_buffer: puzzle.platform.OffscreenBuffer = .{
|
||||
.width = wl_state.window_width,
|
||||
.height = wl_state.window_height,
|
||||
.stride = wl_state.window_width * 4,
|
||||
.data = shared_memory_pool_data,
|
||||
};
|
||||
puzzle.updateAndRender(&app_memory, app_offscreen_buffer, &wl_state.app_input);
|
||||
const app_offscreen_buffer: puzzle.platform.OffscreenBuffer = .{
|
||||
.width = wl_state.window_width,
|
||||
.height = wl_state.window_height,
|
||||
.stride = wl_state.window_width * 4,
|
||||
.data = shared_memory_pool_data,
|
||||
};
|
||||
puzzle.updateAndRender(&app_memory, app_offscreen_buffer, &wl_state.app_input);
|
||||
}
|
||||
|
||||
const render_end_time: u64 = timer.read();
|
||||
const render_time = render_end_time - render_start_time;
|
||||
@@ -963,12 +989,25 @@ pub fn main() u8 {
|
||||
std.debug.print("MISSED FRAME\n", .{});
|
||||
}
|
||||
|
||||
c.wl_surface_attach(wl_surface, wl_buffer, 0, 0);
|
||||
c.wl_surface_damage_buffer(wl_surface, 0, 0, wl_state.window_width, wl_state.window_height);
|
||||
c.wl_surface_commit(wl_surface);
|
||||
if (wl_state.frame_ready) {
|
||||
c.wl_surface_attach(wl_surface, wl_buffer, 0, 0);
|
||||
c.wl_surface_damage_buffer(wl_surface, 0, 0, wl_state.window_width, wl_state.window_height);
|
||||
c.wl_surface_commit(wl_surface);
|
||||
wl_state.frame_ready = false;
|
||||
}
|
||||
|
||||
_ = c.wl_display_roundtrip(display);
|
||||
|
||||
if (!frame_callback_added) {
|
||||
const callback: ?*c.wl_callback = c.wl_surface_frame(wl_surface);
|
||||
if (callback) |cb| {
|
||||
const ret: c_int = c.wl_callback_add_listener(cb, &frame_callback_listener, &wl_state);
|
||||
std.debug.print("[Wayland] Added frame callback with ret {d}.\n", .{ret});
|
||||
}
|
||||
frame_callback_added = true;
|
||||
wl_state.frame_ready = true;
|
||||
}
|
||||
|
||||
// std.posix.nanosleep(0, std.time.ns_per_ms * 32);
|
||||
|
||||
const current = timer.lap();
|
||||
|
||||
+39
-29
@@ -87,6 +87,7 @@ const State = struct {
|
||||
frame_count: i32,
|
||||
mouse_pos: V2,
|
||||
camera: Camera,
|
||||
grabbed_brick_index: ?usize,
|
||||
bricks: [8]Brick,
|
||||
};
|
||||
|
||||
@@ -238,6 +239,8 @@ pub fn updateAndRender(memory: *platform.AppMemory, buffer: platform.OffscreenBu
|
||||
if (!memory.initialized) {
|
||||
state.camera.offset = mid;
|
||||
|
||||
state.grabbed_brick_index = null;
|
||||
|
||||
state.bricks[0] = Brick{
|
||||
.rotating = false,
|
||||
.rotating_time = 0,
|
||||
@@ -350,8 +353,11 @@ pub fn updateAndRender(memory: *platform.AppMemory, buffer: platform.OffscreenBu
|
||||
|
||||
const mouse_world_pos = mouse_pos.sub(state.camera.pos);
|
||||
|
||||
var mouse_on_brick = false;
|
||||
for (&state.bricks) |*brick| {
|
||||
if (!input.mouse_left_down) {
|
||||
state.grabbed_brick_index = null;
|
||||
}
|
||||
|
||||
for (&state.bricks, 0..) |*brick, brick_index| {
|
||||
if (brick.rotating) {
|
||||
brick.rotating_time += input.delta_time;
|
||||
if (brick.rotating_time > 0.25) {
|
||||
@@ -370,41 +376,45 @@ pub fn updateAndRender(memory: *platform.AppMemory, buffer: platform.OffscreenBu
|
||||
const pos = tile_pos.add(brick.pos);
|
||||
|
||||
const camera_pos = pos.add(state.camera.pos);
|
||||
if (pointInsideRect(state.mouse_pos, camera_pos, tile_size)) {
|
||||
if (input.mouse_left_down) {
|
||||
const diff = mouse_pos.sub(state.mouse_pos);
|
||||
brick.pos = brick.pos.add(diff);
|
||||
|
||||
if (keyPressed(&input.key.space)) {
|
||||
brick.rotating = true;
|
||||
const rotated = brick.rotate();
|
||||
brick.tiles = rotated;
|
||||
|
||||
const bbox = findBrickBoundingBox(brick);
|
||||
const center = brick.pos.sub(bbox.center);
|
||||
brick.pos = mouse_world_pos.add(center);
|
||||
if (input.mouse_left_down) {
|
||||
if (pointInsideRect(state.mouse_pos, camera_pos, tile_size)) {
|
||||
if (state.grabbed_brick_index == null) {
|
||||
state.grabbed_brick_index = brick_index;
|
||||
}
|
||||
|
||||
// Flip
|
||||
if (keyPressed(&input.key.f)) {
|
||||
brick.rotating = true;
|
||||
const flipped = brick.transpose();
|
||||
brick.tiles = flipped;
|
||||
|
||||
const bbox = findBrickBoundingBox(brick);
|
||||
const center = brick.pos.sub(bbox.center);
|
||||
brick.pos = mouse_world_pos.add(center);
|
||||
}
|
||||
|
||||
mouse_on_brick = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (brick_index == state.grabbed_brick_index) {
|
||||
const diff = mouse_pos.sub(state.mouse_pos);
|
||||
brick.pos = brick.pos.add(diff);
|
||||
|
||||
if (keyPressed(&input.key.space)) {
|
||||
brick.rotating = true;
|
||||
const rotated = brick.rotate();
|
||||
brick.tiles = rotated;
|
||||
|
||||
const bbox = findBrickBoundingBox(brick);
|
||||
const center = brick.pos.sub(bbox.center);
|
||||
brick.pos = mouse_world_pos.add(center);
|
||||
}
|
||||
|
||||
// Flip
|
||||
if (keyPressed(&input.key.f)) {
|
||||
brick.rotating = true;
|
||||
const flipped = brick.transpose();
|
||||
brick.tiles = flipped;
|
||||
|
||||
const bbox = findBrickBoundingBox(brick);
|
||||
const center = brick.pos.sub(bbox.center);
|
||||
brick.pos = mouse_world_pos.add(center);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (input.mouse_left_down and !mouse_on_brick) {
|
||||
if (input.mouse_left_down and state.grabbed_brick_index == null) {
|
||||
const diff = mouse_pos.sub(state.mouse_pos);
|
||||
state.camera.pos = state.camera.pos.add(diff);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user