diff --git a/src/compile_flags.txt b/src/compile_flags.txt index 1169529..b77fb74 100644 --- a/src/compile_flags.txt +++ b/src/compile_flags.txt @@ -3,5 +3,6 @@ -DED_STRING_IMPLEMENTATION -DED_GFX_IMPLEMENTATION -DED_BUFFER_IMPLEMENTATION +-DED_FILE_IO_IMPLEMENTATION -I../vendor/ -ObjC diff --git a/src/file_io.h b/src/file_io.h new file mode 100644 index 0000000..f2f0c79 --- /dev/null +++ b/src/file_io.h @@ -0,0 +1,138 @@ +#ifndef ED_FILE_IO_INCLUDED +#define ED_FILE_IO_INCLUDED +#include +#include + +#include "string.h" + +uint64_t get_file_size(string file_path); +bool load_file(string file_path, size_t size, void *buffer); + +#ifdef ED_FILE_IO_IMPLEMENTATION + +#if defined(__unix__) +#include +#include +#include + +unsigned long get_file_size(const char *filePath) { + FILE *file = fopen(filePath, "r"); + assert(file && "get_file_size: failed to open file"); + + fseek(file, 0, SEEK_END); + long fsize = ftell(file); + fseek(file, 0, SEEK_SET); + + fclose(file); + + return fsize; +} + +bool load_file(const char *filePath, unsigned long size, void *buffer) { + FILE *file = fopen(filePath, "r"); + assert(file && "load_file: failed to open file"); + + fseek(file, 0, SEEK_END); + long fsize = ftell(file); + fseek(file, 0, SEEK_SET); + + fread(buffer, fsize, 1, file); + + fclose(file); + + return true; +} + +#elif defined(_WIN32) || defined(WIN32) +#include +#define assertm(exp, msg) assert(((void)msg, exp)) + +VOID CALLBACK FileIOCompletionRoutine( + __in DWORD dwErrorCode, + __in DWORD dwNumberOfBytesTransfered, + __in LPOVERLAPPED lpOverlapped ) +{ + printf("Error code: %li", dwErrorCode); + printf("Number of bytes: %li", dwNumberOfBytesTransfered); +} + +unsigned long get_file_size(const char *filePath) { + HANDLE hFile = CreateFile(filePath, + GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, + NULL); + + LARGE_INTEGER size; + assert(GetFileSizeEx(hFile, &size) && "get_file_size: failed to get file size"); + + return size.LowPart; +} + +bool load_file(const char *filePath, unsigned long size, void *buffer) { + HANDLE hFile = CreateFile(filePath, + GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + + OVERLAPPED ol = {0}; + unsigned long bytesRead = 0; + if (!ReadFile(hFile, buffer, size, &bytesRead, NULL)) { + unsigned long error = GetLastError(); + unsigned long msg = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, buffer, size, NULL); + + printf("failed to load file: %s\n", (char *)buffer); + assert(false && "failed to read file"); + } + assert(bytesRead == size && "load_file: didn't one-shot read the whole file"); + + return true; +} +#elif defined(__APPLE__) +#include + +uint64_t get_file_size(string file_path) { + NSFileManager* file_manager = [NSFileManager defaultManager]; + NSString *path = [file_manager stringWithFileSystemRepresentation:(const char *)file_path.data length:file_path.len]; + + NSError *error = NULL; + NSDictionary *attributes = [file_manager attributesOfItemAtPath:path error:&error]; + + if (error) { + NSLog(@"error getting file attributes: %@\n", error.description); + return 0; + } + + NSNumber *file_size = [attributes objectForKey:NSFileSize]; + + return file_size.unsignedLongLongValue; +} + +bool load_file(string file_path, size_t size, void *buffer) { + NSFileManager* file_manager = [NSFileManager defaultManager]; + NSString *path = [file_manager stringWithFileSystemRepresentation:(const char *)file_path.data length:file_path.len]; + + NSData *data = [file_manager contentsAtPath:path]; + if (data == NULL) { + fprintf(stderr, "failed to load file: %.*s\n", (int)file_path.len, file_path.data); + return false; + } + + if (data.length > size) { + fprintf(stderr, "buffer not large enough for file: %.*s\n", (int)file_path.len, file_path.data); + } + + memcpy(buffer, data.bytes, data.length); + + return true; +} + +#endif + +#endif +#endif diff --git a/src/main.c b/src/main.c index ed5e69a..025b68c 100644 --- a/src/main.c +++ b/src/main.c @@ -12,12 +12,14 @@ #define ED_HT_IMPLEMENTATION #define ED_UI_IMPLEMENTATION #define ED_BUFFER_IMPLEMENTATION +#define ED_FILE_IO_IMPLEMENTATION #include "string.h" #include "ht.h" #include "ui.h" #include "ed_array.h" #include "gfx.h" #include "buffer.h" +#include "file_io.h" // static Arena default_arena = {0}; // static Arena temporary_arena = {0}; @@ -112,15 +114,9 @@ void ed_init(_gfx_frame_func frame_func) { gfx_allocate_vertex_buffer(state.gfx_cx, sizeof(GpuUniformParams)); gfx_allocate_vertex_buffer(state.gfx_cx, state.gpu_ui_rects.capacity * sizeof(GpuUiRect)); - uint8_t ttf_buffer[1<<20]; // TODO: grab default font from the system - FILE *ttf_file = fopen("./bin/JetBrainsMono-Medium.ttf", "rb"); - if (!ttf_file) { - fprintf(stderr, "failed to load font\n"); - exit(1); - } - assert(fread(ttf_buffer, 1, 1<<20, ttf_file)); - fclose(ttf_file); + uint8_t ttf_buffer[1<<20]; + assert("failed to load font" && load_file(_String("./bin/JetBrainsMono-Medium.ttf"), 1<<20, ttf_buffer)); stbtt_fontinfo font; stbtt_InitFont(&font, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer, 0));