diff --git a/code/win32_main.cpp b/code/win32_main.cpp index 016c15a..7dc943d 100644 --- a/code/win32_main.cpp +++ b/code/win32_main.cpp @@ -14,225 +14,220 @@ global WINDOWPLACEMENT Global_WindowPosition = {sizeof(Global_WindowPosition)};; static void Win32_PlatformError(char *Message, bool IsFatal) { - MessageBoxA(0, Message, "nv - Platform Error", MB_OK|(IsFatal?MB_ICONSTOP:MB_ICONEXCLAMATION)); - - if(IsFatal) - { - ExitProcess((UINT)-1); - } + MessageBoxA(0, Message, "nv - Platform Error", MB_OK|(IsFatal?MB_ICONSTOP:MB_ICONEXCLAMATION)); + + if(IsFatal) + { + ExitProcess((UINT)-1); + } } static PLATFORM_ALLOCATE_MEMORY(Win32_AllocateMemory) { - win32_state *State = &Global_Win32State; - - umm TotalSize = Size + sizeof(win32_memory_block); - - win32_memory_block *Block = - (win32_memory_block *)VirtualAlloc(0, TotalSize, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); - - Assert(Block); - Block->Block.Base = (u8 *)Block + sizeof(win32_memory_block); - Block->Block.Size = Size; - - win32_memory_block *Sentinel = &State->MemorySentinel; - Block->Next = Sentinel; - - BeginTicketMutex(&State->MemoryMutex); - Block->Prev = Sentinel->Prev; - Block->Prev->Next = Block; - Block->Next->Prev = Block; - EndTicketMutex(&State->MemoryMutex); - - platform_memory_block *Result = &Block->Block; - return(Result); + win32_state *State = &Global_Win32State; + + umm TotalSize = Size + sizeof(win32_memory_block); + + win32_memory_block *Block = + (win32_memory_block *)VirtualAlloc(0, TotalSize, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); + + Assert(Block); + Block->Block.Base = (u8 *)Block + sizeof(win32_memory_block); + Block->Block.Size = Size; + + win32_memory_block *Sentinel = &State->MemorySentinel; + Block->Next = Sentinel; + + BeginTicketMutex(&State->MemoryMutex); + Block->Prev = Sentinel->Prev; + Block->Prev->Next = Block; + Block->Next->Prev = Block; + EndTicketMutex(&State->MemoryMutex); + + platform_memory_block *Result = &Block->Block; + return(Result); } static PLATFORM_DEALLOCATE_MEMORY(Win32_DeallocateMemory) { - win32_state *State = &Global_Win32State; - - win32_memory_block *Win32Block = (win32_memory_block *)Block; - - if(Block) - { - BeginTicketMutex(&State->MemoryMutex); - Win32Block->Prev->Next = Win32Block->Next; - Win32Block->Next->Prev = Win32Block->Prev; - EndTicketMutex(&State->MemoryMutex); - } - - BOOL Result = VirtualFree(Block, 0, MEM_RELEASE); - return(Result); + win32_state *State = &Global_Win32State; + + win32_memory_block *Win32Block = (win32_memory_block *)Block; + + if(Block) + { + BeginTicketMutex(&State->MemoryMutex); + Win32Block->Prev->Next = Win32Block->Next; + Win32Block->Next->Prev = Win32Block->Prev; + EndTicketMutex(&State->MemoryMutex); + } + + BOOL Result = VirtualFree(Block, 0, MEM_RELEASE); + return(Result); } static PLATFORM_OPEN_FILE(Win32_OpenFile) { - DWORD DesiredAccess = 0; - if(FileAccess & PlatformAccess_Read) - { - DesiredAccess |= GENERIC_READ; - } - if(FileAccess & PlatformAccess_Write) - { - DesiredAccess |= GENERIC_WRITE; - } - - DWORD CreationAttributes = 0; - if(FileAccess & PlatformAccess_Read) - { - CreationAttributes = OPEN_EXISTING; - } - - temporary_memory Scratch = GetScratch(0, 0); - - string FullPath = PushFormat(Scratch.Arena, "%S\\%S", Global_Win32State.ContentsPath, Path); - HANDLE File = CreateFileA((char *)FullPath.Data, DesiredAccess, 0, 0, CreationAttributes, 0, 0); - - ReleaseScratch(Scratch); - - platform_file_handle Result = {}; - Result.Platform = (u64)File; - Result.IsValid = (File != INVALID_HANDLE_VALUE); - - return(Result); + DWORD DesiredAccess = 0; + if(FileAccess & PlatformAccess_Read) + { + DesiredAccess |= GENERIC_READ; + } + if(FileAccess & PlatformAccess_Write) + { + DesiredAccess |= GENERIC_WRITE; + } + + DWORD CreationAttributes = 0; + if(FileAccess & PlatformAccess_Read) + { + CreationAttributes = OPEN_EXISTING; + } + + temporary_memory Scratch = GetScratch(0, 0); + + string FullPath = PushFormat(Scratch.Arena, "%S\\%S", Global_Win32State.ContentsPath, Path); + HANDLE File = CreateFileA((char *)FullPath.Data, DesiredAccess, 0, 0, CreationAttributes, 0, 0); + + ReleaseScratch(Scratch); + + platform_file_handle Result = {}; + Result.Platform = (u64)File; + Result.IsValid = (File != INVALID_HANDLE_VALUE); + + return(Result); } static PLATFORM_CLOSE_FILE(Win32_CloseFile) { - HANDLE File = (HANDLE)Handle.Platform; - if(File != INVALID_HANDLE_VALUE) - { - CloseHandle(File); - } + HANDLE File = (HANDLE)Handle.Platform; + if(File != INVALID_HANDLE_VALUE) + { + CloseHandle(File); + } } static PLATFORM_READ_FILE(Win32_ReadFile) { - HANDLE File = (HANDLE)Handle.Platform; - if(File != INVALID_HANDLE_VALUE) - { - DWORD BytesRead; - ReadFile(File, Dest, Size, &BytesRead, 0); - - Assert(BytesRead == Size); - } + HANDLE File = (HANDLE)Handle.Platform; + if(File != INVALID_HANDLE_VALUE) + { + DWORD BytesRead; + ReadFile(File, Dest, Size, &BytesRead, 0); + + Assert(BytesRead == Size); + } } static PLATFORM_GET_FILE_SIZE(Win32_GetFileSize) { - u64 Result = 0; - - HANDLE File = (HANDLE)Handle.Platform; - if(File != INVALID_HANDLE_VALUE) - { - LARGE_INTEGER FileSize; - GetFileSizeEx(File, &FileSize); + u64 Result = 0; - Result = FileSize.QuadPart; - } - - return(Result); + HANDLE File = (HANDLE)Handle.Platform; + if(File != INVALID_HANDLE_VALUE) + { + LARGE_INTEGER FileSize; + GetFileSizeEx(File, &FileSize); + + Result = FileSize.QuadPart; + } + + return(Result); } static PLATFORM_SET_CURSOR(Win32_SetCursor) { - Global_Win32State.Cursor = Cursor; + Global_Win32State.Cursor = Cursor; } inline u64 Win32_GetWallClock(void) { - LARGE_INTEGER Query; - QueryPerformanceCounter(&Query); - - u64 Result = Query.QuadPart; - return(Result); + LARGE_INTEGER Query; + QueryPerformanceCounter(&Query); + + u64 Result = Query.QuadPart; + return(Result); } inline r64 Win32_GetSecondsElapsed(u64 Start, u64 End) { - u64 Elapsed = End - Start; - - r64 Result = (r64)Elapsed/(r64)Global_Win32State.PerformanceFrequency; - return(Result); + u64 Elapsed = End - Start; + + r64 Result = (r64)Elapsed/(r64)Global_Win32State.PerformanceFrequency; + return(Result); } inline FILETIME Win32_GetLastWriteTime(char *Path) { - FILETIME Result = {}; - - HANDLE File = CreateFileA(Path, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); - if(File) - { - FILETIME Creation, LastAccess, LastWrite; - GetFileTime(File, &Creation, &LastAccess, &LastWrite); + FILETIME Result = {}; - Result = LastWrite; + HANDLE File = CreateFileA(Path, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); + if(File) + { + FILETIME Creation, LastAccess, LastWrite; + GetFileTime(File, &Creation, &LastAccess, &LastWrite); + + Result = LastWrite; + + CloseHandle(File); + } - CloseHandle(File); - } - - return(Result); + return(Result); } static win32_loaded_code Win32_LoadCode(void) { - win32_loaded_code Code = {}; - - win32_state *State = &Global_Win32State; - - if(CopyFile(State->DLLPath, State->TempDLLPath, FALSE)) - { - Code.LastWriteTime = Win32_GetLastWriteTime(State->DLLPath); + win32_loaded_code Code = {}; - Code.DLL = LoadLibraryA(State->TempDLLPath); - if(Code.DLL) + win32_state *State = &Global_Win32State; + + if(CopyFile(State->DLLPath, State->TempDLLPath, FALSE)) { - Code.UpdateAndRender = (vn_update_and_render *)GetProcAddress(Code.DLL, "VN_UpdateAndRender"); - if(Code.UpdateAndRender) - { - Code.IsValid = true; - } + Code.LastWriteTime = Win32_GetLastWriteTime(State->DLLPath); + + Code.DLL = LoadLibraryA(State->TempDLLPath); + if(Code.DLL) + { + Code.UpdateAndRender = (vn_update_and_render *)GetProcAddress(Code.DLL, "VN_UpdateAndRender"); + if(Code.UpdateAndRender) + { + Code.IsValid = true; + } + } } - } - - return(Code); + + return(Code); } static void Win32_UnloadCode(win32_loaded_code *Code) { - if(Code->DLL) - { - FreeLibrary(Code->DLL); - } - - *Code = {}; + if(Code->DLL) + { + FreeLibrary(Code->DLL); + } + + *Code = {}; } static void Win32_UpdateCode(win32_loaded_code *Code) { - win32_state *State = &Global_Win32State; - - FILETIME LastWriteTime = Win32_GetLastWriteTime(State->DLLPath); - if(CompareFileTime(&Code->LastWriteTime, &LastWriteTime) != 0) - { - Win32_UnloadCode(Code); - *Code = Win32_LoadCode(); - } + win32_state *State = &Global_Win32State; + + FILETIME LastWriteTime = Win32_GetLastWriteTime(State->DLLPath); + if(CompareFileTime(&Code->LastWriteTime, &LastWriteTime) != 0) + { + Win32_UnloadCode(Code); + *Code = Win32_LoadCode(); + } } static PLATFORM_TOGGLE_FULLSCREEN(Win32_ToggleFullscreen) { - HWND Window = Global_Win32State.Window; - - DWORD Style = GetWindowLong(Window, GWL_STYLE); - if(Style & WS_OVERLAPPEDWINDOW) - { - MONITORINFO MonitorInfo = {sizeof(MonitorInfo)}; - if(GetWindowPlacement(Window, &Global_WindowPosition) && - GetMonitorInfo(MonitorFromWindow(Window, MONITOR_DEFAULTTOPRIMARY), &MonitorInfo)) + HWND Window = Global_Win32State.Window; + + DWORD Style = GetWindowLong(Window, GWL_STYLE); + if(Style & WS_OVERLAPPEDWINDOW) { -<<<<<<< HEAD MONITORINFO MonitorInfo = {sizeof(MonitorInfo)}; if(GetWindowPlacement(Window, &Global_WindowPosition) && GetMonitorInfo(MonitorFromWindow(Window, MONITOR_DEFAULTTOPRIMARY), &MonitorInfo)) @@ -253,472 +248,458 @@ static PLATFORM_TOGGLE_FULLSCREEN(Win32_ToggleFullscreen) SetWindowPlacement(Window, &Global_WindowPosition); SetWindowPos(Window, 0, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_NOOWNERZORDER|SWP_FRAMECHANGED); -======= - SetWindowPos(Window, HWND_TOP, - MonitorInfo.rcMonitor.left, MonitorInfo.rcMonitor.top, - MonitorInfo.rcMonitor.right - MonitorInfo.rcMonitor.left, - MonitorInfo.rcMonitor.bottom - MonitorInfo.rcMonitor.top, - SWP_NOOWNERZORDER | SWP_FRAMECHANGED); ->>>>>>> 376349b92227dcf5369dee77701a9ad8570ab639 } - } - else - { - SetWindowPlacement(Window, &Global_WindowPosition); - SetWindowPos(Window, 0, 0, 0, 0, 0, - SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_NOOWNERZORDER|SWP_FRAMECHANGED); - } } inline v2 Win32_GetMouseP(HWND Window) { - POINT Point; - GetCursorPos(&Point); - ScreenToClient(Window, &Point); - - v2 Result = V2(Point.x, Point.y); - return(Result); + POINT Point; + GetCursorPos(&Point); + ScreenToClient(Window, &Point); + + v2 Result = V2(Point.x, Point.y); + return(Result); } inline v2 Win32_GetWindowDim(HWND Window) { - RECT ClientRect; - GetClientRect(Window, &ClientRect); - - v2 Result = V2(ClientRect.right - ClientRect.left, ClientRect.bottom - ClientRect.top); - return(Result); + RECT ClientRect; + GetClientRect(Window, &ClientRect); + + v2 Result = V2(ClientRect.right - ClientRect.left, ClientRect.bottom - ClientRect.top); + return(Result); } inline platform_modifiers Win32_GetModifiers(void) { - platform_modifiers Modifiers = 0; - - if(GetKeyState(VK_CONTROL) & 0x8000) - { - Modifiers |= PlatformModifier_Ctrl; - } - if(GetKeyState(VK_SHIFT) & 0x8000) - { - Modifiers |= PlatformModifier_Shift; - } - if(GetKeyState(VK_MENU) & 0x8000) - { - Modifiers |= PlatformModifier_Alt; - } - - return(Modifiers); + platform_modifiers Modifiers = 0; + + if(GetKeyState(VK_CONTROL) & 0x8000) + { + Modifiers |= PlatformModifier_Ctrl; + } + if(GetKeyState(VK_SHIFT) & 0x8000) + { + Modifiers |= PlatformModifier_Shift; + } + if(GetKeyState(VK_MENU) & 0x8000) + { + Modifiers |= PlatformModifier_Alt; + } + + return(Modifiers); } static LRESULT Win32_WindowCallback(HWND Window, UINT Message, WPARAM WParam, LPARAM LParam) { - LRESULT Result = 0; - - win32_state *State = &Global_Win32State; - - temporary_memory Scratch = GetScratch(0, 0); - - platform_event *Event = 0; - - b32 ButtonIsUp = false; - axis2 ScrollAxis = Axis2_Y; - - switch(Message) - { - case WM_CLOSE: - { - Global_Running = false; - } break; + LRESULT Result = 0; - case WM_WINDOWPOSCHANGED: - { - // TODO(casey): For now, we are setting the window styles in here - // because sometimes Windows can reposition our window out of fullscreen - // without going through our ToggleFullscreen(), and we want to put our - // title bar and border back when it does! - - WINDOWPOS *NewPos = (WINDOWPOS *)LParam; - - b32 BecomingFullscreen = false; - MONITORINFO MonitorInfo = {sizeof(MonitorInfo)}; - if(GetMonitorInfo(MonitorFromWindow(Window, MONITOR_DEFAULTTOPRIMARY), - &MonitorInfo)) - { - s32 MonWidth = (MonitorInfo.rcMonitor.right - MonitorInfo.rcMonitor.left); - s32 MonHeight = (MonitorInfo.rcMonitor.bottom - MonitorInfo.rcMonitor.top); - BecomingFullscreen = ((MonitorInfo.rcMonitor.left == NewPos->x) && - (MonitorInfo.rcMonitor.top == NewPos->y) && - (MonWidth == NewPos->cx) && - (MonHeight == NewPos->cy)); - } - - DWORD OldStyle = GetWindowLong(Window, GWL_STYLE); - DWORD FullscreenStyle = OldStyle & ~WS_OVERLAPPEDWINDOW; - DWORD WindowedStyle = OldStyle | WS_OVERLAPPEDWINDOW; - DWORD NewStyle = (BecomingFullscreen) ? FullscreenStyle : WindowedStyle; - - if(NewStyle != OldStyle) - { - SetWindowLong(Window, GWL_STYLE, NewStyle); - } - - Result = DefWindowProcA(Window, Message, WParam, LParam); - } break; + win32_state *State = &Global_Win32State; - case WM_MOUSEHWHEEL: - { - ScrollAxis = Axis2_X; - } fallthrough; - case WM_MOUSEWHEEL: - { - Event = PushStruct(&State->EventArena, platform_event); - Event->Type = PlatformEvent_MouseScroll; - Event->Scroll.E[ScrollAxis] = GET_WHEEL_DELTA_WPARAM(WParam) / 120.0; - } break; + temporary_memory Scratch = GetScratch(0, 0); - case WM_LBUTTONUP: - case WM_MBUTTONUP: - case WM_RBUTTONUP: - { - ButtonIsUp = true; - } fallthrough; + platform_event *Event = 0; - case WM_LBUTTONDOWN: - case WM_MBUTTONDOWN: - case WM_RBUTTONDOWN: - { - platform_event_type Type = ButtonIsUp ? PlatformEvent_Release : PlatformEvent_Press; - - platform_key Key = Key_Invalid; - switch(Message) - { - case WM_LBUTTONUP: case WM_LBUTTONDOWN: { Key = Key_MouseLeft; } break; - case WM_MBUTTONUP: case WM_MBUTTONDOWN: { Key = Key_MouseMiddle; } break; - case WM_RBUTTONUP: case WM_RBUTTONDOWN: { Key = Key_MouseRight; } break; - } - - Event = PushStruct(&State->EventArena, platform_event); - Event->Type = Type; - Event->Key = Key; - Event->P = Win32_GetMouseP(Window); - } break; + b32 ButtonIsUp = false; + axis2 ScrollAxis = Axis2_Y; - case WM_SYSKEYUP: - case WM_KEYUP: + switch(Message) { - ButtonIsUp = true; - } fallthrough; - case WM_SYSKEYDOWN: - case WM_KEYDOWN: - { - platform_event_type Type = ButtonIsUp ? PlatformEvent_Release : PlatformEvent_Press; - - u32 VKCode = (u32)WParam; - platform_key Key = Key_Invalid; - - if(VKCode >= 'A' && VKCode <= 'Z') - { - Key = (platform_key)(Key_A + (VKCode - 'A')); - } - else if(VKCode >= VK_F1 && VKCode <= VK_F12) - { - Key = (platform_key)(Key_F1 + (VKCode - VK_F1)); - } - else if(VKCode == VK_LEFT) { Key = Key_Left; } - else if(VKCode == VK_RIGHT) { Key = Key_Right; } - else if(VKCode == VK_UP) { Key = Key_Up; } - else if(VKCode == VK_DOWN) { Key = Key_Down; } - else if(VKCode == VK_SPACE) { Key = Key_Space; } - else if(VKCode == VK_PRIOR) { Key = Key_PageUp; } - else if(VKCode == VK_NEXT) { Key = Key_PageDown; } - else if(VKCode == VK_HOME) { Key = Key_Home; } - else if(VKCode == VK_END) { Key = Key_End; } - else if(VKCode == VK_BACK) { Key = Key_Backspace; } - else if(VKCode == VK_DELETE) { Key = Key_Delete; } - - if(Key != Key_Invalid) - { - Event = PushStruct(&State->EventArena, platform_event); - Event->Type = Type; - Event->Key = Key; - } - - if(!ButtonIsUp && (VKCode == VK_RETURN) && (LParam & (1 << 29))) - { - Win32_ToggleFullscreen(); - } - else - { - Result = DefWindowProc(Window, Message, WParam, LParam); - } - - } break; - - case WM_CHAR: - { - u32 Codepoint = (u32)WParam; - if(Codepoint == '\r') - { - Codepoint = '\n'; - } - - if((Codepoint >= 32 && Codepoint != 127) || Codepoint == '\t' || Codepoint == '\n') - { - Event = PushStruct(&State->EventArena, platform_event); - Event->Type = PlatformEvent_Text; - Event->Codepoint = Codepoint; - } - } break; - - case WM_SETCURSOR: - { - range2_r32 WindowRect = {}; - WindowRect.Max = Win32_GetWindowDim(Window); - if(InRange(WindowRect, Win32_GetMouseP(Window))) - { - persist HCURSOR CursorTable[PlatformCursor_Count]; - persist b32 CursorTableLoaded = false; - if(!CursorTableLoaded) + case WM_CLOSE: { - CursorTable[PlatformCursor_Arrow] = LoadCursor(0, IDC_ARROW); - CursorTable[PlatformCursor_Cross] = LoadCursor(0, IDC_CROSS); - CursorTable[PlatformCursor_Hand] = LoadCursor(0, IDC_HAND); - CursorTable[PlatformCursor_Help] = LoadCursor(0, IDC_HELP); - CursorTable[PlatformCursor_IBeam] = LoadCursor(0, IDC_IBEAM); - CursorTable[PlatformCursor_SlashedCircle] = LoadCursor(0, IDC_NO); - CursorTable[PlatformCursor_ArrowAll] = LoadCursor(0, IDC_SIZEALL); - CursorTable[PlatformCursor_ArrowNESW] = LoadCursor(0, IDC_SIZENESW); - CursorTable[PlatformCursor_ArrowVertical] = LoadCursor(0, IDC_SIZENS); - CursorTable[PlatformCursor_ArrowNWSE] = LoadCursor(0, IDC_SIZENWSE); - CursorTable[PlatformCursor_ArrowHorizontal] = LoadCursor(0, IDC_SIZEWE); - CursorTable[PlatformCursor_Wait] = LoadCursor(0, IDC_WAIT); - - CursorTableLoaded = true; - } + Global_Running = false; + } break; - SetCursor(CursorTable[Global_Win32State.Cursor]); - } - else - { - DefWindowProc(Window, Message, WParam, LParam); - } - } break; + case WM_WINDOWPOSCHANGED: + { + // TODO(casey): For now, we are setting the window styles in here + // because sometimes Windows can reposition our window out of fullscreen + // without going through our ToggleFullscreen(), and we want to put our + // title bar and border back when it does! + + WINDOWPOS *NewPos = (WINDOWPOS *)LParam; + + b32 BecomingFullscreen = false; + MONITORINFO MonitorInfo = {sizeof(MonitorInfo)}; + if(GetMonitorInfo(MonitorFromWindow(Window, MONITOR_DEFAULTTOPRIMARY), + &MonitorInfo)) + { + s32 MonWidth = (MonitorInfo.rcMonitor.right - MonitorInfo.rcMonitor.left); + s32 MonHeight = (MonitorInfo.rcMonitor.bottom - MonitorInfo.rcMonitor.top); + BecomingFullscreen = ((MonitorInfo.rcMonitor.left == NewPos->x) && + (MonitorInfo.rcMonitor.top == NewPos->y) && + (MonWidth == NewPos->cx) && + (MonHeight == NewPos->cy)); + } + + DWORD OldStyle = GetWindowLong(Window, GWL_STYLE); + DWORD FullscreenStyle = OldStyle & ~WS_OVERLAPPEDWINDOW; + DWORD WindowedStyle = OldStyle | WS_OVERLAPPEDWINDOW; + DWORD NewStyle = (BecomingFullscreen) ? FullscreenStyle : WindowedStyle; + + if(NewStyle != OldStyle) + { + SetWindowLong(Window, GWL_STYLE, NewStyle); + } + + Result = DefWindowProcA(Window, Message, WParam, LParam); + } break; + + case WM_MOUSEHWHEEL: + { + ScrollAxis = Axis2_X; + } fallthrough; + case WM_MOUSEWHEEL: + { + Event = PushStruct(&State->EventArena, platform_event); + Event->Type = PlatformEvent_MouseScroll; + Event->Scroll.E[ScrollAxis] = GET_WHEEL_DELTA_WPARAM(WParam) / 120.0; + } break; + + case WM_LBUTTONUP: + case WM_MBUTTONUP: + case WM_RBUTTONUP: + { + ButtonIsUp = true; + } fallthrough; + + case WM_LBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_RBUTTONDOWN: + { + platform_event_type Type = ButtonIsUp ? PlatformEvent_Release : PlatformEvent_Press; + + platform_key Key = Key_Invalid; + switch(Message) + { + case WM_LBUTTONUP: case WM_LBUTTONDOWN: { Key = Key_MouseLeft; } break; + case WM_MBUTTONUP: case WM_MBUTTONDOWN: { Key = Key_MouseMiddle; } break; + case WM_RBUTTONUP: case WM_RBUTTONDOWN: { Key = Key_MouseRight; } break; + } + + Event = PushStruct(&State->EventArena, platform_event); + Event->Type = Type; + Event->Key = Key; + Event->P = Win32_GetMouseP(Window); + } break; + + case WM_SYSKEYUP: + case WM_KEYUP: + { + ButtonIsUp = true; + } fallthrough; + case WM_SYSKEYDOWN: + case WM_KEYDOWN: + { + platform_event_type Type = ButtonIsUp ? PlatformEvent_Release : PlatformEvent_Press; + + u32 VKCode = (u32)WParam; + platform_key Key = Key_Invalid; + + if(VKCode >= 'A' && VKCode <= 'Z') + { + Key = (platform_key)(Key_A + (VKCode - 'A')); + } + else if(VKCode >= VK_F1 && VKCode <= VK_F12) + { + Key = (platform_key)(Key_F1 + (VKCode - VK_F1)); + } + else if(VKCode == VK_LEFT) { Key = Key_Left; } + else if(VKCode == VK_RIGHT) { Key = Key_Right; } + else if(VKCode == VK_UP) { Key = Key_Up; } + else if(VKCode == VK_DOWN) { Key = Key_Down; } + else if(VKCode == VK_SPACE) { Key = Key_Space; } + else if(VKCode == VK_PRIOR) { Key = Key_PageUp; } + else if(VKCode == VK_NEXT) { Key = Key_PageDown; } + else if(VKCode == VK_HOME) { Key = Key_Home; } + else if(VKCode == VK_END) { Key = Key_End; } + else if(VKCode == VK_BACK) { Key = Key_Backspace; } + else if(VKCode == VK_DELETE) { Key = Key_Delete; } + + if(Key != Key_Invalid) + { + Event = PushStruct(&State->EventArena, platform_event); + Event->Type = Type; + Event->Key = Key; + } + + if(!ButtonIsUp && (VKCode == VK_RETURN) && (LParam & (1 << 29))) + { + Win32_ToggleFullscreen(); + } + else + { + Result = DefWindowProc(Window, Message, WParam, LParam); + } + + } break; + + case WM_CHAR: + { + u32 Codepoint = (u32)WParam; + if(Codepoint == '\r') + { + Codepoint = '\n'; + } + + if((Codepoint >= 32 && Codepoint != 127) || Codepoint == '\t' || Codepoint == '\n') + { + Event = PushStruct(&State->EventArena, platform_event); + Event->Type = PlatformEvent_Text; + Event->Codepoint = Codepoint; + } + } break; + + case WM_SETCURSOR: + { + range2_r32 WindowRect = {}; + WindowRect.Max = Win32_GetWindowDim(Window); + if(InRange(WindowRect, Win32_GetMouseP(Window))) + { + persist HCURSOR CursorTable[PlatformCursor_Count]; + persist b32 CursorTableLoaded = false; + if(!CursorTableLoaded) + { + CursorTable[PlatformCursor_Arrow] = LoadCursor(0, IDC_ARROW); + CursorTable[PlatformCursor_Cross] = LoadCursor(0, IDC_CROSS); + CursorTable[PlatformCursor_Hand] = LoadCursor(0, IDC_HAND); + CursorTable[PlatformCursor_Help] = LoadCursor(0, IDC_HELP); + CursorTable[PlatformCursor_IBeam] = LoadCursor(0, IDC_IBEAM); + CursorTable[PlatformCursor_SlashedCircle] = LoadCursor(0, IDC_NO); + CursorTable[PlatformCursor_ArrowAll] = LoadCursor(0, IDC_SIZEALL); + CursorTable[PlatformCursor_ArrowNESW] = LoadCursor(0, IDC_SIZENESW); + CursorTable[PlatformCursor_ArrowVertical] = LoadCursor(0, IDC_SIZENS); + CursorTable[PlatformCursor_ArrowNWSE] = LoadCursor(0, IDC_SIZENWSE); + CursorTable[PlatformCursor_ArrowHorizontal] = LoadCursor(0, IDC_SIZEWE); + CursorTable[PlatformCursor_Wait] = LoadCursor(0, IDC_WAIT); + + CursorTableLoaded = true; + } + + SetCursor(CursorTable[Global_Win32State.Cursor]); + } + else + { + DefWindowProc(Window, Message, WParam, LParam); + } + } break; + + default: + { + Result = DefWindowProc(Window, Message, WParam, LParam); + } break; + } - default: + if(Event) { - Result = DefWindowProc(Window, Message, WParam, LParam); - } break; - } - - if(Event) - { - Event->Modifiers = Win32_GetModifiers(); - DLLInsertLast(State->EventList.First, State->EventList.Last, Event); - } - - ReleaseScratch(Scratch); - - return(Result); + Event->Modifiers = Win32_GetModifiers(); + DLLInsertLast(State->EventList.First, State->EventList.Last, Event); + } + + ReleaseScratch(Scratch); + + return(Result); } static void Win32_ProcessInput(vn_input *Input, HWND Window, r32 dtForFrame) { - win32_state *State = &Global_Win32State; - - { - if(State->EventArenaTemp.Arena) + win32_state *State = &Global_Win32State; + { - EndTemporaryMemory(State->EventArenaTemp); + if(State->EventArenaTemp.Arena) + { + EndTemporaryMemory(State->EventArenaTemp); + } + + State->EventArenaTemp = BeginTemporaryMemory(&State->EventArena); } - State->EventArenaTemp = BeginTemporaryMemory(&State->EventArena); - } - - MSG Message; - while(PeekMessage(&Message, Window, 0, 0, PM_REMOVE)) - { - TranslateMessage(&Message); - DispatchMessageA(&Message); - } - - Input->EventList = &State->EventList; - - v2 NewMouseP = Win32_GetMouseP(Window); - v2 OldMouseP = Input->MouseP; - - Input->dMouseP = NewMouseP - OldMouseP; - Input->MouseP = NewMouseP; - - Input->dtForFrame = dtForFrame; + MSG Message; + while(PeekMessage(&Message, Window, 0, 0, PM_REMOVE)) + { + TranslateMessage(&Message); + DispatchMessageA(&Message); + } + + Input->EventList = &State->EventList; + + v2 NewMouseP = Win32_GetMouseP(Window); + v2 OldMouseP = Input->MouseP; + + Input->dMouseP = NewMouseP - OldMouseP; + Input->MouseP = NewMouseP; + + Input->dtForFrame = dtForFrame; } static void Win32_EnforceFrameRate(u64 FrameBegin, r32 TargetFrameRate) { - win32_state *State = &Global_Win32State; - - r64 TimeElapsed = Win32_GetSecondsElapsed(FrameBegin, Win32_GetWallClock()); - r64 Target = 1.0 / TargetFrameRate; - - r64 ToSleep = Target - TimeElapsed; - if(ToSleep > 0) - { - u64 MSToSleep = (u64)Floor(ToSleep*1000); - if(State->SleepIsGranular) - { - Sleep(MSToSleep); - } + win32_state *State = &Global_Win32State; - while(ToSleep > 0) + r64 TimeElapsed = Win32_GetSecondsElapsed(FrameBegin, Win32_GetWallClock()); + r64 Target = 1.0 / TargetFrameRate; + + r64 ToSleep = Target - TimeElapsed; + if(ToSleep > 0) { - TimeElapsed = Win32_GetSecondsElapsed(FrameBegin, Win32_GetWallClock()); - ToSleep = Target - TimeElapsed; + u64 MSToSleep = (u64)Floor(ToSleep*1000); + if(State->SleepIsGranular) + { + Sleep(MSToSleep); + } + + while(ToSleep > 0) + { + TimeElapsed = Win32_GetSecondsElapsed(FrameBegin, Win32_GetWallClock()); + ToSleep = Target - TimeElapsed; + } } - } } inline void Win32_GetRelevantPaths(win32_state *State) { - GetModuleFileName(0, State->EXEPath, ArrayCount(State->EXEPath)); - if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) - { - Win32_PlatformError("Path to executable is too long. Try running the game from another directory", true); - } - - string EXEPathString = MakeStringFromCString(State->EXEPath); - - s64 OnePastLastSlash = LastIndexOf(EXEPathString, '\\') + 1; - s64 BuildIndex = LastIndexOf(EXEPathString, StrLit("build")); - - if(BuildIndex == -1) - { - State->ContentsPath = MakeString((char *)EXEPathString.Data, OnePastLastSlash); - } - else - { - State->ContentsPath = MakeString((char *)EXEPathString.Data, BuildIndex); - } - - string DLLName = StrLit("vn.dll"); - Copy(State->DLLPath, State->EXEPath, OnePastLastSlash); - Copy(State->DLLPath+OnePastLastSlash, DLLName.Data, DLLName.Count); - - string TempDLLName = StrLit("temp_vn.dll"); - Copy(State->TempDLLPath, State->EXEPath, OnePastLastSlash); - Copy(State->TempDLLPath+OnePastLastSlash, TempDLLName.Data, TempDLLName.Count); + GetModuleFileName(0, State->EXEPath, ArrayCount(State->EXEPath)); + if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + Win32_PlatformError("Path to executable is too long. Try running the game from another directory", true); + } + + string EXEPathString = MakeStringFromCString(State->EXEPath); + + s64 OnePastLastSlash = LastIndexOf(EXEPathString, '\\') + 1; + s64 BuildIndex = LastIndexOf(EXEPathString, StrLit("build")); + + if(BuildIndex == -1) + { + State->ContentsPath = MakeString((char *)EXEPathString.Data, OnePastLastSlash); + } + else + { + State->ContentsPath = MakeString((char *)EXEPathString.Data, BuildIndex); + } + + string DLLName = StrLit("vn.dll"); + Copy(State->DLLPath, State->EXEPath, OnePastLastSlash); + Copy(State->DLLPath+OnePastLastSlash, DLLName.Data, DLLName.Count); + + string TempDLLName = StrLit("temp_vn.dll"); + Copy(State->TempDLLPath, State->EXEPath, OnePastLastSlash); + Copy(State->TempDLLPath+OnePastLastSlash, TempDLLName.Data, TempDLLName.Count); } int WinMain(HINSTANCE Instance, HINSTANCE PreviousInstance, LPSTR CommandLine, int ShowCommand) { - thread_context ThreadContext = {}; - SetThreadContext(&ThreadContext); - - // sixten: Setup Win32 platform state. - { - win32_state *State = &Global_Win32State; - Win32_GetRelevantPaths(State); + thread_context ThreadContext = {}; + SetThreadContext(&ThreadContext); - LARGE_INTEGER FrequencyQuery; - QueryPerformanceFrequency(&FrequencyQuery); - State->PerformanceFrequency = FrequencyQuery.QuadPart; - - State->MemorySentinel.Next = &State->MemorySentinel; - State->MemorySentinel.Prev = &State->MemorySentinel; - - State->SleepIsGranular = (timeBeginPeriod(1) != TIMERR_NOERROR); - } - - // sixten: Setup platform layer - { - Platform.AllocateMemory = Win32_AllocateMemory; - Platform.DeallocateMemory = Win32_DeallocateMemory; - Platform.OpenFile = Win32_OpenFile; - Platform.CloseFile = Win32_CloseFile; - Platform.ReadFile = Win32_ReadFile; - Platform.GetFileSize = Win32_GetFileSize; - Platform.SetCursor = Win32_SetCursor; - Platform.ToggleFullscreen = Win32_ToggleFullscreen; - } - - WNDCLASS WindowClass = {}; - WindowClass.lpszClassName = "vn-window-class"; - WindowClass.lpfnWndProc = Win32_WindowCallback; - WindowClass.hCursor = LoadCursorA(0, IDC_ARROW); - WindowClass.style = CS_OWNDC; - - if(RegisterClassA(&WindowClass)) - { - HWND Window = CreateWindowEx(0, - WindowClass.lpszClassName, - "vn - June 2023 Build", - WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT, CW_USEDEFAULT, - CW_USEDEFAULT, CW_USEDEFAULT, - 0, 0, Instance, 0); - if(Window) + // sixten: Setup Win32 platform state. { - Global_Win32State.Window = Window; - - vn_input Input = {}; - - // sixten: Setup OpenGL - vn_render_commands RenderCommands = {}; - HDC DeviceContext = GetDC(Window); - Win32_CreateOpenGLContext(DeviceContext); - opengl_context OpenGLContext = OpenGL_SetupContext(&RenderCommands, 16*1024); - - vn_memory Memory = {}; - Memory.PlatformAPI = Platform; - - win32_loaded_code LoadedCode = Win32_LoadCode(); - - ShowWindow(Window, SW_SHOWNORMAL); - - u64 CurrentTime = Win32_GetWallClock(); - - Global_Running = true; - while(Global_Running) - { - u64 NewTime = Win32_GetWallClock(); - r64 dtForFrame = Win32_GetSecondsElapsed(CurrentTime, NewTime); - CurrentTime = NewTime; + win32_state *State = &Global_Win32State; + Win32_GetRelevantPaths(State); - Win32_ProcessInput(&Input, Window, dtForFrame); + LARGE_INTEGER FrequencyQuery; + QueryPerformanceFrequency(&FrequencyQuery); + State->PerformanceFrequency = FrequencyQuery.QuadPart; - Win32_SetCursor(PlatformCursor_Arrow); + State->MemorySentinel.Next = &State->MemorySentinel; + State->MemorySentinel.Prev = &State->MemorySentinel; - // sixten: Update and render frame. + State->SleepIsGranular = (timeBeginPeriod(1) != TIMERR_NOERROR); + } + + // sixten: Setup platform layer + { + Platform.AllocateMemory = Win32_AllocateMemory; + Platform.DeallocateMemory = Win32_DeallocateMemory; + Platform.OpenFile = Win32_OpenFile; + Platform.CloseFile = Win32_CloseFile; + Platform.ReadFile = Win32_ReadFile; + Platform.GetFileSize = Win32_GetFileSize; + Platform.SetCursor = Win32_SetCursor; + Platform.ToggleFullscreen = Win32_ToggleFullscreen; + } + + WNDCLASS WindowClass = {}; + WindowClass.lpszClassName = "vn-window-class"; + WindowClass.lpfnWndProc = Win32_WindowCallback; + WindowClass.hCursor = LoadCursorA(0, IDC_ARROW); + WindowClass.style = CS_OWNDC; + + if(RegisterClassA(&WindowClass)) + { + HWND Window = CreateWindowEx(0, + WindowClass.lpszClassName, + "vn - June 2023 Build", + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, CW_USEDEFAULT, + 0, 0, Instance, 0); + if(Window) { - Win32_UpdateCode(&LoadedCode); - - OpenGL_BeginFrame(&RenderCommands, Win32_GetWindowDim(Window)); - - if(LoadedCode.IsValid) - { - LoadedCode.UpdateAndRender(&ThreadContext, &Memory, &Input, &RenderCommands); - } - - b32 UseVSync = (Input.RefreshRate == 0); - wglSwapIntervalEXT(UseVSync); - - OpenGL_EndFrame(&OpenGLContext, &RenderCommands); - wglSwapLayerBuffers(DeviceContext, WGL_SWAP_MAIN_PLANE); + Global_Win32State.Window = Window; + + vn_input Input = {}; + + // sixten: Setup OpenGL + vn_render_commands RenderCommands = {}; + HDC DeviceContext = GetDC(Window); + Win32_CreateOpenGLContext(DeviceContext); + opengl_context OpenGLContext = OpenGL_SetupContext(&RenderCommands, 16*1024); + + vn_memory Memory = {}; + Memory.PlatformAPI = Platform; + + win32_loaded_code LoadedCode = Win32_LoadCode(); + + ShowWindow(Window, SW_SHOWNORMAL); + + u64 CurrentTime = Win32_GetWallClock(); + + Global_Running = true; + while(Global_Running) + { + u64 NewTime = Win32_GetWallClock(); + r64 dtForFrame = Win32_GetSecondsElapsed(CurrentTime, NewTime); + CurrentTime = NewTime; + + Win32_ProcessInput(&Input, Window, dtForFrame); + + Win32_SetCursor(PlatformCursor_Arrow); + + // sixten: Update and render frame. + { + Win32_UpdateCode(&LoadedCode); + + OpenGL_BeginFrame(&RenderCommands, Win32_GetWindowDim(Window)); + + if(LoadedCode.IsValid) + { + LoadedCode.UpdateAndRender(&ThreadContext, &Memory, &Input, &RenderCommands); + } + + b32 UseVSync = (Input.RefreshRate == 0); + wglSwapIntervalEXT(UseVSync); + + OpenGL_EndFrame(&OpenGLContext, &RenderCommands); + wglSwapLayerBuffers(DeviceContext, WGL_SWAP_MAIN_PLANE); + } + + b32 ShouldLimitFrameRate = (Input.RefreshRate > 0); + if(ShouldLimitFrameRate) + { + Win32_EnforceFrameRate(CurrentTime, Input.RefreshRate); + } + } } - - b32 ShouldLimitFrameRate = (Input.RefreshRate > 0); - if(ShouldLimitFrameRate) + else { - Win32_EnforceFrameRate(CurrentTime, Input.RefreshRate); + Win32_PlatformError("Unable to create window.", true); } - } } else { - Win32_PlatformError("Unable to create window.", true); + Win32_PlatformError("Unable to register window class.", true); } - } - else - { - Win32_PlatformError("Unable to register window class.", true); - } - - return(0); + + return(0); } \ No newline at end of file