I see someone already fixed your problem, but there's another huge problem with this code: you're allocating resources and never freeing them. Further, you don't want to init the TTF system and load your font every single time you want to display a message, this is extremely inefficient considering in a game this is something that could happen tens of times per frame times 60 frames per second is hundreds of redundant calls to these functions a second. I would separate this into two functions. Note this is a very C-like way of doing this, someone else posted some C++ wrappers that would do this in a more C++-like way.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
bool init_ttf(const char* font_filename, int font_size, TTF_Font** font) {
if(TTF_Init()) {
goto error;
}
*font = TTF_OpenFont(font_filename, font_size);
if(nullptr == *font) {
goto error;
}
return true;
error:
log_error(TTF_GetError());
TTF_CloseFont(*font);
*font = nullptr;
TTF_Quit();
return false;
}
|
This function initializes the TTF library and loads a font at a specific size for you. You want to keep this around to pass to the second function.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
bool display_text(const char* message, SDL_Renderer* renderer, TTF_Font* font, int x, int y, SDL_Color color) {
bool success = false;
SDL_Surface* message_surface{nullptr};
SDL_Texture* message_texture{nullptr};
message_surface = TTF_RenderText_Solid(font, message, color);
if(nullptr == message_surface) {
log_error(TTF_GetError());
goto done;
}
message_texture = SDL_CreateSurfaceFromTexture(renderer, message_surface);
if(nullptr == message_texture) {
log_error(SDL_GetError());
goto done;
}
SDL_Rect dest_rect{x, y, message_surface->w, message_surface->h};
if(SDL_RenderCopy(renderer, message_texture, NULL, &dest_rect)) {
log_error(SDL_GetError());
goto done;
}
success = true;
done:
SDL_DestroyTexture(message_texture);
SDL_FreeSurface(message_surface);
return success;
}
|
Every function that allocates a resource and does not return that resource should free those resources. Every time. Without exception. As I mentioned above this is a very C-like way of doing this, so you may not want to use my method of doing this, but my point is that there is no code path that does not free resources. If there is an error, everything gets freed first. If there is success, it also gets freed.
You should also work on your variable names. What are a and sr? It's obvious (somewhat) looking at the parameter list, but I'm 10 lines down and I can't remember what sr is. Just call it renderer, it's just a few extra keystrokes.