#include // for fprintf() #include // for exit() #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); } 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"); } 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) { panic("SDL_CreateRenderer"); } //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_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, 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); red = (red + 1) % 256; green = (green + 1) % 64; time_counter += FrameTime; } SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); exit(0); }