diff options
Diffstat (limited to 'main.c')
-rw-r--r-- | main.c | 268 |
1 files changed, 268 insertions, 0 deletions
@@ -0,0 +1,268 @@ +#include "main.h" +#include <SDL2/SDL_rect.h> +#include <SDL2/SDL_timer.h> +#include <stdio.h> +#include <SDL2/SDL.h> +#include <SDL2/SDL_ttf.h> + +#include "player.h" +#include "input.h" +#include "characters.h" + +#define DEFAULT_SCREEN_WIDTH 800 +#define DEFAULT_SCREEN_HEIGHT 600 + +#define SCREEN_FPS 60 +#define DELTA_TIME_SEC (1.0f / SCREEN_FPS) +#define DELTA_TIME_MS ((Uint32)floorf(DELTA_TIME_SEC * 1000.0f)) +#define SIMULATION_STEP_MS 10 + +#define RENDER_ENABLED 1 +#define SHOW_FPS 1 + +int main() +{ + SDL_Window *window; + SDL_Renderer *renderer; + /* SDL_Texture *fps_texture; */ + TTF_Font *Sans; + + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + fprintf(stderr, "SDL ERROR: %s\n", SDL_GetError()); + exit(1); + } + window = + SDL_CreateWindow("Space Battle", 100, 100, DEFAULT_SCREEN_WIDTH, + DEFAULT_SCREEN_HEIGHT, SDL_WINDOW_RESIZABLE); + + if (window == NULL) { + fprintf(stderr, "COULD NOT CREATE SDL WINDOW: %s\n", + SDL_GetError()); + exit(1); + } + + if (RENDER_ENABLED) { + renderer = SDL_CreateRenderer(window, -1, + SDL_RENDERER_ACCELERATED); + + if (renderer == NULL) { + fprintf(stderr, "COULD NOT CREATE SDL RENDERER: %s\n", + SDL_GetError()); + exit(1); + } + TTF_Init(); + Sans = TTF_OpenFont("resources/OpenSans-Regular.ttf", 12); + if (!Sans) { + fprintf(stderr, "COULD NOT OPEN FONT: %s\n", + SDL_GetError()); + exit(1); + } + } + + // TODO: outsource shape definitions + SDL_Vertex vert[3]; + + // center + vert[0].position.x = 400; + vert[0].position.y = 0; + vert[0].color.r = 255; + vert[0].color.g = 0; + vert[0].color.b = 0; + vert[0].color.a = 255; + + // left + vert[1].position.x = 200; + vert[1].position.y = 450; + vert[1].color.r = 0; + vert[1].color.g = 0; + vert[1].color.b = 255; + vert[1].color.a = 255; + + // right + vert[2].position.x = 600; + vert[2].position.y = 450; + vert[2].color.r = 0; + vert[2].color.g = 255; + vert[2].color.b = 0; + vert[2].color.a = 255; + + struct Player player_1 = TEMPLATE_1; + player_1.geometry = vert; + player_1.geometry_len = 3; + + + int action_states[ACTION_STATE_COUNT]; + for (int i = 0; i < ACTION_STATE_COUNT; i++) { + action_states[i] = 0; + } + + int win_x = DEFAULT_SCREEN_WIDTH; + int win_y = DEFAULT_SCREEN_HEIGHT; + int quit = 0; + + // based on: + // https://gafferongames.com/post/fix_your_timestep/ + // doesn't include state-interpolation (yet?) + double physics_total_time = 0.0; + const double physics_timestep = 1 / 60.0; + const double render_timestep = 1 / 60.0; + double current_time = current_sdl_time_in_seconds(); + double physics_time_accumulator = 0.0; + double render_time_accumulator = 0.0; + + float fps = 0.0f; + char fps_text[123] = "start"; + + while (!quit) { + double new_time = current_sdl_time_in_seconds(); + double frame_time = new_time - current_time; + current_time = new_time; + + physics_time_accumulator += frame_time; + render_time_accumulator += frame_time; + + while (physics_time_accumulator >= physics_timestep) { + SDL_Event event; + while (!quit && SDL_PollEvent(&event)) { + /* // e.g. https://stackoverflow.com/a/1252996 */ + handleKeyboardEvent(action_states, event); + + if (action_states[ACTION_QUIT]) + quit = 1; + } + + execute_actions(&player_1, action_states, + physics_timestep); + /* player_move(&player_1, physics_timestep); */ + + physics_time_accumulator -= physics_timestep; + physics_total_time += physics_timestep; + } + + if (RENDER_ENABLED && + render_time_accumulator >= render_timestep) { + /* SDL_SetRenderDrawColor(renderer, HEX_COLOR(BACKGROUND_COLOR)); */ + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); + + SDL_RenderClear(renderer); + + /* render_my_stuff(renderer); */ + /* hexagon_draw(&hex, renderer); */ + + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); + + /* SDL_Rect box = { player_1.pos_x, player_1.pos_y, */ + /* player_1.pos_x + 200, */ + /* player_1.pos_y + 200 }; */ + /* SDL_RenderFillRect(renderer, &box); */ + + /* SDL_RenderDrawLine(renderer, 0, 0, 1000, 1000); */ + + SDL_RenderGeometry(renderer, NULL, player_1.geometry, + player_1.geometry_len, NULL, 0); + + SDL_GetWindowSize(window, &win_x, &win_y); + + if (SHOW_FPS) { + fps = round(1.0f / render_time_accumulator); + sprintf(fps_text, "FPS:%.0f", fps); + + SDL_Rect fps_pos = { 0, 0, 0, 0 }; + render_text(fps_text, fps_pos, Sans, renderer); + + // show action states + if (action_states[ACTION_MOVE_UP]) { + SDL_Rect up_text = { 100, 600, 120, + 620 }; + render_text("UP", up_text, Sans, + renderer); + } + if (action_states[ACTION_MOVE_DOWN]) { + SDL_Rect up_text = { 100, 620, 120, + 640 }; + render_text("DOWN", up_text, Sans, + renderer); + } + if (action_states[ACTION_MOVE_LEFT]) { + SDL_Rect up_text = { 60, 620, 80, 640 }; + render_text("LEFT", up_text, Sans, + renderer); + } + if (action_states[ACTION_MOVE_RIGHT]) { + SDL_Rect up_text = { 140, 620, 160, + 640 }; + render_text("RIGHT", up_text, Sans, + renderer); + } + + // show player attributes + char x_speed_text[123]; + sprintf(x_speed_text, "x-speed: %f", + player_1.vel_x); + SDL_Rect x_speed_text_pos = { 900, 900, 910, + 910 }; + render_text(x_speed_text, x_speed_text_pos, + Sans, renderer); + + char y_speed_text[123]; + sprintf(y_speed_text, "y-speed: %f", + player_1.vel_y); + SDL_Rect y_speed_text_pos = { 900, 920, 910, + 930 }; + render_text(y_speed_text, y_speed_text_pos, + Sans, renderer); + } + + render_time_accumulator = 0; + SDL_RenderPresent(renderer); + } + } + + if (RENDER_ENABLED) { + TTF_CloseFont(Sans); + TTF_Quit(); + + SDL_DestroyRenderer(renderer); + SDL_DestroyWindow(window); + } + SDL_Quit(); + return 0; +} + +void execute_actions(struct Player *player, int *action_states, float delta) +{ + if (action_states[ACTION_MOVE_UP]) { + player_move(player, UP, delta); + } + if (action_states[ACTION_MOVE_DOWN]) { + player_move(player, DOWN, delta); + } + if (action_states[ACTION_MOVE_LEFT]) { + player_move(player, LEFT, delta); + } + if (action_states[ACTION_MOVE_RIGHT]) { + player_move(player, RIGHT, delta); + } +} + +void render_text(char *text, SDL_Rect dest, TTF_Font *Sans, + SDL_Renderer *renderer) +{ + SDL_Color fps_color = { 0, 255, 0, 255 }; + SDL_Surface *surf = TTF_RenderText_Solid(Sans, text, fps_color); + + dest.w = surf->w; + dest.h = surf->h; + + SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surf); + SDL_RenderCopy(renderer, texture, NULL, &dest); + + SDL_DestroyTexture(texture); + SDL_FreeSurface(surf); +} + +double current_sdl_time_in_seconds() +{ + return ((double)SDL_GetPerformanceCounter() / + (double)SDL_GetPerformanceFrequency()); +} |