'Event_Mouse_Delta', Raw Input, WM_INPUT

This commit is contained in:
2026-02-06 02:44:19 +01:00
parent 6d35cfe3a2
commit 3c377106a5
2 changed files with 74 additions and 4 deletions

View File

@@ -11,6 +11,8 @@ Window :: struct {
backend: Backend_Info, backend: Backend_Info,
event_queue: Event_Queue, event_queue: Event_Queue,
mouse_delta: [2]i32,
} }
Event_Queue :: queue.Queue(Event) Event_Queue :: queue.Queue(Event)
@@ -52,12 +54,16 @@ Event_Keyboard :: struct {
Event_Mouse :: union { Event_Mouse :: union {
Event_Mouse_Move, Event_Mouse_Move,
Event_Mouse_Button, Event_Mouse_Button,
Event_Mouse_Delta,
} }
Event_Mouse_Move :: struct { Event_Mouse_Move :: struct {
x, y: u16, x, y: u16,
} }
Mouse_Button :: enum { Left, Middle, Right } Mouse_Button :: enum { Left, Middle, Right }
Event_Mouse_Button :: struct { button: Mouse_Button, state: Event_Input_State } Event_Mouse_Button :: struct { button: Mouse_Button, state: Event_Input_State }
Event_Mouse_Delta :: struct {
x, y: i32,
}
Event_Input :: union { Event_Input :: union {
Event_Keyboard, Event_Keyboard,
@@ -126,11 +132,12 @@ cursor_visible :: proc(window: ^Window) -> bool {
return false return false
} }
set_cursor_position :: proc(window: ^Window, pos: [2]u32) { lock_cursor :: proc(window: ^Window, lock: bool) {
// fmt.printfln("Set cursor pos: %v:%v", pos.x, pos.y)
when ODIN_OS == .Windows { when ODIN_OS == .Windows {
set_cursor_position_windows(window, pos) lock_cursor_windows(window, lock)
} }
show_cursor_window(window, !lock)
} }
get_pointer_to_surface :: proc(window: ^Window) -> rawptr { get_pointer_to_surface :: proc(window: ^Window) -> rawptr {

View File

@@ -65,6 +65,33 @@ Backend_Info :: struct {
return 0 return 0
} }
// Mouse. // Mouse.
case win.WM_INPUT: {
dwSize: win.UINT = size_of(win.RAWINPUT)
lpb: [size_of(win.RAWINPUT)]u8
v := win.GetRawInputData(
win.HRAWINPUT(lparam),
win.RID_INPUT,
&lpb[0],
&dwSize,
size_of(win.RAWINPUTHEADER),
)
raw := (^win.RAWINPUT)(&lpb[0])
if raw.header.dwType == win.RIM_TYPEMOUSE {
mouse_event: Event_Mouse = Event_Mouse_Delta {
x = i32(raw.data.mouse.lLastX),
y = i32(raw.data.mouse.lLastY),
}
assert(event_queue != nil)
queue.push_back(event_queue, Event_Input(mouse_event))
}
return 0
}
case win.WM_MOUSEMOVE: { case win.WM_MOUSEMOVE: {
x := win.GET_X_LPARAM(lparam) x := win.GET_X_LPARAM(lparam)
y := win.GET_Y_LPARAM(lparam) y := win.GET_Y_LPARAM(lparam)
@@ -190,6 +217,19 @@ init_window_windows :: proc(window: ^Window) -> bool {
hwnd = hwnd, hwnd = hwnd,
} }
register_raw_mouse_windows :: proc(hwnd: win.HWND) -> bool {
rid := win.RAWINPUTDEVICE {
usUsagePage = 0x01, // Generic Desktop Controls.
usUsage = 0x02, // Mouse.
dwFlags = win.RIDEV_INPUTSINK,
hwndTarget = hwnd,
}
ok := win.RegisterRawInputDevices(&rid, 1, size_of(win.RAWINPUTDEVICE))
return ok != win.FALSE
}
assert(register_raw_mouse_windows(hwnd))
// fmt.printfln("Window size: %vx%v.", actual_window_width, actual_window_height) // fmt.printfln("Window size: %vx%v.", actual_window_width, actual_window_height)
return true return true
@@ -229,7 +269,7 @@ cursor_visible_windows :: proc(window: ^Window) -> bool {
return old_count >= 0 return old_count >= 0
} }
set_cursor_position_windows :: proc(window: ^Window, pos: [2]u32) { set_cursor_position_windows :: proc(window: ^Window, pos: [2]u16) {
pt := win.POINT { x = i32(pos.x), y = i32(pos.y) } pt := win.POINT { x = i32(pos.x), y = i32(pos.y) }
rect: win.RECT rect: win.RECT
win.GetClientRect(window.backend.hwnd, &rect) win.GetClientRect(window.backend.hwnd, &rect)
@@ -242,6 +282,29 @@ set_cursor_position_windows :: proc(window: ^Window, pos: [2]u32) {
win.SetCursorPos(pt.x, pt.y) win.SetCursorPos(pt.x, pt.y)
} }
lock_cursor_windows :: proc(window: ^Window, lock: bool) {
assert(window != nil)
if lock {
rect: win.RECT
win.GetClientRect(window.backend.hwnd, &rect)
pt := win.POINT{rect.left, rect.top}
win.ClientToScreen(window.backend.hwnd, &pt)
rect.left = pt.x
rect.top = pt.y
pt = win.POINT{rect.right, rect.bottom}
win.ClientToScreen(window.backend.hwnd, &pt)
rect.right = pt.x
rect.bottom = pt.y
win.ClipCursor(&rect)
} else {
win.ClipCursor(nil)
}
}
update_windows :: proc(window: ^Window) { update_windows :: proc(window: ^Window) {
assert(window != nil) assert(window != nil)