fencer/src/program.c
2023-10-16 21:31:48 +02:00

130 lines
3 KiB
C

#include "program.h"
#include "camera.h"
#include "physics_world.h"
#include "sprite.h"
#include "time.h"
#include "assets.h"
#include "debug.h"
#include "input.h"
#include <assert.h>
#include <SDL2/SDL_video.h>
#include <SDL2/SDL_image.h>
SDL_Window* g_window;
static double _target_delta_time = 0.0;
static double _delta_time;
static double _frame_start;
static double _game_start_time;
#define INITFLAGS SDL_INIT_EVENTS | SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_GAMECONTROLLER
static inline
double tstos(struct timespec ts) {
return (double)ts.tv_sec + (double)ts.tv_nsec * 1E-09;
}
struct timespec get_time() {
struct timespec ts;
timespec_get(&ts, TIME_UTC);
return ts;
}
double get_time_s() {
return tstos(get_time());
}
int program_run(const struct ProgramSettings* settings) {
LOG_INFO("Starting program...");
if(settings->target_fps <= 0) {
_target_delta_time = 0;
} else {
_target_delta_time = 1.0f/settings->target_fps;
}
_game_start_time = _frame_start = get_time_s();
SDL_Init(INITFLAGS);
g_window = SDL_CreateWindow(
settings->title,
SDL_WINDOWPOS_CENTERED_DISPLAY(0),
SDL_WINDOWPOS_CENTERED_DISPLAY(0),
settings->view_resolution.x,
settings->view_resolution.y,
SDL_WINDOW_MAXIMIZED | SDL_WINDOW_RESIZABLE);
render_init(g_window, settings);
assets_init();
camera_init();
input_init();
physics_world_init();
LOG_INFO("settings->on_play");
settings->on_play();
LOG_INFO("Starting program loop");
for(;;) {
render_present();
double current_time = get_time_s();
_delta_time += current_time - _frame_start;
_frame_start = current_time;
while(_delta_time > _target_delta_time) {
_delta_time -= _target_delta_time;
settings->on_tick();
physics_world_tick();
}
program_handle_events();
settings->on_draw();
SDL_Delay(1);
}
LOG_ERROR("Failed to exit");
abort();
}
void program_quit() {
assets_clean();
render_clean();
input_clean();
physics_world_clean();
SDL_DestroyWindow(g_window);
SDL_Quit();
exit(0);
}
void program_handle_events() {
SDL_Event event;
while(SDL_PollEvent(&event)) {
switch(event.type) {
default: break;
case SDL_KEYUP:
case SDL_KEYDOWN:
input_handle_event(event);
break;
case SDL_WINDOWEVENT:
if(event.window.windowID == SDL_GetWindowID(g_window)) {
program_handle_windowevent(&event.window);
}
break;
case SDL_QUIT:
program_quit();
break;
}
}
}
void program_handle_windowevent(SDL_WindowEvent* event) {
switch(event->type) {
default:
render_handle_resize();
break;
}
}
inline
float delta_time() {
return _target_delta_time == 0 ? _delta_time : _target_delta_time;
}