Просмотр исходного кода

Added a window interface and win32 windowing now uses it

Karl Zylinski 6 месяцев назад
Родитель
Сommit
067049087e

+ 2 - 2
backend_d3d11.odin

@@ -1,6 +1,7 @@
 #+build windows
 
 package karl2d
+
 import d3d11 "vendor:directx/d3d11"
 import dxgi "vendor:directx/dxgi"
 import "vendor:directx/d3d_compiler"
@@ -42,8 +43,7 @@ d3d11_state_size :: proc() -> int {
 	return size_of(D3D11_State)
 }
 
-d3d11_init :: proc(state: rawptr, window_handle: Window_Handle, swapchain_width, swapchain_height: int,
-	allocator := context.allocator, loc := #caller_location) {
+d3d11_init :: proc(state: rawptr, window_handle: Window_Handle, swapchain_width, swapchain_height: int, allocator := context.allocator) {
 	hwnd := dxgi.HWND(window_handle)
 	s = (^D3D11_State)(state)
 	s.allocator = allocator

+ 1 - 2
backend_interface.odin

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

+ 1 - 1
examples/minimal/minimal.odin

@@ -5,7 +5,7 @@ import k2 "../.."
 main :: proc() {
 	k2.init(1280, 720, "Karl2D Minimal Program")
 
-	for !k2.window_should_close() {
+	for !k2.close_window_wanted() {
 		k2.process_events()
 		k2.clear(k2.BLUE)
 		k2.present()

+ 1 - 1
examples/raylib_ports/2d_camera/2d_camera.odin

@@ -48,7 +48,7 @@ main :: proc() {
 		zoom = 1,
 	}
 
-	for !k2.window_should_close() {
+	for !k2.close_window_wanted() {
 		k2.process_events()
 
 		if k2.key_is_held(.Right) { player.x += 2 }

+ 1 - 1
examples/snake/snake.odin

@@ -100,7 +100,7 @@ main :: proc() {
 	food_eaten_at := time.now()
 	started_at := time.now()
 
-	for !k2.window_should_close() {
+	for !k2.close_window_wanted() {
 		time_now := time.now()
 		dt := f32(time.duration_seconds(time.diff(prev_time, time_now)))
 		prev_time = time_now

+ 23 - 12
karl2d.odin

@@ -33,15 +33,15 @@ init :: proc(window_width: int, window_height: int, window_title: string,
 	s.width = window_width
 	s.height = window_height
 
+	s.wi = WINDOW_INTERFACE_WIN32
+	wi = s.wi
+
 	window_state_alloc_error: runtime.Allocator_Error
-	s.window_state, window_state_alloc_error = mem.alloc(window_state_size())
+	s.window_state, window_state_alloc_error = mem.alloc(wi.state_size())
 	log.assertf(window_state_alloc_error == nil, "Failed allocating memory for window state: %v", window_state_alloc_error)
 
-	window_init(s.window_state, window_width, window_height, window_title)
-
-	
-
-	s.window = window_handle()
+	wi.init(s.window_state, window_width, window_height, window_title, allocator)
+	s.window = wi.window_handle()
 
 	s.rb = BACKEND_D3D11
 	rb_alloc_error: runtime.Allocator_Error
@@ -49,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, s.window, window_width, window_height, allocator, loc)
+	s.rb.init(s.rb_state, s.window, window_width, window_height, allocator)
 	s.vertex_buffer_cpu = make([]u8, VERTEX_BUFFER_MAX, allocator, loc)
 	white_rect: [16*16*4]u8
 	slice.fill(white_rect[:], 255)
@@ -73,7 +73,7 @@ shutdown :: proc() {
 	s.rb.shutdown()
 	delete(s.vertex_buffer_cpu, s.allocator)
 
-	window_shutdown()
+	wi.shutdown()
 
 	a := s.allocator
 	free(s.window_state, a)
@@ -100,10 +100,15 @@ process_events :: proc() {
 	s.keys_went_up = {}
 	s.keys_went_down = {}
 
-	events := window_process_events()
+	wi.process_events()
+
+	events := wi.get_events()
 
 	for &event in events {
 		switch &e in event {
+		case Window_Event_Close_Wanted:
+			s.close_window_wanted = true
+
 		case Window_Event_Key_Went_Down:
 			s.keys_went_down[e.key] = true
 			s.keys_is_held[e.key] = true
@@ -113,6 +118,8 @@ process_events :: proc() {
 			s.keys_went_up[e.key] = true
 		}
 	}
+
+	wi.clear_events()
 }
 
 /* Flushes the current batch. This sends off everything to the GPU that has been queued in the
@@ -159,12 +166,12 @@ 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 _window_should_close()
+close_window_wanted :: proc() -> bool {
+	return s.close_window_wanted
 }
 
 set_window_position :: proc(x: int, y: int) {
-	window_set_position(x, y)
+	wi.set_position(x, y)
 }
 
 set_window_size :: proc(width: int, height: int) {
@@ -513,10 +520,13 @@ _batch_vertex :: proc(v: Vec2, uv: Vec2, color: Color) {
 State :: struct {
 	allocator: runtime.Allocator,
 	custom_context: runtime.Context,
+	wi: Window_Interface,
 	window_state: rawptr,
 	rb: Rendering_Backend,
 	rb_state: rawptr,
 	
+	close_window_wanted: bool,
+
 	keys_went_down: #sparse [Keyboard_Key]bool,
 	keys_went_up: #sparse [Keyboard_Key]bool,
 	keys_is_held: #sparse [Keyboard_Key]bool,
@@ -540,6 +550,7 @@ State :: struct {
 
 @(private="file")
 s: ^State
+wi: Window_Interface
 
 Shader_Input_Format :: enum {
 	Unknown,

+ 30 - 0
window_interface.odin

@@ -0,0 +1,30 @@
+package karl2d
+
+Window_Interface :: struct {
+	state_size: proc() -> int,
+	init: proc(window_state: rawptr, window_width: int, window_height: int, window_title: string, allocator := context.allocator),
+	shutdown: proc(),
+	window_handle: proc() -> Window_Handle,
+	process_events: proc(),
+	get_events: proc() -> []Window_Event,
+	clear_events: proc(),
+	set_position: proc(x: int, y: int),
+}
+
+Window_Handle :: distinct uintptr
+
+Window_Event :: union  {
+	Window_Event_Close_Wanted,
+	Window_Event_Key_Went_Down,
+	Window_Event_Key_Went_Up,
+}
+
+Window_Event_Key_Went_Down :: struct {
+	key: Keyboard_Key,
+}
+
+Window_Event_Key_Went_Up :: struct {
+	key: Keyboard_Key,
+}
+
+Window_Event_Close_Wanted :: struct {}

+ 37 - 35
window_windows.odin → window_win32.odin

@@ -1,42 +1,42 @@
+#+build windows
+
 package karl2d
 
 import win32 "core:sys/windows"
 import "base:runtime"
-import "core:slice"
 
-Window_Handle :: distinct uintptr
+WINDOW_INTERFACE_WIN32 :: Window_Interface {
+	state_size = win32_state_size,
+	init = win32_init,
+	shutdown = win32_shutdown,
+	window_handle = win32_window_handle,
+	process_events = win32_process_events,
+	get_events = win32_get_events,
+	clear_events = win32_clear_events,
+	set_position = win32_set_position,
+}
 
-Window_State :: struct {
+Win32_State :: struct {
+	allocator: runtime.Allocator,
 	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)
+win32_state_size :: proc() -> int {
+	return size_of(Win32_State)
 }
 
 // TODO rename to "ws"
 @(private="file")
-s: ^Window_State
+s: ^Win32_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)
+win32_init :: proc(window_state: rawptr, window_width: int, window_height: int, window_title: string, allocator := context.allocator) {
+	assert(window_state != nil)
+	s = (^Win32_State)(window_state)
+	s.allocator = allocator
+	s.events = make([dynamic]Window_Event, allocator)
 	s.custom_context = context
 	win32.SetProcessDPIAware()
 	CLASS_NAME :: "karl2d"
@@ -70,11 +70,12 @@ window_init :: proc(ws_in: rawptr, window_width: int, window_height: int, window
 	s.hwnd = hwnd
 }
 
-window_shutdown :: proc() {
+win32_shutdown :: proc() {
+	delete(s.events)
 	win32.DestroyWindow(s.hwnd)
 }
 
-window_set_position :: proc(x: int, y: int) {
+win32_set_position :: proc(x: int, y: int) {
 	// TODO: Does x, y respect monitor DPI?
 
 	win32.SetWindowPos(
@@ -88,44 +89,45 @@ window_set_position :: proc(x: int, y: int) {
 	)
 }
 
-window_handle :: proc() -> Window_Handle {
+win32_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 {
+win32_process_events :: proc() {
 	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)
+win32_get_events :: proc() -> []Window_Event {
+	return s.events[:]
 }
 
-_window_should_close :: proc() -> bool {
-	return s.window_should_close
+win32_clear_events :: proc() {
+	runtime.clear(&s.events)
 }
 
+
 _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
+		append(&s.events, Window_Event_Close_Wanted{})
 
 	case win32.WM_KEYDOWN:
-		key := VK_MAP[wparam]
+		key := WIN32_VK_MAP[wparam]
 		append(&s.events, Window_Event_Key_Went_Down {
 			key = key,
 		})
 
 	case win32.WM_KEYUP:
-		key := VK_MAP[wparam]
+		key := WIN32_VK_MAP[wparam]
 		append(&s.events, Window_Event_Key_Went_Up {
 			key = key,
 		})
@@ -134,7 +136,7 @@ _win32_window_proc :: proc "stdcall" (hwnd: win32.HWND, msg: win32.UINT, wparam:
 	return win32.DefWindowProcW(hwnd, msg, wparam, lparam)
 }
 
-VK_MAP := [255]Keyboard_Key {
+WIN32_VK_MAP := [255]Keyboard_Key {
 	win32.VK_A = .A,
 	win32.VK_B = .B,
 	win32.VK_C = .C,