Wed, 02 Jul 2025 23:21:17 +0200
resolve TODOs regarding input.h
a) mouse position must be integer, because it can be negative (though rarely)
b) we should not trade "access complexity" for space in the scancodes array
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * Copyright 2025 Mike Becker. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include "ascension/context.h" #include "ascension/error.h" #include <stdio.h> #include <stdarg.h> #include <cx/printf.h> #include <GL/glew.h> void asc_printf(const char *level, const char *file, unsigned line, const char *fmt, ...) { printf("[%s %s %u] ", level, file, line); va_list ap; va_start(ap, fmt); vprintf(fmt, ap); va_end(ap); putchar('\n'); } void asc_error_(const char *file, unsigned line, const char *fmt, ...) { asc_set_flag(asc_context.flags, ASC_FLAG_HAS_ERROR); // write to error buffer CxBuffer *buf = &asc_context.error_buffer; size_t bufpos = buf->pos; va_list args; va_start(args, fmt); 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); } const char *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; }