medfall

A super great game engine
Log | Files | Refs

commit 144986037ea33d291c5817285197341ea204abbc
parent 269a37d28e97b39bcb285487a252bf4588bdc6f1
Author: Michael Savage <mikejsavage@gmail.com>
Date:   Sat Apr 15 00:25:39 +0300

Use ggformat in str.h

Diffstat:
gl.cc | 21+++++++++++----------
launcher/main.cc | 4++--
linux_audio_output.cc | 8++++----
log.cc | 30+++++++++++++++---------------
log.h | 11++++++++++-
profiler.cc | 21+++++++++++++--------
profiler.h | 2+-
renderer.cc | 20++++++++++----------
stats.cc | 21+++++++++++----------
stats.h | 8++++++--
str.h | 86++++++++++++++++++++++++++++---------------------------------------------------
wave.cc | 2+-
win32_audio_output.cc | 2+-
13 files changed, 115 insertions(+), 121 deletions(-)
diff --git a/gl.cc b/gl.cc @@ -69,16 +69,17 @@ static void gl_debug_output_callback( return; } - // we don't want the trailing \n - size_t len = strlen( message ); - if( len > 0 && message[ len - 1 ] == '\n' ) { - len--; + // remove trailing \n if there is one + str< 1024 > buf; + buf += message; + if( buf.len() > 0 && buf[ buf.len() - 1 ] == '\n' ) { + buf.truncate( buf.len() - 1 ); } - WARN( "GL [%s - %s]: %.*s", + WARN( "GL [{} - {}]: {}", type_string( type ), severity_string( severity ), - len, message ); + buf ); if( severity == GL_DEBUG_SEVERITY_HIGH ) { ASSERT( 0 ); @@ -93,7 +94,7 @@ static void gl_debug_output_callback_amd( } static void glfw_error_callback( int code, const char * message ) { - WARN( "GLFW error %d: %s", code, message ); + WARN( "GLFW error {}: {}", code, message ); } GLFWwindow * gl_init() { @@ -135,12 +136,12 @@ GLFWwindow * gl_init() { }; const char * vendor = ( const char * ) glGetString( GL_VENDOR ); - INFO( "Version %s", glGetString( GL_VERSION ) ); - INFO( "Vendor %s", vendor ); + INFO( "Version {}", glGetString( GL_VERSION ) ); + INFO( "Vendor {}", vendor ); INFO( "OpenGL extensions:" ); for( size_t i = 0; i < ARRAY_COUNT( exts ); i++ ) { - INFO( "%s: %s", exts[ i ].name, exts[ i ].enabled == 0 ? "missing" : "present" ); + INFO( "{}: {}", exts[ i ].name, exts[ i ].enabled == 0 ? "missing" : "present" ); } bool nvidia_and_windows = false; diff --git a/launcher/main.cc b/launcher/main.cc @@ -394,12 +394,12 @@ static WORK_QUEUE_CALLBACK( install_update ) { // TODO: remove game files that are no longer needed FILE * version_txt = fopen( "version.txt", "w" ); - fprintf( version_txt, "%u.%u.%u.%u\n", version.a, version.b, version.c, version.d ); + ggprint_to_file( version_txt, "{}.{}.{}.{}\n", version.a, version.b, version.c, version.d ); fclose( version_txt ); FILE * manifest_txt = fopen( "manifest.txt", "w" ); for( const auto & kv : manifest ) { - fprintf( manifest_txt, "%s %s %llu\n", kv.first.c_str(), kv.second.checksum.e, kv.second.file_size ); + ggprint_to_file( manifest_txt, "{} {} {}\n", kv.first.c_str(), kv.second.checksum.e, kv.second.file_size ); } fclose( manifest_txt ); diff --git a/linux_audio_output.cc b/linux_audio_output.cc @@ -35,7 +35,7 @@ static void audio_error_handler( const char * file, int line, const char * funct void audio_output_init() { alsa_lib = library_open( "libasound.so" ); if( alsa_lib == NULL ) { - FATAL( "Couldn't open libasound.so: %s", dlerror() ); + FATAL( "Couldn't open libasound.so: {}", dlerror() ); } _snd_lib_error_set_handler = ( int ( * )( snd_lib_error_handler_t ) ) library_function( alsa_lib, "snd_lib_error_set_handler" ); @@ -110,14 +110,14 @@ void audio_output_open( AudioOutputDevice * device, AudioOutputCallback callback int err_open = _snd_pcm_open( &device->pcm, "default", SND_PCM_STREAM_PLAYBACK, 0 ); if( err_open != 0 ) { - FATAL( "Couldn't open sound output: %s", _snd_strerror( err_open ) ); + FATAL( "Couldn't open sound output: {}", _snd_strerror( err_open ) ); } int err_params = _snd_pcm_set_params( device->pcm, SND_PCM_FORMAT_S16_LE, SND_PCM_ACCESS_RW_NONINTERLEAVED, channels, sample_rate, 1, latency ); if( err_params != 0 ) { - FATAL( "Couldn't configure sound output: %s", _snd_strerror( err_params ) ); + FATAL( "Couldn't configure sound output: {}", _snd_strerror( err_params ) ); } device->callback = callback; @@ -131,6 +131,6 @@ void audio_output_close( AudioOutputDevice * device ) { int err = _snd_pcm_close( device->pcm ); if( err != 0 ) { - FATAL( "Couldn't close sound output: %s", _snd_strerror( err ) ); + FATAL( "Couldn't close sound output: {}", _snd_strerror( err ) ); } } diff --git a/log.cc b/log.cc @@ -6,6 +6,7 @@ #include "log.h" #include "str.h" #include "strlcpy.h" +#include "strlcat.h" #include "platform_io.h" #include "platform_atomic.h" #include "platform_thread.h" @@ -44,11 +45,11 @@ void logger_init() { mkdir( "logs", 0755 ); u64 now = checked_cast< u64 >( time( NULL ) ); - logs_dir.sprintf( "logs/%llu", now ); + logs_dir.sprintf( "logs/{}", now ); mkdir( logs_dir.c_str(), 0755 ); for( u32 i = 0; i <= LOGLEVEL_COUNT; i++ ) { - const str< 256 > path( "%s/%s.log", logs_dir.c_str(), file_names[ i ] ); + const str< 256 > path( "{}/{}.log", logs_dir.c_str(), file_names[ i ] ); streams[ i ] = fopen( path.c_str(), "w" ); ASSERT( streams[ i ] != NULL ); } @@ -56,6 +57,7 @@ void logger_init() { initialised = true; } +// TODO: this should really use ggformat too void logger_thread_name( const char * fmt, ... ) { u32 i = fetch_add_acqrel( &num_threads, 1 ); ASSERT( i < MAX_THREADS ); @@ -63,18 +65,19 @@ void logger_thread_name( const char * fmt, ... ) { LoggerThread & thread = threads[ i ]; thread.id = thread_getid(); + thread.name[ 0 ] = '\0'; + strlcat( thread.name, "[", sizeof( thread.name ) ); + va_list argp; va_start( argp, fmt ); - str< sizeof( thread.name ) > name( "[" ); - name.appendf( fmt, argp ); - name.appendf( "] " ); + vsnprintf( thread.name + 1, sizeof( thread.name ) - 1, fmt, argp ); va_end( argp ); - strlcpy( thread.name, name.c_str(), sizeof( thread.name ) ); + strlcat( thread.name, "]", sizeof( thread.name ) ); } // TODO: print time? -void logger_log( LogLevel level, const char * fmt, ... ) { +void logger_log( LogLevel level, const char * message ) { logger_init(); str< 1024 > buf; @@ -83,20 +86,17 @@ void logger_log( LogLevel level, const char * fmt, ... ) { u32 n = load_acquire( &num_threads ); for( u32 i = 0; i < n; i++ ) { if( threads[ i ].id == thread_id ) { - buf.appendf( threads[ i ].name ); + buf += threads[ i ].name; } } if( buf.len() == 0 ) { - buf.appendf( "[thread %llu] ", thread_id ); + buf.appendf( "[thread {}] ", thread_id ); } - va_list argp; - va_start( argp, fmt ); - buf.appendf( fmt, argp ); - va_end( argp ); - - buf.appendf( "\n" ); + buf += " "; + buf += message; + buf += "\n"; FILE * console_stream = level == LOGLEVEL_INFO ? stdout : stderr; { diff --git a/log.h b/log.h @@ -2,6 +2,8 @@ #include <stdlib.h> +#include "str.h" + enum LogLevel { LOGLEVEL_FATAL, LOGLEVEL_WARNING, @@ -12,7 +14,14 @@ enum LogLevel { void logger_init(); void logger_thread_name( const char * fmt, ... ); -void logger_log( LogLevel level, const char * fmt, ... ); +void logger_log( LogLevel level, const char * message ); + +template< typename... Rest > +void logger_log( LogLevel level, const char * fmt, Rest... rest ) { + str< 1024 > buf; + buf.appendf( fmt, rest... ); + logger_log( level, buf.c_str() ); +} const char * logger_get_logs_dir(); diff --git a/profiler.cc b/profiler.cc @@ -5,6 +5,8 @@ #include "stats.h" #include "str.h" #include "strlcpy.h" +#include "strlcat.h" +#include "ggformat.h" #include "log.h" #include "platform_time.h" @@ -66,7 +68,7 @@ static void profiler_logger_init() { if( log_file != NULL ) return; logger_init(); - const str< 256 > log_path( "%s/profiler.log", logger_get_logs_dir() ); + const str< 256 > log_path( "{}/profiler.log", logger_get_logs_dir() ); log_file = fopen( log_path.c_str(), "w" ); } @@ -76,7 +78,7 @@ static void write_node( u32 idx, double frame_dt ) { write_node( entry.prev_sibling, frame_dt ); } - fprintf( log_file, "%s (%.2f%%)\n", entry.message.c_str(), entry.dt * 100.0 / frame_dt ); + ggprint_to_file( log_file, "{} ({.2}%)\n", entry.message.c_str(), entry.dt * 100.0 / frame_dt ); if( entry.first_child != 0 ) { write_node( entry.first_child, frame_dt ); @@ -86,7 +88,8 @@ static void write_node( u32 idx, double frame_dt ) { static void write_frame( double frame_dt ) { profiler_logger_init(); write_node( num_log_entries - 1, frame_dt ); - fprintf( log_file, "\n" ); + ggprint_to_file( log_file, "\n" ); + fflush( log_file ); } void profiler_pop( const char * name ) { @@ -105,9 +108,14 @@ void profiler_pop( const char * name ) { name = timer->name; } + str< 512 > spaces; + for( u32 i = 0; i < timer_stack_top; i++ ) { + spaces += " "; + } + ASSERT( num_log_entries < TIMER_LOG_SIZE ); LogEntry * entry = &logs[ num_log_entries ]; - entry->message.sprintf( "%*s%s (%s:%d) - %.3fms", timer_stack_top * 2, "", name, timer->file, timer->line, dt * 1000.0 ); + entry->message.sprintf( "{}{} ({}:{}) - {.3}ms", spaces, name, timer->file, timer->line, dt * 1000.0 ); entry->dt = dt; entry->first_child = last_at_depth[ timer_stack_top + 1 ]; entry->prev_sibling = last_at_depth[ timer_stack_top ]; @@ -128,10 +136,7 @@ void profiler_write_summary() { profiler_logger_init(); for( u32 i = 0; i < num_timers; i++ ) { Timer * timer = &all_timers[ i ]; - - printf( "%s (%s:%d): ", timer->name, timer->file, timer->line ); - stats_print( &timer->stats ); - printf( "\n" ); + ggprint_to_file( log_file, "{} ({}:{}): {}\n", timer->name, timer->file, timer->line, timer->stats ); } } diff --git a/profiler.h b/profiler.h @@ -6,7 +6,7 @@ u32 profiler_new_timer( const char * name, const char * file, int line ); void profiler_push( u32 timer_idx ); void profiler_pop( const char * name = NULL ); -void profiler_print_all(); +void profiler_write_summary(); #define PROFILE_BLOCK_NAME_LENGTH 128 diff --git a/renderer.cc b/renderer.cc @@ -39,7 +39,7 @@ static GLenum bufferusage_to_glenum( BufferUsage usage ) { case BUFFERUSAGE_STREAM: return GL_STREAM_DRAW; } - FATAL( "unsupported BufferUsage: %d", usage ); + FATAL( "unsupported BufferUsage: {}", usage ); return 0; } @@ -52,7 +52,7 @@ static GLenum textureformat_to_glenum( TextureFormat format ) { case TEXFMT_BC4: return GL_COMPRESSED_RED_RGTC1; default: - FATAL( "unsupported TextureFormat: %d", format ); + FATAL( "unsupported TextureFormat: {}", format ); return 0; } } @@ -172,7 +172,7 @@ static GLuint new_gl_shader( GLenum type, const char * src ) { } glGetShaderInfoLog( shader, len, NULL, buf ); - FATAL( "%s", buf ); + FATAL( "{}", buf ); } return shader; @@ -213,7 +213,7 @@ Shader renderer_new_shader( ShaderConfig config ) { } glGetProgramInfoLog( program, len, NULL, buf ); - FATAL( "%s", buf ); + FATAL( "{}", buf ); } const char * ubo_names[] = { "v_hot", "v_cold", "f_hot", "f_cold" }; @@ -230,7 +230,7 @@ Shader renderer_new_shader( ShaderConfig config ) { if( config.texture_uniform_names[ i ] != NULL ) { GLuint uniform = glGetUniformLocation( program, config.texture_uniform_names[ i ] ); if( uniform == GLuint( -1 ) ) { - FATAL( "couldn't find texture uniform: %s", config.texture_uniform_names[ i ] ); + FATAL( "couldn't find texture uniform: {}", config.texture_uniform_names[ i ] ); } glUniform1i( uniform, i ); } @@ -240,7 +240,7 @@ Shader renderer_new_shader( ShaderConfig config ) { if( config.texture_buffer_uniform_names[ i ] != NULL ) { GLuint uniform = glGetUniformLocation( program, config.texture_buffer_uniform_names[ i ] ); if( uniform == GLuint( -1 ) ) { - FATAL( "couldn't find texturebuffer uniform: %s", config.texture_buffer_uniform_names[ i ] ); + FATAL( "couldn't find texturebuffer uniform: {}", config.texture_buffer_uniform_names[ i ] ); } glUniform1i( uniform, i + RENDERER_MAX_TEXTURES ); } @@ -297,7 +297,7 @@ static u32 texture_byte_size( u32 width, u32 height, TextureFormat format, bool case TEXFMT_BC4: return total_dim / 2; default: - FATAL( "unsupported TextureFormat: %d", format ); + FATAL( "unsupported TextureFormat: {}", format ); return 0; } } @@ -342,7 +342,7 @@ Texture renderer_new_texture( TextureConfig config ) { break; default: - FATAL( "unsupported TextureFormat: %d", config.format ); + FATAL( "unsupported TextureFormat: {}", config.format ); break; } @@ -491,7 +491,7 @@ static GLenum depthfunc_to_glenum( DepthFunc depth_func ) { case DEPTHFUNC_DISABLED: return GL_ALWAYS; } - FATAL( "unsupported DepthFunc: %d", depth_func ); + FATAL( "unsupported DepthFunc: {}", depth_func ); return 0; } @@ -503,7 +503,7 @@ static GLenum primitivetype_to_glenum( PrimitiveType primitive_type ) { case PRIMITIVETYPE_LINES: return GL_LINES; } - FATAL( "unsupported PrimitiveType: %d", primitive_type ); + FATAL( "unsupported PrimitiveType: {}", primitive_type ); return 0; } diff --git a/stats.cc b/stats.cc @@ -4,6 +4,7 @@ #include "intrinsics.h" #include "stats.h" +#include "ggformat.h" void stats_init( Stats * stats ) { *stats = { }; @@ -28,8 +29,8 @@ void stats_record( Stats * stats, double x ) { stats->min = stats->max = x; } else { - if( x < stats->min ) stats->min = x; - if( x > stats->max ) stats->max = x; + stats->min = min( x, stats->min ); + stats->max = max( x, stats->max ); } // see if we should keep this sample @@ -48,14 +49,14 @@ void stats_record( Stats * stats, double x ) { stats->num_records++; } -void stats_print( Stats * stats ) { - u32 num_samples = checked_cast< u32 >( min( stats->num_records, u64( STATS_NUM_QUART_SAMPLES ) ) ); - std::sort( stats->samples, stats->samples + num_samples ); +void format( FormatBuffer * fb, const Stats & stats, const FormatOpts & opts ) { + u32 num_samples = checked_cast< u32 >( min( stats.num_records, u64( STATS_NUM_QUART_SAMPLES ) ) ); + std::sort( stats.samples, stats.samples + num_samples ); - printf( "n = %llu, mean = %f, stddev = %f, range = %f to %f, 25%% = %f, 75%% = %f", - stats->num_records, - stats_mean( stats ), stats_stddev( stats ), - stats->min, stats->max, - stats->samples[ num_samples / 4 ], stats->samples[ num_samples * 3 / 4 ] + ggformat_impl( fb, "n = {}, mean = {}, stddev = {}, range = {} to {}, 25% = {}, 75% = {}", + stats.num_records, + stats_mean( &stats ), stats_stddev( &stats ), + stats.min, stats.max, + stats.samples[ num_samples / 4 ], stats.samples[ num_samples * 3 / 4 ] ); } diff --git a/stats.h b/stats.h @@ -1,6 +1,7 @@ #pragma once #include "intrinsics.h" +#include "ggformat.h" #include "rng/well512.h" const u32 STATS_NUM_QUART_SAMPLES = 1024; @@ -14,11 +15,14 @@ struct Stats { u64 num_records; RNGWell512 rng; - double samples[ STATS_NUM_QUART_SAMPLES ]; + + // mutable because we sort samples to pull out percentiles in format + mutable double samples[ STATS_NUM_QUART_SAMPLES ]; }; void stats_init( Stats * stats ); double stats_mean( const Stats * stats ); double stats_stddev( const Stats * stats ); void stats_record( Stats * stats, double x ); -void stats_print( Stats * stats ); + +void format( FormatBuffer * fb, const Stats & stats, const FormatOpts & opts ); diff --git a/str.h b/str.h @@ -2,10 +2,10 @@ #include <stdio.h> #include <stdlib.h> -#include <stdarg.h> #include "intrinsics.h" #include "strlcpy.h" +#include "ggformat.h" template< size_t N > class str { @@ -16,11 +16,9 @@ public: clear(); } - str( const char * fmt, ... ) { - va_list argp; - va_start( argp, fmt ); - sprintf( fmt, argp ); - va_end( argp ); + template< typename... Rest > + str( const char * fmt, Rest... rest ) { + sprintf( fmt, rest... ); } void clear() { @@ -28,66 +26,37 @@ public: length = 0; } - void operator+=( const char * rhs ) { - size_t copied = strlcpy( buf + length, rhs, N - length ); - length += min( copied, N - length - 1 ); - } - - void operator+=( char c ) { - appendf( "%c", c ); - } - - void operator+=( int n ) { - appendf( "%d", n ); - } - - void operator+=( long n ) { - appendf( "%ld", n ); - } - - void operator+=( long long n ) { - appendf( "%lld", n ); - } - - void operator+=( unsigned int n ) { - appendf( "%u", n ); + template< typename T > + void operator+=( const T & x ) { + appendf( "{}", x ); } - void operator+=( unsigned long n ) { - appendf( "%lu", n ); - } - - void operator+=( unsigned long long n ) { - appendf( "%llu", n ); - } - - void operator+=( double x ) { - appendf( "%f", x ); + template< typename... Rest > + void sprintf( const char * fmt, Rest... rest ) { + size_t copied = ggformat( buf, N, fmt, rest... ); + length = min( copied, N - 1 ); } - // TODO: implement our own vsnprintf with support for vectors etc - void sprintf( const char * fmt, va_list argp ) { - size_t copied = vsnprintf( buf, N, fmt, argp ); - length = min( copied, N - 1 ); + template< typename... Rest > + void appendf( const char * fmt, Rest... rest ) { + size_t copied = ggformat( buf + length, N - length, fmt, rest... ); + length += min( copied, N - length - 1 ); } - void sprintf( const char * fmt, ... ) { - va_list argp; - va_start( argp, fmt ); - sprintf( fmt, argp ); - va_end( argp ); + void truncate( size_t len ) { + if( len >= length ) return; + buf[ len ] = '\0'; + length = len; } - void appendf( const char * fmt, va_list argp ) { - size_t copied = vsnprintf( buf + length, N - length, fmt, argp ); - length += min( copied, N - length - 1 ); + char & operator[]( size_t i ) { + ASSERT( i < N ); + return buf[ i ]; } - void appendf( const char * fmt, ... ) { - va_list argp; - va_start( argp, fmt ); - appendf( fmt, argp ); - va_end( argp ); + const char & operator[]( size_t i ) const { + ASSERT( i < N ); + return buf[ i ]; } const char * c_str() const { @@ -102,3 +71,8 @@ private: char buf[ N ]; size_t length; }; + +template< size_t N > +void format( FormatBuffer * fb, const str< N > & buf, const FormatOpts & opts ) { + format( fb, buf.c_str(), opts ); +} diff --git a/wave.cc b/wave.cc @@ -91,7 +91,7 @@ bool wave_decode( MemoryArena * arena, u8 * data, size_t data_len, SoundData * s } break; default: { - WARN( "unrecognised WAVE chunk: %u", chunk_id ); + WARN( "unrecognised WAVE chunk: {}", chunk_id ); return false; } } diff --git a/win32_audio_output.cc b/win32_audio_output.cc @@ -40,7 +40,7 @@ void audio_output_init() { xaudio2_lib = library_open( "XAudio2_7.dll" ); if( xaudio2_lib == NULL ) { - FATAL( "Couldn't open XAudio2_7.dll: %s", library_last_error() ); + FATAL( "Couldn't open XAudio2_7.dll: {}", library_last_error() ); } if( FAILED( XAudio2Create( &xaudio2, 0, XAUDIO2_DEFAULT_PROCESSOR ) ) ) {