1.application.h
#pragma once
#include "defines.h"
struct game;
typedef struct application_config{
i16 start_pos_x;
i16 start_pos_y;
i16 start_width;
i16 start_height;
char* name;
}application_config;
KAPI b8 application_create(struct game* game_inst);
KAPI b8 application_run();
void application_get_framebuffer_size(u32* width,u32* height);
2.application.c
#include "application.h"
#include "game_types.h"
#include "logger.h"
#include "memory/linear_allocator.h"
#include "platform/platform.h"
#include "core/kmemory.h"
#include "core/event.h"
#include "core/input.h"
#include "core/clock.h"
#include "renderer/renderer_frontend.h"
typedef struct application_state{
game* game_inst;
b8 is_running;
b8 is_suspended;
platform_state platform;
i16 width;
i16 height;
clock clock;
f64 last_time;
linear_allocator systems_allocator;
u64 memory_system_memory_requirement;
void* memory_system_state;
u64 logging_system_memory_requirement;
void* logging_system_state;
}application_state;
//static b8 initialized = false;
static application_state* app_state;
b8 application_on_event(u16 code,void* sender,void* listener_inst,event_context context);
b8 application_on_key(u16 code, void* sender,void* listener_inst,event_context context);
b8 application_on_resized(u16 code, void* sender,void* listener_inst,event_context context);
b8 application_create(game* game_inst){
if(game_inst->application_state){
KERROR("application_create called more than once.");
return false;
}
game_inst->application_state = kallocate(sizeof(application_state),MEMORY_TAG_RENDERER);
app_state = game_inst->application_state;
app_state->game_inst = game_inst;
app_state->is_running = false;
app_state->is_suspended = false;
u64 systems_allocator_total_size = 64*1024*1024;
linear_allocator_create(systems_allocator_total_size,0,&app_state->systems_allocator);
initialize_memory(&app_state->memory_system_memory_requirement,0);
app_state->memory_system_state = linear_allocator_allocate(&app_state->systems_allocator,app_state->memory_system_memory_requirement);
initialize_memory(&app_state->memory_system_memory_requirement,app_state->memory_system_state);
initialize_logging(&app_state->logging_system_memory_requirement,0);
app_state->logging_system_state = linear_allocator_allocate(&app_state->systems_allocator,app_state->logging_system_memory_requirement);
if(!initialize_logging(&app_state->logging_system_memory_requirement,app_state->logging_system_state))
{
KERROR("Failed to initialize logging system; shutting down.");
return false;
}
input_initialize();
KFATAL("A test message: %f",3.14f);
KERROR("A test message: %f",3.14f);
KWARN("A test message: %f",3.14f);
KINFO("A test message: %f",3.14f);
KDEBUG("A test message: %f",3.14f);
KTRACE("A test message: %f",3.14f);
if(!event_initialize())
{
KERROR("Event system failed initialization. Application cannot continue.");
return false;
}
event_register(EVENT_CODE_APPLICATION_QUIT,0,application_on_event);
event_register(EVENT_CODE_KEY_PRESSED,0,application_on_key);
event_register(EVENT_CODE_KEY_RELEASED,0,application_on_key);
event_register(EVENT_CODE_RESIZED,0,application_on_resized);
if(!platform_startup(
&app_state->platform,
game_inst->app_config.name,
game_inst->app_config.start_pos_x,
game_inst->app_config.start_pos_y,
game_inst->app_config.start_width,
game_inst->app_config.start_height))
{
return false;
}
//Renderer start up
if(!renderer_initialize(game_inst->app_config.name,&app_state->platform))
{
KFATAL("Failed to initialize renderer.Aborting application!");
}
//Initialzie the game
if(!app_state->game_inst->initialize(app_state->game_inst))
{
KFATAL("Game failed to initialize.");
return false;
}
app_state->game_inst->on_resize(app_state->game_inst,app_state->width,app_state->height);
//initialized = true;
return true;
}
void application_get_framebuffer_size(u32* width,u32* height)
{
*width = app_state->width;
*height = app_state->height;
}
b8 application_run()
{
app_state->is_running = true;
clock_start(&app_state->clock);
clock_update(&app_state->clock);
app_state->last_time = app_state->clock.elapsed;
f64 running_time = 0;
u8 frame_count = 0;
f64 target_frame_seconds = 1.0f / 60;
KINFO(get_memory_usage_str());
while(app_state->is_running){
if(!platform_pump_messages(&app_state->platform))
{
app_state->is_running = false;
}
if(!app_state->is_suspended){
clock_update(&app_state->clock);
f64 current_time = app_state->clock.elapsed;
f64 delta = (current_time - app_state->last_time);
f64 frame_start_time = platform_get_absolute_time();
if(!app_state->game_inst->update(app_state->game_inst,(f32)delta))
{
KFATAL("Game update failed,shutting down.");
app_state->is_running = false;
break;
}
//Call the game render line
if(!app_state->game_inst->render(app_state->game_inst,(f32)delta))
{
KFATAL("Game render failed shutting down.");
app_state->is_running = false;
break;
}
render_packet packet;
packet.delta_time = delta;
renderer_draw_frame(&packet);
f64 frame_end_time = platform_get_absolute_time();
f64 frame_elapsed_time = frame_end_time - frame_start_time;
running_time += frame_elapsed_time;
f64 remaining_seconds = target_frame_seconds - frame_elapsed_time;
if (remaining_seconds >0)
{
u64 remaining_ms = (remaining_seconds * 1000);
b8 limit_frames = false;
if(remaining_ms >0 && limit_frames)
{
platform_sleep(remaining_ms - 1);
}
frame_count++;
}
input_update(delta);
app_state->last_time = current_time;
}
}
app_state->is_running = false;
event_unregister(EVENT_CODE_APPLICATION_QUIT,0,application_on_event);
event_unregister(EVENT_CODE_KEY_PRESSED,0,application_on_key);
event_unregister(EVENT_CODE_KEY_RELEASED,0,application_on_key);
event_shutdown();
input_shutdown();
renderer_shutdown();
platform_shutdown(&app_state->platform);
shutdown_memory();
return true;
}
b8 application_on_event(u16 code,void* sender,void* listener_inst,event_context context)
{
switch(code)
{
case EVENT_CODE_APPLICATION_QUIT:{
KINFO("EVENT_CODE_APPLICATION_QUIT received,shutting down.\n");
app_state->is_running = false;
return true;
}
}
return false;
}
b8 application_on_key(u16 code, void* sender,void* listener_inst,event_context context)
{
if(code == EVENT_CODE_KEY_PRESSED)
{
u16 key_code = context.data.u16[0];
if(key_code == KEY_ESCAPE)
{
event_context data = {};
event_fire(EVENT_CODE_APPLICATION_QUIT,0,data);
return true;
}else if(key_code == KEY_A)
{
KDEBUG("Explicit A Key pressed!");
}else
{
KDEBUG("'%c' key pressed in window.", key_code);
}
}else if(code == EVENT_CODE_KEY_RELEASED)
{
u16 key_code = context.data.u16[0];
if(key_code == KEY_B)
{
KDEBUG("Explicit B Key released!");
}else
{
KDEBUG("'%c' key released in window.",key_code);
}
}
return false;
}
b8 application_on_resized(u16 code,void* sender,void* listener_inst,event_context context)
{
if(code == EVENT_CODE_RESIZED)
{
u16 width = context.data.u16[0];
u16 height = context.data.u16[1];
//Check if defferent.If so trigger a resize event.
if(width != app_state->width || height!=app_state->height)
{
app_state->width = width;
app_state->height = height;
KDEBUG("Window resize: %i,%i",width,height);
//Handle minmization
if(width == 0 || height == 0)
{
KINFO("Window minimized, suspending application.");
return true;
}else
{
if(app_state->is_suspended)
{
KINFO("Window restored,resuming application.");
app_state->is_suspended = false;
}
app_state->game_inst->on_resize(app_state->game_inst,width,height);
renderer_on_resized(width,height);
}
}
}
return false;
}
3.asserts.h
#pragma once
#include "defines.h"
#define KASSERTIONS_ENABLED
#ifdef KASSERTIONS_ENABLED
#if _MSC_VER
#include <intrin.h>
#define debugBreak() __debugbreak()
#else
#define debugBreak() __builtin_trap()
#endif
KAPI void report_assertion_failure(const char* expression,const char* message,const char* file,i32 line);
# define KASSERT(expr) \
{ \
if(expr){ \
\
}else{ \
report_assertion_failure(#expr,"",__FILE__,__LINE__); \
debugBreak(); \
\
\
\
} \
}
# define KASSERT_MSG(expr,message) \
{ \
if(expr){ \
\
}else{ \
report_assertion_failure(#expr,message,__FILE__,__LINE__); \
debugBreak(); \
\
\
\
} \
}
# ifdef _DEBUG
# define KASSERT_DEBUG(expr) \
{ \
if(expr){ \
\
}else{ \
report_assertion_failure(#expr,"",__FILE__,__LINE__); \
debugBreak(); \
\
\
\
} \
}
#else
#define KASSERT_DEBUG(expr)
#endif
#else
#define KASSERT(expr)
#define KASSER_MSG(expr,message)
#define KASSERT_DEBUG(expr)
#endif