HGWCXHOOMSQVV7FN3Y5BPJ2TJMUYFCWHOMD5SH6LJKVKWPQV2BXAC
}
void _gl_debug_message_callback(uint32_t source, uint32_t type, uint32_t id, uint32_t severity, int length, const char *message, const void *ud) {
const char *source_str = source == GL_DEBUG_SOURCE_API ? "API"
: source == GL_DEBUG_SOURCE_WINDOW_SYSTEM ? "Window System"
: source == GL_DEBUG_SOURCE_SHADER_COMPILER ? "Shader Compiler"
: source == GL_DEBUG_SOURCE_THIRD_PARTY ? "Third Party"
: source == GL_DEBUG_SOURCE_APPLICATION ? "Application"
: source == GL_DEBUG_SOURCE_OTHER ? "Other"
: "Invalid";
const char *type_str = type == GL_DEBUG_TYPE_ERROR ? "Error"
: type == GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR ? "Deprecated Behavior"
: type == GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR ? "Undefined Behavior"
: type == GL_DEBUG_TYPE_PORTABILITY ? "Portability"
: type == GL_DEBUG_TYPE_PERFORMANCE ? "Performance"
: type == GL_DEBUG_TYPE_MARKER ? "Marker"
: type == GL_DEBUG_TYPE_PUSH_GROUP ? "Push Group"
: type == GL_DEBUG_TYPE_POP_GROUP ? "Pop Group"
: type == GL_DEBUG_TYPE_OTHER ? "Other"
: "Invalid";
switch(severity) {
case GL_DEBUG_SEVERITY_HIGH:
default:
engine_error("%s from %s: %.*s", type_str, source_str, length, message);
break;
case GL_DEBUG_SEVERITY_MEDIUM:
engine_warning("%s from %s: %.*s", type_str, source_str, length, message);
break;
case GL_DEBUG_SEVERITY_LOW:
engine_debug("%s from %s: %.*s", type_str, source_str, length, message);
break;
case GL_DEBUG_SEVERITY_NOTIFICATION:
engine_info("%s from %s: %.*s", type_str, source_str, length, message);
break;
}
int c = 1;
while(c < argc) {
if(argv[c][0] == '-') {
uint32_t start = c;
c++;
while(c < argc && (argv[c][0] == '-' || argv[c][0] == '+')) c++;
// process -set arguments
i = 1;
while(i < argc) {
if(argv[i] == NULL) {
i++;
continue;
}
if(argv[i][0] == '-' && argv[i][1] == 's' && argv[i][2] == 'e' && argv[i][3] == 't' && argv[i][4] == 0) {
uint32_t start = i;
i++;
while(i < argc && argv[i][0] != '-' && argv[i][0] != '+') i++;
// now files commands have been run, files are loaded. we can loop again for the rendering timer.
// but first, process the + arguments
i = 1;
while(i < argc) {
if(argv[i] == NULL) {
i++;
continue;
}
if(argv[i][0] == '-' || argv[i][0] == '+') {
uint32_t start = i;
i++;
while(i < argc && argv[i][0] != '-' && argv[i][0] != '+') i++;
argv[start] += 1;
_command_execute(i - start, (char const * const *)(argv + start));
for(uint32_t j = start; j < i; j++) {
argv[j] = NULL;
}
} else {
engine_error("unused argument %s", argv[i]);
i++;
}
}
ENGINE_STRING(fs_basedir, ".", "filesystem base directory, defaults to '.'")
static struct alias_DirectoryList _fs_paths;
static void _fs_init(void) {
alias_DirectoryList_init(&_fs_paths);
alias_DirectoryList_add_path(&_fs_paths, NULL, fs_basedir);
}
static alias_Vector(struct engine_Command *) _command_all = ALIAS_VECTOR_INIT;
static alias_Vector(uint32_t) _command_by_name = ALIAS_VECTOR_INIT;
static int _command_by_name_compare(const void *ap, const void *bp, void *ud) {
uint32_t a = *(uint32_t *)ap;
uint32_t b = *(uint32_t *)bp;
return strcmp(_command_all.data[a]->name, _command_all.data[b]->name);
}
static struct engine_Command ** _command_find(const char * name) {
if(_command_all.length == 0) {
return NULL;
}
struct engine_Command _search_command = {.name = name};
uint32_t key = _command_all.length;
_command_all.data[key] = &_search_command;
uint32_t *found = bsearch(&key, _command_by_name.data, _command_by_name.length, sizeof(*_command_by_name.data), _command_by_name_compare, NULL);
if(found == NULL) {
return NULL;
}
return &_command_all.data[*found];
}
static void _command_insert(struct engine_Command *cmd) {
uint32_t index = _command_all.length;
alias_Vector_space_for(&_command_all, NULL, 2);
alias_Vector_space_for(&_command_by_name, NULL, 2);
*alias_Vector_push(&_command_all) = cmd;
*alias_Vector_push(&_command_by_name) = index;
qsort(_command_by_name.data, _command_by_name.length, sizeof(*_command_by_name.data), _command_by_name_compare, NULL);
}
void engine_command_execute(int argc, char const * const * argv) {
static void _command_execute(int argc, char const * const * argv) {
struct engine_Command **cmd_ptr = _command_find(argv[0]);
if(cmd_ptr == NULL) {
engine_error("unknown command %s", argv[0]);
return;
}
(*cmd_ptr)->f(argc, argv);
#define ENGINE_STRING(NAME, DEFAULT, HELP) \
const char *NAME = DEFAULT; \
struct engine_Variable NAME##__var = { \
.tag = engine_Variable_string, \
.name = #NAME, \
.help = HELP, \
._string.ptr = &NAME, \
}; \
static void __attribute__((constructor)) NAME##__register(void) { engine_variable_register(&NAME##__var); }