core: win32: various improvements (#1255)
Signed-off-by: Stephen Gutekanst <stephen@hexops.com> Authored-by: Hordur Johannsson <hordurj@gmail.com>
This commit is contained in:
parent
a5a3d31411
commit
984d4de3bd
6 changed files with 324 additions and 206 deletions
24
src/Core.zig
24
src/Core.zig
|
|
@ -181,8 +181,8 @@ pub const InitOptions = struct {
|
||||||
};
|
};
|
||||||
|
|
||||||
fn update(core: *Mod, entities: *mach.Entities.Mod) !void {
|
fn update(core: *Mod, entities: *mach.Entities.Mod) !void {
|
||||||
_ = core; // autofix
|
_ = core;
|
||||||
_ = entities; // autofix
|
_ = entities;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init(core: *Mod, entities: *mach.Entities.Mod) !void {
|
fn init(core: *Mod, entities: *mach.Entities.Mod) !void {
|
||||||
|
|
@ -517,6 +517,7 @@ pub const Key = enum {
|
||||||
kp_8,
|
kp_8,
|
||||||
kp_9,
|
kp_9,
|
||||||
kp_decimal,
|
kp_decimal,
|
||||||
|
kp_comma,
|
||||||
kp_equal,
|
kp_equal,
|
||||||
kp_enter,
|
kp_enter,
|
||||||
|
|
||||||
|
|
@ -561,6 +562,9 @@ pub const Key = enum {
|
||||||
slash,
|
slash,
|
||||||
grave,
|
grave,
|
||||||
|
|
||||||
|
iso_backslash,
|
||||||
|
international1,
|
||||||
|
|
||||||
unknown,
|
unknown,
|
||||||
|
|
||||||
pub const max = Key.unknown;
|
pub const max = Key.unknown;
|
||||||
|
|
@ -968,17 +972,14 @@ pub fn printTitle(
|
||||||
comptime fmt: []const u8,
|
comptime fmt: []const u8,
|
||||||
args: anytype,
|
args: anytype,
|
||||||
) !void {
|
) !void {
|
||||||
_ = core;
|
|
||||||
_ = window_id;
|
_ = window_id;
|
||||||
_ = fmt;
|
// Allocate and assign a new window title slice.
|
||||||
_ = args;
|
const slice = try std.fmt.allocPrintZ(core.allocator, fmt, args);
|
||||||
// TODO: NO OP
|
defer core.allocator.free(slice);
|
||||||
// // Free any previous window title slice
|
core.setTitle(slice);
|
||||||
// if (core.get(window_id, .title)) |slice| core.state().allocator.free(slice);
|
|
||||||
|
|
||||||
// // Allocate and assign a new window title slice.
|
// TODO: This function does not have access to *core.Mod to update
|
||||||
// const slice = try std.fmt.allocPrintZ(core.state().allocator, fmt, args);
|
// try core.Mod.set(window_id, .title, slice);
|
||||||
// try core.set(window_id, .title, slice);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn exit(core: *Mod) void {
|
fn exit(core: *Mod) void {
|
||||||
|
|
@ -1054,6 +1055,7 @@ pub fn deinitLinuxGamemode() void {
|
||||||
comptime {
|
comptime {
|
||||||
// Core
|
// Core
|
||||||
assertHasField(Platform, "surface_descriptor");
|
assertHasField(Platform, "surface_descriptor");
|
||||||
|
assertHasField(Platform, "refresh_rate");
|
||||||
|
|
||||||
assertHasDecl(Platform, "init");
|
assertHasDecl(Platform, "init");
|
||||||
assertHasDecl(Platform, "deinit");
|
assertHasDecl(Platform, "deinit");
|
||||||
|
|
|
||||||
|
|
@ -22,74 +22,39 @@ const Key = Core.Key;
|
||||||
const KeyMods = Core.KeyMods;
|
const KeyMods = Core.KeyMods;
|
||||||
const Joystick = Core.Joystick;
|
const Joystick = Core.Joystick;
|
||||||
|
|
||||||
const log = std.log.scoped(.mach);
|
|
||||||
|
|
||||||
const EventQueue = std.fifo.LinearFifo(Event, .Dynamic);
|
const EventQueue = std.fifo.LinearFifo(Event, .Dynamic);
|
||||||
const Win32 = @This();
|
const Win32 = @This();
|
||||||
|
|
||||||
/////////////////////////
|
// --------------------------
|
||||||
// Module state
|
// Module state
|
||||||
////////////////////////
|
// --------------------------
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
core: *Core,
|
core: *Core,
|
||||||
|
|
||||||
// Core platform interface
|
// Core platform interface
|
||||||
title: [:0]u8,
|
surface_descriptor: gpu.Surface.Descriptor,
|
||||||
display_mode: DisplayMode,
|
display_mode: DisplayMode,
|
||||||
vsync_mode: VSyncMode,
|
vsync_mode: VSyncMode,
|
||||||
cursor_mode: CursorMode,
|
cursor_mode: CursorMode,
|
||||||
cursor_shape: CursorShape,
|
cursor_shape: CursorShape,
|
||||||
border: bool,
|
border: bool,
|
||||||
headless: bool,
|
headless: bool,
|
||||||
refresh_rate: u32,
|
|
||||||
size: Size,
|
size: Size,
|
||||||
surface_descriptor: gpu.Surface.Descriptor,
|
|
||||||
surface_descriptor_from_hwnd: gpu.Surface.DescriptorFromWindowsHWND,
|
|
||||||
|
|
||||||
// Internals
|
// Internals
|
||||||
window: w.HWND,
|
window: w.HWND,
|
||||||
|
refresh_rate: u32,
|
||||||
surrogate: u16 = 0,
|
surrogate: u16 = 0,
|
||||||
dinput: *w.IDirectInput8W,
|
dinput: *w.IDirectInput8W,
|
||||||
|
saved_window_rect: w.RECT,
|
||||||
|
surface_descriptor_from_hwnd: gpu.Surface.DescriptorFromWindowsHWND,
|
||||||
events: EventQueue,
|
events: EventQueue,
|
||||||
|
input_state: InputState,
|
||||||
oom: std.Thread.ResetEvent = .{},
|
oom: std.Thread.ResetEvent = .{},
|
||||||
|
|
||||||
////////////////////////////
|
// ------------------------------
|
||||||
/// Internals
|
// Platform interface
|
||||||
////////////////////////////
|
// ------------------------------
|
||||||
|
|
||||||
const RequestAdapterResponse = struct {
|
|
||||||
status: gpu.RequestAdapterStatus,
|
|
||||||
adapter: ?*gpu.Adapter,
|
|
||||||
message: ?[*:0]const u8,
|
|
||||||
};
|
|
||||||
|
|
||||||
inline fn requestAdapterCallback(
|
|
||||||
context: *RequestAdapterResponse,
|
|
||||||
status: gpu.RequestAdapterStatus,
|
|
||||||
adapter: ?*gpu.Adapter,
|
|
||||||
message: ?[*:0]const u8,
|
|
||||||
) void {
|
|
||||||
context.* = RequestAdapterResponse{
|
|
||||||
.status = status,
|
|
||||||
.adapter = adapter,
|
|
||||||
.message = message,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fn printUnhandledErrorCallback(_: void, ty: gpu.ErrorType, message: [*:0]const u8) void {
|
|
||||||
switch (ty) {
|
|
||||||
.validation => std.log.err("gpu: validation error: {s}\n", .{message}),
|
|
||||||
.out_of_memory => std.log.err("gpu: out of memory: {s}\n", .{message}),
|
|
||||||
.unknown => std.log.err("gpu: unknown error: {s}\n", .{message}),
|
|
||||||
else => unreachable,
|
|
||||||
}
|
|
||||||
std.process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////
|
|
||||||
/// Platform interface
|
|
||||||
////////////////////////////
|
|
||||||
pub fn init(
|
pub fn init(
|
||||||
self: *Win32,
|
self: *Win32,
|
||||||
options: InitOptions,
|
options: InitOptions,
|
||||||
|
|
@ -98,6 +63,8 @@ pub fn init(
|
||||||
self.core = @fieldParentPtr("platform", self);
|
self.core = @fieldParentPtr("platform", self);
|
||||||
self.events = EventQueue.init(self.allocator);
|
self.events = EventQueue.init(self.allocator);
|
||||||
self.size = options.size;
|
self.size = options.size;
|
||||||
|
self.input_state = .{};
|
||||||
|
self.saved_window_rect = .{ .top = 0, .left = 0, .right = 0, .bottom = 0 };
|
||||||
|
|
||||||
const hInstance = w.GetModuleHandleW(null);
|
const hInstance = w.GetModuleHandleW(null);
|
||||||
const class_name = w.L("mach");
|
const class_name = w.L("mach");
|
||||||
|
|
@ -111,23 +78,19 @@ pub fn init(
|
||||||
});
|
});
|
||||||
if (w.RegisterClassW(&class) == 0) return error.Unexpected;
|
if (w.RegisterClassW(&class) == 0) return error.Unexpected;
|
||||||
|
|
||||||
// TODO set title , copy to self.title
|
|
||||||
const title = try std.unicode.utf8ToUtf16LeAllocZ(self.allocator, options.title);
|
const title = try std.unicode.utf8ToUtf16LeAllocZ(self.allocator, options.title);
|
||||||
defer self.allocator.free(title);
|
defer self.allocator.free(title);
|
||||||
|
|
||||||
var request_window_width:i32 = @bitCast(self.size.width);
|
var request_window_width: i32 = @bitCast(self.size.width);
|
||||||
var request_window_height:i32 = @bitCast(self.size.height);
|
var request_window_height: i32 = @bitCast(self.size.height);
|
||||||
|
|
||||||
const window_ex_style: w.WINDOW_EX_STYLE = .{.APPWINDOW = 1, .WINDOWEDGE = 1, .CLIENTEDGE = 1};
|
const window_ex_style: w.WINDOW_EX_STYLE = .{ .APPWINDOW = 1 };
|
||||||
const window_style: w.WINDOW_STYLE = if (options.border) w.WS_OVERLAPPEDWINDOW else w.WS_POPUPWINDOW;
|
const window_style: w.WINDOW_STYLE = if (options.border) w.WS_OVERLAPPEDWINDOW else w.WS_POPUPWINDOW; // w.WINDOW_STYLE{.POPUP = 1};
|
||||||
|
// TODO (win32): should border == false mean borderless display_mode?
|
||||||
|
|
||||||
var rect: w.RECT = .{ .left = 0, .top = 0, .right = request_window_width, .bottom = request_window_height};
|
var rect: w.RECT = .{ .left = 0, .top = 0, .right = request_window_width, .bottom = request_window_height };
|
||||||
|
|
||||||
if (w.TRUE == w.AdjustWindowRectEx(&rect,
|
if (w.TRUE == w.AdjustWindowRectEx(&rect, window_style, w.FALSE, window_ex_style)) {
|
||||||
window_style,
|
|
||||||
w.FALSE,
|
|
||||||
window_ex_style))
|
|
||||||
{
|
|
||||||
request_window_width = rect.right - rect.left;
|
request_window_width = rect.right - rect.left;
|
||||||
request_window_height = rect.bottom - rect.top;
|
request_window_height = rect.bottom - rect.top;
|
||||||
}
|
}
|
||||||
|
|
@ -157,32 +120,24 @@ pub fn init(
|
||||||
self.dinput = dinput.?;
|
self.dinput = dinput.?;
|
||||||
|
|
||||||
self.surface_descriptor_from_hwnd = .{
|
self.surface_descriptor_from_hwnd = .{
|
||||||
.hinstance = std.os.windows.kernel32.GetModuleHandleW(null).?,
|
.hinstance = std.os.windows.kernel32.GetModuleHandleW(null).?,
|
||||||
.hwnd = window,
|
.hwnd = window,
|
||||||
};
|
|
||||||
|
|
||||||
self.surface_descriptor = .{
|
|
||||||
.next_in_chain = .{
|
|
||||||
.from_windows_hwnd = &self.surface_descriptor_from_hwnd,
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.surface_descriptor = .{ .next_in_chain = .{
|
||||||
|
.from_windows_hwnd = &self.surface_descriptor_from_hwnd,
|
||||||
|
} };
|
||||||
|
self.border = options.border;
|
||||||
|
self.headless = options.headless;
|
||||||
|
self.refresh_rate = 60; // TODO (win32) get monitor refresh rate
|
||||||
|
|
||||||
_ = w.SetWindowLongPtrW(window, w.GWLP_USERDATA, @bitCast(@intFromPtr(self)));
|
_ = w.SetWindowLongPtrW(window, w.GWLP_USERDATA, @bitCast(@intFromPtr(self)));
|
||||||
if (!options.headless) {
|
if (!options.headless) {
|
||||||
setDisplayMode(self, options.display_mode);
|
setDisplayMode(self, options.display_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.size = getClientRect(self);
|
self.size = getClientRect(self);
|
||||||
}
|
_ = w.GetWindowRect(self.window, &self.saved_window_rect);
|
||||||
|
|
||||||
pub fn getClientRect(self: *Win32) Size {
|
|
||||||
var rect: w.RECT = undefined;
|
|
||||||
_ = w.GetClientRect(self.window, &rect);
|
|
||||||
|
|
||||||
const width:u32 = @intCast(rect.right - rect.left);
|
|
||||||
const height:u32 = @intCast(rect.bottom - rect.top);
|
|
||||||
|
|
||||||
return .{ .width = width, .height = height };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Win32) void {
|
pub fn deinit(self: *Win32) void {
|
||||||
|
|
@ -216,18 +171,57 @@ pub fn setTitle(self: *Win32, title: [:0]const u8) void {
|
||||||
self.oom.set();
|
self.oom.set();
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
// TODO update self.title
|
|
||||||
defer self.allocator.free(wtitle);
|
defer self.allocator.free(wtitle);
|
||||||
_ = w.SetWindowTextW(self.window, wtitle);
|
_ = w.SetWindowTextW(self.window, wtitle);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setDisplayMode(self: *Win32, mode: DisplayMode) void {
|
pub fn setDisplayMode(self: *Win32, mode: DisplayMode) void {
|
||||||
// TODO update self.displayMode
|
self.display_mode = mode;
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
.windowed => _ = w.ShowWindow(self.window, w.SW_RESTORE),
|
.windowed => {
|
||||||
// .maximized => _ = w.ShowWindow(self.window, w.SW_MAXIMIZE),
|
const window_style: w.WINDOW_STYLE = if (self.border) w.WS_OVERLAPPEDWINDOW else w.WS_POPUPWINDOW;
|
||||||
.fullscreen => {},
|
const window_ex_style = w.WINDOW_EX_STYLE{ .APPWINDOW = 1 };
|
||||||
.borderless => {},
|
|
||||||
|
_ = w.SetWindowLongW(self.window, w.GWL_STYLE, @bitCast(window_style));
|
||||||
|
_ = w.SetWindowLongW(self.window, w.GWL_EXSTYLE, @bitCast(window_ex_style));
|
||||||
|
|
||||||
|
restoreWindowPosition(self);
|
||||||
|
},
|
||||||
|
.fullscreen => {
|
||||||
|
// TODO (win32) - change to use exclusive fullscreen using ChangeDisplaySetting
|
||||||
|
|
||||||
|
_ = w.GetWindowRect(self.window, &self.saved_window_rect);
|
||||||
|
|
||||||
|
const window_style = w.WINDOW_STYLE{ .POPUP = 1, .VISIBLE = 1 };
|
||||||
|
const window_ex_style = w.WINDOW_EX_STYLE{ .APPWINDOW = 1 };
|
||||||
|
|
||||||
|
_ = w.SetWindowLongW(self.window, w.GWL_STYLE, @bitCast(window_style));
|
||||||
|
_ = w.SetWindowLongW(self.window, w.GWL_EXSTYLE, @bitCast(window_ex_style));
|
||||||
|
|
||||||
|
const monitor = w.MonitorFromWindow(self.window, w.MONITOR_DEFAULTTONEAREST);
|
||||||
|
var monitor_info: w.MONITORINFO = undefined;
|
||||||
|
monitor_info.cbSize = @sizeOf(w.MONITORINFO);
|
||||||
|
if (w.GetMonitorInfoW(monitor, &monitor_info) == w.TRUE) {
|
||||||
|
_ = w.SetWindowPos(self.window, null, monitor_info.rcMonitor.left, monitor_info.rcMonitor.top, monitor_info.rcMonitor.right - monitor_info.rcMonitor.left, monitor_info.rcMonitor.bottom - monitor_info.rcMonitor.top, w.SWP_NOZORDER);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.borderless => {
|
||||||
|
_ = w.GetWindowRect(self.window, &self.saved_window_rect);
|
||||||
|
|
||||||
|
const window_style = w.WINDOW_STYLE{ .POPUP = 1, .VISIBLE = 1 };
|
||||||
|
const window_ex_style = w.WINDOW_EX_STYLE{ .APPWINDOW = 1 };
|
||||||
|
|
||||||
|
_ = w.SetWindowLongW(self.window, w.GWL_STYLE, @bitCast(window_style));
|
||||||
|
_ = w.SetWindowLongW(self.window, w.GWL_EXSTYLE, @bitCast(window_ex_style));
|
||||||
|
|
||||||
|
const monitor = w.MonitorFromWindow(self.window, w.MONITOR_DEFAULTTONEAREST);
|
||||||
|
var monitor_info: w.MONITORINFO = undefined;
|
||||||
|
monitor_info.cbSize = @sizeOf(w.MONITORINFO);
|
||||||
|
if (w.GetMonitorInfoW(monitor, &monitor_info) == w.TRUE) {
|
||||||
|
_ = w.SetWindowPos(self.window, null, monitor_info.rcMonitor.left, monitor_info.rcMonitor.top, monitor_info.rcMonitor.right - monitor_info.rcMonitor.left, monitor_info.rcMonitor.bottom - monitor_info.rcMonitor.top, w.SWP_NOZORDER);
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -248,40 +242,10 @@ pub fn setVSync(self: *Win32, mode: VSyncMode) void {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setSize(self: *Win32, value: Size) void {
|
pub fn setSize(self: *Win32, value: Size) void {
|
||||||
// TODO - use AdjustClientRect to get correct client rect.
|
// TODO (win32) - use AdjustClientRect to get correct client rect.
|
||||||
_ = w.SetWindowPos(self.window,
|
_ = w.SetWindowPos(self.window, null, 0, 0, @as(i32, @intCast(value.width)), @as(i32, @intCast(value.height)), w.SET_WINDOW_POS_FLAGS{ .NOMOVE = 1, .NOZORDER = 1, .NOACTIVATE = 1 });
|
||||||
null,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
@as(i32, @intCast(value.width)),
|
|
||||||
@as(i32, @intCast(value.height)),
|
|
||||||
w.SET_WINDOW_POS_FLAGS{.NOMOVE = 1, .NOZORDER = 1, .NOACTIVATE = 1}
|
|
||||||
);
|
|
||||||
self.size = value;
|
self.size = value;
|
||||||
}
|
}
|
||||||
// pub fn size(self: *Core) core.Size {
|
|
||||||
// var rect: w.RECT = undefined;
|
|
||||||
// _ = w.GetClientRect(self.window, &rect);
|
|
||||||
|
|
||||||
// const width:u32 = @intCast(rect.right - rect.left);
|
|
||||||
// const height:u32 = @intCast(rect.bottom - rect.top);
|
|
||||||
|
|
||||||
// return .{ .width = width, .height = height };
|
|
||||||
// }
|
|
||||||
|
|
||||||
// pub fn setSizeLimit(self: *Core, value: core.SizeLimit) void {
|
|
||||||
// self.mutex.lock();
|
|
||||||
// defer self.mutex.unlock();
|
|
||||||
// self.limits = value;
|
|
||||||
// // trigger WM_GETMINMAXINFO
|
|
||||||
// _ = w.SetWindowPos(self.window, 0, 0, 0, 0, 0, w.SWP_NOMOVE | w.SWP_NOSIZE | w.SWP_NOZORDER | w.SWP_NOACTIVATE);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// pub fn sizeLimit(self: *Core) core.SizeLimit {
|
|
||||||
// self.mutex.lock();
|
|
||||||
// defer self.mutex.unlock();
|
|
||||||
// return self.limits;
|
|
||||||
// }
|
|
||||||
|
|
||||||
pub fn setCursorMode(self: *Win32, mode: CursorMode) void {
|
pub fn setCursorMode(self: *Win32, mode: CursorMode) void {
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
|
|
@ -310,37 +274,61 @@ pub fn setCursorShape(self: *Win32, shape: CursorShape) void {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn keyPressed(self: *Win32, key: Key) bool {
|
pub fn keyPressed(self: *Win32, key: Key) bool {
|
||||||
_ = self;
|
return self.input_state.isKeyPressed(key);
|
||||||
_ = key;
|
|
||||||
// TODO: Not implemented
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn keyReleased(self: *Win32, key: Key) bool {
|
pub fn keyReleased(self: *Win32, key: Key) bool {
|
||||||
_ = self;
|
return self.input_state.isKeyReleased(key);
|
||||||
_ = key;
|
|
||||||
// TODO: Not implemented
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mousePressed(self: *Win32, button: MouseButton) bool {
|
pub fn mousePressed(self: *Win32, button: MouseButton) bool {
|
||||||
_ = self;
|
return self.input_state.isMouseButtonPressed(button);
|
||||||
_ = button;
|
|
||||||
// TODO: Not implemented
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mouseReleased(self: *Win32, button: MouseButton) bool {
|
pub fn mouseReleased(self: *Win32, button: MouseButton) bool {
|
||||||
_ = self;
|
return self.input_state.isMouseButtonReleased(button);
|
||||||
_ = button;
|
|
||||||
// TODO: Not implemented
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mousePosition(self: *Win32) Position {
|
pub fn mousePosition(self: *Win32) Position {
|
||||||
_ = self;
|
return self.input_state.mouse_position;
|
||||||
// TODO: Not implemented
|
}
|
||||||
return Position{.x = 0.0, .y = 0.0};
|
|
||||||
|
pub fn joystickPresent(_: *Win32, _: Joystick) bool {
|
||||||
|
@panic("NOT IMPLEMENTED");
|
||||||
|
}
|
||||||
|
pub fn joystickName(_: *Win32, _: Joystick) ?[:0]const u8 {
|
||||||
|
@panic("NOT IMPLEMENTED");
|
||||||
|
}
|
||||||
|
pub fn joystickButtons(_: *Win32, _: Joystick) ?[]const bool {
|
||||||
|
@panic("NOT IMPLEMENTED");
|
||||||
|
}
|
||||||
|
// May be called from any thread.
|
||||||
|
pub fn joystickAxes(_: *Win32, _: Joystick) ?[]const f32 {
|
||||||
|
@panic("NOT IMPLEMENTED");
|
||||||
|
}
|
||||||
|
pub fn nativeWindowWin32(self: *Win32) w.HWND {
|
||||||
|
return self.window;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------
|
||||||
|
// Internal functions
|
||||||
|
// -----------------------------
|
||||||
|
fn getClientRect(self: *Win32) Size {
|
||||||
|
var rect: w.RECT = undefined;
|
||||||
|
_ = w.GetClientRect(self.window, &rect);
|
||||||
|
|
||||||
|
const width: u32 = @intCast(rect.right - rect.left);
|
||||||
|
const height: u32 = @intCast(rect.bottom - rect.top);
|
||||||
|
|
||||||
|
return .{ .width = width, .height = height };
|
||||||
|
}
|
||||||
|
|
||||||
|
fn restoreWindowPosition(self: *Win32) void {
|
||||||
|
if (self.saved_window_rect.right - self.saved_window_rect.left == 0) {
|
||||||
|
_ = w.ShowWindow(self.window, w.SW_RESTORE);
|
||||||
|
} else {
|
||||||
|
_ = w.SetWindowPos(self.window, null, self.saved_window_rect.left, self.saved_window_rect.top, self.saved_window_rect.right - self.saved_window_rect.left, self.saved_window_rect.bottom - self.saved_window_rect.top, w.SWP_SHOWWINDOW);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn outOfMemory(self: *Win32) bool {
|
pub fn outOfMemory(self: *Win32) bool {
|
||||||
|
|
@ -355,6 +343,18 @@ fn pushEvent(self: *Win32, event: Event) void {
|
||||||
self.events.writeItem(event) catch self.oom.set();
|
self.events.writeItem(event) catch self.oom.set();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn getKeyboardModifiers() mach.Core.KeyMods {
|
||||||
|
return .{
|
||||||
|
.shift = w.GetKeyState(@as(i32, @intFromEnum(w.VK_SHIFT))) < 0, //& 0x8000 == 0x8000,
|
||||||
|
.control = w.GetKeyState(@as(i32, @intFromEnum(w.VK_CONTROL))) < 0, // & 0x8000 == 0x8000,
|
||||||
|
.alt = w.GetKeyState(@as(i32, @intFromEnum(w.VK_MENU))) < 0, // & 0x8000 == 0x8000,
|
||||||
|
.super = (w.GetKeyState(@as(i32, @intFromEnum(w.VK_LWIN)))) < 0 // & 0x8000 == 0x8000)
|
||||||
|
or (w.GetKeyState(@as(i32, @intFromEnum(w.VK_RWIN)))) < 0, // & 0x8000 == 0x8000),
|
||||||
|
.caps_lock = w.GetKeyState(@as(i32, @intFromEnum(w.VK_CAPITAL))) & 1 == 1,
|
||||||
|
.num_lock = w.GetKeyState(@as(i32, @intFromEnum(w.VK_NUMLOCK))) & 1 == 1,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
fn wndProc(wnd: w.HWND, msg: u32, wParam: w.WPARAM, lParam: w.LPARAM) callconv(w.WINAPI) w.LRESULT {
|
fn wndProc(wnd: w.HWND, msg: u32, wParam: w.WPARAM, lParam: w.LPARAM) callconv(w.WINAPI) w.LRESULT {
|
||||||
const self = blk: {
|
const self = blk: {
|
||||||
const userdata: usize = @bitCast(w.GetWindowLongPtrW(wnd, w.GWLP_USERDATA));
|
const userdata: usize = @bitCast(w.GetWindowLongPtrW(wnd, w.GWLP_USERDATA));
|
||||||
|
|
@ -367,19 +367,18 @@ fn wndProc(wnd: w.HWND, msg: u32, wParam: w.WPARAM, lParam: w.LPARAM) callconv(w
|
||||||
self.pushEvent(.close);
|
self.pushEvent(.close);
|
||||||
return 0;
|
return 0;
|
||||||
},
|
},
|
||||||
w.WM_GETMINMAXINFO => {
|
w.WM_SIZE => {
|
||||||
//self.mutex.lock();
|
const width: u32 = @as(u32, @intCast(lParam & 0xFFFF));
|
||||||
//defer self.mutex.unlock();
|
const height: u32 = @as(u32, @intCast((lParam >> 16) & 0xFFFF));
|
||||||
|
self.size = .{ .width = width, .height = height };
|
||||||
|
|
||||||
|
// TODO (win32): only send resize event when sizing is done.
|
||||||
|
// the main mach loops does not run while resizing.
|
||||||
|
// Which means if events are pushed here they will
|
||||||
|
// queue up until resize is done.
|
||||||
|
|
||||||
|
self.core.swap_chain_update.set();
|
||||||
|
|
||||||
// TODO: SizeLimit is no longer in mach core or has changed
|
|
||||||
// const info: *w.MINMAXINFO = blk: {
|
|
||||||
// const int: usize = @bitCast(lParam);
|
|
||||||
// break :blk @ptrFromInt(int);
|
|
||||||
// };
|
|
||||||
// if (self.limits.min.width) |width| info.ptMinTrackSize.x = @bitCast(width);
|
|
||||||
// if (self.limits.min.height) |height| info.ptMinTrackSize.y = @bitCast(height);
|
|
||||||
// if (self.limits.max.width) |width| info.ptMaxTrackSize.x = @bitCast(width);
|
|
||||||
// if (self.limits.max.height) |height| info.ptMaxTrackSize.y = @bitCast(height);
|
|
||||||
return 0;
|
return 0;
|
||||||
},
|
},
|
||||||
w.WM_KEYDOWN, w.WM_KEYUP, w.WM_SYSKEYDOWN, w.WM_SYSKEYUP => {
|
w.WM_KEYDOWN, w.WM_KEYUP, w.WM_SYSKEYDOWN, w.WM_SYSKEYUP => {
|
||||||
|
|
@ -407,15 +406,18 @@ fn wndProc(wnd: w.HWND, msg: u32, wParam: w.WPARAM, lParam: w.LPARAM) callconv(w
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const mods = getKeyboardModifiers();
|
||||||
const key = keyFromScancode(scancode);
|
const key = keyFromScancode(scancode);
|
||||||
if (msg == w.WM_KEYDOWN or msg == w.WM_SYSKEYDOWN) {
|
if (msg == w.WM_KEYDOWN or msg == w.WM_SYSKEYDOWN) {
|
||||||
if (flags & w.KF_REPEAT == 0) {
|
if (flags & w.KF_REPEAT == 0) {
|
||||||
self.pushEvent(.{ .key_press = .{ .key = key, .mods = undefined } });
|
self.pushEvent(.{ .key_press = .{ .key = key, .mods = mods } });
|
||||||
|
self.input_state.keys.setValue(@intFromEnum(key), true);
|
||||||
} else {
|
} else {
|
||||||
self.pushEvent(.{ .key_repeat = .{ .key = key, .mods = undefined } });
|
self.pushEvent(.{ .key_repeat = .{ .key = key, .mods = mods } });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.pushEvent(.{ .key_release = .{ .key = key, .mods = undefined } });
|
self.pushEvent(.{ .key_release = .{ .key = key, .mods = mods } });
|
||||||
|
self.input_state.keys.setValue(@intFromEnum(key), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -449,8 +451,9 @@ fn wndProc(wnd: w.HWND, msg: u32, wParam: w.WPARAM, lParam: w.LPARAM) callconv(w
|
||||||
w.WM_XBUTTONDOWN,
|
w.WM_XBUTTONDOWN,
|
||||||
w.WM_XBUTTONUP,
|
w.WM_XBUTTONUP,
|
||||||
=> {
|
=> {
|
||||||
const x:f64 = @floatFromInt(@as(i16, @truncate(lParam & 0xFFFF)));
|
const mods = getKeyboardModifiers();
|
||||||
const y:f64 = @floatFromInt(@as(i16, @truncate((lParam >> 16) & 0xFFFF)));
|
const x: f64 = @floatFromInt(@as(i16, @truncate(lParam & 0xFFFF)));
|
||||||
|
const y: f64 = @floatFromInt(@as(i16, @truncate((lParam >> 16) & 0xFFFF)));
|
||||||
const xbutton: u32 = @truncate(wParam >> 16);
|
const xbutton: u32 = @truncate(wParam >> 16);
|
||||||
const button: MouseButton = switch (msg) {
|
const button: MouseButton = switch (msg) {
|
||||||
w.WM_LBUTTONDOWN, w.WM_LBUTTONUP => .left,
|
w.WM_LBUTTONDOWN, w.WM_LBUTTONUP => .left,
|
||||||
|
|
@ -464,15 +467,21 @@ fn wndProc(wnd: w.HWND, msg: u32, wParam: w.WPARAM, lParam: w.LPARAM) callconv(w
|
||||||
w.WM_MBUTTONDOWN,
|
w.WM_MBUTTONDOWN,
|
||||||
w.WM_RBUTTONDOWN,
|
w.WM_RBUTTONDOWN,
|
||||||
w.WM_XBUTTONDOWN,
|
w.WM_XBUTTONDOWN,
|
||||||
=> self.pushEvent(.{ .mouse_press = .{ .button = button, .mods = undefined, .pos = .{.x = x, .y = y }}}),
|
=> {
|
||||||
else => self.pushEvent(.{ .mouse_release = .{ .button = button, .mods = undefined, .pos = .{.x = x, .y = y}}}),
|
self.pushEvent(.{ .mouse_press = .{ .button = button, .mods = mods, .pos = .{ .x = x, .y = y } } });
|
||||||
|
self.input_state.mouse_buttons.setValue(@intFromEnum(button), true);
|
||||||
|
},
|
||||||
|
else => {
|
||||||
|
self.pushEvent(.{ .mouse_release = .{ .button = button, .mods = mods, .pos = .{ .x = x, .y = y } } });
|
||||||
|
self.input_state.mouse_buttons.setValue(@intFromEnum(button), false);
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (msg == w.WM_XBUTTONDOWN or msg == w.WM_XBUTTONUP) w.TRUE else 0;
|
return if (msg == w.WM_XBUTTONDOWN or msg == w.WM_XBUTTONUP) w.TRUE else 0;
|
||||||
},
|
},
|
||||||
w.WM_MOUSEMOVE => {
|
w.WM_MOUSEMOVE => {
|
||||||
const x:f64 = @floatFromInt(@as(i16, @truncate(lParam & 0xFFFF)));
|
const x: f64 = @floatFromInt(@as(i16, @truncate(lParam & 0xFFFF)));
|
||||||
const y:f64 = @floatFromInt(@as(i16, @truncate((lParam >> 16) & 0xFFFF)));
|
const y: f64 = @floatFromInt(@as(i16, @truncate((lParam >> 16) & 0xFFFF)));
|
||||||
|
|
||||||
self.pushEvent(.{
|
self.pushEvent(.{
|
||||||
.mouse_motion = .{
|
.mouse_motion = .{
|
||||||
|
|
@ -482,17 +491,33 @@ fn wndProc(wnd: w.HWND, msg: u32, wParam: w.WPARAM, lParam: w.LPARAM) callconv(w
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
self.input_state.mouse_position = .{ .x = x, .y = y };
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
},
|
},
|
||||||
w.WM_MOUSEWHEEL => {
|
w.WM_MOUSEWHEEL => {
|
||||||
|
const WHEEL_DELTA = 120.0;
|
||||||
|
const wheel_high_word: u16 = @truncate((wParam >> 16) & 0xffff);
|
||||||
|
const delta_y: f32 = @as(f32, @floatFromInt(@as(i16, @bitCast(wheel_high_word)))) / WHEEL_DELTA;
|
||||||
|
|
||||||
self.pushEvent(.{
|
self.pushEvent(.{
|
||||||
.mouse_scroll = .{
|
.mouse_scroll = .{
|
||||||
.xoffset = 0,
|
.xoffset = 0,
|
||||||
.yoffset = 0,
|
.yoffset = delta_y,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return 0;
|
return 0;
|
||||||
},
|
},
|
||||||
|
w.WM_SETFOCUS => {
|
||||||
|
self.pushEvent(.{ .focus_gained = {} });
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
w.WM_KILLFOCUS => {
|
||||||
|
self.pushEvent(.{ .focus_lost = {} });
|
||||||
|
// Clear input state when focus is lost to avoid "stuck" button when focus is regained.
|
||||||
|
self.input_state = .{};
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
else => return w.DefWindowProcW(wnd, msg, wParam, lParam),
|
else => return w.DefWindowProcW(wnd, msg, wParam, lParam),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -584,9 +609,13 @@ fn keyFromScancode(scancode: u9) Key {
|
||||||
0x51 => .kp_3,
|
0x51 => .kp_3,
|
||||||
0x52 => .kp_0,
|
0x52 => .kp_0,
|
||||||
0x53 => .kp_decimal,
|
0x53 => .kp_decimal,
|
||||||
|
0x54 => .print, // sysrq
|
||||||
|
0x56 => .iso_backslash,
|
||||||
//0x56 => .europe2,
|
//0x56 => .europe2,
|
||||||
0x57 => .f11,
|
0x57 => .f11,
|
||||||
0x58 => .f12,
|
0x58 => .f12,
|
||||||
|
0x59 => .kp_equal,
|
||||||
|
0x5B => .left_super, // sent by touchpad gestures
|
||||||
//0x5C => .international6,
|
//0x5C => .international6,
|
||||||
0x64 => .f13,
|
0x64 => .f13,
|
||||||
0x65 => .f14,
|
0x65 => .f14,
|
||||||
|
|
@ -602,17 +631,21 @@ fn keyFromScancode(scancode: u9) Key {
|
||||||
//0x70 => .international2,
|
//0x70 => .international2,
|
||||||
//0x73 => .international1,
|
//0x73 => .international1,
|
||||||
//0x76 => .lang5,
|
//0x76 => .lang5,
|
||||||
|
0x73 => .international1,
|
||||||
|
0x76 => .f24,
|
||||||
//0x77 => .lang4,
|
//0x77 => .lang4,
|
||||||
//0x78 => .lang3,
|
//0x78 => .lang3,
|
||||||
//0x79 => .international4,
|
//0x79 => .international4,
|
||||||
//0x7B => .international5,
|
//0x7B => .international5,
|
||||||
//0x7D => .international3,
|
//0x7D => .international3,
|
||||||
//0x7E => .kp_comma,
|
0x7E => .kp_comma,
|
||||||
//0xF1 => .lang2,
|
//0xF1 => .lang2,
|
||||||
//0xF2 => .lang1,
|
//0xF2 => .lang1,
|
||||||
//0x11C => .kp_enter,
|
0x11C => .kp_enter,
|
||||||
0x11D => .right_control,
|
0x11D => .right_control,
|
||||||
//0x135 => .kp_divide,
|
0x135 => .kp_divide,
|
||||||
|
0x136 => .right_shift, // sent by IME
|
||||||
|
0x137 => .print,
|
||||||
0x138 => .right_alt,
|
0x138 => .right_alt,
|
||||||
0x145 => .num_lock,
|
0x145 => .num_lock,
|
||||||
0x146 => .pause,
|
0x146 => .pause,
|
||||||
|
|
@ -635,16 +668,7 @@ fn keyFromScancode(scancode: u9) Key {
|
||||||
return if (scancode > 0 and scancode <= table.len) table[scancode - 1] else .unknown;
|
return if (scancode > 0 and scancode <= table.len) table[scancode - 1] else .unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn joystickPresent(_: *Win32, _: Joystick) bool {
|
// TODO (win32) Implement consistent error handling when interfacing with the Windows API.
|
||||||
@panic("NOT IMPLEMENTED");
|
// TODO (win32) Support High DPI awareness
|
||||||
}
|
// TODO (win32) Consider to add support for mouse capture
|
||||||
pub fn joystickName(_: *Win32, _: Joystick) ?[:0]const u8 {
|
// TODO (win32) Change to using WM_INPUT for mouse movement.
|
||||||
@panic("NOT IMPLEMENTED");
|
|
||||||
}
|
|
||||||
pub fn joystickButtons(_: *Win32, _: Joystick) ?[]const bool {
|
|
||||||
@panic("NOT IMPLEMENTED");
|
|
||||||
}
|
|
||||||
// May be called from any thread.
|
|
||||||
pub fn joystickAxes(_: *Win32, _: Joystick) ?[]const f32 {
|
|
||||||
@panic("NOT IMPLEMENTED");
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@ pub const HICON = w.HICON;
|
||||||
pub const HCURSOR = w.HCURSOR;
|
pub const HCURSOR = w.HCURSOR;
|
||||||
pub const HBRUSH = w.HBRUSH;
|
pub const HBRUSH = w.HBRUSH;
|
||||||
pub const HMENU = w.HMENU;
|
pub const HMENU = w.HMENU;
|
||||||
|
pub const HMONITOR = *opaque {};
|
||||||
|
pub const HDC = w.HDC;
|
||||||
pub const WINAPI = w.WINAPI;
|
pub const WINAPI = w.WINAPI;
|
||||||
pub const TRUE = w.TRUE;
|
pub const TRUE = w.TRUE;
|
||||||
pub const FALSE = w.FALSE;
|
pub const FALSE = w.FALSE;
|
||||||
|
|
@ -648,7 +650,6 @@ pub const IDirectInput8W = extern struct {
|
||||||
pub usingnamespace MethodMixin(@This());
|
pub usingnamespace MethodMixin(@This());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
pub const IID_IDirectInputDevice8W = GUID{ .Data1 = 1423184001, .Data2 = 56341, .Data3 = 18483, .Data4 = .{ 164, 27, 116, 143, 115, 163, 129, 121 } };
|
pub const IID_IDirectInputDevice8W = GUID{ .Data1 = 1423184001, .Data2 = 56341, .Data3 = 18483, .Data4 = .{ 164, 27, 116, 143, 115, 163, 129, 121 } };
|
||||||
pub const IDirectInputDevice8W = extern struct {
|
pub const IDirectInputDevice8W = extern struct {
|
||||||
lpVtbl: *VTable,
|
lpVtbl: *VTable,
|
||||||
|
|
@ -1346,11 +1347,11 @@ pub const WS_EX_WINDOWEDGE = WINDOW_EX_STYLE{ .WINDOWEDGE = 1 };
|
||||||
pub const WS_EX_CLIENTEDGE = WINDOW_EX_STYLE{ .CLIENTEDGE = 1 };
|
pub const WS_EX_CLIENTEDGE = WINDOW_EX_STYLE{ .CLIENTEDGE = 1 };
|
||||||
pub const WS_EX_CONTEXTHELP = WINDOW_EX_STYLE{ .CONTEXTHELP = 1 };
|
pub const WS_EX_CONTEXTHELP = WINDOW_EX_STYLE{ .CONTEXTHELP = 1 };
|
||||||
pub const WS_EX_RIGHT = WINDOW_EX_STYLE{ .RIGHT = 1 };
|
pub const WS_EX_RIGHT = WINDOW_EX_STYLE{ .RIGHT = 1 };
|
||||||
pub const WS_EX_LEFT = WINDOW_EX_STYLE{ };
|
pub const WS_EX_LEFT = WINDOW_EX_STYLE{};
|
||||||
pub const WS_EX_RTLREADING = WINDOW_EX_STYLE{ .RTLREADING = 1 };
|
pub const WS_EX_RTLREADING = WINDOW_EX_STYLE{ .RTLREADING = 1 };
|
||||||
pub const WS_EX_LTRREADING = WINDOW_EX_STYLE{ };
|
pub const WS_EX_LTRREADING = WINDOW_EX_STYLE{};
|
||||||
pub const WS_EX_LEFTSCROLLBAR = WINDOW_EX_STYLE{ .LEFTSCROLLBAR = 1 };
|
pub const WS_EX_LEFTSCROLLBAR = WINDOW_EX_STYLE{ .LEFTSCROLLBAR = 1 };
|
||||||
pub const WS_EX_RIGHTSCROLLBAR = WINDOW_EX_STYLE{ };
|
pub const WS_EX_RIGHTSCROLLBAR = WINDOW_EX_STYLE{};
|
||||||
pub const WS_EX_CONTROLPARENT = WINDOW_EX_STYLE{ .CONTROLPARENT = 1 };
|
pub const WS_EX_CONTROLPARENT = WINDOW_EX_STYLE{ .CONTROLPARENT = 1 };
|
||||||
pub const WS_EX_STATICEDGE = WINDOW_EX_STYLE{ .STATICEDGE = 1 };
|
pub const WS_EX_STATICEDGE = WINDOW_EX_STYLE{ .STATICEDGE = 1 };
|
||||||
pub const WS_EX_APPWINDOW = WINDOW_EX_STYLE{ .APPWINDOW = 1 };
|
pub const WS_EX_APPWINDOW = WINDOW_EX_STYLE{ .APPWINDOW = 1 };
|
||||||
|
|
@ -2298,3 +2299,101 @@ pub const VK_ZOOM = VIRTUAL_KEY.ZOOM;
|
||||||
pub const VK_NONAME = VIRTUAL_KEY.NONAME;
|
pub const VK_NONAME = VIRTUAL_KEY.NONAME;
|
||||||
pub const VK_PA1 = VIRTUAL_KEY.PA1;
|
pub const VK_PA1 = VIRTUAL_KEY.PA1;
|
||||||
pub const VK_OEM_CLEAR = VIRTUAL_KEY.OEM_CLEAR;
|
pub const VK_OEM_CLEAR = VIRTUAL_KEY.OEM_CLEAR;
|
||||||
|
|
||||||
|
// ---------------------------
|
||||||
|
// Keyboard and mouse
|
||||||
|
// ---------------------------
|
||||||
|
// TODO: this type is limited to platform 'windows5.0'
|
||||||
|
pub extern "user32" fn GetFocus() callconv(@import("std").os.windows.WINAPI) ?HWND;
|
||||||
|
|
||||||
|
// TODO: this type is limited to platform 'windows5.0'
|
||||||
|
pub extern "user32" fn GetKBCodePage() callconv(@import("std").os.windows.WINAPI) u32;
|
||||||
|
|
||||||
|
// TODO: this type is limited to platform 'windows5.0'
|
||||||
|
pub extern "user32" fn GetKeyState(
|
||||||
|
nVirtKey: i32,
|
||||||
|
) callconv(@import("std").os.windows.WINAPI) i16;
|
||||||
|
|
||||||
|
// TODO: this type is limited to platform 'windows5.0'
|
||||||
|
pub extern "user32" fn GetAsyncKeyState(
|
||||||
|
vKey: i32,
|
||||||
|
) callconv(@import("std").os.windows.WINAPI) i16;
|
||||||
|
|
||||||
|
// TODO: this type is limited to platform 'windows5.0'
|
||||||
|
pub extern "user32" fn GetKeyboardState(
|
||||||
|
lpKeyState: *[256]u8,
|
||||||
|
) callconv(@import("std").os.windows.WINAPI) BOOL;
|
||||||
|
|
||||||
|
pub extern "user32" fn GetCapture() callconv(@import("std").os.windows.WINAPI) ?HWND;
|
||||||
|
|
||||||
|
// TODO: this type is limited to platform 'windows5.0'
|
||||||
|
pub extern "user32" fn SetCapture(
|
||||||
|
hWnd: ?HWND,
|
||||||
|
) callconv(@import("std").os.windows.WINAPI) ?HWND;
|
||||||
|
|
||||||
|
// TODO: this type is limited to platform 'windows5.0'
|
||||||
|
pub extern "user32" fn ReleaseCapture() callconv(@import("std").os.windows.WINAPI) BOOL;
|
||||||
|
|
||||||
|
// --------------------------
|
||||||
|
// GDI
|
||||||
|
// --------------------------
|
||||||
|
pub const MONITORENUMPROC = *const fn (
|
||||||
|
param0: ?HMONITOR,
|
||||||
|
param1: ?HDC,
|
||||||
|
param2: ?*RECT,
|
||||||
|
param3: LPARAM,
|
||||||
|
) callconv(@import("std").os.windows.WINAPI) BOOL;
|
||||||
|
|
||||||
|
pub const MONITORINFO = extern struct {
|
||||||
|
cbSize: u32,
|
||||||
|
rcMonitor: RECT,
|
||||||
|
rcWork: RECT,
|
||||||
|
dwFlags: u32,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const MONITOR_FROM_FLAGS = enum(u32) {
|
||||||
|
NEAREST = 2,
|
||||||
|
NULL = 0,
|
||||||
|
PRIMARY = 1,
|
||||||
|
};
|
||||||
|
pub const MONITOR_DEFAULTTONEAREST = MONITOR_FROM_FLAGS.NEAREST;
|
||||||
|
pub const MONITOR_DEFAULTTONULL = MONITOR_FROM_FLAGS.NULL;
|
||||||
|
pub const MONITOR_DEFAULTTOPRIMARY = MONITOR_FROM_FLAGS.PRIMARY;
|
||||||
|
|
||||||
|
// TODO: this type is limited to platform 'windows5.0'
|
||||||
|
pub extern "user32" fn MonitorFromPoint(
|
||||||
|
pt: POINT,
|
||||||
|
dwFlags: MONITOR_FROM_FLAGS,
|
||||||
|
) callconv(@import("std").os.windows.WINAPI) ?HMONITOR;
|
||||||
|
|
||||||
|
// TODO: this type is limited to platform 'windows5.0'
|
||||||
|
pub extern "user32" fn MonitorFromRect(
|
||||||
|
lprc: ?*RECT,
|
||||||
|
dwFlags: MONITOR_FROM_FLAGS,
|
||||||
|
) callconv(@import("std").os.windows.WINAPI) ?HMONITOR;
|
||||||
|
|
||||||
|
// TODO: this type is limited to platform 'windows5.0'
|
||||||
|
pub extern "user32" fn MonitorFromWindow(
|
||||||
|
hwnd: ?HWND,
|
||||||
|
dwFlags: MONITOR_FROM_FLAGS,
|
||||||
|
) callconv(@import("std").os.windows.WINAPI) ?HMONITOR;
|
||||||
|
|
||||||
|
// TODO: this type is limited to platform 'windows5.0'
|
||||||
|
pub extern "user32" fn GetMonitorInfoA(
|
||||||
|
hMonitor: ?HMONITOR,
|
||||||
|
lpmi: ?*MONITORINFO,
|
||||||
|
) callconv(@import("std").os.windows.WINAPI) BOOL;
|
||||||
|
|
||||||
|
// TODO: this type is limited to platform 'windows5.0'
|
||||||
|
pub extern "user32" fn GetMonitorInfoW(
|
||||||
|
hMonitor: ?HMONITOR,
|
||||||
|
lpmi: ?*MONITORINFO,
|
||||||
|
) callconv(@import("std").os.windows.WINAPI) BOOL;
|
||||||
|
|
||||||
|
// TODO: this type is limited to platform 'windows5.0'
|
||||||
|
pub extern "user32" fn EnumDisplayMonitors(
|
||||||
|
hdc: ?HDC,
|
||||||
|
lprcClip: ?*RECT,
|
||||||
|
lpfnEnum: ?MONITORENUMPROC,
|
||||||
|
dwData: LPARAM,
|
||||||
|
) callconv(@import("std").os.windows.WINAPI) BOOL;
|
||||||
|
|
|
||||||
|
|
@ -86,13 +86,9 @@ pub const Instance = struct {
|
||||||
);
|
);
|
||||||
if (hr == c.DXGI_ERROR_INVALID_CALL) {
|
if (hr == c.DXGI_ERROR_INVALID_CALL) {
|
||||||
const hr_prev = hr;
|
const hr_prev = hr;
|
||||||
hr = c.CreateDXGIFactory2(
|
hr = c.CreateDXGIFactory2(0, &c.IID_IDXGIFactory4, @ptrCast(&dxgi_factory));
|
||||||
0,
|
|
||||||
&c.IID_IDXGIFactory4,
|
|
||||||
@ptrCast(&dxgi_factory));
|
|
||||||
if (hr == c.S_OK) {
|
if (hr == c.S_OK) {
|
||||||
log.info("note: D3D12 debug layers disabled (couldn't enable, error: {x}), see https://machengine.org/about/faq/#how-to-enable-direct3d-debug-layers",
|
log.info("note: D3D12 debug layers disabled (couldn't enable, error: {x}), see https://machengine.org/about/faq/#how-to-enable-direct3d-debug-layers", .{@as(u32, @bitCast(hr_prev))});
|
||||||
.{@as(u32, @bitCast(hr_prev))});
|
|
||||||
} else {
|
} else {
|
||||||
return error.CreateDXGIFactoryFailed;
|
return error.CreateDXGIFactoryFailed;
|
||||||
}
|
}
|
||||||
|
|
@ -209,8 +205,8 @@ pub const Adapter = struct {
|
||||||
description[l] = 0;
|
description[l] = 0;
|
||||||
|
|
||||||
if ((dxgi_desc.Flags & c.DXGI_ADAPTER_FLAG_SOFTWARE) != 0) {
|
if ((dxgi_desc.Flags & c.DXGI_ADAPTER_FLAG_SOFTWARE) != 0) {
|
||||||
_ = dxgi_adapter.lpVtbl.*.Release.?(dxgi_adapter);
|
_ = dxgi_adapter.lpVtbl.*.Release.?(dxgi_adapter);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const adapter_type: sysgpu.Adapter.Type = blk: {
|
const adapter_type: sysgpu.Adapter.Type = blk: {
|
||||||
|
|
@ -245,8 +241,7 @@ pub const Adapter = struct {
|
||||||
// Select the last discrete_gpu if power preference is high performance.
|
// Select the last discrete_gpu if power preference is high performance.
|
||||||
// Select the last integrated_gpu if power preference is not high performance.
|
// Select the last integrated_gpu if power preference is not high performance.
|
||||||
// TOOD: Other selection criterias?
|
// TOOD: Other selection criterias?
|
||||||
if ((options.power_preference == .high_performance and adapter_type == .discrete_gpu)
|
if ((options.power_preference == .high_performance and adapter_type == .discrete_gpu) or (options.power_preference == .low_power and adapter_type != .discrete_gpu)) {
|
||||||
or (options.power_preference == .low_power and adapter_type != .discrete_gpu)) {
|
|
||||||
if (last_dxgi_adapter) |adapter| {
|
if (last_dxgi_adapter) |adapter| {
|
||||||
_ = adapter.lpVtbl.*.Release.?(adapter);
|
_ = adapter.lpVtbl.*.Release.?(adapter);
|
||||||
}
|
}
|
||||||
|
|
@ -281,7 +276,6 @@ pub const Adapter = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return error.NoAdapterFound;
|
return error.NoAdapterFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -478,7 +472,6 @@ pub const Device = struct {
|
||||||
|
|
||||||
try device.mem_allocator_textures.init(device);
|
try device.mem_allocator_textures.init(device);
|
||||||
|
|
||||||
|
|
||||||
return device;
|
return device;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1428,7 +1421,7 @@ pub const SwapChain = struct {
|
||||||
.SampleDesc = .{ .Count = 1, .Quality = 0 },
|
.SampleDesc = .{ .Count = 1, .Quality = 0 },
|
||||||
.BufferUsage = conv.dxgiUsage(desc.usage),
|
.BufferUsage = conv.dxgiUsage(desc.usage),
|
||||||
.BufferCount = back_buffer_count,
|
.BufferCount = back_buffer_count,
|
||||||
.Scaling = c.DXGI_MODE_SCALING_UNSPECIFIED,
|
.Scaling = c.DXGI_SCALING_STRETCH,
|
||||||
.SwapEffect = c.DXGI_SWAP_EFFECT_FLIP_DISCARD,
|
.SwapEffect = c.DXGI_SWAP_EFFECT_FLIP_DISCARD,
|
||||||
.AlphaMode = c.DXGI_ALPHA_MODE_UNSPECIFIED,
|
.AlphaMode = c.DXGI_ALPHA_MODE_UNSPECIFIED,
|
||||||
.Flags = if (instance.allow_tearing) c.DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING else 0,
|
.Flags = if (instance.allow_tearing) c.DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING else 0,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue