added basic logging
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 17 Oct 2020 19:06:48 +0000 (14:06 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 17 Oct 2020 19:06:48 +0000 (14:06 -0500)
Makefile
include/log.h [new file with mode: 0644]
include/utils.h
src/log.c [new file with mode: 0644]
src/sim.c
src/utils.c

index a0c02c15c7ce25f3dde0840193a5c79490e5b212..717f3ed4971b88c5600130690af1003b4d9ad6d3 100644 (file)
--- 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 (file)
index 0000000..1860941
--- /dev/null
@@ -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
index 1c0e0dc5638cefa8713405ab2625935a994a9471..a0263a2e58a7f4281fba96e5b329e9421d0ef1eb 100644 (file)
@@ -3,11 +3,14 @@
 
 #include <stdint.h> // 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 (file)
index 0000000..e3d49c0
--- /dev/null
+++ b/src/log.c
@@ -0,0 +1,29 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+#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
index 3f452b6cfeeb78f5c594bb24fed183152fa2c0ce..7aeae0f1bc791f7c10a9f0021d50ea090f369ede 100644 (file)
--- a/src/sim.c
+++ b/src/sim.c
 #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");
index 96faa94c63950c8d1e1e5838f5738dbe0246602a..7cbace5d533e9934bd302de5fce528bb46f29190 100644 (file)
@@ -2,13 +2,15 @@
 #include <stdarg.h>
 #include <stdlib.h>
 
+#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.