Merge
This commit is contained in:
parent
6134c6e982
commit
439f00caf4
10 changed files with 279 additions and 7 deletions
|
@ -6,6 +6,6 @@ mkdir build
|
||||||
|
|
||||||
pushd build
|
pushd build
|
||||||
|
|
||||||
clang -g -o cgame.exe ../build.c -O0 -mavx -std=c11 -Wextra -Wno-incompatible-library-redeclaration -Wno-sign-compare -Wno-unused-parameter -Wno-builtin-requires-header -lgdi32 -luser32 -lwinmm -ld3d11 -ldxguid -ld3dcompiler
|
clang -g -o cgame.exe ../build.c -O0 -std=c11 -Wextra -Wno-incompatible-library-redeclaration -Wno-sign-compare -Wno-unused-parameter -Wno-builtin-requires-header -lgdi32 -luser32 -lwinmm -ld3d11 -ldxguid -ld3dcompiler
|
||||||
|
|
||||||
popd
|
popd
|
5
build.c
5
build.c
|
@ -3,7 +3,7 @@
|
||||||
///
|
///
|
||||||
// Build config stuff
|
// Build config stuff
|
||||||
|
|
||||||
#define RUN_TESTS 1
|
#define RUN_TESTS 0
|
||||||
|
|
||||||
// This is only for people developing oogabooga!
|
// This is only for people developing oogabooga!
|
||||||
#define OOGABOOGA_DEV 1
|
#define OOGABOOGA_DEV 1
|
||||||
|
@ -29,6 +29,9 @@ typedef struct Context_Extra {
|
||||||
// Ooga booga needs to be included AFTER configuration and BEFORE the program code
|
// Ooga booga needs to be included AFTER configuration and BEFORE the program code
|
||||||
#include "oogabooga/oogabooga.c"
|
#include "oogabooga/oogabooga.c"
|
||||||
|
|
||||||
|
// #Volatile tutorial below
|
||||||
|
// #Volatile tutorial below
|
||||||
|
// #Volatile tutorial below
|
||||||
|
|
||||||
//
|
//
|
||||||
// Comment & Uncomment these to swap projects (only include one at a time)
|
// Comment & Uncomment these to swap projects (only include one at a time)
|
||||||
|
|
|
@ -7,7 +7,7 @@ pushd build
|
||||||
mkdir release
|
mkdir release
|
||||||
pushd release
|
pushd release
|
||||||
|
|
||||||
clang -o cgame.exe ../../build.c -Ofast -std=c11 -Wextra -Wno-incompatible-library-redeclaration -Wno-sign-compare -Wno-unused-parameter -Wno-builtin-requires-header -lgdi32 -luser32 -lwinmm -ld3d11 -ldxguid -ld3dcompiler -mavx2 -mavx512f -msse4.1 -msse2 -finline-functions -ffast-math -fno-math-errno -funsafe-math-optimizations -freciprocal-math -ffinite-math-only -fassociative-math -fno-signed-zeros -fno-trapping-math -ftree-vectorize -fomit-frame-pointer -funroll-loops -fno-rtti -fno-exceptions
|
clang -o cgame.exe ../../build.c -Ofast -std=c11 -Wextra -Wno-incompatible-library-redeclaration -Wno-sign-compare -Wno-unused-parameter -Wno-builtin-requires-header -lgdi32 -luser32 -lwinmm -ld3d11 -ldxguid -ld3dcompiler -lshlwapi -mavx2 -mavx512f -msse4.1 -msse2 -finline-functions -ffast-math -fno-math-errno -funsafe-math-optimizations -freciprocal-math -ffinite-math-only -fassociative-math -fno-signed-zeros -fno-trapping-math -ftree-vectorize -fomit-frame-pointer -funroll-loops -fno-rtti -fno-exceptions
|
||||||
|
|
||||||
popd
|
popd
|
||||||
popd
|
popd
|
|
@ -1,4 +1,4 @@
|
||||||
|
¨
|
||||||
int entry(int argc, char **argv) {
|
int entry(int argc, char **argv) {
|
||||||
|
|
||||||
window.title = STR("Minimal Game Example");
|
window.title = STR("Minimal Game Example");
|
||||||
|
|
|
@ -15,6 +15,8 @@ int entry(int argc, char **argv) {
|
||||||
Gfx_Image *hammer_image = load_image_from_disk(STR("oogabooga/examples/hammer.png"), get_heap_allocator());
|
Gfx_Image *hammer_image = load_image_from_disk(STR("oogabooga/examples/hammer.png"), get_heap_allocator());
|
||||||
assert(hammer_image, "Failed loading hammer.png");
|
assert(hammer_image, "Failed loading hammer.png");
|
||||||
|
|
||||||
|
Gfx_Font *font = load_font_From_disk(
|
||||||
|
|
||||||
seed_for_random = os_get_current_cycle_count();
|
seed_for_random = os_get_current_cycle_count();
|
||||||
|
|
||||||
const float64 fps_limit = 69000;
|
const float64 fps_limit = 69000;
|
||||||
|
@ -100,6 +102,10 @@ int entry(int argc, char **argv) {
|
||||||
|
|
||||||
draw_image(bush_image, v2(0.65, 0.65), v2(0.2*sin(now), 0.2*sin(now)), COLOR_WHITE);
|
draw_image(bush_image, v2(0.65, 0.65), v2(0.2*sin(now), 0.2*sin(now)), COLOR_WHITE);
|
||||||
|
|
||||||
|
draw_frame.font = STR("");
|
||||||
|
|
||||||
|
draw_text();
|
||||||
|
|
||||||
gfx_update();
|
gfx_update();
|
||||||
|
|
||||||
if (is_key_just_released('E')) {
|
if (is_key_just_released('E')) {
|
||||||
|
|
|
@ -36,3 +36,9 @@ typedef struct Gfx_Image {
|
||||||
Allocator allocator;
|
Allocator allocator;
|
||||||
} Gfx_Image;
|
} Gfx_Image;
|
||||||
|
|
||||||
|
typedef struct Gfx_Font {
|
||||||
|
u32 width, height;
|
||||||
|
u8 *data;
|
||||||
|
Gfx_Handle gfx_handle;
|
||||||
|
Allocator allocator;
|
||||||
|
} Gfx_Font;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
|
|
||||||
|
#include <Shlwapi.h>
|
||||||
|
|
||||||
#define VIRTUAL_MEMORY_BASE ((void*)0x0000690000000000ULL)
|
#define VIRTUAL_MEMORY_BASE ((void*)0x0000690000000000ULL)
|
||||||
|
|
||||||
|
@ -553,6 +554,13 @@ void os_write_string_to_stdout(string s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 *win32_fixed_utf8_to_null_terminated_wide(string utf8, Allocator allocator) {
|
u16 *win32_fixed_utf8_to_null_terminated_wide(string utf8, Allocator allocator) {
|
||||||
|
|
||||||
|
if (utf8.count == 0) {
|
||||||
|
u16 *utf16_str = (u16 *)alloc(allocator, (1) * sizeof(u16));
|
||||||
|
*utf16_str = 0;
|
||||||
|
return utf16_str;
|
||||||
|
}
|
||||||
|
|
||||||
u64 utf16_length = MultiByteToWideChar(CP_UTF8, 0, (LPCCH)utf8.data, (int)utf8.count, 0, 0);
|
u64 utf16_length = MultiByteToWideChar(CP_UTF8, 0, (LPCCH)utf8.data, (int)utf8.count, 0, 0);
|
||||||
|
|
||||||
u16 *utf16_str = (u16 *)alloc(allocator, (utf16_length + 1) * sizeof(u16));
|
u16 *utf16_str = (u16 *)alloc(allocator, (utf16_length + 1) * sizeof(u16));
|
||||||
|
@ -573,6 +581,13 @@ u16 *temp_win32_fixed_utf8_to_null_terminated_wide(string utf8) {
|
||||||
string win32_null_terminated_wide_to_fixed_utf8(const u16 *utf16, Allocator allocator) {
|
string win32_null_terminated_wide_to_fixed_utf8(const u16 *utf16, Allocator allocator) {
|
||||||
u64 utf8_length = WideCharToMultiByte(CP_UTF8, 0, (LPCWCH)utf16, -1, 0, 0, 0, 0);
|
u64 utf8_length = WideCharToMultiByte(CP_UTF8, 0, (LPCWCH)utf16, -1, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
if (utf8_length == 0) {
|
||||||
|
string utf8;
|
||||||
|
utf8.count = 0;
|
||||||
|
utf8.data = 0;
|
||||||
|
return utf8;
|
||||||
|
}
|
||||||
|
|
||||||
u8 *utf8_str = (u8 *)alloc(allocator, utf8_length * sizeof(u8));
|
u8 *utf8_str = (u8 *)alloc(allocator, utf8_length * sizeof(u8));
|
||||||
|
|
||||||
int result = WideCharToMultiByte(CP_UTF8, 0, (LPCWCH)utf16, -1, (LPSTR)utf8_str, (int)utf8_length, 0, 0);
|
int result = WideCharToMultiByte(CP_UTF8, 0, (LPCWCH)utf16, -1, (LPSTR)utf8_str, (int)utf8_length, 0, 0);
|
||||||
|
@ -620,6 +635,79 @@ bool os_file_delete_s(string path) {
|
||||||
return (bool)DeleteFileW(path_wide);
|
return (bool)DeleteFileW(path_wide);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool os_make_directory_s(string path, bool recursive) {
|
||||||
|
wchar_t *wide_path = temp_win32_fixed_utf8_to_null_terminated_wide(path);
|
||||||
|
|
||||||
|
// Convert forward slashes to backslashes
|
||||||
|
for (wchar_t *p = wide_path; *p; ++p) {
|
||||||
|
if (*p == L'/') {
|
||||||
|
*p = L'\\';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recursive) {
|
||||||
|
wchar_t *sep = wcschr(wide_path + 1, L'\\');
|
||||||
|
while (sep) {
|
||||||
|
*sep = 0;
|
||||||
|
if (!CreateDirectoryW(wide_path, NULL) && GetLastError() != ERROR_ALREADY_EXISTS) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*sep = L'\\';
|
||||||
|
sep = wcschr(sep + 1, L'\\');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CreateDirectoryW(wide_path, NULL) && GetLastError() != ERROR_ALREADY_EXISTS) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool os_delete_directory_s(string path, bool recursive) {
|
||||||
|
wchar_t *wide_path = temp_win32_fixed_utf8_to_null_terminated_wide(path);
|
||||||
|
|
||||||
|
if (recursive) {
|
||||||
|
WIN32_FIND_DATAW findFileData;
|
||||||
|
HANDLE hFind = INVALID_HANDLE_VALUE;
|
||||||
|
wchar_t search_path[MAX_PATH];
|
||||||
|
wcscpy(search_path, wide_path);
|
||||||
|
wcscat(search_path, L"\\*");
|
||||||
|
|
||||||
|
hFind = FindFirstFileW(search_path, &findFileData);
|
||||||
|
if (hFind == INVALID_HANDLE_VALUE) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
do {
|
||||||
|
if (wcscmp(findFileData.cFileName, L".") != 0 && wcscmp(findFileData.cFileName, L"..") != 0) {
|
||||||
|
wchar_t child_path[MAX_PATH];
|
||||||
|
wcscpy(child_path, wide_path);
|
||||||
|
wcscat(child_path, L"\\");
|
||||||
|
wcscat(child_path, findFileData.cFileName);
|
||||||
|
|
||||||
|
if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||||
|
if (!os_delete_directory_s(temp_win32_null_terminated_wide_to_fixed_utf8(child_path), true)) {
|
||||||
|
FindClose(hFind);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!DeleteFileW(child_path)) {
|
||||||
|
FindClose(hFind);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (FindNextFileW(hFind, &findFileData) != 0);
|
||||||
|
FindClose(hFind);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!RemoveDirectoryW(wide_path)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool os_file_write_string(File f, string s) {
|
bool os_file_write_string(File f, string s) {
|
||||||
DWORD written;
|
DWORD written;
|
||||||
BOOL result = WriteFile(f, s.data, s.count, &written, NULL);
|
BOOL result = WriteFile(f, s.data, s.count, &written, NULL);
|
||||||
|
@ -717,6 +805,94 @@ bool os_is_directory_s(string path) {
|
||||||
return (attributes & FILE_ATTRIBUTE_DIRECTORY);
|
return (attributes & FILE_ATTRIBUTE_DIRECTORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool os_is_path_absolute(string path) {
|
||||||
|
// #Incomplete #Portability not sure this is very robust.
|
||||||
|
|
||||||
|
if (path.count < 2) return false;
|
||||||
|
|
||||||
|
if (path.data[1] == ':' && ((path.data[0] >= 'A' && path.data[0] <= 'Z') || (path.data[0] >= 'a' && path.data[0] <= 'z'))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.count > 1 && path.data[0] == '\\' && path.data[1] == '\\') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool os_get_absolute_path(string path, string *result, Allocator allocator) {
|
||||||
|
u16 buffer[MAX_PATH];
|
||||||
|
u16 *path_wide = temp_win32_fixed_utf8_to_null_terminated_wide(path);
|
||||||
|
DWORD count = GetFullPathNameW(path_wide, MAX_PATH, buffer, 0);
|
||||||
|
|
||||||
|
if (count == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*result = win32_null_terminated_wide_to_fixed_utf8(buffer, allocator);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool os_get_relative_path(string from, string to, string *result, Allocator allocator) {
|
||||||
|
|
||||||
|
if (!os_is_path_absolute(from)) {
|
||||||
|
bool abs_ok = os_get_absolute_path(from, &from, temp);
|
||||||
|
if (!abs_ok) return false;
|
||||||
|
}
|
||||||
|
if (!os_is_path_absolute(to)) {
|
||||||
|
bool abs_ok = os_get_absolute_path(to, &to, temp);
|
||||||
|
if (!abs_ok) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
u16 buffer[MAX_PATH];
|
||||||
|
|
||||||
|
u16 *from_wide = temp_win32_fixed_utf8_to_null_terminated_wide(from);
|
||||||
|
u16 *to_wide = temp_win32_fixed_utf8_to_null_terminated_wide(to);
|
||||||
|
|
||||||
|
// #Speed is_file and is_directory potentially slow
|
||||||
|
DWORD attr_from = os_is_file(from) ? FILE_ATTRIBUTE_NORMAL : FILE_ATTRIBUTE_DIRECTORY;
|
||||||
|
DWORD attr_to = os_is_file(to) ? FILE_ATTRIBUTE_NORMAL : FILE_ATTRIBUTE_DIRECTORY;
|
||||||
|
|
||||||
|
BOOL success = PathRelativePathToW(buffer,
|
||||||
|
from_wide, attr_from,
|
||||||
|
to_wide, attr_to);
|
||||||
|
if (!success) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 count = 0;
|
||||||
|
while (buffer[count] != 0) count += 1;
|
||||||
|
|
||||||
|
*result = win32_null_terminated_wide_to_fixed_utf8(buffer, allocator);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool os_do_paths_match(string a, string b) {
|
||||||
|
wchar_t *wide_path_a = temp_win32_fixed_utf8_to_null_terminated_wide(a);
|
||||||
|
wchar_t *wide_path_b = temp_win32_fixed_utf8_to_null_terminated_wide(b);
|
||||||
|
|
||||||
|
wchar_t full_path_a[MAX_PATH];
|
||||||
|
wchar_t full_path_b[MAX_PATH];
|
||||||
|
|
||||||
|
// Get the full path for both paths
|
||||||
|
if (!GetFullPathNameW(wide_path_a, MAX_PATH, full_path_a, NULL)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!GetFullPathNameW(wide_path_b, MAX_PATH, full_path_b, NULL)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare the full paths
|
||||||
|
if (wcscmp(full_path_a, full_path_b) == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void fprints(File f, string fmt, ...) {
|
void fprints(File f, string fmt, ...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
|
|
|
@ -206,6 +206,7 @@ void os_file_close(File f);
|
||||||
bool os_file_delete_s(string path);
|
bool os_file_delete_s(string path);
|
||||||
|
|
||||||
bool os_make_directory_s(string path, bool recursive);
|
bool os_make_directory_s(string path, bool recursive);
|
||||||
|
bool os_delete_directory_s(string path, bool recursive);
|
||||||
|
|
||||||
bool os_file_write_string(File f, string s);
|
bool os_file_write_string(File f, string s);
|
||||||
bool os_file_write_bytes(File f, void *buffer, u64 size_in_bytes);
|
bool os_file_write_bytes(File f, void *buffer, u64 size_in_bytes);
|
||||||
|
@ -220,6 +221,13 @@ bool os_read_entire_file_s(string path, string *result, Allocator allocator);
|
||||||
bool os_is_file_s(string path);
|
bool os_is_file_s(string path);
|
||||||
bool os_is_directory_s(string path);
|
bool os_is_directory_s(string path);
|
||||||
|
|
||||||
|
bool os_is_path_absolute(string path);
|
||||||
|
|
||||||
|
bool os_get_absolute_path(string path, string *result, Allocator allocator);
|
||||||
|
bool os_get_relative_path(string from, string to, string *result, Allocator allocator);
|
||||||
|
|
||||||
|
bool os_do_paths_match(string a, string b);
|
||||||
|
|
||||||
// It's a little unfortunate that we need to do this but I can't think of a better solution
|
// It's a little unfortunate that we need to do this but I can't think of a better solution
|
||||||
|
|
||||||
inline File os_file_open_f(const char *path, Os_Io_Open_Flags flags) {return os_file_open_s(STR(path), flags);}
|
inline File os_file_open_f(const char *path, Os_Io_Open_Flags flags) {return os_file_open_s(STR(path), flags);}
|
||||||
|
@ -239,6 +247,11 @@ inline bool os_make_directory_f(const char *path, bool recursive) { return os_ma
|
||||||
string: os_make_directory_s, \
|
string: os_make_directory_s, \
|
||||||
default: os_make_directory_f \
|
default: os_make_directory_f \
|
||||||
)(__VA_ARGS__)
|
)(__VA_ARGS__)
|
||||||
|
inline bool os_delete_directory_f(const char *path, bool recursive) { return os_delete_directory_s(STR(path), recursive); }
|
||||||
|
#define os_delete_directory(...) _Generic((FIRST_ARG(__VA_ARGS__)), \
|
||||||
|
string: os_delete_directory_s, \
|
||||||
|
default: os_delete_directory_f \
|
||||||
|
)(__VA_ARGS__)
|
||||||
|
|
||||||
inline bool os_write_entire_file_f(const char *path, string data) {return os_write_entire_file_s(STR(path), data);}
|
inline bool os_write_entire_file_f(const char *path, string data) {return os_write_entire_file_s(STR(path), data);}
|
||||||
#define os_write_entire_file(...) _Generic((FIRST_ARG(__VA_ARGS__)), \
|
#define os_write_entire_file(...) _Generic((FIRST_ARG(__VA_ARGS__)), \
|
||||||
|
@ -265,6 +278,7 @@ inline bool os_is_directory_f(const char *path) {return os_is_directory_s(STR(pa
|
||||||
)(__VA_ARGS__)
|
)(__VA_ARGS__)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void fprints(File f, string fmt, ...);
|
void fprints(File f, string fmt, ...);
|
||||||
void fprintf(File f, const char* fmt, ...);
|
void fprintf(File f, const char* fmt, ...);
|
||||||
#define fprint(...) _Generic((FIRST_ARG(__VA_ARGS__)), \
|
#define fprint(...) _Generic((FIRST_ARG(__VA_ARGS__)), \
|
||||||
|
|
|
@ -20,3 +20,35 @@ string get_file_extension(string path) {
|
||||||
|
|
||||||
return ZERO(string);
|
return ZERO(string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string get_file_name_including_extension(string file_path) {
|
||||||
|
if (file_path.count <= 0) return ZERO(string);
|
||||||
|
|
||||||
|
s64 last_separator = -1;
|
||||||
|
for (s64 i = file_path.count - 1; i >= 0; i--) {
|
||||||
|
if (file_path.data[i] == '/' || file_path.data[i] == '\\' || file_path.data[i] == ':') {
|
||||||
|
last_separator = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string file_name = ZERO(string);
|
||||||
|
if (last_separator != -1 && last_separator < file_path.count - 1) {
|
||||||
|
file_name.data = file_path.data + last_separator + 1;
|
||||||
|
file_name.count = file_path.count - last_separator - 1;
|
||||||
|
} else {
|
||||||
|
file_name = file_path; // If no separator was found, assume entire path is a file name.
|
||||||
|
}
|
||||||
|
|
||||||
|
return file_name;
|
||||||
|
}
|
||||||
|
string get_file_name_excluding_extension(string file_path) {
|
||||||
|
string file_name = get_file_name_including_extension(file_path);
|
||||||
|
|
||||||
|
for (s64 i = file_name.count-1; i >= 1; i--) {
|
||||||
|
if (file_name.data[i] == '.') {
|
||||||
|
return string_view(file_name, 0, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return file_name;
|
||||||
|
}
|
|
@ -531,6 +531,37 @@ void test_file_io() {
|
||||||
assert(integers_read.count == integers_data.count, "Failed: big file read/write mismatch. Read was %d and written was %d", integers_read.count, integers_data.count);
|
assert(integers_read.count == integers_data.count, "Failed: big file read/write mismatch. Read was %d and written was %d", integers_read.count, integers_data.count);
|
||||||
assert(strings_match(integers_data, integers_read), "Failed: big file read/write mismatch");
|
assert(strings_match(integers_data, integers_read), "Failed: big file read/write mismatch");
|
||||||
|
|
||||||
|
assert(os_is_file("test.txt"), "Failed: test.txt not recognized as file");
|
||||||
|
assert(os_is_file("test_bytes.txt"), "Failed: test_bytes.txt not recognized as file");
|
||||||
|
assert(os_is_file("entire_test.txt"), "Failed: entire_test.txt not recognized as file");
|
||||||
|
assert(os_is_file("balls.txt"), "Failed: balls.txt not recognized as file");
|
||||||
|
assert(os_is_file("integers"), "Failed: integers not recognized as file");
|
||||||
|
|
||||||
|
bool dir_ok = os_make_directory("test_dir", false);
|
||||||
|
assert(dir_ok, "Failed: os_make_directory");
|
||||||
|
|
||||||
|
assert(os_is_directory("test_dir"), "Failed: os_is_directory");
|
||||||
|
|
||||||
|
string dir_abs;
|
||||||
|
bool abs_ok = os_get_absolute_path(STR("test_dir"), &dir_abs, heap);
|
||||||
|
assert(abs_ok, "Failed: os_get_absolute_path");
|
||||||
|
assert(os_is_path_absolute(dir_abs), "Failed: os_is_path_absolute");
|
||||||
|
assert(!os_is_path_absolute(STR("test_dir")), "Failed: os_is_path_absolute");
|
||||||
|
string dir_rel;
|
||||||
|
bool rel_ok = os_get_relative_path(STR("."), dir_abs, &dir_rel, heap);
|
||||||
|
assert(rel_ok, "Failed: os_get_relative_path");
|
||||||
|
assert(os_do_paths_match(dir_rel, STR("test_dir")), "Failed: Resolved relative path does not match. Expected '.\test_dir', got %s.", dir_rel);
|
||||||
|
|
||||||
|
dir_ok = os_make_directory("test_dir1/test_dir2/test_dir3", true);
|
||||||
|
assert(dir_ok, "Failed: os_make_directory");
|
||||||
|
dir_ok = os_make_directory("test_dir1/test_dir2/test_dir4", true);
|
||||||
|
assert(dir_ok, "Failed: os_make_directory");
|
||||||
|
|
||||||
|
assert(os_is_directory("test_dir1"), "Failed: os_is_directory");
|
||||||
|
assert(os_is_directory("test_dir1/test_dir2"), "Failed: os_is_directory");
|
||||||
|
assert(os_is_directory("test_dir1/test_dir2//test_dir3"), "Failed: os_is_directory");
|
||||||
|
assert(os_is_directory("test_dir1/test_dir2//test_dir4"), "Failed: os_is_directory");
|
||||||
|
|
||||||
// Clean up test files
|
// Clean up test files
|
||||||
bool delete_ok = false;
|
bool delete_ok = false;
|
||||||
delete_ok = os_file_delete("test.txt");
|
delete_ok = os_file_delete("test.txt");
|
||||||
|
@ -543,6 +574,10 @@ void test_file_io() {
|
||||||
assert(delete_ok, "Failed: could not delete balls.txt");
|
assert(delete_ok, "Failed: could not delete balls.txt");
|
||||||
delete_ok = os_file_delete("integers");
|
delete_ok = os_file_delete("integers");
|
||||||
assert(delete_ok, "Failed: could not delete integers");
|
assert(delete_ok, "Failed: could not delete integers");
|
||||||
|
delete_ok = os_delete_directory("test_dir", false);
|
||||||
|
assert(delete_ok, "Failed: could not delete test_dir");
|
||||||
|
delete_ok = os_delete_directory("test_dir1", true);
|
||||||
|
assert(delete_ok, "Failed: could not delete test_dir1 (recursive)");
|
||||||
}
|
}
|
||||||
bool floats_roughly_match(float a, float b) {
|
bool floats_roughly_match(float a, float b) {
|
||||||
return fabs(a - b) < 0.01;
|
return fabs(a - b) < 0.01;
|
||||||
|
|
Reference in a new issue