diff --git a/gs_libs/gs_win32.cpp b/gs_libs/gs_win32.cpp index 57b4680..1a3fa09 100644 --- a/gs_libs/gs_win32.cpp +++ b/gs_libs/gs_win32.cpp @@ -70,31 +70,6 @@ internal PLATFORM_ALLOC(Win32Alloc); internal PLATFORM_FREE(Win32Free); internal PLATFORM_REALLOC(Win32Realloc); -// File IO -internal PLATFORM_READ_ENTIRE_FILE(Win32ReadEntireFile); -internal PLATFORM_WRITE_ENTIRE_FILE(Win32WriteEntireFile); -internal FILETIME Win32GetFileLastWriteTime; - -// DLL -struct win32_dll_refresh -{ - FILETIME LastWriteTime; - HMODULE DLL; - - b32 IsValid; - - char SourceDLLPath[MAX_PATH]; - char WorkingDLLPath[MAX_PATH]; - char LockFilePath[MAX_PATH]; -}; - -internal b32 LoadApplicationDLL(char* DLLName, win32_dll_refresh* DLLResult); -internal void UnloadApplicationDLL(win32_dll_refresh* DLL); -internal win32_dll_refresh InitializeDLLHotReloading(char* SourceDLLName, char* WorkingDLLFileName, char* LockFileName); -internal b32 HotLoadDLL(win32_dll_refresh* DLL); - -// Networking - /// // Utils /// @@ -589,314 +564,6 @@ Win32DisplayBufferInWindow(win32_offscreen_buffer* Win32Buffer, window Window) DIB_RGB_COLORS, SRCCOPY); } -/// -// Memory -/// - -internal u8* -Win32BasicAlloc (s32 Size) -{ - return (u8*)VirtualAlloc(NULL, Size, - MEM_COMMIT | MEM_RESERVE, - PAGE_EXECUTE_READWRITE); -} - -PLATFORM_ALLOC(Win32Alloc) -{ - u8* Result = Win32BasicAlloc(Size); - return Result; -} - -PLATFORM_FREE(Win32Free) -{ - b32 Result = VirtualFree(Base, 0, MEM_RELEASE); - if (!Result) - { - s32 Error = WSAGetLastError(); - InvalidCodePath; - } - return Result; -} - -PLATFORM_REALLOC(Win32Realloc) -{ - u8* NewMemory = Win32BasicAlloc(NewSize); - if (Base) - { - GSMemCopy(Base, NewMemory, OldSize); - Win32Free(Base, OldSize); - } - return NewMemory; -} - -// File IO -PLATFORM_READ_ENTIRE_FILE(Win32ReadEntireFile) -{ - platform_memory_result Result = {}; - Result.Error = PLATFORM_MEMORY_NO_ERROR; - - HANDLE FileHandle = CreateFileA ( - Path, - GENERIC_READ, - 0, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); - - if (FileHandle != INVALID_HANDLE_VALUE) - { - DWORD FileSize = GetFileSize(FileHandle, NULL); - Result.Base = (u8*)VirtualAlloc(NULL, FileSize, MEM_COMMIT | MEM_RESERVE, - PAGE_EXECUTE_READWRITE); - if (Result.Base) - { - Result.Size = FileSize; - - s32 BytesRead = 0; - if (ReadFile(FileHandle, (LPVOID)Result.Base, FileSize, (LPDWORD)(&BytesRead), NULL)) - { - - } - else - { - Result.Size = 0; - Result.Error = 1; - } - } - CloseHandle(FileHandle); - } - else - { - // TODO(Peter): failure - } - - return Result; -} - -PLATFORM_WRITE_ENTIRE_FILE(Win32WriteEntireFile) -{ - b32 Result = false; - HANDLE FileHandle = CreateFileA ( - Path, - GENERIC_WRITE, - 0, - NULL, - CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL, - NULL); - - if (FileHandle != INVALID_HANDLE_VALUE) - { - DWORD BytesWritten = 0; - - b32 WriteSuccess = WriteFile(FileHandle, - Contents, Size, - &BytesWritten, - NULL); - - if (WriteSuccess && BytesWritten == (u32)Size) - { - CloseHandle(FileHandle); - Result = true; - } - else - { - Result = false; - } - } - else - { - Result = false; - } - - return Result; -} - -internal FILETIME -GetFileLastWriteTime(char* Path) -{ - FILETIME Result = {}; - - WIN32_FIND_DATA FindData = {}; - HANDLE FileHandle = FindFirstFileA(Path, &FindData); - - if (FileHandle != INVALID_HANDLE_VALUE) - { - Result = FindData.ftLastWriteTime; - FindClose(FileHandle); - } - else - { - // TODO(Peter): Error handling - } - - return Result; -} - -PLATFORM_GET_FILE_PATH(Win32SystemDialogueOpenFile) -{ - b32 Result = false; - - PathBuffer[0] = 0; - - OPENFILENAMEA OpenFileName = {}; - OpenFileName.lStructSize = sizeof(OpenFileName); - OpenFileName.hwndOwner = NULL; - OpenFileName.lpstrFilter = FilterStrings; - OpenFileName.lpstrCustomFilter = NULL; // NOTE(Peter): for preserving last filter string chosen - OpenFileName.nMaxCustFilter = 0; // NOTE(Peter): ignored since we left CustomFilter null - OpenFileName.nFilterIndex = 1; - OpenFileName.lpstrFile = PathBuffer; - OpenFileName.nMaxFile = BufferLength; - OpenFileName.lpstrFileTitle = NULL; - OpenFileName.nMaxFileTitle = 0; // NOTE(Peter): Ignored since fileTitle is null - OpenFileName.lpstrInitialDir = NULL; - OpenFileName.lpstrTitle = NULL; - OpenFileName.Flags = OFN_ENABLESIZING | OFN_FILEMUSTEXIST; - OpenFileName.lpstrDefExt = NULL; - - Result = GetOpenFileNameA (&OpenFileName); - - return Result; -} - -/// -// DLL -/// - -internal void -GetApplicationPath(system_path* Result) -{ - Assert(Result->Path); - Result->PathLength = GetModuleFileNameA(0, Result->Path, Result->PathLength); - - u32 CharactersScanned = 0; - u32 IndexOfLastSlash = 0; - char *Scan = Result->Path; - while(*Scan) - { - if (*Scan == '\\') - { - Result->IndexOfLastSlash = CharactersScanned + 1; - } - Scan++; - CharactersScanned++; - } -} - -internal b32 -LoadApplicationDLL(char* DLLName, win32_dll_refresh* DLLResult) -{ - b32 Success = false; - Assert(DLLResult->DLL == 0); - - DLLResult->DLL = LoadLibraryA(DLLName); // TODO(Peter): Error checking - if (DLLResult->DLL) - { - Success = true; - DLLResult->IsValid = true; - } - - return Success; -} - -internal void -UnloadApplicationDLL(win32_dll_refresh* DLL) -{ - if (DLL->DLL) - { - FreeLibrary(DLL->DLL); - } - DLL->DLL = 0; - DLL->IsValid = false; -} - -internal win32_dll_refresh -InitializeDLLHotReloading(char* SourceDLLName, - char* WorkingDLLFileName, - char* LockFileName) -{ - win32_dll_refresh Result = {}; - Result.IsValid = false; - - system_path ExePath = {}; - ExePath.PathLength = MAX_PATH; - ExePath.Path = (char*)Win32BasicAlloc(ExePath.PathLength); - GetApplicationPath(&ExePath); - - Win32ConcatStrings(ExePath.IndexOfLastSlash, ExePath.Path, - Win32StringLength(SourceDLLName), SourceDLLName, - MAX_PATH, Result.SourceDLLPath); - Win32ConcatStrings(ExePath.IndexOfLastSlash, ExePath.Path, - Win32StringLength(WorkingDLLFileName), WorkingDLLFileName, - MAX_PATH, Result.WorkingDLLPath); - Win32ConcatStrings(ExePath.IndexOfLastSlash, ExePath.Path, - Win32StringLength(LockFileName), LockFileName, - MAX_PATH, Result.LockFilePath); - - Win32Free((u8*)ExePath.Path, ExePath.PathLength); - return Result; - -} - -internal b32 -HotLoadDLL(win32_dll_refresh* DLL) -{ - b32 DidReload = false; - - FILETIME UpdatedLastWriteTime = GetFileLastWriteTime(DLL->SourceDLLPath); - if (CompareFileTime(&UpdatedLastWriteTime, &DLL->LastWriteTime)) - { - WIN32_FILE_ATTRIBUTE_DATA Ignored; - if (!GetFileAttributesEx(DLL->LockFilePath, GetFileExInfoStandard, &Ignored)) - { - UnloadApplicationDLL(DLL); - CopyFileA(DLL->SourceDLLPath, DLL->WorkingDLLPath, FALSE); - LoadApplicationDLL(DLL->WorkingDLLPath, DLL); - DLL->LastWriteTime = UpdatedLastWriteTime; - DidReload = true; - } - } - - return DidReload; -} - -///////////////////////////////////////// -// -// Timing -// -///////////////////////////////////////// - -internal s64 -GetPerformanceFrequency () -{ - LARGE_INTEGER Frequency; - if (!QueryPerformanceFrequency(&Frequency)) - { - s32 Error = GetLastError(); - InvalidCodePath; - } - return (s64)Frequency.QuadPart; -} - -internal s64 -GetWallClock () -{ -#if 0 - s64 Result = __rdtsc(); - return Result; -#else - LARGE_INTEGER Time; - if (!QueryPerformanceCounter(&Time)) - { - s32 Error = GetLastError(); - InvalidCodePath; - } - return (s64)Time.QuadPart; -#endif -} - ///////////////////////////////////////// // // Open GL diff --git a/src/win32_foldhaus.cpp b/src/win32_foldhaus.cpp index 59f01c1..e9074e4 100644 --- a/src/win32_foldhaus.cpp +++ b/src/win32_foldhaus.cpp @@ -15,6 +15,11 @@ #include "foldhaus_platform.h" #include "../gs_libs/gs_win32.cpp" +#include "win32_foldhaus_memory.h" +#include "win32_foldhaus_fileio.h" +#include "win32_foldhaus_dll.h" +#include "win32_foldhaus_timing.h" + #include "foldhaus_renderer.cpp" global_variable b32 Running = false; diff --git a/src/win32_foldhaus_dll.h b/src/win32_foldhaus_dll.h new file mode 100644 index 0000000..9ec7260 --- /dev/null +++ b/src/win32_foldhaus_dll.h @@ -0,0 +1,131 @@ +// +// File: win32_foldhaus_dll.h +// Author: Peter Slattery +// Creation Date: 2020-02-04 +// +// +// NOTE: Relies on having imported foldhaus_platform.h prior to this file +// +#ifndef WIN32_FOLDHAUS_DLL_H + +// DLL +struct win32_dll_refresh +{ + FILETIME LastWriteTime; + HMODULE DLL; + + b32 IsValid; + + char SourceDLLPath[MAX_PATH]; + char WorkingDLLPath[MAX_PATH]; + char LockFilePath[MAX_PATH]; +}; + +internal void +GetApplicationPath(system_path* Result) +{ + Assert(Result->Path); + Result->PathLength = GetModuleFileNameA(0, Result->Path, Result->PathLength); + + u32 CharactersScanned = 0; + u32 IndexOfLastSlash = 0; + char *Scan = Result->Path; + while(*Scan) + { + if (*Scan == '\\') + { + Result->IndexOfLastSlash = CharactersScanned + 1; + } + Scan++; + CharactersScanned++; + } +} + +internal b32 +LoadApplicationDLL(char* DLLName, win32_dll_refresh* DLLResult) +{ + b32 Success = false; + Assert(DLLResult->DLL == 0); + + DLLResult->DLL = LoadLibraryA(DLLName); // TODO(Peter): Error checking + if (DLLResult->DLL) + { + Success = true; + DLLResult->IsValid = true; + } + + return Success; +} + +internal void +UnloadApplicationDLL(win32_dll_refresh* DLL) +{ + if (DLL->DLL) + { + FreeLibrary(DLL->DLL); + } + DLL->DLL = 0; + DLL->IsValid = false; +} + +internal win32_dll_refresh +InitializeDLLHotReloading(char* SourceDLLName, + char* WorkingDLLFileName, + char* LockFileName) +{ + win32_dll_refresh Result = {}; + Result.IsValid = false; + + system_path ExePath = {}; + ExePath.PathLength = MAX_PATH; + ExePath.Path = (char*)VirtualAlloc(NULL, ExePath.PathLength, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); + GetApplicationPath(&ExePath); + + Win32ConcatStrings(ExePath.IndexOfLastSlash, ExePath.Path, + Win32StringLength(SourceDLLName), SourceDLLName, + MAX_PATH, Result.SourceDLLPath); + Win32ConcatStrings(ExePath.IndexOfLastSlash, ExePath.Path, + Win32StringLength(WorkingDLLFileName), WorkingDLLFileName, + MAX_PATH, Result.WorkingDLLPath); + Win32ConcatStrings(ExePath.IndexOfLastSlash, ExePath.Path, + Win32StringLength(LockFileName), LockFileName, + MAX_PATH, Result.LockFilePath); + + Win32Free((u8*)ExePath.Path, ExePath.PathLength); + return Result; + +} + +internal b32 +HotLoadDLL(win32_dll_refresh* DLL) +{ + b32 DidReload = false; + + FILETIME UpdatedLastWriteTime = {}; + WIN32_FIND_DATA FindData = {}; + HANDLE FileHandle = FindFirstFileA(DLL->SourceDLLPath, &FindData); + if (FileHandle != INVALID_HANDLE_VALUE) + { + UpdatedLastWriteTime = FindData.ftLastWriteTime; + FindClose(FileHandle); + } + + if (CompareFileTime(&UpdatedLastWriteTime, &DLL->LastWriteTime)) + { + WIN32_FILE_ATTRIBUTE_DATA Ignored; + if (!GetFileAttributesEx(DLL->LockFilePath, GetFileExInfoStandard, &Ignored)) + { + UnloadApplicationDLL(DLL); + CopyFileA(DLL->SourceDLLPath, DLL->WorkingDLLPath, FALSE); + LoadApplicationDLL(DLL->WorkingDLLPath, DLL); + DLL->LastWriteTime = UpdatedLastWriteTime; + DidReload = true; + } + } + + return DidReload; +} + + +#define WIN32_FOLDHAUS_DLL_H +#endif // WIN32_FOLDHAUS_DLL_H \ No newline at end of file diff --git a/src/win32_foldhaus_fileio.h b/src/win32_foldhaus_fileio.h new file mode 100644 index 0000000..ca4bed9 --- /dev/null +++ b/src/win32_foldhaus_fileio.h @@ -0,0 +1,144 @@ +// +// File: win32_foldhaus_fileio.h +// Author: Peter Slattery +// Creation Date: 2020-02-04 +// +// +// NOTE: Relies on having imported foldhaus_platform.h prior to this file +// +#ifndef WIN32_FOLDHAUS_FILEIO_H + +PLATFORM_READ_ENTIRE_FILE(Win32ReadEntireFile) +{ + platform_memory_result Result = {}; + Result.Error = PLATFORM_MEMORY_NO_ERROR; + + HANDLE FileHandle = CreateFileA ( + Path, + GENERIC_READ, + 0, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if (FileHandle != INVALID_HANDLE_VALUE) + { + DWORD FileSize = GetFileSize(FileHandle, NULL); + Result.Base = (u8*)VirtualAlloc(NULL, FileSize, MEM_COMMIT | MEM_RESERVE, + PAGE_EXECUTE_READWRITE); + if (Result.Base) + { + Result.Size = FileSize; + + s32 BytesRead = 0; + if (ReadFile(FileHandle, (LPVOID)Result.Base, FileSize, (LPDWORD)(&BytesRead), NULL)) + { + + } + else + { + Result.Size = 0; + Result.Error = 1; + } + } + CloseHandle(FileHandle); + } + else + { + // TODO(Peter): failure + } + + return Result; +} + +PLATFORM_WRITE_ENTIRE_FILE(Win32WriteEntireFile) +{ + b32 Result = false; + HANDLE FileHandle = CreateFileA ( + Path, + GENERIC_WRITE, + 0, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if (FileHandle != INVALID_HANDLE_VALUE) + { + DWORD BytesWritten = 0; + + b32 WriteSuccess = WriteFile(FileHandle, + Contents, Size, + &BytesWritten, + NULL); + + if (WriteSuccess && BytesWritten == (u32)Size) + { + CloseHandle(FileHandle); + Result = true; + } + else + { + Result = false; + } + } + else + { + Result = false; + } + + return Result; +} + +internal FILETIME +GetFileLastWriteTime(char* Path) +{ + FILETIME Result = {}; + + WIN32_FIND_DATA FindData = {}; + HANDLE FileHandle = FindFirstFileA(Path, &FindData); + + if (FileHandle != INVALID_HANDLE_VALUE) + { + Result = FindData.ftLastWriteTime; + FindClose(FileHandle); + } + else + { + // TODO(Peter): Error handling + } + + return Result; +} + +PLATFORM_GET_FILE_PATH(Win32SystemDialogueOpenFile) +{ + b32 Result = false; + + PathBuffer[0] = 0; + + OPENFILENAMEA OpenFileName = {}; + OpenFileName.lStructSize = sizeof(OpenFileName); + OpenFileName.hwndOwner = NULL; + OpenFileName.lpstrFilter = FilterStrings; + OpenFileName.lpstrCustomFilter = NULL; // NOTE(Peter): for preserving last filter string chosen + OpenFileName.nMaxCustFilter = 0; // NOTE(Peter): ignored since we left CustomFilter null + OpenFileName.nFilterIndex = 1; + OpenFileName.lpstrFile = PathBuffer; + OpenFileName.nMaxFile = BufferLength; + OpenFileName.lpstrFileTitle = NULL; + OpenFileName.nMaxFileTitle = 0; // NOTE(Peter): Ignored since fileTitle is null + OpenFileName.lpstrInitialDir = NULL; + OpenFileName.lpstrTitle = NULL; + OpenFileName.Flags = OFN_ENABLESIZING | OFN_FILEMUSTEXIST; + OpenFileName.lpstrDefExt = NULL; + + Result = GetOpenFileNameA (&OpenFileName); + + return Result; +} + + +#define WIN32_FOLDHAUS_FILEIO_H +#endif // WIN32_FOLDHAUS_FILEIO_H \ No newline at end of file diff --git a/src/win32_foldhaus_memory.h b/src/win32_foldhaus_memory.h new file mode 100644 index 0000000..f36e01b --- /dev/null +++ b/src/win32_foldhaus_memory.h @@ -0,0 +1,48 @@ +// +// File: win32_foldhaus_memory.h +// Author: Peter Slattery +// Creation Date: 2020-02-04 +// +// +// NOTE: Relies on having imported foldhaus_platform.h prior to this file +// +#ifndef WIN32_FOLDHAUS_MEMORY_H + +internal u8* +Win32BasicAlloc (s32 Size) +{ + return (u8*)VirtualAlloc(NULL, Size, + MEM_COMMIT | MEM_RESERVE, + PAGE_EXECUTE_READWRITE); +} + +PLATFORM_ALLOC(Win32Alloc) +{ + u8* Result = Win32BasicAlloc(Size); + return Result; +} + +PLATFORM_FREE(Win32Free) +{ + b32 Result = VirtualFree(Base, 0, MEM_RELEASE); + if (!Result) + { + s32 Error = WSAGetLastError(); + InvalidCodePath; + } + return Result; +} + +PLATFORM_REALLOC(Win32Realloc) +{ + u8* NewMemory = Win32BasicAlloc(NewSize); + if (Base) + { + GSMemCopy(Base, NewMemory, OldSize); + Win32Free(Base, OldSize); + } + return NewMemory; +} + +#define WIN32_FOLDHAUS_MEMORY_H +#endif // WIN32_FOLDHAUS_MEMORY_H \ No newline at end of file diff --git a/src/win32_foldhaus_timing.h b/src/win32_foldhaus_timing.h new file mode 100644 index 0000000..ed5d041 --- /dev/null +++ b/src/win32_foldhaus_timing.h @@ -0,0 +1,42 @@ +// +// File: win32_foldhaus_timing.h +// Author: Peter Slattery +// Creation Date: 2020-02-04 +// +// +// NOTE: Relies on having imported foldhaus_platform.h prior to this file +// +#ifndef WIN32_FOLDHAUS_TIMING_H + +internal s64 +GetPerformanceFrequency () +{ + LARGE_INTEGER Frequency; + if (!QueryPerformanceFrequency(&Frequency)) + { + s32 Error = GetLastError(); + InvalidCodePath; + } + return (s64)Frequency.QuadPart; +} + +internal s64 +GetWallClock () +{ +#if 0 + s64 Result = __rdtsc(); + return Result; +#else + LARGE_INTEGER Time; + if (!QueryPerformanceCounter(&Time)) + { + s32 Error = GetLastError(); + InvalidCodePath; + } + return (s64)Time.QuadPart; +#endif +} + + +#define WIN32_FOLDHAUS_TIMING_H +#endif // WIN32_FOLDHAUS_TIMING_H \ No newline at end of file diff --git a/todo.txt b/todo.txt index f8cfda1..7c5b274 100644 --- a/todo.txt +++ b/todo.txt @@ -12,10 +12,12 @@ x Hot Code Reloading x Fix it - Make the DLL truly platform agnostic + - math.h: present for trig functions + - windows.h: only thing left is InterlockedIncrement and InterlockedAdd - File Loading - Gracefully handle File Not found -s + - Buckets & Lists - Allow them to use memory arenas - Zero is initialization @@ -122,7 +124,7 @@ update functions - memory visualization - x Log memory allocations - separate rendering thread -- cache led positions. Only update if they are moving + UI Improvements - highlight node field under active edit @@ -174,7 +176,7 @@ x create clips that play Optimization - investigate the memory access pattern of the SACN / LED systems. Guessing they are very slow -- look into why debug logging functions seems to incur a large hit on framrate +x look into why debug logging functions seems to incur a large hit on framrate - patterns are asking to be multithreaded - probably want to convert as much color functions to use u32 Packed Colors - - Probably want to think about this more. What about supporting different color depths