diff --git a/engine/core/build.zig.zon b/engine/core/build.zig.zon index 2da77fb..43ee402 100644 --- a/engine/core/build.zig.zon +++ b/engine/core/build.zig.zon @@ -1,5 +1,5 @@ .{ - .name = "core", + .name = .core, .version = "0.0.0", .dependencies = .{ .spng = .{ .path = "../../lib/spng" }, @@ -14,4 +14,5 @@ .paths = .{ "", }, + .fingerprint = 0x6b8d854f57523e9e, } diff --git a/lib/lua/build.zig.zon b/lib/lua/build.zig.zon index 1f1e39d..cc6db74 100644 --- a/lib/lua/build.zig.zon +++ b/lib/lua/build.zig.zon @@ -1,8 +1,9 @@ .{ - .name = "lua", + .name = .lua, .version = "0.0.0", .dependencies = .{}, .paths = .{ "", }, + .fingerprint = 0xd671372bdb7e7b56, } diff --git a/lib/lua/src/pod.zig b/lib/lua/src/pod.zig index 7ef9b41..991b2c6 100644 --- a/lib/lua/src/pod.zig +++ b/lib/lua/src/pod.zig @@ -344,43 +344,43 @@ pub fn MakeMetatable(comptime T: type) PodLib { const methods = blk: { comptime var m: lua.LibSpec = &.{}; if (T.PodDataTable.toStringOverride != null) { - m = m ++ .{.{ .name = "__tostring", .func = comptime T.PodDataTable.toStringOverride.? }}; + m = m ++ .{lua.c.luaL_Reg{ .name = "__tostring", .func = comptime T.PodDataTable.toStringOverride.? }}; } else { - m = m ++ .{.{ .name = "__tostring", .func = comptime ToStringFunc(T) }}; + m = m ++ .{lua.c.luaL_Reg{ .name = "__tostring", .func = comptime ToStringFunc(T) }}; } - m = m ++ .{.{ .name = "__newindex", .func = comptime SetFunc(T, .{ .allowIndices = true }) }}; - m = m ++ .{.{ .name = "__index", .func = comptime GetFunc(T, .{ .allowIndices = true }) }}; + m = m ++ .{lua.c.luaL_Reg{ .name = "__newindex", .func = comptime SetFunc(T, .{ .allowIndices = true }) }}; + m = m ++ .{lua.c.luaL_Reg{ .name = "__index", .func = comptime GetFunc(T, .{ .allowIndices = true }) }}; if (T.PodDataTable.operators.add) |f| { - m = m ++ .{.{ .name = "__add", .func = comptime Operator2Arg(T, @field(T, f)) }}; + m = m ++ .{lua.c.luaL_Reg{ .name = "__add", .func = comptime Operator2Arg(T, @field(T, f)) }}; } if (T.PodDataTable.operators.sub) |f| { - m = m ++ .{.{ .name = "__sub", .func = comptime Operator2Arg(T, @field(T, f)) }}; + m = m ++ .{lua.c.luaL_Reg{ .name = "__sub", .func = comptime Operator2Arg(T, @field(T, f)) }}; } if (T.PodDataTable.operators.mul) |f| { - m = m ++ .{.{ .name = "__mul", .func = comptime Operator2Arg(T, @field(T, f)) }}; + m = m ++ .{lua.c.luaL_Reg{ .name = "__mul", .func = comptime Operator2Arg(T, @field(T, f)) }}; } if (T.PodDataTable.operators.eq) |f| { - m = m ++ .{.{ .name = "__eq", .func = comptime Operator2Arg(T, @field(T, f)) }}; + m = m ++ .{lua.c.luaL_Reg{ .name = "__eq", .func = comptime Operator2Arg(T, @field(T, f)) }}; } if (T.PodDataTable.destructor) |f| { - m = m ++ .{.{ .name = "__gc", .func = comptime lua.WrapZigFunc(@field(T, f)) }}; + m = m ++ .{lua.c.luaL_Reg{ .name = "__gc", .func = comptime lua.WrapZigFunc(@field(T, f)) }}; } inline for (T.PodDataTable.funcs) |f| { - m = m ++ .{.{ .name = @as([*c]const u8, @ptrCast(f)), .func = comptime lua.WrapZigFunc(@field(T, f)) }}; + m = m ++ .{lua.c.luaL_Reg{ .name = @as([*c]const u8, @ptrCast(f)), .func = comptime lua.WrapZigFunc(@field(T, f)) }}; } inline for (T.PodDataTable.luaFuncs) |f| { - m = m ++ .{.{ .name = @as([*c]const u8, @ptrCast(f)), .func = @field(T, f) }}; + m = m ++ .{lua.c.luaL_Reg{ .name = @as([*c]const u8, @ptrCast(f)), .func = @field(T, f) }}; } inline for (T.PodDataTable.luaDirectFuncs) |f| { - m = m ++ .{.{ .name = @as([*c]const u8, @ptrCast(f.name)), .func = comptime lua.CWrap(@field(T, f.func)) }}; + m = m ++ .{lua.c.luaL_Reg{ .name = @as([*c]const u8, @ptrCast(f.name)), .func = comptime lua.CWrap(@field(T, f.func)) }}; } - break :blk m ++ .{.{ .name = null, .func = null }}; + break :blk m ++ .{lua.c.luaL_Reg{ .name = null, .func = null }}; }; const functions = blk: { @@ -392,7 +392,7 @@ pub fn MakeMetatable(comptime T: type) PodLib { m = m ++ .{lua.c.luaL_Reg{ .name = "new", .func = comptime NewFunc(T) }}; } } - break :blk m ++ .{.{ .name = null, .func = null }}; + break :blk m ++ .{lua.c.luaL_Reg{ .name = null, .func = null }}; }; return .{ .methods = methods, .functions = functions }; } diff --git a/lib/sdl3/content/_cooked/dxil/hello-triangle.frag.dxil b/lib/sdl3/content/_cooked/dxil/hello-triangle.frag.dxil index 0aa0cf2..6115e3a 100644 Binary files a/lib/sdl3/content/_cooked/dxil/hello-triangle.frag.dxil and b/lib/sdl3/content/_cooked/dxil/hello-triangle.frag.dxil differ diff --git a/lib/sdl3/content/_cooked/dxil/hello-triangle.vert.dxil b/lib/sdl3/content/_cooked/dxil/hello-triangle.vert.dxil index 13e4523..fdabb15 100644 Binary files a/lib/sdl3/content/_cooked/dxil/hello-triangle.vert.dxil and b/lib/sdl3/content/_cooked/dxil/hello-triangle.vert.dxil differ diff --git a/lib/sdl3/content/_cooked/msl/hello-triangle.vert.msl b/lib/sdl3/content/_cooked/msl/hello-triangle.vert.msl index cd233ab..15b45b2 100644 --- a/lib/sdl3/content/_cooked/msl/hello-triangle.vert.msl +++ b/lib/sdl3/content/_cooked/msl/hello-triangle.vert.msl @@ -3,8 +3,18 @@ using namespace metal; -constant float2 _25 = {}; -constant float4 _26 = {}; +struct Scene +{ + float3 color; +}; + +struct type_StructuredBuffer_Scene +{ + Scene _m0[1]; +}; + +constant float2 _31 = {}; +constant float4 _32 = {}; struct main0_out { @@ -12,36 +22,45 @@ struct main0_out float4 gl_Position [[position]]; }; -vertex main0_out main0(uint gl_VertexIndex [[vertex_id]]) +vertex main0_out main0(const device type_StructuredBuffer_Scene& test [[buffer(0)]], uint gl_VertexIndex [[vertex_id]]) { main0_out out = {}; - float4 _47; - float2 _48; + float4 _71; + float2 _72; if (gl_VertexIndex == 0u) { - _47 = float4(1.0, 0.0, 0.0, 1.0); - _48 = float2(-1.0); + _71 = float4(test._m0[0u].color, 1.0); + _72 = float2(-1.0); } else { - float4 _45; - float2 _46; + float4 _69; + float2 _70; if (gl_VertexIndex == 1u) { - _45 = float4(0.0, 1.0, 0.0, 1.0); - _46 = float2(1.0, -1.0); + _69 = float4(test._m0[1u].color, 1.0); + _70 = float2(1.0, -1.0); } else { - bool _40 = gl_VertexIndex == 2u; - _45 = select(_26, float4(0.0, 0.0, 1.0, 1.0), bool4(_40)); - _46 = select(_25, float2(0.0, 1.0), bool2(_40)); + bool _57 = gl_VertexIndex == 2u; + float4 _66; + if (_57) + { + _66 = float4(test._m0[2u].color, 1.0); + } + else + { + _66 = _32; + } + _69 = _66; + _70 = select(_31, float2(0.0, 1.0), bool2(_57)); } - _47 = _45; - _48 = _46; + _71 = _69; + _72 = _70; } - out.out_var_TEXCOORD0 = _47; - out.gl_Position = float4(_48, 0.0, 1.0); + out.out_var_TEXCOORD0 = _71; + out.gl_Position = float4(_72, 0.0, 1.0); return out; } diff --git a/lib/sdl3/content/_cooked/spv/hello-triangle.vert.spv b/lib/sdl3/content/_cooked/spv/hello-triangle.vert.spv index 278e3e9..8e1453e 100644 Binary files a/lib/sdl3/content/_cooked/spv/hello-triangle.vert.spv and b/lib/sdl3/content/_cooked/spv/hello-triangle.vert.spv differ diff --git a/lib/sdl3/src/samples/hello-triangle.zig b/lib/sdl3/src/samples/hello-triangle.zig index 74f6c19..90b3ddc 100644 --- a/lib/sdl3/src/samples/hello-triangle.zig +++ b/lib/sdl3/src/samples/hello-triangle.zig @@ -19,6 +19,7 @@ shaderformat: gpu.GPUShaderFormat = undefined, colorBuffer: *gpu.GPUBuffer = undefined, colorBufferTransfer: *gpu.GPUTransferBuffer = undefined, +totalTime: f64 = 0.0, pub fn create(allocator: std.mem.Allocator) !*@This() { const self = try allocator.create(@This()); @@ -30,6 +31,10 @@ pub fn create(allocator: std.mem.Allocator) !*@This() { return self; } +pub fn frameStamp(self: *@This()) f64 { + return @as(f64, @floatFromInt(self.timer.read())) / 1000 / 1000 / 1000; +} + pub fn startContext(self: *@This()) !void { try sdl3.init(.{ .video = true, @@ -93,32 +98,6 @@ pub fn startContext(self: *@This()) !void { .size = 8192 * 2, .props = 0, }); - - { - const buffer = self.device.mapGPUTransferBuffer(self.colorBufferTransfer, true); - - var b: [*][3]f32 = @ptrCast(@alignCast(buffer)); - - b[0] = .{ 1.0, 0.0, 0.0 }; - b[1] = .{ 1.0, 1.0, 0.0 }; - b[2] = .{ 1.0, 0.0, 1.0 }; - self.device.unmapGPUTransferBuffer(self.colorBufferTransfer); - } - - { - const cmd = self.device.acquireGPUCommandBuffer(); - defer _ = cmd.submitGPUCommandBufferAndAcquireFence(); - - { - const copyPass = cmd.beginGPUCopyPass(); - defer copyPass.endGPUCopyPass(); - copyPass.uploadToGPUBuffer(&.{ .transfer_buffer = self.colorBufferTransfer, .offset = 0 }, &.{ - .buffer = self.colorBuffer, - .offset = 0, - .size = 4 * 12, - }, true); - } - } } pub fn loadFileAlloc(filename: []const u8, comptime alignment: usize, allocator: std.mem.Allocator) ![]u8 { @@ -179,17 +158,47 @@ fn update(self: *@This(), dt: f64) void { sdl_event.quit => { self.running = false; }, + sdl_event.key_down => { + const key = event.key.scancode; + if (key == @intFromEnum(sdl3.Scancode.escape)) { + self.running = false; + } + }, else => {}, } - - self.draw(dt); } + + self.draw(dt); + std.debug.print("frametime {d:.3}ms (fps: {d:.1})\r", .{ dt * 1000, 1 / dt }); } pub fn draw(self: *@This(), dt: f64) void { - _ = dt; + self.totalTime += dt; + const cmd = self.device.acquireGPUCommandBuffer(); var swapchain_texture: *gpu.GPUTexture = undefined; + { + const buffer = self.device.mapGPUTransferBuffer(self.colorBufferTransfer, true); + + var b: [*][4]f32 = @ptrCast(@alignCast(buffer)); + + b[0] = .{ @floatCast(std.math.sin(self.totalTime * 3 * 2 + 0.8) * 0.2 + 0.8), 0.4, 0.4, 0.0 }; + b[1] = .{ 0.4, @floatCast(std.math.sin(self.totalTime * 2 * 2 + 0.3) * 0.2 + 0.8), 0.4, 0.0 }; + b[2] = .{ 0.4, 0.4, @floatCast(std.math.sin(self.totalTime * 4 * 2) * 0.2 + 0.8), 0.0 }; + + self.device.unmapGPUTransferBuffer(self.colorBufferTransfer); + } + + { + const copyPass = cmd.beginGPUCopyPass(); + defer copyPass.endGPUCopyPass(); + copyPass.uploadToGPUBuffer(&.{ .transfer_buffer = self.colorBufferTransfer, .offset = 0 }, &.{ + .buffer = self.colorBuffer, + .offset = 0, + .size = 4 * 12, + }, true); + } + if (cmd.waitAndAcquireGPUSwapchainTexture(self.window, &swapchain_texture, null, null)) { var targetInfo: gpu.GPUColorTargetInfo = std.mem.zeroes(gpu.GPUColorTargetInfo); targetInfo.texture = swapchain_texture; @@ -205,6 +214,8 @@ pub fn draw(self: *@This(), dt: f64) void { renderpass.endGPURenderPass(); } + std.debug.print("rendering time: {d:.3}ms ", .{self.frameStamp()}); + _ = cmd.submitGPUCommandBuffer(); } diff --git a/lib/sdl3/src/scancode.zig b/lib/sdl3/src/scancode.zig new file mode 100644 index 0000000..8f64dcc --- /dev/null +++ b/lib/sdl3/src/scancode.zig @@ -0,0 +1,371 @@ +pub const Scancode = enum(c_uint) { + unknown, + + //** + //* \name Usage page 0x07 + //* + //* These values are from usage page 0x07 (USB keyboard page). + //*/ + //* @{ */ + + a = 4, + b = 5, + c = 6, + d = 7, + e = 8, + f = 9, + g = 10, + h = 11, + i = 12, + j = 13, + k = 14, + l = 15, + m = 16, + n = 17, + o = 18, + p = 19, + q = 20, + r = 21, + s = 22, + t = 23, + u = 24, + v = 25, + w = 26, + x = 27, + y = 28, + z = 29, + + @"1" = 30, + @"2" = 31, + @"3" = 32, + @"4" = 33, + @"5" = 34, + @"6" = 35, + @"7" = 36, + @"8" = 37, + @"9" = 38, + @"0" = 39, + + @"return" = 40, + escape = 41, + backspace = 42, + tab = 43, + space = 44, + + minus = 45, + equals = 46, + leftbracket = 47, + rightbracket = 48, + backslash = 49, //**< Located at the lower left of the return + // * key on ISO keyboards and at the right end + // * of the QWERTY row on ANSI keyboards. + // * Produces REVERSE SOLIDUS (backslash) and + // * VERTICAL LINE in a US layout, REVERSE + // * SOLIDUS and VERTICAL LINE in a UK Mac + // * layout, NUMBER SIGN and TILDE in a UK + // * Windows layout, DOLLAR SIGN and POUND SIGN + // * in a Swiss German layout, NUMBER SIGN and + // * APOSTROPHE in a German layout, GRAVE + // * ACCENT and POUND SIGN in a French Mac + // * layout, and ASTERISK and MICRO SIGN in a + // * French Windows layout. + // */ + nonushash = 50, //**< iso usb keyboards actually use this code + //* instead of 49 for the same key, but all + //* OSes I've seen treat the two codes + //* identically. So, as an implementor, unless + //* your keyboard generates both of those + //* codes and your OS treats them differently, + //* you should generate SDL_SCANCODE_BACKSLASH + //* instead of this code. As a user, you + //* should not rely on this code because SDL + //* will never generate it with most (all?) + //* keyboards. + //*/ + semicolon = 51, + apostrophe = 52, + grave = 53, //**< located in the top left corner (on both ansi + //* and ISO keyboards). Produces GRAVE ACCENT and + //* TILDE in a US Windows layout and in US and UK + //* Mac layouts on ANSI keyboards, GRAVE ACCENT + //* and NOT SIGN in a UK Windows layout, SECTION + //* SIGN and PLUS-MINUS SIGN in US and UK Mac + //* layouts on ISO keyboards, SECTION SIGN and + //* DEGREE SIGN in a Swiss German layout (Mac: + //* only on ISO keyboards), CIRCUMFLEX ACCENT and + //* DEGREE SIGN in a German layout (Mac: only on + //* ISO keyboards), SUPERSCRIPT TWO and TILDE in a + //* French Windows layout, COMMERCIAL AT and + //* NUMBER SIGN in a French Mac layout on ISO + //* keyboards, and LESS-THAN SIGN and GREATER-THAN + //* SIGN in a Swiss German, German, or French Mac + //* layout on ANSI keyboards. + //*/ + comma = 54, + period = 55, + slash = 56, + + capslock = 57, + + f1 = 58, + f2 = 59, + f3 = 60, + f4 = 61, + f5 = 62, + f6 = 63, + f7 = 64, + f8 = 65, + f9 = 66, + f10 = 67, + f11 = 68, + f12 = 69, + + printscreen = 70, + scrolllock = 71, + pause = 72, + insert = 73, //**< insert on pc, help on some mac keyboards (but + // does send code 73, not 117) */ + home = 74, + pageup = 75, + delete = 76, + end = 77, + pagedown = 78, + right = 79, + left = 80, + down = 81, + up = 82, + + numlockclear = 83, //**< num lock on pc, clear on mac keyboards + //*/ + kp_divide = 84, + kp_multiply = 85, + kp_minus = 86, + kp_plus = 87, + kp_enter = 88, + kp_1 = 89, + kp_2 = 90, + kp_3 = 91, + kp_4 = 92, + kp_5 = 93, + kp_6 = 94, + kp_7 = 95, + kp_8 = 96, + kp_9 = 97, + kp_0 = 98, + kp_period = 99, + + nonusbackslash = 100, //**< this is the additional key that iso + //* keyboards have over ANSI ones, + //* located between left shift and Y. + //* Produces GRAVE ACCENT and TILDE in a + //* US or UK Mac layout, REVERSE SOLIDUS + //* (backslash) and VERTICAL LINE in a + //* US or UK Windows layout, and + //* LESS-THAN SIGN and GREATER-THAN SIGN + //* in a Swiss German, German, or French + //* layout. */ + application = 101, //**< windows contextual menu, compose */ + power = 102, //**< the usb document says this is a status flag, + // * not a physical key - but some Mac keyboards + // * do have a power key. */ + kp_equals = 103, + f13 = 104, + f14 = 105, + f15 = 106, + f16 = 107, + f17 = 108, + f18 = 109, + f19 = 110, + f20 = 111, + f21 = 112, + f22 = 113, + f23 = 114, + f24 = 115, + execute = 116, + help = 117, //**< al integrated help center */ + menu = 118, //**< menu (show menu) */ + select = 119, + stop = 120, //**< ac stop */ + again = 121, //**< ac redo/repeat */ + undo = 122, //**< ac undo */ + cut = 123, //**< ac cut */ + copy = 124, //**< ac copy */ + paste = 125, //**< ac paste */ + find = 126, //**< ac find */ + mute = 127, + volumeup = 128, + volumedown = 129, + ///* not sure whether there's a reason to enable these */ + ///* sdl_scancode_lockingcapslock = 130, */ + ///* sdl_scancode_lockingnumlock = 131, */ + ///* sdl_scancode_lockingscrolllock = 132, */ + kp_comma = 133, + kp_equalsas400 = 134, + + international1 = 135, // **< used on asian keyboards, see + // footnotes in usb doc */ + international2 = 136, + international3 = 137, //**< yen */ + international4 = 138, + international5 = 139, + international6 = 140, + international7 = 141, + international8 = 142, + international9 = 143, + lang1 = 144, //**< hangul/english toggle */ + lang2 = 145, //**< hanja conversion */ + lang3 = 146, //**< katakana */ + lang4 = 147, //**< hiragana */ + lang5 = 148, //**< zenkaku/hankaku */ + lang6 = 149, //**< reserved */ + lang7 = 150, //**< reserved */ + lang8 = 151, //**< reserved */ + lang9 = 152, //**< reserved */ + + alterase = 153, //**< erase-eaze */ + sysreq = 154, + cancel = 155, //**< ac cancel */ + clear = 156, + prior = 157, + return2 = 158, + separator = 159, + out = 160, + oper = 161, + clearagain = 162, + crsel = 163, + exsel = 164, + + kp_00 = 176, + kp_000 = 177, + thousandsseparator = 178, + decimalseparator = 179, + currencyunit = 180, + currencysubunit = 181, + kp_leftparen = 182, + kp_rightparen = 183, + kp_leftbrace = 184, + kp_rightbrace = 185, + kp_tab = 186, + kp_backspace = 187, + kp_a = 188, + kp_b = 189, + kp_c = 190, + kp_d = 191, + kp_e = 192, + kp_f = 193, + kp_xor = 194, + kp_power = 195, + kp_percent = 196, + kp_less = 197, + kp_greater = 198, + kp_ampersand = 199, + kp_dblampersand = 200, + kp_verticalbar = 201, + kp_dblverticalbar = 202, + kp_colon = 203, + kp_hash = 204, + kp_space = 205, + kp_at = 206, + kp_exclam = 207, + kp_memstore = 208, + kp_memrecall = 209, + kp_memclear = 210, + kp_memadd = 211, + kp_memsubtract = 212, + kp_memmultiply = 213, + kp_memdivide = 214, + kp_plusminus = 215, + kp_clear = 216, + kp_clearentry = 217, + kp_binary = 218, + kp_octal = 219, + kp_decimal = 220, + kp_hexadecimal = 221, + + lctrl = 224, + lshift = 225, + lalt = 226, //**< alt, option */ + lgui = 227, //**< windows, command (apple), meta */ + rctrl = 228, + rshift = 229, + ralt = 230, //**< alt gr, option */ + rgui = 231, //**< windows, command (apple), meta */ + + mode = 257, //**< i'm not sure if this is really not covered + //* by any of the above, but since there's a + //* special sdl_kmod_mode for it i'm adding it here + //*/ + + //* @} *//* Usage page 0x07 */ + + ///** + // * \name Usage page 0x0C + // * + // * These values are mapped from usage page 0x0C (USB consumer page). + // * + // * There are way more keys in the spec than we can represent in the + // * current scancode range, so pick the ones that commonly come up in + // * real world usage. + // */ + ///* @{ */ + sleep = 258, //**< sleep */ + wake = 259, //**< wake */ + + channel_increment = 260, //**< channel increment */ + channel_decrement = 261, //**< channel decrement */ + + media_play = 262, //**< play */ + media_pause = 263, //**< pause */ + media_record = 264, //**< record */ + media_fast_forward = 265, //**< fast forward */ + media_rewind = 266, //**< rewind */ + media_next_track = 267, //**< next track */ + media_previous_track = 268, //**< previous track */ + media_stop = 269, //**< stop */ + media_eject = 270, //**< eject */ + media_play_pause = 271, //**< play / pause */ + media_select = 272, //* media select */ + + ac_new = 273, //**< ac new */ + ac_open = 274, //**< ac open */ + ac_close = 275, //**< ac close */ + ac_exit = 276, //**< ac exit */ + ac_save = 277, //**< ac save */ + ac_print = 278, //**< ac print */ + ac_properties = 279, //**< ac properties */ + + ac_search = 280, //**< ac search */ + ac_home = 281, //**< ac home */ + ac_back = 282, //**< ac back */ + ac_forward = 283, //**< ac forward */ + ac_stop = 284, //**< ac stop */ + ac_refresh = 285, //**< ac refresh */ + ac_bookmarks = 286, //**< ac bookmarks */ + + //* @} *//* Usage page 0x0C */ + + //** + //* \name Mobile keys + //* + //* These are values that are often used on mobile phones. + //*/ + //* @{ */ + + softleft = 287, //**< usually situated below the display on phones and + // used as a multi-function feature key for selecting + // a software defined function shown on the bottom left + // of the display. */ + softright = 288, //**< usually situated below the display on phones and + // used as a multi-function feature key for selecting + // a software defined function shown on the bottom right + // of the display. */ + call = 289, //**< used for accepting phone calls. */ + endcall = 290, //**< used for rejecting phone calls. */ + + //* @} *//* Mobile keys */ + //* Add any other keys here. */ + + reserved = 400, //**< 400-500 reserved for dynamic keycodes */ + + count = 512, //**< not a key, just marks the number of scancodes for array bounds */ +}; diff --git a/lib/sdl3/src/sdl3.zig b/lib/sdl3/src/sdl3.zig index cfdabfb..41ee5c1 100644 --- a/lib/sdl3/src/sdl3.zig +++ b/lib/sdl3/src/sdl3.zig @@ -45,3 +45,4 @@ pub fn pollEvent() ?*Event { } pub const gpu = @import("gpu.zig"); +pub const Scancode = @import("scancode.zig").Scancode;