#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 #include #include SDL_Window* g_window; 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..."); float target_dt = 1.0f/settings->target_fps; if(settings->target_fps <= 0) { target_dt = 0; } _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; do { current = get_time_s(); _delta_time = current - _frame_start; SDL_Delay(1); program_handle_events(); } while(_delta_time <= target_dt); _frame_start = current; settings->on_tick(); settings->on_draw(); physics_world_tick(); } 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 _delta_time; }