From 55c1adba405492888b0d5cf51d8d75390ce93415 Mon Sep 17 00:00:00 2001 From: James Bulman Date: Sun, 5 Oct 2025 00:24:51 +0100 Subject: [PATCH] Added system path stuff on Windows Fixed typo in image loading --- code/core/platform.h | 1 + code/first.c | 1 - code/game/core.c | 2 +- code/os/impl/windows/filesystem.c | 75 +++++++++++++++++++++++++++++++ windows.bat | 2 +- 5 files changed, 78 insertions(+), 3 deletions(-) diff --git a/code/core/platform.h b/code/core/platform.h index b85cd09..63b6827 100644 --- a/code/core/platform.h +++ b/code/core/platform.h @@ -68,6 +68,7 @@ #if OS_WINDOWS #define WIN32_LEAN_AND_MEAN 1 #include + #include #pragma warning(disable : 4201) #elif OS_LINUX #include diff --git a/code/first.c b/code/first.c index a9f4382..7425e00 100644 --- a/code/first.c +++ b/code/first.c @@ -85,7 +85,6 @@ int main(int argc, char **argv) { } } - int w, h; SDL_GetWindowSizeInPixels(window, &w, &h); diff --git a/code/game/core.c b/code/game/core.c index 895c14c..194b74f 100644 --- a/code/game/core.c +++ b/code/game/core.c @@ -1,7 +1,7 @@ void G_ImagesLoad(G_State *game) { M_TempScope(0, 0) { Str8 exe_path = FS_SystemPath(temp.arena, FS_SYSTEM_PATH_EXE); - Str8 path = Sf(temp.arena, "%.*s/assets", exe_path); + Str8 path = Sf(temp.arena, "%.*s/assets", Sv(exe_path)); FS_List assets = FS_PathList(temp.arena, path); diff --git a/code/os/impl/windows/filesystem.c b/code/os/impl/windows/filesystem.c index 3f6575f..4819811 100644 --- a/code/os/impl/windows/filesystem.c +++ b/code/os/impl/windows/filesystem.c @@ -132,3 +132,78 @@ FS_List FS_PathList(M_Arena *arena, Str8 path) { return result; } + +Str8 FS_SystemPath(M_Arena *arena, FS_SystemPathType path) { + Str8 result = { 0 }; + + M_TempScope(1, &arena) { + switch (path) { + case FS_SYSTEM_PATH_EXE: { + U64 offset = M_ArenaOffset(temp.arena); + + DWORD err, nchars; + + DWORD nSize = 1024; + LPWSTR lpFilename = M_ArenaPush(temp.arena, WCHAR, .count = nSize, .flags = M_ARENA_NO_ZERO); + + for (;;) { + nchars = GetModuleFileNameW(0, lpFilename, nSize); + + err = GetLastError(); + if (err != ERROR_INSUFFICIENT_BUFFER) { + break; + } + + M_ArenaPop(temp.arena, offset); + + nSize *= 2; + lpFilename = M_ArenaPush(temp.arena, WCHAR, .count = nSize, .flags = M_ARENA_NO_ZERO); + } + + if (err == ERROR_SUCCESS) { + while (lpFilename[nchars] != '\\') { nchars -= 1; } + lpFilename[nchars] = 0; + + result = Win32_MultiByteStr(arena, lpFilename); + } + } + break; + + case FS_SYSTEM_PATH_WORKING: { + DWORD nSize = GetCurrentDirectoryW(0, 0); + + if (nSize != 0) { + LPWSTR lpBuffer = M_ArenaPush(temp.arena, WCHAR, .count = nSize, .flags = M_ARENA_NO_ZERO); + GetCurrentDirectoryW(nSize, lpBuffer); + + result = Win32_MultiByteStr(arena, lpBuffer); + } + } + break; + + case FS_SYSTEM_PATH_USER: { + LPWSTR wpath; + HRESULT hResult = SHGetKnownFolderPath(&FOLDERID_RoamingAppData, 0, 0, &wpath); + if (hResult == S_OK) { + result = Win32_MultiByteStr(arena, wpath); + CoTaskMemFree(wpath); + } + } + break; + + case FS_SYSTEM_PATH_TEMP: { + DWORD nSize = MAX_PATH + 1; + LPWSTR lpBuffer = M_ArenaPush(temp.arena, WCHAR, .count = nSize); + + DWORD nchars = GetTempPathW(nSize, lpBuffer); + if (nchars != 0) { + lpBuffer[nchars - 1] = 0; // Strip trailing backslash + result = Win32_MultiByteStr(arena, lpBuffer); + } + } + break; + } + } + + return result; +} diff --git a/windows.bat b/windows.bat index 2e578cf..d3daa61 100644 --- a/windows.bat +++ b/windows.bat @@ -68,7 +68,7 @@ glslangValidator -o "assets\shaders\basic.frag.spv" --target-env vulkan1.3 "..\c ECHO [Building source] SET COMPILER_OPTS=-nologo -W4 -I"deps\SDL3\include" -I"deps\stb" -I"%VULKAN_SDK%\Include" -I"..\code" -SET LINKER_OPTS=-LIBPATH:"deps\SDL3\lib" SDL3.lib +SET LINKER_OPTS=-LIBPATH:"deps\SDL3\lib" SDL3.lib Ole32.lib Shell32.lib IF %release% equ 1 ( ECHO [Release build]