feat: config variables, mutex abstraction
- Mutex abstraction (create, destroy, lock, unlock) - Config variables (cvars)
This commit is contained in:
		
							parent
							
								
									1dba3d2d63
								
							
						
					
					
						commit
						63e3f973b2
					
				
							
								
								
									
										43
									
								
								include/config.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								include/config.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,43 @@
 | 
				
			|||||||
 | 
					#ifndef VY_CONFIG_H
 | 
				
			||||||
 | 
					#define VY_CONFIG_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    VY_CVAR_TYPE_INT,
 | 
				
			||||||
 | 
					    VY_CVAR_TYPE_FLOAT,
 | 
				
			||||||
 | 
					    VY_CVAR_TYPE_STRING,
 | 
				
			||||||
 | 
					} vy_cvar_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    const char *name;
 | 
				
			||||||
 | 
					    const char *description;
 | 
				
			||||||
 | 
					    union {
 | 
				
			||||||
 | 
					        int i;
 | 
				
			||||||
 | 
					        float f;
 | 
				
			||||||
 | 
					        const char *s;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    vy_cvar_type type;
 | 
				
			||||||
 | 
					} vy_cvar;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VY_CVAR_I(n, d, v)                                                     \
 | 
				
			||||||
 | 
					    vy_cvar n = {.name        = #n,                                            \
 | 
				
			||||||
 | 
					                 .description = d,                                             \
 | 
				
			||||||
 | 
					                 .i           = (v),                                           \
 | 
				
			||||||
 | 
					                 .type        = VY_CVAR_TYPE_INT}
 | 
				
			||||||
 | 
					#define VY_CVAR_F(n, d, v)                                                     \
 | 
				
			||||||
 | 
					    vy_cvar n = {.name        = #n,                                            \
 | 
				
			||||||
 | 
					                 .description = d,                                             \
 | 
				
			||||||
 | 
					                 .f           = (v),                                           \
 | 
				
			||||||
 | 
					                 .type        = VY_CVAR_TYPE_FLOAT}
 | 
				
			||||||
 | 
					#define VY_CVAR_S(n, d, v)                                                     \
 | 
				
			||||||
 | 
					    vy_cvar n = {.name        = #n,                                            \
 | 
				
			||||||
 | 
					                 .description = d,                                             \
 | 
				
			||||||
 | 
					                 .s           = (v),                                           \
 | 
				
			||||||
 | 
					                 .type        = VY_CVAR_TYPE_STRING}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void vyRegisterCVAR(vy_cvar *cvar);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vy_cvar *vyGetCVAR(const char *name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										18
									
								
								include/threading.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								include/threading.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					#ifndef VY_THREADING_H
 | 
				
			||||||
 | 
					#define VY_THREADING_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* platform independent threading */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdbool.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct vy_mutex_s vy_mutex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vy_mutex *vyCreateMutex(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void vyDestroyMutex(vy_mutex *mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool vyLockMutex(vy_mutex *mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool vyUnlockMutex(vy_mutex *mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
@ -6,6 +6,7 @@
 | 
				
			|||||||
#include <stddef.h>
 | 
					#include <stddef.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define VY_UNUSED(x) ((void)sizeof((x)))
 | 
					#define VY_UNUSED(x) ((void)sizeof((x)))
 | 
				
			||||||
 | 
					#define VY_ARRAY_COUNT(x) (sizeof((x)) / sizeof((x)[0]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
    const char *start;
 | 
					    const char *start;
 | 
				
			||||||
 | 
				
			|||||||
@ -13,9 +13,12 @@ if compiler.get_argument_syntax() == 'gcc'
 | 
				
			|||||||
    )
 | 
					    )
 | 
				
			||||||
