diff --git a/main.c b/main.c index f31a1d8..a18001a 100644 --- a/main.c +++ b/main.c @@ -4,58 +4,137 @@ #include #include // only include this one in the source file with main()! +#define INITIAL_FPS 60 + SDL_Window* window = NULL; SDL_Renderer* renderer = NULL; +static double FPS = INITIAL_FPS; +static double FrameTime = 1.0 / INITIAL_FPS; + +static double PerformancePeriod; + static void panic ( const char *text ) __attribute__((noreturn)); +static double GetTime() +{ + return PerformancePeriod * SDL_GetPerformanceCounter(); +} + +static void SetTitle(SDL_Window * window) +{ + char title[48] = {0}; + SDL_snprintf(title, sizeof(title), "Crude frame limiter @ %6.3f Hz", FPS); + SDL_SetWindowTitle(window, title); +} + void panic ( const char *text ) { - fprintf(stderr, "ERROR: %s. %s\n", text, SDL_GetError()); - SDL_DestroyRenderer(renderer); - SDL_DestroyWindow(window); - SDL_Quit(); - exit(1); + fprintf(stderr, "ERROR: %s. %s\n", text, SDL_GetError()); + SDL_DestroyRenderer(renderer); + SDL_DestroyWindow(window); + SDL_Quit(); + exit(1); } int main( int argc, char* argv[] ) { const int WIDTH = 640; const int HEIGHT = 480; + int delay_threshold = 2; + double sleep_time; + double time_counter = 0; bool loopShouldStop = false; + SDL_SetHint(SDL_HINT_RENDER_VSYNC, 0); + if (!SDL_Init(SDL_INIT_VIDEO)) { panic("SDL_Init failed"); } - window = SDL_CreateWindow("Hello SDL", WIDTH, HEIGHT, 0); - if (!window) + PerformancePeriod = 1.0 / SDL_GetPerformanceFrequency(); + time_counter = GetTime(); + + window = SDL_CreateWindow("Hello SDL", WIDTH, HEIGHT, SDL_WINDOW_OPENGL); + if (!window) { panic("SDL_CreateWindow"); } renderer = SDL_CreateRenderer(window, "opengl"); - if (!renderer) + if (!renderer) { panic("SDL_CreateRenderer"); } - int orange = 0; + //SDL_GetWindowSize(window, &width, &height); + SetTitle(window); + + //if (!SDL_SetRenderVSync(renderer, 1)) + //{ + // panic("SDL_SetRenderVSync"); + //} + + SDL_HideCursor(); + + int red = 0; + int green = 0; while (!loopShouldStop) { SDL_Event e; SDL_zero(e); while (SDL_PollEvent(&e)) { - if (e.type == SDL_EVENT_KEY_DOWN && e.key.mod == SDL_KMOD_LCTRL && e.key.key == SDLK_Q) + if (e.type == SDL_EVENT_QUIT) + loopShouldStop = true; + else if (e.type == SDL_EVENT_KEY_DOWN) + { + if (e.key.key == SDLK_X) + { + FPS -= 0.1; + if (FPS < 1) + { + FPS = 1; + } + FrameTime = 1.0 / FPS; + SetTitle(window); + } + else if (e.key.key == SDLK_C) + { + FPS += 0.1; + FrameTime = 1.0 / FPS; + SetTitle(window); + } + } + else if (e.key.mod == SDL_KMOD_LCTRL && e.key.key == SDLK_Q) loopShouldStop = true; } - SDL_SetRenderDrawColor(renderer, 0, orange, 0, 255); + SDL_SetRenderDrawColor(renderer, red, green, 0, 255); SDL_RenderClear(renderer); + + sleep_time = time_counter - GetTime(); + if (sleep_time * 1000 > delay_threshold) + { + Uint32 ms = (Uint32)(sleep_time * 1000) - delay_threshold; + SDL_Delay(ms); + if (time_counter < GetTime()) + { + delay_threshold++; + SDL_Log("Slept too long. Increased threshold to %u ms.", delay_threshold); + } + } + + while (time_counter > GetTime()) { + /* Waiting for the right moment. */ + } + SDL_RenderPresent(renderer); - orange = (orange + 1) % 256; + red = (red + 1) % 256; + green = (green + 1) % 64; + + time_counter += FrameTime; } SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window);