medfall

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit 975e4b8539fd6e3ba247529b15a92dc7aaaf3437
parent 640d0e6c72e0dfba1db0ec9f312cd10279fcc299
Author: Michael Savage <mikejsavage@gmail.com>
Date:   Sat Feb 20 16:30:18 +0000

Add logging subsystem

Diffstat:
.gitignore | 2++
Makefile | 6+++---
gl.cc | 20+++++++++++---------
log.cc | 49+++++++++++++++++++++++++++++++++++++++++++++++++
log.h | 22++++++++++++++++++++++
main.cc | 6+++---
terrain_manager.cc | 4++--
unix_thread.h | 13+++++++++++++
8 files changed, 105 insertions(+), 17 deletions(-)
diff --git a/.gitignore b/.gitignore @@ -2,6 +2,8 @@ medfall pp sound +logs + *.o *.so stb_*.cc diff --git a/Makefile b/Makefile @@ -5,8 +5,8 @@ STBS := truetype image image_write perlin all: $(BINS) $(MODULES) # Binary dependencies -medfall: main.o gl.o memory_arena.o -pp: pp.o stb_image.o stb_image_write.o +medfall: main.o gl.o log.o memory_arena.o +pp: pp.o stb_image.o log.o stb_image_write.o sound: linux_audio.o wave.o audio.o memory_arena.o # Module dependencies @@ -17,7 +17,7 @@ audio.so: test_audio.o audio.o wave.o linux_audio.o sm.so: shadow_map.o # Common dependencies -COMMON_OBJS := memory_arena.o work_queue.o immediate.o benchmark.o stb_truetype.o stb_image.o +COMMON_OBJS := log.o memory_arena.o work_queue.o immediate.o benchmark.o stb_truetype.o stb_image.o # Compiler flags WARNINGS := -Wall -Wextra -Wno-unused-parameter -Wno-unused-function diff --git a/gl.cc b/gl.cc @@ -1,5 +1,5 @@ #include <stdlib.h> -#include <err.h> +#include <string.h> #include "platform_opengl.h" #include <GLFW/glfw3.h> @@ -9,6 +9,7 @@ #endif #include "game.h" +#include "log.h" #include "gl.h" #define RESET "\x1b[0m" @@ -53,10 +54,11 @@ static void gl_error_printer( const GLenum source, const GLenum type, const GLuint id, const GLenum severity, const GLsizei length, const GLchar * const message, const void * _ ) { - warnx( "GL [%s - %s]: %s", + // %.*s because we don't want the trailing \n + WARN( "GL [%s - %s]: %.*s", type_string( type ), severity_string( severity ), - message ); + strlen( message ) - 1, message ); if( severity == GL_DEBUG_SEVERITY_HIGH ) { exit( 1 ); @@ -65,14 +67,14 @@ static void gl_error_printer( #endif static void glfw_error_printer( const int code, const char * const message ) { - warnx( "GLFW error %d: %s", code, message ); + WARN( "GLFW error %d: %s", code, message ); } GLFWwindow * gl_init() { glfwSetErrorCallback( glfw_error_printer ); if( !glfwInit() ) { - errx( 1, "glfwInit" ); + ERROR( "glfwInit" ); } glfwWindowHint( GLFW_RESIZABLE, 0 ); @@ -85,7 +87,7 @@ GLFWwindow * gl_init() { GLFWwindow * const window = glfwCreateWindow( WIDTH, HEIGHT, "bsp", NULL, NULL ); if( !window ) { - errx( 1, "glfwCreateWindow" ); + ERROR( "glfwCreateWindow" ); } glfwMakeContextCurrent( window ); @@ -94,15 +96,15 @@ GLFWwindow * gl_init() { glewExperimental = true; GLenum glew_error = glewInit(); if( glew_error != GLEW_OK ) { - errx( 1, "glewInit: %s", glewGetErrorString( glew_error ) ); + ERROR( "glewInit: %s", glewGetErrorString( glew_error ) ); } glEnable( GL_DEBUG_OUTPUT ); glDebugMessageCallback( gl_error_printer, NULL ); #endif - warnx( "Version %s", glGetString( GL_VERSION ) ); - warnx( "Vendor %s", glGetString( GL_VENDOR ) ); + INFO( "Version %s", glGetString( GL_VERSION ) ); + INFO( "Vendor %s", glGetString( GL_VENDOR ) ); glEnable( GL_DEPTH_TEST ); glDepthFunc( GL_LEQUAL ); diff --git a/log.cc b/log.cc @@ -0,0 +1,49 @@ +#include <stdio.h> +#include <stdarg.h> +#include <time.h> + +#include "log.h" + +static bool initialised = false; +static FILE * streams[ LOGLEVEL_COUNT + 1 ]; + +static const char * names[ LOGLEVEL_COUNT + 1 ] = { + "errors", + "warnings", + "info", + "all", +}; + +// this might lead to trouble with threads +static void log_init() { + if( initialised ) return; + + for( u32 i = 0; i <= LOGLEVEL_COUNT; i++ ) { + char path[ 128 ]; + snprintf( path, sizeof( path ), "logs/%llu-%s.log", time( NULL ), names[ i ] ); + streams[ i ] = fopen( path, "w" ); + assert( streams[ i ] ); + } + + initialised = true; +} + +// TODO: print time? +void log_generic( LogLevel level, const char * fmt, ... ) { + log_init(); + + va_list argp; + va_start( argp, fmt ); + FILE * stream = level == LOGLEVEL_INFO ? stdout : stderr; + vfprintf( stream, fmt, argp ); + va_end( argp ); + va_start( argp, fmt ); + vfprintf( streams[ level ], fmt, argp ); + va_end( argp ); + va_start( argp, fmt ); + vfprintf( streams[ LOGLEVEL_COUNT ], fmt, argp ); + va_end( argp ); + + fflush( streams[ level ] ); + fflush( streams[ LOGLEVEL_COUNT ] ); +} diff --git a/log.h b/log.h @@ -0,0 +1,22 @@ +#ifndef _LOG_H_ +#define _LOG_H_ + +#include <stdlib.h> + +#include "platform_thread.h" + +enum LogLevel { + LOGLEVEL_ERROR, + LOGLEVEL_WARNING, + LOGLEVEL_INFO, + + LOGLEVEL_COUNT, +}; + +void log_generic( LogLevel level, const char * fmt, ... ); + +#define INFO( form, ... ) log_generic( LOGLEVEL_INFO, "[INFO] [thread %u] " form "\n", thread_getid(), ##__VA_ARGS__ ) +#define WARN( form, ... ) log_generic( LOGLEVEL_WARNING, "[WARN] [thread %u] " form "\n", thread_getid(), ##__VA_ARGS__ ) +#define ERROR( form, ... ) do { log_generic( LOGLEVEL_ERROR, "[ERROR] [thread %u] " form "\n", thread_getid(), ##__VA_ARGS__ ); exit( 1 ); } while( 0 ) + +#endif // _LOG_H_ diff --git a/main.cc b/main.cc @@ -1,5 +1,4 @@ #include <stdio.h> -#include <err.h> #include <time.h> #include <dlfcn.h> #include <sys/stat.h> @@ -12,6 +11,7 @@ #include <GLFW/glfw3.h> #include "game.h" +#include "log.h" #include "intrinsics.h" #include "gl.h" #include "keys.h" @@ -42,7 +42,7 @@ static Game load_game( const char * const path ) { game.frame = ( GameFrame * ) dlsym( game.lib, "game_frame" ); if( !game.init || !game.frame ) { - warnx( "load_game: couldn't find game functions (init = %p, frame = %p)", game.init, game.frame ); + WARN( "load_game: couldn't find game functions (init = %p, frame = %p)", game.init, game.frame ); game.init = NULL; game.frame = NULL; @@ -53,7 +53,7 @@ static Game load_game( const char * const path ) { const char * const error = dlerror(); if( error ) { - warnx( "load_game: %s", error ); + WARN( "load_game: %s", error ); } return game; diff --git a/terrain_manager.cc b/terrain_manager.cc @@ -1,11 +1,11 @@ #include <string.h> -#include <err.h> #include "platform_opengl.h" #include <glm/glm.hpp> #include <glm/gtc/type_ptr.hpp> #include "intrinsics.h" +#include "log.h" #include "heightmap.h" #include "terrain_manager.h" #include "memory_arena.h" @@ -73,7 +73,7 @@ static void terrain_load_tile( u8 * pixels = stbi_load_from_memory( ct.data, ct.len, &width, &height, NULL, 1 ); - if( !pixels ) err( 1, "stbi_load failed (%s)", stbi_failure_reason() ); + if( !pixels ) ERROR( "stbi_load failed (%s)", stbi_failure_reason() ); heightmap_init( hm, tm->arena, pixels, width, height, tx * TILE_SIZE, ty * TILE_SIZE, diff --git a/unix_thread.h b/unix_thread.h @@ -3,6 +3,9 @@ #include <err.h> #include <pthread.h> +#include <sys/syscall.h> + +#include "platform_atomic.h" #define THREAD( f ) void * f( void * data ) typedef THREAD( ThreadCallback ); @@ -19,4 +22,14 @@ inline void thread_init( Thread * thread, ThreadCallback callback, void * data ) } } +inline u32 thread_getid() { +#ifdef __linux__ + return syscall( SYS_gettid ); +#endif + +#ifdef __OpenBSD__ + return getthrid(); +#endif +} + #endif // _UNIX_THREAD_H_