Compare commits
8 Commits
9d0a2cab81
...
45b8b21ec3
Author | SHA1 | Date | |
---|---|---|---|
|
45b8b21ec3 | ||
|
4659cf2aef | ||
|
db530ca3a0 | ||
|
f0dfd5627a | ||
|
0da1e413aa | ||
|
8c165974c7 | ||
|
1ba33bdc26 | ||
|
760515c551 |
@ -22,6 +22,12 @@ static const char *audio_exts[AUDIO_FILE_TYPE_COUNT] = {
|
|||||||
".xm", /* AUDIO_FILE_TYPE_XM */
|
".xm", /* AUDIO_FILE_TYPE_XM */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const uint8_t audio_exts_len[AUDIO_FILE_TYPE_COUNT] = {
|
||||||
|
sizeof ".ogg" - 1,
|
||||||
|
sizeof ".wav" - 1,
|
||||||
|
sizeof ".xm" - 1,
|
||||||
|
};
|
||||||
|
|
||||||
/* TODO: allow for vectorization and packed vectors (alignment care and alike) */
|
/* TODO: allow for vectorization and packed vectors (alignment care and alike) */
|
||||||
|
|
||||||
/* TODO: count frames without use, free the memory when threshold is met */
|
/* TODO: count frames without use, free the memory when threshold is met */
|
||||||
@ -59,14 +65,10 @@ static int64_t get_audio_data(const char *path, unsigned char **data) {
|
|||||||
|
|
||||||
|
|
||||||
static AudioFileType infer_audio_file_type(const char *path) {
|
static AudioFileType infer_audio_file_type(const char *path) {
|
||||||
size_t path_len = SDL_strlen(path);
|
size_t const path_len = SDL_strlen(path);
|
||||||
|
|
||||||
for (int i = 0; i < AUDIO_FILE_TYPE_COUNT; ++i) {
|
for (int i = 0; i < AUDIO_FILE_TYPE_COUNT; ++i) {
|
||||||
size_t ext_length = SDL_strlen(audio_exts[i]);
|
if (SDL_strncmp(&path[path_len - audio_exts_len[i]], audio_exts[i], audio_exts_len[i]) == 0)
|
||||||
if (path_len <= ext_length)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (SDL_strcmp(&path[path_len - ext_length], audio_exts[i]) == 0)
|
|
||||||
return (AudioFileType)i;
|
return (AudioFileType)i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,6 +247,35 @@ void audio_play(const char *path,
|
|||||||
float volume,
|
float volume,
|
||||||
float panning)
|
float panning)
|
||||||
{
|
{
|
||||||
|
if (!ctx.audio_initialized) {
|
||||||
|
profile_start("audio initialization");
|
||||||
|
|
||||||
|
SDL_AudioSpec request, got;
|
||||||
|
SDL_zero(request);
|
||||||
|
|
||||||
|
request.freq = AUDIO_FREQUENCY;
|
||||||
|
request.format = AUDIO_F32;
|
||||||
|
request.channels = 2;
|
||||||
|
#ifndef TWN_FEATURE_PUSH_AUDIO
|
||||||
|
request.callback = audio_callback;
|
||||||
|
#endif
|
||||||
|
/* TODO: check for errors */
|
||||||
|
ctx.audio_device = SDL_OpenAudioDevice(NULL, 0, &request, &got, 0);
|
||||||
|
ctx.audio_stream_format = got.format;
|
||||||
|
ctx.audio_stream_frequency = got.freq;
|
||||||
|
ctx.audio_stream_channel_count = got.channels;
|
||||||
|
/* TODO: relax this */
|
||||||
|
SDL_assert_always(got.freq == AUDIO_FREQUENCY);
|
||||||
|
SDL_assert_always(got.format == AUDIO_F32);
|
||||||
|
SDL_assert_always(got.channels == 2);
|
||||||
|
|
||||||
|
SDL_PauseAudioDevice(ctx.audio_device, 0);
|
||||||
|
|
||||||
|
profile_end("audio initialization");
|
||||||
|
|
||||||
|
ctx.audio_initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (channel) {
|
if (channel) {
|
||||||
AudioChannelItem *pair = shgetp_null(ctx.audio_channels, channel);
|
AudioChannelItem *pair = shgetp_null(ctx.audio_channels, channel);
|
||||||
|
|
||||||
@ -297,17 +328,17 @@ TWN_API void audio_parameter(const char *channel, const char *param, float value
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SDL_strcmp(param, "repeat") == 0) {
|
if (SDL_strncmp(param, "repeat", sizeof "repeat" - 1) == 0) {
|
||||||
pair->value.repeat = (bool)value;
|
pair->value.repeat = (bool)value;
|
||||||
|
|
||||||
} else if (SDL_strcmp(param, "volume") == 0) {
|
} else if (SDL_strncmp(param, "volume", sizeof "volume" - 1) == 0) {
|
||||||
if (value > 1.0f || value < 0.0f) {
|
if (value > 1.0f || value < 0.0f) {
|
||||||
log_warn("Out of range volume for channel %s set", channel);
|
log_warn("Out of range volume for channel %s set", channel);
|
||||||
value = clampf(value, 0.0f, 1.0f);
|
value = clampf(value, 0.0f, 1.0f);
|
||||||
}
|
}
|
||||||
pair->value.volume = value;
|
pair->value.volume = value;
|
||||||
|
|
||||||
} else if (SDL_strcmp(param, "panning") == 0) {
|
} else if (SDL_strncmp(param, "panning", sizeof "panning" - 1) == 0) {
|
||||||
if (value > 1.0f || value < -1.0f) {
|
if (value > 1.0f || value < -1.0f) {
|
||||||
log_warn("Out of range panning for channel %s set", channel);
|
log_warn("Out of range panning for channel %s set", channel);
|
||||||
value = clampf(value, -1.0f, +1.0f);
|
value = clampf(value, -1.0f, +1.0f);
|
||||||
|
@ -79,6 +79,7 @@ typedef struct EngineContext {
|
|||||||
bool render_double_buffered;
|
bool render_double_buffered;
|
||||||
/* signals mouse focus, used to disable mouse capture */
|
/* signals mouse focus, used to disable mouse capture */
|
||||||
bool window_mouse_resident;
|
bool window_mouse_resident;
|
||||||
|
bool audio_initialized;
|
||||||
} EngineContext;
|
} EngineContext;
|
||||||
|
|
||||||
/* TODO: does it need to be marked with TWN_API? */
|
/* TODO: does it need to be marked with TWN_API? */
|
||||||
|
@ -215,11 +215,14 @@ static void main_loop(void) {
|
|||||||
game_object_tick();
|
game_object_tick();
|
||||||
input_state_update_postframe(&ctx.input);
|
input_state_update_postframe(&ctx.input);
|
||||||
|
|
||||||
|
/* TODO: make it works when ctx.ticks_per_second != 60 */
|
||||||
#ifdef TWN_FEATURE_PUSH_AUDIO
|
#ifdef TWN_FEATURE_PUSH_AUDIO
|
||||||
static uint8_t audio_buffer[(AUDIO_FREQUENCY / 60) * sizeof (float) * 2];
|
static uint8_t audio_buffer[(AUDIO_FREQUENCY / 60) * sizeof (float) * 2];
|
||||||
audio_callback(NULL, audio_buffer, sizeof audio_buffer);
|
if (ctx.audio_initialized) {
|
||||||
if (SDL_QueueAudio(ctx.audio_device, audio_buffer, sizeof audio_buffer))
|
audio_callback(NULL, audio_buffer, sizeof audio_buffer);
|
||||||
CRY_SDL("Error queueing audio: ");
|
if (SDL_QueueAudio(ctx.audio_device, audio_buffer, sizeof audio_buffer))
|
||||||
|
CRY_SDL("Error queueing audio: ");
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* TODO: ctx.game_copy = ctx.game should be placed after it, but it messes with state used in render() */
|
/* TODO: ctx.game_copy = ctx.game should be placed after it, but it messes with state used in render() */
|
||||||
@ -340,18 +343,22 @@ ERR_PACK_MANIFEST_PATH_ALLOC_FAIL:
|
|||||||
|
|
||||||
|
|
||||||
static bool initialize(void) {
|
static bool initialize(void) {
|
||||||
if (SDL_Init(SDL_INIT_EVERYTHING & ~SDL_INIT_HAPTIC) == -1) {
|
profile_start("SDL initialization");
|
||||||
|
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_EVENTS) == -1) {
|
||||||
CRY_SDL("SDL initialization failed.");
|
CRY_SDL("SDL initialization failed.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
profile_end("SDL initialization");
|
||||||
|
|
||||||
/* first things first, most things here will be loaded from the config file */
|
/* first things first, most things here will be loaded from the config file */
|
||||||
/* it's expected to be present in the data directory, no matter what */
|
/* it's expected to be present in the data directory, no matter what */
|
||||||
/* that is why PhysicsFS is initialized before anything else */
|
/* that is why PhysicsFS is initialized before anything else */
|
||||||
toml_set_memutil(SDL_malloc, SDL_free);
|
toml_set_memutil(SDL_malloc, SDL_free);
|
||||||
|
|
||||||
|
profile_start("pack dependency resolution");
|
||||||
/* time to orderly resolve any dependencies present */
|
/* time to orderly resolve any dependencies present */
|
||||||
resolve_pack_dependencies("data");
|
resolve_pack_dependencies("data");
|
||||||
|
profile_end("pack dependency resolution");
|
||||||
|
|
||||||
/* load the config file into an opaque table */
|
/* load the config file into an opaque table */
|
||||||
{
|
{
|
||||||
@ -478,6 +485,8 @@ static bool initialize(void) {
|
|||||||
ctx.game.resolution.x = (float)ctx.base_render_width;
|
ctx.game.resolution.x = (float)ctx.base_render_width;
|
||||||
ctx.game.resolution.y = (float)ctx.base_render_height;
|
ctx.game.resolution.y = (float)ctx.base_render_height;
|
||||||
|
|
||||||
|
/* TODO: investigate viability of detached thread driver and window creation, as it's the worst load time offender */
|
||||||
|
profile_start("window creation");
|
||||||
ctx.window = SDL_CreateWindow(datum_title.u.s,
|
ctx.window = SDL_CreateWindow(datum_title.u.s,
|
||||||
SDL_WINDOWPOS_CENTERED,
|
SDL_WINDOWPOS_CENTERED,
|
||||||
SDL_WINDOWPOS_CENTERED,
|
SDL_WINDOWPOS_CENTERED,
|
||||||
@ -486,6 +495,7 @@ static bool initialize(void) {
|
|||||||
//SDL_WINDOW_ALLOW_HIGHDPI |
|
//SDL_WINDOW_ALLOW_HIGHDPI |
|
||||||
SDL_WINDOW_RESIZABLE |
|
SDL_WINDOW_RESIZABLE |
|
||||||
SDL_WINDOW_OPENGL);
|
SDL_WINDOW_OPENGL);
|
||||||
|
profile_end("window creation");
|
||||||
|
|
||||||
if (datum_title.ok)
|
if (datum_title.ok)
|
||||||
SDL_free(datum_title.u.s);
|
SDL_free(datum_title.u.s);
|
||||||
@ -498,6 +508,7 @@ static bool initialize(void) {
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
profile_start("opengl context creation");
|
||||||
ctx.gl_context = SDL_GL_CreateContext(ctx.window);
|
ctx.gl_context = SDL_GL_CreateContext(ctx.window);
|
||||||
if (!ctx.gl_context) {
|
if (!ctx.gl_context) {
|
||||||
CRY_SDL("GL context creation failed.");
|
CRY_SDL("GL context creation failed.");
|
||||||
@ -515,11 +526,12 @@ static bool initialize(void) {
|
|||||||
if (!render_init())
|
if (!render_init())
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
setup_viewport(0, 0, (int)ctx.base_render_width, (int)ctx.base_render_height);
|
||||||
|
profile_end("opengl context creation");
|
||||||
|
|
||||||
/* might need this to have multiple windows */
|
/* might need this to have multiple windows */
|
||||||
ctx.window_id = SDL_GetWindowID(ctx.window);
|
ctx.window_id = SDL_GetWindowID(ctx.window);
|
||||||
|
|
||||||
setup_viewport(0, 0, (int)ctx.base_render_width, (int)ctx.base_render_height);
|
|
||||||
|
|
||||||
/* TODO: */
|
/* TODO: */
|
||||||
// SDL_GetRendererOutputSize(ctx.renderer, &ctx.window_w, &ctx.window_h);
|
// SDL_GetRendererOutputSize(ctx.renderer, &ctx.window_w, &ctx.window_h);
|
||||||
ctx.window_dims.x = (float)ctx.base_render_width;
|
ctx.window_dims.x = (float)ctx.base_render_width;
|
||||||
@ -528,32 +540,6 @@ static bool initialize(void) {
|
|||||||
/* add a watcher for immediate updates on window size */
|
/* add a watcher for immediate updates on window size */
|
||||||
SDL_AddEventWatch(event_callback, NULL);
|
SDL_AddEventWatch(event_callback, NULL);
|
||||||
|
|
||||||
/* audio initialization */
|
|
||||||
{
|
|
||||||
|
|
||||||
SDL_AudioSpec request, got;
|
|
||||||
SDL_zero(request);
|
|
||||||
|
|
||||||
request.freq = AUDIO_FREQUENCY;
|
|
||||||
request.format = AUDIO_F32;
|
|
||||||
request.channels = 2;
|
|
||||||
#ifndef TWN_FEATURE_PUSH_AUDIO
|
|
||||||
request.callback = audio_callback;
|
|
||||||
#endif
|
|
||||||
/* TODO: check for errors */
|
|
||||||
ctx.audio_device = SDL_OpenAudioDevice(NULL, 0, &request, &got, 0);
|
|
||||||
ctx.audio_stream_format = got.format;
|
|
||||||
ctx.audio_stream_frequency = got.freq;
|
|
||||||
ctx.audio_stream_channel_count = got.channels;
|
|
||||||
/* TODO: relax this */
|
|
||||||
SDL_assert_always(got.freq == AUDIO_FREQUENCY);
|
|
||||||
SDL_assert_always(got.format == AUDIO_F32);
|
|
||||||
SDL_assert_always(got.channels == 2);
|
|
||||||
|
|
||||||
SDL_PauseAudioDevice(ctx.audio_device, 0);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* random seeding */
|
/* random seeding */
|
||||||
/* SDL_GetPerformanceCounter returns some platform-dependent number. */
|
/* SDL_GetPerformanceCounter returns some platform-dependent number. */
|
||||||
/* it should vary between game instances. i checked! random enough for me. */
|
/* it should vary between game instances. i checked! random enough for me. */
|
||||||
@ -627,9 +613,9 @@ static bool initialize(void) {
|
|||||||
if (!datum_font_filtering.ok) {
|
if (!datum_font_filtering.ok) {
|
||||||
ctx.font_filtering = TEXT_FONT_FILTERING_DEFAULT;
|
ctx.font_filtering = TEXT_FONT_FILTERING_DEFAULT;
|
||||||
} else {
|
} else {
|
||||||
if (SDL_strcmp(datum_font_filtering.u.s, "nearest") == 0) {
|
if (SDL_strncmp(datum_font_filtering.u.s, "nearest", sizeof "nearest") == 0) {
|
||||||
ctx.font_filtering = TEXTURE_FILTER_NEAREAST;
|
ctx.font_filtering = TEXTURE_FILTER_NEAREAST;
|
||||||
} else if (SDL_strcmp(datum_font_filtering.u.s, "linear") == 0) {
|
} else if (SDL_strncmp(datum_font_filtering.u.s, "linear", sizeof "nearest") == 0) {
|
||||||
ctx.font_filtering = TEXTURE_FILTER_LINEAR;
|
ctx.font_filtering = TEXTURE_FILTER_LINEAR;
|
||||||
} else {
|
} else {
|
||||||
ctx.font_filtering = TEXT_FONT_FILTERING_DEFAULT;
|
ctx.font_filtering = TEXT_FONT_FILTERING_DEFAULT;
|
||||||
@ -642,8 +628,10 @@ static bool initialize(void) {
|
|||||||
ctx.render_queue_2d = NULL;
|
ctx.render_queue_2d = NULL;
|
||||||
ctx.uncolored_mesh_batches = NULL;
|
ctx.uncolored_mesh_batches = NULL;
|
||||||
|
|
||||||
|
profile_start("texture and text cache initialization");
|
||||||
textures_cache_init(&ctx.texture_cache, ctx.window);
|
textures_cache_init(&ctx.texture_cache, ctx.window);
|
||||||
text_cache_init(&ctx.text_cache);
|
text_cache_init(&ctx.text_cache);
|
||||||
|
profile_end("texture and text cache initialization");
|
||||||
|
|
||||||
/* input */
|
/* input */
|
||||||
toml_datum_t datum_keybind_slots = toml_int_in(engine, "keybind_slots");
|
toml_datum_t datum_keybind_slots = toml_int_in(engine, "keybind_slots");
|
||||||
@ -658,13 +646,6 @@ static bool initialize(void) {
|
|||||||
}
|
}
|
||||||
input_state_init(&ctx.input);
|
input_state_init(&ctx.input);
|
||||||
|
|
||||||
/* scripting */
|
|
||||||
/*
|
|
||||||
if (!scripting_init(ctx)) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
ctx.render_double_buffered = true;
|
ctx.render_double_buffered = true;
|
||||||
ctx.window_mouse_resident = true;
|
ctx.window_mouse_resident = true;
|
||||||
|
|
||||||
@ -681,10 +662,6 @@ fail:
|
|||||||
|
|
||||||
/* will not be called on an abnormal exit */
|
/* will not be called on an abnormal exit */
|
||||||
static void clean_up(void) {
|
static void clean_up(void) {
|
||||||
/*
|
|
||||||
scripting_deinit(ctx);
|
|
||||||
*/
|
|
||||||
|
|
||||||
input_state_deinit(&ctx.input);
|
input_state_deinit(&ctx.input);
|
||||||
text_cache_deinit(&ctx.text_cache);
|
text_cache_deinit(&ctx.text_cache);
|
||||||
textures_cache_deinit(&ctx.texture_cache);
|
textures_cache_deinit(&ctx.texture_cache);
|
||||||
@ -709,6 +686,8 @@ static void reset_state(void) {
|
|||||||
|
|
||||||
|
|
||||||
int enter_loop(int argc, char **argv) {
|
int enter_loop(int argc, char **argv) {
|
||||||
|
profile_start("startup");
|
||||||
|
|
||||||
ctx.argc = argc;
|
ctx.argc = argc;
|
||||||
ctx.argv = argv;
|
ctx.argv = argv;
|
||||||
ctx.base_dir = SDL_GetBasePath();
|
ctx.base_dir = SDL_GetBasePath();
|
||||||
@ -727,7 +706,7 @@ int enter_loop(int argc, char **argv) {
|
|||||||
|
|
||||||
for (int i = 1; i < argc; ++i) {
|
for (int i = 1; i < argc; ++i) {
|
||||||
/* override data directory */
|
/* override data directory */
|
||||||
if (SDL_strcmp(argv[i], "--data-dir") == 0) {
|
if (SDL_strncmp(argv[i], "--data-dir", sizeof "--data-dir" - 1) == 0) {
|
||||||
if (argv[i+1] == NULL || SDL_strncmp(argv[i+1], "--", 2) == 0) {
|
if (argv[i+1] == NULL || SDL_strncmp(argv[i+1], "--", 2) == 0) {
|
||||||
CRY("Data dir mount override failed.", "No arguments passed (expected 1).");
|
CRY("Data dir mount override failed.", "No arguments passed (expected 1).");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
@ -744,13 +723,13 @@ int enter_loop(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* force debug mode */
|
/* force debug mode */
|
||||||
if (SDL_strcmp(argv[i], "--debug") == 0) {
|
if (SDL_strncmp(argv[i], "--debug", sizeof "--debug" - 1) == 0) {
|
||||||
force_debug = true;
|
force_debug = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* force release mode */
|
/* force release mode */
|
||||||
if (SDL_strcmp(argv[i], "--release") == 0) {
|
if (SDL_strncmp(argv[i], "--release", sizeof "--release" - 1) == 0) {
|
||||||
force_release = false;
|
force_release = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -786,12 +765,16 @@ int enter_loop(int argc, char **argv) {
|
|||||||
|
|
||||||
update_viewport();
|
update_viewport();
|
||||||
|
|
||||||
|
profile_start("game object load");
|
||||||
/* now we can actually start doing stuff */
|
/* now we can actually start doing stuff */
|
||||||
game_object_load();
|
game_object_load();
|
||||||
|
profile_end("game object load");
|
||||||
|
|
||||||
ctx.was_successful = true;
|
ctx.was_successful = true;
|
||||||
ctx.game.initialization_needed = true;
|
ctx.game.initialization_needed = true;
|
||||||
|
|
||||||
|
profile_end("startup");
|
||||||
|
|
||||||
while (ctx.is_running) {
|
while (ctx.is_running) {
|
||||||
if (game_object_try_reloading()) {
|
if (game_object_try_reloading()) {
|
||||||
ctx.game.initialization_needed = true;
|
ctx.game.initialization_needed = true;
|
||||||
@ -801,7 +784,8 @@ int enter_loop(int argc, char **argv) {
|
|||||||
main_loop();
|
main_loop();
|
||||||
}
|
}
|
||||||
|
|
||||||
profile_list_stats();
|
if (ctx.game.debug)
|
||||||
|
profile_list_stats();
|
||||||
|
|
||||||
/* loop is over */
|
/* loop is over */
|
||||||
game_object_unload();
|
game_object_unload();
|
||||||
|
@ -186,6 +186,8 @@ static void upload_texture_from_surface(GPUTexture texture, SDL_Surface *surface
|
|||||||
|
|
||||||
|
|
||||||
static void recreate_current_atlas_texture(TextureCache *cache) {
|
static void recreate_current_atlas_texture(TextureCache *cache) {
|
||||||
|
profile_start("atlas recreation");
|
||||||
|
|
||||||
/* TODO: should surfaces be freed after they cannot be referenced in atlas builing? */
|
/* TODO: should surfaces be freed after they cannot be referenced in atlas builing? */
|
||||||
/* for example, if full page of 64x64 tiles was already filled, there's no real reason to process them further */
|
/* for example, if full page of 64x64 tiles was already filled, there's no real reason to process them further */
|
||||||
SDL_Surface *atlas_surface = cache->atlas_surfaces[cache->atlas_index];
|
SDL_Surface *atlas_surface = cache->atlas_surfaces[cache->atlas_index];
|
||||||
@ -216,6 +218,8 @@ static void recreate_current_atlas_texture(TextureCache *cache) {
|
|||||||
|
|
||||||
/* texturize it! */
|
/* texturize it! */
|
||||||
upload_texture_from_surface(cache->atlas_textures[cache->atlas_index], atlas_surface);
|
upload_texture_from_surface(cache->atlas_textures[cache->atlas_index], atlas_surface);
|
||||||
|
|
||||||
|
profile_end("atlas recreation");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -307,10 +311,9 @@ void textures_cache_init(TextureCache *cache, SDL_Window *window) {
|
|||||||
cache->window = window;
|
cache->window = window;
|
||||||
sh_new_arena(cache->hash);
|
sh_new_arena(cache->hash);
|
||||||
|
|
||||||
cache->node_buffer = SDL_calloc(ctx.texture_atlas_size, sizeof *cache->node_buffer);
|
cache->node_buffer = SDL_malloc(ctx.texture_atlas_size * sizeof *cache->node_buffer);
|
||||||
|
|
||||||
add_new_atlas(cache);
|
add_new_atlas(cache);
|
||||||
recreate_current_atlas_texture(cache);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ static struct ProfileItem {
|
|||||||
uint64_t tick_start;
|
uint64_t tick_start;
|
||||||
uint64_t tick_accum;
|
uint64_t tick_accum;
|
||||||
uint64_t sample_count;
|
uint64_t sample_count;
|
||||||
|
uint64_t worst_tick;
|
||||||
} value;
|
} value;
|
||||||
} *profiles;
|
} *profiles;
|
||||||
|
|
||||||
@ -319,21 +320,40 @@ void profile_start(char profile[const static 1]) {
|
|||||||
void profile_end(char profile[const static 1]) {
|
void profile_end(char profile[const static 1]) {
|
||||||
struct ProfileItem *p = shgetp_null(profiles, profile);
|
struct ProfileItem *p = shgetp_null(profiles, profile);
|
||||||
if (!p) {
|
if (!p) {
|
||||||
log_warn("profile %s wasn't started!", profile);
|
log_warn("Profile %s wasn't started!", profile);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t took = SDL_GetPerformanceCounter() - p->value.tick_start;
|
||||||
|
|
||||||
|
p->value.tick_accum += took;
|
||||||
p->value.sample_count++;
|
p->value.sample_count++;
|
||||||
p->value.tick_accum += SDL_GetPerformanceCounter() - p->value.tick_start;
|
|
||||||
|
if (p->value.worst_tick < took)
|
||||||
|
p->value.worst_tick = took;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void profile_list_stats(void) {
|
void profile_list_stats(void) {
|
||||||
for (size_t i = 0; i < shlenu(profiles); ++i) {
|
for (size_t i = 0; i < shlenu(profiles); ++i) {
|
||||||
log_info("profile '%s' on average took: %f seconds",
|
if (profiles[i].value.sample_count == 0) {
|
||||||
profiles[i].key,
|
log_warn("Profile %s was started, but not once finished.", profiles[i].key);
|
||||||
(double)profiles[i].value.tick_accum /
|
}
|
||||||
(double)profiles[i].value.sample_count /
|
|
||||||
(double)(SDL_GetPerformanceFrequency()));
|
else if (profiles[i].value.sample_count == 1) {
|
||||||
|
log_info("Profile '%s' took: %f seconds",
|
||||||
|
profiles[i].key,
|
||||||
|
(double)profiles[i].value.tick_accum / (double)(SDL_GetPerformanceFrequency()));
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (profiles[i].value.sample_count > 1) {
|
||||||
|
log_info("Profile '%s' on average took: %f seconds, worst case: %f, sample count: %llu",
|
||||||
|
profiles[i].key,
|
||||||
|
(double)profiles[i].value.tick_accum /
|
||||||
|
(double)profiles[i].value.sample_count /
|
||||||
|
(double)(SDL_GetPerformanceFrequency()),
|
||||||
|
(double)profiles[i].value.worst_tick / (double)(SDL_GetPerformanceFrequency()),
|
||||||
|
profiles[i].value.sample_count);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user