浏览代码

Moved win32 window things to separate file (interface coming soon)

Karl Zylinski 6 月之前
父节点
当前提交
8c5d30409b
共有 4 个文件被更改,包括 196 次插入108 次删除
  1. 1 1
      backend_d3d11.odin
  2. 1 1
      backend_interface.odin
  3. 26 106
      karl2d.odin
  4. 168 0
      window_windows.odin

+ 1 - 1
backend_d3d11.odin

@@ -42,7 +42,7 @@ d3d11_state_size :: proc() -> int {
 	return size_of(D3D11_State)
 }
 
-d3d11_init :: proc(state: rawptr, window_handle: uintptr, swapchain_width, swapchain_height: int,
+d3d11_init :: proc(state: rawptr, window_handle: Window_Handle, swapchain_width, swapchain_height: int,
 	allocator := context.allocator, loc := #caller_location) {
 	hwnd := dxgi.HWND(window_handle)
 	s = (^D3D11_State)(state)

+ 1 - 1
backend_interface.odin

@@ -2,7 +2,7 @@ package karl2d
 
 Rendering_Backend :: struct {
 	state_size: proc() -> int,
-	init: proc(state: rawptr, window_handle: uintptr, swapchain_width, swapchain_height: int,
+	init: proc(state: rawptr, window_handle: Window_Handle, swapchain_width, swapchain_height: int,
 		allocator := context.allocator, loc := #caller_location),
 	shutdown: proc(),
 	clear: proc(color: Color),

+ 26 - 106
karl2d.odin

@@ -1,6 +1,5 @@
 package karl2d
 
-import win32 "core:sys/windows"
 import "base:runtime"
 import "core:mem"
 import "core:log"
@@ -27,67 +26,22 @@ Texture_Handle :: distinct Handle
 // `set_state`.
 init :: proc(window_width: int, window_height: int, window_title: string,
              allocator := context.allocator, loc := #caller_location) -> ^State {
-	win32.SetProcessDPIAware()
 	s = new(State, allocator, loc)
 	s.allocator = allocator
 	s.custom_context = context
 
-	CLASS_NAME :: "karl2d"
-	instance := win32.HINSTANCE(win32.GetModuleHandleW(nil))
-
-	s.run = true
 	s.width = window_width
 	s.height = window_height
 
-	cls := win32.WNDCLASSW {
-		lpfnWndProc = window_proc,
-		lpszClassName = CLASS_NAME,
-		hInstance = instance,
-		hCursor = win32.LoadCursorA(nil, win32.IDC_ARROW),
-	}
-
-	window_proc :: proc "stdcall" (hwnd: win32.HWND, msg: win32.UINT, wparam: win32.WPARAM, lparam: win32.LPARAM) -> win32.LRESULT {
-		context = s.custom_context
-		switch msg {
-		case win32.WM_DESTROY:
-			win32.PostQuitMessage(0)
-			s.run = false
-
-		case win32.WM_CLOSE:
-			s.run = false
-
-		case win32.WM_KEYDOWN:
-			key := VK_MAP[wparam]
-			s.keys_went_down[key] = true
-			s.keys_is_held[key] = true
-
-		case win32.WM_KEYUP:
-			key := VK_MAP[wparam]
-			s.keys_is_held[key] = false
-			s.keys_went_up[key] = true
-		}
-
-		return win32.DefWindowProcW(hwnd, msg, wparam, lparam)
-	}
+	window_state_alloc_error: runtime.Allocator_Error
+	s.window_state, window_state_alloc_error = mem.alloc(window_state_size())
+	log.assertf(window_state_alloc_error == nil, "Failed allocating memory for window state: %v", window_state_alloc_error)
 
-	win32.RegisterClassW(&cls)
+	window_init(s.window_state, window_width, window_height, window_title)
 
-	r: win32.RECT
-	r.right = i32(window_width)
-	r.bottom = i32(window_height)
-
-	style := win32.WS_OVERLAPPEDWINDOW | win32.WS_VISIBLE
-	win32.AdjustWindowRect(&r, style, false)
-
-	hwnd := win32.CreateWindowW(CLASS_NAME,
-		win32.utf8_to_wstring(window_title),
-		style,
-		100, 10, r.right - r.left, r.bottom - r.top,
-		nil, nil, instance, nil)
-
-	s.window = hwnd
+	
 
-	assert(hwnd != nil, "Failed creating window")
+	s.window = window_handle()
 
 	s.rb = BACKEND_D3D11
 	rb_alloc_error: runtime.Allocator_Error
@@ -95,7 +49,7 @@ init :: proc(window_width: int, window_height: int, window_title: string,
 	log.assertf(rb_alloc_error == nil, "Failed allocating memory for rendering backend: %v", rb_alloc_error)
 	s.proj_matrix = make_default_projection(window_width, window_height)
 	s.view_matrix = 1
-	s.rb.init(s.rb_state, uintptr(hwnd), window_width, window_height, allocator, loc)
+	s.rb.init(s.rb_state, s.window, window_width, window_height, allocator, loc)
 	s.vertex_buffer_cpu = make([]u8, VERTEX_BUFFER_MAX, allocator, loc)
 	white_rect: [16*16*4]u8
 	slice.fill(white_rect[:], 255)
@@ -119,9 +73,10 @@ shutdown :: proc() {
 	s.rb.shutdown()
 	delete(s.vertex_buffer_cpu, s.allocator)
 
-	win32.DestroyWindow(s.window)
+	window_shutdown()
 
 	a := s.allocator
+	free(s.window_state, a)
 	free(s.rb_state, a)
 	free(s, a)
 	s = nil
@@ -145,11 +100,18 @@ process_events :: proc() {
 	s.keys_went_up = {}
 	s.keys_went_down = {}
 
-	msg: win32.MSG
+	events := window_process_events()
+
+	for &event in events {
+		switch &e in event {
+		case Window_Event_Key_Went_Down:
+			s.keys_went_down[e.key] = true
+			s.keys_is_held[e.key] = true
 
-	for win32.PeekMessageW(&msg, nil, 0, 0, win32.PM_REMOVE) {
-		win32.TranslateMessage(&msg)
-		win32.DispatchMessageW(&msg)			
+		case Window_Event_Key_Went_Up:
+			s.keys_is_held[e.key] = false
+			s.keys_went_up[e.key] = true
+		}
 	}
 }
 
@@ -198,21 +160,11 @@ key_is_held :: proc(key: Keyboard_Key) -> bool {
 
 // Returns true if the user has tried to close the window.
 window_should_close :: proc() -> bool {
-	return !s.run
+	return _window_should_close()
 }
 
 set_window_position :: proc(x: int, y: int) {
-	// TODO: Does x, y respect monitor DPI?
-
-	win32.SetWindowPos(
-		s.window,
-		{},
-		i32(x),
-		i32(y),
-		0,
-		0,
-		win32.SWP_NOACTIVATE | win32.SWP_NOZORDER | win32.SWP_NOSIZE,
-	)
+	window_set_position(x, y)
 }
 
 set_window_size :: proc(width: int, height: int) {
@@ -556,9 +508,12 @@ _batch_vertex :: proc(v: Vec2, uv: Vec2, color: Color) {
 	
 	s.vertex_buffer_cpu_used += shd.vertex_size
 }
+
+
 State :: struct {
 	allocator: runtime.Allocator,
 	custom_context: runtime.Context,
+	window_state: rawptr,
 	rb: Rendering_Backend,
 	rb_state: rawptr,
 	
@@ -566,12 +521,10 @@ State :: struct {
 	keys_went_up: #sparse [Keyboard_Key]bool,
 	keys_is_held: #sparse [Keyboard_Key]bool,
 
-	window: win32.HWND,
+	window: Window_Handle,
 	width: int,
 	height: int,
 
-	run: bool,
-
 	shape_drawing_texture: Texture_Handle,
 	batch_camera: Maybe(Camera),
 	batch_shader: Maybe(Shader),
@@ -585,39 +538,6 @@ State :: struct {
 	default_shader: Shader,
 }
 
-VK_MAP := [255]Keyboard_Key {
-	win32.VK_A = .A,
-	win32.VK_B = .B,
-	win32.VK_C = .C,
-	win32.VK_D = .D,
-	win32.VK_E = .E,
-	win32.VK_F = .F,
-	win32.VK_G = .G,
-	win32.VK_H = .H,
-	win32.VK_I = .I,
-	win32.VK_J = .J,
-	win32.VK_K = .K,
-	win32.VK_L = .L,
-	win32.VK_M = .M,
-	win32.VK_N = .N,
-	win32.VK_O = .O,
-	win32.VK_P = .P,
-	win32.VK_Q = .Q,
-	win32.VK_R = .R,
-	win32.VK_S = .S,
-	win32.VK_T = .T,
-	win32.VK_U = .U,
-	win32.VK_V = .V,
-	win32.VK_W = .W,
-	win32.VK_X = .X,
-	win32.VK_Y = .Y,
-	win32.VK_Z = .Z,
-	win32.VK_LEFT = .Left,
-	win32.VK_RIGHT = .Right,
-	win32.VK_UP = .Up,
-	win32.VK_DOWN = .Down,
-}
-
 @(private="file")
 s: ^State
 

+ 168 - 0
window_windows.odin

@@ -0,0 +1,168 @@
+package karl2d
+
+import win32 "core:sys/windows"
+import "base:runtime"
+import "core:slice"
+
+Window_Handle :: distinct uintptr
+
+Window_State :: struct {
+	custom_context: runtime.Context,
+	hwnd: win32.HWND,
+	window_should_close: bool,
+	events: [dynamic]Window_Event,
+}
+
+Window_Event_Key_Went_Down :: struct {
+	key: Keyboard_Key,
+}
+
+Window_Event_Key_Went_Up :: struct {
+	key: Keyboard_Key,
+}
+
+Window_Event :: union  {
+	Window_Event_Key_Went_Down,
+	Window_Event_Key_Went_Up,
+}
+
+window_state_size :: proc() -> int {
+	return size_of(Window_State)
+}
+
+// TODO rename to "ws"
+@(private="file")
+s: ^Window_State
+
+window_init :: proc(ws_in: rawptr, window_width: int, window_height: int, window_title: string) {
+	assert(ws_in != nil)
+	s = (^Window_State)(ws_in)
+	s.custom_context = context
+	win32.SetProcessDPIAware()
+	CLASS_NAME :: "karl2d"
+	instance := win32.HINSTANCE(win32.GetModuleHandleW(nil))
+
+	cls := win32.WNDCLASSW {
+		lpfnWndProc = _win32_window_proc,
+		lpszClassName = CLASS_NAME,
+		hInstance = instance,
+		hCursor = win32.LoadCursorA(nil, win32.IDC_ARROW),
+	}
+
+	win32.RegisterClassW(&cls)
+
+	r: win32.RECT
+	r.right = i32(window_width)
+	r.bottom = i32(window_height)
+
+	style := win32.WS_OVERLAPPEDWINDOW | win32.WS_VISIBLE
+	win32.AdjustWindowRect(&r, style, false)
+
+	hwnd := win32.CreateWindowW(CLASS_NAME,
+		win32.utf8_to_wstring(window_title),
+		style,
+		100, 10, r.right - r.left, r.bottom - r.top,
+		nil, nil, instance, nil,
+	)
+
+	assert(hwnd != nil, "Failed creating window")
+
+	s.hwnd = hwnd
+}
+
+window_shutdown :: proc() {
+	win32.DestroyWindow(s.hwnd)
+}
+
+window_set_position :: proc(x: int, y: int) {
+	// TODO: Does x, y respect monitor DPI?
+
+	win32.SetWindowPos(
+		s.hwnd,
+		{},
+		i32(x),
+		i32(y),
+		0,
+		0,
+		win32.SWP_NOACTIVATE | win32.SWP_NOZORDER | win32.SWP_NOSIZE,
+	)
+}
+
+window_handle :: proc() -> Window_Handle {
+	return Window_Handle(s.hwnd)
+}
+
+// TODO: perhaps this should be split into several procs later
+window_process_events :: proc(allocator := context.temp_allocator) -> []Window_Event {
+	msg: win32.MSG
+
+	for win32.PeekMessageW(&msg, nil, 0, 0, win32.PM_REMOVE) {
+		win32.TranslateMessage(&msg)
+		win32.DispatchMessageW(&msg)
+	}
+
+	return slice.clone(s.events[:], allocator)
+}
+
+_window_should_close :: proc() -> bool {
+	return s.window_should_close
+}
+
+_win32_window_proc :: proc "stdcall" (hwnd: win32.HWND, msg: win32.UINT, wparam: win32.WPARAM, lparam: win32.LPARAM) -> win32.LRESULT {
+	context = s.custom_context
+	switch msg {
+	case win32.WM_DESTROY:
+		win32.PostQuitMessage(0)
+		s.window_should_close = true
+
+	case win32.WM_CLOSE:
+		s.window_should_close = true
+
+	case win32.WM_KEYDOWN:
+		key := VK_MAP[wparam]
+		append(&s.events, Window_Event_Key_Went_Down {
+			key = key,
+		})
+
+	case win32.WM_KEYUP:
+		key := VK_MAP[wparam]
+		append(&s.events, Window_Event_Key_Went_Up {
+			key = key,
+		})
+	}
+
+	return win32.DefWindowProcW(hwnd, msg, wparam, lparam)
+}
+
+VK_MAP := [255]Keyboard_Key {
+	win32.VK_A = .A,
+	win32.VK_B = .B,
+	win32.VK_C = .C,
+	win32.VK_D = .D,
+	win32.VK_E = .E,
+	win32.VK_F = .F,
+	win32.VK_G = .G,
+	win32.VK_H = .H,
+	win32.VK_I = .I,
+	win32.VK_J = .J,
+	win32.VK_K = .K,
+	win32.VK_L = .L,
+	win32.VK_M = .M,
+	win32.VK_N = .N,
+	win32.VK_O = .O,
+	win32.VK_P = .P,
+	win32.VK_Q = .Q,
+	win32.VK_R = .R,
+	win32.VK_S = .S,
+	win32.VK_T = .T,
+	win32.VK_U = .U,
+	win32.VK_V = .V,
+	win32.VK_W = .W,
+	win32.VK_X = .X,
+	win32.VK_Y = .Y,
+	win32.VK_Z = .Z,
+	win32.VK_LEFT = .Left,
+	win32.VK_RIGHT = .Right,
+	win32.VK_UP = .Up,
+	win32.VK_DOWN = .Down,
+}