From b5e9536fa83120f1dad7f61fde123d974be150da Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Sat, 17 Oct 2020 14:06:48 -0500 Subject: [PATCH] added basic logging --- Makefile | 1 + include/log.h | 17 +++++++++++++++++ include/utils.h | 9 ++++++--- src/log.c | 29 ++++++++++++++++++++++++++++ src/sim.c | 51 +++++++++++++++++++++++++++++++++++-------------- src/utils.c | 10 ++++++---- 6 files changed, 96 insertions(+), 21 deletions(-) create mode 100644 include/log.h create mode 100644 src/log.c diff --git a/Makefile b/Makefile index a0c02c1..717f3ed 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,7 @@ RELEASE=0 OBJ_FILES=\ + build/log.o \ build/utils.o \ build/vecmath.o \ build/physics.o \ diff --git a/include/log.h b/include/log.h new file mode 100644 index 0000000..1860941 --- /dev/null +++ b/include/log.h @@ -0,0 +1,17 @@ +#ifndef LOG_H +#define LOG_H + +typedef enum LogLevel { + LOG_LEVEL_INFO, + LOG_LEVEL_WARNING, + LOG_LEVEL_ERROR, + + LOG_LEVEL_COUNT, +} LogLevel; + +extern LogLevel LOG_LEVEL_MINIMUM; + +void logprint(LogLevel level, const char* format, ...); +void logvprint(LogLevel level, const char* format, va_list va); + +#endif //LOG_H diff --git a/include/utils.h b/include/utils.h index 1c0e0dc..a0263a2 100644 --- a/include/utils.h +++ b/include/utils.h @@ -3,11 +3,14 @@ #include // NOTE(Brendan): Only for intptr_t -// NOTE(Brendan): Hacky way to get the offset of a struct member. -// offsetof() is the standard way in C to get it, but it is not guarenteed -// to be defined in all C implementations. +// NOTE(Brendan): Hacky way to get the offset of a struct member. offsetof() is the standard way in C to get it, but it is not guarenteed to be defined in all C implementations. #define offset_of(S, mem) (intptr_t) &(((S*)(0))->mem) +// NOTE(Brendan): There are so many uses of 'static' in C and they quickly lose their meaning. +#define internal static // internal void foo() { ... } +#define persist static // void foo() { persist int a = 10; } +#define atleast static // void foo(int a[atleast 10]) { ... } + // NOTE(Brendan): This is useful in many situations and I believe it cleans up the code by making simple, counter based for loops easier to recognize at a glance. #define foreach(var, lo, hi) for (i32 var = lo; var < hi; var++) diff --git a/src/log.c b/src/log.c new file mode 100644 index 0000000..e3d49c0 --- /dev/null +++ b/src/log.c @@ -0,0 +1,29 @@ +#include +#include + +#include "log.h" +#include "utils.h" + +LogLevel LOG_LEVEL_MINIMUM = LOG_LEVEL_INFO; + +internal const char* log_level_strs[LOG_LEVEL_COUNT] = { + "INFO", + "WARN", + "ERROR", +}; + +void logprint(LogLevel level, const char *format, ...) { + va_list va; + va_start(va, format); + logvprint(level, format, va); + va_end(va); +} + +// NOTE(Brendan): This always prints a newline. +void logvprint(LogLevel level, const char* format, va_list va) { + if (level < LOG_LEVEL_MINIMUM) return; + + printf("[%s] ", log_level_strs[level]); + vprintf(format, va); + printf("\n"); +} \ No newline at end of file diff --git a/src/sim.c b/src/sim.c index 3f452b6..7aeae0f 100644 --- a/src/sim.c +++ b/src/sim.c @@ -15,27 +15,35 @@ #include "utils.h" #include "physics.h" +#include "log.h" + #define PI 3.141592653589793238462643383 #define WINDOW_WIDTH 1600 #define WINDOW_HEIGHT 900 #define WINDOW_TITLE "N-Body Simulation" -void glfw_key_handler(GLFWwindow* window, i32 key, i32 scancode, i32 action, i32 mods) { +internal void +glfw_key_handler(GLFWwindow* window, i32 key, i32 scancode, i32 action, i32 mods) { if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) glfwSetWindowShouldClose(window, 1); } -void glfw_resize_handler(GLFWwindow* window, i32 width, i32 height) { +internal void +glfw_resize_handler(GLFWwindow* window, i32 width, i32 height) { glViewport(0, 0, width, height); } -void glfw_error_handler(i32 error, const char* desc) { +internal void +glfw_error_handler(i32 error, const char* desc) { panic_and_die("GLFW Error (%d): %s\n", error, desc); } GLFWwindow* window; -void init_glfw() { +internal void +init_glfw() { + logprint(LOG_LEVEL_INFO, "Initializing GLFW"); + if (!glfwInit()) panic_and_die("Failed to initalize GLFW."); glfwSetErrorCallback(glfw_error_handler); @@ -52,7 +60,10 @@ void init_glfw() { glCullFace(GL_CCW); } -GLuint load_shader(GLenum shader_type, const char* shader_loc) { +internal GLuint +load_shader(GLenum shader_type, const char* shader_loc) { + logprint(LOG_LEVEL_INFO, "Loading shader: %s", shader_loc); + GLuint shader = glCreateShader(shader_type); FILE* shader_file = fopen(shader_loc, "rb"); @@ -79,7 +90,9 @@ GLuint load_shader(GLenum shader_type, const char* shader_loc) { glGetShaderInfoLog(shader, 1023, &log_length, shader_log); shader_log[log_length] = 0; - panic_and_die("Error compiling %s:\n%s\n", shader_loc, shader_log); + panic_and_die("Error compiling shader %s:\n%s\n", + shader_loc, + shader_log); } free(shader_buffer); @@ -87,7 +100,10 @@ GLuint load_shader(GLenum shader_type, const char* shader_loc) { return shader; } -GLuint create_program(GLuint vertex_shader, GLuint fragment_shader) { +internal GLuint +create_program(GLuint vertex_shader, GLuint fragment_shader) { + logprint(LOG_LEVEL_INFO, "Linking GL program"); + GLuint program = glCreateProgram(); glAttachShader(program, vertex_shader); glAttachShader(program, fragment_shader); @@ -116,7 +132,10 @@ GLuint create_program(GLuint vertex_shader, GLuint fragment_shader) { #define CIRCLE_POINT_COUNT 36 // NOTE(Brendan): Treat a circle as a many-sided polygon. // NOTE(Brendan): Returns the VAO where the mesh data was bound. -GLsizei create_circle_mesh() { +internal GLsizei +create_circle_mesh() { + logprint(LOG_LEVEL_INFO, "Generating circle mesh"); + GLsizei vao; glGenVertexArrays(1, &vao); glBindVertexArray(vao); @@ -149,17 +168,20 @@ GLsizei create_circle_mesh() { return vao; } -void deinit_opengl() { +internal void +deinit_opengl() { glfwDestroyWindow(window); glfwTerminate(); } // NOTE(Brendan): dt is expected to be in units of "per second". -void update(f64 dt) { +internal void +update(f64 dt) { } -GLsizei circle_mesh; -void draw() { +internal GLsizei circle_mesh; +internal void +draw() { glClearColor(0.1, 0.1, 0.1, 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -170,7 +192,8 @@ void draw() { glfwSwapBuffers(window); } -void loop() { +internal void +loop() { f64 last_time = glfwGetTime(); f64 curr_time = last_time; f64 delta; @@ -191,7 +214,7 @@ void loop() { i32 main(i32 argc, char* argv[]) { init_glfw(); - circle_mesh = create_circle_mesh(); + circle_mesh = create_circle_mesh(NULL); GLuint v_shader = load_shader(GL_VERTEX_SHADER, "res/shaders/planet_vert.glsl"); GLuint f_shader = load_shader(GL_FRAGMENT_SHADER, "res/shaders/planet_frag.glsl"); diff --git a/src/utils.c b/src/utils.c index 96faa94..7cbace5 100644 --- a/src/utils.c +++ b/src/utils.c @@ -2,13 +2,15 @@ #include #include +#include "log.h" + void panic_and_die(const char* msg, ...) { puts("************ PANIC ************"); - va_list va; - va_start(va, msg); - vprintf(msg, va); - va_end(va); + va_list va; + va_start(va, msg); + logvprint(LOG_LEVEL_ERROR, msg, va); + va_end(va); #ifdef DEBUG // NOTE: This allows for a debugger to stop here. -- 2.25.1