580 FPS means you are running a frame in about a millisecond. Thus, SDL_GetTicks(), with millisecond resolution, is not precise enough to really capture how long each frame lasts. I assume you want to use the "speed" calculation to perform delta time based physics? As your frame rate drops, the delta time for each frame becomes larger, and your game experience could be described as "choppy".
Here is a simple program demonstrating the idea:
#include <ctime>
#include <cmath>
#include <cstdlib>
#include <sstream>
#include <iostream>
#include "SDL.h"
int main() {
std::srand(static_cast<std::time_t>(std::time(nullptr)));
if(SDL_Init(SDL_INIT_VIDEO) < 0) {
std::cout << "Failed to initialise SDL: " << SDL_GetError() << std::endl;
return 1;
}
std::atexit(&SDL_Quit);
SDL_Surface *screen = SDL_SetVideoMode(400, 400, 0, SDL_SWSURFACE);
if(!screen) {
std::cout << "Failed to set video mode: " << SDL_GetError() << std::endl;
return 1;
}
float rectX = screen->w * 0.5f;
float rectY = screen->h * 0.5f;
const float rectWidth = screen->w * 0.1f;
const float rectHeight = screen->h * 0.1f;
const float rectSpeed = 0.1f;
float initialDirection = M_PI * std::rand() / static_cast<float>(RAND_MAX);
float rectDirectionX = std::cos(initialDirection);
float rectDirectionY = std::sin(initialDirection);
bool running = true;
int frames = 0;
int delay = 0;
Uint32 fpsTime = SDL_GetTicks();
Uint32 previous = SDL_GetTicks();
while(running) {
SDL_Event event;
while(SDL_PollEvent(&event)) {
if(event.type == SDL_QUIT) {
running = false;
} else if(event.type == SDL_KEYDOWN) {
if(event.key.keysym.sym == SDLK_ESCAPE) {
running = false;
} else if(event.key.keysym.sym == SDLK_UP) {
++delay;
} else if(event.key.keysym.sym == SDLK_DOWN) {
if(delay > 0) {
--delay;
}
}
}
}
Uint32 now = SDL_GetTicks();
Uint32 delta = now - previous;
previous = now;
rectX += delta * rectSpeed * rectDirectionX;
rectY += delta * rectSpeed * rectDirectionY;
if(rectX < 0 || rectX + rectWidth > screen->w) {
rectDirectionX *= -1;
}
if(rectY < 0 || rectY + rectWidth > screen->h) {
rectDirectionY *= -1;
}
if(now - fpsTime > 1000) {
std::stringstream title;
title << "FPS: " << frames << " (Delay factor: " << delay << ")";
SDL_WM_SetCaption(title.str().c_str(), nullptr);
fpsTime = now;
frames = 0;
}
const Uint32 black = 0;
SDL_FillRect(screen, nullptr, black);
SDL_Rect rect {
static_cast<Sint16>(rectX),
static_cast<Sint16>(rectY),
static_cast<Sint16>(rectWidth),
static_cast<Sint16>(rectHeight)
};
const Uint32 colour = SDL_MapRGB(screen->format, 0xff, 0x00, 0x00);
SDL_FillRect(screen, &rect, colour);
SDL_Flip(screen);
++frames;
if(delay > 0) {
SDL_Delay(delay * 10);
}
}
return 0;
}
Do you think this code is broadly representative of what your code is trying to do? What kind of results do you get with this code, with and without the video and with various "delay" factors?
Have you considered running a fixed time step instead?
Again, some of these issues are actually independent of the library you are using, and moving to another library will not necessarily solve them.

Find content
Not Telling