#include "debug.h" #include "game.h" #include "input.h" #include "render.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define TARGET_FPS 60 #define TARGET_FPS_MS (1000 / (TARGET_FPS)) #define FALL_SPEED_NORMAL 500 // 500 ms #define FALL_SPEED_FAST 50 int fall_speed = FALL_SPEED_NORMAL; int last_fall = 0; int update(Uint64 delta) { input_update(); if (input_once(ACTION_QUIT)) { return -1; } if (!game_is_done()) { last_fall += delta; if (input_once(ACTION_ROTATE)) { game_rotate_shape(); } fall_speed = FALL_SPEED_NORMAL; if (input_repeat(ACTION_MOVE_LEFT)) { game_move_shape(-1); } else if (input_repeat(ACTION_MOVE_RIGHT)) { game_move_shape(1); } else if (input_repeat(ACTION_DROP)) { fall_speed = FALL_SPEED_FAST; } if (last_fall >= fall_speed) { // Keep leftover time to avoid drift when delta is larger than one tick. last_fall -= fall_speed; game_move_shape_down(); } } return 0; } void render() { if (game_is_done()) { render_game_over_text(); } else { render_clear(); game_render(); } render_present(); } void loop() { Uint64 last_frame = 0; for (;;) { Uint64 frame_time, current_time = SDL_GetTicks(); if (update(current_time - last_frame) < 0) { break; } render(); frame_time = SDL_GetTicks() - current_time; // Generates to much noise, enable if you need it. // debug_printf("frame time: %li, delay: %li\n", frame_time, (TARGET_FPS_MS - frame_time)); if (frame_time < TARGET_FPS_MS) { SDL_Delay(TARGET_FPS_MS - frame_time); } last_frame = current_time; } } int main(int argc, char** argv) { SDL_Window* window; SDL_Renderer *renderer; if (!SDL_Init(SDL_INIT_VIDEO)) { fprintf(stderr, "Failed to initalize SDL: %s\n", SDL_GetError()); return 1; } window = SDL_CreateWindow("Tetris", 800, 800, 0); if (!window) { fprintf(stderr, "Failed to create window: %s\n", SDL_GetError()); return 1; } if (!render_init(window)) { fprintf(stderr, "Failed to initalize renderer: %s\n", SDL_GetError()); return 1; } game_init(); loop(); render_shutdown(); SDL_DestroyWindow(window); SDL_Quit(); return 0; }