internal void #if COMPILER_GCC || COMPILER_CLANG win32_logf(const char *fmt, ...) PRINTF_FORMAT #elif COMPILER_MSVC win32_logf(_Printf_format_string_ const char *fmt, ...) #endif { char buffer[4096]; va_list args; va_start(args, fmt); int len = vsnprintf(buffer, sizeof(buffer), fmt, args); va_end(args); if (len < 0) return; if ((u64)len >= sizeof(buffer)) len = sizeof(buffer) - 1; HANDLE handle_stdout = GetStdHandle(STD_OUTPUT_HANDLE); DWORD written = 0; WriteConsoleA(handle_stdout, buffer, (DWORD)len, &written, NULL); } internal void win32_log(String8List messages) { HANDLE handle_stdout = GetStdHandle(STD_OUTPUT_HANDLE); u64 count = 0; for(String8Node *node = messages.first; count < messages.count; node = node->next) { DWORD written = 0; WriteConsoleA(handle_stdout, node->value.data, (DWORD)(node->value.size), &written, NULL); ++count; } } // exit win32 // returns a boolean. i don't know what to do with the boolean if it fails hahahahhaa // not like you can exit hahahahaha0 internal b32 win32_os_exit() { ExitProcess(0); return true; } internal u64 safe_truncate_64(u64 value) { if(value <= (u64)~0) { return 0; // TODO: this needs to be an assert. removed it for now to fix the include issues. } return (u64)value; } internal b32 win32_file_exists(u8 *path) { DWORD attributes = GetFileAttributesA((LPCSTR)path); return ((attributes != INVALID_FILE_ATTRIBUTES) && !(attributes & FILE_ATTRIBUTE_DIRECTORY)); } internal b32 win32_file_write(String8 data, String8 path) { b32 result = false; HANDLE file_handle = CreateFileA((LPCSTR)path.data, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0); if(file_handle != INVALID_HANDLE_VALUE) { DWORD bytes_written; if(WriteFile(file_handle, data.data, (DWORD)data.size, &bytes_written, 0)) { result = (bytes_written == data.size); } else { Log("Writing the file was unsuccessful"); } CloseHandle(file_handle); } else { Log("File handle has the INVALID_HANDLE_VALUE flag."); } return result; } internal String8 win32_file_load(MemArena *arena, u8 *file) { String8 result = {0}; HANDLE file_handle = CreateFileA((LPCSTR)file, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); if(file_handle != INVALID_HANDLE_VALUE) // success { LARGE_INTEGER size; if(GetFileSizeEx(file_handle, &size)) { u32 file_size32 = (u32)safe_truncate_64(size.QuadPart); result = PushString8(arena, file_size32); if(result.data) { DWORD bytes_read; if(ReadFile(file_handle, result.data, file_size32, &bytes_read, 0) && (file_size32 == bytes_read)) { result.size = file_size32; CloseHandle(file_handle); } else { Log("Failed to read file"); if(result.data) VirtualFree(result.data, 0, MEM_RELEASE); // // TODO: Luca says in his code result.data = 0; but doesn't he mean the size. seeing that // we just freed that memory? Or is he zeroing the memory? we don't have access to it any more // so i don't see the point? // TODO: also why aren't we using memory arenas in this case and just doing a new allocation/ // // result.Data = 0; result.size = 0; } } else { Log("received data is NULL"); } } else { Log("received data is of size 0"); } } else { Log("received invalid handle"); } return result; } internal void * win32_load_library() { // TODO: ... } internal void win32_library_get_proc() { // TODO: ... } internal LRESULT CALLBACK win32_window_proc(HWND handle, UINT messages, WPARAM wparam, LPARAM lparam) { switch(messages) { case WM_DESTROY: Win32Running = false; break; case WM_PAINT: break; case WM_SYSKEYDOWN: case WM_SYSKEYUP: case WM_KEYDOWN: case WM_KEYUP: { win32_handle_keyboard_input(); // NOTE: I don't want to inline this because i want this to act a little more platform agnostic and be able to insert any type of keyboard handling directly } break; } return DefWindowProcA(handle, messages, wparam, lparam); } internal HWND win32_create_window(HINSTANCE instance, int height, int width, int display_x, int display_y, const char *window_name) { WNDCLASS window_class = {0}; // TODO(nasr): check if CS_OWNDC CS_HREDRAW CS_VEREDRAW still matter window_class.style = CS_OWNDC|CS_HREDRAW|CS_VREDRAW; window_class.lpfnWndProc = win32_window_proc; window_class.hInstance = instance; window_class.lpszClassName = window_name; HWND window_handle = {}; if(RegisterClass(&window_class)) { window_handle = CreateWindowEx(0, window_class.lpszClassName, window_name, WS_OVERLAPPEDWINDOW | WS_VISIBLE, height, width, display_x, display_y, 0, 0, instance, 0); } Assert(window_handle); ShowWindow(window_handle, true); return window_handle; } internal void win32_run() { MSG message = { }; while(Win32Running) { b32 result = GetMessage(&message, 0, 0, 0); if(result > 0) { TranslateMessage(&message); DispatchMessage(&message); } else { break; } } // cleanup get's handled by the OS, so there is no need worry about that }