main_w32.c (4060B)
1 /* See LICENSE for license details. */ 2 #include "compiler.h" 3 4 #if !OS_WINDOWS 5 #error This file is only meant to be compiled for Win32 6 #endif 7 8 #include "beamformer.h" 9 10 #include "os_win32.c" 11 12 #define OS_DEBUG_LIB_NAME ".\\beamformer.dll" 13 #define OS_DEBUG_LIB_TEMP_NAME ".\\beamformer_temp.dll" 14 15 #define OS_CUDA_LIB_NAME "external\\cuda_toolkit.dll" 16 #define OS_CUDA_LIB_TEMP_NAME "external\\cuda_toolkit_temp.dll" 17 18 #define OS_RENDERDOC_SONAME "renderdoc.dll" 19 20 iptr glfwGetWGLContext(iptr); 21 function iptr 22 os_get_native_gl_context(iptr window) 23 { 24 return glfwGetWGLContext(window); 25 } 26 27 function iptr 28 os_gl_proc_address(char *name) 29 { 30 return wglGetProcAddress(name); 31 } 32 33 #include "static.c" 34 35 function void 36 dispatch_file_watch(OS *os, FileWatchDirectory *fw_dir, u8 *buf, Arena arena) 37 { 38 i64 offset = 0; 39 TempArena save_point = {0}; 40 w32_file_notify_info *fni = (w32_file_notify_info *)buf; 41 do { 42 end_temp_arena(save_point); 43 save_point = begin_temp_arena(&arena); 44 45 Stream path = {.data = arena_commit(&arena, KB(1)), .cap = KB(1)}; 46 47 if (fni->action != FILE_ACTION_MODIFIED) { 48 stream_append_s8(&path, s8("unknown file watch event: ")); 49 stream_append_u64(&path, fni->action); 50 stream_append_byte(&path, '\n'); 51 os->write_file(os->error_handle, stream_to_s8(&path)); 52 stream_reset(&path, 0); 53 } 54 55 stream_append_s8(&path, fw_dir->name); 56 stream_append_byte(&path, '\\'); 57 58 s8 file_name = s16_to_s8(&arena, (s16){.data = fni->filename, 59 .len = fni->filename_size / 2}); 60 stream_append_s8(&path, file_name); 61 stream_append_byte(&path, 0); 62 stream_commit(&path, -1); 63 64 u64 hash = s8_hash(file_name); 65 for (u32 i = 0; i < fw_dir->count; i++) { 66 FileWatch *fw = fw_dir->data + i; 67 if (fw->hash == hash) { 68 fw->callback(os, stream_to_s8(&path), fw->user_data, arena); 69 break; 70 } 71 } 72 73 offset = fni->next_entry_offset; 74 fni = (w32_file_notify_info *)((u8 *)fni + offset); 75 } while (offset); 76 } 77 78 function void 79 clear_io_queue(OS *os, BeamformerInput *input, Arena arena) 80 { 81 os_w32_context *ctx = (os_w32_context *)os->context; 82 83 iptr handle = ctx->io_completion_handle; 84 w32_overlapped *overlapped; 85 u32 bytes_read; 86 uptr user_data; 87 while (GetQueuedCompletionStatus(handle, &bytes_read, &user_data, &overlapped, 0)) { 88 w32_io_completion_event *event = (w32_io_completion_event *)user_data; 89 switch (event->tag) { 90 case W32_IO_FILE_WATCH: { 91 FileWatchDirectory *dir = (FileWatchDirectory *)event->context; 92 dispatch_file_watch(os, dir, dir->buffer.beg, arena); 93 zero_struct(overlapped); 94 ReadDirectoryChangesW(dir->handle, dir->buffer.beg, 4096, 0, 95 FILE_NOTIFY_CHANGE_LAST_WRITE, 0, overlapped, 0); 96 } break; 97 case W32_IO_PIPE: break; 98 } 99 } 100 } 101 102 extern i32 103 main(void) 104 { 105 BeamformerCtx ctx = {0}; 106 BeamformerInput input = {.executable_reloaded = 1}; 107 Arena temp_memory = os_alloc_arena(MB(16)); 108 ctx.error_stream = stream_alloc(&temp_memory, MB(1)); 109 110 ctx.ui_backing_store = sub_arena(&temp_memory, MB(2), KB(4)); 111 ctx.os.compute_worker.arena = sub_arena(&temp_memory, MB(2), KB(4)); 112 113 #define X(name) ctx.os.name = os_ ## name; 114 OS_FNS 115 #undef X 116 117 os_w32_context w32_ctx = {0}; 118 w32_ctx.io_completion_handle = CreateIoCompletionPort(INVALID_FILE, 0, 0, 0); 119 w32_ctx.timer_frequency = os_get_timer_frequency(); 120 121 ctx.os.context = (iptr)&w32_ctx; 122 ctx.os.compute_worker.asleep = 1; 123 ctx.os.error_handle = GetStdHandle(STD_ERROR_HANDLE); 124 125 setup_beamformer(&ctx, &input, &temp_memory); 126 os_wake_waiters(&ctx.os.compute_worker.sync_variable); 127 128 u64 last_time = os_get_timer_counter(); 129 while (!ctx.should_exit) { 130 clear_io_queue(&ctx.os, &input, temp_memory); 131 132 u64 now = os_get_timer_counter(); 133 input.last_mouse = input.mouse; 134 input.mouse.rl = GetMousePosition(); 135 input.dt = (f64)(now - last_time) / w32_ctx.timer_frequency; 136 last_time = now; 137 138 beamformer_frame_step(&ctx, &temp_memory, &input); 139 140 input.executable_reloaded = 0; 141 } 142 143 beamformer_invalidate_shared_memory(&ctx); 144 }