src/context.c

changeset 95
622887f7e954
parent 92
78ce93fb46e5
--- a/src/context.c	Thu Apr 24 18:41:42 2025 +0200
+++ b/src/context.c	Thu Apr 24 19:53:40 2025 +0200
@@ -26,17 +26,96 @@
  */
 
 #include "ascension/context.h"
-#include "ascension/error.h"
-#include "ascension/utils.h"
 
 #include <SDL2/SDL.h>
 #include <SDL2/SDL_ttf.h>
 #include <SDL2/SDL_image.h>
 
+#include <GL/gl.h>
+
+#include <cx/printf.h>
+
 #include <time.h>
 
 AscContext asc_context;
 
+void asc_error_impl(const char* file, unsigned line, char const* fmt, ...) {
+    asc_set_flag(asc_context.flags, ASC_FLAG_HAS_ERROR);
+
+    // write to error buffer
+    va_list args;
+    va_start(args, fmt);
+    CxBuffer* buf = &asc_context.error_buffer;
+    size_t bufpos = buf->pos;
+    int written = cx_vfprintf(buf, cxBufferWriteFunc, fmt, args);
+    cxBufferPut(buf, '\n');
+    va_end(args);
+
+    // also print to stderr
+    // avoid double-formatting, get it directly from the buffer
+    fprintf(stderr, "[ERROR %s %u] %.*s\n",
+        file, line, written, buf->space+bufpos);
+}
+
+bool asc_has_error(void) {
+    return asc_test_flag(asc_context.flags, ASC_FLAG_HAS_ERROR);
+}
+
+char const* asc_get_error(void) {
+    // we zero-terminate the current buffer contents before providing them
+    cxBufferPut(&asc_context.error_buffer, 0);
+    --asc_context.error_buffer.pos;
+    --asc_context.error_buffer.size;
+    return asc_context.error_buffer.space;
+}
+
+void asc_clear_error(void) {
+    cxBufferClear(&asc_context.error_buffer);
+    asc_clear_flag(asc_context.flags, ASC_FLAG_HAS_ERROR);
+}
+
+void asc_error_gl(unsigned code, const char *message) {
+    const char *glerr;
+    switch(code) {
+        case GL_NO_ERROR:
+            return;
+        case GL_INVALID_ENUM:
+            glerr = "invalid enum";
+            break;
+        case GL_INVALID_VALUE:
+            glerr = "invalid value";
+            break;
+        case GL_INVALID_OPERATION:
+            glerr = "invalid operation";
+            break;
+        case GL_INVALID_FRAMEBUFFER_OPERATION:
+            glerr = "invalid framebuffer operation";
+            break;
+        case GL_OUT_OF_MEMORY:
+            glerr = "out of memory";
+            break;
+        case GL_STACK_UNDERFLOW:
+            glerr = "stack underflow";
+            break;
+        case GL_STACK_OVERFLOW:
+            glerr = "stack overflow";
+            break;
+        default:
+            glerr = "unknown GL error";
+    }
+    asc_error("%s\nGL Error: %s", message, glerr);
+}
+
+int asc_error_catch_all_gl(void) {
+    GLenum error;
+    int ret = 0;
+    while ((error = glGetError()) != GL_NO_ERROR) {
+        asc_error_gl(error, "Uncaught");
+        ret = 1;
+    }
+    return ret;
+}
+
 static uint64_t asc_nanos(void) {
     struct timespec ts;
     clock_gettime(CLOCK_MONOTONIC, &ts);

mercurial