elif compiler.get_argument_syntax() == 'msvc'
 | 
					elif compiler.get_argument_syntax() == 'msvc'
 | 
				
			||||||
  add_project_arguments(
 | 
					  add_project_arguments(
 | 
				
			||||||
    ['/wd4146', '/wd4245', '/wd4100', '/D_CRT_SECURE_NO_WARNINGS', '/RTCsu'],
 | 
					    ['/wd4146', '/wd4245', '/wd4100', '/D_CRT_SECURE_NO_WARNINGS'],
 | 
				
			||||||
    language:  'c'
 | 
					    language:  'c'
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					  if buildtype == 'debug'
 | 
				
			||||||
 | 
					    add_project_arguments(['/RTCsu'], language : 'c')
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Debug specific flags
 | 
					# Debug specific flags
 | 
				
			||||||
@ -41,6 +44,8 @@ executable('voyage',
 | 
				
			|||||||
  'include/gfx.h',
 | 
					  'include/gfx.h',
 | 
				
			||||||
  'include/gfx_backend.h',
 | 
					  'include/gfx_backend.h',
 | 
				
			||||||
  'include/fio.h',
 | 
					  'include/fio.h',
 | 
				
			||||||
 | 
					  'include/config.h',
 | 
				
			||||||
 | 
					  'include/threading.h',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  'src/voyage.c',
 | 
					  'src/voyage.c',
 | 
				
			||||||
  'src/fio.c',
 | 
					  'src/fio.c',
 | 
				
			||||||
@ -48,6 +53,8 @@ executable('voyage',
 | 
				
			|||||||
  'src/gfx_main.c',
 | 
					  'src/gfx_main.c',
 | 
				
			||||||
  'src/gfx_shader_loading.c',
 | 
					  'src/gfx_shader_loading.c',
 | 
				
			||||||
  'src/gfx_pipelines.c',
 | 
					  'src/gfx_pipelines.c',
 | 
				
			||||||
 | 
					  'src/config.c',
 | 
				
			||||||
 | 
					  'src/threading.c',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Contrib Sources
 | 
					  # Contrib Sources
 | 
				
			||||||
  'contrib/glad/glad.c',
 | 
					  'contrib/glad/glad.c',
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										39
									
								
								src/config.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								src/config.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,39 @@
 | 
				
			|||||||
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					#include "threading.h"
 | 
				
			||||||
 | 
					#include "voyage.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stddef.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VY_MAX_CVARS 1024
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static vy_cvar *_vars[VY_MAX_CVARS];
 | 
				
			||||||
 | 
					static unsigned int _next = 0;
 | 
				
			||||||
 | 
					static vy_mutex *_mutex   = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void vyRegisterCVAR(vy_cvar *cvar) {
 | 
				
			||||||
 | 
					    if (!_mutex)
 | 
				
			||||||
 | 
					        _mutex = vyCreateMutex();
 | 
				
			||||||
 | 
					    vyLockMutex(_mutex);
 | 
				
			||||||
 | 
					    if (_next < VY_MAX_CVARS) {
 | 
				
			||||||
 | 
					        _vars[_next++] = cvar;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        vyReportError("cvar", "Ran out of space for CVars");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    vyUnlockMutex(_mutex);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vy_cvar *vyGetCVAR(const char *name) {
 | 
				
			||||||
 | 
					    if (!_mutex)
 | 
				
			||||||
 | 
					        _mutex = vyCreateMutex();
 | 
				
			||||||
 | 
					    vy_cvar *var = NULL;
 | 
				
			||||||
 | 
					    vyLockMutex(_mutex);
 | 
				
			||||||
 | 
					    for (unsigned int i = 0; i < _next; ++i) {
 | 
				
			||||||
 | 
					        if (strcmp(name, _vars[i]->name) == 0) {
 | 
				
			||||||
 | 
					            var = _vars[i];
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    vyUnlockMutex(_mutex);
 | 
				
			||||||
 | 
					    return var;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -3,22 +3,66 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "voyage.h"
 | 
					#include "voyage.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _WIN32
 | 
				
			||||||
 | 
					#define WIN32_LEAN_AND_MEAN
 | 
				
			||||||
 | 
					#include <Windows.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* TODO(Kevin): Log to file, show error message box, ... */
 | 
					/* TODO(Kevin): Log to file, show error message box, ... */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void DisplayErrorBox(const char *text)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#ifdef _WIN32
 | 
				
			||||||
 | 
					    WCHAR msg[256];
 | 
				
			||||||
 | 
					    MultiByteToWideChar(CP_UTF8,
 | 
				
			||||||
 | 
					                        MB_PRECOMPOSED,
 | 
				
			||||||
 | 
					                        text,
 | 
				
			||||||
 | 
					                        -1,
 | 
				
			||||||
 | 
					                        msg,
 | 
				
			||||||
 | 
					                        VY_ARRAY_COUNT(msg));
 | 
				
			||||||
 | 
					    MessageBoxW(NULL, msg, L"Error", MB_ICONERROR);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void LogOut(const char *text)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#ifdef _WIN32
 | 
				
			||||||
 | 
					    WCHAR msg[256];
 | 
				
			||||||
 | 
					    MultiByteToWideChar(CP_UTF8,
 | 
				
			||||||
 | 
					                        MB_PRECOMPOSED,
 | 
				
			||||||
 | 
					                        text,
 | 
				
			||||||
 | 
					                        -1,
 | 
				
			||||||
 | 
					                        msg,
 | 
				
			||||||
 | 
					                        VY_ARRAY_COUNT(msg));
 | 
				
			||||||
 | 
					    OutputDebugStringW(msg);
 | 
				
			||||||
 | 
					#elif defined(__linux__)
 | 
				
			||||||
 | 
					    fprintf(stderr, "%s", text);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void vyReportError(const char *subsystem, const char *fmt, ...) {
 | 
					void vyReportError(const char *subsystem, const char *fmt, ...) {
 | 
				
			||||||
 | 
					    char buf[256];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int at = snprintf(buf, VY_ARRAY_COUNT(buf) - 1, "[%s] ", subsystem);
 | 
				
			||||||
    va_list ap;
 | 
					    va_list ap;
 | 
				
			||||||
    va_start(ap, fmt);
 | 
					    va_start(ap, fmt);
 | 
				
			||||||
    fprintf(stderr, "[%s] ", subsystem);
 | 
					    at += vsnprintf(&buf[at], VY_ARRAY_COUNT(buf) - at - 1, fmt, ap);
 | 
				
			||||||
    vfprintf(stderr, fmt, ap);
 | 
					 | 
				
			||||||
    fprintf(stderr, "\n");
 | 
					 | 
				
			||||||
    va_end(ap);
 | 
					    va_end(ap);
 | 
				
			||||||
 | 
					    at += snprintf(&buf[at], VY_ARRAY_COUNT(buf) - at - 1, "\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    LogOut(buf);
 | 
				
			||||||
 | 
					    DisplayErrorBox(buf);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void vyLog(const char *subsystem, const char *fmt, ...) {
 | 
					void vyLog(const char *subsystem, const char *fmt, ...) {
 | 
				
			||||||
 | 
					    char buf[256];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int at = snprintf(buf, VY_ARRAY_COUNT(buf) - 1, "[%s] ", subsystem);
 | 
				
			||||||
    va_list ap;
 | 
					    va_list ap;
 | 
				
			||||||
    va_start(ap, fmt);
 | 
					    va_start(ap, fmt);
 | 
				
			||||||
    fprintf(stderr, "[%s] ", subsystem);
 | 
					    at += vsnprintf(&buf[at], VY_ARRAY_COUNT(buf) - at - 1, fmt, ap);
 | 
				
			||||||
    vfprintf(stderr, fmt, ap);
 | 
					 | 
				
			||||||
    fprintf(stderr, "\n");
 | 
					 | 
				
			||||||
    va_end(ap);
 | 
					    va_end(ap);
 | 
				
			||||||
 | 
					    at += snprintf(&buf[at], VY_ARRAY_COUNT(buf) - at - 1, "\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    LogOut(buf);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -233,7 +233,7 @@ static void DbgPrintShaderFile(const vy_parse_state *state,
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        stmt_index = stmt->next;
 | 
					        stmt_index = stmt->next;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    assert(stmt_index == UINT_MAX);
 | 
					    assert(stmt_index == UINT_MAX || stmt_index == 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool CompareSpanToString(vy_text_span span, const char *cmp) {
 | 
					static bool CompareSpanToString(vy_text_span span, const char *cmp) {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										98
									
								
								src/threading.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								src/threading.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,98 @@
 | 
				
			|||||||
 | 
					#include "threading.h"
 | 
				
			||||||
 | 
					#include "voyage.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _WIN32
 | 
				
			||||||
 | 
					#define WIN32_LEAN_AND_MEAN
 | 
				
			||||||
 | 
					#include <Windows.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct vy_mutex_s {
 | 
				
			||||||
 | 
					    HANDLE handle;
 | 
				
			||||||
 | 
					    ptrdiff_t next_reusable;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MAX_MUTEX 1024
 | 
				
			||||||
 | 
					static vy_mutex _mutex[MAX_MUTEX];
 | 
				
			||||||
 | 
					static ptrdiff_t _first_reusable = MAX_MUTEX;
 | 
				
			||||||
 | 
					static ptrdiff_t _next       = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vy_mutex *vyCreateMutex(void) {
 | 
				
			||||||
 | 
					    if (_first_reusable < MAX_MUTEX) {
 | 
				
			||||||
 | 
					        vy_mutex *mtx   = &_mutex[_first_reusable];
 | 
				
			||||||
 | 
					        _first_reusable = mtx->next_reusable;
 | 
				
			||||||
 | 
					        return mtx;
 | 
				
			||||||
 | 
					    } else if (_next < MAX_MUTEX) {
 | 
				
			||||||
 | 
					        vy_mutex *mtx = &_mutex[_next];
 | 
				
			||||||
 | 
					        mtx->handle   = CreateMutexW(NULL, FALSE, NULL);
 | 
				
			||||||
 | 
					        if (!mtx->handle) {
 | 
				
			||||||
 | 
					            vyLog("core", "Mutex creation failed: %u", GetLastError());
 | 
				
			||||||
 | 
					            return NULL;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        mtx->next_reusable = MAX_MUTEX;
 | 
				
			||||||
 | 
					        ++_next;
 | 
				
			||||||
 | 
					        return mtx;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    vyReportError("core", "Ran out of mutex objects");
 | 
				
			||||||
 | 
					    return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void vyDestroyMutex(vy_mutex *mutex) {
 | 
				
			||||||
 | 
					    ptrdiff_t index      = mutex - &_mutex[0];
 | 
				
			||||||
 | 
					    mutex->next_reusable = _first_reusable;
 | 
				
			||||||
 | 
					    _first_reusable      = index;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool vyLockMutex(vy_mutex *mutex) {
 | 
				
			||||||
 | 
					    return WaitForSingleObject(mutex->handle, INFINITE) == WAIT_OBJECT_0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool vyUnlockMutex(vy_mutex *mutex) {
 | 
				
			||||||
 | 
					    return ReleaseMutex(mutex) != 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#elif defined(__linux__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <pthread.h>
 | 
				
			||||||
 | 
					struct vy_mutex_s {
 | 
				
			||||||
 | 
					    pthread_mutex_t handle;
 | 
				
			||||||
 | 
					    ptrdiff_t next_reusable;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #define MAX_MUTEX 1024
 | 
				
			||||||
 | 
					static vy_mutex _mutex[MAX_MUTEX];
 | 
				
			||||||
 | 
					static ptrdiff_t _first_reusable = MAX_MUTEX;
 | 
				
			||||||
 | 
					static ptrdiff_t _next           = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vy_mutex *vyCreateMutex(void) {
 | 
				
			||||||
 | 
					    if (_first_reusable < MAX_MUTEX) {
 | 
				
			||||||
 | 
					        vy_mutex *mtx   = &_mutex[_first_reusable];
 | 
				
			||||||
 | 
					        _first_reusable = mtx->next_reusable;
 | 
				
			||||||
 | 
					        return mtx;
 | 
				
			||||||
 | 
					    } else if (_next < MAX_MUTEX) {
 | 
				
			||||||
 | 
					        vy_mutex *mtx = &_mutex[_next];
 | 
				
			||||||
 | 
					        if (pthread_mutex_init(&mtx->handle, NULL) != 0) {
 | 
				
			||||||
 | 
					            vyLog("core", "Mutex creation failed: %u", GetLastError());
 | 
				
			||||||
 | 
					            return NULL;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        mtx->next_reusable = MAX_MUTEX;
 | 
				
			||||||
 | 
					        ++_next;
 | 
				
			||||||
 | 
					        return mtx;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    vyReportError("core", "Ran out of mutex objects");
 | 
				
			||||||
 | 
					    return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void vyDestroyMutex(vy_mutex *mutex) {
 | 
				
			||||||
 | 
					    ptrdiff_t index      = mutex - &_mutex[0];
 | 
				
			||||||
 | 
					    mutex->next_reusable = _first_reusable;
 | 
				
			||||||
 | 
					    _first_reusable      = index;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool vyLockMutex(vy_mutex *mutex) {
 | 
				
			||||||
 | 
					    return pthread_mutex_lock(&mutex->handle) == 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool vyUnlockMutex(vy_mutex *mutex) {
 | 
				
			||||||
 | 
					    return pthread_mutex_unlock(&mutex->handle) == 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
@ -7,6 +7,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "fio.h"
 | 
					#include "fio.h"
 | 
				
			||||||
#include "gfx.h"
 | 
					#include "gfx.h"
 | 
				
			||||||
 | 
					#include "threading.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void glfw_error_cb(int err, const char *description) {
 | 
					static void glfw_error_cb(int err, const char *description) {
 | 
				
			||||||
    fprintf(stderr, "[GLFW] %u: %s\n", err, description);
 | 
					    fprintf(stderr, "[GLFW] %u: %s\n", err, description);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user