summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'main.c')
-rw-r--r--main.c268
1 files changed, 268 insertions, 0 deletions
diff --git a/main.c b/main.c
new file mode 100644
index 0000000..53afb18
--- /dev/null
+++ b/main.c
@@ -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());
+}